standard header in about page (#676)
[openemr.git] / public / assets / jquery-ui-1-12-1 / ui / widgets / droppable.js
blob4b932aea39a967e8e95e1a538ed7af9ce1f27727
1 /*!
2  * jQuery UI Droppable 1.12.1
3  * http://jqueryui.com
4  *
5  * Copyright jQuery Foundation and other contributors
6  * Released under the MIT license.
7  * http://jquery.org/license
8  */
10 //>>label: Droppable
11 //>>group: Interactions
12 //>>description: Enables drop targets for draggable elements.
13 //>>docs: http://api.jqueryui.com/droppable/
14 //>>demos: http://jqueryui.com/droppable/
16 ( function( factory ) {
17         if ( typeof define === "function" && define.amd ) {
19                 // AMD. Register as an anonymous module.
20                 define( [
21                         "jquery",
22                         "./draggable",
23                         "./mouse",
24                         "../version",
25                         "../widget"
26                 ], factory );
27         } else {
29                 // Browser globals
30                 factory( jQuery );
31         }
32 }( function( $ ) {
34 $.widget( "ui.droppable", {
35         version: "1.12.1",
36         widgetEventPrefix: "drop",
37         options: {
38                 accept: "*",
39                 addClasses: true,
40                 greedy: false,
41                 scope: "default",
42                 tolerance: "intersect",
44                 // Callbacks
45                 activate: null,
46                 deactivate: null,
47                 drop: null,
48                 out: null,
49                 over: null
50         },
51         _create: function() {
53                 var proportions,
54                         o = this.options,
55                         accept = o.accept;
57                 this.isover = false;
58                 this.isout = true;
60                 this.accept = $.isFunction( accept ) ? accept : function( d ) {
61                         return d.is( accept );
62                 };
64                 this.proportions = function( /* valueToWrite */ ) {
65                         if ( arguments.length ) {
67                                 // Store the droppable's proportions
68                                 proportions = arguments[ 0 ];
69                         } else {
71                                 // Retrieve or derive the droppable's proportions
72                                 return proportions ?
73                                         proportions :
74                                         proportions = {
75                                                 width: this.element[ 0 ].offsetWidth,
76                                                 height: this.element[ 0 ].offsetHeight
77                                         };
78                         }
79                 };
81                 this._addToManager( o.scope );
83                 o.addClasses && this._addClass( "ui-droppable" );
85         },
87         _addToManager: function( scope ) {
89                 // Add the reference and positions to the manager
90                 $.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
91                 $.ui.ddmanager.droppables[ scope ].push( this );
92         },
94         _splice: function( drop ) {
95                 var i = 0;
96                 for ( ; i < drop.length; i++ ) {
97                         if ( drop[ i ] === this ) {
98                                 drop.splice( i, 1 );
99                         }
100                 }
101         },
103         _destroy: function() {
104                 var drop = $.ui.ddmanager.droppables[ this.options.scope ];
106                 this._splice( drop );
107         },
109         _setOption: function( key, value ) {
111                 if ( key === "accept" ) {
112                         this.accept = $.isFunction( value ) ? value : function( d ) {
113                                 return d.is( value );
114                         };
115                 } else if ( key === "scope" ) {
116                         var drop = $.ui.ddmanager.droppables[ this.options.scope ];
118                         this._splice( drop );
119                         this._addToManager( value );
120                 }
122                 this._super( key, value );
123         },
125         _activate: function( event ) {
126                 var draggable = $.ui.ddmanager.current;
128                 this._addActiveClass();
129                 if ( draggable ) {
130                         this._trigger( "activate", event, this.ui( draggable ) );
131                 }
132         },
134         _deactivate: function( event ) {
135                 var draggable = $.ui.ddmanager.current;
137                 this._removeActiveClass();
138                 if ( draggable ) {
139                         this._trigger( "deactivate", event, this.ui( draggable ) );
140                 }
141         },
143         _over: function( event ) {
145                 var draggable = $.ui.ddmanager.current;
147                 // Bail if draggable and droppable are same element
148                 if ( !draggable || ( draggable.currentItem ||
149                                 draggable.element )[ 0 ] === this.element[ 0 ] ) {
150                         return;
151                 }
153                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
154                                 draggable.element ) ) ) {
155                         this._addHoverClass();
156                         this._trigger( "over", event, this.ui( draggable ) );
157                 }
159         },
161         _out: function( event ) {
163                 var draggable = $.ui.ddmanager.current;
165                 // Bail if draggable and droppable are same element
166                 if ( !draggable || ( draggable.currentItem ||
167                                 draggable.element )[ 0 ] === this.element[ 0 ] ) {
168                         return;
169                 }
171                 if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
172                                 draggable.element ) ) ) {
173                         this._removeHoverClass();
174                         this._trigger( "out", event, this.ui( draggable ) );
175                 }
177         },
179         _drop: function( event, custom ) {
181                 var draggable = custom || $.ui.ddmanager.current,
182                         childrenIntersection = false;
184                 // Bail if draggable and droppable are same element
185                 if ( !draggable || ( draggable.currentItem ||
186                                 draggable.element )[ 0 ] === this.element[ 0 ] ) {
187                         return false;
188                 }
190                 this.element
191                         .find( ":data(ui-droppable)" )
192                         .not( ".ui-draggable-dragging" )
193                         .each( function() {
194                                 var inst = $( this ).droppable( "instance" );
195                                 if (
196                                         inst.options.greedy &&
197                                         !inst.options.disabled &&
198                                         inst.options.scope === draggable.options.scope &&
199                                         inst.accept.call(
200                                                 inst.element[ 0 ], ( draggable.currentItem || draggable.element )
201                                         ) &&
202                                         intersect(
203                                                 draggable,
204                                                 $.extend( inst, { offset: inst.element.offset() } ),
205                                                 inst.options.tolerance, event
206                                         )
207                                 ) {
208                                         childrenIntersection = true;
209                                         return false; }
210                         } );
211                 if ( childrenIntersection ) {
212                         return false;
213                 }
215                 if ( this.accept.call( this.element[ 0 ],
216                                 ( draggable.currentItem || draggable.element ) ) ) {
217                         this._removeActiveClass();
218                         this._removeHoverClass();
220                         this._trigger( "drop", event, this.ui( draggable ) );
221                         return this.element;
222                 }
224                 return false;
226         },
228         ui: function( c ) {
229                 return {
230                         draggable: ( c.currentItem || c.element ),
231                         helper: c.helper,
232                         position: c.position,
233                         offset: c.positionAbs
234                 };
235         },
237         // Extension points just to make backcompat sane and avoid duplicating logic
238         // TODO: Remove in 1.13 along with call to it below
239         _addHoverClass: function() {
240                 this._addClass( "ui-droppable-hover" );
241         },
243         _removeHoverClass: function() {
244                 this._removeClass( "ui-droppable-hover" );
245         },
247         _addActiveClass: function() {
248                 this._addClass( "ui-droppable-active" );
249         },
251         _removeActiveClass: function() {
252                 this._removeClass( "ui-droppable-active" );
253         }
254 } );
256 var intersect = $.ui.intersect = ( function() {
257         function isOverAxis( x, reference, size ) {
258                 return ( x >= reference ) && ( x < ( reference + size ) );
259         }
261         return function( draggable, droppable, toleranceMode, event ) {
263                 if ( !droppable.offset ) {
264                         return false;
265                 }
267                 var x1 = ( draggable.positionAbs ||
268                                 draggable.position.absolute ).left + draggable.margins.left,
269                         y1 = ( draggable.positionAbs ||
270                                 draggable.position.absolute ).top + draggable.margins.top,
271                         x2 = x1 + draggable.helperProportions.width,
272                         y2 = y1 + draggable.helperProportions.height,
273                         l = droppable.offset.left,
274                         t = droppable.offset.top,
275                         r = l + droppable.proportions().width,
276                         b = t + droppable.proportions().height;
278                 switch ( toleranceMode ) {
279                 case "fit":
280                         return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
281                 case "intersect":
282                         return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
283                                 x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
284                                 t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
285                                 y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
286                 case "pointer":
287                         return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
288                                 isOverAxis( event.pageX, l, droppable.proportions().width );
289                 case "touch":
290                         return (
291                                 ( y1 >= t && y1 <= b ) || // Top edge touching
292                                 ( y2 >= t && y2 <= b ) || // Bottom edge touching
293                                 ( y1 < t && y2 > b ) // Surrounded vertically
294                         ) && (
295                                 ( x1 >= l && x1 <= r ) || // Left edge touching
296                                 ( x2 >= l && x2 <= r ) || // Right edge touching
297                                 ( x1 < l && x2 > r ) // Surrounded horizontally
298                         );
299                 default:
300                         return false;
301                 }
302         };
303 } )();
306         This manager tracks offsets of draggables and droppables
308 $.ui.ddmanager = {
309         current: null,
310         droppables: { "default": [] },
311         prepareOffsets: function( t, event ) {
313                 var i, j,
314                         m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
315                         type = event ? event.type : null, // workaround for #2317
316                         list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
318                 droppablesLoop: for ( i = 0; i < m.length; i++ ) {
320                         // No disabled and non-accepted
321                         if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
322                                         ( t.currentItem || t.element ) ) ) ) {
323                                 continue;
324                         }
326                         // Filter out elements in the current dragged item
327                         for ( j = 0; j < list.length; j++ ) {
328                                 if ( list[ j ] === m[ i ].element[ 0 ] ) {
329                                         m[ i ].proportions().height = 0;
330                                         continue droppablesLoop;
331                                 }
332                         }
334                         m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
335                         if ( !m[ i ].visible ) {
336                                 continue;
337                         }
339                         // Activate the droppable if used directly from draggables
340                         if ( type === "mousedown" ) {
341                                 m[ i ]._activate.call( m[ i ], event );
342                         }
344                         m[ i ].offset = m[ i ].element.offset();
345                         m[ i ].proportions( {
346                                 width: m[ i ].element[ 0 ].offsetWidth,
347                                 height: m[ i ].element[ 0 ].offsetHeight
348                         } );
350                 }
352         },
353         drop: function( draggable, event ) {
355                 var dropped = false;
357                 // Create a copy of the droppables in case the list changes during the drop (#9116)
358                 $.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
360                         if ( !this.options ) {
361                                 return;
362                         }
363                         if ( !this.options.disabled && this.visible &&
364                                         intersect( draggable, this, this.options.tolerance, event ) ) {
365                                 dropped = this._drop.call( this, event ) || dropped;
366                         }
368                         if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
369                                         ( draggable.currentItem || draggable.element ) ) ) {
370                                 this.isout = true;
371                                 this.isover = false;
372                                 this._deactivate.call( this, event );
373                         }
375                 } );
376                 return dropped;
378         },
379         dragStart: function( draggable, event ) {
381                 // Listen for scrolling so that if the dragging causes scrolling the position of the
382                 // droppables can be recalculated (see #5003)
383                 draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
384                         if ( !draggable.options.refreshPositions ) {
385                                 $.ui.ddmanager.prepareOffsets( draggable, event );
386                         }
387                 } );
388         },
389         drag: function( draggable, event ) {
391                 // If you have a highly dynamic page, you might try this option. It renders positions
392                 // every time you move the mouse.
393                 if ( draggable.options.refreshPositions ) {
394                         $.ui.ddmanager.prepareOffsets( draggable, event );
395                 }
397                 // Run through all droppables and check their positions based on specific tolerance options
398                 $.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
400                         if ( this.options.disabled || this.greedyChild || !this.visible ) {
401                                 return;
402                         }
404                         var parentInstance, scope, parent,
405                                 intersects = intersect( draggable, this, this.options.tolerance, event ),
406                                 c = !intersects && this.isover ?
407                                         "isout" :
408                                         ( intersects && !this.isover ? "isover" : null );
409                         if ( !c ) {
410                                 return;
411                         }
413                         if ( this.options.greedy ) {
415                                 // find droppable parents with same scope
416                                 scope = this.options.scope;
417                                 parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
418                                         return $( this ).droppable( "instance" ).options.scope === scope;
419                                 } );
421                                 if ( parent.length ) {
422                                         parentInstance = $( parent[ 0 ] ).droppable( "instance" );
423                                         parentInstance.greedyChild = ( c === "isover" );
424                                 }
425                         }
427                         // We just moved into a greedy child
428                         if ( parentInstance && c === "isover" ) {
429                                 parentInstance.isover = false;
430                                 parentInstance.isout = true;
431                                 parentInstance._out.call( parentInstance, event );
432                         }
434                         this[ c ] = true;
435                         this[ c === "isout" ? "isover" : "isout" ] = false;
436                         this[ c === "isover" ? "_over" : "_out" ].call( this, event );
438                         // We just moved out of a greedy child
439                         if ( parentInstance && c === "isout" ) {
440                                 parentInstance.isout = false;
441                                 parentInstance.isover = true;
442                                 parentInstance._over.call( parentInstance, event );
443                         }
444                 } );
446         },
447         dragStop: function( draggable, event ) {
448                 draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
450                 // Call prepareOffsets one final time since IE does not fire return scroll events when
451                 // overflow was caused by drag (see #5003)
452                 if ( !draggable.options.refreshPositions ) {
453                         $.ui.ddmanager.prepareOffsets( draggable, event );
454                 }
455         }
458 // DEPRECATED
459 // TODO: switch return back to widget declaration at top of file when this is removed
460 if ( $.uiBackCompat !== false ) {
462         // Backcompat for activeClass and hoverClass options
463         $.widget( "ui.droppable", $.ui.droppable, {
464                 options: {
465                         hoverClass: false,
466                         activeClass: false
467                 },
468                 _addActiveClass: function() {
469                         this._super();
470                         if ( this.options.activeClass ) {
471                                 this.element.addClass( this.options.activeClass );
472                         }
473                 },
474                 _removeActiveClass: function() {
475                         this._super();
476                         if ( this.options.activeClass ) {
477                                 this.element.removeClass( this.options.activeClass );
478                         }
479                 },
480                 _addHoverClass: function() {
481                         this._super();
482                         if ( this.options.hoverClass ) {
483                                 this.element.addClass( this.options.hoverClass );
484                         }
485                 },
486                 _removeHoverClass: function() {
487                         this._super();
488                         if ( this.options.hoverClass ) {
489                                 this.element.removeClass( this.options.hoverClass );
490                         }
491                 }
492         } );
495 return $.ui.droppable;
497 } ) );