1 /** 2 * @fileOverview common render for node 3 * @author yiminghe@gmail.com 4 */ 5 KISSY.add("tree/basenodeRender", function (S, Node, Component, DOM) { 6 var $ = Node.all, 7 LABEL_CLS = "ks-tree-item-content", 8 FILE_CLS = "ks-tree-file-icon", 9 FILE_EXPAND = "ks-tree-expand-icon-{t}", 10 FOLDER_EXPAND = FILE_EXPAND + "minus", 11 FOLDER_COLLAPSED = FILE_EXPAND + "plus", 12 INLINE_BLOCK = " ks-inline-block", 13 FOLDER_ICON_EXPANDED = "ks-tree-expanded-folder-icon", 14 FOLDER_ICON_COLLAPSED = "ks-tree-collapsed-folder-icon", 15 CHILDREN_CLS = "ks-tree-children", 16 CHILDREN_CLS_L = "ks-tree-lchildren", 17 EXPAND_ICON_CLS = "ks-tree-expand-icon", 18 ICON_CLS = "ks-tree-icon", 19 LEAF_CLS = "tree-item-leaf", 20 NOT_LEAF_CLS = "ks-tree-item-folder", 21 ROW_CLS = "ks-tree-item-row"; 22 23 return Component.Render.extend({ 24 25 _computeClass:function (children, parent) { 26 var self = this, 27 expanded = self.get("expanded"), 28 isLeaf = self.get("isLeaf"), 29 iconEl = self.get("iconEl"), 30 expandIconEl = self.get("expandIconEl"), 31 childrenEl = self.get("childrenEl"), 32 expand_cls = [ICON_CLS, EXPAND_ICON_CLS, ""].join(" "), 33 icon_cls = [ICON_CLS, FILE_CLS, ""].join(" ") + INLINE_BLOCK, 34 folder_cls = [ ICON_CLS, expanded ? FOLDER_ICON_EXPANDED : 35 FOLDER_ICON_COLLAPSED, ""].join(" ") + INLINE_BLOCK, 36 lastChild = parent && parent.get("children")[parent.get("children").length - 1], 37 last = !parent || !lastChild || lastChild.get("view") == self; 38 // 强制指定了 isLeaf,否则根据儿子节点集合自动判断 39 if (isLeaf === false || (isLeaf === undefined && children.length)) { 40 iconEl.attr("class", folder_cls); 41 if (expanded) { 42 expand_cls += FOLDER_EXPAND; 43 } else { 44 expand_cls += FOLDER_COLLAPSED; 45 } 46 expandIconEl.attr("class", S.substitute(expand_cls, { 47 t:last ? "l" : "t" 48 }) + INLINE_BLOCK); 49 } else 50 //if (isLeaf !== false && (isLeaf ==true || !children.length)) 51 { 52 iconEl.attr("class", icon_cls); 53 expandIconEl.attr("class", S.substitute((expand_cls + FILE_EXPAND), { 54 t:last ? "l" : "t" 55 }) + INLINE_BLOCK); 56 } 57 childrenEl && childrenEl.attr("class", (last ? CHILDREN_CLS_L : CHILDREN_CLS)); 58 59 }, 60 61 createDom:function () { 62 var self = this, 63 el = self.get("el"), 64 id, 65 rowEl, 66 contentEl = self.get("contentEl"); 67 68 rowEl = $("<div class='" + ROW_CLS + "'/>"); 69 70 id = S.guid('tree-item'); 71 72 self.__set("rowEl", rowEl); 73 74 var expandIconEl = $("<div/>") 75 .appendTo(rowEl); 76 77 var iconEl = $("<div />") 78 .appendTo(rowEl); 79 80 contentEl.appendTo(rowEl); 81 82 el.attr({ 83 role:"treeitem", 84 aria-labelledby:id 85 }).prepend(rowEl); 86 87 self.__set("expandIconEl", expandIconEl); 88 self.__set("iconEl", iconEl); 89 90 }, 91 92 _uiSetExpanded:function (v) { 93 var self = this, 94 childrenEl = self.get("childrenEl"); 95 if (childrenEl) { 96 if (!v) { 97 childrenEl.hide(); 98 } else if (v) { 99 childrenEl.show(); 100 } 101 } 102 self.get("el").attr("aria-expanded", v); 103 }, 104 105 _uiSetSelected:function (v) { 106 var self = this, 107 classes = self.getComponentCssClassWithState("-selected"), 108 // selected 放在 row 上,防止由于子选择器而干扰节点的子节点显示 109 // .selected .label {background:xx;} 110 rowEl = self.get("rowEl"); 111 rowEl[v ? "addClass" : "removeClass"](classes); 112 self.get("el").attr("aria-selected", v); 113 }, 114 115 _uiSetDepth:function (v) { 116 this.get("el").attr("aria-level", v); 117 }, 118 119 _uiSetAriaSize:function (v) { 120 this.get("el").attr("aria-setsize", v); 121 }, 122 123 _uiSetAriaPosInSet:function (v) { 124 this.get("el").attr("aria-posinset", v); 125 }, 126 127 _uiSetTooltip:function (v) { 128 this.get("el").attr("title", v); 129 }, 130 131 /** 132 * 内容容器节点,子树节点都插到这里 133 * 默认调用 Component.Render.prototype.getContentElement 为当前节点的容器 134 * 而对于子树节点,它有自己的子树节点容器(单独的div),而不是儿子都直接放在自己的容器里面 135 * @protected 136 * @return {NodeList} 137 */ 138 getContentElement:function () { 139 var self = this; 140 if (self.get("childrenEl")) { 141 return self.get("childrenEl"); 142 } 143 var c = $("<div " + (self.get("expanded") ? "" : "style='display:none'") 144 + " role='group'><" + "/div>") 145 .appendTo(self.get("el")); 146 self.__set("childrenEl", c); 147 return c; 148 } 149 }, { 150 ATTRS:{ 151 ariaSize:{}, 152 ariaPosInSet:{}, 153 childrenEl:{}, 154 expandIconEl:{}, 155 tooltip:{}, 156 iconEl:{}, 157 expanded:{ 158 value:false 159 }, 160 rowEl:{}, 161 depth:{ 162 value:0 163 }, 164 contentEl:{ 165 valueFn:function () { 166 return $("<span id='" + S.guid("tree-item") + "' class='" + LABEL_CLS + "'/>"); 167 } 168 }, 169 isLeaf:{}, 170 selected:{} 171 }, 172 173 HTML_PARSER:{ 174 childrenEl:function (el) { 175 return el.children("." + CHILDREN_CLS); 176 }, 177 contentEl:function (el) { 178 return el.children("." + LABEL_CLS); 179 }, 180 isLeaf:function (el) { 181 var self = this; 182 if (el.hasClass(self.getCssClassWithPrefix(LEAF_CLS))) { 183 return true; 184 } 185 if (el.hasClass(self.getCssClassWithPrefix(NOT_LEAF_CLS))) { 186 return false; 187 } 188 }, 189 expanded:function (el) { 190 var children = el.one("." + "ks-tree-children"); 191 if (!children) { 192 return false; 193 } 194 return children.css("display") != "none"; 195 } 196 } 197 198 }); 199 200 }, { 201 requires:['node', 'component', 'dom'] 202 });