Merge branch 'MDL-51983-master' of git://github.com/ryanwyllie/moodle
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
@core
|
||||
Feature: Navigate action menu
|
||||
In order to navigate an action menu
|
||||
As a user
|
||||
I need to be able to use the keyboard
|
||||
|
||||
@javascript
|
||||
Scenario: The menu does not close on keyboard navigation
|
||||
When I log in as "admin"
|
||||
# Click to open the user menu.
|
||||
And I click on ".usermenu a.toggle-display" "css_element" in the ".usermenu" "css_element"
|
||||
# The menu should now be visible.
|
||||
Then ".usermenu [role='menu']" "css_element" should be visible
|
||||
# Press down arrow.
|
||||
And I press key "40" in "#actionmenuaction-1" "css_element"
|
||||
# The menu should still be visible.
|
||||
And ".usermenu [role='menu']" "css_element" should be visible
|
||||
|
||||
@javascript
|
||||
Scenario: The menu closes when it clicked outside
|
||||
When I log in as "admin"
|
||||
# Click to open the user menu.
|
||||
And I click on ".usermenu a.toggle-display" "css_element" in the ".usermenu" "css_element"
|
||||
# The menu should now be visible.
|
||||
Then ".usermenu [role='menu']" "css_element" should be visible
|
||||
# Click outside the menu.
|
||||
And I click on "adminsearchquery" "field"
|
||||
# The menu should now be hidden.
|
||||
And ".usermenu [role='menu']" "css_element" should not be visible
|
||||
@@ -1444,4 +1444,40 @@ class behat_general extends behat_base {
|
||||
throw new ExpectationException('Unknown browser button.', $session);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a keydown event for a key on a specific element.
|
||||
*
|
||||
* @When /^I press key "(?P<key_string>(?:[^"]|\\")*)" in "(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>[^"]*)"$/
|
||||
* @param string $key either char-code or character itself,
|
||||
* may optionally be prefixed with ctrl-, alt-, shift- or meta-
|
||||
* @param string $element Element we look for
|
||||
* @param string $selectortype The type of what we look for
|
||||
* @throws DriverException
|
||||
* @throws ExpectationException
|
||||
*/
|
||||
public function i_press_key_in_element($key, $element, $selectortype) {
|
||||
if (!$this->running_javascript()) {
|
||||
throw new DriverException('Key down step is not available with Javascript disabled');
|
||||
}
|
||||
// Gets the node based on the requested selector type and locator.
|
||||
$node = $this->get_selected_node($selectortype, $element);
|
||||
$modifier = null;
|
||||
$validmodifiers = array('ctrl', 'alt', 'shift', 'meta');
|
||||
$char = $key;
|
||||
if (strpos($key, '-')) {
|
||||
list($modifier, $char) = preg_split('/-/', $key, 2);
|
||||
$modifier = strtolower($modifier);
|
||||
if (!in_array($modifier, $validmodifiers)) {
|
||||
throw new ExpectationException(sprintf('Unknown key modifier: %s.', $modifier));
|
||||
}
|
||||
}
|
||||
if (is_numeric($char)) {
|
||||
$char = (int)$char;
|
||||
}
|
||||
|
||||
$node->keyDown($char, $modifier);
|
||||
$node->keyPress($char, $modifier);
|
||||
$node->keyUp($char, $modifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,18 +317,22 @@ ACTIONMENU.prototype = {
|
||||
*/
|
||||
handleKeyboardEvent: function(e) {
|
||||
var next;
|
||||
var markEventHandled = function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
// Handle when the menu is still selected.
|
||||
if (e.currentTarget.ancestor(SELECTOR.TOGGLE, true)) {
|
||||
if ((e.keyCode === 40 || (e.keyCode === 9 && !e.shiftKey)) && this.firstMenuChild) {
|
||||
this.firstMenuChild.focus();
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
} else if (e.keyCode === 38 && this.lastMenuChild) {
|
||||
this.lastMenuChild.focus();
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
} else if (e.keyCode === 9 && e.shiftKey) {
|
||||
this.hideMenu(e);
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -336,11 +340,11 @@ ACTIONMENU.prototype = {
|
||||
if (e.keyCode === 27) {
|
||||
// The escape key was pressed so close the menu.
|
||||
this.hideMenu(e);
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
|
||||
} else if (e.keyCode === 32) {
|
||||
// The space bar was pressed. Trigger a click.
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
e.currentTarget.simulate('click');
|
||||
} else if (e.keyCode === 9) {
|
||||
// The tab key was pressed. Tab moves forwards, Shift + Tab moves backwards through the menu options.
|
||||
@@ -348,13 +352,14 @@ ACTIONMENU.prototype = {
|
||||
// focus is moved to.
|
||||
if (e.target === this.firstMenuChild && e.shiftKey) {
|
||||
this.hideMenu(e);
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
} else if (e.target === this.lastMenuChild && !e.shiftKey) {
|
||||
if (this.hideMenu(e)) {
|
||||
// Determine the next selector and focus on it.
|
||||
next = this.menulink.next(SELECTOR.CAN_RECEIVE_FOCUS_SELECTOR);
|
||||
if (next) {
|
||||
next.focus();
|
||||
markEventHandled(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -403,7 +408,7 @@ ACTIONMENU.prototype = {
|
||||
|
||||
if (next) {
|
||||
next.focus();
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -416,7 +421,7 @@ ACTIONMENU.prototype = {
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
hideIfOutside : function(e) {
|
||||
if (!e.target.ancestor(SELECTOR.MENUCHILD, true)) {
|
||||
if (!e.target.ancestor(SELECTOR.MENUCONTENT, true)) {
|
||||
this.hideMenu(e);
|
||||
}
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -315,18 +315,22 @@ ACTIONMENU.prototype = {
|
||||
*/
|
||||
handleKeyboardEvent: function(e) {
|
||||
var next;
|
||||
var markEventHandled = function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
// Handle when the menu is still selected.
|
||||
if (e.currentTarget.ancestor(SELECTOR.TOGGLE, true)) {
|
||||
if ((e.keyCode === 40 || (e.keyCode === 9 && !e.shiftKey)) && this.firstMenuChild) {
|
||||
this.firstMenuChild.focus();
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
} else if (e.keyCode === 38 && this.lastMenuChild) {
|
||||
this.lastMenuChild.focus();
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
} else if (e.keyCode === 9 && e.shiftKey) {
|
||||
this.hideMenu(e);
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -334,11 +338,11 @@ ACTIONMENU.prototype = {
|
||||
if (e.keyCode === 27) {
|
||||
// The escape key was pressed so close the menu.
|
||||
this.hideMenu(e);
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
|
||||
} else if (e.keyCode === 32) {
|
||||
// The space bar was pressed. Trigger a click.
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
e.currentTarget.simulate('click');
|
||||
} else if (e.keyCode === 9) {
|
||||
// The tab key was pressed. Tab moves forwards, Shift + Tab moves backwards through the menu options.
|
||||
@@ -346,13 +350,14 @@ ACTIONMENU.prototype = {
|
||||
// focus is moved to.
|
||||
if (e.target === this.firstMenuChild && e.shiftKey) {
|
||||
this.hideMenu(e);
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
} else if (e.target === this.lastMenuChild && !e.shiftKey) {
|
||||
if (this.hideMenu(e)) {
|
||||
// Determine the next selector and focus on it.
|
||||
next = this.menulink.next(SELECTOR.CAN_RECEIVE_FOCUS_SELECTOR);
|
||||
if (next) {
|
||||
next.focus();
|
||||
markEventHandled(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -400,7 +405,7 @@ ACTIONMENU.prototype = {
|
||||
|
||||
if (next) {
|
||||
next.focus();
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -413,7 +418,7 @@ ACTIONMENU.prototype = {
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
hideIfOutside : function(e) {
|
||||
if (!e.target.ancestor(SELECTOR.MENUCHILD, true)) {
|
||||
if (!e.target.ancestor(SELECTOR.MENUCONTENT, true)) {
|
||||
this.hideMenu(e);
|
||||
}
|
||||
},
|
||||
|
||||
+13
-8
@@ -315,18 +315,22 @@ ACTIONMENU.prototype = {
|
||||
*/
|
||||
handleKeyboardEvent: function(e) {
|
||||
var next;
|
||||
var markEventHandled = function(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
// Handle when the menu is still selected.
|
||||
if (e.currentTarget.ancestor(SELECTOR.TOGGLE, true)) {
|
||||
if ((e.keyCode === 40 || (e.keyCode === 9 && !e.shiftKey)) && this.firstMenuChild) {
|
||||
this.firstMenuChild.focus();
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
} else if (e.keyCode === 38 && this.lastMenuChild) {
|
||||
this.lastMenuChild.focus();
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
} else if (e.keyCode === 9 && e.shiftKey) {
|
||||
this.hideMenu(e);
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -334,11 +338,11 @@ ACTIONMENU.prototype = {
|
||||
if (e.keyCode === 27) {
|
||||
// The escape key was pressed so close the menu.
|
||||
this.hideMenu(e);
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
|
||||
} else if (e.keyCode === 32) {
|
||||
// The space bar was pressed. Trigger a click.
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
e.currentTarget.simulate('click');
|
||||
} else if (e.keyCode === 9) {
|
||||
// The tab key was pressed. Tab moves forwards, Shift + Tab moves backwards through the menu options.
|
||||
@@ -346,13 +350,14 @@ ACTIONMENU.prototype = {
|
||||
// focus is moved to.
|
||||
if (e.target === this.firstMenuChild && e.shiftKey) {
|
||||
this.hideMenu(e);
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
} else if (e.target === this.lastMenuChild && !e.shiftKey) {
|
||||
if (this.hideMenu(e)) {
|
||||
// Determine the next selector and focus on it.
|
||||
next = this.menulink.next(SELECTOR.CAN_RECEIVE_FOCUS_SELECTOR);
|
||||
if (next) {
|
||||
next.focus();
|
||||
markEventHandled(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -401,7 +406,7 @@ ACTIONMENU.prototype = {
|
||||
|
||||
if (next) {
|
||||
next.focus();
|
||||
e.preventDefault();
|
||||
markEventHandled(e);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -414,7 +419,7 @@ ACTIONMENU.prototype = {
|
||||
* @param {EventFacade} e
|
||||
*/
|
||||
hideIfOutside : function(e) {
|
||||
if (!e.target.ancestor(SELECTOR.MENUCHILD, true)) {
|
||||
if (!e.target.ancestor(SELECTOR.MENUCONTENT, true)) {
|
||||
this.hideMenu(e);
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user