From fdbcec4879a805b9497bfe8e914c585dd44fc510 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Thu, 9 Jan 2025 17:53:52 +0000 Subject: [PATCH] MDL-84147 tool_lp: fix disturbingly large icon relocating competency. --- admin/tool/lp/amd/build/tree.min.js | 2 +- admin/tool/lp/amd/build/tree.min.js.map | 2 +- admin/tool/lp/amd/src/tree.js | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/admin/tool/lp/amd/build/tree.min.js b/admin/tool/lp/amd/build/tree.min.js index d6d373a1320a0..2e2a8108861af 100644 --- a/admin/tool/lp/amd/build/tree.min.js +++ b/admin/tool/lp/amd/build/tree.min.js @@ -10,6 +10,6 @@ * @copyright 2015 Damyon Wiese * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -define("tool_lp/tree",["jquery","core/url","core/log"],(function($,url,log){var expandedImage=$(''),collapsedImage=$(''),Tree=function(selector,multiSelect){this.treeRoot=$(selector),this.multiSelect=void 0===multiSelect||!0===multiSelect,this.items=this.treeRoot.find("li"),this.expandAll=this.items.length<20,this.parents=this.treeRoot.find("li:has(ul)"),multiSelect&&this.treeRoot.attr("aria-multiselectable","true"),this.items.attr("aria-selected","false"),this.visibleItems=null,this.activeItem=null,this.lastActiveItem=null,this.keys={tab:9,enter:13,space:32,pageup:33,pagedown:34,end:35,home:36,left:37,up:38,right:39,down:40,eight:56,asterisk:106},this.init(),this.bindEventHandlers()};return Tree.prototype.init=function(){this.parents.attr("aria-expanded","true"),this.parents.prepend(expandedImage.clone()),this.items.attr("role","tree-item"),this.items.attr("tabindex","-1"),this.parents.attr("role","group"),this.treeRoot.attr("role","tree"),this.visibleItems=this.treeRoot.find("li");var thisObj=this;this.expandAll||(this.parents.each((function(){thisObj.collapseGroup($(this))})),this.expandGroup(this.parents.first()))},Tree.prototype.expandGroup=function(item){item.children("ul").show().attr("aria-hidden","false"),item.attr("aria-expanded","true"),item.children("img").attr("src",expandedImage.attr("src")),this.visibleItems=this.treeRoot.find("li:visible")},Tree.prototype.collapseGroup=function(item){item.children("ul").hide().attr("aria-hidden","true"),item.attr("aria-expanded","false"),item.children("img").attr("src",collapsedImage.attr("src")),this.visibleItems=this.treeRoot.find("li:visible")},Tree.prototype.toggleGroup=function(item){"true"==item.attr("aria-expanded")?this.collapseGroup(item):this.expandGroup(item)},Tree.prototype.triggerChange=function(){var allSelected=this.items.filter("[aria-selected=true]");this.multiSelect||(allSelected=allSelected.first()),this.treeRoot.trigger("selectionchanged",{selected:allSelected})},Tree.prototype.multiSelectItem=function(item){if(this.multiSelect){if(null!==this.lastActiveItem){for(var lastIndex=this.visibleItems.index(this.lastActiveItem),currentIndex=this.visibleItems.index(this.activeItem);lastIndexcurrentIndex;)$(this.visibleItems.get(lastIndex)).attr("aria-selected","true"),lastIndex--}}else this.items.attr("aria-selected","false");item.attr("aria-selected","true"),this.triggerChange()},Tree.prototype.selectItem=function(item){for(var walk=item.parent();"tree"!=walk.attr("role");)"false"==(walk=walk.parent()).attr("aria-expanded")&&this.expandGroup(walk),walk=walk.parent();this.items.attr("aria-selected","false"),item.attr("aria-selected","true"),this.triggerChange()},Tree.prototype.toggleItem=function(item){if(this.multiSelect){var current=item.attr("aria-selected");current="true"===current?"false":"true",item.attr("aria-selected",current),this.triggerChange()}else this.selectItem(item)},Tree.prototype.updateFocus=function(item){this.lastActiveItem=this.activeItem,this.activeItem=item;for(var walk=item.parent();"tree"!=walk.attr("role");)"false"==(walk=walk.parent()).attr("aria-expanded")&&this.expandGroup(walk),walk=walk.parent();this.items.attr("tabindex","-1"),item.attr("tabindex",0)},Tree.prototype.handleKeyDown=function(item,e){var currentIndex=this.visibleItems.index(item),newItem=null,hasKeyModifier=e.shiftKey||e.ctrlKey||e.metaKey||e.altKey,thisObj=this;switch(e.keyCode){case this.keys.home:return(newItem=this.parents.first()).focus(),e.shiftKey?this.multiSelectItem(newItem):hasKeyModifier||this.selectItem(newItem),e.stopPropagation(),!1;case this.keys.end:return(newItem=this.visibleItems.last()).focus(),e.shiftKey?this.multiSelectItem(newItem):hasKeyModifier||this.selectItem(newItem),e.stopPropagation(),!1;case this.keys.enter:case this.keys.space:return e.shiftKey?this.multiSelectItem(item):e.metaKey||e.ctrlKey?this.toggleItem(item):this.selectItem(item),e.stopPropagation(),!1;case this.keys.left:if(item.has("ul")&&"true"==item.attr("aria-expanded"))this.collapseGroup(item);else{var itemParent=item.parent().parent();itemParent.is("li")&&(itemParent.focus(),e.shiftKey?this.multiSelectItem(itemParent):hasKeyModifier||this.selectItem(itemParent))}return e.stopPropagation(),!1;case this.keys.right:return item.has("ul")&&"false"==item.attr("aria-expanded")?this.expandGroup(item):(newItem=item.children("ul").children("li").first()).length>0&&(newItem.focus(),e.shiftKey?this.multiSelectItem(newItem):hasKeyModifier||this.selectItem(newItem)),e.stopPropagation(),!1;case this.keys.up:if(currentIndex>0){var prev=this.visibleItems.eq(currentIndex-1);prev.focus(),e.shiftKey?this.multiSelectItem(prev):hasKeyModifier||this.selectItem(prev)}return e.stopPropagation(),!1;case this.keys.down:if(currentIndex'),collapsedImage=$(''),Tree=function(selector,multiSelect){this.treeRoot=$(selector),this.multiSelect=void 0===multiSelect||!0===multiSelect,this.items=this.treeRoot.find("li"),this.expandAll=this.items.length<20,this.parents=this.treeRoot.find("li:has(ul)"),multiSelect&&this.treeRoot.attr("aria-multiselectable","true"),this.items.attr("aria-selected","false"),this.visibleItems=null,this.activeItem=null,this.lastActiveItem=null,this.keys={tab:9,enter:13,space:32,pageup:33,pagedown:34,end:35,home:36,left:37,up:38,right:39,down:40,eight:56,asterisk:106},this.init(),this.bindEventHandlers()};return Tree.prototype.init=function(){this.parents.attr("aria-expanded","true"),this.parents.prepend(expandedImage.clone()),this.items.attr("role","tree-item"),this.items.attr("tabindex","-1"),this.parents.attr("role","group"),this.treeRoot.attr("role","tree"),this.visibleItems=this.treeRoot.find("li");var thisObj=this;this.expandAll||(this.parents.each((function(){thisObj.collapseGroup($(this))})),this.expandGroup(this.parents.first()))},Tree.prototype.expandGroup=function(item){item.children("ul").show().attr("aria-hidden","false"),item.attr("aria-expanded","true"),item.children("img").attr("src",expandedImage.attr("src")),this.visibleItems=this.treeRoot.find("li:visible")},Tree.prototype.collapseGroup=function(item){item.children("ul").hide().attr("aria-hidden","true"),item.attr("aria-expanded","false"),item.children("img").attr("src",collapsedImage.attr("src")),this.visibleItems=this.treeRoot.find("li:visible")},Tree.prototype.toggleGroup=function(item){"true"==item.attr("aria-expanded")?this.collapseGroup(item):this.expandGroup(item)},Tree.prototype.triggerChange=function(){var allSelected=this.items.filter("[aria-selected=true]");this.multiSelect||(allSelected=allSelected.first()),this.treeRoot.trigger("selectionchanged",{selected:allSelected})},Tree.prototype.multiSelectItem=function(item){if(this.multiSelect){if(null!==this.lastActiveItem){for(var lastIndex=this.visibleItems.index(this.lastActiveItem),currentIndex=this.visibleItems.index(this.activeItem);lastIndexcurrentIndex;)$(this.visibleItems.get(lastIndex)).attr("aria-selected","true"),lastIndex--}}else this.items.attr("aria-selected","false");item.attr("aria-selected","true"),this.triggerChange()},Tree.prototype.selectItem=function(item){for(var walk=item.parent();"tree"!=walk.attr("role");)"false"==(walk=walk.parent()).attr("aria-expanded")&&this.expandGroup(walk),walk=walk.parent();this.items.attr("aria-selected","false"),item.attr("aria-selected","true"),this.triggerChange()},Tree.prototype.toggleItem=function(item){if(this.multiSelect){var current=item.attr("aria-selected");current="true"===current?"false":"true",item.attr("aria-selected",current),this.triggerChange()}else this.selectItem(item)},Tree.prototype.updateFocus=function(item){this.lastActiveItem=this.activeItem,this.activeItem=item;for(var walk=item.parent();"tree"!=walk.attr("role");)"false"==(walk=walk.parent()).attr("aria-expanded")&&this.expandGroup(walk),walk=walk.parent();this.items.attr("tabindex","-1"),item.attr("tabindex",0)},Tree.prototype.handleKeyDown=function(item,e){var currentIndex=this.visibleItems.index(item),newItem=null,hasKeyModifier=e.shiftKey||e.ctrlKey||e.metaKey||e.altKey,thisObj=this;switch(e.keyCode){case this.keys.home:return(newItem=this.parents.first()).focus(),e.shiftKey?this.multiSelectItem(newItem):hasKeyModifier||this.selectItem(newItem),e.stopPropagation(),!1;case this.keys.end:return(newItem=this.visibleItems.last()).focus(),e.shiftKey?this.multiSelectItem(newItem):hasKeyModifier||this.selectItem(newItem),e.stopPropagation(),!1;case this.keys.enter:case this.keys.space:return e.shiftKey?this.multiSelectItem(item):e.metaKey||e.ctrlKey?this.toggleItem(item):this.selectItem(item),e.stopPropagation(),!1;case this.keys.left:if(item.has("ul")&&"true"==item.attr("aria-expanded"))this.collapseGroup(item);else{var itemParent=item.parent().parent();itemParent.is("li")&&(itemParent.focus(),e.shiftKey?this.multiSelectItem(itemParent):hasKeyModifier||this.selectItem(itemParent))}return e.stopPropagation(),!1;case this.keys.right:return item.has("ul")&&"false"==item.attr("aria-expanded")?this.expandGroup(item):(newItem=item.children("ul").children("li").first()).length>0&&(newItem.focus(),e.shiftKey?this.multiSelectItem(newItem):hasKeyModifier||this.selectItem(newItem)),e.stopPropagation(),!1;case this.keys.up:if(currentIndex>0){var prev=this.visibleItems.eq(currentIndex-1);prev.focus(),e.shiftKey?this.multiSelectItem(prev):hasKeyModifier||this.selectItem(prev)}return e.stopPropagation(),!1;case this.keys.down:if(currentIndex.\n\n/**\n * Implement an accessible aria tree widget, from a nested unordered list.\n * Based on http://oaa-accessibility.org/example/41/\n *\n * To respond to selection changed events - use tree.on(\"selectionchanged\", handler).\n * The handler will receive an array of nodes, which are the list items that are currently\n * selected. (Or a single node if multiselect is disabled).\n *\n * @module tool_lp/tree\n * @copyright 2015 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/url', 'core/log'], function($, url, log) {\n // Private variables and functions.\n /** @var {String} expandedImage The html for an expanded tree node twistie. */\n var expandedImage = $('\"\"');\n /** @var {String} collapsedImage The html for a collapsed tree node twistie. */\n var collapsedImage = $('\"\"');\n\n /**\n * Constructor\n *\n * @param {String} selector\n * @param {Boolean} multiSelect\n */\n var Tree = function(selector, multiSelect) {\n this.treeRoot = $(selector);\n this.multiSelect = (typeof multiSelect === 'undefined' || multiSelect === true);\n\n this.items = this.treeRoot.find('li');\n this.expandAll = this.items.length < 20;\n this.parents = this.treeRoot.find('li:has(ul)');\n\n if (multiSelect) {\n this.treeRoot.attr('aria-multiselectable', 'true');\n }\n\n this.items.attr('aria-selected', 'false');\n\n this.visibleItems = null;\n this.activeItem = null;\n this.lastActiveItem = null;\n\n this.keys = {\n tab: 9,\n enter: 13,\n space: 32,\n pageup: 33,\n pagedown: 34,\n end: 35,\n home: 36,\n left: 37,\n up: 38,\n right: 39,\n down: 40,\n eight: 56,\n asterisk: 106\n };\n\n this.init();\n\n this.bindEventHandlers();\n };\n // Public variables and functions.\n\n /**\n * Init this tree\n * @method init\n */\n Tree.prototype.init = function() {\n this.parents.attr('aria-expanded', 'true');\n this.parents.prepend(expandedImage.clone());\n\n this.items.attr('role', 'tree-item');\n this.items.attr('tabindex', '-1');\n this.parents.attr('role', 'group');\n this.treeRoot.attr('role', 'tree');\n\n this.visibleItems = this.treeRoot.find('li');\n\n var thisObj = this;\n if (!this.expandAll) {\n this.parents.each(function() {\n thisObj.collapseGroup($(this));\n });\n this.expandGroup(this.parents.first());\n }\n };\n\n /**\n * Expand a collapsed group.\n *\n * @method expandGroup\n * @param {Object} item is the jquery id of the parent item of the group\n */\n Tree.prototype.expandGroup = function(item) {\n // Find the first child ul node.\n var group = item.children('ul');\n\n // Expand the group.\n group.show().attr('aria-hidden', 'false');\n\n item.attr('aria-expanded', 'true');\n\n item.children('img').attr('src', expandedImage.attr('src'));\n\n // Update the list of visible items.\n this.visibleItems = this.treeRoot.find('li:visible');\n };\n\n /**\n * Collapse an expanded group.\n *\n * @method collapseGroup\n * @param {Object} item is the jquery id of the parent item of the group\n */\n Tree.prototype.collapseGroup = function(item) {\n var group = item.children('ul');\n\n // Collapse the group.\n group.hide().attr('aria-hidden', 'true');\n\n item.attr('aria-expanded', 'false');\n\n item.children('img').attr('src', collapsedImage.attr('src'));\n\n // Update the list of visible items.\n this.visibleItems = this.treeRoot.find('li:visible');\n };\n\n /**\n * Expand or collapse a group.\n *\n * @method toggleGroup\n * @param {Object} item is the jquery id of the parent item of the group\n */\n Tree.prototype.toggleGroup = function(item) {\n if (item.attr('aria-expanded') == 'true') {\n this.collapseGroup(item);\n } else {\n this.expandGroup(item);\n }\n };\n\n /**\n * Whenever the currently selected node has changed, trigger an event using this function.\n *\n * @method triggerChange\n */\n Tree.prototype.triggerChange = function() {\n var allSelected = this.items.filter('[aria-selected=true]');\n if (!this.multiSelect) {\n allSelected = allSelected.first();\n }\n this.treeRoot.trigger('selectionchanged', {selected: allSelected});\n };\n\n /**\n * Select all the items between the last focused item and this currently focused item.\n *\n * @method multiSelectItem\n * @param {Object} item is the jquery id of the newly selected item.\n */\n Tree.prototype.multiSelectItem = function(item) {\n if (!this.multiSelect) {\n this.items.attr('aria-selected', 'false');\n } else if (this.lastActiveItem !== null) {\n var lastIndex = this.visibleItems.index(this.lastActiveItem);\n var currentIndex = this.visibleItems.index(this.activeItem);\n var oneItem = null;\n\n while (lastIndex < currentIndex) {\n oneItem = $(this.visibleItems.get(lastIndex));\n oneItem.attr('aria-selected', 'true');\n lastIndex++;\n }\n while (lastIndex > currentIndex) {\n oneItem = $(this.visibleItems.get(lastIndex));\n oneItem.attr('aria-selected', 'true');\n lastIndex--;\n }\n }\n\n item.attr('aria-selected', 'true');\n this.triggerChange();\n };\n\n /**\n * Select a single item. Make sure all the parents are expanded. De-select all other items.\n *\n * @method selectItem\n * @param {Object} item is the jquery id of the newly selected item.\n */\n Tree.prototype.selectItem = function(item) {\n // Expand all nodes up the tree.\n var walk = item.parent();\n while (walk.attr('role') != 'tree') {\n walk = walk.parent();\n if (walk.attr('aria-expanded') == 'false') {\n this.expandGroup(walk);\n }\n walk = walk.parent();\n }\n this.items.attr('aria-selected', 'false');\n item.attr('aria-selected', 'true');\n this.triggerChange();\n };\n\n /**\n * Toggle the selected state for an item back and forth.\n *\n * @method toggleItem\n * @param {Object} item is the jquery id of the item to toggle.\n */\n Tree.prototype.toggleItem = function(item) {\n if (!this.multiSelect) {\n this.selectItem(item);\n return;\n }\n\n var current = item.attr('aria-selected');\n if (current === 'true') {\n current = 'false';\n } else {\n current = 'true';\n }\n item.attr('aria-selected', current);\n this.triggerChange();\n };\n\n /**\n * Set the focus to this item.\n *\n * @method updateFocus\n * @param {Object} item is the jquery id of the parent item of the group\n */\n Tree.prototype.updateFocus = function(item) {\n this.lastActiveItem = this.activeItem;\n this.activeItem = item;\n // Expand all nodes up the tree.\n var walk = item.parent();\n while (walk.attr('role') != 'tree') {\n walk = walk.parent();\n if (walk.attr('aria-expanded') == 'false') {\n this.expandGroup(walk);\n }\n walk = walk.parent();\n }\n this.items.attr('tabindex', '-1');\n item.attr('tabindex', 0);\n };\n\n /**\n * Handle a key down event - ie navigate the tree.\n *\n * @method handleKeyDown\n * @param {Object} item is the jquery id of the parent item of the group\n * @param {Event} e The event.\n * @return {Boolean}\n */\n // This function should be simplified. In the meantime..\n // eslint-disable-next-line complexity\n Tree.prototype.handleKeyDown = function(item, e) {\n var currentIndex = this.visibleItems.index(item);\n var newItem = null;\n var hasKeyModifier = e.shiftKey || e.ctrlKey || e.metaKey || e.altKey;\n var thisObj = this;\n\n switch (e.keyCode) {\n case this.keys.home: {\n // Jump to first item in tree.\n newItem = this.parents.first();\n newItem.focus();\n if (e.shiftKey) {\n this.multiSelectItem(newItem);\n } else if (!hasKeyModifier) {\n this.selectItem(newItem);\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.end: {\n // Jump to last visible item.\n newItem = this.visibleItems.last();\n newItem.focus();\n if (e.shiftKey) {\n this.multiSelectItem(newItem);\n } else if (!hasKeyModifier) {\n this.selectItem(newItem);\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.enter:\n case this.keys.space: {\n\n if (e.shiftKey) {\n this.multiSelectItem(item);\n } else if (e.metaKey || e.ctrlKey) {\n this.toggleItem(item);\n } else {\n this.selectItem(item);\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.left: {\n if (item.has('ul') && item.attr('aria-expanded') == 'true') {\n this.collapseGroup(item);\n } else {\n // Move up to the parent.\n var itemUL = item.parent();\n var itemParent = itemUL.parent();\n if (itemParent.is('li')) {\n itemParent.focus();\n if (e.shiftKey) {\n this.multiSelectItem(itemParent);\n } else if (!hasKeyModifier) {\n this.selectItem(itemParent);\n }\n }\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.right: {\n if (item.has('ul') && item.attr('aria-expanded') == 'false') {\n this.expandGroup(item);\n } else {\n // Move to the first item in the child group.\n newItem = item.children('ul').children('li').first();\n if (newItem.length > 0) {\n newItem.focus();\n if (e.shiftKey) {\n this.multiSelectItem(newItem);\n } else if (!hasKeyModifier) {\n this.selectItem(newItem);\n }\n }\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.up: {\n\n if (currentIndex > 0) {\n var prev = this.visibleItems.eq(currentIndex - 1);\n prev.focus();\n if (e.shiftKey) {\n this.multiSelectItem(prev);\n } else if (!hasKeyModifier) {\n this.selectItem(prev);\n }\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.down: {\n\n if (currentIndex < this.visibleItems.length - 1) {\n var next = this.visibleItems.eq(currentIndex + 1);\n next.focus();\n if (e.shiftKey) {\n this.multiSelectItem(next);\n } else if (!hasKeyModifier) {\n this.selectItem(next);\n }\n }\n e.stopPropagation();\n return false;\n }\n case this.keys.asterisk: {\n // Expand all groups.\n this.parents.each(function() {\n thisObj.expandGroup($(this));\n });\n\n e.stopPropagation();\n return false;\n }\n case this.keys.eight: {\n if (e.shiftKey) {\n // Expand all groups.\n this.parents.each(function() {\n thisObj.expandGroup($(this));\n });\n\n e.stopPropagation();\n }\n\n return false;\n }\n }\n\n return true;\n };\n\n /**\n * Handle a key press event - ie navigate the tree.\n *\n * @method handleKeyPress\n * @param {Object} item is the jquery id of the parent item of the group\n * @param {Event} e The event.\n * @return {Boolean}\n */\n Tree.prototype.handleKeyPress = function(item, e) {\n if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {\n // Do nothing.\n return true;\n }\n\n switch (e.keyCode) {\n case this.keys.tab: {\n return true;\n }\n case this.keys.enter:\n case this.keys.home:\n case this.keys.end:\n case this.keys.left:\n case this.keys.right:\n case this.keys.up:\n case this.keys.down: {\n e.stopPropagation();\n return false;\n }\n default : {\n var chr = String.fromCharCode(e.which);\n var match = false;\n var itemIndex = this.visibleItems.index(item);\n var itemCount = this.visibleItems.length;\n var currentIndex = itemIndex + 1;\n\n // Check if the active item was the last one on the list.\n if (currentIndex == itemCount) {\n currentIndex = 0;\n }\n\n // Iterate through the menu items (starting from the current item and wrapping) until a match is found\n // or the loop returns to the current menu item.\n while (currentIndex != itemIndex) {\n\n var currentItem = this.visibleItems.eq(currentIndex);\n var titleChr = currentItem.text().charAt(0);\n\n if (currentItem.has('ul')) {\n titleChr = currentItem.find('span').text().charAt(0);\n }\n\n if (titleChr.toLowerCase() == chr) {\n match = true;\n break;\n }\n\n currentIndex = currentIndex + 1;\n if (currentIndex == itemCount) {\n // Reached the end of the list, start again at the beginning.\n currentIndex = 0;\n }\n }\n\n if (match === true) {\n this.updateFocus(this.visibleItems.eq(currentIndex));\n }\n e.stopPropagation();\n return false;\n }\n }\n\n // eslint-disable-next-line no-unreachable\n return true;\n };\n\n /**\n * Attach an event listener to the tree.\n *\n * @method on\n * @param {String} eventname This is the name of the event to listen for. Only 'selectionchanged' is supported for now.\n * @param {Function} handler The function to call when the event is triggered.\n */\n Tree.prototype.on = function(eventname, handler) {\n if (eventname !== 'selectionchanged') {\n log.warning('Invalid custom event name for tree. Only \"selectionchanged\" is supported.');\n } else {\n this.treeRoot.on(eventname, handler);\n }\n };\n\n /**\n * Handle a double click (expand/collapse).\n *\n * @method handleDblClick\n * @param {Object} item is the jquery id of the parent item of the group\n * @param {Event} e The event.\n * @return {Boolean}\n */\n Tree.prototype.handleDblClick = function(item, e) {\n\n if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {\n // Do nothing.\n return true;\n }\n\n // Apply the focus markup.\n this.updateFocus(item);\n\n // Expand or collapse the group.\n this.toggleGroup(item);\n\n e.stopPropagation();\n return false;\n };\n\n /**\n * Handle a click (select).\n *\n * @method handleExpandCollapseClick\n * @param {Object} item is the jquery id of the parent item of the group\n * @param {Event} e The event.\n * @return {Boolean}\n */\n Tree.prototype.handleExpandCollapseClick = function(item, e) {\n\n // Do not shift the focus.\n this.toggleGroup(item);\n e.stopPropagation();\n return false;\n };\n\n\n /**\n * Handle a click (select).\n *\n * @method handleClick\n * @param {Object} item is the jquery id of the parent item of the group\n * @param {Event} e The event.\n * @return {Boolean}\n */\n Tree.prototype.handleClick = function(item, e) {\n\n if (e.shiftKey) {\n this.multiSelectItem(item);\n } else if (e.metaKey || e.ctrlKey) {\n this.toggleItem(item);\n } else {\n this.selectItem(item);\n }\n this.updateFocus(item);\n e.stopPropagation();\n return false;\n };\n\n /**\n * Handle a blur event\n *\n * @method handleBlur\n * @return {Boolean}\n */\n Tree.prototype.handleBlur = function() {\n return true;\n };\n\n /**\n * Handle a focus event\n *\n * @method handleFocus\n * @param {Object} item item is the jquery id of the parent item of the group\n * @return {Boolean}\n */\n Tree.prototype.handleFocus = function(item) {\n\n this.updateFocus(item);\n\n return true;\n };\n\n /**\n * Bind the event listeners we require.\n *\n * @method bindEventHandlers\n */\n Tree.prototype.bindEventHandlers = function() {\n var thisObj = this;\n\n // Bind a dblclick handler to the parent items.\n this.parents.dblclick(function(e) {\n return thisObj.handleDblClick($(this), e);\n });\n\n // Bind a click handler.\n this.items.click(function(e) {\n return thisObj.handleClick($(this), e);\n });\n\n // Bind a toggle handler to the expand/collapse icons.\n this.items.children('img').click(function(e) {\n return thisObj.handleExpandCollapseClick($(this).parent(), e);\n });\n\n // Bind a keydown handler.\n this.items.keydown(function(e) {\n return thisObj.handleKeyDown($(this), e);\n });\n\n // Bind a keypress handler.\n this.items.keypress(function(e) {\n return thisObj.handleKeyPress($(this), e);\n });\n\n // Bind a focus handler.\n this.items.focus(function(e) {\n return thisObj.handleFocus($(this), e);\n });\n\n // Bind a blur handler.\n this.items.blur(function(e) {\n return thisObj.handleBlur($(this), e);\n });\n\n };\n\n return /** @alias module:tool_lp/tree */ Tree;\n});\n"],"names":["define","$","url","log","expandedImage","imageUrl","collapsedImage","Tree","selector","multiSelect","treeRoot","items","this","find","expandAll","length","parents","attr","visibleItems","activeItem","lastActiveItem","keys","tab","enter","space","pageup","pagedown","end","home","left","up","right","down","eight","asterisk","init","bindEventHandlers","prototype","prepend","clone","thisObj","each","collapseGroup","expandGroup","first","item","children","show","hide","toggleGroup","triggerChange","allSelected","filter","trigger","selected","multiSelectItem","lastIndex","index","currentIndex","get","selectItem","walk","parent","toggleItem","current","updateFocus","handleKeyDown","e","newItem","hasKeyModifier","shiftKey","ctrlKey","metaKey","altKey","keyCode","focus","stopPropagation","last","has","itemParent","is","prev","eq","next","handleKeyPress","chr","String","fromCharCode","which","match","itemIndex","itemCount","currentItem","titleChr","text","charAt","toLowerCase","on","eventname","handler","warning","handleDblClick","handleExpandCollapseClick","handleClick","handleBlur","handleFocus","dblclick","click","keydown","keypress","blur"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"tree.min.js","sources":["../src/tree.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 * Implement an accessible aria tree widget, from a nested unordered list.\n * Based on http://oaa-accessibility.org/example/41/\n *\n * To respond to selection changed events - use tree.on(\"selectionchanged\", handler).\n * The handler will receive an array of nodes, which are the list items that are currently\n * selected. (Or a single node if multiselect is disabled).\n *\n * @module tool_lp/tree\n * @copyright 2015 Damyon Wiese \n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\ndefine(['jquery', 'core/url', 'core/log'], function($, url, log) {\n // Private variables and functions.\n /** @var {String} expandedImage The html for an expanded tree node twistie. */\n var expandedImage = $('\"\"');\n /** @var {String} collapsedImage The html for a collapsed tree node twistie. */\n var collapsedImage = $('\"\"');\n\n /**\n * Constructor\n *\n * @param {String} selector\n * @param {Boolean} multiSelect\n */\n var Tree = function(selector, multiSelect) {\n this.treeRoot = $(selector);\n this.multiSelect = (typeof multiSelect === 'undefined' || multiSelect === true);\n\n this.items = this.treeRoot.find('li');\n this.expandAll = this.items.length < 20;\n this.parents = this.treeRoot.find('li:has(ul)');\n\n if (multiSelect) {\n this.treeRoot.attr('aria-multiselectable', 'true');\n }\n\n this.items.attr('aria-selected', 'false');\n\n this.visibleItems = null;\n this.activeItem = null;\n this.lastActiveItem = null;\n\n this.keys = {\n tab: 9,\n enter: 13,\n space: 32,\n pageup: 33,\n pagedown: 34,\n end: 35,\n home: 36,\n left: 37,\n up: 38,\n right: 39,\n down: 40,\n eight: 56,\n asterisk: 106\n };\n\n this.init();\n\n this.bindEventHandlers();\n };\n // Public variables and functions.\n\n /**\n * Init this tree\n * @method init\n */\n Tree.prototype.init = function() {\n this.parents.attr('aria-expanded', 'true');\n this.parents.prepend(expandedImage.clone());\n\n this.items.attr('role', 'tree-item');\n this.items.attr('tabindex', '-1');\n this.parents.attr('role', 'group');\n this.treeRoot.attr('role', 'tree');\n\n this.visibleItems = this.treeRoot.find('li');\n\n var thisObj = this;\n if (!this.expandAll) {\n this.parents.each(function() {\n thisObj.collapseGroup($(this));\n });\n this.expandGroup(this.parents.first());\n }\n };\n\n /**\n * Expand a collapsed group.\n *\n * @method expandGroup\n * @param {Object} item is the jquery id of the parent item of the group\n */\n Tree.prototype.expandGroup = function(item) {\n // Find the first child ul node.\n var group = item.children('ul');\n\n // Expand the group.\n group.show().attr('aria-hidden', 'false');\n\n item.attr('aria-expanded', 'true');\n\n item.children('img').attr('src', expandedImage.attr('src'));\n\n // Update the list of visible items.\n this.visibleItems = this.treeRoot.find('li:visible');\n };\n\n /**\n * Collapse an expanded group.\n *\n * @method collapseGroup\n * @param {Object} item is the jquery id of the parent item of the group\n */\n Tree.prototype.collapseGroup = function(item) {\n var group = item.children('ul');\n\n // Collapse the group.\n group.hide().attr('aria-hidden', 'true');\n\n item.attr('aria-expanded', 'false');\n\n item.children('img').attr('src', collapsedImage.attr('src'));\n\n // Update the list of visible items.\n this.visibleItems = this.treeRoot.find('li:visible');\n };\n\n /**\n * Expand or collapse a group.\n *\n * @method toggleGroup\n * @param {Object} item is the jquery id of the parent item of the group\n */\n Tree.prototype.toggleGroup = function(item) {\n if (item.attr('aria-expanded') == 'true') {\n this.collapseGroup(item);\n } else {\n this.expandGroup(item);\n }\n };\n\n /**\n * Whenever the currently selected node has changed, trigger an event using this function.\n *\n * @method triggerChange\n */\n Tree.prototype.triggerChange = function() {\n var allSelected = this.items.filter('[aria-selected=true]');\n if (!this.multiSelect) {\n allSelected = allSelected.first();\n }\n this.treeRoot.trigger('selectionchanged', {selected: allSelected});\n };\n\n /**\n * Select all the items between the last focused item and this currently focused item.\n *\n * @method multiSelectItem\n * @param {Object} item is the jquery id of the newly selected item.\n */\n Tree.prototype.multiSelectItem = function(item) {\n if (!this.multiSelect) {\n this.items.attr('aria-selected', 'false');\n } else if (this.lastActiveItem !== null) {\n var lastIndex = this.visibleItems.index(this.lastActiveItem);\n var currentIndex = this.visibleItems.index(this.activeItem);\n var oneItem = null;\n\n while (lastIndex < currentIndex) {\n oneItem = $(this.visibleItems.get(lastIndex));\n oneItem.attr('aria-selected', 'true');\n lastIndex++;\n }\n while (lastIndex > currentIndex) {\n oneItem = $(this.visibleItems.get(lastIndex));\n oneItem.attr('aria-selected', 'true');\n lastIndex--;\n }\n }\n\n item.attr('aria-selected', 'true');\n this.triggerChange();\n };\n\n /**\n * Select a single item. Make sure all the parents are expanded. De-select all other items.\n *\n * @method selectItem\n * @param {Object} item is the jquery id of the newly selected item.\n */\n Tree.prototype.selectItem = function(item) {\n // Expand all nodes up the tree.\n var walk = item.parent();\n while (walk.attr('role') != 'tree') {\n walk = walk.parent();\n if (walk.attr('aria-expanded') == 'false') {\n this.expandGroup(walk);\n }\n walk = walk.parent();\n }\n this.items.attr('aria-selected', 'false');\n item.attr('aria-selected', 'true');\n this.triggerChange();\n };\n\n /**\n * Toggle the selected state for an item back and forth.\n *\n * @method toggleItem\n * @param {Object} item is the jquery id of the item to toggle.\n */\n Tree.prototype.toggleItem = function(item) {\n if (!this.multiSelect) {\n this.selectItem(item);\n return;\n }\n\n var current = item.attr('aria-selected');\n if (current === 'true') {\n current = 'false';\n } else {\n current = 'true';\n }\n item.attr('aria-selected', current);\n this.triggerChange();\n };\n\n /**\n * Set the focus to this item.\n *\n * @method updateFocus\n * @param {Object} item is the jquery id of the parent item of the group\n */\n Tree.prototype.updateFocus = function(item) {\n this.lastActiveItem = this.activeItem;\n this.activeItem = item;\n // Expand all nodes up the tree.\n var walk = item.parent();\n while (walk.attr('role') != 'tree') {\n walk = walk.parent();\n if (walk.attr('aria-expanded') == 'false') {\n this.expandGroup(walk);\n }\n walk = walk.parent();\n }\n this.items.attr('tabindex', '-1');\n item.attr('tabindex', 0);\n };\n\n /**\n * Handle a key down event - ie navigate the tree.\n *\n * @method handleKeyDown\n * @param {Object} item is the jquery id of the parent item of the group\n * @param {Event} e The event.\n * @return {Boolean}\n */\n // This function should be simplified. In the meantime..\n // eslint-disable-next-line complexity\n Tree.prototype.handleKeyDown = function(item, e) {\n var currentIndex = this.visibleItems.index(item);\n var newItem = null;\n var hasKeyModifier = e.shiftKey || e.ctrlKey || e.metaKey || e.altKey;\n var thisObj = this;\n\n switch (e.keyCode) {\n case this.keys.home: {\n // Jump to first item in tree.\n newItem = this.parents.first();\n newItem.focus();\n if (e.shiftKey) {\n this.multiSelectItem(newItem);\n } else if (!hasKeyModifier) {\n this.selectItem(newItem);\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.end: {\n // Jump to last visible item.\n newItem = this.visibleItems.last();\n newItem.focus();\n if (e.shiftKey) {\n this.multiSelectItem(newItem);\n } else if (!hasKeyModifier) {\n this.selectItem(newItem);\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.enter:\n case this.keys.space: {\n\n if (e.shiftKey) {\n this.multiSelectItem(item);\n } else if (e.metaKey || e.ctrlKey) {\n this.toggleItem(item);\n } else {\n this.selectItem(item);\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.left: {\n if (item.has('ul') && item.attr('aria-expanded') == 'true') {\n this.collapseGroup(item);\n } else {\n // Move up to the parent.\n var itemUL = item.parent();\n var itemParent = itemUL.parent();\n if (itemParent.is('li')) {\n itemParent.focus();\n if (e.shiftKey) {\n this.multiSelectItem(itemParent);\n } else if (!hasKeyModifier) {\n this.selectItem(itemParent);\n }\n }\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.right: {\n if (item.has('ul') && item.attr('aria-expanded') == 'false') {\n this.expandGroup(item);\n } else {\n // Move to the first item in the child group.\n newItem = item.children('ul').children('li').first();\n if (newItem.length > 0) {\n newItem.focus();\n if (e.shiftKey) {\n this.multiSelectItem(newItem);\n } else if (!hasKeyModifier) {\n this.selectItem(newItem);\n }\n }\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.up: {\n\n if (currentIndex > 0) {\n var prev = this.visibleItems.eq(currentIndex - 1);\n prev.focus();\n if (e.shiftKey) {\n this.multiSelectItem(prev);\n } else if (!hasKeyModifier) {\n this.selectItem(prev);\n }\n }\n\n e.stopPropagation();\n return false;\n }\n case this.keys.down: {\n\n if (currentIndex < this.visibleItems.length - 1) {\n var next = this.visibleItems.eq(currentIndex + 1);\n next.focus();\n if (e.shiftKey) {\n this.multiSelectItem(next);\n } else if (!hasKeyModifier) {\n this.selectItem(next);\n }\n }\n e.stopPropagation();\n return false;\n }\n case this.keys.asterisk: {\n // Expand all groups.\n this.parents.each(function() {\n thisObj.expandGroup($(this));\n });\n\n e.stopPropagation();\n return false;\n }\n case this.keys.eight: {\n if (e.shiftKey) {\n // Expand all groups.\n this.parents.each(function() {\n thisObj.expandGroup($(this));\n });\n\n e.stopPropagation();\n }\n\n return false;\n }\n }\n\n return true;\n };\n\n /**\n * Handle a key press event - ie navigate the tree.\n *\n * @method handleKeyPress\n * @param {Object} item is the jquery id of the parent item of the group\n * @param {Event} e The event.\n * @return {Boolean}\n */\n Tree.prototype.handleKeyPress = function(item, e) {\n if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {\n // Do nothing.\n return true;\n }\n\n switch (e.keyCode) {\n case this.keys.tab: {\n return true;\n }\n case this.keys.enter:\n case this.keys.home:\n case this.keys.end:\n case this.keys.left:\n case this.keys.right:\n case this.keys.up:\n case this.keys.down: {\n e.stopPropagation();\n return false;\n }\n default : {\n var chr = String.fromCharCode(e.which);\n var match = false;\n var itemIndex = this.visibleItems.index(item);\n var itemCount = this.visibleItems.length;\n var currentIndex = itemIndex + 1;\n\n // Check if the active item was the last one on the list.\n if (currentIndex == itemCount) {\n currentIndex = 0;\n }\n\n // Iterate through the menu items (starting from the current item and wrapping) until a match is found\n // or the loop returns to the current menu item.\n while (currentIndex != itemIndex) {\n\n var currentItem = this.visibleItems.eq(currentIndex);\n var titleChr = currentItem.text().charAt(0);\n\n if (currentItem.has('ul')) {\n titleChr = currentItem.find('span').text().charAt(0);\n }\n\n if (titleChr.toLowerCase() == chr) {\n match = true;\n break;\n }\n\n currentIndex = currentIndex + 1;\n if (currentIndex == itemCount) {\n // Reached the end of the list, start again at the beginning.\n currentIndex = 0;\n }\n }\n\n if (match === true) {\n this.updateFocus(this.visibleItems.eq(currentIndex));\n }\n e.stopPropagation();\n return false;\n }\n }\n\n // eslint-disable-next-line no-unreachable\n return true;\n };\n\n /**\n * Attach an event listener to the tree.\n *\n * @method on\n * @param {String} eventname This is the name of the event to listen for. Only 'selectionchanged' is supported for now.\n * @param {Function} handler The function to call when the event is triggered.\n */\n Tree.prototype.on = function(eventname, handler) {\n if (eventname !== 'selectionchanged') {\n log.warning('Invalid custom event name for tree. Only \"selectionchanged\" is supported.');\n } else {\n this.treeRoot.on(eventname, handler);\n }\n };\n\n /**\n * Handle a double click (expand/collapse).\n *\n * @method handleDblClick\n * @param {Object} item is the jquery id of the parent item of the group\n * @param {Event} e The event.\n * @return {Boolean}\n */\n Tree.prototype.handleDblClick = function(item, e) {\n\n if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) {\n // Do nothing.\n return true;\n }\n\n // Apply the focus markup.\n this.updateFocus(item);\n\n // Expand or collapse the group.\n this.toggleGroup(item);\n\n e.stopPropagation();\n return false;\n };\n\n /**\n * Handle a click (select).\n *\n * @method handleExpandCollapseClick\n * @param {Object} item is the jquery id of the parent item of the group\n * @param {Event} e The event.\n * @return {Boolean}\n */\n Tree.prototype.handleExpandCollapseClick = function(item, e) {\n\n // Do not shift the focus.\n this.toggleGroup(item);\n e.stopPropagation();\n return false;\n };\n\n\n /**\n * Handle a click (select).\n *\n * @method handleClick\n * @param {Object} item is the jquery id of the parent item of the group\n * @param {Event} e The event.\n * @return {Boolean}\n */\n Tree.prototype.handleClick = function(item, e) {\n\n if (e.shiftKey) {\n this.multiSelectItem(item);\n } else if (e.metaKey || e.ctrlKey) {\n this.toggleItem(item);\n } else {\n this.selectItem(item);\n }\n this.updateFocus(item);\n e.stopPropagation();\n return false;\n };\n\n /**\n * Handle a blur event\n *\n * @method handleBlur\n * @return {Boolean}\n */\n Tree.prototype.handleBlur = function() {\n return true;\n };\n\n /**\n * Handle a focus event\n *\n * @method handleFocus\n * @param {Object} item item is the jquery id of the parent item of the group\n * @return {Boolean}\n */\n Tree.prototype.handleFocus = function(item) {\n\n this.updateFocus(item);\n\n return true;\n };\n\n /**\n * Bind the event listeners we require.\n *\n * @method bindEventHandlers\n */\n Tree.prototype.bindEventHandlers = function() {\n var thisObj = this;\n\n // Bind a dblclick handler to the parent items.\n this.parents.dblclick(function(e) {\n return thisObj.handleDblClick($(this), e);\n });\n\n // Bind a click handler.\n this.items.click(function(e) {\n return thisObj.handleClick($(this), e);\n });\n\n // Bind a toggle handler to the expand/collapse icons.\n this.items.children('img').click(function(e) {\n return thisObj.handleExpandCollapseClick($(this).parent(), e);\n });\n\n // Bind a keydown handler.\n this.items.keydown(function(e) {\n return thisObj.handleKeyDown($(this), e);\n });\n\n // Bind a keypress handler.\n this.items.keypress(function(e) {\n return thisObj.handleKeyPress($(this), e);\n });\n\n // Bind a focus handler.\n this.items.focus(function(e) {\n return thisObj.handleFocus($(this), e);\n });\n\n // Bind a blur handler.\n this.items.blur(function(e) {\n return thisObj.handleBlur($(this), e);\n });\n\n };\n\n return /** @alias module:tool_lp/tree */ Tree;\n});\n"],"names":["define","$","url","log","expandedImage","imageUrl","collapsedImage","Tree","selector","multiSelect","treeRoot","items","this","find","expandAll","length","parents","attr","visibleItems","activeItem","lastActiveItem","keys","tab","enter","space","pageup","pagedown","end","home","left","up","right","down","eight","asterisk","init","bindEventHandlers","prototype","prepend","clone","thisObj","each","collapseGroup","expandGroup","first","item","children","show","hide","toggleGroup","triggerChange","allSelected","filter","trigger","selected","multiSelectItem","lastIndex","index","currentIndex","get","selectItem","walk","parent","toggleItem","current","updateFocus","handleKeyDown","e","newItem","hasKeyModifier","shiftKey","ctrlKey","metaKey","altKey","keyCode","focus","stopPropagation","last","has","itemParent","is","prev","eq","next","handleKeyPress","chr","String","fromCharCode","which","match","itemIndex","itemCount","currentItem","titleChr","text","charAt","toLowerCase","on","eventname","handler","warning","handleDblClick","handleExpandCollapseClick","handleClick","handleBlur","handleFocus","dblclick","click","keydown","keypress","blur"],"mappings":"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"} \ No newline at end of file diff --git a/admin/tool/lp/amd/src/tree.js b/admin/tool/lp/amd/src/tree.js index 561878bf19ed8..a74472b2c5b53 100644 --- a/admin/tool/lp/amd/src/tree.js +++ b/admin/tool/lp/amd/src/tree.js @@ -28,9 +28,9 @@ define(['jquery', 'core/url', 'core/log'], function($, url, log) { // Private variables and functions. /** @var {String} expandedImage The html for an expanded tree node twistie. */ - var expandedImage = $(''); + var expandedImage = $(''); /** @var {String} collapsedImage The html for a collapsed tree node twistie. */ - var collapsedImage = $(''); + var collapsedImage = $(''); /** * Constructor