ソースを参照

Added `getEditableElement` method and deprecated `view` property in `EditorUI`.

Krzysztof Krztoń 7 年 前
コミット
f131aec806

+ 69 - 10
packages/ckeditor5-core/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.
 	 *

+ 2 - 2
packages/ckeditor5-core/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;
 				} );
 		} );
 	} );

+ 28 - 1
packages/ckeditor5-core/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 );

+ 29 - 5
packages/ckeditor5-core/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();
+		} );
 	} );
 } );