📄 tree.js
字号:
if (this.root[fieldName] == value) return this.root; // Use 'getDescendants()' to retrieve both open and closed nodes. return this.getDescendants().find(fieldName, value); },findAll : function (fieldName, value) { // Use 'getDescendants()' to retrieve both open and closed nodes. return this.getDescendants().findAll(fieldName, value);},// Find a node within this tree by path._findByPath : function (path) { // return early for cases of referring to just root if (path == this.pathDelim) return this.root; var rootPath = this.getPath(this.root); if (path == rootPath) return this.root; var node = this.root, lastDelimPosition = 0, delimLength = this.pathDelim.length; // if the path starts with a references to root, start beyond it if (isc.startsWith(path, rootPath)) { lastDelimPosition = rootPath.length; } else if (isc.startsWith(path, this.pathDelim)) { lastDelimPosition += delimLength; } //this.logWarn("path: " + path); while (true) { var delimPosition = path.indexOf(this.pathDelim, lastDelimPosition); //this.logWarn("delimPosition: " + delimPosition); // skip over two delims in a row (eg "//") and trailing (single) delimeter if (delimPosition == lastDelimPosition) { //this.logWarn("extra delimeter at: " + delimPosition); lastDelimPosition++; continue; } var moreDelims = (delimPosition != -1), // name of the child to look for at this level name = path.substring(lastDelimPosition, moreDelims ? delimPosition : path.length), // find the node number of that child nodeNum = this.findChildNum(node, name); //this.logWarn("name: " + name); if (nodeNum == -1) return null; node = node[this.childrenProperty][nodeNum]; // if there are no more delimeters we're done if (!moreDelims) return node; // advance the lastDelimiter lastDelimPosition = delimPosition + delimLength; // if we got all the way to the end of the path, we're done: return the node if (lastDelimPosition == path.length) return node; }},//> @method tree.findChildNum() (A)// @group location // Given a parent and the name of a child, return the number of that child.//// Note: names of folder nodes will have pathDelim stuck to the end//// @param parent (TreeNode) parent node// @param name (string) name of the child node to find// @return (number) index number of the child, -1 if not found//<findChildNum : function (parent, name) { var children = this.getChildren(parent); if (children == null) return -1; if (name == null) return -1; var length = children.getLength(), nameHasDelim = isc.endsWith(name, this.pathDelim), delimLength = this.pathDelim.length ; for (var i = 0; i < length; i++) { var childName = this.getName(children.get(i)), lengthDiff = childName.length - name.length; if (lengthDiff == 0 && childName == name) return i; if (lengthDiff == delimLength) { // match if childName has trailing delim and name does not if (isc.startsWith(childName, name) && isc.endsWith(childName, this.pathDelim) && !nameHasDelim) { return i; } } else if (nameHasDelim && lengthDiff == -delimLength) { // match if name has trailing delim and childName does not if (isc.startsWith(name, childName)) return i; } } // not found, return -1 return -1;},//> @method tree.getChildren()//// Returns all children of a node. If the node is a leaf, this method returns null.// <br><br>// For load on demand trees (those that only have a partial representation client-side), this// method will return only nodes that have already been loaded from the server. Furthermore,// for databound trees the return value will be a +link{class:ResultSet},// so it's important to access the return value using the +link{interface:List} interface// instead of as a native Javascript Array.//// @param node (TreeNode) The node whose children you want to fetch.// @return (List) List of children for the node (empty List if node is a leaf// or has no children)//// @visibility external//<getChildren : function (parentNode, displayNodeType, normalizer, sortDirection, criteria, context) { if (parentNode == null) parentNode = this.root; // if we're passed a leaf, it has no children, return empty array if (this.isLeaf(parentNode)) return null; // if the parentNode doesn't have a child array, create one if (parentNode[this.childrenProperty] == null) { var children = []; parentNode[this.childrenProperty] = children; // just return the new empty children array return children; } var list = parentNode[this.childrenProperty], subset; // if a criteria was passed in, remove all items that don't pass the criteria if (criteria) { subset = []; for (var i = 0, length = list.length; i < length; i++) { var childNode = list[i]; // CALLBACK API: available variables: "node,parent,tree" if (this.fireCallback(criteria, "node,parent,tree", [childNode, parentNode, this])) subset[subset.length] = childNode; } list = subset; } // reduce the list if a displayNodeType was specified // // if only folders were specified, get the subset that are folders if (displayNodeType == isc.Tree.FOLDERS_ONLY) { subset = []; for (var i = 0, length = list.length; i < length; i++) { if (this.isFolder(list[i])) subset[subset.length] = list[i]; } // if only leaves were specified, get the subset that are leaves } else if (displayNodeType == isc.Tree.LEAVES_ONLY) { subset = []; for (var i = 0, length = list.length; i < length; i++) { if (this.isLeaf(list[i])) subset[subset.length] = list[i]; } // otherwise return the entire list (folders and leaves) } else { subset = list; } // if a normalizer is specified, sort before returning if (normalizer) { subset.sortByProperty(this.sortProp, sortDirection, normalizer, context); } return subset;},//> @method tree.getFolders()//// Returns all the first-level folders of a node.// <br><br>// For load on demand trees (those that only have a partial representation client-side), this// method will return only nodes that have already been loaded from the server. Furthermore,// for databound trees the return value will be a +link{class:ResultSet},// so it's important to access the return value using the +link{interface:List} interface// instead of as a native Javascript Array.//// @param node (TreeNode) node in question// @return (List) List of immediate children that are folders//// @visibility external//<getFolders : function (node, normalizer, sortDirection, criteria, context) { return this.getChildren(node, isc.Tree.FOLDERS_ONLY, normalizer, sortDirection, criteria, context);},//> @method tree.getLeaves()//// Return all the first-level leaves of a node.// <br><br>// For load on demand trees (those that only have a partial representation client-side), this// method will return only nodes that have already been loaded from the server. Furthermore,// for databound trees the return value will be a +link{class:ResultSet},// so it's important to access the return value using the +link{interface:List} interface// instead of as a native Javascript Array.//// @param node (TreeNode) node in question// @return (List) List of immediate children that are leaves.//// @visibility external//<getLeaves : function (node, normalizer, sortDirection, criteria, context) { return this.getChildren(node, isc.Tree.LEAVES_ONLY, normalizer, sortDirection, criteria, context);},//> @method tree.hasChildren()//// Returns true if this node has any children.//// @param node (TreeNode) node in question// @return (boolean) true if the node has children//// @visibility external//<hasChildren : function (node, displayNodeType) { var children = this.getChildren(node, displayNodeType); return children && children.length > 0;},//> @method tree.hasFolders()//// Return true if this this node has any children that are folders.//// @param node (TreeNode) node in question// @return (boolean) true if the node has children that are folders//// @visibility external//<hasFolders : function (node) { return this.hasChildren(node, isc.Tree.FOLDERS_ONLY);},//> @method tree.hasLeaves()//// Return whether this node has any children that are leaves.//// @param node (TreeNode) node in question// @return (boolean) true fi the node has children that are leaves//// @visibility external//<hasLeaves : function (node) { return this.hasChildren(node, isc.Tree.LEAVES_ONLY);},//> @method tree.isDescendantOf()// Is one node a descendant of the other?//// @param child (TreeNode) child node// @param parent (TreeNode) parent node// @return (boolean) true == parent is an ancestor of child// @visibility external//<isDescendantOf : function (child, parent) { if (child == parent) return false; var nextParent = child; while (nextParent != null) { if (nextParent == parent) return true; nextParent = nextParent[this.parentProperty]; } return false;},//> @method tree.getDescendants()//// Returns the list of all descendants of a node. Note: this method can be very slow,// especially on large trees because it assembles a list of all descendants recursively.// Generally, +link{method:Tree.find} in combination with +link{method:Tree.getChildren} will// be much faster.// <br><br>// For load on demand trees (those that only have a partial representation client-side), this// method will return only nodes that have already been loaded from the server. Furthermore,// for databound trees the return value will be a +link{class:ResultSet},// so it's important to access the return value using the +link{interface:List} interface// instead of as a native Javascript Array.//// @param [node] (TreeNode) node in question (the root node is asumed if none specified)// @return (List) List of descendants of the node.//// @visibility external//<getDescendants : function (node, displayNodeType, condition) { if (!node) node = this.root; // create an array to hold the descendants var list = []; // if condition wasn't passed in, set it to an always true condition // XXX convert this to a function if a string, similar to getChildren() if (!condition) condition = function(){return true}; // if the node is a leaf, return the empty list if (this.isLeaf(node)) return list; // iterate through all the children of the node // Note that this can't depend on getChildren() to subset the nodes, // because a folder may have children that meet the criteria but not meet the criteria itself. var children = this.getChildren(node); if (!children) return list; // for each child for (var i = 0, length = children.length, child; i < length; i++) { // get a pointer to the child child = children[i]; // if that child is a folder if (this.isFolder(child)) { // if we're not exluding folders, add the child if (displayNodeType != isc.Tree.LEAVES_ONLY && condition(child)) list[list.length] = child; // now concatenate the list with the descendants of the child list = list.concat(this.getDescendants(child, displayNodeType, condition)); } else { // if we're not excluding leaves, add the leaf to the list if (displayNodeType != isc.Tree.FOLDERS_ONLY && condition(child)) { list[list.length] = child; } } } // finally, return the entire list return list;},//> @method tree.getDescendantFolders()//// Ruturns the list of all descendants of a node that are folders. This works just like// +link{method:Tree.getDescendants}, except leaf nodes are not part of the returned list.// Like +link{method:Tree.getDescendants}, this method can be very slow for large trees.// Generally, +link{method:Tree.find} in combination with +link{method:Tree.getFolders} // be much faster.// <br><br>// For load on demand trees (those that only have a partial representation client-side), this// method wi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -