@@ -127,13 +127,13 @@ export default class Renderer {
127127 */
128128 markToSync ( type , node ) {
129129 if ( type === 'text' ) {
130- if ( this . domConverter . getCorrespondingDom ( node . parent ) ) {
130+ if ( this . domConverter . mapViewToDom ( node . parent ) ) {
131131 this . markedTexts . add ( node ) ;
132132 }
133133 } else {
134134 // If the node has no DOM element it is not rendered yet,
135135 // its children/attributes do not need to be marked to be sync.
136- if ( ! this . domConverter . getCorrespondingDom ( node ) ) {
136+ if ( ! this . domConverter . mapViewToDom ( node ) ) {
137137 return ;
138138 }
139139
@@ -165,9 +165,9 @@ export default class Renderer {
165165 * attributes which do not exist in the view element.
166166 *
167167 * For text nodes it updates the text string if it is different. Note that if parent element is marked as an element
168- * which changed child list, text node update will not be done, because it may not be possible do find a
169- * {@link module:engine/view/domconverter~DomConverter#getCorrespondingDomText corresponding DOM text}. The change will be handled
170- * in the parent element.
168+ * which changed child list, text node update will not be done, because it may not be possible to
169+ * {@link module:engine/view/domconverter~DomConverter#findCorrespondingDomText find a corresponding DOM text}.
170+ * The change will be handled in the parent element.
171171 *
172172 * For elements, which child lists have changed, it calculates a {@link module:utils/diff~diff} and adds or removes children which have
173173 * changed.
@@ -190,7 +190,7 @@ export default class Renderer {
190190 if ( this . _inlineFiller ) {
191191 inlineFillerPosition = this . _getInlineFillerPosition ( ) ;
192192 }
193- // Othewise , if it's needed, create it at the selection position.
193+ // Otherwise , if it's needed, create it at the selection position.
194194 else if ( this . _needsInlineFillerAtSelection ( ) ) {
195195 inlineFillerPosition = this . selection . getFirstPosition ( ) ;
196196
@@ -199,7 +199,7 @@ export default class Renderer {
199199 }
200200
201201 for ( const node of this . markedTexts ) {
202- if ( ! this . markedChildren . has ( node . parent ) && this . domConverter . getCorrespondingDom ( node . parent ) ) {
202+ if ( ! this . markedChildren . has ( node . parent ) && this . domConverter . mapViewToDom ( node . parent ) ) {
203203 this . _updateText ( node , { inlineFillerPosition } ) ;
204204 }
205205 }
@@ -351,7 +351,7 @@ export default class Renderer {
351351 const selectionOffset = selectionPosition . offset ;
352352
353353 // If there is no DOM root we do not care about fillers.
354- if ( ! this . domConverter . getCorrespondingDomElement ( selectionParent . root ) ) {
354+ if ( ! this . domConverter . mapViewToDom ( selectionParent . root ) ) {
355355 return false ;
356356 }
357357
@@ -384,7 +384,7 @@ export default class Renderer {
384384 * filler should be rendered.
385385 */
386386 _updateText ( viewText , options ) {
387- const domText = this . domConverter . getCorrespondingDom ( viewText ) ;
387+ const domText = this . domConverter . findCorrespondingDomText ( viewText ) ;
388388 const newDomText = this . domConverter . viewToDom ( viewText , domText . ownerDocument ) ;
389389
390390 const actualText = domText . data ;
@@ -408,7 +408,7 @@ export default class Renderer {
408408 * @param {module:engine/view/element~Element } viewElement View element to update.
409409 */
410410 _updateAttrs ( viewElement ) {
411- const domElement = this . domConverter . getCorrespondingDom ( viewElement ) ;
411+ const domElement = this . domConverter . mapViewToDom ( viewElement ) ;
412412 const domAttrKeys = Array . from ( domElement . attributes ) . map ( attr => attr . name ) ;
413413 const viewAttrKeys = viewElement . getAttributeKeys ( ) ;
414414
@@ -436,7 +436,7 @@ export default class Renderer {
436436 */
437437 _updateChildren ( viewElement , options ) {
438438 const domConverter = this . domConverter ;
439- const domElement = domConverter . getCorrespondingDom ( viewElement ) ;
439+ const domElement = domConverter . mapViewToDom ( viewElement ) ;
440440
441441 if ( ! domElement ) {
442442 // If there is no `domElement` it means that it was already removed from DOM.
@@ -445,9 +445,7 @@ export default class Renderer {
445445 }
446446
447447 const domDocument = domElement . ownerDocument ;
448-
449448 const filler = options . inlineFillerPosition ;
450-
451449 const actualDomChildren = domElement . childNodes ;
452450 const expectedDomChildren = Array . from ( domConverter . viewChildrenToDom ( viewElement , domDocument , { bind : true } ) ) ;
453451
@@ -464,20 +462,29 @@ export default class Renderer {
464462 const actions = diff ( actualDomChildren , expectedDomChildren , sameNodes ) ;
465463
466464 let i = 0 ;
465+ const nodesToUnbind = new Set ( ) ;
467466
468467 for ( const action of actions ) {
469468 if ( action === 'insert' ) {
470469 insertAt ( domElement , i , expectedDomChildren [ i ] ) ;
471470 i ++ ;
472471 } else if ( action === 'delete' ) {
473- // Whenever element is removed from DOM, unbind it and all of its children.
474- this . domConverter . unbindDomElement ( actualDomChildren [ i ] ) ;
472+ nodesToUnbind . add ( actualDomChildren [ i ] ) ;
475473 remove ( actualDomChildren [ i ] ) ;
476474 } else { // 'equal'
477475 i ++ ;
478476 }
479477 }
480478
479+ // Unbind removed nodes. When node does not have a parent it means that it was removed from DOM tree during
480+ // comparision with the expected DOM. We don't need to check child nodes, because if child node was reinserted,
481+ // it was moved to DOM tree out of the removed node.
482+ for ( const node of nodesToUnbind ) {
483+ if ( ! node . parentNode ) {
484+ this . domConverter . unbindDomElement ( node ) ;
485+ }
486+ }
487+
481488 function sameNodes ( actualDomChild , expectedDomChild ) {
482489 // Elements.
483490 if ( actualDomChild === expectedDomChild ) {
@@ -512,7 +519,7 @@ export default class Renderer {
512519 return ;
513520 }
514521
515- const domRoot = this . domConverter . getCorrespondingDomElement ( this . selection . editableElement ) ;
522+ const domRoot = this . domConverter . mapViewToDom ( this . selection . editableElement ) ;
516523
517524 // Do nothing if there is no focus, or there is no DOM element corresponding to selection's editable element.
518525 if ( ! this . isFocused || ! domRoot ) {
@@ -618,7 +625,7 @@ export default class Renderer {
618625
619626 if ( domSelection . rangeCount ) {
620627 const activeDomElement = doc . activeElement ;
621- const viewElement = this . domConverter . getCorrespondingViewElement ( activeDomElement ) ;
628+ const viewElement = this . domConverter . mapDomToView ( activeDomElement ) ;
622629
623630 if ( activeDomElement && viewElement ) {
624631 doc . getSelection ( ) . removeAllRanges ( ) ;
0 commit comments