summaryrefslogtreecommitdiff
path: root/frontend/beta/js/YUI-extensions/tree/TreeDropZone.js
Side-by-side diff
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 @@
+YAHOO.ext.tree.TreeDropZone = function(tree, config){
+ this.allowParentInsert = false;
+ this.allowContainerDrop = false;
+ this.appendOnly = false;
+ YAHOO.ext.tree.TreeDropZone.superclass.constructor.call(this, tree.container, config);
+ this.tree = tree;
+ this.lastInsertClass = 'ytree-no-status';
+ this.dragOverData = {};
+};
+
+YAHOO.extendX(YAHOO.ext.tree.TreeDropZone, YAHOO.ext.dd.DropZone, {
+ ddGroup : 'TreeDD',
+
+ expandDelay : 1000,
+
+ expandNode : function(node){
+ if(node.hasChildNodes() && !node.isExpanded()){
+ node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
+ }
+ },
+
+ queueExpand : function(node){
+ this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
+ },
+
+ cancelExpand : function(){
+ if(this.expandProcId){
+ clearTimeout(this.expandProcId);
+ this.expandProcId = false;
+ }
+ },
+
+ isValidDropPoint : function(n, pt, dd, e, data){
+ if(!n || !data){ return false; }
+ var targetNode = n.node;
+ var dropNode = data.node;
+ // default drop rules
+ if(!(targetNode && targetNode.isTarget && pt)){
+ return false;
+ }
+ if(pt == 'append' && targetNode.allowChildren === false){
+ return false;
+ }
+ if((pt == 'above' || pt == 'below') && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
+ return false;
+ }
+ if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
+ return false;
+ }
+ // reuse the object
+ var overEvent = this.dragOverData;
+ overEvent.tree = this.tree;
+ overEvent.target = targetNode;
+ overEvent.data = data;
+ overEvent.point = pt;
+ overEvent.source = dd;
+ overEvent.rawEvent = e;
+ overEvent.dropNode = dropNode;
+ overEvent.cancel = false;
+ var result = this.tree.fireEvent('nodedragover', overEvent);
+ return overEvent.cancel === false && result !== false;
+ },
+
+ getDropPoint : function(e, n, dd){
+ var tn = n.node;
+ if(tn.isRoot){
+ return tn.allowChildren !== false ? 'ap-pend' : false; // always append for root
+ }
+ var dragEl = n.ddel;
+ var t = YAHOO.util.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
+ var y = YAHOO.util.Event.getPageY(e);
+ var noAppend = tn.allowChildren === false || tn.isLeaf();
+ if(this.appendOnly || tn.parentNode.allowChildren === false){
+ return noAppend ? false : 'append';
+ }
+ var noBelow = false;
+ if(!this.allowParentInsert){
+ noBelow = tn.hasChildNodes() && tn.isExpanded();
+ }
+ var q = (b - t) / (noAppend ? 2 : 3);
+ if(y >= t && y < t + q){
+ return 'above';
+ }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
+ return 'below';
+ }else{
+ return 'append';
+ }
+ return false;
+ },
+
+ onNodeEnter : function(n, dd, e, data){
+ this.cancelExpand();
+ },
+
+ onNodeOver : function(n, dd, e, data){
+ var pt = this.getDropPoint(e, n, dd);
+ var node = n.node;
+
+ // auto node expand check
+ if(!this.expandProcId && pt == 'append' && node.hasChildNodes() && !n.node.isExpanded()){
+ this.queueExpand(node);
+ }else if(pt != 'append'){
+ this.cancelExpand();
+ }
+
+ // set the insert point style on the target node
+ var returnCls = this.dropNotAllowed;
+ if(this.isValidDropPoint(n, pt, dd, e, data)){
+ if(pt){
+ var el = n.ddel;
+ var cls, returnCls;
+ if(pt == 'above'){
+ returnCls = n.node.isFirst() ? 'ytree-drop-ok-above' : 'ytree-drop-ok-between';
+ cls = 'ytree-drag-insert-above';
+ }else if(pt == 'below'){
+ returnCls = n.node.isLast() ? 'ytree-drop-ok-below' : 'ytree-drop-ok-between';
+ cls = 'ytree-drag-insert-below';
+ }else{
+ returnCls = 'ytree-drop-ok-append';
+ cls = 'ytree-drag-append';
+ }
+ if(this.lastInsertClass != cls){
+ YAHOO.util.Dom.replaceClass(el, this.lastInsertClass, cls);
+ this.lastInsertClass = cls;
+ }
+ }
+ }
+ return returnCls;
+ },
+
+ onNodeOut : function(n, dd, e, data){
+ this.cancelExpand();
+ this.removeDropIndicators(n);
+ },
+
+ onNodeDrop : function(n, dd, e, data){
+ var point = this.getDropPoint(e, n, dd);
+ var targetNode = n.node;
+ targetNode.ui.startDrop();
+ if(!this.isValidDropPoint(n, point, dd, e, data)){
+ targetNode.ui.endDrop();
+ return false;
+ }
+ // first try to find the drop node
+ var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
+ var dropEvent = {
+ tree : this.tree,
+ target: targetNode,
+ data: data,
+ point: point,
+ source: dd,
+ rawEvent: e,
+ dropNode: dropNode,
+ cancel: dropNode ? false : true
+ };
+ var retval = this.tree.fireEvent('beforenodedrop', dropEvent);
+ if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
+ targetNode.ui.endDrop();
+ return false;
+ }
+ if(point == 'append' && !targetNode.isExpanded()){
+ targetNode.expand(false, null, function(){
+ this.completeDrop(dropEvent);
+ }.createDelegate(this));
+ }else{
+ this.completeDrop(dropEvent);
+ }
+ return true;
+ },
+
+ completeDrop : function(de){
+ var ns = de.dropNode, p = de.point, t = de.target;
+ if(!(ns instanceof Array)){
+ ns = [ns];
+ }
+ var n;
+ for(var i = 0, len = ns.length; i < len; i++){
+ n = ns[i];
+ if(p == 'above'){
+ t.parentNode.insertBefore(n, t);
+ }else if(p == 'below'){
+ t.parentNode.insertBefore(n, t.nextSibling);
+ }else{
+ t.appendChild(n);
+ }
+ }
+ n.select(); // select and highlight the last insert
+ if(this.tree.hlDrop){
+ n.ui.highlight();
+ }
+ t.ui.endDrop();
+ this.tree.fireEvent('nodedrop', de);
+ },
+
+ afterNodeMoved : function(dd, data, e, targetNode, dropNode){
+ if(this.tree.hlDrop){
+ dropNode.select();
+ dropNode.ui.highlight();
+ }
+ this.tree.fireEvent('nodedrop', this.tree, targetNode, data, dd, e);
+ },
+
+ getTree : function(){
+ return this.tree;
+ },
+
+ removeDropIndicators : function(n){
+ if(n && n.ddel){
+ var el = n.ddel;
+ YAHOO.util.Dom.removeClass(el, 'ytree-drag-insert-above');
+ YAHOO.util.Dom.removeClass(el, 'ytree-drag-insert-below');
+ YAHOO.util.Dom.removeClass(el, 'ytree-drag-append');
+ this.lastInsertClass = '_noclass';
+ }
+ },
+
+ beforeDragDrop : function(target, e, id){
+ this.cancelExpand();
+ return true;
+ },
+
+ afterRepair : function(data){
+ if(data){
+ data.node.ui.highlight();
+ }
+ this.hideProxy();
+ }
+});