ajaxin-8.x-1.x-dev/js/src/ajaxin.js

js/src/ajaxin.js
/**
 * @file
 * Provides Ajaxin functionality.
 */

/* global define, module */
(function (root, factory) {

  'use strict';

  var _win = window;

  // Inspired by https://github.com/addyosmani/memoize.js/blob/master/memoize.js
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([_win.dBlazy, _win.Drupal, _win.drupalSettings], factory);
  }
  else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but only CommonJS-like
    // environments that support module.exports, like Node.
    module.exports = factory(_win.dBlazy, _win.Drupal, _win.drupalSettings);
  }
  else {
    // Browser globals (root is _win).
    root.Ajaxin = factory(_win.dBlazy, _win.Drupal, _win.drupalSettings);
  }
})(this, function ($, Drupal, drupalSettings) {

  'use strict';

  var _doc = document;
  var _bloader = 'b-loader';

  /**
   * Theme function for a standalone loading animation.
   *
   * @param {Object} settings
   *   An object containing:
   *   - theme: The inline theme.
   *   - themeFullscreen: The fullscreen theme.
   *   - fs: Whether to use the fullscreen wrapper.
   *
   * @return {HTMLElement}
   *   Returns a HTMLElement object.
   */
  Drupal.theme.ajaxin = function (settings) {
    var config = $.extend({}, drupalSettings.ajaxin || {}, settings || {});
    var fs = config.fs || false;
    return fs ? config.themeFullscreen : config.theme;
  };

  /**
   * Constructor for Ajaxin.
   *
   * @param {object} options
   *   The Ajaxin options.
   *
   * @namespace
   */
  function Ajaxin(options) {
    var me = this;

    me.options = $.extend({}, me.defaults, options || {});

    // DOM ready fix.
    setTimeout(function () {
      init(me);
    });
  }

  // Cache our prototype.
  var _proto = Ajaxin.prototype;
  _proto.constructor = Ajaxin;

  _proto.defaults = {
    root: null,
    successClass: 'b-loaded',
    selector: '.b-lazy',
    errorClass: 'b-error',
    loaderClass: _bloader,
    oldLoadingClass: false,
    doneListener: false,
    inside: false,
    addNow: false
  };

  _proto.isLoaded = function (el) {
    return el === null || $.hasClass(el, this.options.successClass);
  };

  _proto.sibling = function (el) {
    var next = el.nextElementSibling;
    return $.isElm(next) && $.hasClass(next, this.options.loaderClass) ? next : null;
  };

  _proto.loader = function (el) {
    return this.options.inside ? $.find(el, '.' + this.options.loaderClass) : this.sibling(el);
  };

  _proto.has = function (el) {
    return $.isElm(this.loader(el));
  };

  _proto.add = function (el) {
    var me = this;
    var settings = drupalSettings.ajaxin || {};
    settings.fs = false;

    // Do not add to blur element to avoid duplicated .b-loader.
    if ($.isElm(el) && !me.has(el) && !$.hasClass(el, 'b-blur')) {
      var template = Drupal.theme('ajaxin', settings);
      el.insertAdjacentHTML(me.options.inside ? 'beforeend' : 'afterend', template);
    }
  };

  _proto.remove = function (el) {
    var me = this;

    // Don't bother removing as when the loader is placed inside, it will be
    // removed automatically on content replacement via .html() alike method.
    if (me.options.inside) {
      return;
    }

    // DOM ready fix.
    setTimeout(function () {
      // me.isLoaded(el) &&
      if ($.isElm(el.parentNode)) {
        var prev = $.prev(el);
        var next = $.next(el);
        if ($.isElm(prev) && $.hasClass(prev, _bloader)) {
          $.remove(prev);
        }
        if ($.isElm(next) && $.hasClass(next, _bloader)) {
          $.remove(next);
        }
      }
    }, 100);
  };

  _proto.onDone = function (e) {
    var me = this;
    var el = e.target;
    var done = me.options.doneListener;

    me.remove(el);
    if (done) {
      $.off(el, done, me.onDone);
    }

    me.count--;

    if (me.count === 0 && !me.destroyed) {
      me.destroy();
      me.destroyed = true;
    }
  };

  _proto.bindEvents = function () {
    var elms = $.findAll(_doc, '.ajaxin-wrapper');

    if (!elms.length) {
      return;
    }

    var doClick = function (e) {
      var el = e.target;

      $.off(el, 'click', doClick);

      // Simply remove the loading animation on clicking it.
      $.remove(el);
    };

    $.each(elms, function (el) {
      // Binds event to `click`.
      $.on(el, 'click', doClick, false);
    });
  };

  _proto.buildOut = function () {
    var me = this;
    var elms = me.elms || [];
    var cLoading = me.options.oldLoadingClass;

    if (!elms.length) {
      return;
    }

    $.each(elms, function (el) {
      if (cLoading) {
        var oldEl = $.closest(el, '.' + cLoading);

        // @todo remove the condition post blazy:2.2+.
        if (!$.isElm(oldEl)) {
          oldEl = $.closest(el, '.is-b-loading');
        }
        $.removeClass(oldEl, cLoading);
      }

      // Appends the progressbar.
      if (!me.isLoaded(el)) {
        // Attaches our loading animation either as a sibling, or child element.
        me.add(el);
      }

      // Binds event to `blazy.done`.
      var done = me.options.doneListener;
      if (done) {
        $.on(el, done, me.onDone.bind(me), false);
      }
    });
  };

  _proto.destroy = function () {
    var me = this;
    me.elms = [];
    me.count = 0;
    me.destroyed = true;
  };

  _proto.reinit = function () {
    var me = this;

    me.destroyed = false;

    init(me);
  };

  function init(me) {
    var sel = me.options.selector;
    sel = sel + ':not(.' + me.options.successClass + '):not(iframe)';
    me.options.selector = sel;
    me.elms = $.findAll(me.options.root || _doc, sel);
    me.count = me.elms.length;
    me.destroyed = false;

    if (me.options.addNow) {
      me.buildOut();
    }

    me.bindEvents();
  }

  return Ajaxin;

});

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

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