1 /** 2 * @fileOverview droppable for kissy 3 * @author yiminghe@gmail.com 4 */ 5 KISSY.add("dd/droppable", function (S, Node, Base, DDM) { 6 7 var PREFIX_CLS = DDM.PREFIX_CLS; 8 9 /** 10 * @name Droppable 11 * @memberOf DD 12 * @class 13 * Make a node droppable. 14 */ 15 function Droppable() { 16 var self = this; 17 Droppable.superclass.constructor.apply(self, arguments); 18 self.addTarget(DDM); 19 S.each([ 20 /** 21 * @name DD.DDM#dropexit 22 * @description fired after a draggable leaves a droppable 23 * @event 24 * @param e 25 * @param e.drag current draggable object 26 * @param e.drop current droppable object 27 */ 28 29 /** 30 * @name DD.Droppable#dropexit 31 * @description fired after a draggable leaves a droppable 32 * @event 33 * @param e 34 * @param e.drag current draggable object 35 * @param e.drop current droppable object 36 */ 37 "dropexit", 38 39 /** 40 * @name DD.DDM#dropenter 41 * @description fired after a draggable object mouseenter a droppable object 42 * @event 43 * @param e 44 * @param e.drag current draggable object 45 * @param e.drop current droppable object 46 */ 47 48 /** 49 * @name DD.Droppable#dropenter 50 * @description fired after a draggable object mouseenter a droppable object 51 * @event 52 * @param e 53 * @param e.drag current draggable object 54 * @param e.drop current droppable object 55 */ 56 57 "dropenter", 58 59 /** 60 * @name DD.DDM#dropover 61 * @description fired after a draggable object mouseover a droppable object 62 * @event 63 * @param e 64 * @param e.drag current draggable object 65 * @param e.drop current droppable object 66 */ 67 68 /** 69 * @name DD.Droppable#dropover 70 * @description fired after a draggable object mouseover a droppable object 71 * @event 72 * @param e 73 * @param e.drag current draggable object 74 * @param e.drop current droppable object 75 */ 76 "dropover", 77 78 /** 79 * @name DD.DDM#drophit 80 * @description fired after drop a draggable onto a droppable object 81 * @event 82 * @param e 83 * @param e.drag current draggable object 84 * @param e.drop current droppable object 85 */ 86 87 /** 88 * @name DD.Droppable#drophit 89 * @description fired after drop a draggable onto a droppable object 90 * @event 91 * @param e 92 * @param e.drag current draggable object 93 * @param e.drop current droppable object 94 */ 95 "drophit" 96 ], function (e) { 97 self.publish(e, { 98 bubbles:1 99 }); 100 }); 101 self._init(); 102 } 103 104 Droppable.ATTRS = 105 /** 106 * @lends DD.Droppable# 107 */ 108 { 109 /** 110 * droppable element 111 * @type String|HTMLElement 112 */ 113 node:{ 114 setter:function (v) { 115 if (v) { 116 return Node.one(v); 117 } 118 } 119 }, 120 121 /** 122 * groups this droppable object belongs to. Default:true 123 * @type Object|Boolean true to match any group 124 */ 125 groups:{ 126 value:true 127 } 128 129 }; 130 131 function validDrop(dropGroups, dragGroups) { 132 if (dropGroups === true) { 133 return 1; 134 } 135 for (var d in dropGroups) { 136 if (dragGroups[d]) { 137 return 1; 138 } 139 } 140 return 0; 141 } 142 143 S.extend(Droppable, Base, 144 /** 145 * @lends DD.Droppable# 146 */ 147 { 148 /** 149 * override by droppable-delegate override 150 * @private 151 */ 152 getNodeFromTarget:function (ev, dragNode, proxyNode) { 153 var node = this.get("node"), 154 domNode = node[0]; 155 // 排除当前拖放和代理节点 156 return domNode == dragNode || 157 domNode == proxyNode 158 ? null : node; 159 }, 160 161 _init:function () { 162 DDM._regDrop(this); 163 }, 164 165 _active:function () { 166 var self = this, 167 drag = DDM.get("activeDrag"), 168 node = self.get("node"), 169 dropGroups = self.get("groups"), 170 dragGroups = drag.get("groups"); 171 if (validDrop(dropGroups, dragGroups)) { 172 DDM._addValidDrop(self); 173 // 委托时取不到节点 174 if (node) { 175 node.addClass(PREFIX_CLS + "drop-active-valid"); 176 DDM.cacheWH(node); 177 } 178 } else if (node) { 179 node.addClass(PREFIX_CLS + "drop-active-invalid"); 180 } 181 }, 182 183 _deActive:function () { 184 var node = this.get("node"); 185 if (node) { 186 node.removeClass(PREFIX_CLS + "drop-active-valid") 187 .removeClass(PREFIX_CLS + "drop-active-invalid"); 188 } 189 }, 190 191 __getCustomEvt:function (ev) { 192 return S.mix({ 193 drag:DDM.get("activeDrag"), 194 drop:this 195 }, ev); 196 }, 197 198 _handleOut:function () { 199 var self = this, 200 ret = self.__getCustomEvt(); 201 self.get("node").removeClass(PREFIX_CLS + "drop-over"); 202 /** 203 * html5 => dragleave 204 */ 205 self.fire("dropexit", ret); 206 }, 207 208 _handleEnter:function (ev) { 209 var self = this, 210 e = self.__getCustomEvt(ev); 211 e.drag._handleEnter(e); 212 self.get("node").addClass(PREFIX_CLS + "drop-over"); 213 self.fire("dropenter", e); 214 }, 215 216 217 _handleOver:function (ev) { 218 var self = this, 219 e = self.__getCustomEvt(ev); 220 e.drag._handleOver(e); 221 self.fire("dropover", e); 222 }, 223 224 _end:function () { 225 var self = this, 226 ret = self.__getCustomEvt(); 227 self.get("node").removeClass(PREFIX_CLS + "drop-over"); 228 self.fire('drophit', ret); 229 }, 230 231 /** 232 * make this droppable' element undroppable 233 */ 234 destroy:function () { 235 DDM._unRegDrop(this); 236 } 237 }); 238 239 return Droppable; 240 241 }, { requires:["node", "base", "./ddm"] });