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