CLIENT GUI Framework
[vnfsdk/refrepo.git] / openo-portal / portal-common / src / main / webapp / common / thirdparty / zTree / js / jquery.ztree.exedit.js
1 /*\r
2  * JQuery zTree exedit v3.5.16\r
3  * http://zTree.me/\r
4  *\r
5  * Copyright (c) 2010 Hunter.z\r
6  *\r
7  * Licensed same as jquery - MIT License\r
8  * http://www.opensource.org/licenses/mit-license.php\r
9  *\r
10  * email: hunter.z@263.net\r
11  * Date: 2014-03-09\r
12  */\r
13 (function($){\r
14         //default consts of exedit\r
15         var _consts = {\r
16                 event: {\r
17                         DRAG: "ztree_drag",\r
18                         DROP: "ztree_drop",\r
19                         RENAME: "ztree_rename",\r
20                         DRAGMOVE:"ztree_dragmove"\r
21                 },\r
22                 id: {\r
23                         EDIT: "_edit",\r
24                         INPUT: "_input",\r
25                         REMOVE: "_remove"\r
26                 },\r
27                 move: {\r
28                         TYPE_INNER: "inner",\r
29                         TYPE_PREV: "prev",\r
30                         TYPE_NEXT: "next"\r
31                 },\r
32                 node: {\r
33                         CURSELECTED_EDIT: "curSelectedNode_Edit",\r
34                         TMPTARGET_TREE: "tmpTargetzTree",\r
35                         TMPTARGET_NODE: "tmpTargetNode"\r
36                 }\r
37         },\r
38         //default setting of exedit\r
39         _setting = {\r
40                 edit: {\r
41                         enable: false,\r
42                         editNameSelectAll: false,\r
43                         showRemoveBtn: true,\r
44                         showRenameBtn: true,\r
45                         removeTitle: "remove",\r
46                         renameTitle: "rename",\r
47                         drag: {\r
48                                 autoExpandTrigger: false,\r
49                                 isCopy: true,\r
50                                 isMove: true,\r
51                                 prev: true,\r
52                                 next: true,\r
53                                 inner: true,\r
54                                 minMoveSize: 5,\r
55                                 borderMax: 10,\r
56                                 borderMin: -5,\r
57                                 maxShowNodeNum: 5,\r
58                                 autoOpenTime: 500\r
59                         }\r
60                 },\r
61                 view: {\r
62                         addHoverDom: null,\r
63                         removeHoverDom: null\r
64                 },\r
65                 callback: {\r
66                         beforeDrag:null,\r
67                         beforeDragOpen:null,\r
68                         beforeDrop:null,\r
69                         beforeEditName:null,\r
70                         beforeRename:null,\r
71                         onDrag:null,\r
72                         onDragMove:null,\r
73                         onDrop:null,\r
74                         onRename:null\r
75                 }\r
76         },\r
77         //default root of exedit\r
78         _initRoot = function (setting) {\r
79                 var r = data.getRoot(setting), rs = data.getRoots();\r
80                 r.curEditNode = null;\r
81                 r.curEditInput = null;\r
82                 r.curHoverNode = null;\r
83                 r.dragFlag = 0;\r
84                 r.dragNodeShowBefore = [];\r
85                 r.dragMaskList = new Array();\r
86                 rs.showHoverDom = true;\r
87         },\r
88         //default cache of exedit\r
89         _initCache = function(treeId) {},\r
90         //default bind event of exedit\r
91         _bindEvent = function(setting) {\r
92                 var o = setting.treeObj;\r
93                 var c = consts.event;\r
94                 o.bind(c.RENAME, function (event, treeId, treeNode, isCancel) {\r
95                         tools.apply(setting.callback.onRename, [event, treeId, treeNode, isCancel]);\r
96                 });\r
97 \r
98                 o.bind(c.DRAG, function (event, srcEvent, treeId, treeNodes) {\r
99                         tools.apply(setting.callback.onDrag, [srcEvent, treeId, treeNodes]);\r
100                 });\r
101 \r
102                 o.bind(c.DRAGMOVE,function(event, srcEvent, treeId, treeNodes){\r
103                         tools.apply(setting.callback.onDragMove,[srcEvent, treeId, treeNodes]);\r
104                 });\r
105 \r
106                 o.bind(c.DROP, function (event, srcEvent, treeId, treeNodes, targetNode, moveType, isCopy) {\r
107                         tools.apply(setting.callback.onDrop, [srcEvent, treeId, treeNodes, targetNode, moveType, isCopy]);\r
108                 });\r
109         },\r
110         _unbindEvent = function(setting) {\r
111                 var o = setting.treeObj;\r
112                 var c = consts.event;\r
113                 o.unbind(c.RENAME);\r
114                 o.unbind(c.DRAG);\r
115                 o.unbind(c.DRAGMOVE);\r
116                 o.unbind(c.DROP);\r
117         },\r
118         //default event proxy of exedit\r
119         _eventProxy = function(e) {\r
120                 var target = e.target,\r
121                 setting = data.getSetting(e.data.treeId),\r
122                 relatedTarget = e.relatedTarget,\r
123                 tId = "", node = null,\r
124                 nodeEventType = "", treeEventType = "",\r
125                 nodeEventCallback = null, treeEventCallback = null,\r
126                 tmp = null;\r
127 \r
128                 if (tools.eqs(e.type, "mouseover")) {\r
129                         tmp = tools.getMDom(setting, target, [{tagName:"a", attrName:"treeNode"+consts.id.A}]);\r
130                         if (tmp) {\r
131                                 tId = tools.getNodeMainDom(tmp).id;\r
132                                 nodeEventType = "hoverOverNode";\r
133                         }\r
134                 } else if (tools.eqs(e.type, "mouseout")) {\r
135                         tmp = tools.getMDom(setting, relatedTarget, [{tagName:"a", attrName:"treeNode"+consts.id.A}]);\r
136                         if (!tmp) {\r
137                                 tId = "remove";\r
138                                 nodeEventType = "hoverOutNode";\r
139                         }\r
140                 } else if (tools.eqs(e.type, "mousedown")) {\r
141                         tmp = tools.getMDom(setting, target, [{tagName:"a", attrName:"treeNode"+consts.id.A}]);\r
142                         if (tmp) {\r
143                                 tId = tools.getNodeMainDom(tmp).id;\r
144                                 nodeEventType = "mousedownNode";\r
145                         }\r
146                 }\r
147                 if (tId.length>0) {\r
148                         node = data.getNodeCache(setting, tId);\r
149                         switch (nodeEventType) {\r
150                                 case "mousedownNode" :\r
151                                         nodeEventCallback = _handler.onMousedownNode;\r
152                                         break;\r
153                                 case "hoverOverNode" :\r
154                                         nodeEventCallback = _handler.onHoverOverNode;\r
155                                         break;\r
156                                 case "hoverOutNode" :\r
157                                         nodeEventCallback = _handler.onHoverOutNode;\r
158                                         break;\r
159                         }\r
160                 }\r
161                 var proxyResult = {\r
162                         stop: false,\r
163                         node: node,\r
164                         nodeEventType: nodeEventType,\r
165                         nodeEventCallback: nodeEventCallback,\r
166                         treeEventType: treeEventType,\r
167                         treeEventCallback: treeEventCallback\r
168                 };\r
169                 return proxyResult\r
170         },\r
171         //default init node of exedit\r
172         _initNode = function(setting, level, n, parentNode, isFirstNode, isLastNode, openFlag) {\r
173                 if (!n) return;\r
174                 n.isHover = false;\r
175                 n.editNameFlag = false;\r
176         },\r
177         //update zTreeObj, add method of edit\r
178         _zTreeTools = function(setting, zTreeTools) {\r
179                 zTreeTools.cancelEditName = function(newName) {\r
180                         var root = data.getRoot(this.setting);\r
181                         if (!root.curEditNode) return;\r
182                         view.cancelCurEditNode(this.setting, newName?newName:null, true);\r
183                 }\r
184                 zTreeTools.copyNode = function(targetNode, node, moveType, isSilent) {\r
185                         if (!node) return null;\r
186                         if (targetNode && !targetNode.isParent && this.setting.data.keep.leaf && moveType === consts.move.TYPE_INNER) return null;\r
187                         var _this = this,\r
188                                 newNode = tools.clone(node);\r
189                         if (!targetNode) {\r
190                                 targetNode = null;\r
191                                 moveType = consts.move.TYPE_INNER;\r
192                         }\r
193                         if (moveType == consts.move.TYPE_INNER) {\r
194                                 function copyCallback() {\r
195                                         view.addNodes(_this.setting, targetNode, [newNode], isSilent);\r
196                                 }\r
197 \r
198                                 if (tools.canAsync(this.setting, targetNode)) {\r
199                                         view.asyncNode(this.setting, targetNode, isSilent, copyCallback);\r
200                                 } else {\r
201                                         copyCallback();\r
202                                 }\r
203                         } else {\r
204                                 view.addNodes(this.setting, targetNode.parentNode, [newNode], isSilent);\r
205                                 view.moveNode(this.setting, targetNode, newNode, moveType, false, isSilent);\r
206                         }\r
207                         return newNode;\r
208                 }\r
209                 zTreeTools.editName = function(node) {\r
210                         if (!node || !node.tId || node !== data.getNodeCache(this.setting, node.tId)) return;\r
211                         if (node.parentTId) view.expandCollapseParentNode(this.setting, node.getParentNode(), true);\r
212                         view.editNode(this.setting, node)\r
213                 }\r
214                 zTreeTools.moveNode = function(targetNode, node, moveType, isSilent) {\r
215                         if (!node) return node;\r
216                         if (targetNode && !targetNode.isParent && this.setting.data.keep.leaf && moveType === consts.move.TYPE_INNER) {\r
217                                 return null;\r
218                         } else if (targetNode && ((node.parentTId == targetNode.tId && moveType == consts.move.TYPE_INNER) || $$(node, this.setting).find("#" + targetNode.tId).length > 0)) {\r
219                                 return null;\r
220                         } else if (!targetNode) {\r
221                                 targetNode = null;\r
222                         }\r
223                         var _this = this;\r
224                         function moveCallback() {\r
225                                 view.moveNode(_this.setting, targetNode, node, moveType, false, isSilent);\r
226                         }\r
227                         if (tools.canAsync(this.setting, targetNode) && moveType === consts.move.TYPE_INNER) {\r
228                                 view.asyncNode(this.setting, targetNode, isSilent, moveCallback);\r
229                         } else {\r
230                                 moveCallback();\r
231                         }\r
232                         return node;\r
233                 }\r
234                 zTreeTools.setEditable = function(editable) {\r
235                         this.setting.edit.enable = editable;\r
236                         return this.refresh();\r
237                 }\r
238         },\r
239         //method of operate data\r
240         _data = {\r
241                 setSonNodeLevel: function(setting, parentNode, node) {\r
242                         if (!node) return;\r
243                         var childKey = setting.data.key.children;\r
244                         node.level = (parentNode)? parentNode.level + 1 : 0;\r
245                         if (!node[childKey]) return;\r
246                         for (var i = 0, l = node[childKey].length; i < l; i++) {\r
247                                 if (node[childKey][i]) data.setSonNodeLevel(setting, node, node[childKey][i]);\r
248                         }\r
249                 }\r
250         },\r
251         //method of event proxy\r
252         _event = {\r
253 \r
254         },\r
255         //method of event handler\r
256         _handler = {\r
257                 onHoverOverNode: function(event, node) {\r
258                         var setting = data.getSetting(event.data.treeId),\r
259                         root = data.getRoot(setting);\r
260                         if (root.curHoverNode != node) {\r
261                                 _handler.onHoverOutNode(event);\r
262                         }\r
263                         root.curHoverNode = node;\r
264                         view.addHoverDom(setting, node);\r
265                 },\r
266                 onHoverOutNode: function(event, node) {\r
267                         var setting = data.getSetting(event.data.treeId),\r
268                         root = data.getRoot(setting);\r
269                         if (root.curHoverNode && !data.isSelectedNode(setting, root.curHoverNode)) {\r
270                                 view.removeTreeDom(setting, root.curHoverNode);\r
271                                 root.curHoverNode = null;\r
272                         }\r
273                 },\r
274                 onMousedownNode: function(eventMouseDown, _node) {\r
275                         var i,l,\r
276                         setting = data.getSetting(eventMouseDown.data.treeId),\r
277                         root = data.getRoot(setting), roots = data.getRoots();\r
278                         //right click can't drag & drop\r
279                         if (eventMouseDown.button == 2 || !setting.edit.enable || (!setting.edit.drag.isCopy && !setting.edit.drag.isMove)) return true;\r
280 \r
281                         //input of edit node name can't drag & drop\r
282                         var target = eventMouseDown.target,\r
283                         _nodes = data.getRoot(setting).curSelectedList,\r
284                         nodes = [];\r
285                         if (!data.isSelectedNode(setting, _node)) {\r
286                                 nodes = [_node];\r
287                         } else {\r
288                                 for (i=0, l=_nodes.length; i<l; i++) {\r
289                                         if (_nodes[i].editNameFlag && tools.eqs(target.tagName, "input") && target.getAttribute("treeNode"+consts.id.INPUT) !== null) {\r
290                                                 return true;\r
291                                         }\r
292                                         nodes.push(_nodes[i]);\r
293                                         if (nodes[0].parentTId !== _nodes[i].parentTId) {\r
294                                                 nodes = [_node];\r
295                                                 break;\r
296                                         }\r
297                                 }\r
298                         }\r
299 \r
300                         view.editNodeBlur = true;\r
301                         view.cancelCurEditNode(setting);\r
302 \r
303                         var doc = $(setting.treeObj.get(0).ownerDocument),\r
304                         body = $(setting.treeObj.get(0).ownerDocument.body), curNode, tmpArrow, tmpTarget,\r
305                         isOtherTree = false,\r
306                         targetSetting = setting,\r
307                         sourceSetting = setting,\r
308                         preNode, nextNode,\r
309                         preTmpTargetNodeId = null,\r
310                         preTmpMoveType = null,\r
311                         tmpTargetNodeId = null,\r
312                         moveType = consts.move.TYPE_INNER,\r
313                         mouseDownX = eventMouseDown.clientX,\r
314                         mouseDownY = eventMouseDown.clientY,\r
315                         startTime = (new Date()).getTime();\r
316 \r
317                         if (tools.uCanDo(setting)) {\r
318                                 doc.bind("mousemove", _docMouseMove);\r
319                         }\r
320                         function _docMouseMove(event) {\r
321                                 //avoid start drag after click node\r
322                                 if (root.dragFlag == 0 && Math.abs(mouseDownX - event.clientX) < setting.edit.drag.minMoveSize\r
323                                         && Math.abs(mouseDownY - event.clientY) < setting.edit.drag.minMoveSize) {\r
324                                         return true;\r
325                                 }\r
326                                 var i, l, tmpNode, tmpDom, tmpNodes,\r
327                                 childKey = setting.data.key.children;\r
328                                 body.css("cursor", "pointer");\r
329 \r
330                                 if (root.dragFlag == 0) {\r
331                                         if (tools.apply(setting.callback.beforeDrag, [setting.treeId, nodes], true) == false) {\r
332                                                 _docMouseUp(event);\r
333                                                 return true;\r
334                                         }\r
335 \r
336                                         for (i=0, l=nodes.length; i<l; i++) {\r
337                                                 if (i==0) {\r
338                                                         root.dragNodeShowBefore = [];\r
339                                                 }\r
340                                                 tmpNode = nodes[i];\r
341                                                 if (tmpNode.isParent && tmpNode.open) {\r
342                                                         view.expandCollapseNode(setting, tmpNode, !tmpNode.open);\r
343                                                         root.dragNodeShowBefore[tmpNode.tId] = true;\r
344                                                 } else {\r
345                                                         root.dragNodeShowBefore[tmpNode.tId] = false;\r
346                                                 }\r
347                                         }\r
348 \r
349                                         root.dragFlag = 1;\r
350                                         roots.showHoverDom = false;\r
351                                         tools.showIfameMask(setting, true);\r
352 \r
353                                         //sort\r
354                                         var isOrder = true, lastIndex = -1;\r
355                                         if (nodes.length>1) {\r
356                                                 var pNodes = nodes[0].parentTId ? nodes[0].getParentNode()[childKey] : data.getNodes(setting);\r
357                                                 tmpNodes = [];\r
358                                                 for (i=0, l=pNodes.length; i<l; i++) {\r
359                                                         if (root.dragNodeShowBefore[pNodes[i].tId] !== undefined) {\r
360                                                                 if (isOrder && lastIndex > -1 && (lastIndex+1) !== i) {\r
361                                                                         isOrder = false;\r
362                                                                 }\r
363                                                                 tmpNodes.push(pNodes[i]);\r
364                                                                 lastIndex = i;\r
365                                                         }\r
366                                                         if (nodes.length === tmpNodes.length) {\r
367                                                                 nodes = tmpNodes;\r
368                                                                 break;\r
369                                                         }\r
370                                                 }\r
371                                         }\r
372                                         if (isOrder) {\r
373                                                 preNode = nodes[0].getPreNode();\r
374                                                 nextNode = nodes[nodes.length-1].getNextNode();\r
375                                         }\r
376 \r
377                                         //set node in selected\r
378                                         curNode = $$("<ul class='zTreeDragUL'></ul>", setting);\r
379                                         for (i=0, l=nodes.length; i<l; i++) {\r
380                                                 tmpNode = nodes[i];\r
381                                                 tmpNode.editNameFlag = false;\r
382                                                 view.selectNode(setting, tmpNode, i>0);\r
383                                                 view.removeTreeDom(setting, tmpNode);\r
384 \r
385                                                 if (i > setting.edit.drag.maxShowNodeNum-1) {\r
386                                                         continue;\r
387                                                 }\r
388 \r
389                                                 tmpDom = $$("<li id='"+ tmpNode.tId +"_tmp'></li>", setting);\r
390                                                 tmpDom.append($$(tmpNode, consts.id.A, setting).clone());\r
391                                                 tmpDom.css("padding", "0");\r
392                                                 tmpDom.children("#" + tmpNode.tId + consts.id.A).removeClass(consts.node.CURSELECTED);\r
393                                                 curNode.append(tmpDom);\r
394                                                 if (i == setting.edit.drag.maxShowNodeNum-1) {\r
395                                                         tmpDom = $$("<li id='"+ tmpNode.tId +"_moretmp'><a>  ...  </a></li>", setting);\r
396                                                         curNode.append(tmpDom);\r
397                                                 }\r
398                                         }\r
399                                         curNode.attr("id", nodes[0].tId + consts.id.UL + "_tmp");\r
400                                         curNode.addClass(setting.treeObj.attr("class"));\r
401                                         curNode.appendTo(body);\r
402 \r
403                                         tmpArrow = $$("<span class='tmpzTreeMove_arrow'></span>", setting);\r
404                                         tmpArrow.attr("id", "zTreeMove_arrow_tmp");\r
405                                         tmpArrow.appendTo(body);\r
406 \r
407                                         setting.treeObj.trigger(consts.event.DRAG, [event, setting.treeId, nodes]);\r
408                                 }\r
409 \r
410                                 if (root.dragFlag == 1) {\r
411                                         if (tmpTarget && tmpArrow.attr("id") == event.target.id && tmpTargetNodeId && (event.clientX + doc.scrollLeft()+2) > ($("#" + tmpTargetNodeId + consts.id.A, tmpTarget).offset().left)) {\r
412                                                 var xT = $("#" + tmpTargetNodeId + consts.id.A, tmpTarget);\r
413                                                 event.target = (xT.length > 0) ? xT.get(0) : event.target;\r
414                                         } else if (tmpTarget) {\r
415                                                 tmpTarget.removeClass(consts.node.TMPTARGET_TREE);\r
416                                                 if (tmpTargetNodeId) $("#" + tmpTargetNodeId + consts.id.A, tmpTarget).removeClass(consts.node.TMPTARGET_NODE + "_" + consts.move.TYPE_PREV)\r
417                                                         .removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_NEXT).removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_INNER);\r
418                                         }\r
419                                         tmpTarget = null;\r
420                                         tmpTargetNodeId = null;\r
421 \r
422                                         //judge drag & drop in multi ztree\r
423                                         isOtherTree = false;\r
424                                         targetSetting = setting;\r
425                                         var settings = data.getSettings();\r
426                                         for (var s in settings) {\r
427                                                 if (settings[s].treeId && settings[s].edit.enable && settings[s].treeId != setting.treeId\r
428                                                         && (event.target.id == settings[s].treeId || $(event.target).parents("#" + settings[s].treeId).length>0)) {\r
429                                                         isOtherTree = true;\r
430                                                         targetSetting = settings[s];\r
431                                                 }\r
432                                         }\r
433 \r
434                                         var docScrollTop = doc.scrollTop(),\r
435                                         docScrollLeft = doc.scrollLeft(),\r
436                                         treeOffset = targetSetting.treeObj.offset(),\r
437                                         scrollHeight = targetSetting.treeObj.get(0).scrollHeight,\r
438                                         scrollWidth = targetSetting.treeObj.get(0).scrollWidth,\r
439                                         dTop = (event.clientY + docScrollTop - treeOffset.top),\r
440                                         dBottom = (targetSetting.treeObj.height() + treeOffset.top - event.clientY - docScrollTop),\r
441                                         dLeft = (event.clientX + docScrollLeft - treeOffset.left),\r
442                                         dRight = (targetSetting.treeObj.width() + treeOffset.left - event.clientX - docScrollLeft),\r
443                                         isTop = (dTop < setting.edit.drag.borderMax && dTop > setting.edit.drag.borderMin),\r
444                                         isBottom = (dBottom < setting.edit.drag.borderMax && dBottom > setting.edit.drag.borderMin),\r
445                                         isLeft = (dLeft < setting.edit.drag.borderMax && dLeft > setting.edit.drag.borderMin),\r
446                                         isRight = (dRight < setting.edit.drag.borderMax && dRight > setting.edit.drag.borderMin),\r
447                                         isTreeInner = dTop > setting.edit.drag.borderMin && dBottom > setting.edit.drag.borderMin && dLeft > setting.edit.drag.borderMin && dRight > setting.edit.drag.borderMin,\r
448                                         isTreeTop = (isTop && targetSetting.treeObj.scrollTop() <= 0),\r
449                                         isTreeBottom = (isBottom && (targetSetting.treeObj.scrollTop() + targetSetting.treeObj.height()+10) >= scrollHeight),\r
450                                         isTreeLeft = (isLeft && targetSetting.treeObj.scrollLeft() <= 0),\r
451                                         isTreeRight = (isRight && (targetSetting.treeObj.scrollLeft() + targetSetting.treeObj.width()+10) >= scrollWidth);\r
452 \r
453                                         if (event.target && tools.isChildOrSelf(event.target, targetSetting.treeId)) {\r
454                                                 //get node <li> dom\r
455                                                 var targetObj = event.target;\r
456                                                 while (targetObj && targetObj.tagName && !tools.eqs(targetObj.tagName, "li") && targetObj.id != targetSetting.treeId) {\r
457                                                         targetObj = targetObj.parentNode;\r
458                                                 }\r
459 \r
460                                                 var canMove = true;\r
461                                                 //don't move to self or children of self\r
462                                                 for (i=0, l=nodes.length; i<l; i++) {\r
463                                                         tmpNode = nodes[i];\r
464                                                         if (targetObj.id === tmpNode.tId) {\r
465                                                                 canMove = false;\r
466                                                                 break;\r
467                                                         } else if ($$(tmpNode, setting).find("#" + targetObj.id).length > 0) {\r
468                                                                 canMove = false;\r
469                                                                 break;\r
470                                                         }\r
471                                                 }\r
472                                                 if (canMove && event.target && tools.isChildOrSelf(event.target, targetObj.id + consts.id.A)) {\r
473                                                         tmpTarget = $(targetObj);\r
474                                                         tmpTargetNodeId = targetObj.id;\r
475                                                 }\r
476                                         }\r
477 \r
478                                         //the mouse must be in zTree\r
479                                         tmpNode = nodes[0];\r
480                                         if (isTreeInner && tools.isChildOrSelf(event.target, targetSetting.treeId)) {\r
481                                                 //judge mouse move in root of ztree\r
482                                                 if (!tmpTarget && (event.target.id == targetSetting.treeId || isTreeTop || isTreeBottom || isTreeLeft || isTreeRight) && (isOtherTree || (!isOtherTree && tmpNode.parentTId))) {\r
483                                                         tmpTarget = targetSetting.treeObj;\r
484                                                 }\r
485                                                 //auto scroll top\r
486                                                 if (isTop) {\r
487                                                         targetSetting.treeObj.scrollTop(targetSetting.treeObj.scrollTop()-10);\r
488                                                 } else if (isBottom)  {\r
489                                                         targetSetting.treeObj.scrollTop(targetSetting.treeObj.scrollTop()+10);\r
490                                                 }\r
491                                                 if (isLeft) {\r
492                                                         targetSetting.treeObj.scrollLeft(targetSetting.treeObj.scrollLeft()-10);\r
493                                                 } else if (isRight) {\r
494                                                         targetSetting.treeObj.scrollLeft(targetSetting.treeObj.scrollLeft()+10);\r
495                                                 }\r
496                                                 //auto scroll left\r
497                                                 if (tmpTarget && tmpTarget != targetSetting.treeObj && tmpTarget.offset().left < targetSetting.treeObj.offset().left) {\r
498                                                         targetSetting.treeObj.scrollLeft(targetSetting.treeObj.scrollLeft()+ tmpTarget.offset().left - targetSetting.treeObj.offset().left);\r
499                                                 }\r
500                                         }\r
501 \r
502                                         curNode.css({\r
503                                                 "top": (event.clientY + docScrollTop + 3) + "px",\r
504                                                 "left": (event.clientX + docScrollLeft + 3) + "px"\r
505                                         });\r
506 \r
507                                         var dX = 0;\r
508                                         var dY = 0;\r
509                                         if (tmpTarget && tmpTarget.attr("id")!=targetSetting.treeId) {\r
510                                                 var tmpTargetNode = tmpTargetNodeId == null ? null: data.getNodeCache(targetSetting, tmpTargetNodeId),\r
511                                                 isCopy = ((event.ctrlKey || event.metaKey) && setting.edit.drag.isMove && setting.edit.drag.isCopy) || (!setting.edit.drag.isMove && setting.edit.drag.isCopy),\r
512                                                 isPrev = !!(preNode && tmpTargetNodeId === preNode.tId),\r
513                                                 isNext = !!(nextNode && tmpTargetNodeId === nextNode.tId),\r
514                                                 isInner = (tmpNode.parentTId && tmpNode.parentTId == tmpTargetNodeId),\r
515                                                 canPrev = (isCopy || !isNext) && tools.apply(targetSetting.edit.drag.prev, [targetSetting.treeId, nodes, tmpTargetNode], !!targetSetting.edit.drag.prev),\r
516                                                 canNext = (isCopy || !isPrev) && tools.apply(targetSetting.edit.drag.next, [targetSetting.treeId, nodes, tmpTargetNode], !!targetSetting.edit.drag.next),\r
517                                                 canInner = (isCopy || !isInner) && !(targetSetting.data.keep.leaf && !tmpTargetNode.isParent) && tools.apply(targetSetting.edit.drag.inner, [targetSetting.treeId, nodes, tmpTargetNode], !!targetSetting.edit.drag.inner);\r
518                                                 if (!canPrev && !canNext && !canInner) {\r
519                                                         tmpTarget = null;\r
520                                                         tmpTargetNodeId = "";\r
521                                                         moveType = consts.move.TYPE_INNER;\r
522                                                         tmpArrow.css({\r
523                                                                 "display":"none"\r
524                                                         });\r
525                                                         if (window.zTreeMoveTimer) {\r
526                                                                 clearTimeout(window.zTreeMoveTimer);\r
527                                                                 window.zTreeMoveTargetNodeTId = null\r
528                                                         }\r
529                                                 } else {\r
530                                                         var tmpTargetA = $("#" + tmpTargetNodeId + consts.id.A, tmpTarget),\r
531                                                         tmpNextA = tmpTargetNode.isLastNode ? null : $("#" + tmpTargetNode.getNextNode().tId + consts.id.A, tmpTarget.next()),\r
532                                                         tmpTop = tmpTargetA.offset().top,\r
533                                                         tmpLeft = tmpTargetA.offset().left,\r
534                                                         prevPercent = canPrev ? (canInner ? 0.25 : (canNext ? 0.5 : 1) ) : -1,\r
535                                                         nextPercent = canNext ? (canInner ? 0.75 : (canPrev ? 0.5 : 0) ) : -1,\r
536                                                         dY_percent = (event.clientY + docScrollTop - tmpTop)/tmpTargetA.height();\r
537                                                         if ((prevPercent==1 ||dY_percent<=prevPercent && dY_percent>=-.2) && canPrev) {\r
538                                                                 dX = 1 - tmpArrow.width();\r
539                                                                 dY = tmpTop - tmpArrow.height()/2;\r
540                                                                 moveType = consts.move.TYPE_PREV;\r
541                                                         } else if ((nextPercent==0 || dY_percent>=nextPercent && dY_percent<=1.2) && canNext) {\r
542                                                                 dX = 1 - tmpArrow.width();\r
543                                                                 dY = (tmpNextA == null || (tmpTargetNode.isParent && tmpTargetNode.open)) ? (tmpTop + tmpTargetA.height() - tmpArrow.height()/2) : (tmpNextA.offset().top - tmpArrow.height()/2);\r
544                                                                 moveType = consts.move.TYPE_NEXT;\r
545                                                         }else {\r
546                                                                 dX = 5 - tmpArrow.width();\r
547                                                                 dY = tmpTop;\r
548                                                                 moveType = consts.move.TYPE_INNER;\r
549                                                         }\r
550                                                         tmpArrow.css({\r
551                                                                 "display":"block",\r
552                                                                 "top": dY + "px",\r
553                                                                 "left": (tmpLeft + dX) + "px"\r
554                                                         });\r
555                                                         tmpTargetA.addClass(consts.node.TMPTARGET_NODE + "_" + moveType);\r
556 \r
557                                                         if (preTmpTargetNodeId != tmpTargetNodeId || preTmpMoveType != moveType) {\r
558                                                                 startTime = (new Date()).getTime();\r
559                                                         }\r
560                                                         if (tmpTargetNode && tmpTargetNode.isParent && moveType == consts.move.TYPE_INNER) {\r
561                                                                 var startTimer = true;\r
562                                                                 if (window.zTreeMoveTimer && window.zTreeMoveTargetNodeTId !== tmpTargetNode.tId) {\r
563                                                                         clearTimeout(window.zTreeMoveTimer);\r
564                                                                         window.zTreeMoveTargetNodeTId = null;\r
565                                                                 }else if (window.zTreeMoveTimer && window.zTreeMoveTargetNodeTId === tmpTargetNode.tId) {\r
566                                                                         startTimer = false;\r
567                                                                 }\r
568                                                                 if (startTimer) {\r
569                                                                         window.zTreeMoveTimer = setTimeout(function() {\r
570                                                                                 if (moveType != consts.move.TYPE_INNER) return;\r
571                                                                                 if (tmpTargetNode && tmpTargetNode.isParent && !tmpTargetNode.open && (new Date()).getTime() - startTime > targetSetting.edit.drag.autoOpenTime\r
572                                                                                         && tools.apply(targetSetting.callback.beforeDragOpen, [targetSetting.treeId, tmpTargetNode], true)) {\r
573                                                                                         view.switchNode(targetSetting, tmpTargetNode);\r
574                                                                                         if (targetSetting.edit.drag.autoExpandTrigger) {\r
575                                                                                                 targetSetting.treeObj.trigger(consts.event.EXPAND, [targetSetting.treeId, tmpTargetNode]);\r
576                                                                                         }\r
577                                                                                 }\r
578                                                                         }, targetSetting.edit.drag.autoOpenTime+50);\r
579                                                                         window.zTreeMoveTargetNodeTId = tmpTargetNode.tId;\r
580                                                                 }\r
581                                                         }\r
582                                                 }\r
583                                         } else {\r
584                                                 moveType = consts.move.TYPE_INNER;\r
585                                                 if (tmpTarget && tools.apply(targetSetting.edit.drag.inner, [targetSetting.treeId, nodes, null], !!targetSetting.edit.drag.inner)) {\r
586                                                         tmpTarget.addClass(consts.node.TMPTARGET_TREE);\r
587                                                 } else {\r
588                                                         tmpTarget = null;\r
589                                                 }\r
590                                                 tmpArrow.css({\r
591                                                         "display":"none"\r
592                                                 });\r
593                                                 if (window.zTreeMoveTimer) {\r
594                                                         clearTimeout(window.zTreeMoveTimer);\r
595                                                         window.zTreeMoveTargetNodeTId = null;\r
596                                                 }\r
597                                         }\r
598                                         preTmpTargetNodeId = tmpTargetNodeId;\r
599                                         preTmpMoveType = moveType;\r
600 \r
601                                         setting.treeObj.trigger(consts.event.DRAGMOVE, [event, setting.treeId, nodes]);\r
602                                 }\r
603                                 return false;\r
604                         }\r
605 \r
606                         doc.bind("mouseup", _docMouseUp);\r
607                         function _docMouseUp(event) {\r
608                                 if (window.zTreeMoveTimer) {\r
609                                         clearTimeout(window.zTreeMoveTimer);\r
610                                         window.zTreeMoveTargetNodeTId = null;\r
611                                 }\r
612                                 preTmpTargetNodeId = null;\r
613                                 preTmpMoveType = null;\r
614                                 doc.unbind("mousemove", _docMouseMove);\r
615                                 doc.unbind("mouseup", _docMouseUp);\r
616                                 doc.unbind("selectstart", _docSelect);\r
617                                 body.css("cursor", "auto");\r
618                                 if (tmpTarget) {\r
619                                         tmpTarget.removeClass(consts.node.TMPTARGET_TREE);\r
620                                         if (tmpTargetNodeId) $("#" + tmpTargetNodeId + consts.id.A, tmpTarget).removeClass(consts.node.TMPTARGET_NODE + "_" + consts.move.TYPE_PREV)\r
621                                                         .removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_NEXT).removeClass(consts.node.TMPTARGET_NODE + "_" + _consts.move.TYPE_INNER);\r
622                                 }\r
623                                 tools.showIfameMask(setting, false);\r
624 \r
625                                 roots.showHoverDom = true;\r
626                                 if (root.dragFlag == 0) return;\r
627                                 root.dragFlag = 0;\r
628 \r
629                                 var i, l, tmpNode;\r
630                                 for (i=0, l=nodes.length; i<l; i++) {\r
631                                         tmpNode = nodes[i];\r
632                                         if (tmpNode.isParent && root.dragNodeShowBefore[tmpNode.tId] && !tmpNode.open) {\r
633                                                 view.expandCollapseNode(setting, tmpNode, !tmpNode.open);\r
634                                                 delete root.dragNodeShowBefore[tmpNode.tId];\r
635                                         }\r
636                                 }\r
637 \r
638                                 if (curNode) curNode.remove();\r
639                                 if (tmpArrow) tmpArrow.remove();\r
640 \r
641                                 var isCopy = ((event.ctrlKey || event.metaKey) && setting.edit.drag.isMove && setting.edit.drag.isCopy) || (!setting.edit.drag.isMove && setting.edit.drag.isCopy);\r
642                                 if (!isCopy && tmpTarget && tmpTargetNodeId && nodes[0].parentTId && tmpTargetNodeId==nodes[0].parentTId && moveType == consts.move.TYPE_INNER) {\r
643                                         tmpTarget = null;\r
644                                 }\r
645                                 if (tmpTarget) {\r
646                                         var dragTargetNode = tmpTargetNodeId == null ? null: data.getNodeCache(targetSetting, tmpTargetNodeId);\r
647                                         if (tools.apply(setting.callback.beforeDrop, [targetSetting.treeId, nodes, dragTargetNode, moveType, isCopy], true) == false) {\r
648                                                 view.selectNodes(sourceSetting, nodes);\r
649                                                 return;\r
650                                         }\r
651                                         var newNodes = isCopy ? tools.clone(nodes) : nodes;\r
652 \r
653                                         function dropCallback() {\r
654                                                 if (isOtherTree) {\r
655                                                         if (!isCopy) {\r
656                                                                 for(var i=0, l=nodes.length; i<l; i++) {\r
657                                                                         view.removeNode(setting, nodes[i]);\r
658                                                                 }\r
659                                                         }\r
660                                                         if (moveType == consts.move.TYPE_INNER) {\r
661                                                                 view.addNodes(targetSetting, dragTargetNode, newNodes);\r
662                                                         } else {\r
663                                                                 view.addNodes(targetSetting, dragTargetNode.getParentNode(), newNodes);\r
664                                                                 if (moveType == consts.move.TYPE_PREV) {\r
665                                                                         for (i=0, l=newNodes.length; i<l; i++) {\r
666                                                                                 view.moveNode(targetSetting, dragTargetNode, newNodes[i], moveType, false);\r
667                                                                         }\r
668                                                                 } else {\r
669                                                                         for (i=-1, l=newNodes.length-1; i<l; l--) {\r
670                                                                                 view.moveNode(targetSetting, dragTargetNode, newNodes[l], moveType, false);\r
671                                                                         }\r
672                                                                 }\r
673                                                         }\r
674                                                 } else {\r
675                                                         if (isCopy && moveType == consts.move.TYPE_INNER) {\r
676                                                                 view.addNodes(targetSetting, dragTargetNode, newNodes);\r
677                                                         } else {\r
678                                                                 if (isCopy) {\r
679                                                                         view.addNodes(targetSetting, dragTargetNode.getParentNode(), newNodes);\r
680                                                                 }\r
681                                                                 if (moveType != consts.move.TYPE_NEXT) {\r
682                                                                         for (i=0, l=newNodes.length; i<l; i++) {\r
683                                                                                 view.moveNode(targetSetting, dragTargetNode, newNodes[i], moveType, false);\r
684                                                                         }\r
685                                                                 } else {\r
686                                                                         for (i=-1, l=newNodes.length-1; i<l; l--) {\r
687                                                                                 view.moveNode(targetSetting, dragTargetNode, newNodes[l], moveType, false);\r
688                                                                         }\r
689                                                                 }\r
690                                                         }\r
691                                                 }\r
692                                                 view.selectNodes(targetSetting, newNodes);\r
693                                                 $$(newNodes[0], setting).focus().blur();\r
694 \r
695                                                 setting.treeObj.trigger(consts.event.DROP, [event, targetSetting.treeId, newNodes, dragTargetNode, moveType, isCopy]);\r
696                                         }\r
697 \r
698                                         if (moveType == consts.move.TYPE_INNER && tools.canAsync(targetSetting, dragTargetNode)) {\r
699                                                 view.asyncNode(targetSetting, dragTargetNode, false, dropCallback);\r
700                                         } else {\r
701                                                 dropCallback();\r
702                                         }\r
703 \r
704                                 } else {\r
705                                         view.selectNodes(sourceSetting, nodes);\r
706                                         setting.treeObj.trigger(consts.event.DROP, [event, setting.treeId, nodes, null, null, null]);\r
707                                 }\r
708                         }\r
709 \r
710                         doc.bind("selectstart", _docSelect);\r
711                         function _docSelect() {\r
712                                 return false;\r
713                         }\r
714 \r
715                         //Avoid FireFox's Bug\r
716                         //If zTree Div CSS set 'overflow', so drag node outside of zTree, and event.target is error.\r
717                         if(eventMouseDown.preventDefault) {\r
718                                 eventMouseDown.preventDefault();\r
719                         }\r
720                         return true;\r
721                 }\r
722         },\r
723         //method of tools for zTree\r
724         _tools = {\r
725                 getAbs: function (obj) {\r
726                         var oRect = obj.getBoundingClientRect(),\r
727                         scrollTop = document.body.scrollTop+document.documentElement.scrollTop,\r
728                         scrollLeft = document.body.scrollLeft+document.documentElement.scrollLeft;\r
729                         return [oRect.left+scrollLeft,oRect.top+scrollTop];\r
730                 },\r
731                 inputFocus: function(inputObj) {\r
732                         if (inputObj.get(0)) {\r
733                                 inputObj.focus();\r
734                                 tools.setCursorPosition(inputObj.get(0), inputObj.val().length);\r
735                         }\r
736                 },\r
737                 inputSelect: function(inputObj) {\r
738                         if (inputObj.get(0)) {\r
739                                 inputObj.focus();\r
740                                 inputObj.select();\r
741                         }\r
742                 },\r
743                 setCursorPosition: function(obj, pos){\r
744                         if(obj.setSelectionRange) {\r
745                                 obj.focus();\r
746                                 obj.setSelectionRange(pos,pos);\r
747                         } else if (obj.createTextRange) {\r
748                                 var range = obj.createTextRange();\r
749                                 range.collapse(true);\r
750                                 range.moveEnd('character', pos);\r
751                                 range.moveStart('character', pos);\r
752                                 range.select();\r
753                         }\r
754                 },\r
755                 showIfameMask: function(setting, showSign) {\r
756                         var root = data.getRoot(setting);\r
757                         //clear full mask\r
758                         while (root.dragMaskList.length > 0) {\r
759                                 root.dragMaskList[0].remove();\r
760                                 root.dragMaskList.shift();\r
761                         }\r
762                         if (showSign) {\r
763                                 //show mask\r
764                                 var iframeList = $$("iframe", setting);\r
765                                 for (var i = 0, l = iframeList.length; i < l; i++) {\r
766                                         var obj = iframeList.get(i),\r
767                                         r = tools.getAbs(obj),\r
768                                         dragMask = $$("<div id='zTreeMask_" + i + "' class='zTreeMask' style='top:" + r[1] + "px; left:" + r[0] + "px; width:" + obj.offsetWidth + "px; height:" + obj.offsetHeight + "px;'></div>", setting);\r
769                                         dragMask.appendTo($$("body", setting));\r
770                                         root.dragMaskList.push(dragMask);\r
771                                 }\r
772                         }\r
773                 }\r
774         },\r
775         //method of operate ztree dom\r
776         _view = {\r
777                 addEditBtn: function(setting, node) {\r
778                         if (node.editNameFlag || $$(node, consts.id.EDIT, setting).length > 0) {\r
779                                 return;\r
780                         }\r
781                         if (!tools.apply(setting.edit.showRenameBtn, [setting.treeId, node], setting.edit.showRenameBtn)) {\r
782                                 return;\r
783                         }\r
784                         var aObj = $$(node, consts.id.A, setting),\r
785                         editStr = "<span class='" + consts.className.BUTTON + " edit' id='" + node.tId + consts.id.EDIT + "' title='"+tools.apply(setting.edit.renameTitle, [setting.treeId, node], setting.edit.renameTitle)+"' treeNode"+consts.id.EDIT+" style='display:none;'></span>";\r
786                         aObj.append(editStr);\r
787 \r
788                         $$(node, consts.id.EDIT, setting).bind('click',\r
789                                 function() {\r
790                                         if (!tools.uCanDo(setting) || tools.apply(setting.callback.beforeEditName, [setting.treeId, node], true) == false) return false;\r
791                                         view.editNode(setting, node);\r
792                                         return false;\r
793                                 }\r
794                                 ).show();\r
795                 },\r
796                 addRemoveBtn: function(setting, node) {\r
797                         if (node.editNameFlag || $$(node, consts.id.REMOVE, setting).length > 0) {\r
798                                 return;\r
799                         }\r
800                         if (!tools.apply(setting.edit.showRemoveBtn, [setting.treeId, node], setting.edit.showRemoveBtn)) {\r
801                                 return;\r
802                         }\r
803                         var aObj = $$(node, consts.id.A, setting),\r
804                         removeStr = "<span class='" + consts.className.BUTTON + " remove' id='" + node.tId + consts.id.REMOVE + "' title='"+tools.apply(setting.edit.removeTitle, [setting.treeId, node], setting.edit.removeTitle)+"' treeNode"+consts.id.REMOVE+" style='display:none;'></span>";\r
805                         aObj.append(removeStr);\r
806 \r
807                         $$(node, consts.id.REMOVE, setting).bind('click',\r
808                                 function() {\r
809                                         if (!tools.uCanDo(setting) || tools.apply(setting.callback.beforeRemove, [setting.treeId, node], true) == false) return false;\r
810                                         view.removeNode(setting, node);\r
811                                         setting.treeObj.trigger(consts.event.REMOVE, [setting.treeId, node]);\r
812                                         return false;\r
813                                 }\r
814                                 ).bind('mousedown',\r
815                                 function(eventMouseDown) {\r
816                                         return true;\r
817                                 }\r
818                                 ).show();\r
819                 },\r
820                 addHoverDom: function(setting, node) {\r
821                         if (data.getRoots().showHoverDom) {\r
822                                 node.isHover = true;\r
823                                 if (setting.edit.enable) {\r
824                                         view.addEditBtn(setting, node);\r
825                                         view.addRemoveBtn(setting, node);\r
826                                 }\r
827                                 tools.apply(setting.view.addHoverDom, [setting.treeId, node]);\r
828                         }\r
829                 },\r
830                 cancelCurEditNode: function (setting, forceName, isCancel) {\r
831                         var root = data.getRoot(setting),\r
832                         nameKey = setting.data.key.name,\r
833                         node = root.curEditNode;\r
834 \r
835                         if (node) {\r
836                                 var inputObj = root.curEditInput,\r
837                                 newName = forceName ? forceName:(isCancel ? node[nameKey]: inputObj.val());\r
838                                 if (tools.apply(setting.callback.beforeRename, [setting.treeId, node, newName, isCancel], true) === false) {\r
839                                         return false;\r
840                                 } else {\r
841                                         node[nameKey] = newName;\r
842                                         setting.treeObj.trigger(consts.event.RENAME, [setting.treeId, node, isCancel]);\r
843                                 }\r
844                                 var aObj = $$(node, consts.id.A, setting);\r
845                                 aObj.removeClass(consts.node.CURSELECTED_EDIT);\r
846                                 inputObj.unbind();\r
847                                 view.setNodeName(setting, node);\r
848                                 node.editNameFlag = false;\r
849                                 root.curEditNode = null;\r
850                                 root.curEditInput = null;\r
851                                 view.selectNode(setting, node, false);\r
852                         }\r
853                         root.noSelection = true;\r
854                         return true;\r
855                 },\r
856                 editNode: function(setting, node) {\r
857                         var root = data.getRoot(setting);\r
858                         view.editNodeBlur = false;\r
859                         if (data.isSelectedNode(setting, node) && root.curEditNode == node && node.editNameFlag) {\r
860                                 setTimeout(function() {tools.inputFocus(root.curEditInput);}, 0);\r
861                                 return;\r
862                         }\r
863                         var nameKey = setting.data.key.name;\r
864                         node.editNameFlag = true;\r
865                         view.removeTreeDom(setting, node);\r
866                         view.cancelCurEditNode(setting);\r
867                         view.selectNode(setting, node, false);\r
868                         $$(node, consts.id.SPAN, setting).html("<input type=text class='rename' id='" + node.tId + consts.id.INPUT + "' treeNode" + consts.id.INPUT + " >");\r
869                         var inputObj = $$(node, consts.id.INPUT, setting);\r
870                         inputObj.attr("value", node[nameKey]);\r
871                         if (setting.edit.editNameSelectAll) {\r
872                                 tools.inputSelect(inputObj);\r
873                         } else {\r
874                                 tools.inputFocus(inputObj);\r
875                         }\r
876 \r
877                         inputObj.bind('blur', function(event) {\r
878                                 if (!view.editNodeBlur) {\r
879                                         view.cancelCurEditNode(setting);\r
880                                 }\r
881                         }).bind('keydown', function(event) {\r
882                                 if (event.keyCode=="13") {\r
883                                         view.editNodeBlur = true;\r
884                                         view.cancelCurEditNode(setting);\r
885                                 } else if (event.keyCode=="27") {\r
886                                         view.cancelCurEditNode(setting, null, true);\r
887                                 }\r
888                         }).bind('click', function(event) {\r
889                                 return false;\r
890                         }).bind('dblclick', function(event) {\r
891                                 return false;\r
892                         });\r
893 \r
894                         $$(node, consts.id.A, setting).addClass(consts.node.CURSELECTED_EDIT);\r
895                         root.curEditInput = inputObj;\r
896                         root.noSelection = false;\r
897                         root.curEditNode = node;\r
898                 },\r
899                 moveNode: function(setting, targetNode, node, moveType, animateFlag, isSilent) {\r
900                         var root = data.getRoot(setting),\r
901                         childKey = setting.data.key.children;\r
902                         if (targetNode == node) return;\r
903                         if (setting.data.keep.leaf && targetNode && !targetNode.isParent && moveType == consts.move.TYPE_INNER) return;\r
904                         var oldParentNode = (node.parentTId ? node.getParentNode(): root),\r
905                         targetNodeIsRoot = (targetNode === null || targetNode == root);\r
906                         if (targetNodeIsRoot && targetNode === null) targetNode = root;\r
907                         if (targetNodeIsRoot) moveType = consts.move.TYPE_INNER;\r
908                         var targetParentNode = (targetNode.parentTId ? targetNode.getParentNode() : root);\r
909 \r
910                         if (moveType != consts.move.TYPE_PREV && moveType != consts.move.TYPE_NEXT) {\r
911                                 moveType = consts.move.TYPE_INNER;\r
912                         }\r
913 \r
914                         if (moveType == consts.move.TYPE_INNER) {\r
915                                 if (targetNodeIsRoot) {\r
916                                         //parentTId of root node is null\r
917                                         node.parentTId = null;\r
918                                 } else {\r
919                                         if (!targetNode.isParent) {\r
920                                                 targetNode.isParent = true;\r
921                                                 targetNode.open = !!targetNode.open;\r
922                                                 view.setNodeLineIcos(setting, targetNode);\r
923                                         }\r
924                                         node.parentTId = targetNode.tId;\r
925                                 }\r
926                         }\r
927 \r
928                         //move node Dom\r
929                         var targetObj, target_ulObj;\r
930                         if (targetNodeIsRoot) {\r
931                                 targetObj = setting.treeObj;\r
932                                 target_ulObj = targetObj;\r
933                         } else {\r
934                                 if (!isSilent && moveType == consts.move.TYPE_INNER) {\r
935                                         view.expandCollapseNode(setting, targetNode, true, false);\r
936                                 } else if (!isSilent) {\r
937                                         view.expandCollapseNode(setting, targetNode.getParentNode(), true, false);\r
938                                 }\r
939                                 targetObj = $$(targetNode, setting);\r
940                                 target_ulObj = $$(targetNode, consts.id.UL, setting);\r
941                                 if (!!targetObj.get(0) && !target_ulObj.get(0)) {\r
942                                         var ulstr = [];\r
943                                         view.makeUlHtml(setting, targetNode, ulstr, '');\r
944                                         targetObj.append(ulstr.join(''));\r
945                                 }\r
946                                 target_ulObj = $$(targetNode, consts.id.UL, setting);\r
947                         }\r
948                         var nodeDom = $$(node, setting);\r
949                         if (!nodeDom.get(0)) {\r
950                                 nodeDom = view.appendNodes(setting, node.level, [node], null, false, true).join('');\r
951                         } else if (!targetObj.get(0)) {\r
952                                 nodeDom.remove();\r
953                         }\r
954                         if (target_ulObj.get(0) && moveType == consts.move.TYPE_INNER) {\r
955                                 target_ulObj.append(nodeDom);\r
956                         } else if (targetObj.get(0) && moveType == consts.move.TYPE_PREV) {\r
957                                 targetObj.before(nodeDom);\r
958                         } else if (targetObj.get(0) && moveType == consts.move.TYPE_NEXT) {\r
959                                 targetObj.after(nodeDom);\r
960                         }\r
961 \r
962                         //repair the data after move\r
963                         var i,l,\r
964                         tmpSrcIndex = -1,\r
965                         tmpTargetIndex = 0,\r
966                         oldNeighbor = null,\r
967                         newNeighbor = null,\r
968                         oldLevel = node.level;\r
969                         if (node.isFirstNode) {\r
970                                 tmpSrcIndex = 0;\r
971                                 if (oldParentNode[childKey].length > 1 ) {\r
972                                         oldNeighbor = oldParentNode[childKey][1];\r
973                                         oldNeighbor.isFirstNode = true;\r
974                                 }\r
975                         } else if (node.isLastNode) {\r
976                                 tmpSrcIndex = oldParentNode[childKey].length -1;\r
977                                 oldNeighbor = oldParentNode[childKey][tmpSrcIndex - 1];\r
978                                 oldNeighbor.isLastNode = true;\r
979                         } else {\r
980                                 for (i = 0, l = oldParentNode[childKey].length; i < l; i++) {\r
981                                         if (oldParentNode[childKey][i].tId == node.tId) {\r
982                                                 tmpSrcIndex = i;\r
983                                                 break;\r
984                                         }\r
985                                 }\r
986                         }\r
987                         if (tmpSrcIndex >= 0) {\r
988                                 oldParentNode[childKey].splice(tmpSrcIndex, 1);\r
989                         }\r
990                         if (moveType != consts.move.TYPE_INNER) {\r
991                                 for (i = 0, l = targetParentNode[childKey].length; i < l; i++) {\r
992                                         if (targetParentNode[childKey][i].tId == targetNode.tId) tmpTargetIndex = i;\r
993                                 }\r
994                         }\r
995                         if (moveType == consts.move.TYPE_INNER) {\r
996                                 if (!targetNode[childKey]) targetNode[childKey] = new Array();\r
997                                 if (targetNode[childKey].length > 0) {\r
998                                         newNeighbor = targetNode[childKey][targetNode[childKey].length - 1];\r
999                                         newNeighbor.isLastNode = false;\r
1000                                 }\r
1001                                 targetNode[childKey].splice(targetNode[childKey].length, 0, node);\r
1002                                 node.isLastNode = true;\r
1003                                 node.isFirstNode = (targetNode[childKey].length == 1);\r
1004                         } else if (targetNode.isFirstNode && moveType == consts.move.TYPE_PREV) {\r
1005                                 targetParentNode[childKey].splice(tmpTargetIndex, 0, node);\r
1006                                 newNeighbor = targetNode;\r
1007                                 newNeighbor.isFirstNode = false;\r
1008                                 node.parentTId = targetNode.parentTId;\r
1009                                 node.isFirstNode = true;\r
1010                                 node.isLastNode = false;\r
1011 \r
1012                         } else if (targetNode.isLastNode && moveType == consts.move.TYPE_NEXT) {\r
1013                                 targetParentNode[childKey].splice(tmpTargetIndex + 1, 0, node);\r
1014                                 newNeighbor = targetNode;\r
1015                                 newNeighbor.isLastNode = false;\r
1016                                 node.parentTId = targetNode.parentTId;\r
1017                                 node.isFirstNode = false;\r
1018                                 node.isLastNode = true;\r
1019 \r
1020                         } else {\r
1021                                 if (moveType == consts.move.TYPE_PREV) {\r
1022                                         targetParentNode[childKey].splice(tmpTargetIndex, 0, node);\r
1023                                 } else {\r
1024                                         targetParentNode[childKey].splice(tmpTargetIndex + 1, 0, node);\r
1025                                 }\r
1026                                 node.parentTId = targetNode.parentTId;\r
1027                                 node.isFirstNode = false;\r
1028                                 node.isLastNode = false;\r
1029                         }\r
1030                         data.fixPIdKeyValue(setting, node);\r
1031                         data.setSonNodeLevel(setting, node.getParentNode(), node);\r
1032 \r
1033                         //repair node what been moved\r
1034                         view.setNodeLineIcos(setting, node);\r
1035                         view.repairNodeLevelClass(setting, node, oldLevel)\r
1036 \r
1037                         //repair node's old parentNode dom\r
1038                         if (!setting.data.keep.parent && oldParentNode[childKey].length < 1) {\r
1039                                 //old parentNode has no child nodes\r
1040                                 oldParentNode.isParent = false;\r
1041                                 oldParentNode.open = false;\r
1042                                 var tmp_ulObj = $$(oldParentNode, consts.id.UL, setting),\r
1043                                 tmp_switchObj = $$(oldParentNode, consts.id.SWITCH, setting),\r
1044                                 tmp_icoObj = $$(oldParentNode, consts.id.ICON, setting);\r
1045                                 view.replaceSwitchClass(oldParentNode, tmp_switchObj, consts.folder.DOCU);\r
1046                                 view.replaceIcoClass(oldParentNode, tmp_icoObj, consts.folder.DOCU);\r
1047                                 tmp_ulObj.css("display", "none");\r
1048 \r
1049                         } else if (oldNeighbor) {\r
1050                                 //old neigbor node\r
1051                                 view.setNodeLineIcos(setting, oldNeighbor);\r
1052                         }\r
1053 \r
1054                         //new neigbor node\r
1055                         if (newNeighbor) {\r
1056                                 view.setNodeLineIcos(setting, newNeighbor);\r
1057                         }\r
1058 \r
1059                         //repair checkbox / radio\r
1060                         if (!!setting.check && setting.check.enable && view.repairChkClass) {\r
1061                                 view.repairChkClass(setting, oldParentNode);\r
1062                                 view.repairParentChkClassWithSelf(setting, oldParentNode);\r
1063                                 if (oldParentNode != node.parent)\r
1064                                         view.repairParentChkClassWithSelf(setting, node);\r
1065                         }\r
1066 \r
1067                         //expand parents after move\r
1068                         if (!isSilent) {\r
1069                                 view.expandCollapseParentNode(setting, node.getParentNode(), true, animateFlag);\r
1070                         }\r
1071                 },\r
1072                 removeEditBtn: function(setting, node) {\r
1073                         $$(node, consts.id.EDIT, setting).unbind().remove();\r
1074                 },\r
1075                 removeRemoveBtn: function(setting, node) {\r
1076                         $$(node, consts.id.REMOVE, setting).unbind().remove();\r
1077                 },\r
1078                 removeTreeDom: function(setting, node) {\r
1079                         node.isHover = false;\r
1080                         view.removeEditBtn(setting, node);\r
1081                         view.removeRemoveBtn(setting, node);\r
1082                         tools.apply(setting.view.removeHoverDom, [setting.treeId, node]);\r
1083                 },\r
1084                 repairNodeLevelClass: function(setting, node, oldLevel) {\r
1085                         if (oldLevel === node.level) return;\r
1086                         var liObj = $$(node, setting),\r
1087                         aObj = $$(node, consts.id.A, setting),\r
1088                         ulObj = $$(node, consts.id.UL, setting),\r
1089                         oldClass = consts.className.LEVEL + oldLevel,\r
1090                         newClass = consts.className.LEVEL + node.level;\r
1091                         liObj.removeClass(oldClass);\r
1092                         liObj.addClass(newClass);\r
1093                         aObj.removeClass(oldClass);\r
1094                         aObj.addClass(newClass);\r
1095                         ulObj.removeClass(oldClass);\r
1096                         ulObj.addClass(newClass);\r
1097                 },\r
1098                 selectNodes : function(setting, nodes) {\r
1099                         for (var i=0, l=nodes.length; i<l; i++) {\r
1100                                 view.selectNode(setting, nodes[i], i>0);\r
1101                         }\r
1102                 }\r
1103         },\r
1104 \r
1105         _z = {\r
1106                 tools: _tools,\r
1107                 view: _view,\r
1108                 event: _event,\r
1109                 data: _data\r
1110         };\r
1111         $.extend(true, $.fn.zTree.consts, _consts);\r
1112         $.extend(true, $.fn.zTree._z, _z);\r
1113 \r
1114         var zt = $.fn.zTree,\r
1115         tools = zt._z.tools,\r
1116         consts = zt.consts,\r
1117         view = zt._z.view,\r
1118         data = zt._z.data,\r
1119         event = zt._z.event,\r
1120         $$ = tools.$;\r
1121 \r
1122         data.exSetting(_setting);\r
1123         data.addInitBind(_bindEvent);\r
1124         data.addInitUnBind(_unbindEvent);\r
1125         data.addInitCache(_initCache);\r
1126         data.addInitNode(_initNode);\r
1127         data.addInitProxy(_eventProxy);\r
1128         data.addInitRoot(_initRoot);\r
1129         data.addZTreeTools(_zTreeTools);\r
1130 \r
1131         var _cancelPreSelectedNode = view.cancelPreSelectedNode;\r
1132         view.cancelPreSelectedNode = function (setting, node) {\r
1133                 var list = data.getRoot(setting).curSelectedList;\r
1134                 for (var i=0, j=list.length; i<j; i++) {\r
1135                         if (!node || node === list[i]) {\r
1136                                 view.removeTreeDom(setting, list[i]);\r
1137                                 if (node) break;\r
1138                         }\r
1139                 }\r
1140                 if (_cancelPreSelectedNode) _cancelPreSelectedNode.apply(view, arguments);\r
1141         }\r
1142 \r
1143         var _createNodes = view.createNodes;\r
1144         view.createNodes = function(setting, level, nodes, parentNode) {\r
1145                 if (_createNodes) {\r
1146                         _createNodes.apply(view, arguments);\r
1147                 }\r
1148                 if (!nodes) return;\r
1149                 if (view.repairParentChkClassWithSelf) {\r
1150                         view.repairParentChkClassWithSelf(setting, parentNode);\r
1151                 }\r
1152         }\r
1153 \r
1154         var _makeNodeUrl = view.makeNodeUrl;\r
1155         view.makeNodeUrl = function(setting, node) {\r
1156                 return setting.edit.enable ? null : (_makeNodeUrl.apply(view, arguments));\r
1157         }\r
1158 \r
1159         var _removeNode = view.removeNode;\r
1160         view.removeNode = function(setting, node) {\r
1161                 var root = data.getRoot(setting);\r
1162                 if (root.curEditNode === node) root.curEditNode = null;\r
1163                 if (_removeNode) {\r
1164                         _removeNode.apply(view, arguments);\r
1165                 }\r
1166         }\r
1167 \r
1168         var _selectNode = view.selectNode;\r
1169         view.selectNode = function(setting, node, addFlag) {\r
1170                 var root = data.getRoot(setting);\r
1171                 if (data.isSelectedNode(setting, node) && root.curEditNode == node && node.editNameFlag) {\r
1172                         return false;\r
1173                 }\r
1174                 if (_selectNode) _selectNode.apply(view, arguments);\r
1175                 view.addHoverDom(setting, node);\r
1176                 return true;\r
1177         }\r
1178 \r
1179         var _uCanDo = tools.uCanDo;\r
1180         tools.uCanDo = function(setting, e) {\r
1181                 var root = data.getRoot(setting);\r
1182                 if (e && (tools.eqs(e.type, "mouseover") || tools.eqs(e.type, "mouseout") || tools.eqs(e.type, "mousedown") || tools.eqs(e.type, "mouseup"))) {\r
1183                         return true;\r
1184                 }\r
1185                 if (root.curEditNode) {\r
1186                         view.editNodeBlur = false;\r
1187                         root.curEditInput.focus();\r
1188                 }\r
1189                 return (!root.curEditNode) && (_uCanDo ? _uCanDo.apply(view, arguments) : true);\r
1190         }\r
1191 })(jQuery);