splide-1.0.x-dev/js/src/splide.base.js

js/src/splide.base.js
/**
 * @file
 * Provides Splide utilities.
 */

(function (factory) {

  'use strict';

  // Browser globals (root is window).
  factory(window.dBlazy, window, window.document);

})(function ($, _win, _doc) {

  'use strict';

  /**
   * Shared objects for drupalSplide.
   *
   * @namespace
   */
  _win.dSplide = {};

  var DS = _win.dSplide;
  var ID = 'splide';
  var NICK = ID + 'base';
  var S_BASE = '.' + ID;
  var AUTOPLAY_OFF = 'is-autoplay--off';
  var IS_ARROWED = 'is-arrowed';
  var IS_DRAGGING = 'is-dragging';
  var IS_LESS = 'is-less';
  var C_TOUCH = 'touchevents';
  var LAST_TAP;

  // @todo remove post blazy:2.29 || 3.0.8.
  if ($.isUnd($.isTouch)) {
    $.isTouch = function isTouch(cb) {
      var query = {};

      // @todo remove check when min D.10.
      if ('matchMedia' in _win) {
        query = _win.matchMedia('(hover: none), (pointer: coarse)');
        if (cb) {
          query.addEventListener('change', cb);
        }
      }

      return (
        ('ontouchstart' in _win) ||
        (_win.DocumentTouch && _doc instanceof _win.DocumentTouch) ||
        query.matches ||
        (navigator.maxTouchPoints > 0) ||
        (navigator.msMaxTouchPoints > 0)
      );
    };

    $.touchOrNot = function touchOrNot() {
      var html = _doc.documentElement;
      var matches = $.isTouch($.touchOrNot);

      $.removeClass(html, [C_TOUCH, 'no-' + C_TOUCH]);
      $.addClass(html, matches ? C_TOUCH : 'no-' + C_TOUCH);
    };
  }

  // Add touchevents classes.
  $.touchOrNot();

  DS.extensions = {};
  DS.listeners = {};
  DS.transitions = [];
  DS.options = {};

  // Init non-module library built-in, yet separated, extensions.
  DS.initExtensions = function () {
    var me = this;
    if (_win.splide && _win.splide.Extensions) {
      if (_win.splide.Extensions.AutoScroll) {
        me.extend({
          AutoScroll: _win.splide.Extensions.AutoScroll
        });
      }
      if (_win.splide.Extensions.Intersection) {
        me.extend({
          Intersection: _win.splide.Extensions.Intersection
        });
      }
    }
  };

  // Init module/ custom listener extensions, must be called before init event.
  DS.initListeners = function (instance) {
    var me = this;
    var root = instance.root;
    var userOptions = $.parse(root.dataset.splide);

    // Need to get a live copy of instance.options as it's modified elsewhere as this runs, and we also want a clone instead of modifying the original.
    var getMergedOptions = function () {
      return $.extend({}, instance.options, userOptions);
    };

    var append = function (prev, sel) {
      var el = $.find(root, sel);
      if ($.isElm(el)) {
        prev.insertAdjacentElement('afterend', el);
      }
    };

    instance.on('drag.' + NICK + ' dragging.' + NICK, function () {
      $.addClass(root, IS_DRAGGING);
    });

    instance.on('dragged.' + NICK, function () {
      // Prevents ending drags from triggering click events, if any registered,
      // by conditioning this IS_DRAGGING class.
      setTimeout(function () {
        $.removeClass(root, IS_DRAGGING);
      }, 101);
    });

    instance.on('mounted.' + NICK + ' resized.' + NICK, function () {
      var opts = getMergedOptions();
      var count = opts.count;
      $[count <= opts.perPage ? 'addClass' : 'removeClass'](root, IS_LESS);
      $[count > 1 && opts.arrows ? 'addClass' : 'removeClass'](root, IS_ARROWED);
    });

    instance.on('autoplay:play.' + NICK, function () {
      $.removeClass(root, AUTOPLAY_OFF);
    });

    instance.on('autoplay:pause.' + NICK, function () {
      $.addClass(root, AUTOPLAY_OFF);
    });

    // Adjust Autoplay behaviors.
    if ($.hasClass(root, 'is-autoplay')) {
      $.on(root, 'click.' + NICK, '.splide__arrow, .splide__pagination__page', function () {
        var auto = instance.Components.Autoplay;

        $.removeClass(root, AUTOPLAY_OFF);

        // @todo remove when the library takes care of this click interaction.
        if (auto) {
          auto.pause();
          auto.play();
        }
      });
    }
    else {
      // Do not interfere autoplay, already managed by library.
      var bar = $.find(root, S_BASE + '__progress__bar');
      if (bar) {
        // Updates the bar width whenever the carousel moves:
        instance.on('mounted.' + NICK + ' move.' + NICK, function () {
          var end = instance.Components.Controller.getEnd() + 1;
          var rate = Math.min((instance.index + 1) / end, 1);

          bar.style.width = String(100 * rate) + '%';
        });
      }
    }

    // Adds arrows down and or pagination inside arrows.
    instance.on('arrows:mounted.' + NICK, function (prev, next) {
      var opts = getMergedOptions();

      if (prev === null) {
        return;
      }

      // Pagination was generated after arrows.
      _win.setTimeout(function () {
        // Puts dots inbetween arrows for easy theming like this: < ooooo >.
        // The library doesn't support other than `slider`, the module does.
        // V4 does not support string.
        // See https://splidejs.com/v3/guides/options/#pagination.
        // See https://splidejs.com/guides/options/#pagination
        if (opts.pagination === S_BASE + '__arrows') {
          append(prev, S_BASE + '__pagination');
        }

        // Puts arrow down inbetween arrows for easy theming like this: < v >.
        if (opts.down) {
          append(prev, S_BASE + '__arrow--down');
        }
      }, 100);
    });

    /*
    @todo remove irrelevant since some v4, no longer moved around by JS
    since the markups were hard-coded in TWIG, unless being disabled.
    Default pagination placements.

    v4 will have is-paginated--inner, inside .splide__slider:
    .splide > .splide__slider
       > .splide__track > UL.splide__list
       > UL.splide__pagination

    v3 will have is-paginated--outer, outside .splide__slider, till changed by
    `slider` value, v3 only:
    .splide
      > .splide__slider > .splide__track > UL.splide__list
      > UL.splide__pagination
      */
    instance.on('pagination:mounted.' + NICK, function (data) {
      var prev = $.prev(data.list);
      var siblings = $.hasClass(prev, 'splide__slider');

      $.addClass(root, siblings ? 'is-paginated--outer' : 'is-paginated--inner');
    });

    instance.on('lazyload:loaded.' + NICK, $.unloading);

    var listeners = me.listeners;
    if (listeners) {
      $.each(listeners, function (listener) {
        if (listener && typeof listener === 'function') {
          var opts = getMergedOptions();
          var fn = listener(instance, instance.Components, opts);
          if ('mount' in fn) {
            fn.mount();
          }
        }
      });
    }
  };

  // Register module/ custom extensions not bound to before init event.
  DS.extend = function (fn) {
    this.extensions = $.extend({}, this.extensions, fn);
  };

  // Register module/ custom listener plugins, must be called before init event.
  DS.listen = function (fn) {
    this.listeners = $.extend({}, this.listeners, fn);
  };

  // Register module/ custom transitions aside from defaults: loop, slide, fade.
  DS.addTransition = function (fn) {
    this.transitions.push(fn);
  };

  DS.getTransition = function (type) {
    var me = this;
    var fn = null;
    if (me.transitions.length) {
      $.each(me.transitions, function (obj) {
        if (obj.fn) {
          if (obj.type && obj.type === type) {
            fn = obj.fn;
            return false;
          }
        }
      });
    }
    return fn;
  };

  DS.fsIconOn = '<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><path d="M5.12 5.12v8.16h2.72V7.84h5.44V5.12zm13.6 0v2.72h5.44v5.44h2.72V5.12Zm-13.6 13.6v8.16h8.16v-2.72H7.84v-5.44zm19.04 0v5.44h-5.44v2.72h8.16v-8.16z" style="stroke-width:.785414"/></svg>';

  DS.applyStyle = function (elm, styles) {
    if (elm) {
      $.each(styles, function (value, prop) {
        if (!$.isNull(value)) {
          elm.style[prop] = value;
        }
      });
    }
  };

  DS.doubletap = function () {
    var now = new Date().getTime();
    var timesince = now - LAST_TAP;

    if ((timesince < 600) && (timesince > 0)) {
      return true;
    }

    LAST_TAP = new Date().getTime();
    return false;
  };

  // https://stackoverflow.com/questions/5527601/normalizing-mousewheel-speed-across-browsers
  DS.wheelDelta = function (e) {
    // FIREFOX WIN / MAC | IE.
    var delta = e.deltaY;
    if (!delta) {
      if (e.wheelDelta) {
        // CHROME WIN/MAC | SAFARI 7 MAC | OPERA WIN/MAC | EDGE.
        delta = e.wheelDelta / 120;
      }
      else if (e.detail) {
        // W3C.
        delta = -e.detail / 2;
      }
    }

    return delta > 0 ? 1 : -1;
  };

  // @todo replace with $.resize post blazy:2.28.
  DS.checkSizes = function (img, parent) {
    var _sizes = {};

    if (!img) {
      return _sizes;
    }

    parent = parent || img.parentNode;

    var recheck = function (e) {
      var aw = $.toInt($.attr(img, 'width'), 0);
      var ah = $.toInt($.attr(img, 'height'), 0);

      _sizes = {
        w: img.offsetWidth,
        h: img.offsetHeight,
        nw: img.naturalWidth || aw,
        nh: img.naturalHeight || ah,
        aw: aw,
        ah: ah,
        pw: parent.offsetWidth,
        ph: parent.offsetHeight
      };

      if (e) {
        $.off(img, 'load.' + NICK, recheck);
      }
    };

    if ($.isDecoded(img) || $.attr(img, 'data-src')) {
      recheck();
    }
    else {
      $.on(img, 'load.' + NICK, recheck);
    }

    return _sizes;
  };

  return DS;

});

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc