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 /** 59 * The function to be called when the user clicks the button. If not 60 * defined, the "command" property is required, and the command gets 61 * executed on click. 62 * @function 63 * @name CKEDITOR.ui.button.prototype.click 64 * @example 65 */ 66 this.click = definition.click || function( editor ) 67 { 68 editor.execCommand( definition.command ); 69 }; 70 71 this._ = {}; 72 }; 73 74 /** 75 * Transforms a button definition in a {@link CKEDITOR.ui.button} instance. 76 * @type Object 77 * @example 78 */ 79 CKEDITOR.ui.button.handler = 80 { 81 create : function( definition ) 82 { 83 return new CKEDITOR.ui.button( definition ); 84 } 85 }; 86 87 CKEDITOR.ui.button.prototype = 88 { 89 /** 90 * Renders the button. 91 * @param {CKEDITOR.editor} editor The editor instance which this button is 92 * to be used by. 93 * @param {Array} output The output array to which append the HTML relative 94 * to this button. 95 * @example 96 */ 97 render : function( editor, output ) 98 { 99 var env = CKEDITOR.env; 100 101 var id = this._.id = 'cke_' + CKEDITOR.tools.getNextNumber(); 102 103 var instance = 104 { 105 id : id, 106 button : this, 107 editor : editor, 108 focus : function() 109 { 110 var element = CKEDITOR.document.getById( id ); 111 element.focus(); 112 }, 113 execute : function() 114 { 115 this.button.click( editor ); 116 } 117 }; 118 119 // Get the command name. 120 var command = this.command; 121 122 if ( command ) 123 { 124 // Get the command instance. 125 command = editor.getCommand( command ); 126 127 if ( command ) 128 { 129 command.on( 'state', function() 130 { 131 this.setState( command.state ); 132 }, this); 133 } 134 } 135 136 var index = CKEDITOR.ui.button._.instances.push( instance ) - 1; 137 138 output.push( 139 '<a id="', id, '"' + 140 ' class="cke_button ', this.className, '" href="javascript:void(\'', ( this.label || '' ).replace( "'", '' ), '\')"' + 141 ' title="', this.title, '"' + 142 ' tabindex="-1"' + 143 ' hidefocus="true"' ); 144 145 // Some browsers don't cancel key events in the keydown but in the 146 // keypress. 147 // TODO: Check if really needed for Gecko+Mac. 148 if ( env.opera || ( env.gecko && env.mac ) ) 149 { 150 output.push( 151 ' onkeypress="return false;"' ); 152 } 153 154 // With Firefox, we need to force the button to redraw, otherwise it 155 // will remain in the focus state. 156 if ( env.gecko ) 157 { 158 output.push( 159 ' onblur="this.style.cssText = this.style.cssText;"' ); 160 } 161 162 output.push( 163 ' onkeydown="return CKEDITOR.ui.button._.keydown(', index, ', event);"' + 164 ' onclick="return CKEDITOR.ui.button._.click(', index, ', event);">' + 165 '<span class="cke_icon"></span>' + 166 '<span class="cke_label">', this.label, '</span>' + 167 '</a>' ); 168 169 return instance; 170 }, 171 172 setState : function( state ) 173 { 174 var element = CKEDITOR.document.getById( this._.id ); 175 176 switch ( state ) 177 { 178 case CKEDITOR.TRISTATE_ON : 179 element.addClass( 'cke_on' ); 180 element.removeClass( 'cke_off' ); 181 element.removeClass( 'cke_disabled' ); 182 break; 183 case CKEDITOR.TRISTATE_DISABLED : 184 element.addClass( 'cke_disabled' ); 185 element.removeClass( 'cke_off' ); 186 element.removeClass( 'cke_on' ); 187 break; 188 default : 189 element.addClass( 'cke_off' ); 190 element.removeClass( 'cke_on' ); 191 element.removeClass( 'cke_disabled' ); 192 break; 193 } 194 } 195 }; 196 197 /** 198 * Handles a button click. 199 * @private 200 */ 201 CKEDITOR.ui.button._ = 202 { 203 instances : [], 204 205 click : function( index ) 206 { 207 CKEDITOR.ui.button._.instances[ index ].execute(); 208 return false; 209 }, 210 211 keydown : function( index, ev ) 212 { 213 var instance = CKEDITOR.ui.button._.instances[ index ]; 214 215 if ( instance.onkey ) 216 { 217 ev = new CKEDITOR.dom.event( ev ); 218 return ( instance.onkey( instance, ev.getKeystroke() ) !== false ); 219 } 220 } 221 }; 222 223 /** 224 * Adds a button definition to the UI elements list. 225 * @param {String} The button name. 226 * @param {Object} The button definition. 227 * @example 228 * editorInstance.ui.addButton( 'MyBold', 229 * { 230 * label : 'My Bold', 231 * command : 'bold' 232 * }); 233 */ 234 CKEDITOR.ui.prototype.addButton = function( name, definition ) 235 { 236 this.add( name, CKEDITOR.UI_BUTTON, definition ); 237 }; 238