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