|
@@ -204,7 +204,7 @@ describe( 'view', () => {
|
|
|
|
|
|
|
|
it( 'should be disabled and re-enabled on render', () => {
|
|
it( 'should be disabled and re-enabled on render', () => {
|
|
|
const observerMock = view.addObserver( ObserverMock );
|
|
const observerMock = view.addObserver( ObserverMock );
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.forceRender();
|
|
|
|
|
|
|
|
sinon.assert.calledOnce( observerMock.disable );
|
|
sinon.assert.calledOnce( observerMock.disable );
|
|
|
sinon.assert.calledOnce( view._renderer.render );
|
|
sinon.assert.calledOnce( view._renderer.render );
|
|
@@ -327,7 +327,7 @@ describe( 'view', () => {
|
|
|
|
|
|
|
|
it( 'should focus editable with selection', () => {
|
|
it( 'should focus editable with selection', () => {
|
|
|
const converterFocusSpy = testUtils.sinon.spy( view.domConverter, 'focus' );
|
|
const converterFocusSpy = testUtils.sinon.spy( view.domConverter, 'focus' );
|
|
|
- const renderSpy = testUtils.sinon.spy( view, 'render' );
|
|
|
|
|
|
|
+ const renderSpy = testUtils.sinon.spy( view, 'forceRender' );
|
|
|
|
|
|
|
|
view.focus();
|
|
view.focus();
|
|
|
|
|
|
|
@@ -344,7 +344,7 @@ describe( 'view', () => {
|
|
|
|
|
|
|
|
it( 'should not focus if document is already focused', () => {
|
|
it( 'should not focus if document is already focused', () => {
|
|
|
const converterFocusSpy = testUtils.sinon.spy( view.domConverter, 'focus' );
|
|
const converterFocusSpy = testUtils.sinon.spy( view.domConverter, 'focus' );
|
|
|
- const renderSpy = testUtils.sinon.spy( view, 'render' );
|
|
|
|
|
|
|
+ const renderSpy = testUtils.sinon.spy( view, 'forceRender' );
|
|
|
viewDocument.isFocused = true;
|
|
viewDocument.isFocused = true;
|
|
|
|
|
|
|
|
view.focus();
|
|
view.focus();
|
|
@@ -377,28 +377,41 @@ describe( 'view', () => {
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
- describe( 'render()', () => {
|
|
|
|
|
|
|
+ describe( 'forceRender()', () => {
|
|
|
it( 'disable observers, renders and enable observers', () => {
|
|
it( 'disable observers, renders and enable observers', () => {
|
|
|
const observerMock = view.addObserver( ObserverMock );
|
|
const observerMock = view.addObserver( ObserverMock );
|
|
|
const renderStub = sinon.stub( view._renderer, 'render' );
|
|
const renderStub = sinon.stub( view._renderer, 'render' );
|
|
|
|
|
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.forceRender();
|
|
|
|
|
|
|
|
sinon.assert.callOrder( observerMock.disable, renderStub, observerMock.enable );
|
|
sinon.assert.callOrder( observerMock.disable, renderStub, observerMock.enable );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
- it( 'should fire view.document.layoutChanged event on render', () => {
|
|
|
|
|
- const spy = sinon.spy();
|
|
|
|
|
|
|
+ it( 'should fire `render` and `layoutChanged` even if there were no changes', () => {
|
|
|
|
|
+ const renderSpy = sinon.spy();
|
|
|
|
|
+ const layoutChangedSpy = sinon.spy();
|
|
|
|
|
|
|
|
- view.document.on( 'layoutChanged', spy );
|
|
|
|
|
|
|
+ view.on( 'render', renderSpy );
|
|
|
|
|
+ view.document.on( 'layoutChanged', layoutChangedSpy );
|
|
|
|
|
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.forceRender();
|
|
|
|
|
|
|
|
- sinon.assert.calledOnce( spy );
|
|
|
|
|
|
|
+ sinon.assert.calledOnce( renderSpy );
|
|
|
|
|
+ sinon.assert.calledOnce( layoutChangedSpy );
|
|
|
|
|
+ } );
|
|
|
|
|
+
|
|
|
|
|
+ it( 'should fire `render` and `layoutChanged` if there is some buffered change', () => {
|
|
|
|
|
+ const renderSpy = sinon.spy();
|
|
|
|
|
+ const layoutChangedSpy = sinon.spy();
|
|
|
|
|
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.on( 'render', renderSpy );
|
|
|
|
|
+ view.document.on( 'layoutChanged', layoutChangedSpy );
|
|
|
|
|
|
|
|
- sinon.assert.calledTwice( spy );
|
|
|
|
|
|
|
+ view.document.selection._setTo( null );
|
|
|
|
|
+ view.forceRender();
|
|
|
|
|
+
|
|
|
|
|
+ sinon.assert.calledOnce( renderSpy );
|
|
|
|
|
+ sinon.assert.calledOnce( layoutChangedSpy );
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
@@ -414,7 +427,7 @@ describe( 'view', () => {
|
|
|
|
|
|
|
|
createViewRoot( viewDocument, 'div', 'main' );
|
|
createViewRoot( viewDocument, 'div', 'main' );
|
|
|
view.attachDomRoot( domDiv );
|
|
view.attachDomRoot( domDiv );
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.forceRender();
|
|
|
|
|
|
|
|
expect( domDiv.childNodes.length ).to.equal( 1 );
|
|
expect( domDiv.childNodes.length ).to.equal( 1 );
|
|
|
expect( isBlockFiller( domDiv.childNodes[ 0 ], BR_FILLER ) ).to.be.true;
|
|
expect( isBlockFiller( domDiv.childNodes[ 0 ], BR_FILLER ) ).to.be.true;
|
|
@@ -432,7 +445,7 @@ describe( 'view', () => {
|
|
|
view.attachDomRoot( domDiv );
|
|
view.attachDomRoot( domDiv );
|
|
|
|
|
|
|
|
viewDocument.getRoot()._appendChild( new ViewElement( 'p' ) );
|
|
viewDocument.getRoot()._appendChild( new ViewElement( 'p' ) );
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.forceRender();
|
|
|
|
|
|
|
|
expect( domDiv.childNodes.length ).to.equal( 1 );
|
|
expect( domDiv.childNodes.length ).to.equal( 1 );
|
|
|
expect( domDiv.childNodes[ 0 ].tagName ).to.equal( 'P' );
|
|
expect( domDiv.childNodes[ 0 ].tagName ).to.equal( 'P' );
|
|
@@ -451,13 +464,13 @@ describe( 'view', () => {
|
|
|
|
|
|
|
|
const viewP = new ViewElement( 'p', { class: 'foo' } );
|
|
const viewP = new ViewElement( 'p', { class: 'foo' } );
|
|
|
viewRoot._appendChild( viewP );
|
|
viewRoot._appendChild( viewP );
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.forceRender();
|
|
|
|
|
|
|
|
expect( domRoot.childNodes.length ).to.equal( 1 );
|
|
expect( domRoot.childNodes.length ).to.equal( 1 );
|
|
|
expect( domRoot.childNodes[ 0 ].getAttribute( 'class' ) ).to.equal( 'foo' );
|
|
expect( domRoot.childNodes[ 0 ].getAttribute( 'class' ) ).to.equal( 'foo' );
|
|
|
|
|
|
|
|
viewP._setAttribute( 'class', 'bar' );
|
|
viewP._setAttribute( 'class', 'bar' );
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.forceRender();
|
|
|
|
|
|
|
|
expect( domRoot.childNodes.length ).to.equal( 1 );
|
|
expect( domRoot.childNodes.length ).to.equal( 1 );
|
|
|
expect( domRoot.childNodes[ 0 ].getAttribute( 'class' ) ).to.equal( 'bar' );
|
|
expect( domRoot.childNodes[ 0 ].getAttribute( 'class' ) ).to.equal( 'bar' );
|
|
@@ -503,7 +516,7 @@ describe( 'view', () => {
|
|
|
} ).to.throw( CKEditorError, /^cannot-change-view-tree/ );
|
|
} ).to.throw( CKEditorError, /^cannot-change-view-tree/ );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.forceRender();
|
|
|
domDiv.remove();
|
|
domDiv.remove();
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
@@ -513,7 +526,9 @@ describe( 'view', () => {
|
|
|
|
|
|
|
|
view.on( 'render', eventSpy );
|
|
view.on( 'render', eventSpy );
|
|
|
|
|
|
|
|
- view.change( () => {} );
|
|
|
|
|
|
|
+ view.change( writer => {
|
|
|
|
|
+ writer.setSelection( null );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
sinon.assert.callOrder( renderSpy, eventSpy );
|
|
sinon.assert.callOrder( renderSpy, eventSpy );
|
|
|
} );
|
|
} );
|
|
@@ -521,16 +536,24 @@ describe( 'view', () => {
|
|
|
it( 'should fire render event once for nested change blocks', () => {
|
|
it( 'should fire render event once for nested change blocks', () => {
|
|
|
const renderSpy = sinon.spy( view._renderer, 'render' );
|
|
const renderSpy = sinon.spy( view._renderer, 'render' );
|
|
|
const eventSpy = sinon.spy();
|
|
const eventSpy = sinon.spy();
|
|
|
|
|
+ const viewEditable = createViewRoot( viewDocument, 'div', 'main' );
|
|
|
|
|
|
|
|
view.on( 'render', eventSpy );
|
|
view.on( 'render', eventSpy );
|
|
|
|
|
|
|
|
- view.change( () => {
|
|
|
|
|
- view.change( () => {} );
|
|
|
|
|
- view.change( () => {
|
|
|
|
|
- view.change( () => {} );
|
|
|
|
|
- view.change( () => {} );
|
|
|
|
|
|
|
+ view.change( writer => {
|
|
|
|
|
+ writer.setSelection( null );
|
|
|
|
|
+ view.change( writer => {
|
|
|
|
|
+ writer.setSelection( viewEditable, 0 );
|
|
|
|
|
+ } );
|
|
|
|
|
+ view.change( writer => {
|
|
|
|
|
+ writer.setSelection( null );
|
|
|
|
|
+ view.change( writer => {
|
|
|
|
|
+ writer.setSelection( viewEditable, 0 );
|
|
|
|
|
+ } );
|
|
|
|
|
+ } );
|
|
|
|
|
+ view.change( writer => {
|
|
|
|
|
+ writer.setSelection( null );
|
|
|
} );
|
|
} );
|
|
|
- view.change( () => {} );
|
|
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
sinon.assert.calledOnce( renderSpy );
|
|
sinon.assert.calledOnce( renderSpy );
|
|
@@ -545,11 +568,12 @@ describe( 'view', () => {
|
|
|
view.on( 'render', eventSpy );
|
|
view.on( 'render', eventSpy );
|
|
|
|
|
|
|
|
view.change( () => {
|
|
view.change( () => {
|
|
|
- view.render();
|
|
|
|
|
- view.change( () => {
|
|
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.forceRender();
|
|
|
|
|
+ view.change( writer => {
|
|
|
|
|
+ writer.setSelection( null );
|
|
|
|
|
+ view.forceRender();
|
|
|
} );
|
|
} );
|
|
|
- view.render();
|
|
|
|
|
|
|
+ view.forceRender();
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
|
sinon.assert.calledOnce( renderSpy );
|
|
sinon.assert.calledOnce( renderSpy );
|
|
@@ -567,7 +591,10 @@ describe( 'view', () => {
|
|
|
viewDocument.registerPostFixer( postFixer2 );
|
|
viewDocument.registerPostFixer( postFixer2 );
|
|
|
view.on( 'render', eventSpy );
|
|
view.on( 'render', eventSpy );
|
|
|
|
|
|
|
|
- view.change( changeSpy );
|
|
|
|
|
|
|
+ view.change( writer => {
|
|
|
|
|
+ changeSpy();
|
|
|
|
|
+ writer.setSelection( null );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
sinon.assert.calledOnce( postFixer1 );
|
|
sinon.assert.calledOnce( postFixer1 );
|
|
|
sinon.assert.calledOnce( postFixer2 );
|
|
sinon.assert.calledOnce( postFixer2 );
|
|
@@ -598,7 +625,10 @@ describe( 'view', () => {
|
|
|
} );
|
|
} );
|
|
|
view.on( 'render', eventSpy );
|
|
view.on( 'render', eventSpy );
|
|
|
|
|
|
|
|
- view.change( changeSpy );
|
|
|
|
|
|
|
+ view.change( writer => {
|
|
|
|
|
+ changeSpy();
|
|
|
|
|
+ writer.setSelection( null );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
sinon.assert.calledOnce( postFixer1 );
|
|
sinon.assert.calledOnce( postFixer1 );
|
|
|
sinon.assert.calledOnce( postFixer2 );
|
|
sinon.assert.calledOnce( postFixer2 );
|