From 5244ab3c5954cf78bab29ed5f3c401294e74ee2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Thu, 10 Jan 2019 15:53:02 +0100 Subject: [PATCH 01/13] Move `element` getter and `uiReady` event to `EditorUI` and deprecate the former. --- src/editor/editor.js | 16 ++++++++++- src/editor/editorui.js | 38 +++++++++++++++++++++++++ src/editor/editorwithui.jsdoc | 25 ++++++++++++++-- tests/_utils-tests/classictesteditor.js | 29 +++++++++++++++++-- tests/_utils/classictesteditor.js | 2 +- tests/editor/editorui.js | 20 +++++++++++++ 6 files changed, 123 insertions(+), 7 deletions(-) diff --git a/src/editor/editor.js b/src/editor/editor.js index ccafa12a..30ccf323 100644 --- a/src/editor/editor.js +++ b/src/editor/editor.js @@ -21,6 +21,7 @@ import EditingKeystrokeHandler from '../editingkeystrokehandler'; import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin'; import mix from '@ckeditor/ckeditor5-utils/src/mix'; +import log from '@ckeditor/ckeditor5-utils/src/log'; import '@ckeditor/ckeditor5-utils/src/version'; @@ -319,7 +320,20 @@ export default class Editor { } } -mix( Editor, ObservableMixin ); +const ObservableMixinExtended = Object.assign( {}, ObservableMixin, { + + _listenTo: ObservableMixin.listenTo, + + listenTo( emitter, event, callback, options = {} ) { + if ( event === 'uiReady' ) { + log.warn( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ); + } + + this._listenTo( emitter, event, callback, options ); + } +} ); + +mix( Editor, ObservableMixinExtended ); /** * Fired after {@link #initPlugins plugins are initialized}. diff --git a/src/editor/editorui.js b/src/editor/editorui.js index 55dabdc3..d85d5c15 100644 --- a/src/editor/editorui.js +++ b/src/editor/editorui.js @@ -64,6 +64,35 @@ export default class EditorUI { this.listenTo( editor.editing.view.document, 'layoutChanged', () => this.update() ); } + /** + * The main (outermost) DOM element of the editor UI. + * + * For example, in {@link module:editor-classic/classiceditor~ClassicEditor} it is a `
` which + * wraps the editable element and the toolbar. In {@link module:editor-inline/inlineeditor~InlineEditor} + * it is the editable element itself (as there is no other wrapper). However, in + * {@link module:editor-decoupled/decouplededitor~DecoupledEditor} it is set to `null` because this editor does not + * come with a single "main" HTML element (its editable element and toolbar are separate). + * + * This property can be understood as a shorthand for retrieving the element that a specific editor integration + * considers to be its main DOM element. + * + * @readonly + * @member {HTMLElement|null} #element + */ + get element() { + return null; + } + + /** + * Fires the {@link module:core/editor/editorui~EditorUI#event:ready `ready`} event. + * + * This method should be called after {@link module:core/editor/editor~Editor#event:pluginsReady} and before + * {@link module:core/editor/editor~Editor#event:dataReady} by the specific editor creator. + */ + ready() { + this.fire( 'ready' ); + } + /** * Fires the {@link module:core/editor/editorui~EditorUI#event:update `update`} event. * @@ -82,6 +111,15 @@ export default class EditorUI { this.view.destroy(); } + /** + * Fired when the editor UI is ready. + * + * Fired after {@link module:core/editor/editor~Editor#event:pluginsReady} and before + * {@link module:core/editor/editor~Editor#event:dataReady}. + * + * @event ready + */ + /** * Fired whenever the UI (all related components) should be refreshed. * diff --git a/src/editor/editorwithui.jsdoc b/src/editor/editorwithui.jsdoc index 10aba4d9..16e3335e 100644 --- a/src/editor/editorwithui.jsdoc +++ b/src/editor/editorwithui.jsdoc @@ -29,6 +29,8 @@ */ /** + * **Deprecated** since `v12.0.0`. The {@link module:core/editor/editorui~EditorUI#element `EditorUI element`} should be used instead. + * * The main (outermost) DOM element of the editor UI. * * For example, in {@link module:editor-classic/classiceditor~ClassicEditor} it is a `
` which @@ -38,18 +40,37 @@ * come with a single "main" HTML element (its editable element and toolbar are separate). * * This property can be understood as a shorthand for retrieving the element that a specific editor integration - * considers to be its main DOM element. There are always other ways to access these elements, too - * (e.g. via {@link #ui `editor.ui`}). + * considers to be its main DOM element. * + * @deprecated v11.2.0 The {@link module:core/editor/editorui~EditorUI#element `EditorUI element`} should be used instead. * @readonly * @member {HTMLElement|null} #element */ /** + * **Deprecated** since `v12.0.0`. The {@link module:core/editor/editorui~EditorUI#event:ready ui ready event} should be listened to instead. + * * Fired when the editor UI is ready. * * Fired after {@link module:core/editor/editor~Editor#event:pluginsReady} and before * {@link module:core/editor/editor~Editor#event:dataReady}. * + * @deprecated v11.2.0 The {@link module:core/editor/editorui~EditorUI#event:ready ui ready event} should be listened to instead. * @event uiReady */ + +/** + * This error is thrown when a component tries to access deprecated + * {@link module:core/editor/editorwithui~EditorWithUI#element editor element}. Instead the + * {@link module:core/editor/editorui~EditorUI#element `EditorUI element`} should be used. + * + * @error deprecated-editor-element + */ + +/** + * This error is thrown when a component tries to listen to deprecated + * {@link module:core/editor/editorwithui~EditorWithUI#event:uiReady editor uiReady event}. + * Instead the {@link module:core/editor/editorui~EditorUI#event:ready ui ready event} should be listened to. + * + * @error deprecated-editor-event-uiReady + */ diff --git a/tests/_utils-tests/classictesteditor.js b/tests/_utils-tests/classictesteditor.js index 8b13cfba..704218cf 100644 --- a/tests/_utils-tests/classictesteditor.js +++ b/tests/_utils-tests/classictesteditor.js @@ -20,16 +20,19 @@ import ElementApiMixin from '../../src/editor/utils/elementapimixin'; import RootElement from '@ckeditor/ckeditor5-engine/src/model/rootelement'; import { getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; +import log from '@ckeditor/ckeditor5-utils/src/log'; import testUtils from '../../tests/_utils/utils'; describe( 'ClassicTestEditor', () => { - let editorElement; + let editorElement, logStub; testUtils.createSinonSandbox(); beforeEach( () => { editorElement = document.createElement( 'div' ); document.body.appendChild( editorElement ); + + logStub = testUtils.sinon.stub( log, 'warn' ).callsFake( () => {} ); } ); describe( 'constructor()', () => { @@ -122,7 +125,7 @@ describe( 'ClassicTestEditor', () => { class EventWatcher extends Plugin { init() { this.editor.on( 'pluginsReady', spy ); - this.editor.on( 'uiReady', spy ); + this.editor.ui.on( 'ready', spy ); this.editor.on( 'dataReady', spy ); this.editor.on( 'ready', spy ); } @@ -133,7 +136,7 @@ describe( 'ClassicTestEditor', () => { plugins: [ EventWatcher ] } ) .then( editor => { - expect( fired ).to.deep.equal( [ 'pluginsReady', 'uiReady', 'dataReady', 'ready' ] ); + expect( fired ).to.deep.equal( [ 'pluginsReady', 'ready', 'dataReady', 'ready' ] ); return editor.destroy(); } ); @@ -199,4 +202,24 @@ describe( 'ClassicTestEditor', () => { } ); } ); } ); + + describe( 'deprecated uiReady event', () => { + it( 'logs deprecated warning when attaching uiReady on listener', () => { + return ClassicTestEditor.create( editorElement, { foo: 1 } ) + .then( editor => { + editor.on( 'uiReady', () => {} ); + + expect( logStub.calledOnceWith( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ) ).to.true; + } ); + } ); + + it( 'logs deprecated warning when attaching uiReady once listener', () => { + return ClassicTestEditor.create( editorElement, { foo: 1 } ) + .then( editor => { + editor.once( 'uiReady', () => {} ); + + expect( logStub.calledOnceWith( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ) ).to.true; + } ); + } ); + } ); } ); diff --git a/tests/_utils/classictesteditor.js b/tests/_utils/classictesteditor.js index 2507402f..c032d52d 100644 --- a/tests/_utils/classictesteditor.js +++ b/tests/_utils/classictesteditor.js @@ -75,7 +75,7 @@ export default class ClassicTestEditor extends Editor { } ) .then( () => { editor._elementReplacer.replace( element, editor.ui.view.element ); - editor.fire( 'uiReady' ); + editor.ui.ready(); } ) .then( () => editor.editing.view.attachDomRoot( editor.ui.view.editableElement ) ) .then( () => editor.data.init( getDataFromElement( element ) ) ) diff --git a/tests/editor/editorui.js b/tests/editor/editorui.js index b5ff4936..12939e56 100644 --- a/tests/editor/editorui.js +++ b/tests/editor/editorui.js @@ -44,6 +44,10 @@ describe( 'EditorUI', () => { expect( ui.focusTracker ).to.be.instanceOf( FocusTracker ); } ); + it( 'should have #element getter', () => { + expect( ui.element ).to.null; + } ); + it( 'should fire update event after viewDocument#layoutChanged', () => { const spy = sinon.spy(); @@ -59,6 +63,22 @@ describe( 'EditorUI', () => { } ); } ); + describe( 'ready()', () => { + it( 'should fire ready event', () => { + const spy = sinon.spy(); + + ui.on( 'ready', spy ); + + ui.ready(); + + sinon.assert.calledOnce( spy ); + + ui.ready(); + + sinon.assert.calledTwice( spy ); + } ); + } ); + describe( 'update()', () => { it( 'should fire update event', () => { const spy = sinon.spy(); From 917ab794b72ecfca02b118ef37674f47a8cf7d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 14 Jan 2019 14:50:47 +0100 Subject: [PATCH 02/13] Added `getEditableElement` method and deprecated `view` property in `EditorUI`. --- src/editor/editorui.js | 79 +++++++++++++++++++++---- tests/_utils-tests/classictesteditor.js | 4 +- tests/_utils/classictesteditor.js | 29 ++++++++- tests/editor/editorui.js | 34 +++++++++-- 4 files changed, 128 insertions(+), 18 deletions(-) diff --git a/src/editor/editorui.js b/src/editor/editorui.js index d85d5c15..1b0f4439 100644 --- a/src/editor/editorui.js +++ b/src/editor/editorui.js @@ -12,6 +12,7 @@ import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin'; import mix from '@ckeditor/ckeditor5-utils/src/mix'; +import log from '@ckeditor/ckeditor5-utils/src/log'; /** * A class providing the minimal interface that is required to successfully bootstrap any editor UI. @@ -23,7 +24,8 @@ export default class EditorUI { * Creates an instance of the editor UI class. * * @param {module:core/editor/editor~Editor} editor The editor instance. - * @param {module:ui/editorui/editoruiview~EditorUIView} view The view of the UI. + * @param {module:ui/editorui/editoruiview~EditorUIView} [view] The view of the UI. This parameter is **deprecated** + * since `v12.0.0` and should not be used. */ constructor( editor, view ) { /** @@ -34,14 +36,6 @@ export default class EditorUI { */ this.editor = editor; - /** - * The main (top–most) view of the editor UI. - * - * @readonly - * @member {module:ui/editorui/editoruiview~EditorUIView} #view - */ - this.view = view; - /** * An instance of the {@link module:ui/componentfactory~ComponentFactory}, a registry used by plugins * to register factories of specific UI components. @@ -60,10 +54,64 @@ export default class EditorUI { */ this.focusTracker = new FocusTracker(); + /** + * **Deprecated** since `v12.0.0`. This property is deprecated and should not be used. Use the property + * from the subclass directly instead, for example + * {@link module:editor-classic/classiceditorui~ClassicEditorUI#_view ClassicEditorUI#_view}. + * + * The main (top–most) view of the editor UI. + * + * @deprecated v12.0.0 This property is deprecated and should not be used. Use the property + * from the subclass directly instead, for example + * {@link module:editor-classic/classiceditorui~ClassicEditorUI#_view ClassicEditorUI#_view}. + * @private + * @member {module:ui/editorui/editoruiview~EditorUIView} #_view + */ + this._view = view; + + // Check if `view` parameter was passed. It is deprecated and should not be used. + if ( view ) { + /** + * This error is thrown when the deprecated `view` parameter is passed to the + * {@link module:core/editor/editorui~EditorUI#constructor EditorUI constructor}. Only subclass (for example + * {@link module:editor-classic/classiceditorui~ClassicEditorUI}) should use it without passing it further. + * + * @error deprecated-editorui-view-param-in-constructor + */ + log.warn( 'deprecated-editorui-view-param-in-constructor: The EditorUI#constructor `view` parameter is deprecated.' ); + } + // Informs UI components that should be refreshed after layout change. this.listenTo( editor.editing.view.document, 'layoutChanged', () => this.update() ); } + /** + * **Deprecated** since `v12.0.0`. This property is deprecated and should not be used. Use the property + * from the subclass directly instead, for example + * {@link module:editor-classic/classiceditorui~ClassicEditorUI#view ClassicEditorUI#view}. + * + * The main (top–most) view of the editor UI. + * + * @deprecated v12.0.0 This property is deprecated and should not be used. Use the property + * from the subclass directly instead, for example + * {@link module:editor-classic/classiceditorui~ClassicEditorUI#view ClassicEditorUI#view}. + * @readonly + * @member {module:ui/editorui/editoruiview~EditorUIView} #view + */ + get view() { + /** + * This error is thrown when a component tries to access deprecated + * {@link module:core/editor/editorui~EditorUI#element `EditorUI view`} property. Instead the `view` property + * from the subclass (for example {@link module:editor-classic/classiceditorui~ClassicEditorUI#view ClassicEditorUI#view}) + * should be accessed directly. + * + * @error deprecated-editorui-view + */ + log.warn( 'deprecated-editorui-view: The EditorUI#view property is deprecated.' ); + + return this._view; + } + /** * The main (outermost) DOM element of the editor UI. * @@ -108,9 +156,20 @@ export default class EditorUI { */ destroy() { this.stopListening(); - this.view.destroy(); + + if ( this._view ) { + this._view.destroy(); + } } + /** + * Returns the editable editor element with the given name or null if editable does not exist. + * + * @method module:core/editor/editorui~EditorUI#getEditableElement + * @param {String} [rootName=main] The editable name. + * @returns {module:ui/editableui/editableuiview~EditableUIView|null} + */ + /** * Fired when the editor UI is ready. * diff --git a/tests/_utils-tests/classictesteditor.js b/tests/_utils-tests/classictesteditor.js index 704218cf..a84c6955 100644 --- a/tests/_utils-tests/classictesteditor.js +++ b/tests/_utils-tests/classictesteditor.js @@ -209,7 +209,7 @@ describe( 'ClassicTestEditor', () => { .then( editor => { editor.on( 'uiReady', () => {} ); - expect( logStub.calledOnceWith( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ) ).to.true; + expect( logStub.calledWith( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ) ).to.true; } ); } ); @@ -218,7 +218,7 @@ describe( 'ClassicTestEditor', () => { .then( editor => { editor.once( 'uiReady', () => {} ); - expect( logStub.calledOnceWith( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ) ).to.true; + expect( logStub.calledWith( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ) ).to.true; } ); } ); } ); diff --git a/tests/_utils/classictesteditor.js b/tests/_utils/classictesteditor.js index c032d52d..fc1929ac 100644 --- a/tests/_utils/classictesteditor.js +++ b/tests/_utils/classictesteditor.js @@ -33,7 +33,7 @@ export default class ClassicTestEditor extends Editor { // Use the HTML data processor in this editor. this.data.processor = new HtmlDataProcessor(); - this.ui = new EditorUI( this, new BoxedEditorUIView( this.locale ) ); + this.ui = new ClassicTestEditorUI( this, new BoxedEditorUIView( this.locale ) ); // Expose properties normally exposed by the ClassicEditorUI. this.ui.view.editable = new InlineEditableUIView( this.ui.view.locale ); @@ -90,5 +90,32 @@ export default class ClassicTestEditor extends Editor { } } +/** + * A simplified classic editor ui class. + * + * @memberOf tests.core._utils + * @extends core.editor.EditorUI + */ +class ClassicTestEditorUI extends EditorUI { + /** + * @inheritDoc + */ + constructor( editor, view ) { + super( editor ); + + this._view = view; + } + + /** + * The main (top–most) view of the editor UI. + * + * @readonly + * @member {module:ui/editorui/editoruiview~EditorUIView} #view + */ + get view() { + return this._view; + } +} + mix( ClassicTestEditor, DataApiMixin ); mix( ClassicTestEditor, ElementApiMixin ); diff --git a/tests/editor/editorui.js b/tests/editor/editorui.js index 12939e56..82dab5b0 100644 --- a/tests/editor/editorui.js +++ b/tests/editor/editorui.js @@ -11,16 +11,16 @@ import ComponentFactory from '@ckeditor/ckeditor5-ui/src/componentfactory'; import View from '@ckeditor/ckeditor5-ui/src/view'; import testUtils from '../_utils/utils'; +import log from '@ckeditor/ckeditor5-utils/src/log'; describe( 'EditorUI', () => { - let editor, view, ui; + let editor, ui; testUtils.createSinonSandbox(); beforeEach( () => { editor = new Editor(); - view = new View(); - ui = new EditorUI( editor, view ); + ui = new EditorUI( editor ); } ); afterEach( () => { @@ -32,7 +32,20 @@ describe( 'EditorUI', () => { expect( ui.editor ).to.equal( editor ); } ); - it( 'should set #view', () => { + it( 'should not set #view by default', () => { + testUtils.sinon.stub( log, 'warn' ).callsFake( () => {} ); + + expect( ui._view ).to.undefined; + expect( ui.view ).to.undefined; + } ); + + it( 'should set #view if passed', () => { + testUtils.sinon.stub( log, 'warn' ).callsFake( () => {} ); + + const editor = new Editor(); + const view = new View(); + const ui = new EditorUI( editor, view ); + expect( ui.view ).to.equal( view ); } ); @@ -104,12 +117,23 @@ describe( 'EditorUI', () => { sinon.assert.called( spy ); } ); - it( 'should destroy the #view', () => { + it( 'should destroy the #view if present', () => { + testUtils.sinon.stub( log, 'warn' ).callsFake( () => {} ); + + const editor = new Editor(); + const view = new View(); + const ui = new EditorUI( editor, view ); const spy = sinon.spy( view, 'destroy' ); ui.destroy(); sinon.assert.called( spy ); } ); + + it( 'should not throw when view absent', () => { + expect( () => { + ui.destroy(); + } ).to.not.throw(); + } ); } ); } ); From 4508a01c8362b7b8f8f86b456a93a7f994ba30f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Tue, 15 Jan 2019 13:08:12 +0100 Subject: [PATCH 03/13] Docs: Corrected deprecated annotation. --- src/editor/editorwithui.jsdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/editor/editorwithui.jsdoc b/src/editor/editorwithui.jsdoc index 16e3335e..cb0a78e9 100644 --- a/src/editor/editorwithui.jsdoc +++ b/src/editor/editorwithui.jsdoc @@ -42,7 +42,7 @@ * This property can be understood as a shorthand for retrieving the element that a specific editor integration * considers to be its main DOM element. * - * @deprecated v11.2.0 The {@link module:core/editor/editorui~EditorUI#element `EditorUI element`} should be used instead. + * @deprecated v12.0.0 The {@link module:core/editor/editorui~EditorUI#element `EditorUI element`} should be used instead. * @readonly * @member {HTMLElement|null} #element */ @@ -55,7 +55,7 @@ * Fired after {@link module:core/editor/editor~Editor#event:pluginsReady} and before * {@link module:core/editor/editor~Editor#event:dataReady}. * - * @deprecated v11.2.0 The {@link module:core/editor/editorui~EditorUI#event:ready ui ready event} should be listened to instead. + * @deprecated v12.0.0 The {@link module:core/editor/editorui~EditorUI#event:ready ui ready event} should be listened to instead. * @event uiReady */ From f608c66535d91a0c477433e397af21c5394f99f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Thu, 17 Jan 2019 13:19:48 +0100 Subject: [PATCH 04/13] Refactoring. --- src/editor/editorui.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/editor/editorui.js b/src/editor/editorui.js index 1b0f4439..0cc00c11 100644 --- a/src/editor/editorui.js +++ b/src/editor/editorui.js @@ -139,6 +139,7 @@ export default class EditorUI { */ ready() { this.fire( 'ready' ); + this.fire( 'uiReady' ); } /** @@ -167,7 +168,7 @@ export default class EditorUI { * * @method module:core/editor/editorui~EditorUI#getEditableElement * @param {String} [rootName=main] The editable name. - * @returns {module:ui/editableui/editableuiview~EditableUIView|null} + * @returns {HTMLElement|null} */ /** From cae9a087c5918fb77d7b8c458db496d52b031824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Thu, 17 Jan 2019 14:34:02 +0100 Subject: [PATCH 05/13] Fire `uiReady` event on editor instance. --- src/editor/editorui.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/editor/editorui.js b/src/editor/editorui.js index 0cc00c11..da06feeb 100644 --- a/src/editor/editorui.js +++ b/src/editor/editorui.js @@ -139,7 +139,7 @@ export default class EditorUI { */ ready() { this.fire( 'ready' ); - this.fire( 'uiReady' ); + this.editor.fire( 'uiReady' ); } /** From 82dd46b3204a53157ac018656f300083d494908e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Thu, 17 Jan 2019 17:54:18 +0100 Subject: [PATCH 06/13] Introduced `getEditableElement()` and `getEditableElementsNames()` methods in `EditorUI`. --- src/editor/editorui.js | 25 +++++++++++++++++++- tests/editor/editorui.js | 50 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/editor/editorui.js b/src/editor/editorui.js index da06feeb..f9dc7475 100644 --- a/src/editor/editorui.js +++ b/src/editor/editorui.js @@ -54,6 +54,14 @@ export default class EditorUI { */ this.focusTracker = new FocusTracker(); + /** + * Stores all editable elements used by the editor instance. + * + * @protected + * @member {Array.} + */ + this._editableElements = []; + /** * **Deprecated** since `v12.0.0`. This property is deprecated and should not be used. Use the property * from the subclass directly instead, for example @@ -158,6 +166,8 @@ export default class EditorUI { destroy() { this.stopListening(); + this._editableElements = []; + if ( this._view ) { this._view.destroy(); } @@ -166,10 +176,23 @@ export default class EditorUI { /** * Returns the editable editor element with the given name or null if editable does not exist. * - * @method module:core/editor/editorui~EditorUI#getEditableElement * @param {String} [rootName=main] The editable name. * @returns {HTMLElement|null} */ + getEditableElement( rootName = 'main' ) { + const editable = this._editableElements.find( editable => editable.name === rootName ); + + return editable ? editable.element : null; + } + + /** + * Returns array of names of all editor editable elements. + * + * @returns {Array.} + */ + getEditableElementsNames() { + return this._editableElements.map( editable => editable.name ); + } /** * Fired when the editor UI is ready. diff --git a/tests/editor/editorui.js b/tests/editor/editorui.js index 82dab5b0..2e26576d 100644 --- a/tests/editor/editorui.js +++ b/tests/editor/editorui.js @@ -13,6 +13,8 @@ import View from '@ckeditor/ckeditor5-ui/src/view'; import testUtils from '../_utils/utils'; import log from '@ckeditor/ckeditor5-utils/src/log'; +/* global document */ + describe( 'EditorUI', () => { let editor, ui; @@ -136,4 +138,52 @@ describe( 'EditorUI', () => { } ).to.not.throw(); } ); } ); + + describe( 'getEditableElement()', () => { + it( 'should return editable element (default root name)', () => { + const ui = new EditorUI( editor ); + const editableMock = { name: 'main', element: document.createElement( 'div' ) }; + + ui._editableElements.push( editableMock ); + + expect( ui.getEditableElement() ).to.equal( editableMock.element ); + } ); + + it( 'should return editable element (custom root name)', () => { + const ui = new EditorUI( editor ); + const editableMock1 = { name: 'root1', element: document.createElement( 'div' ) }; + const editableMock2 = { name: 'root2', element: document.createElement( 'p' ) }; + + ui._editableElements.push( editableMock1 ); + ui._editableElements.push( editableMock2 ); + + expect( ui.getEditableElement( 'root1' ) ).to.equal( editableMock1.element ); + expect( ui.getEditableElement( 'root2' ) ).to.equal( editableMock2.element ); + } ); + + it( 'should return null if editable with specified name does not exist', () => { + const ui = new EditorUI( editor ); + + expect( ui.getEditableElement() ).to.null; + } ); + } ); + + describe( 'getEditableElementsNames()', () => { + it( 'should return array of names', () => { + const ui = new EditorUI( editor ); + const editableMock1 = { name: 'main', element: document.createElement( 'div' ) }; + const editableMock2 = { name: 'root2', element: document.createElement( 'p' ) }; + + ui._editableElements.push( editableMock1 ); + ui._editableElements.push( editableMock2 ); + + expect( ui.getEditableElementsNames() ).to.deep.equal( [ 'main', 'root2' ] ); + } ); + + it( 'should return empty array if no editables', () => { + const ui = new EditorUI( editor ); + + expect( ui.getEditableElementsNames() ).to.be.empty; + } ); + } ); } ); From 0920efcdc7af71a138744bd6f792bd7d71b3ffee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Fri, 18 Jan 2019 13:15:24 +0100 Subject: [PATCH 07/13] Delegate `ready` event as `uiReady` event instead of using `ready()` method. --- src/editor/editorui.js | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/editor/editorui.js b/src/editor/editorui.js index f9dc7475..09e826f1 100644 --- a/src/editor/editorui.js +++ b/src/editor/editorui.js @@ -91,6 +91,9 @@ export default class EditorUI { // Informs UI components that should be refreshed after layout change. this.listenTo( editor.editing.view.document, 'layoutChanged', () => this.update() ); + + // Delegate `ready` as `editor.uiReady` event. The `uiReady` is deprecated and should be fired too. + this.delegate( 'ready' ).to( this.editor, 'uiReady' ); } /** @@ -139,17 +142,6 @@ export default class EditorUI { return null; } - /** - * Fires the {@link module:core/editor/editorui~EditorUI#event:ready `ready`} event. - * - * This method should be called after {@link module:core/editor/editor~Editor#event:pluginsReady} and before - * {@link module:core/editor/editor~Editor#event:dataReady} by the specific editor creator. - */ - ready() { - this.fire( 'ready' ); - this.editor.fire( 'uiReady' ); - } - /** * Fires the {@link module:core/editor/editorui~EditorUI#event:update `update`} event. * From 8456f20e0ad56e688a57981a37a6f05966c938b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Fri, 18 Jan 2019 13:16:21 +0100 Subject: [PATCH 08/13] Tests: Test editor adjustments. --- tests/_utils/classictesteditor.js | 39 +++++++++++++++++++------------ tests/editor/editorui.js | 16 ------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/tests/_utils/classictesteditor.js b/tests/_utils/classictesteditor.js index fc1929ac..4b11a94c 100644 --- a/tests/_utils/classictesteditor.js +++ b/tests/_utils/classictesteditor.js @@ -38,9 +38,6 @@ export default class ClassicTestEditor extends Editor { // Expose properties normally exposed by the ClassicEditorUI. this.ui.view.editable = new InlineEditableUIView( this.ui.view.locale ); - // A helper to easily replace the editor#element with editor.editable#element. - this._elementReplacer = new ElementReplacer(); - // Create the ("main") root element of the model tree. this.model.document.createRoot(); } @@ -49,7 +46,6 @@ export default class ClassicTestEditor extends Editor { * @inheritDoc */ destroy() { - this._elementReplacer.restore(); this.ui.destroy(); return super.destroy(); @@ -66,17 +62,7 @@ export default class ClassicTestEditor extends Editor { editor.initPlugins() // Simulate EditorUI.init() (e.g. like in ClassicEditorUI). The ui#view // should be rendered after plugins are initialized. - .then( () => { - const view = editor.ui.view; - - view.render(); - view.main.add( view.editable ); - view.editableElement = view.editable.element; - } ) - .then( () => { - editor._elementReplacer.replace( element, editor.ui.view.element ); - editor.ui.ready(); - } ) + .then( () => editor.ui.init( element ) ) .then( () => editor.editing.view.attachDomRoot( editor.ui.view.editableElement ) ) .then( () => editor.data.init( getDataFromElement( element ) ) ) .then( () => { @@ -103,6 +89,9 @@ class ClassicTestEditorUI extends EditorUI { constructor( editor, view ) { super( editor ); + // A helper to easily replace the editor#element with editor.editable#element. + this._elementReplacer = new ElementReplacer(); + this._view = view; } @@ -115,6 +104,26 @@ class ClassicTestEditorUI extends EditorUI { get view() { return this._view; } + + init( element ) { + const view = this.view; + + view.render(); + view.main.add( view.editable ); + view.editableElement = view.editable.element; + + this._elementReplacer.replace( element, this.view.element ); + + this.fire( 'ready' ); + } + + /** + * @inheritDoc + */ + destroy() { + this._elementReplacer.restore(); + super.destroy(); + } } mix( ClassicTestEditor, DataApiMixin ); diff --git a/tests/editor/editorui.js b/tests/editor/editorui.js index 2e26576d..df54217e 100644 --- a/tests/editor/editorui.js +++ b/tests/editor/editorui.js @@ -78,22 +78,6 @@ describe( 'EditorUI', () => { } ); } ); - describe( 'ready()', () => { - it( 'should fire ready event', () => { - const spy = sinon.spy(); - - ui.on( 'ready', spy ); - - ui.ready(); - - sinon.assert.calledOnce( spy ); - - ui.ready(); - - sinon.assert.calledTwice( spy ); - } ); - } ); - describe( 'update()', () => { it( 'should fire update event', () => { const spy = sinon.spy(); From e0f2968c6a6edb83451605cb41bf6bfb82c6d6ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 21 Jan 2019 12:17:36 +0100 Subject: [PATCH 09/13] Refactoring. --- src/editor/editorui.js | 21 ++++++--------------- tests/editor/editorui.js | 16 +++++++++------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/editor/editorui.js b/src/editor/editorui.js index 09e826f1..cee04cce 100644 --- a/src/editor/editorui.js +++ b/src/editor/editorui.js @@ -58,24 +58,17 @@ export default class EditorUI { * Stores all editable elements used by the editor instance. * * @protected - * @member {Array.} + * @member {Map.} */ - this._editableElements = []; + this._editableElements = new Map(); /** - * **Deprecated** since `v12.0.0`. This property is deprecated and should not be used. Use the property - * from the subclass directly instead, for example - * {@link module:editor-classic/classiceditorui~ClassicEditorUI#_view ClassicEditorUI#_view}. - * * The main (top–most) view of the editor UI. * - * @deprecated v12.0.0 This property is deprecated and should not be used. Use the property - * from the subclass directly instead, for example - * {@link module:editor-classic/classiceditorui~ClassicEditorUI#_view ClassicEditorUI#_view}. * @private * @member {module:ui/editorui/editoruiview~EditorUIView} #_view */ - this._view = view; + this._view = view; // This property was created in order to deprecate `this.view`. Should be removed with removal of `view` getter. // Check if `view` parameter was passed. It is deprecated and should not be used. if ( view ) { @@ -172,18 +165,16 @@ export default class EditorUI { * @returns {HTMLElement|null} */ getEditableElement( rootName = 'main' ) { - const editable = this._editableElements.find( editable => editable.name === rootName ); - - return editable ? editable.element : null; + return this._editableElements.has( rootName ) ? this._editableElements.get( rootName ) : null; } /** * Returns array of names of all editor editable elements. * - * @returns {Array.} + * @returns {Iterable.} */ getEditableElementsNames() { - return this._editableElements.map( editable => editable.name ); + return this._editableElements.keys(); } /** diff --git a/tests/editor/editorui.js b/tests/editor/editorui.js index df54217e..655e7dd6 100644 --- a/tests/editor/editorui.js +++ b/tests/editor/editorui.js @@ -128,7 +128,7 @@ describe( 'EditorUI', () => { const ui = new EditorUI( editor ); const editableMock = { name: 'main', element: document.createElement( 'div' ) }; - ui._editableElements.push( editableMock ); + ui._editableElements.set( editableMock.name, editableMock.element ); expect( ui.getEditableElement() ).to.equal( editableMock.element ); } ); @@ -138,8 +138,8 @@ describe( 'EditorUI', () => { const editableMock1 = { name: 'root1', element: document.createElement( 'div' ) }; const editableMock2 = { name: 'root2', element: document.createElement( 'p' ) }; - ui._editableElements.push( editableMock1 ); - ui._editableElements.push( editableMock2 ); + ui._editableElements.set( editableMock1.name, editableMock1.element ); + ui._editableElements.set( editableMock2.name, editableMock2.element ); expect( ui.getEditableElement( 'root1' ) ).to.equal( editableMock1.element ); expect( ui.getEditableElement( 'root2' ) ).to.equal( editableMock2.element ); @@ -153,15 +153,17 @@ describe( 'EditorUI', () => { } ); describe( 'getEditableElementsNames()', () => { - it( 'should return array of names', () => { + it( 'should return iterable object of names', () => { const ui = new EditorUI( editor ); const editableMock1 = { name: 'main', element: document.createElement( 'div' ) }; const editableMock2 = { name: 'root2', element: document.createElement( 'p' ) }; - ui._editableElements.push( editableMock1 ); - ui._editableElements.push( editableMock2 ); + ui._editableElements.set( editableMock1.name, editableMock1.element ); + ui._editableElements.set( editableMock2.name, editableMock2.element ); - expect( ui.getEditableElementsNames() ).to.deep.equal( [ 'main', 'root2' ] ); + const names = ui.getEditableElementsNames(); + expect( names[ Symbol.iterator ] ).to.instanceof( Function ); + expect( Array.from( names ) ).to.deep.equal( [ 'main', 'root2' ] ); } ); it( 'should return empty array if no editables', () => { From 8f0e82bd481bdba7c346f3ba428b5d10ebad0f86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 21 Jan 2019 12:20:08 +0100 Subject: [PATCH 10/13] Param name updated. --- src/editor/editor.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/editor/editor.js b/src/editor/editor.js index 30ccf323..6a2f9557 100644 --- a/src/editor/editor.js +++ b/src/editor/editor.js @@ -324,12 +324,12 @@ const ObservableMixinExtended = Object.assign( {}, ObservableMixin, { _listenTo: ObservableMixin.listenTo, - listenTo( emitter, event, callback, options = {} ) { - if ( event === 'uiReady' ) { + listenTo( emitter, evt, callback, options = {} ) { + if ( evt === 'uiReady' ) { log.warn( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ); } - this._listenTo( emitter, event, callback, options ); + this._listenTo( emitter, evt, callback, options ); } } ); From ccb03daba5e0f3aa95570903066ef42572c92fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Mon, 21 Jan 2019 13:37:06 +0100 Subject: [PATCH 11/13] Tests: Adjusted `ClassicTestEditor`. --- tests/_utils/classictesteditor.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/_utils/classictesteditor.js b/tests/_utils/classictesteditor.js index 4b11a94c..b49c40f3 100644 --- a/tests/_utils/classictesteditor.js +++ b/tests/_utils/classictesteditor.js @@ -112,6 +112,8 @@ class ClassicTestEditorUI extends EditorUI { view.main.add( view.editable ); view.editableElement = view.editable.element; + this._editableElements.set( 'main', view.editable.element ); + this._elementReplacer.replace( element, this.view.element ); this.fire( 'ready' ); From c914464545ec6fc5ab1533d7df153953cb77a794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Krzto=C5=84?= Date: Tue, 22 Jan 2019 09:09:13 +0100 Subject: [PATCH 12/13] Removed deprecated code. --- src/editor/editor.js | 16 +------ src/editor/editorui.js | 61 +------------------------ src/editor/editorwithui.jsdoc | 47 ------------------- tests/_utils-tests/classictesteditor.js | 25 +--------- tests/_utils/classictesteditor.js | 7 ++- tests/editor/editorui.js | 37 ++------------- 6 files changed, 14 insertions(+), 179 deletions(-) diff --git a/src/editor/editor.js b/src/editor/editor.js index 6a2f9557..ccafa12a 100644 --- a/src/editor/editor.js +++ b/src/editor/editor.js @@ -21,7 +21,6 @@ import EditingKeystrokeHandler from '../editingkeystrokehandler'; import ObservableMixin from '@ckeditor/ckeditor5-utils/src/observablemixin'; import mix from '@ckeditor/ckeditor5-utils/src/mix'; -import log from '@ckeditor/ckeditor5-utils/src/log'; import '@ckeditor/ckeditor5-utils/src/version'; @@ -320,20 +319,7 @@ export default class Editor { } } -const ObservableMixinExtended = Object.assign( {}, ObservableMixin, { - - _listenTo: ObservableMixin.listenTo, - - listenTo( emitter, evt, callback, options = {} ) { - if ( evt === 'uiReady' ) { - log.warn( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ); - } - - this._listenTo( emitter, evt, callback, options ); - } -} ); - -mix( Editor, ObservableMixinExtended ); +mix( Editor, ObservableMixin ); /** * Fired after {@link #initPlugins plugins are initialized}. diff --git a/src/editor/editorui.js b/src/editor/editorui.js index cee04cce..eb953d9e 100644 --- a/src/editor/editorui.js +++ b/src/editor/editorui.js @@ -12,7 +12,6 @@ import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin'; import mix from '@ckeditor/ckeditor5-utils/src/mix'; -import log from '@ckeditor/ckeditor5-utils/src/log'; /** * A class providing the minimal interface that is required to successfully bootstrap any editor UI. @@ -24,10 +23,8 @@ export default class EditorUI { * Creates an instance of the editor UI class. * * @param {module:core/editor/editor~Editor} editor The editor instance. - * @param {module:ui/editorui/editoruiview~EditorUIView} [view] The view of the UI. This parameter is **deprecated** - * since `v12.0.0` and should not be used. */ - constructor( editor, view ) { + constructor( editor ) { /** * The editor that the UI belongs to. * @@ -62,58 +59,8 @@ export default class EditorUI { */ this._editableElements = new Map(); - /** - * The main (top–most) view of the editor UI. - * - * @private - * @member {module:ui/editorui/editoruiview~EditorUIView} #_view - */ - this._view = view; // This property was created in order to deprecate `this.view`. Should be removed with removal of `view` getter. - - // Check if `view` parameter was passed. It is deprecated and should not be used. - if ( view ) { - /** - * This error is thrown when the deprecated `view` parameter is passed to the - * {@link module:core/editor/editorui~EditorUI#constructor EditorUI constructor}. Only subclass (for example - * {@link module:editor-classic/classiceditorui~ClassicEditorUI}) should use it without passing it further. - * - * @error deprecated-editorui-view-param-in-constructor - */ - log.warn( 'deprecated-editorui-view-param-in-constructor: The EditorUI#constructor `view` parameter is deprecated.' ); - } - // Informs UI components that should be refreshed after layout change. this.listenTo( editor.editing.view.document, 'layoutChanged', () => this.update() ); - - // Delegate `ready` as `editor.uiReady` event. The `uiReady` is deprecated and should be fired too. - this.delegate( 'ready' ).to( this.editor, 'uiReady' ); - } - - /** - * **Deprecated** since `v12.0.0`. This property is deprecated and should not be used. Use the property - * from the subclass directly instead, for example - * {@link module:editor-classic/classiceditorui~ClassicEditorUI#view ClassicEditorUI#view}. - * - * The main (top–most) view of the editor UI. - * - * @deprecated v12.0.0 This property is deprecated and should not be used. Use the property - * from the subclass directly instead, for example - * {@link module:editor-classic/classiceditorui~ClassicEditorUI#view ClassicEditorUI#view}. - * @readonly - * @member {module:ui/editorui/editoruiview~EditorUIView} #view - */ - get view() { - /** - * This error is thrown when a component tries to access deprecated - * {@link module:core/editor/editorui~EditorUI#element `EditorUI view`} property. Instead the `view` property - * from the subclass (for example {@link module:editor-classic/classiceditorui~ClassicEditorUI#view ClassicEditorUI#view}) - * should be accessed directly. - * - * @error deprecated-editorui-view - */ - log.warn( 'deprecated-editorui-view: The EditorUI#view property is deprecated.' ); - - return this._view; } /** @@ -151,11 +98,7 @@ export default class EditorUI { destroy() { this.stopListening(); - this._editableElements = []; - - if ( this._view ) { - this._view.destroy(); - } + this._editableElements = new Map(); } /** diff --git a/src/editor/editorwithui.jsdoc b/src/editor/editorwithui.jsdoc index cb0a78e9..ba938a66 100644 --- a/src/editor/editorwithui.jsdoc +++ b/src/editor/editorwithui.jsdoc @@ -27,50 +27,3 @@ * @readonly * @member {module:core/editor/editorui~EditorUI} #ui */ - -/** - * **Deprecated** since `v12.0.0`. The {@link module:core/editor/editorui~EditorUI#element `EditorUI element`} should be used instead. - * - * The main (outermost) DOM element of the editor UI. - * - * For example, in {@link module:editor-classic/classiceditor~ClassicEditor} it is a `
` which - * wraps the editable element and the toolbar. In {@link module:editor-inline/inlineeditor~InlineEditor} - * it is the editable element itself (as there is no other wrapper). However, in - * {@link module:editor-decoupled/decouplededitor~DecoupledEditor} it is set to `null` because this editor does not - * come with a single "main" HTML element (its editable element and toolbar are separate). - * - * This property can be understood as a shorthand for retrieving the element that a specific editor integration - * considers to be its main DOM element. - * - * @deprecated v12.0.0 The {@link module:core/editor/editorui~EditorUI#element `EditorUI element`} should be used instead. - * @readonly - * @member {HTMLElement|null} #element - */ - -/** - * **Deprecated** since `v12.0.0`. The {@link module:core/editor/editorui~EditorUI#event:ready ui ready event} should be listened to instead. - * - * Fired when the editor UI is ready. - * - * Fired after {@link module:core/editor/editor~Editor#event:pluginsReady} and before - * {@link module:core/editor/editor~Editor#event:dataReady}. - * - * @deprecated v12.0.0 The {@link module:core/editor/editorui~EditorUI#event:ready ui ready event} should be listened to instead. - * @event uiReady - */ - -/** - * This error is thrown when a component tries to access deprecated - * {@link module:core/editor/editorwithui~EditorWithUI#element editor element}. Instead the - * {@link module:core/editor/editorui~EditorUI#element `EditorUI element`} should be used. - * - * @error deprecated-editor-element - */ - -/** - * This error is thrown when a component tries to listen to deprecated - * {@link module:core/editor/editorwithui~EditorWithUI#event:uiReady editor uiReady event}. - * Instead the {@link module:core/editor/editorui~EditorUI#event:ready ui ready event} should be listened to. - * - * @error deprecated-editor-event-uiReady - */ diff --git a/tests/_utils-tests/classictesteditor.js b/tests/_utils-tests/classictesteditor.js index a84c6955..8b0ad00d 100644 --- a/tests/_utils-tests/classictesteditor.js +++ b/tests/_utils-tests/classictesteditor.js @@ -20,19 +20,16 @@ import ElementApiMixin from '../../src/editor/utils/elementapimixin'; import RootElement from '@ckeditor/ckeditor5-engine/src/model/rootelement'; import { getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; -import log from '@ckeditor/ckeditor5-utils/src/log'; import testUtils from '../../tests/_utils/utils'; describe( 'ClassicTestEditor', () => { - let editorElement, logStub; + let editorElement; testUtils.createSinonSandbox(); beforeEach( () => { editorElement = document.createElement( 'div' ); document.body.appendChild( editorElement ); - - logStub = testUtils.sinon.stub( log, 'warn' ).callsFake( () => {} ); } ); describe( 'constructor()', () => { @@ -202,24 +199,4 @@ describe( 'ClassicTestEditor', () => { } ); } ); } ); - - describe( 'deprecated uiReady event', () => { - it( 'logs deprecated warning when attaching uiReady on listener', () => { - return ClassicTestEditor.create( editorElement, { foo: 1 } ) - .then( editor => { - editor.on( 'uiReady', () => {} ); - - expect( logStub.calledWith( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ) ).to.true; - } ); - } ); - - it( 'logs deprecated warning when attaching uiReady once listener', () => { - return ClassicTestEditor.create( editorElement, { foo: 1 } ) - .then( editor => { - editor.once( 'uiReady', () => {} ); - - expect( logStub.calledWith( 'deprecated-editor-event-uiReady: The editor#uiReady event is deprecated.' ) ).to.true; - } ); - } ); - } ); } ); diff --git a/tests/_utils/classictesteditor.js b/tests/_utils/classictesteditor.js index b49c40f3..dd7589e2 100644 --- a/tests/_utils/classictesteditor.js +++ b/tests/_utils/classictesteditor.js @@ -63,7 +63,7 @@ export default class ClassicTestEditor extends Editor { // Simulate EditorUI.init() (e.g. like in ClassicEditorUI). The ui#view // should be rendered after plugins are initialized. .then( () => editor.ui.init( element ) ) - .then( () => editor.editing.view.attachDomRoot( editor.ui.view.editableElement ) ) + .then( () => editor.editing.view.attachDomRoot( editor.ui.getEditableElement() ) ) .then( () => editor.data.init( getDataFromElement( element ) ) ) .then( () => { editor.fire( 'dataReady' ); @@ -114,7 +114,7 @@ class ClassicTestEditorUI extends EditorUI { this._editableElements.set( 'main', view.editable.element ); - this._elementReplacer.replace( element, this.view.element ); + this._elementReplacer.replace( element, view.element ); this.fire( 'ready' ); } @@ -124,6 +124,9 @@ class ClassicTestEditorUI extends EditorUI { */ destroy() { this._elementReplacer.restore(); + + this._view.destroy(); + super.destroy(); } } diff --git a/tests/editor/editorui.js b/tests/editor/editorui.js index 655e7dd6..c8d3c60b 100644 --- a/tests/editor/editorui.js +++ b/tests/editor/editorui.js @@ -8,10 +8,8 @@ import Editor from '../../src/editor/editor'; import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; import ComponentFactory from '@ckeditor/ckeditor5-ui/src/componentfactory'; -import View from '@ckeditor/ckeditor5-ui/src/view'; import testUtils from '../_utils/utils'; -import log from '@ckeditor/ckeditor5-utils/src/log'; /* global document */ @@ -34,23 +32,6 @@ describe( 'EditorUI', () => { expect( ui.editor ).to.equal( editor ); } ); - it( 'should not set #view by default', () => { - testUtils.sinon.stub( log, 'warn' ).callsFake( () => {} ); - - expect( ui._view ).to.undefined; - expect( ui.view ).to.undefined; - } ); - - it( 'should set #view if passed', () => { - testUtils.sinon.stub( log, 'warn' ).callsFake( () => {} ); - - const editor = new Editor(); - const view = new View(); - const ui = new EditorUI( editor, view ); - - expect( ui.view ).to.equal( view ); - } ); - it( 'should create #componentFactory factory', () => { expect( ui.componentFactory ).to.be.instanceOf( ComponentFactory ); } ); @@ -103,23 +84,15 @@ describe( 'EditorUI', () => { sinon.assert.called( spy ); } ); - it( 'should destroy the #view if present', () => { - testUtils.sinon.stub( log, 'warn' ).callsFake( () => {} ); + it( 'should reset editables array', () => { + ui._editableElements.set( 'foo', {} ); + ui._editableElements.set( 'bar', {} ); - const editor = new Editor(); - const view = new View(); - const ui = new EditorUI( editor, view ); - const spy = sinon.spy( view, 'destroy' ); + expect( ui._editableElements.size ).to.equal( 2 ); ui.destroy(); - sinon.assert.called( spy ); - } ); - - it( 'should not throw when view absent', () => { - expect( () => { - ui.destroy(); - } ).to.not.throw(); + expect( ui._editableElements.size ).to.equal( 0 ); } ); } ); From bb3d97834b637fed9ab8a43f5772ef7b5ee8f1d2 Mon Sep 17 00:00:00 2001 From: Piotr Jasiun Date: Tue, 22 Jan 2019 17:20:11 +0100 Subject: [PATCH 13/13] Simplified getEditableElement. --- src/editor/editorui.js | 4 ++-- tests/editor/editorui.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/editor/editorui.js b/src/editor/editorui.js index 60cc68d4..a69c3177 100644 --- a/src/editor/editorui.js +++ b/src/editor/editorui.js @@ -107,10 +107,10 @@ export default class EditorUI { * Returns the editable editor element with the given name or null if editable does not exist. * * @param {String} [rootName=main] The editable name. - * @returns {HTMLElement|null} + * @returns {HTMLElement|undefined} */ getEditableElement( rootName = 'main' ) { - return this._editableElements.has( rootName ) ? this._editableElements.get( rootName ) : null; + return this._editableElements.get( rootName ); } /** diff --git a/tests/editor/editorui.js b/tests/editor/editorui.js index c8d3c60b..341fb9d6 100644 --- a/tests/editor/editorui.js +++ b/tests/editor/editorui.js @@ -121,7 +121,7 @@ describe( 'EditorUI', () => { it( 'should return null if editable with specified name does not exist', () => { const ui = new EditorUI( editor ); - expect( ui.getEditableElement() ).to.null; + expect( ui.getEditableElement() ).to.be.undefined; } ); } );