2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
6 CKEDITOR.plugins.add( 'richcombo',
8 requires : [ 'floatpanel', 'listblock', 'button' ],
10 beforeInit : function( editor )
12 editor.ui.addHandler( CKEDITOR.UI_RICHCOMBO, CKEDITOR.ui.richCombo.handler );
21 CKEDITOR.UI_RICHCOMBO = 3;
23 CKEDITOR.ui.richCombo = CKEDITOR.tools.createClass(
25 $ : function( definition )
27 // Copy all definition properties to this object.
28 CKEDITOR.tools.extend( this, definition,
31 title : definition.label,
32 modes : { wysiwyg : 1 }
35 // We don't want the panel definition in this object.
36 var panelDefinition = this.panel || {};
39 this.id = CKEDITOR.tools.getNextNumber();
41 this.document = ( panelDefinition
42 && panelDefinition.parent
43 && panelDefinition.parent.getDocument() )
46 panelDefinition.className = ( panelDefinition.className || '' ) + ' cke_rcombopanel';
47 panelDefinition.block =
49 multiSelect : panelDefinition.multiSelect,
50 attributes : panelDefinition.attributes
55 panelDefinition : panelDefinition,
57 state : CKEDITOR.TRISTATE_OFF
65 create : function( definition )
67 return new CKEDITOR.ui.richCombo( definition );
74 renderHtml : function( editor )
77 this.render( editor, output );
78 return output.join( '' );
83 * @param {CKEDITOR.editor} editor The editor instance which this button is
85 * @param {Array} output The output array to which append the HTML relative
89 render : function( editor, output )
91 var env = CKEDITOR.env;
93 var id = 'cke_' + this.id;
94 var clickFn = CKEDITOR.tools.addFunction( function( $element )
98 if ( _.state == CKEDITOR.TRISTATE_DISABLED )
101 this.createPanel( editor );
110 var value = this.getValue();
112 _.list.mark( value );
116 _.panel.showBlock( this.id, new CKEDITOR.dom.element( $element ), 4 );
125 var element = CKEDITOR.document.getById( id ).getChild( 1 );
131 editor.on( 'mode', function()
133 this.setState( this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );
138 var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element )
140 ev = new CKEDITOR.dom.event( ev );
142 var keystroke = ev.getKeystroke();
147 case 40 : // ARROW-DOWN
149 CKEDITOR.tools.callFunction( clickFn, element );
152 // Delegate the default behavior to toolbar button key handling.
153 instance.onkey( instance, keystroke );
156 // Avoid subsequent focus grab on editor document.
161 instance.keyDownFn = keyDownFn;
164 '<span class="cke_rcombo">',
167 if ( this.className )
168 output.push( ' class="', this.className, ' cke_off"');
172 '<span id="' + id+ '_label" class=cke_label>', this.label, '</span>',
173 '<a hidefocus=true title="', this.title, '" tabindex="-1"',
174 env.gecko && env.version >= 10900 && !env.hc ? '' : ' href="javascript:void(\'' + this.label + '\')"',
175 ' role="button" aria-labelledby="', id , '_label" aria-describedby="', id, '_text" aria-haspopup="true"' );
177 // Some browsers don't cancel key events in the keydown but in the
179 // TODO: Check if really needed for Gecko+Mac.
180 if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) )
183 ' onkeypress="return false;"' );
186 // With Firefox, we need to force it to redraw, otherwise it
187 // will remain in the focus state.
188 if ( CKEDITOR.env.gecko )
191 ' onblur="this.style.cssText = this.style.cssText;"' );
195 ' onkeydown="CKEDITOR.tools.callFunction( ', keyDownFn, ', event, this );"' +
196 ' onclick="CKEDITOR.tools.callFunction(', clickFn, ', this); return false;">' +
198 '<span id="' + id + '_text" class="cke_text cke_inline_label">' + this.label + '</span>' +
200 '<span class=cke_openbutton>' + ( CKEDITOR.env.hc ? '<span>▼</span>' : CKEDITOR.env.air ? ' ' : '' ) + '</span>' + // BLACK DOWN-POINTING TRIANGLE
211 createPanel : function( editor )
216 var panelDefinition = this._.panelDefinition,
217 panelBlockDefinition = this._.panelDefinition.block,
218 panelParentElement = panelDefinition.parent || CKEDITOR.document.getBody(),
219 panel = new CKEDITOR.ui.floatPanel( editor, panelParentElement, panelDefinition ),
220 list = panel.addListBlock( this.id, panelBlockDefinition ),
223 panel.onShow = function()
226 this.element.getFirst().addClass( me.className + '_panel' );
228 me.setState( CKEDITOR.TRISTATE_ON );
230 list.focus( !me.multiSelect && me.getValue() );
238 panel.onHide = function( preventOnClose )
241 this.element.getFirst().removeClass( me.className + '_panel' );
243 me.setState( me.modes && me.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );
247 if ( !preventOnClose && me.onClose )
251 panel.onEscape = function()
254 me.document.getById( 'cke_' + me.id ).getFirst().getNext().focus();
257 list.onClick = function( value, marked )
259 // Move the focus to the main windows, otherwise it will stay
260 // into the floating panel, even if invisible, and Safari and
261 // Opera will go a bit crazy.
262 me.document.getWindow().focus();
265 me.onClick.call( me, value, marked );
268 me.setValue( value, me._.items[ value ] );
275 this._.panel = panel;
278 panel.getBlock( this.id ).onHide = function()
281 me.setState( CKEDITOR.TRISTATE_OFF );
288 setValue : function( value, text )
290 this._.value = value;
292 var textElement = this.document.getById( 'cke_' + this.id + '_text' );
295 if ( !( value || text ) )
298 textElement.addClass( 'cke_inline_label' );
301 textElement.removeClass( 'cke_inline_label' );
303 textElement.setHtml( typeof text != 'undefined' ? text : value );
307 getValue : function()
309 return this._.value || '';
312 unmarkAll : function()
314 this._.list.unmarkAll();
317 mark : function( value )
319 this._.list.mark( value );
322 hideItem : function( value )
324 this._.list.hideItem( value );
327 hideGroup : function( groupTitle )
329 this._.list.hideGroup( groupTitle );
334 this._.list.showAll();
337 add : function( value, html, text )
339 this._.items[ value ] = text || value;
340 this._.list.add( value, html, text );
343 startGroup : function( title )
345 this._.list.startGroup( title );
350 if ( !this._.committed )
352 this._.list.commit();
353 this._.committed = 1;
354 CKEDITOR.ui.fire( 'ready', this );
356 this._.committed = 1;
359 setState : function( state )
361 if ( this._.state == state )
364 this.document.getById( 'cke_' + this.id ).setState( state );
366 this._.state = state;
371 CKEDITOR.ui.prototype.addRichCombo = function( name, definition )
373 this.add( name, CKEDITOR.UI_RICHCOMBO, definition );