Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

Commit 8147685

Browse files
committed
Fixed attributes rendering for replaced elements.
1 parent 0cee0a1 commit 8147685

File tree

1 file changed

+25
-1
lines changed

1 file changed

+25
-1
lines changed

src/view/renderer.js

+25-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ export default class Renderer {
302302
* @param {module:engine/view/node~Node} viewElement The view element which children mappings will be updated.
303303
*/
304304
_updateChildrenMappings( viewElement ) {
305-
// We do not perform any operations on DOM here so there is no need to bind view element or convert its' children.
305+
// We do not perform any operations on DOM here so there is no need to bind view element or convert its children.
306306
const diff = this._diffElementChildren( viewElement, { bind: false, withChildren: false } );
307307

308308
if ( diff ) {
@@ -317,8 +317,23 @@ export default class Renderer {
317317
const viewChild = viewElement.getChild( insertIndex );
318318

319319
if ( viewChild ) {
320+
// Because we replace previous view element mapping with the new one, the corresponding DOM element
321+
// will not be rerendered. The new view element may have different attributes than the old one.
322+
// Its corresponding DOM element will not be rerendered so new attributes will not be present in a DOM.
323+
// Such situation may take place if only previous view element was added to `this.markedAttributes`
324+
// or none of elements were added (relying on 'this._updateChildren()' which by rerendering the element
325+
// also rerenders its attributes). See #1427 for more detailed case study.
326+
// It may also happen that 'oldViewElement' mapping is not present since its parent mapping
327+
// was removed ('domConverter.unbindDomElement' also unbinds children mappings).
328+
const oldViewChild = this.domConverter.mapDomToView( diff.actualDomChildren[ deleteIndex ] );
329+
if ( !oldViewChild || oldViewChild && !oldViewChild.isSimilar( viewChild ) ) {
330+
this.markedAttributes.add( viewChild );
331+
}
332+
333+
// Remap 'DomConverter' bindings.
320334
this.domConverter.unbindDomElement( diff.actualDomChildren[ deleteIndex ] );
321335
this.domConverter.bindElements( diff.actualDomChildren[ deleteIndex ], viewChild );
336+
322337
// View element may have children which needs to be updated, but are not marked, mark them to update.
323338
this.markedChildren.add( viewChild );
324339
}
@@ -537,6 +552,15 @@ export default class Renderer {
537552
*/
538553
_updateAttrs( viewElement ) {
539554
const domElement = this.domConverter.mapViewToDom( viewElement );
555+
556+
if ( !domElement ) {
557+
// If there is no `domElement` it means that 'viewElement' is outdated as its mapping was updated
558+
// in 'this._updateChildrenMappings()'. There is no need to process it as new view element which
559+
// replaced old 'viewElement' mapping was also added to 'this.markedAttributes'
560+
// in 'this._updateChildrenMappings()' so it will be processed separately.
561+
return;
562+
}
563+
540564
const domAttrKeys = Array.from( domElement.attributes ).map( attr => attr.name );
541565
const viewAttrKeys = viewElement.getAttributeKeys();
542566

0 commit comments

Comments
 (0)