Proyectos de Subversion Moodle

Rev

Autoría | Ultima modificación | Ver Log |

{"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 <http://www.gnu.org/licenses/>.\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 <damyon@moodle.com>\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 = $('<img alt=\"\" src=\"' + url.imageUrl('t/expanded') + '\"/>');\n    /** @var {String} collapsedImage The html for a collapsed tree node twistie. */\n    var collapsedImage = $('<img alt=\"\" src=\"' + url.imageUrl('t/collapsed') + '\"/>');\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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"}