1 /* 2 Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** 7 * Creates a command class instance. 8 * @class Represents a command that can be executed on an editor instance. 9 * @param {CKEDITOR.editor} editor The editor instance this command will be 10 * related to. 11 * @param {CKEDITOR.commandDefinition} commandDefinition The command 12 * definition. 13 * @augments CKEDITOR.event 14 * @example 15 * var command = new CKEDITOR.command( editor, 16 * { 17 * exec : function( editor ) 18 * { 19 * alert( editor.document.getBody().getHtml() ); 20 * } 21 * }); 22 */ 23 CKEDITOR.command = function( editor, commandDefinition ) 24 { 25 /** 26 * Lists UI items that are associated to this command. This list can be 27 * used to interact with the UI on command execution (by the execution code 28 * itself, for example). 29 * @type Array 30 * @example 31 * alert( 'Number of UI items associated to this command: ' + command.<b>uiItems</b>.length ); 32 */ 33 this.uiItems = []; 34 35 /** 36 * Executes the command. 37 * @param {Object} [data] Any data to pass to the command. Depends on the 38 * command implementation and requirements. 39 * @returns {Boolean} A boolean indicating that the command has been 40 * successfully executed. 41 * @example 42 * command.<b>exec()</b>; // The command gets executed. 43 */ 44 this.exec = function( data ) 45 { 46 if ( this.state == CKEDITOR.TRISTATE_DISABLED ) 47 return false; 48 49 if ( this.editorFocus ) // Give editor focus if necessary (#4355). 50 editor.focus(); 51 52 if ( this.fire( 'exec' ) === true ) 53 return true; 54 55 return ( commandDefinition.exec.call( this, editor, data ) !== false ); 56 }; 57 58 /** 59 * Explicitly update the status of the command, by firing the {@link CKEDITOR.command#event:refresh} event, 60 * as well as invoke the {@link CKEDITOR.commandDefinition.prototype.refresh} method if defined, this method 61 * is to allow different parts of the editor code to contribute in command status resolution. 62 */ 63 this.refresh = function() 64 { 65 if ( this.fire( 'refresh' ) === true ) 66 return true; 67 68 return ( commandDefinition.refresh && commandDefinition.refresh.apply( this, arguments ) !== false ); 69 }; 70 71 CKEDITOR.tools.extend( this, commandDefinition, 72 // Defaults 73 /** @lends CKEDITOR.command.prototype */ 74 { 75 /** 76 * The editor modes within which the command can be executed. The 77 * execution will have no action if the current mode is not listed 78 * in this property. 79 * @type Object 80 * @default { wysiwyg : 1 } 81 * @see CKEDITOR.editor.prototype.mode 82 * @example 83 * // Enable the command in both WYSIWYG and Source modes. 84 * command.<b>modes</b> = { wysiwyg : 1, source : 1 }; 85 * @example 86 * // Enable the command in Source mode only. 87 * command.<b>modes</b> = { source : 1 }; 88 */ 89 modes : { wysiwyg : 1 }, 90 91 /** 92 * Indicates that the editor will get the focus before executing 93 * the command. 94 * @type Boolean 95 * @default true 96 * @example 97 * // Do not force the editor to have focus when executing the command. 98 * command.<b>editorFocus</b> = false; 99 */ 100 editorFocus : 1, 101 102 /** 103 * Indicates the editor state. Possible values are: 104 * <ul> 105 * <li>{@link CKEDITOR.TRISTATE_DISABLED}: the command is 106 * disabled. It's execution will have no effect. Same as 107 * {@link disable}.</li> 108 * <li>{@link CKEDITOR.TRISTATE_ON}: the command is enabled 109 * and currently active in the editor (for context sensitive commands, 110 * for example).</li> 111 * <li>{@link CKEDITOR.TRISTATE_OFF}: the command is enabled 112 * and currently inactive in the editor (for context sensitive 113 * commands, for example).</li> 114 * </ul> 115 * Do not set this property directly, using the {@link #setState} 116 * method instead. 117 * @type Number 118 * @default {@link CKEDITOR.TRISTATE_OFF} 119 * @example 120 * if ( command.<b>state</b> == CKEDITOR.TRISTATE_DISABLED ) 121 * alert( 'This command is disabled' ); 122 */ 123 state : CKEDITOR.TRISTATE_OFF 124 }); 125 126 // Call the CKEDITOR.event constructor to initialize this instance. 127 CKEDITOR.event.call( this ); 128 }; 129 130 CKEDITOR.command.prototype = 131 { 132 /** 133 * Enables the command for execution. The command state (see 134 * {@link CKEDITOR.command.prototype.state}) available before disabling it 135 * is restored. 136 * @example 137 * command.<b>enable()</b>; 138 * command.exec(); // Execute the command. 139 */ 140 enable : function() 141 { 142 if ( this.state == CKEDITOR.TRISTATE_DISABLED ) 143 this.setState( ( !this.preserveState || ( typeof this.previousState == 'undefined' ) ) ? CKEDITOR.TRISTATE_OFF : this.previousState ); 144 }, 145 146 /** 147 * Disables the command for execution. The command state (see 148 * {@link CKEDITOR.command.prototype.state}) will be set to 149 * {@link CKEDITOR.TRISTATE_DISABLED}. 150 * @example 151 * command.<b>disable()</b>; 152 * command.exec(); // "false" - Nothing happens. 153 */ 154 disable : function() 155 { 156 this.setState( CKEDITOR.TRISTATE_DISABLED ); 157 }, 158 159 /** 160 * Sets the command state. 161 * @param {Number} newState The new state. See {@link #state}. 162 * @returns {Boolean} Returns "true" if the command state changed. 163 * @example 164 * command.<b>setState( CKEDITOR.TRISTATE_ON )</b>; 165 * command.exec(); // Execute the command. 166 * command.<b>setState( CKEDITOR.TRISTATE_DISABLED )</b>; 167 * command.exec(); // "false" - Nothing happens. 168 * command.<b>setState( CKEDITOR.TRISTATE_OFF )</b>; 169 * command.exec(); // Execute the command. 170 */ 171 setState : function( newState ) 172 { 173 // Do nothing if there is no state change. 174 if ( this.state == newState ) 175 return false; 176 177 this.previousState = this.state; 178 179 // Set the new state. 180 this.state = newState; 181 182 // Fire the "state" event, so other parts of the code can react to the 183 // change. 184 this.fire( 'state' ); 185 186 return true; 187 }, 188 189 /** 190 * Toggles the on/off (active/inactive) state of the command. This is 191 * mainly used internally by context sensitive commands. 192 * @example 193 * command.<b>toggleState()</b>; 194 */ 195 toggleState : function() 196 { 197 if ( this.state == CKEDITOR.TRISTATE_OFF ) 198 this.setState( CKEDITOR.TRISTATE_ON ); 199 else if ( this.state == CKEDITOR.TRISTATE_ON ) 200 this.setState( CKEDITOR.TRISTATE_OFF ); 201 } 202 }; 203 204 CKEDITOR.event.implementOn( CKEDITOR.command.prototype, true ); 205 206 /** 207 * Indicates the previous command state. 208 * @name CKEDITOR.command.prototype.previousState 209 * @type Number 210 * @see #state 211 * @example 212 * alert( command.<b>previousState</b> ); 213 */ 214 215 /** 216 * Fired when the command state changes. 217 * @name CKEDITOR.command#state 218 * @event 219 * @example 220 * command.on( <b>'state'</b> , function( e ) 221 * { 222 * // Alerts the new state. 223 * alert( this.state ); 224 * }); 225 */ 226