summaryrefslogtreecommitdiff
path: root/frontend/beta/js/YUI-extensions/tree/TreeDropZone.js
Unidiff
Diffstat (limited to 'frontend/beta/js/YUI-extensions/tree/TreeDropZone.js') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/beta/js/YUI-extensions/tree/TreeDropZone.js228
1 files changed, 228 insertions, 0 deletions
diff --git a/frontend/beta/js/YUI-extensions/tree/TreeDropZone.js b/frontend/beta/js/YUI-extensions/tree/TreeDropZone.js
new file mode 100644
index 0000000..91c24e1
--- a/dev/null
+++ b/frontend/beta/js/YUI-extensions/tree/TreeDropZone.js
@@ -0,0 +1,228 @@
1YAHOO.ext.tree.TreeDropZone = function(tree, config){
2 this.allowParentInsert = false;
3 this.allowContainerDrop = false;
4 this.appendOnly = false;
5 YAHOO.ext.tree.TreeDropZone.superclass.constructor.call(this, tree.container, config);
6 this.tree = tree;
7 this.lastInsertClass = 'ytree-no-status';
8 this.dragOverData = {};
9};
10
11YAHOO.extendX(YAHOO.ext.tree.TreeDropZone, YAHOO.ext.dd.DropZone, {
12 ddGroup : 'TreeDD',
13
14 expandDelay : 1000,
15
16 expandNode : function(node){
17 if(node.hasChildNodes() && !node.isExpanded()){
18 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
19 }
20 },
21
22 queueExpand : function(node){
23 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
24 },
25
26 cancelExpand : function(){
27 if(this.expandProcId){
28 clearTimeout(this.expandProcId);
29 this.expandProcId = false;
30 }
31 },
32
33 isValidDropPoint : function(n, pt, dd, e, data){
34 if(!n || !data){ return false; }
35 var targetNode = n.node;
36 var dropNode = data.node;
37 // default drop rules
38 if(!(targetNode && targetNode.isTarget && pt)){
39 return false;
40 }
41 if(pt == 'append' && targetNode.allowChildren === false){
42 return false;
43 }
44 if((pt == 'above' || pt == 'below') && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
45 return false;
46 }
47 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
48 return false;
49 }
50 // reuse the object
51 var overEvent = this.dragOverData;
52 overEvent.tree = this.tree;
53 overEvent.target = targetNode;
54 overEvent.data = data;
55 overEvent.point = pt;
56 overEvent.source = dd;
57 overEvent.rawEvent = e;
58 overEvent.dropNode = dropNode;
59 overEvent.cancel = false;
60 var result = this.tree.fireEvent('nodedragover', overEvent);
61 return overEvent.cancel === false && result !== false;
62 },
63
64 getDropPoint : function(e, n, dd){
65 var tn = n.node;
66 if(tn.isRoot){
67 return tn.allowChildren !== false ? 'ap-pend' : false; // always append for root
68 }
69 var dragEl = n.ddel;
70 var t = YAHOO.util.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
71 var y = YAHOO.util.Event.getPageY(e);
72 var noAppend = tn.allowChildren === false || tn.isLeaf();
73 if(this.appendOnly || tn.parentNode.allowChildren === false){
74 return noAppend ? false : 'append';
75 }
76 var noBelow = false;
77 if(!this.allowParentInsert){
78 noBelow = tn.hasChildNodes() && tn.isExpanded();
79 }
80 var q = (b - t) / (noAppend ? 2 : 3);
81 if(y >= t && y < t + q){
82 return 'above';
83 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
84 return 'below';
85 }else{
86 return 'append';
87 }
88 return false;
89 },
90
91 onNodeEnter : function(n, dd, e, data){
92 this.cancelExpand();
93 },
94
95 onNodeOver : function(n, dd, e, data){
96 var pt = this.getDropPoint(e, n, dd);
97 var node = n.node;
98
99 // auto node expand check
100 if(!this.expandProcId && pt == 'append' && node.hasChildNodes() && !n.node.isExpanded()){
101 this.queueExpand(node);
102 }else if(pt != 'append'){
103 this.cancelExpand();
104 }
105
106 // set the insert point style on the target node
107 var returnCls = this.dropNotAllowed;
108 if(this.isValidDropPoint(n, pt, dd, e, data)){
109 if(pt){
110 var el = n.ddel;
111 var cls, returnCls;
112 if(pt == 'above'){
113 returnCls = n.node.isFirst() ? 'ytree-drop-ok-above' : 'ytree-drop-ok-between';
114 cls = 'ytree-drag-insert-above';
115 }else if(pt == 'below'){
116 returnCls = n.node.isLast() ? 'ytree-drop-ok-below' : 'ytree-drop-ok-between';
117 cls = 'ytree-drag-insert-below';
118 }else{
119 returnCls = 'ytree-drop-ok-append';
120 cls = 'ytree-drag-append';
121 }
122 if(this.lastInsertClass != cls){
123 YAHOO.util.Dom.replaceClass(el, this.lastInsertClass, cls);
124 this.lastInsertClass = cls;
125 }
126 }
127 }
128 return returnCls;
129 },
130
131 onNodeOut : function(n, dd, e, data){
132 this.cancelExpand();
133 this.removeDropIndicators(n);
134 },
135
136 onNodeDrop : function(n, dd, e, data){
137 var point = this.getDropPoint(e, n, dd);
138 var targetNode = n.node;
139 targetNode.ui.startDrop();
140 if(!this.isValidDropPoint(n, point, dd, e, data)){
141 targetNode.ui.endDrop();
142 return false;
143 }
144 // first try to find the drop node
145 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
146 var dropEvent = {
147 tree : this.tree,
148 target: targetNode,
149 data: data,
150 point: point,
151 source: dd,
152 rawEvent: e,
153 dropNode: dropNode,
154 cancel: dropNode ? false : true
155 };
156 var retval = this.tree.fireEvent('beforenodedrop', dropEvent);
157 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
158 targetNode.ui.endDrop();
159 return false;
160 }
161 if(point == 'append' && !targetNode.isExpanded()){
162 targetNode.expand(false, null, function(){
163 this.completeDrop(dropEvent);
164 }.createDelegate(this));
165 }else{
166 this.completeDrop(dropEvent);
167 }
168 return true;
169 },
170
171 completeDrop : function(de){
172 var ns = de.dropNode, p = de.point, t = de.target;
173 if(!(ns instanceof Array)){
174 ns = [ns];
175 }
176 var n;
177 for(var i = 0, len = ns.length; i < len; i++){
178 n = ns[i];
179 if(p == 'above'){
180 t.parentNode.insertBefore(n, t);
181 }else if(p == 'below'){
182 t.parentNode.insertBefore(n, t.nextSibling);
183 }else{
184 t.appendChild(n);
185 }
186 }
187 n.select(); // select and highlight the last insert
188 if(this.tree.hlDrop){
189 n.ui.highlight();
190 }
191 t.ui.endDrop();
192 this.tree.fireEvent('nodedrop', de);
193 },
194
195 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
196 if(this.tree.hlDrop){
197 dropNode.select();
198 dropNode.ui.highlight();
199 }
200 this.tree.fireEvent('nodedrop', this.tree, targetNode, data, dd, e);
201 },
202
203 getTree : function(){
204 return this.tree;
205 },
206
207 removeDropIndicators : function(n){
208 if(n && n.ddel){
209 var el = n.ddel;
210 YAHOO.util.Dom.removeClass(el, 'ytree-drag-insert-above');
211 YAHOO.util.Dom.removeClass(el, 'ytree-drag-insert-below');
212 YAHOO.util.Dom.removeClass(el, 'ytree-drag-append');
213 this.lastInsertClass = '_noclass';
214 }
215 },
216
217 beforeDragDrop : function(target, e, id){
218 this.cancelExpand();
219 return true;
220 },
221
222 afterRepair : function(data){
223 if(data){
224 data.node.ui.highlight();
225 }
226 this.hideProxy();
227 }
228});