JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.0
[ckeditor.git] / _source / plugins / richcombo / plugin.js
diff --git a/_source/plugins/richcombo/plugin.js b/_source/plugins/richcombo/plugin.js
new file mode 100644 (file)
index 0000000..f76db46
--- /dev/null
@@ -0,0 +1,357 @@
+/*\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( 'richcombo',\r
+{\r
+       requires : [ 'floatpanel', 'listblock', 'button' ],\r
+\r
+       beforeInit : function( editor )\r
+       {\r
+               editor.ui.addHandler( CKEDITOR.UI_RICHCOMBO, CKEDITOR.ui.richCombo.handler );\r
+       }\r
+});\r
+\r
+/**\r
+ * Button UI element.\r
+ * @constant\r
+ * @example\r
+ */\r
+CKEDITOR.UI_RICHCOMBO = 3;\r
+\r
+CKEDITOR.ui.richCombo = CKEDITOR.tools.createClass(\r
+{\r
+       $ : function( definition )\r
+       {\r
+               // Copy all definition properties to this object.\r
+               CKEDITOR.tools.extend( this, definition,\r
+                       // Set defaults.\r
+                       {\r
+                               title : definition.label,\r
+                               modes : { wysiwyg : 1 }\r
+                       });\r
+\r
+               // We don't want the panel definition in this object.\r
+               var panelDefinition = this.panel || {};\r
+               delete this.panel;\r
+\r
+               this.id = CKEDITOR.tools.getNextNumber();\r
+\r
+               this.document = ( panelDefinition\r
+                                                       && panelDefinition.parent\r
+                                                       && panelDefinition.parent.getDocument() )\r
+                                               || CKEDITOR.document;\r
+\r
+               panelDefinition.className = ( panelDefinition.className || '' ) + ' cke_rcombopanel';\r
+\r
+               this._ =\r
+               {\r
+                       panelDefinition : panelDefinition,\r
+                       items : {},\r
+                       state : CKEDITOR.TRISTATE_OFF\r
+               };\r
+       },\r
+\r
+       statics :\r
+       {\r
+               handler :\r
+               {\r
+                       create : function( definition )\r
+                       {\r
+                               return new CKEDITOR.ui.richCombo( definition );\r
+                       }\r
+               }\r
+       },\r
+\r
+       proto :\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
+                       var clickFn = CKEDITOR.tools.addFunction( function( $element )\r
+                               {\r
+                                       var _ = this._;\r
+\r
+                                       if ( _.state == CKEDITOR.TRISTATE_DISABLED )\r
+                                               return;\r
+\r
+                                       this.createPanel( editor );\r
+\r
+                                       if ( _.on )\r
+                                       {\r
+                                               _.panel.hide();\r
+                                               return;\r
+                                       }\r
+\r
+                                       if ( !_.committed )\r
+                                       {\r
+                                               _.list.commit();\r
+                                               _.committed = 1;\r
+                                       }\r
+\r
+                                       var value = this.getValue();\r
+                                       if ( value )\r
+                                               _.list.mark( value );\r
+                                       else\r
+                                               _.list.unmarkAll();\r
+\r
+                                       _.panel.showBlock( this.id, new CKEDITOR.dom.element( $element ), 4 );\r
+                               },\r
+                               this );\r
+\r
+                       var instance = {\r
+                               id : id,\r
+                               combo : this,\r
+                               focus : function()\r
+                               {\r
+                                       var element = CKEDITOR.document.getById( id ).getChild( 1 );\r
+                                       element.focus();\r
+                               },\r
+                               execute : clickFn\r
+                       };\r
+\r
+                       editor.on( 'mode', function()\r
+                               {\r
+                                       this.setState( this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );\r
+                               },\r
+                               this );\r
+\r
+                       var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element )\r
+                               {\r
+                                       ev = new CKEDITOR.dom.event( ev );\r
+\r
+                                       var keystroke = ev.getKeystroke();\r
+                                       switch ( keystroke )\r
+                                       {\r
+                                               case 13 :       // ENTER\r
+                                               case 32 :       // SPACE\r
+                                               case 40 :       // ARROW-DOWN\r
+                                                       // Show panel\r
+                                                       CKEDITOR.tools.callFunction( clickFn, element );\r
+                                                       break;\r
+                                               default :\r
+                                                       // Delegate the default behavior to toolbar button key handling.\r
+                                                       instance.onkey( instance,  keystroke );\r
+                                       }\r
+\r
+                                       // Avoid subsequent focus grab on editor document.\r
+                                       ev.preventDefault();\r
+                               });\r
+\r
+                       output.push(\r
+                               '<span class="cke_rcombo">',\r
+                               '<span id=', id );\r
+\r
+                       if ( this.className )\r
+                               output.push( ' class="', this.className, ' cke_off"');\r
+\r
+                       output.push(\r
+                               '>' +\r
+                                       '<span class=cke_label>', this.label, '</span>' +\r
+                                       '<a hidefocus=true title="', this.title, '" tabindex="-1" href="javascript:void(\'', this.label, '\')"' );\r
+\r
+                       // Some browsers don't cancel key events in the keydown but in the\r
+                       // keypress.\r
+                       // TODO: Check if really needed for Gecko+Mac.\r
+                       if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) )\r
+                       {\r
+                               output.push(\r
+                                       ' onkeypress="return false;"' );\r
+                       }\r
+\r
+                       // With Firefox, we need to force it to redraw, otherwise it\r
+                       // will remain in the focus state.\r
+                       if ( CKEDITOR.env.gecko )\r
+                       {\r
+                               output.push(\r
+                                       ' onblur="this.style.cssText = this.style.cssText;"' );\r
+                       }\r
+\r
+                       output.push(\r
+                                       ' onkeydown="CKEDITOR.tools.callFunction( ', keyDownFn, ', event, this );"' +\r
+                                       ' onclick="CKEDITOR.tools.callFunction(', clickFn, ', this); return false;">' +\r
+                                               '<span>' +\r
+                                                       '<span class="cke_accessibility">' + ( this.voiceLabel ? this.voiceLabel + ' ' : '' ) + '</span>' +\r
+                                                       '<span id="' + id + '_text" class="cke_text cke_inline_label">' + this.label + '</span>' +\r
+                                               '</span>' +\r
+                                               '<span class=cke_openbutton></span>' +\r
+                                       '</a>' +\r
+                               '</span>' +\r
+                               '</span>' );\r
+\r
+                       if ( this.onRender )\r
+                               this.onRender();\r
+\r
+                       return instance;\r
+               },\r
+\r
+               createPanel : function( editor )\r
+               {\r
+                       if ( this._.panel )\r
+                               return;\r
+\r
+                       var panelDefinition = this._.panelDefinition,\r
+                               panelParentElement = panelDefinition.parent || CKEDITOR.document.getBody(),\r
+                               panel = new CKEDITOR.ui.floatPanel( editor, panelParentElement, panelDefinition ),\r
+                               list = panel.addListBlock( this.id, this.multiSelect ),\r
+                               me = this;\r
+\r
+                       panel.onShow = function()\r
+                               {\r
+                                       if ( me.className )\r
+                                               this.element.getFirst().addClass( me.className + '_panel' );\r
+\r
+                                       me.setState( CKEDITOR.TRISTATE_ON );\r
+\r
+                                       list.focus( !me.multiSelect && me.getValue() );\r
+\r
+                                       me._.on = 1;\r
+\r
+                                       if ( me.onOpen )\r
+                                               me.onOpen();\r
+                               };\r
+\r
+                       panel.onHide = function()\r
+                               {\r
+                                       if ( me.className )\r
+                                               this.element.getFirst().removeClass( me.className + '_panel' );\r
+\r
+                                       me.setState( CKEDITOR.TRISTATE_OFF );\r
+\r
+                                       me._.on = 0;\r
+\r
+                                       if ( me.onClose )\r
+                                               me.onClose();\r
+                               };\r
+\r
+                       panel.onEscape = function()\r
+                               {\r
+                                       panel.hide();\r
+                                       me.document.getById( 'cke_' + me.id ).getFirst().getNext().focus();\r
+                               };\r
+\r
+                       list.onClick = function( value, marked )\r
+                               {\r
+                                       // Move the focus to the main windows, otherwise it will stay\r
+                                       // into the floating panel, even if invisible, and Safari and\r
+                                       // Opera will go a bit crazy.\r
+                                       me.document.getWindow().focus();\r
+\r
+                                       if ( me.onClick )\r
+                                               me.onClick.call( me, value, marked );\r
+\r
+                                       if ( marked )\r
+                                               me.setValue( value, me._.items[ value ] );\r
+                                       else\r
+                                               me.setValue( '' );\r
+\r
+                                       panel.hide();\r
+                               };\r
+\r
+                       this._.panel = panel;\r
+                       this._.list = list;\r
+\r
+                       panel.getBlock( this.id ).onHide = function()\r
+                               {\r
+                                       me._.on = 0;\r
+                                       me.setState( CKEDITOR.TRISTATE_OFF );\r
+                               };\r
+\r
+                       if ( this.init )\r
+                               this.init();\r
+               },\r
+\r
+               setValue : function( value, text )\r
+               {\r
+                       this._.value = value;\r
+\r
+                       var textElement = this.document.getById( 'cke_' + this.id + '_text' );\r
+\r
+                       if ( !value )\r
+                       {\r
+                               text = this.label;\r
+                               textElement.addClass( 'cke_inline_label' );\r
+                       }\r
+                       else\r
+                               textElement.removeClass( 'cke_inline_label' );\r
+                       textElement.setHtml( typeof text != 'undefined' ? text : value );\r
+               },\r
+\r
+               getValue : function()\r
+               {\r
+                       return this._.value || '';\r
+               },\r
+\r
+               unmarkAll : function()\r
+               {\r
+                       this._.list.unmarkAll();\r
+               },\r
+\r
+               mark : function( value )\r
+               {\r
+                       this._.list.mark( value );\r
+               },\r
+\r
+               hideItem : function( value )\r
+               {\r
+                       this._.list.hideItem( value );\r
+               },\r
+\r
+               hideGroup : function( groupTitle )\r
+               {\r
+                       this._.list.hideGroup( groupTitle );\r
+               },\r
+\r
+               showAll : function()\r
+               {\r
+                       this._.list.showAll();\r
+               },\r
+\r
+               add : function( value, html, text )\r
+               {\r
+                       this._.items[ value ] = text || value;\r
+                       this._.list.add( value, html, text );\r
+               },\r
+\r
+               startGroup : function( title )\r
+               {\r
+                       this._.list.startGroup( title );\r
+               },\r
+\r
+               commit : function()\r
+               {\r
+                       this._.list.commit();\r
+               },\r
+\r
+               setState : function( state )\r
+               {\r
+                       if ( this._.state == state )\r
+                               return;\r
+\r
+                       this.document.getById( 'cke_' + this.id ).setState( state );\r
+\r
+                       this._.state = state;\r
+               }\r
+       }\r
+});\r
+\r
+CKEDITOR.ui.prototype.addRichCombo = function( name, definition )\r
+{\r
+       this.add( name, CKEDITOR.UI_RICHCOMBO, definition );\r
+};\r