|
@@ -284,7 +284,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 );
|
|
@@ -407,7 +407,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();
|
|
|
|
|
|
|
@@ -424,7 +424,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();
|
|
@@ -457,28 +457,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( renderSpy );
|
|
|
|
|
+ sinon.assert.calledOnce( layoutChangedSpy );
|
|
|
|
|
+ } );
|
|
|
|
|
|
|
|
- sinon.assert.calledOnce( spy );
|
|
|
|
|
|
|
+ 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 );
|
|
|
|
|
+
|
|
|
|
|
+ view.document.selection._setTo( null );
|
|
|
|
|
+ view.forceRender();
|
|
|
|
|
|
|
|
- sinon.assert.calledTwice( spy );
|
|
|
|
|
|
|
+ sinon.assert.calledOnce( renderSpy );
|
|
|
|
|
+ sinon.assert.calledOnce( layoutChangedSpy );
|
|
|
} );
|
|
} );
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
@@ -494,7 +507,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;
|
|
@@ -512,7 +525,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' );
|
|
@@ -531,13 +544,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' );
|
|
@@ -583,7 +596,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();
|
|
|
} );
|
|
} );
|
|
|
|
|
|
|
@@ -593,7 +606,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 );
|
|
|
} );
|
|
} );
|
|
@@ -601,16 +616,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 );
|
|
@@ -625,11 +648,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 );
|
|
@@ -647,7 +671,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 );
|
|
@@ -678,7 +705,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 );
|