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

Commit

Permalink
Merge pull request #353 from ckeditor/t/311a
Browse files Browse the repository at this point in the history
Other: The `closeDropdownOnBlur()` helper should use `clickOutsideHandler()`. Decorated the `View#render()` method. Closes #311.
  • Loading branch information
Reinmar committed Jan 16, 2018
2 parents ca6c636 + 01d0230 commit 269e97b
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 31 deletions.
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

0 comments on commit 269e97b

Please sign in to comment.