|
@@ -1521,6 +1521,128 @@ describe( 'Renderer', () => {
|
|
|
expect( domP.innerHTML ).to.equal( '<b>x </b><i> y</i>' );
|
|
expect( domP.innerHTML ).to.equal( '<b>x </b><i> y</i>' );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
|
|
+ // #1125
|
|
|
|
|
+ it( 'should properly rerender many changes done in one batch', () => {
|
|
|
|
|
+ // This test transforms:
|
|
|
|
|
+ //
|
|
|
|
|
+ // <h2>He<strong>ding 1</strong></h2>
|
|
|
|
|
+ // <p>Ph <strong>Bold</strong> <i>It<strong>alic</strong></i> <a><strong>Lin</strong>k</a></p>
|
|
|
|
|
+ // <blockquote><ul><li>Quoted <strong>item 1</strong></li></ul></blockquote>
|
|
|
|
|
+ //
|
|
|
|
|
+ // into:
|
|
|
|
|
+ //
|
|
|
|
|
+ // <h2>Heading 2</h2>
|
|
|
|
|
+ // <p>Ph <i><strong>Italic</strong></i> <a><strong>L</strong>ink 1</a></p>
|
|
|
|
|
+ // <blockquote><p>Qu<strong>ote</strong></p><ul><li><strong>Quoted item 1</strong></li></ul></blockquote>
|
|
|
|
|
+ //
|
|
|
|
|
+ // during one rerender to check if complex structure changes are rerendered correctly.
|
|
|
|
|
+ const viewContent = parse( '' +
|
|
|
|
|
+ '<container:h2>He' +
|
|
|
|
|
+ '<attribute:i>ading 1</attribute:i>' +
|
|
|
|
|
+ '</container:h2>' +
|
|
|
|
|
+ '<container:p>Ph ' +
|
|
|
|
|
+ '<attribute:strong>Bold</attribute:strong> ' +
|
|
|
|
|
+ '<attribute:i>It' +
|
|
|
|
|
+ '<attribute:strong>alic</attribute:strong>' +
|
|
|
|
|
+ '</attribute:i> ' +
|
|
|
|
|
+ '<attribute:a href="https://ckeditor.com">' +
|
|
|
|
|
+ '<attribute:strong>Lin</attribute:strong>' +
|
|
|
|
|
+ 'k</attribute:a>' +
|
|
|
|
|
+ '</container:p>' +
|
|
|
|
|
+ '<container:blockquote>' +
|
|
|
|
|
+ '<container:ul>' +
|
|
|
|
|
+ '<container:li>Quoted <attribute:strong>item 1</attribute:strong></container:li>' +
|
|
|
|
|
+ '</container:ul>' +
|
|
|
|
|
+ '</container:blockquote>' );
|
|
|
|
|
+
|
|
|
|
|
+ viewRoot._appendChildren( viewContent );
|
|
|
|
|
+
|
|
|
|
|
+ renderer.markToSync( 'children', viewRoot );
|
|
|
|
|
+ renderer.render();
|
|
|
|
|
+
|
|
|
|
|
+ // '<h2>He<i>ading 1</i></h2>' -> '<h2>Heading 2</h2>'
|
|
|
|
|
+ const viewHeading = viewRoot.getChild( 0 );
|
|
|
|
|
+ viewHeading._removeChildren( 0, viewHeading.childCount );
|
|
|
|
|
+ viewHeading._insertChildren( 0, new ViewText( 'Heading 2' ) );
|
|
|
|
|
+
|
|
|
|
|
+ // Usually whole subtree is marked to sync so we mark root, changed element and all its direct children.
|
|
|
|
|
+ renderer.markToSync( 'children', viewRoot );
|
|
|
|
|
+ renderer.markToSync( 'children', viewHeading );
|
|
|
|
|
+ renderer.markToSync( 'text', viewHeading.getChild( 0 ) );
|
|
|
|
|
+
|
|
|
|
|
+ // '<p>Ph <strong>Bold</strong> <i>It<strong>alic</strong></i> <a><strong>Lin</strong>k</a></p>'
|
|
|
|
|
+ // -> '<p>Ph <i><strong>Italic</strong></i> <a><strong>L</strong>ink 1</a></p>'
|
|
|
|
|
+ const viewP = viewRoot.getChild( 1 );
|
|
|
|
|
+ viewP._removeChildren( 0, viewP.childCount );
|
|
|
|
|
+ viewP._insertChildren( 0, parse( 'Ph <attribute:i><attribute:strong>Italic</attribute:strong></attribute:i> ' +
|
|
|
|
|
+ '<attribute:a href="https://ckeditor.com"><attribute:strong>L</attribute:strong>ink 1</attribute:a>' ) );
|
|
|
|
|
+
|
|
|
|
|
+ renderer.markToSync( 'children', viewRoot );
|
|
|
|
|
+ renderer.markToSync( 'children', viewP );
|
|
|
|
|
+ renderer.markToSync( 'children', viewP.getChild( 1 ) );
|
|
|
|
|
+ renderer.markToSync( 'children', viewP.getChild( 3 ) );
|
|
|
|
|
+ renderer.markToSync( 'text', viewP.getChild( 0 ) );
|
|
|
|
|
+ renderer.markToSync( 'text', viewP.getChild( 2 ) );
|
|
|
|
|
+
|
|
|
|
|
+ // '<blockquote><ul><li>Quoted <strong>item 1</strong></li></ul></blockquote>'
|
|
|
|
|
+ // -> '<blockquote><p>Qu<strong>ote</strong></p><ul><li><strong>Quoted item 1</strong></li></ul></blockquote>'
|
|
|
|
|
+ const viewBq = viewRoot.getChild( 2 );
|
|
|
|
|
+ viewBq._removeChildren( 0, viewBq.childCount );
|
|
|
|
|
+ viewBq._insertChildren( 0, parse( '<container:p>Qu<attribute:strong>ote</attribute:strong></container:p>' +
|
|
|
|
|
+ '<container:ul><container:li><attribute:strong>Quoted item 1</attribute:strong></container:li></container:ul>' ) );
|
|
|
|
|
+
|
|
|
|
|
+ renderer.markToSync( 'children', viewRoot );
|
|
|
|
|
+ renderer.markToSync( 'children', viewBq );
|
|
|
|
|
+ renderer.markToSync( 'children', viewBq.getChild( 0 ) );
|
|
|
|
|
+ renderer.markToSync( 'children', viewBq.getChild( 1 ) );
|
|
|
|
|
+
|
|
|
|
|
+ renderer.render();
|
|
|
|
|
+
|
|
|
|
|
+ expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<h2>Heading 2</h2>' +
|
|
|
|
|
+ '<p>Ph <i><strong>Italic</strong></i> <a href="https://ckeditor.com"><strong>L</strong>ink 1</a></p>' +
|
|
|
|
|
+ '<blockquote><p>Qu<strong>ote</strong></p><ul><li><strong>Quoted item 1</strong></li></ul></blockquote>' );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ // #1125
|
|
|
|
|
+ it( 'should properly rerender changes when whole content replaced at once', () => {
|
|
|
|
|
+ // This test replaces:
|
|
|
|
|
+ //
|
|
|
|
|
+ // <h1>Header</h1>
|
|
|
|
|
+ // <blockquote><ul><li>Quoted <strong>item 1</strong></li><li>Item 2</li></ul></blockquote>
|
|
|
|
|
+ //
|
|
|
|
|
+ // with:
|
|
|
|
|
+ //
|
|
|
|
|
+ // <h2>Header</h2>
|
|
|
|
|
+ // <p>Not Quoted <strong>item 1</strong> and item 2</p>
|
|
|
|
|
+ //
|
|
|
|
|
+ // during one rerender to check if complex structure changes are rerendered correctly.
|
|
|
|
|
+ const viewContent = parse( '' +
|
|
|
|
|
+ '<container:h1>Header</container:h1>' +
|
|
|
|
|
+ '<container:blockquote>' +
|
|
|
|
|
+ '<container:ul>' +
|
|
|
|
|
+ '<container:li>Quoted <attribute:strong>item 1</attribute:strong></container:li>' +
|
|
|
|
|
+ '<container:li>Item 2</container:li>' +
|
|
|
|
|
+ '</container:ul>' +
|
|
|
|
|
+ '</container:blockquote>' );
|
|
|
|
|
+
|
|
|
|
|
+ viewRoot._appendChildren( viewContent );
|
|
|
|
|
+
|
|
|
|
|
+ renderer.markToSync( 'children', viewRoot );
|
|
|
|
|
+ renderer.render();
|
|
|
|
|
+
|
|
|
|
|
+ const newViewContent = parse( '' +
|
|
|
|
|
+ '<container:h2>Header</container:h2>' +
|
|
|
|
|
+ '<container:p>Not Quoted <attribute:strong>item 1</attribute:strong> and item 2</container:p>' );
|
|
|
|
|
+
|
|
|
|
|
+ viewRoot._removeChildren( 0, viewRoot.childCount );
|
|
|
|
|
+ viewRoot._appendChildren( newViewContent );
|
|
|
|
|
+
|
|
|
|
|
+ renderer.markToSync( 'children', viewRoot );
|
|
|
|
|
+ renderer.render();
|
|
|
|
|
+
|
|
|
|
|
+ expect( normalizeHtml( domRoot.innerHTML ) ).to.equal( '<h2>Header</h2><p>Not Quoted <strong>item 1</strong> and item 2</p>' );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
describe( 'fake selection', () => {
|
|
describe( 'fake selection', () => {
|
|
|
beforeEach( () => {
|
|
beforeEach( () => {
|
|
|
const { view: viewP, selection: newSelection } = parse(
|
|
const { view: viewP, selection: newSelection } = parse(
|