vendor: 5,239 bytes, lines 1-205
1/*! 2 * Draggabilly PACKAGED v3.0.0 3 * Make that shiz draggable 4 * https://draggabilly.desandro.com 5 * MIT license 6 */ 7 8/** 9 * Bridget makes jQuery widgets 10 * v2.0.1 11 * MIT license 12 */ 13 14/* jshint browser: true, strict: true, undef: true, unused: true */ 15 16( function( window, factory ) { 17 // universal module definition 18 /*jshint strict: false */ /* globals define, module, require */ 19 if ( typeof define == 'function' && define.amd ) { 20 // AMD 21 define( [ 'jquery' ], function( jQuery ) { 22 return factory( window, jQuery ); 23 }); 24 } else if ( typeof module == 'object' && module.exports ) { 25 // CommonJS 26 module.exports = factory( 27 window, 28 require('jquery') 29 ); 30 } else { 31 // browser global 32 window.jQueryBridget = factory( 33 window, 34 window.jQuery 35 ); 36 } 37 38 }( window, function factory( window, jQuery ) { 39 'use strict'; 40 41 // ----- utils ----- // 42 43 var arraySlice = Array.prototype.slice; 44 45 // helper function for logging errors 46 // $.error breaks jQuery chaining 47 var console = window.console; 48 var logError = typeof console == 'undefined' ? function() {} : 49 function( message ) { 50 console.error( message ); 51 }; 52 53 // ----- jQueryBridget ----- // 54 55 function jQueryBridget( namespace, PluginClass, $ ) { 56 $ = $ || jQuery || window.jQuery; 57 if ( !$ ) { 58 return; 59 } 60 61 // add option method -> $().plugin('option', {...}) 62 if ( !PluginClass.prototype.option ) { 63 // option setter 64 PluginClass.prototype.option = function( opts ) { 65 // bail out if not an object 66 if ( !$.isPlainObject( opts ) ){ 67 return; 68 } 69 this.options = $.extend( true, this.options, opts ); 70 }; 71 } 72 73 // make jQuery plugin 74 $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { 75 if ( typeof arg0 == 'string' ) { 76 // method call $().plugin( 'methodName', { options } ) 77 // shift arguments by 1 78 var args = arraySlice.call( arguments, 1 ); 79 return methodCall( this, arg0, args ); 80 } 81 // just $().plugin({ options }) 82 plainCall( this, arg0 ); 83 return this; 84 }; 85 86 // $().plugin('methodName') 87 function methodCall( $elems, methodName, args ) { 88 var returnValue; 89 var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; 90 91 $elems.each( function( i, elem ) { 92 // get instance 93 var instance = $.data( elem, namespace ); 94 if ( !instance ) { 95 logError( namespace + ' not initialized. Cannot call methods, i.e. ' + 96 pluginMethodStr ); 97 return; 98 } 99 100 var method = instance[ methodName ]; 101 if ( !method || methodName.charAt(0) == '_' ) { 102 logError( pluginMethodStr + ' is not a valid method' ); 103 return; 104 } 105 106 // apply method, get return value 107 var value = method.apply( instance, args ); 108 // set return value if value is returned, use only first value 109 returnValue = returnValue === undefined ? value : returnValue; 110 }); 111 112 return returnValue !== undefined ? returnValue : $elems; 113 } 114 115 function plainCall( $elems, options ) { 116 $elems.each( function( i, elem ) { 117 var instance = $.data( elem, namespace ); 118 if ( instance ) { 119 // set options & init 120 instance.option( options ); 121 instance._init(); 122 } else { 123 // initialize new instance 124 instance = new PluginClass( elem, options ); 125 $.data( elem, namespace, instance ); 126 } 127 }); 128 } 129 130 updateJQuery( $ ); 131 132 } 133 134 // ----- updateJQuery ----- // 135 136 // set $.bridget for v1 backwards compatibility 137 function updateJQuery( $ ) { 138 if ( !$ || ( $ && $.bridget ) ) { 139 return; 140 } 141 $.bridget = jQueryBridget; 142 } 143 144 updateJQuery( jQuery || window.jQuery ); 145 146 // ----- ----- // 147 148 return jQueryBridget; 149 150 })); 151 /*! 152 * Infinite Scroll v2.0.4 153 * measure size of elements 154 * MIT license 155 */ 156 157 ( function( window, factory ) { 158 if ( typeof module == 'object' && module.exports ) { 159 // CommonJS 160 module.exports = factory(); 161 } else { 162 // browser global 163 window.getSize = factory(); 164 } 165 166 } )( window, function factory() { 167 168 // -------------------------- helpers -------------------------- // 169 170 // get a number from a string, not a percentage 171 function getStyleSize( value ) { 172 let num = parseFloat( value ); 173 // not a percent like '100%', and a number 174 let isValid = value.indexOf('%') == -1 && !isNaN( num ); 175 return isValid && num; 176 } 177 178 // -------------------------- measurements -------------------------- // 179 180 let measurements = [ 181 'paddingLeft', 182 'paddingRight', 183 'paddingTop', 184 'paddingBottom', 185 'marginLeft', 186 'marginRight', 187 'marginTop', 188 'marginBottom', 189 'borderLeftWidth', 190 'borderRightWidth', 191 'borderTopWidth', 192 'borderBottomWidth', 193 ]; 194 195 let measurementsLength = measurements.length; 196 197 function getZeroSize() { 198 let size = { 199 width: 0, 200 height: 0, 201 innerWidth: 0, 202 innerHeight: 0, 203 outerWidth: 0, 204 outerHeight: 0, 205 };
vendor: 10,820 bytes, lines 206-564
206 measurements.forEach( ( measurement ) => { 207 size[ measurement ] = 0; 208 } ); 209 return size; 210 } 211 212 // -------------------------- getSize -------------------------- // 213 214 function getSize( elem ) { 215 // use querySeletor if elem is string 216 if ( typeof elem == 'string' ) elem = document.querySelector( elem ); 217 218 // do not proceed on non-objects 219 let isElement = elem && typeof elem == 'object' && elem.nodeType; 220 if ( !isElement ) return; 221 222 let style = getComputedStyle( elem ); 223 224 // if hidden, everything is 0 225 if ( style.display == 'none' ) return getZeroSize(); 226 227 let size = {}; 228 size.width = elem.offsetWidth; 229 size.height = elem.offsetHeight; 230 231 let isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 232 233 // get all measurements 234 measurements.forEach( ( measurement ) => { 235 let value = style[ measurement ]; 236 let num = parseFloat( value ); 237 // any 'auto', 'medium' value will be 0 238 size[ measurement ] = !isNaN( num ) ? num : 0; 239 } ); 240 241 let paddingWidth = size.paddingLeft + size.paddingRight; 242 let paddingHeight = size.paddingTop + size.paddingBottom; 243 let marginWidth = size.marginLeft + size.marginRight; 244 let marginHeight = size.marginTop + size.marginBottom; 245 let borderWidth = size.borderLeftWidth + size.borderRightWidth; 246 let borderHeight = size.borderTopWidth + size.borderBottomWidth; 247 248 // overwrite width and height if we can get it from style 249 let styleWidth = getStyleSize( style.width ); 250 if ( styleWidth !== false ) { 251 size.width = styleWidth + 252 // add padding and border unless it's already including it 253 ( isBorderBox ? 0 : paddingWidth + borderWidth ); 254 } 255 256 let styleHeight = getStyleSize( style.height ); 257 if ( styleHeight !== false ) { 258 size.height = styleHeight + 259 // add padding and border unless it's already including it 260 ( isBorderBox ? 0 : paddingHeight + borderHeight ); 261 } 262 263 size.innerWidth = size.width - ( paddingWidth + borderWidth ); 264 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 265 266 size.outerWidth = size.width + marginWidth; 267 size.outerHeight = size.height + marginHeight; 268 269 return size; 270 } 271 272 return getSize; 273 274 } ); 275 /** 276 * EvEmitter v2.1.1 277 * Lil' event emitter 278 * MIT License 279 */ 280 281 ( function( global, factory ) { 282 // universal module definition 283 if ( typeof module == 'object' && module.exports ) { 284 // CommonJS - Browserify, Webpack 285 module.exports = factory(); 286 } else { 287 // Browser globals 288 global.EvEmitter = factory(); 289 } 290 291 }( typeof window != 'undefined' ? window : this, function() { 292 293 function EvEmitter() {} 294 295 let proto = EvEmitter.prototype; 296 297 proto.on = function( eventName, listener ) { 298 if ( !eventName || !listener ) return this; 299 300 // set events hash 301 let events = this._events = this._events || {}; 302 // set listeners array 303 let listeners = events[ eventName ] = events[ eventName ] || []; 304 // only add once 305 if ( !listeners.includes( listener ) ) { 306 listeners.push( listener ); 307 } 308 309 return this; 310 }; 311 312 proto.once = function( eventName, listener ) { 313 if ( !eventName || !listener ) return this; 314 315 // add event 316 this.on( eventName, listener ); 317 // set once flag 318 // set onceEvents hash 319 let onceEvents = this._onceEvents = this._onceEvents || {}; 320 // set onceListeners object 321 let onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 322 // set flag 323 onceListeners[ listener ] = true; 324 325 return this; 326 }; 327 328 proto.off = function( eventName, listener ) { 329 let listeners = this._events && this._events[ eventName ]; 330 if ( !listeners || !listeners.length ) return this; 331 332 let index = listeners.indexOf( listener ); 333 if ( index != -1 ) { 334 listeners.splice( index, 1 ); 335 } 336 337 return this; 338 }; 339 340 proto.emitEvent = function( eventName, args ) { 341 let listeners = this._events && this._events[ eventName ]; 342 if ( !listeners || !listeners.length ) return this; 343 344 // copy over to avoid interference if .off() in listener 345 listeners = listeners.slice( 0 ); 346 args = args || []; 347 // once stuff 348 let onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 349 350 for ( let listener of listeners ) { 351 let isOnce = onceListeners && onceListeners[ listener ]; 352 if ( isOnce ) { 353 // remove listener 354 // remove before trigger to prevent recursion 355 this.off( eventName, listener ); 356 // unset once flag 357 delete onceListeners[ listener ]; 358 } 359 // trigger listener 360 listener.apply( this, args ); 361 } 362 363 return this; 364 }; 365 366 proto.allOff = function() { 367 delete this._events; 368 delete this._onceEvents; 369 return this; 370 }; 371 372 return EvEmitter; 373 374 } ) ); 375 /*! 376 * Unidragger v3.0.0 377 * Draggable base class 378 * MIT license 379 */ 380 381 ( function( window, factory ) { 382 // universal module definition 383 if ( typeof module == 'object' && module.exports ) { 384 // CommonJS 385 module.exports = factory( 386 window, 387 require('ev-emitter'), 388 ); 389 } else { 390 // browser global 391 window.Unidragger = factory( 392 window, 393 window.EvEmitter, 394 ); 395 } 396 397 }( typeof window != 'undefined' ? window : this, function factory( window, EvEmitter ) { 398 399 function Unidragger() {} 400 401 // inherit EvEmitter 402 let proto = Unidragger.prototype = Object.create( EvEmitter.prototype ); 403 404 // ----- bind start ----- // 405 406 // trigger handler methods for events 407 proto.handleEvent = function( event ) { 408 let method = 'on' + event.type; 409 if ( this[ method ] ) { 410 this[ method ]( event ); 411 } 412 }; 413 414 let startEvent, activeEvents; 415 if ( 'ontouchstart' in window ) { 416 // HACK prefer Touch Events as you can preventDefault on touchstart to 417 // disable scroll in iOS & mobile Chrome metafizzy/flickity#1177 418 startEvent = 'touchstart'; 419 activeEvents = [ 'touchmove', 'touchend', 'touchcancel' ]; 420 } else if ( window.PointerEvent ) { 421 // Pointer Events 422 startEvent = 'pointerdown'; 423 activeEvents = [ 'pointermove', 'pointerup', 'pointercancel' ]; 424 } else { 425 // mouse events 426 startEvent = 'mousedown'; 427 activeEvents = [ 'mousemove', 'mouseup' ]; 428 } 429 430 // prototype so it can be overwriteable by Flickity 431 proto.touchActionValue = 'none'; 432 433 proto.bindHandles = function() { 434 this._bindHandles( 'addEventListener', this.touchActionValue ); 435 }; 436 437 proto.unbindHandles = function() { 438 this._bindHandles( 'removeEventListener', '' ); 439 }; 440 441 /** 442 * Add or remove start event 443 * @param {String} bindMethod - addEventListener or removeEventListener 444 * @param {String} touchAction - value for touch-action CSS property 445 */ 446 proto._bindHandles = function( bindMethod, touchAction ) { 447 this.handles.forEach( ( handle ) => { 448 handle[ bindMethod ]( startEvent, this ); 449 handle[ bindMethod ]( 'click', this ); 450 // touch-action: none to override browser touch gestures. metafizzy/flickity#540 451 if ( window.PointerEvent ) handle.style.touchAction = touchAction; 452 } ); 453 }; 454 455 proto.bindActivePointerEvents = function() { 456 activeEvents.forEach( ( eventName ) => { 457 window.addEventListener( eventName, this ); 458 } ); 459 }; 460 461 proto.unbindActivePointerEvents = function() { 462 activeEvents.forEach( ( eventName ) => { 463 window.removeEventListener( eventName, this ); 464 } ); 465 }; 466 467 // ----- event handler helpers ----- // 468 469 // trigger method with matching pointer 470 proto.withPointer = function( methodName, event ) { 471 if ( event.pointerId == this.pointerIdentifier ) { 472 this[ methodName ]( event, event ); 473 } 474 }; 475 476 // trigger method with matching touch 477 proto.withTouch = function( methodName, event ) { 478 let touch; 479 for ( let changedTouch of event.changedTouches ) { 480 if ( changedTouch.identifier == this.pointerIdentifier ) { 481 touch = changedTouch; 482 } 483 } 484 if ( touch ) this[ methodName ]( event, touch ); 485 }; 486 487 // ----- start event ----- // 488 489 proto.onmousedown = function( event ) { 490 this.pointerDown( event, event ); 491 }; 492 493 proto.ontouchstart = function( event ) { 494 this.pointerDown( event, event.changedTouches[0] ); 495 }; 496 497 proto.onpointerdown = function( event ) { 498 this.pointerDown( event, event ); 499 }; 500 501 // nodes that have text fields 502 const cursorNodes = [ 'TEXTAREA', 'INPUT', 'SELECT', 'OPTION' ]; 503 // input types that do not have text fields 504 const clickTypes = [ 'radio', 'checkbox', 'button', 'submit', 'image', 'file' ]; 505 506 /** 507 * any time you set `event, pointer` it refers to: 508 * @param {Event} event 509 * @param {Event | Touch} pointer 510 */ 511 proto.pointerDown = function( event, pointer ) { 512 // dismiss multi-touch taps, right clicks, and clicks on text fields 513 let isCursorNode = cursorNodes.includes( event.target.nodeName ); 514 let isClickType = clickTypes.includes( event.target.type ); 515 let isOkayElement = !isCursorNode || isClickType; 516 let isOkay = !this.isPointerDown && !event.button && isOkayElement; 517 if ( !isOkay ) return; 518 519 this.isPointerDown = true; 520 // save pointer identifier to match up touch events 521 this.pointerIdentifier = pointer.pointerId !== undefined ? 522 // pointerId for pointer events, touch.indentifier for touch events 523 pointer.pointerId : pointer.identifier; 524 525 this.pointerDown( event, pointer ); 526 this.bindActivePointerEvents(); 527 this.emitEvent( 'pointerDown', [ event, pointer ] ); 528 }; 529 530 // ----- move ----- // 531 532 proto.onmousemove = function( event ) { 533 this.pointerMove( event, event ); 534 }; 535 536 proto.onpointermove = function( event ) { 537 this.withPointer( 'pointerMove', event ); 538 }; 539 540 proto.ontouchmove = function( event ) { 541 this.withTouch( 'pointerMove', event ); 542 }; 543 544 proto.pointerMove = function( event, pointer ) { 545 let moveVector = { 546 x: pointer.pageX - this.pointerDownPointer.pageX, 547 y: pointer.pageY - this.pointerDownPointer.pageY, 548 }; 549 this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] ); 550 // start drag if pointer has moved far enough to start drag 551 let isDragStarting = !this.isDragging && this.hasDragStarted( moveVector ); 552 if ( isDragStarting ) this.dragStart( event, pointer ); 553 if ( this.isDragging ) this.dragMove( event, pointer, moveVector ); 554 }; 555 556 // condition if pointer has moved far enough to start drag 557 proto.hasDragStarted = function( moveVector ) { 558 return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3; 559 }; 560 561 // ----- drag ----- // 562 563 proto.dragStart = function( event, pointer ) { 564 this.isDragging = true;
565 this.isPreventingClicks = true; // set flag to prevent clicks 566 this.emitEvent( 'dragStart', [ event, pointer ] ); 567 }; 568 569 proto.dragMove = function( event, pointer, moveVector ) { 570 this.emitEvent( 'dragMove', [ event, pointer, moveVector ] ); 571 }; 572 573 // ----- end ----- // 574 575 proto.onmouseup = function( event ) { 576 this.pointerUp( event, event ); 577 }; 578 579 proto.onpointerup = function( event ) { 580 this.withPointer( 'pointerUp', event ); 581 }; 582 583 proto.ontouchend = function( event ) { 584 this.withTouch( 'pointerUp', event ); 585 }; 586 587 proto.pointerUp = function( event, pointer ) { 588 this.pointerDone(); 589 this.emitEvent( 'pointerUp', [ event, pointer ] ); 590 591 if ( this.isDragging ) { 592 this.dragEnd( event, pointer ); 593 } else { 594 // pointer didn't move enough for drag to start 595 this.staticClick( event, pointer ); 596 } 597 }; 598 599 proto.dragEnd = function( event, pointer ) { 600 this.isDragging = false; // reset flag 601 // re-enable clicking async 602 setTimeout( () => delete this.isPreventing
602Clicks ); 603 604 this.emitEvent( 'dragEnd', [ event, pointer ] ); 605 }; 606 607 // triggered on pointer up & pointer cancel 608 proto.pointerDone = function() { 609 this.isPointerDown = false; 610 delete this.pointerIdentifier; 611 this.unbindActivePointerEvents(); 612 this.emitEvent('pointerDone'); 613 }; 614 615 // ----- cancel ----- // 616 617 proto.onpointercancel = function( event ) { 618 this.withPointer( 'pointerCancel', event ); 619 }; 620 621 proto.ontouchcancel = function( event ) { 622 this.withTouch( 'pointerCancel', event ); 623 }; 624 625 proto.pointerCancel = function( event, pointer ) { 626 this.pointerDone(); 627 this.emitEvent( 'pointerCancel', [ event, pointer ] ); 628 }; 629 630 // ----- click ----- // 631 632 // handle all clicks and prevent clicks when dragging 633 proto.onclick = function( event ) { 634 if ( this.isPreventingClicks ) event.preventDefault(); 635 }; 636 637 // triggered after pointer down & up with no/tiny movement 638 proto.staticClick = function( event, pointer ) { 639 // ignore emulated mouse up clicks 640 let isMouseup = event.type == 'mouseup'; 641 if ( isMouseup && this.isIgnoringMouseUp ) return; 642 643 this.emitEvent( 'staticClick', [ event, pointer ] ); 644 645 // set flag for emulated clicks 300ms after touchend 646 if ( isMouseup ) { 647 this.isIgnoringMouseUp = true; 648 // reset flag after 400ms 649 setTimeout( () => { 650 delete this.isIgnoringMouseUp; 651 }, 400 ); 652 } 653 }; 654 655 // ----- ----- // 656 657 return Unidragger; 658 659 } ) ); 660 /*! 661 * Draggabilly v3.0.0 662 * Make that shiz draggable 663 * https://draggabilly.desandro.com 664 * MIT license 665 */ 666 667 ( function( window, factory ) { 668 // universal module definition 669 if ( typeof module == 'object' && module.exports ) { 670 // CommonJS 671 module.exports = factory( 672 window, 673 require('get-size'), 674 require('unidragger'), 675 ); 676 } else { 677 // browser global 678 window.Draggabilly = factory( 679 window, 680 window.getSize, 681 window.Unidragger, 682 ); 683 } 684 685 }( typeof window != 'undefined' ? window : this, 686 function factory( window, getSize, Unidragger ) { 687 688 // -------------------------- helpers & variables -------------------------- // 689 690 function noop() {} 691 692 let jQuery = window.jQuery; 693 694 // -------------------------- Draggabilly -------------------------- // 695 696 function Draggabilly( element, options ) { 697 // querySelector if string 698 this.element = typeof element == 'string' ? 699 document.querySelector( element ) : element; 700 701 if ( jQuery ) { 702 this.$element = jQuery( this.element ); 703 } 704 705 // options 706 this.options = {}; 707 this.option( options ); 708 709 this._create(); 710 } 711 712 // inherit Unidragger methods 713 let proto = Draggabilly.prototype = Object.create( Unidragger.prototype ); 714 715 /** 716 * set options 717 * @param {Object} opts 718 */ 719 proto.option = function( opts ) { 720 this.options = { 721 ...this.options, 722 ...opts, 723 }; 724 }; 725 726 // css position values that don't need to be set 727 const positionValues = [ 'relative', 'absolute', 'fixed' ]; 728 729 proto._create = function() { 730 // properties 731 this.position = {}; 732 this._getPosition(); 733 734 this.startPoint = { x: 0, y: 0 }; 735 this.dragPoint = { x: 0, y: 0 }; 736 737 this.startPosition = { ...this.position }; 738 739 // set relative positioning 740 let style = getComputedStyle( this.element ); 741 if ( !positionValues.includes( style.position ) ) { 742 this.element.style.position = 'relative'; 743 } 744 745 // events 746 this.on( 'pointerDown', this.handlePointerDown ); 747 this.on( 'pointerUp', this.handlePointerUp ); 748 this.on( 'dragStart', this.handleDragStart ); 749 this.on( 'dragMove', this.handleDragMove ); 750 this.on( 'dragEnd', this.handleDragEnd ); 751 752 this.setHandles(); 753 this.enable(); 754 }; 755 756 // set this.handles and bind start events to 'em 757 proto.setHandles = function() { 758 let { handle } = this.options; 759 if ( typeof handle == 'string' ) { 760 this.handles = this.element.querySelectorAll( handle ); 761 } else if ( typeof handle == 'object' && handle.length ) { 762 this.handles = handle; 763 } else if ( handle instanceof HTMLElement ) { 764 this.handles = [ handle ]; 765 } else { 766 this.handles = [ this.element ]; 767 } 768 }; 769 770 const cancelableEvents = [ 'dragStart', 'dragMove', 'dragEnd' ]; 771 772 // duck-punch emitEvent to dispatch jQuery events as well 773 let emitEvent = proto.emitEvent; 774 proto.emitEvent = function( eventName, args ) { 775 // do not emit cancelable events if dragging is disabled 776 let isCanceled = !this.isEnabled && cancelableEvents.includes( eventName ); 777 if ( isCanceled ) return; 778 779 emitEvent.call( this, eventName, args ); 780 781 // trigger jQuery event 782 let jquery = window.jQuery; 783 if ( !jquery || !this.$element ) return; 784 // create jQuery event 785 let event; 786 let jqArgs = args; 787 let isFirstArgEvent = args && args[0] instanceof Event; 788 if ( isFirstArgEvent ) [ event, ...jqArgs ] = args; 789 /* eslint-disable-next-line new-cap */ 790 let $event = jquery.Event( event ); 791 $event.type = eventName; 792 this.$element.trigger( $event, jqArgs ); 793 }; 794 795 // -------------------------- position -------------------------- // 796 797 // get x/y position from style 798 proto._getPosition = function() { 799 let style = getComputedStyle( this.element ); 800 let x = this._getPositionCoord( style.left, 'width' ); 801 let y = this._getPositionCoord( style.top, 'height' ); 802 // clean up 'auto' or other non-integer values 803 this.position.x = isNaN( x ) ? 0 : x; 804 this.position.y = isNaN( y ) ? 0 : y; 805 806 this._addTransformPosition( style ); 807 }; 808 809 proto._getPositionCoord = function( styleSide, measure ) { 810 if ( styleSide.includes('%') ) { 811 // convert percent into pixel for Safari, #75 812 let parentSize = getSize( this.element.parentNode ); 813 // prevent not-in-DOM element throwing bug, #131 814 return !parentSize ? 0 : 815 ( parseFloat( styleSide ) / 100 ) * parentSize[ measure ]; 816 } 817 return parseInt( styleSide, 10 ); 818 }; 819 820 // add transform: translate( x, y ) to position 821 proto._addTransformPosition = function( style ) { 822 let transform = style.transform; 823 // bail out if value is 'none' 824 if ( !transform.startsWith('matrix') ) return; 825 826 // split matrix(1, 0, 0, 1, x, y) 827 let matrixValues = transform.split(','); 828 // translate X value is in 12th or 4th position 829 let xIndex = transform.startsWith('matrix3d') ? 12 : 4; 830 let translateX = parseInt( matrixValues[ xIndex ], 10 ); 831 // translate Y value is in 13th or 5th position 832 let translateY = parseInt( matrixValues[ xIndex + 1 ], 10 ); 833 this.position.x += translateX; 834 this.position.y += translateY; 835 }; 836 837 // -------------------------- events -------------------------- // 838 839 proto.handlePointerDown = function( event, pointer ) { 840 if ( !this.isEnabled ) return; 841 // track start event position 842 // Safari 9 overrides pageX and pageY. These values needs to be copied. flickity#842 843 this.pointerDownPointer = { 844 pageX: pointer.pageX, 845 pageY: pointer.pageY, 846 }; 847 848 event.preventDefault(); 849 document.activeElement.blur(); 850 // bind move and end events 851 this.bindActivePointerEvents( event ); 852 this.element.classList.add('is-pointer-down'); 853 }; 854 855 proto.handleDragStart = function() { 856 if ( !this.isEnabled ) return; 857 858 this._getPosition(); 859 this.measureContainment(); 860 // position _when_ drag began 861 this.startPosition.x = this.position.x; 862 this.startPosition.y = this.position.y; 863 // reset left/top style 864 this.setLeftTop(); 865 866 this.dragPoint.x = 0; 867 this.dragPoint.y = 0; 868 869 this.element.classList.add('is-dragging'); 870 // start animation 871 this.animate(); 872 }; 873 874 proto.measureContainment = function() {
875 let container = this.getContainer(); 876 if ( !container ) return; 877 878 let elemSize = getSize( this.element ); 879 let containerSize = getSize( container ); 880 let { 881 borderLeftWidth, 882 borderRightWidth, 883 borderTopWidth, 884 borderBottomWidth, 885 } = containerSize; 886 let elemRect = this.element.getBoundingClientRect(); 887 let containerRect = container.getBoundingClientRect(); 888 889 let borderSizeX = borderLeftWidth + borderRightWidth; 890 let borderSizeY = borderTopWidth + borderBottomWidth; 891 892 let position = this.relativeStartPosition = { 893 x: elemRect.left - ( containerRect.left + borderLeftWidth ), 894 y: elemRect.top - ( containerRect.top + borderTopWidth ), 895 }; 896 897 this.containSize = { 898 width: ( containerSize.width - borderSizeX ) - position.x - elemSize.width, 899 height: ( containerSize.height - borderSizeY ) - position.y - elemSize.height, 900 }; 901 }; 902 903 proto.getContainer = function() { 904 let containment = this.options.containment; 905 if ( !containment ) return; 906 907 let isElement = containment instanceof HTMLElement; 908 // use as element 909 if ( isElement ) return containment; 910 911 // querySelector if string 912 if ( typeof containment == 'string' ) { 913 return document.querySelector( containment ); 914 } 915 // fallback to parent element 916 return this.element.parentNode; 917 }; 918 919 // ----- move event ----- // 920 921 /** 922 * drag move 923 * @param {Event} event 924 * @param {Event | Touch} pointer 925 * @param {Object} moveVector - x and y coordinates 926 */ 927 proto.handleDragMove = function( event, pointer, moveVector ) { 928 if ( !this.isEnabled ) return; 929 930 let dragX = moveVector.x; 931 let dragY = moveVector.y; 932 933 let grid = this.options.grid; 934 let gridX = grid && grid[0]; 935 let gridY = grid && grid[1]; 936 937 dragX = applyGrid( dragX, gridX ); 938 dragY = applyGrid( dragY, gridY ); 939 940 dragX = this.containDrag( 'x', dragX, gridX ); 941 dragY = this.containDrag( 'y', dragY, gridY ); 942 943 // constrain to axis 944 dragX = this.options.axis == 'y' ? 0 : dragX; 945 dragY = this.options.axis == 'x' ? 0 : dragY; 946 947 this.position.x = this.startPosition.x + dragX; 948 this.position.y = this.startPosition.y + dragY; 949 // set dragPoint properties 950 this.dragPoint.x = dragX; 951 this.dragPoint.y = dragY; 952 }; 953 954 function applyGrid( value, grid, method ) { 955 if ( !grid ) return value; 956 957 method = method || 'round'; 958 return Math[ method ]( value/grid ) * grid; 959 } 960 961 proto.containDrag = function( axis, drag, grid ) { 962 if ( !this.options.containment ) return drag; 963 964 let measure = axis == 'x' ? 'width' : 'height'; 965 966 let rel = this.relativeStartPosition[ axis ]; 967 let min = applyGrid( -rel, grid, 'ceil' ); 968 let max = this.containSize[ measure ]; 969 max = applyGrid( max, grid, 'floor' ); 970 return Math.max( min, Math.min( max, drag ) ); 971 }; 972 973 // ----- end event ----- // 974 975 proto.handlePointerUp = function() { 976 this.element.classList.remove('is-pointer-down'); 977 }; 978 979 proto.handleDragEnd = function() { 980 if ( !this.isEnabled ) return; 981 982 // use top left position when complete 983 this.element.style.transform = ''; 984 this.setLeftTop(); 985 this.element.classList.remove('is-dragging'); 986 }; 987 988 // -------------------------- animation -------------------------- // 989 990 proto.animate = function() { 991 // only render and animate if dragging 992 if ( !this.isDragging ) return; 993 994 this.positionDrag(); 995 requestAnimationFrame( () => this.animate() ); 996 }; 997 998 // left/top positioning 999 proto.setLeftTop = function() { 1000 let { x, y } = this.position; 1001 this.element.style.left = `${x}px`; 1002 this.element.style.top = `${y}px`; 1003 }; 1004 1005 proto.positionDrag = function() { 1006 let { x, y } = this.dragPoint; 1007 this.element.style.transform = `translate3d(${x}px, ${y}px, 0)`; 1008 }; 1009 1010 // ----- methods ----- // 1011 1012 /** 1013 * @param {Number} x 1014 * @param {Number} y 1015 */ 1016 proto.setPosition = function( x, y ) { 1017 this.position.x = x; 1018 this.position.y = y; 1019 this.setLeftTop(); 1020 }; 1021 1022 proto.enable = function() { 1023 if ( this.isEnabled ) return; 1024 this.isEnabled = true; 1025 this.bindHandles(); 1026 }; 1027 1028 proto.disable = function() { 1029 if ( !this.isEnabled ) return; 1030 this.isEnabled = false;
1031 if ( this.isDragging ) this.dragEnd(); 1032 this.unbindHandles(); 1033 }; 1034 1035 const resetCssProperties = [ 'transform', 'left', 'top', 'position' ]; 1036 1037 proto.destroy = function() { 1038 this.disable(); 1039 // reset styles 1040 resetCssProperties.forEach( ( prop ) => { 1041 this.element.style[ prop ] = ''; 1042 } ); 1043 // unbind handles 1044 this.unbindHandles(); 1045 // remove jQuery data 1046 if ( this.$element ) this.$element.removeData('draggabilly'); 1047 }; 1048 1049 // ----- jQuery bridget ----- // 1050 1051 // required for jQuery bridget 1052 proto._init = noop; 1053 1054 if ( jQuery && jQuery.bridget ) { 1055 jQuery.bridget( 'draggabilly', Draggabilly ); 1056 } 1057 1058 // ----- ----- // 1059 1060 return Draggabilly; 1061 1062 } ) );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.