barbajs-1.0.0-alpha1/dist/core/barba.umd.js

dist/core/barba.umd.js
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  typeof define === 'function' && define.amd ? define(factory) :
  (global = global || self, global.barba = factory());
})(this, (function () {
  function _assertThisInitialized(e) {
    if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
    return e;
  }
  function _construct(t, e, r) {
    if (_isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
    var o = [null];
    o.push.apply(o, e);
    var p = new (t.bind.apply(t, o))();
    return r && _setPrototypeOf(p, r.prototype), p;
  }
  function _defineProperties(e, r) {
    for (var t = 0; t < r.length; t++) {
      var o = r[t];
      o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o);
    }
  }
  function _createClass(e, r, t) {
    return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
      writable: !1
    }), e;
  }
  function _extends() {
    return _extends = Object.assign ? Object.assign.bind() : function (n) {
      for (var e = 1; e < arguments.length; e++) {
        var t = arguments[e];
        for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
      }
      return n;
    }, _extends.apply(null, arguments);
  }
  function _getPrototypeOf(t) {
    return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
      return t.__proto__ || Object.getPrototypeOf(t);
    }, _getPrototypeOf(t);
  }
  function _inheritsLoose(t, o) {
    t.prototype = Object.create(o.prototype), t.prototype.constructor = t, _setPrototypeOf(t, o);
  }
  function _isNativeFunction(t) {
    try {
      return -1 !== Function.toString.call(t).indexOf("[native code]");
    } catch (n) {
      return "function" == typeof t;
    }
  }
  function _isNativeReflectConstruct() {
    try {
      var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
    } catch (t) {}
    return (_isNativeReflectConstruct = function () {
      return !!t;
    })();
  }
  function _setPrototypeOf(t, e) {
    return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
      return t.__proto__ = e, t;
    }, _setPrototypeOf(t, e);
  }
  function _toPrimitive(t, r) {
    if ("object" != typeof t || !t) return t;
    var e = t[Symbol.toPrimitive];
    if (void 0 !== e) {
      var i = e.call(t, r || "default");
      if ("object" != typeof i) return i;
      throw new TypeError("@@toPrimitive must return a primitive value.");
    }
    return ("string" === r ? String : Number)(t);
  }
  function _toPropertyKey(t) {
    var i = _toPrimitive(t, "string");
    return "symbol" == typeof i ? i : i + "";
  }
  function _wrapNativeSuper(t) {
    var r = "function" == typeof Map ? new Map() : void 0;
    return _wrapNativeSuper = function (t) {
      if (null === t || !_isNativeFunction(t)) return t;
      if ("function" != typeof t) throw new TypeError("Super expression must either be null or a function");
      if (void 0 !== r) {
        if (r.has(t)) return r.get(t);
        r.set(t, Wrapper);
      }
      function Wrapper() {
        return _construct(t, arguments, _getPrototypeOf(this).constructor);
      }
      return Wrapper.prototype = Object.create(t.prototype, {
        constructor: {
          value: Wrapper,
          enumerable: !1,
          writable: !0,
          configurable: !0
        }
      }), _setPrototypeOf(Wrapper, t);
    }, _wrapNativeSuper(t);
  }

  var version = "2.10.3";

  var HookMethods = function HookMethods() {
    this.before = void 0;
    this.beforeLeave = void 0;
    this.leave = void 0;
    this.afterLeave = void 0;
    this.beforeEnter = void 0;
    this.enter = void 0;
    this.afterEnter = void 0;
    this.after = void 0;
  };

  /**
   * @barba/core/modules/Logger
   * <br><br>
   * ## Logger.
   *
   * - Display informations via the console
   *
   * @module core/modules/Logger
   * @preferred
   */
  /***/
  /**
   * Log levels, all lower level messages are printed
   *
   * 0. mute
   * 1. error = `console.error()`
   * 2. warning= `console.warn()`
   * 3. info = `console.info()`
   * 4. debug = `console.log()`
   */
  var LogLevels;
  (function (LogLevels) {
    LogLevels[LogLevels["off"] = 0] = "off";
    LogLevels[LogLevels["error"] = 1] = "error";
    LogLevels[LogLevels["warning"] = 2] = "warning";
    LogLevels[LogLevels["info"] = 3] = "info";
    LogLevels[LogLevels["debug"] = 4] = "debug";
  })(LogLevels || (LogLevels = {}));
  /**
   * Global log level
   */
  var _level = LogLevels.off;
  var Logger = /*#__PURE__*/function () {
    /**
     * Get global log level.
     */
    Logger.getLevel = function getLevel() {
      return _level;
    }
    /**
     * Set global log level.
     */;
    Logger.setLevel = function setLevel(name) {
      _level = LogLevels[name];
      return _level;
    }
    /**
     * Log "prefix".
     */;

    /**
     * Creates an instance of Logger.
     */
    function Logger(source) {
      this._source = void 0;
      this._source = source;
    }
    /**
     * Permanent, unremovable log.
     */
    // public print(...objects: any[]): void {
    //   this._log(console.info, LogLevels.off, objects);
    // }
    /**
     * Error log.
     */
    var _proto = Logger.prototype;
    _proto.error = function error() {
      this._log(console.error, LogLevels.error, [].slice.call(arguments));
    }
    /**
     * Warn log.
     */;
    _proto.warn = function warn() {
      this._log(console.warn, LogLevels.warning, [].slice.call(arguments));
    }
    /**
     * Info log.
     */;
    _proto.info = function info() {
      this._log(console.info, LogLevels.info, [].slice.call(arguments));
    }
    /**
     * Debug log.
     */;
    _proto.debug = function debug() {
      this._log(console.log, LogLevels.debug, [].slice.call(arguments));
    }
    /**
     * Internal logger.
     */;
    _proto._log = function _log(fn, level, objects) {
      if (level <= Logger.getLevel()) {
        fn.apply(console, ["[" + this._source + "] "].concat(objects));
      }
    };
    return Logger;
  }();

  /**
   * Tokenize input string.
   */
  function lexer(str) {
      var tokens = [];
      var i = 0;
      while (i < str.length) {
          var char = str[i];
          if (char === "*" || char === "+" || char === "?") {
              tokens.push({ type: "MODIFIER", index: i, value: str[i++] });
              continue;
          }
          if (char === "\\") {
              tokens.push({ type: "ESCAPED_CHAR", index: i++, value: str[i++] });
              continue;
          }
          if (char === "{") {
              tokens.push({ type: "OPEN", index: i, value: str[i++] });
              continue;
          }
          if (char === "}") {
              tokens.push({ type: "CLOSE", index: i, value: str[i++] });
              continue;
          }
          if (char === ":") {
              var name = "";
              var j = i + 1;
              while (j < str.length) {
                  var code = str.charCodeAt(j);
                  if (
                  // `0-9`
                  (code >= 48 && code <= 57) ||
                      // `A-Z`
                      (code >= 65 && code <= 90) ||
                      // `a-z`
                      (code >= 97 && code <= 122) ||
                      // `_`
                      code === 95) {
                      name += str[j++];
                      continue;
                  }
                  break;
              }
              if (!name)
                  throw new TypeError("Missing parameter name at ".concat(i));
              tokens.push({ type: "NAME", index: i, value: name });
              i = j;
              continue;
          }
          if (char === "(") {
              var count = 1;
              var pattern = "";
              var j = i + 1;
              if (str[j] === "?") {
                  throw new TypeError("Pattern cannot start with \"?\" at ".concat(j));
              }
              while (j < str.length) {
                  if (str[j] === "\\") {
                      pattern += str[j++] + str[j++];
                      continue;
                  }
                  if (str[j] === ")") {
                      count--;
                      if (count === 0) {
                          j++;
                          break;
                      }
                  }
                  else if (str[j] === "(") {
                      count++;
                      if (str[j + 1] !== "?") {
                          throw new TypeError("Capturing groups are not allowed at ".concat(j));
                      }
                  }
                  pattern += str[j++];
              }
              if (count)
                  throw new TypeError("Unbalanced pattern at ".concat(i));
              if (!pattern)
                  throw new TypeError("Missing pattern at ".concat(i));
              tokens.push({ type: "PATTERN", index: i, value: pattern });
              i = j;
              continue;
          }
          tokens.push({ type: "CHAR", index: i, value: str[i++] });
      }
      tokens.push({ type: "END", index: i, value: "" });
      return tokens;
  }
  /**
   * Parse a string for the raw tokens.
   */
  function parse$1(str, options) {
      if (options === void 0) { options = {}; }
      var tokens = lexer(str);
      var _a = options.prefixes, prefixes = _a === void 0 ? "./" : _a, _b = options.delimiter, delimiter = _b === void 0 ? "/#?" : _b;
      var result = [];
      var key = 0;
      var i = 0;
      var path = "";
      var tryConsume = function (type) {
          if (i < tokens.length && tokens[i].type === type)
              return tokens[i++].value;
      };
      var mustConsume = function (type) {
          var value = tryConsume(type);
          if (value !== undefined)
              return value;
          var _a = tokens[i], nextType = _a.type, index = _a.index;
          throw new TypeError("Unexpected ".concat(nextType, " at ").concat(index, ", expected ").concat(type));
      };
      var consumeText = function () {
          var result = "";
          var value;
          while ((value = tryConsume("CHAR") || tryConsume("ESCAPED_CHAR"))) {
              result += value;
          }
          return result;
      };
      var isSafe = function (value) {
          for (var _i = 0, delimiter_1 = delimiter; _i < delimiter_1.length; _i++) {
              var char = delimiter_1[_i];
              if (value.indexOf(char) > -1)
                  return true;
          }
          return false;
      };
      var safePattern = function (prefix) {
          var prev = result[result.length - 1];
          var prevText = prefix || (prev && typeof prev === "string" ? prev : "");
          if (prev && !prevText) {
              throw new TypeError("Must have text between two parameters, missing text after \"".concat(prev.name, "\""));
          }
          if (!prevText || isSafe(prevText))
              return "[^".concat(escapeString(delimiter), "]+?");
          return "(?:(?!".concat(escapeString(prevText), ")[^").concat(escapeString(delimiter), "])+?");
      };
      while (i < tokens.length) {
          var char = tryConsume("CHAR");
          var name = tryConsume("NAME");
          var pattern = tryConsume("PATTERN");
          if (name || pattern) {
              var prefix = char || "";
              if (prefixes.indexOf(prefix) === -1) {
                  path += prefix;
                  prefix = "";
              }
              if (path) {
                  result.push(path);
                  path = "";
              }
              result.push({
                  name: name || key++,
                  prefix: prefix,
                  suffix: "",
                  pattern: pattern || safePattern(prefix),
                  modifier: tryConsume("MODIFIER") || "",
              });
              continue;
          }
          var value = char || tryConsume("ESCAPED_CHAR");
          if (value) {
              path += value;
              continue;
          }
          if (path) {
              result.push(path);
              path = "";
          }
          var open = tryConsume("OPEN");
          if (open) {
              var prefix = consumeText();
              var name_1 = tryConsume("NAME") || "";
              var pattern_1 = tryConsume("PATTERN") || "";
              var suffix = consumeText();
              mustConsume("CLOSE");
              result.push({
                  name: name_1 || (pattern_1 ? key++ : ""),
                  pattern: name_1 && !pattern_1 ? safePattern(prefix) : pattern_1,
                  prefix: prefix,
                  suffix: suffix,
                  modifier: tryConsume("MODIFIER") || "",
              });
              continue;
          }
          mustConsume("END");
      }
      return result;
  }
  /**
   * Escape a regular expression string.
   */
  function escapeString(str) {
      return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
  }
  /**
   * Get the flags for a regexp from the options.
   */
  function flags(options) {
      return options && options.sensitive ? "" : "i";
  }
  /**
   * Pull out keys from a regexp.
   */
  function regexpToRegexp(path, keys) {
      if (!keys)
          return path;
      var groupsRegex = /\((?:\?<(.*?)>)?(?!\?)/g;
      var index = 0;
      var execResult = groupsRegex.exec(path.source);
      while (execResult) {
          keys.push({
              // Use parenthesized substring match if available, index otherwise
              name: execResult[1] || index++,
              prefix: "",
              suffix: "",
              modifier: "",
              pattern: "",
          });
          execResult = groupsRegex.exec(path.source);
      }
      return path;
  }
  /**
   * Transform an array into a regexp.
   */
  function arrayToRegexp(paths, keys, options) {
      var parts = paths.map(function (path) { return pathToRegexp$1(path, keys, options).source; });
      return new RegExp("(?:".concat(parts.join("|"), ")"), flags(options));
  }
  /**
   * Create a path regexp from string input.
   */
  function stringToRegexp(path, keys, options) {
      return tokensToRegexp(parse$1(path, options), keys, options);
  }
  /**
   * Expose a function for taking tokens and returning a RegExp.
   */
  function tokensToRegexp(tokens, keys, options) {
      if (options === void 0) { options = {}; }
      var _a = options.strict, strict = _a === void 0 ? false : _a, _b = options.start, start = _b === void 0 ? true : _b, _c = options.end, end = _c === void 0 ? true : _c, _d = options.encode, encode = _d === void 0 ? function (x) { return x; } : _d, _e = options.delimiter, delimiter = _e === void 0 ? "/#?" : _e, _f = options.endsWith, endsWith = _f === void 0 ? "" : _f;
      var endsWithRe = "[".concat(escapeString(endsWith), "]|$");
      var delimiterRe = "[".concat(escapeString(delimiter), "]");
      var route = start ? "^" : "";
      // Iterate over the tokens and create our regexp string.
      for (var _i = 0, tokens_1 = tokens; _i < tokens_1.length; _i++) {
          var token = tokens_1[_i];
          if (typeof token === "string") {
              route += escapeString(encode(token));
          }
          else {
              var prefix = escapeString(encode(token.prefix));
              var suffix = escapeString(encode(token.suffix));
              if (token.pattern) {
                  if (keys)
                      keys.push(token);
                  if (prefix || suffix) {
                      if (token.modifier === "+" || token.modifier === "*") {
                          var mod = token.modifier === "*" ? "?" : "";
                          route += "(?:".concat(prefix, "((?:").concat(token.pattern, ")(?:").concat(suffix).concat(prefix, "(?:").concat(token.pattern, "))*)").concat(suffix, ")").concat(mod);
                      }
                      else {
                          route += "(?:".concat(prefix, "(").concat(token.pattern, ")").concat(suffix, ")").concat(token.modifier);
                      }
                  }
                  else {
                      if (token.modifier === "+" || token.modifier === "*") {
                          throw new TypeError("Can not repeat \"".concat(token.name, "\" without a prefix and suffix"));
                      }
                      route += "(".concat(token.pattern, ")").concat(token.modifier);
                  }
              }
              else {
                  route += "(?:".concat(prefix).concat(suffix, ")").concat(token.modifier);
              }
          }
      }
      if (end) {
          if (!strict)
              route += "".concat(delimiterRe, "?");
          route += !options.endsWith ? "$" : "(?=".concat(endsWithRe, ")");
      }
      else {
          var endToken = tokens[tokens.length - 1];
          var isEndDelimited = typeof endToken === "string"
              ? delimiterRe.indexOf(endToken[endToken.length - 1]) > -1
              : endToken === undefined;
          if (!strict) {
              route += "(?:".concat(delimiterRe, "(?=").concat(endsWithRe, "))?");
          }
          if (!isEndDelimited) {
              route += "(?=".concat(delimiterRe, "|").concat(endsWithRe, ")");
          }
      }
      return new RegExp(route, flags(options));
  }
  /**
   * Normalize the given path string, returning a regular expression.
   *
   * An empty array can be passed in for the keys, which will hold the
   * placeholder key descriptions. For example, using `/user/:id`, `keys` will
   * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
   */
  function pathToRegexp$1(path, keys, options) {
      if (path instanceof RegExp)
          return regexpToRegexp(path, keys);
      if (Array.isArray(path))
          return arrayToRegexp(path, keys, options);
      return stringToRegexp(path, keys, options);
  }

  /**
   * @barba/core/schemas
   * <br><br>
   * ## Schemas description.
   *
   * @module core/schemas
   * @preferred
   */
  /**
   * See [[ISchemaAttribute]]
   */
  var schemaAttribute = {
    container: 'container',
    history: 'history',
    namespace: 'namespace',
    prefix: 'data-barba',
    prevent: 'prevent',
    wrapper: 'wrapper'
  };

  /**
   * @barba/core/utils/dom
   * <br><br>
   * ## Dom utils
   *
   * - Access DOM contents
   * - DOM vs string conversions
   *
   * @module core/utils/dom
   * @preferred
   */
  var Dom = /*#__PURE__*/function () {
    function Dom() {
      this._attr = schemaAttribute;
      this._parser = void 0;
      this._sibling = {
        after: null,
        before: null,
        parent: null
      };
    }
    var _proto = Dom.prototype;
    /**
     * Convert HTMLDocument to string.
     */
    _proto.toString = function toString(el) {
      return el.outerHTML;
    }
    /**
     * Parse HTML string to HTMLDocument.
     */
    // see https://github.com/barbajs/barba/issues/362
    // Seems that using DOMParser.parseFromString causes this issue.
    ;
    _proto.toDocument = function toDocument(htmlString) {
      /* istanbul ignore else */
      if (!this._parser) {
        this._parser = new DOMParser();
      }
      return this._parser.parseFromString(htmlString, 'text/html');
    }
    /**
     * Parse HTML string to DIVElement.
     *
     * DOMParser.parseFromString fails with img[srcset] on iOS.
     * see https://github.com/barbajs/barba/issues/362
     */;
    _proto.toElement = function toElement(htmlString) {
      var div = document.createElement('div');
      div.innerHTML = htmlString;
      return div;
    }
    /**
     * Get HTML content.
     */;
    _proto.getHtml = function getHtml(doc) {
      if (doc === void 0) {
        doc = document;
      }
      return this.toString(doc.documentElement);
    }
    /**
     * Get full document content.
     */
    // getDocument(el = document.documentElement) {
    //   return this.toStr(el);
    // },
    /**
     * Get `[data-barba="wrapper"]`.
     */;
    _proto.getWrapper = function getWrapper(scope) {
      if (scope === void 0) {
        scope = document;
      }
      return scope.querySelector("[" + this._attr.prefix + "=\"" + this._attr.wrapper + "\"]");
    }
    /**
     * Get `[data-barba="container"]`.
     */;
    _proto.getContainer = function getContainer(scope) {
      if (scope === void 0) {
        scope = document;
      }
      return scope.querySelector("[" + this._attr.prefix + "=\"" + this._attr.container + "\"]");
    }
    /**
     * Remove container and store next sibling (if applicable).
     */;
    _proto.removeContainer = function removeContainer(container) {
      if (document.body.contains(container)) {
        this._updateSibling(container);
        container.parentNode.removeChild(container);
      }
    }
    /**
     * Add container near previous container
     */;
    _proto.addContainer = function addContainer(container, wrapper) {
      var siblingBefore = this.getContainer() || this._sibling.before;
      if (siblingBefore) {
        this._insertAfter(container, siblingBefore);
      } else if (this._sibling.after) {
        this._sibling.after.parentNode.insertBefore(container, this._sibling.after);
      } else if (this._sibling.parent) {
        this._sibling.parent.appendChild(container);
      } else {
        wrapper.appendChild(container);
      }
    }
    /**
     * Get current dom sibling
     */;
    _proto.getSibling = function getSibling() {
      return this._sibling;
    }
    /**
     * Get `[data-barba-namespace]`.
     */;
    _proto.getNamespace = function getNamespace(scope) {
      if (scope === void 0) {
        scope = document;
      }
      var ns = scope.querySelector("[" + this._attr.prefix + "-" + this._attr.namespace + "]");
      return ns ? ns.getAttribute(this._attr.prefix + "-" + this._attr.namespace) : null;
    }
    /**
     * Get URL from `href` value.
     */;
    _proto.getHref = function getHref(el) {
      // HTML tagName is UPPERCASE, xhtml tagName keeps existing case.
      if (el.tagName && el.tagName.toLowerCase() === 'a') {
        // HTMLAnchorElement, full URL available
        if (typeof el.href === 'string') {
          return el.href;
        }
        // Probably a SVGAElement…
        var href = el.getAttribute('href') || el.getAttribute('xlink:href');
        /* istanbul ignore else */
        if (href) {
          // When link comes from SVG, `href` returns an object, not a string.
          var attr = href.baseVal || href;
          return this.resolveUrl(attr);
        }
      }
      return null;
    }
    // Copyright 2014 Simon Lydell
    // X11 (“MIT”) Licensed. (See LICENSE
    // https://github.com/lydell/resolve-url/blob/master/resolve-url.js
    /* istanbul ignore next */;
    _proto.resolveUrl = function resolveUrl() {
      var numUrls = [].slice.call(arguments).length;
      if (numUrls === 0) {
        throw new Error('resolveUrl requires at least one argument; got none.');
      }
      var base = document.createElement('base');
      base.href = arguments[0];
      if (numUrls === 1) {
        return base.href;
      }
      var head = document.getElementsByTagName('head')[0];
      head.insertBefore(base, head.firstChild);
      var a = document.createElement('a');
      var resolved;
      for (var index = 1; index < numUrls; index++) {
        a.href = arguments[index];
        resolved = a.href;
        base.href = resolved;
      }
      head.removeChild(base);
      return resolved;
    }
    /**
     * Insert node after another node.
     */;
    _proto._insertAfter = function _insertAfter(newNode, referenceNode) {
      referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
    }
    /**
     * Update current dom sibling regarding container
     */;
    _proto._updateSibling = function _updateSibling(container) {
      this._sibling = {
        after: container.nextElementSibling,
        before: container.previousElementSibling,
        parent: container.parentElement
      };
      return this._sibling;
    };
    return Dom;
  }();
  var dom = new Dom();

  var History = /*#__PURE__*/function () {
    function History() {
      this._session = void 0;
      this._states = [];
      this._pointer = -1;
    }
    var _proto = History.prototype;
    /**
     * Init with first state.
     */
    _proto.init = function init(url, ns) {
      this._session = 'barba';
      var state = {
        data: {},
        ns: ns,
        scroll: {
          x: window.scrollX,
          y: window.scrollY
        },
        url: url
      };
      this._pointer = 0;
      this._states.push(state);
      var item = {
        from: this._session,
        index: this._pointer,
        states: [].concat(this._states)
      };
      window.history && window.history.replaceState(item, '', url);
    };
    _proto.change = function change(url, trigger, e) {
      if (e && e.state) {
        // If popstate, move to existing state
        // and get back/forward direction.
        var state = e.state;
        var index = state.index;
        var diff = this._pointer - index;
        trigger = this._getDirection(diff);
        // Work with previous states
        this.replace(state.states);
        this._pointer = index;
      } else {
        // Add new state
        this.add(url, trigger);
      }
      return trigger;
    }
    /**
     * Add a new state.
     */;
    _proto.add = function add(url, trigger, action, data) {
      // If no state, it will be updated later.
      var ns = 'tmp';
      var method = action != null ? action : this._getAction(trigger);
      var state = {
        data: data != null ? data : {},
        ns: ns,
        scroll: {
          x: window.scrollX,
          y: window.scrollY
        },
        url: url
      };
      switch (method) {
        case 'push':
          this._pointer = this.size;
          this._states.push(state);
          break;
        case 'replace':
          this.set(this._pointer, state);
          break;
      }
      var item = {
        from: this._session,
        index: this._pointer,
        states: [].concat(this._states)
      };
      switch (method) {
        case 'push':
          window.history && window.history.pushState(item, '', url);
          break;
        case 'replace':
          window.history && window.history.replaceState(item, '', url);
          break;
      }
    }
    /**
     * Store custom user data per state.
     */;
    _proto.store = function store(data, i) {
      var index = i || this._pointer;
      var state = this.get(index);
      // merge data (allow data overwrite)
      state.data = _extends({}, state.data, data);
      // update states
      this.set(index, state);
      var item = {
        from: this._session,
        index: this._pointer,
        states: [].concat(this._states)
      };
      // update browser history
      window.history.replaceState(item, '');
    }
    /**
     * Update state.
     */;
    _proto.update = function update(data, i) {
      var index = i || this._pointer;
      var existing = this.get(index);
      var state = _extends({}, existing, data);
      this.set(index, state);
    }
    /**
     * Remove last state.
     */;
    _proto.remove = function remove(i) {
      if (i) {
        this._states.splice(i, 1);
      } else {
        this._states.pop();
      }
      this._pointer--;
    }
    /**
     * Delete all states.
     */;
    _proto.clear = function clear() {
      this._states = [];
      this._pointer = -1;
    }
    /**
     * Replace all states.
     */;
    _proto.replace = function replace(newStates) {
      this._states = newStates;
    }
    /**
     * Get state by index.
     */;
    _proto.get = function get(index) {
      return this._states[index];
    }
    /**
     * Set state by index.
     */;
    _proto.set = function set(i, state) {
      return this._states[i] = state;
    }
    /**
     * Get the current state.
     */;
    /**
     * Get the history action: push vs replace
     */
    _proto._getAction = function _getAction(trigger) {
      var action = 'push';
      // Manage `data-barba-history` attribute
      // to get the right action (push vs replace).
      var el = trigger;
      var attr = schemaAttribute.prefix + "-" + schemaAttribute.history;
      if (el.hasAttribute && el.hasAttribute(attr)) {
        action = el.getAttribute(attr);
      }
      return action;
    }
    /**
     * Get the direction of popstate change
     */;
    _proto._getDirection = function _getDirection(diff) {
      // Check if "session switch"
      if (Math.abs(diff) > 1) {
        // Ex 6-0 > 0 -> forward, 0-6 < 0 -> back
        return diff > 0 ? 'forward' : 'back';
      } else {
        if (diff === 0) {
          return 'popstate';
        } else {
          // Ex 6-5 > 0 -> back, 5-6 < 0 -> forward
          return diff > 0 ? 'back' : 'forward';
        }
      }
    };
    _createClass(History, [{
      key: "current",
      get: function get() {
        return this._states[this._pointer];
      }
      /**
       * Get the previous state.
       */
    }, {
      key: "previous",
      get: function get() {
        return this._pointer < 1 ? null : this._states[this._pointer - 1];
      }
      /**
       * Get the state size.
       */
    }, {
      key: "size",
      get: function get() {
        return this._states.length;
      }
    }]);
    return History;
  }();
  var history = new History();

  /**
   * @barba/core/utils/helpers
   * <br><br>
   * ## Helpers
   *
   * - Update next page data
   *
   * @module core/utils/helpers
   * @preferred
   */
  /**
   * Update `data.next`, the title and the history
   */
  var update = function update(page, data) {
    try {
      var _temp = function () {
        if (!data.next.html) {
          return Promise.resolve(page).then(function (response) {
            var next = data.next;
            if (response) {
              // see: https://github.com/barbajs/barba/issues/362
              // const nextDocument = dom.toDocument(html);
              var nextDocument = dom.toElement(response.html);
              next.namespace = dom.getNamespace(nextDocument);
              next.container = dom.getContainer(nextDocument);
              // see https://github.com/barbajs/barba/issues/362
              // next.html = dom.getHtml(nextDocument);
              // next.html = nextDocument.innerHTML;
              next.url = response.url;
              next.html = response.html;
              // Update history namespace (not available when initially set)
              history.update({
                ns: next.namespace
              });
              // Update title.
              var _dom$toDocument = dom.toDocument(response.html),
                title = _dom$toDocument.title;
              document.title = title;
            }
          });
        }
      }();
      // If not already updated
      return Promise.resolve(_temp && _temp.then ? _temp.then(function () {}) : void 0);
    } catch (e) {
      return Promise.reject(e);
    }
  };
  /**
   * Next tick
   */
  var nextTick = function nextTick() {
    return new Promise(function (resolve) {
      window.requestAnimationFrame(resolve);
      // DEV: same result?
      // setTimeout(resolve, 0);
    });
  };
  /**
   * Turn a route string such as `/user/:name` into a regular expression.
   *
   * Used for:
   *
   * - routes to ignore
   * - route transition resolution
   *
   * @see https://www.npmjs.com/package/path-to-regexp
   */
  var pathToRegexp = pathToRegexp$1;

  var helpers = {
    __proto__: null,
    update: update,
    nextTick: nextTick,
    pathToRegexp: pathToRegexp
  };

  /**
   * @barba/core/utils/url
   * <br><br>
   * ## URL utils.
   *
   * - Collect and structure informations from URLs
   *
   * @module core/utils/url
   */
  /**
   * Get location href.
   */
  var getHref = function getHref() {
    return window.location.href;
  };
  /**
   * Get absolute href from URL.
   */
  var getAbsoluteHref = function getAbsoluteHref(url, base) {
    if (base === void 0) {
      base = document.baseURI;
    }
    return new URL(url, base).href;
  };
  /**
   * Get location origin.
   */
  var getOrigin = function getOrigin() {
    return window.location.origin;
  };
  /**
   * Get port based on URL or location.
   */
  var getPort = function getPort(url) {
    if (url === void 0) {
      url = window.location.href;
    }
    return parse(url).port;
  };
  /**
   * Get path from URL.
   */
  var getPath = function getPath(url) {
    if (url === void 0) {
      url = window.location.href;
    }
    return parse(url).path;
  };
  /**
   * Get query object from URL.
   */
  var getQuery = function getQuery(url, stringify) {
    if (stringify === void 0) {
      stringify = false;
    }
    return stringify ? JSON.stringify(parse(url).query) : parse(url).query;
  };
  /**
   * Get hash from URL.
   */
  var getHash = function getHash(url) {
    return parse(url).hash;
  };
  /**
   * Parse URL for path, query and hash and more.
   */
  var parse = function parse(url) {
    // Port
    var port;
    var matches = url.match(/:\d+/);
    if (matches === null) {
      if (/^http/.test(url)) {
        port = 80;
      }
      if (/^https/.test(url)) {
        port = 443;
      }
    } else {
      var portString = matches[0].substring(1);
      port = parseInt(portString, 10);
    }
    // Path
    var path = url.replace(getOrigin(), '');
    var hash;
    var query = {};
    // Hash
    var hashIndex = path.indexOf('#');
    if (hashIndex >= 0) {
      hash = path.slice(hashIndex + 1);
      path = path.slice(0, hashIndex);
    }
    // Query
    var queryIndex = path.indexOf('?');
    if (queryIndex >= 0) {
      query = parseQuery(path.slice(queryIndex + 1));
      path = path.slice(0, queryIndex);
    }
    return {
      hash: hash,
      path: path,
      port: port,
      query: query
    };
  };
  /**
   * Parse a query string to object.
   */
  var parseQuery = function parseQuery(str) {
    return str.split('&').reduce(function (acc, el) {
      var _el$split = el.split('='),
        key = _el$split[0],
        value = _el$split[1];
      acc[key] = value;
      return acc;
    }, {});
  };
  /**
   * Clean URL, remove "hash" and/or "trailing slash".
   */
  var clean = function clean(url) {
    if (url === void 0) {
      url = window.location.href;
    }
    return url.replace(/(\/#.*|\/|#.*)$/, '');
  };

  var url = {
    __proto__: null,
    getHref: getHref,
    getAbsoluteHref: getAbsoluteHref,
    getOrigin: getOrigin,
    getPort: getPort,
    getPath: getPath,
    getQuery: getQuery,
    getHash: getHash,
    parse: parse,
    parseQuery: parseQuery,
    clean: clean
  };

  /**
   * Init a page request.
   * Fetch the page and returns a promise with the text content.
   */
  function request(url, ttl, requestError, cache, headers) {
    if (ttl === void 0) {
      ttl = 2e3;
    }
    return new Promise(function (resolve, reject) {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function () {
        if (xhr.readyState === XMLHttpRequest.DONE) {
          if (xhr.status === 200) {
            /* istanbul ignore next: bypass jest since xhr-mock doesn't support custom xhr.responseURL */
            var responseURL = xhr.responseURL !== '' && xhr.responseURL !== url ? xhr.responseURL : url;
            resolve({
              html: xhr.responseText,
              url: _extends({
                href: responseURL
              }, parse(responseURL))
            });
            cache.update(url, {
              status: 'fulfilled',
              target: responseURL
            });
          } else if (xhr.status) {
            // HTTP code is not 200, reject with response.
            var response = {
              status: xhr.status,
              statusText: xhr.statusText
            };
            requestError(url, response);
            reject(response);
            cache.update(url, {
              status: 'rejected'
            });
          }
        }
      };
      xhr.ontimeout = function () {
        var error = new Error("Timeout error [" + ttl + "]");
        requestError(url, error);
        reject(error);
        cache.update(url, {
          status: 'rejected'
        });
      };
      xhr.onerror = function () {
        var error = new Error("Fetch error");
        requestError(url, error);
        reject(error);
        cache.update(url, {
          status: 'rejected'
        });
      };
      xhr.open('GET', url);
      xhr.timeout = ttl;
      xhr.setRequestHeader('Accept', 'text/html,application/xhtml+xml,application/xml');
      xhr.setRequestHeader('x-barba', 'yes');
      headers.all().forEach(function (value, key) {
        xhr.setRequestHeader(key, value);
      });
      xhr.send();
    });
  }

  function isPromise(obj) {
    return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
  }

  // https://github.com/SBoudrias/run-async
  /* istanbul ignore next */
  function runAsync(func, ctx) {
    if (ctx === void 0) {
      ctx = {};
    }
    return function () {
      var _arguments = arguments;
      var async = false;
      var promise = new Promise(function (resolve, reject) {
        // Add async to context
        ctx.async = function () {
          async = true;
          return function (err, value) {
            if (err) {
              reject(err);
            } else {
              resolve(value);
            }
          };
        };
        var answer = func.apply(ctx, [].slice.call(_arguments));
        if (!async) {
          if (isPromise(answer)) {
            answer.then(resolve, reject);
          } else {
            resolve(answer);
          }
        }
      });
      return promise;
    };
  }

  var Hooks = /*#__PURE__*/function (_HookMethods) {
    _inheritsLoose(Hooks, _HookMethods);
    // [key in HooksAll]?: any;

    /**
     * All available hooks.
     *
     * See [[HooksAll]]
     */
    // TODO: get hooks from defs (DRY)?

    /**
     * Registered hooks.
     *
     * - Unique hook name
     * - Associated data set(s) (callback + context)
     */

    function Hooks() {
      var _this;
      _this = _HookMethods.call(this) || this;
      _this.logger = new Logger('@barba/core');
      _this.all = ['ready', 'page', 'reset', 'currentAdded', 'currentRemoved', 'nextAdded', 'nextRemoved', 'beforeOnce', 'once', 'afterOnce', 'before', 'beforeLeave', 'leave', 'afterLeave', 'beforeEnter', 'enter', 'afterEnter', 'after'];
      _this.registered = new Map();
      _this.init();
      return _this;
    }
    var _proto = Hooks.prototype;
    _proto.init = function init() {
      var _this2 = this;
      this.registered.clear();
      this.all.forEach(function (hook) {
        if (!_this2[hook]) {
          _this2[hook] = function (fn, ctx) {
            if (!_this2.registered.has(hook)) {
              _this2.registered.set(hook, new Set());
            }
            var set = _this2.registered.get(hook);
            set.add({
              ctx: ctx || {},
              fn: fn
            });
          };
        }
      });
    }
    /**
     * Do hook.
     *
     * Trigger registered hooks.
     */;
    _proto["do"] = function _do(name) {
      var _arguments = arguments,
        _this3 = this;
      if (this.registered.has(name)) {
        // Let's start a chain of promises
        var chain = Promise.resolve();
        this.registered.get(name).forEach(function (hook) {
          // Chain async hooks promisified
          chain = chain.then(function () {
            return runAsync(hook.fn, hook.ctx).apply(void 0, [].slice.call(_arguments, 1));
          });
        });
        return chain["catch"](function (error) {
          _this3.logger.debug("Hook error [" + name + "]");
          _this3.logger.error(error);
        });
      }
      return Promise.resolve();
    };
    _proto.clear = function clear() {
      var _this4 = this;
      this.all.forEach(function (hook) {
        delete _this4[hook];
      });
      this.init();
    }
    /**
     * Help, print available and registered hooks.
     */;
    _proto.help = function help() {
      this.logger.info("Available hooks: " + this.all.join(','));
      var registered = [];
      this.registered.forEach(function (_value, key) {
        return registered.push(key);
      });
      this.logger.info("Registered hooks: " + registered.join(','));
    };
    return Hooks;
  }(HookMethods);
  var hooks = new Hooks();

  /**
   * @barba/core/modules/ignore
   * <br><br>
   * ## Manage ignore options.
   *
   * - cache
   * - prefetch
   *
   * @module core/modules/ignore
   * @preferred
   */
  var Ignore = /*#__PURE__*/function () {
    function Ignore(ignore) {
      this._ignoreAll = void 0;
      this._ignoreRegexes = [];
      if (typeof ignore === 'boolean') {
        this._ignoreAll = ignore;
      } else {
        var paths = Array.isArray(ignore) ? ignore : [ignore];
        this._ignoreRegexes = paths.map(function (p) {
          return pathToRegexp(p);
        });
      }
    }
    var _proto = Ignore.prototype;
    _proto.checkHref = function checkHref(href) {
      if (typeof this._ignoreAll === 'boolean') {
        return this._ignoreAll;
      }
      var _parse = parse(href),
        path = _parse.path;
      return this._ignoreRegexes.some(function (regex) {
        return regex.exec(path) !== null;
      });
    };
    return Ignore;
  }();

  var Cache = /*#__PURE__*/function (_Ignore) {
    _inheritsLoose(Cache, _Ignore);
    function Cache(ignore) {
      var _this;
      _this = _Ignore.call(this, ignore) || this;
      _this._state = new Map();
      return _this;
    }
    /**
     * Set value to cache
     */
    var _proto = Cache.prototype;
    _proto.set = function set(href, request, action, status, target) {
      this._state.set(href, {
        action: action,
        request: request,
        status: status,
        target: target != null ? target : href
      });
      return {
        action: action,
        request: request,
        status: status,
        target: target
      };
    }
    /**
     * Get data from cache
     */;
    _proto.get = function get(href) {
      return this._state.get(href);
    }
    /**
     * Get request from cache
     */;
    _proto.getRequest = function getRequest(href) {
      return this._state.get(href).request;
    }
    /**
     * Get action from cache
     */;
    _proto.getAction = function getAction(href) {
      return this._state.get(href).action;
    }
    /**
     * Get status from cache
     */;
    _proto.getStatus = function getStatus(href) {
      return this._state.get(href).status;
    }
    /**
     * Get target from cache
     */;
    _proto.getTarget = function getTarget(href) {
      return this._state.get(href).target;
    }
    /**
     * Check if value exists into cache
     */;
    _proto.has = function has(href) {
      /* istanbul ignore else */
      if (this.checkHref(href)) {
        return false;
      }
      return this._state.has(href);
    }
    /**
     * Delete value from cache
     */;
    _proto["delete"] = function _delete(href) {
      return this._state["delete"](href);
    }
    /**
     * Update cache value
     */;
    _proto.update = function update(href, data) {
      var state = _extends({}, this._state.get(href), data);
      this._state.set(href, state);
      return state;
    };
    return Cache;
  }(Ignore);

  /**
   * @barba/core/modules/headers
   * <br><br>
   * ## Manage request Headers.
   *
   * @module core/modules/headers
   * @preferred
   */
  var Headers = /*#__PURE__*/function () {
    function Headers() {
      this._list = new Map();
    }
    var _proto = Headers.prototype;
    /**
     * Set a new header
     */
    _proto.set = function set(name, value) {
      this._list.set(name, value);
      return {
        name: value
      };
    }
    /**
     * Get a specific header
     */;
    _proto.get = function get(name) {
      return this._list.get(name);
    }
    /**
     * Get all headers
     */;
    _proto.all = function all() {
      return this._list;
    }
    /**
     * Check if header exists
     */;
    _proto.has = function has(name) {
      return this._list.has(name);
    }
    /**
     * Delete a header
     */;
    _proto["delete"] = function _delete(name) {
      return this._list["delete"](name);
    }
    /**
     * Clear all headers
     */;
    _proto.clear = function clear() {
      return this._list.clear();
    };
    return Headers;
  }();

  /**
   * Make sure the browser supports `history.pushState`.
   */
  var pushState = function pushState() {
    return !window.history.pushState;
  };
  /**
   * Make sure there is an `el` and `href`.
   */
  var exists = function exists(_ref) {
    var el = _ref.el,
      href = _ref.href;
    return !el || !href;
  };
  /**
   * If the user is pressing ctrl + click, the browser will open a new tab.
   */
  var newTab = function newTab(_ref2) {
    var event = _ref2.event;
    return event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
  };
  /**
   * If the link has `_blank` target.
   */
  var blank = function blank(_ref3) {
    var el = _ref3.el;
    return el.hasAttribute('target') && el.target === '_blank';
  };
  /**
   * If the domain is the same (in order to avoid pushState cross origin security problem).
   * Note: SVGAElement do not have `protocol` neither `hostname` properties.
   */
  var corsDomain = function corsDomain(_ref4) {
    var el = _ref4.el;
    return el.protocol !== undefined && window.location.protocol !== el.protocol || el.hostname !== undefined && window.location.hostname !== el.hostname;
  };
  /**
   * If the port is the same.
   * Note: SVGAElement do not have `port` property.
   */
  var corsPort = function corsPort(_ref5) {
    var el = _ref5.el;
    return el.port !== undefined && getPort() !== getPort(el.href);
  };
  /**
   * If the link has download attribute.
   */
  var download = function download(_ref6) {
    var el = _ref6.el;
    return el.getAttribute && typeof el.getAttribute('download') === 'string';
  };
  /**
   * If the links contains [data-barba-prevent] or [data-barba-prevent="self"].
   */
  var preventSelf = function preventSelf(_ref7) {
    var el = _ref7.el;
    return el.hasAttribute(schemaAttribute.prefix + "-" + schemaAttribute.prevent);
  };
  /**
   * If some link ancestor contains [data-barba-prevent="all"].
   */
  var preventAll = function preventAll(_ref8) {
    var el = _ref8.el;
    return Boolean(el.closest("[" + schemaAttribute.prefix + "-" + schemaAttribute.prevent + "=\"all\"]"));
  };
  /**
   * If the link is the current URL.
   *
   * > Not in the test suite.
   */
  var sameUrl = function sameUrl(_ref9) {
    var href = _ref9.href;
    return clean(href) === clean() && getPort(href) === getPort();
  };
  var Prevent = /*#__PURE__*/function (_Ignore) {
    _inheritsLoose(Prevent, _Ignore);
    function Prevent(ignore) {
      var _this;
      _this = _Ignore.call(this, ignore) || this;
      _this.suite = [];
      _this.tests = new Map();
      _this.init();
      return _this;
    }
    var _proto = Prevent.prototype;
    _proto.init = function init() {
      // Add defaults
      this.add('pushState', pushState);
      this.add('exists', exists);
      this.add('newTab', newTab);
      this.add('blank', blank);
      this.add('corsDomain', corsDomain);
      this.add('corsPort', corsPort);
      this.add('download', download);
      this.add('preventSelf', preventSelf);
      this.add('preventAll', preventAll);
      // Outside of the test suite
      this.add('sameUrl', sameUrl, false);
    };
    _proto.add = function add(name, check, suite) {
      if (suite === void 0) {
        suite = true;
      }
      this.tests.set(name, check);
      suite && this.suite.push(name);
    }
    /**
     * Run individual test
     */;
    _proto.run = function run(name, el, event, href) {
      return this.tests.get(name)({
        el: el,
        event: event,
        href: href
      });
    }
    /**
     * Run test suite
     */;
    _proto.checkLink = function checkLink(el, event, href) {
      var _this2 = this;
      return this.suite.some(function (name) {
        return _this2.run(name, el, event, href);
      });
    };
    return Prevent;
  }(Ignore);

  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
  var BarbaError = /*#__PURE__*/function (_Error) {
    _inheritsLoose(BarbaError, _Error);
    /* istanbul ignore next */
    function BarbaError(error, label) {
      var _this;
      if (label === void 0) {
        label = 'Barba error';
      }
      // Pass remaining arguments (including vendor specific ones) to parent constructor
      _this = _Error.call.apply(_Error, [this].concat([].slice.call(arguments, 2))) || this;
      _this.error = void 0;
      _this.label = void 0;
      _this.error = error;
      _this.label = label;
      // Maintains proper stack trace for where our error was thrown (only available on V8)
      /* istanbul ignore else */
      if (Error.captureStackTrace) {
        Error.captureStackTrace(_assertThisInitialized(_this), BarbaError);
      }
      _this.name = 'BarbaError';
      return _this;
    }
    return BarbaError;
  }(/*#__PURE__*/_wrapNativeSuper(Error));

  /**
   * @barba/core/modules/store
   * <br><br>
   * ## Transitions store.
   *
   * - Resolve transition
   * - Manage rules
   *
   * @module core/modules/store
   * @preferred
   */
  var Store = /*#__PURE__*/function () {
    /**
     * All registered transitions.
     */

    /**
     * "Page only" registered transitions.
     */

    /**
     * "Once only" registered transitions.
     */

    /**
     * Rules for transition resolution.
     *
     * Defaults:
     *
     * - namespace
     * - custom
     */

    /**
     * Init store.
     */
    function Store(transitions) {
      if (transitions === void 0) {
        transitions = [];
      }
      this.logger = new Logger('@barba/core');
      this.all = [];
      this.page = [];
      this.once = [];
      this._rules = [{
        name: 'namespace',
        type: 'strings'
      }, {
        name: 'custom',
        type: 'function'
      }];
      /* istanbul ignore else */
      if (transitions) {
        // TODO: add check for valid transitions? criteria? (once || enter && leave)
        this.all = this.all.concat(transitions);
      }
      this.update();
    }
    /**
     * Add rule or transition.
     */
    var _proto = Store.prototype;
    _proto.add = function add(type, data) {
      switch (type) {
        case 'rule':
          // TODO: check for valid rule
          this._rules.splice(data.position || 0, 0, data.value);
          break;
        case 'transition':
        default:
          // TODO: check for valid transition
          this.all.push(data);
          break;
      }
      this.update();
    }
    /**
     * Resolve transition.
     */;
    _proto.resolve = function resolve(data, filters) {
      var _this = this;
      if (filters === void 0) {
        filters = {};
      }
      // Filter on "once"
      var transitions = filters.once ? this.once : this.page;
      // Filter on "self"
      if (filters.self) {
        transitions = transitions.filter(function (t) {
          return t.name && t.name === 'self';
        });
      } else {
        transitions = transitions.filter(function (t) {
          return !t.name || t.name !== 'self';
        });
      }
      // All matching transition infos
      var matching = new Map();
      // Active = first of valid transitions
      // sorted by directions (from/to, from || to, …)
      var active = transitions.find(function (t) {
        var valid = true;
        var match = {};
        if (filters.self && t.name === 'self') {
          matching.set(t, match);
          return true;
        }
        // Check rules
        _this._rules.reverse().forEach(function (rule) {
          if (valid) {
            valid = _this._check(t, rule, data, match);
            // From/to check
            if (t.from && t.to) {
              valid = _this._check(t, rule, data, match, 'from') && _this._check(t, rule, data, match, 'to');
            }
            if (t.from && !t.to) {
              valid = _this._check(t, rule, data, match, 'from');
            }
            if (!t.from && t.to) {
              valid = _this._check(t, rule, data, match, 'to');
            }
          }
        });
        matching.set(t, match);
        return valid;
      });
      var activeMatch = matching.get(active);
      var transitionType = [];
      if (filters.once) {
        transitionType.push('once');
      } else {
        transitionType.push('page');
      }
      if (filters.self) {
        transitionType.push('self');
      }
      if (activeMatch) {
        var _this$logger;
        // Log resolved transition
        var infos = [active];
        // Log if matching criteria
        Object.keys(activeMatch).length > 0 && infos.push(activeMatch);
        (_this$logger = this.logger).info.apply(_this$logger, ["Transition found [" + transitionType.join(',') + "]"].concat(infos));
      } else {
        this.logger.info("No transition found [" + transitionType.join(',') + "]");
      }
      return active;
    }
    /**
     * ### Update store.
     *
     * - Reorder transition by priorities
     * - Get wait indicator
     * - Get once transitions
     */;
    _proto.update = function update() {
      var _this2 = this;
      // Reorder by priorities
      this.all = this.all.map(function (t) {
        return _this2._addPriority(t);
      }).sort(function (a, b) {
        return a.priority - b.priority;
      }).reverse().map(function (t) {
        delete t.priority;
        return t;
      });
      this.page = this.all.filter(function (t) {
        return t.leave !== undefined || t.enter !== undefined;
      });
      this.once = this.all.filter(function (t) {
        return t.once !== undefined;
      });
    }
    /**
     * ### Check if transition apply.
     *
     * Based on rule, page data and optional direction:
     *
     * 1. transition has no rule "property":
     *    - always returns true
     * 2. transition has rule "property":
     *     - "strings" should be present on both side (transition + page) and match
     *     - "function" should return true
     */;
    _proto._check = function _check(transition, rule, data, match, direction) {
      var isValid = true;
      var hasMatch = false;
      var t = transition;
      var name = rule.name,
        type = rule.type;
      var strRule = name;
      var objRule = name;
      var fnName = name;
      var base = direction ? t[direction] : t; // = t || t.from || t.to
      var page = direction === 'to' ? data.next : data.current; // = current || next
      var exist = direction ? base && base[name] : base[name];
      // If transition rule exists
      if (exist) {
        switch (type) {
          case 'strings':
          default:
            {
              // Array support
              var names = Array.isArray(base[strRule]) ? base[strRule] : [base[strRule]];
              // For matching, prop should be present on both sides and match
              if (page[strRule] && names.indexOf(page[strRule]) !== -1) {
                hasMatch = true;
              }
              // If transition prop is different from current, not valid
              if (names.indexOf(page[strRule]) === -1) {
                isValid = false;
              }
              break;
            }
          case 'object':
            {
              // Array support
              var _names = Array.isArray(base[objRule]) ? base[objRule] : [base[objRule]];
              // For matching, prop should be present on both sides and match
              if (page[objRule]) {
                if (page[objRule].name && _names.indexOf(page[objRule].name) !== -1) {
                  hasMatch = true;
                }
                // If transition prop is different from current, not valid
                if (_names.indexOf(page[objRule].name) === -1) {
                  isValid = false;
                }
              } else {
                isValid = false;
              }
              break;
            }
          case 'function':
            if (base[fnName](data)) {
              hasMatch = true;
            } else {
              isValid = false;
            }
            break;
        }
        if (hasMatch) {
          if (direction) {
            match[direction] = match[direction] || {};
            match[direction][name] = t[direction][name];
          } else {
            match[name] = t[name];
          }
        }
      }
      return isValid;
    }
    /**
     * ### Calculate transition priority.
     *
     * Based on:
     *
     * - rule "position" (index) give tens, hundreds, thousands, …
     * - from/to properties give units (0, 1 or 2)
     */;
    _proto._calculatePriority = function _calculatePriority(t, ruleName, ruleIndex) {
      var priority = 0;
      if (t[ruleName] || t.from && t.from[ruleName] || t.to && t.to[ruleName]) {
        priority += Math.pow(10, ruleIndex);
        if (t.from && t.from[ruleName]) {
          priority += 1;
        }
        if (t.to && t.to[ruleName]) {
          priority += 2;
        }
      }
      return priority;
    };
    _proto._addPriority = function _addPriority(t) {
      var _this3 = this;
      t.priority = 0;
      var priority = 0;
      this._rules.forEach(function (rule, i) {
        var name = rule.name;
        var index = i + 1;
        priority += _this3._calculatePriority(t, name, index);
      });
      t.priority = priority;
      return t;
    };
    return Store;
  }();

  function _catch$1(body, recover) {
    try {
      var result = body();
    } catch (e) {
      return recover(e);
    }
    if (result && result.then) {
      return result.then(void 0, recover);
    }
    return result;
  }
  var Transitions = /*#__PURE__*/function () {
    function Transitions(transitions) {
      if (transitions === void 0) {
        transitions = [];
      }
      this.logger = new Logger('@barba/core');
      this.store = void 0;
      this._running = false;
      this.store = new Store(transitions);
    }
    /**
     * Get resolved transition
     *
     * - based on data
     */
    var _proto = Transitions.prototype;
    _proto.get = function get(data, filters) {
      return this.store.resolve(data, filters);
    }
    /**
     * Animation running status.
     */;
    /**
     * ### Do "once" transition.
     *
     * Hooks: see [[HooksOnce]].
     */
    _proto.doOnce = function doOnce(_ref) {
      var data = _ref.data,
        transition = _ref.transition;
      try {
        var _temp2 = function _temp2() {
          _this._running = false;
        };
        var _this = this;
        var t = transition || {};
        _this._running = true;
        var _temp = _catch$1(function () {
          return Promise.resolve(_this._doAsyncHook('beforeOnce', data, t)).then(function () {
            return Promise.resolve(_this.once(data, t)).then(function () {
              return Promise.resolve(_this._doAsyncHook('afterOnce', data, t)).then(function () {});
            });
          });
        }, function (error) {
          _this._running = false;
          _this.logger.debug('Transition error [before/after/once]');
          _this.logger.error(error);
        });
        return Promise.resolve(_temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp));
      } catch (e) {
        return Promise.reject(e);
      }
    }
    /**
     * ### Do "page" transition.
     *
     * Hooks: see [[HooksPage]].
     *
     * `sync: false` (default) order:
     *
     * 1. before
     * 2. beforeLeave
     * 3. leave
     * 4. afterLeave
     * 5. beforeEnter
     * 6. enter
     * 7. afterEnter
     * 8. after
     *
     * `sync: true` order:
     *
     * 1. before
     * 2. beforeLeave
     * 3. beforeEnter
     * 4. leave & enter
     * 5. afterLeave
     * 6. afterEnter
     * 7. after
     */
    ;
    _proto.doPage = function doPage(_ref2) {
      var data = _ref2.data,
        transition = _ref2.transition,
        page = _ref2.page,
        wrapper = _ref2.wrapper;
      try {
        var _temp1 = function _temp1(_result5) {
          if (_exit) return _result5;
          _this2._running = false;
        };
        var _exit;
        var _this2 = this;
        var t = transition || {};
        var sync = t.sync === true || false;
        _this2._running = true;
        var _temp0 = _catch$1(function () {
          function _temp9() {
            return Promise.resolve(_this2._doAsyncHook('before', data, t)).then(function () {
              var _exit2;
              function _temp7(_result2) {
                return _exit2 ? _result2 : Promise.resolve(_this2.remove(data)).then(function () {
                  return Promise.resolve(_this2._doAsyncHook('after', data, t)).then(function () {});
                });
              }
              var _temp6 = function () {
                if (sync) {
                  return _catch$1(function () {
                    return Promise.resolve(_this2.add(data, wrapper)).then(function () {
                      // Before actions
                      return Promise.resolve(_this2._doAsyncHook('beforeLeave', data, t)).then(function () {
                        return Promise.resolve(_this2._doAsyncHook('beforeEnter', data, t)).then(function () {
                          // Actions
                          // After actions
                          return Promise.resolve(Promise.all([_this2.leave(data, t), _this2.enter(data, t)])).then(function () {
                            return Promise.resolve(_this2._doAsyncHook('afterLeave', data, t)).then(function () {
                              return Promise.resolve(_this2._doAsyncHook('afterEnter', data, t)).then(function () {});
                            });
                          });
                        });
                      });
                    });
                  }, function (error) {
                    if (_this2._isTransitionError(error)) {
                      throw new BarbaError(error, 'Transition error [sync]');
                    }
                  });
                } else {
                  var _temp5 = function _temp5(_result3) {
                    return _exit2 ? _result3 : _catch$1(function () {
                      var _temp3 = function () {
                        if (leaveResult !== false) {
                          return Promise.resolve(_this2.add(data, wrapper)).then(function () {
                            return Promise.resolve(_this2._doAsyncHook('beforeEnter', data, t)).then(function () {
                              return Promise.resolve(_this2.enter(data, t, leaveResult)).then(function () {
                                return Promise.resolve(_this2._doAsyncHook('afterEnter', data, t)).then(function () {});
                              });
                            });
                          });
                        }
                      }();
                      if (_temp3 && _temp3.then) return _temp3.then(function () {});
                    }, function (error) {
                      if (_this2._isTransitionError(error)) {
                        throw new BarbaError(error, 'Transition error [before/after/enter]');
                      }
                    });
                  };
                  var leaveResult = false;
                  var _temp4 = _catch$1(function () {
                    // Leave
                    return Promise.resolve(_this2._doAsyncHook('beforeLeave', data, t)).then(function () {
                      return Promise.resolve(Promise.all([_this2.leave(data, t), update(page, data)]).then(function (values) {
                        return values[0];
                      })).then(function (_Promise$all$then) {
                        leaveResult = _Promise$all$then;
                        return Promise.resolve(_this2._doAsyncHook('afterLeave', data, t)).then(function () {}); // TODO: check here "valid" page result
                        // before going further
                      });
                    });
                  }, function (error) {
                    if (_this2._isTransitionError(error)) {
                      throw new BarbaError(error, 'Transition error [before/after/leave]');
                    }
                  });
                  return _temp4 && _temp4.then ? _temp4.then(_temp5) : _temp5(_temp4);
                }
              }();
              return _temp6 && _temp6.then ? _temp6.then(_temp7) : _temp7(_temp6); // Remove current container
            });
          }
          var _temp8 = function () {
            if (sync) {
              return Promise.resolve(update(page, data)).then(function () {});
            }
          }();
          // Check sync mode, wait for next content
          return _temp8 && _temp8.then ? _temp8.then(_temp9) : _temp9(_temp8);
        }, function (error) {
          _this2._running = false;
          // If "custom/specific" barba error.
          /* istanbul ignore else */
          if (error.name && error.name === 'BarbaError') {
            _this2.logger.debug(error.label);
            _this2.logger.error(error.error);
            throw error;
          }
          _this2.logger.debug('Transition error [page]');
          _this2.logger.error(error);
          throw error;
        });
        return Promise.resolve(_temp0 && _temp0.then ? _temp0.then(_temp1) : _temp1(_temp0));
      } catch (e) {
        return Promise.reject(e);
      }
    }
    /**
     * Once hook + async "once" transition.
     */
    ;
    _proto.once = function once(data, t) {
      try {
        return Promise.resolve(hooks["do"]('once', data, t)).then(function () {
          return t.once ? runAsync(t.once, t)(data) : Promise.resolve();
        });
      } catch (e) {
        return Promise.reject(e);
      }
    }
    /**
     * Leave hook + async "leave" transition.
     */
    ;
    _proto.leave = function leave(data, t) {
      try {
        return Promise.resolve(hooks["do"]('leave', data, t)).then(function () {
          return t.leave ? runAsync(t.leave, t)(data) : Promise.resolve();
        });
      } catch (e) {
        return Promise.reject(e);
      }
    }
    /**
     * Enter hook + async "enter" transition.
     */
    ;
    _proto.enter = function enter(data, t, leaveResult) {
      try {
        return Promise.resolve(hooks["do"]('enter', data, t)).then(function () {
          return t.enter ? runAsync(t.enter, t)(data, leaveResult) : Promise.resolve();
        });
      } catch (e) {
        return Promise.reject(e);
      }
    }
    /**
     * Add next container.
     */
    ;
    _proto.add = function add(data, wrapper) {
      try {
        dom.addContainer(data.next.container, wrapper);
        hooks["do"]('nextAdded', data);
        return Promise.resolve();
      } catch (e) {
        return Promise.reject(e);
      }
    }
    /**
     * Remove current container.
     */
    ;
    _proto.remove = function remove(data) {
      try {
        dom.removeContainer(data.current.container);
        hooks["do"]('currentRemoved', data);
        return Promise.resolve();
      } catch (e) {
        return Promise.reject(e);
      }
    };
    _proto._isTransitionError = function _isTransitionError(error) {
      if (error.message) {
        // Errors from request
        return !/Timeout error|Fetch error/.test(error.message);
      }
      if (error.status) {
        // Errors from request
        return false;
      }
      return true;
    }
    /**
     * Do hooks + async transition methods.
     */;
    _proto._doAsyncHook = function _doAsyncHook(hook, data, t) {
      try {
        return Promise.resolve(hooks["do"](hook, data, t)).then(function () {
          return t[hook] ? runAsync(t[hook], t)(data) : Promise.resolve();
        });
      } catch (e) {
        return Promise.reject(e);
      }
    };
    _createClass(Transitions, [{
      key: "isRunning",
      get: function get() {
        return this._running;
      },
      set: function set(status) {
        this._running = status;
      }
      /**
       * Check for registered once transition(s).
       */
    }, {
      key: "hasOnce",
      get: function get() {
        return this.store.once.length > 0;
      }
      /**
       * Check for registered self transition.
       */
    }, {
      key: "hasSelf",
      get: function get() {
        return this.store.all.some(function (t) {
          return t.name === 'self';
        });
      }
      /**
       * ### Wait indicator.
       *
       * Tells Barba to get next page data<br>
       * before starting the resolution<br>
       * because some registered transitions need<br>
       * next page data to be resolved (eg: `sync: true`, `to: { namespace }`, …)
       */
    }, {
      key: "shouldWait",
      get: function get() {
        return this.store.all.some(function (t) {
          return t.to && !t.to.route || t.sync;
        });
      }
    }]);
    return Transitions;
  }();

  /**
   * @barba/core/modules/views
   * <br><br>
   * ## Views manager.
   *
   * @module core/modules/views
   * @preferred
   */
  var Views = /*#__PURE__*/function () {
    /**
     * Available hook names for views.
     */

    /**
     * Registered views by namespace.
     */

    /**
     * Init views.
     */
    function Views(views) {
      var _this = this;
      this.names = ['beforeLeave', 'afterLeave', 'beforeEnter', 'afterEnter'];
      this.byNamespace = new Map();
      if (views.length === 0) {
        return;
      }
      // TODO: add check
      // for valid views? criteria? (namespace property, string ?)
      // or duplicate
      views.forEach(function (view) {
        _this.byNamespace.set(view.namespace, view);
      });
      this.names.forEach(function (name) {
        hooks[name](_this._createHook(name));
      });
    }
    /**
     * Create the hook method.
     *
     * - get view based on namespace
     * - execute callback with transition data
     */
    var _proto = Views.prototype;
    _proto._createHook = function _createHook(name) {
      var _this2 = this;
      return function (data) {
        var _ref = name.match(/enter/i) ? data.next : data.current,
          namespace = _ref.namespace;
        var view = _this2.byNamespace.get(namespace);
        // TODO: manage self…
        // if (view && data.trigger !== 'self') {
        if (view && view[name]) {
          return runAsync(view[name], view)(data);
        }
        return Promise.resolve();
      };
    };
    return Views;
  }();

  // Element.prototype.matches polyfill
  // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill
  if (!Element.prototype.matches) {
    Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
  }
  // Element.prototype.closest polyfill
  // https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
  if (!Element.prototype.closest) {
    Element.prototype.closest = function closest(s) {
      var el = this;
      do {
        if (el.matches(s)) {
          return el;
        }
        el = el.parentElement || el.parentNode;
      } while (el !== null && el.nodeType === 1);
      return null;
    };
  }

  /**
   * @module core/schemas
   */
  /**
   * See [[ISchemaPage]]
   */
  var schemaPage = {
    container: null,
    html: '',
    namespace: '',
    url: {
      hash: '',
      href: '',
      path: '',
      port: null,
      query: {}
    }
  };

  function _catch(body, recover) {
    try {
      var result = body();
    } catch (e) {
      return recover(e);
    }
    if (result && result.then) {
      return result.then(void 0, recover);
    }
    return result;
  }
  var Core = /*#__PURE__*/function () {
    function Core() {
      this.version = version;
      this.schemaPage = schemaPage;
      this.Logger = Logger;
      this.logger = new Logger('@barba/core');
      this.plugins = [];
      this.timeout = void 0;
      this.cacheIgnore = void 0;
      this.cacheFirstPage = void 0;
      this.prefetchIgnore = void 0;
      this.preventRunning = void 0;
      this.hooks = hooks;
      this.cache = void 0;
      this.headers = void 0;
      this.prevent = void 0;
      this.transitions = void 0;
      this.views = void 0;
      this.dom = dom;
      this.helpers = helpers;
      this.history = history;
      this.request = request;
      this.url = url;
      this._data = void 0;
      this._requestCustomError = void 0;
      this._wrapper = void 0;
      this._linkEvent = void 0;
    }
    /**
     * Version.
     */
    /**
     * Schemas.
     */
    /**
     * Logger class, allows plugins to create Logger.
     */
    /**
     * Barba logger.
     */
    /**
     * Plugins.
     */
    /**
     * Options
     */
    /**
     * Hooks
     */
    /**
     * Modules.
     */
    // public history: History;
    /**
     * Utils.
     */
    var _proto = Core.prototype;
    /**
     * ### Init plugin with options.
     *
     * See [[IBarbaPlugin]] for more details.
     */
    _proto.use = function use(plugin, options) {
      var installedPlugins = this.plugins;
      // Plugin installation
      if (installedPlugins.indexOf(plugin) > -1) {
        this.logger.warn("Plugin [" + plugin.name + "] already installed.");
        return;
      }
      if (typeof plugin.install !== 'function') {
        this.logger.warn("Plugin [" + plugin.name + "] has no \"install\" method.");
        return;
      }
      plugin.install(this, options);
      installedPlugins.push(plugin);
    }
    /**
     * ### Init barba with options.
     *
     * See [[IBarbaOptions]] for more details.
     *
     * Default values are:
     *
     * - transitions: `[]`
     * - views: `[]`
     * - schema: [[SchemaAttribute]]
     * - timeout: `2e3`
     * - cacheIgnore: `false`
     * - cacheFirstPage: `false`
     * - prefetchIgnore: `false`
     * - preventRunning: `false`
     * - prevent: `null`,
     * - debug: `false`
     * - logLevel: `'off'`
     */;
    _proto.init = function init(/** @ignore */_temp) {
      var _ref = _temp === void 0 ? {} : _temp,
        _ref$transitions = _ref.transitions,
        transitions = _ref$transitions === void 0 ? [] : _ref$transitions,
        _ref$views = _ref.views,
        views = _ref$views === void 0 ? [] : _ref$views,
        _ref$schema = _ref.schema,
        schema = _ref$schema === void 0 ? schemaAttribute : _ref$schema,
        requestError = _ref.requestError,
        _ref$timeout = _ref.timeout,
        timeout = _ref$timeout === void 0 ? 2e3 : _ref$timeout,
        _ref$cacheIgnore = _ref.cacheIgnore,
        cacheIgnore = _ref$cacheIgnore === void 0 ? false : _ref$cacheIgnore,
        _ref$cacheFirstPage = _ref.cacheFirstPage,
        cacheFirstPage = _ref$cacheFirstPage === void 0 ? false : _ref$cacheFirstPage,
        _ref$prefetchIgnore = _ref.prefetchIgnore,
        prefetchIgnore = _ref$prefetchIgnore === void 0 ? false : _ref$prefetchIgnore,
        _ref$preventRunning = _ref.preventRunning,
        preventRunning = _ref$preventRunning === void 0 ? false : _ref$preventRunning,
        _ref$prevent = _ref.prevent,
        preventCustom = _ref$prevent === void 0 ? null : _ref$prevent,
        _ref$debug = _ref.debug,
        debug = _ref$debug === void 0 ? false : _ref$debug,
        _ref$logLevel = _ref.logLevel,
        logLevel = _ref$logLevel === void 0 ? 'off' : _ref$logLevel;
      // 0. Set logger level and print version
      Logger.setLevel(debug === true ? 'debug' : logLevel);
      this.logger.info(this.version);
      // 1. Manage options
      Object.keys(schema).forEach(function (k) {
        var attr = k;
        /* istanbul ignore else */
        if (schemaAttribute[attr]) {
          schemaAttribute[attr] = schema[attr];
        }
      });
      this._requestCustomError = requestError;
      this.timeout = timeout;
      this.cacheIgnore = cacheIgnore;
      this.cacheFirstPage = cacheFirstPage;
      this.prefetchIgnore = prefetchIgnore;
      this.preventRunning = preventRunning;
      // 2. Get and check wrapper
      this._wrapper = this.dom.getWrapper();
      if (!this._wrapper) {
        throw new Error('[@barba/core] No Barba wrapper found');
      }
      // 3. Init pages (get "current" data)
      this._resetData();
      var current = this.data.current;
      if (!current.container) {
        throw new Error('[@barba/core] No Barba container found');
      }
      // 4. Init other modules
      this.cache = new Cache(cacheIgnore);
      this.headers = new Headers();
      this.prevent = new Prevent(prefetchIgnore);
      this.transitions = new Transitions(transitions);
      this.views = new Views(views);
      // Add prevent custom
      if (preventCustom !== null) {
        if (typeof preventCustom !== 'function') {
          throw new Error('[@barba/core] Prevent should be a function');
        }
        this.prevent.add('preventCustom', preventCustom);
      }
      // 5. Init history
      this.history.init(current.url.href, current.namespace);
      // 6. Add to cache
      if (cacheFirstPage) {
        this.cache.set(current.url.href, Promise.resolve({
          html: current.html,
          url: current.url
        }), 'init', 'fulfilled');
      }
      // 7. Bind context
      this._onLinkEnter = this._onLinkEnter.bind(this);
      this._onLinkClick = this._onLinkClick.bind(this);
      this._onStateChange = this._onStateChange.bind(this);
      this._bind();
      // 8. Init plugins
      this.plugins.forEach(function (plugin) {
        return plugin.init();
      });
      // 9. Barba ready
      // Set next + trigger for once and `beforeEnter`/`afterEnter` view on page load.
      var onceData = this.data;
      onceData.trigger = 'barba';
      onceData.next = onceData.current;
      onceData.current = _extends({}, this.schemaPage);
      this.hooks["do"]('ready', onceData);
      // 9. Finally, do once…
      this.once(onceData);
      // Clean data for first barba transition…
      this._resetData();
    };
    _proto.destroy = function destroy() {
      this._resetData();
      this._unbind();
      this.history.clear();
      this.hooks.clear();
      this.plugins = [];
    };
    /**
     * ### Force a page change without Barba transition.
     */
    _proto.force = function force(href) {
      // DEV
      // Can be used waiting animation cancellation management…
      window.location.assign(href);
    }
    /**
     * ### Go for a Barba transition.
     *
     * Manage "self page" href:
     *
     * - if same url and no self transition, keep default behavior
     *   - link: reload the page
     *   - anchor: scroll to
     * - if same url with self transition, use it
     * - then start a page transition.
     */;
    _proto.go = function go(href, trigger, e) {
      if (trigger === void 0) {
        trigger = 'barba';
      }
      this._linkEvent = null;
      // If animation running, force reload
      if (this.transitions.isRunning) {
        this.force(href);
        return;
      }
      var self = false;
      // Check prevent sameURL against current history
      // + state check
      // + update trigger with direction
      if (trigger === 'popstate') {
        self = this.history.current && this.url.getPath(this.history.current.url) === this.url.getPath(href) && this.url.getQuery(this.history.current.url, true) === this.url.getQuery(href, true);
      } else {
        self = this.prevent.run('sameUrl', null, null, href);
      }
      if (self && !this.transitions.hasSelf) {
        return;
      }
      trigger = this.history.change(this.cache.has(href) ? this.cache.get(href).target : href, trigger, e);
      if (e) {
        e.stopPropagation();
        e.preventDefault();
      }
      return this.page(href, trigger, e != null ? e : undefined, self);
    }
    /**
     * ### Start an "once" transition.
     *
     * If some registered "once" transition,
     * get the "resolved" transition from the store and start it.
     */;
    _proto.once = function once(readyData) {
      try {
        var _this = this;
        return Promise.resolve(_this.hooks["do"]('beforeEnter', readyData)).then(function () {
          function _temp3() {
            return Promise.resolve(_this.hooks["do"]('afterEnter', readyData)).then(function () {});
          }
          var _temp2 = function () {
            if (_this.transitions.hasOnce) {
              var transition = _this.transitions.get(readyData, {
                once: true
              });
              return Promise.resolve(_this.transitions.doOnce({
                transition: transition,
                data: readyData
              })).then(function () {});
            }
          }();
          // Check if once transition
          return _temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2);
        });
      } catch (e) {
        return Promise.reject(e);
      }
    }
    /**
     * ### Start a "page" transition.
     *
     * 1. If no running transition, updates data with full URL properties and trigger.
     * 2. Get page from cache or init request.
     * 3. Wait if some transitions need "next" data (`sync: true`, `to: …`).
     * 4. Manage the history, depending on trigger.
     * 5. Get "data" and trigger "go" hook.
     * 6. Get the "resolved" transition from the store and start it.
     * 7. Update title and reset data (current, next = undefined).
     *
     * > If "self", use the "self" transition
     */
    ;
    _proto.page = function page(href, trigger, event, self) {
      try {
        var _temp6 = function _temp6() {
          var data = _this2.data;
          // Hook: between trigger and transition
          // Can be used to resolve "route"…
          return Promise.resolve(_this2.hooks["do"]('page', data)).then(function () {
            var _temp4 = _catch(function () {
              var transition = _this2.transitions.get(data, {
                once: false,
                self: self
              });
              return Promise.resolve(_this2.transitions.doPage({
                data: data,
                page: page,
                transition: transition,
                wrapper: _this2._wrapper
              })).then(function () {
                _this2._resetData();
              });
            }, function () {
              if (Logger.getLevel() === 0) {
                _this2.force(data.next.url.href);
              }
            });
            if (_temp4 && _temp4.then) return _temp4.then(function () {});
          });
        };
        var _this2 = this;
        _this2.data.next.url = _extends({
          href: href
        }, _this2.url.parse(href));
        _this2.data.trigger = trigger;
        _this2.data.event = event;
        var page;
        if (_this2.cache.has(href)) {
          page = _this2.cache.update(href, {
            action: 'click'
          }).request;
        } else {
          var pageRequest = _this2.request(href, _this2.timeout, _this2.onRequestError.bind(_this2, trigger), _this2.cache, _this2.headers);
          // manage 301 server response: replace history
          pageRequest.then(function (response) {
            /* istanbul ignore next: bypass jest since xhr-mock doesn't support custom xhr.responseURL */
            if (response.url.href !== href) {
              _this2.history.add(response.url.href, trigger, 'replace');
            }
          });
          page = _this2.cache.set(href, pageRequest, 'click', 'pending').request;
        }
        // Need to wait before getting the right transition
        var _temp5 = function () {
          if (_this2.transitions.shouldWait) {
            return Promise.resolve(update(page, _this2.data)).then(function () {});
          }
        }();
        return Promise.resolve(_temp5 && _temp5.then ? _temp5.then(_temp6) : _temp6(_temp5));
      } catch (e) {
        return Promise.reject(e);
      }
    }
    /**
     * When a request error occurs.
     *
     * Allow the user to manage request error. (E.g: 404)
     */
    ;
    _proto.onRequestError = function onRequestError(trigger) {
      // Cancel transition status
      this.transitions.isRunning = false;
      var _slice$call = [].slice.call(arguments, 1),
        href = _slice$call[0],
        response = _slice$call[1];
      var action = this.cache.getAction(href);
      this.cache["delete"](href);
      // Custom requestError returning false will return here.
      if (this._requestCustomError && this._requestCustomError(trigger, action, href, response) === false) {
        return false;
      }
      // Force page change
      if (action === 'click') {
        this.force(href);
      }
      return false;
    }
    /**
     * Programmatically prefetch
     */;
    _proto.prefetch = function prefetch(href) {
      var _this3 = this;
      // only prefetch absolute href
      href = this.url.getAbsoluteHref(href);
      // Already in cache
      /* istanbul ignore next */
      if (this.cache.has(href)) {
        return;
      }
      this.cache.set(href, this.request(href, this.timeout, this.onRequestError.bind(this, 'barba'), this.cache, this.headers)["catch"](function (error) {
        _this3.logger.error(error);
      }), 'prefetch', 'pending');
    }
    /**
     * Bind event listeners.
     */;
    _proto._bind = function _bind() {
      /* istanbul ignore else */
      if (this.prefetchIgnore !== true) {
        document.addEventListener('mouseover', this._onLinkEnter);
        document.addEventListener('touchstart', this._onLinkEnter);
      }
      document.addEventListener('click', this._onLinkClick);
      window.addEventListener('popstate', this._onStateChange);
    }
    /**
     * Bind event listeners.
     */;
    _proto._unbind = function _unbind() {
      /* istanbul ignore else */
      if (this.prefetchIgnore !== true) {
        document.removeEventListener('mouseover', this._onLinkEnter);
        document.removeEventListener('touchstart', this._onLinkEnter);
      }
      document.removeEventListener('click', this._onLinkClick);
      window.removeEventListener('popstate', this._onStateChange);
    }
    /**
     * When a element is entered.
     *
     * Get valid link element.
     * Cache URL if needed.
     */;
    _proto._onLinkEnter = function _onLinkEnter(e) {
      var _this4 = this;
      var link = this._getLinkElement(e);
      if (!link) {
        return;
      }
      var href = this.url.getAbsoluteHref(this.dom.getHref(link));
      if (this.prevent.checkHref(href)) {
        return;
      }
      // Already in cache
      if (this.cache.has(href)) {
        return;
      }
      this.cache.set(href, this.request(href, this.timeout, this.onRequestError.bind(this, link), this.cache, this.headers)["catch"](function (error) {
        _this4.logger.error(error);
      }), 'enter', 'pending');
    }
    /**
     * When an element is clicked.
     *
     * Get valid link element.
     * Prevent same URL.
     * Go for a Barba transition.
     */;
    _proto._onLinkClick = function _onLinkClick(e) {
      // This use `prevent.checkLink` under the hood to get eligible link.
      var link = this._getLinkElement(e);
      if (!link) {
        return;
      }
      if (this.transitions.isRunning && this.preventRunning) {
        e.preventDefault();
        e.stopPropagation();
        return;
      }
      this._linkEvent = e;
      this.go(this.dom.getHref(link), link, e);
    }
    /**
     * When History state changes.
     *
     * Get "href" from URL
     * Go for a Barba transition.
     */;
    _proto._onStateChange = function _onStateChange(e) {
      this.go(this.url.getHref(), 'popstate', e);
    }
    /**
     * Get a valid link ancestor.
     *
     * Check for a "href" attribute.
     * Then check if eligible for Barba.
     */;
    _proto._getLinkElement = function _getLinkElement(e) {
      var el = e.target;
      while (el && !this.dom.getHref(el)) {
        el = el.parentNode;
      }
      // Check prevent
      if (!el || this.prevent.checkLink(el, e, this.dom.getHref(el))) {
        return;
      }
      return el;
    }
    /**
     * Reset pages data.
     *
     * Set "current" and unset "next".
     */;
    _proto._resetData = function _resetData() {
      var href = this.url.getHref();
      var current = {
        container: this.dom.getContainer(),
        html: this.dom.getHtml(),
        namespace: this.dom.getNamespace(),
        url: _extends({
          href: href
        }, this.url.parse(href))
      };
      this._data = {
        current: current,
        event: undefined,
        next: _extends({}, this.schemaPage),
        trigger: undefined
      };
      this.hooks["do"]('reset', this.data);
    };
    _createClass(Core, [{
      key: "data",
      get: function get() {
        return this._data;
      }
    }, {
      key: "wrapper",
      get: function get() {
        return this._wrapper;
      }
    }]);
    return Core;
  }();
  var core = new Core();

  return core;

}));

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

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