Skip to content
This repository was archived by the owner on Jun 26, 2020. It is now read-only.

t/311a: The closeDropdownOnBlur helper should use clickOutsideHandler #353

Merged
merged 2 commits into from
Jan 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 10 additions & 23 deletions src/dropdown/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 ]
} );
} );
}
11 changes: 11 additions & 0 deletions src/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ export default class View {
* @private
* @member {Object} #_bindTemplate
*/

this.decorate( 'render' );
}

/**
Expand Down Expand Up @@ -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 );
Expand Down
8 changes: 4 additions & 4 deletions tests/dropdown/button/createbuttondropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,15 @@ 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
} ) );

// Closed the dropdown.
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
} ) );

Expand All @@ -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
} ) );

Expand All @@ -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
} ) );

Expand Down
8 changes: 4 additions & 4 deletions tests/dropdown/list/createlistdropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ 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
} ) );

// Closed the dropdown.
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
} ) );

Expand All @@ -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
} ) );

Expand All @@ -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
} ) );

Expand Down
11 changes: 11 additions & 0 deletions tests/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down