diff --git a/course/tests/behat/activities_edit_with_block_dock.feature b/course/tests/behat/activities_edit_with_block_dock.feature new file mode 100644 index 00000000000..36803cbd380 --- /dev/null +++ b/course/tests/behat/activities_edit_with_block_dock.feature @@ -0,0 +1,29 @@ +@core @core_course @_cross_browser +Feature: Open the edit menu when a block is docked + In order to edit an activity with a block docked + As a teacher + I need to open the action menu + + @javascript + Scenario: Open the action menu with a block docked + Given the following "users" exists: + | username | firstname | lastname | email | + | teacher1 | Teacher | 1 | teacher1@asd.com | + And the following "courses" exists: + | fullname | shortname | format | + | Course 1 | C1 | weeks | + And the following "course enrolments" exists: + | user | course | role | + | teacher1 | C1 | editingteacher | + And I log in as "teacher1" + And I follow "Course 1" + And I turn editing mode on + And I add a "Glossary" to section "1" and I fill the form with: + | Name | Test glossary name | + | Description | Test glossary description | + And I dock "Navigation" block + When I open "Test glossary name" actions menu + Then "Test glossary name" actions menu should be open + And I reload the page + When I open "Test glossary name" actions menu + Then "Test glossary name" actions menu should be open diff --git a/course/tests/behat/behat_course.php b/course/tests/behat/behat_course.php index d31c1b966a5..e4a9133e951 100644 --- a/course/tests/behat/behat_course.php +++ b/course/tests/behat/behat_course.php @@ -643,6 +643,30 @@ class behat_course extends behat_base { return new Given('I click on "a[role=\'menuitem\']" "css_element" in the "' . $this->escape($activityname) . '" activity'); } + /** + * Checks that the specified activity's action menu is open. + * + * @Then /^"(?P(?:[^"]|\\")*)" actions menu should be open$/ + * @throws DriverException The step is not available when Javascript is disabled + * @param string $activityname + * @return Given + */ + public function actions_menu_should_be_open($activityname) { + + if (!$this->running_javascript()) { + throw new DriverException('Activities actions menu not available when Javascript is disabled'); + } + + // If it is already closed we do nothing. + $activitynode = $this->get_activity_node($activityname); + $classes = array_flip(explode(' ', $activitynode->getAttribute('class'))); + if (empty($classes['action-menu-shown'])) { + throw new ExpectationException(sprintf("The action menu for '%s' is not open", $activityname), $this->getSession()); + } + + return; + } + /** * Indents to the right the activity or resource specified by it's name. Editing mode should be on. * diff --git a/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu-debug.js b/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu-debug.js index 6f6c786c060..9b0f72079dc 100644 --- a/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu-debug.js +++ b/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu-debug.js @@ -286,7 +286,8 @@ ACTIONMENU.prototype = { var menu = e.target.ancestor(SELECTOR.MENU), menuvisible = (menu.hasClass('show')); - e.preventDefault(); + // Prevent event propagation as it will trigger the hideIfOutside event handler in certain situations. + e.halt(true); this.hideMenu(); if (menuvisible) { // The menu was visible and the user has clicked to toggle it again. diff --git a/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu-min.js b/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu-min.js index 2806b0f8828..38f3d5e2592 100644 --- a/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu-min.js +++ b/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu-min.js @@ -1,2 +1,2 @@ -YUI.add("moodle-core-actionmenu",function(e,t){var n=e.one(e.config.doc.body),r={MENUSHOWN:"action-menu-shown"},i={CAN_RECEIVE_FOCUS_SELECTOR:'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',MENU:".moodle-actionmenu[data-enhance=moodle-core-actionmenu]",MENUBAR:'[role="menubar"]',MENUITEM:'[role="menuitem"]',MENUCONTENT:".menu[data-rel=menu-content]",MENUCONTENTCHILD:"li a",MENUCHILD:".menu li a",TOGGLE:".toggle-display",KEEPOPEN:'[data-keepopen="1"]',MENUBARITEMS:['[role="menubar"] > [role="menuitem"]','[role="menubar"] > [role="presentation"] > [role="menuitem"]'],MENUITEMS:['> [role="menuitem"]','> [role="presentation"] > [role="menuitem"]']},s,o={TL:"tl",TR:"tr",BL:"bl",BR:"br"};s=function(){s.superclass.constructor.apply(this,arguments)},s.prototype={dialogue:null,events:[],owner:null,menulink:null,menuChildren:null,firstMenuChild:null,lastMenuChild:null,initializer:function(){e.all(i.MENU).each(this.enhance,this),n.delegate("key",this.moveMenuItem,"down:37,39",i.MENUBARITEMS.join(","),this),n.delegate("click",this.toggleMenu,i.MENU+" "+i.TOGGLE,this),n.delegate("key",this.showIfHidden,"down:enter,38,40",i.MENU+" "+i.TOGGLE,this),n.delegate("key",function(e){e.currentTarget.simulate("click"),e.preventDefault()},"down:32",i.MENUBARITEMS.join(","))},enhance:function(e){var t=e.one(i.MENUCONTENT),n;if(!t)return!1;n=t.getData("align")||this.get("align").join("-"),e.one(i.TOGGLE).set("aria-haspopup",!0),t.set("aria-hidden",!0),t.hasClass("align-"+n)||t.addClass("align-"+n),t.hasChildNodes()&&e.setAttribute("data-enhanced","1")},moveMenuItem:function(e){var t,n=e.target.ancestor(i.MENUITEM,!0);return e.keyCode===37?t=this.getMenuItem(n,!0):e.keyCode===39&&(t=this.getMenuItem(n)),t&&t.focus(),this},getMenuItem:function(e,t){var n=e.ancestor(i.MENUBAR),r;if(!n)return null;r=n.all(i.MENUITEMS.join(","));if(!r)return null;var s=r.size();if(s===1)return null;var o=0,u=1,a=0;for(o=0;o=this.menuChildren.size()&&(r=0),t=this.menuChildren.item(r),o++;while(oa?(c=i=a,p=n=o):n=o+a&&(p=o+a-i),s>f&&l.toLowerCase()==="hidden"&&(h=s=f,e.setStyle("overflow","auto"));if(r>=u&&r+s>u+f){d=u+f-s;try{v=e.getStyle("boxShadow").replace(/.*? (\d+)px \d+px$/,"$1"),(new RegExp(/^\d+$/)).test(v)&&d-u>v&&(d-=v)}catch(m){}}p!==null&&e.setX(p),d!==null&&e.setY(d),c!==null&&e.setStyle("width",c.toString()+"px"),h!==null&&e.setStyle("height",h.toString()+"px")}},e.extend(s,e.Base,s.prototype,{NAME:"moodle-core-actionmenu",ATTRS:{align:{value:[o.TR,o.BR]}}}),M.core=M.core||{},M.core.actionmenu=M.core.actionmenu||{},M.core.actionmenu.instance=null,M.core.actionmenu.init=M.core.actionmenu.init||function(e){M.core.actionmenu.instance=M.core.actionmenu.instance||new s(e)},M.core.actionmenu.newDOMNode=function(e){if(M.core.actionmenu.instance=== -null)return!0;e.all(i.MENU).each(M.core.actionmenu.instance.enhance,M.core.actionmenu.instance)}},"@VERSION@",{requires:["base","event","node-event-simulate"]}); +YUI.add("moodle-core-actionmenu",function(e,t){var n=e.one(e.config.doc.body),r={MENUSHOWN:"action-menu-shown"},i={CAN_RECEIVE_FOCUS_SELECTOR:'input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',MENU:".moodle-actionmenu[data-enhance=moodle-core-actionmenu]",MENUBAR:'[role="menubar"]',MENUITEM:'[role="menuitem"]',MENUCONTENT:".menu[data-rel=menu-content]",MENUCONTENTCHILD:"li a",MENUCHILD:".menu li a",TOGGLE:".toggle-display",KEEPOPEN:'[data-keepopen="1"]',MENUBARITEMS:['[role="menubar"] > [role="menuitem"]','[role="menubar"] > [role="presentation"] > [role="menuitem"]'],MENUITEMS:['> [role="menuitem"]','> [role="presentation"] > [role="menuitem"]']},s,o={TL:"tl",TR:"tr",BL:"bl",BR:"br"};s=function(){s.superclass.constructor.apply(this,arguments)},s.prototype={dialogue:null,events:[],owner:null,menulink:null,menuChildren:null,firstMenuChild:null,lastMenuChild:null,initializer:function(){e.all(i.MENU).each(this.enhance,this),n.delegate("key",this.moveMenuItem,"down:37,39",i.MENUBARITEMS.join(","),this),n.delegate("click",this.toggleMenu,i.MENU+" "+i.TOGGLE,this),n.delegate("key",this.showIfHidden,"down:enter,38,40",i.MENU+" "+i.TOGGLE,this),n.delegate("key",function(e){e.currentTarget.simulate("click"),e.preventDefault()},"down:32",i.MENUBARITEMS.join(","))},enhance:function(e){var t=e.one(i.MENUCONTENT),n;if(!t)return!1;n=t.getData("align")||this.get("align").join("-"),e.one(i.TOGGLE).set("aria-haspopup",!0),t.set("aria-hidden",!0),t.hasClass("align-"+n)||t.addClass("align-"+n),t.hasChildNodes()&&e.setAttribute("data-enhanced","1")},moveMenuItem:function(e){var t,n=e.target.ancestor(i.MENUITEM,!0);return e.keyCode===37?t=this.getMenuItem(n,!0):e.keyCode===39&&(t=this.getMenuItem(n)),t&&t.focus(),this},getMenuItem:function(e,t){var n=e.ancestor(i.MENUBAR),r;if(!n)return null;r=n.all(i.MENUITEMS.join(","));if(!r)return null;var s=r.size();if(s===1)return null;var o=0,u=1,a=0;for(o=0;o=this.menuChildren.size()&&(r=0),t=this.menuChildren.item(r),o++;while(oa?(c=i=a,p=n=o):n=o+a&&(p=o+a-i),s>f&&l.toLowerCase()==="hidden"&&(h=s=f,e.setStyle("overflow","auto"));if(r>=u&&r+s>u+f){d=u+f-s;try{v=e.getStyle("boxShadow").replace(/.*? (\d+)px \d+px$/,"$1"),(new RegExp(/^\d+$/)).test(v)&&d-u>v&&(d-=v)}catch(m){}}p!==null&&e.setX(p),d!==null&&e.setY(d),c!==null&&e.setStyle("width",c.toString()+"px"),h!==null&&e.setStyle("height",h.toString()+"px")}},e.extend(s,e.Base,s.prototype,{NAME:"moodle-core-actionmenu",ATTRS:{align:{value:[o.TR,o.BR]}}}),M.core=M.core||{},M.core.actionmenu=M.core.actionmenu||{},M.core.actionmenu.instance=null,M.core.actionmenu.init=M.core.actionmenu.init||function(e){M.core.actionmenu.instance=M.core.actionmenu.instance||new s(e)},M.core.actionmenu.newDOMNode=function(e){if(M.core.actionmenu.instance===null +)return!0;e.all(i.MENU).each(M.core.actionmenu.instance.enhance,M.core.actionmenu.instance)}},"@VERSION@",{requires:["base","event","node-event-simulate"]}); diff --git a/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu.js b/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu.js index 02a6e8a0011..f08c612b3e0 100644 --- a/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu.js +++ b/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu.js @@ -284,7 +284,8 @@ ACTIONMENU.prototype = { var menu = e.target.ancestor(SELECTOR.MENU), menuvisible = (menu.hasClass('show')); - e.preventDefault(); + // Prevent event propagation as it will trigger the hideIfOutside event handler in certain situations. + e.halt(true); this.hideMenu(); if (menuvisible) { // The menu was visible and the user has clicked to toggle it again. diff --git a/lib/yui/src/actionmenu/js/actionmenu.js b/lib/yui/src/actionmenu/js/actionmenu.js index 7eb93de0d01..9e84085d7f3 100644 --- a/lib/yui/src/actionmenu/js/actionmenu.js +++ b/lib/yui/src/actionmenu/js/actionmenu.js @@ -284,7 +284,8 @@ ACTIONMENU.prototype = { var menu = e.target.ancestor(SELECTOR.MENU), menuvisible = (menu.hasClass('show')); - e.preventDefault(); + // Prevent event propagation as it will trigger the hideIfOutside event handler in certain situations. + e.halt(true); this.hideMenu(); if (menuvisible) { // The menu was visible and the user has clicked to toggle it again.