3 //Make nodes selectable by expression
\r
4 $.extend($.expr[':'], { droppable: "(' '+a.className+' ').indexOf(' ui-droppable ')" });
\r
6 //Macros for external methods that support chaining
\r
7 var methods = "destroy,enable,disable".split(",");
\r
8 for(var i=0;i<methods.length;i++) {
\r
9 var cur = methods[i], f;
\r
10 eval('f = function() { var a = arguments; return this.each(function() { if(jQuery(this).is(".ui-droppable")) jQuery.data(this, "ui-droppable")["'+cur+'"](a); }); }');
\r
11 $.fn["droppable"+cur.substr(0,1).toUpperCase()+cur.substr(1)] = f;
\r
14 //get instance method
\r
15 $.fn.droppableInstance = function() {
\r
16 if($(this[0]).is(".ui-droppable")) return $.data(this[0], "ui-droppable");
\r
20 $.fn.droppable = function(o) {
\r
21 return this.each(function() {
\r
22 new $.ui.droppable(this,o);
\r
26 $.ui.droppable = function(el,o) {
\r
29 this.element = el; if($.browser.msie) el.droppable = 1;
\r
30 $.data(el, "ui-droppable", this);
\r
33 $.extend(this.options, o);
\r
35 var accept = o.accept;
\r
36 $.extend(this.options, {
\r
37 accept: o.accept && o.accept.constructor == Function ? o.accept : function(d) {
\r
38 return $(d).is(accept);
\r
40 tolerance: o.tolerance || 'intersect'
\r
45 this.mouseBindings = [function(e) { return self.move.apply(self, [e]); },function(e) { return self.drop.apply(self, [e]); }];
\r
46 $(this.element).bind("mousemove", this.mouseBindings[0]);
\r
47 $(this.element).bind("mouseup", this.mouseBindings[1]);
\r
49 $.ui.ddmanager.droppables.push({ item: this, over: 0, out: 1 }); // Add the reference and positions to the manager
\r
50 $(this.element).addClass("ui-droppable");
\r
54 $.extend($.ui.droppable.prototype, {
\r
56 prepareCallbackObj: function(c) {
\r
62 options: this.options
\r
65 destroy: function() {
\r
66 $(this.element).removeClass("ui-droppable").removeClass("ui-droppable-disabled");
\r
67 $(this.element).unbind("mousemove", this.mouseBindings[0]);
\r
68 $(this.element).unbind("mouseup", this.mouseBindings[1]);
\r
70 for(var i=0;i<$.ui.ddmanager.droppables.length;i++) {
\r
71 if($.ui.ddmanager.droppables[i].item == this) $.ui.ddmanager.droppables.splice(i,1);
\r
74 enable: function() {
\r
75 $(this.element).removeClass("ui-droppable-disabled");
\r
76 this.disabled = false;
\r
78 disable: function() {
\r
79 $(this.element).addClass("ui-droppable-disabled");
\r
80 this.disabled = true;
\r
84 if(!$.ui.ddmanager.current) return;
\r
86 var o = this.options;
\r
87 var c = $.ui.ddmanager.current;
\r
89 /* Save current target, if no last target given */
\r
90 var findCurrentTarget = function(e) {
\r
91 if(e.currentTarget) return e.currentTarget;
\r
92 var el = e.srcElement;
\r
93 do { if(el.droppable) return el; el = el.parentNode; } while (el); //This is only used in IE! references in DOM are evil!
\r
95 if(c && o.accept(c.element)) c.currentTarget = findCurrentTarget(e);
\r
97 c.drag.apply(c, [e]);
\r
98 e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
\r
101 over: function(e) {
\r
103 var c = $.ui.ddmanager.current;
\r
104 if (!c || c.element == this.element) return; // Bail if draggable and droppable are same element
\r
106 var o = this.options;
\r
107 if (o.accept(c.element)) {
\r
108 $.ui.plugin.call(this, 'over', [e, this.prepareCallbackObj(c)]);
\r
109 $(this.element).triggerHandler("dropover", [e, this.prepareCallbackObj(c)], o.over);
\r
115 var c = $.ui.ddmanager.current;
\r
116 if (!c || c.element == this.element) return; // Bail if draggable and droppable are same element
\r
118 var o = this.options;
\r
119 if (o.accept(c.element)) {
\r
120 $.ui.plugin.call(this, 'out', [e, this.prepareCallbackObj(c)]);
\r
121 $(this.element).triggerHandler("dropout", [e, this.prepareCallbackObj(c)], o.out);
\r
125 drop: function(e) {
\r
127 var c = $.ui.ddmanager.current;
\r
128 if (!c || c.element == this.element) return; // Bail if draggable and droppable are same element
\r
130 var o = this.options;
\r
131 if(o.accept(c.element)) { // Fire callback
\r
132 if(o.greedy && !c.slowMode) {
\r
133 if(c.currentTarget == this.element) {
\r
134 $.ui.plugin.call(this, 'drop', [e, {
\r
137 element: c.element,
\r
140 $(this.element).triggerHandler("drop", [e, {
\r
143 element: c.element,
\r
148 $.ui.plugin.call(this, 'drop', [e, this.prepareCallbackObj(c)]);
\r
149 $(this.element).triggerHandler("drop", [e, this.prepareCallbackObj(c)], o.drop);
\r
154 activate: function(e) {
\r
155 var c = $.ui.ddmanager.current;
\r
156 $.ui.plugin.call(this, 'activate', [e, this.prepareCallbackObj(c)]);
\r
157 if(c) $(this.element).triggerHandler("dropactivate", [e, this.prepareCallbackObj(c)], this.options.activate);
\r
159 deactivate: function(e) {
\r
160 var c = $.ui.ddmanager.current;
\r
161 $.ui.plugin.call(this, 'deactivate', [e, this.prepareCallbackObj(c)]);
\r
162 if(c) $(this.element).triggerHandler("dropdeactivate", [e, this.prepareCallbackObj(c)], this.options.deactivate);
\r
166 $.ui.intersect = function(oDrag, oDrop, toleranceMode) {
\r
169 var x1 = oDrag.rpos[0] - oDrag.options.cursorAt.left + oDrag.options.margins.left, x2 = x1 + oDrag.helperSize.width,
\r
170 y1 = oDrag.rpos[1] - oDrag.options.cursorAt.top + oDrag.options.margins.top, y2 = y1 + oDrag.helperSize.height;
\r
171 var l = oDrop.offset.left, r = l + oDrop.item.element.offsetWidth,
\r
172 t = oDrop.offset.top, b = t + oDrop.item.element.offsetHeight;
\r
173 switch (toleranceMode) {
\r
175 return ( l < x1 && x2 < r
\r
176 && t < y1 && y2 < b);
\r
179 return ( l < x1 + (oDrag.helperSize.width / 2) // Right Half
\r
180 && x2 - (oDrag.helperSize.width / 2) < r // Left Half
\r
181 && t < y1 + (oDrag.helperSize.height / 2) // Bottom Half
\r
182 && y2 - (oDrag.helperSize.height / 2) < b ); // Top Half
\r
185 return ( l < oDrag.rpos[0] && oDrag.rpos[0] < r
\r
186 && t < oDrag.rpos[1] && oDrag.rpos[1] < b);
\r
189 return ( (l < x1 && x1 < r && t < y1 && y1 < b) // Top-Left Corner
\r
190 || (l < x1 && x1 < r && t < y2 && y2 < b) // Bottom-Left Corner
\r
191 || (l < x2 && x2 < r && t < y1 && y1 < b) // Top-Right Corner
\r
192 || (l < x2 && x2 < r && t < y2 && y2 < b) ); // Bottom-Right Corner
\r