1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 CKEDITOR.plugins.add( 'panelbutton', 7 { 8 requires : [ 'button' ], 9 beforeInit : function( editor ) 10 { 11 editor.ui.addHandler( CKEDITOR.UI_PANELBUTTON, CKEDITOR.ui.panelButton.handler ); 12 } 13 }); 14 15 /** 16 * Button UI element. 17 * @constant 18 * @example 19 */ 20 CKEDITOR.UI_PANELBUTTON = 4; 21 22 CKEDITOR.ui.panelButton = CKEDITOR.tools.createClass( 23 { 24 $ : function( definition ) 25 { 26 // Copy all definition properties to this object. 27 CKEDITOR.tools.extend( this, definition, 28 // Set defaults. 29 { 30 title : definition.label, 31 modes : { wysiwyg : 1 } 32 }); 33 34 // We don't want the panel definition in this object. 35 var panelDefinition = this.panel; 36 delete this.panel; 37 38 this.document = ( panelDefinition 39 && panelDefinition.parent 40 && panelDefinition.parent.getDocument() ) 41 || CKEDITOR.document; 42 this._ = 43 { 44 panelDefinition : panelDefinition 45 }; 46 }, 47 48 statics : 49 { 50 handler : 51 { 52 create : function( definition ) 53 { 54 return new CKEDITOR.ui.panelButton( definition ); 55 } 56 } 57 }, 58 59 proto : 60 { 61 render : function( editor, output ) 62 { 63 var id = this._.id = 'cke_' + CKEDITOR.tools.getNextNumber(); 64 65 var instance = 66 { 67 id : id, 68 focus : function() 69 { 70 var element = CKEDITOR.document.getById( id ); 71 element.focus(); 72 }, 73 execute : function() 74 { 75 this.button.click( editor ); 76 } 77 }; 78 79 var clickFn = CKEDITOR.tools.addFunction( function( $element ) 80 { 81 var _ = this._; 82 83 if ( _.state == CKEDITOR.TRISTATE_DISABLED ) 84 return; 85 86 this.createPanel( editor ); 87 88 if ( _.on ) 89 { 90 _.panel.hide(); 91 return; 92 } 93 94 _.panel.showBlock( this._.id, new CKEDITOR.dom.element( $element ), 4 ); 95 }, 96 this ); 97 var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element ){ 98 99 ev = new CKEDITOR.dom.event( ev ); 100 101 var keystroke = ev.getKeystroke(); 102 switch ( keystroke ) 103 { 104 case 13 : // ENTER 105 case 32 : // SPACE 106 case 40 : // ARROW-DOWN 107 // Show panel 108 CKEDITOR.tools.callFunction( clickFn, element ); 109 break; 110 default : 111 // Delegate the default behavior to toolbar button key handling. 112 instance.onkey( instance, keystroke ); 113 } 114 115 // Avoid subsequent focus grab on editor document. 116 ev.preventDefault(); 117 }); 118 119 var label = this.label || ''; 120 121 var classes = 'cke_off'; 122 123 if ( this.className ) 124 classes += ' ' + this.className; 125 126 editor.on( 'mode', function() 127 { 128 this.setState( this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED ); 129 }, 130 this ); 131 132 output.push( 133 '<span class="cke_button">', 134 '<a id="', id, '"' + 135 ' class="', classes, '" href="javascript:void(\'', ( this.title || '' ).replace( "'", '' ), '\')"' + 136 ' title="', this.title, '"' + 137 ' tabindex="-1"' + 138 ' hidefocus="true"' ); 139 140 // Some browsers don't cancel key events in the keydown but in the 141 // keypress. 142 // TODO: Check if really needed for Gecko+Mac. 143 if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) ) 144 { 145 output.push( 146 ' onkeypress="return false;"' ); 147 } 148 149 // With Firefox, we need to force the button to redraw, otherwise it 150 // will remain in the focus state. 151 if ( CKEDITOR.env.gecko ) 152 { 153 output.push( 154 ' onblur="this.style.cssText = this.style.cssText;"' ); 155 } 156 157 output.push( 158 ' onkeydown="CKEDITOR.tools.callFunction( ', keyDownFn, ', event, this );"' + 159 ' onclick="CKEDITOR.tools.callFunction(', clickFn, ', this);">' + 160 '<span class="cke_icon"></span>' + 161 '<span class="cke_label">', this.label, '</span>' + 162 '<span class="cke_buttonarrow"></span>' + 163 '</a>' + 164 '</span>' ); 165 166 return instance; 167 }, 168 169 createPanel : function( editor ) 170 { 171 var _ = this._; 172 173 if ( _.panel ) 174 return; 175 176 var panelDefinition = this._.panelDefinition || {}, 177 panelParentElement = panelDefinition.parent || CKEDITOR.document.getBody(), 178 panel = this._.panel = new CKEDITOR.ui.floatPanel( editor, panelParentElement, panelDefinition ), 179 me = this; 180 181 panel.onShow = function() 182 { 183 if ( me.className ) 184 this.element.getFirst().addClass( me.className + '_panel' ); 185 186 me.setState( CKEDITOR.TRISTATE_ON ); 187 188 _.on = 1; 189 190 if ( me.onOpen ) 191 me.onOpen(); 192 }; 193 194 panel.onHide = function() 195 { 196 if ( me.className ) 197 this.element.getFirst().removeClass( me.className + '_panel' ); 198 199 me.setState( CKEDITOR.TRISTATE_OFF ); 200 201 _.on = 0; 202 203 if ( me.onClose ) 204 me.onClose(); 205 }; 206 207 panel.onEscape = function() 208 { 209 panel.hide(); 210 me.document.getById( _.id ).focus(); 211 }; 212 213 214 if ( this.onBlock ) 215 this.onBlock( panel, _.id ); 216 }, 217 218 setState : CKEDITOR.ui.button.prototype.setState 219 } 220 }); 221