]>
Commit | Line | Data |
---|---|---|
3332bebe | 1 | /** |
317f8f8f | 2 | * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. |
3332bebe IB |
3 | * For licensing, see LICENSE.md or http://ckeditor.com/license |
4 | */ | |
5 | ||
6 | /** | |
7 | * Represents a command that can be executed on an editor instance. | |
8 | * | |
9 | * var command = new CKEDITOR.command( editor, { | |
10 | * exec: function( editor ) { | |
11 | * alert( editor.document.getBody().getHtml() ); | |
12 | * } | |
13 | * } ); | |
14 | * | |
15 | * @class | |
16 | * @extends CKEDITOR.commandDefinition | |
17 | * @mixins CKEDITOR.event | |
18 | * @constructor Creates a command class instance. | |
19 | * @param {CKEDITOR.editor} editor The editor instance this command will be | |
20 | * related to. | |
21 | * @param {CKEDITOR.commandDefinition} commandDefinition The command | |
22 | * definition. | |
23 | */ | |
24 | CKEDITOR.command = function( editor, commandDefinition ) { | |
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 | * | |
30 | * alert( 'Number of UI items associated to this command: ' + command.uiItems.length ); | |
31 | */ | |
32 | this.uiItems = []; | |
33 | ||
34 | /** | |
35 | * Executes the command. | |
36 | * | |
37 | * command.exec(); // The command gets executed. | |
38 | * | |
39 | * **Note:** You should use the {@link CKEDITOR.editor#execCommand} method instead of calling | |
40 | * `command.exec()` directly. | |
41 | * | |
42 | * @param {Object} [data] Any data to pass to the command. Depends on the | |
43 | * command implementation and requirements. | |
44 | * @returns {Boolean} A boolean indicating that the command has been successfully executed. | |
45 | */ | |
46 | this.exec = function( data ) { | |
47 | if ( this.state == CKEDITOR.TRISTATE_DISABLED || !this.checkAllowed() ) | |
48 | return false; | |
49 | ||
317f8f8f | 50 | if ( this.editorFocus ) // Give editor focus if necessary (http://dev.ckeditor.com/ticket/4355). |
3332bebe IB |
51 | editor.focus(); |
52 | ||
53 | if ( this.fire( 'exec' ) === false ) | |
54 | return true; | |
55 | ||
56 | return ( commandDefinition.exec.call( this, editor, data ) !== false ); | |
57 | }; | |
58 | ||
59 | /** | |
60 | * Explicitly update the status of the command, by firing the {@link CKEDITOR.command#event-refresh} event, | |
61 | * as well as invoke the {@link CKEDITOR.commandDefinition#refresh} method if defined, this method | |
62 | * is to allow different parts of the editor code to contribute in command status resolution. | |
63 | * | |
64 | * @param {CKEDITOR.editor} editor The editor instance. | |
65 | * @param {CKEDITOR.dom.elementPath} path | |
66 | */ | |
67 | this.refresh = function( editor, path ) { | |
68 | // Do nothing is we're on read-only and this command doesn't support it. | |
69 | // We don't need to disabled the command explicitely here, because this | |
70 | // is already done by the "readOnly" event listener. | |
71 | if ( !this.readOnly && editor.readOnly ) | |
72 | return true; | |
73 | ||
74 | // Disable commands that are not allowed in the current selection path context. | |
75 | if ( this.context && !path.isContextFor( this.context ) ) { | |
76 | this.disable(); | |
77 | return true; | |
78 | } | |
79 | ||
80 | // Disable commands that are not allowed by the active filter. | |
81 | if ( !this.checkAllowed( true ) ) { | |
82 | this.disable(); | |
83 | return true; | |
84 | } | |
85 | ||
86 | // Make the "enabled" state a default for commands enabled from start. | |
87 | if ( !this.startDisabled ) | |
88 | this.enable(); | |
89 | ||
90 | // Disable commands which shouldn't be enabled in this mode. | |
91 | if ( this.modes && !this.modes[ editor.mode ] ) | |
92 | this.disable(); | |
93 | ||
94 | if ( this.fire( 'refresh', { editor: editor, path: path } ) === false ) | |
95 | return true; | |
96 | ||
97 | return ( commandDefinition.refresh && commandDefinition.refresh.apply( this, arguments ) !== false ); | |
98 | }; | |
99 | ||
100 | var allowed; | |
101 | ||
102 | /** | |
103 | * Checks whether this command is allowed by the active allowed | |
104 | * content filter ({@link CKEDITOR.editor#activeFilter}). This means | |
105 | * that if command implements {@link CKEDITOR.feature} interface it will be tested | |
106 | * by the {@link CKEDITOR.filter#checkFeature} method. | |
107 | * | |
108 | * @since 4.1 | |
109 | * @param {Boolean} [noCache] Skip cache for example due to active filter change. Since CKEditor 4.2. | |
110 | * @returns {Boolean} Whether this command is allowed. | |
111 | */ | |
112 | this.checkAllowed = function( noCache ) { | |
113 | if ( !noCache && typeof allowed == 'boolean' ) | |
114 | return allowed; | |
115 | ||
116 | return allowed = editor.activeFilter.checkFeature( this ); | |
117 | }; | |
118 | ||
119 | CKEDITOR.tools.extend( this, commandDefinition, { | |
120 | /** | |
121 | * The editor modes within which the command can be executed. The | |
122 | * execution will have no action if the current mode is not listed | |
123 | * in this property. | |
124 | * | |
125 | * // Enable the command in both WYSIWYG and Source modes. | |
126 | * command.modes = { wysiwyg:1,source:1 }; | |
127 | * | |
128 | * // Enable the command in Source mode only. | |
129 | * command.modes = { source:1 }; | |
130 | * | |
131 | * @see CKEDITOR.editor#mode | |
132 | */ | |
133 | modes: { wysiwyg: 1 }, | |
134 | ||
135 | /** | |
136 | * Indicates that the editor will get the focus before executing | |
137 | * the command. | |
138 | * | |
139 | * // Do not force the editor to have focus when executing the command. | |
140 | * command.editorFocus = false; | |
141 | * | |
142 | * @property {Boolean} [=true] | |
143 | */ | |
144 | editorFocus: 1, | |
145 | ||
146 | /** | |
147 | * Indicates that this command is sensible to the selection context. | |
148 | * If `true`, the {@link CKEDITOR.command#method-refresh} method will be | |
149 | * called for this command on the {@link CKEDITOR.editor#event-selectionChange} event. | |
150 | * | |
151 | * @property {Boolean} [=false] | |
152 | */ | |
153 | contextSensitive: !!commandDefinition.context, | |
154 | ||
155 | /** | |
156 | * Indicates the editor state. Possible values are: | |
157 | * | |
158 | * * {@link CKEDITOR#TRISTATE_DISABLED}: the command is | |
159 | * disabled. It's execution will have no effect. Same as {@link #disable}. | |
160 | * * {@link CKEDITOR#TRISTATE_ON}: the command is enabled | |
161 | * and currently active in the editor (for context sensitive commands, for example). | |
162 | * * {@link CKEDITOR#TRISTATE_OFF}: the command is enabled | |
163 | * and currently inactive in the editor (for context sensitive commands, for example). | |
164 | * | |
165 | * Do not set this property directly, using the {@link #setState} method instead. | |
166 | * | |
167 | * if ( command.state == CKEDITOR.TRISTATE_DISABLED ) | |
168 | * alert( 'This command is disabled' ); | |
169 | * | |
170 | * @property {Number} [=CKEDITOR.TRISTATE_DISABLED] | |
171 | */ | |
172 | state: CKEDITOR.TRISTATE_DISABLED | |
173 | } ); | |
174 | ||
175 | // Call the CKEDITOR.event constructor to initialize this instance. | |
176 | CKEDITOR.event.call( this ); | |
177 | }; | |
178 | ||
179 | CKEDITOR.command.prototype = { | |
180 | /** | |
181 | * Enables the command for execution. The command state (see | |
182 | * {@link CKEDITOR.command#property-state}) available before disabling it is restored. | |
183 | * | |
184 | * command.enable(); | |
185 | * command.exec(); // Execute the command. | |
186 | */ | |
187 | enable: function() { | |
188 | if ( this.state == CKEDITOR.TRISTATE_DISABLED && this.checkAllowed() ) | |
189 | this.setState( ( !this.preserveState || ( typeof this.previousState == 'undefined' ) ) ? CKEDITOR.TRISTATE_OFF : this.previousState ); | |
190 | }, | |
191 | ||
192 | /** | |
193 | * Disables the command for execution. The command state (see | |
194 | * {@link CKEDITOR.command#property-state}) will be set to {@link CKEDITOR#TRISTATE_DISABLED}. | |
195 | * | |
196 | * command.disable(); | |
197 | * command.exec(); // "false" - Nothing happens. | |
198 | */ | |
199 | disable: function() { | |
200 | this.setState( CKEDITOR.TRISTATE_DISABLED ); | |
201 | }, | |
202 | ||
203 | /** | |
204 | * Sets the command state. | |
205 | * | |
206 | * command.setState( CKEDITOR.TRISTATE_ON ); | |
207 | * command.exec(); // Execute the command. | |
208 | * command.setState( CKEDITOR.TRISTATE_DISABLED ); | |
209 | * command.exec(); // 'false' - Nothing happens. | |
210 | * command.setState( CKEDITOR.TRISTATE_OFF ); | |
211 | * command.exec(); // Execute the command. | |
212 | * | |
213 | * @param {Number} newState The new state. See {@link #property-state}. | |
214 | * @returns {Boolean} Returns `true` if the command state changed. | |
215 | */ | |
216 | setState: function( newState ) { | |
217 | // Do nothing if there is no state change. | |
218 | if ( this.state == newState ) | |
219 | return false; | |
220 | ||
221 | if ( newState != CKEDITOR.TRISTATE_DISABLED && !this.checkAllowed() ) | |
222 | return false; | |
223 | ||
224 | this.previousState = this.state; | |
225 | ||
226 | // Set the new state. | |
227 | this.state = newState; | |
228 | ||
229 | // Fire the "state" event, so other parts of the code can react to the | |
230 | // change. | |
231 | this.fire( 'state' ); | |
232 | ||
233 | return true; | |
234 | }, | |
235 | ||
236 | /** | |
237 | * Toggles the on/off (active/inactive) state of the command. This is | |
238 | * mainly used internally by context sensitive commands. | |
239 | * | |
240 | * command.toggleState(); | |
241 | */ | |
242 | toggleState: function() { | |
243 | if ( this.state == CKEDITOR.TRISTATE_OFF ) | |
244 | this.setState( CKEDITOR.TRISTATE_ON ); | |
245 | else if ( this.state == CKEDITOR.TRISTATE_ON ) | |
246 | this.setState( CKEDITOR.TRISTATE_OFF ); | |
247 | } | |
248 | }; | |
249 | ||
250 | CKEDITOR.event.implementOn( CKEDITOR.command.prototype ); | |
251 | ||
252 | /** | |
253 | * Indicates the previous command state. | |
254 | * | |
255 | * alert( command.previousState ); | |
256 | * | |
257 | * @property {Number} previousState | |
258 | * @see #state | |
259 | */ | |
260 | ||
261 | /** | |
262 | * Fired when the command state changes. | |
263 | * | |
264 | * command.on( 'state', function() { | |
265 | * // Alerts the new state. | |
266 | * alert( this.state ); | |
267 | * } ); | |
268 | * | |
269 | * @event state | |
270 | */ | |
271 | ||
272 | /** | |
273 | * @event refresh | |
274 | * @todo | |
275 | */ |