{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/controller/editingcontroller.js","webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/controller/datacontroller.js"],"names":["EditingController","model","stylesProcessor","_this","this","Object","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_classCallCheck_js__WEBPACK_IMPORTED_MODULE_1__","view","View","mapper","Mapper","downcastDispatcher","DowncastDispatcher","schema","doc","document","selection","markers","listenTo","_disableRendering","priority","change","writer","convertChanges","differ","convertSelection","convertSelectionChange","on","insertText","remove","clearAttributes","convertRangeSelection","convertCollapsedSelection","roots","bindTo","using","root","rootName","viewRoot","RootEditableElement","name","bindElements","destroy","stopListening","mix","ObservableMixin","DataController","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_classCallCheck_js__WEBPACK_IMPORTED_MODULE_11__","upcastDispatcher","UpcastDispatcher","viewDocument","ViewDocument","htmlProcessor","HtmlDataProcessor","processor","_viewWriter","ViewDowncastWriter","convertText","convertToModelFragment","decorate","fire","enqueueChange","autoParagraphEmptyRoots","options","arguments","length","undefined","_options$rootName","_options$trim","trim","_checkIfRootsExists","CKEditorError","getRoot","hasContent","ignoreWhitespaces","stringify","modelElementOrFragment","viewDocumentFragment","toView","toData","viewWriter","clearBindings","modelRange","ModelRange","_createIn","ViewDocumentFragment","conversionApi","convertInsert","_step","is","Array","from","_getMarkersRelativeToElement","_iterator","_createForOfIteratorHelper","s","n","done","_step$value","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_slicedToArray_js__WEBPACK_IMPORTED_MODULE_8__","value","range","convertMarkerAdd","err","e","f","data","_this2","version","initialData","main","keys","_i","_Object$keys","modelRoot","insert","parse","Promise","resolve","_this3","newData","batchType","setSelection","removeSelectionAttribute","getAttributeKeys","_i2","_Object$keys2","createRangeIn","context","toModel","viewElementOrFragment","_this4","convert","callback","pattern","registerRawContentMatcher","rootNames","_step2","_iterator2","getRootNames","includes","element","result","_step3","elementRange","_iterator3","marker","markerRange","getRange","isMarkerCollapsed","isCollapsed","isMarkerAtElementBoundary","start","isEqual","end","push","updatedMarkerRange","getIntersection"],"mappings":"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","file":"js/chunk-a849a216.5c02eb84.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/controller/editingcontroller\n */\n\nimport RootEditableElement from '../view/rooteditableelement';\nimport View from '../view/view';\nimport Mapper from '../conversion/mapper';\nimport DowncastDispatcher from '../conversion/downcastdispatcher';\nimport { clearAttributes, convertCollapsedSelection, convertRangeSelection, insertText, remove } from '../conversion/downcasthelpers';\n\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport { convertSelectionChange } from '../conversion/upcasthelpers';\n\n// @if CK_DEBUG_ENGINE // const { dumpTrees, initDocumentDumping } = require( '../dev-utils/utils' );\n\n/**\n * Controller for the editing pipeline. The editing pipeline controls {@link ~EditingController#model model} rendering,\n * including selection handling. It also creates the {@link ~EditingController#view view} which builds a\n * browser-independent virtualization over the DOM elements. The editing controller also attaches default converters.\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class EditingController {\n\t/**\n\t * Creates an editing controller instance.\n\t *\n\t * @param {module:engine/model/model~Model} model Editing model.\n\t * @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor The styles processor instance.\n\t */\n\tconstructor( model, stylesProcessor ) {\n\t\t/**\n\t\t * Editor model.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/model~Model}\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * Editing view controller.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/view~View}\n\t\t */\n\t\tthis.view = new View( stylesProcessor );\n\n\t\t/**\n\t\t * Mapper which describes the model-view binding.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/mapper~Mapper}\n\t\t */\n\t\tthis.mapper = new Mapper();\n\n\t\t/**\n\t\t * Downcast dispatcher that converts changes from the model to {@link #view the editing view}.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/downcastdispatcher~DowncastDispatcher} #downcastDispatcher\n\t\t */\n\t\tthis.downcastDispatcher = new DowncastDispatcher( {\n\t\t\tmapper: this.mapper,\n\t\t\tschema: model.schema\n\t\t} );\n\n\t\tconst doc = this.model.document;\n\t\tconst selection = doc.selection;\n\t\tconst markers = this.model.markers;\n\n\t\t// When plugins listen on model changes (on selection change, post fixers, etc.) and change the view as a result of\n\t\t// model's change, they might trigger view rendering before the conversion is completed (e.g. before the selection\n\t\t// is converted). We disable rendering for the length of the outermost model change() block to prevent that.\n\t\t//\n\t\t// See https://github.com/ckeditor/ckeditor5-engine/issues/1528\n\t\tthis.listenTo( this.model, '_beforeChanges', () => {\n\t\t\tthis.view._disableRendering( true );\n\t\t}, { priority: 'highest' } );\n\n\t\tthis.listenTo( this.model, '_afterChanges', () => {\n\t\t\tthis.view._disableRendering( false );\n\t\t}, { priority: 'lowest' } );\n\n\t\t// Whenever model document is changed, convert those changes to the view (using model.Document#differ).\n\t\t// Do it on 'low' priority, so changes are converted after other listeners did their job.\n\t\t// Also convert model selection.\n\t\tthis.listenTo( doc, 'change', () => {\n\t\t\tthis.view.change( writer => {\n\t\t\t\tthis.downcastDispatcher.convertChanges( doc.differ, markers, writer );\n\t\t\t\tthis.downcastDispatcher.convertSelection( selection, markers, writer );\n\t\t\t} );\n\t\t}, { priority: 'low' } );\n\n\t\t// Convert selection from the view to the model when it changes in the view.\n\t\tthis.listenTo( this.view.document, 'selectionChange', convertSelectionChange( this.model, this.mapper ) );\n\n\t\t// Attach default model converters.\n\t\tthis.downcastDispatcher.on( 'insert:$text', insertText(), { priority: 'lowest' } );\n\t\tthis.downcastDispatcher.on( 'remove', remove(), { priority: 'low' } );\n\n\t\t// Attach default model selection converters.\n\t\tthis.downcastDispatcher.on( 'selection', clearAttributes(), { priority: 'high' } );\n\t\tthis.downcastDispatcher.on( 'selection', convertRangeSelection(), { priority: 'low' } );\n\t\tthis.downcastDispatcher.on( 'selection', convertCollapsedSelection(), { priority: 'low' } );\n\n\t\t// Binds {@link module:engine/view/document~Document#roots view roots collection} to\n\t\t// {@link module:engine/model/document~Document#roots model roots collection} so creating\n\t\t// model root automatically creates corresponding view root.\n\t\tthis.view.document.roots.bindTo( this.model.document.roots ).using( root => {\n\t\t\t// $graveyard is a special root that has no reflection in the view.\n\t\t\tif ( root.rootName == '$graveyard' ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tconst viewRoot = new RootEditableElement( this.view.document, root.name );\n\n\t\t\tviewRoot.rootName = root.rootName;\n\t\t\tthis.mapper.bindElements( root, viewRoot );\n\n\t\t\treturn viewRoot;\n\t\t} );\n\n\t\t// @if CK_DEBUG_ENGINE // initDocumentDumping( this.model.document );\n\t\t// @if CK_DEBUG_ENGINE // initDocumentDumping( this.view.document );\n\n\t\t// @if CK_DEBUG_ENGINE // dumpTrees( this.model.document, this.model.document.version );\n\t\t// @if CK_DEBUG_ENGINE // dumpTrees( this.view.document, this.model.document.version );\n\n\t\t// @if CK_DEBUG_ENGINE // this.model.document.on( 'change', () => {\n\t\t// @if CK_DEBUG_ENGINE //\tdumpTrees( this.view.document, this.model.document.version );\n\t\t// @if CK_DEBUG_ENGINE // }, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Removes all event listeners attached to the `EditingController`. Destroys all objects created\n\t * by `EditingController` that need to be destroyed.\n\t */\n\tdestroy() {\n\t\tthis.view.destroy();\n\t\tthis.stopListening();\n\t}\n}\n\nmix( EditingController, 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/controller/datacontroller\n */\n\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\nimport ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin';\nimport CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror';\n\nimport Mapper from '../conversion/mapper';\n\nimport DowncastDispatcher from '../conversion/downcastdispatcher';\nimport { insertText } from '../conversion/downcasthelpers';\n\nimport UpcastDispatcher from '../conversion/upcastdispatcher';\nimport { convertText, convertToModelFragment } from '../conversion/upcasthelpers';\n\nimport ViewDocumentFragment from '../view/documentfragment';\nimport ViewDocument from '../view/document';\nimport ViewDowncastWriter from '../view/downcastwriter';\n\nimport ModelRange from '../model/range';\nimport { autoParagraphEmptyRoots } from '../model/utils/autoparagraphing';\nimport HtmlDataProcessor from '../dataprocessor/htmldataprocessor';\n\n/**\n * Controller for the data pipeline. The data pipeline controls how data is retrieved from the document\n * and set inside it. Hence, the controller features two methods which allow to {@link ~DataController#get get}\n * and {@link ~DataController#set set} data of the {@link ~DataController#model model}\n * using given:\n *\n * * {@link module:engine/dataprocessor/dataprocessor~DataProcessor data processor},\n * * downcast converters,\n * * upcast converters.\n *\n * An instance of the data controller is always available in the {@link module:core/editor/editor~Editor#data `editor.data`}\n * property:\n *\n *\t\teditor.data.get( { rootName: 'customRoot' } ); // -> '
Hello!
'\n *\n * @mixes module:utils/observablemixin~ObservableMixin\n */\nexport default class DataController {\n\t/**\n\t * Creates a data controller instance.\n\t *\n\t * @param {module:engine/model/model~Model} model Data model.\n\t * @param {module:engine/view/stylesmap~StylesProcessor} stylesProcessor The styles processor instance.\n\t */\n\tconstructor( model, stylesProcessor ) {\n\t\t/**\n\t\t * Data model.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/model/model~Model}\n\t\t */\n\t\tthis.model = model;\n\n\t\t/**\n\t\t * Mapper used for the conversion. It has no permanent bindings, because they are created when getting data and\n\t\t * cleared directly after the data are converted. However, the mapper is defined as a class property, because\n\t\t * it needs to be passed to the `DowncastDispatcher` as a conversion API.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/mapper~Mapper}\n\t\t */\n\t\tthis.mapper = new Mapper();\n\n\t\t/**\n\t\t * Downcast dispatcher used by the {@link #get get method}. Downcast converters should be attached to it.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/downcastdispatcher~DowncastDispatcher}\n\t\t */\n\t\tthis.downcastDispatcher = new DowncastDispatcher( {\n\t\t\tmapper: this.mapper,\n\t\t\tschema: model.schema\n\t\t} );\n\t\tthis.downcastDispatcher.on( 'insert:$text', insertText(), { priority: 'lowest' } );\n\n\t\t/**\n\t\t * Upcast dispatcher used by the {@link #set set method}. Upcast converters should be attached to it.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/conversion/upcastdispatcher~UpcastDispatcher}\n\t\t */\n\t\tthis.upcastDispatcher = new UpcastDispatcher( {\n\t\t\tschema: model.schema\n\t\t} );\n\n\t\t/**\n\t\t * The view document used by the data controller.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/document~Document}\n\t\t */\n\t\tthis.viewDocument = new ViewDocument( stylesProcessor );\n\n\t\t/**\n\t\t * Styles processor used during the conversion.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/view/stylesmap~StylesProcessor}\n\t\t */\n\t\tthis.stylesProcessor = stylesProcessor;\n\n\t\t/**\n\t\t * Data processor used specifically for HTML conversion.\n\t\t *\n\t\t * @readonly\n\t\t * @member {module:engine/dataprocessor/htmldataprocessor~HtmlDataProcessor} #htmlProcessor\n\t\t */\n\t\tthis.htmlProcessor = new HtmlDataProcessor( this.viewDocument );\n\n\t\t/**\n\t\t * Data processor used during the conversion.\n\t\t * Same instance as {@link #htmlProcessor} by default. Can be replaced at run time to handle different format, e.g. XML or Markdown.\n\t\t *\n\t\t * @member {module:engine/dataprocessor/dataprocessor~DataProcessor} #processor\n\t\t */\n\t\tthis.processor = this.htmlProcessor;\n\n\t\t/**\n\t\t * The view downcast writer just for data conversion purposes, i.e. to modify\n\t\t * the {@link #viewDocument}.\n\t\t *\n\t\t * @private\n\t\t * @readonly\n\t\t * @member {module:engine/view/downcastwriter~DowncastWriter}\n\t\t */\n\t\tthis._viewWriter = new ViewDowncastWriter( this.viewDocument );\n\n\t\t// Define default converters for text and elements.\n\t\t//\n\t\t// Note that if there is no default converter for the element it will be skipped, for instance `foo` will be\n\t\t// converted to nothing. We therefore add `convertToModelFragment` as a last converter so it converts children of that\n\t\t// element to the document fragment and so `foo` will be converted to `foo` if there is no converter for ``.\n\t\tthis.upcastDispatcher.on( 'text', convertText(), { priority: 'lowest' } );\n\t\tthis.upcastDispatcher.on( 'element', convertToModelFragment(), { priority: 'lowest' } );\n\t\tthis.upcastDispatcher.on( 'documentFragment', convertToModelFragment(), { priority: 'lowest' } );\n\n\t\tthis.decorate( 'init' );\n\t\tthis.decorate( 'set' );\n\n\t\t// Fire the `ready` event when the initialization has completed. Such low-level listener gives possibility\n\t\t// to plug into the initialization pipeline without interrupting the initialization flow.\n\t\tthis.on( 'init', () => {\n\t\t\tthis.fire( 'ready' );\n\t\t}, { priority: 'lowest' } );\n\n\t\t// Fix empty roots after DataController is 'ready' (note that init method could be decorated and stopped).\n\t\t// We need to handle this event because initial data could be empty and post-fixer would not get triggered.\n\t\tthis.on( 'ready', () => {\n\t\t\tthis.model.enqueueChange( 'transparent', autoParagraphEmptyRoots );\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Returns the model's data converted by downcast dispatchers attached to {@link #downcastDispatcher} and\n\t * formatted by the {@link #processor data processor}.\n\t *\n\t * @param {Object} [options] Additional configuration for the retrieved data. `DataController` provides two optional\n\t * properties: `rootName` and `trim`. Other properties of this object are specified by various editor features.\n\t * @param {String} [options.rootName='main'] Root name.\n\t * @param {String} [options.trim='empty'] Whether returned data should be trimmed. This option is set to `empty` by default,\n\t * which means whenever editor content is considered empty, an empty string will be returned. To turn off trimming completely\n\t * use `'none'`. In such cases exact content will be returned (for example `` for an empty editor).\n\t * @returns {String} Output data.\n\t */\n\tget( options = {} ) {\n\t\tconst { rootName = 'main', trim = 'empty' } = options;\n\n\t\tif ( !this._checkIfRootsExists( [ rootName ] ) ) {\n\t\t\t/**\n\t\t\t * Cannot get data from a non-existing root. This error is thrown when {@link #get DataController#get() method}\n\t\t\t * is called with non-existent root name. For example, if there is an editor instance with only `main` root,\n\t\t\t * calling {@link #get} like:\n\t\t\t *\n\t\t\t *\t\tdata.get( { rootName: 'root2' } );\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-get-non-existent-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-get-non-existent-root', this );\n\t\t}\n\n\t\tconst root = this.model.document.getRoot( rootName );\n\n\t\tif ( trim === 'empty' && !this.model.hasContent( root, { ignoreWhitespaces: true } ) ) {\n\t\t\treturn '';\n\t\t}\n\n\t\treturn this.stringify( root, options );\n\t}\n\n\t/**\n\t * Returns the content of the given {@link module:engine/model/element~Element model's element} or\n\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the downcast converters\n\t * attached to {@link #downcastDispatcher} and formatted by the {@link #processor data processor}.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} modelElementOrFragment\n\t * Element whose content will be stringified.\n\t * @param {Object} [options] Additional configuration passed to the conversion process.\n\t * @returns {String} Output data.\n\t */\n\tstringify( modelElementOrFragment, options = {} ) {\n\t\t// Model -> view.\n\t\tconst viewDocumentFragment = this.toView( modelElementOrFragment, options );\n\n\t\t// View -> data.\n\t\treturn this.processor.toData( viewDocumentFragment );\n\t}\n\n\t/**\n\t * Returns the content of the given {@link module:engine/model/element~Element model element} or\n\t * {@link module:engine/model/documentfragment~DocumentFragment model document fragment} converted by the downcast\n\t * converters attached to {@link #downcastDispatcher} to a\n\t * {@link module:engine/view/documentfragment~DocumentFragment view document fragment}.\n\t *\n\t * @param {module:engine/model/element~Element|module:engine/model/documentfragment~DocumentFragment} modelElementOrFragment\n\t * Element or document fragment whose content will be converted.\n\t * @param {Object} [options={}] Additional configuration that will be available through\n\t * {@link module:engine/conversion/downcastdispatcher~DowncastConversionApi#options} during the conversion process.\n\t * @returns {module:engine/view/documentfragment~DocumentFragment} Output view DocumentFragment.\n\t */\n\ttoView( modelElementOrFragment, options = {} ) {\n\t\tconst viewDocument = this.viewDocument;\n\t\tconst viewWriter = this._viewWriter;\n\n\t\t// Clear bindings so the call to this method gives correct results.\n\t\tthis.mapper.clearBindings();\n\n\t\t// First, convert elements.\n\t\tconst modelRange = ModelRange._createIn( modelElementOrFragment );\n\t\tconst viewDocumentFragment = new ViewDocumentFragment( viewDocument );\n\n\t\tthis.mapper.bindElements( modelElementOrFragment, viewDocumentFragment );\n\n\t\t// Make additional options available during conversion process through `conversionApi`.\n\t\tthis.downcastDispatcher.conversionApi.options = options;\n\n\t\t// We have no view controller and rendering to DOM in DataController so view.change() block is not used here.\n\t\tthis.downcastDispatcher.convertInsert( modelRange, viewWriter );\n\n\t\t// Convert markers.\n\t\t// For document fragment, simply take the markers assigned to this document fragment.\n\t\t// For model root, all markers in that root will be taken.\n\t\t// For model element, we need to check which markers are intersecting with this element and relatively modify the markers' ranges.\n\t\t// Collapsed markers at element boundary, although considered as not intersecting with the element, will also be returned.\n\t\tconst markers = modelElementOrFragment.is( 'documentFragment' ) ?\n\t\t\tArray.from( modelElementOrFragment.markers ) :\n\t\t\t_getMarkersRelativeToElement( modelElementOrFragment );\n\n\t\tfor ( const [ name, range ] of markers ) {\n\t\t\tthis.downcastDispatcher.convertMarkerAdd( name, range, viewWriter );\n\t\t}\n\n\t\t// Clean `conversionApi`.\n\t\tdelete this.downcastDispatcher.conversionApi.options;\n\n\t\treturn viewDocumentFragment;\n\t}\n\n\t/**\n\t * Sets initial input data parsed by the {@link #processor data processor} and\n\t * converted by the {@link #upcastDispatcher view-to-model converters}.\n\t * Initial data can be set only to document that {@link module:engine/model/document~Document#version} is equal 0.\n\t *\n\t * **Note** This method is {@link module:utils/observablemixin~ObservableMixin#decorate decorated} which is\n\t * used by e.g. collaborative editing plugin that syncs remote data on init.\n\t *\n\t * When data is passed as a string it is initialized on a default `main` root:\n\t *\n\t *\t\tdataController.init( '
Foo
' ); // Initializes data on the `main` root.\n\t *\n\t * To initialize data on a different root or multiple roots at once, object containing `rootName` - `data` pairs should be passed:\n\t *\n\t *\t\tdataController.init( { main: 'Foo
', title: 'Foo
', root2: 'Bar
' } );\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-init-non-existent-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-init-non-existent-root', this );\n\t\t}\n\n\t\tthis.model.enqueueChange( 'transparent', writer => {\n\t\t\tfor ( const rootName of Object.keys( initialData ) ) {\n\t\t\t\tconst modelRoot = this.model.document.getRoot( rootName );\n\t\t\t\twriter.insert( this.parse( initialData[ rootName ], modelRoot ), modelRoot, 0 );\n\t\t\t}\n\t\t} );\n\n\t\treturn Promise.resolve();\n\t}\n\n\t/**\n\t * Sets input data parsed by the {@link #processor data processor} and\n\t * converted by the {@link #upcastDispatcher view-to-model converters}.\n\t * This method can be used any time to replace existing editor data by the new one without clearing the\n\t * {@link module:engine/model/document~Document#history document history}.\n\t *\n\t * This method also creates a batch with all the changes applied. If all you need is to parse data, use\n\t * the {@link #parse} method.\n\t *\n\t * When data is passed as a string it is set on a default `main` root:\n\t *\n\t *\t\tdataController.set( 'Foo
' ); // Sets data on the `main` root.\n\t *\n\t * To set data on a different root or multiple roots at once, object containing `rootName` - `data` pairs should be passed:\n\t *\n\t *\t\tdataController.set( { main: 'Foo
', title: 'Foo
', { batchType: 'default' } ); // Sets data as a new change.\n\t *\n\t * @fires set\n\t * @param {String|Object.Foo
', root2: 'Bar
' } );\n\t\t\t *\n\t\t\t * will throw this error.\n\t\t\t *\n\t\t\t * @error datacontroller-set-non-existent-root\n\t\t\t */\n\t\t\tthrow new CKEditorError( 'datacontroller-set-non-existent-root', this );\n\t\t}\n\n\t\tconst batchType = options.batchType || 'default';\n\n\t\tthis.model.enqueueChange( batchType, writer => {\n\t\t\twriter.setSelection( null );\n\t\t\twriter.removeSelectionAttribute( this.model.document.selection.getAttributeKeys() );\n\n\t\t\tfor ( const rootName of Object.keys( newData ) ) {\n\t\t\t\t// Save to model.\n\t\t\t\tconst modelRoot = this.model.document.getRoot( rootName );\n\n\t\t\t\twriter.remove( writer.createRangeIn( modelRoot ) );\n\t\t\t\twriter.insert( this.parse( newData[ rootName ], modelRoot ), modelRoot, 0 );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Returns the data parsed by the {@link #processor data processor} and then converted by upcast converters\n\t * attached to the {@link #upcastDispatcher}.\n\t *\n\t * @see #set\n\t * @param {String} data Data to parse.\n\t * @param {module:engine/model/schema~SchemaContextDefinition} [context='$root'] Base context in which the view will\n\t * be converted to the model. See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} Parsed data.\n\t */\n\tparse( data, context = '$root' ) {\n\t\t// data -> view\n\t\tconst viewDocumentFragment = this.processor.toView( data );\n\n\t\t// view -> model\n\t\treturn this.toModel( viewDocumentFragment, context );\n\t}\n\n\t/**\n\t * Returns the result of the given {@link module:engine/view/element~Element view element} or\n\t * {@link module:engine/view/documentfragment~DocumentFragment view document fragment} converted by the\n\t * {@link #upcastDispatcher view-to-model converters}, wrapped by {@link module:engine/model/documentfragment~DocumentFragment}.\n\t *\n\t * When marker elements were converted during the conversion process, it will be set as a document fragment's\n\t * {@link module:engine/model/documentfragment~DocumentFragment#markers static markers map}.\n\t *\n\t * @param {module:engine/view/element~Element|module:engine/view/documentfragment~DocumentFragment} viewElementOrFragment\n\t * Element or document fragment whose content will be converted.\n\t * @param {module:engine/model/schema~SchemaContextDefinition} [context='$root'] Base context in which the view will\n\t * be converted to the model. See: {@link module:engine/conversion/upcastdispatcher~UpcastDispatcher#convert}.\n\t * @returns {module:engine/model/documentfragment~DocumentFragment} Output document fragment.\n\t */\n\ttoModel( viewElementOrFragment, context = '$root' ) {\n\t\treturn this.model.change( writer => {\n\t\t\treturn this.upcastDispatcher.convert( viewElementOrFragment, writer, context );\n\t\t} );\n\t}\n\n\t/**\n\t * Adds a style processor normalization rules.\n\t *\n\t * You can implement your own rules as well as use one of the available processor rules:\n\t *\n\t * * background: {@link module:engine/view/styles/background~addBackgroundRules}\n\t * * border: {@link module:engine/view/styles/border~addBorderRules}\n\t * * margin: {@link module:engine/view/styles/margin~addMarginRules}\n\t * * padding: {@link module:engine/view/styles/padding~addPaddingRules}\n\t *\n\t * @param {Function} callback\n\t */\n\taddStyleProcessorRules( callback ) {\n\t\tcallback( this.stylesProcessor );\n\t}\n\n\t/**\n\t * Registers a {@link module:engine/view/matcher~MatcherPattern} on {@link #htmlProcessor htmlProcessor}\n\t * and {@link #processor processor} for view elements whose content should be treated as a raw data\n\t * and not processed during conversion from DOM to view elements.\n\t *\n\t * The raw data can be later accessed by {@link module:engine/view/element~Element#getCustomProperty view element custom property}\n\t * `\"$rawContent\"`.\n\t *\n\t * @param {module:engine/view/matcher~MatcherPattern} pattern Pattern matching all view elements whose content should\n\t * be treated as a raw data.\n\t */\n\tregisterRawContentMatcher( pattern ) {\n\t\t// No need to register the pattern if both `htmlProcessor` and `processor` are the same instances.\n\t\tif ( this.processor && this.processor !== this.htmlProcessor ) {\n\t\t\tthis.processor.registerRawContentMatcher( pattern );\n\t\t}\n\n\t\tthis.htmlProcessor.registerRawContentMatcher( pattern );\n\t}\n\n\t/**\n\t * Removes all event listeners set by the DataController.\n\t */\n\tdestroy() {\n\t\tthis.stopListening();\n\t}\n\n\t/**\n\t * Checks if all provided root names are existing editor roots.\n\t *\n\t * @private\n\t * @param {Array.