1/******/ (function(modules) { // webpackBootstrap 2/******/ // The module cache 3/******/ var installedModules = {}; 4/******/ 5/******/ // The require function 6/******/ function __webpack_require__(moduleId) { 7/******/ 8/******/ // Check if module is in cache 9/******/ if(installedModules[moduleId]) { 10/******/ return installedModules[moduleId].exports; 11/******/ } 12/******/ // Create a new module (and put it into the cache) 13/******/ var module = installedModules[moduleId] = { 14/******/ i: moduleId, 15/******/ l: false, 16/******/ exports: {} 17/******/ }; 18/******/ 19/******/ // Execute the module function 20/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 21/******/ 22/******/ // Flag the module as loaded 23/******/ module.l = true; 24/******/ 25/******/ // Return the exports of the module 26/******/ return module.exports; 27/******/ } 28/******/ 29/******/ 30/******/ // expose the modules object (__webpack_modules__) 31/******/ __webpack_require__.m = modules; 32/******/ 33/******/ // expose the module cache 34/******/ __webpack_require__.c = installedModules; 35/******/ 36/******/ // define getter function for harmony exports 37/******/ __webpack_require__.d = function(exports, name, getter) { 38/******/ if(!__webpack_require__.o(exports, name)) { 39/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); 40/******/ } 41/******/ }; 42/******/ 43/******/ // define __esModule on exports 44/******/ __webpack_require__.r = function(exports) { 45/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 46/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 47/******/ } 48/******/ Object.defineProperty(exports, '__esModule', { value: true }); 49/******/ }; 50/******/ 51/******/ // create a fake namespace object 52/******/ // mode & 1: value is a module id, require it 53/******/ // mode & 2: merge all properties of value into the ns 54/******/ // mode & 4: return value when already ns object 55/******/ // mode & 8|1: behave like require 56/******/ __webpack_require__.t = function(value, mode) { 57/******/ if(mode & 1) value = __webpack_require__(value); 58/******/ if(mode & 8) return value; 59/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; 60/******/ var ns = Object.create(null); 61/******/ __webpack_require__.r(ns); 62/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); 63/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); 64/******/ return ns; 65/******/ }; 66/******/ 67/******/ // getDefaultExport function for compatibility with non-harmony modules 68/******/ __webpack_require__.n = function(module) { 69/******/ var getter = module && module.__esModule ? 70/******/ function getDefault() { return module['default']; } : 71/******/ function getModuleExports() { return module; }; 72/******/ __webpack_require__.d(getter, 'a', getter); 73/******/ return getter; 74/******/ }; 75/******/ 76/******/ // Object.prototype.hasOwnProperty.call 77/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; 78/******/ 79/******/ // __webpack_public_path__ 80/******/ __webpack_require__.p = ""; 81/******/ 82/******/ 83/******/ // Load entry module and return exports 84/******/ return __webpack_require__(__webpack_require__.s = 323); 85/******/ }) 86/************************************************************************/ 87/******/ ({ 88 89/***/ 323: 90/***/ (function(module, __webpack_exports__, __webpack_require__) { 91 92"use strict"; 93__webpack_require__.r(__webpack_exports__); 94/* harmony import */ var _owl_carousel_owl_carousel__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(324); 95/* harmony import */ var _owl_carousel_owl_carousel__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_owl_carousel_owl_carousel__WEBPACK_IMPORTED_MODULE_0__); 96/** 97 * @File Name : owl-carousel-library.js 98 * @Description : owl-carousel-component.js file for slider in Page Designer 99 **/ 100 101 102 103 104 105$(document).ready(function () { 106 var carouselIndicator = $(".product-set-carousel").attr("data-custom-indicator"); 107 var carouselIndicatorAttr = carouselIndicator == 'yes' ? true : false; 108 109 var carouselControls = $(".product-set-carousel").attr("data-custom-dots"); 110 var carouselControlsAttr = carouselControls == 'yes' ? true : false; 111 112 113 $('.owl-carousel-1').owlCarousel({ 114 margin: 10, 115 nav: carouselIndicatorAttr, 116 autoplay:true, 117 loop:false, 118 rewind:true, 119 autoplayTimeout: 7000, 120 smartSpeed: 750, 121 navText: ["<div class='nav-btn prev-slide'></div>", "<div class='nav-btn next-slide'></div>"], 122 dots: carouselControlsAttr, 123 responsive: { 124 0: { 125 items: 1 126 }, 127 600: { 128 items: 1 129 }, 130 1000: { 131 items: 1 132 } 133 }, 134 onInitialized: function(e) { 135 var current = e.item.index; 136 if (current === 0) { 137 $('.owl-prev').addClass('disabled'); 138 } 139 } 140 }) 141 142 $(".owl-carousel-1").on('changed.owl.carousel', function (e) { 143 var current = e.item.index; 144 if (current === 0) { 145 $(this).find('.owl-prev').addClass('disabled'); 146 } 147 else{ 148 if ($(this).find('.owl-prev').hasClass('disabled')){ 149 $(this).find('.owl-prev').removeClass('disabled'); 150 } 151 } 152 });
vendor: 94,367 bytes, lines 153-3656
153 154 $('.owl-carousel-2').owlCarousel({ 155 margin: 10, 156 nav: false, 157 autoplay: true, 158 loop: true, 159 responsive: { 160 0: { 161 items: 1 162 }, 163 600: { 164 items: 1 165 }, 166 1000: { 167 items: 1 168 } 169 } 170 }) 171 $('.owl-carousel-3').owlCarousel({ 172 margin: 10, 173 nav: false, 174 autoplay: true, 175 loop: true, 176 responsive: { 177 0: { 178 items: 1 179 }, 180 600: { 181 items: 1 182 }, 183 1000: { 184 items: 1 185 } 186 } 187 }) 188}); 189function startCarousel() { 190 $('.owl-carousel-2').owlCarousel({ 191 margin: 10, 192 nav: true, 193 autoplay: true, 194 loop: false, 195 responsive: { 196 0: { 197 items: 1 198 }, 199 600: { 200 items: 1 201 }, 202 1000: { 203 items: 1 204 } 205 } 206 }) 207} 208function stopCarousel() { 209 var owl = $('.owl-carousel'); 210 owl.trigger('destroy.owl.carousel'); 211 owl.addClass('off'); 212} 213 214/***/ }), 215 216/***/ 324: 217/***/ (function(module, exports) { 218 219/** 220 * Owl Carousel v2.3.4 221 */ 222/** 223 * Owl carousel 224 * @todo Lazy Load Icon 225 * @todo prevent animationend bubling 226 * @todo itemsScaleUp 227 * @todo Test Zepto 228 * @todo stagePadding calculate wrong active classes 229 */ 230;(function($, window, document, undefined) { 231 232 /** 233 * Creates a carousel. 234 * @class The Owl Carousel. 235 * @public 236 * @param {HTMLElement|jQuery} element - The element to create the carousel for. 237 * @param {Object} [options] - The options 238 */ 239 function Owl(element, options) { 240 241 /** 242 * Current settings for the carousel. 243 * @public 244 */ 245 this.settings = null; 246 247 /** 248 * Current options set by the caller including defaults. 249 * @public 250 */ 251 this.options = $.extend({}, Owl.Defaults, options); 252 253 /** 254 * Plugin element. 255 * @public 256 */ 257 this.$element = $(element); 258 259 /** 260 * Proxied event handlers. 261 * @protected 262 */ 263 this._handlers = {}; 264 265 /** 266 * References to the running plugins of this carousel. 267 * @protected 268 */ 269 this._plugins = {}; 270 271 /** 272 * Currently suppressed events to prevent them from being retriggered. 273 * @protected 274 */ 275 this._supress = {}; 276 277 /** 278 * Absolute current position. 279 * @protected 280 */ 281 this._current = null; 282 283 /** 284 * Animation speed in milliseconds. 285 * @protected 286 */ 287 this._speed = null; 288 289 /** 290 * Coordinates of all items in pixel. 291 * @todo The name of this member is missleading. 292 * @protected 293 */ 294 this._coordinates = []; 295 296 /** 297 * Current breakpoint. 298 * @todo Real media queries would be nice. 299 * @protected 300 */ 301 this._breakpoint = null; 302 303 /** 304 * Current width of the plugin element. 305 */ 306 this._width = null; 307 308 /** 309 * All real items. 310 * @protected 311 */ 312 this._items = []; 313 314 /** 315 * All cloned items. 316 * @protected 317 */ 318 this._clones = []; 319 320 /** 321 * Merge values of all items. 322 * @todo Maybe this could be part of a plugin. 323 * @protected 324 */ 325 this._mergers = []; 326 327 /** 328 * Widths of all items. 329 */ 330 this._widths = []; 331 332 /** 333 * Invalidated parts within the update process. 334 * @protected 335 */ 336 this._invalidated = {}; 337 338 /** 339 * Ordered list of workers for the update process. 340 * @protected 341 */ 342 this._pipe = []; 343 344 /** 345 * Current state information for the drag operation. 346 * @todo #261 347 * @protected 348 */ 349 this._drag = { 350 time: null, 351 target: null, 352 pointer: null, 353 stage: { 354 start: null, 355 current: null 356 }, 357 direction: null 358 }; 359 360 /** 361 * Current state information and their tags. 362 * @type {Object} 363 * @protected 364 */ 365 this._states = { 366 current: {}, 367 tags: { 368 'initializing': [ 'busy' ], 369 'animating': [ 'busy' ], 370 'dragging': [ 'interacting' ] 371 } 372 }; 373 374 $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) { 375 this._handlers[handler] = $.proxy(this[handler], this); 376 }, this)); 377 378 $.each(Owl.Plugins, $.proxy(function(key, plugin) { 379 this._plugins[key.charAt(0).toLowerCase() + key.slice(1)] 380 = new plugin(this); 381 }, this)); 382 383 $.each(Owl.Workers, $.proxy(function(priority, worker) { 384 this._pipe.push({ 385 'filter': worker.filter, 386 'run': $.proxy(worker.run, this) 387 }); 388 }, this)); 389 390 this.setup(); 391 this.initialize(); 392 } 393 394 /** 395 * Default options for the carousel. 396 * @public 397 */ 398 Owl.Defaults = { 399 items: 3, 400 loop: false, 401 center: false, 402 rewind: false, 403 checkVisibility: true, 404 405 mouseDrag: true, 406 touchDrag: true, 407 pullDrag: true, 408 freeDrag: false, 409 410 margin: 0, 411 stagePadding: 0, 412 413 merge: false, 414 mergeFit: true, 415 autoWidth: false, 416 417 startPosition: 0, 418 rtl: false, 419 420 smartSpeed: 250, 421 fluidSpeed: false, 422 dragEndSpeed: false, 423 424 responsive: {}, 425 responsiveRefreshRate: 200, 426 responsiveBaseElement: window, 427 428 fallbackEasing: 'swing', 429 slideTransition: '', 430 431 info: false, 432 433 nestedItemSelector: false, 434 itemElement: 'div', 435 stageElement: 'div', 436 437 refreshClass: 'owl-refresh', 438 loadedClass: 'owl-loaded', 439 loadingClass: 'owl-loading', 440 rtlClass: 'owl-rtl', 441 responsiveClass: 'owl-responsive', 442 dragClass: 'owl-drag', 443 itemClass: 'owl-item', 444 stageClass: 'owl-stage', 445 stageOuterClass: 'owl-stage-outer', 446 grabClass: 'owl-grab' 447 }; 448 449 /** 450 * Enumeration for width. 451 * @public 452 * @readonly 453 * @enum {String} 454 */ 455 Owl.Width = { 456 Default: 'default', 457 Inner: 'inner', 458 Outer: 'outer' 459 }; 460 461 /** 462 * Enumeration for types. 463 * @public 464 * @readonly 465 * @enum {String} 466 */ 467 Owl.Type = { 468 Event: 'event', 469 State: 'state' 470 }; 471 472 /** 473 * Contains all registered plugins. 474 * @public 475 */ 476 Owl.Plugins = {}; 477 478 /** 479 * List of workers involved in the update process. 480 */ 481 Owl.Workers = [ { 482 filter: [ 'width', 'settings' ], 483 run: function() { 484 this._width = this.$element.width(); 485 } 486 }, { 487 filter: [ 'width', 'items', 'settings' ], 488 run: function(cache) { 489 cache.current = this._items && this._items[this.relative(this._current)]; 490 } 491 }, { 492 filter: [ 'items', 'settings' ], 493 run: function() { 494 this.$stage.children('.cloned').remove(); 495 } 496 }, { 497 filter: [ 'width', 'items', 'settings' ], 498 run: function(cache) { 499 var margin = this.settings.margin || '', 500 grid = !this.settings.autoWidth, 501 rtl = this.settings.rtl, 502 css = { 503 'width': 'auto', 504 'margin-left': rtl ? margin : '', 505 'margin-right': rtl ? '' : margin 506 }; 507 508 !grid && this.$stage.children().css(css); 509 510 cache.css = css; 511 } 512 }, { 513 filter: [ 'width', 'items', 'settings' ], 514 run: function(cache) { 515 var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin, 516 merge = null, 517 iterator = this._items.length, 518 grid = !this.settings.autoWidth, 519 widths = []; 520 521 cache.items = { 522 merge: false, 523 width: width 524 }; 525 526 while (iterator--) { 527 merge = this._mergers[iterator]; 528 merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge; 529 530 cache.items.merge = merge > 1 || cache.items.merge; 531 532 widths[iterator] = !grid ? this._items[iterator].width() : width * merge; 533 } 534 535 this._widths = widths; 536 } 537 }, { 538 filter: [ 'items', 'settings' ], 539 run: function() { 540 var clones = [], 541 items = this._items, 542 settings = this.settings, 543 // TODO: Should be computed from number of min width items in stage 544 view = Math.max(settings.items * 2, 4), 545 size = Math.ceil(items.length / 2) * 2, 546 repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0, 547 append = '', 548 prepend = ''; 549 550 repeat /= 2; 551 552 while (repeat > 0) { 553 // Switch to only using appended clones 554 clones.push(this.normalize(clones.length / 2, true)); 555 append = append + items[clones[clones.length - 1]][0].outerHTML; 556 clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true)); 557 prepend = items[clones[clones.length - 1]][0].outerHTML + prepend; 558 repeat -= 1; 559 } 560 561 this._clones = clones; 562 563 $(append).addClass('cloned').appendTo(this.$stage); 564 $(prepend).addClass('cloned').prependTo(this.$stage); 565 } 566 }, { 567 filter: [ 'width', 'items', 'settings' ], 568 run: function() { 569 var rtl = this.settings.rtl ? 1 : -1, 570 size = this._clones.length + this._items.length, 571 iterator = -1, 572 previous = 0, 573 current = 0, 574 coordinates = []; 575 576 while (++iterator < size) { 577 previous = coordinates[iterator - 1] || 0; 578 current = this._widths[this.relative(iterator)] + this.settings.margin; 579 coordinates.push(previous + current * rtl); 580 } 581 582 this._coordinates = coordinates; 583 } 584 }, { 585 filter: [ 'width', 'items', 'settings' ], 586 run: function() { 587 var padding = this.settings.stagePadding, 588 coordinates = this._coordinates, 589 css = { 590 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2, 591 'padding-left': padding || '', 592 'padding-right': padding || '' 593 }; 594 595 this.$stage.css(css); 596 } 597 }, { 598 filter: [ 'width', 'items', 'settings' ], 599 run: function(cache) { 600 var iterator = this._coordinates.length, 601 grid = !this.settings.autoWidth, 602 items = this.$stage.children(); 603 604 if (grid && cache.items.merge) { 605 while (iterator--) { 606 cache.css.width = this._widths[this.relative(iterator)]; 607 items.eq(iterator).css(cache.css); 608 } 609 } else if (grid) { 610 cache.css.width = cache.items.width; 611 items.css(cache.css); 612 } 613 } 614 }, { 615 filter: [ 'items' ], 616 run: function() { 617 this._coordinates.length < 1 && this.$stage.removeAttr('style'); 618 } 619 }, { 620 filter: [ 'width', 'items', 'settings' ], 621 run: function(cache) { 622 cache.current = cache.current ? this.$stage.children().index(cache.current) : 0; 623 cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current)); 624 this.reset(cache.current); 625 } 626 }, { 627 filter: [ 'position' ], 628 run: function() { 629 this.animate(this.coordinates(this._current)); 630 } 631 }, { 632 filter: [ 'width', 'position', 'items', 'settings' ], 633 run: function() { 634 var rtl = this.settings.rtl ? 1 : -1, 635 padding = this.settings.stagePadding * 2, 636 begin = this.coordinates(this.current()) + padding, 637 end = begin + this.width() * rtl, 638 inner, outer, matches = [], i, n; 639 640 for (i = 0, n = this._coordinates.length; i < n; i++) { 641 inner = this._coordinates[i - 1] || 0; 642 outer = Math.abs(this._coordinates[i]) + padding * rtl; 643 644 if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end))) 645 || (this.op(outer, '<', begin) && this.op(outer, '>', end))) { 646 matches.push(i); 647 } 648 } 649 650 this.$stage.children('.active').removeClass('active'); 651 this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active'); 652 653 this.$stage.children('.center').removeClass('center'); 654 if (this.settings.center) { 655 this.$stage.children().eq(this.current()).addClass('center'); 656 } 657 } 658 } ]; 659 660 /** 661 * Create the stage DOM element 662 */ 663 Owl.prototype.initializeStage = function() { 664 this.$stage = this.$element.find('.' + this.settings.stageClass); 665 666 // if the stage is already in the DOM, grab it and skip stage initialization 667 if (this.$stage.length) { 668 return; 669 } 670 671 this.$element.addClass(this.options.loadingClass); 672 673 // create stage 674 this.$stage = $('<' + this.settings.stageElement + '>', { 675 "class": this.settings.stageClass 676 }).wrap( $( '<div/>', { 677 "class": this.settings.stageOuterClass 678 })); 679 680 // append stage 681 this.$element.append(this.$stage.parent()); 682 }; 683 684 /** 685 * Create item DOM elements 686 */ 687 Owl.prototype.initializeItems = function() { 688 var $items = this.$element.find('.owl-item'); 689 690 // if the items are already in the DOM, grab them and skip item initialization 691 if ($items.length) { 692 this._items = $items.get().map(function(item) { 693 return $(item); 694 }); 695 696 this._mergers = this._items.map(function() { 697 return 1; 698 }); 699 700 this.refresh(); 701 702 return; 703 } 704 705 // append content 706 this.replace(this.$element.children().not(this.$stage.parent())); 707 708 // check visibility 709 if (this.isVisible()) { 710 // update view 711 this.refresh(); 712 } else { 713 // invalidate width 714 this.invalidate('width'); 715 } 716 717 this.$element 718 .removeClass(this.options.loadingClass) 719 .addClass(this.options.loadedClass); 720 }; 721 722 /** 723 * Initializes the carousel. 724 * @protected 725 */ 726 Owl.prototype.initialize = function() { 727 this.enter('initializing'); 728 this.trigger('initialize'); 729 730 this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl); 731 732 if (this.settings.autoWidth && !this.is('pre-loading')) { 733 var imgs, nestedSelector, width; 734 imgs = this.$element.find('img'); 735 nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined; 736 width = this.$element.children(nestedSelector).width(); 737 738 if (imgs.length && width <= 0) { 739 this.preloadAutoWidthImages(imgs); 740 } 741 } 742 743 this.initializeStage(); 744 this.initializeItems(); 745 746 // register event handlers 747 this.registerEventHandlers(); 748 749 this.leave('initializing'); 750 this.trigger('initialized'); 751 }; 752 753 /** 754 * @returns {Boolean} visibility of $element 755 * if you know the carousel will always be visible you can set `checkVisibility` to `false` to 756 * prevent the expensive browser layout forced reflow the $element.is(':visible') does 757 */ 758 Owl.prototype.isVisible = function() { 759 return this.settings.checkVisibility 760 ? this.$element.is(':visible') 761 : true; 762 }; 763 764 /** 765 * Setups the current settings. 766 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8? 767 * @todo Support for media queries by using `matchMedia` would be nice. 768 * @public 769 */ 770 Owl.prototype.setup = function() { 771 var viewport = this.viewport(), 772 overwrites = this.options.responsive, 773 match = -1, 774 settings = null; 775 776 if (!overwrites) { 777 settings = $.extend({}, this.options); 778 } else { 779 $.each(overwrites, function(breakpoint) { 780 if (breakpoint <= viewport && breakpoint > match) { 781 match = Number(breakpoint); 782 } 783 }); 784 785 settings = $.extend({}, this.options, overwrites[match]); 786 if (typeof settings.stagePadding === 'function') { 787 settings.stagePadding = settings.stagePadding(); 788 } 789 delete settings.responsive; 790 791 // responsive class 792 if (settings.responsiveClass) { 793 this.$element.attr('class', 794 this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match) 795 ); 796 } 797 } 798 799 this.trigger('change', { property: { name: 'settings', value: settings } }); 800 this._breakpoint = match; 801 this.settings = settings; 802 this.invalidate('settings'); 803 this.trigger('changed', { property: { name: 'settings', value: this.settings } }); 804 }; 805 806 /** 807 * Updates option logic if necessery. 808 * @protected 809 */ 810 Owl.prototype.optionsLogic = function() { 811 if (this.settings.autoWidth) { 812 this.settings.stagePadding = false; 813 this.settings.merge = false; 814 } 815 }; 816 817 /** 818 * Prepares an item before add. 819 * @todo Rename event parameter `content` to `item`. 820 * @protected 821 * @returns {jQuery|HTMLElement} - The item container. 822 */ 823 Owl.prototype.prepare = function(item) { 824 var event = this.trigger('prepare', { content: item }); 825 826 if (!event.data) { 827 event.data = $('<' + this.settings.itemElement + '/>') 828 .addClass(this.options.itemClass).append(item) 829 } 830 831 this.trigger('prepared', { content: event.data }); 832 833 return event.data; 834 }; 835 836 /** 837 * Updates the view. 838 * @public 839 */ 840 Owl.prototype.update = function() { 841 var i = 0, 842 n = this._pipe.length, 843 filter = $.proxy(function(p) { return this[p] }, this._invalidated), 844 cache = {}; 845 846 while (i < n) { 847 if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) { 848 this._pipe[i].run(cache); 849 } 850 i++; 851 } 852 853 this._invalidated = {}; 854 855 !this.is('valid') && this.enter('valid'); 856 }; 857 858 /** 859 * Gets the width of the view. 860 * @public 861 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return. 862 * @returns {Number} - The width of the view in pixel. 863 */ 864 Owl.prototype.width = function(dimension) { 865 dimension = dimension || Owl.Width.Default; 866 switch (dimension) { 867 case Owl.Width.Inner: 868 case Owl.Width.Outer: 869 return this._width; 870 default: 871 return this._width - this.settings.stagePadding * 2 + this.settings.margin; 872 } 873 }; 874 875 /** 876 * Refreshes the carousel primarily for adaptive purposes. 877 * @public 878 */ 879 Owl.prototype.refresh = function() { 880 this.enter('refreshing'); 881 this.trigger('refresh'); 882 883 this.setup(); 884 885 this.optionsLogic(); 886 887 this.$element.addClass(this.options.refreshClass); 888 889 this.update(); 890 891 this.$element.removeClass(this.options.refreshClass); 892 893 this.leave('refreshing'); 894 this.trigger('refreshed'); 895 }; 896 897 /** 898 * Checks window `resize` event. 899 * @protected 900 */ 901 Owl.prototype.onThrottledResize = function() { 902 window.clearTimeout(this.resizeTimer); 903 this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate); 904 }; 905 906 /** 907 * Checks window `resize` event. 908 * @protected 909 */ 910 Owl.prototype.onResize = function() { 911 if (!this._items.length) { 912 return false; 913 } 914 915 if (this._width === this.$element.width()) { 916 return false; 917 } 918 919 if (!this.isVisible()) { 920 return false; 921 } 922 923 this.enter('resizing'); 924 925 if (this.trigger('resize').isDefaultPrevented()) { 926 this.leave('resizing'); 927 return false; 928 } 929 930 this.invalidate('width'); 931 932 this.refresh(); 933 934 this.leave('resizing'); 935 this.trigger('resized'); 936 }; 937 938 /** 939 * Registers event handlers. 940 * @todo Check `msPointerEnabled` 941 * @todo #261 942 * @protected 943 */ 944 Owl.prototype.registerEventHandlers = function() { 945 if ($.support.transition) { 946 this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this)); 947 } 948 949 if (this.settings.responsive !== false) { 950 this.on(window, 'resize', this._handlers.onThrottledResize); 951 } 952 953 if (this.settings.mouseDrag) { 954 this.$element.addClass(this.options.dragClass); 955 this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this)); 956 this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false }); 957 } 958 959 if (this.settings.touchDrag){ 960 this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this)); 961 this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this)); 962 } 963 }; 964 965 /** 966 * Handles `touchstart` and `mousedown` events. 967 * @todo Horizontal swipe threshold as option 968 * @todo #261 969 * @protected 970 * @param {Event} event - The event arguments. 971 */ 972 Owl.prototype.onDragStart = function(event) { 973 var stage = null; 974 975 if (event.which === 3) { 976 return; 977 } 978 979 if ($.support.transform) { 980 stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(','); 981 stage = { 982 x: stage[stage.length === 16 ? 12 : 4], 983 y: stage[stage.length === 16 ? 13 : 5] 984 }; 985 } else { 986 stage = this.$stage.position(); 987 stage = { 988 x: this.settings.rtl ? 989 stage.left + this.$stage.width() - this.width() + this.settings.margin : 990 stage.left, 991 y: stage.top 992 }; 993 } 994 995 if (this.is('animating')) { 996 $.support.transform ? this.animate(stage.x) : this.$stage.stop() 997 this.invalidate('position'); 998 } 999 1000 this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown'); 1001 1002 this.speed(0); 1003 1004 this._drag.time = new Date().getTime(); 1005 this._drag.target = $(event.target); 1006 this._drag.stage.start = stage; 1007 this._drag.stage.current = stage; 1008 this._drag.pointer = this.pointer(event); 1009 1010 $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this)); 1011 1012 $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) { 1013 var delta = this.difference(this._drag.pointer, this.pointer(event)); 1014 1015 $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this)); 1016 1017 if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) { 1018 return; 1019 } 1020 1021 event.preventDefault(); 1022 1023 this.enter('dragging'); 1024 this.trigger('drag'); 1025 }, this)); 1026 }; 1027 1028 /** 1029 * Handles the `touchmove` and `mousemove` events. 1030 * @todo #261 1031 * @protected 1032 * @param {Event} event - The event arguments. 1033 */ 1034 Owl.prototype.onDragMove = function(event) { 1035 var minimum = null, 1036 maximum = null, 1037 pull = null, 1038 delta = this.difference(this._drag.pointer, this.pointer(event)), 1039 stage = this.difference(this._drag.stage.start, delta); 1040 1041 if (!this.is('dragging')) { 1042 return; 1043 } 1044 1045 event.preventDefault(); 1046 1047 if (this.settings.loop) { 1048 minimum = this.coordinates(this.minimum()); 1049 maximum = this.coordinates(this.maximum() + 1) - minimum; 1050 stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum; 1051 } else { 1052 minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum()); 1053 maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum()); 1054 pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0; 1055 stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull); 1056 } 1057 1058 this._drag.stage.current = stage; 1059 1060 this.animate(stage.x); 1061 }; 1062 1063 /** 1064 * Handles the `touchend` and `mouseup` events. 1065 * @todo #261 1066 * @todo Threshold for click event 1067 * @protected 1068 * @param {Event} event - The event arguments. 1069 */ 1070 Owl.prototype.onDragEnd = function(event) { 1071 var delta = this.difference(this._drag.pointer, this.pointer(event)), 1072 stage = this._drag.stage.current, 1073 direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right'; 1074 1075 $(document).off('.owl.core'); 1076 1077 this.$element.removeClass(this.options.grabClass); 1078 1079 if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) { 1080 this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed); 1081 this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction)); 1082 this.invalidate('position'); 1083 this.update(); 1084 1085 this._drag.direction = direction; 1086 1087 if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) { 1088 this._drag.target.one('click.owl.core', function() { return false; }); 1089 } 1090 } 1091 1092 if (!this.is('dragging')) { 1093 return; 1094 } 1095 1096 this.leave('dragging'); 1097 this.trigger('dragged'); 1098 }; 1099 1100 /** 1101 * Gets absolute position of the closest item for a coordinate. 1102 * @todo Setting `freeDrag` makes `closest` not reusable. See #165. 1103 * @protected 1104 * @param {Number} coordinate - The coordinate in pixel. 1105 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`. 1106 * @return {Number} - The absolute position of the closest item. 1107 */ 1108 Owl.prototype.closest = function(coordinate, direction) { 1109 var position = -1, 1110 pull = 30, 1111 width = this.width(), 1112 coordinates = this.coordinates(); 1113 1114 if (!this.settings.freeDrag) { 1115 // check closest item 1116 $.each(coordinates, $.proxy(function(index, value) { 1117 // on a left pull, check on current index 1118 if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) { 1119 position = index; 1120 // on a right pull, check on previous index 1121 // to do so, subtract width from value and set position = index + 1 1122 } else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) { 1123 position = index + 1; 1124 } else if (this.op(coordinate, '<', value) 1125 && this.op(coordinate, '>', coordinates[index + 1] !== undefined ? coordinates[index + 1] : value - width)) { 1126 position = direction === 'left' ? index + 1 : index; 1127 } 1128 return position === -1; 1129 }, this)); 1130 } 1131 1132 if (!this.settings.loop) { 1133 // non loop boundries 1134 if (this.op(coordinate, '>', coordinates[this.minimum()])) { 1135 position = coordinate = this.minimum(); 1136 } else if (this.op(coordinate, '<', coordinates[this.maximum()])) { 1137 position = coordinate = this.maximum(); 1138 } 1139 } 1140 1141 return position; 1142 }; 1143 1144 /** 1145 * Animates the stage. 1146 * @todo #270 1147 * @public 1148 * @param {Number} coordinate - The coordinate in pixels. 1149 */ 1150 Owl.prototype.animate = function(coordinate) { 1151 var animate = this.speed() > 0; 1152 1153 this.is('animating') && this.onTransitionEnd(); 1154 1155 if (animate) { 1156 this.enter('animating'); 1157 this.trigger('translate'); 1158 } 1159 1160 if ($.support.transform3d && $.support.transition) { 1161 this.$stage.css({ 1162 transform: 'translate3d(' + coordinate + 'px,0px,0px)', 1163 transition: (this.speed() / 1000) + 's' + ( 1164 this.settings.slideTransition ? ' ' + this.settings.slideTransition : '' 1165 ) 1166 }); 1167 } else if (animate) { 1168 this.$stage.animate({ 1169 left: coordinate + 'px' 1170 }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this)); 1171 } else { 1172 this.$stage.css({ 1173 left: coordinate + 'px' 1174 }); 1175 } 1176 }; 1177 1178 /** 1179 * Checks whether the carousel is in a specific state or not. 1180 * @param {String} state - The state to check. 1181 * @returns {Boolean} - The flag which indicates if the carousel is busy. 1182 */ 1183 Owl.prototype.is = function(state) { 1184 return this._states.current[state] && this._states.current[state] > 0; 1185 }; 1186 1187 /** 1188 * Sets the absolute position of the current item. 1189 * @public 1190 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged. 1191 * @returns {Number} - The absolute position of the current item. 1192 */ 1193 Owl.prototype.current = function(position) { 1194 if (position === undefined) { 1195 return this._current; 1196 } 1197 1198 if (this._items.length === 0) { 1199 return undefined; 1200 } 1201 1202 position = this.normalize(position); 1203 1204 if (this._current !== position) { 1205 var event = this.trigger('change', { property: { name: 'position', value: position } }); 1206 1207 if (event.data !== undefined) { 1208 position = this.normalize(event.data); 1209 } 1210 1211 this._current = position; 1212 1213 this.invalidate('position'); 1214 1215 this.trigger('changed', { property: { name: 'position', value: this._current } }); 1216 } 1217 1218 return this._current; 1219 }; 1220 1221 /** 1222 * Invalidates the given part of the update routine. 1223 * @param {String} [part] - The part to invalidate. 1224 * @returns {Array.<String>} - The invalidated parts. 1225 */ 1226 Owl.prototype.invalidate = function(part) { 1227 if ($.type(part) === 'string') { 1228 this._invalidated[part] = true; 1229 this.is('valid') && this.leave('valid'); 1230 } 1231 return $.map(this._invalidated, function(v, i) { return i }); 1232 }; 1233 1234 /** 1235 * Resets the absolute position of the current item. 1236 * @public 1237 * @param {Number} position - The absolute position of the new item. 1238 */ 1239 Owl.prototype.reset = function(position) { 1240 position = this.normalize(position); 1241 1242 if (position === undefined) { 1243 return; 1244 } 1245 1246 this._speed = 0; 1247 this._current = position; 1248 1249 this.suppress([ 'translate', 'translated' ]); 1250 1251 this.animate(this.coordinates(position)); 1252 1253 this.release([ 'translate', 'translated' ]); 1254 }; 1255 1256 /** 1257 * Normalizes an absolute or a relative position of an item. 1258 * @public 1259 * @param {Number} position - The absolute or relative position to normalize. 1260 * @param {Boolean} [relative=false] - Whether the given position is relative or not. 1261 * @returns {Number} - The normalized position. 1262 */ 1263 Owl.prototype.normalize = function(position, relative) { 1264 var n = this._items.length, 1265 m = relative ? 0 : this._clones.length; 1266 1267 if (!this.isNumeric(position) || n < 1) { 1268 position = undefined; 1269 } else if (position < 0 || position >= n + m) { 1270 position = ((position - m / 2) % n + n) % n + m / 2; 1271 } 1272 1273 return position; 1274 }; 1275 1276 /** 1277 * Converts an absolute position of an item into a relative one. 1278 * @public 1279 * @param {Number} position - The absolute position to convert. 1280 * @returns {Number} - The converted position. 1281 */ 1282 Owl.prototype.relative = function(position) { 1283 position -= this._clones.length / 2; 1284 return this.normalize(position, true); 1285 }; 1286 1287 /** 1288 * Gets the maximum position for the current item. 1289 * @public 1290 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 1291 * @returns {Number} 1292 */ 1293 Owl.prototype.maximum = function(relative) { 1294 var settings = this.settings, 1295 maximum = this._coordinates.length, 1296 iterator, 1297 reciprocalItemsWidth, 1298 elementWidth; 1299 1300 if (settings.loop) { 1301 maximum = this._clones.length / 2 + this._items.length - 1; 1302 } else if (settings.autoWidth || settings.merge) { 1303 iterator = this._items.length; 1304 if (iterator) { 1305 reciprocalItemsWidth = this._items[--iterator].width(); 1306 elementWidth = this.$element.width(); 1307 while (iterator--) { 1308 reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin; 1309 if (reciprocalItemsWidth > elementWidth) { 1310 break; 1311 } 1312 } 1313 } 1314 maximum = iterator + 1; 1315 } else if (settings.center) { 1316 maximum = this._items.length - 1; 1317 } else { 1318 maximum = this._items.length - settings.items; 1319 } 1320 1321 if (relative) { 1322 maximum -= this._clones.length / 2; 1323 } 1324 1325 return Math.max(maximum, 0); 1326 }; 1327 1328 /** 1329 * Gets the minimum position for the current item. 1330 * @public 1331 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position. 1332 * @returns {Number} 1333 */ 1334 Owl.prototype.minimum = function(relative) { 1335 return relative ? 0 : this._clones.length / 2; 1336 }; 1337 1338 /** 1339 * Gets an item at the specified relative position. 1340 * @public 1341 * @param {Number} [position] - The relative position of the item. 1342 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 1343 */ 1344 Owl.prototype.items = function(position) { 1345 if (position === undefined) { 1346 return this._items.slice(); 1347 } 1348 1349 position = this.normalize(position, true); 1350 return this._items[position]; 1351 }; 1352 1353 /** 1354 * Gets an item at the specified relative position. 1355 * @public 1356 * @param {Number} [position] - The relative position of the item. 1357 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given. 1358 */ 1359 Owl.prototype.mergers = function(position) { 1360 if (position === undefined) { 1361 return this._mergers.slice(); 1362 } 1363 1364 position = this.normalize(position, true); 1365 return this._mergers[position]; 1366 }; 1367 1368 /** 1369 * Gets the absolute positions of clones for an item. 1370 * @public 1371 * @param {Number} [position] - The relative position of the item. 1372 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given. 1373 */ 1374 Owl.prototype.clones = function(position) { 1375 var odd = this._clones.length / 2, 1376 even = odd + this._items.length, 1377 map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 }; 1378 1379 if (position === undefined) { 1380 return $.map(this._clones, function(v, i) { return map(i) }); 1381 } 1382 1383 return $.map(this._clones, function(v, i) { return v === position ? map(i) : null }); 1384 }; 1385 1386 /** 1387 * Sets the current animation speed. 1388 * @public 1389 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged. 1390 * @returns {Number} - The current animation speed in milliseconds. 1391 */ 1392 Owl.prototype.speed = function(speed) { 1393 if (speed !== undefined) { 1394 this._speed = speed; 1395 } 1396 1397 return this._speed; 1398 }; 1399 1400 /** 1401 * Gets the coordinate of an item. 1402 * @todo The name of this method is missleanding. 1403 * @public 1404 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`. 1405 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates. 1406 */ 1407 Owl.prototype.coordinates = function(position) { 1408 var multiplier = 1, 1409 newPosition = position - 1, 1410 coordinate; 1411 1412 if (position === undefined) { 1413 return $.map(this._coordinates, $.proxy(function(coordinate, index) { 1414 return this.coordinates(index); 1415 }, this)); 1416 } 1417 1418 if (this.settings.center) { 1419 if (this.settings.rtl) { 1420 multiplier = -1; 1421 newPosition = position + 1; 1422 } 1423 1424 coordinate = this._coordinates[position]; 1425 coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier; 1426 } else { 1427 coordinate = this._coordinates[newPosition] || 0; 1428 } 1429 1430 coordinate = Math.ceil(coordinate); 1431 1432 return coordinate; 1433 }; 1434 1435 /** 1436 * Calculates the speed for a translation. 1437 * @protected 1438 * @param {Number} from - The absolute position of the start item. 1439 * @param {Number} to - The absolute position of the target item. 1440 * @param {Number} [factor=undefined] - The time factor in milliseconds. 1441 * @returns {Number} - The time in milliseconds for the translation. 1442 */ 1443 Owl.prototype.duration = function(from, to, factor) { 1444 if (factor === 0) { 1445 return 0; 1446 } 1447 1448 return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed)); 1449 }; 1450 1451 /** 1452 * Slides to the specified item. 1453 * @public 1454 * @param {Number} position - The position of the item. 1455 * @param {Number} [speed] - The time in milliseconds for the transition. 1456 */ 1457 Owl.prototype.to = function(position, speed) { 1458 var current = this.current(), 1459 revert = null, 1460 distance = position - this.relative(current), 1461 direction = (distance > 0) - (distance < 0), 1462 items = this._items.length, 1463 minimum = this.minimum(), 1464 maximum = this.maximum(); 1465 1466 if (this.settings.loop) { 1467 if (!this.settings.rewind && Math.abs(distance) > items / 2) { 1468 distance += direction * -1 * items; 1469 } 1470 1471 position = current + distance; 1472 revert = ((position - minimum) % items + items) % items + minimum; 1473 1474 if (revert !== position && revert - distance <= maximum && revert - distance > 0) { 1475 current = revert - distance; 1476 position = revert; 1477 this.reset(current); 1478 } 1479 } else if (this.settings.rewind) { 1480 maximum += 1; 1481 position = (position % maximum + maximum) % maximum; 1482 } else { 1483 position = Math.max(minimum, Math.min(maximum, position)); 1484 } 1485 1486 this.speed(this.duration(current, position, speed)); 1487 this.current(position); 1488 1489 if (this.isVisible()) { 1490 this.update(); 1491 } 1492 }; 1493 1494 /** 1495 * Slides to the next item. 1496 * @public 1497 * @param {Number} [speed] - The time in milliseconds for the transition. 1498 */ 1499 Owl.prototype.next = function(speed) { 1500 speed = speed || false; 1501 this.to(this.relative(this.current()) + 1, speed); 1502 }; 1503 1504 /** 1505 * Slides to the previous item. 1506 * @public 1507 * @param {Number} [speed] - The time in milliseconds for the transition. 1508 */ 1509 Owl.prototype.prev = function(speed) { 1510 speed = speed || false; 1511 this.to(this.relative(this.current()) - 1, speed); 1512 }; 1513 1514 /** 1515 * Handles the end of an animation. 1516 * @protected 1517 * @param {Event} event - The event arguments. 1518 */ 1519 Owl.prototype.onTransitionEnd = function(event) { 1520 1521 // if css2 animation then event object is undefined 1522 if (event !== undefined) { 1523 event.stopPropagation(); 1524 1525 // Catch only owl-stage transitionEnd event 1526 if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) { 1527 return false; 1528 } 1529 } 1530 1531 this.leave('animating'); 1532 this.trigger('translated'); 1533 }; 1534 1535 /** 1536 * Gets viewport width. 1537 * @protected 1538 * @return {Number} - The width in pixel. 1539 */ 1540 Owl.prototype.viewport = function() { 1541 var width; 1542 if (this.options.responsiveBaseElement !== window) { 1543 width = $(this.options.responsiveBaseElement).width(); 1544 } else if (window.innerWidth) { 1545 width = window.innerWidth; 1546 } else if (document.documentElement && document.documentElement.clientWidth) { 1547 width = document.documentElement.clientWidth; 1548 } else { 1549 console.warn('Can not detect viewport width.'); 1550 } 1551 return width; 1552 }; 1553 1554 /** 1555 * Replaces the current content. 1556 * @public 1557 * @param {HTMLElement|jQuery|String} content - The new content. 1558 */ 1559 Owl.prototype.replace = function(content) { 1560 this.$stage.empty(); 1561 this._items = []; 1562 1563 if (content) { 1564 content = (content instanceof jQuery) ? content : $(content); 1565 } 1566 1567 if (this.settings.nestedItemSelector) { 1568 content = content.find('.' + this.settings.nestedItemSelector); 1569 } 1570 1571 content.filter(function() { 1572 return this.nodeType === 1; 1573 }).each($.proxy(function(index, item) { 1574 item = this.prepare(item); 1575 this.$stage.append(item); 1576 this._items.push(item); 1577 this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 1578 }, this)); 1579 1580 this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0); 1581 1582 this.invalidate('items'); 1583 }; 1584 1585 /** 1586 * Adds an item. 1587 * @todo Use `item` instead of `content` for the event arguments. 1588 * @public 1589 * @param {HTMLElement|jQuery|String} content - The item content to add. 1590 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end. 1591 */ 1592 Owl.prototype.add = function(content, position) { 1593 var current = this.relative(this._current); 1594 1595 position = position === undefined ? this._items.length : this.normalize(position, true); 1596 content = content instanceof jQuery ? content : $(content); 1597 1598 this.trigger('add', { content: content, position: position }); 1599 1600 content = this.prepare(content); 1601 1602 if (this._items.length === 0 || position === this._items.length) { 1603 this._items.length === 0 && this.$stage.append(content); 1604 this._items.length !== 0 && this._items[position - 1].after(content); 1605 this._items.push(content); 1606 this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 1607 } else { 1608 this._items[position].before(content); 1609 this._items.splice(position, 0, content); 1610 this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1); 1611 } 1612 1613 this._items[current] && this.reset(this._items[current].index()); 1614 1615 this.invalidate('items'); 1616 1617 this.trigger('added', { content: content, position: position }); 1618 }; 1619 1620 /** 1621 * Removes an item by its position. 1622 * @todo Use `item` instead of `content` for the event arguments. 1623 * @public 1624 * @param {Number} position - The relative position of the item to remove. 1625 */ 1626 Owl.prototype.remove = function(position) { 1627 position = this.normalize(position, true); 1628 1629 if (position === undefined) { 1630 return; 1631 } 1632 1633 this.trigger('remove', { content: this._items[position], position: position }); 1634 1635 this._items[position].remove(); 1636 this._items.splice(position, 1); 1637 this._mergers.splice(position, 1); 1638 1639 this.invalidate('items'); 1640 1641 this.trigger('removed', { content: null, position: position }); 1642 }; 1643 1644 /** 1645 * Preloads images with auto width. 1646 * @todo Replace by a more generic approach 1647 * @protected 1648 */ 1649 Owl.prototype.preloadAutoWidthImages = function(images) { 1650 images.each($.proxy(function(i, element) { 1651 this.enter('pre-loading'); 1652 element = $(element); 1653 $(new Image()).one('load', $.proxy(function(e) { 1654 element.attr('src', e.target.src); 1655 element.css('opacity', 1); 1656 this.leave('pre-loading'); 1657 !this.is('pre-loading') && !this.is('initializing') && this.refresh(); 1658 }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina')); 1659 }, this)); 1660 }; 1661 1662 /** 1663 * Destroys the carousel. 1664 * @public 1665 */ 1666 Owl.prototype.destroy = function() { 1667 1668 this.$element.off('.owl.core'); 1669 this.$stage.off('.owl.core'); 1670 $(document).off('.owl.core'); 1671 1672 if (this.settings.responsive !== false) { 1673 window.clearTimeout(this.resizeTimer); 1674 this.off(window, 'resize', this._handlers.onThrottledResize); 1675 } 1676 1677 for (var i in this._plugins) { 1678 this._plugins[i].destroy(); 1679 } 1680 1681 this.$stage.children('.cloned').remove(); 1682 1683 this.$stage.unwrap(); 1684 this.$stage.children().contents().unwrap(); 1685 this.$stage.children().unwrap(); 1686 this.$stage.remove(); 1687 this.$element 1688 .removeClass(this.options.refreshClass) 1689 .removeClass(this.options.loadingClass) 1690 .removeClass(this.options.loadedClass) 1691 .removeClass(this.options.rtlClass) 1692 .removeClass(this.options.dragClass) 1693 .removeClass(this.options.grabClass) 1694 .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), '')) 1695 .removeData('owl.carousel'); 1696 }; 1697 1698 /** 1699 * Operators to calculate right-to-left and left-to-right. 1700 * @protected 1701 * @param {Number} [a] - The left side operand. 1702 * @param {String} [o] - The operator. 1703 * @param {Number} [b] - The right side operand. 1704 */ 1705 Owl.prototype.op = function(a, o, b) { 1706 var rtl = this.settings.rtl; 1707 switch (o) { 1708 case '<': 1709 return rtl ? a > b : a < b; 1710 case '>': 1711 return rtl ? a < b : a > b; 1712 case '>=': 1713 return rtl ? a <= b : a >= b; 1714 case '<=': 1715 return rtl ? a >= b : a <= b; 1716 default: 1717 break; 1718 } 1719 }; 1720 1721 /** 1722 * Attaches to an internal event. 1723 * @protected 1724 * @param {HTMLElement} element - The event source. 1725 * @param {String} event - The event name. 1726 * @param {Function} listener - The event handler to attach. 1727 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not. 1728 */ 1729 Owl.prototype.on = function(element, event, listener, capture) { 1730 if (element.addEventListener) { 1731 element.addEventListener(event, listener, capture); 1732 } else if (element.attachEvent) { 1733 element.attachEvent('on' + event, listener); 1734 } 1735 }; 1736 1737 /** 1738 * Detaches from an internal event. 1739 * @protected 1740 * @param {HTMLElement} element - The event source. 1741 * @param {String} event - The event name. 1742 * @param {Function} listener - The attached event handler to detach. 1743 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not. 1744 */ 1745 Owl.prototype.off = function(element, event, listener, capture) { 1746 if (element.removeEventListener) { 1747 element.removeEventListener(event, listener, capture); 1748 } else if (element.detachEvent) { 1749 element.detachEvent('on' + event, listener); 1750 } 1751 }; 1752 1753 /** 1754 * Triggers a public event. 1755 * @todo Remove `status`, `relatedTarget` should be used instead. 1756 * @protected 1757 * @param {String} name - The event name. 1758 * @param {*} [data=null] - The event data. 1759 * @param {String} [namespace=carousel] - The event namespace. 1760 * @param {String} [state] - The state which is associated with the event. 1761 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not. 1762 * @returns {Event} - The event arguments. 1763 */ 1764 Owl.prototype.trigger = function(name, data, namespace, state, enter) { 1765 var status = { 1766 item: { count: this._items.length, index: this.current() } 1767 }, handler = $.camelCase( 1768 $.grep([ 'on', name, namespace ], function(v) { return v }) 1769 .join('-').toLowerCase() 1770 ), event = $.Event( 1771 [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(), 1772 $.extend({ relatedTarget: this }, status, data) 1773 ); 1774 1775 if (!this._supress[name]) { 1776 $.each(this._plugins, function(name, plugin) { 1777 if (plugin.onTrigger) { 1778 plugin.onTrigger(event); 1779 } 1780 }); 1781 1782 this.register({ type: Owl.Type.Event, name: name }); 1783 this.$element.trigger(event); 1784 1785 if (this.settings && typeof this.settings[handler] === 'function') { 1786 this.settings[handler].call(this, event); 1787 } 1788 } 1789 1790 return event; 1791 }; 1792 1793 /** 1794 * Enters a state. 1795 * @param name - The state name. 1796 */ 1797 Owl.prototype.enter = function(name) { 1798 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 1799 if (this._states.current[name] === undefined) { 1800 this._states.current[name] = 0; 1801 } 1802 1803 this._states.current[name]++; 1804 }, this)); 1805 }; 1806 1807 /** 1808 * Leaves a state. 1809 * @param name - The state name. 1810 */ 1811 Owl.prototype.leave = function(name) { 1812 $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) { 1813 this._states.current[name]--; 1814 }, this)); 1815 }; 1816 1817 /** 1818 * Registers an event or state. 1819 * @public 1820 * @param {Object} object - The event or state to register. 1821 */ 1822 Owl.prototype.register = function(object) { 1823 if (object.type === Owl.Type.Event) { 1824 if (!$.event.special[object.name]) { 1825 $.event.special[object.name] = {}; 1826 } 1827 1828 if (!$.event.special[object.name].owl) { 1829 var _default = $.event.special[object.name]._default; 1830 $.event.special[object.name]._default = function(e) { 1831 if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) { 1832 return _default.apply(this, arguments); 1833 } 1834 return e.namespace && e.namespace.indexOf('owl') > -1; 1835 }; 1836 $.event.special[object.name].owl = true; 1837 } 1838 } else if (object.type === Owl.Type.State) { 1839 if (!this._states.tags[object.name]) { 1840 this._states.tags[object.name] = object.tags; 1841 } else { 1842 this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags); 1843 } 1844 1845 this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) { 1846 return $.inArray(tag, this._states.tags[object.name]) === i; 1847 }, this)); 1848 } 1849 }; 1850 1851 /** 1852 * Suppresses events. 1853 * @protected 1854 * @param {Array.<String>} events - The events to suppress. 1855 */ 1856 Owl.prototype.suppress = function(events) { 1857 $.each(events, $.proxy(function(index, event) { 1858 this._supress[event] = true; 1859 }, this)); 1860 }; 1861 1862 /** 1863 * Releases suppressed events. 1864 * @protected 1865 * @param {Array.<String>} events - The events to release. 1866 */ 1867 Owl.prototype.release = function(events) { 1868 $.each(events, $.proxy(function(index, event) { 1869 delete this._supress[event]; 1870 }, this)); 1871 }; 1872 1873 /** 1874 * Gets unified pointer coordinates from event. 1875 * @todo #261 1876 * @protected 1877 * @param {Event} - The `mousedown` or `touchstart` event. 1878 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position. 1879 */ 1880 Owl.prototype.pointer = function(event) { 1881 var result = { x: null, y: null }; 1882 1883 event = event.originalEvent || event || window.event; 1884 1885 event = event.touches && event.touches.length ? 1886 event.touches[0] : event.changedTouches && event.changedTouches.length ? 1887 event.changedTouches[0] : event; 1888 1889 if (event.pageX) { 1890 result.x = event.pageX; 1891 result.y = event.pageY; 1892 } else { 1893 result.x = event.clientX; 1894 result.y = event.clientY; 1895 } 1896 1897 return result; 1898 }; 1899 1900 /** 1901 * Determines if the input is a Number or something that can be coerced to a Number 1902 * @protected 1903 * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested 1904 * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number 1905 */ 1906 Owl.prototype.isNumeric = function(number) { 1907 return !isNaN(parseFloat(number)); 1908 }; 1909 1910 /** 1911 * Gets the difference of two vectors. 1912 * @todo #261 1913 * @protected 1914 * @param {Object} - The first vector. 1915 * @param {Object} - The second vector. 1916 * @returns {Object} - The difference. 1917 */ 1918 Owl.prototype.difference = function(first, second) { 1919 return { 1920 x: first.x - second.x, 1921 y: first.y - second.y 1922 }; 1923 }; 1924 1925 /** 1926 * The jQuery Plugin for the Owl Carousel 1927 * @todo Navigation plugin `next` and `prev` 1928 * @public 1929 */ 1930 $.fn.owlCarousel = function(option) { 1931 var args = Array.prototype.slice.call(arguments, 1); 1932 1933 return this.each(function() { 1934 var $this = $(this), 1935 data = $this.data('owl.carousel'); 1936 1937 if (!data) { 1938 data = new Owl(this, typeof option == 'object' && option); 1939 $this.data('owl.carousel', data); 1940 1941 $.each([ 1942 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove' 1943 ], function(i, event) { 1944 data.register({ type: Owl.Type.Event, name: event }); 1945 data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) { 1946 if (e.namespace && e.relatedTarget !== this) { 1947 this.suppress([ event ]); 1948 data[event].apply(this, [].slice.call(arguments, 1)); 1949 this.release([ event ]); 1950 } 1951 }, data)); 1952 }); 1953 } 1954 1955 if (typeof option == 'string' && option.charAt(0) !== '_') { 1956 data[option].apply(data, args); 1957 } 1958 }); 1959 }; 1960 1961 /** 1962 * The constructor for the jQuery Plugin 1963 * @public 1964 */ 1965 $.fn.owlCarousel.Constructor = Owl; 1966 1967})(window.Zepto || window.jQuery, window, document); 1968 1969/** 1970 * AutoRefresh Plugin 1971 * @version 2.3.4 1972 * @author Artus Kolanowski 1973 * @author David Deutsch 1974 * @license The MIT License (MIT) 1975 */ 1976;(function($, window, document, undefined) { 1977 1978 /** 1979 * Creates the auto refresh plugin. 1980 * @class The Auto Refresh Plugin 1981 * @param {Owl} carousel - The Owl Carousel 1982 */ 1983 var AutoRefresh = function(carousel) { 1984 /** 1985 * Reference to the core. 1986 * @protected 1987 * @type {Owl} 1988 */ 1989 this._core = carousel; 1990 1991 /** 1992 * Refresh interval. 1993 * @protected 1994 * @type {number} 1995 */ 1996 this._interval = null; 1997 1998 /** 1999 * Whether the element is currently visible or not. 2000 * @protected 2001 * @type {Boolean} 2002 */ 2003 this._visible = null; 2004 2005 /** 2006 * All event handlers. 2007 * @protected 2008 * @type {Object} 2009 */ 2010 this._handlers = { 2011 'initialized.owl.carousel': $.proxy(function(e) { 2012 if (e.namespace && this._core.settings.autoRefresh) { 2013 this.watch(); 2014 } 2015 }, this) 2016 }; 2017 2018 // set default options 2019 this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options); 2020 2021 // register event handlers 2022 this._core.$element.on(this._handlers); 2023 }; 2024 2025 /** 2026 * Default options. 2027 * @public 2028 */ 2029 AutoRefresh.Defaults = { 2030 autoRefresh: true, 2031 autoRefreshInterval: 500 2032 }; 2033 2034 /** 2035 * Watches the element. 2036 */ 2037 AutoRefresh.prototype.watch = function() { 2038 if (this._interval) { 2039 return; 2040 } 2041 2042 this._visible = this._core.isVisible(); 2043 this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval); 2044 }; 2045 2046 /** 2047 * Refreshes the element. 2048 */ 2049 AutoRefresh.prototype.refresh = function() { 2050 if (this._core.isVisible() === this._visible) { 2051 return; 2052 } 2053 2054 this._visible = !this._visible; 2055 2056 this._core.$element.toggleClass('owl-hidden', !this._visible); 2057 2058 this._visible && (this._core.invalidate('width') && this._core.refresh()); 2059 }; 2060 2061 /** 2062 * Destroys the plugin. 2063 */ 2064 AutoRefresh.prototype.destroy = function() { 2065 var handler, property; 2066 2067 window.clearInterval(this._interval); 2068 2069 for (handler in this._handlers) { 2070 this._core.$element.off(handler, this._handlers[handler]); 2071 } 2072 for (property in Object.getOwnPropertyNames(this)) { 2073 typeof this[property] != 'function' && (this[property] = null); 2074 } 2075 }; 2076 2077 $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh; 2078 2079})(window.Zepto || window.jQuery, window, document); 2080 2081/** 2082 * Lazy Plugin 2083 * @version 2.3.4 2084 * @author Bartosz Wojciechowski 2085 * @author David Deutsch 2086 * @license The MIT License (MIT) 2087 */ 2088;(function($, window, document, undefined) { 2089 2090 /** 2091 * Creates the lazy plugin. 2092 * @class The Lazy Plugin 2093 * @param {Owl} carousel - The Owl Carousel 2094 */ 2095 var Lazy = function(carousel) { 2096 2097 /** 2098 * Reference to the core. 2099 * @protected 2100 * @type {Owl} 2101 */ 2102 this._core = carousel; 2103 2104 /** 2105 * Already loaded items. 2106 * @protected 2107 * @type {Array.<jQuery>} 2108 */ 2109 this._loaded = []; 2110 2111 /** 2112 * Event handlers. 2113 * @protected 2114 * @type {Object} 2115 */ 2116 this._handlers = { 2117 'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy(function(e) { 2118 if (!e.namespace) { 2119 return; 2120 } 2121 2122 if (!this._core.settings || !this._core.settings.lazyLoad) { 2123 return; 2124 } 2125 2126 if ((e.property && e.property.name == 'position') || e.type == 'initialized') { 2127 var settings = this._core.settings, 2128 n = (settings.center && Math.ceil(settings.items / 2) || settings.items), 2129 i = ((settings.center && n * -1) || 0), 2130 position = (e.property && e.property.value !== undefined ? e.property.value : this._core.current()) + i, 2131 clones = this._core.clones().length, 2132 load = $.proxy(function(i, v) { this.load(v) }, this); 2133 //TODO: Need documentation for this new option 2134 if (settings.lazyLoadEager > 0) { 2135 n += settings.lazyLoadEager; 2136 // If the carousel is looping also preload images that are to the "left" 2137 if (settings.loop) { 2138 position -= settings.lazyLoadEager; 2139 n++; 2140 } 2141 } 2142 2143 while (i++ < n) { 2144 this.load(clones / 2 + this._core.relative(position)); 2145 clones && $.each(this._core.clones(this._core.relative(position)), load); 2146 position++; 2147 } 2148 } 2149 }, this) 2150 }; 2151 2152 // set the default options 2153 this._core.options = $.extend({}, Lazy.Defaults, this._core.options); 2154 2155 // register event handler 2156 this._core.$element.on(this._handlers); 2157 }; 2158 2159 /** 2160 * Default options. 2161 * @public 2162 */ 2163 Lazy.Defaults = { 2164 lazyLoad: false, 2165 lazyLoadEager: 0 2166 }; 2167 2168 /** 2169 * Loads all resources of an item at the specified position. 2170 * @param {Number} position - The absolute position of the item. 2171 * @protected 2172 */ 2173 Lazy.prototype.load = function(position) { 2174 var $item = this._core.$stage.children().eq(position), 2175 $elements = $item && $item.find('.owl-lazy'); 2176 2177 if (!$elements || $.inArray($item.get(0), this._loaded) > -1) { 2178 return; 2179 } 2180 2181 $elements.each($.proxy(function(index, element) { 2182 var $element = $(element), image, 2183 url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src') || $element.attr('data-srcset'); 2184 2185 this._core.trigger('load', { element: $element, url: url }, 'lazy'); 2186 2187 if ($element.is('img')) { 2188 $element.one('load.owl.lazy', $.proxy(function() { 2189 $element.css('opacity', 1); 2190 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 2191 }, this)).attr('src', url); 2192 } else if ($element.is('source')) { 2193 $element.one('load.owl.lazy', $.proxy(function() { 2194 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 2195 }, this)).attr('srcset', url); 2196 } else { 2197 image = new Image(); 2198 image.onload = $.proxy(function() { 2199 $element.css({ 2200 'background-image': 'url("' + url + '")', 2201 'opacity': '1' 2202 }); 2203 this._core.trigger('loaded', { element: $element, url: url }, 'lazy'); 2204 }, this); 2205 image.src = url; 2206 } 2207 }, this)); 2208 2209 this._loaded.push($item.get(0)); 2210 }; 2211 2212 /** 2213 * Destroys the plugin. 2214 * @public 2215 */ 2216 Lazy.prototype.destroy = function() { 2217 var handler, property; 2218 2219 for (handler in this.handlers) { 2220 this._core.$element.off(handler, this.handlers[handler]); 2221 } 2222 for (property in Object.getOwnPropertyNames(this)) { 2223 typeof this[property] != 'function' && (this[property] = null); 2224 } 2225 }; 2226 2227 $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy; 2228 2229})(window.Zepto || window.jQuery, window, document); 2230 2231/** 2232 * AutoHeight Plugin 2233 * @version 2.3.4 2234 * @author Bartosz Wojciechowski 2235 * @author David Deutsch 2236 * @license The MIT License (MIT) 2237 */ 2238;(function($, window, document, undefined) { 2239 2240 /** 2241 * Creates the auto height plugin. 2242 * @class The Auto Height Plugin 2243 * @param {Owl} carousel - The Owl Carousel 2244 */ 2245 var AutoHeight = function(carousel) { 2246 /** 2247 * Reference to the core. 2248 * @protected 2249 * @type {Owl} 2250 */ 2251 this._core = carousel; 2252 2253 this._previousHeight = null; 2254 2255 /** 2256 * All event handlers. 2257 * @protected 2258 * @type {Object} 2259 */ 2260 this._handlers = { 2261 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) { 2262 if (e.namespace && this._core.settings.autoHeight) { 2263 this.update(); 2264 } 2265 }, this), 2266 'changed.owl.carousel': $.proxy(function(e) { 2267 if (e.namespace && this._core.settings.autoHeight && e.property.name === 'position'){ 2268 this.update(); 2269 } 2270 }, this), 2271 'loaded.owl.lazy': $.proxy(function(e) { 2272 if (e.namespace && this._core.settings.autoHeight 2273 && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) { 2274 this.update(); 2275 } 2276 }, this) 2277 }; 2278 2279 // set default options 2280 this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options); 2281 2282 // register event handlers 2283 this._core.$element.on(this._handlers); 2284 this._intervalId = null; 2285 var refThis = this; 2286 2287 // These changes have been taken from a PR by gavrochelegnou proposed in #1575 2288 // and have been made compatible with the latest jQuery version 2289 $(window).on('load', function() { 2290 if (refThis._core.settings.autoHeight) { 2291 refThis.update(); 2292 } 2293 }); 2294 2295 // Autoresize the height of the carousel when window is resized 2296 // When carousel has images, the height is dependent on the width 2297 // and should also change on resize 2298 $(window).resize(function() { 2299 if (refThis._core.settings.autoHeight) { 2300 if (refThis._intervalId != null) { 2301 clearTimeout(refThis._intervalId); 2302 } 2303 2304 refThis._intervalId = setTimeout(function() { 2305 refThis.update(); 2306 }, 250); 2307 } 2308 }); 2309 2310 }; 2311 2312 /** 2313 * Default options. 2314 * @public 2315 */ 2316 AutoHeight.Defaults = { 2317 autoHeight: false, 2318 autoHeightClass: 'owl-height' 2319 }; 2320 2321 /** 2322 * Updates the view. 2323 */ 2324 AutoHeight.prototype.update = function() { 2325 var start = this._core._current, 2326 end = start + this._core.settings.items, 2327 lazyLoadEnabled = this._core.settings.lazyLoad, 2328 visible = this._core.$stage.children().toArray().slice(start, end), 2329 heights = [], 2330 maxheight = 0; 2331 2332 $.each(visible, function(index, item) { 2333 heights.push($(item).height()); 2334 }); 2335 2336 maxheight = Math.max.apply(null, heights); 2337 2338 if (maxheight <= 1 && lazyLoadEnabled && this._previousHeight) { 2339 maxheight = this._previousHeight; 2340 } 2341 2342 this._previousHeight = maxheight; 2343 2344 this._core.$stage.parent() 2345 .height(maxheight) 2346 .addClass(this._core.settings.autoHeightClass); 2347 }; 2348 2349 AutoHeight.prototype.destroy = function() { 2350 var handler, property; 2351 2352 for (handler in this._handlers) { 2353 this._core.$element.off(handler, this._handlers[handler]); 2354 } 2355 for (property in Object.getOwnPropertyNames(this)) { 2356 typeof this[property] !== 'function' && (this[property] = null); 2357 } 2358 }; 2359 2360 $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight; 2361 2362})(window.Zepto || window.jQuery, window, document); 2363 2364/** 2365 * Video Plugin 2366 * @version 2.3.4 2367 * @author Bartosz Wojciechowski 2368 * @author David Deutsch 2369 * @license The MIT License (MIT) 2370 */ 2371;(function($, window, document, undefined) { 2372 2373 /** 2374 * Creates the video plugin. 2375 * @class The Video Plugin 2376 * @param {Owl} carousel - The Owl Carousel 2377 */ 2378 var Video = function(carousel) { 2379 /** 2380 * Reference to the core. 2381 * @protected 2382 * @type {Owl} 2383 */ 2384 this._core = carousel; 2385 2386 /** 2387 * Cache all video URLs. 2388 * @protected 2389 * @type {Object} 2390 */ 2391 this._videos = {}; 2392 2393 /** 2394 * Current playing item. 2395 * @protected 2396 * @type {jQuery} 2397 */ 2398 this._playing = null; 2399 2400 /** 2401 * All event handlers. 2402 * @todo The cloned content removale is too late 2403 * @protected 2404 * @type {Object} 2405 */ 2406 this._handlers = { 2407 'initialized.owl.carousel': $.proxy(function(e) { 2408 if (e.namespace) { 2409 this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] }); 2410 } 2411 }, this), 2412 'resize.owl.carousel': $.proxy(function(e) { 2413 if (e.namespace && this._core.settings.video && this.isInFullScreen()) { 2414 e.preventDefault(); 2415 } 2416 }, this), 2417 'refreshed.owl.carousel': $.proxy(function(e) { 2418 if (e.namespace && this._core.is('resizing')) { 2419 this._core.$stage.find('.cloned .owl-video-frame').remove(); 2420 } 2421 }, this), 2422 'changed.owl.carousel': $.proxy(function(e) { 2423 if (e.namespace && e.property.name === 'position' && this._playing) { 2424 this.stop(); 2425 } 2426 }, this), 2427 'prepared.owl.carousel': $.proxy(function(e) { 2428 if (!e.namespace) { 2429 return; 2430 } 2431 2432 var $element = $(e.content).find('.owl-video'); 2433 2434 if ($element.length) { 2435 $element.css('display', 'none'); 2436 this.fetch($element, $(e.content)); 2437 } 2438 }, this) 2439 }; 2440 2441 // set default options 2442 this._core.options = $.extend({}, Video.Defaults, this._core.options); 2443 2444 // register event handlers 2445 this._core.$element.on(this._handlers); 2446 2447 this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) { 2448 this.play(e); 2449 }, this)); 2450 }; 2451 2452 /** 2453 * Default options. 2454 * @public 2455 */ 2456 Video.Defaults = { 2457 video: false, 2458 videoHeight: false, 2459 videoWidth: false 2460 }; 2461 2462 /** 2463 * Gets the video ID and the type (YouTube/Vimeo/vzaar only). 2464 * @protected 2465 * @param {jQuery} target - The target containing the video data. 2466 * @param {jQuery} item - The item containing the video. 2467 */ 2468 Video.prototype.fetch = function(target, item) { 2469 var type = (function() { 2470 if (target.attr('data-vimeo-id')) { 2471 return 'vimeo'; 2472 } else if (target.attr('data-vzaar-id')) { 2473 return 'vzaar' 2474 } else { 2475 return 'youtube'; 2476 } 2477 })(), 2478 id = target.attr('data-vimeo-id') || target.attr('data-youtube-id') || target.attr('data-vzaar-id'), 2479 width = target.attr('data-width') || this._core.settings.videoWidth, 2480 height = target.attr('data-height') || this._core.settings.videoHeight, 2481 url = target.attr('href'); 2482 2483 if (url) { 2484 2485 /* 2486 Parses the id's out of the following urls (and probably more): 2487 https://www.youtube.com/watch?v=:id 2488 https://youtu.be/:id 2489 https://vimeo.com/:id 2490 https://vimeo.com/channels/:channel/:id 2491 https://vimeo.com/groups/:group/videos/:id 2492 https://app.vzaar.com/videos/:id 2493 2494 Visual example: https://regexper.com/#(http%3A%7Chttps%3A%7C)%5C%2F%5C%2F(player.%7Cwww.%7Capp.)%3F(vimeo%5C.com%7Cyoutu(be%5C.com%7C%5C.be%7Cbe%5C.googleapis%5C.com)%7Cvzaar%5C.com)%5C%2F(video%5C%2F%7Cvideos%5C%2F%7Cembed%5C%2F%7Cchannels%5C%2F.%2B%5C%2F%7Cgroups%5C%2F.%2B%5C%2F%7Cwatch%5C%3Fv%3D%7Cv%5C%2F)%3F(%5BA-Za-z0-9._%25-%5D*)(%5C%26%5CS%2B)%3F 2495 */ 2496 2497 id = url.match(/(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com|be\-nocookie\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/); 2498 2499 if (id[3].indexOf('youtu') > -1) { 2500 type = 'youtube'; 2501 } else if (id[3].indexOf('vimeo') > -1) { 2502 type = 'vimeo'; 2503 } else if (id[3].indexOf('vzaar') > -1) { 2504 type = 'vzaar'; 2505 } else { 2506 throw new Error('Video URL not supported.'); 2507 } 2508 id = id[6]; 2509 } else { 2510 throw new Error('Missing video URL.'); 2511 } 2512 2513 this._videos[url] = { 2514 type: type, 2515 id: id, 2516 width: width, 2517 height: height 2518 }; 2519 2520 item.attr('data-video', url); 2521 2522 this.thumbnail(target, this._videos[url]); 2523 }; 2524 2525 /** 2526 * Creates video thumbnail. 2527 * @protected 2528 * @param {jQuery} target - The target containing the video data. 2529 * @param {Object} info - The video info object. 2530 * @see `fetch` 2531 */ 2532 Video.prototype.thumbnail = function(target, video) { 2533 var tnLink, 2534 icon, 2535 path, 2536 dimensions = video.width && video.height ? 'width:' + video.width + 'px;height:' + video.height + 'px;' : '', 2537 customTn = target.find('img'), 2538 srcType = 'src', 2539 lazyClass = '', 2540 settings = this._core.settings, 2541 create = function(path) { 2542 icon = '<div class="owl-video-play-icon"></div>'; 2543 2544 if (settings.lazyLoad) { 2545 tnLink = $('<div/>',{ 2546 "class": 'owl-video-tn ' + lazyClass, 2547 "srcType": path 2548 }); 2549 } else { 2550 tnLink = $( '<div/>', { 2551 "class": "owl-video-tn", 2552 "style": 'opacity:1;background-image:url(' + path + ')' 2553 }); 2554 } 2555 target.after(tnLink); 2556 target.after(icon); 2557 }; 2558 2559 // wrap video content into owl-video-wrapper div 2560 target.wrap( $( '<div/>', { 2561 "class": "owl-video-wrapper", 2562 "style": dimensions 2563 })); 2564 2565 if (this._core.settings.lazyLoad) { 2566 srcType = 'data-src'; 2567 lazyClass = 'owl-lazy'; 2568 } 2569 2570 // custom thumbnail 2571 if (customTn.length) { 2572 create(customTn.attr(srcType)); 2573 customTn.remove(); 2574 return false; 2575 } 2576 2577 if (video.type === 'youtube') { 2578 path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg"; 2579 create(path); 2580 } else if (video.type === 'vimeo') { 2581 $.ajax({ 2582 type: 'GET', 2583 url: '//vimeo.com/api/v2/video/' + video.id + '.json', 2584 jsonp: 'callback', 2585 dataType: 'jsonp', 2586 success: function(data) { 2587 path = data[0].thumbnail_large; 2588 create(path); 2589 } 2590 }); 2591 } else if (video.type === 'vzaar') { 2592 $.ajax({ 2593 type: 'GET', 2594 url: '//vzaar.com/api/videos/' + video.id + '.json', 2595 jsonp: 'callback', 2596 dataType: 'jsonp', 2597 success: function(data) { 2598 path = data.framegrab_url; 2599 create(path); 2600 } 2601 }); 2602 } 2603 }; 2604 2605 /** 2606 * Stops the current video. 2607 * @public 2608 */ 2609 Video.prototype.stop = function() { 2610 this._core.trigger('stop', null, 'video'); 2611 this._playing.find('.owl-video-frame').remove(); 2612 this._playing.removeClass('owl-video-playing'); 2613 this._playing = null; 2614 this._core.leave('playing'); 2615 this._core.trigger('stopped', null, 'video'); 2616 }; 2617 2618 /** 2619 * Starts the current video. 2620 * @public 2621 * @param {Event} event - The event arguments. 2622 */ 2623 Video.prototype.play = function(event) { 2624 var target = $(event.target), 2625 item = target.closest('.' + this._core.settings.itemClass), 2626 video = this._videos[item.attr('data-video')], 2627 width = video.width || '100%', 2628 height = video.height || this._core.$stage.height(), 2629 html, 2630 iframe; 2631 2632 if (this._playing) { 2633 return; 2634 } 2635 2636 this._core.enter('playing'); 2637 this._core.trigger('play', null, 'video'); 2638 2639 item = this._core.items(this._core.relative(item.index())); 2640 2641 this._core.reset(item.index()); 2642 2643 html = $( '<iframe frameborder="0" allowfullscreen mozallowfullscreen webkitAllowFullScreen ></iframe>' ); 2644 html.attr( 'height', height ); 2645 html.attr( 'width', width ); 2646 if (video.type === 'youtube') { 2647 html.attr( 'src', '//www.youtube.com/embed/' + video.id + '?autoplay=1&rel=0&v=' + video.id ); 2648 } else if (video.type === 'vimeo') { 2649 html.attr( 'src', '//player.vimeo.com/video/' + video.id + '?autoplay=1' ); 2650 } else if (video.type === 'vzaar') { 2651 html.attr( 'src', '//view.vzaar.com/' + video.id + '/player?autoplay=true' ); 2652 } 2653 2654 iframe = $(html).wrap( '<div class="owl-video-frame" />' ).insertAfter(item.find('.owl-video')); 2655 2656 this._playing = item.addClass('owl-video-playing'); 2657 }; 2658 2659 /** 2660 * Checks whether an video is currently in full screen mode or not. 2661 * @todo Bad style because looks like a readonly method but changes members. 2662 * @protected 2663 * @returns {Boolean} 2664 */ 2665 Video.prototype.isInFullScreen = function() { 2666 var element = document.fullscreenElement || document.mozFullScreenElement || 2667 document.webkitFullscreenElement; 2668 2669 return element && $(element).parent().hasClass('owl-video-frame'); 2670 }; 2671 2672 /** 2673 * Destroys the plugin. 2674 */ 2675 Video.prototype.destroy = function() { 2676 var handler, property; 2677 2678 this._core.$element.off('click.owl.video'); 2679 2680 for (handler in this._handlers) { 2681 this._core.$element.off(handler, this._handlers[handler]); 2682 } 2683 for (property in Object.getOwnPropertyNames(this)) { 2684 typeof this[property] != 'function' && (this[property] = null); 2685 } 2686 }; 2687 2688 $.fn.owlCarousel.Constructor.Plugins.Video = Video; 2689 2690})(window.Zepto || window.jQuery, window, document); 2691 2692/** 2693 * Animate Plugin 2694 * @version 2.3.4 2695 * @author Bartosz Wojciechowski 2696 * @author David Deutsch 2697 * @license The MIT License (MIT) 2698 */ 2699;(function($, window, document, undefined) { 2700 2701 /** 2702 * Creates the animate plugin. 2703 * @class The Navigation Plugin 2704 * @param {Owl} scope - The Owl Carousel 2705 */ 2706 var Animate = function(scope) { 2707 this.core = scope; 2708 this.core.options = $.extend({}, Animate.Defaults, this.core.options); 2709 this.swapping = true; 2710 this.previous = undefined; 2711 this.next = undefined; 2712 2713 this.handlers = { 2714 'change.owl.carousel': $.proxy(function(e) { 2715 if (e.namespace && e.property.name == 'position') { 2716 this.previous = this.core.current(); 2717 this.next = e.property.value; 2718 } 2719 }, this), 2720 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) { 2721 if (e.namespace) { 2722 this.swapping = e.type == 'translated'; 2723 } 2724 }, this), 2725 'translate.owl.carousel': $.proxy(function(e) { 2726 if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) { 2727 this.swap(); 2728 } 2729 }, this) 2730 }; 2731 2732 this.core.$element.on(this.handlers); 2733 }; 2734 2735 /** 2736 * Default options. 2737 * @public 2738 */ 2739 Animate.Defaults = { 2740 animateOut: false, 2741 animateIn: false 2742 }; 2743 2744 /** 2745 * Toggles the animation classes whenever an translations starts. 2746 * @protected 2747 * @returns {Boolean|undefined} 2748 */ 2749 Animate.prototype.swap = function() { 2750 2751 if (this.core.settings.items !== 1) { 2752 return; 2753 } 2754 2755 if (!$.support.animation || !$.support.transition) { 2756 return; 2757 } 2758 2759 this.core.speed(0); 2760 2761 var left, 2762 clear = $.proxy(this.clear, this), 2763 previous = this.core.$stage.children().eq(this.previous), 2764 next = this.core.$stage.children().eq(this.next), 2765 incoming = this.core.settings.animateIn, 2766 outgoing = this.core.settings.animateOut; 2767 2768 if (this.core.current() === this.previous) { 2769 return; 2770 } 2771 2772 if (outgoing) { 2773 left = this.core.coordinates(this.previous) - this.core.coordinates(this.next); 2774 previous.one($.support.animation.end, clear) 2775 .css( { 'left': left + 'px' } ) 2776 .addClass('animated owl-animated-out') 2777 .addClass(outgoing); 2778 } 2779 2780 if (incoming) { 2781 next.one($.support.animation.end, clear) 2782 .addClass('animated owl-animated-in') 2783 .addClass(incoming); 2784 } 2785 }; 2786 2787 Animate.prototype.clear = function(e) { 2788 $(e.target).css( { 'left': '' } ) 2789 .removeClass('animated owl-animated-out owl-animated-in') 2790 .removeClass(this.core.settings.animateIn) 2791 .removeClass(this.core.settings.animateOut); 2792 this.core.onTransitionEnd(); 2793 }; 2794 2795 /** 2796 * Destroys the plugin. 2797 * @public 2798 */ 2799 Animate.prototype.destroy = function() { 2800 var handler, property; 2801 2802 for (handler in this.handlers) { 2803 this.core.$element.off(handler, this.handlers[handler]); 2804 } 2805 for (property in Object.getOwnPropertyNames(this)) { 2806 typeof this[property] != 'function' && (this[property] = null); 2807 } 2808 }; 2809 2810 $.fn.owlCarousel.Constructor.Plugins.Animate = Animate; 2811 2812})(window.Zepto || window.jQuery, window, document); 2813 2814/** 2815 * Autoplay Plugin 2816 * @version 2.3.4 2817 * @author Bartosz Wojciechowski 2818 * @author Artus Kolanowski 2819 * @author David Deutsch 2820 * @author Tom De Caluwé 2821 * @license The MIT License (MIT) 2822 */ 2823;(function($, window, document, undefined) { 2824 2825 /** 2826 * Creates the autoplay plugin. 2827 * @class The Autoplay Plugin 2828 * @param {Owl} scope - The Owl Carousel 2829 */ 2830 var Autoplay = function(carousel) { 2831 /** 2832 * Reference to the core. 2833 * @protected 2834 * @type {Owl} 2835 */ 2836 this._core = carousel; 2837 2838 /** 2839 * The autoplay timeout id. 2840 * @type {Number} 2841 */ 2842 this._call = null; 2843 2844 /** 2845 * Depending on the state of the plugin, this variable contains either 2846 * the start time of the timer or the current timer value if it's 2847 * paused. Since we start in a paused state we initialize the timer 2848 * value. 2849 * @type {Number} 2850 */ 2851 this._time = 0; 2852 2853 /** 2854 * Stores the timeout currently used. 2855 * @type {Number} 2856 */ 2857 this._timeout = 0; 2858 2859 /** 2860 * Indicates whenever the autoplay is paused. 2861 * @type {Boolean} 2862 */ 2863 this._paused = true; 2864 2865 /** 2866 * All event handlers. 2867 * @protected 2868 * @type {Object} 2869 */ 2870 this._handlers = { 2871 'changed.owl.carousel': $.proxy(function(e) { 2872 if (e.namespace && e.property.name === 'settings') { 2873 if (this._core.settings.autoplay) { 2874 this.play(); 2875 } else { 2876 this.stop(); 2877 } 2878 } else if (e.namespace && e.property.name === 'position' && this._paused) { 2879 // Reset the timer. This code is triggered when the position 2880 // of the carousel was changed through user interaction. 2881 this._time = 0; 2882 } 2883 }, this), 2884 'initialized.owl.carousel': $.proxy(function(e) { 2885 if (e.namespace && this._core.settings.autoplay) { 2886 this.play(); 2887 } 2888 }, this), 2889 'play.owl.autoplay': $.proxy(function(e, t, s) { 2890 if (e.namespace) { 2891 this.play(t, s); 2892 } 2893 }, this), 2894 'stop.owl.autoplay': $.proxy(function(e) { 2895 if (e.namespace) { 2896 this.stop(); 2897 } 2898 }, this), 2899 'mouseover.owl.autoplay': $.proxy(function() { 2900 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 2901 this.pause(); 2902 } 2903 }, this), 2904 'mouseleave.owl.autoplay': $.proxy(function() { 2905 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 2906 this.play(); 2907 } 2908 }, this), 2909 'touchstart.owl.core': $.proxy(function() { 2910 if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) { 2911 this.pause(); 2912 } 2913 }, this), 2914 'touchend.owl.core': $.proxy(function() { 2915 if (this._core.settings.autoplayHoverPause) { 2916 this.play(); 2917 } 2918 }, this) 2919 }; 2920 2921 // register event handlers 2922 this._core.$element.on(this._handlers); 2923 2924 // set default options 2925 this._core.options = $.extend({}, Autoplay.Defaults, this._core.options); 2926 }; 2927 2928 /** 2929 * Default options. 2930 * @public 2931 */ 2932 Autoplay.Defaults = { 2933 autoplay: false, 2934 autoplayTimeout: 5000, 2935 autoplayHoverPause: false, 2936 autoplaySpeed: false 2937 }; 2938 2939 /** 2940 * Transition to the next slide and set a timeout for the next transition. 2941 * @private 2942 * @param {Number} [speed] - The animation speed for the animations. 2943 */ 2944 Autoplay.prototype._next = function(speed) { 2945 this._call = window.setTimeout( 2946 $.proxy(this._next, this, speed), 2947 this._timeout * (Math.round(this.read() / this._timeout) + 1) - this.read() 2948 ); 2949 2950 if (this._core.is('interacting') || document.hidden) { 2951 return; 2952 } 2953 this._core.next(speed || this._core.settings.autoplaySpeed); 2954 } 2955 2956 /** 2957 * Reads the current timer value when the timer is playing. 2958 * @public 2959 */ 2960 Autoplay.prototype.read = function() { 2961 return new Date().getTime() - this._time; 2962 }; 2963 2964 /** 2965 * Starts the autoplay. 2966 * @public 2967 * @param {Number} [timeout] - The interval before the next animation starts. 2968 * @param {Number} [speed] - The animation speed for the animations. 2969 */ 2970 Autoplay.prototype.play = function(timeout, speed) { 2971 var elapsed; 2972 2973 if (!this._core.is('rotating')) { 2974 this._core.enter('rotating'); 2975 } 2976 2977 timeout = timeout || this._core.settings.autoplayTimeout; 2978 2979 // Calculate the elapsed time since the last transition. If the carousel 2980 // wasn't playing this calculation will yield zero. 2981 elapsed = Math.min(this._time % (this._timeout || timeout), timeout); 2982 2983 if (this._paused) { 2984 // Start the clock. 2985 this._time = this.read(); 2986 this._paused = false; 2987 } else { 2988 // Clear the active timeout to allow replacement. 2989 window.clearTimeout(this._call); 2990 } 2991 2992 // Adjust the origin of the timer to match the new timeout value. 2993 this._time += this.read() % timeout - elapsed; 2994 2995 this._timeout = timeout; 2996 this._call = window.setTimeout($.proxy(this._next, this, speed), timeout - elapsed); 2997 }; 2998 2999 /** 3000 * Stops the autoplay. 3001 * @public 3002 */ 3003 Autoplay.prototype.stop = function() { 3004 if (this._core.is('rotating')) { 3005 // Reset the clock. 3006 this._time = 0; 3007 this._paused = true; 3008 3009 window.clearTimeout(this._call); 3010 this._core.leave('rotating'); 3011 } 3012 }; 3013 3014 /** 3015 * Pauses the autoplay. 3016 * @public 3017 */ 3018 Autoplay.prototype.pause = function() { 3019 if (this._core.is('rotating') && !this._paused) { 3020 // Pause the clock. 3021 this._time = this.read(); 3022 this._paused = true; 3023 3024 window.clearTimeout(this._call); 3025 } 3026 }; 3027 3028 /** 3029 * Destroys the plugin. 3030 */ 3031 Autoplay.prototype.destroy = function() { 3032 var handler, property; 3033 3034 this.stop(); 3035 3036 for (handler in this._handlers) { 3037 this._core.$element.off(handler, this._handlers[handler]); 3038 } 3039 for (property in Object.getOwnPropertyNames(this)) { 3040 typeof this[property] != 'function' && (this[property] = null); 3041 } 3042 }; 3043 3044 $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay; 3045 3046})(window.Zepto || window.jQuery, window, document); 3047 3048/** 3049 * Navigation Plugin 3050 * @version 2.3.4 3051 * @author Artus Kolanowski 3052 * @author David Deutsch 3053 * @license The MIT License (MIT) 3054 */ 3055;(function($, window, document, undefined) { 3056 'use strict'; 3057 3058 /** 3059 * Creates the navigation plugin. 3060 * @class The Navigation Plugin 3061 * @param {Owl} carousel - The Owl Carousel. 3062 */ 3063 var Navigation = function(carousel) { 3064 /** 3065 * Reference to the core. 3066 * @protected 3067 * @type {Owl} 3068 */ 3069 this._core = carousel; 3070 3071 /** 3072 * Indicates whether the plugin is initialized or not. 3073 * @protected 3074 * @type {Boolean} 3075 */ 3076 this._initialized = false; 3077 3078 /** 3079 * The current paging indexes. 3080 * @protected 3081 * @type {Array} 3082 */ 3083 this._pages = []; 3084 3085 /** 3086 * All DOM elements of the user interface. 3087 * @protected 3088 * @type {Object} 3089 */ 3090 this._controls = {}; 3091 3092 /** 3093 * Markup for an indicator. 3094 * @protected 3095 * @type {Array.<String>} 3096 */ 3097 this._templates = []; 3098 3099 /** 3100 * The carousel element. 3101 * @type {jQuery} 3102 */ 3103 this.$element = this._core.$element; 3104 3105 /** 3106 * Overridden methods of the carousel. 3107 * @protected 3108 * @type {Object} 3109 */ 3110 this._overrides = { 3111 next: this._core.next, 3112 prev: this._core.prev, 3113 to: this._core.to 3114 }; 3115 3116 /** 3117 * All event handlers. 3118 * @protected 3119 * @type {Object} 3120 */ 3121 this._handlers = { 3122 'prepared.owl.carousel': $.proxy(function(e) { 3123 if (e.namespace && this._core.settings.dotsData) { 3124 this._templates.push('<div class="' + this._core.settings.dotClass + '">' + 3125 $(e.content).find('[data-dot]').addBack('[data-dot]').attr('data-dot') + '</div>'); 3126 } 3127 }, this), 3128 'added.owl.carousel': $.proxy(function(e) { 3129 if (e.namespace && this._core.settings.dotsData) { 3130 this._templates.splice(e.position, 0, this._templates.pop()); 3131 } 3132 }, this), 3133 'remove.owl.carousel': $.proxy(function(e) { 3134 if (e.namespace && this._core.settings.dotsData) { 3135 this._templates.splice(e.position, 1); 3136 } 3137 }, this), 3138 'changed.owl.carousel': $.proxy(function(e) { 3139 if (e.namespace && e.property.name == 'position') { 3140 this.draw(); 3141 } 3142 }, this), 3143 'initialized.owl.carousel': $.proxy(function(e) { 3144 if (e.namespace && !this._initialized) { 3145 this._core.trigger('initialize', null, 'navigation'); 3146 this.initialize(); 3147 this.update(); 3148 this.draw(); 3149 this._initialized = true; 3150 this._core.trigger('initialized', null, 'navigation'); 3151 } 3152 }, this), 3153 'refreshed.owl.carousel': $.proxy(function(e) { 3154 if (e.namespace && this._initialized) { 3155 this._core.trigger('refresh', null, 'navigation'); 3156 this.update(); 3157 this.draw(); 3158 this._core.trigger('refreshed', null, 'navigation'); 3159 } 3160 }, this) 3161 }; 3162 3163 // set default options 3164 this._core.options = $.extend({}, Navigation.Defaults, this._core.options); 3165 3166 // register event handlers 3167 this.$element.on(this._handlers); 3168 }; 3169 3170 /** 3171 * Default options. 3172 * @public 3173 * @todo Rename `slideBy` to `navBy` 3174 */ 3175 Navigation.Defaults = { 3176 nav: false, 3177 navText: [ 3178 '<span aria-label="' + 'Previous' + '">‹</span>', 3179 '<span aria-label="' + 'Next' + '">›</span>' 3180 ], 3181 navSpeed: false, 3182 navElement: 'button type="button" role="presentation"', 3183 navContainer: false, 3184 navContainerClass: 'owl-nav', 3185 navClass: [ 3186 'owl-prev', 3187 'owl-next' 3188 ], 3189 slideBy: 1, 3190 dotClass: 'owl-dot', 3191 dotsClass: 'owl-dots', 3192 dots: true, 3193 dotsEach: false, 3194 dotsData: false, 3195 dotsSpeed: false, 3196 dotsContainer: false 3197 }; 3198 3199 /** 3200 * Initializes the layout of the plugin and extends the carousel. 3201 * @protected 3202 */ 3203 Navigation.prototype.initialize = function() { 3204 var override, 3205 settings = this._core.settings; 3206 3207 // create DOM structure for relative navigation 3208 this._controls.$relative = (settings.navContainer ? $(settings.navContainer) 3209 : $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled'); 3210 3211 this._controls.$previous = $('<' + settings.navElement + '>') 3212 .addClass(settings.navClass[0]) 3213 .html(settings.navText[0]) 3214 .prependTo(this._controls.$relative) 3215 .on('click', $.proxy(function(e) { 3216 this.prev(settings.navSpeed); 3217 }, this)); 3218 this._controls.$next = $('<' + settings.navElement + '>') 3219 .addClass(settings.navClass[1]) 3220 .html(settings.navText[1]) 3221 .appendTo(this._controls.$relative) 3222 .on('click', $.proxy(function(e) { 3223 this.next(settings.navSpeed); 3224 }, this)); 3225 3226 // create DOM structure for absolute navigation 3227 if (!settings.dotsData) { 3228 this._templates = [ $('<button role="button">') 3229 .addClass(settings.dotClass) 3230 .append($('<span>')) 3231 .prop('outerHTML') ]; 3232 } 3233 3234 this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer) 3235 : $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled'); 3236 3237 this._controls.$absolute.on('click', 'button', $.proxy(function(e) { 3238 var index = $(e.target).parent().is(this._controls.$absolute) 3239 ? $(e.target).index() : $(e.target).parent().index(); 3240 3241 e.preventDefault(); 3242 3243 this.to(index, settings.dotsSpeed); 3244 }, this)); 3245 3246 /*$el.on('focusin', function() { 3247 $(document).off(".carousel"); 3248 3249 $(document).on('keydown.carousel', function(e) { 3250 if(e.keyCode == 37) { 3251 $el.trigger('prev.owl') 3252 } 3253 if(e.keyCode == 39) { 3254 $el.trigger('next.owl') 3255 } 3256 }); 3257 });*/ 3258 3259 // override public methods of the carousel 3260 for (override in this._overrides) { 3261 this._core[override] = $.proxy(this[override], this); 3262 } 3263 }; 3264 3265 /** 3266 * Destroys the plugin. 3267 * @protected 3268 */ 3269 Navigation.prototype.destroy = function() { 3270 var handler, control, property, override, settings; 3271 settings = this._core.settings; 3272 3273 for (handler in this._handlers) { 3274 this.$element.off(handler, this._handlers[handler]); 3275 } 3276 for (control in this._controls) { 3277 if (control === '$relative' && settings.navContainer) { 3278 this._controls[control].html(''); 3279 } else { 3280 this._controls[control].remove(); 3281 } 3282 } 3283 for (override in this.overides) { 3284 this._core[override] = this._overrides[override]; 3285 } 3286 for (property in Object.getOwnPropertyNames(this)) { 3287 typeof this[property] != 'function' && (this[property] = null); 3288 } 3289 }; 3290 3291 /** 3292 * Updates the internal state. 3293 * @protected 3294 */ 3295 Navigation.prototype.update = function() { 3296 var i, j, k, 3297 lower = this._core.clones().length / 2, 3298 upper = lower + this._core.items().length, 3299 maximum = this._core.maximum(true), 3300 settings = this._core.settings, 3301 size = settings.center || settings.autoWidth || settings.dotsData 3302 ? 1 : settings.dotsEach || settings.items; 3303 3304 if (settings.slideBy !== 'page') { 3305 settings.slideBy = Math.min(settings.slideBy, settings.items); 3306 } 3307 3308 if (settings.dots || settings.slideBy == 'page') { 3309 this._pages = []; 3310 3311 for (i = lower, j = 0, k = 0; i < upper; i++) { 3312 if (j >= size || j === 0) { 3313 this._pages.push({ 3314 start: Math.min(maximum, i - lower), 3315 end: i - lower + size - 1 3316 }); 3317 if (Math.min(maximum, i - lower) === maximum) { 3318 break; 3319 } 3320 j = 0, ++k; 3321 } 3322 j += this._core.mergers(this._core.relative(i)); 3323 } 3324 } 3325 }; 3326 3327 /** 3328 * Draws the user interface. 3329 * @todo The option `dotsData` wont work. 3330 * @protected 3331 */ 3332 Navigation.prototype.draw = function() { 3333 var difference, 3334 settings = this._core.settings, 3335 disabled = this._core.items().length <= settings.items, 3336 index = this._core.relative(this._core.current()), 3337 loop = settings.loop || settings.rewind; 3338 3339 this._controls.$relative.toggleClass('disabled', !settings.nav || disabled); 3340 3341 if (settings.nav) { 3342 this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true)); 3343 this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true)); 3344 } 3345 3346 this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled); 3347 3348 if (settings.dots) { 3349 difference = this._pages.length - this._controls.$absolute.children().length; 3350 3351 if (settings.dotsData && difference !== 0) { 3352 this._controls.$absolute.html(this._templates.join('')); 3353 } else if (difference > 0) { 3354 this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0])); 3355 } else if (difference < 0) { 3356 this._controls.$absolute.children().slice(difference).remove(); 3357 } 3358 3359 this._controls.$absolute.find('.active').removeClass('active'); 3360 this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active'); 3361 } 3362 }; 3363 3364 /** 3365 * Extends event data. 3366 * @protected 3367 * @param {Event} event - The event object which gets thrown. 3368 */ 3369 Navigation.prototype.onTrigger = function(event) { 3370 var settings = this._core.settings; 3371 3372 event.page = { 3373 index: $.inArray(this.current(), this._pages), 3374 count: this._pages.length, 3375 size: settings && (settings.center || settings.autoWidth || settings.dotsData 3376 ? 1 : settings.dotsEach || settings.items) 3377 }; 3378 }; 3379 3380 /** 3381 * Gets the current page position of the carousel. 3382 * @protected 3383 * @returns {Number} 3384 */ 3385 Navigation.prototype.current = function() { 3386 var current = this._core.relative(this._core.current()); 3387 return $.grep(this._pages, $.proxy(function(page, index) { 3388 return page.start <= current && page.end >= current; 3389 }, this)).pop(); 3390 }; 3391 3392 /** 3393 * Gets the current succesor/predecessor position. 3394 * @protected 3395 * @returns {Number} 3396 */ 3397 Navigation.prototype.getPosition = function(successor) { 3398 var position, length, 3399 settings = this._core.settings; 3400 3401 if (settings.slideBy == 'page') { 3402 position = $.inArray(this.current(), this._pages); 3403 length = this._pages.length; 3404 successor ? ++position : --position; 3405 position = this._pages[((position % length) + length) % length].start; 3406 } else { 3407 position = this._core.relative(this._core.current()); 3408 length = this._core.items().length; 3409 successor ? position += settings.slideBy : position -= settings.slideBy; 3410 } 3411 3412 return position; 3413 }; 3414 3415 /** 3416 * Slides to the next item or page. 3417 * @public 3418 * @param {Number} [speed=false] - The time in milliseconds for the transition. 3419 */ 3420 Navigation.prototype.next = function(speed) { 3421 $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed); 3422 }; 3423 3424 /** 3425 * Slides to the previous item or page. 3426 * @public 3427 * @param {Number} [speed=false] - The time in milliseconds for the transition. 3428 */ 3429 Navigation.prototype.prev = function(speed) { 3430 $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed); 3431 }; 3432 3433 /** 3434 * Slides to the specified item or page. 3435 * @public 3436 * @param {Number} position - The position of the item or page. 3437 * @param {Number} [speed] - The time in milliseconds for the transition. 3438 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not. 3439 */ 3440 Navigation.prototype.to = function(position, speed, standard) { 3441 var length; 3442 3443 if (!standard && this._pages.length) { 3444 length = this._pages.length; 3445 $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed); 3446 } else { 3447 $.proxy(this._overrides.to, this._core)(position, speed); 3448 } 3449 }; 3450 3451 $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation; 3452 3453})(window.Zepto || window.jQuery, window, document); 3454 3455/** 3456 * Hash Plugin 3457 * @version 2.3.4 3458 * @author Artus Kolanowski 3459 * @author David Deutsch 3460 * @license The MIT License (MIT) 3461 */ 3462;(function($, window, document, undefined) { 3463 'use strict'; 3464 3465 /** 3466 * Creates the hash plugin. 3467 * @class The Hash Plugin 3468 * @param {Owl} carousel - The Owl Carousel 3469 */ 3470 var Hash = function(carousel) { 3471 /** 3472 * Reference to the core. 3473 * @protected 3474 * @type {Owl} 3475 */ 3476 this._core = carousel; 3477 3478 /** 3479 * Hash index for the items. 3480 * @protected 3481 * @type {Object} 3482 */ 3483 this._hashes = {}; 3484 3485 /** 3486 * The carousel element. 3487 * @type {jQuery} 3488 */ 3489 this.$element = this._core.$element; 3490 3491 /** 3492 * All event handlers. 3493 * @protected 3494 * @type {Object} 3495 */ 3496 this._handlers = { 3497 'initialized.owl.carousel': $.proxy(function(e) { 3498 if (e.namespace && this._core.settings.startPosition === 'URLHash') { 3499 $(window).trigger('hashchange.owl.navigation'); 3500 } 3501 }, this), 3502 'prepared.owl.carousel': $.proxy(function(e) { 3503 if (e.namespace) { 3504 var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash'); 3505 3506 if (!hash) { 3507 return; 3508 } 3509 3510 this._hashes[hash] = e.content; 3511 } 3512 }, this), 3513 'changed.owl.carousel': $.proxy(function(e) { 3514 if (e.namespace && e.property.name === 'position') { 3515 var current = this._core.items(this._core.relative(this._core.current())), 3516 hash = $.map(this._hashes, function(item, hash) { 3517 return item === current ? hash : null; 3518 }).join(); 3519 3520 if (!hash || window.location.hash.slice(1) === hash) { 3521 return; 3522 } 3523 3524 window.location.hash = hash; 3525 } 3526 }, this) 3527 }; 3528 3529 // set default options 3530 this._core.options = $.extend({}, Hash.Defaults, this._core.options); 3531 3532 // register the event handlers 3533 this.$element.on(this._handlers); 3534 3535 // register event listener for hash navigation 3536 $(window).on('hashchange.owl.navigation', $.proxy(function(e) { 3537 var hash = window.location.hash.substring(1), 3538 items = this._core.$stage.children(), 3539 position = this._hashes[hash] && items.index(this._hashes[hash]); 3540 3541 if (position === undefined || position === this._core.current()) { 3542 return; 3543 } 3544 3545 this._core.to(this._core.relative(position), false, true); 3546 }, this)); 3547 }; 3548 3549 /** 3550 * Default options. 3551 * @public 3552 */ 3553 Hash.Defaults = { 3554 URLhashListener: false 3555 }; 3556 3557 /** 3558 * Destroys the plugin. 3559 * @public 3560 */ 3561 Hash.prototype.destroy = function() { 3562 var handler, property; 3563 3564 $(window).off('hashchange.owl.navigation'); 3565 3566 for (handler in this._handlers) { 3567 this._core.$element.off(handler, this._handlers[handler]); 3568 } 3569 for (property in Object.getOwnPropertyNames(this)) { 3570 typeof this[property] != 'function' && (this[property] = null); 3571 } 3572 }; 3573 3574 $.fn.owlCarousel.Constructor.Plugins.Hash = Hash; 3575 3576})(window.Zepto || window.jQuery, window, document); 3577 3578/** 3579 * Support Plugin 3580 * 3581 * @version 2.3.4 3582 * @author Vivid Planet Software GmbH 3583 * @author Artus Kolanowski 3584 * @author David Deutsch 3585 * @license The MIT License (MIT) 3586 */ 3587;(function($, window, document, undefined) { 3588 3589 var style = $('<support>').get(0).style, 3590 prefixes = 'Webkit Moz O ms'.split(' '), 3591 events = { 3592 transition: { 3593 end: { 3594 WebkitTransition: 'webkitTransitionEnd', 3595 MozTransition: 'transitionend', 3596 OTransition: 'oTransitionEnd', 3597 transition: 'transitionend' 3598 } 3599 }, 3600 animation: { 3601 end: { 3602 WebkitAnimation: 'webkitAnimationEnd', 3603 MozAnimation: 'animationend', 3604 OAnimation: 'oAnimationEnd', 3605 animation: 'animationend' 3606 } 3607 } 3608 }, 3609 tests = { 3610 csstransforms: function() { 3611 return !!test('transform'); 3612 }, 3613 csstransforms3d: function() { 3614 return !!test('perspective'); 3615 }, 3616 csstransitions: function() { 3617 return !!test('transition'); 3618 }, 3619 cssanimations: function() { 3620 return !!test('animation'); 3621 } 3622 }; 3623 3624 function test(property, prefixed) { 3625 var result = false, 3626 upper = property.charAt(0).toUpperCase() + property.slice(1); 3627 3628 $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) { 3629 if (style[property] !== undefined) { 3630 result = prefixed ? property : true; 3631 return false; 3632 } 3633 }); 3634 3635 return result; 3636 } 3637 3638 function prefixed(property) { 3639 return test(property, true); 3640 } 3641 3642 if (tests.csstransitions()) { 3643 /* jshint -W053 */ 3644 $.support.transition = new String(prefixed('transition')) 3645 $.support.transition.end = events.transition.end[ $.support.transition ]; 3646 } 3647 3648 if (tests.cssanimations()) { 3649 /* jshint -W053 */ 3650 $.support.animation = new String(prefixed('animation')) 3651 $.support.animation.end = events.animation.end[ $.support.animation ]; 3652 } 3653 3654 if (tests.csstransforms()) { 3655 /* jshint -W053 */ 3656 $.support.transform = new String(prefixed('transform'));
3657 $.support.transform3d = tests.csstransforms3d(); 3658 } 3659 3660})(window.Zepto || window.jQuery, window, document); 3661 3662 3663/***/ }) 3664 3665/******/ });
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.