swup 2.0.14 → 2.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/swup.js CHANGED
@@ -91,7 +91,7 @@ return /******/ (function(modules) { // webpackBootstrap
91
91
  /******/
92
92
  /******/
93
93
  /******/ // Load entry module and return exports
94
- /******/ return __webpack_require__(__webpack_require__.s = 2);
94
+ /******/ return __webpack_require__(__webpack_require__.s = 3);
95
95
  /******/ })
96
96
  /************************************************************************/
97
97
  /******/ ([
@@ -104,37 +104,45 @@ return /******/ (function(modules) { // webpackBootstrap
104
104
  Object.defineProperty(exports, "__esModule", {
105
105
  value: true
106
106
  });
107
- exports.Link = exports.markSwupElements = exports.getCurrentUrl = exports.transitionEnd = exports.fetch = exports.getDataFromHtml = exports.createHistoryRecord = exports.classify = undefined;
107
+ exports.Link = exports.markSwupElements = exports.normalizeUrl = exports.getCurrentUrl = exports.transitionProperty = exports.transitionEnd = exports.fetch = exports.getDataFromHtml = exports.createHistoryRecord = exports.classify = undefined;
108
108
 
109
- var _classify = __webpack_require__(8);
109
+ var _classify = __webpack_require__(7);
110
110
 
111
111
  var _classify2 = _interopRequireDefault(_classify);
112
112
 
113
- var _createHistoryRecord = __webpack_require__(9);
113
+ var _createHistoryRecord = __webpack_require__(8);
114
114
 
115
115
  var _createHistoryRecord2 = _interopRequireDefault(_createHistoryRecord);
116
116
 
117
- var _getDataFromHtml = __webpack_require__(10);
117
+ var _getDataFromHtml = __webpack_require__(9);
118
118
 
119
119
  var _getDataFromHtml2 = _interopRequireDefault(_getDataFromHtml);
120
120
 
121
- var _fetch = __webpack_require__(11);
121
+ var _fetch = __webpack_require__(10);
122
122
 
123
123
  var _fetch2 = _interopRequireDefault(_fetch);
124
124
 
125
- var _transitionEnd = __webpack_require__(12);
125
+ var _transitionEnd = __webpack_require__(11);
126
126
 
127
127
  var _transitionEnd2 = _interopRequireDefault(_transitionEnd);
128
128
 
129
+ var _transitionProperty = __webpack_require__(12);
130
+
131
+ var _transitionProperty2 = _interopRequireDefault(_transitionProperty);
132
+
129
133
  var _getCurrentUrl = __webpack_require__(13);
130
134
 
131
135
  var _getCurrentUrl2 = _interopRequireDefault(_getCurrentUrl);
132
136
 
133
- var _markSwupElements = __webpack_require__(14);
137
+ var _normalizeUrl = __webpack_require__(14);
138
+
139
+ var _normalizeUrl2 = _interopRequireDefault(_normalizeUrl);
140
+
141
+ var _markSwupElements = __webpack_require__(15);
134
142
 
135
143
  var _markSwupElements2 = _interopRequireDefault(_markSwupElements);
136
144
 
137
- var _Link = __webpack_require__(15);
145
+ var _Link = __webpack_require__(2);
138
146
 
139
147
  var _Link2 = _interopRequireDefault(_Link);
140
148
 
@@ -145,7 +153,9 @@ var createHistoryRecord = exports.createHistoryRecord = _createHistoryRecord2.de
145
153
  var getDataFromHtml = exports.getDataFromHtml = _getDataFromHtml2.default;
146
154
  var fetch = exports.fetch = _fetch2.default;
147
155
  var transitionEnd = exports.transitionEnd = _transitionEnd2.default;
156
+ var transitionProperty = exports.transitionProperty = _transitionProperty2.default;
148
157
  var getCurrentUrl = exports.getCurrentUrl = _getCurrentUrl2.default;
158
+ var normalizeUrl = exports.normalizeUrl = _normalizeUrl2.default;
149
159
  var markSwupElements = exports.markSwupElements = _markSwupElements2.default;
150
160
  var Link = exports.Link = _Link2.default;
151
161
 
@@ -179,6 +189,14 @@ var queryAll = exports.queryAll = function queryAll(selector) {
179
189
  return Array.prototype.slice.call(context.querySelectorAll(selector));
180
190
  };
181
191
 
192
+ var escapeCssIdentifier = exports.escapeCssIdentifier = function escapeCssIdentifier(ident) {
193
+ if (window.CSS && window.CSS.escape) {
194
+ return CSS.escape(ident);
195
+ } else {
196
+ return ident;
197
+ }
198
+ };
199
+
182
200
  /***/ }),
183
201
  /* 2 */
184
202
  /***/ (function(module, exports, __webpack_require__) {
@@ -186,7 +204,69 @@ var queryAll = exports.queryAll = function queryAll(selector) {
186
204
  "use strict";
187
205
 
188
206
 
189
- var _index = __webpack_require__(3);
207
+ Object.defineProperty(exports, "__esModule", {
208
+ value: true
209
+ });
210
+
211
+ 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; }; }();
212
+
213
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
214
+
215
+ var Link = function () {
216
+ function Link(elementOrUrl) {
217
+ _classCallCheck(this, Link);
218
+
219
+ if (elementOrUrl instanceof Element || elementOrUrl instanceof SVGElement) {
220
+ this.link = elementOrUrl;
221
+ } else {
222
+ this.link = document.createElement('a');
223
+ this.link.href = elementOrUrl;
224
+ }
225
+ }
226
+
227
+ _createClass(Link, [{
228
+ key: 'getPath',
229
+ value: function getPath() {
230
+ var path = this.link.pathname;
231
+ if (path[0] !== '/') {
232
+ path = '/' + path;
233
+ }
234
+ return path;
235
+ }
236
+ }, {
237
+ key: 'getAddress',
238
+ value: function getAddress() {
239
+ var path = this.link.pathname + this.link.search;
240
+
241
+ if (this.link.getAttribute('xlink:href')) {
242
+ path = this.link.getAttribute('xlink:href');
243
+ }
244
+
245
+ if (path[0] !== '/') {
246
+ path = '/' + path;
247
+ }
248
+ return path;
249
+ }
250
+ }, {
251
+ key: 'getHash',
252
+ value: function getHash() {
253
+ return this.link.hash;
254
+ }
255
+ }]);
256
+
257
+ return Link;
258
+ }();
259
+
260
+ exports.default = Link;
261
+
262
+ /***/ }),
263
+ /* 3 */
264
+ /***/ (function(module, exports, __webpack_require__) {
265
+
266
+ "use strict";
267
+
268
+
269
+ var _index = __webpack_require__(4);
190
270
 
191
271
  var _index2 = _interopRequireDefault(_index);
192
272
 
@@ -195,7 +275,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
195
275
  module.exports = _index2.default; // this is here for webpack to expose Swup as window.Swup
196
276
 
197
277
  /***/ }),
198
- /* 3 */
278
+ /* 4 */
199
279
  /***/ (function(module, exports, __webpack_require__) {
200
280
 
201
281
  "use strict";
@@ -212,47 +292,51 @@ var _createClass = function () { function defineProperties(target, props) { for
212
292
  // modules
213
293
 
214
294
 
215
- var _delegate = __webpack_require__(4);
295
+ var _delegateIt = __webpack_require__(5);
216
296
 
217
- var _delegate2 = _interopRequireDefault(_delegate);
297
+ var _delegateIt2 = _interopRequireDefault(_delegateIt);
218
298
 
219
299
  var _Cache = __webpack_require__(6);
220
300
 
221
301
  var _Cache2 = _interopRequireDefault(_Cache);
222
302
 
223
- var _loadPage = __webpack_require__(7);
303
+ var _loadPage = __webpack_require__(16);
224
304
 
225
305
  var _loadPage2 = _interopRequireDefault(_loadPage);
226
306
 
227
- var _renderPage = __webpack_require__(16);
307
+ var _renderPage = __webpack_require__(17);
228
308
 
229
309
  var _renderPage2 = _interopRequireDefault(_renderPage);
230
310
 
231
- var _triggerEvent = __webpack_require__(17);
311
+ var _triggerEvent = __webpack_require__(18);
232
312
 
233
313
  var _triggerEvent2 = _interopRequireDefault(_triggerEvent);
234
314
 
235
- var _on = __webpack_require__(18);
315
+ var _on = __webpack_require__(19);
236
316
 
237
317
  var _on2 = _interopRequireDefault(_on);
238
318
 
239
- var _off = __webpack_require__(19);
319
+ var _off = __webpack_require__(20);
240
320
 
241
321
  var _off2 = _interopRequireDefault(_off);
242
322
 
243
- var _updateTransition = __webpack_require__(20);
323
+ var _updateTransition = __webpack_require__(21);
244
324
 
245
325
  var _updateTransition2 = _interopRequireDefault(_updateTransition);
246
326
 
247
- var _getAnimationPromises = __webpack_require__(21);
327
+ var _getAnchorElement = __webpack_require__(22);
328
+
329
+ var _getAnchorElement2 = _interopRequireDefault(_getAnchorElement);
330
+
331
+ var _getAnimationPromises = __webpack_require__(23);
248
332
 
249
333
  var _getAnimationPromises2 = _interopRequireDefault(_getAnimationPromises);
250
334
 
251
- var _getPageData = __webpack_require__(22);
335
+ var _getPageData = __webpack_require__(24);
252
336
 
253
337
  var _getPageData2 = _interopRequireDefault(_getPageData);
254
338
 
255
- var _plugins = __webpack_require__(23);
339
+ var _plugins = __webpack_require__(25);
256
340
 
257
341
  var _utils = __webpack_require__(1);
258
342
 
@@ -310,7 +394,7 @@ var Swup = function () {
310
394
  willReplaceContent: []
311
395
  };
312
396
 
313
- // variable for id of element to scroll to after render
397
+ // variable for anchor to scroll to after render
314
398
  this.scrollToElement = null;
315
399
  // variable for promise used for preload, so no new loading of the same page starts while page is loading
316
400
  this.preloadPromise = null;
@@ -336,6 +420,7 @@ var Swup = function () {
336
420
  this.updateTransition = _updateTransition2.default;
337
421
  this.getAnimationPromises = _getAnimationPromises2.default;
338
422
  this.getPageData = _getPageData2.default;
423
+ this.getAnchorElement = _getAnchorElement2.default;
339
424
  this.log = function () {}; // here so it can be used by plugins
340
425
  this.use = _plugins.use;
341
426
  this.unuse = _plugins.unuse;
@@ -357,13 +442,13 @@ var Swup = function () {
357
442
  }
358
443
 
359
444
  // add event listeners
360
- this.delegatedListeners.click = (0, _delegate2.default)(document, this.options.linkSelector, 'click', this.linkClickHandler.bind(this));
445
+ this.delegatedListeners.click = (0, _delegateIt2.default)(document, this.options.linkSelector, 'click', this.linkClickHandler.bind(this));
361
446
  window.addEventListener('popstate', this.boundPopStateHandler);
362
447
 
363
448
  // initial save to cache
364
- var page = (0, _helpers.getDataFromHtml)(document.documentElement.outerHTML, this.options.containers);
365
- page.url = page.responseURL = (0, _helpers.getCurrentUrl)();
366
449
  if (this.options.cache) {
450
+ var page = (0, _helpers.getDataFromHtml)(document.documentElement.outerHTML, this.options.containers);
451
+ page.url = page.responseURL = (0, _helpers.getCurrentUrl)();
367
452
  this.cache.cacheUrl(page);
368
453
  }
369
454
 
@@ -439,7 +524,7 @@ var Swup = function () {
439
524
  if (link.getHash() != '') {
440
525
  // link to the same URL with hash
441
526
  this.triggerEvent('samePageWithHash', event);
442
- var element = document.querySelector(link.getHash());
527
+ var element = (0, _getAnchorElement2.default)(link.getHash());
443
528
  if (element != null) {
444
529
  history.replaceState({
445
530
  url: link.getAddress() + link.getHash(),
@@ -493,92 +578,96 @@ var Swup = function () {
493
578
  exports.default = Swup;
494
579
 
495
580
  /***/ }),
496
- /* 4 */
497
- /***/ (function(module, exports, __webpack_require__) {
581
+ /* 5 */
582
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
498
583
 
499
- var closest = __webpack_require__(5);
500
-
501
- /**
502
- * Delegates event to a selector.
503
- *
504
- * @param {Element} element
505
- * @param {String} selector
506
- * @param {String} type
507
- * @param {Function} callback
508
- * @param {Boolean} useCapture
509
- * @return {Object}
510
- */
511
- function delegate(element, selector, type, callback, useCapture) {
512
- var listenerFn = listener.apply(this, arguments);
513
-
514
- element.addEventListener(type, listenerFn, useCapture);
515
-
516
- return {
517
- destroy: function() {
518
- element.removeEventListener(type, listenerFn, useCapture);
519
- }
584
+ "use strict";
585
+ __webpack_require__.r(__webpack_exports__);
586
+ /** Keeps track of raw listeners added to the base elements to avoid duplication */
587
+ const ledger = new WeakMap();
588
+ function editLedger(wanted, baseElement, callback, setup) {
589
+ var _a, _b;
590
+ if (!wanted && !ledger.has(baseElement)) {
591
+ return false;
592
+ }
593
+ const elementMap = (_a = ledger.get(baseElement)) !== null && _a !== void 0 ? _a : new WeakMap();
594
+ ledger.set(baseElement, elementMap);
595
+ if (!wanted && !ledger.has(baseElement)) {
596
+ return false;
597
+ }
598
+ const setups = (_b = elementMap.get(callback)) !== null && _b !== void 0 ? _b : new Set();
599
+ elementMap.set(callback, setups);
600
+ const existed = setups.has(setup);
601
+ if (wanted) {
602
+ setups.add(setup);
520
603
  }
604
+ else {
605
+ setups.delete(setup);
606
+ }
607
+ return existed && wanted;
521
608
  }
522
-
523
- /**
524
- * Finds closest match and invokes callback.
525
- *
526
- * @param {Element} element
527
- * @param {String} selector
528
- * @param {String} type
529
- * @param {Function} callback
530
- * @return {Function}
531
- */
532
- function listener(element, selector, type, callback) {
533
- return function(e) {
534
- e.delegateTarget = closest(e.target, selector);
535
-
536
- if (e.delegateTarget) {
537
- callback.call(element, e);
609
+ function isEventTarget(elements) {
610
+ return typeof elements.addEventListener === 'function';
611
+ }
612
+ function safeClosest(event, selector) {
613
+ let target = event.target;
614
+ if (target instanceof Text) {
615
+ target = target.parentElement;
616
+ }
617
+ if (target instanceof Element && event.currentTarget instanceof Element) {
618
+ // `.closest()` may match ancestors of `currentTarget` but we only need its children
619
+ const closest = target.closest(selector);
620
+ if (closest && event.currentTarget.contains(closest)) {
621
+ return closest;
538
622
  }
539
623
  }
540
624
  }
541
-
542
- module.exports = delegate;
543
-
544
-
545
- /***/ }),
546
- /* 5 */
547
- /***/ (function(module, exports) {
548
-
549
- var DOCUMENT_NODE_TYPE = 9;
550
-
551
- /**
552
- * A polyfill for Element.matches()
553
- */
554
- if (typeof Element !== 'undefined' && !Element.prototype.matches) {
555
- var proto = Element.prototype;
556
-
557
- proto.matches = proto.matchesSelector ||
558
- proto.mozMatchesSelector ||
559
- proto.msMatchesSelector ||
560
- proto.oMatchesSelector ||
561
- proto.webkitMatchesSelector;
562
- }
563
-
564
- /**
565
- * Finds the closest parent that matches a selector.
566
- *
567
- * @param {Element} element
568
- * @param {String} selector
569
- * @return {Function}
570
- */
571
- function closest (element, selector) {
572
- while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {
573
- if (typeof element.matches === 'function' &&
574
- element.matches(selector)) {
575
- return element;
625
+ // This type isn't exported as a declaration, so it needs to be duplicated above
626
+ function delegate(base, selector, type, callback, options) {
627
+ // Handle Selector-based usage
628
+ if (typeof base === 'string') {
629
+ base = document.querySelectorAll(base);
630
+ }
631
+ // Handle Array-like based usage
632
+ if (!isEventTarget(base)) {
633
+ const subscriptions = Array.prototype.map.call(base, (element) => delegate(element, selector, type, callback, options));
634
+ return {
635
+ destroy() {
636
+ for (const subscription of subscriptions) {
637
+ subscription.destroy();
638
+ }
639
+ },
640
+ };
641
+ }
642
+ // `document` should never be the base, it's just an easy way to define "global event listeners"
643
+ const baseElement = base instanceof Document ? base.documentElement : base;
644
+ // Handle the regular Element usage
645
+ const capture = Boolean(typeof options === 'object' ? options.capture : options);
646
+ const listenerFn = (event) => {
647
+ const delegateTarget = safeClosest(event, selector);
648
+ if (delegateTarget) {
649
+ event.delegateTarget = delegateTarget;
650
+ callback.call(baseElement, event);
576
651
  }
577
- element = element.parentNode;
652
+ };
653
+ // Drop unsupported `once` option https://github.com/fregante/delegate-it/pull/28#discussion_r863467939
654
+ if (typeof options === 'object') {
655
+ delete options.once;
656
+ }
657
+ const setup = JSON.stringify({ selector, type, capture });
658
+ const isAlreadyListening = editLedger(true, baseElement, callback, setup);
659
+ const delegateSubscription = {
660
+ destroy() {
661
+ baseElement.removeEventListener(type, listenerFn, options);
662
+ editLedger(false, baseElement, callback, setup);
663
+ },
664
+ };
665
+ if (!isAlreadyListening) {
666
+ baseElement.addEventListener(type, listenerFn, options);
578
667
  }
668
+ return delegateSubscription;
579
669
  }
580
-
581
- module.exports = closest;
670
+ /* harmony default export */ __webpack_exports__["default"] = (delegate);
582
671
 
583
672
 
584
673
  /***/ }),
@@ -591,9 +680,12 @@ module.exports = closest;
591
680
  Object.defineProperty(exports, "__esModule", {
592
681
  value: true
593
682
  });
683
+ exports.Cache = undefined;
594
684
 
595
685
  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; }; }();
596
686
 
687
+ var _helpers = __webpack_require__(0);
688
+
597
689
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
598
690
 
599
691
  var Cache = exports.Cache = function () {
@@ -607,6 +699,7 @@ var Cache = exports.Cache = function () {
607
699
  _createClass(Cache, [{
608
700
  key: 'cacheUrl',
609
701
  value: function cacheUrl(page) {
702
+ page.url = (0, _helpers.normalizeUrl)(page.url);
610
703
  if (page.url in this.pages === false) {
611
704
  this.pages[page.url] = page;
612
705
  }
@@ -616,16 +709,18 @@ var Cache = exports.Cache = function () {
616
709
  }, {
617
710
  key: 'getPage',
618
711
  value: function getPage(url) {
712
+ url = (0, _helpers.normalizeUrl)(url);
619
713
  return this.pages[url];
620
714
  }
621
715
  }, {
622
716
  key: 'getCurrentPage',
623
717
  value: function getCurrentPage() {
624
- return this.getPage(window.location.pathname + window.location.search);
718
+ return this.getPage((0, _helpers.getCurrentUrl)());
625
719
  }
626
720
  }, {
627
721
  key: 'exists',
628
722
  value: function exists(url) {
723
+ url = (0, _helpers.normalizeUrl)(url);
629
724
  return url in this.pages;
630
725
  }
631
726
  }, {
@@ -654,130 +749,6 @@ exports.default = Cache;
654
749
  "use strict";
655
750
 
656
751
 
657
- Object.defineProperty(exports, "__esModule", {
658
- value: true
659
- });
660
-
661
- 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; };
662
-
663
- var _helpers = __webpack_require__(0);
664
-
665
- var loadPage = function loadPage(data, popstate) {
666
- var _this = this;
667
-
668
- // create array for storing animation promises
669
- var animationPromises = [],
670
- xhrPromise = void 0;
671
- var animateOut = function animateOut() {
672
- _this.triggerEvent('animationOutStart');
673
-
674
- // handle classes
675
- document.documentElement.classList.add('is-changing');
676
- document.documentElement.classList.add('is-leaving');
677
- document.documentElement.classList.add('is-animating');
678
- if (popstate) {
679
- document.documentElement.classList.add('is-popstate');
680
- }
681
- document.documentElement.classList.add('to-' + (0, _helpers.classify)(data.url));
682
-
683
- // animation promise stuff
684
- animationPromises = _this.getAnimationPromises('out');
685
- Promise.all(animationPromises).then(function () {
686
- _this.triggerEvent('animationOutDone');
687
- });
688
-
689
- // create history record if this is not a popstate call
690
- if (!popstate) {
691
- // create pop element with or without anchor
692
- var state = void 0;
693
- if (_this.scrollToElement != null) {
694
- state = data.url + _this.scrollToElement;
695
- } else {
696
- state = data.url;
697
- }
698
-
699
- (0, _helpers.createHistoryRecord)(state);
700
- }
701
- };
702
-
703
- this.triggerEvent('transitionStart', popstate);
704
-
705
- // set transition object
706
- if (data.customTransition != null) {
707
- this.updateTransition(window.location.pathname, data.url, data.customTransition);
708
- document.documentElement.classList.add('to-' + (0, _helpers.classify)(data.customTransition));
709
- } else {
710
- this.updateTransition(window.location.pathname, data.url);
711
- }
712
-
713
- // start/skip animation
714
- if (!popstate || this.options.animateHistoryBrowsing) {
715
- animateOut();
716
- } else {
717
- this.triggerEvent('animationSkipped');
718
- }
719
-
720
- // start/skip loading of page
721
- if (this.cache.exists(data.url)) {
722
- xhrPromise = new Promise(function (resolve) {
723
- resolve();
724
- });
725
- this.triggerEvent('pageRetrievedFromCache');
726
- } else {
727
- if (!this.preloadPromise || this.preloadPromise.route != data.url) {
728
- xhrPromise = new Promise(function (resolve, reject) {
729
- (0, _helpers.fetch)(_extends({}, data, { headers: _this.options.requestHeaders }), function (response) {
730
- if (response.status === 500) {
731
- _this.triggerEvent('serverError');
732
- reject(data.url);
733
- return;
734
- } else {
735
- // get json data
736
- var page = _this.getPageData(response);
737
- if (page != null) {
738
- page.url = data.url;
739
- } else {
740
- reject(data.url);
741
- return;
742
- }
743
- // render page
744
- _this.cache.cacheUrl(page);
745
- _this.triggerEvent('pageLoaded');
746
- }
747
- resolve();
748
- });
749
- });
750
- } else {
751
- xhrPromise = this.preloadPromise;
752
- }
753
- }
754
-
755
- // when everything is ready, handle the outcome
756
- Promise.all(animationPromises.concat([xhrPromise])).then(function () {
757
- // render page
758
- _this.renderPage(_this.cache.getPage(data.url), popstate);
759
- _this.preloadPromise = null;
760
- }).catch(function (errorUrl) {
761
- // rewrite the skipPopStateHandling function to redirect manually when the history.go is processed
762
- _this.options.skipPopStateHandling = function () {
763
- window.location = errorUrl;
764
- return true;
765
- };
766
-
767
- // go back to the actual page were still at
768
- window.history.go(-1);
769
- });
770
- };
771
-
772
- exports.default = loadPage;
773
-
774
- /***/ }),
775
- /* 8 */
776
- /***/ (function(module, exports, __webpack_require__) {
777
-
778
- "use strict";
779
-
780
-
781
752
  Object.defineProperty(exports, "__esModule", {
782
753
  value: true
783
754
  });
@@ -796,7 +767,7 @@ var classify = function classify(text) {
796
767
  exports.default = classify;
797
768
 
798
769
  /***/ }),
799
- /* 9 */
770
+ /* 8 */
800
771
  /***/ (function(module, exports, __webpack_require__) {
801
772
 
802
773
  "use strict";
@@ -816,7 +787,7 @@ var createHistoryRecord = function createHistoryRecord(url) {
816
787
  exports.default = createHistoryRecord;
817
788
 
818
789
  /***/ }),
819
- /* 10 */
790
+ /* 9 */
820
791
  /***/ (function(module, exports, __webpack_require__) {
821
792
 
822
793
  "use strict";
@@ -826,8 +797,6 @@ Object.defineProperty(exports, "__esModule", {
826
797
  value: true
827
798
  });
828
799
 
829
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
830
-
831
800
  var _utils = __webpack_require__(1);
832
801
 
833
802
  var getDataFromHtml = function getDataFromHtml(html, containers) {
@@ -835,25 +804,20 @@ var getDataFromHtml = function getDataFromHtml(html, containers) {
835
804
  fakeDom.innerHTML = html;
836
805
  var blocks = [];
837
806
 
838
- var _loop = function _loop(i) {
839
- if (fakeDom.querySelector(containers[i]) == null) {
840
- // page in invalid
841
- return {
842
- v: null
843
- };
807
+ containers.forEach(function (selector) {
808
+ if ((0, _utils.query)(selector, fakeDom) == null) {
809
+ console.error('Container ' + selector + ' not found on page.');
810
+ return null;
844
811
  } else {
845
- (0, _utils.queryAll)(containers[i]).forEach(function (item, index) {
846
- (0, _utils.queryAll)(containers[i], fakeDom)[index].setAttribute('data-swup', blocks.length); // marks element with data-swup
847
- blocks.push((0, _utils.queryAll)(containers[i], fakeDom)[index].outerHTML);
812
+ if ((0, _utils.queryAll)(selector).length !== (0, _utils.queryAll)(selector, fakeDom).length) {
813
+ console.warn('Mismatched number of containers found on new page.');
814
+ }
815
+ (0, _utils.queryAll)(selector).forEach(function (item, index) {
816
+ (0, _utils.queryAll)(selector, fakeDom)[index].setAttribute('data-swup', blocks.length);
817
+ blocks.push((0, _utils.queryAll)(selector, fakeDom)[index].outerHTML);
848
818
  });
849
819
  }
850
- };
851
-
852
- for (var i = 0; i < containers.length; i++) {
853
- var _ret = _loop(i);
854
-
855
- if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
856
- }
820
+ });
857
821
 
858
822
  var json = {
859
823
  title: fakeDom.querySelector('title').innerText,
@@ -872,7 +836,7 @@ var getDataFromHtml = function getDataFromHtml(html, containers) {
872
836
  exports.default = getDataFromHtml;
873
837
 
874
838
  /***/ }),
875
- /* 11 */
839
+ /* 10 */
876
840
  /***/ (function(module, exports, __webpack_require__) {
877
841
 
878
842
  "use strict";
@@ -919,7 +883,7 @@ var fetch = function fetch(setOptions) {
919
883
  exports.default = fetch;
920
884
 
921
885
  /***/ }),
922
- /* 12 */
886
+ /* 11 */
923
887
  /***/ (function(module, exports, __webpack_require__) {
924
888
 
925
889
  "use strict";
@@ -929,25 +893,34 @@ Object.defineProperty(exports, "__esModule", {
929
893
  value: true
930
894
  });
931
895
  var transitionEnd = function transitionEnd() {
932
- var el = document.createElement('div');
896
+ if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) {
897
+ return 'webkitTransitionEnd';
898
+ } else {
899
+ return 'transitionend';
900
+ }
901
+ };
933
902
 
934
- var transEndEventNames = {
935
- WebkitTransition: 'webkitTransitionEnd',
936
- MozTransition: 'transitionend',
937
- OTransition: 'oTransitionEnd otransitionend',
938
- transition: 'transitionend'
939
- };
903
+ exports.default = transitionEnd;
904
+
905
+ /***/ }),
906
+ /* 12 */
907
+ /***/ (function(module, exports, __webpack_require__) {
908
+
909
+ "use strict";
940
910
 
941
- for (var name in transEndEventNames) {
942
- if (el.style[name] !== undefined) {
943
- return transEndEventNames[name];
944
- }
945
- }
946
911
 
947
- return false;
912
+ Object.defineProperty(exports, "__esModule", {
913
+ value: true
914
+ });
915
+ var transitionProperty = function transitionProperty() {
916
+ if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) {
917
+ return 'WebkitTransition';
918
+ } else {
919
+ return 'transition';
920
+ }
948
921
  };
949
922
 
950
- exports.default = transitionEnd;
923
+ exports.default = transitionProperty;
951
924
 
952
925
  /***/ }),
953
926
  /* 13 */
@@ -972,6 +945,29 @@ exports.default = getCurrentUrl;
972
945
  "use strict";
973
946
 
974
947
 
948
+ Object.defineProperty(exports, "__esModule", {
949
+ value: true
950
+ });
951
+
952
+ var _Link = __webpack_require__(2);
953
+
954
+ var _Link2 = _interopRequireDefault(_Link);
955
+
956
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
957
+
958
+ var normalizeUrl = function normalizeUrl(url) {
959
+ return new _Link2.default(url).getAddress();
960
+ };
961
+
962
+ exports.default = normalizeUrl;
963
+
964
+ /***/ }),
965
+ /* 15 */
966
+ /***/ (function(module, exports, __webpack_require__) {
967
+
968
+ "use strict";
969
+
970
+
975
971
  Object.defineProperty(exports, "__esModule", {
976
972
  value: true
977
973
  });
@@ -981,26 +977,22 @@ var _utils = __webpack_require__(1);
981
977
  var markSwupElements = function markSwupElements(element, containers) {
982
978
  var blocks = 0;
983
979
 
984
- var _loop = function _loop(i) {
985
- if (element.querySelector(containers[i]) == null) {
986
- console.warn('Element ' + containers[i] + ' is not in current page.');
980
+ containers.forEach(function (selector) {
981
+ if ((0, _utils.query)(selector, element) == null) {
982
+ console.error('Container ' + selector + ' not found on page.');
987
983
  } else {
988
- (0, _utils.queryAll)(containers[i]).forEach(function (item, index) {
989
- (0, _utils.queryAll)(containers[i], element)[index].setAttribute('data-swup', blocks);
984
+ (0, _utils.queryAll)(selector).forEach(function (item, index) {
985
+ (0, _utils.queryAll)(selector, element)[index].setAttribute('data-swup', blocks);
990
986
  blocks++;
991
987
  });
992
988
  }
993
- };
994
-
995
- for (var i = 0; i < containers.length; i++) {
996
- _loop(i);
997
- }
989
+ });
998
990
  };
999
991
 
1000
992
  exports.default = markSwupElements;
1001
993
 
1002
994
  /***/ }),
1003
- /* 15 */
995
+ /* 16 */
1004
996
  /***/ (function(module, exports, __webpack_require__) {
1005
997
 
1006
998
  "use strict";
@@ -1010,59 +1002,121 @@ Object.defineProperty(exports, "__esModule", {
1010
1002
  value: true
1011
1003
  });
1012
1004
 
1013
- 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; }; }();
1005
+ 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; };
1014
1006
 
1015
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1007
+ var _helpers = __webpack_require__(0);
1016
1008
 
1017
- var Link = function () {
1018
- function Link(elementOrUrl) {
1019
- _classCallCheck(this, Link);
1009
+ var loadPage = function loadPage(data, popstate) {
1010
+ var _this = this;
1020
1011
 
1021
- if (elementOrUrl instanceof Element || elementOrUrl instanceof SVGElement) {
1022
- this.link = elementOrUrl;
1023
- } else {
1024
- this.link = document.createElement('a');
1025
- this.link.href = elementOrUrl;
1026
- }
1027
- }
1012
+ // create array for storing animation promises
1013
+ var animationPromises = [],
1014
+ xhrPromise = void 0;
1015
+ var animateOut = function animateOut() {
1016
+ _this.triggerEvent('animationOutStart');
1028
1017
 
1029
- _createClass(Link, [{
1030
- key: 'getPath',
1031
- value: function getPath() {
1032
- var path = this.link.pathname;
1033
- if (path[0] !== '/') {
1034
- path = '/' + path;
1035
- }
1036
- return path;
1018
+ // handle classes
1019
+ document.documentElement.classList.add('is-changing');
1020
+ document.documentElement.classList.add('is-leaving');
1021
+ document.documentElement.classList.add('is-animating');
1022
+ if (popstate) {
1023
+ document.documentElement.classList.add('is-popstate');
1037
1024
  }
1038
- }, {
1039
- key: 'getAddress',
1040
- value: function getAddress() {
1041
- var path = this.link.pathname + this.link.search;
1025
+ document.documentElement.classList.add('to-' + (0, _helpers.classify)(data.url));
1042
1026
 
1043
- if (this.link.getAttribute('xlink:href')) {
1044
- path = this.link.getAttribute('xlink:href');
1045
- }
1027
+ // animation promise stuff
1028
+ animationPromises = _this.getAnimationPromises('out');
1029
+ Promise.all(animationPromises).then(function () {
1030
+ _this.triggerEvent('animationOutDone');
1031
+ });
1046
1032
 
1047
- if (path[0] !== '/') {
1048
- path = '/' + path;
1033
+ // create history record if this is not a popstate call
1034
+ if (!popstate) {
1035
+ // create pop element with or without anchor
1036
+ var state = void 0;
1037
+ if (_this.scrollToElement != null) {
1038
+ state = data.url + _this.scrollToElement;
1039
+ } else {
1040
+ state = data.url;
1049
1041
  }
1050
- return path;
1042
+
1043
+ (0, _helpers.createHistoryRecord)(state);
1051
1044
  }
1052
- }, {
1053
- key: 'getHash',
1054
- value: function getHash() {
1055
- return this.link.hash;
1045
+ };
1046
+
1047
+ this.triggerEvent('transitionStart', popstate);
1048
+
1049
+ // set transition object
1050
+ if (data.customTransition != null) {
1051
+ this.updateTransition(window.location.pathname, data.url, data.customTransition);
1052
+ document.documentElement.classList.add('to-' + (0, _helpers.classify)(data.customTransition));
1053
+ } else {
1054
+ this.updateTransition(window.location.pathname, data.url);
1055
+ }
1056
+
1057
+ // start/skip animation
1058
+ if (!popstate || this.options.animateHistoryBrowsing) {
1059
+ animateOut();
1060
+ } else {
1061
+ this.triggerEvent('animationSkipped');
1062
+ }
1063
+
1064
+ // start/skip loading of page
1065
+ if (this.cache.exists(data.url)) {
1066
+ xhrPromise = new Promise(function (resolve) {
1067
+ resolve();
1068
+ });
1069
+ this.triggerEvent('pageRetrievedFromCache');
1070
+ } else {
1071
+ if (!this.preloadPromise || this.preloadPromise.route != data.url) {
1072
+ xhrPromise = new Promise(function (resolve, reject) {
1073
+ (0, _helpers.fetch)(_extends({}, data, { headers: _this.options.requestHeaders }), function (response) {
1074
+ if (response.status === 500) {
1075
+ _this.triggerEvent('serverError');
1076
+ reject(data.url);
1077
+ return;
1078
+ } else {
1079
+ // get json data
1080
+ var page = _this.getPageData(response);
1081
+ if (page != null) {
1082
+ page.url = data.url;
1083
+ } else {
1084
+ reject(data.url);
1085
+ return;
1086
+ }
1087
+ // render page
1088
+ _this.cache.cacheUrl(page);
1089
+ _this.triggerEvent('pageLoaded');
1090
+ }
1091
+ resolve();
1092
+ });
1093
+ });
1094
+ } else {
1095
+ xhrPromise = this.preloadPromise;
1056
1096
  }
1057
- }]);
1097
+ }
1058
1098
 
1059
- return Link;
1060
- }();
1099
+ // when everything is ready, handle the outcome
1100
+ Promise.all(animationPromises.concat([xhrPromise])).then(function () {
1101
+ // render page
1102
+ _this.renderPage(_this.cache.getPage(data.url), popstate);
1103
+ _this.preloadPromise = null;
1104
+ }).catch(function (errorUrl) {
1105
+ // rewrite the skipPopStateHandling function to redirect manually when the history.go is processed
1106
+ _this.options.skipPopStateHandling = function () {
1107
+ window.location = errorUrl;
1108
+ return true;
1109
+ };
1061
1110
 
1062
- exports.default = Link;
1111
+ // go back to the actual page were still at
1112
+ window.history.go(-1);
1113
+ });
1114
+ };
1115
+
1116
+ exports.default = loadPage;
1063
1117
 
1064
1118
  /***/ }),
1065
- /* 16 */
1119
+ /* 17 */
1066
1120
  /***/ (function(module, exports, __webpack_require__) {
1067
1121
 
1068
1122
  "use strict";
@@ -1074,8 +1128,6 @@ Object.defineProperty(exports, "__esModule", {
1074
1128
 
1075
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; };
1076
1130
 
1077
- var _utils = __webpack_require__(1);
1078
-
1079
1131
  var _helpers = __webpack_require__(0);
1080
1132
 
1081
1133
  var renderPage = function renderPage(page, popstate) {
@@ -1084,16 +1136,16 @@ var renderPage = function renderPage(page, popstate) {
1084
1136
  document.documentElement.classList.remove('is-leaving');
1085
1137
 
1086
1138
  // replace state in case the url was redirected
1087
- var link = new _helpers.Link(page.responseURL);
1088
- if (window.location.pathname !== link.getPath()) {
1139
+ var url = new _helpers.Link(page.responseURL).getPath();
1140
+ if (window.location.pathname !== url) {
1089
1141
  window.history.replaceState({
1090
- url: link.getPath(),
1142
+ url: url,
1091
1143
  random: Math.random(),
1092
1144
  source: 'swup'
1093
- }, document.title, link.getPath());
1145
+ }, document.title, url);
1094
1146
 
1095
1147
  // save new record for redirected url
1096
- this.cache.cacheUrl(_extends({}, page, { url: link.getPath() }));
1148
+ this.cache.cacheUrl(_extends({}, page, { url: url }));
1097
1149
  }
1098
1150
 
1099
1151
  // only add for non-popstate transitions
@@ -1151,7 +1203,7 @@ var renderPage = function renderPage(page, popstate) {
1151
1203
  exports.default = renderPage;
1152
1204
 
1153
1205
  /***/ }),
1154
- /* 17 */
1206
+ /* 18 */
1155
1207
  /***/ (function(module, exports, __webpack_require__) {
1156
1208
 
1157
1209
  "use strict";
@@ -1178,7 +1230,7 @@ var triggerEvent = function triggerEvent(eventName, originalEvent) {
1178
1230
  exports.default = triggerEvent;
1179
1231
 
1180
1232
  /***/ }),
1181
- /* 18 */
1233
+ /* 19 */
1182
1234
  /***/ (function(module, exports, __webpack_require__) {
1183
1235
 
1184
1236
  "use strict";
@@ -1198,7 +1250,7 @@ var on = function on(event, handler) {
1198
1250
  exports.default = on;
1199
1251
 
1200
1252
  /***/ }),
1201
- /* 19 */
1253
+ /* 20 */
1202
1254
  /***/ (function(module, exports, __webpack_require__) {
1203
1255
 
1204
1256
  "use strict";
@@ -1238,7 +1290,7 @@ var off = function off(event, handler) {
1238
1290
  exports.default = off;
1239
1291
 
1240
1292
  /***/ }),
1241
- /* 20 */
1293
+ /* 21 */
1242
1294
  /***/ (function(module, exports, __webpack_require__) {
1243
1295
 
1244
1296
  "use strict";
@@ -1259,7 +1311,38 @@ var updateTransition = function updateTransition(from, to, custom) {
1259
1311
  exports.default = updateTransition;
1260
1312
 
1261
1313
  /***/ }),
1262
- /* 21 */
1314
+ /* 22 */
1315
+ /***/ (function(module, exports, __webpack_require__) {
1316
+
1317
+ "use strict";
1318
+
1319
+
1320
+ Object.defineProperty(exports, "__esModule", {
1321
+ value: true
1322
+ });
1323
+
1324
+ var _utils = __webpack_require__(1);
1325
+
1326
+ var getAnchorElement = function getAnchorElement(hash) {
1327
+ if (!hash) {
1328
+ return null;
1329
+ }
1330
+
1331
+ if (hash.charAt(0) === '#') {
1332
+ hash = hash.substring(1);
1333
+ }
1334
+
1335
+ hash = decodeURIComponent(hash);
1336
+ hash = (0, _utils.escapeCssIdentifier)(hash);
1337
+
1338
+ // https://html.spec.whatwg.org/#find-a-potential-indicated-element
1339
+ return (0, _utils.query)('#' + hash) || (0, _utils.query)('a[name=\'' + hash + '\']');
1340
+ };
1341
+
1342
+ exports.default = getAnchorElement;
1343
+
1344
+ /***/ }),
1345
+ /* 23 */
1263
1346
  /***/ (function(module, exports, __webpack_require__) {
1264
1347
 
1265
1348
  "use strict";
@@ -1274,9 +1357,24 @@ var _utils = __webpack_require__(1);
1274
1357
  var _helpers = __webpack_require__(0);
1275
1358
 
1276
1359
  var getAnimationPromises = function getAnimationPromises() {
1360
+ var _this = this;
1361
+
1277
1362
  var promises = [];
1278
- var animatedElements = (0, _utils.queryAll)(this.options.animationSelector);
1363
+ var animatedElements = (0, _utils.queryAll)(this.options.animationSelector, document.body);
1364
+
1365
+ if (!animatedElements.length) {
1366
+ console.error('No animated elements found by selector ' + this.options.animationSelector);
1367
+ return [Promise.resolve()];
1368
+ }
1369
+
1279
1370
  animatedElements.forEach(function (element) {
1371
+ var transitionDuration = window.getComputedStyle(element)[(0, _helpers.transitionProperty)() + 'Duration'];
1372
+ // Resolve immediately if no transition defined
1373
+ if (!transitionDuration || transitionDuration == '0s') {
1374
+ console.error('No CSS transition duration defined for element of selector ' + _this.options.animationSelector);
1375
+ promises.push(Promise.resolve());
1376
+ return;
1377
+ }
1280
1378
  var promise = new Promise(function (resolve) {
1281
1379
  element.addEventListener((0, _helpers.transitionEnd)(), function (event) {
1282
1380
  if (element == event.target) {
@@ -1286,13 +1384,14 @@ var getAnimationPromises = function getAnimationPromises() {
1286
1384
  });
1287
1385
  promises.push(promise);
1288
1386
  });
1387
+
1289
1388
  return promises;
1290
1389
  };
1291
1390
 
1292
1391
  exports.default = getAnimationPromises;
1293
1392
 
1294
1393
  /***/ }),
1295
- /* 22 */
1394
+ /* 24 */
1296
1395
  /***/ (function(module, exports, __webpack_require__) {
1297
1396
 
1298
1397
  "use strict";
@@ -1324,7 +1423,7 @@ var getPageData = function getPageData(request) {
1324
1423
  exports.default = getPageData;
1325
1424
 
1326
1425
  /***/ }),
1327
- /* 23 */
1426
+ /* 25 */
1328
1427
  /***/ (function(module, exports, __webpack_require__) {
1329
1428
 
1330
1429
  "use strict";