JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.0
[ckeditor.git] / _source / plugins / panel / plugin.js
diff --git a/_source/plugins/panel/plugin.js b/_source/plugins/panel/plugin.js
new file mode 100644 (file)
index 0000000..603fc25
--- /dev/null
@@ -0,0 +1,330 @@
+/*\r
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.html or http://ckeditor.com/license\r
+*/\r
+\r
+CKEDITOR.plugins.add( 'panel',\r
+{\r
+       beforeInit : function( editor )\r
+       {\r
+               editor.ui.addHandler( CKEDITOR.UI_PANEL, CKEDITOR.ui.panel.handler );\r
+       }\r
+});\r
+\r
+/**\r
+ * Panel UI element.\r
+ * @constant\r
+ * @example\r
+ */\r
+CKEDITOR.UI_PANEL = 2;\r
+\r
+CKEDITOR.ui.panel = function( document, definition )\r
+{\r
+       // Copy all definition properties to this object.\r
+       if ( definition )\r
+               CKEDITOR.tools.extend( this, definition );\r
+\r
+       // Set defaults.\r
+       CKEDITOR.tools.extend( this,\r
+               {\r
+                       className : '',\r
+                       css : []\r
+               });\r
+\r
+       this.id = CKEDITOR.tools.getNextNumber();\r
+       this.document = document;\r
+\r
+       this._ =\r
+       {\r
+               blocks : {}\r
+       };\r
+};\r
+\r
+/**\r
+ * Transforms a rich combo definition in a {@link CKEDITOR.ui.richCombo}\r
+ * instance.\r
+ * @type Object\r
+ * @example\r
+ */\r
+CKEDITOR.ui.panel.handler =\r
+{\r
+       create : function( definition )\r
+       {\r
+               return new CKEDITOR.ui.panel( definition );\r
+       }\r
+};\r
+\r
+CKEDITOR.ui.panel.prototype =\r
+{\r
+       renderHtml : function( editor )\r
+       {\r
+               var output = [];\r
+               this.render( editor, output );\r
+               return output.join( '' );\r
+       },\r
+\r
+       /**\r
+        * Renders the combo.\r
+        * @param {CKEDITOR.editor} editor The editor instance which this button is\r
+        *              to be used by.\r
+        * @param {Array} output The output array to which append the HTML relative\r
+        *              to this button.\r
+        * @example\r
+        */\r
+       render : function( editor, output )\r
+       {\r
+               var id = 'cke_' + this.id;\r
+\r
+               output.push(\r
+                       '<div class="', editor.skinClass ,'"' +\r
+                               ' lang="', editor.langCode, '"' +\r
+                               // iframe loading need sometime, keep the panel hidden(#4186).\r
+                               ' style="display:none;z-index:' + ( editor.config.baseFloatZIndex + 1 ) + '">' +\r
+                               '<div' +\r
+                                       ' id=', id,\r
+                                       ' dir=', editor.lang.dir,\r
+                                       ' class="cke_panel cke_', editor.lang.dir );\r
+\r
+               if ( this.className )\r
+                       output.push( ' ', this.className );\r
+\r
+               output.push(\r
+                               '">' );\r
+\r
+               if ( this.forceIFrame || this.css.length )\r
+               {\r
+                       output.push(\r
+                                               '<iframe id="', id, '_frame"' +\r
+                                                       ' frameborder="0"' +\r
+                                                       ' src="javascript:void(' );\r
+\r
+                       output.push(\r
+                                                       // Support for custom document.domain in IE.\r
+                                                       CKEDITOR.env.isCustomDomain() ?\r
+                                                               '(function(){' +\r
+                                                                       'document.open();' +\r
+                                                                       'document.domain=\'' + document.domain + '\';' +\r
+                                                                       'document.close();' +\r
+                                                               '})()'\r
+                                                       :\r
+                                                               '0' );\r
+\r
+                       output.push(\r
+                                               ')"></iframe>' );\r
+               }\r
+\r
+               output.push(\r
+                               '</div>' +\r
+                       '</div>' );\r
+\r
+               return id;\r
+       },\r
+\r
+       getHolderElement : function()\r
+       {\r
+               var holder = this._.holder;\r
+\r
+               if ( !holder )\r
+               {\r
+                       if ( this.forceIFrame || this.css.length )\r
+                       {\r
+                               var iframe = this.document.getById( 'cke_' + this.id + '_frame' ),\r
+                                       parentDiv = iframe.getParent(),\r
+                                       dir = parentDiv.getAttribute( 'dir' ),\r
+                                       className = parentDiv.getParent().getAttribute( 'class' ),\r
+                                       langCode = parentDiv.getParent().getAttribute( 'lang' ),\r
+                                       doc = iframe.getFrameDocument();\r
+                               // Initialize the IFRAME document body.\r
+                               doc.$.open();\r
+\r
+                               // Support for custom document.domain in IE.\r
+                               if ( CKEDITOR.env.isCustomDomain() )\r
+                                       doc.$.domain = document.domain;\r
+\r
+                               var onLoad = CKEDITOR.tools.addFunction( CKEDITOR.tools.bind( function( ev )\r
+                                       {\r
+                                               this.isLoaded = true;\r
+                                               if ( this.onLoad )\r
+                                                       this.onLoad();\r
+                                       }, this ) );\r
+\r
+                               doc.$.write(\r
+                                       '<!DOCTYPE html>' +\r
+                                       '<html dir="' + dir + '" class="' + className + '_container" lang="' + langCode + '">' +\r
+                                               '<head>' +\r
+                                                       '<style>.' + className + '_container{visibility:hidden}</style>' +\r
+                                               '</head>' +\r
+                                               '<body class="cke_' + dir + ' cke_panel_frame ' + CKEDITOR.env.cssClass + '" style="margin:0;padding:0"' +\r
+                                               ' onload="( window.CKEDITOR || window.parent.CKEDITOR ).tools.callFunction(' + onLoad + ');">' +\r
+                                               '</body>' +\r
+                                               // It looks strange, but for FF2, the styles must go\r
+                                               // after <body>, so it (body) becames immediatelly\r
+                                               // available. (#3031)\r
+                                               '<link type="text/css" rel=stylesheet href="' + this.css.join( '"><link type="text/css" rel="stylesheet" href="' ) + '">' +\r
+                                       '<\/html>' );\r
+                               doc.$.close();\r
+\r
+                               var win = doc.getWindow();\r
+\r
+                               // Register the CKEDITOR global.\r
+                               win.$.CKEDITOR = CKEDITOR;\r
+\r
+                               doc.on( 'keydown', function( evt )\r
+                                       {\r
+                                               var keystroke = evt.data.getKeystroke();\r
+\r
+                                               // Delegate key processing to block.\r
+                                               if ( this._.onKeyDown && this._.onKeyDown( keystroke ) === false )\r
+                                               {\r
+                                                       evt.data.preventDefault();\r
+                                                       return;\r
+                                               }\r
+\r
+                                               if ( keystroke == 27 )          // ESC\r
+                                                       this.onEscape && this.onEscape();\r
+                                       },\r
+                                       this );\r
+\r
+                               holder = doc.getBody();\r
+                       }\r
+                       else\r
+                               holder = this.document.getById( 'cke_' + this.id );\r
+\r
+                       this._.holder = holder;\r
+               }\r
+\r
+               return holder;\r
+       },\r
+\r
+       addBlock : function( name, block )\r
+       {\r
+               block = this._.blocks[ name ] = block || new CKEDITOR.ui.panel.block( this.getHolderElement() );\r
+\r
+               if ( !this._.currentBlock )\r
+                       this.showBlock( name );\r
+\r
+               return block;\r
+       },\r
+\r
+       getBlock : function( name )\r
+       {\r
+               return this._.blocks[ name ];\r
+       },\r
+\r
+       showBlock : function( name )\r
+       {\r
+               var blocks = this._.blocks,\r
+                       block = blocks[ name ],\r
+                       current = this._.currentBlock;\r
+\r
+               if ( current )\r
+                       current.hide();\r
+\r
+               this._.currentBlock = block;\r
+\r
+               // Reset the focus index, so it will always go into the first one.\r
+               block._.focusIndex = -1;\r
+\r
+               this._.onKeyDown = block.onKeyDown && CKEDITOR.tools.bind( block.onKeyDown, block );\r
+\r
+               block.show();\r
+\r
+               return block;\r
+       }\r
+};\r
+\r
+CKEDITOR.ui.panel.block = CKEDITOR.tools.createClass(\r
+{\r
+       $ : function( blockHolder )\r
+       {\r
+               this.element = blockHolder.append(\r
+                       blockHolder.getDocument().createElement( 'div',\r
+                               {\r
+                                       attributes :\r
+                                       {\r
+                                               'class' : 'cke_panel_block'\r
+                                       },\r
+                                       styles :\r
+                                       {\r
+                                               display : 'none'\r
+                                       }\r
+                               }) );\r
+\r
+               this.keys = {};\r
+\r
+               this._.focusIndex = -1;\r
+       },\r
+\r
+       _ : {},\r
+\r
+       proto :\r
+       {\r
+               show : function()\r
+               {\r
+                       this.element.setStyle( 'display', '' );\r
+               },\r
+\r
+               hide : function()\r
+               {\r
+                       if ( !this.onHide || this.onHide.call( this )  !== true )\r
+                               this.element.setStyle( 'display', 'none' );\r
+               },\r
+\r
+               onKeyDown : function( keystroke )\r
+               {\r
+                       var keyAction = this.keys[ keystroke ];\r
+                       switch ( keyAction )\r
+                       {\r
+                               // Move forward.\r
+                               case 'next' :\r
+                                       var index = this._.focusIndex,\r
+                                               links = this.element.getElementsByTag( 'a' ),\r
+                                               link;\r
+\r
+                                       while ( ( link = links.getItem( ++index ) ) )\r
+                                       {\r
+                                               // Move the focus only if the element is marked with\r
+                                               // the _cke_focus and it it's visible (check if it has\r
+                                               // width).\r
+                                               if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth )\r
+                                               {\r
+                                                       this._.focusIndex = index;\r
+                                                       link.focus();\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       return false;\r
+\r
+                               // Move backward.\r
+                               case 'prev' :\r
+                                       index = this._.focusIndex;\r
+                                       links = this.element.getElementsByTag( 'a' );\r
+\r
+                                       while ( index > 0 && ( link = links.getItem( --index ) ) )\r
+                                       {\r
+                                               // Move the focus only if the element is marked with\r
+                                               // the _cke_focus and it it's visible (check if it has\r
+                                               // width).\r
+                                               if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth )\r
+                                               {\r
+                                                       this._.focusIndex = index;\r
+                                                       link.focus();\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+                                       return false;\r
+\r
+                               case 'click' :\r
+                                       index = this._.focusIndex;\r
+                                       link = index >= 0 && this.element.getElementsByTag( 'a' ).getItem( index );\r
+\r
+                                       if ( link )\r
+                                               link.$.click ? link.$.click() : link.$.onclick();\r
+\r
+                                       return false;\r
+                       }\r
+\r
+                       return true;\r
+               }\r
+       }\r
+});\r