Blame | Last modification | View Log | RSS feed
/** jQuery UI Droppable 1.8.5** Copyright 2010, AUTHORS.txt (http://jqueryui.com/about)* Dual licensed under the MIT or GPL Version 2 licenses.* http://jquery.org/license** http://docs.jquery.com/UI/Droppables** Depends:* jquery.ui.core.js* jquery.ui.widget.js* jquery.ui.mouse.js* jquery.ui.draggable.js*/(function( $, undefined ) {$.widget("ui.droppable", {widgetEventPrefix: "drop",options: {accept: '*',activeClass: false,addClasses: true,greedy: false,hoverClass: false,scope: 'default',tolerance: 'intersect'},_create: function() {var o = this.options, accept = o.accept;this.isover = 0; this.isout = 1;this.accept = $.isFunction(accept) ? accept : function(d) {return d.is(accept);};//Store the droppable's proportionsthis.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight };// Add the reference and positions to the manager$.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];$.ui.ddmanager.droppables[o.scope].push(this);(o.addClasses && this.element.addClass("ui-droppable"));},destroy: function() {var drop = $.ui.ddmanager.droppables[this.options.scope];for ( var i = 0; i < drop.length; i++ )if ( drop[i] == this )drop.splice(i, 1);this.element.removeClass("ui-droppable ui-droppable-disabled").removeData("droppable").unbind(".droppable");return this;},_setOption: function(key, value) {if(key == 'accept') {this.accept = $.isFunction(value) ? value : function(d) {return d.is(value);};}$.Widget.prototype._setOption.apply(this, arguments);},_activate: function(event) {var draggable = $.ui.ddmanager.current;if(this.options.activeClass) this.element.addClass(this.options.activeClass);(draggable && this._trigger('activate', event, this.ui(draggable)));},_deactivate: function(event) {var draggable = $.ui.ddmanager.current;if(this.options.activeClass) this.element.removeClass(this.options.activeClass);(draggable && this._trigger('deactivate', event, this.ui(draggable)));},_over: function(event) {var draggable = $.ui.ddmanager.current;if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same elementif (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {if(this.options.hoverClass) this.element.addClass(this.options.hoverClass);this._trigger('over', event, this.ui(draggable));}},_out: function(event) {var draggable = $.ui.ddmanager.current;if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same elementif (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);this._trigger('out', event, this.ui(draggable));}},_drop: function(event,custom) {var draggable = custom || $.ui.ddmanager.current;if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same elementvar childrenIntersection = false;this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() {var inst = $.data(this, 'droppable');if(inst.options.greedy&& !inst.options.disabled&& inst.options.scope == draggable.options.scope&& inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element))&& $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)) { childrenIntersection = true; return false; }});if(childrenIntersection) return false;if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {if(this.options.activeClass) this.element.removeClass(this.options.activeClass);if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass);this._trigger('drop', event, this.ui(draggable));return this.element;}return false;},ui: function(c) {return {draggable: (c.currentItem || c.element),helper: c.helper,position: c.position,offset: c.positionAbs};}});$.extend($.ui.droppable, {version: "1.8.5"});$.ui.intersect = function(draggable, droppable, toleranceMode) {if (!droppable.offset) return false;var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width,y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height;var l = droppable.offset.left, r = l + droppable.proportions.width,t = droppable.offset.top, b = t + droppable.proportions.height;switch (toleranceMode) {case 'fit':return (l <= x1 && x2 <= r&& t <= y1 && y2 <= b);break;case 'intersect':return (l < x1 + (draggable.helperProportions.width / 2) // Right Half&& x2 - (draggable.helperProportions.width / 2) < r // Left Half&& t < y1 + (draggable.helperProportions.height / 2) // Bottom Half&& y2 - (draggable.helperProportions.height / 2) < b ); // Top Halfbreak;case 'pointer':var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left),draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top),isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width);return isOver;break;case 'touch':return ((y1 >= t && y1 <= b) || // Top edge touching(y2 >= t && y2 <= b) || // Bottom edge touching(y1 < t && y2 > b) // Surrounded vertically) && ((x1 >= l && x1 <= r) || // Left edge touching(x2 >= l && x2 <= r) || // Right edge touching(x1 < l && x2 > r) // Surrounded horizontally);break;default:return false;break;}};/*This manager tracks offsets of draggables and droppables*/$.ui.ddmanager = {current: null,droppables: { 'default': [] },prepareOffsets: function(t, event) {var m = $.ui.ddmanager.droppables[t.options.scope] || [];var type = event ? event.type : null; // workaround for #2317var list = (t.currentItem || t.element).find(":data(droppable)").andSelf();droppablesLoop: for (var i = 0; i < m.length; i++) {if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-acceptedfor (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged itemm[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continuem[i].offset = m[i].element.offset();m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables}},drop: function(draggable, event) {var dropped = false;$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {if(!this.options) return;if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance))dropped = dropped || this._drop.call(this, event);if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {this.isout = 1; this.isover = 0;this._deactivate.call(this, event);}});return dropped;},drag: function(draggable, event) {//If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event);//Run through all droppables and check their positions based on specific tolerance options$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {if(this.options.disabled || this.greedyChild || !this.visible) return;var intersects = $.ui.intersect(draggable, this, this.options.tolerance);var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null);if(!c) return;var parentInstance;if (this.options.greedy) {var parent = this.element.parents(':data(droppable):eq(0)');if (parent.length) {parentInstance = $.data(parent[0], 'droppable');parentInstance.greedyChild = (c == 'isover' ? 1 : 0);}}// we just moved into a greedy childif (parentInstance && c == 'isover') {parentInstance['isover'] = 0;parentInstance['isout'] = 1;parentInstance._out.call(parentInstance, event);}this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0;this[c == "isover" ? "_over" : "_out"].call(this, event);// we just moved out of a greedy childif (parentInstance && c == 'isout') {parentInstance['isout'] = 0;parentInstance['isover'] = 1;parentInstance._over.call(parentInstance, event);}});}};})(jQuery);