|
103 | 103 | */
|
104 | 104 | this.id = CKEDITOR.tools.getNextId();
|
105 | 105 |
|
| 106 | + /** |
| 107 | + * Indicates editor initialization status. The following statuses are available: |
| 108 | + * |
| 109 | + * * **unloaded**: the initial state - editor's instance has been initialized, |
| 110 | + * but its components (config, plugins, language files) are not loaded yet. |
| 111 | + * * **loaded**: editor's components have been loaded - see {@link CKEDITOR.editor#loaded} event. |
| 112 | + * * **ready**: editor is fully initialized and ready - see {@link CKEDITOR.editor#instanceReady} event. |
| 113 | + * * **destroyed**: the editor has been destroyed - see {@link CKEDITOR.editor#method-destroy} method. |
| 114 | + * |
| 115 | + * @property {String} |
| 116 | + */ |
| 117 | + this.status = 'unloaded'; |
| 118 | + |
106 | 119 | /**
|
107 | 120 | * The configurations for this editor instance. It inherits all
|
108 | 121 | * settings defined in {@link CKEDITOR.config}, combined with settings
|
|
140 | 153 | this.keystrokeHandler = new CKEDITOR.keystrokeHandler( this );
|
141 | 154 |
|
142 | 155 | // Make the editor update its command states on mode change.
|
143 |
| - this.on( 'mode', updateCommands ); |
144 | 156 | this.on( 'readOnly', updateCommands );
|
145 | 157 | this.on( 'selectionChange', updateCommandsContext );
|
146 | 158 |
|
147 | 159 | // Handle startup focus.
|
148 | 160 | this.on( 'instanceReady', function() {
|
| 161 | + updateCommands.call( this ); |
| 162 | + // First 'mode' event is fired before this 'instanceReady', |
| 163 | + // so to avoid updating commands twice, add this listener here. |
| 164 | + this.on( 'mode', updateCommands ); |
| 165 | + |
149 | 166 | this.config.startupFocus && this.focus();
|
150 |
| - }); |
| 167 | + } ); |
151 | 168 |
|
152 | 169 | CKEDITOR.fire( 'instanceCreated', null, this );
|
153 | 170 |
|
|
172 | 189 | }
|
173 | 190 |
|
174 | 191 | function updateCommands() {
|
175 |
| - var command, |
176 |
| - commands = this.commands, |
| 192 | + var commands = this.commands, |
177 | 193 | mode = this.mode;
|
178 | 194 |
|
179 | 195 | if ( !mode )
|
180 | 196 | return;
|
181 | 197 |
|
182 |
| - for ( var name in commands ) { |
183 |
| - command = commands[ name ]; |
184 |
| - command[ command.startDisabled ? 'disable' : this.readOnly && !command.readOnly ? 'disable' : command.modes[ mode ] ? 'enable' : 'disable' ](); |
185 |
| - } |
| 198 | + for ( var name in commands ) |
| 199 | + updateCommand( this, commands[ name ] ); |
| 200 | + } |
| 201 | + |
| 202 | + function updateCommand( editor, cmd ) { |
| 203 | + cmd[ cmd.startDisabled ? 'disable' : editor.readOnly && !cmd.readOnly ? 'disable' : cmd.modes[ editor.mode ] ? 'enable' : 'disable' ](); |
186 | 204 | }
|
187 | 205 |
|
188 | 206 | function updateCommandsContext( ev ) {
|
|
526 | 544 | for ( i = 0; i < editor.config.blockedKeystrokes.length; i++ )
|
527 | 545 | editor.keystrokeHandler.blockedKeystrokes[ editor.config.blockedKeystrokes[ i ] ] = 1;
|
528 | 546 |
|
| 547 | + editor.status = 'loaded'; |
529 | 548 | editor.fireOnce( 'loaded' );
|
530 | 549 | CKEDITOR.fire( 'instanceLoaded', null, editor );
|
531 | 550 | });
|
|
571 | 590 | addCommand: function( commandName, commandDefinition ) {
|
572 | 591 | commandDefinition.name = commandName.toLowerCase();
|
573 | 592 | var cmd = new CKEDITOR.command( this, commandDefinition );
|
| 593 | + |
| 594 | + // Update command when added after editor has been already initialized. |
| 595 | + if ( this.status == 'ready' && this.mode ) |
| 596 | + updateCommand( this, cmd ); |
| 597 | + |
574 | 598 | return this.commands[ commandName ] = cmd;
|
575 | 599 | },
|
576 | 600 |
|
|
593 | 617 |
|
594 | 618 | this.editable( null );
|
595 | 619 |
|
| 620 | + this.status = 'destroyed'; |
| 621 | + |
596 | 622 | this.fire( 'destroy' );
|
597 | 623 |
|
598 | 624 | // Plug off all listeners to prevent any further events firing.
|
|
865 | 891 | *
|
866 | 892 | * function beforeUnload( evt ) {
|
867 | 893 | * if ( CKEDITOR.instances.editor1.checkDirty() )
|
868 |
| - * return e.returnValue = "You will lose the changes made in the editor."; |
| 894 | + * return evt.returnValue = "You will lose the changes made in the editor."; |
869 | 895 | * }
|
870 | 896 | *
|
871 | 897 | * if ( window.addEventListener )
|
|
876 | 902 | * @returns {Boolean} `true` if the contents contain changes.
|
877 | 903 | */
|
878 | 904 | checkDirty: function() {
|
879 |
| - return this._.previousValue !== this.getSnapshot(); |
| 905 | + return this.status == 'ready' && this._.previousValue !== this.getSnapshot(); |
880 | 906 | },
|
881 | 907 |
|
882 | 908 | /**
|
@@ -1080,6 +1106,16 @@ CKEDITOR.ELEMENT_MODE_INLINE = 3;
|
1080 | 1106 | * @param {CKEDITOR.editor} editor The editor instance that has been created.
|
1081 | 1107 | */
|
1082 | 1108 |
|
| 1109 | +/** |
| 1110 | + * Fired when CKEDITOR instance's components (config, languages and plugins) are fully |
| 1111 | + * loaded and initialized. However, the editor will be fully ready to for interaction |
| 1112 | + * on {@link CKEDITOR#instanceReady}. |
| 1113 | + * |
| 1114 | + * @event instanceLoaded |
| 1115 | + * @member CKEDITOR |
| 1116 | + * @param {CKEDITOR.editor} editor This editor instance that has been loaded. |
| 1117 | + */ |
| 1118 | + |
1083 | 1119 | /**
|
1084 | 1120 | * Fired when a CKEDITOR instance is destroyed.
|
1085 | 1121 | *
|
@@ -1230,6 +1266,15 @@ CKEDITOR.ELEMENT_MODE_INLINE = 3;
|
1230 | 1266 | * @param {CKEDITOR.editor} editor This editor instance.
|
1231 | 1267 | */
|
1232 | 1268 |
|
| 1269 | +/** |
| 1270 | + * Fired when editor's components (config, languages and plugins) are fully |
| 1271 | + * loaded and initialized. However, the editor will be fully ready to for interaction |
| 1272 | + * on {@link #instanceReady}. |
| 1273 | + * |
| 1274 | + * @event loaded |
| 1275 | + * @param {CKEDITOR.editor} editor This editor instance. |
| 1276 | + */ |
| 1277 | + |
1233 | 1278 | /**
|
1234 | 1279 | * Internal event to perform the {@link #method-insertHtml} call.
|
1235 | 1280 | *
|
|
0 commit comments