1 /** 2 * @fileOverview generate proxy drag object, 3 * @author yiminghe@gmail.com 4 */ 5 KISSY.add("dd/proxy", function (S, Node, Base, DDM) { 6 var DESTRUCTOR_ID = "__proxy_destructors", 7 stamp = S.stamp, 8 MARKER = S.guid("__dd_proxy"); 9 10 /** 11 * @name Proxy 12 * @memberOf DD 13 * @extends Base 14 * @class 15 * provide abilities for draggable tp create a proxy drag node, 16 * instead of dragging the original node. 17 */ 18 function Proxy() { 19 var self = this; 20 Proxy.superclass.constructor.apply(self, arguments); 21 self[DESTRUCTOR_ID] = {}; 22 } 23 24 Proxy.ATTRS = 25 /** 26 * @lends DD.Proxy# 27 */ 28 { 29 /** 30 * how to get the proxy node. default:clone the node itself deeply. 31 * @type {Function} 32 */ 33 node:{ 34 value:function (drag) { 35 return new Node(drag.get("node").clone(true)); 36 } 37 }, 38 /** 39 * destroy the proxy node at the end of this drag. default:false 40 * @type {Boolean} 41 */ 42 destroyOnEnd:{ 43 value:false 44 }, 45 46 /** 47 * move the original node at the end of the drag. default:true 48 * @type {Boolean} 49 */ 50 moveOnEnd:{ 51 value:true 52 }, 53 54 /** 55 * Current proxy node. 56 * @type {NodeList} 57 */ 58 proxyNode:{ 59 60 } 61 }; 62 63 S.extend(Proxy, Base, 64 /** 65 * @lends DD.Proxy# 66 */ 67 { 68 /** 69 * make this draggable object can be proxied. 70 * @param {DD.Draggable} drag 71 */ 72 attachDrag:function (drag) { 73 74 var self = this, 75 tag = stamp(drag, 1, MARKER); 76 77 if (tag && self[DESTRUCTOR_ID][tag]) { 78 return; 79 } 80 81 function start() { 82 var node = self.get("node"), 83 dragNode = drag.get("node"); 84 // cache proxy node 85 if (!self.get("proxyNode")) { 86 if (S.isFunction(node)) { 87 node = node(drag); 88 node.addClass("ks-dd-proxy"); 89 node.css("position", "absolute"); 90 self.set("proxyNode", node); 91 } 92 } else { 93 node = self.get("proxyNode"); 94 } 95 node.show(); 96 dragNode.parent().append(node); 97 DDM.cacheWH(node); 98 node.offset(dragNode.offset()); 99 drag.__set("dragNode", dragNode); 100 drag.__set("node", node); 101 } 102 103 function end() { 104 var node = self.get("proxyNode"); 105 if (self.get("moveOnEnd")) { 106 drag.get("dragNode").offset(node.offset()); 107 } 108 if (self.get("destroyOnEnd")) { 109 node.remove(); 110 self.set("proxyNode", 0); 111 } else { 112 node.hide(); 113 } 114 drag.__set("node", drag.get("dragNode")); 115 } 116 117 drag.on("dragstart", start); 118 drag.on("dragend", end); 119 120 tag = stamp(drag, 0, MARKER); 121 122 self[DESTRUCTOR_ID][tag] = { 123 drag:drag, 124 fn:function () { 125 drag.detach("dragstart", start); 126 drag.detach("dragend", end); 127 } 128 }; 129 }, 130 /** 131 * make this draggable object unproxied 132 * @param {DD.Draggable} drag 133 */ 134 detachDrag:function (drag) { 135 var self = this, 136 tag = stamp(drag, 1, MARKER), 137 destructors = self[DESTRUCTOR_ID]; 138 if (tag && destructors[tag]) { 139 destructors[tag].fn(); 140 delete destructors[tag]; 141 } 142 }, 143 144 /** 145 * make all draggable object associated with this proxy object unproxied 146 */ 147 destroy:function () { 148 var self = this, 149 node = self.get("node"), 150 destructors = self[DESTRUCTOR_ID]; 151 if (node && !S.isFunction(node)) { 152 node.remove(); 153 } 154 for (var d in destructors) { 155 this.detachDrag(destructors[d].drag); 156 } 157 } 158 }); 159 160 // for compatibility 161 var ProxyPrototype = Proxy.prototype; 162 ProxyPrototype.attach = ProxyPrototype.attachDrag; 163 ProxyPrototype.unAttach = ProxyPrototype.detachDrag; 164 165 return Proxy; 166 }, { 167 requires:['node', 'base', './ddm'] 168 });