swup
Version:
Complete, flexible, extensible and easy to use page transition library for your web.
291 lines (232 loc) • 9.2 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
// modules
var _delegate = require('delegate');
var _delegate2 = _interopRequireDefault(_delegate);
var _Cache = require('./modules/Cache');
var _Cache2 = _interopRequireDefault(_Cache);
var _loadPage = require('./modules/loadPage');
var _loadPage2 = _interopRequireDefault(_loadPage);
var _renderPage = require('./modules/renderPage');
var _renderPage2 = _interopRequireDefault(_renderPage);
var _triggerEvent = require('./modules/triggerEvent');
var _triggerEvent2 = _interopRequireDefault(_triggerEvent);
var _on = require('./modules/on');
var _on2 = _interopRequireDefault(_on);
var _off = require('./modules/off');
var _off2 = _interopRequireDefault(_off);
var _updateTransition = require('./modules/updateTransition');
var _updateTransition2 = _interopRequireDefault(_updateTransition);
var _getAnimationPromises = require('./modules/getAnimationPromises');
var _getAnimationPromises2 = _interopRequireDefault(_getAnimationPromises);
var _getPageData = require('./modules/getPageData');
var _getPageData2 = _interopRequireDefault(_getPageData);
var _plugins = require('./modules/plugins');
var _utils = require('./utils');
var _helpers = require('./helpers');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Swup = function () {
function Swup(setOptions) {
_classCallCheck(this, Swup);
// default options
var defaults = {
animateHistoryBrowsing: false,
animationSelector: '[class*="transition-"]',
linkSelector: 'a[href^="' + window.location.origin + '"]:not([data-no-swup]), a[href^="/"]:not([data-no-swup]), a[href^="#"]:not([data-no-swup])',
cache: true,
containers: ['#swup'],
requestHeaders: {
'X-Requested-With': 'swup',
Accept: 'text/html, application/xhtml+xml'
},
plugins: [],
skipPopStateHandling: function skipPopStateHandling(event) {
return !(event.state && event.state.source === 'swup');
}
};
// merge options
var options = _extends({}, defaults, setOptions);
// handler arrays
this._handlers = {
animationInDone: [],
animationInStart: [],
animationOutDone: [],
animationOutStart: [],
animationSkipped: [],
clickLink: [],
contentReplaced: [],
disabled: [],
enabled: [],
openPageInNewTab: [],
pageLoaded: [],
pageRetrievedFromCache: [],
pageView: [],
popState: [],
samePage: [],
samePageWithHash: [],
serverError: [],
transitionStart: [],
transitionEnd: [],
willReplaceContent: []
};
// variable for id of element to scroll to after render
this.scrollToElement = null;
// variable for promise used for preload, so no new loading of the same page starts while page is loading
this.preloadPromise = null;
// variable for save options
this.options = options;
// variable for plugins array
this.plugins = [];
// variable for current transition object
this.transition = {};
// variable for keeping event listeners from "delegate"
this.delegatedListeners = {};
// make modules accessible in instance
this.cache = new _Cache2.default();
this.cache.swup = this;
this.loadPage = _loadPage2.default;
this.renderPage = _renderPage2.default;
this.triggerEvent = _triggerEvent2.default;
this.on = _on2.default;
this.off = _off2.default;
this.updateTransition = _updateTransition2.default;
this.getAnimationPromises = _getAnimationPromises2.default;
this.getPageData = _getPageData2.default;
this.log = function () {}; // here so it can be used by plugins
this.use = _plugins.use;
this.unuse = _plugins.unuse;
this.findPlugin = _plugins.findPlugin;
// enable swup
this.enable();
}
_createClass(Swup, [{
key: 'enable',
value: function enable() {
var _this = this;
// check for Promise support
if (typeof Promise === 'undefined') {
console.warn('Promise is not supported');
return;
}
// add event listeners
this.delegatedListeners.click = (0, _delegate2.default)(document, this.options.linkSelector, 'click', this.linkClickHandler.bind(this));
window.addEventListener('popstate', this.popStateHandler.bind(this));
// initial save to cache
var page = (0, _helpers.getDataFromHtml)(document.documentElement.outerHTML, this.options.containers);
page.url = page.responseURL = (0, _helpers.getCurrentUrl)();
if (this.options.cache) {
this.cache.cacheUrl(page);
}
// mark swup blocks in html
(0, _helpers.markSwupElements)(document.documentElement, this.options.containers);
// mount plugins
this.options.plugins.forEach(function (plugin) {
_this.use(plugin);
});
// modify initial history record
window.history.replaceState(Object.assign({}, window.history.state, {
url: window.location.href,
random: Math.random(),
source: 'swup'
}), document.title, window.location.href);
// trigger enabled event
this.triggerEvent('enabled');
// add swup-enabled class to html tag
document.documentElement.classList.add('swup-enabled');
// trigger page view event
this.triggerEvent('pageView');
}
}, {
key: 'destroy',
value: function destroy() {
var _this2 = this;
// remove delegated listeners
this.delegatedListeners.click.destroy();
this.delegatedListeners.mouseover.destroy();
// remove popstate listener
window.removeEventListener('popstate', this.popStateHandler.bind(this));
// empty cache
this.cache.empty();
// unmount plugins
this.options.plugins.forEach(function (plugin) {
_this2.unuse(plugin);
});
// remove swup data atributes from blocks
(0, _utils.queryAll)('[data-swup]').forEach(function (element) {
element.removeAttribute('data-swup');
});
// remove handlers
this.off();
// trigger disable event
this.triggerEvent('disabled');
// remove swup-enabled class from html tag
document.documentElement.classList.remove('swup-enabled');
}
}, {
key: 'linkClickHandler',
value: function linkClickHandler(event) {
// no control key pressed
if (!event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey) {
// index of pressed button needs to be checked because Firefox triggers click on all mouse buttons
if (event.button === 0) {
this.triggerEvent('clickLink', event);
event.preventDefault();
var link = new _helpers.Link(event.delegateTarget);
if (link.getAddress() == (0, _helpers.getCurrentUrl)() || link.getAddress() == '') {
// link to the same URL
if (link.getHash() != '') {
// link to the same URL with hash
this.triggerEvent('samePageWithHash', event);
var element = document.querySelector(link.getHash());
if (element != null) {
history.replaceState({
url: link.getAddress() + link.getHash(),
random: Math.random(),
source: 'swup'
}, document.title, link.getAddress() + link.getHash());
} else {
// referenced element not found
console.warn('Element for offset not found (' + link.getHash() + ')');
}
} else {
// link to the same URL without hash
this.triggerEvent('samePage', event);
}
} else {
// link to different url
if (link.getHash() != '') {
this.scrollToElement = link.getHash();
}
// get custom transition from data
var customTransition = event.delegateTarget.getAttribute('data-swup-transition');
// load page
this.loadPage({ url: link.getAddress(), customTransition: customTransition }, false);
}
}
} else {
// open in new tab (do nothing)
this.triggerEvent('openPageInNewTab', event);
}
}
}, {
key: 'popStateHandler',
value: function popStateHandler(event) {
if (this.options.skipPopStateHandling(event)) return;
var link = new _helpers.Link(event.state ? event.state.url : window.location.pathname);
if (link.getHash() !== '') {
this.scrollToElement = link.getHash();
} else {
event.preventDefault();
}
this.triggerEvent('popState', event);
this.loadPage({ url: link.getAddress() }, event);
}
}]);
return Swup;
}();
exports.default = Swup;