--- /dev/null
+<html>\r
+<head>\r
+ <title>The source code</title>\r
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
+</head>\r
+<body onload="prettyPrint();">\r
+ <pre class="prettyprint lang-js"><div id="cls-Ext.tree.TreeNodeUI"></div>/**\r
+ * @class Ext.tree.TreeNodeUI\r
+ * This class provides the default UI implementation for Ext TreeNodes.\r
+ * The TreeNode UI implementation is separate from the\r
+ * tree implementation, and allows customizing of the appearance of\r
+ * tree nodes.<br>\r
+ * <p>\r
+ * If you are customizing the Tree's user interface, you\r
+ * may need to extend this class, but you should never need to instantiate this class.<br>\r
+ * <p>\r
+ * This class provides access to the user interface components of an Ext TreeNode, through\r
+ * {@link Ext.tree.TreeNode#getUI}\r
+ */\r
+Ext.tree.TreeNodeUI = function(node){\r
+ this.node = node;\r
+ this.rendered = false;\r
+ this.animating = false;\r
+ this.wasLeaf = true;\r
+ this.ecc = 'x-tree-ec-icon x-tree-elbow';\r
+ this.emptyIcon = Ext.BLANK_IMAGE_URL;\r
+};\r
+\r
+Ext.tree.TreeNodeUI.prototype = {\r
+ // private\r
+ removeChild : function(node){\r
+ if(this.rendered){\r
+ this.ctNode.removeChild(node.ui.getEl());\r
+ } \r
+ },\r
+\r
+ // private\r
+ beforeLoad : function(){\r
+ this.addClass("x-tree-node-loading");\r
+ },\r
+\r
+ // private\r
+ afterLoad : function(){\r
+ this.removeClass("x-tree-node-loading");\r
+ },\r
+\r
+ // private\r
+ onTextChange : function(node, text, oldText){\r
+ if(this.rendered){\r
+ this.textNode.innerHTML = text;\r
+ }\r
+ },\r
+\r
+ // private\r
+ onDisableChange : function(node, state){\r
+ this.disabled = state;\r
+ if (this.checkbox) {\r
+ this.checkbox.disabled = state;\r
+ } \r
+ if(state){\r
+ this.addClass("x-tree-node-disabled");\r
+ }else{\r
+ this.removeClass("x-tree-node-disabled");\r
+ } \r
+ },\r
+\r
+ // private\r
+ onSelectedChange : function(state){\r
+ if(state){\r
+ this.focus();\r
+ this.addClass("x-tree-selected");\r
+ }else{\r
+ //this.blur();\r
+ this.removeClass("x-tree-selected");\r
+ }\r
+ },\r
+\r
+ // private\r
+ onMove : function(tree, node, oldParent, newParent, index, refNode){\r
+ this.childIndent = null;\r
+ if(this.rendered){\r
+ var targetNode = newParent.ui.getContainer();\r
+ if(!targetNode){//target not rendered\r
+ this.holder = document.createElement("div");\r
+ this.holder.appendChild(this.wrap);\r
+ return;\r
+ }\r
+ var insertBefore = refNode ? refNode.ui.getEl() : null;\r
+ if(insertBefore){\r
+ targetNode.insertBefore(this.wrap, insertBefore);\r
+ }else{\r
+ targetNode.appendChild(this.wrap);\r
+ }\r
+ this.node.renderIndent(true, oldParent != newParent);\r
+ }\r
+ },\r
+\r
+<div id="method-Ext.tree.TreeNodeUI-addClass"></div>/**\r
+ * Adds one or more CSS classes to the node's UI element.\r
+ * Duplicate classes are automatically filtered out.\r
+ * @param {String/Array} className The CSS class to add, or an array of classes\r
+ */\r
+ addClass : function(cls){\r
+ if(this.elNode){\r
+ Ext.fly(this.elNode).addClass(cls);\r
+ }\r
+ },\r
+\r
+<div id="method-Ext.tree.TreeNodeUI-removeClass"></div>/**\r
+ * Removes one or more CSS classes from the node's UI element.\r
+ * @param {String/Array} className The CSS class to remove, or an array of classes\r
+ */\r
+ removeClass : function(cls){\r
+ if(this.elNode){\r
+ Ext.fly(this.elNode).removeClass(cls); \r
+ }\r
+ },\r
+\r
+ // private\r
+ remove : function(){\r
+ if(this.rendered){\r
+ this.holder = document.createElement("div");\r
+ this.holder.appendChild(this.wrap);\r
+ } \r
+ },\r
+\r
+ // private\r
+ fireEvent : function(){\r
+ return this.node.fireEvent.apply(this.node, arguments); \r
+ },\r
+\r
+ // private\r
+ initEvents : function(){\r
+ this.node.on("move", this.onMove, this);\r
+\r
+ if(this.node.disabled){\r
+ this.addClass("x-tree-node-disabled");\r
+ if (this.checkbox) {\r
+ this.checkbox.disabled = true;\r
+ } \r
+ }\r
+ if(this.node.hidden){\r
+ this.hide();\r
+ }\r
+ var ot = this.node.getOwnerTree();\r
+ var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;\r
+ if(dd && (!this.node.isRoot || ot.rootVisible)){\r
+ Ext.dd.Registry.register(this.elNode, {\r
+ node: this.node,\r
+ handles: this.getDDHandles(),\r
+ isHandle: false\r
+ });\r
+ }\r
+ },\r
+\r
+ // private\r
+ getDDHandles : function(){\r
+ return [this.iconNode, this.textNode, this.elNode];\r
+ },\r
+\r
+<div id="method-Ext.tree.TreeNodeUI-hide"></div>/**\r
+ * Hides this node.\r
+ */\r
+ hide : function(){\r
+ this.node.hidden = true;\r
+ if(this.wrap){\r
+ this.wrap.style.display = "none";\r
+ }\r
+ },\r
+\r
+<div id="method-Ext.tree.TreeNodeUI-show"></div>/**\r
+ * Shows this node.\r
+ */\r
+ show : function(){\r
+ this.node.hidden = false;\r
+ if(this.wrap){\r
+ this.wrap.style.display = "";\r
+ } \r
+ },\r
+\r
+ // private\r
+ onContextMenu : function(e){\r
+ if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {\r
+ e.preventDefault();\r
+ this.focus();\r
+ this.fireEvent("contextmenu", this.node, e);\r
+ }\r
+ },\r
+\r
+ // private\r
+ onClick : function(e){\r
+ if(this.dropping){\r
+ e.stopEvent();\r
+ return;\r
+ }\r
+ if(this.fireEvent("beforeclick", this.node, e) !== false){\r
+ var a = e.getTarget('a');\r
+ if(!this.disabled && this.node.attributes.href && a){\r
+ this.fireEvent("click", this.node, e);\r
+ return;\r
+ }else if(a && e.ctrlKey){\r
+ e.stopEvent();\r
+ }\r
+ e.preventDefault();\r
+ if(this.disabled){\r
+ return;\r
+ }\r
+\r
+ if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){\r
+ this.node.toggle();\r
+ }\r
+\r
+ this.fireEvent("click", this.node, e);\r
+ }else{\r
+ e.stopEvent();\r
+ }\r
+ },\r
+\r
+ // private\r
+ onDblClick : function(e){\r
+ e.preventDefault();\r
+ if(this.disabled){\r
+ return;\r
+ }\r
+ if(this.checkbox){\r
+ this.toggleCheck();\r
+ }\r
+ if(!this.animating && this.node.isExpandable()){\r
+ this.node.toggle();\r
+ }\r
+ this.fireEvent("dblclick", this.node, e);\r
+ },\r
+\r
+ onOver : function(e){\r
+ this.addClass('x-tree-node-over');\r
+ },\r
+\r
+ onOut : function(e){\r
+ this.removeClass('x-tree-node-over');\r
+ },\r
+\r
+ // private\r
+ onCheckChange : function(){\r
+ var checked = this.checkbox.checked;\r
+ // fix for IE6\r
+ this.checkbox.defaultChecked = checked; \r
+ this.node.attributes.checked = checked;\r
+ this.fireEvent('checkchange', this.node, checked);\r
+ },\r
+\r
+ // private\r
+ ecClick : function(e){\r
+ if(!this.animating && this.node.isExpandable()){\r
+ this.node.toggle();\r
+ }\r
+ },\r
+\r
+ // private\r
+ startDrop : function(){\r
+ this.dropping = true;\r
+ },\r
+ \r
+ // delayed drop so the click event doesn't get fired on a drop\r
+ endDrop : function(){ \r
+ setTimeout(function(){\r
+ this.dropping = false;\r
+ }.createDelegate(this), 50); \r
+ },\r
+\r
+ // private\r
+ expand : function(){\r
+ this.updateExpandIcon();\r
+ this.ctNode.style.display = "";\r
+ },\r
+\r
+ // private\r
+ focus : function(){\r
+ if(!this.node.preventHScroll){\r
+ try{this.anchor.focus();\r
+ }catch(e){}\r
+ }else{\r
+ try{\r
+ var noscroll = this.node.getOwnerTree().getTreeEl().dom;\r
+ var l = noscroll.scrollLeft;\r
+ this.anchor.focus();\r
+ noscroll.scrollLeft = l;\r
+ }catch(e){}\r
+ }\r
+ },\r
+\r
+<div id="method-Ext.tree.TreeNodeUI-toggleCheck"></div>/**\r
+ * Sets the checked status of the tree node to the passed value, or, if no value was passed,\r
+ * toggles the checked status. If the node was rendered with no checkbox, this has no effect.\r
+ * @param {Boolean} (optional) The new checked status.\r
+ */\r
+ toggleCheck : function(value){\r
+ var cb = this.checkbox;\r
+ if(cb){\r
+ cb.checked = (value === undefined ? !cb.checked : value);\r
+ this.onCheckChange();\r
+ }\r
+ },\r
+\r
+ // private\r
+ blur : function(){\r
+ try{\r
+ this.anchor.blur();\r
+ }catch(e){} \r
+ },\r
+\r
+ // private\r
+ animExpand : function(callback){\r
+ var ct = Ext.get(this.ctNode);\r
+ ct.stopFx();\r
+ if(!this.node.isExpandable()){\r
+ this.updateExpandIcon();\r
+ this.ctNode.style.display = "";\r
+ Ext.callback(callback);\r
+ return;\r
+ }\r
+ this.animating = true;\r
+ this.updateExpandIcon();\r
+ \r
+ ct.slideIn('t', {\r
+ callback : function(){\r
+ this.animating = false;\r
+ Ext.callback(callback);\r
+ },\r
+ scope: this,\r
+ duration: this.node.ownerTree.duration || .25\r
+ });\r
+ },\r
+\r
+ // private\r
+ highlight : function(){\r
+ var tree = this.node.getOwnerTree();\r
+ Ext.fly(this.wrap).highlight(\r
+ tree.hlColor || "C3DAF9",\r
+ {endColor: tree.hlBaseColor}\r
+ );\r
+ },\r
+\r
+ // private\r
+ collapse : function(){\r
+ this.updateExpandIcon();\r
+ this.ctNode.style.display = "none";\r
+ },\r
+\r
+ // private\r
+ animCollapse : function(callback){\r
+ var ct = Ext.get(this.ctNode);\r
+ ct.enableDisplayMode('block');\r
+ ct.stopFx();\r
+\r
+ this.animating = true;\r
+ this.updateExpandIcon();\r
+\r
+ ct.slideOut('t', {\r
+ callback : function(){\r
+ this.animating = false;\r
+ Ext.callback(callback);\r
+ },\r
+ scope: this,\r
+ duration: this.node.ownerTree.duration || .25\r
+ });\r
+ },\r
+\r
+ // private\r
+ getContainer : function(){\r
+ return this.ctNode; \r
+ },\r
+\r
+ // private\r
+ getEl : function(){\r
+ return this.wrap; \r
+ },\r
+\r
+ // private\r
+ appendDDGhost : function(ghostNode){\r
+ ghostNode.appendChild(this.elNode.cloneNode(true));\r
+ },\r
+\r
+ // private\r
+ getDDRepairXY : function(){\r
+ return Ext.lib.Dom.getXY(this.iconNode);\r
+ },\r
+\r
+ // private\r
+ onRender : function(){\r
+ this.render(); \r
+ },\r
+\r
+ // private\r
+ render : function(bulkRender){\r
+ var n = this.node, a = n.attributes;\r
+ var targetNode = n.parentNode ? \r
+ n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;\r
+ \r
+ if(!this.rendered){\r
+ this.rendered = true;\r
+\r
+ this.renderElements(n, a, targetNode, bulkRender);\r
+\r
+ if(a.qtip){\r
+ if(this.textNode.setAttributeNS){\r
+ this.textNode.setAttributeNS("ext", "qtip", a.qtip);\r
+ if(a.qtipTitle){\r
+ this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);\r
+ }\r
+ }else{\r
+ this.textNode.setAttribute("ext:qtip", a.qtip);\r
+ if(a.qtipTitle){\r
+ this.textNode.setAttribute("ext:qtitle", a.qtipTitle);\r
+ }\r
+ } \r
+ }else if(a.qtipCfg){\r
+ a.qtipCfg.target = Ext.id(this.textNode);\r
+ Ext.QuickTips.register(a.qtipCfg);\r
+ }\r
+ this.initEvents();\r
+ if(!this.node.expanded){\r
+ this.updateExpandIcon(true);\r
+ }\r
+ }else{\r
+ if(bulkRender === true) {\r
+ targetNode.appendChild(this.wrap);\r
+ }\r
+ }\r
+ },\r
+\r
+ // private\r
+ renderElements : function(n, a, targetNode, bulkRender){\r
+ // add some indent caching, this helps performance when rendering a large tree\r
+ this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';\r
+\r
+ var cb = typeof a.checked == 'boolean';\r
+\r
+ var href = a.href ? a.href : Ext.isGecko ? "" : "#";\r
+ var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',\r
+ '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",\r
+ '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',\r
+ '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',\r
+ cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',\r
+ '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',\r
+ a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",\r
+ '<ul class="x-tree-node-ct" style="display:none;"></ul>',\r
+ "</li>"].join('');\r
+\r
+ var nel;\r
+ if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){\r
+ this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);\r
+ }else{\r
+ this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);\r
+ }\r
+ \r
+ this.elNode = this.wrap.childNodes[0];\r
+ this.ctNode = this.wrap.childNodes[1];\r
+ var cs = this.elNode.childNodes;\r
+ this.indentNode = cs[0];\r
+ this.ecNode = cs[1];\r
+ this.iconNode = cs[2];\r
+ var index = 3;\r
+ if(cb){\r
+ this.checkbox = cs[3];\r
+ // fix for IE6\r
+ this.checkbox.defaultChecked = this.checkbox.checked; \r
+ index++;\r
+ }\r
+ this.anchor = cs[index];\r
+ this.textNode = cs[index].firstChild;\r
+ },\r
+\r
+<div id="method-Ext.tree.TreeNodeUI-getAnchor"></div>/**\r
+ * Returns the <a> element that provides focus for the node's UI.\r
+ * @return {HtmlElement} The DOM anchor element.\r
+ */\r
+ getAnchor : function(){\r
+ return this.anchor;\r
+ },\r
+ \r
+<div id="method-Ext.tree.TreeNodeUI-getTextEl"></div>/**\r
+ * Returns the text node.\r
+ * @return {HtmlNode} The DOM text node.\r
+ */\r
+ getTextEl : function(){\r
+ return this.textNode;\r
+ },\r
+ \r
+<div id="method-Ext.tree.TreeNodeUI-getIconEl"></div>/**\r
+ * Returns the icon <img> element.\r
+ * @return {HtmlElement} The DOM image element.\r
+ */\r
+ getIconEl : function(){\r
+ return this.iconNode;\r
+ },\r
+\r
+<div id="method-Ext.tree.TreeNodeUI-isChecked"></div>/**\r
+ * Returns the checked status of the node. If the node was rendered with no\r
+ * checkbox, it returns false.\r
+ * @return {Boolean} The checked flag.\r
+ */\r
+ isChecked : function(){\r
+ return this.checkbox ? this.checkbox.checked : false; \r
+ },\r
+\r
+ // private\r
+ updateExpandIcon : function(){\r
+ if(this.rendered){\r
+ var n = this.node, c1, c2;\r
+ var cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow";\r
+ var hasChild = n.hasChildNodes();\r
+ if(hasChild || n.attributes.expandable){\r
+ if(n.expanded){\r
+ cls += "-minus";\r
+ c1 = "x-tree-node-collapsed";\r
+ c2 = "x-tree-node-expanded";\r
+ }else{\r
+ cls += "-plus";\r
+ c1 = "x-tree-node-expanded";\r
+ c2 = "x-tree-node-collapsed";\r
+ }\r
+ if(this.wasLeaf){\r
+ this.removeClass("x-tree-node-leaf");\r
+ this.wasLeaf = false;\r
+ }\r
+ if(this.c1 != c1 || this.c2 != c2){\r
+ Ext.fly(this.elNode).replaceClass(c1, c2);\r
+ this.c1 = c1; this.c2 = c2;\r
+ }\r
+ }else{\r
+ if(!this.wasLeaf){\r
+ Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");\r
+ delete this.c1;\r
+ delete this.c2;\r
+ this.wasLeaf = true;\r
+ }\r
+ }\r
+ var ecc = "x-tree-ec-icon "+cls;\r
+ if(this.ecc != ecc){\r
+ this.ecNode.className = ecc;\r
+ this.ecc = ecc;\r
+ }\r
+ }\r
+ },\r
+ \r
+ // private\r
+ onIdChange: function(id){\r
+ if(this.rendered){\r
+ this.elNode.setAttribute('ext:tree-node-id', id);\r
+ }\r
+ },\r
+\r
+ // private\r
+ getChildIndent : function(){\r
+ if(!this.childIndent){\r
+ var buf = [];\r
+ var p = this.node;\r
+ while(p){\r
+ if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){\r
+ if(!p.isLast()) {\r
+ buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');\r
+ } else {\r
+ buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');\r
+ }\r
+ }\r
+ p = p.parentNode;\r
+ }\r
+ this.childIndent = buf.join("");\r
+ }\r
+ return this.childIndent;\r
+ },\r
+\r
+ // private\r
+ renderIndent : function(){\r
+ if(this.rendered){\r
+ var indent = "";\r
+ var p = this.node.parentNode;\r
+ if(p){\r
+ indent = p.ui.getChildIndent();\r
+ }\r
+ if(this.indentMarkup != indent){ // don't rerender if not required\r
+ this.indentNode.innerHTML = indent;\r
+ this.indentMarkup = indent;\r
+ }\r
+ this.updateExpandIcon();\r
+ }\r
+ },\r
+\r
+ destroy : function(){\r
+ if(this.elNode){\r
+ Ext.dd.Registry.unregister(this.elNode.id);\r
+ }\r
+ delete this.elNode;\r
+ delete this.ctNode;\r
+ delete this.indentNode;\r
+ delete this.ecNode;\r
+ delete this.iconNode;\r
+ delete this.checkbox;\r
+ delete this.anchor;\r
+ delete this.textNode;\r
+ \r
+ if (this.holder){\r
+ delete this.wrap;\r
+ Ext.removeNode(this.holder);\r
+ delete this.holder;\r
+ }else{\r
+ Ext.removeNode(this.wrap);\r
+ delete this.wrap;\r
+ }\r
+ }\r
+};\r
+\r
+<div id="cls-Ext.tree.RootTreeNodeUI"></div>/**\r
+ * @class Ext.tree.RootTreeNodeUI\r
+ * This class provides the default UI implementation for <b>root</b> Ext TreeNodes.\r
+ * The RootTreeNode UI implementation allows customizing the appearance of the root tree node.<br>\r
+ * <p>\r
+ * If you are customizing the Tree's user interface, you\r
+ * may need to extend this class, but you should never need to instantiate this class.<br>\r
+ */\r
+Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {\r
+ // private\r
+ render : function(){\r
+ if(!this.rendered){\r
+ var targetNode = this.node.ownerTree.innerCt.dom;\r
+ this.node.expanded = true;\r
+ targetNode.innerHTML = '<div class="x-tree-root-node"></div>';\r
+ this.wrap = this.ctNode = targetNode.firstChild;\r
+ }\r
+ },\r
+ collapse : Ext.emptyFn,\r
+ expand : Ext.emptyFn\r
+});</pre> \r
+</body>\r
+</html>
\ No newline at end of file