From f5593410afff8783bc81ee3fa0b0d24681d18b41 Mon Sep 17 00:00:00 2001 From: Sam Hemelryk Date: Thu, 17 Oct 2013 09:14:29 +1300 Subject: [PATCH] MDL-40976 actionmenu: toggle button second click now hides --- .../moodle-core-actionmenu-debug.js | 13 ++++++++++--- .../moodle-core-actionmenu-min.js | 2 +- .../moodle-core-actionmenu.js | 8 +++++++- lib/yui/src/actionmenu/js/actionmenu.js | 13 ++++++++++--- 4 files changed, 28 insertions(+), 8 deletions(-) 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 bbad33716b421..443e64b15dbc0 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 @@ -64,7 +64,7 @@ ACTIONMENU.prototype = { * @method initializer */ initializer : function() { - Y.log('Initialising action menu manager', 'note', ACTIONMENU.NAME); + Y.log('Initialising the action menu manager', 'debug', ACTIONMENU.NAME); Y.all(SELECTOR.MENU).each(this.enhance, this); BODY.delegate('click', this.toggleMenu, SELECTOR.MENU + ' ' + SELECTOR.TOGGLE, this); BODY.delegate('key', this.toggleMenu, 'enter,space', SELECTOR.MENU + ' ' + SELECTOR.TOGGLE, this); @@ -99,6 +99,7 @@ ACTIONMENU.prototype = { */ hideMenu : function() { if (this.dialogue) { + Y.log('Hiding an action menu', 'debug', ACTIONMENU.NAME); this.dialogue.removeClass('show'); this.dialogue.one(SELECTOR.MENUCONTENT).set('aria-hidden', true); this.dialogue = null; @@ -121,11 +122,17 @@ ACTIONMENU.prototype = { * @param {EventFacade} e */ toggleMenu : function(e) { + var menu = e.target.ancestor(SELECTOR.MENU), + menuvisible = (menu.hasClass('show')); // Stop all immediate propogation of the events we attach later will be // triggered and the dialogue immediately hidden again. e.halt(true); this.hideMenu(); - this.showMenu(e.target.ancestor(SELECTOR.MENU)); + if (menuvisible) { + // The menu was visible and the user has clicked to toggle it again. + return; + } + this.showMenu(menu); // Close the menu if the user presses escape. this.events.push(BODY.on('key', this.hideMenu, 'esc', this)); // Close the menu if the user clicks outside the menu. @@ -154,7 +161,7 @@ ACTIONMENU.prototype = { * @returns {M.core.dialogue|dialogue} */ showMenu : function(menu) { - Y.log('Displaying action menu', 'note', ACTIONMENU.NAME); + Y.log('Displaying an action menu', 'debug', ACTIONMENU.NAME); var ownerselector = menu.getData('owner'), menucontent = menu.one(SELECTOR.MENUCONTENT); this.owner = (ownerselector) ? menu.ancestor(ownerselector) : null; 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 ccf664f9d3f9a..3892cd902ebab 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 +1 @@ -YUI.add("moodle-core-actionmenu",function(e,t){var n=e.one(e.config.doc.body),r={MENUSHOWN:"action-menu-shown"},i={MENU:".moodle-actionmenu[data-enhance=moodle-core-actionmenu]",MENUCONTENT:".menu[data-rel=menu-content]",TOGGLE:".toggle-display"},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,initializer:function(){e.all(i.MENU).each(this.enhance,this),n.delegate("click",this.toggleMenu,i.MENU+" "+i.TOGGLE,this),n.delegate("key",this.toggleMenu,"enter,space",i.MENU+" "+i.TOGGLE,this)},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")},hideMenu:function(){this.dialogue&&(this.dialogue.removeClass("show"),this.dialogue.one(i.MENUCONTENT).set("aria-hidden",!0),this.dialogue=null),this.owner&&(this.owner.removeClass(r.MENUSHOWN),this.owner=null);for(var e in this.events)this.events[e].detach&&this.events[e].detach();this.events=[]},toggleMenu:function(e){e.halt(!0),this.hideMenu(),this.showMenu(e.target.ancestor(i.MENU)),this.events.push(n.on("key",this.hideMenu,"esc",this)),this.events.push(n.on("click",this.hideIfOutside,this)),this.events.push(n.delegate("focus",this.hideIfOutside,"*",this))},hideIfOutside:function(e){!e.target.test(i.MENU)&&!e.target.ancestor(i.MENU)&&this.hideMenu()},showMenu:function(e){var t=e.getData("owner"),n=e.one(i.MENUCONTENT);return this.owner=t?e.ancestor(t):null,this.dialogue=e,e.addClass("show"),this.owner&&this.owner.addClass(r.MENUSHOWN),this.constrain(n.set("aria-hidden",!1)),!0},constrain:function(e){var t=e.getData("constraint"),n=e.getX(),r=e.getY(),i=e.get("offsetWidth"),s=e.get("offsetHeight"),o=0,u=0,a,f,l=null,c=null,h=null,p=null;t&&(t=e.ancestor(t)),t?(a=t.get("offsetWidth"),f=t.get("offsetHeight"),o=t.getX(),u=t.getY()):(a=e.get("docWidth"),f=e.get("docHeight")),i>a?(l=i=a,h=n=o):n=o+a&&(h=o+a-i),s>f?(c=s=f,p=r=u):ru+f&&(p=u+f-s),h!==null&&e.setX(h),p!==null&&e.setY(p),l!==null&&e.setStyle("width",l.toString()+"px"),c!==null&&e.setStyle("height",c.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"]}); +YUI.add("moodle-core-actionmenu",function(e,t){var n=e.one(e.config.doc.body),r={MENUSHOWN:"action-menu-shown"},i={MENU:".moodle-actionmenu[data-enhance=moodle-core-actionmenu]",MENUCONTENT:".menu[data-rel=menu-content]",TOGGLE:".toggle-display"},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,initializer:function(){e.all(i.MENU).each(this.enhance,this),n.delegate("click",this.toggleMenu,i.MENU+" "+i.TOGGLE,this),n.delegate("key",this.toggleMenu,"enter,space",i.MENU+" "+i.TOGGLE,this)},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")},hideMenu:function(){this.dialogue&&(this.dialogue.removeClass("show"),this.dialogue.one(i.MENUCONTENT).set("aria-hidden",!0),this.dialogue=null),this.owner&&(this.owner.removeClass(r.MENUSHOWN),this.owner=null);for(var e in this.events)this.events[e].detach&&this.events[e].detach();this.events=[]},toggleMenu:function(e){var t=e.target.ancestor(i.MENU),r=t.hasClass("show");e.halt(!0),this.hideMenu();if(r)return;this.showMenu(t),this.events.push(n.on("key",this.hideMenu,"esc",this)),this.events.push(n.on("click",this.hideIfOutside,this)),this.events.push(n.delegate("focus",this.hideIfOutside,"*",this))},hideIfOutside:function(e){!e.target.test(i.MENU)&&!e.target.ancestor(i.MENU)&&this.hideMenu()},showMenu:function(e){var t=e.getData("owner"),n=e.one(i.MENUCONTENT);return this.owner=t?e.ancestor(t):null,this.dialogue=e,e.addClass("show"),this.owner&&this.owner.addClass(r.MENUSHOWN),this.constrain(n.set("aria-hidden",!1)),!0},constrain:function(e){var t=e.getData("constraint"),n=e.getX(),r=e.getY(),i=e.get("offsetWidth"),s=e.get("offsetHeight"),o=0,u=0,a,f,l=null,c=null,h=null,p=null;t&&(t=e.ancestor(t)),t?(a=t.get("offsetWidth"),f=t.get("offsetHeight"),o=t.getX(),u=t.getY()):(a=e.get("docWidth"),f=e.get("docHeight")),i>a?(l=i=a,h=n=o):n=o+a&&(h=o+a-i),s>f?(c=s=f,p=r=u):ru+f&&(p=u+f-s),h!==null&&e.setX(h),p!==null&&e.setY(p),l!==null&&e.setStyle("width",l.toString()+"px"),c!==null&&e.setStyle("height",c.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"]}); 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 971328d0c00b5..fcdb2c5374edd 100644 --- a/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu.js +++ b/lib/yui/build/moodle-core-actionmenu/moodle-core-actionmenu.js @@ -120,11 +120,17 @@ ACTIONMENU.prototype = { * @param {EventFacade} e */ toggleMenu : function(e) { + var menu = e.target.ancestor(SELECTOR.MENU), + menuvisible = (menu.hasClass('show')); // Stop all immediate propogation of the events we attach later will be // triggered and the dialogue immediately hidden again. e.halt(true); this.hideMenu(); - this.showMenu(e.target.ancestor(SELECTOR.MENU)); + if (menuvisible) { + // The menu was visible and the user has clicked to toggle it again. + return; + } + this.showMenu(menu); // Close the menu if the user presses escape. this.events.push(BODY.on('key', this.hideMenu, 'esc', this)); // Close the menu if the user clicks outside the menu. diff --git a/lib/yui/src/actionmenu/js/actionmenu.js b/lib/yui/src/actionmenu/js/actionmenu.js index c6216e5593927..c08379faca0ae 100644 --- a/lib/yui/src/actionmenu/js/actionmenu.js +++ b/lib/yui/src/actionmenu/js/actionmenu.js @@ -62,7 +62,7 @@ ACTIONMENU.prototype = { * @method initializer */ initializer : function() { - Y.log('Initialising action menu manager', 'note', ACTIONMENU.NAME); + Y.log('Initialising the action menu manager', 'debug', ACTIONMENU.NAME); Y.all(SELECTOR.MENU).each(this.enhance, this); BODY.delegate('click', this.toggleMenu, SELECTOR.MENU + ' ' + SELECTOR.TOGGLE, this); BODY.delegate('key', this.toggleMenu, 'enter,space', SELECTOR.MENU + ' ' + SELECTOR.TOGGLE, this); @@ -97,6 +97,7 @@ ACTIONMENU.prototype = { */ hideMenu : function() { if (this.dialogue) { + Y.log('Hiding an action menu', 'debug', ACTIONMENU.NAME); this.dialogue.removeClass('show'); this.dialogue.one(SELECTOR.MENUCONTENT).set('aria-hidden', true); this.dialogue = null; @@ -119,11 +120,17 @@ ACTIONMENU.prototype = { * @param {EventFacade} e */ toggleMenu : function(e) { + var menu = e.target.ancestor(SELECTOR.MENU), + menuvisible = (menu.hasClass('show')); // Stop all immediate propogation of the events we attach later will be // triggered and the dialogue immediately hidden again. e.halt(true); this.hideMenu(); - this.showMenu(e.target.ancestor(SELECTOR.MENU)); + if (menuvisible) { + // The menu was visible and the user has clicked to toggle it again. + return; + } + this.showMenu(menu); // Close the menu if the user presses escape. this.events.push(BODY.on('key', this.hideMenu, 'esc', this)); // Close the menu if the user clicks outside the menu. @@ -152,7 +159,7 @@ ACTIONMENU.prototype = { * @returns {M.core.dialogue|dialogue} */ showMenu : function(menu) { - Y.log('Displaying action menu', 'note', ACTIONMENU.NAME); + Y.log('Displaying an action menu', 'debug', ACTIONMENU.NAME); var ownerselector = menu.getData('owner'), menucontent = menu.one(SELECTOR.MENUCONTENT); this.owner = (ownerselector) ? menu.ancestor(ownerselector) : null;