jQuery UI 1.10 has already been released, and 1.11 is on the horizon (1.9 is marked "legacy" as of writing). 1.10 drops the compatibility layer for 1.8 API. So, users should definitely be encouraged to upgrade their code to move away from the deprecated 1.8 APIs. However, to take it one step at a time, this commit upgrades us to 1.9 first. That way we're at least not using an unsupported code base anymore, while at the same time not rolling out breaking changes. jQuery UI has redesigned many of its APIs[1], but compatibility with the jQuery UI 1.8 API is maintained throughout 1.9.x. * Base theme is now called "Smoothness". * Sorting the entries in Resources.php alphabetically to make it easier to ensure all files are listed when comparing them side-by-side. * Update dependencies to match the "Depends:" header inside the javascript files. * In jQuery UI 1.9, effect files were renamed to match the jquery.ui.*.js naming pattern. * New modules: - jquery.ui.menu - jquery.ui.spinner - jquery.ui.tooltip * Release notes: - http://blog.jqueryui.com/2012/10/jquery-ui-1-9-0/ - http://jqueryui.com/upgrade-guide/1.9/ - http://jqueryui.com/changelog/1.9.0/ - http://blog.jqueryui.com/2012/10/jquery-ui-1-9-1/ - http://jqueryui.com/changelog/1.9.1/ - http://blog.jqueryui.com/2012/11/jquery-ui-1-9-2/ [1] http://blog.jqueryui.com/2011/03/api-redesigns-the-past-present-and-future/ Bug: 47076 Change-Id: I0e10b42fb7c25b9d4704719f21c44c08f36ddfa7
294 lines
10 KiB
JavaScript
294 lines
10 KiB
JavaScript
/*!
|
|
* jQuery UI Droppable 1.9.2
|
|
* http://jqueryui.com
|
|
*
|
|
* Copyright 2012 jQuery Foundation and other contributors
|
|
* Released under the MIT license.
|
|
* http://jquery.org/license
|
|
*
|
|
* http://api.jqueryui.com/droppable/
|
|
*
|
|
* Depends:
|
|
* jquery.ui.core.js
|
|
* jquery.ui.widget.js
|
|
* jquery.ui.mouse.js
|
|
* jquery.ui.draggable.js
|
|
*/
|
|
(function( $, undefined ) {
|
|
|
|
$.widget("ui.droppable", {
|
|
version: "1.9.2",
|
|
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 proportions
|
|
this.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");
|
|
},
|
|
|
|
_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 element
|
|
|
|
if (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 element
|
|
|
|
if (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 element
|
|
|
|
var 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
|
|
};
|
|
}
|
|
|
|
});
|
|
|
|
$.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 Half
|
|
break;
|
|
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 #2317
|
|
var 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-accepted
|
|
for (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 item
|
|
m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue
|
|
|
|
if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables
|
|
|
|
m[i].offset = m[i].element.offset();
|
|
m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight };
|
|
|
|
}
|
|
|
|
},
|
|
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 = this._drop.call(this, event) || dropped;
|
|
|
|
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;
|
|
|
|
},
|
|
dragStart: function( draggable, event ) {
|
|
//Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
|
|
draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
|
|
if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
|
|
});
|
|
},
|
|
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) {
|
|
// find droppable parents with same scope
|
|
var scope = this.options.scope;
|
|
var parent = this.element.parents(':data(droppable)').filter(function () {
|
|
return $.data(this, 'droppable').options.scope === scope;
|
|
});
|
|
|
|
if (parent.length) {
|
|
parentInstance = $.data(parent[0], 'droppable');
|
|
parentInstance.greedyChild = (c == 'isover' ? 1 : 0);
|
|
}
|
|
}
|
|
|
|
// we just moved into a greedy child
|
|
if (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 child
|
|
if (parentInstance && c == 'isout') {
|
|
parentInstance['isout'] = 0;
|
|
parentInstance['isover'] = 1;
|
|
parentInstance._over.call(parentInstance, event);
|
|
}
|
|
});
|
|
|
|
},
|
|
dragStop: function( draggable, event ) {
|
|
draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
|
|
//Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
|
|
if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event );
|
|
}
|
|
};
|
|
|
|
})(jQuery);
|