diff --git a/src/view/renderer.js b/src/view/renderer.js index a16adc5a2..83de61120 100644 --- a/src/view/renderer.js +++ b/src/view/renderer.js @@ -306,7 +306,9 @@ export default class Renderer { // It may also happen that 'newViewChild' mapping is not present since its parent mapping // was already removed (the 'domConverter.unbindDomElement()' method also unbinds children // mappings) so we also check for '!newViewChild'. - if ( !newViewChild || newViewChild && !newViewChild.isSimilar( viewElement ) ) { + // Also check if new element ('newViewChild') was marked to have its attributes rerenderd, + // if so, marked reused view element too (#1560). + if ( !newViewChild || newViewChild && !newViewChild.isSimilar( viewElement ) || this.markedAttributes.has( newViewChild ) ) { this.markedAttributes.add( viewElement ); } diff --git a/tests/view/renderer.js b/tests/view/renderer.js index 68c5c8f8b..5bf88a609 100644 --- a/tests/view/renderer.js +++ b/tests/view/renderer.js @@ -17,6 +17,7 @@ import DocumentSelection from '../../src/view/documentselection'; import DomConverter from '../../src/view/domconverter'; import Renderer from '../../src/view/renderer'; import DocumentFragment from '../../src/view/documentfragment'; +import DowncastWriter from '../../src/view/downcastwriter'; import CKEditorError from '@ckeditor/ckeditor5-utils/src/ckeditorerror'; import { parse, setData as setViewData, getData as getViewData } from '../../src/dev-utils/view'; import { INLINE_FILLER, INLINE_FILLER_LENGTH, isBlockFiller, BR_FILLER } from '../../src/view/filler'; @@ -3038,6 +3039,68 @@ describe( 'Renderer', () => { expect( domRoot.innerHTML ).to.equal( '
' ); } ); } ); + + // #1560 + describe( 'attributes manipulation on replaced element', () => { + it( 'should rerender element if it was removed after having its attributes removed (attribute)', () => { + const writer = new DowncastWriter(); + + // 1. Setup initial view/DOM. + viewRoot._appendChild( parse( '1
' ); + + // 2. Modify view. + writer.removeAttribute( 'data-placeholder', viewP ); + + viewRoot._removeChildren( 0, viewRoot.childCount ); + + viewRoot._appendChild( parse( '1
2
' ); + } ); + + it( 'should rerender element if it was removed after having its attributes removed (classes)', () => { + const writer = new DowncastWriter(); + + // 1. Setup initial view/DOM. + viewRoot._appendChild( parse( 'p
' ); + + // 2. Modify view. + writer.removeClass( 'cke-test2', viewP ); + + viewRoot._removeChildren( 0, viewRoot.childCount ); + + viewRoot._appendChild( parse( 'p
p2
' ); + } ); + } ); } ); describe( '#922', () => {