{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/treewalker.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/view.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/uielement.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/upcastwriter.js"],"names":["TreeWalker","options","boundaries","startPosition","CKEditorError","direction","this","position","Position","_createAt","singleCharacters","shallow","ignoreElementEnd","_boundaryStartParent","start","parent","_boundaryEndParent","end","Symbol","iterator","skip","done","value","prevPosition","next","_next","_previous","node","clone","previousPosition","offset","childCount","Text","isAtEnd","_createAfter","data","getChild","Element","_formatReturnValue","item","charactersCount","length","TextProxy","textLength","endOffset","textProxy","isAtStart","_createBefore","startOffset","type","nextPosition","offsetInText","textNode","isEqual","View","stylesProcessor","document","Document","domConverter","DomConverter","domRoots","Map","set","_renderer","Renderer","selection","bind","to","_initialDomRootAttributes","WeakMap","_observers","_ongoingChange","_postFixersInProgress","_renderingDisabled","_hasChangedSinceTheLastRendering","_writer","DowncastWriter","addObserver","MutationObserver","SelectionObserver","FocusObserver","KeyObserver","FakeSelectionObserver","CompositionObserver","env","isAndroid","InputObserver","injectQuirksHandling","injectUiElementHandling","on","_render","fire","listenTo","domRoot","name","viewRoot","getRoot","_name","tagName","toLowerCase","initialDomRootAttributes","Array","from","attributes","addClass","split","setAttribute","updateContenteditableAttribute","isReadOnly","removeClass","bindElements","markToSync","domDocuments","add","ownerDocument","evt","change","values","observer","observe","get","forEach","removeAttribute","attribute","delete","unbindDomElement","Observer","domElement","enable","disable","range","getFirstRange","scrollViewportToShowTarget","target","viewRangeToDom","viewportOffset","isFocused","editable","editableElement","focus","forceRender","callback","isRenderingInProgress","callbackResult","_callPostFixers","err","rethrowUnexpectedError","destroy","stopListening","itemOrPosition","Range","_createOn","element","_createIn","selectable","placeOrOffset","Selection","flag","disableObservers","render","enableObservers","mix","ObservableMixin","UIElement","children","_isAllowedInsideAttributeElement","getFillerOffset","index","nodes","Node","domDocument","toDomElement","createElement","getAttributeKeys","key","getAttribute","view","jumpOverUiElement","keyCode","keyCodes","arrowright","domSelection","domTarget","defaultView","getSelection","domSelectionCollapsed","rangeCount","getRangeAt","collapsed","shiftKey","domParent","focusNode","domOffset","focusOffset","viewPosition","domPositionToView","jumpedOverAnyUiElement","nextViewPosition","getLastMatchingPosition","is","newDomPosition","viewPositionToDom","collapse","extend","UpcastWriter","DocumentFragment","attrs","deep","_clone","items","_appendChild","_insertChild","howMany","_removeChildren","removeChildren","getChildIndex","oldElement","newElement","insertChild","remove","getChildren","newName","getAttributes","replace","_setAttribute","_removeAttribute","className","_addClass","_removeClass","property","isPlainObject","undefined","_setStyle","_removeStyle","_setCustomProperty","_removeCustomProperty"],"mappings":"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","file":"js/chunk-vendors~e300ff19.71a5b53f.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 engine/view/treewalker\n */\n\nimport Element from './element';\nimport Text from './text';\nimport TextProxy from './textproxy';\nimport Position from './position';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\n/**\n * Position iterator class. It allows to iterate forward and backward over the document.\n */\nexport default class TreeWalker {\n\t/**\n\t * Creates a range iterator. All parameters are optional, but you have to specify either `boundaries` or `startPosition`.\n\t *\n\t * @constructor\n\t * @param {Object} options Object with configuration.\n\t * @param {module:engine/view/range~Range} [options.boundaries=null] Range to define boundaries of the iterator.\n\t * @param {module:engine/view/position~Position} [options.startPosition] Starting position.\n\t * @param {'forward'|'backward'} [options.direction='forward'] Walking direction.\n\t * @param {Boolean} [options.singleCharacters=false] Flag indicating whether all characters from\n\t * {@link module:engine/view/text~Text} should be returned as one {@link module:engine/view/text~Text} (`false`) ore one by one as\n\t * {@link module:engine/view/textproxy~TextProxy} (`true`).\n\t * @param {Boolean} [options.shallow=false] Flag indicating whether iterator should enter elements or not. If the\n\t * iterator is shallow child nodes of any iterated node will not be returned along with `elementEnd` tag.\n\t * @param {Boolean} [options.ignoreElementEnd=false] Flag indicating whether iterator should ignore `elementEnd`\n\t * tags. If the option is true walker will not return a parent node of start position. If this option is `true`\n\t * each {@link module:engine/view/element~Element} will be returned once, while if the option is `false` they might be returned\n\t * twice: for `'elementStart'` and `'elementEnd'`.\n\t */\n\tconstructor( options = {} ) {\n\t\tif ( !options.boundaries && !options.startPosition ) {\n\t\t\t/**\n\t\t\t * Neither boundaries nor starting position have been defined.\n\t\t\t *\n\t\t\t * @error view-tree-walker-no-start-position\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'view-tree-walker-no-start-position',\n\t\t\t\tnull\n\t\t\t);\n\t\t}\n\n\t\tif ( options.direction && options.direction != 'forward' && options.direction != 'backward' ) {\n\t\t\t/**\n\t\t\t * Only `backward` and `forward` direction allowed.\n\t\t\t *\n\t\t\t * @error view-tree-walker-unknown-direction\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-tree-walker-unknown-direction', options.startPosition, { direction: options.direction } );\n\t\t}\n\n\t\t/**\n\t\t * Iterator boundaries.\n\t\t *\n\t\t * When the iterator is walking `'forward'` on the end of boundary or is walking `'backward'`\n\t\t * on the start of boundary, then `{ done: true }` is returned.\n\t\t *\n\t\t * If boundaries are not defined they are set before first and after last child of the root node.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/range~Range} module:engine/view/treewalker~TreeWalker#boundaries\n\t\t */\n\t\tthis.boundaries = options.boundaries || null;\n\n\t\t/**\n\t\t * Iterator position. If start position is not defined then position depends on {@link #direction}. If direction is\n\t\t * `'forward'` position starts form the beginning, when direction is `'backward'` position starts from the end.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/position~Position} module:engine/view/treewalker~TreeWalker#position\n\t\t */\n\t\tif ( options.startPosition ) {\n\t\t\tthis.position = Position._createAt( options.startPosition );\n\t\t} else {\n\t\t\tthis.position = Position._createAt( options.boundaries[ options.direction == 'backward' ? 'end' : 'start' ] );\n\t\t}\n\n\t\t/**\n\t\t * Walking direction. Defaults `'forward'`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {'backward'|'forward'} module:engine/view/treewalker~TreeWalker#direction\n\t\t */\n\t\tthis.direction = options.direction || 'forward';\n\n\t\t/**\n\t\t * Flag indicating whether all characters from {@link module:engine/view/text~Text} should be returned as one\n\t\t * {@link module:engine/view/text~Text} or one by one as {@link module:engine/view/textproxy~TextProxy}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/view/treewalker~TreeWalker#singleCharacters\n\t\t */\n\t\tthis.singleCharacters = !!options.singleCharacters;\n\n\t\t/**\n\t\t * Flag indicating whether iterator should enter elements or not. If the iterator is shallow child nodes of any\n\t\t * iterated node will not be returned along with `elementEnd` tag.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/view/treewalker~TreeWalker#shallow\n\t\t */\n\t\tthis.shallow = !!options.shallow;\n\n\t\t/**\n\t\t * Flag indicating whether iterator should ignore `elementEnd` tags. If set to `true`, walker will not\n\t\t * return a parent node of the start position. Each {@link module:engine/view/element~Element} will be returned once.\n\t\t * When set to `false` each element might be returned twice: for `'elementStart'` and `'elementEnd'`.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} module:engine/view/treewalker~TreeWalker#ignoreElementEnd\n\t\t */\n\t\tthis.ignoreElementEnd = !!options.ignoreElementEnd;\n\n\t\t/**\n\t\t * Start boundary parent.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/view/node~Node} module:engine/view/treewalker~TreeWalker#_boundaryStartParent\n\t\t */\n\t\tthis._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;\n\n\t\t/**\n\t\t * End boundary parent.\n\t\t *\n\t\t * @private\n\t\t * @member {module:engine/view/node~Node} module:engine/view/treewalker~TreeWalker#_boundaryEndParent\n\t\t */\n\t\tthis._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;\n\t}\n\n\t/**\n\t * Iterable interface.\n\t *\n\t * @returns {Iterable.}\n\t */\n\t[ Symbol.iterator ]() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Moves {@link #position} in the {@link #direction} skipping values as long as the callback function returns `true`.\n\t *\n\t * For example:\n\t *\n\t * \t\twalker.skip( value => value.type == 'text' ); //

{}foo

->

foo[]

\n\t * \t\twalker.skip( value => true ); // Move the position to the end:

{}foo

->

foo

[]\n\t * \t\twalker.skip( value => false ); // Do not move the position.\n\t *\n\t * @param {Function} skip Callback function. Gets {@link module:engine/view/treewalker~TreeWalkerValue} and should\n\t * return `true` if the value should be skipped or `false` if not.\n\t */\n\tskip( skip ) {\n\t\tlet done, value, prevPosition;\n\n\t\tdo {\n\t\t\tprevPosition = this.position;\n\n\t\t\t( { done, value } = this.next() );\n\t\t} while ( !done && skip( value ) );\n\n\t\tif ( !done ) {\n\t\t\tthis.position = prevPosition;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the next tree walker's value.\n\t *\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue} Object implementing iterator interface, returning\n\t * information about taken step.\n\t */\n\tnext() {\n\t\tif ( this.direction == 'forward' ) {\n\t\t\treturn this._next();\n\t\t} else {\n\t\t\treturn this._previous();\n\t\t}\n\t}\n\n\t/**\n\t * Makes a step forward in view. Moves the {@link #position} to the next position and returns the encountered value.\n\t *\n\t * @private\n\t * @returns {Object}\n\t * @returns {Boolean} return.done `true` if iterator is done, `false` otherwise.\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue} return.value Information about taken step.\n\t */\n\t_next() {\n\t\tlet position = this.position.clone();\n\t\tconst previousPosition = this.position;\n\t\tconst parent = position.parent;\n\n\t\t// We are at the end of the root.\n\t\tif ( parent.parent === null && position.offset === parent.childCount ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent === this._boundaryEndParent && position.offset == this.boundaries.end.offset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// Get node just after current position.\n\t\tlet node;\n\n\t\t// Text is a specific parent because it contains string instead of child nodes.\n\t\tif ( parent instanceof Text ) {\n\t\t\tif ( position.isAtEnd ) {\n\t\t\t\t// Prevent returning \"elementEnd\" for Text node. Skip that value and return the next walker step.\n\t\t\t\tthis.position = Position._createAfter( parent );\n\n\t\t\t\treturn this._next();\n\t\t\t}\n\n\t\t\tnode = parent.data[ position.offset ];\n\t\t} else {\n\t\t\tnode = parent.getChild( position.offset );\n\t\t}\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( !this.shallow ) {\n\t\t\t\tposition = new Position( node, 0 );\n\t\t\t} else {\n\t\t\t\tposition.offset++;\n\t\t\t}\n\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t} else if ( node instanceof Text ) {\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tposition = new Position( node, 0 );\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._next();\n\t\t\t} else {\n\t\t\t\tlet charactersCount = node.data.length;\n\t\t\t\tlet item;\n\n\t\t\t\t// If text stick out of walker range, we need to cut it and wrap in TextProxy.\n\t\t\t\tif ( node == this._boundaryEndParent ) {\n\t\t\t\t\tcharactersCount = this.boundaries.end.offset;\n\t\t\t\t\titem = new TextProxy( node, 0, charactersCount );\n\t\t\t\t\tposition = Position._createAfter( item );\n\t\t\t\t} else {\n\t\t\t\t\titem = new TextProxy( node, 0, node.data.length );\n\t\t\t\t\t// If not just keep moving forward.\n\t\t\t\t\tposition.offset++;\n\t\t\t\t}\n\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t\t}\n\t\t} else if ( typeof node == 'string' ) {\n\t\t\tlet textLength;\n\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\ttextLength = 1;\n\t\t\t} else {\n\t\t\t\t// Check if text stick out of walker range.\n\t\t\t\tconst endOffset = parent === this._boundaryEndParent ? this.boundaries.end.offset : parent.data.length;\n\n\t\t\t\ttextLength = endOffset - position.offset;\n\t\t\t}\n\n\t\t\tconst textProxy = new TextProxy( parent, position.offset, textLength );\n\n\t\t\tposition.offset += textLength;\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'text', textProxy, previousPosition, position, textLength );\n\t\t} else {\n\t\t\t// `node` is not set, we reached the end of current `parent`.\n\t\t\tposition = Position._createAfter( parent );\n\t\t\tthis.position = position;\n\n\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\treturn this._next();\n\t\t\t} else {\n\t\t\t\treturn this._formatReturnValue( 'elementEnd', parent, previousPosition, position );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Makes a step backward in view. Moves the {@link #position} to the previous position and returns the encountered value.\n\t *\n\t * @private\n\t * @returns {Object}\n\t * @returns {Boolean} return.done True if iterator is done.\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue} return.value Information about taken step.\n\t */\n\t_previous() {\n\t\tlet position = this.position.clone();\n\t\tconst previousPosition = this.position;\n\t\tconst parent = position.parent;\n\n\t\t// We are at the beginning of the root.\n\t\tif ( parent.parent === null && position.offset === 0 ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// We reached the walker boundary.\n\t\tif ( parent == this._boundaryStartParent && position.offset == this.boundaries.start.offset ) {\n\t\t\treturn { done: true };\n\t\t}\n\n\t\t// Get node just before current position.\n\t\tlet node;\n\n\t\t// Text {@link module:engine/view/text~Text} element is a specific parent because contains string instead of child nodes.\n\t\tif ( parent instanceof Text ) {\n\t\t\tif ( position.isAtStart ) {\n\t\t\t\t// Prevent returning \"elementStart\" for Text node. Skip that value and return the next walker step.\n\t\t\t\tthis.position = Position._createBefore( parent );\n\n\t\t\t\treturn this._previous();\n\t\t\t}\n\n\t\t\tnode = parent.data[ position.offset - 1 ];\n\t\t} else {\n\t\t\tnode = parent.getChild( position.offset - 1 );\n\t\t}\n\n\t\tif ( node instanceof Element ) {\n\t\t\tif ( !this.shallow ) {\n\t\t\t\tposition = new Position( node, node.childCount );\n\t\t\t\tthis.position = position;\n\n\t\t\t\tif ( this.ignoreElementEnd ) {\n\t\t\t\t\treturn this._previous();\n\t\t\t\t} else {\n\t\t\t\t\treturn this._formatReturnValue( 'elementEnd', node, previousPosition, position );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tposition.offset--;\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._formatReturnValue( 'elementStart', node, previousPosition, position, 1 );\n\t\t\t}\n\t\t} else if ( node instanceof Text ) {\n\t\t\tif ( this.singleCharacters ) {\n\t\t\t\tposition = new Position( node, node.data.length );\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._previous();\n\t\t\t} else {\n\t\t\t\tlet charactersCount = node.data.length;\n\t\t\t\tlet item;\n\n\t\t\t\t// If text stick out of walker range, we need to cut it and wrap in TextProxy.\n\t\t\t\tif ( node == this._boundaryStartParent ) {\n\t\t\t\t\tconst offset = this.boundaries.start.offset;\n\n\t\t\t\t\titem = new TextProxy( node, offset, node.data.length - offset );\n\t\t\t\t\tcharactersCount = item.data.length;\n\t\t\t\t\tposition = Position._createBefore( item );\n\t\t\t\t} else {\n\t\t\t\t\titem = new TextProxy( node, 0, node.data.length );\n\t\t\t\t\t// If not just keep moving backward.\n\t\t\t\t\tposition.offset--;\n\t\t\t\t}\n\n\t\t\t\tthis.position = position;\n\n\t\t\t\treturn this._formatReturnValue( 'text', item, previousPosition, position, charactersCount );\n\t\t\t}\n\t\t} else if ( typeof node == 'string' ) {\n\t\t\tlet textLength;\n\n\t\t\tif ( !this.singleCharacters ) {\n\t\t\t\t// Check if text stick out of walker range.\n\t\t\t\tconst startOffset = parent === this._boundaryStartParent ? this.boundaries.start.offset : 0;\n\n\t\t\t\ttextLength = position.offset - startOffset;\n\t\t\t} else {\n\t\t\t\ttextLength = 1;\n\t\t\t}\n\n\t\t\tposition.offset -= textLength;\n\n\t\t\tconst textProxy = new TextProxy( parent, position.offset, textLength );\n\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'text', textProxy, previousPosition, position, textLength );\n\t\t} else {\n\t\t\t// `node` is not set, we reached the beginning of current `parent`.\n\t\t\tposition = Position._createBefore( parent );\n\t\t\tthis.position = position;\n\n\t\t\treturn this._formatReturnValue( 'elementStart', parent, previousPosition, position, 1 );\n\t\t}\n\t}\n\n\t/**\n\t * Format returned data and adjust `previousPosition` and `nextPosition` if reach the bound of the {@link module:engine/view/text~Text}.\n\t *\n\t * @private\n\t * @param {module:engine/view/treewalker~TreeWalkerValueType} type Type of step.\n\t * @param {module:engine/view/item~Item} item Item between old and new position.\n\t * @param {module:engine/view/position~Position} previousPosition Previous position of iterator.\n\t * @param {module:engine/view/position~Position} nextPosition Next position of iterator.\n\t * @param {Number} [length] Length of the item.\n\t * @returns {module:engine/view/treewalker~TreeWalkerValue}\n\t */\n\t_formatReturnValue( type, item, previousPosition, nextPosition, length ) {\n\t\t// Text is a specific parent, because contains string instead of children.\n\t\t// Walker doesn't enter to the Text except situations when walker is iterating over every single character,\n\t\t// or the bound starts/ends inside the Text. So when the position is at the beginning or at the end of the Text\n\t\t// we move it just before or just after Text.\n\t\tif ( item instanceof TextProxy ) {\n\t\t\t// Position is at the end of Text.\n\t\t\tif ( item.offsetInText + item.data.length == item.textNode.data.length ) {\n\t\t\t\tif ( this.direction == 'forward' && !( this.boundaries && this.boundaries.end.isEqual( this.position ) ) ) {\n\t\t\t\t\tnextPosition = Position._createAfter( item.textNode );\n\t\t\t\t\t// When we change nextPosition of returned value we need also update walker current position.\n\t\t\t\t\tthis.position = nextPosition;\n\t\t\t\t} else {\n\t\t\t\t\tpreviousPosition = Position._createAfter( item.textNode );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Position is at the begining ot the text.\n\t\t\tif ( item.offsetInText === 0 ) {\n\t\t\t\tif ( this.direction == 'backward' && !( this.boundaries && this.boundaries.start.isEqual( this.position ) ) ) {\n\t\t\t\t\tnextPosition = Position._createBefore( item.textNode );\n\t\t\t\t\t// When we change nextPosition of returned value we need also update walker current position.\n\t\t\t\t\tthis.position = nextPosition;\n\t\t\t\t} else {\n\t\t\t\t\tpreviousPosition = Position._createBefore( item.textNode );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tdone: false,\n\t\t\tvalue: {\n\t\t\t\ttype,\n\t\t\t\titem,\n\t\t\t\tpreviousPosition,\n\t\t\t\tnextPosition,\n\t\t\t\tlength\n\t\t\t}\n\t\t};\n\t}\n}\n\n/**\n * Type of the step made by {@link module:engine/view/treewalker~TreeWalker}.\n * Possible values: `'elementStart'` if walker is at the beginning of a node, `'elementEnd'` if walker is at the end\n * of node, or `'text'` if walker traversed over single and multiple characters.\n * For {@link module:engine/view/text~Text} `elementStart` and `elementEnd` is not returned.\n *\n * @typedef {String} module:engine/view/treewalker~TreeWalkerValueType\n */\n\n/**\n * Object returned by {@link module:engine/view/treewalker~TreeWalker} when traversing tree view.\n *\n * @typedef {Object} module:engine/view/treewalker~TreeWalkerValue\n * @property {module:engine/view/treewalker~TreeWalkerValueType} type\n * @property {module:engine/view/item~Item} item Item between the old and the new positions\n * of the tree walker.\n * @property {module:engine/view/position~Position} previousPosition Previous position of the iterator.\n * * Forward iteration: For `'elementEnd'` it is the last position inside the element. For all other types it is the\n * position before the item.\n * * Backward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n * the position after item.\n * * If the position is at the beginning or at the end of the {@link module:engine/view/text~Text} it is always moved from the\n * inside of the text to its parent just before or just after that text.\n * @property {module:engine/view/position~Position} nextPosition Next position of the iterator.\n * * Forward iteration: For `'elementStart'` it is the first position inside the element. For all other types it is\n * the position after the item.\n * * Backward iteration: For `'elementEnd'` it is last position inside element. For all other types it is the position\n * before the item.\n * * If the position is at the beginning or at the end of the {@link module:engine/view/text~Text} it is always moved from the\n * inside of the text to its parent just before or just after that text.\n * @property {Number} [length] Length of the item. For `'elementStart'` it is `1`. For `'text'` it is\n * the length of that text. For `'elementEnd'` it is `undefined`.\n */\n\n/**\n * Tree walking directions.\n *\n * @typedef {'forward'|'backward'} module:engine/view/treewalker~TreeWalkerDirection\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 engine/view/view\n */\n\nimport Document from './document';\nimport DowncastWriter from './downcastwriter';\nimport Renderer from './renderer';\nimport DomConverter from './domconverter';\nimport Position from './position';\nimport Range from './range';\nimport Selection from './selection';\n\nimport MutationObserver from './observer/mutationobserver';\nimport KeyObserver from './observer/keyobserver';\nimport FakeSelectionObserver from './observer/fakeselectionobserver';\nimport SelectionObserver from './observer/selectionobserver';\nimport FocusObserver from './observer/focusobserver';\nimport CompositionObserver from './observer/compositionobserver';\nimport InputObserver from './observer/inputobserver';\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport { scrollViewportToShowTarget } from '@ckeditor/ckeditor5-utils/src/dom/scroll';\nimport { injectUiElementHandling } from './uielement';\nimport { injectQuirksHandling } from './filler';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport env from '@ckeditor/ckeditor5-utils/src/env';\n\n/**\n * Editor's view controller class. Its main responsibility is DOM - View management for editing purposes, to provide\n * abstraction over the DOM structure and events and hide all browsers quirks.\n *\n * View controller renders view document to DOM whenever view structure changes. To determine when view can be rendered,\n * all changes need to be done using the {@link module:engine/view/view~View#change} method, using\n * {@link module:engine/view/downcastwriter~DowncastWriter}:\n *\n *\t\tview.change( writer => {\n *\t\t\twriter.insert( position, writer.createText( 'foo' ) );\n *\t\t} );\n *\n * View controller also register {@link module:engine/view/observer/observer~Observer observers} which observes changes\n * on DOM and fire events on the {@link module:engine/view/document~Document Document}.\n * Note that the following observers are added by the class constructor and are always available:\n *\n * * {@link module:engine/view/observer/mutationobserver~MutationObserver},\n * * {@link module:engine/view/observer/selectionobserver~SelectionObserver},\n * * {@link module:engine/view/observer/focusobserver~FocusObserver},\n * * {@link module:engine/view/observer/keyobserver~KeyObserver},\n * * {@link module:engine/view/observer/fakeselectionobserver~FakeSelectionObserver}.\n * * {@link module:engine/view/observer/compositionobserver~CompositionObserver}.\n *\n * This class also {@link module:engine/view/view~View#attachDomRoot binds the DOM and the view elements}.\n *\n * If you do not need full a DOM - view management, and only want to transform a tree of view elements to a tree of DOM\n * elements you do not need this controller. You can use the {@link module:engine/view/domconverter~DomConverter DomConverter} instead.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class View {\n\t/**\n\t * @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor The styles processor instance.\n\t */\n\tconstructor( stylesProcessor ) {\n\t\t/**\n\t\t * Instance of the {@link module:engine/view/document~Document} associated with this view controller.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/view/document~Document}\n\t\t */\n\t\tthis.document = new Document( stylesProcessor );\n\n\t\t/**\n\t\t * Instance of the {@link module:engine/view/domconverter~DomConverter domConverter} used by\n\t\t * {@link module:engine/view/view~View#_renderer renderer}\n\t\t * and {@link module:engine/view/observer/observer~Observer observers}.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/view/domconverter~DomConverter}\n\t\t */\n\t\tthis.domConverter = new DomConverter( this.document );\n\n\t\t/**\n\t\t * Roots of the DOM tree. Map on the `HTMLElement`s with roots names as keys.\n\t\t *\n\t\t * @readonly\n\t\t * @type {Map.}\n\t\t */\n\t\tthis.domRoots = new Map();\n\n\t\t/**\n\t\t * Used to prevent calling {@link #forceRender} and {@link #change} during rendering view to the DOM.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} #isRenderingInProgress\n\t\t */\n\t\tthis.set( 'isRenderingInProgress', false );\n\n\t\t/**\n\t\t * Informs whether the DOM selection is inside any of the DOM roots managed by the view.\n\t\t *\n\t\t * @readonly\n\t\t * @member {Boolean} #hasDomSelection\n\t\t */\n\t\tthis.set( 'hasDomSelection', false );\n\n\t\t/**\n\t\t * Instance of the {@link module:engine/view/renderer~Renderer renderer}.\n\t\t *\n\t\t * @protected\n\t\t * @type {module:engine/view/renderer~Renderer}\n\t\t */\n\t\tthis._renderer = new Renderer( this.domConverter, this.document.selection );\n\t\tthis._renderer.bind( 'isFocused' ).to( this.document );\n\n\t\t/**\n\t\t * A DOM root attributes cache. It saves the initial values of DOM root attributes before the DOM element\n\t\t * is {@link module:engine/view/view~View#attachDomRoot attached} to the view so later on, when\n\t\t * the view is destroyed ({@link module:engine/view/view~View#detachDomRoot}), they can be easily restored.\n\t\t * This way, the DOM element can go back to the (clean) state as if the editing view never used it.\n\t\t *\n\t\t * @private\n\t\t * @member {WeakMap.}\n\t\t */\n\t\tthis._initialDomRootAttributes = new WeakMap();\n\n\t\t/**\n\t\t * Map of registered {@link module:engine/view/observer/observer~Observer observers}.\n\t\t *\n\t\t * @private\n\t\t * @type {Map.}\n\t\t */\n\t\tthis._observers = new Map();\n\n\t\t/**\n\t\t * Is set to `true` when {@link #change view changes} are currently in progress.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._ongoingChange = false;\n\n\t\t/**\n\t\t * Used to prevent calling {@link #forceRender} and {@link #change} during rendering view to the DOM.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._postFixersInProgress = false;\n\n\t\t/**\n\t\t * Internal flag to temporary disable rendering. See the usage in the {@link #_disableRendering}.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._renderingDisabled = false;\n\n\t\t/**\n\t\t * Internal flag that disables rendering when there are no changes since the last rendering.\n\t\t * It stores information about changed selection and changed elements from attached document roots.\n\t\t *\n\t\t * @private\n\t\t * @type {Boolean}\n\t\t */\n\t\tthis._hasChangedSinceTheLastRendering = false;\n\n\t\t/**\n\t\t * DowncastWriter instance used in {@link #change change method} callbacks.\n\t\t *\n\t\t * @private\n\t\t * @type {module:engine/view/downcastwriter~DowncastWriter}\n\t\t */\n\t\tthis._writer = new DowncastWriter( this.document );\n\n\t\t// Add default observers.\n\t\tthis.addObserver( MutationObserver );\n\t\tthis.addObserver( SelectionObserver );\n\t\tthis.addObserver( FocusObserver );\n\t\tthis.addObserver( KeyObserver );\n\t\tthis.addObserver( FakeSelectionObserver );\n\t\tthis.addObserver( CompositionObserver );\n\n\t\tif ( env.isAndroid ) {\n\t\t\tthis.addObserver( InputObserver );\n\t\t}\n\n\t\t// Inject quirks handlers.\n\t\tinjectQuirksHandling( this );\n\t\tinjectUiElementHandling( this );\n\n\t\t// Use 'normal' priority so that rendering is performed as first when using that priority.\n\t\tthis.on( 'render', () => {\n\t\t\tthis._render();\n\n\t\t\t// Informs that layout has changed after render.\n\t\t\tthis.document.fire( 'layoutChanged' );\n\n\t\t\t// Reset the `_hasChangedSinceTheLastRendering` flag after rendering.\n\t\t\tthis._hasChangedSinceTheLastRendering = false;\n\t\t} );\n\n\t\t// Listen to the document selection changes directly.\n\t\tthis.listenTo( this.document.selection, 'change', () => {\n\t\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\t} );\n\t}\n\n\t/**\n\t * Attaches a DOM root element to the view element and enable all observers on that element.\n\t * Also {@link module:engine/view/renderer~Renderer#markToSync mark element} to be synchronized\n\t * with the view what means that all child nodes will be removed and replaced with content of the view root.\n\t *\n\t * This method also will change view element name as the same as tag name of given dom root.\n\t * Name is always transformed to lower case.\n\t *\n\t * **Note:** Use {@link #detachDomRoot `detachDomRoot()`} to revert this action.\n\t *\n\t * @param {Element} domRoot DOM root element.\n\t * @param {String} [name='main'] Name of the root.\n\t */\n\tattachDomRoot( domRoot, name = 'main' ) {\n\t\tconst viewRoot = this.document.getRoot( name );\n\n\t\t// Set view root name the same as DOM root tag name.\n\t\tviewRoot._name = domRoot.tagName.toLowerCase();\n\n\t\tconst initialDomRootAttributes = {};\n\n\t\t// 1. Copy and cache the attributes to remember the state of the element before attaching.\n\t\t// The cached attributes will be restored in detachDomRoot() so the element goes to the\n\t\t// clean state as if the editing view never used it.\n\t\t// 2. Apply the attributes using the view writer, so they all go under the control of the engine.\n\t\t// The editing view takes over the attribute management completely because various\n\t\t// features (e.g. addPlaceholder()) require dynamic changes of those attributes and they\n\t\t// cannot be managed by the engine and the UI library at the same time.\n\t\tfor ( const { name, value } of Array.from( domRoot.attributes ) ) {\n\t\t\tinitialDomRootAttributes[ name ] = value;\n\n\t\t\t// Do not use writer.setAttribute() for the class attribute. The EditableUIView class\n\t\t\t// and its descendants could have already set some using the writer.addClass() on the view\n\t\t\t// document root. They haven't been rendered yet so they are not present in the DOM root.\n\t\t\t// Using writer.setAttribute( 'class', ... ) would override them completely.\n\t\t\tif ( name === 'class' ) {\n\t\t\t\tthis._writer.addClass( value.split( ' ' ), viewRoot );\n\t\t\t} else {\n\t\t\t\tthis._writer.setAttribute( name, value, viewRoot );\n\t\t\t}\n\t\t}\n\n\t\tthis._initialDomRootAttributes.set( domRoot, initialDomRootAttributes );\n\n\t\tconst updateContenteditableAttribute = () => {\n\t\t\tthis._writer.setAttribute( 'contenteditable', !viewRoot.isReadOnly, viewRoot );\n\n\t\t\tif ( viewRoot.isReadOnly ) {\n\t\t\t\tthis._writer.addClass( 'ck-read-only', viewRoot );\n\t\t\t} else {\n\t\t\t\tthis._writer.removeClass( 'ck-read-only', viewRoot );\n\t\t\t}\n\t\t};\n\n\t\t// Set initial value.\n\t\tupdateContenteditableAttribute();\n\n\t\tthis.domRoots.set( name, domRoot );\n\t\tthis.domConverter.bindElements( domRoot, viewRoot );\n\t\tthis._renderer.markToSync( 'children', viewRoot );\n\t\tthis._renderer.markToSync( 'attributes', viewRoot );\n\t\tthis._renderer.domDocuments.add( domRoot.ownerDocument );\n\n\t\tviewRoot.on( 'change:children', ( evt, node ) => this._renderer.markToSync( 'children', node ) );\n\t\tviewRoot.on( 'change:attributes', ( evt, node ) => this._renderer.markToSync( 'attributes', node ) );\n\t\tviewRoot.on( 'change:text', ( evt, node ) => this._renderer.markToSync( 'text', node ) );\n\t\tviewRoot.on( 'change:isReadOnly', () => this.change( updateContenteditableAttribute ) );\n\n\t\tviewRoot.on( 'change', () => {\n\t\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\t} );\n\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.observe( domRoot, name );\n\t\t}\n\t}\n\n\t/**\n\t * Detaches a DOM root element from the view element and restores its attributes to the state before\n\t * {@link #attachDomRoot `attachDomRoot()`}.\n\t *\n\t * @param {String} name Name of the root to detach.\n\t */\n\tdetachDomRoot( name ) {\n\t\tconst domRoot = this.domRoots.get( name );\n\n\t\t// Remove all root attributes so the DOM element is \"bare\".\n\t\tArray.from( domRoot.attributes ).forEach( ( { name } ) => domRoot.removeAttribute( name ) );\n\n\t\tconst initialDomRootAttributes = this._initialDomRootAttributes.get( domRoot );\n\n\t\t// Revert all view root attributes back to the state before attachDomRoot was called.\n\t\tfor ( const attribute in initialDomRootAttributes ) {\n\t\t\tdomRoot.setAttribute( attribute, initialDomRootAttributes[ attribute ] );\n\t\t}\n\n\t\tthis.domRoots.delete( name );\n\t\tthis.domConverter.unbindDomElement( domRoot );\n\t}\n\n\t/**\n\t * Gets DOM root element.\n\t *\n\t * @param {String} [name='main'] Name of the root.\n\t * @returns {Element} DOM root element instance.\n\t */\n\tgetDomRoot( name = 'main' ) {\n\t\treturn this.domRoots.get( name );\n\t}\n\n\t/**\n\t * Creates observer of the given type if not yet created, {@link module:engine/view/observer/observer~Observer#enable enables} it\n\t * and {@link module:engine/view/observer/observer~Observer#observe attaches} to all existing and future\n\t * {@link #domRoots DOM roots}.\n\t *\n\t * Note: Observers are recognized by their constructor (classes). A single observer will be instantiated and used only\n\t * when registered for the first time. This means that features and other components can register a single observer\n\t * multiple times without caring whether it has been already added or not.\n\t *\n\t * @param {Function} Observer The constructor of an observer to add.\n\t * Should create an instance inheriting from {@link module:engine/view/observer/observer~Observer}.\n\t * @returns {module:engine/view/observer/observer~Observer} Added observer instance.\n\t */\n\taddObserver( Observer ) {\n\t\tlet observer = this._observers.get( Observer );\n\n\t\tif ( observer ) {\n\t\t\treturn observer;\n\t\t}\n\n\t\tobserver = new Observer( this );\n\n\t\tthis._observers.set( Observer, observer );\n\n\t\tfor ( const [ name, domElement ] of this.domRoots ) {\n\t\t\tobserver.observe( domElement, name );\n\t\t}\n\n\t\tobserver.enable();\n\n\t\treturn observer;\n\t}\n\n\t/**\n\t * Returns observer of the given type or `undefined` if such observer has not been added yet.\n\t *\n\t * @param {Function} Observer The constructor of an observer to get.\n\t * @returns {module:engine/view/observer/observer~Observer|undefined} Observer instance or undefined.\n\t */\n\tgetObserver( Observer ) {\n\t\treturn this._observers.get( Observer );\n\t}\n\n\t/**\n\t * Disables all added observers.\n\t */\n\tdisableObservers() {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.disable();\n\t\t}\n\t}\n\n\t/**\n\t * Enables all added observers.\n\t */\n\tenableObservers() {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.enable();\n\t\t}\n\t}\n\n\t/**\n\t * Scrolls the page viewport and {@link #domRoots} with their ancestors to reveal the\n\t * caret, if not already visible to the user.\n\t */\n\tscrollToTheSelection() {\n\t\tconst range = this.document.selection.getFirstRange();\n\n\t\tif ( range ) {\n\t\t\tscrollViewportToShowTarget( {\n\t\t\t\ttarget: this.domConverter.viewRangeToDom( range ),\n\t\t\t\tviewportOffset: 20\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * It will focus DOM element representing {@link module:engine/view/editableelement~EditableElement EditableElement}\n\t * that is currently having selection inside.\n\t */\n\tfocus() {\n\t\tif ( !this.document.isFocused ) {\n\t\t\tconst editable = this.document.selection.editableElement;\n\n\t\t\tif ( editable ) {\n\t\t\t\tthis.domConverter.focus( editable );\n\t\t\t\tthis.forceRender();\n\t\t\t} else {\n\t\t\t\t// Before focusing view document, selection should be placed inside one of the view's editables.\n\t\t\t\t// Normally its selection will be converted from model document (which have default selection), but\n\t\t\t\t// when using view document on its own, we need to manually place selection before focusing it.\n\t\t\t\t//\n\t\t\t\t// @if CK_DEBUG // console.warn( 'There is no selection in any editable to focus.' );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * The `change()` method is the primary way of changing the view. You should use it to modify any node in the view tree.\n\t * It makes sure that after all changes are made the view is rendered to the DOM (assuming that the view will be changed\n\t * inside the callback). It prevents situations when the DOM is updated when the view state is not yet correct. It allows\n\t * to nest calls one inside another and still performs a single rendering after all those changes are made.\n\t * It also returns the return value of its callback.\n\t *\n\t *\t\tconst text = view.change( writer => {\n\t *\t\t\tconst newText = writer.createText( 'foo' );\n\t *\t\t\twriter.insert( position1, newText );\n\t *\n\t *\t\t\tview.change( writer => {\n\t *\t\t\t\twriter.insert( position2, writer.createText( 'bar' ) );\n\t *\t\t\t} );\n\t *\n\t * \t\t\twriter.remove( range );\n\t *\n\t * \t\t\treturn newText;\n\t *\t\t} );\n\t *\n\t * When the outermost change block is done and rendering to the DOM is over the\n\t * {@link module:engine/view/view~View#event:render `View#render`} event is fired.\n\t *\n\t * This method throws a `applying-view-changes-on-rendering` error when\n\t * the change block is used after rendering to the DOM has started.\n\t *\n\t * @param {Function} callback Callback function which may modify the view.\n\t * @returns {*} Value returned by the callback.\n\t */\n\tchange( callback ) {\n\t\tif ( this.isRenderingInProgress || this._postFixersInProgress ) {\n\t\t\t/**\n\t\t\t * Thrown when there is an attempt to make changes to the view tree when it is in incorrect state. This may\n\t\t\t * cause some unexpected behaviour and inconsistency between the DOM and the view.\n\t\t\t * This may be caused by:\n\t\t\t *\n\t\t\t * * calling {@link #change} or {@link #forceRender} during rendering process,\n\t\t\t * * calling {@link #change} or {@link #forceRender} inside of\n\t\t\t * {@link module:engine/view/document~Document#registerPostFixer post-fixer function}.\n\t\t\t *\n\t\t\t * @error cannot-change-view-tree\n\t\t\t */\n\t\t\tthrow new CKEditorError(\n\t\t\t\t'cannot-change-view-tree',\n\t\t\t\tthis\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\t// Recursive call to view.change() method - execute listener immediately.\n\t\t\tif ( this._ongoingChange ) {\n\t\t\t\treturn callback( this._writer );\n\t\t\t}\n\n\t\t\t// This lock will assure that all recursive calls to view.change() will end up in same block - one \"render\"\n\t\t\t// event for all nested calls.\n\t\t\tthis._ongoingChange = true;\n\t\t\tconst callbackResult = callback( this._writer );\n\t\t\tthis._ongoingChange = false;\n\n\t\t\t// This lock is used by editing controller to render changes from outer most model.change() once. As plugins might call\n\t\t\t// view.change() inside model.change() block - this will ensures that postfixers and rendering are called once after all\n\t\t\t// changes. Also, we don't need to render anything if there're no changes since last rendering.\n\t\t\tif ( !this._renderingDisabled && this._hasChangedSinceTheLastRendering ) {\n\t\t\t\tthis._postFixersInProgress = true;\n\t\t\t\tthis.document._callPostFixers( this._writer );\n\t\t\t\tthis._postFixersInProgress = false;\n\n\t\t\t\tthis.fire( 'render' );\n\t\t\t}\n\n\t\t\treturn callbackResult;\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 * Forces rendering {@link module:engine/view/document~Document view document} to DOM. If any view changes are\n\t * currently in progress, rendering will start after all {@link #change change blocks} are processed.\n\t *\n\t * Note that this method is dedicated for special cases. All view changes should be wrapped in the {@link #change}\n\t * block and the view will automatically check whether it needs to render DOM or not.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `applying-view-changes-on-rendering` when\n\t * trying to re-render when rendering to DOM has already started.\n\t */\n\tforceRender() {\n\t\tthis._hasChangedSinceTheLastRendering = true;\n\t\tthis.change( () => {} );\n\t}\n\n\t/**\n\t * Destroys this instance. Makes sure that all observers are destroyed and listeners removed.\n\t */\n\tdestroy() {\n\t\tfor ( const observer of this._observers.values() ) {\n\t\t\tobserver.destroy();\n\t\t}\n\n\t\tthis.document.destroy();\n\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param {module:engine/view/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tcreatePositionAt( itemOrPosition, offset ) {\n\t\treturn Position._createAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item after which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tcreatePositionAfter( item ) {\n\t\treturn Position._createAfter( item );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item before which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tcreatePositionBefore( item ) {\n\t\treturn Position._createBefore( item );\n\t}\n\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param {module:engine/view/position~Position} start Start position.\n\t * @param {module:engine/view/position~Position} [end] End position. If not set, range will be collapsed at `start` position.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRange( start, end ) {\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t *\n\t * @param {module:engine/view/item~Item} item\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRangeOn( item ) {\n\t\treturn Range._createOn( item );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param {module:engine/view/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRangeIn( element ) {\n\t\treturn Range._createIn( element );\n\t}\n\n\t/**\n\t Creates new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * \t\t// Creates empty selection without ranges.\n\t *\t\tconst selection = view.createSelection();\n\t *\n\t *\t\t// Creates selection at the given range.\n\t *\t\tconst range = view.createRange( start, end );\n\t *\t\tconst selection = view.createSelection( range );\n\t *\n\t *\t\t// Creates selection at the given ranges\n\t * \t\tconst ranges = [ view.createRange( start1, end2 ), view.createRange( star2, end2 ) ];\n\t *\t\tconst selection = view.createSelection( ranges );\n\t *\n\t *\t\t// Creates selection from the other selection.\n\t *\t\tconst otherSelection = view.createSelection();\n\t *\t\tconst selection = view.createSelection( otherSelection );\n\t *\n\t *\t\t// Creates selection from the document selection.\n\t *\t\tconst selection = view.createSelection( editor.editing.view.document.selection );\n\t *\n\t * \t\t// Creates selection at the given position.\n\t *\t\tconst position = view.createPositionFromPath( root, path );\n\t *\t\tconst selection = view.createSelection( position );\n\t *\n\t *\t\t// Creates collapsed selection at the position of given item and offset.\n\t *\t\tconst paragraph = view.createContainerElement( 'paragraph' );\n\t *\t\tconst selection = view.createSelection( paragraph, offset );\n\t *\n\t *\t\t// Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t *\t\t// first child of that element and ends after the last child of that element.\n\t *\t\tconst selection = view.createSelection( paragraph, 'in' );\n\t *\n\t *\t\t// Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t *\t\t// just after the item.\n\t *\t\tconst selection = view.createSelection( paragraph, 'on' );\n\t *\n\t * `Selection`'s factory method allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Creates backward selection.\n\t *\t\tconst selection = view.createSelection( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tconst selection = view.createSelection( range, { fake: true, label: 'foo' } );\n\t *\n\t * @param {module:engine/view/selection~Selectable} [selectable=null]\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Offset or place when selectable is an `Item`.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t * @returns {module:engine/view/selection~Selection}\n\t */\n\tcreateSelection( selectable, placeOrOffset, options ) {\n\t\treturn new Selection( selectable, placeOrOffset, options );\n\t}\n\n\t/**\n\t * Disables or enables rendering. If the flag is set to `true` then the rendering will be disabled.\n\t * If the flag is set to `false` and if there was some change in the meantime, then the rendering action will be performed.\n\t *\n\t * @protected\n\t * @param {Boolean} flag A flag indicates whether the rendering should be disabled.\n\t */\n\t_disableRendering( flag ) {\n\t\tthis._renderingDisabled = flag;\n\n\t\tif ( flag == false ) {\n\t\t\t// Render when you stop blocking rendering.\n\t\t\tthis.change( () => {} );\n\t\t}\n\t}\n\n\t/**\n\t * Renders all changes. In order to avoid triggering the observers (e.g. mutations) all observers are disabled\n\t * before rendering and re-enabled after that.\n\t *\n\t * @private\n\t */\n\t_render() {\n\t\tthis.isRenderingInProgress = true;\n\t\tthis.disableObservers();\n\t\tthis._renderer.render();\n\t\tthis.enableObservers();\n\t\tthis.isRenderingInProgress = false;\n\t}\n\n\t/**\n\t * Fired after a topmost {@link module:engine/view/view~View#change change block} and all\n\t * {@link module:engine/view/document~Document#registerPostFixer post-fixers} are executed.\n\t *\n\t * Actual rendering is performed as a first listener on 'normal' priority.\n\t *\n\t *\t\tview.on( 'render', () => {\n\t *\t\t\t// Rendering to the DOM is complete.\n\t *\t\t} );\n\t *\n\t * This event is useful when you want to update interface elements after the rendering, e.g. position of the\n\t * balloon panel. If you wants to change view structure use\n\t * {@link module:engine/view/document~Document#registerPostFixer post-fixers}.\n\t *\n\t * @event module:engine/view/view~View#event:render\n\t */\n}\n\nmix( View, ObservableMixin );\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 engine/view/uielement\n */\n\nimport Element from './element';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\nimport Node from './node';\nimport { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';\n\n/**\n * UI element class. It should be used to represent editing UI which needs to be injected into the editing view\n * If possible, you should keep your UI outside the editing view. However, if that is not possible,\n * UI elements can be used.\n *\n * How a UI element is rendered is in your control (you pass a callback to\n * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`}).\n * The editor will ignore your UI element – the selection cannot be placed in it, it is skipped (invisible) when\n * the user modifies the selection by using arrow keys and the editor does not listen to any mutations which\n * happen inside your UI elements.\n *\n * The limitation is that you cannot convert a model element to a UI element. UI elements need to be\n * created for {@link module:engine/model/markercollection~Marker markers} or as additinal elements\n * inside normal {@link module:engine/view/containerelement~ContainerElement container elements}.\n *\n * To create a new UI element use the\n * {@link module:engine/view/downcastwriter~DowncastWriter#createUIElement `downcastWriter#createUIElement()`} method.\n *\n * @extends module:engine/view/element~Element\n */\nexport default class UIElement extends Element {\n\t/**\n\t * Creates new instance of UIElement.\n\t *\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-uielement-cannot-add` when third parameter is passed,\n\t * to inform that usage of UIElement is incorrect (adding child nodes to UIElement is forbidden).\n\t *\n\t * @see module:engine/view/downcastwriter~DowncastWriter#createUIElement\n\t * @protected\n\t * @param {module:engine/view/document~Document} document The document instance to which this element belongs.\n\t * @param {String} name Node name.\n\t * @param {Object|Iterable} [attributes] Collection of attributes.\n\t * @param {module:engine/view/node~Node|Iterable.} [children]\n\t * A list of nodes to be inserted into created element.\n\t */\n\tconstructor( document, name, attributes, children ) {\n\t\tsuper( document, name, attributes, children );\n\n\t\t// Override the default of the base class.\n\t\tthis._isAllowedInsideAttributeElement = true;\n\n\t\t/**\n\t\t * Returns `null` because filler is not needed for UIElements.\n\t\t *\n\t\t * @method #getFillerOffset\n\t\t * @returns {null} Always returns null.\n\t\t */\n\t\tthis.getFillerOffset = getFillerOffset;\n\t}\n\n\t/**\n\t * Checks whether this object is of the given.\n\t *\n\t *\t\tuiElement.is( 'uiElement' ); // -> true\n\t *\t\tuiElement.is( 'element' ); // -> true\n\t *\t\tuiElement.is( 'node' ); // -> true\n\t *\t\tuiElement.is( 'view:uiElement' ); // -> true\n\t *\t\tuiElement.is( 'view:element' ); // -> true\n\t *\t\tuiElement.is( 'view:node' ); // -> true\n\t *\n\t *\t\tuiElement.is( 'model:element' ); // -> false\n\t *\t\tuiElement.is( 'documentFragment' ); // -> false\n\t *\n\t * Assuming that the object being checked is an ui element, you can also check its\n\t * {@link module:engine/view/uielement~UIElement#name name}:\n\t *\n\t *\t\tuiElement.is( 'element', 'span' ); // -> true if this is a span ui element\n\t *\t\tuiElement.is( 'uiElement', 'span' ); // -> same as above\n\t *\t\ttext.is( 'element', 'span' ); -> false\n\t *\n\t * {@link module:engine/view/node~Node#is Check the entire list of view objects} which implement the `is()` method.\n\t *\n\t * @param {String} type Type to check.\n\t * @param {String} [name] Element name.\n\t * @returns {Boolean}\n\t */\n\tis( type, name = null ) {\n\t\tif ( !name ) {\n\t\t\treturn type === 'uiElement' || type === 'view:uiElement' ||\n\t\t\t\t// From super.is(). This is highly utilised method and cannot call super. See ckeditor/ckeditor5#6529.\n\t\t\t\ttype === 'element' || type === 'view:element' ||\n\t\t\t\ttype === 'node' || type === 'view:node';\n\t\t} else {\n\t\t\treturn name === this.name && (\n\t\t\t\ttype === 'uiElement' || type === 'view:uiElement' ||\n\t\t\t\ttype === 'element' || type === 'view:element'\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Overrides {@link module:engine/view/element~Element#_insertChild} method.\n\t * Throws {@link module:utils/ckeditorerror~CKEditorError CKEditorError} `view-uielement-cannot-add` to prevent adding any child nodes\n\t * to UIElement.\n\t *\n\t * @protected\n\t */\n\t_insertChild( index, nodes ) {\n\t\tif ( nodes && ( nodes instanceof Node || Array.from( nodes ).length > 0 ) ) {\n\t\t\t/**\n\t\t\t * Cannot add children to {@link module:engine/view/uielement~UIElement}.\n\t\t\t *\n\t\t\t * @error view-uielement-cannot-add\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'view-uielement-cannot-add', this );\n\t\t}\n\t}\n\n\t/**\n\t * Renders this {@link module:engine/view/uielement~UIElement} to DOM. This method is called by\n\t * {@link module:engine/view/domconverter~DomConverter}.\n\t * Do not use inheritance to create custom rendering method, replace `render()` method instead:\n\t *\n\t *\t\tconst myUIElement = downcastWriter.createUIElement( 'span' );\n\t *\t\tmyUIElement.render = function( domDocument ) {\n\t *\t\t\tconst domElement = this.toDomElement( domDocument );\n\t *\t\t\tdomElement.innerHTML = 'this is ui element';\n\t *\n\t *\t\t\treturn domElement;\n\t *\t\t};\n\t *\n\t * If changes in your UI element should trigger some editor UI update you should call\n\t * the {@link module:core/editor/editorui~EditorUI#update `editor.ui.update()`} method\n\t * after rendering your UI element.\n\t *\n\t * @param {Document} domDocument\n\t * @returns {HTMLElement}\n\t */\n\trender( domDocument ) {\n\t\treturn this.toDomElement( domDocument );\n\t}\n\n\t/**\n\t * Creates DOM element based on this view UIElement.\n\t * Note that each time this method is called new DOM element is created.\n\t *\n\t * @param {Document} domDocument\n\t * @returns {HTMLElement}\n\t */\n\ttoDomElement( domDocument ) {\n\t\tconst domElement = domDocument.createElement( this.name );\n\n\t\tfor ( const key of this.getAttributeKeys() ) {\n\t\t\tdomElement.setAttribute( key, this.getAttribute( key ) );\n\t\t}\n\n\t\treturn domElement;\n\t}\n}\n\n/**\n * This function injects UI element handling to the given {@link module:engine/view/document~Document document}.\n *\n * A callback is added to {@link module:engine/view/document~Document#event:keydown document keydown event}.\n * The callback handles the situation when right arrow key is pressed and selection is collapsed before a UI element.\n * Without this handler, it would be impossible to \"jump over\" UI element using right arrow key.\n *\n * @param {module:engine/view/view~View} view View controller to which the quirks handling will be injected.\n */\nexport function injectUiElementHandling( view ) {\n\tview.document.on( 'keydown', ( evt, data ) => jumpOverUiElement( evt, data, view.domConverter ) );\n}\n\n// Returns `null` because block filler is not needed for UIElements.\n//\n// @returns {null}\nfunction getFillerOffset() {\n\treturn null;\n}\n\n// Selection cannot be placed in a `UIElement`. Whenever it is placed there, it is moved before it. This\n// causes a situation when it is impossible to jump over `UIElement` using right arrow key, because the selection\n// ends up in ui element (in DOM) and is moved back to the left. This handler fixes this situation.\nfunction jumpOverUiElement( evt, data, domConverter ) {\n\tif ( data.keyCode == keyCodes.arrowright ) {\n\t\tconst domSelection = data.domTarget.ownerDocument.defaultView.getSelection();\n\t\tconst domSelectionCollapsed = domSelection.rangeCount == 1 && domSelection.getRangeAt( 0 ).collapsed;\n\n\t\t// Jump over UI element if selection is collapsed or shift key is pressed. These are the cases when selection would extend.\n\t\tif ( domSelectionCollapsed || data.shiftKey ) {\n\t\t\tconst domParent = domSelection.focusNode;\n\t\t\tconst domOffset = domSelection.focusOffset;\n\n\t\t\tconst viewPosition = domConverter.domPositionToView( domParent, domOffset );\n\n\t\t\t// In case if dom element is not converted to view or is not mapped or something. Happens for example in some tests.\n\t\t\tif ( viewPosition === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Skip all following ui elements.\n\t\t\tlet jumpedOverAnyUiElement = false;\n\n\t\t\tconst nextViewPosition = viewPosition.getLastMatchingPosition( value => {\n\t\t\t\tif ( value.item.is( 'uiElement' ) ) {\n\t\t\t\t\t// Remember that there was at least one ui element.\n\t\t\t\t\tjumpedOverAnyUiElement = true;\n\t\t\t\t}\n\n\t\t\t\t// Jump over ui elements, jump over empty attribute elements, move up from inside of attribute element.\n\t\t\t\tif ( value.item.is( 'uiElement' ) || value.item.is( 'attributeElement' ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// Don't jump over text or don't get out of container element.\n\t\t\t\treturn false;\n\t\t\t} );\n\n\t\t\t// If anything has been skipped, fix position.\n\t\t\t// This `if` could be possibly omitted but maybe it is better not to mess with DOM selection if not needed.\n\t\t\tif ( jumpedOverAnyUiElement ) {\n\t\t\t\tconst newDomPosition = domConverter.viewPositionToDom( nextViewPosition );\n\n\t\t\t\tif ( domSelectionCollapsed ) {\n\t\t\t\t\t// Selection was collapsed, so collapse it at further position.\n\t\t\t\t\tdomSelection.collapse( newDomPosition.parent, newDomPosition.offset );\n\t\t\t\t} else {\n\t\t\t\t\t// Selection was not collapse, so extend it instead of collapsing.\n\t\t\t\t\tdomSelection.extend( newDomPosition.parent, newDomPosition.offset );\n\t\t\t\t}\n\t\t\t}\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 module:engine/view/upcastwriter\n */\n\nimport DocumentFragment from './documentfragment';\nimport Element from './element';\nimport Text from './text';\nimport { isPlainObject } from 'lodash-es';\nimport Position from './position';\nimport Range from './range';\nimport Selection from './selection';\n\n/**\n * View upcast writer. It provides a set of methods used to manipulate non-semantic view trees.\n *\n * It should be used only while working on a non-semantic view\n * (e.g. a view created from HTML string on paste).\n * To manipulate a view which was or is being downcasted from the the model use the\n * {@link module:engine/view/downcastwriter~DowncastWriter downcast writer}.\n *\n * Read more about changing the view in the {@glink framework/guides/architecture/editing-engine#changing-the-view Changing the view}\n * section of the {@glink framework/guides/architecture/editing-engine Editing engine architecture} guide.\n *\n * Unlike `DowncastWriter`, which is available in the {@link module:engine/view/view~View#change `View#change()`} block,\n * `UpcastWriter` can be created wherever you need it:\n *\n *\t\tconst writer = new UpcastWriter( viewDocument );\n *\t\tconst text = writer.createText( 'foo!' );\n *\n *\t\twriter.appendChild( text, someViewElement );\n */\nexport default class UpcastWriter {\n\t/**\n\t * @param {module:engine/view/document~Document} document The view document instance in which this upcast writer operates.\n\t */\n\tconstructor( document ) {\n\t\t/**\n\t\t * The view document instance in which this upcast writer operates.\n\t\t *\n\t\t * @readonly\n\t\t * @type {module:engine/view/document~Document}\n\t\t */\n\t\tthis.document = document;\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/documentfragment~DocumentFragment} instance.\n\t *\n\t * @param {module:engine/view/node~Node|Iterable.} [children]\n\t * A list of nodes to be inserted into the created document fragment.\n\t * @returns {module:engine/view/documentfragment~DocumentFragment} The created document fragment.\n\t */\n\tcreateDocumentFragment( children ) {\n\t\treturn new DocumentFragment( this.document, children );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/element~Element} instance.\n\t *\n\t * Attributes can be passed in various formats:\n\t *\n\t *\t\tupcastWriter.createElement( 'div', { class: 'editor', contentEditable: 'true' } ); // object\n\t *\t\tupcastWriter.createElement( 'div', [ [ 'class', 'editor' ], [ 'contentEditable', 'true' ] ] ); // map-like iterator\n\t *\t\tupcastWriter.createElement( 'div', mapOfAttributes ); // map\n\t *\n\t * @param {String} name Node name.\n\t * @param {Object|Iterable} [attrs] Collection of attributes.\n\t * @param {module:engine/view/node~Node|Iterable.} [children]\n\t * A list of nodes to be inserted into created element.\n\t * @returns {module:engine/view/element~Element} Created element.\n\t */\n\tcreateElement( name, attrs, children ) {\n\t\treturn new Element( this.document, name, attrs, children );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/text~Text} instance.\n\t *\n\t * @param {String} data The text's data.\n\t * @returns {module:engine/view/text~Text} The created text node.\n\t */\n\tcreateText( data ) {\n\t\treturn new Text( this.document, data );\n\t}\n\n\t/**\n\t * Clones the provided element.\n\t *\n\t * @see module:engine/view/element~Element#_clone\n\t * @param {module:engine/view/element~Element} element Element to be cloned.\n\t * @param {Boolean} [deep=false] If set to `true` clones element and all its children recursively. When set to `false`,\n\t * element will be cloned without any children.\n\t * @returns {module:engine/view/element~Element} Clone of this element.\n\t */\n\tclone( element, deep = false ) {\n\t\treturn element._clone( deep );\n\t}\n\n\t/**\n\t * Appends a child node or a list of child nodes at the end of this node\n\t * and sets the parent of these nodes to this element.\n\t *\n\t * @see module:engine/view/element~Element#_appendChild\n\t * @param {module:engine/view/item~Item|Iterable.} items Items to be inserted.\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} element Element\n\t * to which items will be appended.\n\t * @fires module:engine/view/node~Node#event:change\n\t * @returns {Number} Number of appended nodes.\n\t */\n\tappendChild( items, element ) {\n\t\treturn element._appendChild( items );\n\t}\n\n\t/**\n\t * Inserts a child node or a list of child nodes on the given index and sets the parent of these nodes to\n\t * this element.\n\t *\n\t * @see module:engine/view/element~Element#_insertChild\n\t * @param {Number} index Offset at which nodes should be inserted.\n\t * @param {module:engine/view/item~Item|Iterable.} items Items to be inserted.\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} element Element\n\t * to which items will be inserted.\n\t * @fires module:engine/view/node~Node#event:change\n\t * @returns {Number} Number of inserted nodes.\n\t */\n\tinsertChild( index, items, element ) {\n\t\treturn element._insertChild( index, items );\n\t}\n\n\t/**\n\t * Removes the given number of child nodes starting at the given index and set the parent of these nodes to `null`.\n\t *\n\t * @see module:engine/view/element~Element#_removeChildren\n\t * @param {Number} index Offset from which nodes will be removed.\n\t * @param {Number} howMany Number of nodes to remove.\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} element Element\n\t * which children will be removed.\n\t * @fires module:engine/view/node~Node#event:change\n\t * @returns {Array.} The array containing removed nodes.\n\t */\n\tremoveChildren( index, howMany, element ) {\n\t\treturn element._removeChildren( index, howMany );\n\t}\n\n\t/**\n\t * Removes given element from the view structure. Will not have effect on detached elements.\n\t *\n\t * @param {module:engine/view/element~Element} element Element which will be removed.\n\t * @returns {Array.} The array containing removed nodes.\n\t */\n\tremove( element ) {\n\t\tconst parent = element.parent;\n\n\t\tif ( parent ) {\n\t\t\treturn this.removeChildren( parent.getChildIndex( element ), 1, parent );\n\t\t}\n\n\t\treturn [];\n\t}\n\n\t/**\n\t * Replaces given element with the new one in the view structure. Will not have effect on detached elements.\n\t *\n\t * @param {module:engine/view/element~Element} oldElement Element which will be replaced.\n\t * @param {module:engine/view/element~Element} newElement Element which will be inserted in the place of the old element.\n\t * @returns {Boolean} Whether old element was successfully replaced.\n\t */\n\treplace( oldElement, newElement ) {\n\t\tconst parent = oldElement.parent;\n\n\t\tif ( parent ) {\n\t\t\tconst index = parent.getChildIndex( oldElement );\n\n\t\t\tthis.removeChildren( index, 1, parent );\n\t\t\tthis.insertChild( index, newElement, parent );\n\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Removes given element from view structure and places its children in its position.\n\t * It does nothing if element has no parent.\n\t *\n\t * @param {module:engine/view/element~Element} element Element to unwrap.\n\t */\n\tunwrapElement( element ) {\n\t\tconst parent = element.parent;\n\n\t\tif ( parent ) {\n\t\t\tconst index = parent.getChildIndex( element );\n\n\t\t\tthis.remove( element );\n\t\t\tthis.insertChild( index, element.getChildren(), parent );\n\t\t}\n\t}\n\n\t/**\n\t * Renames element by creating a copy of a given element but with its name changed and then moving contents of the\n\t * old element to the new one.\n\t *\n\t * Since this function creates a new element and removes the given one, the new element is returned to keep reference.\n\t *\n\t * @param {String} newName New element name.\n\t * @param {module:engine/view/element~Element} element Element to be renamed.\n\t * @returns {module:engine/view/element~Element|null} New element or null if the old element\n\t * was not replaced (happens for detached elements).\n\t */\n\trename( newName, element ) {\n\t\tconst newElement = new Element( this.document, newName, element.getAttributes(), element.getChildren() );\n\n\t\treturn this.replace( element, newElement ) ? newElement : null;\n\t}\n\n\t/**\n\t * Adds or overwrites element's attribute with a specified key and value.\n\t *\n\t *\t\twriter.setAttribute( linkElement, 'href', 'http://ckeditor.com' );\n\t *\n\t * @see module:engine/view/element~Element#_setAttribute\n\t * @param {String} key Attribute key.\n\t * @param {String} value Attribute value.\n\t * @param {module:engine/view/element~Element} element Element for which attribute will be set.\n\t */\n\tsetAttribute( key, value, element ) {\n\t\telement._setAttribute( key, value );\n\t}\n\n\t/**\n\t * Removes attribute from the element.\n\t *\n\t *\t\twriter.removeAttribute( linkElement, 'href' );\n\t *\n\t * @see module:engine/view/element~Element#_removeAttribute\n\t * @param {String} key Attribute key.\n\t * @param {module:engine/view/element~Element} element Element from which attribute will be removed.\n\t */\n\tremoveAttribute( key, element ) {\n\t\telement._removeAttribute( key );\n\t}\n\n\t/**\n\t * Adds specified class to the element.\n\t *\n\t *\t\twriter.addClass( linkElement, 'foo' );\n\t *\t\twriter.addClass( linkElement, [ 'foo', 'bar' ] );\n\t *\n\t * @see module:engine/view/element~Element#_addClass\n\t * @param {Array.|String} className Single class name or array of class names which will be added.\n\t * @param {module:engine/view/element~Element} element Element for which class will be added.\n\t */\n\taddClass( className, element ) {\n\t\telement._addClass( className );\n\t}\n\n\t/**\n\t * Removes specified class from the element.\n\t *\n\t *\t\twriter.removeClass( linkElement, 'foo' );\n\t *\t\twriter.removeClass( linkElement, [ 'foo', 'bar' ] );\n\t *\n\t * @see module:engine/view/element~Element#_removeClass\n\t * @param {Array.|String} className Single class name or array of class names which will be removed.\n\t * @param {module:engine/view/element~Element} element Element from which class will be removed.\n\t */\n\tremoveClass( className, element ) {\n\t\telement._removeClass( className );\n\t}\n\n\t/**\n\t * Adds style to the element.\n\t *\n\t *\t\twriter.setStyle( element, 'color', 'red' );\n\t *\t\twriter.setStyle( element, {\n\t *\t\t\tcolor: 'red',\n\t *\t\t\tposition: 'fixed'\n\t *\t\t} );\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#set `StylesMap#set()`} for details.\n\t *\n\t * @see module:engine/view/element~Element#_setStyle\n\t * @param {String|Object} property Property name or object with key - value pairs.\n\t * @param {String} [value] Value to set. This parameter is ignored if object is provided as the first parameter.\n\t * @param {module:engine/view/element~Element} element Element for which style will be added.\n\t */\n\tsetStyle( property, value, element ) {\n\t\tif ( isPlainObject( property ) && element === undefined ) {\n\t\t\telement = value;\n\t\t}\n\t\telement._setStyle( property, value );\n\t}\n\n\t/**\n\t * Removes specified style from the element.\n\t *\n\t *\t\twriter.removeStyle( element, 'color' ); // Removes 'color' style.\n\t *\t\twriter.removeStyle( element, [ 'color', 'border-top' ] ); // Removes both 'color' and 'border-top' styles.\n\t *\n\t * **Note**: This method can work with normalized style names if\n\t * {@link module:engine/controller/datacontroller~DataController#addStyleProcessorRules a particular style processor rule is enabled}.\n\t * See {@link module:engine/view/stylesmap~StylesMap#remove `StylesMap#remove()`} for details.\n\t *\n\t * @see module:engine/view/element~Element#_removeStyle\n\t * @param {Array.|String} property Style property name or names to be removed.\n\t * @param {module:engine/view/element~Element} element Element from which style will be removed.\n\t */\n\tremoveStyle( property, element ) {\n\t\telement._removeStyle( property );\n\t}\n\n\t/**\n\t * Sets a custom property on element. Unlike attributes, custom properties are not rendered to the DOM,\n\t * so they can be used to add special data to elements.\n\t *\n\t * @see module:engine/view/element~Element#_setCustomProperty\n\t * @param {String|Symbol} key Custom property name/key.\n\t * @param {*} value Custom property value to be stored.\n\t * @param {module:engine/view/element~Element} element Element for which custom property will be set.\n\t */\n\tsetCustomProperty( key, value, element ) {\n\t\telement._setCustomProperty( key, value );\n\t}\n\n\t/**\n\t * Removes a custom property stored under the given key.\n\t *\n\t * @see module:engine/view/element~Element#_removeCustomProperty\n\t * @param {String|Symbol} key Name/key of the custom property to be removed.\n\t * @param {module:engine/view/element~Element} element Element from which the custom property will be removed.\n\t * @returns {Boolean} Returns true if property was removed.\n\t */\n\tremoveCustomProperty( key, element ) {\n\t\treturn element._removeCustomProperty( key );\n\t}\n\n\t/**\n\t * Creates position at the given location. The location can be specified as:\n\t *\n\t * * a {@link module:engine/view/position~Position position},\n\t * * parent element and offset (offset defaults to `0`),\n\t * * parent element and `'end'` (sets position at the end of that element),\n\t * * {@link module:engine/view/item~Item view item} and `'before'` or `'after'` (sets position before or after given view item).\n\t *\n\t * This method is a shortcut to other constructors such as:\n\t *\n\t * * {@link #createPositionBefore},\n\t * * {@link #createPositionAfter},\n\t *\n\t * @param {module:engine/view/item~Item|module:engine/model/position~Position} itemOrPosition\n\t * @param {Number|'end'|'before'|'after'} [offset] Offset or one of the flags. Used only when\n\t * first parameter is a {@link module:engine/view/item~Item view item}.\n\t */\n\tcreatePositionAt( itemOrPosition, offset ) {\n\t\treturn Position._createAt( itemOrPosition, offset );\n\t}\n\n\t/**\n\t * Creates a new position after given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item after which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tcreatePositionAfter( item ) {\n\t\treturn Position._createAfter( item );\n\t}\n\n\t/**\n\t * Creates a new position before given view item.\n\t *\n\t * @param {module:engine/view/item~Item} item View item before which the position should be located.\n\t * @returns {module:engine/view/position~Position}\n\t */\n\tcreatePositionBefore( item ) {\n\t\treturn Position._createBefore( item );\n\t}\n\n\t/**\n\t * Creates a range spanning from `start` position to `end` position.\n\t *\n\t * **Note:** This factory method creates it's own {@link module:engine/view/position~Position} instances basing on passed values.\n\t *\n\t * @param {module:engine/view/position~Position} start Start position.\n\t * @param {module:engine/view/position~Position} [end] End position. If not set, range will be collapsed at `start` position.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRange( start, end ) {\n\t\treturn new Range( start, end );\n\t}\n\n\t/**\n\t * Creates a range that starts before given {@link module:engine/view/item~Item view item} and ends after it.\n\t *\n\t * @param {module:engine/view/item~Item} item\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRangeOn( item ) {\n\t\treturn Range._createOn( item );\n\t}\n\n\t/**\n\t * Creates a range inside an {@link module:engine/view/element~Element element} which starts before the first child of\n\t * that element and ends after the last child of that element.\n\t *\n\t * @param {module:engine/view/element~Element} element Element which is a parent for the range.\n\t * @returns {module:engine/view/range~Range}\n\t */\n\tcreateRangeIn( element ) {\n\t\treturn Range._createIn( element );\n\t}\n\n\t/**\n\t * Creates a new {@link module:engine/view/selection~Selection} instance.\n\t *\n\t * \t\t// Creates empty selection without ranges.\n\t *\t\tconst selection = writer.createSelection();\n\t *\n\t *\t\t// Creates selection at the given range.\n\t *\t\tconst range = writer.createRange( start, end );\n\t *\t\tconst selection = writer.createSelection( range );\n\t *\n\t *\t\t// Creates selection at the given ranges\n\t * \t\tconst ranges = [ writer.createRange( start1, end2 ), writer.createRange( star2, end2 ) ];\n\t *\t\tconst selection = writer.createSelection( ranges );\n\t *\n\t *\t\t// Creates selection from the other selection.\n\t *\t\tconst otherSelection = writer.createSelection();\n\t *\t\tconst selection = writer.createSelection( otherSelection );\n\t *\n\t *\t\t// Creates selection from the document selection.\n\t *\t\tconst selection = writer.createSelection( editor.editing.view.document.selection );\n\t *\n\t * \t\t// Creates selection at the given position.\n\t *\t\tconst position = writer.createPositionFromPath( root, path );\n\t *\t\tconst selection = writer.createSelection( position );\n\t *\n\t *\t\t// Creates collapsed selection at the position of given item and offset.\n\t *\t\tconst paragraph = writer.createContainerElement( 'paragraph' );\n\t *\t\tconst selection = writer.createSelection( paragraph, offset );\n\t *\n\t *\t\t// Creates a range inside an {@link module:engine/view/element~Element element} which starts before the\n\t *\t\t// first child of that element and ends after the last child of that element.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'in' );\n\t *\n\t *\t\t// Creates a range on an {@link module:engine/view/item~Item item} which starts before the item and ends\n\t *\t\t// just after the item.\n\t *\t\tconst selection = writer.createSelection( paragraph, 'on' );\n\t *\n\t * `Selection`'s constructor allow passing additional options (`backward`, `fake` and `label`) as the last argument.\n\t *\n\t *\t\t// Creates backward selection.\n\t *\t\tconst selection = writer.createSelection( range, { backward: true } );\n\t *\n\t * Fake selection does not render as browser native selection over selected elements and is hidden to the user.\n\t * This way, no native selection UI artifacts are displayed to the user and selection over elements can be\n\t * represented in other way, for example by applying proper CSS class.\n\t *\n\t * Additionally fake's selection label can be provided. It will be used to describe fake selection in DOM\n\t * (and be properly handled by screen readers).\n\t *\n\t *\t\t// Creates fake selection with label.\n\t *\t\tconst selection = writer.createSelection( range, { fake: true, label: 'foo' } );\n\t *\n\t * @param {module:engine/view/selection~Selectable} [selectable=null]\n\t * @param {Number|'before'|'end'|'after'|'on'|'in'} [placeOrOffset] Offset or place when selectable is an `Item`.\n\t * @param {Object} [options]\n\t * @param {Boolean} [options.backward] Sets this selection instance to be backward.\n\t * @param {Boolean} [options.fake] Sets this selection instance to be marked as `fake`.\n\t * @param {String} [options.label] Label for the fake selection.\n\t * @returns {module:engine/view/selection~Selection}\n\t */\n\tcreateSelection( selectable, placeOrOffset, options ) {\n\t\treturn new Selection( selectable, placeOrOffset, options );\n\t}\n}\n"],"sourceRoot":""}