{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-core/src/command.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/context.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/commandcollection.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/editingkeystrokehandler.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/editor/editor.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/editor/editorui.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/editor/utils/attachtoform.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/editor/utils/dataapimixin.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/editor/utils/elementapimixin.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/editor/utils/securesourceelement.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/index.js","webpack:///./node_modules/@ckeditor/ckeditor5-core/src/contextplugin.js"],"names":["Command","editor","this","set","undefined","_disableStack","Set","decorate","listenTo","model","document","refresh","on","evt","isEnabled","stop","priority","name","value","forceDisabled","clearForceDisabled","id","add","size","forceDisable","delete","off","stopListening","return","mix","ObservableMixin","Context","config","Config","constructor","defaultConfig","availablePlugins","builtinPlugins","define","plugins","PluginCollection","languageConfig","get","locale","Locale","uiLanguage","ui","contentLanguage","t","editors","Collection","_contextOwner","substitutePlugins","concat","Plugin","CKEditorError","isContextPlugin","init","Promise","all","Array","from","destroy","then","isContextOwner","has","remove","resolve","result","names","includes","context","initPlugins","CommandCollection","_commands","Map","commandName","command","args","execute","keys","values","Symbol","iterator","commands","EditingKeystrokeHandler","keystroke","callback","options","evtData","cancel","KeystrokeHandler","Editor","_context","language","_addEditor","_getEditorConfig","once","state","Model","stylesProcessor","StylesProcessor","data","DataController","editing","EditingController","view","bind","to","conversion","Conversion","downcastDispatcher","upcastDispatcher","addAlias","keystrokes","removePlugins","extraPlugins","readyPromise","fire","_removeEditor","err","rethrowUnexpectedError","focus","EditorUI","componentFactory","ComponentFactory","focusTracker","FocusTracker","_editableElementsMap","update","domElement","ckeditorInstance","rootName","console","warn","editorUI","EmitterMixin","attachToForm","isFunction","updateSourceElement","sourceElement","tagName","toLowerCase","form","originalSubmit","onSubmit","submit","apply","addEventListener","removeEventListener","DataApiMixin","setData","getData","ElementApiMixin","setDataInElement","secureSourceElement","icons","check","eraser","lowVision","image","alignBottom","alignMiddle","alignTop","alignLeft","alignCenter","alignRight","alignJustify","objectLeft","objectCenter","objectRight","objectFullWidth","objectSizeFull","objectSizeLarge","objectSizeSmall","objectSizeMedium","pencil","pilcrow","quote","threeVerticalDots","ContextPlugin"],"mappings":"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","file":"js/chunk-vendors~1e9e7c11.f098b778.js","sourcesContent":["/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/command\n */\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The base class for CKEditor commands.\n *\n * Commands are the main way to manipulate editor contents and state. They are mostly used by UI elements (or by other\n * commands) to make changes in the model. Commands are available in every part of code that has access to\n * the {@link module:core/editor/editor~Editor editor} instance.\n *\n * Instances of registered commands can be retrieved from {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n * The easiest way to execute a command is through {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n *\n * By default commands are disabled when the editor is in {@link module:core/editor/editor~Editor#isReadOnly read-only} mode.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Command {\n\t/**\n\t * Creates a new `Command` instance.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor Editor on which this command will be used.\n\t */\n\tconstructor( editor ) {\n\t\t/**\n\t\t * The editor on which this command will be used.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\n\t\t/**\n\t\t * The value of the command. A concrete command class should define what it represents for it.\n\t\t *\n\t\t * For example, the `'bold'` command's value indicates whether the selection starts in a bolded text.\n\t\t * And the value of the `'link'` command may be an object with links details.\n\t\t *\n\t\t * It is possible for a command to have no value (e.g. for stateless actions such as `'uploadImage'`).\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member #value\n\t\t */\n\t\tthis.set( 'value', undefined );\n\n\t\t/**\n\t\t * Flag indicating whether a command is enabled or disabled.\n\t\t * A disabled command will do nothing when executed.\n\t\t *\n\t\t * A concrete command class should control this value by overriding the {@link #refresh `refresh()`} method.\n\t\t *\n\t\t * It is possible to disable a command from \"outside\". For instance, in your integration you may want to disable\n\t\t * a certain set of commands for the time being. To do that, you can use the fact that `isEnabled` is observable\n\t\t * and it fires the `set:isEnabled` event every time anyone tries to modify its value:\n\t\t *\n\t\t *\t\tfunction disableCommand( cmd ) {\n\t\t *\t\t\tcmd.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t *\n\t\t *\t\t\tcmd.isEnabled = false;\n\t\t *\n\t\t *\t\t\t// Make it possible to enable the command again.\n\t\t *\t\t\treturn () => {\n\t\t *\t\t\t\tcmd.off( 'set:isEnabled', forceDisable );\n\t\t *\t\t\t\tcmd.refresh();\n\t\t *\t\t\t};\n\t\t *\n\t\t *\t\t\tfunction forceDisable( evt ) {\n\t\t *\t\t\t\tevt.return = false;\n\t\t *\t\t\t\tevt.stop();\n\t\t *\t\t\t}\n\t\t *\t\t}\n\t\t *\n\t\t *\t\t// Usage:\n\t\t *\n\t\t *\t\t// Disabling the command.\n\t\t *\t\tconst enableBold = disableCommand( editor.commands.get( 'bold' ) );\n\t\t *\n\t\t *\t\t// Enabling the command again.\n\t\t *\t\tenableBold();\n\t\t *\n\t\t * @observable\n\t\t * @readonly\n\t\t * @member {Boolean} #isEnabled\n\t\t */\n\t\tthis.set( 'isEnabled', false );\n\n\t\t/**\n\t\t * Holds identifiers for {@link #forceDisabled} mechanism.\n\t\t *\n\t\t * @type {Set.}\n\t\t * @private\n\t\t */\n\t\tthis._disableStack = new Set();\n\n\t\tthis.decorate( 'execute' );\n\n\t\t// By default every command is refreshed when changes are applied to the model.\n\t\tthis.listenTo( this.editor.model.document, 'change', () => {\n\t\t\tthis.refresh();\n\t\t} );\n\n\t\tthis.on( 'execute', evt => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tevt.stop();\n\t\t\t}\n\t\t}, { priority: 'high' } );\n\n\t\t// By default commands are disabled when the editor is in read-only mode.\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, value ) => {\n\t\t\tif ( value ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Refreshes the command. The command should update its {@link #isEnabled} and {@link #value} properties\n\t * in this method.\n\t *\n\t * This method is automatically called when\n\t * {@link module:engine/model/document~Document#event:change any changes are applied to the document}.\n\t */\n\trefresh() {\n\t\tthis.isEnabled = true;\n\t}\n\n\t/**\n\t * Disables the command.\n\t *\n\t * Command may be disabled by multiple features or algorithms (at once). When disabling a command, unique id should be passed\n\t * (e.g. feature name). The same identifier should be used when {@link #clearForceDisabled enabling back} the command.\n\t * The command becomes enabled only after all features {@link #clearForceDisabled enabled it back}.\n\t *\n\t * Disabling and enabling a command:\n\t *\n\t *\t\tcommand.isEnabled; // -> true\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Command disabled by multiple features:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'OtherFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> false\n\t *\t\tcommand.clearForceDisabled( 'OtherFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * Multiple disabling with the same identifier is redundant:\n\t *\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.forceDisabled( 'MyFeature' );\n\t *\t\tcommand.clearForceDisabled( 'MyFeature' );\n\t *\t\tcommand.isEnabled; // -> true\n\t *\n\t * **Note:** some commands or algorithms may have more complex logic when it comes to enabling or disabling certain commands,\n\t * so the command might be still disabled after {@link #clearForceDisabled} was used.\n\t *\n\t * @param {String} id Unique identifier for disabling. Use the same id when {@link #clearForceDisabled enabling back} the command.\n\t */\n\tforceDisabled( id ) {\n\t\tthis._disableStack.add( id );\n\n\t\tif ( this._disableStack.size == 1 ) {\n\t\t\tthis.on( 'set:isEnabled', forceDisable, { priority: 'highest' } );\n\t\t\tthis.isEnabled = false;\n\t\t}\n\t}\n\n\t/**\n\t * Clears forced disable previously set through {@link #forceDisabled}. See {@link #forceDisabled}.\n\t *\n\t * @param {String} id Unique identifier, equal to the one passed in {@link #forceDisabled} call.\n\t */\n\tclearForceDisabled( id ) {\n\t\tthis._disableStack.delete( id );\n\n\t\tif ( this._disableStack.size == 0 ) {\n\t\t\tthis.off( 'set:isEnabled', forceDisable );\n\t\t\tthis.refresh();\n\t\t}\n\t}\n\n\t/**\n\t * Executes the command.\n\t *\n\t * A command may accept parameters. They will be passed from {@link module:core/editor/editor~Editor#execute `editor.execute()`}\n\t * to the command.\n\t *\n\t * The `execute()` method will automatically abort when the command is disabled ({@link #isEnabled} is `false`).\n\t * This behavior is implemented by a high priority listener to the {@link #event:execute} event.\n\t *\n\t * In order to see how to disable a command from \"outside\" see the {@link #isEnabled} documentation.\n\t *\n\t * This method may return a value, which would be forwarded all the way down to the\n\t * {@link module:core/editor/editor~Editor#execute `editor.execute()`}.\n\t *\n\t * @fires execute\n\t */\n\texecute() {}\n\n\t/**\n\t * Destroys the command.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Event fired by the {@link #execute} method. The command action is a listener to this event so it's\n\t * possible to change/cancel the behavior of the command by listening to this event.\n\t *\n\t * See {@link module:utils/observablemixin~ObservableMixin#decorate} for more information and samples.\n\t *\n\t * **Note:** This event is fired even if command is disabled. However, it is automatically blocked\n\t * by a high priority listener in order to prevent command execution.\n\t *\n\t * @event execute\n\t */\n}\n\nmix( Command, ObservableMixin );\n\n// Helper function that forces command to be disabled.\nfunction forceDisable( evt ) {\n\tevt.return = false;\n\tevt.stop();\n}\n","/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/context\n */\n\nimport Config from '@ckeditor/ckeditor5-utils/src/config';\nimport Collection from '@ckeditor/ckeditor5-utils/src/collection';\nimport PluginCollection from './plugincollection';\nimport Locale from '@ckeditor/ckeditor5-utils/src/locale';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Provides a common, higher-level environment for solutions that use multiple {@link module:core/editor/editor~Editor editors}\n * or plugins that work outside the editor. Use it instead of {@link module:core/editor/editor~Editor.create `Editor.create()`}\n * in advanced application integrations.\n *\n * All configuration options passed to a context will be used as default options for editor instances initialized in that context.\n *\n * {@link module:core/contextplugin~ContextPlugin Context plugins} passed to a context instance will be shared among all\n * editor instances initialized in this context. These will be the same plugin instances for all the editors.\n *\n * **Note:** The context can only be initialized with {@link module:core/contextplugin~ContextPlugin context plugins}\n * (e.g. [comments](https://ckeditor.com/collaboration/comments/)). Regular {@link module:core/plugin~Plugin plugins} require an\n * editor instance to work and cannot be added to a context.\n *\n * **Note:** You can add a context plugin to an editor instance, though.\n *\n * If you are using multiple editor instances on one page and use any context plugins, create a context to share the configuration and\n * plugins among these editors. Some plugins will use the information about all existing editors to better integrate between them.\n *\n * If you are using plugins that do not require an editor to work (e.g. [comments](https://ckeditor.com/collaboration/comments/)),\n * enable and configure them using the context.\n *\n * If you are using only a single editor on each page, use {@link module:core/editor/editor~Editor.create `Editor.create()`} instead.\n * In such case, a context instance will be created by the editor instance in a transparent way.\n *\n * See {@link module:core/context~Context.create `Context.create()`} for usage examples.\n */\nexport default class Context {\n\t/**\n\t * Creates a context instance with a given configuration.\n\t *\n\t * Usually not to be used directly. See the static {@link module:core/context~Context.create `create()`} method.\n\t *\n\t * @param {Object} [config={}] The context configuration.\n\t */\n\tconstructor( config ) {\n\t\t/**\n\t\t * Stores all the configurations specific to this context instance.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:utils/config~Config}\n\t\t */\n\t\tthis.config = new Config( config, this.constructor.defaultConfig );\n\n\t\tconst availablePlugins = this.constructor.builtinPlugins;\n\n\t\tthis.config.define( 'plugins', availablePlugins );\n\n\t\t/**\n\t\t * The plugins loaded and in use by this context instance.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:core/plugincollection~PluginCollection}\n\t\t */\n\t\tthis.plugins = new PluginCollection( this, availablePlugins );\n\n\t\tconst languageConfig = this.config.get( 'language' ) || {};\n\n\t\t/**\n\t\t * @readonly\n\t\t * @type {module:utils/locale~Locale}\n\t\t */\n\t\tthis.locale = new Locale( {\n\t\t\tuiLanguage: typeof languageConfig === 'string' ? languageConfig : languageConfig.ui,\n\t\t\tcontentLanguage: this.config.get( 'language.content' )\n\t\t} );\n\n\t\t/**\n\t\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t\t *\n\t\t * @see module:utils/locale~Locale#t\n\t\t * @method #t\n\t\t */\n\t\tthis.t = this.locale.t;\n\n\t\t/**\n\t\t * A list of editors that this context instance is injected to.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:utils/collection~Collection}\n\t\t */\n\t\tthis.editors = new Collection();\n\n\t\t/**\n\t\t * Reference to the editor which created the context.\n\t\t * Null when the context was created outside of the editor.\n\t\t *\n\t\t * It is used to destroy the context when removing the editor that has created the context.\n\t\t *\n\t\t * @private\n\t\t * @type {module:core/editor/editor~Editor|null}\n\t\t */\n\t\tthis._contextOwner = null;\n\t}\n\n\t/**\n\t * Loads and initializes plugins specified in the configuration.\n\t *\n\t * @returns {Promise.} A promise which resolves\n\t * once the initialization is completed, providing an array of loaded plugins.\n\t */\n\tinitPlugins() {\n\t\tconst plugins = this.config.get( 'plugins' ) || [];\n\t\tconst substitutePlugins = this.config.get( 'substitutePlugins' ) || [];\n\n\t\t// Plugins for substitution should be checked as well.\n\t\tfor ( const Plugin of plugins.concat( substitutePlugins ) ) {\n\t\t\tif ( typeof Plugin != 'function' ) {\n\t\t\t\t/**\n\t\t\t\t * Only a constructor function is allowed as a {@link module:core/contextplugin~ContextPlugin context plugin}.\n\t\t\t\t *\n\t\t\t\t * @error context-initplugins-constructor-only\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'context-initplugins-constructor-only',\n\t\t\t\t\tnull,\n\t\t\t\t\t{ Plugin }\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ( Plugin.isContextPlugin !== true ) {\n\t\t\t\t/**\n\t\t\t\t * Only a plugin marked as a {@link module:core/contextplugin~ContextPlugin.isContextPlugin context plugin}\n\t\t\t\t * is allowed to be used with a context.\n\t\t\t\t *\n\t\t\t\t * @error context-initplugins-invalid-plugin\n\t\t\t\t */\n\t\t\t\tthrow new CKEditorError(\n\t\t\t\t\t'context-initplugins-invalid-plugin',\n\t\t\t\t\tnull,\n\t\t\t\t\t{ Plugin }\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\treturn this.plugins.init( plugins, [], substitutePlugins );\n\t}\n\n\t/**\n\t * Destroys the context instance and all editors used with the context,\n\t * releasing all resources used by the context.\n\t *\n\t * @returns {Promise} A promise that resolves once the context instance is fully destroyed.\n\t */\n\tdestroy() {\n\t\treturn Promise.all( Array.from( this.editors, editor => editor.destroy() ) )\n\t\t\t.then( () => this.plugins.destroy() );\n\t}\n\n\t/**\n\t * Adds a reference to the editor which is used with this context.\n\t *\n\t * When the given editor has created the context, the reference to this editor will be stored\n\t * as a {@link ~Context#_contextOwner}.\n\t *\n\t * This method should only be used by the editor.\n\t *\n\t * @protected\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @param {Boolean} isContextOwner Stores the given editor as a context owner.\n\t */\n\t_addEditor( editor, isContextOwner ) {\n\t\tif ( this._contextOwner ) {\n\t\t\t/**\n\t\t\t * Cannot add multiple editors to the context which is created by the editor.\n\t\t\t *\n\t\t\t * @error context-addeditor-private-context\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'context-addeditor-private-context' );\n\t\t}\n\n\t\tthis.editors.add( editor );\n\n\t\tif ( isContextOwner ) {\n\t\t\tthis._contextOwner = editor;\n\t\t}\n\t}\n\n\t/**\n\t * Removes a reference to the editor which was used with this context.\n\t * When the context was created by the given editor, the context will be destroyed.\n\t *\n\t * This method should only be used by the editor.\n\t *\n\t * @protected\n\t * @param {module:core/editor/editor~Editor} editor\n\t * @return {Promise} A promise that resolves once the editor is removed from the context or when the context was destroyed.\n\t */\n\t_removeEditor( editor ) {\n\t\tif ( this.editors.has( editor ) ) {\n\t\t\tthis.editors.remove( editor );\n\t\t}\n\n\t\tif ( this._contextOwner === editor ) {\n\t\t\treturn this.destroy();\n\t\t}\n\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * Returns the context configuration which will be copied to the editors created using this context.\n\t *\n\t * The configuration returned by this method has the plugins configuration removed — plugins are shared with all editors\n\t * through another mechanism.\n\t *\n\t * This method should only be used by the editor.\n\t *\n\t * @protected\n\t * @returns {Object} Configuration as a plain object.\n\t */\n\t_getEditorConfig() {\n\t\tconst result = {};\n\n\t\tfor ( const name of this.config.names() ) {\n\t\t\tif ( ![ 'plugins', 'removePlugins', 'extraPlugins' ].includes( name ) ) {\n\t\t\t\tresult[ name ] = this.config.get( name );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Creates and initializes a new context instance.\n\t *\n\t *\t\tconst commonConfig = { ... }; // Configuration for all the plugins and editors.\n\t *\t\tconst editorPlugins = [ ... ]; // Regular plugins here.\n\t *\n\t *\t\tContext\n\t *\t\t\t.create( {\n\t *\t\t\t\t// Only context plugins here.\n\t *\t\t\t\tplugins: [ ... ],\n\t *\n\t *\t\t\t\t// Configure the language for all the editors (it cannot be overwritten).\n\t *\t\t\t\tlanguage: { ... },\n\t *\n\t *\t\t\t\t// Configuration for context plugins.\n\t *\t\t\t\tcomments: { ... },\n\t *\t\t\t\t...\n\t *\n\t *\t\t\t\t// Default configuration for editor plugins.\n\t *\t\t\t\ttoolbar: { ... },\n\t *\t\t\t\timage: { ... },\n\t *\t\t\t\t...\n\t *\t\t\t} )\n\t *\t\t\t.then( context => {\n\t *\t\t\t\tconst promises = [];\n\t *\n\t *\t\t\t\tpromises.push( ClassicEditor.create(\n\t *\t\t\t\t\tdocument.getElementById( 'editor1' ),\n\t *\t\t\t\t\t{\n\t *\t\t\t\t\t\teditorPlugins,\n\t *\t\t\t\t\t\tcontext\n\t *\t\t\t\t\t}\n\t *\t\t\t\t) );\n\t *\n\t *\t\t\t\tpromises.push( ClassicEditor.create(\n\t *\t\t\t\t\tdocument.getElementById( 'editor2' ),\n\t *\t\t\t\t\t{\n\t *\t\t\t\t\t\teditorPlugins,\n\t *\t\t\t\t\t\tcontext,\n\t *\t\t\t\t\t\ttoolbar: { ... } // You can overwrite the configuration of the context.\n\t *\t\t\t\t\t}\n\t *\t\t\t\t) );\n\t *\n\t *\t\t\t\treturn Promise.all( promises );\n\t *\t\t\t} );\n\t *\n\t * @param {Object} [config] The context configuration.\n\t * @returns {Promise} A promise resolved once the context is ready. The promise resolves with the created context instance.\n\t */\n\tstatic create( config ) {\n\t\treturn new Promise( resolve => {\n\t\t\tconst context = new this( config );\n\n\t\t\tresolve( context.initPlugins().then( () => context ) );\n\t\t} );\n\t}\n}\n\n/**\n * An array of plugins built into the `Context` class.\n *\n * It is used in CKEditor 5 builds featuring `Context` to provide a list of context plugins which are later automatically initialized\n * during the context initialization.\n *\n * They will be automatically initialized by `Context` unless `config.plugins` is passed.\n *\n *\t\t// Build some context plugins into the Context class first.\n *\t\tContext.builtinPlugins = [ FooPlugin, BarPlugin ];\n *\n *\t\t// Normally, you need to define config.plugins, but since Context.builtinPlugins was\n *\t\t// defined, now you can call create() without any configuration.\n *\t\tContext\n *\t\t\t.create()\n *\t\t\t.then( context => {\n *\t\t\t\tcontext.plugins.get( FooPlugin ); // -> An instance of the Foo plugin.\n *\t\t\t\tcontext.plugins.get( BarPlugin ); // -> An instance of the Bar plugin.\n *\t\t\t} );\n *\n * See also {@link module:core/context~Context.defaultConfig `Context.defaultConfig`}\n * and {@link module:core/editor/editor~Editor.builtinPlugins `Editor.builtinPlugins`}.\n *\n * @static\n * @member {Array.} module:core/context~Context.builtinPlugins\n */\n\n/**\n * The default configuration which is built into the `Context` class.\n *\n * It is used in CKEditor 5 builds featuring `Context` to provide the default configuration options which are later used during the\n * context initialization.\n *\n *\t\tContext.defaultConfig = {\n *\t\t\tfoo: 1,\n *\t\t\tbar: 2\n *\t\t};\n *\n *\t\tContext\n *\t\t\t.create()\n *\t\t\t.then( context => {\n *\t\t\t\tcontext.config.get( 'foo' ); // -> 1\n *\t\t\t\tcontext.config.get( 'bar' ); // -> 2\n *\t\t\t} );\n *\n *\t\t// The default options can be overridden by the configuration passed to create().\n *\t\tContext\n *\t\t\t.create( { bar: 3 } )\n *\t\t\t.then( context => {\n *\t\t\t\tcontext.config.get( 'foo' ); // -> 1\n *\t\t\t\tcontext.config.get( 'bar' ); // -> 3\n *\t\t\t} );\n *\n * See also {@link module:core/context~Context.builtinPlugins `Context.builtinPlugins`}\n * and {@link module:core/editor/editor~Editor.defaultConfig `Editor.defaultConfig`}.\n *\n * @static\n * @member {Object} module:core/context~Context.defaultConfig\n */\n","/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/commandcollection\n */\n\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Collection of commands. Its instance is available in {@link module:core/editor/editor~Editor#commands `editor.commands`}.\n */\nexport default class CommandCollection {\n\t/**\n\t * Creates collection instance.\n\t */\n\tconstructor() {\n\t\t/**\n\t\t * Command map.\n\t\t *\n\t\t * @private\n\t\t * @member {Map}\n\t\t */\n\t\tthis._commands = new Map();\n\t}\n\n\t/**\n\t * Registers a new command.\n\t *\n\t * @param {String} commandName The name of the command.\n\t * @param {module:core/command~Command} command\n\t */\n\tadd( commandName, command ) {\n\t\tthis._commands.set( commandName, command );\n\t}\n\n\t/**\n\t * Retrieves a command from the collection.\n\t *\n\t * @param {String} commandName The name of the command.\n\t * @returns {module:core/command~Command}\n\t */\n\tget( commandName ) {\n\t\treturn this._commands.get( commandName );\n\t}\n\n\t/**\n\t * Executes a command.\n\t *\n\t * @param {String} commandName The name of the command.\n\t * @param {*} [...commandParams] Command parameters.\n\t * @returns {*} The value returned by the {@link module:core/command~Command#execute `command.execute()`}.\n\t */\n\texecute( commandName, ...args ) {\n\t\tconst command = this.get( commandName );\n\n\t\tif ( !command ) {\n\t\t\t/**\n\t\t\t * Command does not exist.\n\t\t\t *\n\t\t\t * @error commandcollection-command-not-found\n\t\t\t * @param {String} commandName Name of the command.\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'commandcollection-command-not-found', this, { commandName } );\n\t\t}\n\n\t\treturn command.execute( ...args );\n\t}\n\n\t/**\n\t * Returns iterator of command names.\n\t *\n\t * @returns {Iterable.}\n\t */\n\t* names() {\n\t\tyield* this._commands.keys();\n\t}\n\n\t/**\n\t * Returns iterator of command instances.\n\t *\n\t * @returns {Iterable.}\n\t */\n\t* commands() {\n\t\tyield* this._commands.values();\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * Returns `[ commandName, commandInstance ]` pairs.\n\t *\n\t * @returns {Iterable.}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this._commands[ Symbol.iterator ]();\n\t}\n\n\t/**\n\t * Destroys all collection commands.\n\t */\n\tdestroy() {\n\t\tfor ( const command of this.commands() ) {\n\t\t\tcommand.destroy();\n\t\t}\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/editingkeystrokehandler\n */\n\nimport KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';\n\n/**\n * A keystroke handler for editor editing. Its instance is available\n * in {@link module:core/editor/editor~Editor#keystrokes} so plugins\n * can register their keystrokes.\n *\n * E.g. an undo plugin would do this:\n *\n *\t\teditor.keystrokes.set( 'Ctrl+Z', 'undo' );\n *\t\teditor.keystrokes.set( 'Ctrl+Shift+Z', 'redo' );\n *\t\teditor.keystrokes.set( 'Ctrl+Y', 'redo' );\n *\n * @extends module:utils/keystrokehandler~KeystrokeHandler\n */\nexport default class EditingKeystrokeHandler extends KeystrokeHandler {\n\t/**\n\t * Creates an instance of the keystroke handler.\n\t *\n\t * @param {module:core/editor/editor~Editor} editor\n\t */\n\tconstructor( editor ) {\n\t\tsuper();\n\n\t\t/**\n\t\t * The editor instance.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editor/editor~Editor}\n\t\t */\n\t\tthis.editor = editor;\n\t}\n\n\t/**\n\t * Registers a handler for the specified keystroke.\n\t *\n\t * The handler can be specified as a command name or a callback.\n\t *\n\t * @param {String|Array.} keystroke Keystroke defined in a format accepted by\n\t * the {@link module:utils/keyboard~parseKeystroke} function.\n\t * @param {Function|String} callback If a string is passed, then the keystroke will\n\t * {@link module:core/editor/editor~Editor#execute execute a command}.\n\t * If a function, then it will be called with the\n\t * {@link module:engine/view/observer/keyobserver~KeyEventData key event data} object and\n\t * a `cancel()` helper to both `preventDefault()` and `stopPropagation()` of the event.\n\t * @param {Object} [options={}] Additional options.\n\t * @param {module:utils/priorities~PriorityString|Number} [options.priority='normal'] The priority of the keystroke\n\t * callback. The higher the priority value the sooner the callback will be executed. Keystrokes having the same priority\n\t * are called in the order they were added.\n\t */\n\tset( keystroke, callback, options = {} ) {\n\t\tif ( typeof callback == 'string' ) {\n\t\t\tconst commandName = callback;\n\n\t\t\tcallback = ( evtData, cancel ) => {\n\t\t\t\tthis.editor.execute( commandName );\n\t\t\t\tcancel();\n\t\t\t};\n\t\t}\n\n\t\tsuper.set( keystroke, callback, options );\n\t}\n}\n","/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module core/editor/editor\n */\n\nimport Context from '../context';\nimport Config from '@ckeditor/ckeditor5-utils/src/config';\nimport EditingController from '@ckeditor/ckeditor5-engine/src/controller/editingcontroller';\nimport PluginCollection from '../plugincollection';\nimport CommandCollection from '../commandcollection';\nimport DataController from '@ckeditor/ckeditor5-engine/src/controller/datacontroller';\nimport Conversion from '@ckeditor/ckeditor5-engine/src/conversion/conversion';\nimport Model from '@ckeditor/ckeditor5-engine/src/model/model';\nimport EditingKeystrokeHandler from '../editingkeystrokehandler';\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport { StylesProcessor } from '@ckeditor/ckeditor5-engine/src/view/stylesmap';\n\n/**\n * The class representing a basic, generic editor.\n *\n * Check out the list of its subclasses to learn about specific editor implementations.\n *\n * All editor implementations (like {@link module:editor-classic/classiceditor~ClassicEditor} or\n * {@link module:editor-inline/inlineeditor~InlineEditor}) should extend this class. They can add their\n * own methods and properties.\n *\n * When you are implementing a plugin, this editor represents the API\n * which your plugin can expect to get when using its {@link module:core/plugin~Plugin#editor} property.\n *\n * This API should be sufficient in order to implement the \"editing\" part of your feature\n * (schema definition, conversion, commands, keystrokes, etc.).\n * It does not define the editor UI, which is available only if\n * the specific editor implements also the {@link module:core/editor/editorwithui~EditorWithUI} interface\n * (as most editor implementations do).\n *\n * @abstract\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class Editor {\n\t/**\n\t * Creates a new instance of the editor class.\n\t *\n\t * Usually, not to be used directly. See the static {@link module:core/editor/editor~Editor.create `create()`} method.\n\t *\n\t * @param {Object} [config={}] The editor configuration.\n\t */\n\tconstructor( config = {} ) {\n\t\t/**\n\t\t * The editor context.\n\t\t * When it is not provided through the configuration, the editor creates it.\n\t\t *\n\t\t * @protected\n\t\t * @type {module:core/context~Context}\n\t\t */\n\t\tthis._context = config.context || new Context( { language: config.language } );\n\t\tthis._context._addEditor( this, !config.context );\n\n\t\t// Clone the plugins to make sure that the plugin array will not be shared\n\t\t// between editors and make the watchdog feature work correctly.\n\t\tconst availablePlugins = Array.from( this.constructor.builtinPlugins || [] );\n\n\t\t/**\n\t\t * Stores all configurations specific to this editor instance.\n\t\t *\n\t\t *\t\teditor.config.get( 'image.toolbar' );\n\t\t *\t\t// -> [ 'imageStyle:full', 'imageStyle:side', '|', 'imageTextAlternative' ]\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:utils/config~Config}\n\t\t */\n\t\tthis.config = new Config( config, this.constructor.defaultConfig );\n\t\tthis.config.define( 'plugins', availablePlugins );\n\t\tthis.config.define( this._context._getEditorConfig() );\n\n\t\t/**\n\t\t * The plugins loaded and in use by this editor instance.\n\t\t *\n\t\t *\t\teditor.plugins.get( 'Clipboard' ); // -> An instance of the clipboard plugin.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/plugincollection~PluginCollection}\n\t\t */\n\t\tthis.plugins = new PluginCollection( this, availablePlugins, this._context.plugins );\n\n\t\t/**\n\t\t * The locale instance.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:utils/locale~Locale}\n\t\t */\n\t\tthis.locale = this._context.locale;\n\n\t\t/**\n\t\t * Shorthand for {@link module:utils/locale~Locale#t}.\n\t\t *\n\t\t * @see module:utils/locale~Locale#t\n\t\t * @method #t\n\t\t */\n\t\tthis.t = this.locale.t;\n\n\t\t/**\n\t\t * Commands registered to the editor.\n\t\t *\n\t\t * Use the shorthand {@link #execute `editor.execute()`} method to execute commands:\n\t\t *\n\t\t *\t\t// Execute the bold command:\n\t\t *\t\teditor.execute( 'bold' );\n\t\t *\n\t\t *\t\t// Check the state of the bold command:\n\t\t *\t\teditor.commands.get( 'bold' ).value;\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/commandcollection~CommandCollection}\n\t\t */\n\t\tthis.commands = new CommandCollection();\n\n\t\t/**\n\t\t * Indicates the editor life-cycle state.\n\t\t *\n\t\t * The editor is in one of the following states:\n\t\t *\n\t\t * * `initializing` – During the editor initialization (before\n\t\t * {@link module:core/editor/editor~Editor.create `Editor.create()`}) finished its job.\n\t\t * * `ready` – After the promise returned by the {@link module:core/editor/editor~Editor.create `Editor.create()`}\n\t\t * method is resolved.\n\t\t * * `destroyed` – Once the {@link #destroy `editor.destroy()`} method was called.\n\t\t *\n\t\t * @observable\n\t\t * @member {'initializing'|'ready'|'destroyed'} #state\n\t\t */\n\t\tthis.set( 'state', 'initializing' );\n\t\tthis.once( 'ready', () => ( this.state = 'ready' ), { priority: 'high' } );\n\t\tthis.once( 'destroy', () => ( this.state = 'destroyed' ), { priority: 'high' } );\n\n\t\t/**\n\t\t * Defines whether this editor is in read-only mode.\n\t\t *\n\t\t * In read-only mode the editor {@link #commands commands} are disabled so it is not possible\n\t\t * to modify the document by using them. Also, the editable element(s) become non-editable.\n\t\t *\n\t\t * In order to make the editor read-only, you can set this value directly:\n\t\t *\n\t\t *\t\teditor.isReadOnly = true;\n\t\t *\n\t\t * @observable\n\t\t * @member {Boolean} #isReadOnly\n\t\t */\n\t\tthis.set( 'isReadOnly', false );\n\n\t\t/**\n\t\t * The editor's model.\n\t\t *\n\t\t * The central point of the editor's abstract data model.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/model~Model}\n\t\t */\n\t\tthis.model = new Model();\n\n\t\tconst stylesProcessor = new StylesProcessor();\n\n\t\t/**\n\t\t * The {@link module:engine/controller/datacontroller~DataController data controller}.\n\t\t * Used e.g. for setting and retrieving the editor data.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/controller/datacontroller~DataController}\n\t\t */\n\t\tthis.data = new DataController( this.model, stylesProcessor );\n\n\t\t/**\n\t\t * The {@link module:engine/controller/editingcontroller~EditingController editing controller}.\n\t\t * Controls user input and rendering the content for editing.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/controller/editingcontroller~EditingController}\n\t\t */\n\t\tthis.editing = new EditingController( this.model, stylesProcessor );\n\t\tthis.editing.view.document.bind( 'isReadOnly' ).to( this );\n\n\t\t/**\n\t\t * Conversion manager through which you can register model-to-view and view-to-model converters.\n\t\t *\n\t\t * See the {@link module:engine/conversion/conversion~Conversion} documentation to learn how to add converters.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/conversion~Conversion}\n\t\t */\n\t\tthis.conversion = new Conversion( [ this.editing.downcastDispatcher, this.data.downcastDispatcher ], this.data.upcastDispatcher );\n\t\tthis.conversion.addAlias( 'dataDowncast', this.data.downcastDispatcher );\n\t\tthis.conversion.addAlias( 'editingDowncast', this.editing.downcastDispatcher );\n\n\t\t/**\n\t\t * An instance of the {@link module:core/editingkeystrokehandler~EditingKeystrokeHandler}.\n\t\t *\n\t\t * It allows setting simple keystrokes:\n\t\t *\n\t\t *\t\t// Execute the bold command on Ctrl+E:\n\t\t *\t\teditor.keystrokes.set( 'Ctrl+E', 'bold' );\n\t\t *\n\t\t *\t\t// Execute your own callback:\n\t\t *\t\teditor.keystrokes.set( 'Ctrl+E', ( data, cancel ) => {\n\t\t *\t\t\tconsole.log( data.keyCode );\n\t\t *\n\t\t *\t\t\t// Prevent the default (native) action and stop the underlying keydown event\n\t\t *\t\t\t// so no other editor feature will interfere.\n\t\t *\t\t\tcancel();\n\t\t *\t\t} );\n\t\t *\n\t\t * Note: Certain typing-oriented keystrokes (like Backspace or Enter) are handled\n\t\t * by a low-level mechanism and trying to listen to them via the keystroke handler will not work reliably.\n\t\t * To handle these specific keystrokes, see the events fired by the\n\t\t * {@link module:engine/view/document~Document editing view document} (`editor.editing.view.document`).\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:core/editingkeystrokehandler~EditingKeystrokeHandler}\n\t\t */\n\t\tthis.keystrokes = new EditingKeystrokeHandler( this );\n\t\tthis.keystrokes.listenTo( this.editing.view.document );\n\t}\n\n\t/**\n\t * Loads and initializes plugins specified in the configuration.\n\t *\n\t * @returns {Promise.} A promise which resolves\n\t * once the initialization is completed, providing an array of loaded plugins.\n\t */\n\tinitPlugins() {\n\t\tconst config = this.config;\n\t\tconst plugins = config.get( 'plugins' );\n\t\tconst removePlugins = config.get( 'removePlugins' ) || [];\n\t\tconst extraPlugins = config.get( 'extraPlugins' ) || [];\n\t\tconst substitutePlugins = config.get( 'substitutePlugins' ) || [];\n\n\t\treturn this.plugins.init( plugins.concat( extraPlugins ), removePlugins, substitutePlugins );\n\t}\n\n\t/**\n\t * Destroys the editor instance, releasing all resources used by it.\n\t *\n\t * **Note** The editor cannot be destroyed during the initialization phase so if it is called\n\t * while the editor {@link #state is being initialized}, it will wait for the editor initialization before destroying it.\n\t *\n\t * @fires destroy\n\t * @returns {Promise} A promise that resolves once the editor instance is fully destroyed.\n\t */\n\tdestroy() {\n\t\tlet readyPromise = Promise.resolve();\n\n\t\tif ( this.state == 'initializing' ) {\n\t\t\treadyPromise = new Promise( resolve => this.once( 'ready', resolve ) );\n\t\t}\n\n\t\treturn readyPromise\n\t\t\t.then( () => {\n\t\t\t\tthis.fire( 'destroy' );\n\t\t\t\tthis.stopListening();\n\t\t\t\tthis.commands.destroy();\n\t\t\t} )\n\t\t\t.then( () => this.plugins.destroy() )\n\t\t\t.then( () => {\n\t\t\t\tthis.model.destroy();\n\t\t\t\tthis.data.destroy();\n\t\t\t\tthis.editing.destroy();\n\t\t\t\tthis.keystrokes.destroy();\n\t\t\t} )\n\t\t\t// Remove the editor from the context.\n\t\t\t// When the context was created by this editor, the context will be destroyed.\n\t\t\t.then( () => this._context._removeEditor( this ) );\n\t}\n\n\t/**\n\t * Executes the specified command with given parameters.\n\t *\n\t * Shorthand for:\n\t *\n\t *\t\teditor.commands.get( commandName ).execute( ... );\n\t *\n\t * @param {String} commandName The name of the command to execute.\n\t * @param {*} [...commandParams] Command parameters.\n\t * @returns {*} The value returned by the {@link module:core/commandcollection~CommandCollection#execute `commands.execute()`}.\n\t */\n\texecute( ...args ) {\n\t\ttry {\n\t\t\treturn this.commands.execute( ...args );\n\t\t} catch ( err ) {\n\t\t\t// @if CK_DEBUG // throw err;\n\t\t\t/* istanbul ignore next */\n\t\t\tCKEditorError.rethrowUnexpectedError( err, this );\n\t\t}\n\t}\n\n\t/**\n\t * Focuses the editor.\n\t *\n\t * **Note** To explicitly focus the editing area of the editor, use the\n\t * {@link module:engine/view/view~View#focus `editor.editing.view.focus()`} method of the editing view.\n\t *\n\t * Check out the {@glink framework/guides/deep-dive/ui/focus-tracking#focus-in-the-editor-ui Focus in the editor UI} section\n\t * of the {@glink framework/guides/deep-dive/ui/focus-tracking Deep dive into focus tracking} guide to learn more.\n\t */\n\tfocus() {\n\t\tthis.editing.view.focus();\n\t}\n\n\t/**\n\t * Creates and initializes a new editor instance.\n\t *\n\t * This is an abstract method. Every editor type needs to implement its own initialization logic.\n\t *\n\t * See the `create()` methods of the existing editor types to learn how to use them:\n\t *\n\t * * {@link module:editor-classic/classiceditor~ClassicEditor.create `ClassicEditor.create()`}\n\t * * {@link module:editor-balloon/ballooneditor~BalloonEditor.create `BalloonEditor.create()`}\n\t * * {@link module:editor-decoupled/decouplededitor~DecoupledEditor.create `DecoupledEditor.create()`}\n\t * * {@link module:editor-inline/inlineeditor~InlineEditor.create `InlineEditor.create()`}\n\t *\n\t * @abstract\n\t * @method module:core/editor/editor~Editor.create\n\t */\n}\n\nmix( Editor, ObservableMixin );\n\n/**\n * Fired when the {@link module:engine/controller/datacontroller~DataController#event:ready data} and all additional\n * editor components are ready.\n *\n * Note: This event is most useful for plugin developers. When integrating the editor with your website or\n * application, you do not have to listen to `editor#ready` because when the promise returned by the static\n * {@link module:core/editor/editor~Editor.create `Editor.create()`} event is resolved, the editor is already ready.\n * In fact, since the first moment when the editor instance is available to you is inside `then()`'s callback,\n * you cannot even add a listener to the `editor#ready` event.\n *\n * See also the {@link #state `editor.state`} property.\n *\n * @event ready\n */\n\n/**\n * Fired when this editor instance is destroyed. The editor at this point is not usable and this event should be used to\n * perform the clean-up in any plugin.\n *\n *\n * See also the {@link #state `editor.state`} property.\n *\n * @event destroy\n */\n\n/**\n * This error is thrown when trying to pass a `