Ver Fonte

Introduce DOM Event Observer.

Piotr Jasiun há 10 anos atrás
pai
commit
d1ef917280

+ 99 - 0
packages/ckeditor5-engine/src/treeview/observer/domeventobserver.js

@@ -0,0 +1,99 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+/**
+ * Base class for DOM event observers. This class handle
+ * {@link core.treeView.observer.Observer#observe adding} listeners to DOM elements,
+ * {@link core.treeView.observer.Observer#disable disabling} and
+ * {@link core.treeView.observer.Observer#enable re-enabling} events. Child class need to define DOM event
+ * {@link core.treeView.observer.DomEventObserver#domEventType type} and
+ * {@link core.treeView.observer.DomEventObserver#onDomEvent callback}.
+ *
+ * For instance:
+ *
+ *		class ClickObserver extends DomEventObserver {
+ *			get domEventType() {
+ *				return 'click';
+ *			}
+ *
+ *			onDomEvent( domEvt ) {
+ *				this.fire( 'click' );
+ *			}
+ *		}
+ */
+export default class DomEventObserver {
+	/**
+	 * @inheritDoc
+	 */
+	init( treeView ) {
+		/**
+		 * Reference to the {@link core.treeView.TreeView} object.
+		 *
+		 * @member {core.treeView.TreeView} core.treeView.observer.DomEventObserver#treeView
+		 */
+		this.treeView = treeView;
+
+		/**
+		 * State of the observer. If it is disabled not event should be fired.
+		 *
+		 * @member {Boolean} core.treeView.observer.DomEventObserver#isEnabled
+		 */
+		this.isEnabled = false;
+
+		/**
+		 * Type of the DOM event the observer should listen on.
+		 *
+		 * @member {String} core.treeView.observer.DomEventObserver#domEventType
+		 */
+
+		/**
+		 * Callback which should be called when the DOM event occurred. Note that the callback will not be called if
+		 * observer {@link core.treeView.observer.DomEventObserver#isEnabled is not enabled}.
+		 *
+		 * @see core.treeView.observer.DomEventObserver#domEventType
+		 * @member {Function} core.treeView.observer.DomEventObserver#onDomEvent
+		 */
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	observe( domElement ) {
+		domElement.addEventListener( this.domEventType, domEvent => {
+			if ( this.isEnabled ) {
+				this.onDomEvent( domEvent );
+			}
+		} );
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	enable() {
+		this.isEnabled = true;
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	disable() {
+		this.isEnabled = false;
+	}
+
+	/**
+	 * Calls {@link core.treeView.TreeView#fire} if observer
+	 * {@link core.treeView.observer.DomEventObserver#isEnabled is enabled}.
+	 *
+	 * @see core.treeView.TreeView#fire
+	 * @param {...*} args Fire arguments @see core.treeView.TreeView#fire
+	 */
+	fire( ...args ) {
+		if ( this.isEnabled ) {
+			this.treeView.fire.apply( this.treeView, args );
+		}
+	}
+}

+ 109 - 0
packages/ckeditor5-engine/tests/treeview/observer/domeventobserver.js

@@ -0,0 +1,109 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* bender-tags: treeview */
+
+'use strict';
+
+import DomEventObserver from '/ckeditor5/core/treeview/observer/domeventobserver.js';
+import TreeView from '/ckeditor5/core/treeview/treeview.js';
+
+class TestObserver extends DomEventObserver {
+	constructor( id ) {
+		super();
+
+		this.id = id;
+
+		this.domEventType = 'click';
+	}
+
+	onDomEvent( domEvt ) {
+		this.fire( 'click', this.id, domEvt );
+	}
+}
+
+describe( 'DomEventObserver', () => {
+	it( 'should add event lister', () => {
+		const testObserver = new TestObserver( 'foo' );
+		const domElement = document.createElement( 'p' );
+		const domEvent = new MouseEvent( 'click' );
+		const treeView = new TreeView();
+		const evtSpy = sinon.spy();
+
+		treeView.createRoot( domElement, 'root' );
+		treeView.addObserver( testObserver );
+		treeView.on( 'click', evtSpy );
+
+		domElement.dispatchEvent( domEvent );
+
+		expect( evtSpy.calledOnce ).to.be.true;
+		expect( evtSpy.args[ 0 ][ 1 ] ).to.equal( 'foo' );
+		expect( evtSpy.args[ 0 ][ 2 ] ).to.equal( domEvent );
+	} );
+
+	it( 'should not fire event if observer is disabled', () => {
+		const testObserver = new TestObserver( 'foo' );
+		const domElement = document.createElement( 'p' );
+		const domEvent = new MouseEvent( 'click' );
+		const treeView = new TreeView();
+		const evtSpy = sinon.spy();
+
+		treeView.createRoot( domElement, 'root' );
+		treeView.addObserver( testObserver );
+		treeView.on( 'click', evtSpy );
+
+		testObserver.disable();
+
+		domElement.dispatchEvent( domEvent );
+
+		expect( evtSpy.called ).to.be.false;
+	} );
+
+	it( 'should be fire event if observer is disabled and re-enabled', () => {
+		const testObserver = new TestObserver( 'foo' );
+		const domElement = document.createElement( 'p' );
+		const domEvent = new MouseEvent( 'click' );
+		const treeView = new TreeView();
+		const evtSpy = sinon.spy();
+
+		treeView.createRoot( domElement, 'root' );
+		treeView.addObserver( testObserver );
+		treeView.on( 'click', evtSpy );
+
+		testObserver.disable();
+
+		domElement.dispatchEvent( domEvent );
+
+		expect( evtSpy.called ).to.be.false;
+
+		testObserver.enable();
+
+		domElement.dispatchEvent( domEvent );
+
+		expect( evtSpy.calledOnce ).to.be.true;
+	} );
+
+	describe( 'fire', () => {
+		it( 'should do nothing if observer is disabled', () => {
+			const testObserver = new TestObserver();
+			const treeView = new TreeView();
+			const fireSpy = sinon.spy( treeView, 'fire' );
+
+			testObserver.init( treeView );
+
+			testObserver.disable();
+
+			testObserver.fire( 'click' );
+
+			expect( fireSpy.called ).to.be.false;
+
+			testObserver.enable();
+
+			testObserver.fire( 'click' );
+
+			expect( fireSpy.calledOnce ).to.be.true;
+		} );
+	} );
+} );