8
0
Просмотр исходного кода

Introduced EditorUI class with an #update event.

Oskar Wróbel 7 лет назад
Родитель
Сommit
1b796971e3

+ 102 - 0
packages/ckeditor5-core/src/editor/editorui.js

@@ -0,0 +1,102 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module core/editor/editorui
+ */
+
+import ComponentFactory from '@ckeditor/ckeditor5-ui/src/componentfactory';
+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 throttle from '@ckeditor/ckeditor5-utils/src/lib/lodash/throttle';
+
+/**
+ * Class providing the minimal interface that is required to successfully bootstrap any editor UI.
+ *
+ * @mixes module:utils/emittermixin~EmitterMixin
+ */
+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.
+	 */
+	constructor( editor, view ) {
+		/**
+		 * Editor that the UI belongs to.
+		 *
+		 * @readonly
+		 * @member {module:core/editor/editor~Editor} #editor
+		 */
+		this.editor = editor;
+
+		/**
+		 * The main (top–most) view of the editor UI.
+		 *
+		 * @readonly
+		 * @member {module:ui/editorui/editoruiview~EditorUIView} #view
+		 */
+		this.view = view;
+
+		/**
+		 * Instance of the {@link module:ui/componentfactory~ComponentFactory}, a registry used by plugins
+		 * to register factories of specific UI components.
+		 *
+		 * @readonly
+		 * @member {module:ui/componentfactory~ComponentFactory} #componentFactory
+		 */
+		this.componentFactory = new ComponentFactory( editor );
+
+		/**
+		 * Keeps information about editor UI focus and propagates it among various plugins and components,
+		 * unifying them in a uniform focus group.
+		 *
+		 * @readonly
+		 * @member {module:utils/focustracker~FocusTracker} #focusTracker
+		 */
+		this.focusTracker = new FocusTracker();
+
+		/**
+		 * Fires throttled {@link module:core/editor/editorui~EditorUI#event:update} event.
+		 *
+		 * @protected
+		 * @type {Function}
+		 */
+		this._throttledUpdate = throttle( () => this.fire( 'update' ), 200 );
+
+		// Informs UI components that should be refreshed after layout change.
+		this.listenTo( editor.editing.view.document, 'layoutChanged', () => this._throttledUpdate() );
+	}
+
+	/**
+	 * Triggers the UI update.
+	 */
+	update() {
+		this._throttledUpdate();
+	}
+
+	/**
+	 * Destroys the UI.
+	 */
+	destroy() {
+		this.stopListening();
+		this._throttledUpdate.cancel();
+		this.view.destroy();
+	}
+
+	/**
+	 * Fired whenever UI and all related components should be refreshed.
+	 *
+	 * It is fired after each {@link module:engine/view/document~Document#event:layoutChanged} event
+	 * besides it can be fired manually through {@link module:core/editor/editorui~EditorUI#update} method.
+	 *
+	 * @event core/editor/editorui~EditorUI#event:update
+	 */
+}
+
+mix( EditorUI, EmitterMixin );

+ 0 - 44
packages/ckeditor5-core/src/editor/editorui.jsdoc

@@ -1,44 +0,0 @@
-/**
- * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/**
- * @module core/editor/editorui
- */
-
-/**
- * Minimal interface that is required to successfully bootstrap any editor UI.
- *
- * @interface EditorUI
- */
-
-/**
- * Editor that the UI belongs to.
- *
- * @readonly
- * @member {module:core/editor/editor~Editor} #editor
- */
-
-/**
- * The main (top–most) view of the editor UI.
- *
- * @readonly
- * @member {module:ui/editorui/editoruiview~EditorUIView} #view
- */
-
-/**
- * Instance of the {@link module:ui/componentfactory~ComponentFactory}, a registry used by plugins
- * to register factories of specific UI components.
- *
- * @readonly
- * @member {module:ui/componentfactory~ComponentFactory} #componentFactory
- */
-
-/**
- * Keeps information about editor UI focus and propagates it among various plugins and components,
- * unifying them in a uniform focus group.
- *
- * @readonly
- * @member {module:utils/focustracker~FocusTracker} #focusTracker
- */

+ 106 - 0
packages/ckeditor5-core/tests/editor/editorui.js

@@ -0,0 +1,106 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import EditorUI from '../../src/editor/editorui';
+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 '@ckeditor/ckeditor5-core/tests/_utils/utils';
+
+testUtils.createSinonSandbox();
+
+describe( 'EditorUI', () => {
+	let editor, view, ui;
+
+	beforeEach( () => {
+		editor = new Editor();
+		view = new View();
+		ui = new EditorUI( editor, view );
+	} );
+
+	afterEach( () => {
+		return Promise.all( [
+			editor.destroy(),
+			ui.destroy()
+		] );
+	} );
+
+	describe( 'constructor()', () => {
+		it( 'sets #editor', () => {
+			expect( ui.editor ).to.equal( editor );
+		} );
+
+		it( 'sets #view', () => {
+			expect( ui.view ).to.equal( view );
+		} );
+
+		it( 'creates #componentFactory factory', () => {
+			expect( ui.componentFactory ).to.be.instanceOf( ComponentFactory );
+		} );
+
+		it( 'creates #focusTracker', () => {
+			expect( ui.focusTracker ).to.be.instanceOf( FocusTracker );
+		} );
+
+		it( 'should fire throttled update event after viewDocument#layoutChanged', () => {
+			const spy = sinon.spy();
+
+			ui.on( 'update', spy );
+
+			editor.editing.view.document.fire( 'layoutChanged' );
+
+			sinon.assert.calledOnce( spy );
+
+			editor.editing.view.document.fire( 'layoutChanged' );
+
+			sinon.assert.calledOnce( spy );
+
+			ui._throttledUpdate.flush();
+
+			sinon.assert.calledTwice( spy );
+		} );
+	} );
+
+	describe( 'update()', () => {
+		it( 'should fire throttled update event', () => {
+			const spy = sinon.spy();
+
+			ui.on( 'update', spy );
+
+			ui.update();
+
+			sinon.assert.calledOnce( spy );
+
+			ui.update();
+
+			sinon.assert.calledOnce( spy );
+
+			ui._throttledUpdate.flush();
+
+			sinon.assert.calledTwice( spy );
+		} );
+	} );
+
+	describe( 'destroy()', () => {
+		it( 'stops listening', () => {
+			const spy = sinon.spy( ui, 'stopListening' );
+
+			ui.destroy();
+
+			sinon.assert.called( spy );
+		} );
+
+		it( 'destroys the #view', () => {
+			const spy = sinon.spy( view, 'destroy' );
+
+			ui.destroy();
+
+			sinon.assert.called( spy );
+		} );
+	} );
+} );