io-8.x-1.x-dev/js/src/io.pager.js

js/src/io.pager.js
/**
 * @file
 * Provides AJAX append command for both automatic or manual pagers.
 */

(function ($, Drupal, drupalSettings, _win, _doc) {

  'use strict';

  drupalSettings.io = drupalSettings.io || {};

  var _id = 'io-pager';
  var _idOnce = _id;
  var _nick = 'iop';
  var _isNick = 'is-' + _nick;
  var _dataId = 'data-' + _id;
  var _dataTrigger = _dataId + '-trigger';
  var _dataView = 'data-io-view';
  var _idBEM = 'pager--io';
  var _element = '.' + _idBEM;
  var _mounted = _isNick + '-mounted';
  var _elementAutoload = _element + '--autoload:not(.' + _mounted + ')';
  var _isDone = _isNick + '-done';
  var _idAjaxWraper = 'ajax-pager';
  var _idVef = 'exposed-form';
  var _base = Drupal.io.base || {};
  var _sanitizer = $.sanitizer;
  var _isDoneTriggered = false;
  var elView = null;

  // Provides the IO append command.
  Drupal.AjaxCommands.prototype.ioAppend = function (ajax, response) {
    var me = Drupal.io.pager;
    var opts = response.settings || {};
    var contentSelector = opts.contentSelector
      || (opts.style === 'table' ? '.views-table tbody' : '[' + _dataId + ']');
    var method = opts.method || 'append';
    var selPager = opts.pagerSelector;
    var viewDomId = opts.view_dom_id;
    var view = Drupal.views.instances['views_dom_id:' + viewDomId];
    var settings = ajax.settings || drupalSettings;
    var elNewContent = _doc.createElement('div');
    var selView = '.js-view-dom-id-' + viewDomId;
    var elVef = !$.isUnd(view) && view.$exposed_form.length ? view.$exposed_form[0] : null;

    elNewContent.innerHTML = response.data ? _sanitizer.sanitize(response.data.trim()) : '';
    elView = $.isUnd(view) ? $.find(_doc, selView) : view.$view[0];

    if (!$.isElm(elView)) {
      return;
    }

    // If removing content from the wrapper, detach behaviors first.
    Drupal.detachBehaviors(elView, settings);

    // Update the pager.
    var oldPager = $.find(elView, selPager);
    var newPager = $.find(elNewContent, selPager);

    if ($.isElm(oldPager)) {
      $.removeClass(oldPager, _mounted);
      Drupal.detachBehaviors(oldPager, settings);
      var content = $.isElm(newPager) ? newPager.innerHTML : '';
      oldPager.innerHTML = content ? _sanitizer.sanitize(content) : '';
    }

    // Add the new content to the page.
    var oldCn = $.find(elView, contentSelector);
    var newCn = $.find(elNewContent, contentSelector);
    if ($.isElm(oldCn) && $.isElm(newCn) && newCn.innerHTML) {
      $[method](oldCn, _sanitizer.sanitize(newCn.innerHTML));
    }

    // Remove once so that the exposed form and pager are processed on attach.
    $.once.removeSafely(_idAjaxWraper, selView, _doc);
    if ($.isElm(elVef)) {
      var exposedId = $.attr(elVef, 'id');
      $.once.removeSafely(_idVef, '#' + exposedId, _doc);
    }

    // Attach all JavaScript behaviors to the newly loaded content.
    Drupal.attachBehaviors(elView, settings);

    // DOM ready fix.
    setTimeout(function () {
      checkAjaxin();

      var link = $.find(elView, me.trigger);

      // The IO pager is all done if no link is found.
      if (!$.isElm(link)) {
        $.addClass(oldPager, _isDone);

        if (!_isDoneTriggered) {
          $.trigger(_win, 'io:done');
          _isDoneTriggered = true;
        }
      }
    }, 901);

  };

  /**
   * Intersection Observer API public methods for Views pagers.
   *
   * @namespace
   */
  Drupal.io.pager = $.extend({}, _base, {
    el: null,
    $trigger: null,
    settings: drupalSettings.io.pager || {},
    dataTrigger: _dataTrigger,
    trigger: '[' + _dataTrigger + ']',
    globals: function () {
      var me = this;
      var commons = {
        intersecting: me.intersecting.bind(me),
        success: me.success.bind(me),
        error: me.error.bind(me),
        visibleClass: 'is-iop-visible'
      };

      return $.extend({}, me.settings, commons);
    },

    // For static sites.
    loadStatic: function (el, path) {
      var $view = $.closest(el, '[' + _dataView + ']');
      var matches = /(js-view-dom-id-\w+)/.exec($.attr($view, 'class'));
      var domId = matches[1].replace('js-view-dom-id-', '');
      var style = $.attr($view, _dataView);

      // @todo update this, it is a blind guess without static sites for now.
      /* eslint-disable indent */
      fetch(path, {
        method: 'GET',
        credentials: 'same-origin',
        headers: {
          'Content-Type': 'text/html; charset=UTF-8'
        }
      }).then(checkStatus).then(function (response) {
        return response.text();
      }).then(function (body) {
        var elDiv = _doc.createElement('div');

        elDiv.innerHTML = _sanitizer.sanitize(body.trim());

        var elNewView = $.find(elDiv, '[' + _dataView + ']:first-child');
        var classes = $.attr($view, 'class');

        if (elNewView.length) {
          $.attr(elNewView, 'class', classes);

          var response = {
            command: 'ioAppend',
            data: _sanitizer.sanitize(elNewView.outerHTML),
            io: 'pager',
            settings: {
              view_dom_id: domId,
              style: style
            }
          };
          Drupal.AjaxCommands.prototype.ioAppend({}, response);
        }
      });
    },

    loadOrClick: function (el) {
      var me = this;
      var path = el.href;

      // Static sites ala Tome has `/page/` in url.
      if (path && path.indexOf('/page/') >= 0) {
        me.loadStatic(el, path);
      }
      else {
        el.click();
      }
    },

    intersecting: function (el) {
      var me = this;

      // Allows Blazy to change it into IOEntry for better usages.
      el = el.target || el;

      // Bail out if AJAX is already requested, or successful.
      if (el && (me.isError(el) || !el.iohit)) {
        me.loadOrClick(el);

        // We need to continue hitting auto pager, set it false.
        el.iohit = false;
      }
    }
  });

  function checkStatus(response) {
    if (response.status >= 200 && response.status < 300) {
      return response;
    }
    else {
      var error = new Error(response.statusText);
      error.response = response;
      throw error;
    }
  }

  function checkAjaxin() {
    var cn = $.find(_doc, '.ajaxin-wrapper--fs');
    $.remove(cn);
  }

  /**
   * IO automatic pager utility functions.
   *
   * @param {HTMLElement} elm
   *   The IO pager HTML element.
   */
  function process(elm) {
    var me = Drupal.io.pager;
    var link = $.find(elm, me.trigger);

    me.el = elm;
    me.$trigger = link;

    // Initializes Io pager instance.
    me.mount(true);
    $.addClass(elm, _mounted);
  }

  /**
   * Auloload ajaxified views using the IO API, or the old scroll event, bLazy.
   *
   * @type {Drupal~behavior}
   */
  Drupal.behaviors.ioPager = {
    attach: function (context) {
      $.once(process, _idOnce, _elementAutoload, context);
    },
    detach: function (context, settings, trigger) {
      if (trigger === 'unload') {
        $.once.removeSafely(_idOnce, _elementAutoload, context, true);
      }
    }
  };

})(dBlazy, Drupal, drupalSettings, this, this.document);

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

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