AutorÃa | Ultima modificación | Ver Log |
/**
* Implement an accessible aria tree widget, from a nested unordered list.
* Based on http://oaa-accessibility.org/example/41/
*
* To respond to selection changed events - use tree.on("selectionchanged", handler).
* The handler will receive an array of nodes, which are the list items that are currently
* selected. (Or a single node if multiselect is disabled).
*
* @module tool_lp/tree
* @copyright 2015 Damyon Wiese <damyon@moodle.com>
* @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=$('<img alt="" src="'+url.imageUrl("t/expanded")+'"/>'),collapsedImage=$('<img alt="" src="'+url.imageUrl("t/collapsed")+'"/>'),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"),t
his.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",{sel
ected: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);lastIndex<currentIndex;)$(this.visibleItems.get(lastIndex)).attr("aria-selected","true"),lastIndex++;for(;lastIndex>currentIndex;)$(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.triggerCh
ange()}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.selectIte
m(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<this.visibleItems.length-1){var next=this.visibleItems.eq(currentIndex+1);next.focus(),e.shiftKey?this.multiSelectItem(next):hasKeyModifier||this.selectItem(next)}
return e.stopPropagation(),!1;case this.keys.asterisk:return this.parents.each((function(){thisObj.expandGroup($(this))})),e.stopPropagation(),!1;case this.keys.eight:return e.shiftKey&&(this.parents.each((function(){thisObj.expandGroup($(this))})),e.stopPropagation()),!1}return!0},Tree.prototype.handleKeyPress=function(item,e){if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey)return!0;switch(e.keyCode){case this.keys.tab:return!0;case this.keys.enter:case this.keys.home:case this.keys.end:case this.keys.left:case this.keys.right:case this.keys.up:case this.keys.down:return e.stopPropagation(),!1;default:var chr=String.fromCharCode(e.which),match=!1,itemIndex=this.visibleItems.index(item),itemCount=this.visibleItems.length,currentIndex=itemIndex+1;for(currentIndex==itemCount&&(currentIndex=0);currentIndex!=itemIndex;){var currentItem=this.visibleItems.eq(currentIndex),titleChr=currentItem.text().charAt(0);if(currentItem.has("ul")&&(titleChr=currentItem.find("span").text().charAt(0)),titleChr.toLowerCase()==chr){
match=!0;break}(currentIndex+=1)==itemCount&&(currentIndex=0)}return!0===match&&this.updateFocus(this.visibleItems.eq(currentIndex)),e.stopPropagation(),!1}return!0},Tree.prototype.on=function(eventname,handler){"selectionchanged"!==eventname?log.warning('Invalid custom event name for tree. Only "selectionchanged" is supported.'):this.treeRoot.on(eventname,handler)},Tree.prototype.handleDblClick=function(item,e){return!!(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey)||(this.updateFocus(item),this.toggleGroup(item),e.stopPropagation(),!1)},Tree.prototype.handleExpandCollapseClick=function(item,e){return this.toggleGroup(item),e.stopPropagation(),!1},Tree.prototype.handleClick=function(item,e){return e.shiftKey?this.multiSelectItem(item):e.metaKey||e.ctrlKey?this.toggleItem(item):this.selectItem(item),this.updateFocus(item),e.stopPropagation(),!1},Tree.prototype.handleBlur=function(){return!0},Tree.prototype.handleFocus=function(item){return this.updateFocus(item),!0},Tree.prototype.bindEventHandlers=function(){v
ar thisObj=this;this.parents.dblclick((function(e){return thisObj.handleDblClick($(this),e)})),this.items.click((function(e){return thisObj.handleClick($(this),e)})),this.items.children("img").click((function(e){return thisObj.handleExpandCollapseClick($(this).parent(),e)})),this.items.keydown((function(e){return thisObj.handleKeyDown($(this),e)})),this.items.keypress((function(e){return thisObj.handleKeyPress($(this),e)})),this.items.focus((function(e){return thisObj.handleFocus($(this),e)})),this.items.blur((function(e){return thisObj.handleBlur($(this),e)}))},Tree}));
//# sourceMappingURL=tree.min.js.map