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