📄 treebasiccontrollerv3.js
字号:
/* Copyright (c) 2004-2006, The Dojo Foundation All Rights Reserved. Licensed under the Academic Free License version 2.1 or above OR the modified BSD license. For more information on Dojo licensing, see: http://dojotoolkit.org/community/licensing.shtml*/dojo.provide("dojo.widget.TreeBasicControllerV3");dojo.require("dojo.event.*");dojo.require("dojo.json")dojo.require("dojo.io.*");dojo.require("dojo.widget.TreeCommon");dojo.require("dojo.widget.TreeNodeV3");dojo.require("dojo.widget.TreeV3");dojo.widget.defineWidget( "dojo.widget.TreeBasicControllerV3", [dojo.widget.HtmlWidget, dojo.widget.TreeCommon], function(){ this.listenedTrees = {}; },{ // TODO: do something with addChild / setChild, so that RpcController become able // to hook on this and report to server // TODO: make sure keyboard control stuff works when node is moved between trees // node should be unfocus()'ed when it its ancestor is moved and tree,lastFocus - cleared /** * TreeCommon.listenTree will attach listeners to these events * * The logic behind the naming: * 1. (after|before) * 2. if an event refers to tree, then add "Tree" * 3. add action */ listenTreeEvents: ["afterSetFolder", "afterTreeCreate", "beforeTreeDestroy"], listenNodeFilter: function(elem) { return elem instanceof dojo.widget.Widget}, editor: null, initialize: function(args) { if (args.editor) { this.editor = dojo.widget.byId(args.editor); this.editor.controller = this; } }, getInfo: function(elem) { return elem.getInfo(); }, onBeforeTreeDestroy: function(message) { this.unlistenTree(message.source); }, onAfterSetFolder: function(message) { //dojo.profile.start("onTreeChange"); if (message.source.expandLevel > 0) { this.expandToLevel(message.source, message.source.expandLevel); } if (message.source.loadLevel > 0) { this.loadToLevel(message.source, message.source.loadLevel); } //dojo.profile.end("onTreeChange"); }, // down arrow _focusNextVisible: function(nodeWidget) { // if this is an expanded folder, get the first child if (nodeWidget.isFolder && nodeWidget.isExpanded && nodeWidget.children.length > 0) { returnWidget = nodeWidget.children[0]; } else { // find a parent node with a sibling while (nodeWidget.isTreeNode && nodeWidget.isLastChild()) { nodeWidget = nodeWidget.parent; } if (nodeWidget.isTreeNode) { var returnWidget = nodeWidget.parent.children[nodeWidget.getParentIndex()+1]; } } if (returnWidget && returnWidget.isTreeNode) { this._focusLabel(returnWidget); return returnWidget; } }, // up arrow _focusPreviousVisible: function(nodeWidget) { var returnWidget = nodeWidget; // if younger siblings if (!nodeWidget.isFirstChild()) { var previousSibling = nodeWidget.parent.children[nodeWidget.getParentIndex()-1] nodeWidget = previousSibling; // if the previous nodeWidget is expanded, dive in deep while (nodeWidget.isFolder && nodeWidget.isExpanded && nodeWidget.children.length > 0) { returnWidget = nodeWidget; // move to the last child nodeWidget = nodeWidget.children[nodeWidget.children.length-1]; } } else { // if this is the first child, return the parent nodeWidget = nodeWidget.parent; } if (nodeWidget && nodeWidget.isTreeNode) { returnWidget = nodeWidget; } if (returnWidget && returnWidget.isTreeNode) { this._focusLabel(returnWidget); return returnWidget; } }, // right arrow _focusZoomIn: function(nodeWidget) { var returnWidget = nodeWidget; // if not expanded, expand, else move to 1st child if (nodeWidget.isFolder && !nodeWidget.isExpanded) { this.expand(nodeWidget); }else if (nodeWidget.children.length > 0) { nodeWidget = nodeWidget.children[0]; } if (nodeWidget && nodeWidget.isTreeNode) { returnWidget = nodeWidget; } if (returnWidget && returnWidget.isTreeNode) { this._focusLabel(returnWidget); return returnWidget; } }, // left arrow _focusZoomOut: function(node) { var returnWidget = node; // if not expanded, expand, else move to 1st child if (node.isFolder && node.isExpanded) { this.collapse(node); } else { node = node.parent; } if (node && node.isTreeNode) { returnWidget = node; } if (returnWidget && returnWidget.isTreeNode) { this._focusLabel(returnWidget); return returnWidget; } }, onFocusNode: function(e) { var node = this.domElement2TreeNode(e.target); if (node) { node.viewFocus(); dojo.event.browser.stopEvent(e); } }, onBlurNode: function(e) { var node = this.domElement2TreeNode(e.target); if (!node) { return; } var labelNode = node.labelNode; labelNode.setAttribute("tabIndex", "-1"); node.viewUnfocus(); dojo.event.browser.stopEvent(e); // this could have been set to -1 by the shift+TAB processing node.tree.domNode.setAttribute("tabIndex", "0"); }, _focusLabel: function(node) { //dojo.debug((new Error()).stack) var lastFocused = node.tree.lastFocused; var labelNode; if (lastFocused && lastFocused.labelNode) { labelNode = lastFocused.labelNode; // help Opera out with blur events dojo.event.disconnect(labelNode, "onblur", this, "onBlurNode"); labelNode.setAttribute("tabIndex", "-1"); dojo.html.removeClass(labelNode, "TreeLabelFocused"); } // set tabIndex so that the tab key can find this node labelNode = node.labelNode; labelNode.setAttribute("tabIndex", "0"); node.tree.lastFocused = node; // add an outline - this helps opera a lot dojo.html.addClass(labelNode, "TreeLabelFocused"); dojo.event.connectOnce(labelNode, "onblur", this, "onBlurNode"); // prevent the domNode from seeing the focus event dojo.event.connectOnce(labelNode, "onfocus", this, "onFocusNode"); // set focus so that the label wil be voiced using screen readers labelNode.focus(); }, onKey: function(e) { if (!e.key || e.ctrkKey || e.altKey) { return; } // pretend the key was directed toward the current focused node (helps opera out) var nodeWidget = this.domElement2TreeNode(e.target); if (!nodeWidget) { return; } var treeWidget = nodeWidget.tree; if (treeWidget.lastFocused && treeWidget.lastFocused.labelNode) { nodeWidget = treeWidget.lastFocused; } switch(e.key) { case e.KEY_TAB: if (e.shiftKey) { // we're moving backwards so don't tab to the domNode // it'll be added back in onBlurNode treeWidget.domNode.setAttribute("tabIndex", "-1"); } break; case e.KEY_RIGHT_ARROW: this._focusZoomIn(nodeWidget); dojo.event.browser.stopEvent(e); break; case e.KEY_LEFT_ARROW: this._focusZoomOut(nodeWidget); dojo.event.browser.stopEvent(e); break; case e.KEY_UP_ARROW: this._focusPreviousVisible(nodeWidget); dojo.event.browser.stopEvent(e); break; case e.KEY_DOWN_ARROW: this._focusNextVisible(nodeWidget); dojo.event.browser.stopEvent(e); break; } }, onFocusTree: function(e) { if (!e.currentTarget) { return; } try { var treeWidget = this.getWidgetByNode(e.currentTarget); if (!treeWidget || !treeWidget.isTree) { return; } // on first focus, choose the root node var nodeWidget = this.getWidgetByNode(treeWidget.domNode.firstChild); if (nodeWidget && nodeWidget.isTreeNode) { if (treeWidget.lastFocused && treeWidget.lastFocused.isTreeNode) { // onClick could have chosen a non-root node nodeWidget = treeWidget.lastFocused; } this._focusLabel(nodeWidget); } } catch(e) {} }, // perform actions-initializers for tree onAfterTreeCreate: function(message) { var tree = message.source; dojo.event.browser.addListener(tree.domNode, "onKey", dojo.lang.hitch(this, this.onKey)); dojo.event.browser.addListener(tree.domNode, "onmousedown", dojo.lang.hitch(this, this.onTreeMouseDown)); dojo.event.browser.addListener(tree.domNode, "onclick", dojo.lang.hitch(this, this.onTreeClick)); dojo.event.browser.addListener(tree.domNode, "onfocus", dojo.lang.hitch(this, this.onFocusTree)); tree.domNode.setAttribute("tabIndex", "0"); if (tree.expandLevel) { this.expandToLevel(tree, tree.expandLevel) } if (tree.loadLevel) { this.loadToLevel(tree, tree.loadLevel); } }, onTreeMouseDown: function(e) { }, onTreeClick: function(e){ //dojo.profile.start("onTreeClick"); var domElement = e.target; //dojo.debug('click') // find node var node = this.domElement2TreeNode(domElement); if (!node || !node.isTreeNode) { return; } var checkExpandClick = function(el) { return el === node.expandNode; } if (this.checkPathCondition(domElement, checkExpandClick)) { this.processExpandClick(node); } this._focusLabel(node); //dojo.profile.end("onTreeClick"); }, processExpandClick: function(node){ //dojo.profile.start("processExpandClick"); if (node.isExpanded){ this.collapse(node); } else { this.expand(node); } //dojo.profile.end("processExpandClick"); }, /** * time between expand calls for batch operations * @see expandToLevel */ batchExpandTimeout: 20, expandAll: function(nodeOrTree) { return this.expandToLevel(nodeOrTree, Number.POSITIVE_INFINITY); }, collapseAll: function(nodeOrTree) { var _this = this; var filter = function(elem) { return (elem instanceof dojo.widget.Widget) && elem.isFolder && elem.isExpanded; } if (nodeOrTree.isTreeNode) { this.processDescendants(nodeOrTree, filter, this.collapse); } else if (nodeOrTree.isTree) { dojo.lang.forEach(nodeOrTree.children,function(c) { _this.processDescendants(c, filter, _this.collapse) }); } }, /** * expand tree to specific node */ expandToNode: function(node) { n = node.parent s = [] while (!n.isExpanded) { s.push(n) n = n.parent } dojo.lang.forEach(s, function(n) { n.expand() }) }, /** * walk a node in time, forward order, with pauses between expansions */ expandToLevel: function(nodeOrTree, level) { dojo.require("dojo.widget.TreeTimeoutIterator"); var _this = this; var filterFunc = function(elem) { var res = elem.isFolder || elem.children && elem.children.length; //dojo.debug("Filter "+elem+ " result:"+res); return res; }; var callFunc = function(node, iterator) { _this.expand(node, true);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -