{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-engine/src/conversion/downcastdispatcher.js"],"names":["DowncastDispatcher","conversionApi","Object","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_classCallCheck_js__WEBPACK_IMPORTED_MODULE_9__","this","assign","dispatcher","_reconversionEventsMapping","Map","differ","markers","writer","_step","_iterator","_createForOfIteratorHelper","getMarkersToRemove","s","n","done","change","value","convertMarkerRemove","name","range","err","e","f","_step2","changes","_mapChangesWithAutomaticReconversion","_iterator2","entry","type","convertInsert","Range","_createFromPositionAndShift","position","length","convertRemove","reconvertElement","element","convertAttribute","attributeKey","attributeOldValue","attributeNewValue","_step3","_iterator3","mapper","flushUnboundMarkerNames","markerName","markerRange","get","getRange","convertMarkerAdd","_step4","_iterator4","getMarkersToAdd","consumable","_createInsertConsumable","_step5","_iterator5","Array","from","map","walkerValueToEventData","data","_convertInsertWithAttributes","_clearConversionApi","fire","key","oldValue","newValue","_createConsumableForRange","concat","_step6","_iterator6","item","itemRange","previousPosition","_testAndFire","elementRange","_createOn","currentView","toViewElement","remove","_step7","convertedViewElement","_iterator7","_createIn","view","elementOrTextProxyToView","root","move","createRangeOn","toViewPosition","Position","_createBefore","unbindViewElement","selection","markersAtSelection","getMarkersAtPosition","getFirstPosition","_createSelectionConsumable","isCollapsed","_i","_markersAtSelection","marker","shouldMarkerChangeBeConverted","test","_step8","_iterator8","getAttributeKeys","getFirstRange","getAttribute","rootName","eventName","Consumable","add","_step9","_iterator9","getItems","modelName","set","_step10","_iterator10","_step11","_iterator11","_step12","_iterator12","_step13","_iterator13","_step14","_iterator14","getEventName","_step15","_iterator15","_step16","itemsToReconvert","Set","updated","_iterator16","getChanges","start","positionParent","parent","textNode","getTextNodeAtPosition","push","getNodeAfterPosition","is","_isReconvertTriggerEvent","has","elementName","modelPosition","ancestors","getAncestors","shift","reverse","hasCustomHandling","some","containsItem","viewElement","getCustomProperty","mappedPosition","mix","EmitterMixin"],"mappings":"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","file":"js/chunk-2d0ab146.314d46e7.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/conversion/downcastdispatcher\n */\n\nimport Consumable from './modelconsumable';\nimport Range from '../model/range';\nimport Position, { getNodeAfterPosition, getTextNodeAtPosition } from '../model/position';\n\nimport EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';\nimport mix from '@ckeditor/ckeditor5-utils/src/mix';\n\n/**\n * The downcast dispatcher is a central point of downcasting (conversion from the model to the view), which is a process of reacting\n * to changes in the model and firing a set of events. Callbacks listening to these events are called converters. The\n * converters' role is to convert the model changes to changes in view (for example, adding view nodes or\n * changing attributes on view elements).\n *\n * During the conversion process, downcast dispatcher fires events basing on the state of the model and prepares\n * data for these events. It is important to understand that the events are connected with the changes done on the model,\n * for example: \"a node has been inserted\" or \"an attribute has changed\". This is in contrary to upcasting (a view-to-model conversion)\n * where you convert the view state (view nodes) to a model tree.\n *\n * The events are prepared basing on a diff created by {@link module:engine/model/differ~Differ Differ}, which buffers them\n * and then passes to the downcast dispatcher as a diff between the old model state and the new model state.\n *\n * Note that because the changes are converted, there is a need to have a mapping between the model structure and the view structure.\n * To map positions and elements during the downcast (a model-to-view conversion), use {@link module:engine/conversion/mapper~Mapper}.\n *\n * Downcast dispatcher fires the following events for model tree changes:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert`} –\n * If a range of nodes was inserted to the model tree.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:remove `remove`} –\n * If a range of nodes was removed from the model tree.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`} –\n * If an attribute was added, changed or removed from a model node.\n *\n * For {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:insert `insert`}\n * and {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute `attribute`},\n * downcast dispatcher generates {@link module:engine/conversion/modelconsumable~ModelConsumable consumables}.\n * These are used to have control over which changes have already been consumed. It is useful when some converters\n * overwrite others or convert multiple changes (for example, it converts an insertion of an element and also converts that\n * element's attributes during the insertion).\n *\n * Additionally, downcast dispatcher fires events for {@link module:engine/model/markercollection~Marker marker} changes:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker} – If a marker was added.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:removeMarker} – If a marker was removed.\n *\n * Note that changing a marker is done through removing the marker from the old range and adding it to the new range,\n * so both events are fired.\n *\n * Finally, downcast dispatcher also handles firing events for the {@link module:engine/model/selection model selection}\n * conversion:\n *\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:selection}\n * – Converts the selection from the model to the view.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:attribute}\n * – Fired for every selection attribute.\n * * {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher#event:addMarker}\n * – Fired for every marker that contains a selection.\n *\n * Unlike the model tree and the markers, the events for selection are not fired for changes but for a selection state.\n *\n * When providing custom listeners for a downcast dispatcher, remember to check whether a given change has not been\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} yet.\n *\n * When providing custom listeners for downcast dispatcher, keep in mind that any callback that has\n * {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed} a value from a consumable and\n * converted the change should also stop the event (for efficiency purposes).\n *\n * When providing custom listeners for downcast dispatcher, remember to use the provided\n * {@link module:engine/view/downcastwriter~DowncastWriter view downcast writer} to apply changes to the view document.\n *\n * You can read more about conversion in the following guides:\n *\n * * {@glink framework/guides/deep-dive/conversion/conversion-introduction Advanced conversion concepts — attributes}\n * * {@glink framework/guides/deep-dive/conversion/conversion-extending-output Extending the editor output }\n * * {@glink framework/guides/deep-dive/conversion/custom-element-conversion Custom element conversion}\n *\n * An example of a custom converter for the downcast dispatcher:\n *\n *\t\t// You will convert inserting a \"paragraph\" model element into the model.\n *\t\tdowncastDispatcher.on( 'insert:paragraph', ( evt, data, conversionApi ) => {\n *\t\t\t// Remember to check whether the change has not been consumed yet and consume it.\n *\t\t\tif ( !conversionApi.consumable.consume( data.item, 'insert' ) ) {\n *\t\t\t\treturn;\n *\t\t\t}\n *\n *\t\t\t// Translate the position in the model to a position in the view.\n *\t\t\tconst viewPosition = conversionApi.mapper.toViewPosition( data.range.start );\n *\n *\t\t\t// Create a

element that will be inserted into the view at the `viewPosition`.\n *\t\t\tconst viewElement = conversionApi.writer.createContainerElement( 'p' );\n *\n *\t\t\t// Bind the newly created view element to the model element so positions will map accordingly in the future.\n *\t\t\tconversionApi.mapper.bindElements( data.item, viewElement );\n *\n *\t\t\t// Add the newly created view element to the view.\n *\t\t\tconversionApi.writer.insert( viewPosition, viewElement );\n *\n *\t\t\t// Remember to stop the event propagation.\n *\t\t\tevt.stop();\n *\t\t} );\n */\nexport default class DowncastDispatcher {\n\t/**\n\t * Creates a downcast dispatcher instance.\n\t *\n\t * @see module:engine/conversion/downcastdispatcher~DowncastConversionApi\n\t * @param {Object} conversionApi Additional properties for an interface that will be passed to events fired\n\t * by the downcast dispatcher.\n\t */\n\tconstructor( conversionApi ) {\n\t\t/**\n\t\t * An interface passed by the dispatcher to the event callbacks.\n\t\t *\n\t\t * @member {module:engine/conversion/downcastdispatcher~DowncastConversionApi}\n\t\t */\n\t\tthis.conversionApi = Object.assign( { dispatcher: this }, conversionApi );\n\n\t\t/**\n\t\t * Maps conversion event names that will trigger element reconversion for a given element name.\n\t\t *\n\t\t * @type {Map}\n\t\t * @private\n\t\t */\n\t\tthis._reconversionEventsMapping = new Map();\n\t}\n\n\t/**\n\t * Takes a {@link module:engine/model/differ~Differ model differ} object with buffered changes and fires conversion basing on it.\n\t *\n\t * @param {module:engine/model/differ~Differ} differ The differ object with buffered changes.\n\t * @param {module:engine/model/markercollection~MarkerCollection} markers Markers connected with the converted model.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer The view writer that should be used to modify the view document.\n\t */\n\tconvertChanges( differ, markers, writer ) {\n\t\t// Before the view is updated, remove markers which have changed.\n\t\tfor ( const change of differ.getMarkersToRemove() ) {\n\t\t\tthis.convertMarkerRemove( change.name, change.range, writer );\n\t\t}\n\n\t\tconst changes = this._mapChangesWithAutomaticReconversion( differ );\n\n\t\t// Convert changes that happened on model tree.\n\t\tfor ( const entry of changes ) {\n\t\t\tif ( entry.type === 'insert' ) {\n\t\t\t\tthis.convertInsert( Range._createFromPositionAndShift( entry.position, entry.length ), writer );\n\t\t\t} else if ( entry.type === 'remove' ) {\n\t\t\t\tthis.convertRemove( entry.position, entry.length, entry.name, writer );\n\t\t\t} else if ( entry.type === 'reconvert' ) {\n\t\t\t\tthis.reconvertElement( entry.element, writer );\n\t\t\t} else {\n\t\t\t\t// Defaults to 'attribute' change.\n\t\t\t\tthis.convertAttribute( entry.range, entry.attributeKey, entry.attributeOldValue, entry.attributeNewValue, writer );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const markerName of this.conversionApi.mapper.flushUnboundMarkerNames() ) {\n\t\t\tconst markerRange = markers.get( markerName ).getRange();\n\n\t\t\tthis.convertMarkerRemove( markerName, markerRange, writer );\n\t\t\tthis.convertMarkerAdd( markerName, markerRange, writer );\n\t\t}\n\n\t\t// After the view is updated, convert markers which have changed.\n\t\tfor ( const change of differ.getMarkersToAdd() ) {\n\t\t\tthis.convertMarkerAdd( change.name, change.range, writer );\n\t\t}\n\t}\n\n\t/**\n\t * Starts a conversion of a range insertion.\n\t *\n\t * For each node in the range, {@link #event:insert `insert` event is fired}. For each attribute on each node,\n\t * {@link #event:attribute `attribute` event is fired}.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @param {module:engine/model/range~Range} range The inserted range.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer The view writer that should be used to modify the view document.\n\t */\n\tconvertInsert( range, writer ) {\n\t\tthis.conversionApi.writer = writer;\n\n\t\t// Create a list of things that can be consumed, consisting of nodes and their attributes.\n\t\tthis.conversionApi.consumable = this._createInsertConsumable( range );\n\n\t\t// Fire a separate insert event for each node and text fragment contained in the range.\n\t\tfor ( const data of Array.from( range ).map( walkerValueToEventData ) ) {\n\t\t\tthis._convertInsertWithAttributes( data );\n\t\t}\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Fires conversion of a single node removal. Fires {@link #event:remove remove event} with provided data.\n\t *\n\t * @param {module:engine/model/position~Position} position Position from which node was removed.\n\t * @param {Number} length Offset size of removed node.\n\t * @param {String} name Name of removed node.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.\n\t */\n\tconvertRemove( position, length, name, writer ) {\n\t\tthis.conversionApi.writer = writer;\n\n\t\tthis.fire( 'remove:' + name, { position, length }, this.conversionApi );\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Starts a conversion of an attribute change on a given `range`.\n\t *\n\t * For each node in the given `range`, {@link #event:attribute attribute event} is fired with the passed data.\n\t *\n\t * @fires attribute\n\t * @param {module:engine/model/range~Range} range Changed range.\n\t * @param {String} key Key of the attribute that has changed.\n\t * @param {*} oldValue Attribute value before the change or `null` if the attribute has not been set before.\n\t * @param {*} newValue New attribute value or `null` if the attribute has been removed.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify view document.\n\t */\n\tconvertAttribute( range, key, oldValue, newValue, writer ) {\n\t\tthis.conversionApi.writer = writer;\n\n\t\t// Create a list with attributes to consume.\n\t\tthis.conversionApi.consumable = this._createConsumableForRange( range, `attribute:${ key }` );\n\n\t\t// Create a separate attribute event for each node in the range.\n\t\tfor ( const value of range ) {\n\t\t\tconst item = value.item;\n\t\t\tconst itemRange = Range._createFromPositionAndShift( value.previousPosition, value.length );\n\t\t\tconst data = {\n\t\t\t\titem,\n\t\t\t\trange: itemRange,\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: oldValue,\n\t\t\t\tattributeNewValue: newValue\n\t\t\t};\n\n\t\t\tthis._testAndFire( `attribute:${ key }`, data );\n\t\t}\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Starts the reconversion of an element. It will:\n\t *\n\t * * Fire an {@link #event:insert `insert` event} for the element to reconvert.\n\t * * Fire an {@link #event:attribute `attribute` event} for element attributes.\n\t *\n\t * This will not reconvert children of the element if they have existing (already converted) views. For newly inserted child elements\n\t * it will behave the same as {@link #convertInsert}.\n\t *\n\t * Element reconversion is defined by the `triggerBy` configuration for the\n\t * {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`} conversion helper.\n\t *\n\t * @fires insert\n\t * @fires attribute\n\t * @param {module:engine/model/element~Element} element The element to be reconverted.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer The view writer that should be used to modify the view document.\n\t */\n\treconvertElement( element, writer ) {\n\t\tconst elementRange = Range._createOn( element );\n\n\t\tthis.conversionApi.writer = writer;\n\n\t\t// Create a list of things that can be consumed, consisting of nodes and their attributes.\n\t\tthis.conversionApi.consumable = this._createInsertConsumable( elementRange );\n\n\t\tconst mapper = this.conversionApi.mapper;\n\t\tconst currentView = mapper.toViewElement( element );\n\n\t\t// Remove the old view but do not remove mapper mappings - those will be used to revive existing elements.\n\t\twriter.remove( currentView );\n\n\t\t// Convert the element - without converting children.\n\t\tthis._convertInsertWithAttributes( {\n\t\t\titem: element,\n\t\t\trange: elementRange\n\t\t} );\n\n\t\tconst convertedViewElement = mapper.toViewElement( element );\n\n\t\t// Iterate over children of reconverted element in order to...\n\t\tfor ( const value of Range._createIn( element ) ) {\n\t\t\tconst { item } = value;\n\n\t\t\tconst view = elementOrTextProxyToView( item, mapper );\n\n\t\t\t// ...either bring back previously converted view...\n\t\t\tif ( view ) {\n\t\t\t\t// Do not move views that are already in converted element - those might be created by the main element converter in case\n\t\t\t\t// when main element converts also its direct children.\n\t\t\t\tif ( view.root !== convertedViewElement.root ) {\n\t\t\t\t\twriter.move(\n\t\t\t\t\t\twriter.createRangeOn( view ),\n\t\t\t\t\t\tmapper.toViewPosition( Position._createBefore( item ) )\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// ... or by converting newly inserted elements.\n\t\t\telse {\n\t\t\t\tthis._convertInsertWithAttributes( walkerValueToEventData( value ) );\n\t\t\t}\n\t\t}\n\n\t\t// After reconversion is done we can unbind the old view.\n\t\tmapper.unbindViewElement( currentView );\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Starts the model selection conversion.\n\t *\n\t * Fires events for a given {@link module:engine/model/selection~Selection selection} to start the selection conversion.\n\t *\n\t * @fires selection\n\t * @fires addMarker\n\t * @fires attribute\n\t * @param {module:engine/model/selection~Selection} selection The selection to convert.\n\t * @param {module:engine/model/markercollection~MarkerCollection} markers Markers connected with the converted model.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify the view document.\n\t */\n\tconvertSelection( selection, markers, writer ) {\n\t\tconst markersAtSelection = Array.from( markers.getMarkersAtPosition( selection.getFirstPosition() ) );\n\n\t\tthis.conversionApi.writer = writer;\n\t\tthis.conversionApi.consumable = this._createSelectionConsumable( selection, markersAtSelection );\n\n\t\tthis.fire( 'selection', { selection }, this.conversionApi );\n\n\t\tif ( !selection.isCollapsed ) {\n\t\t\tthis._clearConversionApi();\n\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const marker of markersAtSelection ) {\n\t\t\tconst markerRange = marker.getRange();\n\n\t\t\tif ( !shouldMarkerChangeBeConverted( selection.getFirstPosition(), marker, this.conversionApi.mapper ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst data = {\n\t\t\t\titem: selection,\n\t\t\t\tmarkerName: marker.name,\n\t\t\t\tmarkerRange\n\t\t\t};\n\n\t\t\tif ( this.conversionApi.consumable.test( selection, 'addMarker:' + marker.name ) ) {\n\t\t\t\tthis.fire( 'addMarker:' + marker.name, data, this.conversionApi );\n\t\t\t}\n\t\t}\n\n\t\tfor ( const key of selection.getAttributeKeys() ) {\n\t\t\tconst data = {\n\t\t\t\titem: selection,\n\t\t\t\trange: selection.getFirstRange(),\n\t\t\t\tattributeKey: key,\n\t\t\t\tattributeOldValue: null,\n\t\t\t\tattributeNewValue: selection.getAttribute( key )\n\t\t\t};\n\n\t\t\t// Do not fire event if the attribute has been consumed.\n\t\t\tif ( this.conversionApi.consumable.test( selection, 'attribute:' + data.attributeKey ) ) {\n\t\t\t\tthis.fire( 'attribute:' + data.attributeKey + ':$text', data, this.conversionApi );\n\t\t\t}\n\t\t}\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Converts the added marker. Fires the {@link #event:addMarker `addMarker`} event for each item\n\t * in the marker's range. If the range is collapsed, a single event is dispatched. See the event description for more details.\n\t *\n\t * @fires addMarker\n\t * @param {String} markerName Marker name.\n\t * @param {module:engine/model/range~Range} markerRange The marker range.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify the view document.\n\t */\n\tconvertMarkerAdd( markerName, markerRange, writer ) {\n\t\t// Do not convert if range is in graveyard.\n\t\tif ( markerRange.root.rootName == '$graveyard' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.conversionApi.writer = writer;\n\n\t\t// In markers' case, event name == consumable name.\n\t\tconst eventName = 'addMarker:' + markerName;\n\n\t\t//\n\t\t// First, fire an event for the whole marker.\n\t\t//\n\t\tconst consumable = new Consumable();\n\t\tconsumable.add( markerRange, eventName );\n\n\t\tthis.conversionApi.consumable = consumable;\n\n\t\tthis.fire( eventName, { markerName, markerRange }, this.conversionApi );\n\n\t\t//\n\t\t// Do not fire events for each item inside the range if the range got consumed.\n\t\t//\n\t\tif ( !consumable.test( markerRange, eventName ) ) {\n\t\t\tthis._clearConversionApi();\n\n\t\t\treturn;\n\t\t}\n\n\t\t//\n\t\t// Then, fire an event for each item inside the marker range.\n\t\t//\n\t\tthis.conversionApi.consumable = this._createConsumableForRange( markerRange, eventName );\n\n\t\tfor ( const item of markerRange.getItems() ) {\n\t\t\t// Do not fire event for already consumed items.\n\t\t\tif ( !this.conversionApi.consumable.test( item, eventName ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst data = { item, range: Range._createOn( item ), markerName, markerRange };\n\n\t\t\tthis.fire( eventName, data, this.conversionApi );\n\t\t}\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Fires the conversion of the marker removal. Fires the {@link #event:removeMarker `removeMarker`} event with the provided data.\n\t *\n\t * @fires removeMarker\n\t * @param {String} markerName Marker name.\n\t * @param {module:engine/model/range~Range} markerRange The marker range.\n\t * @param {module:engine/view/downcastwriter~DowncastWriter} writer View writer that should be used to modify the view document.\n\t */\n\tconvertMarkerRemove( markerName, markerRange, writer ) {\n\t\t// Do not convert if range is in graveyard.\n\t\tif ( markerRange.root.rootName == '$graveyard' ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.conversionApi.writer = writer;\n\n\t\tthis.fire( 'removeMarker:' + markerName, { markerName, markerRange }, this.conversionApi );\n\n\t\tthis._clearConversionApi();\n\t}\n\n\t/**\n\t * Maps the model element \"insert\" reconversion for given event names. The event names must be fully specified:\n\t *\n\t * * For \"attribute\" change event, it should include the main element name, i.e: `'attribute:attributeName:elementName'`.\n\t * * For child node change events, these should use the child event name as well, i.e:\n\t * * For adding a node: `'insert:childElementName'`.\n\t * * For removing a node: `'remove:childElementName'`.\n\t *\n\t * **Note**: This method should not be used directly. The reconversion is defined by the `triggerBy()` configuration of the\n\t * `elementToElement()` conversion helper.\n\t *\n\t * @protected\n\t * @param {String} modelName The name of the main model element for which the events will trigger the reconversion.\n\t * @param {String} eventName The name of an event that would trigger conversion for a given model element.\n\t */\n\t_mapReconversionTriggerEvent( modelName, eventName ) {\n\t\tthis._reconversionEventsMapping.set( eventName, modelName );\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume from a given range,\n\t * assuming that the range has just been inserted to the model.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range The inserted range.\n\t * @returns {module:engine/conversion/modelconsumable~ModelConsumable} The values to consume.\n\t */\n\t_createInsertConsumable( range ) {\n\t\tconst consumable = new Consumable();\n\n\t\tfor ( const value of range ) {\n\t\t\tconst item = value.item;\n\n\t\t\tconsumable.add( item, 'insert' );\n\n\t\t\tfor ( const key of item.getAttributeKeys() ) {\n\t\t\t\tconsumable.add( item, 'attribute:' + key );\n\t\t\t}\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/modelconsumable~ModelConsumable} with values to consume for a given range.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} range The affected range.\n\t * @param {String} type Consumable type.\n\t * @returns {module:engine/conversion/modelconsumable~ModelConsumable} The values to consume.\n\t */\n\t_createConsumableForRange( range, type ) {\n\t\tconst consumable = new Consumable();\n\n\t\tfor ( const item of range.getItems() ) {\n\t\t\tconsumable.add( item, type );\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Creates {@link module:engine/conversion/modelconsumable~ModelConsumable} with selection consumable values.\n\t *\n\t * @private\n\t * @param {module:engine/model/selection~Selection} selection The selection to create the consumable from.\n\t * @param {Iterable.} markers Markers that contain the selection.\n\t * @returns {module:engine/conversion/modelconsumable~ModelConsumable} The values to consume.\n\t */\n\t_createSelectionConsumable( selection, markers ) {\n\t\tconst consumable = new Consumable();\n\n\t\tconsumable.add( selection, 'selection' );\n\n\t\tfor ( const marker of markers ) {\n\t\t\tconsumable.add( selection, 'addMarker:' + marker.name );\n\t\t}\n\n\t\tfor ( const key of selection.getAttributeKeys() ) {\n\t\t\tconsumable.add( selection, 'attribute:' + key );\n\t\t}\n\n\t\treturn consumable;\n\t}\n\n\t/**\n\t * Tests passed `consumable` to check whether given event can be fired and if so, fires it.\n\t *\n\t * @private\n\t * @fires insert\n\t * @fires attribute\n\t * @param {String} type Event type.\n\t * @param {Object} data Event data.\n\t */\n\t_testAndFire( type, data ) {\n\t\tif ( !this.conversionApi.consumable.test( data.item, type ) ) {\n\t\t\t// Do not fire event if the item was consumed.\n\t\t\treturn;\n\t\t}\n\n\t\tthis.fire( getEventName( type, data ), data, this.conversionApi );\n\t}\n\n\t/**\n\t * Clears the conversion API object.\n\t *\n\t * @private\n\t */\n\t_clearConversionApi() {\n\t\tdelete this.conversionApi.writer;\n\t\tdelete this.conversionApi.consumable;\n\t}\n\n\t/**\n\t * Internal method for converting element insertion. It will fire events for the inserted element and events for its attributes.\n\t *\n\t * @private\n\t * @fires insert\n\t * @fires attribute\n\t * @param {Object} data Event data.\n\t */\n\t_convertInsertWithAttributes( data ) {\n\t\tthis._testAndFire( 'insert', data );\n\n\t\t// Fire a separate addAttribute event for each attribute that was set on inserted items.\n\t\t// This is important because most attributes converters will listen only to add/change/removeAttribute events.\n\t\t// If we would not add this part, attributes on inserted nodes would not be converted.\n\t\tfor ( const key of data.item.getAttributeKeys() ) {\n\t\t\tdata.attributeKey = key;\n\t\t\tdata.attributeOldValue = null;\n\t\t\tdata.attributeNewValue = data.item.getAttribute( key );\n\n\t\t\tthis._testAndFire( `attribute:${ key }`, data );\n\t\t}\n\t}\n\n\t/**\n\t * Returns differ changes together with added \"reconvert\" type changes for {@link #reconvertElement}. These are defined by\n\t * a the `triggerBy()` configuration for the\n\t * {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`} conversion helper.\n\t *\n\t * This method will remove every mapped insert or remove change with a single \"reconvert\" change.\n\t *\n\t * For instance: Having a `triggerBy()` configuration defined for the `` element that issues this element reconversion on\n\t * `foo` and `bar` attributes change, and a set of changes for this element:\n\t *\n\t *\t\tconst differChanges = [\n\t *\t\t\t{ type: 'attribute', attributeKey: 'foo', ... },\n\t *\t\t\t{ type: 'attribute', attributeKey: 'bar', ... },\n\t *\t\t\t{ type: 'attribute', attributeKey: 'baz', ... }\n\t *\t\t];\n\t *\n\t * This method will return:\n\t *\n\t *\t\tconst updatedChanges = [\n\t *\t\t\t{ type: 'reconvert', element: complexElementInstance },\n\t *\t\t\t{ type: 'attribute', attributeKey: 'baz', ... }\n\t *\t\t];\n\t *\n\t * In the example above, the `'baz'` attribute change will fire an {@link #event:attribute attribute event}\n\t *\n\t * @param {module:engine/model/differ~Differ} differ The differ object with buffered changes.\n\t * @returns {Array.} Updated set of changes.\n\t * @private\n\t */\n\t_mapChangesWithAutomaticReconversion( differ ) {\n\t\tconst itemsToReconvert = new Set();\n\t\tconst updated = [];\n\n\t\tfor ( const entry of differ.getChanges() ) {\n\t\t\tconst position = entry.position || entry.range.start;\n\t\t\t// Cached parent - just in case. See https://github.com/ckeditor/ckeditor5/issues/6579.\n\t\t\tconst positionParent = position.parent;\n\t\t\tconst textNode = getTextNodeAtPosition( position, positionParent );\n\n\t\t\t// Reconversion is done only on elements so skip text changes.\n\t\t\tif ( textNode ) {\n\t\t\t\tupdated.push( entry );\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst element = entry.type === 'attribute' ? getNodeAfterPosition( position, positionParent, null ) : positionParent;\n\n\t\t\t// Case of text node set directly in root. For now used only in tests but can be possible when enabled in paragraph-like roots.\n\t\t\t// See: https://github.com/ckeditor/ckeditor5/issues/762.\n\t\t\tif ( element.is( '$text' ) ) {\n\t\t\t\tupdated.push( entry );\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet eventName;\n\n\t\t\tif ( entry.type === 'attribute' ) {\n\t\t\t\teventName = `attribute:${ entry.attributeKey }:${ element.name }`;\n\t\t\t} else {\n\t\t\t\teventName = `${ entry.type }:${ entry.name }`;\n\t\t\t}\n\n\t\t\tif ( this._isReconvertTriggerEvent( eventName, element.name ) ) {\n\t\t\t\tif ( itemsToReconvert.has( element ) ) {\n\t\t\t\t\t// Element is already reconverted, so skip this change.\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\titemsToReconvert.add( element );\n\n\t\t\t\t// Add special \"reconvert\" change.\n\t\t\t\tupdated.push( { type: 'reconvert', element } );\n\t\t\t} else {\n\t\t\t\tupdated.push( entry );\n\t\t\t}\n\t\t}\n\n\t\treturn updated;\n\t}\n\n\t/**\n\t * Checks if the resulting change should trigger element reconversion.\n\t *\n\t * These are defined by a `triggerBy()` configuration for the\n\t * {@link module:engine/conversion/downcasthelpers~DowncastHelpers#elementToElement `elementToElement()`} conversion helper.\n\t *\n\t * @private\n\t * @param {String} eventName The event name to check.\n\t * @param {String} elementName The element name to check.\n\t * @returns {Boolean}\n\t */\n\t_isReconvertTriggerEvent( eventName, elementName ) {\n\t\treturn this._reconversionEventsMapping.get( eventName ) === elementName;\n\t}\n\n\t/**\n\t * Fired for inserted nodes.\n\t *\n\t * `insert` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `insert:name`. `name` is either `'$text'`, when {@link module:engine/model/text~Text a text node} has been inserted,\n\t * or {@link module:engine/model/element~Element#name name} of inserted element.\n\t *\n\t * This way listeners can either listen to a general `insert` event or specific event (for example `insert:paragraph`).\n\t *\n\t * @event insert\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item} data.item Inserted item.\n\t * @param {module:engine/model/range~Range} data.range Range spanning over inserted item.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired for removed nodes.\n\t *\n\t * `remove` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `remove:name`. `name` is either `'$text'`, when {@link module:engine/model/text~Text a text node} has been removed,\n\t * or the {@link module:engine/model/element~Element#name name} of removed element.\n\t *\n\t * This way listeners can either listen to a general `remove` event or specific event (for example `remove:paragraph`).\n\t *\n\t * @event remove\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/position~Position} data.position Position from which the node has been removed.\n\t * @param {Number} data.length Offset size of the removed node.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired in the following cases:\n\t *\n\t * * when an attribute has been added, changed, or removed from a node,\n\t * * when a node with an attribute is inserted,\n\t * * when collapsed model selection attribute is converted.\n\t *\n\t * `attribute` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `attribute:attributeKey:name`. `attributeKey` is the key of added/changed/removed attribute.\n\t * `name` is either `'$text'` if change was on {@link module:engine/model/text~Text a text node},\n\t * or the {@link module:engine/model/element~Element#name name} of element which attribute has changed.\n\t *\n\t * This way listeners can either listen to a general `attribute:bold` event or specific event (for example `attribute:src:imageBlock`).\n\t *\n\t * @event attribute\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item|module:engine/model/documentselection~DocumentSelection} data.item Changed item\n\t * or converted selection.\n\t * @param {module:engine/model/range~Range} data.range Range spanning over changed item or selection range.\n\t * @param {String} data.attributeKey Attribute key.\n\t * @param {*} data.attributeOldValue Attribute value before the change. This is `null` when selection attribute is converted.\n\t * @param {*} data.attributeNewValue New attribute value.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired for {@link module:engine/model/selection~Selection selection} changes.\n\t *\n\t * @event selection\n\t * @param {module:engine/model/selection~Selection} selection Selection that is converted.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired when a new marker is added to the model. Also fired when a collapsed model selection that is inside a marker is converted.\n\t *\n\t * `addMarker` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `addMarker:markerName`. By specifying certain marker names, you can make the events even more gradual. For example,\n\t * if markers are named `foo:abc`, `foo:bar`, then it is possible to listen to `addMarker:foo` or `addMarker:foo:abc` and\n\t * `addMarker:foo:bar` events.\n\t *\n\t * If the marker range is not collapsed:\n\t *\n\t * * the event is fired for each item in the marker range one by one,\n\t * * `conversionApi.consumable` includes each item of the marker range and the consumable value is same as the event name.\n\t *\n\t * If the marker range is collapsed:\n\t *\n\t * * there is only one event,\n\t * * `conversionApi.consumable` includes marker range with the event name.\n\t *\n\t * If the selection inside a marker is converted:\n\t *\n\t * * there is only one event,\n\t * * `conversionApi.consumable` includes the selection instance with the event name.\n\t *\n\t * @event addMarker\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/item~Item|module:engine/model/selection~Selection} data.item Item inside the new marker or\n\t * the selection that is being converted.\n\t * @param {module:engine/model/range~Range} [data.range] Range spanning over converted item. Available only in marker conversion, if\n\t * the marker range was not collapsed.\n\t * @param {module:engine/model/range~Range} data.markerRange Marker range.\n\t * @param {String} data.markerName Marker name.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n\n\t/**\n\t * Fired when a marker is removed from the model.\n\t *\n\t * `removeMarker` is a namespace for a class of events. Names of actually called events follow this pattern:\n\t * `removeMarker:markerName`. By specifying certain marker names, you can make the events even more gradual. For example,\n\t * if markers are named `foo:abc`, `foo:bar`, then it is possible to listen to `removeMarker:foo` or `removeMarker:foo:abc` and\n\t * `removeMarker:foo:bar` events.\n\t *\n\t * @event removeMarker\n\t * @param {Object} data Additional information about the change.\n\t * @param {module:engine/model/range~Range} data.markerRange Marker range.\n\t * @param {String} data.markerName Marker name.\n\t * @param {module:engine/conversion/downcastdispatcher~DowncastConversionApi} conversionApi Conversion interface\n\t * to be used by callback, passed in `DowncastDispatcher` constructor.\n\t */\n}\n\nmix( DowncastDispatcher, EmitterMixin );\n\n// Helper function, checks whether change of `marker` at `modelPosition` should be converted. Marker changes are not\n// converted if they happen inside an element with custom conversion method.\n//\n// @param {module:engine/model/position~Position} modelPosition\n// @param {module:engine/model/markercollection~Marker} marker\n// @param {module:engine/conversion/mapper~Mapper} mapper\n// @returns {Boolean}\nfunction shouldMarkerChangeBeConverted( modelPosition, marker, mapper ) {\n\tconst range = marker.getRange();\n\tconst ancestors = Array.from( modelPosition.getAncestors() );\n\tancestors.shift(); // Remove root element. It cannot be passed to `model.Range#containsItem`.\n\tancestors.reverse();\n\n\tconst hasCustomHandling = ancestors.some( element => {\n\t\tif ( range.containsItem( element ) ) {\n\t\t\tconst viewElement = mapper.toViewElement( element );\n\n\t\t\treturn !!viewElement.getCustomProperty( 'addHighlight' );\n\t\t}\n\t} );\n\n\treturn !hasCustomHandling;\n}\n\nfunction getEventName( type, data ) {\n\tconst name = data.item.name || '$text';\n\n\treturn `${ type }:${ name }`;\n}\n\nfunction walkerValueToEventData( value ) {\n\tconst item = value.item;\n\tconst itemRange = Range._createFromPositionAndShift( value.previousPosition, value.length );\n\n\treturn {\n\t\titem,\n\t\trange: itemRange\n\t};\n}\n\nfunction elementOrTextProxyToView( item, mapper ) {\n\tif ( item.is( 'textProxy' ) ) {\n\t\tconst mappedPosition = mapper.toViewPosition( Position._createBefore( item ) );\n\t\tconst positionParent = mappedPosition.parent;\n\n\t\treturn positionParent.is( '$text' ) ? positionParent : null;\n\t}\n\n\treturn mapper.toViewElement( item );\n}\n\n/**\n * Conversion interface that is registered for given {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher}\n * and is passed as one of parameters when {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher dispatcher}\n * fires its events.\n *\n * @interface module:engine/conversion/downcastdispatcher~DowncastConversionApi\n */\n\n/**\n * The {@link module:engine/conversion/downcastdispatcher~DowncastDispatcher} instance.\n *\n * @member {module:engine/conversion/downcastdispatcher~DowncastDispatcher} #dispatcher\n */\n\n/**\n * Stores the information about what parts of a processed model item are still waiting to be handled. After a piece of a model item was\n * converted, an appropriate consumable value should be {@link module:engine/conversion/modelconsumable~ModelConsumable#consume consumed}.\n *\n * @member {module:engine/conversion/modelconsumable~ModelConsumable} #consumable\n */\n\n/**\n * The {@link module:engine/conversion/mapper~Mapper} instance.\n *\n * @member {module:engine/conversion/mapper~Mapper} #mapper\n */\n\n/**\n * The {@link module:engine/model/schema~Schema} instance set for the model that is downcast.\n *\n * @member {module:engine/model/schema~Schema} #schema\n */\n\n/**\n * The {@link module:engine/view/downcastwriter~DowncastWriter} instance used to manipulate the data during conversion.\n *\n * @member {module:engine/view/downcastwriter~DowncastWriter} #writer\n */\n\n/**\n * An object with an additional configuration which can be used during the conversion process. Available only for data downcast conversion.\n *\n * @member {Object} #options\n */\n"],"sourceRoot":""}