MDL-60207 javascript: close modal when user touch/click outside it

This commit is contained in:
Treu Quan 2018-01-22 13:24:52 +07:00 committed by Ryan Wyllie
parent 6b2e04676a
commit 30e1f5a023
8 changed files with 116 additions and 6 deletions

File diff suppressed because one or more lines are too long

View File

@ -722,6 +722,15 @@ define(['jquery', 'core/templates', 'core/notification', 'core/key_codes',
}
}.bind(this));
// Listen for clicks on the modal container.
this.getRoot().click(function(e) {
// If the click wasn't inside the modal element then we should
// hide the modal.
if (!$(e.target).closest(SELECTORS.MODAL).length) {
this.hide();
}
}.bind(this));
CustomEvents.define(this.getModal(), [CustomEvents.events.activate]);
this.getModal().on(CustomEvents.events.activate, SELECTORS.HIDE, function(e, data) {
this.hide();

View File

@ -0,0 +1,50 @@
@core
Feature: Close modals by clicking outside them
In order to easily close the currently open pop-up
As a user
Clicking outside the modal should close it.
@javascript
Scenario: The popup closes when clicked on dead space - YUI
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| quiz | Test quiz name | Test quiz description | C1 | quiz1 |
And I log in as "admin"
And I am on "Course 1" course homepage
And I follow "Test quiz name"
And I click on "Edit quiz" "button"
And I click on "Add" "link"
And I click on "a new question" "link"
# Cannot use the normal I click on here, because the pop-up gets in the way.
And I click on ".moodle-dialogue-lightbox" "css_element" skipping visibility check
Then I should not see "Choose a question type to add"
@javascript
Scenario: The popup closes when clicked on dead space - Modal
And I log in as "admin"
And I click on "Site home" "link"
And I turn editing mode on
And I click on "Add a block" "link"
And I click on ".modal" "css_element"
Then ".modal-backdrop" "css_element" should not be visible
And ".modal-content" "css_element" should not be visible
@javascript
Scenario: The popup help closes when clicked
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "activities" exist:
| activity | name | intro | course | idnumber |
| quiz | Test quiz name | Test quiz description | C1 | quiz1 |
And I log in as "admin"
And I am on "Course 1" course homepage
And I follow "Test quiz name"
And I click on "Edit quiz" "button"
And I click on "Help with Editing quiz" "icon"
And I should see "More help"
And I click on "body" "css_element"
Then I should not see "More help"

View File

@ -1722,4 +1722,19 @@ class behat_general extends behat_base {
$value = ($shift == ' shift') ? [\WebDriver\Key::SHIFT . \WebDriver\Key::TAB] : [\WebDriver\Key::TAB];
$this->getSession()->getDriver()->getWebDriverSession()->activeElement()->postValue(['value' => $value]);
}
/**
* Trigger click on node via javascript instead of actually clicking on it via pointer.
* This function resolves the issue of nested elements.
*
* @When /^I click on "(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>[^"]*)" skipping visibility check$/
* @param string $element
* @param string $selectortype
*/
public function i_click_on_skipping_visibility_check($element, $selectortype) {
// Gets the node based on the requested selector type and locator.
$node = $this->get_selected_node($selectortype, $element);
$this->js_trigger_click($node);
}
}

View File

@ -81,7 +81,8 @@ Y.extend(DIALOGUE, Y.Panel, {
// Orientation change event listener.
_orientationevent: null,
_calculatedzindex: false,
// Current maskNode id
_currentMaskNodeId: null,
/**
* The original position of the dialogue before it was reposition to
* avoid browser jumping.
@ -131,6 +132,10 @@ Y.extend(DIALOGUE, Y.Panel, {
// hidden by default. ARIA visibility is managed for modal dialogues.
this.get(BASE).set('aria-hidden', 'true');
this.plug(Y.M.core.LockScroll);
var maskNode = this.get('maskNode');
maskNode.on('click', this.hide, this);
this._currentMaskNodeId = maskNode.get('_yuid');
}
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
@ -157,6 +162,13 @@ Y.extend(DIALOGUE, Y.Panel, {
this._originalPosition = bb.getXY();
}
// Check if maskNode already init click event.
var maskNode = this.get('maskNode');
if (this._currentMaskNodeId !== maskNode.get('_yuid')) {
this._currentMaskNodeId = maskNode.get('_yuid');
maskNode.on('click', this.hide, this);
}
if (bb.getStyle('position') !== 'fixed') {
// If the boundingBox has been positioned in a fixed manner, then it will not position correctly to scrollTop.
bb.setStyles({

File diff suppressed because one or more lines are too long

View File

@ -81,7 +81,8 @@ Y.extend(DIALOGUE, Y.Panel, {
// Orientation change event listener.
_orientationevent: null,
_calculatedzindex: false,
// Current maskNode id
_currentMaskNodeId: null,
/**
* The original position of the dialogue before it was reposition to
* avoid browser jumping.
@ -131,6 +132,10 @@ Y.extend(DIALOGUE, Y.Panel, {
// hidden by default. ARIA visibility is managed for modal dialogues.
this.get(BASE).set('aria-hidden', 'true');
this.plug(Y.M.core.LockScroll);
var maskNode = this.get('maskNode');
maskNode.on('click', this.hide, this);
this._currentMaskNodeId = maskNode.get('_yuid');
}
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
@ -157,6 +162,13 @@ Y.extend(DIALOGUE, Y.Panel, {
this._originalPosition = bb.getXY();
}
// Check if maskNode already init click event.
var maskNode = this.get('maskNode');
if (this._currentMaskNodeId !== maskNode.get('_yuid')) {
this._currentMaskNodeId = maskNode.get('_yuid');
maskNode.on('click', this.hide, this);
}
if (bb.getStyle('position') !== 'fixed') {
// If the boundingBox has been positioned in a fixed manner, then it will not position correctly to scrollTop.
bb.setStyles({

View File

@ -51,7 +51,8 @@ Y.extend(DIALOGUE, Y.Panel, {
// Orientation change event listener.
_orientationevent: null,
_calculatedzindex: false,
// Current maskNode id
_currentMaskNodeId: null,
/**
* The original position of the dialogue before it was reposition to
* avoid browser jumping.
@ -101,6 +102,10 @@ Y.extend(DIALOGUE, Y.Panel, {
// hidden by default. ARIA visibility is managed for modal dialogues.
this.get(BASE).set('aria-hidden', 'true');
this.plug(Y.M.core.LockScroll);
var maskNode = this.get('maskNode');
maskNode.on('click', this.hide, this);
this._currentMaskNodeId = maskNode.get('_yuid');
}
// Workaround upstream YUI bug http://yuilibrary.com/projects/yui3/ticket/2532507
@ -127,6 +132,13 @@ Y.extend(DIALOGUE, Y.Panel, {
this._originalPosition = bb.getXY();
}
// Check if maskNode already init click event.
var maskNode = this.get('maskNode');
if (this._currentMaskNodeId !== maskNode.get('_yuid')) {
this._currentMaskNodeId = maskNode.get('_yuid');
maskNode.on('click', this.hide, this);
}
if (bb.getStyle('position') !== 'fixed') {
// If the boundingBox has been positioned in a fixed manner, then it will not position correctly to scrollTop.
bb.setStyles({