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( 'button', 7 { 8 beforeInit : function( editor ) 9 { 10 editor.ui.addHandler( CKEDITOR.UI_BUTTON, CKEDITOR.ui.button.handler ); 11 } 12 }); 13 14 /** 15 * Button UI element. 16 * @constant 17 * @example 18 */ 19 CKEDITOR.UI_BUTTON = 1; 20 21 /** 22 * Represents a button UI element. This class should not be called directly. To 23 * create new buttons use {@link CKEDITOR.ui.prototype.addButton} instead. 24 * @constructor 25 * @param {Object} definition The button definition. 26 * @example 27 */ 28 CKEDITOR.ui.button = function( definition ) 29 { 30 /** 31 * The button label. 32 * @name CKEDITOR.ui.button.prototype.label 33 * @type String 34 * @example 35 */ 36 this.label = definition.label; 37 38 /** 39 * The button advisory title. It is usually displayed as the button tooltip. 40 * If not defined, the label is used. 41 * @name CKEDITOR.ui.button.prototype.title 42 * @type String 43 * @example 44 */ 45 this.title = definition.title || definition.label; 46 47 /** 48 * The command name associated to the button. If no command is defined, the 49 * "click" event is used. 50 * @name CKEDITOR.ui.button.prototype.command 51 * @type String 52 * @example 53 */ 54 this.command = definition.command; 55 56 this.className = definition.className || ( definition.command && 'cke_button_' + definition.command ) || ''; 57 58 this.icon = definition.icon; 59 this.iconOffset = definition.iconOffset; 60 61 /** 62 * The function to be called when the user clicks the button. If not 63 * defined, the "command" property is required, and the command gets 64 * executed on click. 65 * @function 66 * @name CKEDITOR.ui.button.prototype.click 67 * @example 68 */ 69 this.click = definition.click || function( editor ) 70 { 71 editor.execCommand( definition.command ); 72 }; 73 74 this._ = {}; 75 }; 76 77 /** 78 * Transforms a button definition in a {@link CKEDITOR.ui.button} instance. 79 * @type Object 80 * @example 81 */ 82 CKEDITOR.ui.button.handler = 83 { 84 create : function( definition ) 85 { 86 return new CKEDITOR.ui.button( definition ); 87 } 88 }; 89 90 CKEDITOR.ui.button.prototype = 91 { 92 /** 93 * Renders the button. 94 * @param {CKEDITOR.editor} editor The editor instance which this button is 95 * to be used by. 96 * @param {Array} output The output array to which append the HTML relative 97 * to this button. 98 * @example 99 */ 100 render : function( editor, output ) 101 { 102 var env = CKEDITOR.env; 103 104 var id = this._.id = 'cke_' + CKEDITOR.tools.getNextNumber(); 105 106 var instance = 107 { 108 id : id, 109 button : this, 110 editor : editor, 111 focus : function() 112 { 113 var element = CKEDITOR.document.getById( id ); 114 element.focus(); 115 }, 116 execute : function() 117 { 118 this.button.click( editor ); 119 } 120 }; 121 122 var index = CKEDITOR.ui.button._.instances.push( instance ) - 1; 123 124 var classes = ''; 125 126 // Get the command name. 127 var command = this.command; 128 129 if ( command ) 130 { 131 // Get the command instance. 132 command = editor.getCommand( command ); 133 134 if ( command ) 135 { 136 command.on( 'state', function() 137 { 138 this.setState( command.state ); 139 }, this); 140 141 classes += ' cke_' + ( 142 command.state == CKEDITOR.TRISTATE_ON ? 'on' : 143 command.state == CKEDITOR.TRISTATE_DISABLED ? 'disabled' : 144 'off' ); 145 } 146 } 147 148 if ( this.className ) 149 classes += ' ' + this.className; 150 151 output.push( 152 '<span class="cke_button">', 153 '<a id="', id, '"' + 154 ' class="', classes, '" href="javascript:void(\'', ( this.title || '' ).replace( "'", '' ), '\')"' + 155 ' title="', this.title, '"' + 156 ' tabindex="-1"' + 157 ' hidefocus="true"' ); 158 159 // Some browsers don't cancel key events in the keydown but in the 160 // keypress. 161 // TODO: Check if really needed for Gecko+Mac. 162 if ( env.opera || ( env.gecko && env.mac ) ) 163 { 164 output.push( 165 ' onkeypress="return false;"' ); 166 } 167 168 // With Firefox, we need to force the button to redraw, otherwise it 169 // will remain in the focus state. 170 if ( env.gecko ) 171 { 172 output.push( 173 ' onblur="this.style.cssText = this.style.cssText;"' ); 174 } 175 176 output.push( 177 ' onkeydown="return CKEDITOR.ui.button._.keydown(', index, ', event);"' + 178 ' onfocus="return CKEDITOR.ui.button._.focus(', index, ', event);"' + 179 ' onclick="return CKEDITOR.ui.button._.click(', index, ', event);">' + 180 '<span class="cke_icon"' ); 181 182 if ( this.icon ) 183 { 184 var offset = ( this.iconOffset || 0 ) * -16; 185 output.push( ' style="background-image:url(', CKEDITOR.getUrl( this.icon ), ');background-position:0 ' + offset + 'px;"' ); 186 } 187 188 output.push( 189 '></span>' + 190 '<span class="cke_label">', this.label, '</span>' + 191 '</a>', 192 '</span>' ); 193 194 return instance; 195 }, 196 197 setState : function( state ) 198 { 199 if ( this._.state == state ) 200 return; 201 202 CKEDITOR.document.getById( this._.id ).setState( state ); 203 204 this._.state = state; 205 } 206 }; 207 208 /** 209 * Handles a button click. 210 * @private 211 */ 212 CKEDITOR.ui.button._ = 213 { 214 instances : [], 215 216 click : function( index ) 217 { 218 CKEDITOR.ui.button._.instances[ index ].execute(); 219 return false; 220 }, 221 222 keydown : function( index, ev ) 223 { 224 var instance = CKEDITOR.ui.button._.instances[ index ]; 225 226 if ( instance.onkey ) 227 { 228 ev = new CKEDITOR.dom.event( ev ); 229 return ( instance.onkey( instance, ev.getKeystroke() ) !== false ); 230 } 231 }, 232 233 focus : function( index, ev ) 234 { 235 var instance = CKEDITOR.ui.button._.instances[ index ]; 236 237 if ( instance.onfocus ) 238 return ( instance.onfocus( instance, new CKEDITOR.dom.event( ev ) ) !== false ); 239 } 240 }; 241 242 /** 243 * Adds a button definition to the UI elements list. 244 * @param {String} The button name. 245 * @param {Object} The button definition. 246 * @example 247 * editorInstance.ui.addButton( 'MyBold', 248 * { 249 * label : 'My Bold', 250 * command : 'bold' 251 * }); 252 */ 253 CKEDITOR.ui.prototype.addButton = function( name, definition ) 254 { 255 this.add( name, CKEDITOR.UI_BUTTON, definition ); 256 }; 257