commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-old / civicrm / bower_components / jquery-ui / ui / droppable.js
1 /*!
2 * jQuery UI Droppable 1.11.4
3 * http://jqueryui.com
4 *
5 * Copyright jQuery Foundation and other contributors
6 * Released under the MIT license.
7 * http://jquery.org/license
8 *
9 * http://api.jqueryui.com/droppable/
10 */
11 (function( factory ) {
12 if ( typeof define === "function" && define.amd ) {
13
14 // AMD. Register as an anonymous module.
15 define([
16 "jquery",
17 "./core",
18 "./widget",
19 "./mouse",
20 "./draggable"
21 ], factory );
22 } else {
23
24 // Browser globals
25 factory( jQuery );
26 }
27 }(function( $ ) {
28
29 $.widget( "ui.droppable", {
30 version: "1.11.4",
31 widgetEventPrefix: "drop",
32 options: {
33 accept: "*",
34 activeClass: false,
35 addClasses: true,
36 greedy: false,
37 hoverClass: false,
38 scope: "default",
39 tolerance: "intersect",
40
41 // callbacks
42 activate: null,
43 deactivate: null,
44 drop: null,
45 out: null,
46 over: null
47 },
48 _create: function() {
49
50 var proportions,
51 o = this.options,
52 accept = o.accept;
53
54 this.isover = false;
55 this.isout = true;
56
57 this.accept = $.isFunction( accept ) ? accept : function( d ) {
58 return d.is( accept );
59 };
60
61 this.proportions = function( /* valueToWrite */ ) {
62 if ( arguments.length ) {
63 // Store the droppable's proportions
64 proportions = arguments[ 0 ];
65 } else {
66 // Retrieve or derive the droppable's proportions
67 return proportions ?
68 proportions :
69 proportions = {
70 width: this.element[ 0 ].offsetWidth,
71 height: this.element[ 0 ].offsetHeight
72 };
73 }
74 };
75
76 this._addToManager( o.scope );
77
78 o.addClasses && this.element.addClass( "ui-droppable" );
79
80 },
81
82 _addToManager: function( scope ) {
83 // Add the reference and positions to the manager
84 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
85 $.ui.ddmanager.droppables[ scope ].push( this );
86 },
87
88 _splice: function( drop ) {
89 var i = 0;
90 for ( ; i < drop.length; i++ ) {
91 if ( drop[ i ] === this ) {
92 drop.splice( i, 1 );
93 }
94 }
95 },
96
97 _destroy: function() {
98 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
99
100 this._splice( drop );
101
102 this.element.removeClass( "ui-droppable ui-droppable-disabled" );
103 },
104
105 _setOption: function( key, value ) {
106
107 if ( key === "accept" ) {
108 this.accept = $.isFunction( value ) ? value : function( d ) {
109 return d.is( value );
110 };
111 } else if ( key === "scope" ) {
112 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
113
114 this._splice( drop );
115 this._addToManager( value );
116 }
117
118 this._super( key, value );
119 },
120
121 _activate: function( event ) {
122 var draggable = $.ui.ddmanager.current;
123 if ( this.options.activeClass ) {
124 this.element.addClass( this.options.activeClass );
125 }
126 if ( draggable ){
127 this._trigger( "activate", event, this.ui( draggable ) );
128 }
129 },
130
131 _deactivate: function( event ) {
132 var draggable = $.ui.ddmanager.current;
133 if ( this.options.activeClass ) {
134 this.element.removeClass( this.options.activeClass );
135 }
136 if ( draggable ){
137 this._trigger( "deactivate", event, this.ui( draggable ) );
138 }
139 },
140
141 _over: function( event ) {
142
143 var draggable = $.ui.ddmanager.current;
144
145 // Bail if draggable and droppable are same element
146 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
147 return;
148 }
149
150 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
151 if ( this.options.hoverClass ) {
152 this.element.addClass( this.options.hoverClass );
153 }
154 this._trigger( "over", event, this.ui( draggable ) );
155 }
156
157 },
158
159 _out: function( event ) {
160
161 var draggable = $.ui.ddmanager.current;
162
163 // Bail if draggable and droppable are same element
164 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
165 return;
166 }
167
168 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
169 if ( this.options.hoverClass ) {
170 this.element.removeClass( this.options.hoverClass );
171 }
172 this._trigger( "out", event, this.ui( draggable ) );
173 }
174
175 },
176
177 _drop: function( event, custom ) {
178
179 var draggable = custom || $.ui.ddmanager.current,
180 childrenIntersection = false;
181
182 // Bail if draggable and droppable are same element
183 if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
184 return false;
185 }
186
187 this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
188 var inst = $( this ).droppable( "instance" );
189 if (
190 inst.options.greedy &&
191 !inst.options.disabled &&
192 inst.options.scope === draggable.options.scope &&
193 inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
194 $.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
195 ) { childrenIntersection = true; return false; }
196 });
197 if ( childrenIntersection ) {
198 return false;
199 }
200
201 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
202 if ( this.options.activeClass ) {
203 this.element.removeClass( this.options.activeClass );
204 }
205 if ( this.options.hoverClass ) {
206 this.element.removeClass( this.options.hoverClass );
207 }
208 this._trigger( "drop", event, this.ui( draggable ) );
209 return this.element;
210 }
211
212 return false;
213
214 },
215
216 ui: function( c ) {
217 return {
218 draggable: ( c.currentItem || c.element ),
219 helper: c.helper,
220 position: c.position,
221 offset: c.positionAbs
222 };
223 }
224
225 });
226
227 $.ui.intersect = (function() {
228 function isOverAxis( x, reference, size ) {
229 return ( x >= reference ) && ( x < ( reference + size ) );
230 }
231
232 return function( draggable, droppable, toleranceMode, event ) {
233
234 if ( !droppable.offset ) {
235 return false;
236 }
237
238 var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
239 y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
240 x2 = x1 + draggable.helperProportions.width,
241 y2 = y1 + draggable.helperProportions.height,
242 l = droppable.offset.left,
243 t = droppable.offset.top,
244 r = l + droppable.proportions().width,
245 b = t + droppable.proportions().height;
246
247 switch ( toleranceMode ) {
248 case "fit":
249 return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
250 case "intersect":
251 return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
252 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
253 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
254 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
255 case "pointer":
256 return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
257 case "touch":
258 return (
259 ( y1 >= t && y1 <= b ) || // Top edge touching
260 ( y2 >= t && y2 <= b ) || // Bottom edge touching
261 ( y1 < t && y2 > b ) // Surrounded vertically
262 ) && (
263 ( x1 >= l && x1 <= r ) || // Left edge touching
264 ( x2 >= l && x2 <= r ) || // Right edge touching
265 ( x1 < l && x2 > r ) // Surrounded horizontally
266 );
267 default:
268 return false;
269 }
270 };
271 })();
272
273 /*
274 This manager tracks offsets of draggables and droppables
275 */
276 $.ui.ddmanager = {
277 current: null,
278 droppables: { "default": [] },
279 prepareOffsets: function( t, event ) {
280
281 var i, j,
282 m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
283 type = event ? event.type : null, // workaround for #2317
284 list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
285
286 droppablesLoop: for ( i = 0; i < m.length; i++ ) {
287
288 // No disabled and non-accepted
289 if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
290 continue;
291 }
292
293 // Filter out elements in the current dragged item
294 for ( j = 0; j < list.length; j++ ) {
295 if ( list[ j ] === m[ i ].element[ 0 ] ) {
296 m[ i ].proportions().height = 0;
297 continue droppablesLoop;
298 }
299 }
300
301 m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
302 if ( !m[ i ].visible ) {
303 continue;
304 }
305
306 // Activate the droppable if used directly from draggables
307 if ( type === "mousedown" ) {
308 m[ i ]._activate.call( m[ i ], event );
309 }
310
311 m[ i ].offset = m[ i ].element.offset();
312 m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
313
314 }
315
316 },
317 drop: function( draggable, event ) {
318
319 var dropped = false;
320 // Create a copy of the droppables in case the list changes during the drop (#9116)
321 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
322
323 if ( !this.options ) {
324 return;
325 }
326 if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
327 dropped = this._drop.call( this, event ) || dropped;
328 }
329
330 if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
331 this.isout = true;
332 this.isover = false;
333 this._deactivate.call( this, event );
334 }
335
336 });
337 return dropped;
338
339 },
340 dragStart: function( draggable, event ) {
341 // Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
342 draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
343 if ( !draggable.options.refreshPositions ) {
344 $.ui.ddmanager.prepareOffsets( draggable, event );
345 }
346 });
347 },
348 drag: function( draggable, event ) {
349
350 // If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
351 if ( draggable.options.refreshPositions ) {
352 $.ui.ddmanager.prepareOffsets( draggable, event );
353 }
354
355 // Run through all droppables and check their positions based on specific tolerance options
356 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
357
358 if ( this.options.disabled || this.greedyChild || !this.visible ) {
359 return;
360 }
361
362 var parentInstance, scope, parent,
363 intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
364 c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
365 if ( !c ) {
366 return;
367 }
368
369 if ( this.options.greedy ) {
370 // find droppable parents with same scope
371 scope = this.options.scope;
372 parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
373 return $( this ).droppable( "instance" ).options.scope === scope;
374 });
375
376 if ( parent.length ) {
377 parentInstance = $( parent[ 0 ] ).droppable( "instance" );
378 parentInstance.greedyChild = ( c === "isover" );
379 }
380 }
381
382 // we just moved into a greedy child
383 if ( parentInstance && c === "isover" ) {
384 parentInstance.isover = false;
385 parentInstance.isout = true;
386 parentInstance._out.call( parentInstance, event );
387 }
388
389 this[ c ] = true;
390 this[c === "isout" ? "isover" : "isout"] = false;
391 this[c === "isover" ? "_over" : "_out"].call( this, event );
392
393 // we just moved out of a greedy child
394 if ( parentInstance && c === "isout" ) {
395 parentInstance.isout = false;
396 parentInstance.isover = true;
397 parentInstance._over.call( parentInstance, event );
398 }
399 });
400
401 },
402 dragStop: function( draggable, event ) {
403 draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
404 // Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
405 if ( !draggable.options.refreshPositions ) {
406 $.ui.ddmanager.prepareOffsets( draggable, event );
407 }
408 }
409 };
410
411 return $.ui.droppable;
412
413 }));