swup 3.0.4 → 3.0.6

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.
Files changed (49) hide show
  1. package/dist/Swup.cjs +1 -1
  2. package/dist/Swup.cjs.map +1 -1
  3. package/dist/Swup.module.js +1 -1
  4. package/dist/Swup.module.js.map +1 -1
  5. package/dist/Swup.umd.js +1 -1
  6. package/dist/Swup.umd.js.map +1 -1
  7. package/dist/types/Swup.d.ts +16 -14
  8. package/dist/types/helpers/fetch.d.ts +2 -2
  9. package/dist/types/helpers.d.ts +10 -10
  10. package/dist/types/index.d.ts +5 -5
  11. package/dist/types/modules/Cache.d.ts +2 -2
  12. package/dist/types/modules/enterPage.d.ts +2 -2
  13. package/dist/types/modules/events.d.ts +1 -1
  14. package/dist/types/modules/fetchPage.d.ts +3 -3
  15. package/dist/types/modules/getAnimationPromises.d.ts +1 -1
  16. package/dist/types/modules/getPageData.d.ts +2 -2
  17. package/dist/types/modules/leavePage.d.ts +2 -2
  18. package/dist/types/modules/loadPage.d.ts +1 -1
  19. package/dist/types/modules/plugins.d.ts +1 -1
  20. package/dist/types/modules/renderPage.d.ts +2 -2
  21. package/dist/types/modules/transitions.d.ts +1 -1
  22. package/dist/types/utils.d.ts +1 -1
  23. package/package.json +15 -12
  24. package/src/Swup.ts +25 -25
  25. package/src/__test__/index.test.ts +26 -10
  26. package/src/helpers/createHistoryRecord.ts +1 -1
  27. package/src/helpers/delegateEvent.ts +1 -1
  28. package/src/helpers/fetch.ts +2 -2
  29. package/src/helpers/getDataFromHtml.ts +1 -1
  30. package/src/helpers/markSwupElements.ts +1 -1
  31. package/src/helpers/updateHistoryRecord.ts +1 -1
  32. package/src/helpers.ts +10 -10
  33. package/src/index.ts +5 -5
  34. package/src/modules/Cache.ts +3 -3
  35. package/src/modules/__test__/events.test.ts +7 -6
  36. package/src/modules/enterPage.ts +3 -3
  37. package/src/modules/events.ts +1 -1
  38. package/src/modules/fetchPage.ts +4 -4
  39. package/src/modules/getAnchorElement.ts +1 -1
  40. package/src/modules/getAnimationPromises.ts +2 -2
  41. package/src/modules/getPageData.ts +3 -3
  42. package/src/modules/leavePage.ts +2 -2
  43. package/src/modules/loadPage.ts +6 -6
  44. package/src/modules/plugins.ts +1 -1
  45. package/src/modules/renderPage.ts +3 -3
  46. package/src/modules/transitions.ts +1 -1
  47. package/src/utils.ts +1 -1
  48. package/dist/Swup.modern.js +0 -2
  49. package/dist/Swup.modern.js.map +0 -1
package/src/Swup.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import delegate from 'delegate-it';
2
2
 
3
- import version from './config/version';
3
+ import version from './config/version.js';
4
4
 
5
5
  import {
6
6
  cleanupAnimationClasses,
@@ -9,24 +9,24 @@ import {
9
9
  Location,
10
10
  markSwupElements,
11
11
  updateHistoryRecord
12
- } from './helpers';
13
- import { Unsubscribe } from './helpers/delegateEvent';
14
-
15
- import { Cache } from './modules/Cache';
16
- import { enterPage } from './modules/enterPage';
17
- import { getAnchorElement } from './modules/getAnchorElement';
18
- import { getAnimationPromises } from './modules/getAnimationPromises';
19
- import { getPageData } from './modules/getPageData';
20
- import { fetchPage } from './modules/fetchPage';
21
- import { leavePage } from './modules/leavePage';
22
- import { loadPage, performPageLoad } from './modules/loadPage';
23
- import { replaceContent } from './modules/replaceContent';
24
- import { on, off, triggerEvent, Handlers } from './modules/events';
25
- import { use, unuse, findPlugin, Plugin } from './modules/plugins';
26
- import { renderPage } from './modules/renderPage';
27
- import { updateTransition, shouldSkipTransition } from './modules/transitions';
28
-
29
- import { queryAll } from './utils';
12
+ } from './helpers.js';
13
+ import { Unsubscribe } from './helpers/delegateEvent.js';
14
+
15
+ import { Cache } from './modules/Cache.js';
16
+ import { enterPage } from './modules/enterPage.js';
17
+ import { getAnchorElement } from './modules/getAnchorElement.js';
18
+ import { getAnimationPromises } from './modules/getAnimationPromises.js';
19
+ import { getPageData } from './modules/getPageData.js';
20
+ import { fetchPage } from './modules/fetchPage.js';
21
+ import { leavePage } from './modules/leavePage.js';
22
+ import { loadPage, performPageLoad } from './modules/loadPage.js';
23
+ import { replaceContent } from './modules/replaceContent.js';
24
+ import { on, off, triggerEvent, Handlers } from './modules/events.js';
25
+ import { use, unuse, findPlugin, Plugin } from './modules/plugins.js';
26
+ import { renderPage } from './modules/renderPage.js';
27
+ import { updateTransition, shouldSkipTransition } from './modules/transitions.js';
28
+
29
+ import { queryAll } from './utils.js';
30
30
 
31
31
  export type Transition = {
32
32
  from?: string;
@@ -47,7 +47,7 @@ export type Options = {
47
47
  requestHeaders: Record<string, string>;
48
48
  plugins: Plugin[];
49
49
  skipPopStateHandling: (event: any) => boolean;
50
- ignoreVisit: (url: string, { el }: { el?: Element }) => boolean;
50
+ ignoreVisit: (url: string, { el, event }: { el?: Element; event?: Event }) => boolean;
51
51
  resolveUrl: (url: string) => string;
52
52
  };
53
53
 
@@ -122,7 +122,7 @@ export default class Swup {
122
122
  animationSelector: '[class*="transition-"]',
123
123
  cache: true,
124
124
  containers: ['#swup'],
125
- ignoreVisit: (url, { el } = {}) => !!el?.closest('[data-no-swup]'),
125
+ ignoreVisit: (url, { el, event } = {}) => !!el?.closest('[data-no-swup]'),
126
126
  linkSelector: 'a[href]',
127
127
  plugins: [],
128
128
  resolveUrl: (url) => url,
@@ -215,7 +215,7 @@ export default class Swup {
215
215
  document.documentElement.classList.remove('swup-enabled');
216
216
  }
217
217
 
218
- shouldIgnoreVisit(href: string, { el }: { el?: Element } = {}) {
218
+ shouldIgnoreVisit(href: string, { el, event }: { el?: Element; event?: Event } = {}) {
219
219
  const { origin, url, hash } = Location.fromUrl(href);
220
220
 
221
221
  // Ignore if the new origin doesn't match the current one
@@ -229,7 +229,7 @@ export default class Swup {
229
229
  }
230
230
 
231
231
  // Ignore if the visit should be ignored as per user options
232
- if (this.options.ignoreVisit(url + hash, { el })) {
232
+ if (this.options.ignoreVisit(url + hash, { el, event })) {
233
233
  return true;
234
234
  }
235
235
 
@@ -242,7 +242,7 @@ export default class Swup {
242
242
  const { href, url, hash } = Location.fromElement(linkEl as HTMLAnchorElement);
243
243
 
244
244
  // Exit early if the link should be ignored
245
- if (this.shouldIgnoreVisit(href, { el: linkEl })) {
245
+ if (this.shouldIgnoreVisit(href, { el: linkEl, event })) {
246
246
  return;
247
247
  }
248
248
 
@@ -320,7 +320,7 @@ export default class Swup {
320
320
  const href = event.state?.url ?? location.href;
321
321
 
322
322
  // Exit early if the link should be ignored
323
- if (this.shouldIgnoreVisit(href)) {
323
+ if (this.shouldIgnoreVisit(href, { event })) {
324
324
  return;
325
325
  }
326
326
 
@@ -1,5 +1,8 @@
1
+ import delegate from 'delegate-it';
2
+ import { describe, expect, it, vi } from 'vitest';
3
+
1
4
  import pckg from '../../package.json';
2
- import Swup, { Options, Plugin } from '../index';
5
+ import Swup, { Options, Plugin } from '../index.js';
3
6
 
4
7
  const baseUrl = window.location.origin;
5
8
 
@@ -7,9 +10,9 @@ function createPlugin(plugin = {}) {
7
10
  return {
8
11
  name: 'TestPlugin',
9
12
  isSwupPlugin: true as const,
10
- mount: jest.fn(() => {}),
11
- unmount: jest.fn(() => {}),
12
- _checkRequirements: jest.fn(() => true),
13
+ mount: vi.fn(() => {}),
14
+ unmount: vi.fn(() => {}),
15
+ _checkRequirements: vi.fn(() => true),
13
16
  ...plugin
14
17
  };
15
18
  }
@@ -52,20 +55,33 @@ describe('Exports', () => {
52
55
 
53
56
  describe('ignoreVisit', () => {
54
57
  it('should be called with relative URL', () => {
55
- const ignoreVisit = jest.fn(() => true);
58
+ const ignoreVisit = vi.fn(() => true);
56
59
  const swup = new Swup({ ignoreVisit });
57
-
58
- swup.shouldIgnoreVisit(baseUrl + '/path/?query#hash');
60
+ swup.shouldIgnoreVisit(`${baseUrl}/path/?query#hash`);
59
61
 
60
62
  expect(ignoreVisit.mock.calls).toHaveLength(1);
61
- expect(ignoreVisit.mock.lastCall).toBeDefined();
62
63
  expect((ignoreVisit.mock.lastCall as any)[0]).toEqual('/path/?query#hash');
63
64
  });
64
65
 
65
- it('should be called from loadPage method', () => {
66
- const ignoreVisit = jest.fn(() => true);
66
+ it('should have access to element and event params', () => {
67
+ const el = document.createElement('a');
68
+ el.href = `${baseUrl}/path/?query#hash`;
69
+ const event = new MouseEvent('click') as delegate.Event<MouseEvent>;
70
+ event.delegateTarget = el;
71
+
72
+ const ignoreVisit = vi.fn(() => true);
67
73
  const swup = new Swup({ ignoreVisit });
74
+ swup.linkClickHandler(event);
68
75
 
76
+ expect(ignoreVisit.mock.calls).toHaveLength(1);
77
+ expect((ignoreVisit.mock.lastCall as any)[1]).toEqual(
78
+ expect.objectContaining({ el, event })
79
+ );
80
+ });
81
+
82
+ it('should be called from loadPage method', () => {
83
+ const ignoreVisit = vi.fn(() => true);
84
+ const swup = new Swup({ ignoreVisit });
69
85
  swup.loadPage({ url: '/path/' });
70
86
 
71
87
  expect(ignoreVisit.mock.calls).toHaveLength(1);
@@ -1,4 +1,4 @@
1
- import { getCurrentUrl } from './getCurrentUrl';
1
+ import { getCurrentUrl } from './getCurrentUrl.js';
2
2
 
3
3
  export const createHistoryRecord = (
4
4
  url: string,
@@ -1,5 +1,5 @@
1
1
  import delegate, { EventType } from 'delegate-it';
2
- import { ParseSelector } from 'typed-query-selector/parser';
2
+ import { ParseSelector } from 'typed-query-selector/parser.js';
3
3
 
4
4
  export type Unsubscribe = {
5
5
  destroy: () => void;
@@ -1,5 +1,5 @@
1
- import { TransitionOptions } from '../modules/loadPage';
2
- import { Options } from '../Swup';
1
+ import { TransitionOptions } from '../modules/loadPage.js';
2
+ import { Options } from '../Swup.js';
3
3
 
4
4
  export const fetch = (
5
5
  options: TransitionOptions & { headers: Options['requestHeaders'] },
@@ -1,4 +1,4 @@
1
- import { query, queryAll } from '../utils';
1
+ import { query, queryAll } from '../utils.js';
2
2
 
3
3
  export type PageHtmlData = {
4
4
  title: string;
@@ -1,4 +1,4 @@
1
- import { query, queryAll } from '../utils';
1
+ import { query, queryAll } from '../utils.js';
2
2
 
3
3
  export const markSwupElements = (element: Element, containers: string[]): void => {
4
4
  let blocks = 0;
@@ -1,4 +1,4 @@
1
- import { getCurrentUrl } from './getCurrentUrl';
1
+ import { getCurrentUrl } from './getCurrentUrl.js';
2
2
 
3
3
  export const updateHistoryRecord = (
4
4
  url: string | null = null,
package/src/helpers.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  // Re-export all helpers to allow custom package export path
2
2
  // e.g. import { getPageData } from 'swup/helpers'
3
3
 
4
- export { classify } from './helpers/classify';
5
- export { createHistoryRecord } from './helpers/createHistoryRecord';
6
- export { updateHistoryRecord } from './helpers/updateHistoryRecord';
7
- export { delegateEvent } from './helpers/delegateEvent';
8
- export { getDataFromHtml } from './helpers/getDataFromHtml';
9
- export { fetch } from './helpers/fetch';
10
- export { getCurrentUrl } from './helpers/getCurrentUrl';
11
- export { Location } from './helpers/Location';
12
- export { markSwupElements } from './helpers/markSwupElements';
13
- export { cleanupAnimationClasses } from './helpers/cleanupAnimationClasses';
4
+ export { classify } from './helpers/classify.js';
5
+ export { createHistoryRecord } from './helpers/createHistoryRecord.js';
6
+ export { updateHistoryRecord } from './helpers/updateHistoryRecord.js';
7
+ export { delegateEvent } from './helpers/delegateEvent.js';
8
+ export { getDataFromHtml } from './helpers/getDataFromHtml.js';
9
+ export { fetch } from './helpers/fetch.js';
10
+ export { getCurrentUrl } from './helpers/getCurrentUrl.js';
11
+ export { Location } from './helpers/Location.js';
12
+ export { markSwupElements } from './helpers/markSwupElements.js';
13
+ export { cleanupAnimationClasses } from './helpers/cleanupAnimationClasses.js';
package/src/index.ts CHANGED
@@ -1,10 +1,10 @@
1
- import Swup, { Options } from './Swup';
2
- import { Plugin } from './modules/plugins';
3
- import { Handler } from './modules/events';
1
+ import Swup, { Options } from './Swup.js';
2
+ import { Plugin } from './modules/plugins.js';
3
+ import { Handler } from './modules/events.js';
4
4
 
5
5
  export default Swup;
6
6
 
7
- export * from './helpers';
8
- export * from './utils';
7
+ export * from './helpers.js';
8
+ export * from './utils.js';
9
9
 
10
10
  export type { Options, Plugin, Handler };
@@ -1,6 +1,6 @@
1
- import { getCurrentUrl, Location } from '../helpers';
2
- import Swup from '../Swup';
3
- import { PageData } from './getPageData';
1
+ import { getCurrentUrl, Location } from '../helpers.js';
2
+ import Swup from '../Swup.js';
3
+ import { PageData } from './getPageData.js';
4
4
 
5
5
  export interface PageRecord extends PageData {
6
6
  url: string;
@@ -1,10 +1,11 @@
1
- import Swup from '../../Swup';
2
- import { Handler } from '../events';
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import Swup from '../../Swup.js';
3
+ import { Handler } from '../events.js';
3
4
 
4
5
  describe('events', () => {
5
6
  it('should add event handlers to handlers array', () => {
6
7
  const swup = new Swup();
7
- const handler = jest.fn();
8
+ const handler = vi.fn();
8
9
 
9
10
  swup.on('enabled', handler);
10
11
 
@@ -13,7 +14,7 @@ describe('events', () => {
13
14
 
14
15
  it('should remove event handlers from handlers array', () => {
15
16
  const swup = new Swup();
16
- const handler = jest.fn();
17
+ const handler = vi.fn();
17
18
 
18
19
  swup.on('enabled', handler);
19
20
  swup.on('animationInDone', handler);
@@ -35,7 +36,7 @@ describe('events', () => {
35
36
 
36
37
  it('should trigger event handler', () => {
37
38
  const swup = new Swup();
38
- const handler = jest.fn();
39
+ const handler = vi.fn();
39
40
 
40
41
  swup.on('enabled', handler);
41
42
 
@@ -46,7 +47,7 @@ describe('events', () => {
46
47
 
47
48
  it('should trigger event handler with event', () => {
48
49
  const swup = new Swup();
49
- const handler: Handler<'popState'> = jest.fn();
50
+ const handler: Handler<'popState'> = vi.fn();
50
51
  const event = new PopStateEvent('');
51
52
 
52
53
  swup.on('popState', handler);
@@ -1,6 +1,6 @@
1
- import { nextTick } from '../utils';
2
- import Swup from '../Swup';
3
- import { PageRenderOptions } from './renderPage';
1
+ import { nextTick } from '../utils.js';
2
+ import Swup from '../Swup.js';
3
+ import { PageRenderOptions } from './renderPage.js';
4
4
 
5
5
  export const enterPage = function (this: Swup, { event, skipTransition }: PageRenderOptions = {}) {
6
6
  if (skipTransition) {
@@ -1,4 +1,4 @@
1
- import Swup from '../Swup';
1
+ import Swup from '../Swup.js';
2
2
  import delegate from 'delegate-it';
3
3
 
4
4
  type HandlersEventMap = {
@@ -1,7 +1,7 @@
1
- import Swup from '../Swup';
2
- import { fetch } from '../helpers';
3
- import { TransitionOptions } from './loadPage';
4
- import { PageRecord } from './Cache';
1
+ import Swup from '../Swup.js';
2
+ import { fetch } from '../helpers.js';
3
+ import { TransitionOptions } from './loadPage.js';
4
+ import { PageRecord } from './Cache.js';
5
5
 
6
6
  export function fetchPage(this: Swup, data: TransitionOptions): Promise<PageRecord> {
7
7
  const headers = this.options.requestHeaders;
@@ -1,4 +1,4 @@
1
- import { escapeCssIdentifier, query } from '../utils';
1
+ import { escapeCssIdentifier, query } from '../utils.js';
2
2
 
3
3
  export const getAnchorElement = (hash: string): Element | null => {
4
4
  if (!hash) {
@@ -1,5 +1,5 @@
1
- import { queryAll, toMs } from '../utils';
2
- import Swup from '../Swup';
1
+ import { queryAll, toMs } from '../utils.js';
2
+ import Swup from '../Swup.js';
3
3
 
4
4
  // Transition property/event sniffing
5
5
  let transitionProp = 'transition';
@@ -1,6 +1,6 @@
1
- import { getDataFromHtml } from '../helpers';
2
- import Swup from '../Swup';
3
- import { PageHtmlData } from '../helpers/getDataFromHtml';
1
+ import { getDataFromHtml } from '../helpers.js';
2
+ import Swup from '../Swup.js';
3
+ import { PageHtmlData } from '../helpers/getDataFromHtml.js';
4
4
 
5
5
  export type PageData = PageHtmlData & {
6
6
  responseURL: string;
@@ -1,5 +1,5 @@
1
- import Swup from '../Swup';
2
- import { PageRenderOptions } from './renderPage';
1
+ import Swup from '../Swup.js';
2
+ import { PageRenderOptions } from './renderPage.js';
3
3
 
4
4
  export const leavePage = function (this: Swup, { event, skipTransition }: PageRenderOptions = {}) {
5
5
  const isHistoryVisit = event instanceof PopStateEvent;
@@ -1,6 +1,6 @@
1
- import { classify, createHistoryRecord, getCurrentUrl } from '../helpers';
2
- import Swup from '../Swup';
3
- import { PageRecord } from './Cache';
1
+ import { classify, createHistoryRecord, getCurrentUrl } from '../helpers.js';
2
+ import Swup from '../Swup.js';
3
+ import { PageRecord } from './Cache.js';
4
4
 
5
5
  export type TransitionOptions = {
6
6
  url: string;
@@ -41,6 +41,9 @@ export function performPageLoad(this: Swup, data: PageLoadOptions) {
41
41
  // start/skip animation
42
42
  const animationPromises = this.leavePage({ event, skipTransition });
43
43
 
44
+ // Load page data
45
+ const fetchPromise = this.fetchPage(data);
46
+
44
47
  // create history record if this is not a popstate call (with or without anchor)
45
48
  if (!isHistoryVisit) {
46
49
  createHistoryRecord(url + (this.scrollToElement || ''));
@@ -48,9 +51,6 @@ export function performPageLoad(this: Swup, data: PageLoadOptions) {
48
51
 
49
52
  this.currentPageUrl = getCurrentUrl();
50
53
 
51
- // Load page data
52
- const fetchPromise = this.fetchPage(data);
53
-
54
54
  // when everything is ready, render the page
55
55
  Promise.all<PageRecord | void>([fetchPromise, ...animationPromises])
56
56
  .then(([pageData]) => {
@@ -1,4 +1,4 @@
1
- import Swup from '../Swup';
1
+ import Swup from '../Swup.js';
2
2
 
3
3
  export type Plugin = {
4
4
  name: string;
@@ -1,6 +1,6 @@
1
- import { Location, updateHistoryRecord, getCurrentUrl } from '../helpers';
2
- import Swup from '../Swup';
3
- import { PageRecord } from './Cache';
1
+ import { Location, updateHistoryRecord, getCurrentUrl } from '../helpers.js';
2
+ import Swup from '../Swup.js';
3
+ import { PageRecord } from './Cache.js';
4
4
 
5
5
  export type PageRenderOptions = {
6
6
  event?: PopStateEvent;
@@ -1,4 +1,4 @@
1
- import Swup from '../Swup';
1
+ import Swup from '../Swup.js';
2
2
 
3
3
  export function updateTransition(this: Swup, from: string, to: string, custom?: string): void {
4
4
  this.transition = { from, to, custom };
package/src/utils.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  // Re-export all utils to allow custom package export path
2
2
  // e.g. import { queryAll } from 'swup/utils'
3
3
 
4
- export * from './utils/index';
4
+ export * from './utils/index.js';
@@ -1,2 +0,0 @@
1
- import t from"delegate-it";function e(){return e=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t},e.apply(this,arguments)}const n=(t,e)=>String(t).toLowerCase().replace(/[\s/_.]+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+|-+$/g,"")||e||"",i=({hash:t}={})=>location.pathname+location.search+(t?location.hash:""),s=(t,n={})=>{const s=e({url:t=t||i({hash:!0}),random:Math.random(),source:"swup"},n);history.pushState(s,"",t)},o=(t=null,n={})=>{t=t||i({hash:!0});const s=e({},history.state,{url:t,random:Math.random(),source:"swup"},n);history.replaceState(s,"",t)},r=["base"],a=(e,n,i,s={})=>{let{base:o=document}=s,a=function(t,e){if(null==t)return{};var n,i,s={},o=Object.keys(t);for(i=0;i<o.length;i++)e.indexOf(n=o[i])>=0||(s[n]=t[n]);return s}(s,r);const l=t(o,e,n,i,a);return{destroy:()=>l.destroy()}},l=(t,e=document)=>e.querySelector(t),u=(t,e=document)=>Array.from(e.querySelectorAll(t)),c=t=>{requestAnimationFrame(()=>{requestAnimationFrame(()=>{t()})})},h=t=>window.CSS&&window.CSS.escape?CSS.escape(t):t,d=t=>1e3*Number(t.slice(0,-1).replace(",",".")),p=(t,e)=>{var n,i;let s=document.createElement("html");s.innerHTML=t;let o=[];e.forEach(t=>{if(null==l(t,s))return console.warn(`[swup] Container ${t} not found on page.`),null;u(t).length!==u(t,s).length&&console.warn("[swup] Mismatched number of containers found on new page."),u(t).forEach((e,n)=>{u(t,s)[n].setAttribute("data-swup",String(o.length)),o.push(u(t,s)[n].outerHTML)})});const r=(null==(n=l("title",s))?void 0:n.innerText)||"",a=null==(i=l("body",s))?void 0:i.className;return s.innerHTML="",s=null,{title:r,pageClass:a,blocks:o,originalContent:t}},g=(t,n)=>{const i={url:window.location.pathname+window.location.search,method:"GET",data:null,headers:{}},{url:s,method:o,headers:r,data:a}=e({},i,t),l=new XMLHttpRequest;return l.onreadystatechange=function(){4===l.readyState&&n(l)},l.open(o,s,!0),Object.entries(r).forEach(([t,e])=>{l.setRequestHeader(t,e)}),l.send(a),l};class m extends URL{constructor(t,e=document.baseURI){super(t.toString(),e)}get url(){return this.pathname+this.search}static fromElement(t){const e=t.getAttribute("href")||t.getAttribute("xlink:href");return new m(e)}static fromUrl(t){return new m(t)}}const f=(t,e)=>{let n=0;e.forEach(e=>{null==l(e,t)?console.warn(`[swup] Container ${e} not found on page.`):u(e).forEach((i,s)=>{u(e,t)[s].setAttribute("data-swup",String(n)),n++})})},v=t=>/^to-/.test(t)||["is-changing","is-rendering","is-popstate"].includes(t),w=()=>{const t=document.documentElement.className.split(" ").filter(v);document.documentElement.classList.remove(...t)};class E{constructor(t){this.pages={},this.last=null,this.swup=void 0,this.swup=t}getCacheUrl(t){return this.swup.resolveUrl(m.fromUrl(t).url)}cacheUrl(t){t.url=this.getCacheUrl(t.url),t.url in this.pages==0&&(this.pages[t.url]=t),t.responseURL=this.getCacheUrl(t.responseURL),this.last=this.pages[t.url],this.swup.log(`Cache (${Object.keys(this.pages).length})`,this.pages)}getPage(t){return t=this.getCacheUrl(t),this.pages[t]}getCurrentPage(){return this.getPage(i())}exists(t){return(t=this.getCacheUrl(t))in this.pages}empty(){this.pages={},this.last=null,this.swup.log("Cache cleared")}remove(t){delete this.pages[this.getCacheUrl(t)]}}const P=function({event:t,skipTransition:e}={}){if(e)return this.triggerEvent("transitionEnd",t),this.cleanupAnimationClasses(),[Promise.resolve()];c(()=>{this.triggerEvent("animationInStart"),document.documentElement.classList.remove("is-animating")});const n=this.getAnimationPromises("in");return Promise.all(n).then(()=>{this.triggerEvent("animationInDone"),this.triggerEvent("transitionEnd",t),this.cleanupAnimationClasses()}),n},S=t=>t?("#"===t.charAt(0)&&(t=t.substring(1)),t=decodeURIComponent(t),t=h(t),l(`#${t}`)||l(`a[name='${t}']`)):null;let b="transition",k="transitionend",U="animation",y="animationend";function L(t){const e=this.options.animationSelector;if(!1===e)return[Promise.resolve()];const n=u(e,document.body);return n.length?n.map(t=>function(t,e,n=null){const{type:i,timeout:s,propCount:o}=function(t,e=null){const n=window.getComputedStyle(t),i=`${b}Duration`,s=`${U}Delay`,o=`${U}Duration`,r=n[`${b}Delay`].split(", "),a=(n[i]||"").split(", "),l=C(r,a),u=(n[s]||"").split(", "),c=(n[o]||"").split(", "),h=C(u,c);let d="",p=0,g=0;return"transition"===e?l>0&&(d="transition",p=l,g=a.length):"animation"===e?h>0&&(d="animation",p=h,g=c.length):(p=Math.max(l,h),d=p>0?l>h?"transition":"animation":null,g=d?"transition"===d?a.length:c.length:0),{type:d,timeout:p,propCount:g}}(t,n);return i&&s?new Promise(e=>{const n="transition"===i?k:y,r=performance.now();let a=0;const l=()=>{t.removeEventListener(n,u),e()},u=e=>{if(e.target===t){if(!(t=>!!t.elapsedTime)(e))throw new Error("Not a transition or animation event.");(performance.now()-r)/1e3<e.elapsedTime||++a>=o&&l()}};setTimeout(()=>{a<o&&l()},s+1),t.addEventListener(n,u)}):(console.warn(`[swup] No CSS transition duration defined for element of selector ${e}`),Promise.resolve())}(t,e)):(console.warn(`[swup] No animated elements found by selector ${e}`),[Promise.resolve()])}function C(t,e){for(;t.length<e.length;)t=t.concat(t);return Math.max(...e.map((e,n)=>d(e)+d(t[n])))}void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(b="WebkitTransition",k="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(U="WebkitAnimation",y="webkitAnimationEnd");const T=function(t){const n=p(t.responseText,this.options.containers);return n?e({},n,{responseURL:t.responseURL||window.location.href}):(console.warn("[swup] Received page is invalid."),null)};function H(t){const n=this.options.requestHeaders,{url:i}=t;return this.cache.exists(i)?(this.triggerEvent("pageRetrievedFromCache"),Promise.resolve(this.cache.getPage(i))):new Promise((s,o)=>{g(e({},t,{headers:n}),t=>{if(500===t.status)return this.triggerEvent("serverError"),void o(i);const n=this.getPageData(t);if(!n||!n.blocks.length)return void o(i);const r=e({},n,{url:i});this.cache.cacheUrl(r),this.triggerEvent("pageLoaded"),s(r)})})}const R=function({event:t,skipTransition:e}={}){const n=t instanceof PopStateEvent;if(e)return this.triggerEvent("animationSkipped"),[Promise.resolve()];this.triggerEvent("animationOutStart"),document.documentElement.classList.add("is-changing","is-leaving","is-animating"),n&&document.documentElement.classList.add("is-popstate");const i=this.getAnimationPromises("out");return Promise.all(i).then(()=>{this.triggerEvent("animationOutDone")}),i};function A(t){const{url:e}=t;this.shouldIgnoreVisit(e)?window.location.href=e:this.performPageLoad(t)}function $(t){const{url:e,event:o,customTransition:r}=null!=t?t:{},a=o instanceof PopStateEvent,l=this.shouldSkipTransition({url:e,event:o});this.triggerEvent("transitionStart",o),this.updateTransition(i(),e,r),null!=r&&document.documentElement.classList.add(`to-${n(r)}`);const u=this.leavePage({event:o,skipTransition:l});a||s(e+(this.scrollToElement||"")),this.currentPageUrl=i();const c=this.fetchPage(t);Promise.all([c,...u]).then(([t])=>{this.renderPage(t,{event:o,skipTransition:l})}).catch(t=>{void 0!==t&&(this.options.skipPopStateHandling=()=>(window.location=t,!0),history.go(-1))})}const _=function({blocks:t,title:e}){return t.forEach((t,e)=>{document.body.querySelector(`[data-swup="${e}"]`).outerHTML=t}),document.title=e,Promise.resolve()};function O(t,e){const n=this._handlers[t];n?n.push(e):console.warn(`Unsupported event ${t}.`)}function x(t,e){if(t&&e){const n=this._handlers[t];n.includes(e)?this._handlers[t]=n.filter(t=>t!==e):console.warn(`Handler for event '${t}' not found.`)}else t?this._handlers[t]=[]:Object.keys(this._handlers).forEach(t=>{this._handlers[t]=[]})}function q(t,e){this._handlers[t].forEach(t=>{try{t(e)}catch(t){console.error(t)}});const n=new CustomEvent(`swup:${t}`,{detail:t});document.dispatchEvent(n)}const D=function(t){var e;if(null==(e=t)?void 0:e.isSwupPlugin){if(t.swup=this,!t._checkRequirements||t._checkRequirements())return t._beforeMount&&t._beforeMount(),t.mount(),this.plugins.push(t),this.plugins}else console.error("Not a swup plugin instance",t)};function I(t){const e=this.findPlugin(t);if(e)return e.unmount(),e._afterUnmount&&e._afterUnmount(),this.plugins=this.plugins.filter(t=>t!==e),this.plugins;console.error("No such plugin",e)}function M(t){return this.plugins.find(e=>e===t||e.name===t)}const N=function(t,{event:n,skipTransition:s}={}){if(document.documentElement.classList.remove("is-leaving"),!this.isSameResolvedUrl(i(),t.url))return;const{url:r}=m.fromUrl(t.responseURL);this.isSameResolvedUrl(i(),r)||(this.cache.cacheUrl(e({},t,{url:r})),this.currentPageUrl=i(),o(r)),s||document.documentElement.classList.add("is-rendering"),this.triggerEvent("willReplaceContent",n),this.replaceContent(t).then(()=>{this.triggerEvent("contentReplaced",n),this.triggerEvent("pageView",n),this.options.cache||this.cache.empty(),this.enterPage({event:n,skipTransition:s}),this.scrollToElement=null})};function W(t,e,n){this.transition={from:t,to:e,custom:n}}function V({event:t}){return!(!(t instanceof PopStateEvent)||this.options.animateHistoryBrowsing)}class j{constructor(t={}){this.version="3.0.4",this._handlers={animationInDone:[],animationInStart:[],animationOutDone:[],animationOutStart:[],animationSkipped:[],clickLink:[],contentReplaced:[],disabled:[],enabled:[],openPageInNewTab:[],pageLoaded:[],pageRetrievedFromCache:[],pageView:[],popState:[],samePage:[],samePageWithHash:[],serverError:[],transitionStart:[],transitionEnd:[],willReplaceContent:[]},this.scrollToElement=null,this.options=void 0,this.plugins=[],this.transition={},this.cache=void 0,this.currentPageUrl=i(),this.delegatedListeners={},this.boundPopStateHandler=void 0,this.loadPage=A,this.performPageLoad=$,this.leavePage=R,this.renderPage=N,this.replaceContent=_,this.enterPage=P,this.triggerEvent=q,this.delegateEvent=a,this.on=O,this.off=x,this.updateTransition=W,this.shouldSkipTransition=V,this.getAnimationPromises=L,this.getPageData=T,this.fetchPage=H,this.getAnchorElement=S,this.log=()=>{},this.use=D,this.unuse=I,this.findPlugin=M,this.getCurrentUrl=i,this.cleanupAnimationClasses=w,this.defaults={animateHistoryBrowsing:!1,animationSelector:'[class*="transition-"]',cache:!0,containers:["#swup"],ignoreVisit:(t,{el:e}={})=>!(null==e||!e.closest("[data-no-swup]")),linkSelector:"a[href]",plugins:[],resolveUrl:t=>t,requestHeaders:{"X-Requested-With":"swup",Accept:"text/html, application/xhtml+xml"},skipPopStateHandling:t=>{var e;return"swup"!==(null==(e=t.state)?void 0:e.source)}},this.options=e({},this.defaults,t),this.boundPopStateHandler=this.popStateHandler.bind(this),this.cache=new E(this),this.enable()}enable(){"undefined"!=typeof Promise?(this.delegatedListeners.click=a(this.options.linkSelector,"click",this.linkClickHandler.bind(this)),window.addEventListener("popstate",this.boundPopStateHandler),f(document.documentElement,this.options.containers),this.options.plugins.forEach(t=>this.use(t)),o(),this.triggerEvent("enabled"),document.documentElement.classList.add("swup-enabled"),this.triggerEvent("pageView")):console.warn("Promise is not supported")}destroy(){this.delegatedListeners.click.destroy(),window.removeEventListener("popstate",this.boundPopStateHandler),this.cache.empty(),this.options.plugins.forEach(t=>{this.unuse(t)}),u("[data-swup]").forEach(t=>{t.removeAttribute("data-swup")}),this.off(),this.triggerEvent("disabled"),document.documentElement.classList.remove("swup-enabled")}shouldIgnoreVisit(t,{el:e}={}){const{origin:n,url:i,hash:s}=m.fromUrl(t);return n!==window.location.origin||!(!e||!this.triggerWillOpenNewWindow(e))||!!this.options.ignoreVisit(i+s,{el:e})}linkClickHandler(t){const e=t.delegateTarget,{href:n,url:s,hash:o}=m.fromElement(e);if(this.shouldIgnoreVisit(n,{el:e}))return;if(t.metaKey||t.ctrlKey||t.shiftKey||t.altKey)return void this.triggerEvent("openPageInNewTab",t);if(0!==t.button)return;if(this.triggerEvent("clickLink",t),t.preventDefault(),!s||s===i())return void this.handleLinkToSamePage(s,o,t);if(this.isSameResolvedUrl(s,i()))return;this.scrollToElement=o||null;const r=e.getAttribute("data-swup-transition")||void 0;this.performPageLoad({url:s,customTransition:r})}handleLinkToSamePage(t,e,n){if(e){if(this.triggerEvent("samePageWithHash",n),!S(e))return console.warn(`Element for offset not found (#${e})`);o(t+e)}else this.triggerEvent("samePage",n)}triggerWillOpenNewWindow(t){return!!t.matches('[download], [target="_blank"]')}popStateHandler(t){var e,n;if(this.options.skipPopStateHandling(t))return;if(this.isSameResolvedUrl(i(),this.currentPageUrl))return;const s=null!=(e=null==(n=t.state)?void 0:n.url)?e:location.href;if(this.shouldIgnoreVisit(s))return;const{url:o,hash:r}=m.fromUrl(s);r?this.scrollToElement=r:t.preventDefault(),this.triggerEvent("popState",t),this.options.animateHistoryBrowsing||(document.documentElement.classList.remove("is-animating"),w()),this.performPageLoad({url:o,event:t})}resolveUrl(t){if("function"!=typeof this.options.resolveUrl)return console.warn("[swup] options.resolveUrl expects a callback function."),t;const e=this.options.resolveUrl(t);return e&&"string"==typeof e?e.startsWith("//")||e.startsWith("http")?(console.warn("[swup] options.resolveUrl needs to return a relative url"),t):e:(console.warn("[swup] options.resolveUrl needs to return a url"),t)}isSameResolvedUrl(t,e){return this.resolveUrl(t)===this.resolveUrl(e)}}export{m as Location,n as classify,w as cleanupAnimationClasses,s as createHistoryRecord,j as default,a as delegateEvent,h as escapeCssIdentifier,g as fetch,i as getCurrentUrl,p as getDataFromHtml,f as markSwupElements,c as nextTick,l as query,u as queryAll,d as toMs,o as updateHistoryRecord};
2
- //# sourceMappingURL=Swup.modern.js.map