Przeglądaj źródła

Merge branch 'master' into t/ckeditor5/645

Aleksander Nowodzinski 8 lat temu
rodzic
commit
c5714b7214

+ 1 - 1
packages/ckeditor5-ui/src/componentfactory.js

@@ -59,7 +59,7 @@ export default class ComponentFactory {
 	/**
 	 * Returns an iterator of registered component names. Names are returned in lower case.
 	 *
-	 * @returns {Iterator.<String>}
+	 * @returns {Iterable.<String>}
 	 */
 	* names() {
 		yield* this._components.keys();

+ 10 - 23
packages/ckeditor5-ui/src/dropdown/utils.js

@@ -7,7 +7,7 @@
  * @module ui/dropdown/utils
  */
 
-/* global document */
+import clickOutsideHandler from '../bindings/clickoutsidehandler';
 
 /**
  * Adds a behavior to a dropdownView that focuses dropdown panel view contents on keystrokes.
@@ -57,27 +57,14 @@ export function closeDropdownOnExecute( dropdownView, viewCollection ) {
  * @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView
  */
 export function closeDropdownOnBlur( dropdownView ) {
-	dropdownView.on( 'change:isOpen', ( evt, name, value ) => {
-		if ( value ) {
-			attachDocumentClickListener( document, dropdownView );
-		} else {
-			dropdownView.stopListening( document );
-		}
-	} );
-}
-
-// Attaches a "click" listener in DOM to check if any element outside
-// the dropdown has been clicked.
-//
-// @private
-// @param {module:ui/dropdown/listdropdownview~ListDropdownView} dropdownView
-function attachDocumentClickListener( document, dropdownView ) {
-	// TODO: It will probably be focus/blur-based rather than click. It should be bound
-	// to focusmanager of some sort.
-	dropdownView.listenTo( document, 'click', ( evtInfo, { target: domEvtTarget } ) => {
-		// Collapse the dropdown when the webpage outside of the component is clicked.
-		if ( dropdownView.element != domEvtTarget && !dropdownView.element.contains( domEvtTarget ) ) {
-			dropdownView.isOpen = false;
-		}
+	dropdownView.on( 'render', () => {
+		clickOutsideHandler( {
+			emitter: dropdownView,
+			activator: () => dropdownView.isOpen,
+			callback: () => {
+				dropdownView.isOpen = false;
+			},
+			contextElements: [ dropdownView.element ]
+		} );
 	} );
 }

+ 1 - 1
packages/ckeditor5-ui/src/template.js

@@ -237,7 +237,7 @@ export default class Template {
 	 *			console.log( view );
 	 *		}
 	 *
-	 * @returns {Iterator.<module:ui/view~View>}
+	 * @returns {Iterable.<module:ui/view~View>}
 	 */
 	* getViews() {
 		function* search( def ) {

+ 11 - 0
packages/ckeditor5-ui/src/view.js

@@ -190,6 +190,8 @@ export default class View {
 		 * @private
 		 * @member {Object} #_bindTemplate
 		 */
+
+		this.decorate( 'render' );
 	}
 
 	/**
@@ -492,6 +494,15 @@ export default class View {
 
 		this._viewCollections.map( c => c.destroy() );
 	}
+
+	/**
+	 * Event fired by the {@link #render} method. Actual rendering is executed as a listener to
+	 * this event with the default priority.
+	 *
+	 * See {@link module:utils/observablemixin~ObservableMixin.decorate} for more information and samples.
+	 *
+	 * @event render
+	 */
 }
 
 mix( View, DomEmitterMixin );

+ 4 - 4
packages/ckeditor5-ui/tests/dropdown/button/createbuttondropdown.js

@@ -95,7 +95,7 @@ describe( 'createButtonDropdown', () => {
 			view.isOpen = true;
 
 			// Fire event from outside of the dropdown.
-			document.body.dispatchEvent( new Event( 'click', {
+			document.body.dispatchEvent( new Event( 'mousedown', {
 				bubbles: true
 			} ) );
 
@@ -103,7 +103,7 @@ describe( 'createButtonDropdown', () => {
 			expect( view.isOpen ).to.be.false;
 
 			// Fire event from outside of the dropdown.
-			document.body.dispatchEvent( new Event( 'click', {
+			document.body.dispatchEvent( new Event( 'mousedown', {
 				bubbles: true
 			} ) );
 
@@ -116,7 +116,7 @@ describe( 'createButtonDropdown', () => {
 			view.isOpen = true;
 
 			// Event from view.element should be discarded.
-			view.element.dispatchEvent( new Event( 'click', {
+			view.element.dispatchEvent( new Event( 'mousedown', {
 				bubbles: true
 			} ) );
 
@@ -127,7 +127,7 @@ describe( 'createButtonDropdown', () => {
 			const child = document.createElement( 'div' );
 			view.element.appendChild( child );
 
-			child.dispatchEvent( new Event( 'click', {
+			child.dispatchEvent( new Event( 'mousedown', {
 				bubbles: true
 			} ) );
 

+ 4 - 4
packages/ckeditor5-ui/tests/dropdown/list/createlistdropdown.js

@@ -106,7 +106,7 @@ describe( 'createListDropdown', () => {
 			view.isOpen = true;
 
 			// Fire event from outside of the dropdown.
-			document.body.dispatchEvent( new Event( 'click', {
+			document.body.dispatchEvent( new Event( 'mousedown', {
 				bubbles: true
 			} ) );
 
@@ -114,7 +114,7 @@ describe( 'createListDropdown', () => {
 			expect( view.isOpen ).to.be.false;
 
 			// Fire event from outside of the dropdown.
-			document.body.dispatchEvent( new Event( 'click', {
+			document.body.dispatchEvent( new Event( 'mousedown', {
 				bubbles: true
 			} ) );
 
@@ -127,7 +127,7 @@ describe( 'createListDropdown', () => {
 			view.isOpen = true;
 
 			// Event from view.element should be discarded.
-			view.element.dispatchEvent( new Event( 'click', {
+			view.element.dispatchEvent( new Event( 'mousedown', {
 				bubbles: true
 			} ) );
 
@@ -138,7 +138,7 @@ describe( 'createListDropdown', () => {
 			const child = document.createElement( 'div' );
 			view.element.appendChild( child );
 
-			child.dispatchEvent( new Event( 'click', {
+			child.dispatchEvent( new Event( 'mousedown', {
 				bubbles: true
 			} ) );
 

+ 11 - 0
packages/ckeditor5-ui/tests/view.js

@@ -195,6 +195,17 @@ describe( 'View', () => {
 	} );
 
 	describe( 'render()', () => {
+		it( 'is decorated', done => {
+			const view = new View();
+
+			view.on( 'render', () => {
+				expect( view.isRendered ).to.be.true;
+				done();
+			} );
+
+			view.render();
+		} );
+
 		it( 'should throw if already rendered', () => {
 			const view = new View();