]>
git.immae.eu Git - perso/Immae/Projets/packagist/piedsjaloux-ckeditor-component.git/blob - editor.js
31188d24cb266f7d87ce624fd4a9dd6f39eb6a8c
2 * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
3 * For licensing, see LICENSE.md or http://ckeditor.com/license
7 * @fileOverview Defines the {@link CKEDITOR.editor} class that represents an
12 // Override the basic constructor defined at editor_basic.js.
13 Editor
.prototype = CKEDITOR
.editor
.prototype;
14 CKEDITOR
.editor
= Editor
;
17 * Represents an editor instance. This constructor should be rarely
18 * used in favor of the {@link CKEDITOR} editor creation functions.
20 * @class CKEDITOR.editor
21 * @mixins CKEDITOR.event
22 * @constructor Creates an editor class instance.
23 * @param {Object} [instanceConfig] Configuration values for this specific instance.
24 * @param {CKEDITOR.dom.element} [element] The DOM element upon which this editor
26 * @param {Number} [mode] The element creation mode to be used by this editor.
28 function Editor( instanceConfig
, element
, mode
) {
29 // Call the CKEDITOR.event constructor to initialize this instance.
30 CKEDITOR
.event
.call( this );
32 // Make a clone of the config object, to avoid having it touched by our code. (#9636)
33 instanceConfig
= instanceConfig
&& CKEDITOR
.tools
.clone( instanceConfig
);
35 // if editor is created off one page element.
36 if ( element
!== undefined ) {
37 // Asserting element and mode not null.
38 if ( !( element
instanceof CKEDITOR
.dom
.element
) )
39 throw new Error( 'Expect element of type CKEDITOR.dom.element.' );
41 throw new Error( 'One of the element modes must be specified.' );
43 if ( CKEDITOR
.env
.ie
&& CKEDITOR
.env
.quirks
&& mode
== CKEDITOR
.ELEMENT_MODE_INLINE
)
44 throw new Error( 'Inline element mode is not supported on IE quirks.' );
46 if ( !isSupportedElement( element
, mode
) )
47 throw new Error( 'The specified element mode is not supported on element: "' + element
.getName() + '".' );
50 * The original host page element upon which the editor is created. It is only
51 * supposed to be provided by the particular editor creator and is not subject to
55 * @property {CKEDITOR.dom.element}
57 this.element
= element
;
60 * This property indicates the way this instance is associated with the {@link #element}.
61 * See also {@link CKEDITOR#ELEMENT_MODE_INLINE} and {@link CKEDITOR#ELEMENT_MODE_REPLACE}.
66 this.elementMode
= mode
;
68 this.name
= ( this.elementMode
!= CKEDITOR
.ELEMENT_MODE_APPENDTO
) && ( element
.getId() || element
.getNameAtt() );
70 this.elementMode
= CKEDITOR
.ELEMENT_MODE_NONE
;
73 // Declare the private namespace.
79 * Contains all UI templates created for this editor instance.
87 * A unique identifier of this editor instance.
89 * **Note:** It will be originated from the `id` or `name`
90 * attribute of the {@link #element}, otherwise a name pattern of
91 * `'editor{n}'` will be used.
96 this.name
= this.name
|| genEditorName();
99 * A unique random string assigned to each editor instance on the page.
104 this.id
= CKEDITOR
.tools
.getNextId();
107 * Indicates editor initialization status. The following statuses are available:
109 * * **unloaded**: The initial state — the editor instance was initialized,
110 * but its components (configuration, plugins, language files) are not loaded yet.
111 * * **loaded**: The editor components were loaded — see the {@link CKEDITOR.editor#loaded} event.
112 * * **ready**: The editor is fully initialized and ready — see the {@link CKEDITOR.editor#instanceReady} event.
113 * * **destroyed**: The editor was destroyed — see the {@link CKEDITOR.editor#method-destroy} method.
119 this.status
= 'unloaded';
122 * The configuration for this editor instance. It inherits all
123 * settings defined in {@link CKEDITOR.config}, combined with settings
124 * loaded from custom configuration files and those defined inline in
125 * the page when creating the editor.
127 * var editor = CKEDITOR.instances.editor1;
128 * alert( editor.config.skin ); // e.g. 'moono'
131 * @property {CKEDITOR.config}
133 this.config
= CKEDITOR
.tools
.prototypedCopy( CKEDITOR
.config
);
136 * The namespace containing UI features related to this editor instance.
139 * @property {CKEDITOR.ui}
141 this.ui
= new CKEDITOR
.ui( this );
144 * Controls the focus state of this editor instance. This property
145 * is rarely used for normal API operations. It is mainly
146 * targeted at developers adding UI elements to the editor interface.
149 * @property {CKEDITOR.focusManager}
151 this.focusManager
= new CKEDITOR
.focusManager( this );
154 * Controls keystroke typing in this editor instance.
157 * @property {CKEDITOR.keystrokeHandler}
159 this.keystrokeHandler
= new CKEDITOR
.keystrokeHandler( this );
161 // Make the editor update its command states on mode change.
162 this.on( 'readOnly', updateCommands
);
163 this.on( 'selectionChange', function( evt
) {
164 updateCommandsContext( this, evt
.data
.path
);
166 this.on( 'activeFilterChange', function() {
167 updateCommandsContext( this, this.elementPath(), true );
169 this.on( 'mode', updateCommands
);
171 // Handle startup focus.
172 this.on( 'instanceReady', function() {
173 this.config
.startupFocus
&& this.focus();
176 CKEDITOR
.fire( 'instanceCreated', null, this );
178 // Add this new editor to the CKEDITOR.instances collections.
179 CKEDITOR
.add( this );
181 // Return the editor instance immediately to enable early stage event registrations.
182 CKEDITOR
.tools
.setTimeout( function() {
183 if ( this.status
!== 'destroyed' ) {
184 initConfig( this, instanceConfig
);
186 CKEDITOR
.warn( 'editor-incorrect-destroy' );
193 function genEditorName() {
195 var name
= 'editor' + ( ++nameCounter
);
197 while ( CKEDITOR
.instances
[ name
] );
202 // Asserting element DTD depending on mode.
203 function isSupportedElement( element
, mode
) {
204 if ( mode
== CKEDITOR
.ELEMENT_MODE_INLINE
)
205 return element
.is( CKEDITOR
.dtd
.$editable
) || element
.is( 'textarea' );
206 else if ( mode
== CKEDITOR
.ELEMENT_MODE_REPLACE
)
207 return !element
.is( CKEDITOR
.dtd
.$nonBodyContent
);
211 function updateCommands() {
212 var commands
= this.commands
,
215 for ( name
in commands
)
216 updateCommand( this, commands
[ name
] );
219 function updateCommand( editor
, cmd
) {
220 cmd
[ cmd
.startDisabled
? 'disable' : editor
.readOnly
&& !cmd
.readOnly
? 'disable' : cmd
.modes
[ editor
.mode
] ? 'enable' : 'disable' ]();
223 function updateCommandsContext( editor
, path
, forceRefresh
) {
224 // Commands cannot be refreshed without a path. In edge cases
225 // it may happen that there's no selection when this function is executed.
226 // For example when active filter is changed in #10877.
232 commands
= editor
.commands
;
234 for ( name
in commands
) {
235 command
= commands
[ name
];
237 if ( forceRefresh
|| command
.contextSensitive
)
238 command
.refresh( editor
, path
);
242 // ##### START: Config Privates
244 // These function loads custom configuration files and cache the
245 // CKEDITOR.editorConfig functions defined on them, so there is no need to
246 // download them more than once for several instances.
247 var loadConfigLoaded
= {};
249 function loadConfig( editor
) {
250 var customConfig
= editor
.config
.customConfig
;
252 // Check if there is a custom config to load.
256 customConfig
= CKEDITOR
.getUrl( customConfig
);
258 var loadedConfig
= loadConfigLoaded
[ customConfig
] || ( loadConfigLoaded
[ customConfig
] = {} );
260 // If the custom config has already been downloaded, reuse it.
261 if ( loadedConfig
.fn
) {
262 // Call the cached CKEDITOR.editorConfig defined in the custom
263 // config file for the editor instance depending on it.
264 loadedConfig
.fn
.call( editor
, editor
.config
);
266 // If there is no other customConfig in the chain, fire the
267 // "configLoaded" event.
268 if ( CKEDITOR
.getUrl( editor
.config
.customConfig
) == customConfig
|| !loadConfig( editor
) )
269 editor
.fireOnce( 'customConfigLoaded' );
271 // Load the custom configuration file.
272 // To resolve customConfig race conflicts, use scriptLoader#queue
273 // instead of scriptLoader#load (#6504).
274 CKEDITOR
.scriptLoader
.queue( customConfig
, function() {
275 // If the CKEDITOR.editorConfig function has been properly
276 // defined in the custom configuration file, cache it.
277 if ( CKEDITOR
.editorConfig
)
278 loadedConfig
.fn
= CKEDITOR
.editorConfig
;
280 loadedConfig
.fn = function() {};
282 // Call the load config again. This time the custom
283 // config is already cached and so it will get loaded.
284 loadConfig( editor
);
291 function initConfig( editor
, instanceConfig
) {
292 // Setup the lister for the "customConfigLoaded" event.
293 editor
.on( 'customConfigLoaded', function() {
294 if ( instanceConfig
) {
295 // Register the events that may have been set at the instance
296 // configuration object.
297 if ( instanceConfig
.on
) {
298 for ( var eventName
in instanceConfig
.on
) {
299 editor
.on( eventName
, instanceConfig
.on
[ eventName
] );
303 // Overwrite the settings from the in-page config.
304 CKEDITOR
.tools
.extend( editor
.config
, instanceConfig
, true );
306 delete editor
.config
.on
;
309 onConfigLoaded( editor
);
312 // The instance config may override the customConfig setting to avoid
313 // loading the default ~/config.js file.
314 if ( instanceConfig
&& instanceConfig
.customConfig
!= null )
315 editor
.config
.customConfig
= instanceConfig
.customConfig
;
317 // Load configs from the custom configuration files.
318 if ( !loadConfig( editor
) )
319 editor
.fireOnce( 'customConfigLoaded' );
322 // ##### END: Config Privates
324 // Set config related properties.
325 function onConfigLoaded( editor
) {
326 var config
= editor
.config
;
329 * Indicates the read-only state of this editor. This is a read-only property.
330 * See also {@link CKEDITOR.editor#setReadOnly}.
334 * @property {Boolean}
336 editor
.readOnly
= isEditorReadOnly();
338 function isEditorReadOnly() {
339 if ( config
.readOnly
) {
343 if ( editor
.elementMode
== CKEDITOR
.ELEMENT_MODE_INLINE
) {
344 if ( editor
.element
.is( 'textarea' ) ) {
345 return editor
.element
.hasAttribute( 'disabled' ) || editor
.element
.hasAttribute( 'readonly' );
347 return editor
.element
.isReadOnly();
349 } else if ( editor
.elementMode
== CKEDITOR
.ELEMENT_MODE_REPLACE
) {
350 return editor
.element
.hasAttribute( 'disabled' ) || editor
.element
.hasAttribute( 'readonly' );
357 * Indicates that the editor is running in an environment where
358 * no block elements are accepted inside the content.
360 * This can be for example inline editor based on an `<h1>` element.
363 * @property {Boolean}
365 editor
.blockless
= editor
.elementMode
== CKEDITOR
.ELEMENT_MODE_INLINE
?
366 !( editor
.element
.is( 'textarea' ) || CKEDITOR
.dtd
[ editor
.element
.getName() ].p
) :
370 * The [tabbing navigation](http://en.wikipedia.org/wiki/Tabbing_navigation) order determined for this editor instance.
371 * This can be set by the <code>{@link CKEDITOR.config#tabIndex}</code>
372 * setting or taken from the `tabindex` attribute of the
373 * {@link #element} associated with the editor.
375 * alert( editor.tabIndex ); // e.g. 0
378 * @property {Number} [=0]
380 editor
.tabIndex
= config
.tabIndex
|| editor
.element
&& editor
.element
.getAttribute( 'tabindex' ) || 0;
382 editor
.activeEnterMode
= editor
.enterMode
= validateEnterMode( editor
, config
.enterMode
);
383 editor
.activeShiftEnterMode
= editor
.shiftEnterMode
= validateEnterMode( editor
, config
.shiftEnterMode
);
385 // Set CKEDITOR.skinName. Note that it is not possible to have
386 // different skins on the same page, so the last one to set it "wins".
388 CKEDITOR
.skinName
= config
.skin
;
390 // Fire the "configLoaded" event.
391 editor
.fireOnce( 'configLoaded' );
393 initComponents( editor
);
396 // Various other core components that read editor configuration.
397 function initComponents( editor
) {
398 // Documented in dataprocessor.js.
399 editor
.dataProcessor
= new CKEDITOR
.htmlDataProcessor( editor
);
401 // Set activeFilter directly to avoid firing event.
402 editor
.filter
= editor
.activeFilter
= new CKEDITOR
.filter( editor
);
407 function loadSkin( editor
) {
408 CKEDITOR
.skin
.loadPart( 'editor', function() {
413 function loadLang( editor
) {
414 CKEDITOR
.lang
.load( editor
.config
.language
, editor
.config
.defaultLanguage
, function( languageCode
, lang
) {
415 var configTitle
= editor
.config
.title
;
418 * The code for the language resources that have been loaded
419 * for the user interface elements of this editor instance.
421 * alert( editor.langCode ); // e.g. 'en'
426 editor
.langCode
= languageCode
;
429 * An object that contains all language strings used by the editor interface.
431 * alert( editor.lang.basicstyles.bold ); // e.g. 'Negrito' (if the language is set to Portuguese)
434 * @property {Object} lang
436 // As we'll be adding plugin specific entries that could come
437 // from different language code files, we need a copy of lang,
438 // not a direct reference to it.
439 editor
.lang
= CKEDITOR
.tools
.prototypedCopy( lang
);
442 * Indicates the human-readable title of this editor. Although this is a read-only property,
443 * it can be initialized with {@link CKEDITOR.config#title}.
445 * **Note:** Please do not confuse this property with {@link CKEDITOR.editor#name editor.name}
446 * which identifies the instance in the {@link CKEDITOR#instances} literal.
450 * @property {String/Boolean}
452 editor
.title
= typeof configTitle
== 'string' || configTitle
=== false ? configTitle : [ editor
.lang
.editor
, editor
.name
].join( ', ' );
454 if ( !editor
.config
.contentsLangDirection
) {
455 // Fallback to either the editable element direction or editor UI direction depending on creators.
456 editor
.config
.contentsLangDirection
= editor
.elementMode
== CKEDITOR
.ELEMENT_MODE_INLINE
? editor
.element
.getDirection( 1 ) : editor
.lang
.dir
;
459 editor
.fire( 'langLoaded' );
461 preloadStylesSet( editor
);
465 // Preloads styles set file (config.stylesSet).
466 // If stylesSet was defined directly (by an array)
467 // this function will call loadPlugins fully synchronously.
468 // If stylesSet is a string (path) loadPlugins will
469 // be called asynchronously.
470 // In both cases - styles will be preload before plugins initialization.
471 function preloadStylesSet( editor
) {
472 editor
.getStylesSet( function( styles
) {
473 // Wait for editor#loaded, so plugins could add their listeners.
474 // But listen with high priority to fire editor#stylesSet before editor#uiReady and editor#setData.
475 editor
.once( 'loaded', function() {
476 // Note: we can't use fireOnce because this event may canceled and fired again.
477 editor
.fire( 'stylesSet', { styles: styles
} );
480 loadPlugins( editor
);
484 function loadPlugins( editor
) {
485 var config
= editor
.config
,
486 plugins
= config
.plugins
,
487 extraPlugins
= config
.extraPlugins
,
488 removePlugins
= config
.removePlugins
;
490 if ( extraPlugins
) {
491 // Remove them first to avoid duplications.
492 var extraRegex
= new RegExp( '(?:^|,)(?:' + extraPlugins
.replace( /\s*,\s*/g, '|' ) + ')(?=,|$)', 'g' );
493 plugins
= plugins
.replace( extraRegex
, '' );
495 plugins
+= ',' + extraPlugins
;
498 if ( removePlugins
) {
499 var removeRegex
= new RegExp( '(?:^|,)(?:' + removePlugins
.replace( /\s*,\s*/g, '|' ) + ')(?=,|$)', 'g' );
500 plugins
= plugins
.replace( removeRegex
, '' );
503 // Load the Adobe AIR plugin conditionally.
504 CKEDITOR
.env
.air
&& ( plugins
+= ',adobeair' );
506 // Load all plugins defined in the "plugins" setting.
507 CKEDITOR
.plugins
.load( plugins
.split( ',' ), function( plugins
) {
508 // The list of plugins.
509 var pluginsArray
= [];
511 // The language code to get loaded for each plugin. Null
512 // entries will be appended for plugins with no language files.
513 var languageCodes
= [];
515 // The list of URLs to language files.
516 var languageFiles
= [];
519 * An object that contains references to all plugins used by this
522 * alert( editor.plugins.dialog.path ); // e.g. 'http://example.com/ckeditor/plugins/dialog/'
524 * // Check if a plugin is available.
525 * if ( editor.plugins.image ) {
532 editor
.plugins
= plugins
;
534 // Loop through all plugins, to build the list of language
535 // files to get loaded.
537 // Check also whether any of loaded plugins doesn't require plugins
538 // defined in config.removePlugins. Throw non-blocking error if this happens.
539 for ( var pluginName
in plugins
) {
540 var plugin
= plugins
[ pluginName
],
541 pluginLangs
= plugin
.lang
,
543 requires
= plugin
.requires
,
546 // Transform it into a string, if it's not one.
547 if ( CKEDITOR
.tools
.isArray( requires
) )
548 requires
= requires
.join( ',' );
550 if ( requires
&& ( match
= requires
.match( removeRegex
) ) ) {
551 while ( ( name
= match
.pop() ) ) {
552 CKEDITOR
.error( 'editor-plugin-required', { plugin: name
.replace( ',', '' ), requiredBy: pluginName
} );
556 // If the plugin has "lang".
557 if ( pluginLangs
&& !editor
.lang
[ pluginName
] ) {
558 // Trasnform the plugin langs into an array, if it's not one.
559 if ( pluginLangs
.split
)
560 pluginLangs
= pluginLangs
.split( ',' );
562 // Resolve the plugin language. If the current language
563 // is not available, get English or the first one.
564 if ( CKEDITOR
.tools
.indexOf( pluginLangs
, editor
.langCode
) >= 0 )
565 lang
= editor
.langCode
;
567 // The language code may have the locale information (zh-cn).
568 // Fall back to locale-less in that case (zh).
569 var langPart
= editor
.langCode
.replace( /-.*/, '' );
570 if ( langPart
!= editor
.langCode
&& CKEDITOR
.tools
.indexOf( pluginLangs
, langPart
) >= 0 )
572 // Try the only "generic" option we have: English.
573 else if ( CKEDITOR
.tools
.indexOf( pluginLangs
, 'en' ) >= 0 )
576 lang
= pluginLangs
[ 0 ];
579 if ( !plugin
.langEntries
|| !plugin
.langEntries
[ lang
] ) {
580 // Put the language file URL into the list of files to
582 languageFiles
.push( CKEDITOR
.getUrl( plugin
.path
+ 'lang/' + lang
+ '.js' ) );
584 editor
.lang
[ pluginName
] = plugin
.langEntries
[ lang
];
589 // Save the language code, so we know later which
590 // language has been resolved to this plugin.
591 languageCodes
.push( lang
);
593 pluginsArray
.push( plugin
);
596 // Load all plugin specific language files in a row.
597 CKEDITOR
.scriptLoader
.load( languageFiles
, function() {
598 // Initialize all plugins that have the "beforeInit" and "init" methods defined.
599 var methods
= [ 'beforeInit', 'init', 'afterInit' ];
600 for ( var m
= 0; m
< methods
.length
; m
++ ) {
601 for ( var i
= 0; i
< pluginsArray
.length
; i
++ ) {
602 var plugin
= pluginsArray
[ i
];
604 // Uses the first loop to update the language entries also.
605 if ( m
=== 0 && languageCodes
[ i
] && plugin
.lang
&& plugin
.langEntries
)
606 editor
.lang
[ plugin
.name
] = plugin
.langEntries
[ languageCodes
[ i
] ];
608 // Call the plugin method (beforeInit and init).
609 if ( plugin
[ methods
[ m
] ] )
610 plugin
[ methods
[ m
] ]( editor
);
614 editor
.fireOnce( 'pluginsLoaded' );
616 // Setup the configured keystrokes.
617 config
.keystrokes
&& editor
.setKeystroke( editor
.config
.keystrokes
);
619 // Setup the configured blocked keystrokes.
620 for ( i
= 0; i
< editor
.config
.blockedKeystrokes
.length
; i
++ )
621 editor
.keystrokeHandler
.blockedKeystrokes
[ editor
.config
.blockedKeystrokes
[ i
] ] = 1;
623 editor
.status
= 'loaded';
624 editor
.fireOnce( 'loaded' );
625 CKEDITOR
.fire( 'instanceLoaded', null, editor
);
630 // Send to data output back to editor's associated element.
631 function updateEditorElement() {
632 var element
= this.element
;
634 // Some editor creation mode will not have the
635 // associated element.
636 if ( element
&& this.elementMode
!= CKEDITOR
.ELEMENT_MODE_APPENDTO
) {
637 var data
= this.getData();
639 if ( this.config
.htmlEncodeOutput
)
640 data
= CKEDITOR
.tools
.htmlEncode( data
);
642 if ( element
.is( 'textarea' ) )
643 element
.setValue( data
);
645 element
.setHtml( data
);
652 // Always returns ENTER_BR in case of blockless editor.
653 function validateEnterMode( editor
, enterMode
) {
654 return editor
.blockless
? CKEDITOR
.ENTER_BR : enterMode
;
657 // Create DocumentFragment from specified ranges. For now it handles only tables in Firefox
658 // and returns DocumentFragment from the 1. range for other cases. (#13884)
659 function createDocumentFragmentFromRanges( ranges
, editable
) {
660 var docFragment
= new CKEDITOR
.dom
.documentFragment(),
665 for ( var i
= 0; i
< ranges
.length
; i
++ ) {
666 var range
= ranges
[ i
],
667 container
= range
.startContainer
;
669 if ( container
.getName
&& container
.getName() == 'tr' ) {
671 tableClone
= container
.getAscendant( 'table' ).clone();
672 tableClone
.append( container
.getAscendant( 'tbody' ).clone() );
673 docFragment
.append( tableClone
);
674 tableClone
= tableClone
.findOne( 'tbody' );
677 if ( !( currentRow
&& currentRow
.equals( container
) ) ) {
678 currentRow
= container
;
679 currentRowClone
= container
.clone();
680 tableClone
.append( currentRowClone
);
683 currentRowClone
.append( range
.cloneContents() );
685 // If there was something else copied with table,
686 // append it to DocumentFragment.
687 docFragment
.append( range
.cloneContents() );
692 return editable
.getHtmlFromRange( ranges
[ 0 ] );
698 CKEDITOR
.tools
.extend( CKEDITOR
.editor
.prototype, {
700 * Adds a command definition to the editor instance. Commands added with
701 * this function can be executed later with the <code>{@link #execCommand}</code> method.
703 * editorInstance.addCommand( 'sample', {
704 * exec: function( editor ) {
705 * alert( 'Executing a command for the editor name "' + editor.name + '"!' );
709 * @param {String} commandName The indentifier name of the command.
710 * @param {CKEDITOR.commandDefinition} commandDefinition The command definition.
712 addCommand: function( commandName
, commandDefinition
) {
713 commandDefinition
.name
= commandName
.toLowerCase();
714 var cmd
= new CKEDITOR
.command( this, commandDefinition
);
716 // Update command when mode is set.
717 // This guarantees that commands added before first editor#mode
718 // aren't immediately updated, but waits for editor#mode and that
719 // commands added later are immediately refreshed, even when added
720 // before instanceReady. #10103, #10249
722 updateCommand( this, cmd
);
724 return this.commands
[ commandName
] = cmd
;
728 * Attaches the editor to a form to call {@link #updateElement} before form submission.
729 * This method is called by both creators ({@link CKEDITOR#replace replace} and
730 * {@link CKEDITOR#inline inline}), so there is no reason to call it manually.
734 _attachToForm: function() {
736 element
= editor
.element
,
737 form
= new CKEDITOR
.dom
.element( element
.$.form
);
739 // If are replacing a textarea, we must
740 if ( element
.is( 'textarea' ) ) {
742 form
.on( 'submit', onSubmit
);
744 // Check if there is no element/elements input with name == "submit".
745 // If they exists they will overwrite form submit function (form.$.submit).
746 // If form.$.submit is overwritten we can not do anything with it.
747 if ( isFunction( form
.$.submit
) ) {
748 // Setup the submit function because it doesn't fire the
750 form
.$.submit
= CKEDITOR
.tools
.override( form
.$.submit
, function( originalSubmit
) {
754 // For IE, the DOM submit function is not a
755 // function, so we need third check.
756 if ( originalSubmit
.apply
)
757 originalSubmit
.apply( this );
764 // Remove 'submit' events registered on form element before destroying.(#3988)
765 editor
.on( 'destroy', function() {
766 form
.removeListener( 'submit', onSubmit
);
771 function onSubmit( evt
) {
772 editor
.updateElement();
774 // #8031 If textarea had required attribute and editor is empty fire 'required' event and if
775 // it was cancelled, prevent submitting the form.
776 if ( editor
._
.required
&& !element
.getValue() && editor
.fire( 'required' ) === false ) {
777 // When user press save button event (evt) is undefined (see save plugin).
778 // This method works because it throws error so originalSubmit won't be called.
779 // Also this error won't be shown because it will be caught in save plugin.
780 evt
.data
.preventDefault();
784 function isFunction( f
) {
785 // For IE8 typeof fun == object so we cannot use it.
786 return !!( f
&& f
.call
&& f
.apply
);
791 * Destroys the editor instance, releasing all resources used by it.
792 * If the editor replaced an element, the element will be recovered.
794 * alert( CKEDITOR.instances.editor1 ); // e.g. object
795 * CKEDITOR.instances.editor1.destroy();
796 * alert( CKEDITOR.instances.editor1 ); // undefined
798 * @param {Boolean} [noUpdate] If the instance is replacing a DOM
799 * element, this parameter indicates whether or not to update the
800 * element with the instance content.
802 destroy: function( noUpdate
) {
803 this.fire( 'beforeDestroy' );
805 !noUpdate
&& updateEditorElement
.call( this );
807 this.editable( null );
810 this.filter
.destroy();
814 delete this.activeFilter
;
816 this.status
= 'destroyed';
818 this.fire( 'destroy' );
820 // Plug off all listeners to prevent any further events firing.
821 this.removeAllListeners();
823 CKEDITOR
.remove( this );
824 CKEDITOR
.fire( 'instanceDestroyed', null, this );
828 * Returns an {@link CKEDITOR.dom.elementPath element path} for the selection in the editor.
830 * @param {CKEDITOR.dom.node} [startNode] From which the path should start,
831 * if not specified defaults to editor selection's
832 * start element yielded by {@link CKEDITOR.dom.selection#getStartElement}.
833 * @returns {CKEDITOR.dom.elementPath}
835 elementPath: function( startNode
) {
837 var sel
= this.getSelection();
841 startNode
= sel
.getStartElement();
844 return startNode
? new CKEDITOR
.dom
.elementPath( startNode
, this.editable() ) : null;
848 * Shortcut to create a {@link CKEDITOR.dom.range} instance from the editable element.
850 * @returns {CKEDITOR.dom.range} The DOM range created if the editable has presented.
851 * @see CKEDITOR.dom.range
853 createRange: function() {
854 var editable
= this.editable();
855 return editable
? new CKEDITOR
.dom
.range( editable
) : null;
859 * Executes a command associated with the editor.
861 * editorInstance.execCommand( 'bold' );
863 * @param {String} commandName The indentifier name of the command.
864 * @param {Object} [data] The data to be passed to the command.
865 * @returns {Boolean} `true` if the command was executed
866 * successfully, otherwise `false`.
867 * @see CKEDITOR.editor#addCommand
869 execCommand: function( commandName
, data
) {
870 var command
= this.getCommand( commandName
);
878 if ( command
&& command
.state
!= CKEDITOR
.TRISTATE_DISABLED
) {
879 if ( this.fire( 'beforeCommandExec', eventData
) !== false ) {
880 eventData
.returnValue
= command
.exec( eventData
.commandData
);
882 // Fire the 'afterCommandExec' immediately if command is synchronous.
883 if ( !command
.async
&& this.fire( 'afterCommandExec', eventData
) !== false )
884 return eventData
.returnValue
;
888 // throw 'Unknown command name "' + commandName + '"';
893 * Gets one of the registered commands. Note that after registering a
894 * command definition with {@link #addCommand}, it is
895 * transformed internally into an instance of
896 * {@link CKEDITOR.command}, which will then be returned by this function.
898 * @param {String} commandName The name of the command to be returned.
899 * This is the same name that is used to register the command with `addCommand`.
900 * @returns {CKEDITOR.command} The command object identified by the provided name.
902 getCommand: function( commandName
) {
903 return this.commands
[ commandName
];
907 * Gets the editor data. The data will be in "raw" format. It is the same
908 * data that is posted by the editor.
910 * if ( CKEDITOR.instances.editor1.getData() == '' )
911 * alert( 'There is no data available.' );
913 * @param {Boolean} internal If set to `true`, it will prevent firing the
914 * {@link CKEDITOR.editor#beforeGetData} and {@link CKEDITOR.editor#event-getData} events, so
915 * the real content of the editor will not be read and cached data will be returned. The method will work
916 * much faster, but this may result in the editor returning the data that is not up to date. This parameter
917 * should thus only be set to `true` when you are certain that the cached data is up to date.
919 * @returns {String} The editor data.
921 getData: function( internal ) {
922 !internal && this.fire( 'beforeGetData' );
924 var eventData
= this._
.data
;
926 if ( typeof eventData
!= 'string' ) {
927 var element
= this.element
;
928 if ( element
&& this.elementMode
== CKEDITOR
.ELEMENT_MODE_REPLACE
)
929 eventData
= element
.is( 'textarea' ) ? element
.getValue() : element
.getHtml();
934 eventData
= { dataValue: eventData
};
936 // Fire "getData" so data manipulation may happen.
937 !internal && this.fire( 'getData', eventData
);
939 return eventData
.dataValue
;
943 * Gets the "raw data" currently available in the editor. This is a
944 * fast method which returns the data as is, without processing, so it is
945 * not recommended to use it on resulting pages. Instead it can be used
946 * combined with the {@link #method-loadSnapshot} method in order
947 * to automatically save the editor data from time to time
948 * while the user is using the editor, to avoid data loss, without risking
949 * performance issues.
951 * alert( editor.getSnapshot() );
955 * * {@link CKEDITOR.editor#method-getData}.
957 * @returns {String} Editor "raw data".
959 getSnapshot: function() {
960 var data
= this.fire( 'getSnapshot' );
962 if ( typeof data
!= 'string' ) {
963 var element
= this.element
;
965 if ( element
&& this.elementMode
== CKEDITOR
.ELEMENT_MODE_REPLACE
) {
966 data
= element
.is( 'textarea' ) ? element
.getValue() : element
.getHtml();
969 // If we don't have a proper element, set data to an empty string,
970 // as this method is expected to return a string. (#13385)
979 * Loads "raw data" into the editor. The data is loaded with processing
980 * straight to the editing area. It should not be used as a way to load
981 * any kind of data, but instead in combination with
982 * {@link #method-getSnapshot}-produced data.
984 * var data = editor.getSnapshot();
985 * editor.loadSnapshot( data );
987 * @see CKEDITOR.editor#setData
989 loadSnapshot: function( snapshot
) {
990 this.fire( 'loadSnapshot', snapshot
);
994 * Sets the editor data. The data must be provided in the "raw" format (HTML).
996 * Note that this method is asynchronous. The `callback` parameter must
997 * be used if interaction with the editor is needed after setting the data.
999 * CKEDITOR.instances.editor1.setData( '<p>This is the editor data.</p>' );
1001 * CKEDITOR.instances.editor1.setData( '<p>Some other editor data.</p>', {
1002 * callback: function() {
1003 * this.checkDirty(); // true
1007 * Note: In **CKEditor 4.4.2** the signature of this method has changed. All arguments
1008 * except `data` were wrapped into the `options` object. However, backward compatibility
1009 * was preserved and it is still possible to use the `data, callback, internal` arguments.
1012 * @param {String} data The HTML code to replace current editor content.
1013 * @param {Object} [options]
1014 * @param {Boolean} [options.internal=false] Whether to suppress any event firing when copying data internally inside the editor.
1015 * @param {Function} [options.callback] Function to be called after `setData` is completed (on {@link #dataReady}).
1016 * @param {Boolean} [options.noSnapshot=false] If set to `true`, it will prevent recording an undo snapshot.
1017 * Introduced in CKEditor 4.4.2.
1019 setData: function( data
, options
, internal ) {
1020 var fireSnapshot
= true,
1021 // Backward compatibility.
1025 if ( options
&& typeof options
== 'object' ) {
1026 internal = options
.internal;
1027 callback
= options
.callback
;
1028 fireSnapshot
= !options
.noSnapshot
;
1031 if ( !internal && fireSnapshot
)
1032 this.fire( 'saveSnapshot' );
1034 if ( callback
|| !internal ) {
1035 this.once( 'dataReady', function( evt
) {
1036 if ( !internal && fireSnapshot
)
1037 this.fire( 'saveSnapshot' );
1040 callback
.call( evt
.editor
);
1044 // Fire "setData" so data manipulation may happen.
1045 eventData
= { dataValue: data
};
1046 !internal && this.fire( 'setData', eventData
);
1048 this._
.data
= eventData
.dataValue
;
1050 !internal && this.fire( 'afterSetData', eventData
);
1054 * Puts or restores the editor into the read-only state. When in read-only,
1055 * the user is not able to change the editor content, but can still use
1056 * some editor features. This function sets the {@link #property-readOnly}
1057 * property of the editor, firing the {@link #event-readOnly} event.
1059 * **Note:** The current editing area will be reloaded.
1062 * @param {Boolean} [isReadOnly] Indicates that the editor must go
1063 * read-only (`true`, default) or be restored and made editable (`false`).
1065 setReadOnly: function( isReadOnly
) {
1066 isReadOnly
= ( isReadOnly
== null ) || isReadOnly
;
1068 if ( this.readOnly
!= isReadOnly
) {
1069 this.readOnly
= isReadOnly
;
1071 // Block or release BACKSPACE key according to current read-only
1072 // state to prevent browser's history navigation (#9761).
1073 this.keystrokeHandler
.blockedKeystrokes
[ 8 ] = +isReadOnly
;
1075 this.editable().setReadOnly( isReadOnly
);
1077 // Fire the readOnly event so the editor features can update
1078 // their state accordingly.
1079 this.fire( 'readOnly' );
1084 * Inserts HTML code into the currently selected position in the editor in WYSIWYG mode.
1088 * CKEDITOR.instances.editor1.insertHtml( '<p>This is a new paragraph.</p>' );
1090 * Fires the {@link #event-insertHtml} and {@link #event-afterInsertHtml} events. The HTML is inserted
1091 * in the {@link #event-insertHtml} event's listener with a default priority (10) so you can add listeners with
1092 * lower or higher priorities in order to execute some code before or after the HTML is inserted.
1094 * @param {String} html HTML code to be inserted into the editor.
1095 * @param {String} [mode='html'] The mode in which the HTML code will be inserted. One of the following:
1097 * * `'html'` – The inserted content will completely override the styles at the selected position.
1098 * * `'unfiltered_html'` – Like `'html'` but the content is not filtered with {@link CKEDITOR.filter}.
1099 * * `'text'` – The inserted content will inherit the styles applied in
1100 * the selected position. This mode should be used when inserting "htmlified" plain text
1101 * (HTML without inline styles and styling elements like `<b>`, `<strong>`, `<span style="...">`).
1103 * @param {CKEDITOR.dom.range} [range] If specified, the HTML will be inserted into the range
1104 * instead of into the selection. The selection will be placed at the end of the insertion (like in the normal case).
1105 * Introduced in CKEditor 4.5.
1107 insertHtml: function( html
, mode
, range
) {
1108 this.fire( 'insertHtml', { dataValue: html
, mode: mode
, range: range
} );
1112 * Inserts text content into the currently selected position in the
1113 * editor in WYSIWYG mode. The styles of the selected element will be applied to the inserted text.
1114 * Spaces around the text will be left untouched.
1116 * CKEDITOR.instances.editor1.insertText( ' line1 \n\n line2' );
1118 * Fires the {@link #event-insertText} and {@link #event-afterInsertHtml} events. The text is inserted
1119 * in the {@link #event-insertText} event's listener with a default priority (10) so you can add listeners with
1120 * lower or higher priorities in order to execute some code before or after the text is inserted.
1123 * @param {String} text Text to be inserted into the editor.
1125 insertText: function( text
) {
1126 this.fire( 'insertText', text
);
1130 * Inserts an element into the currently selected position in the editor in WYSIWYG mode.
1132 * var element = CKEDITOR.dom.element.createFromHtml( '<img src="hello.png" border="0" title="Hello" />' );
1133 * CKEDITOR.instances.editor1.insertElement( element );
1135 * Fires the {@link #event-insertElement} event. The element is inserted in the listener with a default priority (10),
1136 * so you can add listeners with lower or higher priorities in order to execute some code before or after
1137 * the element is inserted.
1139 * @param {CKEDITOR.dom.element} element The element to be inserted into the editor.
1141 insertElement: function( element
) {
1142 this.fire( 'insertElement', element
);
1146 * Gets the selected HTML (it is returned as a {@link CKEDITOR.dom.documentFragment document fragment}
1147 * or a string). This method is designed to work as the user would expect the copy functionality to work.
1148 * For instance, if the following selection was made:
1150 * <p>a<b>b{c}d</b>e</p>
1152 * The following HTML will be returned:
1156 * As you can see, the information about the bold formatting was preserved, even though the selection was
1157 * anchored inside the `<b>` element.
1161 * * the {@link #extractSelectedHtml} method,
1162 * * the {@link CKEDITOR.editable#getHtmlFromRange} method.
1165 * @param {Boolean} [toString] If `true`, then stringified HTML will be returned.
1166 * @returns {CKEDITOR.dom.documentFragment/String}
1168 getSelectedHtml: function( toString
) {
1169 var editable
= this.editable(),
1170 selection
= this.getSelection(),
1171 ranges
= selection
&& selection
.getRanges();
1173 if ( !editable
|| !ranges
|| ranges
.length
=== 0 ) {
1177 var docFragment
= createDocumentFragmentFromRanges( ranges
, editable
);
1179 return toString
? docFragment
.getHtml() : docFragment
;
1183 * Gets the selected HTML (it is returned as a {@link CKEDITOR.dom.documentFragment document fragment}
1184 * or a string) and removes the selected part of the DOM. This method is designed to work as the user would
1185 * expect the cut and delete functionalities to work.
1189 * * the {@link #getSelectedHtml} method,
1190 * * the {@link CKEDITOR.editable#extractHtmlFromRange} method.
1193 * @param {Boolean} [toString] If `true`, then stringified HTML will be returned.
1194 * @param {Boolean} [removeEmptyBlock=false] Default `false` means that the function will keep an empty block (if the
1195 * entire content was removed) or it will create it (if a block element was removed) and set the selection in that block.
1196 * If `true`, the empty block will be removed or not created. In this case the function will not handle the selection.
1197 * @returns {CKEDITOR.dom.documentFragment/String/null}
1199 extractSelectedHtml: function( toString
, removeEmptyBlock
) {
1200 var editable
= this.editable(),
1201 ranges
= this.getSelection().getRanges();
1203 if ( !editable
|| ranges
.length
=== 0 ) {
1207 var range
= ranges
[ 0 ],
1208 docFragment
= editable
.extractHtmlFromRange( range
, removeEmptyBlock
);
1210 if ( !removeEmptyBlock
) {
1211 this.getSelection().selectRanges( [ range
] );
1214 return toString
? docFragment
.getHtml() : docFragment
;
1218 * Moves the selection focus to the editing area space in the editor.
1221 this.fire( 'beforeFocus' );
1225 * Checks whether the current editor content contains changes when
1226 * compared to the content loaded into the editor at startup, or to
1227 * the content available in the editor when {@link #resetDirty}
1230 * function beforeUnload( evt ) {
1231 * if ( CKEDITOR.instances.editor1.checkDirty() )
1232 * return evt.returnValue = "You will lose the changes made in the editor.";
1235 * if ( window.addEventListener )
1236 * window.addEventListener( 'beforeunload', beforeUnload, false );
1238 * window.attachEvent( 'onbeforeunload', beforeUnload );
1240 * @returns {Boolean} `true` if the content contains changes.
1242 checkDirty: function() {
1243 return this.status
== 'ready' && this._
.previousValue
!== this.getSnapshot();
1247 * Resets the "dirty state" of the editor so subsequent calls to
1248 * {@link #checkDirty} will return `false` if the user will not
1249 * have made further changes to the content.
1251 * alert( editor.checkDirty() ); // e.g. true
1252 * editor.resetDirty();
1253 * alert( editor.checkDirty() ); // false
1255 resetDirty: function() {
1256 this._
.previousValue
= this.getSnapshot();
1260 * Updates the `<textarea>` element that was replaced by the editor with
1261 * the current data available in the editor.
1263 * **Note:** This method will only affect those editor instances created
1264 * with the {@link CKEDITOR#ELEMENT_MODE_REPLACE} element mode or inline instances
1265 * bound to `<textarea>` elements.
1267 * CKEDITOR.instances.editor1.updateElement();
1268 * alert( document.getElementById( 'editor1' ).value ); // The current editor data.
1270 * @see CKEDITOR.editor#element
1272 updateElement: function() {
1273 return updateEditorElement
.call( this );
1277 * Assigns keystrokes associated with editor commands.
1279 * editor.setKeystroke( CKEDITOR.CTRL + 115, 'save' ); // Assigned Ctrl+S to the "save" command.
1280 * editor.setKeystroke( CKEDITOR.CTRL + 115, false ); // Disabled Ctrl+S keystroke assignment.
1281 * editor.setKeystroke( [
1282 * [ CKEDITOR.ALT + 122, false ],
1283 * [ CKEDITOR.CTRL + 121, 'link' ],
1284 * [ CKEDITOR.SHIFT + 120, 'bold' ]
1287 * This method may be used in the following cases:
1289 * * By plugins (like `link` or `basicstyles`) to set their keystrokes when plugins are being loaded.
1290 * * During the runtime to modify existing keystrokes.
1292 * The editor handles keystroke configuration in the following order:
1294 * 1. Plugins use this method to define default keystrokes.
1295 * 2. Editor extends default keystrokes with {@link CKEDITOR.config#keystrokes}.
1296 * 3. Editor blocks keystrokes defined in {@link CKEDITOR.config#blockedKeystrokes}.
1298 * You can then set new keystrokes using this method during the runtime.
1301 * @param {Number/Array} keystroke A keystroke or an array of keystroke definitions.
1302 * @param {String/Boolean} [behavior] A command to be executed on the keystroke.
1304 setKeystroke: function() {
1305 var keystrokes
= this.keystrokeHandler
.keystrokes
,
1306 newKeystrokes
= CKEDITOR
.tools
.isArray( arguments
[ 0 ] ) ? arguments
[ 0 ] : [ [].slice
.call( arguments
, 0 ) ],
1307 keystroke
, behavior
;
1309 for ( var i
= newKeystrokes
.length
; i
--; ) {
1310 keystroke
= newKeystrokes
[ i
];
1313 // It may be a pair of: [ key, command ]
1314 if ( CKEDITOR
.tools
.isArray( keystroke
) ) {
1315 behavior
= keystroke
[ 1 ];
1316 keystroke
= keystroke
[ 0 ];
1320 keystrokes
[ keystroke
] = behavior
;
1322 delete keystrokes
[ keystroke
];
1327 * Shorthand for {@link CKEDITOR.filter#addFeature}.
1330 * @param {CKEDITOR.feature} feature See {@link CKEDITOR.filter#addFeature}.
1331 * @returns {Boolean} See {@link CKEDITOR.filter#addFeature}.
1333 addFeature: function( feature
) {
1334 return this.filter
.addFeature( feature
);
1338 * Sets the active filter ({@link #activeFilter}). Fires the {@link #activeFilterChange} event.
1340 * // Set active filter which allows only 4 elements.
1341 * // Buttons like Bold, Italic will be disabled.
1342 * var filter = new CKEDITOR.filter( 'p strong em br' );
1343 * editor.setActiveFilter( filter );
1345 * Setting a new filter will also change the {@link #setActiveEnterMode active Enter modes} to the first values
1346 * allowed by the new filter (see {@link CKEDITOR.filter#getAllowedEnterMode}).
1349 * @param {CKEDITOR.filter} filter Filter instance or a falsy value (e.g. `null`) to reset to the default one.
1351 setActiveFilter: function( filter
) {
1353 filter
= this.filter
;
1355 if ( this.activeFilter
!== filter
) {
1356 this.activeFilter
= filter
;
1357 this.fire( 'activeFilterChange' );
1359 // Reset active filter to the main one - it resets enter modes, too.
1360 if ( filter
=== this.filter
)
1361 this.setActiveEnterMode( null, null );
1363 this.setActiveEnterMode(
1364 filter
.getAllowedEnterMode( this.enterMode
),
1365 filter
.getAllowedEnterMode( this.shiftEnterMode
, true )
1371 * Sets the active Enter modes: ({@link #enterMode} and {@link #shiftEnterMode}).
1372 * Fires the {@link #activeEnterModeChange} event.
1374 * Prior to CKEditor 4.3 Enter modes were static and it was enough to check {@link CKEDITOR.config#enterMode}
1375 * and {@link CKEDITOR.config#shiftEnterMode} when implementing a feature which should depend on the Enter modes.
1376 * Since CKEditor 4.3 these options are source of initial:
1378 * * static {@link #enterMode} and {@link #shiftEnterMode} values,
1379 * * dynamic {@link #activeEnterMode} and {@link #activeShiftEnterMode} values.
1381 * However, the dynamic Enter modes can be changed during runtime by using this method, to reflect the selection context.
1382 * For example, if selection is moved to the {@link CKEDITOR.plugins.widget widget}'s nested editable which
1383 * is a {@link #blockless blockless one}, then the active Enter modes should be changed to {@link CKEDITOR#ENTER_BR}
1384 * (in this case [Widget System](#!/guide/dev_widgets) takes care of that).
1386 * **Note:** This method should not be used to configure the editor – use {@link CKEDITOR.config#enterMode} and
1387 * {@link CKEDITOR.config#shiftEnterMode} instead. This method should only be used to dynamically change
1388 * Enter modes during runtime based on selection changes.
1389 * Keep in mind that changed Enter mode may be overwritten by another plugin/feature when it decided that
1390 * the changed context requires this.
1392 * **Note:** In case of blockless editor (inline editor based on an element which cannot contain block elements
1393 * — see {@link CKEDITOR.editor#blockless}) only {@link CKEDITOR#ENTER_BR} is a valid Enter mode. Therefore
1394 * this method will not allow to set other values.
1396 * **Note:** Changing the {@link #activeFilter active filter} may cause the Enter mode to change if default Enter modes
1397 * are not allowed by the new filter.
1400 * @param {Number} enterMode One of {@link CKEDITOR#ENTER_P}, {@link CKEDITOR#ENTER_DIV}, {@link CKEDITOR#ENTER_BR}.
1401 * Pass falsy value (e.g. `null`) to reset the Enter mode to the default value ({@link #enterMode} and/or {@link #shiftEnterMode}).
1402 * @param {Number} shiftEnterMode See the `enterMode` argument.
1404 setActiveEnterMode: function( enterMode
, shiftEnterMode
) {
1405 // Validate passed modes or use default ones (validated on init).
1406 enterMode
= enterMode
? validateEnterMode( this, enterMode
) : this.enterMode
;
1407 shiftEnterMode
= shiftEnterMode
? validateEnterMode( this, shiftEnterMode
) : this.shiftEnterMode
;
1409 if ( this.activeEnterMode
!= enterMode
|| this.activeShiftEnterMode
!= shiftEnterMode
) {
1410 this.activeEnterMode
= enterMode
;
1411 this.activeShiftEnterMode
= shiftEnterMode
;
1412 this.fire( 'activeEnterModeChange' );
1417 * Shows a notification to the user.
1419 * If the [Notification](http://ckeditor.com/addons/notification) plugin is not enabled, this function shows
1420 * a normal alert with the given `message`. The `type` and `progressOrDuration` parameters are supported
1421 * only by the Notification plugin.
1423 * If the Notification plugin is enabled, this method creates and shows a new notification.
1424 * By default the notification is shown over the editor content, in the viewport if it is possible.
1426 * See {@link CKEDITOR.plugins.notification}.
1429 * @member CKEDITOR.editor
1430 * @param {String} message The message displayed in the notification.
1431 * @param {String} [type='info'] The type of the notification. Can be `'info'`, `'warning'`, `'success'` or `'progress'`.
1432 * @param {Number} [progressOrDuration] If the type is `progress`, the third parameter may be a progress from `0` to `1`
1433 * (defaults to `0`). Otherwise the third parameter may be a notification duration denoting after how many milliseconds
1434 * the notification should be closed automatically. `0` means that the notification will not close automatically and the user
1435 * needs to close it manually. See {@link CKEDITOR.plugins.notification#duration}.
1436 * Note that `warning` notifications will not be closed automatically.
1437 * @returns {CKEDITOR.plugins.notification} Created and shown notification.
1439 showNotification: function( message
) {
1440 alert( message
); // jshint ignore:line
1446 * The editor has no associated element.
1449 * @property {Number} [=0]
1452 CKEDITOR
.ELEMENT_MODE_NONE
= 0;
1455 * The element is to be replaced by the editor instance.
1458 * @property {Number} [=1]
1461 CKEDITOR
.ELEMENT_MODE_REPLACE
= 1;
1464 * The editor is to be created inside the element.
1467 * @property {Number} [=2]
1470 CKEDITOR
.ELEMENT_MODE_APPENDTO
= 2;
1473 * The editor is to be attached to the element, using it as the editing block.
1476 * @property {Number} [=3]
1479 CKEDITOR
.ELEMENT_MODE_INLINE
= 3;
1482 * Whether to escape HTML when the editor updates the original input element.
1484 * config.htmlEncodeOutput = true;
1487 * @cfg {Boolean} [htmlEncodeOutput=false]
1488 * @member CKEDITOR.config
1492 * If `true`, makes the editor start in read-only state. Otherwise, it will check
1493 * if the linked `<textarea>` element has the `disabled` attribute.
1495 * Read more in the [documentation](#!/guide/dev_readonly)
1496 * and see the [SDK sample](http://sdk.ckeditor.com/samples/readonly.html).
1498 * config.readOnly = true;
1501 * @cfg {Boolean} [readOnly=false]
1502 * @member CKEDITOR.config
1503 * @see CKEDITOR.editor#setReadOnly
1507 * Whether an editable element should have focus when the editor is loading for the first time.
1509 * config.startupFocus = true;
1511 * @cfg {Boolean} [startupFocus=false]
1512 * @member CKEDITOR.config
1516 * Customizes the {@link CKEDITOR.editor#title human-readable title} of this editor. This title is displayed in
1517 * tooltips and impacts various [accessibility aspects](#!/guide/dev_a11y-section-announcing-the-editor-on-the-page),
1518 * e.g. it is commonly used by screen readers for distinguishing editor instances and for navigation.
1519 * Accepted values are a string or `false`.
1521 * **Note:** When `config.title` is set globally, the same value will be applied to all editor instances
1522 * loaded with this config. This may adversely affect accessibility as screen reader users will be unable
1523 * to distinguish particular editor instances and navigate between them.
1525 * **Note:** Setting `config.title = false` may also impair accessibility in a similar way.
1527 * **Note:** Please do not confuse this property with {@link CKEDITOR.editor#name}
1528 * which identifies the instance in the {@link CKEDITOR#instances} literal.
1530 * // Sets the title to 'My WYSIWYG editor.'. The original title of the element (if it exists)
1531 * // will be restored once the editor instance is destroyed.
1532 * config.title = 'My WYSIWYG editor.';
1534 * // Do not touch the title. If the element already has a title, it remains unchanged.
1535 * // Also if no `title` attribute exists, nothing new will be added.
1536 * config.title = false;
1540 * * CKEDITOR.editor#name
1541 * * CKEDITOR.editor#title
1544 * @cfg {String/Boolean} [title=based on editor.name]
1545 * @member CKEDITOR.config
1549 * Sets listeners on editor events.
1551 * **Note:** This property can only be set in the `config` object passed directly
1552 * to {@link CKEDITOR#replace}, {@link CKEDITOR#inline}, and other creators.
1554 * CKEDITOR.replace( 'editor1', {
1556 * instanceReady: function() {
1557 * alert( this.name ); // 'editor1'
1567 * @member CKEDITOR.config
1571 * The outermost element in the DOM tree in which the editable element resides. It is provided
1572 * by a specific editor creator after the editor UI is created and is not intended to
1575 * var editor = CKEDITOR.instances.editor1;
1576 * alert( editor.container.getName() ); // 'span'
1579 * @property {CKEDITOR.dom.element} container
1583 * The document that stores the editor content.
1585 * * For the classic (`iframe`-based) editor it is equal to the document inside the
1586 * `iframe` containing the editable element.
1587 * * For the inline editor it is equal to {@link CKEDITOR#document}.
1589 * The document object is available after the {@link #contentDom} event is fired
1590 * and may be invalidated when the {@link #contentDomUnload} event is fired
1591 * (classic editor only).
1593 * editor.on( 'contentDom', function() {
1594 * console.log( editor.document );
1598 * @property {CKEDITOR.dom.document} document
1602 * The window instance related to the {@link #document} property.
1604 * It is always equal to the `editor.document.getWindow()`.
1606 * See the {@link #document} property documentation.
1609 * @property {CKEDITOR.dom.window} window
1613 * The main filter instance used for input data filtering, data
1614 * transformations, and activation of features.
1616 * It points to a {@link CKEDITOR.filter} instance set up based on
1617 * editor configuration.
1621 * @property {CKEDITOR.filter} filter
1625 * The active filter instance which should be used in the current context (location selection).
1626 * This instance will be used to make a decision which commands, buttons and other
1627 * {@link CKEDITOR.feature features} can be enabled.
1629 * By default it equals the {@link #filter} and it can be changed by the {@link #setActiveFilter} method.
1631 * editor.on( 'activeFilterChange', function() {
1632 * if ( editor.activeFilter.check( 'cite' ) )
1633 * // Do something when <cite> was enabled - e.g. enable a button.
1635 * // Otherwise do something else.
1638 * See also the {@link #setActiveEnterMode} method for an explanation of dynamic settings.
1642 * @property {CKEDITOR.filter} activeFilter
1646 * The main (static) Enter mode which is a validated version of the {@link CKEDITOR.config#enterMode} setting.
1647 * Currently only one rule exists — {@link #blockless blockless editors} may have
1648 * Enter modes set only to {@link CKEDITOR#ENTER_BR}.
1652 * @property {Number} enterMode
1656 * See the {@link #enterMode} property.
1660 * @property {Number} shiftEnterMode
1664 * The dynamic Enter mode which should be used in the current context (selection location).
1665 * By default it equals the {@link #enterMode} and it can be changed by the {@link #setActiveEnterMode} method.
1667 * See also the {@link #setActiveEnterMode} method for an explanation of dynamic settings.
1671 * @property {Number} activeEnterMode
1675 * See the {@link #activeEnterMode} property.
1679 * @property {Number} activeShiftEnterMode
1683 * Event fired by the {@link #setActiveFilter} method when the {@link #activeFilter} is changed.
1686 * @event activeFilterChange
1690 * Event fired by the {@link #setActiveEnterMode} method when any of the active Enter modes is changed.
1691 * See also the {@link #activeEnterMode} and {@link #activeShiftEnterMode} properties.
1694 * @event activeEnterModeChange
1698 * Event fired when a CKEDITOR instance is created, but still before initializing it.
1699 * To interact with a fully initialized instance, use the
1700 * {@link CKEDITOR#instanceReady} event instead.
1702 * @event instanceCreated
1704 * @param {CKEDITOR.editor} editor The editor instance that has been created.
1708 * Event fired when CKEDITOR instance's components (configuration, languages and plugins) are fully
1709 * loaded and initialized. However, the editor will be fully ready for interaction
1710 * on {@link CKEDITOR#instanceReady}.
1712 * @event instanceLoaded
1714 * @param {CKEDITOR.editor} editor This editor instance that has been loaded.
1718 * Event fired when a CKEDITOR instance is destroyed.
1720 * @event instanceDestroyed
1722 * @param {CKEDITOR.editor} editor The editor instance that has been destroyed.
1726 * Event fired when a CKEDITOR instance is created, fully initialized and ready for interaction.
1728 * @event instanceReady
1730 * @param {CKEDITOR.editor} editor The editor instance that has been created.
1734 * Event fired when the language is loaded into the editor instance.
1738 * @param {CKEDITOR.editor} editor This editor instance.
1742 * Event fired when all plugins are loaded and initialized into the editor instance.
1744 * @event pluginsLoaded
1745 * @param {CKEDITOR.editor} editor This editor instance.
1749 * Event fired when the styles set is loaded. During the editor initialization
1750 * phase the {@link #getStylesSet} method returns only styles that
1751 * are already loaded, which may not include e.g. styles parsed
1752 * by the `stylesheetparser` plugin. Thus, to be notified when all
1753 * styles are ready, you can listen on this event.
1757 * @param {CKEDITOR.editor} editor This editor instance.
1758 * @param {Array} styles An array of styles definitions.
1762 * Event fired before the command execution when {@link #execCommand} is called.
1764 * @event beforeCommandExec
1765 * @param {CKEDITOR.editor} editor This editor instance.
1767 * @param {String} data.name The command name.
1768 * @param {Object} data.commandData The data to be sent to the command. This
1769 * can be manipulated by the event listener.
1770 * @param {CKEDITOR.command} data.command The command itself.
1774 * Event fired after the command execution when {@link #execCommand} is called.
1776 * @event afterCommandExec
1777 * @param {CKEDITOR.editor} editor This editor instance.
1779 * @param {String} data.name The command name.
1780 * @param {Object} data.commandData The data sent to the command.
1781 * @param {CKEDITOR.command} data.command The command itself.
1782 * @param {Object} data.returnValue The value returned by the command execution.
1786 * Event fired when a custom configuration file is loaded, before the final
1787 * configuration initialization.
1789 * Custom configuration files can be loaded thorugh the
1790 * {@link CKEDITOR.config#customConfig} setting. Several files can be loaded
1791 * by changing this setting.
1793 * @event customConfigLoaded
1794 * @param {CKEDITOR.editor} editor This editor instance.
1798 * Event fired once the editor configuration is ready (loaded and processed).
1800 * @event configLoaded
1801 * @param {CKEDITOR.editor} editor This editor instance.
1805 * Event fired when this editor instance is destroyed. The editor at this
1806 * point is not usable and this event should be used to perform the clean-up
1810 * @param {CKEDITOR.editor} editor This editor instance.
1814 * Internal event to get the current data.
1816 * @event beforeGetData
1817 * @param {CKEDITOR.editor} editor This editor instance.
1821 * Internal event to perform the {@link #method-getSnapshot} call.
1823 * @event getSnapshot
1824 * @param {CKEDITOR.editor} editor This editor instance.
1828 * Internal event to perform the {@link #method-loadSnapshot} call.
1830 * @event loadSnapshot
1831 * @param {CKEDITOR.editor} editor This editor instance.
1832 * @param {String} data The data that will be used.
1836 * Event fired before the {@link #method-getData} call returns, allowing for additional manipulation.
1839 * @param {CKEDITOR.editor} editor This editor instance.
1841 * @param {String} data.dataValue The data that will be returned.
1845 * Event fired before the {@link #method-setData} call is executed, allowing for additional manipulation.
1848 * @param {CKEDITOR.editor} editor This editor instance.
1850 * @param {String} data.dataValue The data that will be used.
1854 * Event fired at the end of the {@link #method-setData} call execution. Usually it is better to use the
1855 * {@link #dataReady} event.
1857 * @event afterSetData
1858 * @param {CKEDITOR.editor} editor This editor instance.
1860 * @param {String} data.dataValue The data that has been set.
1864 * Event fired as an indicator of the editor data loading. It may be the result of
1865 * calling {@link #method-setData} explicitly or an internal
1866 * editor function, like the editor editing mode switching (move to Source and back).
1869 * @param {CKEDITOR.editor} editor This editor instance.
1873 * Event fired when the CKEDITOR instance is completely created, fully initialized
1874 * and ready for interaction.
1876 * @event instanceReady
1877 * @param {CKEDITOR.editor} editor This editor instance.
1881 * Event fired when editor components (configuration, languages and plugins) are fully
1882 * loaded and initialized. However, the editor will be fully ready to for interaction
1883 * on {@link #instanceReady}.
1886 * @param {CKEDITOR.editor} editor This editor instance.
1890 * Event fired by the {@link #method-insertHtml} method. See the method documentation for more information
1891 * about how this event can be used.
1894 * @param {CKEDITOR.editor} editor This editor instance.
1896 * @param {String} data.mode The mode in which the data is inserted (see {@link #method-insertHtml}).
1897 * @param {String} data.dataValue The HTML code to insert.
1898 * @param {CKEDITOR.dom.range} [data.range] See {@link #method-insertHtml}'s `range` parameter.
1902 * Event fired by the {@link #method-insertText} method. See the method documentation for more information
1903 * about how this event can be used.
1906 * @param {CKEDITOR.editor} editor This editor instance.
1907 * @param {String} data The text to insert.
1911 * Event fired by the {@link #method-insertElement} method. See the method documentation for more information
1912 * about how this event can be used.
1914 * @event insertElement
1915 * @param {CKEDITOR.editor} editor This editor instance.
1916 * @param {CKEDITOR.dom.element} data The element to insert.
1920 * Event fired after data insertion using the {@link #method-insertHtml}, {@link CKEDITOR.editable#insertHtml},
1921 * or {@link CKEDITOR.editable#insertHtmlIntoRange} methods.
1924 * @event afterInsertHtml
1926 * @param {CKEDITOR.dom.range} [data.intoRange] If set, the HTML was not inserted into the current selection, but into
1927 * the specified range. This property is set if the {@link CKEDITOR.editable#insertHtmlIntoRange} method was used,
1928 * but not if for the {@link CKEDITOR.editable#insertHtml} method.
1932 * Event fired after the {@link #property-readOnly} property changes.
1936 * @param {CKEDITOR.editor} editor This editor instance.
1940 * Event fired when a UI template is added to the editor instance. It makes
1941 * it possible to bring customizations to the template source.
1944 * @param {CKEDITOR.editor} editor This editor instance.
1946 * @param {String} data.name The template name.
1947 * @param {String} data.source The source data for this template.
1951 * Event fired when the editor content (its DOM structure) is ready.
1952 * It is similar to the native `DOMContentLoaded` event, but it applies to
1953 * the editor content. It is also the first event fired after
1954 * the {@link CKEDITOR.editable} is initialized.
1956 * This event is particularly important for classic (`iframe`-based)
1957 * editor, because on editor initialization and every time the data are set
1958 * (by {@link CKEDITOR.editor#method-setData}) content DOM structure
1959 * is rebuilt. Thus, e.g. you need to attach DOM event listeners
1960 * on editable one more time.
1962 * For inline editor this event is fired only once — when the
1963 * editor is initialized for the first time. This is because setting
1964 * editor content does not cause editable destruction and creation.
1966 * The {@link #contentDom} event goes along with {@link #contentDomUnload}
1967 * which is fired before the content DOM structure is destroyed. This is the
1968 * right moment to detach content DOM event listener. Otherwise
1969 * browsers like IE or Opera may throw exceptions when accessing
1970 * elements from the detached document.
1972 * **Note:** {@link CKEDITOR.editable#attachListener} is a convenient
1973 * way to attach listeners that will be detached on {@link #contentDomUnload}.
1975 * editor.on( 'contentDom', function() {
1976 * var editable = editor.editable();
1978 * editable.attachListener( editable, 'click', function() {
1979 * console.log( 'The editable was clicked.' );
1984 * @param {CKEDITOR.editor} editor This editor instance.
1988 * Event fired before the content DOM structure is destroyed.
1989 * See {@link #contentDom} documentation for more details.
1991 * @event contentDomUnload
1992 * @param {CKEDITOR.editor} editor This editor instance.
1996 * Event fired when the content DOM changes and some of the references as well as
1997 * the native DOM event listeners could be lost.
1998 * This event is useful when it is important to keep track of references
1999 * to elements in the editable content from code.
2002 * @event contentDomInvalidated
2003 * @param {CKEDITOR.editor} editor This editor instance.