diff --git a/lib/amd/build/popover_region_controller.min.js b/lib/amd/build/popover_region_controller.min.js index 923128515b1..8d02b60def8 100644 --- a/lib/amd/build/popover_region_controller.min.js +++ b/lib/amd/build/popover_region_controller.min.js @@ -8,6 +8,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @since 3.2 */ -define("core/popover_region_controller",["jquery","core/str","core/custom_interaction_events"],(function($,str,customEvents){var SELECTORS_CONTENT=".popover-region-content",SELECTORS_CONTENT_CONTAINER=".popover-region-content-container",SELECTORS_MENU_CONTAINER=".popover-region-container",SELECTORS_MENU_TOGGLE=".popover-region-toggle",SELECTORS_CAN_RECEIVE_FOCUS='input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',PopoverRegionController=function(element){this.root=$(element),this.content=this.root.find(SELECTORS_CONTENT),this.contentContainer=this.root.find(SELECTORS_CONTENT_CONTAINER),this.menuContainer=this.root.find(SELECTORS_MENU_CONTAINER),this.menuToggle=this.root.find(SELECTORS_MENU_TOGGLE),this.isLoading=!1,this.promises={closeHandlers:$.Deferred(),navigationHandlers:$.Deferred()},this.registerBaseEventListeners()};return PopoverRegionController.prototype.events=function(){return{menuOpened:"popoverregion:menuopened",menuClosed:"popoverregion:menuclosed",startLoading:"popoverregion:startLoading",stopLoading:"popoverregion:stopLoading"}},PopoverRegionController.prototype.getContentContainer=function(){return this.contentContainer},PopoverRegionController.prototype.getContent=function(){return this.content},PopoverRegionController.prototype.isMenuOpen=function(){return!this.root.hasClass("collapsed")},PopoverRegionController.prototype.toggleMenu=function(){this.isMenuOpen()?this.closeMenu():this.openMenu()},PopoverRegionController.prototype.closeMenu=function(){this.isMenuOpen()&&(this.root.addClass("collapsed"),this.menuContainer.attr("aria-expanded","false"),this.menuContainer.attr("aria-hidden","true"),this.updateButtonAriaLabel(),this.updateFocusItemTabIndex(),this.root.trigger(this.events().menuClosed))},PopoverRegionController.prototype.openMenu=function(){this.isMenuOpen()||(this.root.removeClass("collapsed"),this.menuContainer.attr("aria-expanded","true"),this.menuContainer.attr("aria-hidden","false"),this.updateButtonAriaLabel(),this.updateFocusItemTabIndex(),this.promises.closeHandlers.resolve(),this.promises.navigationHandlers.resolve(),this.root.trigger(this.events().menuOpened))},PopoverRegionController.prototype.updateButtonAriaLabel=function(){this.isMenuOpen()?str.get_string("hidepopoverwindow").done(function(string){this.menuToggle.attr("aria-label",string)}.bind(this)):str.get_string("showpopoverwindow").done(function(string){this.menuToggle.attr("aria-label",string)}.bind(this))},PopoverRegionController.prototype.startLoading=function(){this.isLoading=!0,this.getContentContainer().addClass("loading"),this.getContentContainer().attr("aria-busy","true"),this.root.trigger(this.events().startLoading)},PopoverRegionController.prototype.stopLoading=function(){this.isLoading=!1,this.getContentContainer().removeClass("loading"),this.getContentContainer().attr("aria-busy","false"),this.root.trigger(this.events().stopLoading)},PopoverRegionController.prototype.focusMenuToggle=function(){this.menuToggle.focus()},PopoverRegionController.prototype.contentItemHasFocus=function(){return this.getContentItemWithFocus().length>0},PopoverRegionController.prototype.getContentItemWithFocus=function(){var currentFocus=$(document.activeElement),items=this.getContent().children(),currentItem=items.filter(currentFocus);return currentItem.length||(currentItem=items.has(currentFocus)),currentItem},PopoverRegionController.prototype.focusContentItem=function(item){item.is(SELECTORS_CAN_RECEIVE_FOCUS)?item.focus():item.find(SELECTORS_CAN_RECEIVE_FOCUS).first().focus()},PopoverRegionController.prototype.focusFirstContentItem=function(){this.focusContentItem(this.getContent().children().first())},PopoverRegionController.prototype.focusLastContentItem=function(){this.focusContentItem(this.getContent().children().last())},PopoverRegionController.prototype.focusNextContentItem=function(){var currentItem=this.getContentItemWithFocus();currentItem.length&¤tItem.next()&&this.focusContentItem(currentItem.next())},PopoverRegionController.prototype.focusPreviousContentItem=function(){var currentItem=this.getContentItemWithFocus();currentItem.length&¤tItem.prev()&&this.focusContentItem(currentItem.prev())},PopoverRegionController.prototype.registerBaseEventListeners=function(){customEvents.define(this.root,[customEvents.events.activate,customEvents.events.escape]),this.root.on(customEvents.events.activate,SELECTORS_MENU_TOGGLE,function(){this.toggleMenu()}.bind(this)),this.promises.closeHandlers.done(function(){this.root.on(customEvents.events.escape,function(){this.closeMenu(),this.focusMenuToggle()}.bind(this)),$("html").click(function(e){var target=$(e.target);this.root.is(target)||this.root.has(target).length||this.closeMenu()}.bind(this)),customEvents.define(this.getContentContainer(),[customEvents.events.scrollBottom])}.bind(this))},PopoverRegionController.prototype.registerListNavigationEventListeners=function(){customEvents.define(this.root,[customEvents.events.down]),this.root.on(customEvents.events.down,function(e,data){this.isMenuOpen()?this.contentItemHasFocus()?this.focusNextContentItem():this.focusFirstContentItem():(this.openMenu(),this.focusFirstContentItem()),data.originalEvent.preventDefault()}.bind(this)),this.promises.navigationHandlers.done(function(){customEvents.define(this.root,[customEvents.events.up,customEvents.events.home,customEvents.events.end]),this.root.on(customEvents.events.up,function(e,data){this.focusPreviousContentItem(),data.originalEvent.preventDefault()}.bind(this)),this.root.on(customEvents.events.home,function(e,data){this.focusFirstContentItem(),data.originalEvent.preventDefault()}.bind(this)),this.root.on(customEvents.events.end,function(e,data){this.focusLastContentItem(),data.originalEvent.preventDefault()}.bind(this))}.bind(this))},PopoverRegionController.prototype.updateFocusItemTabIndex=function(){this.isMenuOpen()?this.menuContainer.find(SELECTORS_CAN_RECEIVE_FOCUS).removeAttr("tabindex"):this.menuContainer.find(SELECTORS_CAN_RECEIVE_FOCUS).attr("tabindex","-1")},PopoverRegionController})); +define("core/popover_region_controller",["jquery","core/str","core/custom_interaction_events"],(function($,str,customEvents){var SELECTORS_CONTENT=".popover-region-content",SELECTORS_CONTENT_CONTAINER=".popover-region-content-container",SELECTORS_MENU_CONTAINER=".popover-region-container",SELECTORS_MENU_TOGGLE=".popover-region-toggle",SELECTORS_CAN_RECEIVE_FOCUS='input:not([type="hidden"]), a[href], button, textarea, select, [tabindex]',PopoverRegionController=function(element){this.root=$(element),this.content=this.root.find(SELECTORS_CONTENT),this.contentContainer=this.root.find(SELECTORS_CONTENT_CONTAINER),this.menuContainer=this.root.find(SELECTORS_MENU_CONTAINER),this.menuToggle=this.root.find(SELECTORS_MENU_TOGGLE),this.isLoading=!1,this.promises={closeHandlers:$.Deferred(),navigationHandlers:$.Deferred()},this.registerBaseEventListeners()};return PopoverRegionController.prototype.events=function(){return{menuOpened:"popoverregion:menuopened",menuClosed:"popoverregion:menuclosed",startLoading:"popoverregion:startLoading",stopLoading:"popoverregion:stopLoading"}},PopoverRegionController.prototype.getContentContainer=function(){return this.contentContainer},PopoverRegionController.prototype.getContent=function(){return this.content},PopoverRegionController.prototype.isMenuOpen=function(){return!this.root.hasClass("collapsed")},PopoverRegionController.prototype.toggleMenu=function(){this.isMenuOpen()?this.closeMenu():this.openMenu()},PopoverRegionController.prototype.closeMenu=function(){this.isMenuOpen()&&(this.root.addClass("collapsed"),this.menuContainer.attr("aria-expanded","false"),this.menuContainer.attr("aria-hidden","true"),this.updateButtonAriaLabel(),this.updateFocusItemTabIndex(),this.root.trigger(this.events().menuClosed))},PopoverRegionController.prototype.openMenu=function(){this.isMenuOpen()||(this.root.removeClass("collapsed"),this.menuContainer.attr("aria-expanded","true"),this.menuContainer.attr("aria-hidden","false"),this.updateButtonAriaLabel(),this.updateFocusItemTabIndex(),this.promises.closeHandlers.resolve(),this.promises.navigationHandlers.resolve(),this.root.trigger(this.events().menuOpened))},PopoverRegionController.prototype.updateButtonAriaLabel=function(){this.isMenuOpen()?str.get_string("hidepopoverwindow").done(function(string){this.menuToggle.attr("aria-label",string)}.bind(this)):str.get_string("showpopoverwindow").done(function(string){this.menuToggle.attr("aria-label",string)}.bind(this))},PopoverRegionController.prototype.startLoading=function(){this.isLoading=!0,this.getContentContainer().addClass("loading"),this.getContentContainer().attr("aria-busy","true"),this.root.trigger(this.events().startLoading)},PopoverRegionController.prototype.stopLoading=function(){this.isLoading=!1,this.getContentContainer().removeClass("loading"),this.getContentContainer().attr("aria-busy","false"),this.root.trigger(this.events().stopLoading)},PopoverRegionController.prototype.focusMenuToggle=function(){this.menuToggle.focus()},PopoverRegionController.prototype.contentItemHasFocus=function(){return this.getContentItemWithFocus().length>0},PopoverRegionController.prototype.getContentItemWithFocus=function(){var currentFocus=$(document.activeElement),items=this.getContent().children(),currentItem=items.filter(currentFocus);return currentItem.length||(currentItem=items.has(currentFocus)),currentItem},PopoverRegionController.prototype.focusContentItem=function(item){item.is(SELECTORS_CAN_RECEIVE_FOCUS)?item.focus():item.find(SELECTORS_CAN_RECEIVE_FOCUS).first().focus()},PopoverRegionController.prototype.focusFirstContentItem=function(){this.focusContentItem(this.getContent().children().first())},PopoverRegionController.prototype.focusLastContentItem=function(){this.focusContentItem(this.getContent().children().last())},PopoverRegionController.prototype.focusNextContentItem=function(){var currentItem=this.getContentItemWithFocus();currentItem.length&¤tItem.next()&&this.focusContentItem(currentItem.next())},PopoverRegionController.prototype.focusPreviousContentItem=function(){var currentItem=this.getContentItemWithFocus();currentItem.length&¤tItem.prev()&&this.focusContentItem(currentItem.prev())},PopoverRegionController.prototype.registerBaseEventListeners=function(){customEvents.define(this.root,[customEvents.events.activate,customEvents.events.escape]),this.root.on(customEvents.events.activate,SELECTORS_MENU_TOGGLE,function(){this.toggleMenu()}.bind(this)),this.promises.closeHandlers.done(function(){this.root.on(customEvents.events.escape,function(){this.closeMenu(),this.focusMenuToggle()}.bind(this)),document.addEventListener("click",(e=>{const target=e.target;this.root.is(target)||this.root.has(target).length||this.closeMenu()}),!0),customEvents.define(this.getContentContainer(),[customEvents.events.scrollBottom])}.bind(this))},PopoverRegionController.prototype.registerListNavigationEventListeners=function(){customEvents.define(this.root,[customEvents.events.down]),this.root.on(customEvents.events.down,function(e,data){this.isMenuOpen()?this.contentItemHasFocus()?this.focusNextContentItem():this.focusFirstContentItem():(this.openMenu(),this.focusFirstContentItem()),data.originalEvent.preventDefault()}.bind(this)),this.promises.navigationHandlers.done(function(){customEvents.define(this.root,[customEvents.events.up,customEvents.events.home,customEvents.events.end]),this.root.on(customEvents.events.up,function(e,data){this.focusPreviousContentItem(),data.originalEvent.preventDefault()}.bind(this)),this.root.on(customEvents.events.home,function(e,data){this.focusFirstContentItem(),data.originalEvent.preventDefault()}.bind(this)),this.root.on(customEvents.events.end,function(e,data){this.focusLastContentItem(),data.originalEvent.preventDefault()}.bind(this))}.bind(this))},PopoverRegionController.prototype.updateFocusItemTabIndex=function(){this.isMenuOpen()?this.menuContainer.find(SELECTORS_CAN_RECEIVE_FOCUS).removeAttr("tabindex"):this.menuContainer.find(SELECTORS_CAN_RECEIVE_FOCUS).attr("tabindex","-1")},PopoverRegionController})); //# sourceMappingURL=popover_region_controller.min.js.map \ No newline at end of file diff --git a/lib/amd/build/popover_region_controller.min.js.map b/lib/amd/build/popover_region_controller.min.js.map index a5ef8dc22c1..27589575f0e 100644 --- a/lib/amd/build/popover_region_controller.min.js.map +++ b/lib/amd/build/popover_region_controller.min.js.map @@ -1 +1 @@ -{"version":3,"file":"popover_region_controller.min.js","sources":["../src/popover_region_controller.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Controls the popover region element.\n *\n * See template: core/popover_region\n *\n * @module core/popover_region_controller\n * @copyright 2015 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.2\n */\ndefine(['jquery', 'core/str', 'core/custom_interaction_events'],\n function($, str, customEvents) {\n\n var SELECTORS = {\n CONTENT: '.popover-region-content',\n CONTENT_CONTAINER: '.popover-region-content-container',\n MENU_CONTAINER: '.popover-region-container',\n MENU_TOGGLE: '.popover-region-toggle',\n CAN_RECEIVE_FOCUS: 'input:not([type=\"hidden\"]), a[href], button, textarea, select, [tabindex]',\n };\n\n /**\n * Constructor for the PopoverRegionController.\n *\n * @param {jQuery} element object root element of the popover\n */\n var PopoverRegionController = function(element) {\n this.root = $(element);\n this.content = this.root.find(SELECTORS.CONTENT);\n this.contentContainer = this.root.find(SELECTORS.CONTENT_CONTAINER);\n this.menuContainer = this.root.find(SELECTORS.MENU_CONTAINER);\n this.menuToggle = this.root.find(SELECTORS.MENU_TOGGLE);\n this.isLoading = false;\n this.promises = {\n closeHandlers: $.Deferred(),\n navigationHandlers: $.Deferred(),\n };\n\n // Core event listeners to open and close.\n this.registerBaseEventListeners();\n };\n\n /**\n * The collection of events triggered by this controller.\n *\n * @returns {object}\n */\n PopoverRegionController.prototype.events = function() {\n return {\n menuOpened: 'popoverregion:menuopened',\n menuClosed: 'popoverregion:menuclosed',\n startLoading: 'popoverregion:startLoading',\n stopLoading: 'popoverregion:stopLoading',\n };\n };\n\n /**\n * Return the container element for the content element.\n *\n * @method getContentContainer\n * @return {jQuery} object\n */\n PopoverRegionController.prototype.getContentContainer = function() {\n return this.contentContainer;\n };\n\n /**\n * Return the content element.\n *\n * @method getContent\n * @return {jQuery} object\n */\n PopoverRegionController.prototype.getContent = function() {\n return this.content;\n };\n\n /**\n * Checks if the popover is displayed.\n *\n * @method isMenuOpen\n * @return {bool}\n */\n PopoverRegionController.prototype.isMenuOpen = function() {\n return !this.root.hasClass('collapsed');\n };\n\n /**\n * Toggle the visibility of the popover.\n *\n * @method toggleMenu\n */\n PopoverRegionController.prototype.toggleMenu = function() {\n if (this.isMenuOpen()) {\n this.closeMenu();\n } else {\n this.openMenu();\n }\n };\n\n /**\n * Hide the popover.\n *\n * Note: This triggers the menuClosed event.\n *\n * @method closeMenu\n */\n PopoverRegionController.prototype.closeMenu = function() {\n // We're already closed.\n if (!this.isMenuOpen()) {\n return;\n }\n\n this.root.addClass('collapsed');\n this.menuContainer.attr('aria-expanded', 'false');\n this.menuContainer.attr('aria-hidden', 'true');\n this.updateButtonAriaLabel();\n this.updateFocusItemTabIndex();\n this.root.trigger(this.events().menuClosed);\n };\n\n /**\n * Show the popover.\n *\n * Note: This triggers the menuOpened event.\n *\n * @method openMenu\n */\n PopoverRegionController.prototype.openMenu = function() {\n // We're already open.\n if (this.isMenuOpen()) {\n return;\n }\n\n this.root.removeClass('collapsed');\n this.menuContainer.attr('aria-expanded', 'true');\n this.menuContainer.attr('aria-hidden', 'false');\n this.updateButtonAriaLabel();\n this.updateFocusItemTabIndex();\n // Resolve the promises to allow the handlers to be added\n // to the DOM, if they have been requested.\n this.promises.closeHandlers.resolve();\n this.promises.navigationHandlers.resolve();\n this.root.trigger(this.events().menuOpened);\n };\n\n /**\n * Set the appropriate aria label on the popover toggle.\n *\n * @method updateButtonAriaLabel\n */\n PopoverRegionController.prototype.updateButtonAriaLabel = function() {\n if (this.isMenuOpen()) {\n str.get_string('hidepopoverwindow').done(function(string) {\n this.menuToggle.attr('aria-label', string);\n }.bind(this));\n } else {\n str.get_string('showpopoverwindow').done(function(string) {\n this.menuToggle.attr('aria-label', string);\n }.bind(this));\n }\n };\n\n /**\n * Set the loading state on this popover.\n *\n * Note: This triggers the startLoading event.\n *\n * @method startLoading\n */\n PopoverRegionController.prototype.startLoading = function() {\n this.isLoading = true;\n this.getContentContainer().addClass('loading');\n this.getContentContainer().attr('aria-busy', 'true');\n this.root.trigger(this.events().startLoading);\n };\n\n /**\n * Undo the loading state on this popover.\n *\n * Note: This triggers the stopLoading event.\n *\n * @method stopLoading\n */\n PopoverRegionController.prototype.stopLoading = function() {\n this.isLoading = false;\n this.getContentContainer().removeClass('loading');\n this.getContentContainer().attr('aria-busy', 'false');\n this.root.trigger(this.events().stopLoading);\n };\n\n /**\n * Sets the focus on the menu toggle.\n *\n * @method focusMenuToggle\n */\n PopoverRegionController.prototype.focusMenuToggle = function() {\n this.menuToggle.focus();\n };\n\n /**\n * Check if a content item has focus.\n *\n * @method contentItemHasFocus\n * @return {bool}\n */\n PopoverRegionController.prototype.contentItemHasFocus = function() {\n return this.getContentItemWithFocus().length > 0;\n };\n\n /**\n * Return the currently focused content item.\n *\n * @method getContentItemWithFocus\n * @return {jQuery} object\n */\n PopoverRegionController.prototype.getContentItemWithFocus = function() {\n var currentFocus = $(document.activeElement);\n var items = this.getContent().children();\n var currentItem = items.filter(currentFocus);\n\n if (!currentItem.length) {\n currentItem = items.has(currentFocus);\n }\n\n return currentItem;\n };\n\n /**\n * Focus the given content item or the first focusable element within\n * the content item.\n *\n * @method focusContentItem\n * @param {object} item The content item jQuery element\n */\n PopoverRegionController.prototype.focusContentItem = function(item) {\n if (item.is(SELECTORS.CAN_RECEIVE_FOCUS)) {\n item.focus();\n } else {\n item.find(SELECTORS.CAN_RECEIVE_FOCUS).first().focus();\n }\n };\n\n /**\n * Set focus on the first content item in the list.\n *\n * @method focusFirstContentItem\n */\n PopoverRegionController.prototype.focusFirstContentItem = function() {\n this.focusContentItem(this.getContent().children().first());\n };\n\n /**\n * Set focus on the last content item in the list.\n *\n * @method focusLastContentItem\n */\n PopoverRegionController.prototype.focusLastContentItem = function() {\n this.focusContentItem(this.getContent().children().last());\n };\n\n /**\n * Set focus on the content item after the item that currently has focus\n * in the list.\n *\n * @method focusNextContentItem\n */\n PopoverRegionController.prototype.focusNextContentItem = function() {\n var currentItem = this.getContentItemWithFocus();\n\n if (currentItem.length && currentItem.next()) {\n this.focusContentItem(currentItem.next());\n }\n };\n\n /**\n * Set focus on the content item preceding the item that currently has focus\n * in the list.\n *\n * @method focusPreviousContentItem\n */\n PopoverRegionController.prototype.focusPreviousContentItem = function() {\n var currentItem = this.getContentItemWithFocus();\n\n if (currentItem.length && currentItem.prev()) {\n this.focusContentItem(currentItem.prev());\n }\n };\n\n /**\n * Register the minimal amount of listeners for the popover to function.\n *\n * @method registerBaseEventListeners\n */\n PopoverRegionController.prototype.registerBaseEventListeners = function() {\n customEvents.define(this.root, [\n customEvents.events.activate,\n customEvents.events.escape,\n ]);\n\n // Toggle the popover visibility on activation (click/enter/space) of the toggle button.\n this.root.on(customEvents.events.activate, SELECTORS.MENU_TOGGLE, function() {\n this.toggleMenu();\n }.bind(this));\n\n // Delay the binding of these handlers until the region has been opened.\n this.promises.closeHandlers.done(function() {\n // Close the popover if escape is pressed.\n this.root.on(customEvents.events.escape, function() {\n this.closeMenu();\n this.focusMenuToggle();\n }.bind(this));\n\n // Close the popover if any other part of the page is clicked.\n $('html').click(function(e) {\n var target = $(e.target);\n if (!this.root.is(target) && !this.root.has(target).length) {\n this.closeMenu();\n }\n }.bind(this));\n\n customEvents.define(this.getContentContainer(), [\n customEvents.events.scrollBottom\n ]);\n }.bind(this));\n };\n\n /**\n * Set up the event listeners for keyboard navigating a list of content items.\n *\n * @method registerListNavigationEventListeners\n */\n PopoverRegionController.prototype.registerListNavigationEventListeners = function() {\n customEvents.define(this.root, [\n customEvents.events.down\n ]);\n\n // If the down arrow is pressed then open the menu and focus the first content\n // item or focus the next content item if the menu is open.\n this.root.on(customEvents.events.down, function(e, data) {\n if (!this.isMenuOpen()) {\n this.openMenu();\n this.focusFirstContentItem();\n } else {\n if (this.contentItemHasFocus()) {\n this.focusNextContentItem();\n } else {\n this.focusFirstContentItem();\n }\n }\n\n data.originalEvent.preventDefault();\n }.bind(this));\n\n // Delay the binding of these handlers until the region has been opened.\n this.promises.navigationHandlers.done(function() {\n customEvents.define(this.root, [\n customEvents.events.up,\n customEvents.events.home,\n customEvents.events.end,\n ]);\n\n // Shift focus to the previous content item if the up key is pressed.\n this.root.on(customEvents.events.up, function(e, data) {\n this.focusPreviousContentItem();\n data.originalEvent.preventDefault();\n }.bind(this));\n\n // Jump focus to the first content item if the home key is pressed.\n this.root.on(customEvents.events.home, function(e, data) {\n this.focusFirstContentItem();\n data.originalEvent.preventDefault();\n }.bind(this));\n\n // Jump focus to the last content item if the end key is pressed.\n this.root.on(customEvents.events.end, function(e, data) {\n this.focusLastContentItem();\n data.originalEvent.preventDefault();\n }.bind(this));\n }.bind(this));\n };\n\n /**\n * Set the appropriate tabindex attribute on the popover toggle.\n *\n * @method updateFocusItemTabIndex\n */\n PopoverRegionController.prototype.updateFocusItemTabIndex = function() {\n if (this.isMenuOpen()) {\n this.menuContainer.find(SELECTORS.CAN_RECEIVE_FOCUS).removeAttr('tabindex');\n } else {\n this.menuContainer.find(SELECTORS.CAN_RECEIVE_FOCUS).attr('tabindex', '-1');\n }\n };\n\n return PopoverRegionController;\n});\n"],"names":["define","$","str","customEvents","SELECTORS","PopoverRegionController","element","root","content","this","find","contentContainer","menuContainer","menuToggle","isLoading","promises","closeHandlers","Deferred","navigationHandlers","registerBaseEventListeners","prototype","events","menuOpened","menuClosed","startLoading","stopLoading","getContentContainer","getContent","isMenuOpen","hasClass","toggleMenu","closeMenu","openMenu","addClass","attr","updateButtonAriaLabel","updateFocusItemTabIndex","trigger","removeClass","resolve","get_string","done","string","bind","focusMenuToggle","focus","contentItemHasFocus","getContentItemWithFocus","length","currentFocus","document","activeElement","items","children","currentItem","filter","has","focusContentItem","item","is","first","focusFirstContentItem","focusLastContentItem","last","focusNextContentItem","next","focusPreviousContentItem","prev","activate","escape","on","click","e","target","scrollBottom","registerListNavigationEventListeners","down","data","originalEvent","preventDefault","up","home","end","removeAttr"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"popover_region_controller.min.js","sources":["../src/popover_region_controller.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see .\n\n/**\n * Controls the popover region element.\n *\n * See template: core/popover_region\n *\n * @module core/popover_region_controller\n * @copyright 2015 Ryan Wyllie \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n * @since 3.2\n */\ndefine(['jquery', 'core/str', 'core/custom_interaction_events'],\n function($, str, customEvents) {\n\n var SELECTORS = {\n CONTENT: '.popover-region-content',\n CONTENT_CONTAINER: '.popover-region-content-container',\n MENU_CONTAINER: '.popover-region-container',\n MENU_TOGGLE: '.popover-region-toggle',\n CAN_RECEIVE_FOCUS: 'input:not([type=\"hidden\"]), a[href], button, textarea, select, [tabindex]',\n };\n\n /**\n * Constructor for the PopoverRegionController.\n *\n * @param {jQuery} element object root element of the popover\n */\n var PopoverRegionController = function(element) {\n this.root = $(element);\n this.content = this.root.find(SELECTORS.CONTENT);\n this.contentContainer = this.root.find(SELECTORS.CONTENT_CONTAINER);\n this.menuContainer = this.root.find(SELECTORS.MENU_CONTAINER);\n this.menuToggle = this.root.find(SELECTORS.MENU_TOGGLE);\n this.isLoading = false;\n this.promises = {\n closeHandlers: $.Deferred(),\n navigationHandlers: $.Deferred(),\n };\n\n // Core event listeners to open and close.\n this.registerBaseEventListeners();\n };\n\n /**\n * The collection of events triggered by this controller.\n *\n * @returns {object}\n */\n PopoverRegionController.prototype.events = function() {\n return {\n menuOpened: 'popoverregion:menuopened',\n menuClosed: 'popoverregion:menuclosed',\n startLoading: 'popoverregion:startLoading',\n stopLoading: 'popoverregion:stopLoading',\n };\n };\n\n /**\n * Return the container element for the content element.\n *\n * @method getContentContainer\n * @return {jQuery} object\n */\n PopoverRegionController.prototype.getContentContainer = function() {\n return this.contentContainer;\n };\n\n /**\n * Return the content element.\n *\n * @method getContent\n * @return {jQuery} object\n */\n PopoverRegionController.prototype.getContent = function() {\n return this.content;\n };\n\n /**\n * Checks if the popover is displayed.\n *\n * @method isMenuOpen\n * @return {bool}\n */\n PopoverRegionController.prototype.isMenuOpen = function() {\n return !this.root.hasClass('collapsed');\n };\n\n /**\n * Toggle the visibility of the popover.\n *\n * @method toggleMenu\n */\n PopoverRegionController.prototype.toggleMenu = function() {\n if (this.isMenuOpen()) {\n this.closeMenu();\n } else {\n this.openMenu();\n }\n };\n\n /**\n * Hide the popover.\n *\n * Note: This triggers the menuClosed event.\n *\n * @method closeMenu\n */\n PopoverRegionController.prototype.closeMenu = function() {\n // We're already closed.\n if (!this.isMenuOpen()) {\n return;\n }\n\n this.root.addClass('collapsed');\n this.menuContainer.attr('aria-expanded', 'false');\n this.menuContainer.attr('aria-hidden', 'true');\n this.updateButtonAriaLabel();\n this.updateFocusItemTabIndex();\n this.root.trigger(this.events().menuClosed);\n };\n\n /**\n * Show the popover.\n *\n * Note: This triggers the menuOpened event.\n *\n * @method openMenu\n */\n PopoverRegionController.prototype.openMenu = function() {\n // We're already open.\n if (this.isMenuOpen()) {\n return;\n }\n\n this.root.removeClass('collapsed');\n this.menuContainer.attr('aria-expanded', 'true');\n this.menuContainer.attr('aria-hidden', 'false');\n this.updateButtonAriaLabel();\n this.updateFocusItemTabIndex();\n // Resolve the promises to allow the handlers to be added\n // to the DOM, if they have been requested.\n this.promises.closeHandlers.resolve();\n this.promises.navigationHandlers.resolve();\n this.root.trigger(this.events().menuOpened);\n };\n\n /**\n * Set the appropriate aria label on the popover toggle.\n *\n * @method updateButtonAriaLabel\n */\n PopoverRegionController.prototype.updateButtonAriaLabel = function() {\n if (this.isMenuOpen()) {\n str.get_string('hidepopoverwindow').done(function(string) {\n this.menuToggle.attr('aria-label', string);\n }.bind(this));\n } else {\n str.get_string('showpopoverwindow').done(function(string) {\n this.menuToggle.attr('aria-label', string);\n }.bind(this));\n }\n };\n\n /**\n * Set the loading state on this popover.\n *\n * Note: This triggers the startLoading event.\n *\n * @method startLoading\n */\n PopoverRegionController.prototype.startLoading = function() {\n this.isLoading = true;\n this.getContentContainer().addClass('loading');\n this.getContentContainer().attr('aria-busy', 'true');\n this.root.trigger(this.events().startLoading);\n };\n\n /**\n * Undo the loading state on this popover.\n *\n * Note: This triggers the stopLoading event.\n *\n * @method stopLoading\n */\n PopoverRegionController.prototype.stopLoading = function() {\n this.isLoading = false;\n this.getContentContainer().removeClass('loading');\n this.getContentContainer().attr('aria-busy', 'false');\n this.root.trigger(this.events().stopLoading);\n };\n\n /**\n * Sets the focus on the menu toggle.\n *\n * @method focusMenuToggle\n */\n PopoverRegionController.prototype.focusMenuToggle = function() {\n this.menuToggle.focus();\n };\n\n /**\n * Check if a content item has focus.\n *\n * @method contentItemHasFocus\n * @return {bool}\n */\n PopoverRegionController.prototype.contentItemHasFocus = function() {\n return this.getContentItemWithFocus().length > 0;\n };\n\n /**\n * Return the currently focused content item.\n *\n * @method getContentItemWithFocus\n * @return {jQuery} object\n */\n PopoverRegionController.prototype.getContentItemWithFocus = function() {\n var currentFocus = $(document.activeElement);\n var items = this.getContent().children();\n var currentItem = items.filter(currentFocus);\n\n if (!currentItem.length) {\n currentItem = items.has(currentFocus);\n }\n\n return currentItem;\n };\n\n /**\n * Focus the given content item or the first focusable element within\n * the content item.\n *\n * @method focusContentItem\n * @param {object} item The content item jQuery element\n */\n PopoverRegionController.prototype.focusContentItem = function(item) {\n if (item.is(SELECTORS.CAN_RECEIVE_FOCUS)) {\n item.focus();\n } else {\n item.find(SELECTORS.CAN_RECEIVE_FOCUS).first().focus();\n }\n };\n\n /**\n * Set focus on the first content item in the list.\n *\n * @method focusFirstContentItem\n */\n PopoverRegionController.prototype.focusFirstContentItem = function() {\n this.focusContentItem(this.getContent().children().first());\n };\n\n /**\n * Set focus on the last content item in the list.\n *\n * @method focusLastContentItem\n */\n PopoverRegionController.prototype.focusLastContentItem = function() {\n this.focusContentItem(this.getContent().children().last());\n };\n\n /**\n * Set focus on the content item after the item that currently has focus\n * in the list.\n *\n * @method focusNextContentItem\n */\n PopoverRegionController.prototype.focusNextContentItem = function() {\n var currentItem = this.getContentItemWithFocus();\n\n if (currentItem.length && currentItem.next()) {\n this.focusContentItem(currentItem.next());\n }\n };\n\n /**\n * Set focus on the content item preceding the item that currently has focus\n * in the list.\n *\n * @method focusPreviousContentItem\n */\n PopoverRegionController.prototype.focusPreviousContentItem = function() {\n var currentItem = this.getContentItemWithFocus();\n\n if (currentItem.length && currentItem.prev()) {\n this.focusContentItem(currentItem.prev());\n }\n };\n\n /**\n * Register the minimal amount of listeners for the popover to function.\n *\n * @method registerBaseEventListeners\n */\n PopoverRegionController.prototype.registerBaseEventListeners = function() {\n customEvents.define(this.root, [\n customEvents.events.activate,\n customEvents.events.escape,\n ]);\n\n // Toggle the popover visibility on activation (click/enter/space) of the toggle button.\n this.root.on(customEvents.events.activate, SELECTORS.MENU_TOGGLE, function() {\n this.toggleMenu();\n }.bind(this));\n\n // Delay the binding of these handlers until the region has been opened.\n this.promises.closeHandlers.done(function() {\n // Close the popover if escape is pressed.\n this.root.on(customEvents.events.escape, function() {\n this.closeMenu();\n this.focusMenuToggle();\n }.bind(this));\n\n // Close the popover if any other part of the page is clicked.\n document.addEventListener('click', (e) => {\n const target = e.target;\n // Check if the click is outside the root element.\n if (!this.root.is(target) && !this.root.has(target).length) {\n this.closeMenu();\n }\n }, true); // `true` makes it a capture phase event listener.\n\n customEvents.define(this.getContentContainer(), [\n customEvents.events.scrollBottom\n ]);\n }.bind(this));\n };\n\n /**\n * Set up the event listeners for keyboard navigating a list of content items.\n *\n * @method registerListNavigationEventListeners\n */\n PopoverRegionController.prototype.registerListNavigationEventListeners = function() {\n customEvents.define(this.root, [\n customEvents.events.down\n ]);\n\n // If the down arrow is pressed then open the menu and focus the first content\n // item or focus the next content item if the menu is open.\n this.root.on(customEvents.events.down, function(e, data) {\n if (!this.isMenuOpen()) {\n this.openMenu();\n this.focusFirstContentItem();\n } else {\n if (this.contentItemHasFocus()) {\n this.focusNextContentItem();\n } else {\n this.focusFirstContentItem();\n }\n }\n\n data.originalEvent.preventDefault();\n }.bind(this));\n\n // Delay the binding of these handlers until the region has been opened.\n this.promises.navigationHandlers.done(function() {\n customEvents.define(this.root, [\n customEvents.events.up,\n customEvents.events.home,\n customEvents.events.end,\n ]);\n\n // Shift focus to the previous content item if the up key is pressed.\n this.root.on(customEvents.events.up, function(e, data) {\n this.focusPreviousContentItem();\n data.originalEvent.preventDefault();\n }.bind(this));\n\n // Jump focus to the first content item if the home key is pressed.\n this.root.on(customEvents.events.home, function(e, data) {\n this.focusFirstContentItem();\n data.originalEvent.preventDefault();\n }.bind(this));\n\n // Jump focus to the last content item if the end key is pressed.\n this.root.on(customEvents.events.end, function(e, data) {\n this.focusLastContentItem();\n data.originalEvent.preventDefault();\n }.bind(this));\n }.bind(this));\n };\n\n /**\n * Set the appropriate tabindex attribute on the popover toggle.\n *\n * @method updateFocusItemTabIndex\n */\n PopoverRegionController.prototype.updateFocusItemTabIndex = function() {\n if (this.isMenuOpen()) {\n this.menuContainer.find(SELECTORS.CAN_RECEIVE_FOCUS).removeAttr('tabindex');\n } else {\n this.menuContainer.find(SELECTORS.CAN_RECEIVE_FOCUS).attr('tabindex', '-1');\n }\n };\n\n return PopoverRegionController;\n});\n"],"names":["define","$","str","customEvents","SELECTORS","PopoverRegionController","element","root","content","this","find","contentContainer","menuContainer","menuToggle","isLoading","promises","closeHandlers","Deferred","navigationHandlers","registerBaseEventListeners","prototype","events","menuOpened","menuClosed","startLoading","stopLoading","getContentContainer","getContent","isMenuOpen","hasClass","toggleMenu","closeMenu","openMenu","addClass","attr","updateButtonAriaLabel","updateFocusItemTabIndex","trigger","removeClass","resolve","get_string","done","string","bind","focusMenuToggle","focus","contentItemHasFocus","getContentItemWithFocus","length","currentFocus","document","activeElement","items","children","currentItem","filter","has","focusContentItem","item","is","first","focusFirstContentItem","focusLastContentItem","last","focusNextContentItem","next","focusPreviousContentItem","prev","activate","escape","on","addEventListener","e","target","scrollBottom","registerListNavigationEventListeners","down","data","originalEvent","preventDefault","up","home","end","removeAttr"],"mappings":"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"} \ No newline at end of file diff --git a/lib/amd/src/popover_region_controller.js b/lib/amd/src/popover_region_controller.js index d709835302b..6837f02dc37 100644 --- a/lib/amd/src/popover_region_controller.js +++ b/lib/amd/src/popover_region_controller.js @@ -326,12 +326,13 @@ define(['jquery', 'core/str', 'core/custom_interaction_events'], }.bind(this)); // Close the popover if any other part of the page is clicked. - $('html').click(function(e) { - var target = $(e.target); + document.addEventListener('click', (e) => { + const target = e.target; + // Check if the click is outside the root element. if (!this.root.is(target) && !this.root.has(target).length) { this.closeMenu(); } - }.bind(this)); + }, true); // `true` makes it a capture phase event listener. customEvents.define(this.getContentContainer(), [ customEvents.events.scrollBottom