{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/view/view.js"],"names":["View","stylesProcessor","_this","this","Object","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_classCallCheck_js__WEBPACK_IMPORTED_MODULE_11__","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","ArrowKeysObserver","env","isAndroid","InputObserver","injectQuirksHandling","injectUiElementHandling","on","_render","fire","listenTo","domRoot","_this2","name","arguments","length","undefined","viewRoot","getRoot","_name","tagName","toLowerCase","initialDomRootAttributes","_i","_Array$from","Array","from","attributes","_Array$from$_i","value","addClass","split","setAttribute","updateContenteditableAttribute","isReadOnly","removeClass","bindElements","markToSync","domDocuments","add","ownerDocument","evt","node","change","_step","_iterator","_createForOfIteratorHelper","values","s","n","done","observer","observe","err","e","f","get","forEach","_ref","removeAttribute","attribute","delete","unbindDomElement","Observer","_step2","_iterator2","_step2$value","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_slicedToArray_js__WEBPACK_IMPORTED_MODULE_3__","domElement","enable","_step3","_iterator3","disable","_step4","_iterator4","range","getFirstRange","scrollViewportToShowTarget","target","viewRangeToDom","viewportOffset","isFocused","editable","editableElement","focus","forceRender","callback","isRenderingInProgress","CKEditorError","callbackResult","_callPostFixers","rethrowUnexpectedError","_step5","_iterator5","destroy","stopListening","itemOrPosition","offset","Position","_createAt","item","_createAfter","_createBefore","start","end","Range","_createOn","element","_createIn","selectable","placeOrOffset","options","Selection","flag","disableObservers","render","enableObservers","mix","ObservableMixin"],"mappings":"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","file":"js/chunk-5a5e452b.cc52a60f.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/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';\nimport ArrowKeysObserver from './observer/arrowkeysobserver';\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\t\tthis.addObserver( ArrowKeysObserver );\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\n\t\t// Trigger re-render if only the focus changed.\n\t\tthis.listenTo( this.document, 'change:isFocused', () => {\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"],"sourceRoot":""}