From 31f48fa2cc74fdbd12a6367fa3d9ed0f8bece085 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Thu, 30 Jul 2020 10:49:48 +0200 Subject: [PATCH] Do not update the inspector on editor events when the UI is collapsed. --- src/ckeditorinspector.js | 43 ++++++++++++++++++++++++++-- tests/inspector/ckeditorinspector.js | 38 +++++++++++++++++++++++- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/ckeditorinspector.js b/src/ckeditorinspector.js index 6da67c6..0eda1e6 100644 --- a/src/ckeditorinspector.js +++ b/src/ckeditorinspector.js @@ -182,6 +182,7 @@ export default class CKEditorInspector { const container = CKEditorInspector._wrapper = document.createElement( 'div' ); let previousEditor; + let wasUICollapsed; container.className = 'ck-inspector-wrapper'; document.body.appendChild( container ); @@ -190,11 +191,29 @@ export default class CKEditorInspector { // is changing or the view is being rendered. CKEditorInspector._editorListener = new EditorListener( { onModelChange() { - CKEditorInspector._store.dispatch( updateModelState() ); - CKEditorInspector._store.dispatch( updateCommandsState() ); + const store = CKEditorInspector._store; + const isUICollapsed = store.getState().ui.isCollapsed; + + // Don't update the model and commands state if the entire inspector is collapsed. + // See https://github.com/ckeditor/ckeditor5-inspector/issues/80. + if ( isUICollapsed ) { + return; + } + + store.dispatch( updateModelState() ); + store.dispatch( updateCommandsState() ); }, onViewRender() { - CKEditorInspector._store.dispatch( updateViewState() ); + const store = CKEditorInspector._store; + const isUICollapsed = store.getState().ui.isCollapsed; + + // Don't update the view state if the entire inspector is collapsed. + // See https://github.com/ckeditor/ckeditor5-inspector/issues/80. + if ( isUICollapsed ) { + return; + } + + store.dispatch( updateViewState() ); } } ); @@ -234,6 +253,24 @@ export default class CKEditorInspector { } } ); + // Watch for changes of the current editor in the global store, and update the + // model/view/commands state when the UI uncollapses. Normally, when the inspector + // is collapsed, it does not respond to changes in the model/view/commands to improve + // the performance and DX. See https://github.com/ckeditor/ckeditor5-inspector/issues/80. + CKEditorInspector._store.subscribe( () => { + const store = CKEditorInspector._store; + const isUICollapsed = store.getState().ui.isCollapsed; + const hasUIUncollapsed = wasUICollapsed && !isUICollapsed; + + wasUICollapsed = isUICollapsed; + + if ( hasUIUncollapsed ) { + store.dispatch( updateModelState() ); + store.dispatch( updateCommandsState() ); + store.dispatch( updateViewState() ); + } + } ); + ReactDOM.render( diff --git a/tests/inspector/ckeditorinspector.js b/tests/inspector/ckeditorinspector.js index b1feae8..e3c8c12 100644 --- a/tests/inspector/ckeditorinspector.js +++ b/tests/inspector/ckeditorinspector.js @@ -16,7 +16,8 @@ import { import { SET_EDITORS, - setCurrentEditorName + setCurrentEditorName, + toggleIsCollapsed } from '../../src/data/actions'; import { LOCAL_STORAGE_IS_COLLAPSED } from '../../src/data/reducer'; @@ -137,6 +138,19 @@ describe( 'CKEditorInspector', () => { spy.restore(); } ); + // https://github.com/ckeditor/ckeditor5-inspector/issues/80 + it( 'should not respond to editor events when the inspector UI is collapsed', () => { + CKEditorInspector.attach( { foo: editor } ); + dispatchStoreAction( toggleIsCollapsed() ); + + const spy = sinon.stub( CKEditorInspector._store, 'dispatch' ); + + editor.model.document.fire( 'change' ); + sinon.assert.notCalled( spy ); + + spy.restore(); + } ); + it( 'should stop listening to editor events when the inspector is being detached', () => { CKEditorInspector.attach( { foo: editor } ); @@ -311,6 +325,28 @@ describe( 'CKEditorInspector', () => { } ); } ); + // https://github.com/ckeditor/ckeditor5-inspector/issues/80 + it( 'should update model/view/commands state immediatelly when the inspector UI uncollapses', () => { + CKEditorInspector.attach( { foo: editor } ); + + dispatchStoreAction( toggleIsCollapsed() ); + + const spy = sinon.spy( CKEditorInspector._store, 'dispatch' ); + + editor.model.document.fire( 'change' ); + sinon.assert.notCalled( spy ); + + dispatchStoreAction( toggleIsCollapsed() ); + + sinon.assert.callCount( spy, 4 ); + // Note: The 0 call was TOGGLE_IS_COLLAPSED. + sinon.assert.calledWithExactly( spy.getCall( 1 ), { type: UPDATE_MODEL_STATE } ); + sinon.assert.calledWithExactly( spy.getCall( 2 ), { type: UPDATE_COMMANDS_STATE } ); + sinon.assert.calledWithExactly( spy.getCall( 3 ), { type: UPDATE_VIEW_STATE } ); + + spy.restore(); + } ); + describe( 'options', () => { describe( '#isCollapsed', () => { it( 'should be false if unspecified', () => {