├── .npmignore
├── entry.js
├── src
├── modules
│ ├── createAnimationPromise.js
│ ├── getAnimation.js
│ ├── renderPage.js
│ └── loadPage.js
└── index.js
├── .gitignore
├── .github
├── workflows
│ └── npm-publish.yml
└── ISSUE_TEMPLATE
│ └── issue-template.md
├── package.json
├── webpack.config.js
├── LICENSE
├── readme.md
└── dist
├── swupjs.min.js
└── swupjs.js
/.npmignore:
--------------------------------------------------------------------------------
1 | src/
2 | entry.js
3 | webpack.config.js
4 | .idea
5 | .github
6 |
--------------------------------------------------------------------------------
/entry.js:
--------------------------------------------------------------------------------
1 | // this is here for webpack to expose Swupjs as window.Swupjs
2 | import Swupjs from './src/index.js'
3 | module.exports = Swupjs
--------------------------------------------------------------------------------
/src/modules/createAnimationPromise.js:
--------------------------------------------------------------------------------
1 | module.exports = function (fn) {
2 | return new Promise(resolve => {
3 | fn(resolve)
4 | })
5 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.DS_Store
3 | !.gitignore
4 | !.htaccess
5 | !web.config
6 | node_modules
7 | bower_components
8 | Thumbs.db
9 | wiki-common
10 | wiki-images files
11 | wiki-wishlist
12 | *.sublime-project
13 | *.sublime-workspace
14 | .editorconfig
15 | .idea
16 | lib
--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow publishes a package to NPM
2 |
3 | name: Publish package
4 |
5 | on:
6 | release:
7 | types: [published]
8 |
9 | jobs:
10 | publish-npm:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v2
14 | - uses: actions/setup-node@v1
15 | with:
16 | node-version: 12
17 | registry-url: https://registry.npmjs.org/
18 | - run: npm ci
19 | - run: npm publish --access public
20 | env:
21 | NODE_AUTH_TOKEN: ${{secrets.npm_token}}
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/issue-template.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Issue template
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe your issue**:
11 | Describe your issue here...
12 |
13 | **Swup config or any additional relevant code used**:
14 |
15 | ```javascript
16 | const swup = Swup();
17 | ```
18 |
19 | **Before creating this issue, did you think of...**:
20 | - [ ] Have you checked closed issues for similar/related problems.
21 | - [ ] Have you provided all helpful information available?
22 | - [ ] Have you considered creating a demo so we can help you better?
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "swupjs",
3 | "version": "1.7.1",
4 | "description": "Complete, flexible, easy to use page transition library - swup extension.",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "compile": "babel --presets es2015,stage-0 -d lib/ src/",
9 | "build": "webpack-cli",
10 | "prepublish": "npm run compile"
11 | },
12 | "author": "Georgy Marchuk",
13 | "license": "MIT",
14 | "repository": {
15 | "type": "git",
16 | "url": "https://github.com/gmrchk/swupjs.git"
17 | },
18 | "keywords": [
19 | "js",
20 | "animation",
21 | "page",
22 | "transition"
23 | ],
24 | "devDependencies": {
25 | "babel-cli": "^6.26.0",
26 | "babel-loader": "^7.1.4",
27 | "babel-preset-es2015": "^6.24.1",
28 | "babel-preset-stage-0": "^6.24.1",
29 | "uglifyjs-webpack-plugin": "^1.2.5",
30 | "webpack": "^4.8.3",
31 | "webpack-cli": "^5.0.1"
32 | },
33 | "dependencies": {
34 | "swup": "^1.9.0"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
2 |
3 | module.exports = {
4 | mode: "production",
5 | entry: {
6 | "swupjs": "./entry.js",
7 | "swupjs.min": "./entry.js",
8 | },
9 | output: {
10 | library: "Swupjs",
11 | libraryTarget: "umd",
12 | filename: "[name].js",
13 | },
14 | module: {
15 | rules: [
16 | {
17 | test: /\.js$/,
18 | loader: 'babel-loader',
19 | exclude: /node_modules/,
20 | options: {
21 | presets: ['es2015', 'stage-0'],
22 | }
23 | }
24 | ]
25 | },
26 | optimization: {
27 | minimizer: [
28 | // we specify a custom UglifyJsPlugin here to get source maps in production
29 | new UglifyJsPlugin({
30 | uglifyOptions: {
31 | compress: false,
32 | ecma: 6,
33 | mangle: true
34 | },
35 | include: /\.min\.js$/
36 | })
37 | ]
38 | }
39 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Georgy Marchuk
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import Swup from 'swup'
2 |
3 | // modules
4 | import loadPage from './modules/loadPage'
5 | import renderPage from './modules/renderPage'
6 | import getAnimation from './modules/getAnimation'
7 | import createAnimationPromise from './modules/createAnimationPromise'
8 |
9 | export default class Swupjs extends Swup {
10 | constructor(setOptions) {
11 | let defaults = {
12 | animations: {
13 | '*': {
14 | out: function (next) {
15 | next()
16 | },
17 | in: function (next) {
18 | next()
19 | }
20 | }
21 | }
22 | }
23 |
24 | let options = {
25 | ...defaults,
26 | ...setOptions
27 | }
28 |
29 | super(options)
30 |
31 | this.animations = options.animations
32 | }
33 |
34 | /**
35 | * make modules accessible in instance
36 | */
37 | loadPage = loadPage
38 | renderPage = renderPage
39 | getAnimation = getAnimation
40 | createAnimationPromise = createAnimationPromise
41 | }
42 |
--------------------------------------------------------------------------------
/src/modules/getAnimation.js:
--------------------------------------------------------------------------------
1 | module.exports = function (transition, animations, type) {
2 |
3 | let animation = null
4 | let animationName = null
5 | let topRating = 0
6 |
7 | Object.keys(animations).forEach(item => {
8 | let rating = 0
9 | if (item.includes('>')) {
10 | let route = item.split('>')
11 | let from = route[0]
12 | let to = route[1]
13 |
14 | // TO equals to TO
15 | if (to == transition.to || to == "*") {
16 | rating++
17 | }
18 |
19 | // equals to CUSTOM animation
20 | if (to == transition.custom) {
21 | rating=rating+2
22 | }
23 |
24 | // FROM equals or is ANY
25 | if (from == transition.from || from == "*") {
26 | rating++
27 | }
28 | }
29 |
30 | // set new final animation
31 | if (rating > topRating) {
32 | topRating = rating
33 | animationName = item
34 | animation = animations[item]
35 | }
36 | })
37 |
38 | if (animation == null || topRating == 1) {
39 | animation = animations['*']
40 | animationName = '*'
41 | }
42 |
43 | return animation[type]
44 | }
--------------------------------------------------------------------------------
/src/modules/renderPage.js:
--------------------------------------------------------------------------------
1 | const { forEach } = Array.prototype;
2 | import Link from 'swup/lib/Link';
3 |
4 | module.exports = function (page, popstate) {
5 | document.documentElement.classList.remove('is-leaving')
6 |
7 | // replace state in case the url was redirected
8 | let link = new Link()
9 | link.setPath(page.responseURL)
10 |
11 | if (window.location.pathname !== link.getPath()) {
12 | window.history.replaceState({
13 | url: link.getPath(),
14 | random: Math.random(),
15 | source: "swup",
16 | },
17 | document.title,
18 | link.getPath(),
19 | );
20 | }
21 |
22 | if (!popstate || this.options.animateHistoryBrowsing) {
23 | document.documentElement.classList.add('is-rendering')
24 | }
25 |
26 | this.triggerEvent('willReplaceContent');
27 |
28 | // replace blocks
29 | for (var i = 0; i < page.blocks.length; i++) {
30 | document.body.querySelector(`[data-swup="${i}"]`).outerHTML = page.blocks[i]
31 | }
32 |
33 | // set title
34 | document.title = page.title;
35 |
36 | // handle classes after render
37 | // remove
38 | if (this.options.pageClassPrefix !== false) {
39 | document.body.className.split(' ').forEach(className => {
40 | // empty string for page class
41 | if (className != "" && className.includes(this.options.pageClassPrefix)) {
42 | document.body.classList.remove(className)
43 | }
44 | })
45 | }
46 |
47 | // add
48 | if (page.pageClass != "") {
49 | page.pageClass.split(' ').forEach(className => {
50 | if (className != "" && className.includes(this.options.pageClassPrefix)) {
51 | document.body.classList.add(className)
52 | }
53 | })
54 | }
55 |
56 | this.triggerEvent('contentReplaced')
57 | this.triggerEvent('pageView')
58 |
59 | if (!this.options.cache) {
60 | this.cache.empty(this.options.debugMode)
61 | }
62 |
63 | // scrolling
64 | if (!this.options.doScrollingRightAway || this.scrollToElement) {
65 | this.doScrolling(popstate)
66 | }
67 |
68 | // detect animation end
69 | let animationPromises = []
70 | if (!popstate || this.options.animateHistoryBrowsing) {
71 | this.triggerEvent('animationInStart')
72 | let animationPromise = this.createAnimationPromise(this.getAnimation(this.transition, this.animations, 'in'))
73 | animationPromises.push(animationPromise)
74 | }
75 |
76 | //preload pages if possible
77 | this.preloadPages()
78 |
79 | if (!popstate || this.options.animateHistoryBrowsing) {
80 | Promise
81 | .all(animationPromises)
82 | .then(() => {
83 | this.triggerEvent('animationInDone')
84 | // remove "to-{page}" classes
85 | document.documentElement.className.split(' ').forEach(classItem => {
86 | if (new RegExp("^to-").test(classItem) || classItem === "is-changing" || classItem === "is-rendering" || classItem === "is-popstate") {
87 | document.documentElement.classList.remove(classItem);
88 | }
89 | })
90 | })
91 | }
92 |
93 | // update current url
94 | this.getUrl()
95 | // reset scroll-to element
96 | this.scrollToElement = null
97 | }
--------------------------------------------------------------------------------
/src/modules/loadPage.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = function (data, popstate) {
3 | // scrolling
4 | if (this.options.doScrollingRightAway && !this.scrollToElement) {
5 | this.doScrolling(popstate)
6 | }
7 |
8 | // create array for storing animation promises
9 | let animationPromises = []
10 |
11 | // set transition object
12 | if (data.customTransition != null) {
13 | this.updateTransition(window.location.pathname, data.url, data.customTransition)
14 | document.documentElement.classList.add(`to-${ this.classify(data.customTransition) }`)
15 | } else {
16 | this.updateTransition(window.location.pathname, data.url)
17 | }
18 |
19 | if (!popstate || this.options.animateHistoryBrowsing) {
20 | // start animation
21 | this.triggerEvent('animationOutStart')
22 | document.documentElement.classList.add('is-changing')
23 | document.documentElement.classList.add('is-leaving')
24 | if (popstate) {
25 | document.documentElement.classList.add('is-popstate')
26 | }
27 | document.documentElement.classList.add('to-' + this.classify(data.url))
28 |
29 | // animation promise
30 | let animationPromise = this.createAnimationPromise(this.getAnimation(this.transition, this.animations, 'out'))
31 | animationPromises.push(animationPromise)
32 |
33 | Promise
34 | .all(animationPromises)
35 | .then(() => {
36 | this.triggerEvent('animationOutDone')
37 | })
38 |
39 | // create pop element with or without anchor
40 | if (this.scrollToElement != null) {
41 | var pop = data.url + this.scrollToElement;
42 | } else {
43 | var pop = data.url;
44 | }
45 | if(!popstate)
46 | this.createState(pop)
47 | } else {
48 | // proceed without animating
49 | this.triggerEvent('animationSkipped')
50 | }
51 |
52 | if (this.cache.exists(data.url)) {
53 | var xhrPromise = new Promise(resolve => {
54 | resolve()
55 | })
56 | this.triggerEvent('pageRetrievedFromCache')
57 | } else {
58 | if (!this.preloadPromise || this.preloadPromise.route != data.url) {
59 | var xhrPromise = new Promise((resolve, reject) => {
60 | this.getPage(data, (response, request) => {
61 | if (request.status === 500) {
62 | this.triggerEvent('serverError')
63 | reject(data.url)
64 | return;
65 | } else {
66 | // get json data
67 | var page = this.getDataFromHtml(response, request)
68 | if (page != null) {
69 | page.url = data.url
70 | } else {
71 | reject(data.url)
72 | return;
73 | }
74 | // render page
75 | this.cache.cacheUrl(page, this.options.debugMode)
76 | this.triggerEvent('pageLoaded')
77 | }
78 | resolve()
79 | })
80 | })
81 | } else {
82 | var xhrPromise = this.preloadPromise
83 | }
84 | }
85 |
86 | Promise
87 | .all(animationPromises.concat([xhrPromise]))
88 | .then(() => {
89 | this.renderPage(this.cache.getPage(data.url), popstate)
90 | this.preloadPromise = null
91 | })
92 | .catch(errorUrl => {
93 | // rewrite the skipPopStateHandling function to redirect manually when the history.go is processed
94 | this.options.skipPopStateHandling = function () {
95 | window.location = errorUrl
96 | return true
97 | }
98 |
99 | // go back to the actual page were still at
100 | window.history.go(-1)
101 | });
102 | }
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # swupjs
2 |
3 | | WARNING: this repository is deprecated in favour of [JS-plugin](https://swup.js.org/plugins/js-plugin) |
4 | | --- |
5 |
6 | Swupjs is an extension of [swup](https://github.com/gmrchk/swup), which modifies the module for use with JavaScript animations.
7 |
8 | Swupjs only slightly modifies swup, where all the capabilities of swup remain the same, with only one exception - timing and animations are based on JavaScript, not CSS transitions.
9 | For more information about functionality and idea of swupjs, refer to [swup](https://github.com/gmrchk/swup) documentation.
10 |
11 | ## Installation
12 | ```bash
13 | npm install swupjs
14 | ```
15 |
16 | or include the file from the dist folder
17 |
18 | ```html
19 |
20 | ```
21 |
22 | ## How it works
23 | Swupjs is enabled similarly as swup.
24 | ```javascript
25 | let options = {}
26 | const swupjs = new Swupjs(options)
27 | ```
28 |
29 | ## Animations option
30 | To use your animations for page transitions, you first need to define the animation object.
31 |
32 | ```javascript
33 | animations: {
34 | '*': {
35 | out: function (next) {
36 | next()
37 | },
38 | in: function (next) {
39 | next()
40 | }
41 | }
42 | }
43 | ```
44 |
45 | The example above is the default setup in swupjs and defines two animations, where **out** is the animation (function) being executed before content replace, and **in** is animation being executed after the content is replaced.
46 | As one may have noticed, one parameter is passed into both functions.
47 | Call of `next` function serves as an indicator, that animation is done - so in a real world `next()` would be called as a callback of the animation.
48 | As you can see, by default no animation is being executed and `next()` is called right away.
49 |
50 | **Note:** Although the whole purpose of swup is to enable page transitions, this can still enhance your user experience even without the animation as it can shorten your load time drastically when preload and/or cache options are set to `true`. In most cases, your page change should be immediate without any wait time.
51 |
52 | ```javascript
53 | out: function (next) {
54 | setTimeout(next, 2000)
55 | }
56 | ```
57 | In the example above, next function is called after two seconds, which means that swupjs would wait two seconds (or any time necessary for the load of the new page content), before continuing to the content replace.
58 |
59 | Animation object needs to be passed as a part of your options.
60 |
61 | ```javascript
62 | let options = {
63 | animations: {
64 | '*': {
65 | out: function (next) {
66 | next()
67 | },
68 | in: function (next) {
69 | next()
70 | }
71 | }
72 | }
73 | }
74 | const swupjs = new Swupjs(options)
75 | ```
76 |
77 | Basic usage with tools like GSAP would look something like the following:
78 | ```javascript
79 | let options = {
80 | animations: {
81 | '*': {
82 | in: function(next){
83 | document.querySelector('#swup').style.opacity = 0;
84 | TweenLite.to(document.querySelector('#swup'), .5, {
85 | opacity: 1,
86 | onComplete: next
87 | });
88 | },
89 | out: function(next){
90 | document.querySelector('#swup').style.opacity = 1;
91 | TweenLite.to(document.querySelector('#swup'), .5, {
92 | opacity: 0,
93 | onComplete: next
94 | });
95 | }
96 | },
97 | }
98 | }
99 |
100 | const swupjs = new Swupjs(options);
101 | ```
102 |
103 |
104 | ## Choosing the animation
105 | As one may have noticed, the name of animation object in options is defined as `'*'`, which serves as a fallback or base set of animations used throughout the website.
106 | Custom animations can be defined for a transition between any pages, where the name is defined by `[starting route]>[final route]`.
107 |
108 | ```javascript
109 | ...
110 | 'homepage>documentation': {
111 | out: function (next) {
112 | next()
113 | },
114 | in: function (next) {
115 | next()
116 | }
117 | }
118 | ...
119 | ```
120 |
121 | The animation above would be executed for the transition between homepage (/) and documentation page (/documentation).
122 | Notice that for the lack of route, keyword "homepage" is used.
123 | Any of the two routes can also be defined by wildcard symbol (`homepage>*` or `*>documentation`).
124 | The most fitting animation is always chosen.
125 |
126 | ## Custom animation to dynamic pages
127 | Similarly to swup, where `data-swup-transition` attribute of the clicked link is used for assigning a special class to the html tag, swupjs uses the same attribute for choosing custom animation.
128 | In case the attribute is defined on clicked link, swupjs also tests the animation object for the content of the data attribute.
129 | So following attribute `data-swup-transition="post"` would end up in `*>post` being executed.
130 |
131 | ```javascript
132 | ...
133 | '*': {
134 | ...
135 | },
136 | '*>documentation': {
137 | ...
138 | },
139 | '*>post': {
140 | ...
141 | }
142 | ...
143 | ```
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/dist/swupjs.min.js:
--------------------------------------------------------------------------------
1 | (function e(t,n){if(typeof exports==="object"&&typeof module==="object")module.exports=n();else if(typeof define==="function"&&define.amd)define([],n);else if(typeof exports==="object")exports["Swupjs"]=n();else t["Swupjs"]=n()})(window,function(){return function(e){var t={};function n(i){if(t[i]){return t[i].exports}var o=t[i]={i,l:false,exports:{}};e[i].call(o.exports,o,o.exports,n);o.l=true;return o.exports}n.m=e;n.c=t;n.d=function(e,t,i){if(!n.o(e,t)){Object.defineProperty(e,t,{configurable:false,enumerable:true,get:i})}};n.r=function(e){Object.defineProperty(e,"__esModule",{value:true})};n.n=function(e){var t=e&&e.__esModule?function t(){return e["default"]}:function t(){return e};n.d(t,"a",t);return t};n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)};n.p="";return n(n.s=30)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:true});t.query=i;t.queryAll=o;function i(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:document;if(typeof e!=="string"){return e}return t.querySelector(e)}function o(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:document;if(typeof e!=="string"){return e}return Array.prototype.slice.call(t.querySelectorAll(e))}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:true});var i=function(){function e(e,t){for(var n=0;n")){var a=n.split(">");var l=a[0];var u=a[1];if(u==e.to||u=="*"){s++}if(u==e.custom){s=s+2}if(l==e.from||l=="*"){s++}}if(s>r){r=s;o=n;i=t[n]}});if(i==null||r==1){i=t["*"];o="*"}return i[n]}},function(e,t,n){"use strict";var i=n(1);var o=r(i);function r(e){return e&&e.__esModule?e:{default:e}}var s=Array.prototype.forEach;e.exports=function(e,t){var n=this;document.documentElement.classList.remove("is-leaving");var i=new o.default;i.setPath(e.responseURL);if(window.location.pathname!==i.getPath()){window.history.replaceState({url:i.getPath(),random:Math.random(),source:"swup"},document.title,i.getPath())}if(!t||this.options.animateHistoryBrowsing){document.documentElement.classList.add("is-rendering")}this.triggerEvent("willReplaceContent");for(var r=0;r-1){this._handlers[t].splice(r,1)}}else{console.warn("Handler for event '"+t+"' no found.")}}else{this._handlers[t]=[]}}else{Object.keys(this._handlers).forEach(function(e){i._handlers[e]=[]})}}},function(e,t,n){"use strict";e.exports=function e(t,n){if(this._handlers[t]){this._handlers[t].push(n)}else{console.warn("Unsupported event "+t+".")}}},function(e,t,n){"use strict";var i=n(0);e.exports=function(e){var t=this;var n=0;for(var o=0;o2&&arguments[2]!==undefined?arguments[2]:this.options.animateScroll;var o=1-this.options.scrollFriction;var r=this.options.scrollAcceleration;var s=0;var a=0;var l=0;var u=0;var c=0;var d=null;function f(){return document.body.scrollTop||document.documentElement.scrollTop}var h=function e(){var t=p();m();if(c===1&&l>s||c===-1&<?-1:1;u=t+c;l=t;a=0;if(s!=l){h()}else{n.triggerEvent("scrollDone")}};this.triggerEvent("scrollStart");if(i==0){window.scrollTo(0,t);this.triggerEvent("scrollDone")}else{v(t)}}},function(e,t,n){"use strict";e.exports=function(){this.currentUrl=window.location.pathname+window.location.search}},function(e,t,n){"use strict";e.exports=function(e,t){if(this.options.debugMode&&t){console.groupCollapsed("%cswup:"+"%c"+e,"color: #343434","color: #009ACD");console.log(t);console.groupEnd()}else if(this.options.debugMode){console.log("%cswup:"+"%c"+e,"color: #343434","color: #009ACD")}this._handlers[e].forEach(function(e){try{e(t)}catch(e){console.error(e)}});var n=new CustomEvent("swup:"+e,{detail:e});document.dispatchEvent(n)}},function(e,t,n){"use strict";e.exports=function(e){window.history.pushState({url:e||window.location.href.split(window.location.hostname)[1],random:Math.random(),source:"swup"},document.getElementsByTagName("title")[0].innerText,e||window.location.href.split(window.location.hostname)[1])}},function(e,t,n){"use strict";var i=n(0);var o=n(1);var r=s(o);function s(e){return e&&e.__esModule?e:{default:e}}var a=Array.prototype.forEach;e.exports=function(e,t){var n=this;document.documentElement.classList.remove("is-leaving");var o=new r.default;o.setPath(e.responseURL);if(window.location.pathname!==o.getPath()){window.history.replaceState({url:o.getPath(),random:Math.random(),source:"swup"},document.title,o.getPath())}if(!t||this.options.animateHistoryBrowsing){document.documentElement.classList.add("is-rendering")}this.triggerEvent("willReplaceContent");for(var s=0;s","");var r=document.createElement("div");r.innerHTML=o;var s=[];for(var a=0;a1&&arguments[1]!==undefined?arguments[1]:false;var n={url:window.location.pathname+window.location.search,method:"GET",data:null};var o=i({},n,e);var r=new XMLHttpRequest;r.onreadystatechange=function(){if(r.readyState===4){if(r.status!==500){t(r.responseText,r)}else{t(null,r)}}};r.open(o.method,o.url,true);r.setRequestHeader("X-Requested-With","swup");r.send(o.data);return r}},function(e,t,n){"use strict";e.exports=function e(){var t=document.createElement("div");var n={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var i in n){if(t.style[i]!==undefined){return n[i]}}return false}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:true});var i=function(){function e(e,t){for(var n=0;n 1 && arguments[1] !== undefined ? arguments[1] : document;
96 |
97 | if (typeof selector !== 'string') {
98 | return selector;
99 | }
100 |
101 | return context.querySelector(selector);
102 | }
103 |
104 | function queryAll(selector) {
105 | var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document;
106 |
107 | if (typeof selector !== 'string') {
108 | return selector;
109 | }
110 |
111 | return Array.prototype.slice.call(context.querySelectorAll(selector));
112 | }
113 |
114 | /***/ }),
115 | /* 1 */
116 | /***/ (function(module, exports, __webpack_require__) {
117 |
118 | "use strict";
119 |
120 |
121 | Object.defineProperty(exports, "__esModule", {
122 | value: true
123 | });
124 |
125 | 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; }; }();
126 |
127 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
128 |
129 | var Link = function () {
130 | function Link() {
131 | _classCallCheck(this, Link);
132 |
133 | this.link = document.createElement("a");
134 | }
135 |
136 | _createClass(Link, [{
137 | key: 'setPath',
138 | value: function setPath(href) {
139 | this.link.href = href;
140 | }
141 | }, {
142 | key: 'getPath',
143 | value: function getPath() {
144 | var path = this.link.pathname;
145 | if (path[0] != '/') {
146 | path = '/' + path;
147 | }
148 | return path;
149 | }
150 | }, {
151 | key: 'getAddress',
152 | value: function getAddress() {
153 | var path = this.link.pathname + this.link.search;
154 | if (path[0] != '/') {
155 | path = '/' + path;
156 | }
157 | return path;
158 | }
159 | }, {
160 | key: 'getHash',
161 | value: function getHash() {
162 | return this.link.hash;
163 | }
164 | }]);
165 |
166 | return Link;
167 | }();
168 |
169 | exports.default = Link;
170 |
171 | /***/ }),
172 | /* 2 */
173 | /***/ (function(module, exports, __webpack_require__) {
174 |
175 | "use strict";
176 |
177 |
178 | module.exports = function (fn) {
179 | return new Promise(function (resolve) {
180 | fn(resolve);
181 | });
182 | };
183 |
184 | /***/ }),
185 | /* 3 */
186 | /***/ (function(module, exports, __webpack_require__) {
187 |
188 | "use strict";
189 |
190 |
191 | module.exports = function (transition, animations, type) {
192 |
193 | var animation = null;
194 | var animationName = null;
195 | var topRating = 0;
196 |
197 | Object.keys(animations).forEach(function (item) {
198 | var rating = 0;
199 | if (item.includes('>')) {
200 | var route = item.split('>');
201 | var from = route[0];
202 | var to = route[1];
203 |
204 | // TO equals to TO
205 | if (to == transition.to || to == "*") {
206 | rating++;
207 | }
208 |
209 | // equals to CUSTOM animation
210 | if (to == transition.custom) {
211 | rating = rating + 2;
212 | }
213 |
214 | // FROM equals or is ANY
215 | if (from == transition.from || from == "*") {
216 | rating++;
217 | }
218 | }
219 |
220 | // set new final animation
221 | if (rating > topRating) {
222 | topRating = rating;
223 | animationName = item;
224 | animation = animations[item];
225 | }
226 | });
227 |
228 | if (animation == null || topRating == 1) {
229 | animation = animations['*'];
230 | animationName = '*';
231 | }
232 |
233 | return animation[type];
234 | };
235 |
236 | /***/ }),
237 | /* 4 */
238 | /***/ (function(module, exports, __webpack_require__) {
239 |
240 | "use strict";
241 |
242 |
243 | var _Link = __webpack_require__(1);
244 |
245 | var _Link2 = _interopRequireDefault(_Link);
246 |
247 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
248 |
249 | var forEach = Array.prototype.forEach;
250 |
251 |
252 | module.exports = function (page, popstate) {
253 | var _this = this;
254 |
255 | document.documentElement.classList.remove('is-leaving');
256 |
257 | // replace state in case the url was redirected
258 | var link = new _Link2.default();
259 | link.setPath(page.responseURL);
260 |
261 | if (window.location.pathname !== link.getPath()) {
262 | window.history.replaceState({
263 | url: link.getPath(),
264 | random: Math.random(),
265 | source: "swup"
266 | }, document.title, link.getPath());
267 | }
268 |
269 | if (!popstate || this.options.animateHistoryBrowsing) {
270 | document.documentElement.classList.add('is-rendering');
271 | }
272 |
273 | this.triggerEvent('willReplaceContent');
274 |
275 | // replace blocks
276 | for (var i = 0; i < page.blocks.length; i++) {
277 | document.body.querySelector('[data-swup="' + i + '"]').outerHTML = page.blocks[i];
278 | }
279 |
280 | // set title
281 | document.title = page.title;
282 |
283 | // handle classes after render
284 | // remove
285 | if (this.options.pageClassPrefix !== false) {
286 | document.body.className.split(' ').forEach(function (className) {
287 | // empty string for page class
288 | if (className != "" && className.includes(_this.options.pageClassPrefix)) {
289 | document.body.classList.remove(className);
290 | }
291 | });
292 | }
293 |
294 | // add
295 | if (page.pageClass != "") {
296 | page.pageClass.split(' ').forEach(function (className) {
297 | if (className != "" && className.includes(_this.options.pageClassPrefix)) {
298 | document.body.classList.add(className);
299 | }
300 | });
301 | }
302 |
303 | this.triggerEvent('contentReplaced');
304 | this.triggerEvent('pageView');
305 |
306 | if (!this.options.cache) {
307 | this.cache.empty(this.options.debugMode);
308 | }
309 |
310 | // scrolling
311 | if (!this.options.doScrollingRightAway || this.scrollToElement) {
312 | this.doScrolling(popstate);
313 | }
314 |
315 | // detect animation end
316 | var animationPromises = [];
317 | if (!popstate || this.options.animateHistoryBrowsing) {
318 | this.triggerEvent('animationInStart');
319 | var animationPromise = this.createAnimationPromise(this.getAnimation(this.transition, this.animations, 'in'));
320 | animationPromises.push(animationPromise);
321 | }
322 |
323 | //preload pages if possible
324 | this.preloadPages();
325 |
326 | if (!popstate || this.options.animateHistoryBrowsing) {
327 | Promise.all(animationPromises).then(function () {
328 | _this.triggerEvent('animationInDone');
329 | // remove "to-{page}" classes
330 | document.documentElement.className.split(' ').forEach(function (classItem) {
331 | if (new RegExp("^to-").test(classItem) || classItem === "is-changing" || classItem === "is-rendering" || classItem === "is-popstate") {
332 | document.documentElement.classList.remove(classItem);
333 | }
334 | });
335 | });
336 | }
337 |
338 | // update current url
339 | this.getUrl();
340 | // reset scroll-to element
341 | this.scrollToElement = null;
342 | };
343 |
344 | /***/ }),
345 | /* 5 */
346 | /***/ (function(module, exports, __webpack_require__) {
347 |
348 | "use strict";
349 |
350 |
351 | module.exports = function (data, popstate) {
352 | var _this = this;
353 |
354 | // scrolling
355 | if (this.options.doScrollingRightAway && !this.scrollToElement) {
356 | this.doScrolling(popstate);
357 | }
358 |
359 | // create array for storing animation promises
360 | var animationPromises = [];
361 |
362 | // set transition object
363 | if (data.customTransition != null) {
364 | this.updateTransition(window.location.pathname, data.url, data.customTransition);
365 | document.documentElement.classList.add('to-' + this.classify(data.customTransition));
366 | } else {
367 | this.updateTransition(window.location.pathname, data.url);
368 | }
369 |
370 | if (!popstate || this.options.animateHistoryBrowsing) {
371 | // start animation
372 | this.triggerEvent('animationOutStart');
373 | document.documentElement.classList.add('is-changing');
374 | document.documentElement.classList.add('is-leaving');
375 | if (popstate) {
376 | document.documentElement.classList.add('is-popstate');
377 | }
378 | document.documentElement.classList.add('to-' + this.classify(data.url));
379 |
380 | // animation promise
381 | var animationPromise = this.createAnimationPromise(this.getAnimation(this.transition, this.animations, 'out'));
382 | animationPromises.push(animationPromise);
383 |
384 | Promise.all(animationPromises).then(function () {
385 | _this.triggerEvent('animationOutDone');
386 | });
387 |
388 | // create pop element with or without anchor
389 | if (this.scrollToElement != null) {
390 | var pop = data.url + this.scrollToElement;
391 | } else {
392 | var pop = data.url;
393 | }
394 | if (!popstate) this.createState(pop);
395 | } else {
396 | // proceed without animating
397 | this.triggerEvent('animationSkipped');
398 | }
399 |
400 | if (this.cache.exists(data.url)) {
401 | var xhrPromise = new Promise(function (resolve) {
402 | resolve();
403 | });
404 | this.triggerEvent('pageRetrievedFromCache');
405 | } else {
406 | if (!this.preloadPromise || this.preloadPromise.route != data.url) {
407 | var xhrPromise = new Promise(function (resolve, reject) {
408 | _this.getPage(data, function (response, request) {
409 | if (request.status === 500) {
410 | _this.triggerEvent('serverError');
411 | reject(data.url);
412 | return;
413 | } else {
414 | // get json data
415 | var page = _this.getDataFromHtml(response, request);
416 | if (page != null) {
417 | page.url = data.url;
418 | } else {
419 | reject(data.url);
420 | return;
421 | }
422 | // render page
423 | _this.cache.cacheUrl(page, _this.options.debugMode);
424 | _this.triggerEvent('pageLoaded');
425 | }
426 | resolve();
427 | });
428 | });
429 | } else {
430 | var xhrPromise = this.preloadPromise;
431 | }
432 | }
433 |
434 | Promise.all(animationPromises.concat([xhrPromise])).then(function () {
435 | _this.renderPage(_this.cache.getPage(data.url), popstate);
436 | _this.preloadPromise = null;
437 | }).catch(function (errorUrl) {
438 | // rewrite the skipPopStateHandling function to redirect manually when the history.go is processed
439 | _this.options.skipPopStateHandling = function () {
440 | window.location = errorUrl;
441 | return true;
442 | };
443 |
444 | // go back to the actual page were still at
445 | window.history.go(-1);
446 | });
447 | };
448 |
449 | /***/ }),
450 | /* 6 */
451 | /***/ (function(module, exports, __webpack_require__) {
452 |
453 | "use strict";
454 |
455 |
456 | module.exports = function (str) {
457 | if (this.options.debugMode) {
458 | console.log(str + '%c', 'color: #009ACD');
459 | }
460 | };
461 |
462 | /***/ }),
463 | /* 7 */
464 | /***/ (function(module, exports, __webpack_require__) {
465 |
466 | "use strict";
467 |
468 |
469 | module.exports = function (plugin, options) {
470 | var _this = this;
471 |
472 | options = Object.assign({}, plugin.options, options);
473 |
474 | plugin.options = options;
475 |
476 | var getCurrentPageHtml = function getCurrentPageHtml() {
477 | var page = _this.cache.getPage(window.location.pathname + window.location.search);
478 | var html = document.createElement('html');
479 | html.innerHTML = page.originalContent;
480 | return html;
481 | };
482 |
483 | this.plugins.push(plugin);
484 | plugin.exec(options, this, getCurrentPageHtml);
485 | return this.plugins;
486 | };
487 |
488 | /***/ }),
489 | /* 8 */
490 | /***/ (function(module, exports, __webpack_require__) {
491 |
492 | "use strict";
493 |
494 |
495 | var _utils = __webpack_require__(0);
496 |
497 | module.exports = function () {
498 | var _this = this;
499 |
500 | if (this.options.preload) {
501 | (0, _utils.queryAll)('[data-swup-preload]').forEach(function (element) {
502 | _this.preloadPage(element.href);
503 | });
504 | }
505 | };
506 |
507 | /***/ }),
508 | /* 9 */
509 | /***/ (function(module, exports, __webpack_require__) {
510 |
511 | "use strict";
512 |
513 |
514 | var _Link = __webpack_require__(1);
515 |
516 | var _Link2 = _interopRequireDefault(_Link);
517 |
518 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
519 |
520 | module.exports = function (pathname) {
521 | var _this = this;
522 |
523 | var link = new _Link2.default();
524 | link.setPath(pathname);
525 | return new Promise(function (resolve, reject) {
526 | if (link.getAddress() != _this.currentUrl && !_this.cache.exists(link.getAddress())) {
527 | _this.getPage({ url: link.getAddress() }, function (response, request) {
528 | if (request.status === 500) {
529 | _this.triggerEvent('serverError');
530 | reject();
531 | } else {
532 | // get json data
533 | var page = _this.getDataFromHtml(response, request);
534 | if (page != null) {
535 | page.url = link.getAddress();
536 | _this.cache.cacheUrl(page, _this.options.debugMode);
537 | _this.triggerEvent('pagePreloaded');
538 | }
539 | resolve(_this.cache.getPage(link.getAddress()));
540 | }
541 | });
542 | } else {
543 | resolve(_this.cache.getPage(link.getAddress()));
544 | }
545 | });
546 | };
547 |
548 | /***/ }),
549 | /* 10 */
550 | /***/ (function(module, exports, __webpack_require__) {
551 |
552 | "use strict";
553 |
554 |
555 | module.exports = function (from, to, custom) {
556 |
557 | // homepage case
558 | if (from == "/") {
559 | from = "/homepage";
560 | }
561 | if (to == "/") {
562 | to = "/homepage";
563 | }
564 |
565 | // transition routes
566 | this.transition = {
567 | from: from.replace('/', ''),
568 | to: to.replace('/', '')
569 | };
570 |
571 | if (custom) {
572 | this.transition.custom = custom;
573 | }
574 | };
575 |
576 | /***/ }),
577 | /* 11 */
578 | /***/ (function(module, exports, __webpack_require__) {
579 |
580 | "use strict";
581 |
582 |
583 | module.exports = function off(event, handler) {
584 | var _this = this;
585 |
586 | if (event != null) {
587 | if (handler != null) {
588 | if (this._handlers[event] && this._handlers[event].filter(function (savedHandler) {
589 | return savedHandler === handler;
590 | }).length) {
591 | var toRemove = this._handlers[event].filter(function (savedHandler) {
592 | return savedHandler === handler;
593 | })[0];
594 | var index = this._handlers[event].indexOf(toRemove);
595 | if (index > -1) {
596 | this._handlers[event].splice(index, 1);
597 | }
598 | } else {
599 | console.warn("Handler for event '" + event + "' no found.");
600 | }
601 | } else {
602 | this._handlers[event] = [];
603 | }
604 | } else {
605 | Object.keys(this._handlers).forEach(function (keys) {
606 | _this._handlers[keys] = [];
607 | });
608 | }
609 | };
610 |
611 | /***/ }),
612 | /* 12 */
613 | /***/ (function(module, exports, __webpack_require__) {
614 |
615 | "use strict";
616 |
617 |
618 | module.exports = function on(event, handler) {
619 | if (this._handlers[event]) {
620 | this._handlers[event].push(handler);
621 | } else {
622 | console.warn("Unsupported event " + event + ".");
623 | }
624 | };
625 |
626 | /***/ }),
627 | /* 13 */
628 | /***/ (function(module, exports, __webpack_require__) {
629 |
630 | "use strict";
631 |
632 |
633 | var _utils = __webpack_require__(0);
634 |
635 | module.exports = function (element) {
636 | var _this = this;
637 |
638 | var blocks = 0;
639 |
640 | for (var i = 0; i < this.options.elements.length; i++) {
641 | if (element.querySelector(this.options.elements[i]) == null) {
642 | console.warn("Element " + this.options.elements[i] + " is not in current page.");
643 | } else {
644 | (0, _utils.queryAll)(this.options.elements[i]).forEach(function (item, index) {
645 | (0, _utils.queryAll)(_this.options.elements[i], element)[index].dataset.swup = blocks;
646 | blocks++;
647 | });
648 | }
649 | }
650 | };
651 |
652 | /***/ }),
653 | /* 14 */
654 | /***/ (function(module, exports, __webpack_require__) {
655 |
656 | "use strict";
657 |
658 |
659 | module.exports = function (popstate) {
660 | if (this.options.scroll && (!popstate || this.options.animateHistoryBrowsing)) {
661 | if (this.scrollToElement != null) {
662 | var element = document.querySelector(this.scrollToElement);
663 | if (element != null) {
664 | var top = element.getBoundingClientRect().top + window.pageYOffset;
665 | this.scrollTo(document.body, top);
666 | } else {
667 | console.warn("Element for offset not found (" + this.scrollToElement + ")");
668 | }
669 | this.scrollToElement = null;
670 | } else {
671 | this.scrollTo(document.body, 0);
672 | }
673 | }
674 | };
675 |
676 | /***/ }),
677 | /* 15 */
678 | /***/ (function(module, exports, __webpack_require__) {
679 |
680 | "use strict";
681 |
682 |
683 | module.exports = function (text) {
684 | var output = text.toString().toLowerCase().replace(/\s+/g, '-') // Replace spaces with -
685 | .replace(/\//g, '-') // Replace / with -
686 | .replace(/[^\w\-]+/g, '') // Remove all non-word chars
687 | .replace(/\-\-+/g, '-') // Replace multiple - with single -
688 | .replace(/^-+/, '') // Trim - from start of text
689 | .replace(/-+$/, ''); // Trim - from end of text
690 | if (output[0] == "/") output = output.splice(1);
691 | if (output == '') output = 'homepage';
692 | return output;
693 | };
694 |
695 | /***/ }),
696 | /* 16 */
697 | /***/ (function(module, exports, __webpack_require__) {
698 |
699 | "use strict";
700 |
701 |
702 | module.exports = function (element, to) {
703 | var _this = this;
704 |
705 | var animatedScroll = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.options.animateScroll;
706 |
707 | var friction = 1 - this.options.scrollFriction;
708 | var acceleration = this.options.scrollAcceleration;
709 |
710 | var positionY = 0;
711 | var velocityY = 0;
712 | var targetPositionY = 0;
713 | var targetPositionYWithOffset = 0;
714 | var direction = 0;
715 |
716 | var raf = null;
717 |
718 | function getScrollTop() {
719 | return document.body.scrollTop || document.documentElement.scrollTop;
720 | }
721 |
722 | var animate = function animate() {
723 | var distance = update();
724 | render();
725 |
726 | if (direction === 1 && targetPositionY > positionY || direction === -1 && targetPositionY < positionY) {
727 | raf = requestAnimationFrame(animate);
728 | } else {
729 | window.scrollTo(0, targetPositionY);
730 | _this.triggerEvent('scrollDone');
731 | }
732 | };
733 |
734 | function update() {
735 | var distance = targetPositionYWithOffset - positionY;
736 | var attraction = distance * acceleration;
737 |
738 | applyForce(attraction);
739 |
740 | velocityY *= friction;
741 | positionY += velocityY;
742 |
743 | return distance;
744 | }
745 |
746 | var applyForce = function applyForce(force) {
747 | velocityY += force;
748 | };
749 |
750 | var render = function render() {
751 | window.scrollTo(0, positionY);
752 | };
753 |
754 | window.addEventListener('mousewheel', function (event) {
755 | if (raf) {
756 | cancelAnimationFrame(raf);
757 | raf = null;
758 | }
759 | }, {
760 | passive: true
761 | });
762 |
763 | var scrollTo = function scrollTo(offset, callback) {
764 | positionY = getScrollTop();
765 | direction = positionY > offset ? -1 : 1;
766 | targetPositionYWithOffset = offset + direction;
767 | targetPositionY = offset;
768 | velocityY = 0;
769 | if (positionY != targetPositionY) {
770 | animate();
771 | } else {
772 | _this.triggerEvent('scrollDone');
773 | }
774 | };
775 |
776 | this.triggerEvent('scrollStart');
777 | if (animatedScroll == 0) {
778 | window.scrollTo(0, to);
779 | this.triggerEvent('scrollDone');
780 | } else {
781 | scrollTo(to);
782 | }
783 | };
784 |
785 | /***/ }),
786 | /* 17 */
787 | /***/ (function(module, exports, __webpack_require__) {
788 |
789 | "use strict";
790 |
791 |
792 | module.exports = function () {
793 | this.currentUrl = window.location.pathname + window.location.search;
794 | };
795 |
796 | /***/ }),
797 | /* 18 */
798 | /***/ (function(module, exports, __webpack_require__) {
799 |
800 | "use strict";
801 |
802 |
803 | module.exports = function (eventName, originalEvent) {
804 | if (this.options.debugMode && originalEvent) {
805 | console.groupCollapsed('%cswup:' + '%c' + eventName, 'color: #343434', 'color: #009ACD');
806 | console.log(originalEvent);
807 | console.groupEnd();
808 | } else if (this.options.debugMode) {
809 | console.log('%cswup:' + '%c' + eventName, 'color: #343434', 'color: #009ACD');
810 | }
811 |
812 | // call saved handlers with "on" method and pass originalEvent object if available
813 | this._handlers[eventName].forEach(function (handler) {
814 | try {
815 | handler(originalEvent);
816 | } catch (error) {
817 | console.error(error);
818 | }
819 | });
820 |
821 | // trigger event on document with prefix "swup:"
822 | var event = new CustomEvent('swup:' + eventName, { detail: eventName });
823 | document.dispatchEvent(event);
824 | };
825 |
826 | /***/ }),
827 | /* 19 */
828 | /***/ (function(module, exports, __webpack_require__) {
829 |
830 | "use strict";
831 |
832 |
833 | module.exports = function (url) {
834 | window.history.pushState({
835 | url: url || window.location.href.split(window.location.hostname)[1],
836 | random: Math.random(),
837 | source: "swup"
838 | }, document.getElementsByTagName('title')[0].innerText, url || window.location.href.split(window.location.hostname)[1]);
839 | };
840 |
841 | /***/ }),
842 | /* 20 */
843 | /***/ (function(module, exports, __webpack_require__) {
844 |
845 | "use strict";
846 |
847 |
848 | var _utils = __webpack_require__(0);
849 |
850 | var _Link = __webpack_require__(1);
851 |
852 | var _Link2 = _interopRequireDefault(_Link);
853 |
854 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
855 |
856 | var forEach = Array.prototype.forEach;
857 |
858 |
859 | module.exports = function (page, popstate) {
860 | var _this = this;
861 |
862 | document.documentElement.classList.remove('is-leaving');
863 |
864 | // replace state in case the url was redirected
865 | var link = new _Link2.default();
866 | link.setPath(page.responseURL);
867 |
868 | if (window.location.pathname !== link.getPath()) {
869 | window.history.replaceState({
870 | url: link.getPath(),
871 | random: Math.random(),
872 | source: "swup"
873 | }, document.title, link.getPath());
874 | }
875 |
876 | // only add for non-popstate transitions
877 | if (!popstate || this.options.animateHistoryBrowsing) {
878 | document.documentElement.classList.add('is-rendering');
879 | }
880 |
881 | this.triggerEvent('willReplaceContent');
882 |
883 | // replace blocks
884 | for (var i = 0; i < page.blocks.length; i++) {
885 | document.body.querySelector('[data-swup="' + i + '"]').outerHTML = page.blocks[i];
886 | }
887 |
888 | // set title
889 | document.title = page.title;
890 |
891 | // handle classes after render
892 | // remove
893 | if (this.options.pageClassPrefix !== false) {
894 | document.body.className.split(' ').forEach(function (className) {
895 | // empty string for page class
896 | if (className != "" && className.includes(_this.options.pageClassPrefix)) {
897 | document.body.classList.remove(className);
898 | }
899 | });
900 | }
901 | // add
902 | if (page.pageClass != "") {
903 | page.pageClass.split(' ').forEach(function (className) {
904 | if (className != "" && className.includes(_this.options.pageClassPrefix)) {
905 | document.body.classList.add(className);
906 | }
907 | });
908 | }
909 |
910 | this.triggerEvent('contentReplaced');
911 | this.triggerEvent('pageView');
912 | if (!this.options.cache) {
913 | this.cache.empty(this.options.debugMode);
914 | }
915 | setTimeout(function () {
916 | if (!popstate || _this.options.animateHistoryBrowsing) {
917 | _this.triggerEvent('animationInStart');
918 | document.documentElement.classList.remove('is-animating');
919 | }
920 | }, 10);
921 |
922 | // scrolling
923 | if (!this.options.doScrollingRightAway || this.scrollToElement) {
924 | this.doScrolling(popstate);
925 | }
926 |
927 | // detect animation end
928 | var animatedElements = (0, _utils.queryAll)(this.options.animationSelector);
929 | var promises = [];
930 | forEach.call(animatedElements, function (element) {
931 | var promise = new Promise(function (resolve) {
932 | element.addEventListener(_this.transitionEndEvent, function (event) {
933 | if (element == event.target) {
934 | resolve();
935 | }
936 | });
937 | });
938 | promises.push(promise);
939 | });
940 |
941 | //preload pages if possible
942 | this.preloadPages();
943 |
944 | if (!popstate || this.options.animateHistoryBrowsing) {
945 | Promise.all(promises).then(function () {
946 | _this.triggerEvent('animationInDone');
947 | // remove "to-{page}" classes
948 | document.documentElement.className.split(' ').forEach(function (classItem) {
949 | if (new RegExp("^to-").test(classItem) || classItem === "is-changing" || classItem === "is-rendering" || classItem === "is-popstate") {
950 | document.documentElement.classList.remove(classItem);
951 | }
952 | });
953 | });
954 | }
955 |
956 | // update current url
957 | this.getUrl();
958 | // reset scroll-to element
959 | this.scrollToElement = null;
960 | };
961 |
962 | /***/ }),
963 | /* 21 */
964 | /***/ (function(module, exports, __webpack_require__) {
965 |
966 | "use strict";
967 |
968 |
969 | var _utils = __webpack_require__(0);
970 |
971 | var forEach = Array.prototype.forEach;
972 |
973 |
974 | module.exports = function (data, popstate) {
975 | var _this = this;
976 |
977 | // scrolling
978 | if (this.options.doScrollingRightAway && !this.scrollToElement) {
979 | this.doScrolling(popstate);
980 | }
981 |
982 | // create array for storing animation promises
983 | var animationPromises = [];
984 |
985 | // set transition object
986 | if (data.customTransition != null) {
987 | this.updateTransition(window.location.pathname, data.url, data.customTransition);
988 | document.documentElement.classList.add('to-' + this.classify(data.customTransition));
989 | } else {
990 | this.updateTransition(window.location.pathname, data.url);
991 | }
992 |
993 | if (!popstate || this.options.animateHistoryBrowsing) {
994 | // start animation
995 | this.triggerEvent('animationOutStart');
996 | document.documentElement.classList.add('is-changing');
997 | document.documentElement.classList.add('is-leaving');
998 | document.documentElement.classList.add('is-animating');
999 | if (popstate) {
1000 | document.documentElement.classList.add('is-popstate');
1001 | }
1002 | document.documentElement.classList.add('to-' + this.classify(data.url));
1003 |
1004 | // detect animation end
1005 | var animatedElements = (0, _utils.queryAll)(this.options.animationSelector);
1006 | forEach.call(animatedElements, function (element) {
1007 | var promise = new Promise(function (resolve) {
1008 | element.addEventListener(_this.transitionEndEvent, function (event) {
1009 | if (element == event.target) {
1010 | resolve();
1011 | }
1012 | });
1013 | });
1014 | animationPromises.push(promise);
1015 | });
1016 |
1017 | Promise.all(animationPromises).then(function () {
1018 | _this.triggerEvent('animationOutDone');
1019 | });
1020 |
1021 | // create pop element with or without anchor
1022 | if (this.scrollToElement != null) {
1023 | var pop = data.url + this.scrollToElement;
1024 | } else {
1025 | var pop = data.url;
1026 | }
1027 | if (!popstate) this.createState(pop);
1028 | } else {
1029 | // proceed without animating
1030 | this.triggerEvent('animationSkipped');
1031 | }
1032 |
1033 | if (this.cache.exists(data.url)) {
1034 | var xhrPromise = new Promise(function (resolve) {
1035 | resolve();
1036 | });
1037 | this.triggerEvent('pageRetrievedFromCache');
1038 | } else {
1039 | if (!this.preloadPromise || this.preloadPromise.route != data.url) {
1040 | var xhrPromise = new Promise(function (resolve, reject) {
1041 | _this.getPage(data, function (response, request) {
1042 | if (request.status === 500) {
1043 | _this.triggerEvent('serverError');
1044 | reject(data.url);
1045 | return;
1046 | } else {
1047 | // get json data
1048 | var page = _this.getDataFromHtml(response, request);
1049 | if (page != null) {
1050 | page.url = data.url;
1051 | } else {
1052 | reject(data.url);
1053 | return;
1054 | }
1055 | // render page
1056 | _this.cache.cacheUrl(page, _this.options.debugMode);
1057 | _this.triggerEvent('pageLoaded');
1058 | }
1059 | resolve();
1060 | });
1061 | });
1062 | } else {
1063 | var xhrPromise = this.preloadPromise;
1064 | }
1065 | }
1066 |
1067 | Promise.all(animationPromises.concat([xhrPromise])).then(function () {
1068 | // render page
1069 | _this.renderPage(_this.cache.getPage(data.url), popstate);
1070 | _this.preloadPromise = null;
1071 | }).catch(function (errorUrl) {
1072 | // rewrite the skipPopStateHandling function to redirect manually when the history.go is processed
1073 | _this.options.skipPopStateHandling = function () {
1074 | window.location = errorUrl;
1075 | return true;
1076 | };
1077 |
1078 | // go back to the actual page were still at
1079 | window.history.go(-1);
1080 | });
1081 | };
1082 |
1083 | /***/ }),
1084 | /* 22 */
1085 | /***/ (function(module, exports, __webpack_require__) {
1086 |
1087 | "use strict";
1088 |
1089 |
1090 | var _utils = __webpack_require__(0);
1091 |
1092 | module.exports = function (html, request) {
1093 | var _this = this;
1094 |
1095 | var content = html.replace('', '');
1096 | var fakeDom = document.createElement('div');
1097 | fakeDom.innerHTML = content;
1098 | var blocks = [];
1099 |
1100 | for (var i = 0; i < this.options.elements.length; i++) {
1101 | if (fakeDom.querySelector(this.options.elements[i]) == null) {
1102 | console.warn('Element ' + this.options.elements[i] + ' is not found in cached page.');
1103 | return null;
1104 | } else {
1105 | (0, _utils.queryAll)(this.options.elements[i]).forEach(function (item, index) {
1106 | (0, _utils.queryAll)(_this.options.elements[i], fakeDom)[index].dataset.swup = blocks.length;
1107 | blocks.push((0, _utils.queryAll)(_this.options.elements[i], fakeDom)[index].outerHTML);
1108 | });
1109 | }
1110 | }
1111 |
1112 | var json = {
1113 | title: fakeDom.querySelector('title').innerText,
1114 | pageClass: fakeDom.querySelector('#swupBody').className,
1115 | originalContent: html,
1116 | blocks: blocks,
1117 | responseURL: request != null ? request.responseURL : window.location.href
1118 | };
1119 | return json;
1120 | };
1121 |
1122 | /***/ }),
1123 | /* 23 */
1124 | /***/ (function(module, exports, __webpack_require__) {
1125 |
1126 | "use strict";
1127 |
1128 |
1129 | 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; };
1130 |
1131 | module.exports = function (options) {
1132 | var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
1133 |
1134 | var defaults = {
1135 | url: window.location.pathname + window.location.search,
1136 | method: "GET",
1137 | data: null
1138 | };
1139 |
1140 | var data = _extends({}, defaults, options);
1141 |
1142 | var request = new XMLHttpRequest();
1143 |
1144 | request.onreadystatechange = function () {
1145 | if (request.readyState === 4) {
1146 | if (request.status !== 500) {
1147 | callback(request.responseText, request);
1148 | } else {
1149 | callback(null, request);
1150 | }
1151 | }
1152 | };
1153 |
1154 | request.open(data.method, data.url, true);
1155 | request.setRequestHeader("X-Requested-With", "swup");
1156 | request.send(data.data);
1157 | return request;
1158 | };
1159 |
1160 | /***/ }),
1161 | /* 24 */
1162 | /***/ (function(module, exports, __webpack_require__) {
1163 |
1164 | "use strict";
1165 |
1166 |
1167 | module.exports = function transitionEnd() {
1168 | var el = document.createElement('div');
1169 |
1170 | var transEndEventNames = {
1171 | WebkitTransition: 'webkitTransitionEnd',
1172 | MozTransition: 'transitionend',
1173 | OTransition: 'oTransitionEnd otransitionend',
1174 | transition: 'transitionend'
1175 | };
1176 |
1177 | for (var name in transEndEventNames) {
1178 | if (el.style[name] !== undefined) {
1179 | return transEndEventNames[name];
1180 | }
1181 | }
1182 |
1183 | return false;
1184 | };
1185 |
1186 | /***/ }),
1187 | /* 25 */
1188 | /***/ (function(module, exports, __webpack_require__) {
1189 |
1190 | "use strict";
1191 |
1192 |
1193 | Object.defineProperty(exports, "__esModule", {
1194 | value: true
1195 | });
1196 |
1197 | 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; }; }();
1198 |
1199 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1200 |
1201 | var Cache = function () {
1202 | function Cache() {
1203 | _classCallCheck(this, Cache);
1204 |
1205 | this.pages = {};
1206 | this.count = 0;
1207 | this.last = null;
1208 | }
1209 |
1210 | _createClass(Cache, [{
1211 | key: 'cacheUrl',
1212 | value: function cacheUrl(page, displayCache) {
1213 | this.count++;
1214 | if (page.url in this.pages === false) {
1215 | this.pages[page.url] = page;
1216 | }
1217 | this.last = this.pages[page.url];
1218 | if (displayCache) {
1219 | this.displayCache();
1220 | }
1221 | }
1222 | }, {
1223 | key: 'getPage',
1224 | value: function getPage(url) {
1225 | return this.pages[url];
1226 | }
1227 | }, {
1228 | key: 'displayCache',
1229 | value: function displayCache() {
1230 | console.groupCollapsed('Cache (' + Object.keys(this.pages).length + ')');
1231 | for (var key in this.pages) {
1232 | console.log(this.pages[key]);
1233 | }
1234 | console.groupEnd();
1235 | }
1236 | }, {
1237 | key: 'exists',
1238 | value: function exists(url) {
1239 | if (url in this.pages) return true;
1240 | return false;
1241 | }
1242 | }, {
1243 | key: 'empty',
1244 | value: function empty(showLog) {
1245 | this.pages = {};
1246 | this.count = 0;
1247 | this.last = null;
1248 | if (showLog) {
1249 | console.log('Cache cleared');
1250 | }
1251 | }
1252 | }, {
1253 | key: 'remove',
1254 | value: function remove(url) {
1255 | delete this.pages[url];
1256 | }
1257 | }]);
1258 |
1259 | return Cache;
1260 | }();
1261 |
1262 | exports.default = Cache;
1263 |
1264 | /***/ }),
1265 | /* 26 */
1266 | /***/ (function(module, exports) {
1267 |
1268 | var DOCUMENT_NODE_TYPE = 9;
1269 |
1270 | /**
1271 | * A polyfill for Element.matches()
1272 | */
1273 | if (typeof Element !== 'undefined' && !Element.prototype.matches) {
1274 | var proto = Element.prototype;
1275 |
1276 | proto.matches = proto.matchesSelector ||
1277 | proto.mozMatchesSelector ||
1278 | proto.msMatchesSelector ||
1279 | proto.oMatchesSelector ||
1280 | proto.webkitMatchesSelector;
1281 | }
1282 |
1283 | /**
1284 | * Finds the closest parent that matches a selector.
1285 | *
1286 | * @param {Element} element
1287 | * @param {String} selector
1288 | * @return {Function}
1289 | */
1290 | function closest (element, selector) {
1291 | while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
1292 | if (typeof element.matches === 'function' &&
1293 | element.matches(selector)) {
1294 | return element;
1295 | }
1296 | element = element.parentNode;
1297 | }
1298 | }
1299 |
1300 | module.exports = closest;
1301 |
1302 |
1303 | /***/ }),
1304 | /* 27 */
1305 | /***/ (function(module, exports, __webpack_require__) {
1306 |
1307 | var closest = __webpack_require__(26);
1308 |
1309 | /**
1310 | * Delegates event to a selector.
1311 | *
1312 | * @param {Element} element
1313 | * @param {String} selector
1314 | * @param {String} type
1315 | * @param {Function} callback
1316 | * @param {Boolean} useCapture
1317 | * @return {Object}
1318 | */
1319 | function delegate(element, selector, type, callback, useCapture) {
1320 | var listenerFn = listener.apply(this, arguments);
1321 |
1322 | element.addEventListener(type, listenerFn, useCapture);
1323 |
1324 | return {
1325 | destroy: function() {
1326 | element.removeEventListener(type, listenerFn, useCapture);
1327 | }
1328 | }
1329 | }
1330 |
1331 | /**
1332 | * Finds closest match and invokes callback.
1333 | *
1334 | * @param {Element} element
1335 | * @param {String} selector
1336 | * @param {String} type
1337 | * @param {Function} callback
1338 | * @return {Function}
1339 | */
1340 | function listener(element, selector, type, callback) {
1341 | return function(e) {
1342 | e.delegateTarget = closest(e.target, selector);
1343 |
1344 | if (e.delegateTarget) {
1345 | callback.call(element, e);
1346 | }
1347 | }
1348 | }
1349 |
1350 | module.exports = delegate;
1351 |
1352 |
1353 | /***/ }),
1354 | /* 28 */
1355 | /***/ (function(module, exports, __webpack_require__) {
1356 |
1357 | "use strict";
1358 |
1359 |
1360 | Object.defineProperty(exports, "__esModule", {
1361 | value: true
1362 | });
1363 |
1364 | 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; };
1365 |
1366 | 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; }; }();
1367 |
1368 | // helpers
1369 |
1370 |
1371 | // modules
1372 |
1373 |
1374 | var _delegate = __webpack_require__(27);
1375 |
1376 | var _delegate2 = _interopRequireDefault(_delegate);
1377 |
1378 | var _Cache = __webpack_require__(25);
1379 |
1380 | var _Cache2 = _interopRequireDefault(_Cache);
1381 |
1382 | var _Link = __webpack_require__(1);
1383 |
1384 | var _Link2 = _interopRequireDefault(_Link);
1385 |
1386 | var _transitionEnd = __webpack_require__(24);
1387 |
1388 | var _transitionEnd2 = _interopRequireDefault(_transitionEnd);
1389 |
1390 | var _request = __webpack_require__(23);
1391 |
1392 | var _request2 = _interopRequireDefault(_request);
1393 |
1394 | var _getDataFromHtml = __webpack_require__(22);
1395 |
1396 | var _getDataFromHtml2 = _interopRequireDefault(_getDataFromHtml);
1397 |
1398 | var _loadPage = __webpack_require__(21);
1399 |
1400 | var _loadPage2 = _interopRequireDefault(_loadPage);
1401 |
1402 | var _renderPage = __webpack_require__(20);
1403 |
1404 | var _renderPage2 = _interopRequireDefault(_renderPage);
1405 |
1406 | var _createState = __webpack_require__(19);
1407 |
1408 | var _createState2 = _interopRequireDefault(_createState);
1409 |
1410 | var _triggerEvent = __webpack_require__(18);
1411 |
1412 | var _triggerEvent2 = _interopRequireDefault(_triggerEvent);
1413 |
1414 | var _getUrl = __webpack_require__(17);
1415 |
1416 | var _getUrl2 = _interopRequireDefault(_getUrl);
1417 |
1418 | var _scrollTo = __webpack_require__(16);
1419 |
1420 | var _scrollTo2 = _interopRequireDefault(_scrollTo);
1421 |
1422 | var _classify = __webpack_require__(15);
1423 |
1424 | var _classify2 = _interopRequireDefault(_classify);
1425 |
1426 | var _doScrolling = __webpack_require__(14);
1427 |
1428 | var _doScrolling2 = _interopRequireDefault(_doScrolling);
1429 |
1430 | var _markSwupElements = __webpack_require__(13);
1431 |
1432 | var _markSwupElements2 = _interopRequireDefault(_markSwupElements);
1433 |
1434 | var _on = __webpack_require__(12);
1435 |
1436 | var _on2 = _interopRequireDefault(_on);
1437 |
1438 | var _off = __webpack_require__(11);
1439 |
1440 | var _off2 = _interopRequireDefault(_off);
1441 |
1442 | var _updateTransition = __webpack_require__(10);
1443 |
1444 | var _updateTransition2 = _interopRequireDefault(_updateTransition);
1445 |
1446 | var _preloadPage = __webpack_require__(9);
1447 |
1448 | var _preloadPage2 = _interopRequireDefault(_preloadPage);
1449 |
1450 | var _preloadPages = __webpack_require__(8);
1451 |
1452 | var _preloadPages2 = _interopRequireDefault(_preloadPages);
1453 |
1454 | var _usePlugin = __webpack_require__(7);
1455 |
1456 | var _usePlugin2 = _interopRequireDefault(_usePlugin);
1457 |
1458 | var _log = __webpack_require__(6);
1459 |
1460 | var _log2 = _interopRequireDefault(_log);
1461 |
1462 | var _utils = __webpack_require__(0);
1463 |
1464 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1465 |
1466 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1467 |
1468 | var Swup = function () {
1469 | function Swup(setOptions) {
1470 | _classCallCheck(this, Swup);
1471 |
1472 | // default options
1473 | var defaults = {
1474 | cache: true,
1475 | animationSelector: '[class*="transition-"]',
1476 | elements: ['#swup'],
1477 | pageClassPrefix: '',
1478 | debugMode: false,
1479 | scroll: true,
1480 |
1481 | doScrollingRightAway: false,
1482 | animateScroll: true,
1483 | scrollFriction: .3,
1484 | scrollAcceleration: .04,
1485 |
1486 | preload: true,
1487 | support: true,
1488 | plugins: [],
1489 |
1490 | skipPopStateHandling: function skipPopStateHandling(event) {
1491 | if (event.state && event.state.source == "swup") {
1492 | return false;
1493 | }
1494 | return true;
1495 | },
1496 | animateHistoryBrowsing: false,
1497 |
1498 | LINK_SELECTOR: 'a[href^="' + window.location.origin + '"]:not([data-no-swup]), a[href^="/"]:not([data-no-swup]), a[href^="#"]:not([data-no-swup])',
1499 | FORM_SELECTOR: 'form[data-swup-form]'
1500 |
1501 | /**
1502 | * current transition object
1503 | */
1504 | };this.transition = {};
1505 |
1506 | var options = _extends({}, defaults, setOptions);
1507 |
1508 | /**
1509 | * handler arrays
1510 | */
1511 | this._handlers = {
1512 | animationInDone: [],
1513 | animationInStart: [],
1514 | animationOutDone: [],
1515 | animationOutStart: [],
1516 | animationSkipped: [],
1517 | clickLink: [],
1518 | contentReplaced: [],
1519 | disabled: [],
1520 | enabled: [],
1521 | hoverLink: [],
1522 | openPageInNewTab: [],
1523 | pageLoaded: [],
1524 | pagePreloaded: [],
1525 | pageRetrievedFromCache: [],
1526 | pageView: [],
1527 | popState: [],
1528 | samePage: [],
1529 | samePageWithHash: [],
1530 | scrollDone: [],
1531 | scrollStart: [],
1532 | serverError: [],
1533 | submitForm: [],
1534 | willReplaceContent: []
1535 | };
1536 |
1537 | /**
1538 | * helper variables
1539 | */
1540 | // id of element to scroll to after render
1541 | this.scrollToElement = null;
1542 | // promise used for preload, so no new loading of the same page starts while page is loading
1543 | this.preloadPromise = null;
1544 | // save options
1545 | this.options = options;
1546 | // plugins array
1547 | this.plugins = [];
1548 |
1549 | /**
1550 | * make modules accessible in instance
1551 | */
1552 | this.getUrl = _getUrl2.default;
1553 | this.cache = new _Cache2.default();
1554 | this.link = new _Link2.default();
1555 | this.transitionEndEvent = (0, _transitionEnd2.default)();
1556 | this.getDataFromHtml = _getDataFromHtml2.default;
1557 | this.getPage = _request2.default;
1558 | this.scrollTo = _scrollTo2.default;
1559 | this.loadPage = _loadPage2.default;
1560 | this.renderPage = _renderPage2.default;
1561 | this.createState = _createState2.default;
1562 | this.triggerEvent = _triggerEvent2.default;
1563 | this.classify = _classify2.default;
1564 | this.doScrolling = _doScrolling2.default;
1565 | this.markSwupElements = _markSwupElements2.default;
1566 | this.on = _on2.default;
1567 | this.off = _off2.default;
1568 | this.updateTransition = _updateTransition2.default;
1569 | this.preloadPage = _preloadPage2.default;
1570 | this.preloadPages = _preloadPages2.default;
1571 | this.usePlugin = _usePlugin2.default;
1572 | this.log = _log2.default;
1573 | this.enable = this.enable;
1574 | this.destroy = this.destroy;
1575 |
1576 | // attach instance to window in debug mode
1577 | if (this.options.debugMode) {
1578 | window.swup = this;
1579 | }
1580 |
1581 | this.getUrl();
1582 | this.enable();
1583 | }
1584 |
1585 | _createClass(Swup, [{
1586 | key: 'enable',
1587 | value: function enable() {
1588 | var _this = this;
1589 |
1590 | /**
1591 | * support check
1592 | */
1593 | if (this.options.support) {
1594 | // check pushState support
1595 | if (!('pushState' in window.history)) {
1596 | console.warn('pushState is not supported');
1597 | return;
1598 | }
1599 | // check transitionEnd support
1600 | if ((0, _transitionEnd2.default)()) {
1601 | this.transitionEndEvent = (0, _transitionEnd2.default)();
1602 | } else {
1603 | console.warn('transitionEnd detection is not supported');
1604 | return;
1605 | }
1606 | // check Promise support
1607 | if (typeof Promise === "undefined" || Promise.toString().indexOf("[native code]") === -1) {
1608 | console.warn('Promise is not supported');
1609 | return;
1610 | }
1611 | }
1612 |
1613 | // variable to keep event listeners from "delegate"
1614 | this.delegatedListeners = {};
1615 |
1616 | /**
1617 | * link click handler
1618 | */
1619 | this.delegatedListeners.click = (0, _delegate2.default)(document, this.options.LINK_SELECTOR, 'click', this.linkClickHandler.bind(this));
1620 |
1621 | /**
1622 | * link mouseover handler (preload)
1623 | */
1624 | this.delegatedListeners.mouseover = (0, _delegate2.default)(document.body, this.options.LINK_SELECTOR, 'mouseover', this.linkMouseoverHandler.bind(this));
1625 |
1626 | /**
1627 | * form submit handler
1628 | */
1629 | this.delegatedListeners.formSubmit = (0, _delegate2.default)(document, this.options.FORM_SELECTOR, 'submit', this.formSubmitHandler.bind(this));
1630 |
1631 | /**
1632 | * popstate handler
1633 | */
1634 | window.addEventListener('popstate', this.popStateHandler.bind(this));
1635 |
1636 | /**
1637 | * initial save to cache
1638 | */
1639 | var page = this.getDataFromHtml(document.documentElement.outerHTML);
1640 | page.url = this.currentUrl;
1641 | if (this.options.cache) {
1642 | this.cache.cacheUrl(page, this.options.debugMode);
1643 | }
1644 |
1645 | /**
1646 | * mark swup blocks in html
1647 | */
1648 | this.markSwupElements(document.documentElement);
1649 |
1650 | /**
1651 | * enable plugins from options
1652 | */
1653 | this.options.plugins.forEach(function (item) {
1654 | return _this.usePlugin(item);
1655 | });
1656 |
1657 | /**
1658 | * modify initial history record
1659 | */
1660 | window.history.replaceState(Object.assign({}, window.history.state, {
1661 | url: window.location.href,
1662 | random: Math.random(),
1663 | source: "swup"
1664 | }), document.title, window.location.href);
1665 |
1666 | /**
1667 | * Disable browser scroll control on popstates when animateHistoryBrowsing option is enabled
1668 | */
1669 | if (this.options.animateHistoryBrowsing) {
1670 | window.history.scrollRestoration = "manual";
1671 | }
1672 |
1673 | /**
1674 | * trigger enabled event
1675 | */
1676 | this.triggerEvent('enabled');
1677 | document.documentElement.classList.add('swup-enabled');
1678 |
1679 | /**
1680 | * trigger page view event
1681 | */
1682 | this.triggerEvent('pageView');
1683 |
1684 | /**
1685 | * preload pages if possible
1686 | */
1687 | this.preloadPages();
1688 | }
1689 | }, {
1690 | key: 'destroy',
1691 | value: function destroy() {
1692 | // remove delegated listeners
1693 | this.delegatedListeners.click.destroy();
1694 | this.delegatedListeners.mouseover.destroy();
1695 |
1696 | // remove popstate listener
1697 | window.removeEventListener('popstate', this.popStateHandler.bind(this));
1698 |
1699 | // empty cache
1700 | this.cache.empty();
1701 |
1702 | // remove swup data atributes from blocks
1703 | (0, _utils.queryAll)('[data-swup]').forEach(function (element) {
1704 | delete element.dataset.swup;
1705 | });
1706 |
1707 | // remove handlers
1708 | this.off();
1709 |
1710 | this.triggerEvent('disabled');
1711 | document.documentElement.classList.remove('swup-enabled');
1712 | }
1713 | }, {
1714 | key: 'linkClickHandler',
1715 | value: function linkClickHandler(event) {
1716 | // no control key pressed
1717 | if (!event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey) {
1718 | // index of pressed button needs to be checked because Firefox triggers click on all mouse buttons
1719 | if (event.button === 0) {
1720 | this.triggerEvent('clickLink', event);
1721 | var link = new _Link2.default();
1722 | event.preventDefault();
1723 | link.setPath(event.delegateTarget.href);
1724 |
1725 | if (link.getAddress() == this.currentUrl || link.getAddress() == '') {
1726 | // link to the same URL
1727 | if (link.getHash() != '') {
1728 | // link to the same URL with hash
1729 | this.triggerEvent('samePageWithHash', event);
1730 | var element = document.querySelector(link.getHash());
1731 | if (element != null) {
1732 | // referenced element found
1733 | if (this.options.scroll) {
1734 | var top = element.getBoundingClientRect().top + window.pageYOffset;
1735 | this.scrollTo(document.body, top);
1736 | }
1737 | history.replaceState({
1738 | url: link.getAddress() + link.getHash(),
1739 | random: Math.random(),
1740 | source: "swup"
1741 | }, document.title, link.getAddress() + link.getHash());
1742 | } else {
1743 | // referenced element not found
1744 | console.warn('Element for offset not found (' + link.getHash() + ')');
1745 | }
1746 | } else {
1747 | // link to the same URL without hash
1748 | this.triggerEvent('samePage', event);
1749 | if (this.options.scroll) {
1750 | this.scrollTo(document.body, 0, 1);
1751 | }
1752 | }
1753 | } else {
1754 | // link to different url
1755 | if (link.getHash() != '') {
1756 | this.scrollToElement = link.getHash();
1757 | }
1758 |
1759 | // get custom transition from data
1760 | var customTransition = event.delegateTarget.dataset.swupTransition;
1761 |
1762 | // load page
1763 | this.loadPage({ url: link.getAddress(), customTransition: customTransition }, false);
1764 | }
1765 | }
1766 | } else {
1767 | // open in new tab (do nothing)
1768 | this.triggerEvent('openPageInNewTab', event);
1769 | }
1770 | }
1771 | }, {
1772 | key: 'linkMouseoverHandler',
1773 | value: function linkMouseoverHandler(event) {
1774 | var _this2 = this;
1775 |
1776 | this.triggerEvent('hoverLink', event);
1777 | if (this.options.preload) {
1778 | var link = new _Link2.default();
1779 | link.setPath(event.delegateTarget.href);
1780 | if (link.getAddress() != this.currentUrl && !this.cache.exists(link.getAddress()) && this.preloadPromise == null) {
1781 | this.preloadPromise = new Promise(function (resolve, reject) {
1782 | _this2.getPage({ url: link.getAddress() }, function (response, request) {
1783 | if (request.status === 500) {
1784 | _this2.triggerEvent('serverError', event);
1785 | reject(link.getAddress());
1786 | return;
1787 | } else {
1788 | // get json data
1789 | var page = _this2.getDataFromHtml(response, request);
1790 | if (page != null) {
1791 | page.url = link.getAddress();
1792 | _this2.cache.cacheUrl(page, _this2.options.debugMode);
1793 | _this2.triggerEvent('pagePreloaded', event);
1794 | } else {
1795 | reject(link.getAddress());
1796 | return;
1797 | }
1798 | }
1799 | resolve();
1800 | _this2.preloadPromise = null;
1801 | });
1802 | });
1803 | this.preloadPromise.route = link.getAddress();
1804 | }
1805 | }
1806 | }
1807 | }, {
1808 | key: 'formSubmitHandler',
1809 | value: function formSubmitHandler(event) {
1810 | // no control key pressed
1811 | if (!event.metaKey) {
1812 | this.triggerEvent('submitForm', event);
1813 | event.preventDefault();
1814 | var form = event.target;
1815 | var formData = new FormData(form);
1816 |
1817 | var link = new _Link2.default();
1818 | link.setPath(form.action);
1819 |
1820 | if (link.getHash() != '') {
1821 | this.scrollToElement = link.getHash();
1822 | }
1823 |
1824 | if (form.method.toLowerCase() != "get") {
1825 | // remove page from cache
1826 | this.cache.remove(link.getAddress());
1827 |
1828 | // send data
1829 | this.loadPage({
1830 | url: link.getAddress(),
1831 | method: form.method,
1832 | data: formData
1833 | });
1834 | } else {
1835 | // create base url
1836 | var url = link.getAddress() || window.location.href;
1837 | var inputs = (0, _utils.queryAll)('input, select', form);
1838 | if (url.indexOf('?') == -1) {
1839 | url += "?";
1840 | } else {
1841 | url += "&";
1842 | }
1843 |
1844 | // add form data to url
1845 | inputs.forEach(function (input) {
1846 | if (input.type == "checkbox" || input.type == "radio") {
1847 | if (input.checked) {
1848 | url += encodeURIComponent(input.name) + "=" + encodeURIComponent(input.value) + "&";
1849 | }
1850 | } else {
1851 | url += encodeURIComponent(input.name) + "=" + encodeURIComponent(input.value) + "&";
1852 | }
1853 | });
1854 |
1855 | // remove last "&"
1856 | url = url.slice(0, -1);
1857 |
1858 | // remove page from cache
1859 | this.cache.remove(url);
1860 |
1861 | // send data
1862 | this.loadPage({
1863 | url: url
1864 | });
1865 | }
1866 | } else {
1867 | this.triggerEvent('openFormSubmitInNewTab', event);
1868 | }
1869 | }
1870 | }, {
1871 | key: 'popStateHandler',
1872 | value: function popStateHandler(event) {
1873 | var link = new _Link2.default();
1874 | if (this.options.skipPopStateHandling(event)) return;
1875 | link.setPath(event.state ? event.state.url : window.location.pathname);
1876 | if (link.getHash() != '') {
1877 | this.scrollToElement = link.getHash();
1878 | } else {
1879 | event.preventDefault();
1880 | }
1881 | this.triggerEvent('popState', event);
1882 | this.loadPage({ url: link.getAddress() }, event);
1883 | }
1884 | }]);
1885 |
1886 | return Swup;
1887 | }();
1888 |
1889 | exports.default = Swup;
1890 |
1891 | /***/ }),
1892 | /* 29 */
1893 | /***/ (function(module, exports, __webpack_require__) {
1894 |
1895 | "use strict";
1896 |
1897 |
1898 | Object.defineProperty(exports, "__esModule", {
1899 | value: true
1900 | });
1901 |
1902 | 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; };
1903 |
1904 | var _swup = __webpack_require__(28);
1905 |
1906 | var _swup2 = _interopRequireDefault(_swup);
1907 |
1908 | var _loadPage = __webpack_require__(5);
1909 |
1910 | var _loadPage2 = _interopRequireDefault(_loadPage);
1911 |
1912 | var _renderPage = __webpack_require__(4);
1913 |
1914 | var _renderPage2 = _interopRequireDefault(_renderPage);
1915 |
1916 | var _getAnimation = __webpack_require__(3);
1917 |
1918 | var _getAnimation2 = _interopRequireDefault(_getAnimation);
1919 |
1920 | var _createAnimationPromise = __webpack_require__(2);
1921 |
1922 | var _createAnimationPromise2 = _interopRequireDefault(_createAnimationPromise);
1923 |
1924 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1925 |
1926 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1927 |
1928 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
1929 |
1930 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
1931 |
1932 | // modules
1933 |
1934 |
1935 | var Swupjs = function (_Swup) {
1936 | _inherits(Swupjs, _Swup);
1937 |
1938 | function Swupjs(setOptions) {
1939 | _classCallCheck(this, Swupjs);
1940 |
1941 | var defaults = {
1942 | animations: {
1943 | '*': {
1944 | out: function out(next) {
1945 | next();
1946 | },
1947 | in: function _in(next) {
1948 | next();
1949 | }
1950 | }
1951 | }
1952 | };
1953 |
1954 | var options = _extends({}, defaults, setOptions);
1955 |
1956 | var _this = _possibleConstructorReturn(this, (Swupjs.__proto__ || Object.getPrototypeOf(Swupjs)).call(this, options));
1957 |
1958 | _this.loadPage = _loadPage2.default;
1959 | _this.renderPage = _renderPage2.default;
1960 | _this.getAnimation = _getAnimation2.default;
1961 | _this.createAnimationPromise = _createAnimationPromise2.default;
1962 |
1963 |
1964 | _this.animations = options.animations;
1965 | return _this;
1966 | }
1967 |
1968 | /**
1969 | * make modules accessible in instance
1970 | */
1971 |
1972 |
1973 | return Swupjs;
1974 | }(_swup2.default);
1975 |
1976 | exports.default = Swupjs;
1977 |
1978 | /***/ }),
1979 | /* 30 */
1980 | /***/ (function(module, exports, __webpack_require__) {
1981 |
1982 | "use strict";
1983 |
1984 |
1985 | var _index = __webpack_require__(29);
1986 |
1987 | var _index2 = _interopRequireDefault(_index);
1988 |
1989 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
1990 |
1991 | module.exports = _index2.default; // this is here for webpack to expose Swupjs as window.Swupjs
1992 |
1993 | /***/ })
1994 | /******/ ]);
1995 | });
--------------------------------------------------------------------------------