Skip to content

Commit

Permalink
MDL-60207 javascript: close modal when user touch/click outside it
Browse files Browse the repository at this point in the history
  • Loading branch information
Treu Quan authored and ryanwyllie committed May 29, 2018
1 parent 6b2e046 commit 30e1f5a
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lib/amd/build/modal.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions lib/amd/src/modal.js
Expand Up @@ -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();
Expand Down
50 changes: 50 additions & 0 deletions lib/tests/behat/action_modal.feature
@@ -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"
15 changes: 15 additions & 0 deletions lib/tests/behat/behat_general.php
Expand Up @@ -1722,4 +1722,19 @@ public function i_manually_press_tab($shift = '') {
$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);
}
}
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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({
Expand Down

0 comments on commit 30e1f5a

Please sign in to comment.