vendor: 39,702 bytes, lines 1-1516
1/** 2 * Owl carousel 3 * @version 2.3.4 4 * @author Bartosz Wojciechowski 5 * @author David Deutsch 6 * @license The MIT License (MIT) 7 * @todo Lazy Load Icon 8 * @todo prevent animationend bubling 9 * @todo itemsScaleUp 10 * @todo Test Zepto 11 * @todo stagePadding calculate wrong active classes 12 */ 13;(function($, window, document, undefined) { 14 15 /** 16 * Creates a carousel. 17 * @class The Owl Carousel. 18 * @public 19 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 20 * @param {Object} [options] - The options 21 */ 22 function Owl(element, options) { 23 24 /** 25 * Current settings for the carousel. 26 * @public 27 */ 28 this.settings = null; 29 30 /** 31 * Current options set by the caller including defaults. 32 * @public 33 */ 34 this.options = $.extend({}, Owl.Defaults, options); 35 36 /** 37 * Plugin element. 38 * @public 39 */ 40 this.$element = $(element); 41 42 /** 43 * Proxied event handlers. 44 * @protected 45 */ 46 this._handlers = {}; 47 48 /** 49 * References to the running plugins of this carousel. 50 * @protected 51 */ 52 this._plugins = {}; 53 54 /** 55 * Currently suppressed events to prevent them from being retriggered. 56 * @protected 57 */ 58 this._supress = {}; 59 60 /** 61 * Absolute current position. 62 * @protected 63 */ 64 this._current = null; 65 66 /** 67 * Animation speed in milliseconds. 68 * @protected 69 */ 70 this._speed = null; 71 72 /** 73 * Coordinates of all items in pixel. 74 * @todo The name of this member is missleading. 75 * @protected 76 */ 77 this._coordinates = []; 78 79 /** 80 * Current breakpoint. 81 * @todo Real media queries would be nice. 82 * @protected 83 */ 84 this._breakpoint = null; 85 86 /** 87 * Current width of the plugin element. 88 */ 89 this._width = null; 90 91 /** 92 * All real items. 93 * @protected 94 */ 95 this._items = []; 96 97 /** 98 * All cloned items. 99 * @protected 100 */ 101 this._clones = []; 102 103 /** 104 * Merge values of all items. 105 * @todo Maybe this could be part of a plugin. 106 * @protected 107 */ 108 this._mergers = []; 109 110 /** 111 * Widths of all items. 112 */ 113 this._widths = []; 114 115 /** 116 * Invalidated parts within the update process. 117 * @protected 118 */ 119 this._invalidated = {}; 120 121 /** 122 * Ordered list of workers for the update process. 123 * @protected 124 */ 125 this._pipe = []; 126 127 /** 128 * Current state information for the drag operation. 129 * @todo #261 130 * @protected 131 */ 132 this._drag = { 133 time: null, 134 target: null, 135 pointer: null, 136 stage: { 137 start: null, 138 current: null 139 }, 140 direction: null 141 }; 142 143 /** 144 * Current state information and their tags. 145 * @type {Object} 146 * @protected 147 */ 148 this._states = { 149 current: {}, 150 tags: { 151 'initializing': [ 'busy' ], 152 'animating': [ 'busy' ], 153 'dragging': [ 'interacting' ] 154 } 155 }; 156 157 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 158 this._handlers[handler] = $.proxy(this[handler], this); 159 }, this)); 160 161 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 162 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 163 = new plugin(this); 164 }, this)); 165 166 $.each(Owl.Workers, $.proxy(function(priority, worker) { 167 this._pipe.push({ 168 'filter': worker.filter, 169 'run': $.proxy(worker.run, this) 170 }); 171 }, this)); 172 173 this.setup(); 174 this.initialize(); 175 } 176 177 /** 178 * Default options for the carousel. 179 * @public 180 */ 181 Owl.Defaults = { 182 items: 3, 183 loop: false, 184 center: false, 185 rewind: false, 186 checkVisibility: true, 187 188 mouseDrag: true, 189 touchDrag: true, 190 pullDrag: true, 191 freeDrag: false, 192 193 margin: 0, 194 stagePadding: 0, 195 196 merge: false, 197 mergeFit: true, 198 autoWidth: false, 199 200 startPosition: 0, 201 rtl: false, 202 203 smartSpeed: 250, 204 fluidSpeed: false, 205 dragEndSpeed: false, 206 207 responsive: {}, 208 responsiveRefreshRate: 200, 209 responsiveBaseElement: window, 210 211 fallbackEasing: 'swing', 212 slideTransition: '', 213 214 info: false, 215 216 nestedItemSelector: false, 217 itemElement: 'div', 218 stageElement: 'div', 219 220 refreshClass: 'owl-refresh', 221 loadedClass: 'owl-loaded', 222 loadingClass: 'owl-loading', 223 rtlClass: 'owl-rtl', 224 responsiveClass: 'owl-responsive', 225 dragClass: 'owl-drag', 226 itemClass: 'owl-item', 227 stageClass: 'owl-stage', 228 stageOuterClass: 'owl-stage-outer', 229 grabClass: 'owl-grab' 230 }; 231 232 /** 233 * Enumeration for width. 234 * @public 235 * @readonly 236 * @enum {String} 237 */ 238 Owl.Width = { 239 Default: 'default', 240 Inner: 'inner', 241 Outer: 'outer' 242 }; 243 244 /** 245 * Enumeration for types. 246 * @public 247 * @readonly 248 * @enum {String} 249 */ 250 Owl.Type = { 251 Event: 'event', 252 State: 'state' 253 }; 254 255 /** 256 * Contains all registered plugins. 257 * @public 258 */ 259 Owl.Plugins = {}; 260 261 /** 262 * List of workers involved in the update process. 263 */ 264 Owl.Workers = [ { 265 filter: [ 'width', 'settings' ], 266 run: function() { 267 this._width = this.$element.width(); 268 } 269 }, { 270 filter: [ 'width', 'items', 'settings' ], 271 run: function(cache) { 272 cache.current = this._items && this._items[this.relative(this._current)]; 273 } 274 }, { 275 filter: [ 'items', 'settings' ], 276 run: function() { 277 this.$stage.children('.cloned').remove(); 278 } 279 }, { 280 filter: [ 'width', 'items', 'settings' ], 281 run: function(cache) { 282 var margin = this.settings.margin || '', 283 grid = !this.settings.autoWidth, 284 rtl = this.settings.rtl, 285 css = { 286 'width': 'auto', 287 'margin-left': rtl ? margin : '', 288 'margin-right': rtl ? '' : margin 289 }; 290 291 !grid && this.$stage.children().css(css); 292 293 cache.css = css; 294 } 295 }, { 296 filter: [ 'width', 'items', 'settings' ], 297 run: function(cache) { 298 var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin, 299 merge = null, 300 iterator = this._items.length, 301 grid = !this.settings.autoWidth, 302 widths = []; 303 304 cache.items = { 305 merge: false, 306 width: width 307 }; 308 309 while (iterator--) { 310 merge = this._mergers[iterator]; 311 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 312 313 cache.items.merge = merge > 1 || cache.items.merge; 314 315 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 316 } 317 318 this._widths = widths; 319 } 320 }, { 321 filter: [ 'items', 'settings' ], 322 run: function() { 323 var clones = [], 324 items = this._items, 325 settings = this.settings, 326 // TODO: Should be computed from number of min width items in stage 327 view = Math.max(settings.items * 2, 4), 328 size = Math.ceil(items.length / 2) * 2, 329 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 330 append = '', 331 prepend = ''; 332 333 repeat /= 2; 334 335 while (repeat > 0) { 336 // Switch to only using appended clones 337 clones.push(this.normalize(clones.length / 2, true)); 338 $(items[clones[clones.length - 1]][0]).clone(true).addClass('cloned').appendTo(this.$stage); 339 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 340 $(items[clones[clones.length - 1]][0]).clone(true).addClass('cloned').prependTo(this.$stage); 341 repeat -= 1; 342 } 343 this._clones = clones; 344 } 345 }, { 346 filter: [ 'width', 'items', 'settings' ], 347 run: function() { 348 var rtl = this.settings.rtl ? 1 : -1, 349 size = this._clones.length + this._items.length, 350 iterator = -1, 351 previous = 0, 352 current = 0, 353 coordinates = []; 354 355 while (++iterator < size) { 356 previous = coordinates[iterator - 1] || 0; 357 current = this._widths[this.relative(iterator)] + this.settings.margin; 358 coordinates.push(previous + current * rtl); 359 } 360 361 this._coordinates = coordinates; 362 } 363 }, { 364 filter: [ 'width', 'items', 'settings' ], 365 run: function() { 366 var padding = this.settings.stagePadding, 367 coordinates = this._coordinates, 368 css = { 369 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 370 'padding-left': padding || '', 371 'padding-right': padding || '' 372 }; 373 374 this.$stage.css(css); 375 } 376 }, { 377 filter: [ 'width', 'items', 'settings' ], 378 run: function(cache) { 379 var iterator = this._coordinates.length, 380 grid = !this.settings.autoWidth, 381 items = this.$stage.children(); 382 383 if (grid && cache.items.merge) { 384 while (iterator--) { 385 cache.css.width = this._widths[this.relative(iterator)]; 386 items.eq(iterator).css(cache.css); 387 } 388 } else if (grid) { 389 cache.css.width = cache.items.width; 390 items.css(cache.css); 391 } 392 } 393 }, { 394 filter: [ 'items' ], 395 run: function() { 396 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 397 } 398 }, { 399 filter: [ 'width', 'items', 'settings' ], 400 run: function(cache) { 401 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 402 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 403 this.reset(cache.current); 404 } 405 }, { 406 filter: [ 'position' ], 407 run: function() { 408 this.animate(this.coordinates(this._current)); 409 } 410 }, { 411 filter: [ 'width', 'position', 'items', 'settings' ], 412 run: function() { 413 var rtl = this.settings.rtl ? 1 : -1, 414 padding = this.settings.stagePadding * 2, 415 begin = this.coordinates(this.current()) + padding, 416 end = begin + this.width() * rtl, 417 inner, outer, matches = [], i, n; 418 419 for (i = 0, n = this._coordinates.length; i < n; i++) { 420 inner = this._coordinates[i - 1] || 0; 421 outer = Math.abs(this._coordinates[i]) + padding * rtl; 422 423 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 424 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 425 matches.push(i); 426 } 427 } 428 429 this.$stage.children('.active').removeClass('active'); 430 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 431 432 this.$stage.children('.center').removeClass('center'); 433 if (this.settings.center) { 434 this.$stage.children().eq(this.current()).addClass('center'); 435 } 436 } 437 } ]; 438 439 /** 440 * Create the stage DOM element 441 */ 442 Owl.prototype.initializeStage = function() { 443 this.$stage = this.$element.find('.' + this.settings.stageClass); 444 445 // if the stage is already in the DOM, grab it and skip stage initialization 446 if (this.$stage.length) { 447 return; 448 } 449 450 this.$element.addClass(this.options.loadingClass); 451 452 // create stage 453 this.$stage = $('<' + this.settings.stageElement + '>', { 454 "class": this.settings.stageClass 455 }).wrap( $( '<div/>', { 456 "class": this.settings.stageOuterClass 457 })); 458 459 // append stage 460 this.$element.append(this.$stage.parent()); 461 }; 462 463 /** 464 * Create item DOM elements 465 */ 466 Owl.prototype.initializeItems = function() { 467 var $items = this.$element.find('.owl-item'); 468 469 // if the items are already in the DOM, grab them and skip item initialization 470 if ($items.length) { 471 this._items = $items.get().map(function(item) { 472 return $(item); 473 }); 474 475 this._mergers = this._items.map(function() { 476 return 1; 477 }); 478 479 this.refresh(); 480 481 return; 482 } 483 484 // append content 485 this.replace(this.$element.children().not(this.$stage.parent())); 486 487 // check visibility 488 if (this.isVisible()) { 489 // update view 490 this.refresh(); 491 } else { 492 // invalidate width 493 this.invalidate('width'); 494 } 495 496 this.$element 497 .removeClass(this.options.loadingClass) 498 .addClass(this.options.loadedClass); 499 }; 500 501 /** 502 * Initializes the carousel. 503 * @protected 504 */ 505 Owl.prototype.initialize = function() { 506 this.enter('initializing'); 507 this.trigger('initialize'); 508 509 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 510 511 if (this.settings.autoWidth && !this.is('pre-loading')) { 512 var imgs, nestedSelector, width; 513 imgs = this.$element.find('img'); 514 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 515 width = this.$element.children(nestedSelector).width(); 516 517 if (imgs.length && width <= 0) { 518 this.preloadAutoWidthImages(imgs); 519 } 520 } 521 522 this.initializeStage(); 523 this.initializeItems(); 524 525 // register event handlers 526 this.registerEventHandlers(); 527 528 this.leave('initializing'); 529 this.trigger('initialized'); 530 }; 531 532 /** 533 * @returns {Boolean} visibility of $element 534 * if you know the carousel will always be visible you can set `checkVisibility` to `false` to 535 * prevent the expensive browser layout forced reflow the $element.is(':visible') does 536 */ 537 Owl.prototype.isVisible = function() { 538 return this.settings.checkVisibility 539 ? this.$element.is(':visible') 540 : true; 541 }; 542 543 /** 544 * Setups the current settings. 545 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 546 * @todo Support for media queries by using `matchMedia` would be nice. 547 * @public 548 */ 549 Owl.prototype.setup = function() { 550 var viewport = this.viewport(), 551 overwrites = this.options.responsive, 552 match = -1, 553 settings = null; 554 555 if (!overwrites) { 556 settings = $.extend({}, this.options); 557 } else { 558 $.each(overwrites, function(breakpoint) { 559 if (breakpoint <= viewport && breakpoint > match) { 560 match = Number(breakpoint); 561 } 562 }); 563 564 settings = $.extend({}, this.options, overwrites[match]); 565 if (typeof settings.stagePadding === 'function') { 566 settings.stagePadding = settings.stagePadding(); 567 } 568 delete settings.responsive; 569 570 // responsive class 571 if (settings.responsiveClass) { 572 this.$element.attr('class', 573 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 574 ); 575 } 576 } 577 578 this.trigger('change', { property: { name: 'settings', value: settings } }); 579 this._breakpoint = match; 580 this.settings = settings; 581 this.invalidate('settings'); 582 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 583 }; 584 585 /** 586 * Updates option logic if necessery. 587 * @protected 588 */ 589 Owl.prototype.optionsLogic = function() { 590 if (this.settings.autoWidth) { 591 this.settings.stagePadding = false; 592 this.settings.merge = false; 593 } 594 }; 595 596 /** 597 * Prepares an item before add. 598 * @todo Rename event parameter `content` to `item`. 599 * @protected 600 * @returns {jQuery|HTMLElement} - The item container. 601 */ 602 Owl.prototype.prepare = function(item) { 603 var event = this.trigger('prepare', { content: item }); 604 605 if (!event.data) { 606 event.data = $('<' + this.settings.itemElement + '/>') 607 .addClass(this.options.itemClass).append(item) 608 } 609 610 this.trigger('prepared', { content: event.data }); 611 612 return event.data; 613 }; 614 615 /** 616 * Updates the view. 617 * @public 618 */ 619 Owl.prototype.update = function() { 620 var i = 0, 621 n = this._pipe.length, 622 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 623 cache = {}; 624 625 while (i < n) { 626 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 627 this._pipe[i].run(cache); 628 } 629 i++; 630 } 631 632 this._invalidated = {}; 633 634 !this.is('valid') && this.enter('valid'); 635 }; 636 637 /** 638 * Gets the width of the view. 639 * @public 640 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 641 * @returns {Number} - The width of the view in pixel. 642 */ 643 Owl.prototype.width = function(dimension) { 644 dimension = dimension || Owl.Width.Default; 645 switch (dimension) { 646 case Owl.Width.Inner: 647 case Owl.Width.Outer: 648 return this._width; 649 default: 650 return this._width - this.settings.stagePadding * 2 + this.settings.margin; 651 } 652 }; 653 654 /** 655 * Refreshes the carousel primarily for adaptive purposes. 656 * @public 657 */ 658 Owl.prototype.refresh = function(resizing) { 659 resizing = resizing || false; 660 661 this.enter('refreshing'); 662 this.trigger('refresh'); 663 664 this.setup(); 665 666 this.optionsLogic(); 667 668 this.$element.addClass(this.options.refreshClass); 669 670 this.update(); 671 672 if (!resizing) { 673 this.onResize(); 674 } 675 676 this.$element.removeClass(this.options.refreshClass); 677 678 this.leave('refreshing'); 679 this.trigger('refreshed'); 680 }; 681 682 /** 683 * Checks window `resize` event. 684 * @protected 685 */ 686 Owl.prototype.onThrottledResize = function() { 687 window.clearTimeout(this.resizeTimer); 688 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 689 }; 690 691 /** 692 * Checks window `resize` event. 693 * @protected 694 */ 695 Owl.prototype.onResize = function() { 696 var resizing = true; 697 698 if (!this._items.length) { 699 return false; 700 } 701 702 if (this._width === this.$element.width()) { 703 return false; 704 } 705 706 if (!this.isVisible()) { 707 return false; 708 } 709 710 this.enter('resizing'); 711 712 if (this.trigger('resize').isDefaultPrevented()) { 713 this.leave('resizing'); 714 return false; 715 } 716 717 this.invalidate('width'); 718 719 this.refresh(resizing); 720 721 this.leave('resizing'); 722 this.trigger('resized'); 723 }; 724 725 /** 726 * Registers event handlers. 727 * @todo Check `msPointerEnabled` 728 * @todo #261 729 * @protected 730 */ 731 Owl.prototype.registerEventHandlers = function() { 732 if ($.support.transition) { 733 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 734 } 735 736 if (this.settings.responsive !== false) { 737 this.on(window, 'resize', this._handlers.onThrottledResize); 738 } 739 740 if (this.settings.mouseDrag) { 741 this.$element.addClass(this.options.dragClass); 742 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 743 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 744 } 745 746 if (this.settings.touchDrag){ 747 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 748 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 749 } 750 }; 751 752 /** 753 * Handles `touchstart` and `mousedown` events. 754 * @todo Horizontal swipe threshold as option 755 * @todo #261 756 * @protected 757 * @param {Event} event - The event arguments. 758 */ 759 Owl.prototype.onDragStart = function(event) { 760 var stage = null; 761 762 if (event.which === 3) { 763 return; 764 } 765 766 if ($.support.transform) { 767 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 768 stage = { 769 x: stage[stage.length === 16 ? 12 : 4], 770 y: stage[stage.length === 16 ? 13 : 5] 771 }; 772 } else { 773 stage = this.$stage.position(); 774 stage = { 775 x: this.settings.rtl ? 776 stage.left + this.$stage.width() - this.width() + this.settings.margin : 777 stage.left, 778 y: stage.top 779 }; 780 } 781 782 if (this.is('animating')) { 783 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 784 this.invalidate('position'); 785 } 786 787 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 788 789 this.speed(0); 790 791 this._drag.time = new Date().getTime(); 792 this._drag.target = $(event.target); 793 this._drag.stage.start = stage; 794 this._drag.stage.current = stage; 795 this._drag.pointer = this.pointer(event); 796 797 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 798 799 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 800 var delta = this.difference(this._drag.pointer, this.pointer(event)); 801 802 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 803 804 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 805 return; 806 } 807 808 event.preventDefault(); 809 810 this.enter('dragging'); 811 this.trigger('drag'); 812 }, this)); 813 }; 814 815 /** 816 * Handles the `touchmove` and `mousemove` events. 817 * @todo #261 818 * @protected 819 * @param {Event} event - The event arguments. 820 */ 821 Owl.prototype.onDragMove = function(event) { 822 var minimum = null, 823 maximum = null, 824 pull = null, 825 delta = this.difference(this._drag.pointer, this.pointer(event)), 826 stage = this.difference(this._drag.stage.start, delta); 827 828 if (!this.is('dragging')) { 829 return; 830 } 831 832 event.preventDefault(); 833 834 if (this.settings.loop) { 835 minimum = this.coordinates(this.minimum()); 836 maximum = this.coordinates(this.maximum() + 1) - minimum; 837 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 838 } else { 839 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 840 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 841 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 842 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 843 } 844 845 this._drag.stage.current = stage; 846 847 this.animate(stage.x); 848 }; 849 850 /** 851 * Handles the `touchend` and `mouseup` events. 852 * @todo #261 853 * @todo Threshold for click event 854 * @protected 855 * @param {Event} event - The event arguments. 856 */ 857 Owl.prototype.onDragEnd = function(event) { 858 var delta = this.difference(this._drag.pointer, this.pointer(event)), 859 stage = this._drag.stage.current, 860 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 861 862 $(document).off('.owl.core'); 863 864 this.$element.removeClass(this.options.grabClass); 865 866 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 867 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 868 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 869 this.invalidate('position'); 870 this.update(); 871 872 this._drag.direction = direction; 873 874 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 875 this._drag.target.one('click.owl.core', function() { return false; }); 876 } 877 } 878 879 if (!this.is('dragging')) { 880 return; 881 } 882 883 this.leave('dragging'); 884 this.trigger('dragged'); 885 }; 886 887 /** 888 * Gets absolute position of the closest item for a coordinate. 889 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 890 * @protected 891 * @param {Number} coordinate - The coordinate in pixel. 892 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 893 * @return {Number} - The absolute position of the closest item. 894 */ 895 Owl.prototype.closest = function(coordinate, direction) { 896 var position = -1, 897 pull = 30, 898 width = this.width(), // visible carousel width 899 count = this.settings.items, 900 itemWidth = Math.round(width / count), 901 coordinates = this.coordinates(); 902 903 if (!this.settings.freeDrag) { 904 // check closest item 905 $.each(coordinates, $.proxy(function(index, value) { 906 // on a left pull, check on current index 907 if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) { 908 position = index; 909 // on a right pull, check on previous index 910 // to do so, subtract width from value and set position = index + 1 911 } else if (direction === 'right' && coordinate > value - itemWidth - pull && coordinate < value - itemWidth + pull) { 912 position = index + 1; 913 } else if (this.op(coordinate, '<', value) 914 && this.op(coordinate, '>', coordinates[index + 1] !== undefined ? coordinates[index + 1] : value - width)) { 915 position = direction === 'left' ? index + 1 : index; 916 } 917 return position === -1; 918 }, this)); 919 } 920 921 if (!this.settings.loop) { 922 // non loop boundries 923 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 924 position = coordinate = this.minimum(); 925 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 926 position = coordinate = this.maximum(); 927 } 928 } 929 930 return position; 931 }; 932 933 /** 934 * Animates the stage. 935 * @todo #270 936 * @public 937 * @param {Number} coordinate - The coordinate in pixels. 938 */ 939 Owl.prototype.animate = function(coordinate) { 940 var animate = this.speed() > 0; 941 942 this.is('animating') && this.onTransitionEnd(); 943 944 if (animate) { 945 this.enter('animating'); 946 this.trigger('translate'); 947 } 948 949 if ($.support.transform3d && $.support.transition) { 950 this.$stage.css({ 951 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 952 transition: (this.speed() / 1000) + 's' + ( 953 this.settings.slideTransition ? ' ' + this.settings.slideTransition : '' 954 ) 955 }); 956 } else if (animate) { 957 this.$stage.animate({ 958 left: coordinate + 'px' 959 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 960 } else { 961 this.$stage.css({ 962 left: coordinate + 'px' 963 }); 964 } 965 }; 966 967 /** 968 * Checks whether the carousel is in a specific state or not. 969 * @param {String} state - The state to check. 970 * @returns {Boolean} - The flag which indicates if the carousel is busy. 971 */ 972 Owl.prototype.is = function(state) { 973 return this._states.current[state] && this._states.current[state] > 0; 974 }; 975 976 /** 977 * Sets the absolute position of the current item. 978 * @public 979 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 980 * @returns {Number} - The absolute position of the current item. 981 */ 982 Owl.prototype.current = function(position) { 983 if (position === undefined) { 984 return this._current; 985 } 986 987 if (this._items.length === 0) { 988 return undefined; 989 } 990 991 position = this.normalize(position); 992 993 if (this._current !== position) { 994 var event = this.trigger('change', { property: { name: 'position', value: position } }); 995 996 if (event.data !== undefined) { 997 position = this.normalize(event.data); 998 } 999 1000 this._current = position; 1001 1002 this.invalidate('position'); 1003 1004 this.trigger('changed', { property: { name: 'position', value: this._current } }); 1005 } 1006 1007 return this._current; 1008 }; 1009 1010 /** 1011 * Invalidates the given part of the update routine. 1012 * @param {String} [part] - The part to invalidate. 1013 * @returns {Array.<String>} - The invalidated parts. 1014 */ 1015 Owl.prototype.invalidate = function(part) { 1016 if ($.type(part) === 'string') { 1017 this._invalidated[part] = true; 1018 this.is('valid') && this.leave('valid'); 1019 } 1020 return $.map(this._invalidated, function(v, i) { return i }); 1021 }; 1022 1023 /** 1024 * Resets the absolute position of the current item. 1025 * @public 1026 * @param {Number} position - The absolute position of the new item. 1027 */ 1028 Owl.prototype.reset = function(position) { 1029 position = this.normalize(position); 1030 1031 if (position === undefined) { 1032 return; 1033 } 1034 1035 this._speed = 0; 1036 this._current = position; 1037 1038 this.suppress([ 'translate', 'translated' ]); 1039 1040 this.animate(this.coordinates(position)); 1041 1042 this.release([ 'translate', 'translated' ]); 1043 }; 1044 1045 /** 1046 * Normalizes an absolute or a relative position of an item. 1047 * @public 1048 * @param {Number} position - The absolute or relative position to normalize. 1049 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 1050 * @returns {Number} - The normalized position. 1051 */ 1052 Owl.prototype.normalize = function(position, relative) { 1053 var n = this._items.length, 1054 m = relative ? 0 : this._clones.length; 1055 1056 if (!this.isNumeric(position) || n < 1) { 1057 position = undefined; 1058 } else if (position < 0 || position >= n + m) { 1059 position = ((position - m / 2) % n + n) % n + m / 2; 1060 } 1061 1062 return position; 1063 }; 1064 1065 /** 1066 * Converts an absolute position of an item into a relative one. 1067 * @public 1068 * @param {Number} position - The absolute position to convert. 1069 * @returns {Number} - The converted position. 1070 */ 1071 Owl.prototype.relative = function(position) { 1072 position -= this._clones.length / 2; 1073 return this.normalize(position, true); 1074 }; 1075 1076 /** 1077 * Gets the maximum position for the current item. 1078 * @public 1079 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 1080 * @returns {Number} 1081 */ 1082 Owl.prototype.maximum = function(relative) { 1083 var settings = this.settings, 1084 maximum = this._coordinates.length, 1085 iterator, 1086 reciprocalItemsWidth, 1087 elementWidth; 1088 1089 if (settings.loop) { 1090 maximum = this._clones.length / 2 + this._items.length - 1; 1091 } else if (settings.autoWidth || settings.merge) { 1092 iterator = this._items.length; 1093 if (iterator) { 1094 reciprocalItemsWidth = this._items[--iterator].width(); 1095 elementWidth = this.$element.width(); 1096 while (iterator--) { 1097 reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin; 1098 if (reciprocalItemsWidth > elementWidth) { 1099 break; 1100 } 1101 } 1102 } 1103 maximum = iterator + 1; 1104 } else if (settings.center) { 1105 maximum = this._items.length - 1; 1106 } else { 1107 maximum = this._items.length - settings.items; 1108 } 1109 1110 if (relative) { 1111 maximum -= this._clones.length / 2; 1112 } 1113 1114 return Math.max(maximum, 0); 1115 }; 1116 1117 /** 1118 * Gets the minimum position for the current item. 1119 * @public 1120 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 1121 * @returns {Number} 1122 */ 1123 Owl.prototype.minimum = function(relative) { 1124 return relative ? 0 : this._clones.length / 2; 1125 }; 1126 1127 /** 1128 * Gets an item at the specified relative position. 1129 * @public 1130 * @param {Number} [position] - The relative position of the item. 1131 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 1132 */ 1133 Owl.prototype.items = function(position) { 1134 if (position === undefined) { 1135 return this._items.slice(); 1136 } 1137 1138 position = this.normalize(position, true); 1139 return this._items[position]; 1140 }; 1141 1142 /** 1143 * Gets an item at the specified relative position. 1144 * @public 1145 * @param {Number} [position] - The relative position of the item. 1146 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 1147 */ 1148 Owl.prototype.mergers = function(position) { 1149 if (position === undefined) { 1150 return this._mergers.slice(); 1151 } 1152 1153 position = this.normalize(position, true); 1154 return this._mergers[position]; 1155 }; 1156 1157 /** 1158 * Gets the absolute positions of clones for an item. 1159 * @public 1160 * @param {Number} [position] - The relative position of the item. 1161 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 1162 */ 1163 Owl.prototype.clones = function(position) { 1164 var odd = this._clones.length / 2, 1165 even = odd + this._items.length, 1166 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 1167 1168 if (position === undefined) { 1169 return $.map(this._clones, function(v, i) { return map(i) }); 1170 } 1171 1172 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 1173 }; 1174 1175 /** 1176 * Sets the current animation speed. 1177 * @public 1178 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 1179 * @returns {Number} - The current animation speed in milliseconds. 1180 */ 1181 Owl.prototype.speed = function(speed) { 1182 if (speed !== undefined) { 1183 this._speed = speed; 1184 } 1185 1186 return this._speed; 1187 }; 1188 1189 /** 1190 * Gets the coordinate of an item. 1191 * @todo The name of this method is missleanding. 1192 * @public 1193 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 1194 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 1195 */ 1196 Owl.prototype.coordinates = function(position) { 1197 var multiplier = 1, 1198 newPosition = position - 1, 1199 coordinate; 1200 1201 if (position === undefined) { 1202 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 1203 return this.coordinates(index); 1204 }, this)); 1205 } 1206 1207 if (this.settings.center) { 1208 if (this.settings.rtl) { 1209 multiplier = -1; 1210 newPosition = position + 1; 1211 } 1212 1213 coordinate = this._coordinates[position]; 1214 coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier; 1215 } else { 1216 coordinate = this._coordinates[newPosition] || 0; 1217 } 1218 1219 coordinate = Math.ceil(coordinate); 1220 1221 return coordinate; 1222 }; 1223 1224 /** 1225 * Calculates the speed for a translation. 1226 * @protected 1227 * @param {Number} from - The absolute position of the start item. 1228 * @param {Number} to - The absolute position of the target item. 1229 * @param {Number} [factor=undefined] - The time factor in milliseconds. 1230 * @returns {Number} - The time in milliseconds for the translation. 1231 */ 1232 Owl.prototype.duration = function(from, to, factor) { 1233 if (factor === 0) { 1234 return 0; 1235 } 1236 1237 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 1238 }; 1239 1240 /** 1241 * Slides to the specified item. 1242 * @public 1243 * @param {Number} position - The position of the item. 1244 * @param {Number} [speed] - The time in milliseconds for the transition. 1245 */ 1246 Owl.prototype.to = function(position, speed) { 1247 var current = this.current(), 1248 revert = null, 1249 distance = position - this.relative(current), 1250 direction = (distance > 0) - (distance < 0), 1251 items = this._items.length, 1252 minimum = this.minimum(), 1253 maximum = this.maximum(); 1254 1255 if (this.settings.loop) { 1256 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 1257 distance += direction * -1 * items; 1258 } 1259 1260 position = current + distance; 1261 revert = ((position - minimum) % items + items) % items + minimum; 1262 1263 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 1264 current = revert - distance; 1265 position = revert; 1266 this.reset(current); 1267 } 1268 } else if (this.settings.rewind) { 1269 maximum += 1; 1270 position = (position % maximum + maximum) % maximum; 1271 } else { 1272 position = Math.max(minimum, Math.min(maximum, position)); 1273 } 1274 1275 this.speed(this.duration(current, position, speed)); 1276 this.current(position); 1277 1278 if (this.isVisible()) { 1279 this.update(); 1280 } 1281 }; 1282 1283 /** 1284 * Slides to the next item. 1285 * @public 1286 * @param {Number} [speed] - The time in milliseconds for the transition. 1287 */ 1288 Owl.prototype.next = function(speed) { 1289 speed = speed || false; 1290 this.to(this.relative(this.current()) + 1, speed); 1291 }; 1292 1293 /** 1294 * Slides to the previous item. 1295 * @public 1296 * @param {Number} [speed] - The time in milliseconds for the transition. 1297 */ 1298 Owl.prototype.prev = function(speed) { 1299 speed = speed || false; 1300 this.to(this.relative(this.current()) - 1, speed); 1301 }; 1302 1303 /** 1304 * Handles the end of an animation. 1305 * @protected 1306 * @param {Event} event - The event arguments. 1307 */ 1308 Owl.prototype.onTransitionEnd = function(event) { 1309 1310 // if css2 animation then event object is undefined 1311 if (event !== undefined) { 1312 event.stopPropagation(); 1313 1314 // Catch only owl-stage transitionEnd event 1315 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 1316 return false; 1317 } 1318 } 1319 1320 this.leave('animating'); 1321 this.trigger('translated'); 1322 }; 1323 1324 /** 1325 * Gets viewport width. 1326 * @protected 1327 * @return {Number} - The width in pixel. 1328 */ 1329 Owl.prototype.viewport = function() { 1330 var width; 1331 if (this.options.responsiveBaseElement !== window) { 1332 width = $(this.options.responsiveBaseElement).width(); 1333 } else if (window.innerWidth) { 1334 width = window.innerWidth; 1335 } else if (document.documentElement && document.documentElement.clientWidth) { 1336 width = document.documentElement.clientWidth; 1337 } else { 1338 console.warn('Can not detect viewport width.'); 1339 } 1340 return width; 1341 }; 1342 1343 /** 1344 * Replaces the current content. 1345 * @public 1346 * @param {HTMLElement|jQuery|String} content - The new content. 1347 */ 1348 Owl.prototype.replace = function(content) { 1349 this.$stage.empty(); 1350 this._items = []; 1351 1352 if (content) { 1353 content = (content instanceof jQuery) ? content : $(content); 1354 } 1355 1356 if (this.settings.nestedItemSelector) { 1357 content = content.find('.' + this.settings.nestedItemSelector); 1358 } 1359 1360 content.filter(function() { 1361 return this.nodeType === 1; 1362 }).each($.proxy(function(index, item) { 1363 item = this.prepare(item); 1364 this.$stage.append(item); 1365 this._items.push(item); 1366 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 1367 }, this)); 1368 1369 this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 1370 1371 this.invalidate('items'); 1372 }; 1373 1374 /** 1375 * Adds an item. 1376 * @todo Use `item` instead of `content` for the event arguments. 1377 * @public 1378 * @param {HTMLElement|jQuery|String} content - The item content to add. 1379 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 1380 */ 1381 Owl.prototype.add = function(content, position) { 1382 var current = this.relative(this._current); 1383 1384 position = position === undefined ? this._items.length : this.normalize(position, true); 1385 content = content instanceof jQuery ? content : $(content); 1386 1387 this.trigger('add', { content: content, position: position }); 1388 1389 content = this.prepare(content); 1390 1391 if (this._items.length === 0 || position === this._items.length) { 1392 this._items.length === 0 && this.$stage.append(content); 1393 this._items.length !== 0 && this._items[position - 1].after(content); 1394 this._items.push(content); 1395 this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 1396 } else { 1397 this._items[position].before(content); 1398 this._items.splice(position, 0, content); 1399 this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 1400 } 1401 1402 this._items[current] && this.reset(this._items[current].index()); 1403 1404 this.invalidate('items'); 1405 1406 this.trigger('added', { content: content, position: position }); 1407 }; 1408 1409 /** 1410 * Removes an item by its position. 1411 * @todo Use `item` instead of `content` for the event arguments. 1412 * @public 1413 * @param {Number} position - The relative position of the item to remove. 1414 */ 1415 Owl.prototype.remove = function(position) { 1416 position = this.normalize(position, true); 1417 1418 if (position === undefined) { 1419 return; 1420 } 1421 1422 this.trigger('remove', { content: this._items[position], position: position }); 1423 1424 this._items[position].remove(); 1425 this._items.splice(position, 1); 1426 this._mergers.splice(position, 1); 1427 1428 this.invalidate('items'); 1429 1430 this.trigger('removed', { content: null, position: position }); 1431 }; 1432 1433 /** 1434 * Preloads images with auto width. 1435 * @todo Replace by a more generic approach 1436 * @protected 1437 */ 1438 Owl.prototype.preloadAutoWidthImages = function(images) { 1439 images.each($.proxy(function(i, element) { 1440 this.enter('pre-loading'); 1441 element = $(element); 1442 $(new Image()).one('load', $.proxy(function(e) { 1443 element.attr('src', e.target.src); 1444 element.css('opacity', 1); 1445 this.leave('pre-loading'); 1446 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 1447 }, this)).attr('src', (window.devicePixelRatio > 1) ? element.attr('data-src-retina') : element.attr('data-src') || element.attr('src')); 1448 }, this)); 1449 }; 1450 1451 /** 1452 * Destroys the carousel. 1453 * @public 1454 */ 1455 Owl.prototype.destroy = function() { 1456 1457 this.$element.off('.owl.core'); 1458 this.$stage.off('.owl.core'); 1459 $(document).off('.owl.core'); 1460 1461 if (this.settings.responsive !== false) { 1462 window.clearTimeout(this.resizeTimer); 1463 this.off(window, 'resize', this._handlers.onThrottledResize); 1464 } 1465 1466 for (var i in this._plugins) { 1467 this._plugins[i].destroy(); 1468 } 1469 1470 this.$stage.children('.cloned').remove(); 1471 1472 this.$stage.unwrap(); 1473 this.$stage.children().contents().unwrap(); 1474 this.$stage.children().unwrap(); 1475 this.$stage.remove(); 1476 this.$element 1477 .removeClass(this.options.refreshClass) 1478 .removeClass(this.options.loadingClass) 1479 .removeClass(this.options.loadedClass) 1480 .removeClass(this.options.rtlClass) 1481 .removeClass(this.options.dragClass) 1482 .removeClass(this.options.grabClass) 1483 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 1484 .removeData('owl.carousel'); 1485 }; 1486 1487 /** 1488 * Operators to calculate right-to-left and left-to-right. 1489 * @protected 1490 * @param {Number} [a] - The left side operand. 1491 * @param {String} [o] - The operator. 1492 * @param {Number} [b] - The right side operand. 1493 */ 1494 Owl.prototype.op = function(a, o, b) { 1495 var rtl = this.settings.rtl; 1496 switch (o) { 1497 case '<': 1498 return rtl ? a > b : a < b; 1499 case '>': 1500 return rtl ? a < b : a > b; 1501 case '>=': 1502 return rtl ? a <= b : a >= b; 1503 case '<=': 1504 return rtl ? a >= b : a <= b; 1505 default: 1506 break; 1507 } 1508 }; 1509 1510 /** 1511 * Attaches to an internal event. 1512 * @protected 1513 * @param {HTMLElement} element - The event source. 1514 * @param {String} event - The event name. 1515 * @param {Function} listener - The event handler to attach. 1516 * @param {Boolean} capture - Wether the event should be handled at the capturing p
vendor: 6,976 bytes, lines 1516-1756
1516hase or not. 1517 */ 1518 Owl.prototype.on = function(element, event, listener, capture) { 1519 if (element.addEventListener) { 1520 element.addEventListener(event, listener, capture); 1521 } else if (element.attachEvent) { 1522 element.attachEvent('on' + event, listener); 1523 } 1524 }; 1525 1526 /** 1527 * Detaches from an internal event. 1528 * @protected 1529 * @param {HTMLElement} element - The event source. 1530 * @param {String} event - The event name. 1531 * @param {Function} listener - The attached event handler to detach. 1532 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 1533 */ 1534 Owl.prototype.off = function(element, event, listener, capture) { 1535 if (element.removeEventListener) { 1536 element.removeEventListener(event, listener, capture); 1537 } else if (element.detachEvent) { 1538 element.detachEvent('on' + event, listener); 1539 } 1540 }; 1541 1542 /** 1543 * Triggers a public event. 1544 * @todo Remove `status`, `relatedTarget` should be used instead. 1545 * @protected 1546 * @param {String} name - The event name. 1547 * @param {*} [data=null] - The event data. 1548 * @param {String} [namespace=carousel] - The event namespace. 1549 * @param {String} [state] - The state which is associated with the event. 1550 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 1551 * @returns {Event} - The event arguments. 1552 */ 1553 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 1554 var status = { 1555 item: { count: this._items.length, index: this.current() } 1556 }, handler = $.camelCase( 1557 $.grep([ 'on', name, namespace ], function(v) { return v }) 1558 .join('-').toLowerCase() 1559 ), event = $.Event( 1560 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 1561 $.extend({ relatedTarget: this }, status, data) 1562 ); 1563 1564 if (!this._supress[name]) { 1565 $.each(this._plugins, function(name, plugin) { 1566 if (plugin.onTrigger) { 1567 plugin.onTrigger(event); 1568 } 1569 }); 1570 1571 this.register({ type: Owl.Type.Event, name: name }); 1572 this.$element.trigger(event); 1573 1574 if (this.settings && typeof this.settings[handler] === 'function') { 1575 this.settings[handler].call(this, event); 1576 } 1577 } 1578 1579 return event; 1580 }; 1581 1582 /** 1583 * Enters a state. 1584 * @param name - The state name. 1585 */ 1586 Owl.prototype.enter = function(name) { 1587 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 1588 if (this._states.current[name] === undefined) { 1589 this._states.current[name] = 0; 1590 } 1591 1592 this._states.current[name]++; 1593 }, this)); 1594 }; 1595 1596 /** 1597 * Leaves a state. 1598 * @param name - The state name. 1599 */ 1600 Owl.prototype.leave = function(name) { 1601 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 1602 this._states.current[name]--; 1603 }, this)); 1604 }; 1605 1606 /** 1607 * Registers an event or state. 1608 * @public 1609 * @param {Object} object - The event or state to register. 1610 */ 1611 Owl.prototype.register = function(object) { 1612 if (object.type === Owl.Type.Event) { 1613 if (!$.event.special[object.name]) { 1614 $.event.special[object.name] = {}; 1615 } 1616 1617 if (!$.event.special[object.name].owl) { 1618 var _default = $.event.special[object.name]._default; 1619 $.event.special[object.name]._default = function(e) { 1620 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 1621 return _default.apply(this, arguments); 1622 } 1623 return e.namespace && e.namespace.indexOf('owl') > -1; 1624 }; 1625 $.event.special[object.name].owl = true; 1626 } 1627 } else if (object.type === Owl.Type.State) { 1628 if (!this._states.tags[object.name]) { 1629 this._states.tags[object.name] = object.tags; 1630 } else { 1631 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 1632 } 1633 1634 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 1635 return $.inArray(tag, this._states.tags[object.name]) === i; 1636 }, this)); 1637 } 1638 }; 1639 1640 /** 1641 * Suppresses events. 1642 * @protected 1643 * @param {Array.<String>} events - The events to suppress. 1644 */ 1645 Owl.prototype.suppress = function(events) { 1646 $.each(events, $.proxy(function(index, event) { 1647 this._supress[event] = true; 1648 }, this)); 1649 }; 1650 1651 /** 1652 * Releases suppressed events. 1653 * @protected 1654 * @param {Array.<String>} events - The events to release. 1655 */ 1656 Owl.prototype.release = function(events) { 1657 $.each(events, $.proxy(function(index, event) { 1658 delete this._supress[event]; 1659 }, this)); 1660 }; 1661 1662 /** 1663 * Gets unified pointer coordinates from event. 1664 * @todo #261 1665 * @protected 1666 * @param {Event} - The `mousedown` or `touchstart` event. 1667 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 1668 */ 1669 Owl.prototype.pointer = function(event) { 1670 var result = { x: null, y: null }; 1671 1672 event = event.originalEvent || event || window.event; 1673 1674 event = event.touches && event.touches.length ? 1675 event.touches[0] : event.changedTouches && event.changedTouches.length ? 1676 event.changedTouches[0] : event; 1677 1678 if (event.pageX) { 1679 result.x = event.pageX; 1680 result.y = event.pageY; 1681 } else { 1682 result.x = event.clientX; 1683 result.y = event.clientY; 1684 } 1685 1686 return result; 1687 }; 1688 1689 /** 1690 * Determines if the input is a Number or something that can be coerced to a Number 1691 * @protected 1692 * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested 1693 * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number 1694 */ 1695 Owl.prototype.isNumeric = function(number) { 1696 return !isNaN(parseFloat(number)); 1697 }; 1698 1699 /** 1700 * Gets the difference of two vectors. 1701 * @todo #261 1702 * @protected 1703 * @param {Object} - The first vector. 1704 * @param {Object} - The second vector. 1705 * @returns {Object} - The difference. 1706 */ 1707 Owl.prototype.difference = function(first, second) { 1708 return { 1709 x: first.x - second.x, 1710 y: first.y - second.y 1711 }; 1712 }; 1713 1714 /** 1715 * The jQuery Plugin for the Owl Carousel 1716 * @todo Navigation plugin `next` and `prev` 1717 * @public 1718 */ 1719 $.fn.owlCarousel = function(option) { 1720 var args = Array.prototype.slice.call(arguments, 1); 1721 1722 return this.each(function() { 1723 var $this = $(this), 1724 data = $this.data('owl.carousel'); 1725 1726 if (!data) { 1727 data = new Owl(this, typeof option == 'object' && option); 1728 $this.data('owl.carousel', data); 1729 1730 $.each([ 1731 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 1732 ], function(i, event) { 1733 data.register({ type: Owl.Type.Event, name: event }); 1734 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 1735 if (e.namespace && e.relatedTarget !== this) { 1736 this.suppress([ event ]); 1737 data[event].apply(this, [].slice.call(arguments, 1)); 1738 this.release([ event ]); 1739 } 1740 }, data)); 1741 }); 1742 } 1743 1744 if (typeof option == 'string' && option.charAt(0) !== '_') { 1745 data[option].apply(data, args); 1746 } 1747 }); 1748 }; 1749 1750 /** 1751 * The constructor for the jQuery Plugin 1752 * @public 1753 */ 1754 $.fn.owlCarousel.Constructor = Owl; 1755 1756})(window.Zepto || window.jQuery, window, document);
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.