swup
Version:
Animated page transitions with css.
102 lines (89 loc) • 3.53 kB
JavaScript
var forEach = Array.prototype.forEach;
module.exports = function (data, popstate) {
var _this = this;
var finalPage = null;
// scrolling
if (this.options.doScrollingRightAway && !this.scrollToElement) {
this.doScrolling(popstate);
}
var animationPromises = [];
if (!popstate) {
// start animation
document.documentElement.classList.add('is-changing');
document.documentElement.classList.add('is-leaving');
document.documentElement.classList.add('is-animating');
document.documentElement.classList.add('to-' + this.classify(data.url));
// detect animation end
var animatedElements = document.querySelectorAll(this.options.animationSelector);
forEach.call(animatedElements, function (element) {
var promise = new Promise(function (resolve) {
element.addEventListener(_this.transitionEndEvent, function (event) {
if (element == event.target) {
resolve();
}
});
});
animationPromises.push(promise);
});
Promise.all(animationPromises).then(function () {
_this.triggerEvent('animationOutDone');
});
// create pop element with or without anchor
if (this.scrollToElement != null) {
var pop = data.url + this.scrollToElement;
} else {
var pop = data.url;
}
this.createState(pop);
} else {
// proceed without animating
this.triggerEvent('animationSkipped');
}
if (this.cache.exists(data.url)) {
var xhrPromise = new Promise(function (resolve) {
resolve();
});
this.triggerEvent('pageRetrievedFromCache');
} else {
if (!this.preloadPromise || this.preloadPromise.route != data.url) {
var xhrPromise = new Promise(function (resolve, reject) {
_this.getPage(data, function (response, request) {
if (request.status === 500) {
_this.triggerEvent('serverError');
reject(data.url);
return;
} else {
// get json data
var page = _this.getDataFromHtml(response);
if (page != null) {
page.url = data.url;
} else {
reject(data.url);
return;
}
// render page
_this.cache.cacheUrl(page, _this.options.debugMode);
_this.triggerEvent('pageLoaded');
}
resolve();
});
});
} else {
var xhrPromise = this.preloadPromise;
}
}
Promise.all(animationPromises.concat([xhrPromise])).then(function () {
finalPage = _this.cache.getPage(data.url);
_this.renderPage(finalPage, popstate);
_this.preloadPromise = null;
}).catch(function (errorUrl) {
// rewrite the skipPopStateHandling function to redirect manually when the history.go is processed
_this.options.skipPopStateHandling = function () {
window.location = errorUrl;
return true;
};
// go back to the actual page were still at
window.history.go(-1);
});
};
;