a:112:{s:9:"#provides";s:10:"dijit.Tree";s:9:"#resource";s:7:"Tree.js";s:9:"#requires";a:8:{i:0;a:3:{i:0;s:6:"common";i:1;s:7:"dojo.fx";i:2;s:4:"dojo";}i:1;a:2:{i:0;s:6:"common";i:1;s:13:"dijit._Widget";}i:2;a:2:{i:0;s:6:"common";i:1;s:16:"dijit._Templated";}i:3;a:2:{i:0;s:6:"common";i:1;s:16:"dijit._Container";}i:4;a:2:{i:0;s:6:"common";i:1;s:16:"dijit._Contained";}i:5;a:3:{i:0;s:6:"common";i:1;s:11:"dojo.cookie";i:2;s:4:"dojo";}i:6;a:2:{i:0;s:6:"common";i:1;s:25:"dijit.tree.TreeStoreModel";}i:7;a:2:{i:0;s:6:"common";i:1;s:27:"dijit.tree.ForestStoreModel";}}s:15:"dijit._TreeNode";a:5:{s:4:"type";s:8:"Function";s:6:"chains";a:2:{s:9:"prototype";a:1:{i:0;s:13:"dijit._Widget";}s:4:"call";a:4:{i:0;s:13:"dijit._Widget";i:1;s:16:"dijit._Templated";i:2;s:16:"dijit._Container";i:3;s:16:"dijit._Contained";}}s:6:"mixins";a:1:{s:9:"prototype";a:3:{i:0;s:26:"dijit._Templated.prototype";i:1;s:26:"dijit._Container.prototype";i:2;s:26:"dijit._Contained.prototype";}}s:7:"summary";s:117:"Single node within a tree. This class is used internally
by Tree and should not be accessed directly.
tags:
private";s:9:"classlike";b:1;}s:20:"dijit._TreeNode.item";a:3:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:14:"dojo.data.Item";s:7:"summary";s:40:"the dojo.data entry this tree represents";}s:26:"dijit._TreeNode.isTreeNode";a:4:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"tags";a:1:{i:0;s:9:"protected";}s:4:"type";s:7:"Boolean";s:7:"summary";s:96:"Indicates that this is a TreeNode. Used by `dijit.Tree` only,
should not be accessed directly.";}s:21:"dijit._TreeNode.label";a:3:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:6:"String";s:7:"summary";s:22:"Text of this tree node";}s:28:"dijit._TreeNode.isExpandable";a:5:{s:9:"prototype";s:15:"dijit._TreeNode";s:8:"instance";s:15:"dijit._TreeNode";s:4:"tags";a:1:{i:0;s:7:"private";}s:4:"type";s:7:"Boolean";s:7:"summary";s:57:"This node has children, so show the expando node (+ sign)";}s:26:"dijit._TreeNode.isExpanded";a:5:{s:9:"prototype";s:15:"dijit._TreeNode";s:8:"instance";s:15:"dijit._TreeNode";s:4:"tags";a:1:{i:0;s:8:"readonly";}s:4:"type";s:7:"Boolean";s:7:"summary";s:44:"This node is currently expanded (ie, opened)";}s:21:"dijit._TreeNode.state";a:5:{s:9:"prototype";s:15:"dijit._TreeNode";s:8:"instance";s:15:"dijit._TreeNode";s:4:"tags";a:1:{i:0;s:7:"private";}s:4:"type";s:6:"String";s:7:"summary";s:190:"Dynamic loading-related stuff.
When an empty folder node appears, it is "UNCHECKED" first,
then after dojo.data query it becomes "LOADING" and, finally "LOADED"";}s:28:"dijit._TreeNode.templatePath";a:2:{s:9:"prototype";s:15:"dijit._TreeNode";s:7:"summary";s:0:"";}s:26:"dijit._TreeNode.postCreate";a:4:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:6:"source";s:1770:"dojo.provide("dijit.Tree");
dojo.require("dojo.fx");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit._Container");
dojo.require("dijit._Contained");
dojo.require("dojo.cookie");
dojo.declare(
"dijit._TreeNode",
[dijit._Widget, dijit._Templated, dijit._Container, dijit._Contained],
{
// summary:
// Single node within a tree. This class is used internally
// by Tree and should not be accessed directly.
// tags:
// private
// item: dojo.data.Item
// the dojo.data entry this tree represents
item: null,
// isTreeNode: [protected] Boolean
// Indicates that this is a TreeNode. Used by `dijit.Tree` only,
// should not be accessed directly.
isTreeNode: true,
// label: String
// Text of this tree node
label: "",
// isExpandable: [private] Boolean
// This node has children, so show the expando node (+ sign)
isExpandable: null,
// isExpanded: [readonly] Boolean
// This node is currently expanded (ie, opened)
isExpanded: false,
// state: [private] String
// Dynamic loading-related stuff.
// When an empty folder node appears, it is "UNCHECKED" first,
// then after dojo.data query it becomes "LOADING" and, finally "LOADED"
state: "UNCHECKED",
templatePath: dojo.moduleUrl("dijit", "templates/TreeNode.html"),
postCreate: function(){
// set label, escaping special characters
this.setLabelNode(this.label);
// set expand icon for leaf
this._setExpando();
// set icon and label class based on item
this._updateItemClasses(this.item);
if(this.isExpandable){
dijit.setWaiState(this.labelNode, "expanded", this.isExpanded);
if(this == this.tree.rootNode){
dijit.setWaitState(this.tree.domNode, "expanded", this.isExpanded);
}
} ";s:7:"summary";s:0:"";}s:30:"dijit._TreeNode._setIndentAttr";a:7:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:6:"indent";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:517:" this.indent = indent;
// Math.max() is to prevent negative padding on hidden root node (when indent == -1)
// 19 is the width of the expandoIcon (TODO: get this from CSS instead of hardcoding)
var pixels = (Math.max(indent, 0) * 19) + "px";
dojo.style(this.domNode, "backgroundPosition", pixels + " 0px");
dojo.style(this.rowNode, dojo._isBodyLtr() ? "paddingLeft" : "paddingRight", pixels);
dojo.forEach(this.getChildren(), function(child){
child.attr("indent", indent+1);
});";s:7:"summary";s:52:"Tell this node how many levels it should be indented";s:11:"description";s:76:"0 for top level nodes, 1 for their children, 2 for their
grandchildren, etc.";s:7:"private";b:1;}s:30:"dijit._TreeNode.markProcessing";a:5:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:6:"source";s:52:" this.state = "LOADING";
this._setExpando(true); ";s:7:"summary";s:47:"Visually denote that tree is loading data, etc.";s:4:"tags";s:7:"private";}s:32:"dijit._TreeNode.unmarkProcessing";a:5:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:6:"source";s:27:" this._setExpando(false); ";s:7:"summary";s:39:"Clear markup from markProcessing() call";s:4:"tags";s:7:"private";}s:34:"dijit._TreeNode._updateItemClasses";a:7:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"item";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:807:" var tree = this.tree, model = tree.model;
if(tree._v10Compat && item === model.root){
// For back-compat with 1.0, need to use null to specify root item (TODO: remove in 2.0)
item = null;
}
if(this._iconClass){
dojo.removeClass(this.iconNode, this._iconClass);
}
this._iconClass = tree.getIconClass(item, this.isExpanded);
if(this._iconClass){
dojo.addClass(this.iconNode, this._iconClass);
}
dojo.style(this.iconNode, tree.getIconStyle(item, this.isExpanded) || {});
if(this._labelClass){
dojo.removeClass(this.labelNode, this._labelClass);
}
this._labelClass = tree.getLabelClass(item, this.isExpanded);
if(this._labelClass){
dojo.addClass(this.labelNode, this._labelClass);
}
dojo.style(this.labelNode, tree.getLabelStyle(item, this.isExpanded) || {});";s:7:"summary";s:113:"Set appropriate CSS classes for icon and label dom node
(used to allow for item updates to change respective CSS)";s:4:"tags";s:7:"private";s:7:"private";b:1;}s:29:"dijit._TreeNode._updateLayout";a:6:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:6:"source";s:327:" var parent = this.getParent();
if(!parent || parent.rowNode.style.display == "none"){
/* if we are hiding the root node then make every first level child look like a root node */
dojo.addClass(this.domNode, "dijitTreeIsRoot");
}else{
dojo.toggleClass(this.domNode, "dijitTreeIsLast", !this.getNextSibling());
}";s:7:"summary";s:44:"Set appropriate CSS classes for this.domNode";s:4:"tags";s:7:"private";s:7:"private";b:1;}s:27:"dijit._TreeNode._setExpando";a:6:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:10:"processing";a:1:{s:4:"type";s:7:"Boolean";}}s:6:"source";s:5013:"dojo.provide("dijit.Tree");
dojo.require("dojo.fx");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit._Container");
dojo.require("dijit._Contained");
dojo.require("dojo.cookie");
dojo.declare(
"dijit._TreeNode",
[dijit._Widget, dijit._Templated, dijit._Container, dijit._Contained],
{
// summary:
// Single node within a tree. This class is used internally
// by Tree and should not be accessed directly.
// tags:
// private
// item: dojo.data.Item
// the dojo.data entry this tree represents
item: null,
// isTreeNode: [protected] Boolean
// Indicates that this is a TreeNode. Used by `dijit.Tree` only,
// should not be accessed directly.
isTreeNode: true,
// label: String
// Text of this tree node
label: "",
// isExpandable: [private] Boolean
// This node has children, so show the expando node (+ sign)
isExpandable: null,
// isExpanded: [readonly] Boolean
// This node is currently expanded (ie, opened)
isExpanded: false,
// state: [private] String
// Dynamic loading-related stuff.
// When an empty folder node appears, it is "UNCHECKED" first,
// then after dojo.data query it becomes "LOADING" and, finally "LOADED"
state: "UNCHECKED",
templatePath: dojo.moduleUrl("dijit", "templates/TreeNode.html"),
postCreate: function(){
// set label, escaping special characters
this.setLabelNode(this.label);
// set expand icon for leaf
this._setExpando();
// set icon and label class based on item
this._updateItemClasses(this.item);
if(this.isExpandable){
dijit.setWaiState(this.labelNode, "expanded", this.isExpanded);
if(this == this.tree.rootNode){
dijit.setWaitState(this.tree.domNode, "expanded", this.isExpanded);
}
}
},
_setIndentAttr: function(indent){
// summary:
// Tell this node how many levels it should be indented
// description:
// 0 for top level nodes, 1 for their children, 2 for their
// grandchildren, etc.
this.indent = indent;
// Math.max() is to prevent negative padding on hidden root node (when indent == -1)
// 19 is the width of the expandoIcon (TODO: get this from CSS instead of hardcoding)
var pixels = (Math.max(indent, 0) * 19) + "px";
dojo.style(this.domNode, "backgroundPosition", pixels + " 0px");
dojo.style(this.rowNode, dojo._isBodyLtr() ? "paddingLeft" : "paddingRight", pixels);
dojo.forEach(this.getChildren(), function(child){
child.attr("indent", indent+1);
});
},
markProcessing: function(){
// summary:
// Visually denote that tree is loading data, etc.
// tags:
// private
this.state = "LOADING";
this._setExpando(true);
},
unmarkProcessing: function(){
// summary:
// Clear markup from markProcessing() call
// tags:
// private
this._setExpando(false);
},
_updateItemClasses: function(item){
// summary:
// Set appropriate CSS classes for icon and label dom node
// (used to allow for item updates to change respective CSS)
// tags:
// private
var tree = this.tree, model = tree.model;
if(tree._v10Compat && item === model.root){
// For back-compat with 1.0, need to use null to specify root item (TODO: remove in 2.0)
item = null;
}
if(this._iconClass){
dojo.removeClass(this.iconNode, this._iconClass);
}
this._iconClass = tree.getIconClass(item, this.isExpanded);
if(this._iconClass){
dojo.addClass(this.iconNode, this._iconClass);
}
dojo.style(this.iconNode, tree.getIconStyle(item, this.isExpanded) || {});
if(this._labelClass){
dojo.removeClass(this.labelNode, this._labelClass);
}
this._labelClass = tree.getLabelClass(item, this.isExpanded);
if(this._labelClass){
dojo.addClass(this.labelNode, this._labelClass);
}
dojo.style(this.labelNode, tree.getLabelStyle(item, this.isExpanded) || {});
},
_updateLayout: function(){
// summary:
// Set appropriate CSS classes for this.domNode
// tags:
// private
var parent = this.getParent();
if(!parent || parent.rowNode.style.display == "none"){
/* if we are hiding the root node then make every first level child look like a root node */
dojo.addClass(this.domNode, "dijitTreeIsRoot");
}else{
dojo.toggleClass(this.domNode, "dijitTreeIsLast", !this.getNextSibling());
}
},
_setExpando: function(/*Boolean*/ processing){
// summary:
// Set the right image for the expando node
// tags:
// private
// apply the appropriate class to the expando node
var styles = ["dijitTreeExpandoLoading", "dijitTreeExpandoOpened",
"dijitTreeExpandoClosed", "dijitTreeExpandoLeaf"];
var _a11yStates = ["*","-","+","*"];
var idx = processing ? 0 : (this.isExpandable ? (this.isExpanded ? 1 : 2) : 3);
dojo.forEach(styles,
function(s){
dojo.removeClass(this.expandoNode, s);
}, this
);
dojo.addClass(this.expandoNode, styles[idx]);
// provide a non-image based indicator for images-off mode
this.expandoNodeText.innerHTML = _a11yStates[idx];";s:7:"summary";s:40:"Set the right image for the expando node";s:7:"private";b:1;}s:22:"dijit._TreeNode.expand";a:4:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:6:"source";s:627:" if(this.isExpanded){ return; }
// cancel in progress collapse operation
this._wipeOut && this._wipeOut.stop();
this.isExpanded = true;
dijit.setWaiState(this.labelNode, "expanded", "true");
dijit.setWaiRole(this.containerNode, "group");
dojo.addClass(this.contentNode,'dijitTreeContentExpanded');
this._setExpando();
this._updateItemClasses(this.item);
if(this == this.tree.rootNode){
dijit.setWaiState(this.tree.domNode, "expanded", "true");
}
if(!this._wipeIn){
this._wipeIn = dojo.fx.wipeIn({
node: this.containerNode, duration: dijit.defaultDuration
});
}
this._wipeIn.play();";s:7:"summary";s:16:"Show my children";}s:24:"dijit._TreeNode.collapse";a:4:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:6:"source";s:585:" if(!this.isExpanded){ return; }
// cancel in progress expand operation
this._wipeIn && this._wipeIn.stop();
this.isExpanded = false;
dijit.setWaiState(this.labelNode, "expanded", "false");
if(this == this.tree.rootNode){
dijit.setWaiState(this.tree.domNode, "expanded", "false");
}
dojo.removeClass(this.contentNode,'dijitTreeContentExpanded');
this._setExpando();
this._updateItemClasses(this.item);
if(!this._wipeOut){
this._wipeOut = dojo.fx.wipeOut({
node: this.containerNode, duration: dijit.defaultDuration
});
}
this._wipeOut.play();";s:7:"summary";s:37:"Collapse this node (if it's expanded)";}s:28:"dijit._TreeNode.setLabelNode";a:5:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:5:"label";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:94:" this.labelNode.innerHTML = "";
this.labelNode.appendChild(dojo.doc.createTextNode(label));";s:7:"summary";s:14:"Sets the label";}s:22:"dijit._TreeNode.indent";a:4:{s:9:"prototype";s:15:"dijit._TreeNode";s:8:"instance";s:15:"dijit._TreeNode";s:4:"type";s:7:"Integer";s:7:"summary";s:38:"Levels from this node to the root node";}s:29:"dijit._TreeNode.setChildItems";a:6:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:5:"items";a:1:{s:4:"type";s:8:"Object[]";}}s:6:"source";s:2152:" var tree = this.tree,
model = tree.model;
// Orphan all my existing children.
// If items contains some of the same items as before then we will reattach them.
// Don't call this.removeChild() because that will collapse the tree etc.
this.getChildren().forEach(function(child){
dijit._Container.prototype.removeChild.call(this, child);
}, this);
this.state = "LOADED";
if(items && items.length > 0){
this.isExpandable = true;
// Create _TreeNode widget for each specified tree node, unless one already
// exists and isn't being used (presumably it's from a DnD move and was recently
// released
dojo.forEach(items, function(item){
var id = model.getIdentity(item),
existingNode = tree._itemNodeMap[id],
node =
( existingNode && !existingNode.getParent() ) ?
existingNode :
this.tree._createTreeNode({
item: item,
tree: tree,
isExpandable: model.mayHaveChildren(item),
label: tree.getLabel(item),
indent: this.indent + 1
});
if(existingNode){
existingNode.attr('indent', this.indent+1);
}
this.addChild(node);
// note: this won't work if there are two nodes for one item (multi-parented items); will be fixed later
tree._itemNodeMap[id] = node;
if(this.tree._state(item)){
tree._expandNode(node);
}
}, this);
// note that updateLayout() needs to be called on each child after
// _all_ the children exist
dojo.forEach(this.getChildren(), function(child, idx){
child._updateLayout();
});
}else{
this.isExpandable=false;
}
if(this._setExpando){
// change expando to/from dot or + icon, as appropriate
this._setExpando(false);
}
// On initial tree show, make the selected TreeNode as either the root node of the tree,
// or the first child, if the root node is hidden
if(this == tree.rootNode){
var fc = this.tree.showRoot ? this : this.getChildren()[0];
if(fc){
fc.setSelected(true);
tree.lastFocused = fc;
}else{
// fallback: no nodes in tree so focus on Tree
itself
tree.domNode.setAttribute("tabIndex", "0");
}
}";s:7:"summary";s:112:"Sets the child items of this node, removing/adding nodes
from current children to match specified items[] array.";s:6:"chains";a:1:{s:4:"call";a:1:{i:0;s:38:"dijit._Container.prototype.removeChild";}}}s:27:"dijit._TreeNode.removeChild";a:5:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"node";a:1:{s:4:"type";s:8:"treeNode";}}s:6:"source";s:228:" this.inherited(arguments);
var children = this.getChildren();
if(children.length == 0){
this.isExpandable = false;
this.collapse();
}
dojo.forEach(children, function(child){
child._updateLayout();
});";s:7:"summary";s:0:"";}s:30:"dijit._TreeNode.makeExpandable";a:4:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:6:"source";s:9549:"dojo.provide("dijit.Tree");
dojo.require("dojo.fx");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit._Container");
dojo.require("dijit._Contained");
dojo.require("dojo.cookie");
dojo.declare(
"dijit._TreeNode",
[dijit._Widget, dijit._Templated, dijit._Container, dijit._Contained],
{
// summary:
// Single node within a tree. This class is used internally
// by Tree and should not be accessed directly.
// tags:
// private
// item: dojo.data.Item
// the dojo.data entry this tree represents
item: null,
// isTreeNode: [protected] Boolean
// Indicates that this is a TreeNode. Used by `dijit.Tree` only,
// should not be accessed directly.
isTreeNode: true,
// label: String
// Text of this tree node
label: "",
// isExpandable: [private] Boolean
// This node has children, so show the expando node (+ sign)
isExpandable: null,
// isExpanded: [readonly] Boolean
// This node is currently expanded (ie, opened)
isExpanded: false,
// state: [private] String
// Dynamic loading-related stuff.
// When an empty folder node appears, it is "UNCHECKED" first,
// then after dojo.data query it becomes "LOADING" and, finally "LOADED"
state: "UNCHECKED",
templatePath: dojo.moduleUrl("dijit", "templates/TreeNode.html"),
postCreate: function(){
// set label, escaping special characters
this.setLabelNode(this.label);
// set expand icon for leaf
this._setExpando();
// set icon and label class based on item
this._updateItemClasses(this.item);
if(this.isExpandable){
dijit.setWaiState(this.labelNode, "expanded", this.isExpanded);
if(this == this.tree.rootNode){
dijit.setWaitState(this.tree.domNode, "expanded", this.isExpanded);
}
}
},
_setIndentAttr: function(indent){
// summary:
// Tell this node how many levels it should be indented
// description:
// 0 for top level nodes, 1 for their children, 2 for their
// grandchildren, etc.
this.indent = indent;
// Math.max() is to prevent negative padding on hidden root node (when indent == -1)
// 19 is the width of the expandoIcon (TODO: get this from CSS instead of hardcoding)
var pixels = (Math.max(indent, 0) * 19) + "px";
dojo.style(this.domNode, "backgroundPosition", pixels + " 0px");
dojo.style(this.rowNode, dojo._isBodyLtr() ? "paddingLeft" : "paddingRight", pixels);
dojo.forEach(this.getChildren(), function(child){
child.attr("indent", indent+1);
});
},
markProcessing: function(){
// summary:
// Visually denote that tree is loading data, etc.
// tags:
// private
this.state = "LOADING";
this._setExpando(true);
},
unmarkProcessing: function(){
// summary:
// Clear markup from markProcessing() call
// tags:
// private
this._setExpando(false);
},
_updateItemClasses: function(item){
// summary:
// Set appropriate CSS classes for icon and label dom node
// (used to allow for item updates to change respective CSS)
// tags:
// private
var tree = this.tree, model = tree.model;
if(tree._v10Compat && item === model.root){
// For back-compat with 1.0, need to use null to specify root item (TODO: remove in 2.0)
item = null;
}
if(this._iconClass){
dojo.removeClass(this.iconNode, this._iconClass);
}
this._iconClass = tree.getIconClass(item, this.isExpanded);
if(this._iconClass){
dojo.addClass(this.iconNode, this._iconClass);
}
dojo.style(this.iconNode, tree.getIconStyle(item, this.isExpanded) || {});
if(this._labelClass){
dojo.removeClass(this.labelNode, this._labelClass);
}
this._labelClass = tree.getLabelClass(item, this.isExpanded);
if(this._labelClass){
dojo.addClass(this.labelNode, this._labelClass);
}
dojo.style(this.labelNode, tree.getLabelStyle(item, this.isExpanded) || {});
},
_updateLayout: function(){
// summary:
// Set appropriate CSS classes for this.domNode
// tags:
// private
var parent = this.getParent();
if(!parent || parent.rowNode.style.display == "none"){
/* if we are hiding the root node then make every first level child look like a root node */
dojo.addClass(this.domNode, "dijitTreeIsRoot");
}else{
dojo.toggleClass(this.domNode, "dijitTreeIsLast", !this.getNextSibling());
}
},
_setExpando: function(/*Boolean*/ processing){
// summary:
// Set the right image for the expando node
// tags:
// private
// apply the appropriate class to the expando node
var styles = ["dijitTreeExpandoLoading", "dijitTreeExpandoOpened",
"dijitTreeExpandoClosed", "dijitTreeExpandoLeaf"];
var _a11yStates = ["*","-","+","*"];
var idx = processing ? 0 : (this.isExpandable ? (this.isExpanded ? 1 : 2) : 3);
dojo.forEach(styles,
function(s){
dojo.removeClass(this.expandoNode, s);
}, this
);
dojo.addClass(this.expandoNode, styles[idx]);
// provide a non-image based indicator for images-off mode
this.expandoNodeText.innerHTML = _a11yStates[idx];
},
expand: function(){
// summary:
// Show my children
if(this.isExpanded){ return; }
// cancel in progress collapse operation
this._wipeOut && this._wipeOut.stop();
this.isExpanded = true;
dijit.setWaiState(this.labelNode, "expanded", "true");
dijit.setWaiRole(this.containerNode, "group");
dojo.addClass(this.contentNode,'dijitTreeContentExpanded');
this._setExpando();
this._updateItemClasses(this.item);
if(this == this.tree.rootNode){
dijit.setWaiState(this.tree.domNode, "expanded", "true");
}
if(!this._wipeIn){
this._wipeIn = dojo.fx.wipeIn({
node: this.containerNode, duration: dijit.defaultDuration
});
}
this._wipeIn.play();
},
collapse: function(){
// summary:
// Collapse this node (if it's expanded)
if(!this.isExpanded){ return; }
// cancel in progress expand operation
this._wipeIn && this._wipeIn.stop();
this.isExpanded = false;
dijit.setWaiState(this.labelNode, "expanded", "false");
if(this == this.tree.rootNode){
dijit.setWaiState(this.tree.domNode, "expanded", "false");
}
dojo.removeClass(this.contentNode,'dijitTreeContentExpanded');
this._setExpando();
this._updateItemClasses(this.item);
if(!this._wipeOut){
this._wipeOut = dojo.fx.wipeOut({
node: this.containerNode, duration: dijit.defaultDuration
});
}
this._wipeOut.play();
},
setLabelNode: function(label){
// summary:
// Sets the label
this.labelNode.innerHTML = "";
this.labelNode.appendChild(dojo.doc.createTextNode(label));
},
// indent: Integer
// Levels from this node to the root node
indent: 0,
setChildItems: function(/* Object[] */ items){
// summary:
// Sets the child items of this node, removing/adding nodes
// from current children to match specified items[] array.
var tree = this.tree,
model = tree.model;
// Orphan all my existing children.
// If items contains some of the same items as before then we will reattach them.
// Don't call this.removeChild() because that will collapse the tree etc.
this.getChildren().forEach(function(child){
dijit._Container.prototype.removeChild.call(this, child);
}, this);
this.state = "LOADED";
if(items && items.length > 0){
this.isExpandable = true;
// Create _TreeNode widget for each specified tree node, unless one already
// exists and isn't being used (presumably it's from a DnD move and was recently
// released
dojo.forEach(items, function(item){
var id = model.getIdentity(item),
existingNode = tree._itemNodeMap[id],
node =
( existingNode && !existingNode.getParent() ) ?
existingNode :
this.tree._createTreeNode({
item: item,
tree: tree,
isExpandable: model.mayHaveChildren(item),
label: tree.getLabel(item),
indent: this.indent + 1
});
if(existingNode){
existingNode.attr('indent', this.indent+1);
}
this.addChild(node);
// note: this won't work if there are two nodes for one item (multi-parented items); will be fixed later
tree._itemNodeMap[id] = node;
if(this.tree._state(item)){
tree._expandNode(node);
}
}, this);
// note that updateLayout() needs to be called on each child after
// _all_ the children exist
dojo.forEach(this.getChildren(), function(child, idx){
child._updateLayout();
});
}else{
this.isExpandable=false;
}
if(this._setExpando){
// change expando to/from dot or + icon, as appropriate
this._setExpando(false);
}
// On initial tree show, make the selected TreeNode as either the root node of the tree,
// or the first child, if the root node is hidden
if(this == tree.rootNode){
var fc = this.tree.showRoot ? this : this.getChildren()[0];
if(fc){
fc.setSelected(true);
tree.lastFocused = fc;
}else{
// fallback: no nodes in tree so focus on Tree
itself
tree.domNode.setAttribute("tabIndex", "0");
}
}
},
removeChild: function(/* treeNode */ node){
this.inherited(arguments);
var children = this.getChildren();
if(children.length == 0){
this.isExpandable = false;
this.collapse();
}
dojo.forEach(children, function(child){
child._updateLayout();
});
},
makeExpandable: function(){
//summary:
// if this node wasn't already showing the expando node,
// turn it into one and call _setExpando()
// TODO: hmm this isn't called from anywhere, maybe should remove it for 2.0
this.isExpandable = true;
this._setExpando(false);";s:7:"summary";s:0:"";}s:29:"dijit._TreeNode._onLabelFocus";a:7:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:3:"evt";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:89:" dojo.addClass(this.labelNode, "dijitTreeLabelFocused");
this.tree._onNodeFocus(this);";s:7:"summary";s:59:"Called when this node is focused (possibly programatically)";s:4:"tags";s:7:"private";s:7:"private";b:1;}s:28:"dijit._TreeNode._onLabelBlur";a:7:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:3:"evt";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:60:" dojo.removeClass(this.labelNode, "dijitTreeLabelFocused");";s:7:"summary";s:240:"Called when focus was moved away from this node, either to
another TreeNode or away from the Tree entirely.
Note that we aren't using _onFocus/_onBlur builtin to dijit
because _onBlur() isn't called when focus is moved to my child TreeNode.";s:4:"tags";s:7:"private";s:7:"private";b:1;}s:27:"dijit._TreeNode.setSelected";a:6:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:8:"selected";a:1:{s:4:"type";s:7:"Boolean";}}s:6:"source";s:217:" var labelNode = this.labelNode;
labelNode.setAttribute("tabIndex", selected ? "0" : "-1");
dijit.setWaiState(labelNode, "selected", selected);
dojo.toggleClass(this.rowNode, "dijitTreeNodeSelected", selected);";s:7:"summary";s:105:"A Tree has a (single) currently selected node.
Mark that this node is/isn't that currently selected node.";s:11:"description";s:138:"In particular, setting a node as selected involves setting tabIndex
so that when user tabs to the tree, focus will go to that node (only).";}s:29:"dijit._TreeNode._onMouseEnter";a:7:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:3:"evt";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:94:" dojo.addClass(this.rowNode, "dijitTreeNodeHover");
this.tree._onNodeMouseEnter(this, evt);";s:7:"summary";s:40:"Handler for onmouseenter event on a node";s:4:"tags";s:7:"private";s:7:"private";b:1;}s:29:"dijit._TreeNode._onMouseLeave";a:7:{s:9:"prototype";s:15:"dijit._TreeNode";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:3:"evt";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:97:" dojo.removeClass(this.rowNode, "dijitTreeNodeHover");
this.tree._onNodeMouseLeave(this, evt);";s:7:"summary";s:40:"Handler for onmouseenter event on a node";s:4:"tags";s:7:"private";s:7:"private";b:1;}s:26:"dijit._TreeNode._iconClass";a:3:{s:8:"instance";s:15:"dijit._TreeNode";s:7:"private";b:1;s:7:"summary";s:0:"";}s:27:"dijit._TreeNode._labelClass";a:3:{s:8:"instance";s:15:"dijit._TreeNode";s:7:"private";b:1;s:7:"summary";s:0:"";}s:41:"dijit._TreeNode.expandoNodeText.innerHTML";a:2:{s:8:"instance";s:15:"dijit._TreeNode";s:7:"summary";s:0:"";}s:23:"dijit._TreeNode._wipeIn";a:3:{s:8:"instance";s:15:"dijit._TreeNode";s:7:"private";b:1;s:7:"summary";s:0:"";}s:24:"dijit._TreeNode._wipeOut";a:3:{s:8:"instance";s:15:"dijit._TreeNode";s:7:"private";b:1;s:7:"summary";s:0:"";}s:35:"dijit._TreeNode.labelNode.innerHTML";a:2:{s:8:"instance";s:15:"dijit._TreeNode";s:7:"summary";s:0:"";}s:10:"dijit.Tree";a:5:{s:4:"type";s:8:"Function";s:6:"chains";a:2:{s:9:"prototype";a:1:{i:0;s:13:"dijit._Widget";}s:4:"call";a:2:{i:0;s:13:"dijit._Widget";i:1;s:16:"dijit._Templated";}}s:6:"mixins";a:1:{s:9:"prototype";a:1:{i:0;s:26:"dijit._Templated.prototype";}}s:7:"summary";s:52:"This widget displays hierarchical data from a store.";s:9:"classlike";b:1;}s:16:"dijit.Tree.store";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"tags";a:1:{i:0;s:10:"deprecated";}s:4:"type";s:23:"String||dojo.data.Store";s:7:"summary";s:99:"Deprecated. Use "model" parameter instead.
The store to get data to display in the tree.";}s:16:"dijit.Tree.model";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:8:"instance";s:10:"dijit.Tree";s:4:"type";s:16:"dijit.Tree.model";s:7:"summary";s:138:"Interface to read tree data, get notifications of changes to tree data,
and for handling drop operations (i.e drag and drop onto the tree)";}s:16:"dijit.Tree.query";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"tags";a:1:{i:0;s:10:"deprecated";}s:4:"type";s:8:"anything";s:7:"summary";s:146:"Deprecated. User should specify query to the model directly instead.
Specifies datastore query to return the root item or top items for the tree.";}s:16:"dijit.Tree.label";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"tags";a:1:{i:0;s:10:"deprecated";}s:4:"type";s:6:"String";s:7:"summary";s:254:"Deprecated. Use dijit.tree.ForestStoreModel directly instead.
Used in conjunction with query parameter.
If a query is specified (rather than a root node id), and a label is also specified,
then a fake root node is created and displayed, with this label.";}s:19:"dijit.Tree.showRoot";a:5:{s:9:"prototype";s:10:"dijit.Tree";s:8:"instance";s:10:"dijit.Tree";s:4:"tags";a:1:{i:0;s:5:"const";}s:4:"type";s:7:"Boolean";s:7:"summary";s:45:"Should the root node be displayed, or hidden?";}s:23:"dijit.Tree.childrenAttr";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"tags";a:1:{i:0;s:10:"deprecated";}s:4:"type";s:7:"String[";s:7:"summary";s:123:"Deprecated. This information should be specified in the model.
One ore more attributes that holds children of a tree node";}s:22:"dijit.Tree.openOnClick";a:3:{s:9:"prototype";s:10:"dijit.Tree";s:4:"type";s:7:"Boolean";s:7:"summary";s:83:"If true, clicking a folder node's label will open it, rather than calling onClick()";}s:25:"dijit.Tree.openOnDblClick";a:3:{s:9:"prototype";s:10:"dijit.Tree";s:4:"type";s:7:"Boolean";s:7:"summary";s:93:"If true, double-clicking a folder node's label will open it, rather than calling onDblClick()";}s:23:"dijit.Tree.templatePath";a:2:{s:9:"prototype";s:10:"dijit.Tree";s:7:"summary";s:0:"";}s:23:"dijit.Tree.isExpandable";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"tags";a:2:{i:0;s:7:"private";i:1;s:10:"deprecated";}s:4:"type";s:7:"Boolean";s:7:"summary";s:82:"TODO: this appears to be vestigal, back from when Tree extended TreeNode. Remove.";}s:17:"dijit.Tree.isTree";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"tags";a:2:{i:0;s:7:"private";i:1;s:10:"deprecated";}s:4:"type";s:7:"Boolean";s:7:"summary";s:43:"TODO: this appears to be vestigal. Remove.";}s:18:"dijit.Tree.persist";a:3:{s:9:"prototype";s:10:"dijit.Tree";s:4:"type";s:7:"Boolean";s:7:"summary";s:49:"Enables/disables use of cookies for state saving.";}s:24:"dijit.Tree.dndController";a:5:{s:9:"prototype";s:10:"dijit.Tree";s:8:"instance";s:10:"dijit.Tree";s:4:"tags";a:1:{i:0;s:9:"protected";}s:4:"type";s:6:"String";s:7:"summary";s:151:"Class name to use as as the dnd controller. Specifying this class enables DnD.
Generally you should specify this as "dijit._tree.dndSource".";}s:20:"dijit.Tree.dndParams";a:2:{s:9:"prototype";s:10:"dijit.Tree";s:7:"summary";s:0:"";}s:20:"dijit.Tree.onDndDrop";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"tags";a:1:{i:0;s:9:"protected";}s:4:"type";s:8:"Function";s:7:"summary";s:105:"Parameter to dndController, see `dijit._tree.dndSource.onDndDrop`.
Generally this doesn't need to be set.";}s:22:"dijit.Tree.itemCreator";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"tags";a:1:{i:0;s:9:"protected";}s:4:"type";s:8:"Function";s:7:"summary";s:107:"Parameter to dndController, see `dijit._tree.dndSource.itemCreator`.
Generally this doesn't need to be set.";}s:22:"dijit.Tree.onDndCancel";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"tags";a:1:{i:0;s:9:"protected";}s:4:"type";s:8:"Function";s:7:"summary";s:107:"Parameter to dndController, see `dijit._tree.dndSource.onDndCancel`.
Generally this doesn't need to be set.";}s:26:"dijit.Tree.checkAcceptance";a:7:{s:9:"prototype";s:10:"dijit.Tree";s:4:"type";s:8:"Function";s:10:"parameters";a:2:{s:6:"source";a:2:{s:4:"type";s:21:"dijit.tree._dndSource";s:7:"summary";s:31:"The source which provides items";}s:5:"nodes";a:2:{s:4:"type";s:8:"DOMNode[";s:7:"summary";s:102:"Array of DOM nodes corresponding to nodes being dropped, dijitTreeRow nodes if
source is a dijit.Tree.";}}s:6:"source";s:25:" return true; // Boolean";s:7:"summary";s:59:"Checks if the Tree itself can accept nodes from this source";s:4:"tags";s:9:"extension";s:7:"returns";s:7:"Boolean";}s:30:"dijit.Tree.checkItemAcceptance";a:8:{s:9:"prototype";s:10:"dijit.Tree";s:4:"type";s:8:"Function";s:10:"parameters";a:3:{s:6:"target";a:2:{s:4:"type";s:7:"DOMNode";s:7:"summary";s:134:"The dijitTreeRoot DOM node inside of the TreeNode that we are dropping on to
Use dijit.getEnclosingWidget(target) to get the TreeNode.";}s:6:"source";a:2:{s:4:"type";s:21:"dijit._tree.dndSource";s:7:"summary";s:34:"The (set of) nodes we are dropping";}s:8:"position";a:2:{s:4:"type";s:6:"String";s:7:"summary";s:58:""over", "before", or "after"";}}s:6:"source";s:25:" return true; // Boolean";s:7:"summary";s:99:"Stub function to be overridden if one wants to check for the ability to drop at the node/item level";s:11:"description";s:229:"In the base case, this is called to check if target can become a child of source.
When betweenThreshold is set, position="before" or "after" means that we
are asking if the source node can be dropped before/after the target node.";s:4:"tags";s:9:"extension";s:7:"returns";s:7:"Boolean";}s:24:"dijit.Tree.dragThreshold";a:3:{s:9:"prototype";s:10:"dijit.Tree";s:4:"type";s:7:"Integer";s:7:"summary";s:81:"Number of pixels mouse moves before it's considered the start of a drag operation";}s:27:"dijit.Tree.betweenThreshold";a:3:{s:9:"prototype";s:10:"dijit.Tree";s:4:"type";s:7:"Integer";s:7:"summary";s:492:"Set to a positive value to allow drag and drop "between" nodes.
If during DnD mouse is over a (target) node but less than betweenThreshold
pixels from the bottom edge, dropping the the dragged node will make it
the next sibling of the target node, rather than the child.
Similarly, if mouse is over a target node but less that betweenThreshold
pixels from the top edge, dropping the dragged node will make it
the target node's previous sibling rather than the target node's child.";}s:19:"dijit.Tree._publish";a:6:{s:9:"prototype";s:10:"dijit.Tree";s:4:"type";s:8:"Function";s:10:"parameters";a:2:{s:9:"topicName";a:1:{s:4:"type";s:6:"String";}s:7:"message";a:1:{s:4:"type";s:6:"Object";}}s:6:"source";s:83:" dojo.publish(this.id, [dojo.mixin({tree: this, event: topicName}, message||{})]);";s:7:"summary";s:39:"Publish a message for this widget/topic";s:7:"private";b:1;}s:30:"dijit.Tree.postMixInProperties";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"type";s:8:"Function";s:6:"source";s:164:" this.tree = this;
this._itemNodeMap={};
if(!this.cookieName){
this.cookieName = this.id + "SaveStateCookie";
}
// TODO: this.inherited(arguments)";s:7:"summary";s:0:"";}s:21:"dijit.Tree.postCreate";a:4:{s:9:"prototype";s:10:"dijit.Tree";s:4:"type";s:8:"Function";s:6:"source";s:784:" this._initState();
// Create glue between store and Tree, if not specified directly by user
if(!this.model){
this._store2model();
}
// monitor changes to items
this.connect(this.model, "onChange", "_onItemChange");
this.connect(this.model, "onChildrenChange", "_onItemChildrenChange");
this.connect(this.model, "onDelete", "_onItemDelete");
this._load();
this.inherited(arguments);
if(this.dndController){
if(dojo.isString(this.dndController)){
this.dndController = dojo.getObject(this.dndController);
}
var params={};
for (var i=0; i
0){
this.isExpandable = true;
// Create _TreeNode widget for each specified tree node, unless one already
// exists and isn't being used (presumably it's from a DnD move and was recently
// released
dojo.forEach(items, function(item){
var id = model.getIdentity(item),
existingNode = tree._itemNodeMap[id],
node =
( existingNode && !existingNode.getParent() ) ?
existingNode :
this.tree._createTreeNode({
item: item,
tree: tree,
isExpandable: model.mayHaveChildren(item),
label: tree.getLabel(item),
indent: this.indent + 1
});
if(existingNode){
existingNode.attr('indent', this.indent+1);
}
this.addChild(node);
// note: this won't work if there are two nodes for one item (multi-parented items); will be fixed later
tree._itemNodeMap[id] = node;
if(this.tree._state(item)){
tree._expandNode(node);
}
}, this);
// note that updateLayout() needs to be called on each child after
// _all_ the children exist
dojo.forEach(this.getChildren(), function(child, idx){
child._updateLayout();
});
}else{
this.isExpandable=false;
}
if(this._setExpando){
// change expando to/from dot or + icon, as appropriate
this._setExpando(false);
}
// On initial tree show, make the selected TreeNode as either the root node of the tree,
// or the first child, if the root node is hidden
if(this == tree.rootNode){
var fc = this.tree.showRoot ? this : this.getChildren()[0];
if(fc){
fc.setSelected(true);
tree.lastFocused = fc;
}else{
// fallback: no nodes in tree so focus on Tree itself
tree.domNode.setAttribute("tabIndex", "0");
}
}
},
removeChild: function(/* treeNode */ node){
this.inherited(arguments);
var children = this.getChildren();
if(children.length == 0){
this.isExpandable = false;
this.collapse();
}
dojo.forEach(children, function(child){
child._updateLayout();
});
},
makeExpandable: function(){
//summary:
// if this node wasn't already showing the expando node,
// turn it into one and call _setExpando()
// TODO: hmm this isn't called from anywhere, maybe should remove it for 2.0
this.isExpandable = true;
this._setExpando(false);
},
_onLabelFocus: function(evt){
// summary:
// Called when this node is focused (possibly programatically)
// tags:
// private
dojo.addClass(this.labelNode, "dijitTreeLabelFocused");
this.tree._onNodeFocus(this);
},
_onLabelBlur: function(evt){
// summary:
// Called when focus was moved away from this node, either to
// another TreeNode or away from the Tree entirely.
// Note that we aren't using _onFocus/_onBlur builtin to dijit
// because _onBlur() isn't called when focus is moved to my child TreeNode.
// tags:
// private
dojo.removeClass(this.labelNode, "dijitTreeLabelFocused");
},
setSelected: function(/*Boolean*/ selected){
// summary:
// A Tree has a (single) currently selected node.
// Mark that this node is/isn't that currently selected node.
// description:
// In particular, setting a node as selected involves setting tabIndex
// so that when user tabs to the tree, focus will go to that node (only).
var labelNode = this.labelNode;
labelNode.setAttribute("tabIndex", selected ? "0" : "-1");
dijit.setWaiState(labelNode, "selected", selected);
dojo.toggleClass(this.rowNode, "dijitTreeNodeSelected", selected);
},
_onMouseEnter: function(evt){
// summary:
// Handler for onmouseenter event on a node
// tags:
// private
dojo.addClass(this.rowNode, "dijitTreeNodeHover");
this.tree._onNodeMouseEnter(this, evt);
},
_onMouseLeave: function(evt){
// summary:
// Handler for onmouseenter event on a node
// tags:
// private
dojo.removeClass(this.rowNode, "dijitTreeNodeHover");
this.tree._onNodeMouseLeave(this, evt);
}
});
dojo.declare(
"dijit.Tree",
[dijit._Widget, dijit._Templated],
{
// summary:
// This widget displays hierarchical data from a store.
// store: [deprecated] String||dojo.data.Store
// Deprecated. Use "model" parameter instead.
// The store to get data to display in the tree.
store: null,
// model: dijit.Tree.model
// Interface to read tree data, get notifications of changes to tree data,
// and for handling drop operations (i.e drag and drop onto the tree)
model: null,
// query: [deprecated] anything
// Deprecated. User should specify query to the model directly instead.
// Specifies datastore query to return the root item or top items for the tree.
query: null,
// label: [deprecated] String
// Deprecated. Use dijit.tree.ForestStoreModel directly instead.
// Used in conjunction with query parameter.
// If a query is specified (rather than a root node id), and a label is also specified,
// then a fake root node is created and displayed, with this label.
label: "",
// showRoot: [const] Boolean
// Should the root node be displayed, or hidden?
showRoot: true,
// childrenAttr: [deprecated] String[]
// Deprecated. This information should be specified in the model.
// One ore more attributes that holds children of a tree node
childrenAttr: ["children"],
// openOnClick: Boolean
// If true, clicking a folder node's label will open it, rather than calling onClick()
openOnClick: false,
// openOnDblClick: Boolean
// If true, double-clicking a folder node's label will open it, rather than calling onDblClick()
openOnDblClick: false,
templatePath: dojo.moduleUrl("dijit", "templates/Tree.html"),
// isExpandable: [private deprecated] Boolean
// TODO: this appears to be vestigal, back from when Tree extended TreeNode. Remove.
isExpandable: true,
// isTree: [private deprecated] Boolean
// TODO: this appears to be vestigal. Remove.
isTree: true,
// persist: Boolean
// Enables/disables use of cookies for state saving.
persist: true,
// dndController: [protected] String
// Class name to use as as the dnd controller. Specifying this class enables DnD.
// Generally you should specify this as "dijit._tree.dndSource".
dndController: null,
// parameters to pull off of the tree and pass on to the dndController as its params
dndParams: ["onDndDrop","itemCreator","onDndCancel","checkAcceptance", "checkItemAcceptance", "dragThreshold", "betweenThreshold"],
//declare the above items so they can be pulled from the tree's markup
// onDndDrop: [protected] Function
// Parameter to dndController, see `dijit._tree.dndSource.onDndDrop`.
// Generally this doesn't need to be set.
onDndDrop: null,
// itemCreator: [protected] Function
// Parameter to dndController, see `dijit._tree.dndSource.itemCreator`.
// Generally this doesn't need to be set.
itemCreator: null,
// onDndCancel: [protected] Function
// Parameter to dndController, see `dijit._tree.dndSource.onDndCancel`.
// Generally this doesn't need to be set.
onDndCancel: null,
checkAcceptance: function(source, nodes){
// summary:
// Checks if the Tree itself can accept nodes from this source
// source: dijit.tree._dndSource
// The source which provides items
// nodes: DOMNode[]
// Array of DOM nodes corresponding to nodes being dropped, dijitTreeRow nodes if
// source is a dijit.Tree.
// tags:
// extension
return true; // Boolean
},
checkAcceptance: null,
checkItemAcceptance: function(target, source, position){
// summary:
// Stub function to be overridden if one wants to check for the ability to drop at the node/item level
// description:
// In the base case, this is called to check if target can become a child of source.
// When betweenThreshold is set, position="before" or "after" means that we
// are asking if the source node can be dropped before/after the target node.
// target: DOMNode
// The dijitTreeRoot DOM node inside of the TreeNode that we are dropping on to
// Use dijit.getEnclosingWidget(target) to get the TreeNode.
// source: dijit._tree.dndSource
// The (set of) nodes we are dropping
// position: String
// "over", "before", or "after"
// tags:
// extension
return true; // Boolean
},
checkItemAcceptance: null,
// dragThreshold: Integer
// Number of pixels mouse moves before it's considered the start of a drag operation
dragThreshold: 0,
// betweenThreshold: Integer
// Set to a positive value to allow drag and drop "between" nodes.
//
// If during DnD mouse is over a (target) node but less than betweenThreshold
// pixels from the bottom edge, dropping the the dragged node will make it
// the next sibling of the target node, rather than the child.
//
// Similarly, if mouse is over a target node but less that betweenThreshold
// pixels from the top edge, dropping the dragged node will make it
// the target node's previous sibling rather than the target node's child.
betweenThreshold: 0,
_publish: function(/*String*/ topicName, /*Object*/ message){
// summary:
// Publish a message for this widget/topic
dojo.publish(this.id, [dojo.mixin({tree: this, event: topicName}, message||{})]);
},
postMixInProperties: function(){
this.tree = this;
this._itemNodeMap={};
if(!this.cookieName){
this.cookieName = this.id + "SaveStateCookie";
}
// TODO: this.inherited(arguments)
},
postCreate: function(){
this._initState();
// Create glue between store and Tree, if not specified directly by user
if(!this.model){
this._store2model();
}
// monitor changes to items
this.connect(this.model, "onChange", "_onItemChange");
this.connect(this.model, "onChildrenChange", "_onItemChildrenChange");
this.connect(this.model, "onDelete", "_onItemDelete");
this._load();
this.inherited(arguments);
if(this.dndController){
if(dojo.isString(this.dndController)){
this.dndController = dojo.getObject(this.dndController);
}
var params={};
for (var i=0; i
0){
this.isExpandable = true;
// Create _TreeNode widget for each specified tree node, unless one already
// exists and isn't being used (presumably it's from a DnD move and was recently
// released
dojo.forEach(items, function(item){
var id = model.getIdentity(item),
existingNode = tree._itemNodeMap[id],
node =
( existingNode && !existingNode.getParent() ) ?
existingNode :
this.tree._createTreeNode({
item: item,
tree: tree,
isExpandable: model.mayHaveChildren(item),
label: tree.getLabel(item),
indent: this.indent + 1
});
if(existingNode){
existingNode.attr('indent', this.indent+1);
}
this.addChild(node);
// note: this won't work if there are two nodes for one item (multi-parented items); will be fixed later
tree._itemNodeMap[id] = node;
if(this.tree._state(item)){
tree._expandNode(node);
}
}, this);
// note that updateLayout() needs to be called on each child after
// _all_ the children exist
dojo.forEach(this.getChildren(), function(child, idx){
child._updateLayout();
});
}else{
this.isExpandable=false;
}
if(this._setExpando){
// change expando to/from dot or + icon, as appropriate
this._setExpando(false);
}
// On initial tree show, make the selected TreeNode as either the root node of the tree,
// or the first child, if the root node is hidden
if(this == tree.rootNode){
var fc = this.tree.showRoot ? this : this.getChildren()[0];
if(fc){
fc.setSelected(true);
tree.lastFocused = fc;
}else{
// fallback: no nodes in tree so focus on Tree itself
tree.domNode.setAttribute("tabIndex", "0");
}
}
},
removeChild: function(/* treeNode */ node){
this.inherited(arguments);
var children = this.getChildren();
if(children.length == 0){
this.isExpandable = false;
this.collapse();
}
dojo.forEach(children, function(child){
child._updateLayout();
});
},
makeExpandable: function(){
//summary:
// if this node wasn't already showing the expando node,
// turn it into one and call _setExpando()
// TODO: hmm this isn't called from anywhere, maybe should remove it for 2.0
this.isExpandable = true;
this._setExpando(false);
},
_onLabelFocus: function(evt){
// summary:
// Called when this node is focused (possibly programatically)
// tags:
// private
dojo.addClass(this.labelNode, "dijitTreeLabelFocused");
this.tree._onNodeFocus(this);
},
_onLabelBlur: function(evt){
// summary:
// Called when focus was moved away from this node, either to
// another TreeNode or away from the Tree entirely.
// Note that we aren't using _onFocus/_onBlur builtin to dijit
// because _onBlur() isn't called when focus is moved to my child TreeNode.
// tags:
// private
dojo.removeClass(this.labelNode, "dijitTreeLabelFocused");
},
setSelected: function(/*Boolean*/ selected){
// summary:
// A Tree has a (single) currently selected node.
// Mark that this node is/isn't that currently selected node.
// description:
// In particular, setting a node as selected involves setting tabIndex
// so that when user tabs to the tree, focus will go to that node (only).
var labelNode = this.labelNode;
labelNode.setAttribute("tabIndex", selected ? "0" : "-1");
dijit.setWaiState(labelNode, "selected", selected);
dojo.toggleClass(this.rowNode, "dijitTreeNodeSelected", selected);
},
_onMouseEnter: function(evt){
// summary:
// Handler for onmouseenter event on a node
// tags:
// private
dojo.addClass(this.rowNode, "dijitTreeNodeHover");
this.tree._onNodeMouseEnter(this, evt);
},
_onMouseLeave: function(evt){
// summary:
// Handler for onmouseenter event on a node
// tags:
// private
dojo.removeClass(this.rowNode, "dijitTreeNodeHover");
this.tree._onNodeMouseLeave(this, evt);
}
});
dojo.declare(
"dijit.Tree",
[dijit._Widget, dijit._Templated],
{
// summary:
// This widget displays hierarchical data from a store.
// store: [deprecated] String||dojo.data.Store
// Deprecated. Use "model" parameter instead.
// The store to get data to display in the tree.
store: null,
// model: dijit.Tree.model
// Interface to read tree data, get notifications of changes to tree data,
// and for handling drop operations (i.e drag and drop onto the tree)
model: null,
// query: [deprecated] anything
// Deprecated. User should specify query to the model directly instead.
// Specifies datastore query to return the root item or top items for the tree.
query: null,
// label: [deprecated] String
// Deprecated. Use dijit.tree.ForestStoreModel directly instead.
// Used in conjunction with query parameter.
// If a query is specified (rather than a root node id), and a label is also specified,
// then a fake root node is created and displayed, with this label.
label: "",
// showRoot: [const] Boolean
// Should the root node be displayed, or hidden?
showRoot: true,
// childrenAttr: [deprecated] String[]
// Deprecated. This information should be specified in the model.
// One ore more attributes that holds children of a tree node
childrenAttr: ["children"],
// openOnClick: Boolean
// If true, clicking a folder node's label will open it, rather than calling onClick()
openOnClick: false,
// openOnDblClick: Boolean
// If true, double-clicking a folder node's label will open it, rather than calling onDblClick()
openOnDblClick: false,
templatePath: dojo.moduleUrl("dijit", "templates/Tree.html"),
// isExpandable: [private deprecated] Boolean
// TODO: this appears to be vestigal, back from when Tree extended TreeNode. Remove.
isExpandable: true,
// isTree: [private deprecated] Boolean
// TODO: this appears to be vestigal. Remove.
isTree: true,
// persist: Boolean
// Enables/disables use of cookies for state saving.
persist: true,
// dndController: [protected] String
// Class name to use as as the dnd controller. Specifying this class enables DnD.
// Generally you should specify this as "dijit._tree.dndSource".
dndController: null,
// parameters to pull off of the tree and pass on to the dndController as its params
dndParams: ["onDndDrop","itemCreator","onDndCancel","checkAcceptance", "checkItemAcceptance", "dragThreshold", "betweenThreshold"],
//declare the above items so they can be pulled from the tree's markup
// onDndDrop: [protected] Function
// Parameter to dndController, see `dijit._tree.dndSource.onDndDrop`.
// Generally this doesn't need to be set.
onDndDrop: null,
// itemCreator: [protected] Function
// Parameter to dndController, see `dijit._tree.dndSource.itemCreator`.
// Generally this doesn't need to be set.
itemCreator: null,
// onDndCancel: [protected] Function
// Parameter to dndController, see `dijit._tree.dndSource.onDndCancel`.
// Generally this doesn't need to be set.
onDndCancel: null,
checkAcceptance: function(source, nodes){
// summary:
// Checks if the Tree itself can accept nodes from this source
// source: dijit.tree._dndSource
// The source which provides items
// nodes: DOMNode[]
// Array of DOM nodes corresponding to nodes being dropped, dijitTreeRow nodes if
// source is a dijit.Tree.
// tags:
// extension
return true; // Boolean
},
checkAcceptance: null,
checkItemAcceptance: function(target, source, position){
// summary:
// Stub function to be overridden if one wants to check for the ability to drop at the node/item level
// description:
// In the base case, this is called to check if target can become a child of source.
// When betweenThreshold is set, position="before" or "after" means that we
// are asking if the source node can be dropped before/after the target node.
// target: DOMNode
// The dijitTreeRoot DOM node inside of the TreeNode that we are dropping on to
// Use dijit.getEnclosingWidget(target) to get the TreeNode.
// source: dijit._tree.dndSource
// The (set of) nodes we are dropping
// position: String
// "over", "before", or "after"
// tags:
// extension
return true; // Boolean
},
checkItemAcceptance: null,
// dragThreshold: Integer
// Number of pixels mouse moves before it's considered the start of a drag operation
dragThreshold: 0,
// betweenThreshold: Integer
// Set to a positive value to allow drag and drop "between" nodes.
//
// If during DnD mouse is over a (target) node but less than betweenThreshold
// pixels from the bottom edge, dropping the the dragged node will make it
// the next sibling of the target node, rather than the child.
//
// Similarly, if mouse is over a target node but less that betweenThreshold
// pixels from the top edge, dropping the dragged node will make it
// the target node's previous sibling rather than the target node's child.
betweenThreshold: 0,
_publish: function(/*String*/ topicName, /*Object*/ message){
// summary:
// Publish a message for this widget/topic
dojo.publish(this.id, [dojo.mixin({tree: this, event: topicName}, message||{})]);
},
postMixInProperties: function(){
this.tree = this;
this._itemNodeMap={};
if(!this.cookieName){
this.cookieName = this.id + "SaveStateCookie";
}
// TODO: this.inherited(arguments)
},
postCreate: function(){
this._initState();
// Create glue between store and Tree, if not specified directly by user
if(!this.model){
this._store2model();
}
// monitor changes to items
this.connect(this.model, "onChange", "_onItemChange");
this.connect(this.model, "onChildrenChange", "_onItemChildrenChange");
this.connect(this.model, "onDelete", "_onItemDelete");
this._load();
this.inherited(arguments);
if(this.dndController){
if(dojo.isString(this.dndController)){
this.dndController = dojo.getObject(this.dndController);
}
var params={};
for (var i=0; i