X-Git-Url: https://scm.cri.minesparis.psl.eu/git/ckeditor.git/blobdiff_plain/256592bf803e851aa7fc953e08a6e9e58d970f8c..871bad8291b6dbc29d489d95d185458caab25158:/skins/ckeditor/_source/plugins/panel/plugin.js diff --git a/skins/ckeditor/_source/plugins/panel/plugin.js b/skins/ckeditor/_source/plugins/panel/plugin.js new file mode 100644 index 0000000..cb0a615 --- /dev/null +++ b/skins/ckeditor/_source/plugins/panel/plugin.js @@ -0,0 +1,403 @@ +/* +Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. +For licensing, see LICENSE.html or http://ckeditor.com/license +*/ + +CKEDITOR.plugins.add( 'panel', +{ + beforeInit : function( editor ) + { + editor.ui.addHandler( CKEDITOR.UI_PANEL, CKEDITOR.ui.panel.handler ); + } +}); + +/** + * Panel UI element. + * @constant + * @example + */ +CKEDITOR.UI_PANEL = 'panel'; + +CKEDITOR.ui.panel = function( document, definition ) +{ + // Copy all definition properties to this object. + if ( definition ) + CKEDITOR.tools.extend( this, definition ); + + // Set defaults. + CKEDITOR.tools.extend( this, + { + className : '', + css : [] + }); + + this.id = CKEDITOR.tools.getNextId(); + this.document = document; + + this._ = + { + blocks : {} + }; +}; + +/** + * Transforms a rich combo definition in a {@link CKEDITOR.ui.richCombo} + * instance. + * @type Object + * @example + */ +CKEDITOR.ui.panel.handler = +{ + create : function( definition ) + { + return new CKEDITOR.ui.panel( definition ); + } +}; + +CKEDITOR.ui.panel.prototype = +{ + renderHtml : function( editor ) + { + var output = []; + this.render( editor, output ); + return output.join( '' ); + }, + + /** + * Renders the combo. + * @param {CKEDITOR.editor} editor The editor instance which this button is + * to be used by. + * @param {Array} output The output array to which append the HTML relative + * to this button. + * @example + */ + render : function( editor, output ) + { + var id = this.id; + + output.push( + '
' ); + + return id; + }, + + getHolderElement : function() + { + var holder = this._.holder; + + if ( !holder ) + { + if ( this.forceIFrame || this.css.length ) + { + var iframe = this.document.getById( this.id + '_frame' ), + parentDiv = iframe.getParent(), + dir = parentDiv.getAttribute( 'dir' ), + className = parentDiv.getParent().getAttribute( 'class' ), + langCode = parentDiv.getParent().getAttribute( 'lang' ), + doc = iframe.getFrameDocument(); + + var onLoad = CKEDITOR.tools.addFunction( CKEDITOR.tools.bind( function( ev ) + { + this.isLoaded = true; + if ( this.onLoad ) + this.onLoad(); + }, this ) ); + + var data = + '' + + '' + + '' + + '' + + '' + + '' + + // It looks strange, but for FF2, the styles must go + // after , so it (body) becames immediatelly + // available. (#3031) + CKEDITOR.tools.buildStyleHtml( this.css ) + + '<\/html>'; + + doc.write( data ); + + var win = doc.getWindow(); + + // Register the CKEDITOR global. + win.$.CKEDITOR = CKEDITOR; + + // Arrow keys for scrolling is only preventable with 'keypress' event in Opera (#4534). + doc.on( 'key' + ( CKEDITOR.env.opera? 'press':'down' ), function( evt ) + { + var keystroke = evt.data.getKeystroke(), + dir = this.document.getById( this.id ).getAttribute( 'dir' ); + + // Delegate key processing to block. + if ( this._.onKeyDown && this._.onKeyDown( keystroke ) === false ) + { + evt.data.preventDefault(); + return; + } + + // ESC/ARROW-LEFT(ltr) OR ARROW-RIGHT(rtl) + if ( keystroke == 27 || keystroke == ( dir == 'rtl' ? 39 : 37 ) ) + { + if ( this.onEscape && this.onEscape( keystroke ) === false ) + evt.data.preventDefault(); + } + }, + this ); + + holder = doc.getBody(); + holder.unselectable(); + CKEDITOR.env.air && CKEDITOR.tools.callFunction( onLoad ); + } + else + holder = this.document.getById( this.id ); + + this._.holder = holder; + } + + return holder; + }, + + addBlock : function( name, block ) + { + block = this._.blocks[ name ] = block instanceof CKEDITOR.ui.panel.block ? block + : new CKEDITOR.ui.panel.block( this.getHolderElement(), block ); + + if ( !this._.currentBlock ) + this.showBlock( name ); + + return block; + }, + + getBlock : function( name ) + { + return this._.blocks[ name ]; + }, + + showBlock : function( name ) + { + var blocks = this._.blocks, + block = blocks[ name ], + current = this._.currentBlock, + holder = this.forceIFrame ? + this.document.getById( this.id + '_frame' ) + : this._.holder; + + // Disable context menu for block panel. + holder.getParent().getParent().disableContextMenu(); + + if ( current ) + { + // Clean up the current block's effects on holder. + holder.removeAttributes( current.attributes ); + current.hide(); + } + + this._.currentBlock = block; + + holder.setAttributes( block.attributes ); + CKEDITOR.fire( 'ariaWidget', holder ); + + // Reset the focus index, so it will always go into the first one. + block._.focusIndex = -1; + + this._.onKeyDown = block.onKeyDown && CKEDITOR.tools.bind( block.onKeyDown, block ); + + block.onMark = function( item ) + { + holder.setAttribute( 'aria-activedescendant', item.getId() + '_option' ); + }; + + block.onUnmark = function() + { + holder.removeAttribute( 'aria-activedescendant' ); + }; + + block.show(); + + return block; + }, + + destroy : function() + { + this.element && this.element.remove(); + } +}; + +CKEDITOR.ui.panel.block = CKEDITOR.tools.createClass( +{ + $ : function( blockHolder, blockDefinition ) + { + this.element = blockHolder.append( + blockHolder.getDocument().createElement( 'div', + { + attributes : + { + 'tabIndex' : -1, + 'class' : 'cke_panel_block', + 'role' : 'presentation' + }, + styles : + { + display : 'none' + } + }) ); + + // Copy all definition properties to this object. + if ( blockDefinition ) + CKEDITOR.tools.extend( this, blockDefinition ); + + if ( !this.attributes.title ) + this.attributes.title = this.attributes[ 'aria-label' ]; + + this.keys = {}; + + this._.focusIndex = -1; + + // Disable context menu for panels. + this.element.disableContextMenu(); + }, + + _ : { + + /** + * Mark the item specified by the index as current activated. + */ + markItem: function( index ) + { + if ( index == -1 ) + return; + var links = this.element.getElementsByTag( 'a' ); + var item = links.getItem( this._.focusIndex = index ); + + // Safari need focus on the iframe window first(#3389), but we need + // lock the blur to avoid hiding the panel. + if ( CKEDITOR.env.webkit || CKEDITOR.env.opera ) + item.getDocument().getWindow().focus(); + item.focus(); + + this.onMark && this.onMark( item ); + } + }, + + proto : + { + show : function() + { + this.element.setStyle( 'display', '' ); + }, + + hide : function() + { + if ( !this.onHide || this.onHide.call( this ) !== true ) + this.element.setStyle( 'display', 'none' ); + }, + + onKeyDown : function( keystroke ) + { + var keyAction = this.keys[ keystroke ]; + switch ( keyAction ) + { + // Move forward. + case 'next' : + var index = this._.focusIndex, + links = this.element.getElementsByTag( 'a' ), + link; + + while ( ( link = links.getItem( ++index ) ) ) + { + // Move the focus only if the element is marked with + // the _cke_focus and it it's visible (check if it has + // width). + if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth ) + { + this._.focusIndex = index; + link.focus(); + break; + } + } + return false; + + // Move backward. + case 'prev' : + index = this._.focusIndex; + links = this.element.getElementsByTag( 'a' ); + + while ( index > 0 && ( link = links.getItem( --index ) ) ) + { + // Move the focus only if the element is marked with + // the _cke_focus and it it's visible (check if it has + // width). + if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth ) + { + this._.focusIndex = index; + link.focus(); + break; + } + } + return false; + + case 'click' : + case 'mouseup' : + index = this._.focusIndex; + link = index >= 0 && this.element.getElementsByTag( 'a' ).getItem( index ); + + if ( link ) + link.$[ keyAction ] ? link.$[ keyAction ]() : link.$[ 'on' + keyAction ](); + + return false; + } + + return true; + } + } +}); + +/** + * Fired when a panel is added to the document + * @name CKEDITOR#ariaWidget + * @event + * @param {Object} holder The element wrapping the panel + */