swup 3.1.1 → 4.0.0-rc.20
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/README.md +94 -0
- package/dist/Swup.cjs +1 -1
- package/dist/Swup.cjs.map +1 -1
- package/dist/Swup.modern.js +1 -1
- package/dist/Swup.modern.js.map +1 -1
- package/dist/Swup.module.js +1 -1
- package/dist/Swup.module.js.map +1 -1
- package/dist/Swup.umd.js +1 -1
- package/dist/Swup.umd.js.map +1 -1
- package/dist/types/Swup.d.ts +53 -45
- package/dist/types/helpers/Location.d.ts +10 -7
- package/dist/types/helpers/delegateEvent.d.ts +2 -2
- package/dist/types/helpers/matchPath.d.ts +3 -0
- package/dist/types/helpers.d.ts +1 -4
- package/dist/types/index.d.ts +7 -4
- package/dist/types/modules/Cache.d.ts +14 -14
- package/dist/types/modules/Classes.d.ts +13 -0
- package/dist/types/modules/Context.d.ts +73 -0
- package/dist/types/modules/Hooks.d.ts +241 -0
- package/dist/types/modules/__test__/cache.test.d.ts +1 -0
- package/dist/types/modules/__test__/hooks.test.d.ts +1 -0
- package/dist/types/modules/__test__/replaceContent.test.d.ts +1 -0
- package/dist/types/modules/awaitAnimations.d.ts +21 -0
- package/dist/types/modules/enterPage.d.ts +5 -2
- package/dist/types/modules/fetchPage.d.ts +23 -3
- package/dist/types/modules/getAnchorElement.d.ts +2 -1
- package/dist/types/modules/leavePage.d.ts +5 -2
- package/dist/types/modules/plugins.d.ts +7 -0
- package/dist/types/modules/renderPage.d.ts +6 -6
- package/dist/types/modules/replaceContent.d.ts +8 -11
- package/dist/types/modules/visit.d.ts +33 -0
- package/dist/types/utils/index.d.ts +3 -1
- package/package.json +13 -9
- package/src/Swup.ts +172 -182
- package/src/__test__/index.test.ts +8 -3
- package/src/helpers/Location.ts +12 -9
- package/src/helpers/__test__/matchPath.test.ts +54 -0
- package/src/helpers/delegateEvent.ts +3 -2
- package/src/helpers/matchPath.ts +22 -0
- package/src/helpers.ts +2 -5
- package/src/index.ts +36 -4
- package/src/modules/Cache.ts +43 -33
- package/src/modules/Classes.ts +48 -0
- package/src/modules/Context.ts +121 -0
- package/src/modules/Hooks.ts +413 -0
- package/src/modules/__test__/cache.test.ts +142 -0
- package/src/modules/__test__/hooks.test.ts +263 -0
- package/src/modules/__test__/replaceContent.test.ts +92 -0
- package/src/modules/awaitAnimations.ts +169 -0
- package/src/modules/enterPage.ts +23 -17
- package/src/modules/fetchPage.ts +74 -29
- package/src/modules/getAnchorElement.ts +2 -1
- package/src/modules/leavePage.ts +26 -20
- package/src/modules/plugins.ts +7 -2
- package/src/modules/renderPage.ts +52 -33
- package/src/modules/replaceContent.ts +33 -16
- package/src/modules/visit.ts +143 -0
- package/src/utils/index.ts +25 -5
- package/dist/types/helpers/cleanupAnimationClasses.d.ts +0 -2
- package/dist/types/helpers/fetch.d.ts +0 -5
- package/dist/types/helpers/getDataFromHtml.d.ts +0 -7
- package/dist/types/helpers/markSwupElements.d.ts +0 -1
- package/dist/types/modules/events.d.ts +0 -33
- package/dist/types/modules/getAnimationPromises.d.ts +0 -7
- package/dist/types/modules/getPageData.d.ts +0 -6
- package/dist/types/modules/loadPage.d.ts +0 -15
- package/dist/types/modules/transitions.d.ts +0 -6
- package/readme.md +0 -60
- package/src/helpers/cleanupAnimationClasses.ts +0 -8
- package/src/helpers/fetch.ts +0 -33
- package/src/helpers/getDataFromHtml.ts +0 -39
- package/src/helpers/markSwupElements.ts +0 -16
- package/src/modules/__test__/events.test.ts +0 -72
- package/src/modules/events.ts +0 -92
- package/src/modules/getAnimationPromises.ts +0 -183
- package/src/modules/getPageData.ts +0 -24
- package/src/modules/loadPage.ts +0 -81
- package/src/modules/transitions.ts +0 -10
- /package/dist/types/{modules/__test__/events.test.d.ts → helpers/__test__/matchPath.test.d.ts} +0 -0
package/src/modules/leavePage.ts
CHANGED
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
import Swup from '../Swup.js';
|
|
2
|
-
import {
|
|
2
|
+
import { classify } from '../helpers.js';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Perform the out/leave animation of the current page.
|
|
6
|
+
* @returns Promise<void>
|
|
7
|
+
*/
|
|
8
|
+
export const leavePage = async function (this: Swup) {
|
|
9
|
+
if (!this.context.animation.animate) {
|
|
10
|
+
await this.hooks.trigger('animation:skip');
|
|
11
|
+
return;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
|
-
this.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// animation promise stuff
|
|
21
|
-
const animationPromises: Promise<void>[] = this.getAnimationPromises('out');
|
|
22
|
-
Promise.all(animationPromises).then(() => {
|
|
23
|
-
this.triggerEvent('animationOutDone');
|
|
14
|
+
await this.hooks.trigger('animation:out:start', undefined, () => {
|
|
15
|
+
this.classes.add('is-changing', 'is-leaving', 'is-animating');
|
|
16
|
+
if (this.context.history.popstate) {
|
|
17
|
+
this.classes.add('is-popstate');
|
|
18
|
+
}
|
|
19
|
+
if (this.context.animation.name) {
|
|
20
|
+
this.classes.add(`to-${classify(this.context.animation.name)}`);
|
|
21
|
+
}
|
|
24
22
|
});
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
await this.hooks.trigger(
|
|
25
|
+
'animation:await',
|
|
26
|
+
{ direction: 'out' },
|
|
27
|
+
async (context, { direction }) => {
|
|
28
|
+
await this.awaitAnimations({ selector: context.animation.selector, direction });
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
await this.hooks.trigger('animation:out:end');
|
|
27
33
|
};
|
package/src/modules/plugins.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import Swup from '../Swup.js';
|
|
2
2
|
|
|
3
3
|
export type Plugin = {
|
|
4
|
+
/** Name of this plugin */
|
|
4
5
|
name: string;
|
|
6
|
+
/** Identify as a swup plugin */
|
|
5
7
|
isSwupPlugin: true;
|
|
8
|
+
/** Run on mount */
|
|
6
9
|
mount: () => void;
|
|
10
|
+
/** Run on unmount */
|
|
7
11
|
unmount: () => void;
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
/** The swup instance that mounted this plugin */
|
|
10
14
|
swup?: Swup;
|
|
11
15
|
|
|
12
|
-
|
|
16
|
+
/** Version of this plugin. Currently not in use, defined here for backward compatiblity. */
|
|
13
17
|
version?: string;
|
|
18
|
+
/** Version requirements of this plugin. Example: `{ swup: '>=4' }` */
|
|
14
19
|
requires?: Record<string, string>;
|
|
15
20
|
_beforeMount?: () => void;
|
|
16
21
|
_afterUnmount?: () => void;
|
|
@@ -1,53 +1,72 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { updateHistoryRecord, getCurrentUrl, classify } from '../helpers.js';
|
|
2
2
|
import Swup from '../Swup.js';
|
|
3
|
-
import {
|
|
3
|
+
import { PageData } from './fetchPage.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Render the next page: replace the content and update scroll position.
|
|
7
|
+
* @returns Promise<void>
|
|
8
|
+
*/
|
|
9
|
+
export const renderPage = async function (this: Swup, requestedUrl: string, page: PageData) {
|
|
10
|
+
const { url, html } = page;
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
this: Swup,
|
|
12
|
-
page: PageRecord,
|
|
13
|
-
{ event, skipTransition }: PageRenderOptions = {}
|
|
14
|
-
) {
|
|
15
|
-
document.documentElement.classList.remove('is-leaving');
|
|
12
|
+
this.classes.remove('is-leaving');
|
|
16
13
|
|
|
17
14
|
// do nothing if another page was requested in the meantime
|
|
18
|
-
if (!this.isSameResolvedUrl(getCurrentUrl(),
|
|
15
|
+
if (!this.isSameResolvedUrl(getCurrentUrl(), requestedUrl)) {
|
|
19
16
|
return;
|
|
20
17
|
}
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// update cache and state if the url was redirected
|
|
19
|
+
// update state if the url was redirected
|
|
25
20
|
if (!this.isSameResolvedUrl(getCurrentUrl(), url)) {
|
|
26
|
-
this.cache.cacheUrl({ ...page, url });
|
|
27
|
-
this.currentPageUrl = getCurrentUrl();
|
|
28
21
|
updateHistoryRecord(url);
|
|
22
|
+
this.currentPageUrl = getCurrentUrl();
|
|
23
|
+
this.context.to.url = this.currentPageUrl;
|
|
29
24
|
}
|
|
30
25
|
|
|
31
|
-
// only add for page loads
|
|
32
|
-
if (
|
|
33
|
-
|
|
26
|
+
// only add for animated page loads
|
|
27
|
+
if (this.context.animation.animate) {
|
|
28
|
+
this.classes.add('is-rendering');
|
|
34
29
|
}
|
|
35
30
|
|
|
36
|
-
|
|
31
|
+
// save html into context for easier retrieval
|
|
32
|
+
this.context.to.html = html;
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
this.
|
|
34
|
+
// replace content: allow handlers and plugins to overwrite paga data and containers
|
|
35
|
+
await this.hooks.trigger('content:replace', { page }, (context, { page }) => {
|
|
36
|
+
const success = this.replaceContent(page, { containers: context.containers });
|
|
37
|
+
if (!success) {
|
|
38
|
+
throw new Error('[swup] Container mismatch, aborting');
|
|
39
|
+
}
|
|
40
|
+
if (this.context.animation.animate) {
|
|
41
|
+
// Make sure to add these classes to new containers as well
|
|
42
|
+
this.classes.add('is-animating', 'is-changing', 'is-rendering');
|
|
43
|
+
if (this.context.animation.name) {
|
|
44
|
+
this.classes.add(`to-${classify(this.context.animation.name)}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
});
|
|
41
48
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
await this.hooks.trigger(
|
|
50
|
+
'content:scroll',
|
|
51
|
+
{ options: { behavior: 'auto' } },
|
|
52
|
+
(context, { options }) => {
|
|
53
|
+
if (this.context.scroll.target) {
|
|
54
|
+
const target = this.getAnchorElement(this.context.scroll.target);
|
|
55
|
+
if (target) {
|
|
56
|
+
target.scrollIntoView(options);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (this.context.scroll.reset) {
|
|
61
|
+
window.scrollTo(0, 0);
|
|
62
|
+
}
|
|
45
63
|
}
|
|
64
|
+
);
|
|
46
65
|
|
|
47
|
-
|
|
48
|
-
this.enterPage({ event, skipTransition });
|
|
66
|
+
await this.hooks.trigger('page:view', { url: this.currentPageUrl, title: document.title });
|
|
49
67
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
68
|
+
// empty cache if it's disabled (in case preload plugin filled it)
|
|
69
|
+
if (!this.options.cache) {
|
|
70
|
+
this.cache.clear();
|
|
71
|
+
}
|
|
53
72
|
};
|
|
@@ -1,26 +1,43 @@
|
|
|
1
|
+
import Swup, { Options } from '../Swup.js';
|
|
2
|
+
import { PageData } from './fetchPage.js';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Perform the replacement of content after loading a page.
|
|
3
6
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* It takes an object with the page data as return from `getPageData` and has to
|
|
7
|
-
* return a Promise that resolves once all content has been replaced and the
|
|
8
|
-
* site is ready to start animating in the new page.
|
|
7
|
+
* It takes an object with the page data as returned from `fetchPage` and a list
|
|
8
|
+
* of container selectors to replace.
|
|
9
9
|
*
|
|
10
|
-
* @
|
|
11
|
-
* @returns Promise
|
|
10
|
+
* @returns Whether all containers were replaced.
|
|
12
11
|
*/
|
|
13
|
-
export const replaceContent = function (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
});
|
|
12
|
+
export const replaceContent = function (
|
|
13
|
+
this: Swup,
|
|
14
|
+
{ html }: PageData,
|
|
15
|
+
{ containers }: { containers: Options['containers'] } = this.options
|
|
16
|
+
): boolean {
|
|
17
|
+
const incomingDocument = new DOMParser().parseFromString(html, 'text/html');
|
|
20
18
|
|
|
21
19
|
// Update browser title
|
|
20
|
+
const title = incomingDocument.querySelector('title')?.innerText || '';
|
|
22
21
|
document.title = title;
|
|
23
22
|
|
|
24
|
-
//
|
|
25
|
-
|
|
23
|
+
// Update content containers
|
|
24
|
+
const replaced = containers
|
|
25
|
+
.map((selector) => {
|
|
26
|
+
const currentEl = document.querySelector(selector);
|
|
27
|
+
const incomingEl = incomingDocument.querySelector(selector);
|
|
28
|
+
if (currentEl && incomingEl) {
|
|
29
|
+
currentEl.replaceWith(incomingEl);
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
if (!currentEl) {
|
|
33
|
+
console.warn(`[swup] Container missing in current document: ${selector}`);
|
|
34
|
+
}
|
|
35
|
+
if (!incomingEl) {
|
|
36
|
+
console.warn(`[swup] Container missing in incoming document: ${selector}`);
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
})
|
|
40
|
+
.filter(Boolean);
|
|
41
|
+
|
|
42
|
+
return replaced.length === containers.length;
|
|
26
43
|
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import Swup from '../Swup.js';
|
|
2
|
+
import { createHistoryRecord, updateHistoryRecord, getCurrentUrl, Location } from '../helpers.js';
|
|
3
|
+
import { FetchOptions } from './fetchPage.js';
|
|
4
|
+
import { ContextInitOptions } from './Context.js';
|
|
5
|
+
|
|
6
|
+
export type HistoryAction = 'push' | 'replace';
|
|
7
|
+
export type HistoryDirection = 'forwards' | 'backwards';
|
|
8
|
+
|
|
9
|
+
type VisitOptions = {
|
|
10
|
+
/** Whether this visit is animated. Default: `true` */
|
|
11
|
+
animate?: boolean;
|
|
12
|
+
/** Name of a custom animation to run. */
|
|
13
|
+
animation?: string;
|
|
14
|
+
/** History action to perform: `push` for creating a new history entry, `replace` for replacing the current entry. Default: `push` */
|
|
15
|
+
history?: HistoryAction;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Navigate to a new URL.
|
|
20
|
+
* @param url The URL to navigate to.
|
|
21
|
+
* @param options Options for how to perform this visit.
|
|
22
|
+
* @returns Promise<void>
|
|
23
|
+
*/
|
|
24
|
+
export function visit(
|
|
25
|
+
this: Swup,
|
|
26
|
+
url: string,
|
|
27
|
+
options: VisitOptions & FetchOptions = {},
|
|
28
|
+
context: Omit<ContextInitOptions, 'to'> = {}
|
|
29
|
+
) {
|
|
30
|
+
// Check if the visit should be ignored
|
|
31
|
+
if (this.shouldIgnoreVisit(url)) {
|
|
32
|
+
window.location.href = url;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const { url: to, hash } = Location.fromUrl(url);
|
|
37
|
+
this.context = this.createContext({ ...context, to, hash });
|
|
38
|
+
this.performVisit(to, options);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Start a visit to a new URL.
|
|
43
|
+
*
|
|
44
|
+
* Internal method that assumes the global context has already been set up.
|
|
45
|
+
*
|
|
46
|
+
* As a user, you should call `swup.visit(url)` instead.
|
|
47
|
+
*
|
|
48
|
+
* @param url The URL to navigate to.
|
|
49
|
+
* @param options Options for how to perform this visit.
|
|
50
|
+
* @returns Promise<void>
|
|
51
|
+
*/
|
|
52
|
+
export async function performVisit(
|
|
53
|
+
this: Swup,
|
|
54
|
+
url: string,
|
|
55
|
+
options: VisitOptions & FetchOptions = {}
|
|
56
|
+
) {
|
|
57
|
+
if (typeof url !== 'string') {
|
|
58
|
+
throw new Error(`swup.visit() requires a URL parameter`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
this.context.to.url = Location.fromUrl(url).url;
|
|
62
|
+
const { animation, animate, history: historyAction } = options;
|
|
63
|
+
options.referrer = options.referrer || this.currentPageUrl;
|
|
64
|
+
|
|
65
|
+
if (animate === false) {
|
|
66
|
+
this.context.animation.animate = false;
|
|
67
|
+
}
|
|
68
|
+
if (historyAction) {
|
|
69
|
+
this.context.history.action = historyAction;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Clean up old animation classes and set custom animation name
|
|
73
|
+
if (!this.context.animation.animate) {
|
|
74
|
+
this.classes.clear();
|
|
75
|
+
} else if (animation) {
|
|
76
|
+
this.context.animation.name = animation;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
await this.hooks.trigger('visit:start');
|
|
81
|
+
|
|
82
|
+
// Begin fetching page
|
|
83
|
+
const pagePromise = this.hooks.trigger(
|
|
84
|
+
'page:request',
|
|
85
|
+
{ url: this.context.to.url, options },
|
|
86
|
+
async (context, { options }) => await this.fetchPage(context.to.url as string, options)
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
// Create history record if this is not a popstate call (with or without anchor)
|
|
90
|
+
if (!this.context.history.popstate) {
|
|
91
|
+
const newUrl = url + (this.context.scroll.target || '');
|
|
92
|
+
if (this.context.history.action === 'replace') {
|
|
93
|
+
updateHistoryRecord(newUrl);
|
|
94
|
+
} else {
|
|
95
|
+
const index = this.currentHistoryIndex + 1;
|
|
96
|
+
createHistoryRecord(newUrl, { index });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.currentPageUrl = getCurrentUrl();
|
|
101
|
+
|
|
102
|
+
// Wait for page before starting to animate out?
|
|
103
|
+
if (this.context.animation.wait) {
|
|
104
|
+
const { html } = await pagePromise;
|
|
105
|
+
this.context.to.html = html;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Wait for page to load and leave animation to finish
|
|
109
|
+
const animationPromise = this.leavePage();
|
|
110
|
+
const [page] = await Promise.all([pagePromise, animationPromise]);
|
|
111
|
+
|
|
112
|
+
// Render page: replace content and scroll to top/fragment
|
|
113
|
+
await this.renderPage(this.context.to.url, page);
|
|
114
|
+
|
|
115
|
+
// Wait for enter animation
|
|
116
|
+
await this.enterPage();
|
|
117
|
+
|
|
118
|
+
// Finalize visit
|
|
119
|
+
await this.hooks.trigger('visit:end', undefined, () => this.classes.clear());
|
|
120
|
+
|
|
121
|
+
// Reset context after visit?
|
|
122
|
+
// if (this.context.to && this.isSameResolvedUrl(this.context.to.url, requestedUrl)) {
|
|
123
|
+
// this.createContext({ to: undefined });
|
|
124
|
+
// }
|
|
125
|
+
} catch (error: unknown) {
|
|
126
|
+
// Return early if error is undefined (probably aborted preload request)
|
|
127
|
+
if (!error) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Log to console as we swallow almost all hook errors
|
|
132
|
+
console.error(error);
|
|
133
|
+
|
|
134
|
+
// Rewrite `skipPopStateHandling` to redirect manually when `history.go` is processed
|
|
135
|
+
this.options.skipPopStateHandling = () => {
|
|
136
|
+
window.location.href = this.context.to.url as string;
|
|
137
|
+
return true;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// Go back to the actual page we're still at
|
|
141
|
+
history.go(-1);
|
|
142
|
+
}
|
|
143
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -9,21 +9,41 @@ export const queryAll = (
|
|
|
9
9
|
return Array.from(context.querySelectorAll(selector));
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
export const nextTick = (
|
|
13
|
-
|
|
12
|
+
export const nextTick = (): Promise<void> => {
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
14
|
requestAnimationFrame(() => {
|
|
15
|
-
|
|
15
|
+
requestAnimationFrame(() => {
|
|
16
|
+
resolve();
|
|
17
|
+
});
|
|
16
18
|
});
|
|
17
19
|
});
|
|
18
20
|
};
|
|
19
21
|
|
|
22
|
+
export function isPromise<T>(obj: any): obj is PromiseLike<T> {
|
|
23
|
+
return (
|
|
24
|
+
!!obj &&
|
|
25
|
+
(typeof obj === 'object' || typeof obj === 'function') &&
|
|
26
|
+
typeof obj.then === 'function'
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function runAsPromise(func: Function, args: any[] = [], ctx: any = {}): Promise<any> {
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
const result = func.apply(ctx, args);
|
|
33
|
+
if (isPromise(result)) {
|
|
34
|
+
result.then(resolve, reject);
|
|
35
|
+
} else {
|
|
36
|
+
resolve(result);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
20
41
|
export const escapeCssIdentifier = (ident: string) => {
|
|
21
42
|
// @ts-ignore this is for support check, so it's correct that TS complains
|
|
22
43
|
if (window.CSS && window.CSS.escape) {
|
|
23
44
|
return CSS.escape(ident);
|
|
24
|
-
} else {
|
|
25
|
-
return ident;
|
|
26
45
|
}
|
|
46
|
+
return ident;
|
|
27
47
|
};
|
|
28
48
|
|
|
29
49
|
// Fix for Chrome below v61 formatting CSS floats with comma in some locales
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const markSwupElements: (element: Element, containers: string[]) => void;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import Swup from '../Swup.js';
|
|
2
|
-
import { DelegateEvent } from 'delegate-it';
|
|
3
|
-
type HandlersEventMap = {
|
|
4
|
-
animationInDone: undefined;
|
|
5
|
-
animationInStart: undefined;
|
|
6
|
-
animationOutDone: undefined;
|
|
7
|
-
animationOutStart: undefined;
|
|
8
|
-
animationSkipped: undefined;
|
|
9
|
-
clickLink: DelegateEvent<MouseEvent>;
|
|
10
|
-
contentReplaced: PopStateEvent | undefined;
|
|
11
|
-
disabled: undefined;
|
|
12
|
-
enabled: undefined;
|
|
13
|
-
openPageInNewTab: DelegateEvent<MouseEvent>;
|
|
14
|
-
pageLoaded: undefined;
|
|
15
|
-
pageRetrievedFromCache: undefined;
|
|
16
|
-
pageView: PopStateEvent | undefined;
|
|
17
|
-
popState: PopStateEvent;
|
|
18
|
-
samePage: DelegateEvent<MouseEvent>;
|
|
19
|
-
samePageWithHash: DelegateEvent<MouseEvent>;
|
|
20
|
-
serverError: undefined;
|
|
21
|
-
transitionStart: PopStateEvent | undefined;
|
|
22
|
-
transitionEnd: PopStateEvent | undefined;
|
|
23
|
-
willReplaceContent: PopStateEvent | undefined;
|
|
24
|
-
};
|
|
25
|
-
type AvailableEventNames = keyof HandlersEventMap;
|
|
26
|
-
export type Handler<T extends keyof HandlersEventMap> = (event: HandlersEventMap[T]) => void;
|
|
27
|
-
export type Handlers = {
|
|
28
|
-
[Key in keyof HandlersEventMap]: Handler<Key>[];
|
|
29
|
-
};
|
|
30
|
-
export declare function on<TEventType extends AvailableEventNames>(this: Swup, event: TEventType, handler: Handler<TEventType>): void;
|
|
31
|
-
export declare function off<TEventType extends AvailableEventNames>(this: Swup, event?: TEventType, handler?: Handler<TEventType>): void;
|
|
32
|
-
export declare function triggerEvent<TEventType extends AvailableEventNames>(this: Swup, eventName: TEventType, originalEvent?: HandlersEventMap[TEventType]): void;
|
|
33
|
-
export {};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import Swup from '../Swup.js';
|
|
2
|
-
export declare function getAnimationPromises(this: Swup, animationType: 'in' | 'out'): Promise<void>[];
|
|
3
|
-
export declare function getTransitionInfo(element: Element, expectedType?: 'animation' | 'transition' | null): {
|
|
4
|
-
type: string | null;
|
|
5
|
-
timeout: number;
|
|
6
|
-
propCount: number;
|
|
7
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import Swup from '../Swup.js';
|
|
2
|
-
export type HistoryAction = 'push' | 'replace';
|
|
3
|
-
export type TransitionOptions = {
|
|
4
|
-
url: string;
|
|
5
|
-
customTransition?: string;
|
|
6
|
-
history?: HistoryAction;
|
|
7
|
-
};
|
|
8
|
-
export type PageLoadOptions = {
|
|
9
|
-
url: string;
|
|
10
|
-
customTransition?: string;
|
|
11
|
-
history?: HistoryAction;
|
|
12
|
-
event?: PopStateEvent;
|
|
13
|
-
};
|
|
14
|
-
export declare function loadPage(this: Swup, data: TransitionOptions): void;
|
|
15
|
-
export declare function performPageLoad(this: Swup, data: PageLoadOptions): void;
|
package/readme.md
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
<br>
|
|
2
|
-
|
|
3
|
-
<p align="center">
|
|
4
|
-
<img width="280" alt="swup" src="https://swup.js.org/assets/images/swup-logo.svg">
|
|
5
|
-
</p>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
<a href="https://www.npmjs.com/package/swup"><img src="https://img.shields.io/npm/v/swup.svg" alt="npm version"></a>
|
|
9
|
-
<a href="https://bundlephobia.com/package/swup"><img src="https://img.shields.io/bundlephobia/minzip/swup?label=size" alt="Bundle size"></a>
|
|
10
|
-
<a href="https://github.com/gmrchk/swup/blob/master/LICENSE"><img src="https://img.shields.io/github/license/gmrchk/swup.svg" alt="License"></a>
|
|
11
|
-
<a href="https://www.npmjs.com/package/swup"><img src="https://img.shields.io/npm/dt/swup.svg" alt="npm downloads"></a>
|
|
12
|
-
<a href="https://github.com/swup/swup/actions/workflows/e2e-tests.yml"><img src="https://img.shields.io/github/actions/workflow/status/swup/swup/e2e-tests.yml?branch=master&label=tests" alt="Test status"></a>
|
|
13
|
-
</p>
|
|
14
|
-
|
|
15
|
-
<br>
|
|
16
|
-
|
|
17
|
-
# Swup
|
|
18
|
-
|
|
19
|
-
Complete, flexible, extensible, and easy-to-use page transition library for your server-side rendered website.
|
|
20
|
-
|
|
21
|
-
[Features](#features) •
|
|
22
|
-
[Documentation](https://swup.js.org/getting-started) •
|
|
23
|
-
[Plugins](https://swup.js.org/plugins) •
|
|
24
|
-
[Themes](https://swup.js.org/themes) •
|
|
25
|
-
[Discussions](https://github.com/swup/swup/discussions)
|
|
26
|
-
|
|
27
|
-
## Overview
|
|
28
|
-
|
|
29
|
-
Swup is a library that helps you add page transitions to server-side rendered websites. It handles
|
|
30
|
-
the complete lifecycle of a page visit by intercepting link clicks, loading the new page in the
|
|
31
|
-
background, replacing the content and transitioning between the old and the new page.
|
|
32
|
-
|
|
33
|
-
Its goal is to make adding transitions to a site as simple as possible, while providing lots of
|
|
34
|
-
other quality-of-life improvements.
|
|
35
|
-
|
|
36
|
-
## Features
|
|
37
|
-
|
|
38
|
-
- ✨ Auto-detects [CSS transitions](https://swup.js.org/getting-started/how-it-works) for perfect timing
|
|
39
|
-
- 🔗 Updates URLs and preserves native browser history behavior
|
|
40
|
-
- 📦 Uses a [cache](https://swup.js.org/api/cache) to speed up subsequent page loads
|
|
41
|
-
- 💡 Offers [events](https://swup.js.org/events) for hooking into the lifecycle
|
|
42
|
-
- 🔌 Has a powerful [plugin system](https://swup.js.org/plugins) and many official and third-party plugins
|
|
43
|
-
- 🎨 Provides ready-to-go [themes](https://swup.js.org/themes) to get started quickly
|
|
44
|
-
|
|
45
|
-
## Examples
|
|
46
|
-
|
|
47
|
-
<img src="https://user-images.githubusercontent.com/9338324/49190360-50125480-f372-11e8-89e9-d2fb091a2240.gif" width="100%">
|
|
48
|
-
|
|
49
|
-
Take a look at [Sites using swup](https://github.com/swup/swup/discussions/333) for more examples.
|
|
50
|
-
|
|
51
|
-
## Having trouble?
|
|
52
|
-
|
|
53
|
-
If you're having trouble implementing swup, check out the [Common Issues](https://swup.js.org/other/common-issues) section of the docs, look at [closed issues](https://github.com/gmrchk/swup/issues?q=is%3Aissue+is%3Aclosed) or create a [new discussion](https://github.com/swup/swup/discussions/new).
|
|
54
|
-
|
|
55
|
-
## Want to Contribute?
|
|
56
|
-
|
|
57
|
-
<a href="https://github.com/swup/swup/discussions/424">We're looking for maintainers!</a> 👀
|
|
58
|
-
|
|
59
|
-
Become a sponsor on [Open Collective](https://opencollective.com/swup) or support development through
|
|
60
|
-
[GitHub sponsors](https://github.com/sponsors/gmrchk).
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export const isSwupClass = (className: string): boolean =>
|
|
2
|
-
/^to-/.test(className) || ['is-changing', 'is-rendering', 'is-popstate'].includes(className);
|
|
3
|
-
|
|
4
|
-
export const cleanupAnimationClasses = (): void => {
|
|
5
|
-
const htmlClasses = document.documentElement.className.split(' ');
|
|
6
|
-
const removeClasses = htmlClasses.filter(isSwupClass);
|
|
7
|
-
document.documentElement.classList.remove(...removeClasses);
|
|
8
|
-
};
|
package/src/helpers/fetch.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { TransitionOptions } from '../modules/loadPage.js';
|
|
2
|
-
import { Options } from '../Swup.js';
|
|
3
|
-
|
|
4
|
-
export const fetch = (
|
|
5
|
-
options: TransitionOptions & { headers: Options['requestHeaders'] },
|
|
6
|
-
callback: (request: XMLHttpRequest) => void
|
|
7
|
-
): XMLHttpRequest => {
|
|
8
|
-
const defaults = {
|
|
9
|
-
url: window.location.pathname + window.location.search,
|
|
10
|
-
method: 'GET',
|
|
11
|
-
data: null,
|
|
12
|
-
headers: {}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const { url, method, headers, data } = { ...defaults, ...options };
|
|
16
|
-
|
|
17
|
-
const request = new XMLHttpRequest();
|
|
18
|
-
|
|
19
|
-
request.onreadystatechange = function () {
|
|
20
|
-
if (request.readyState === 4) {
|
|
21
|
-
// if (request.status === 500) {} else {}
|
|
22
|
-
callback(request);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
request.open(method, url, true);
|
|
27
|
-
Object.entries(headers).forEach(([key, header]) => {
|
|
28
|
-
request.setRequestHeader(key, header);
|
|
29
|
-
});
|
|
30
|
-
request.send(data);
|
|
31
|
-
|
|
32
|
-
return request;
|
|
33
|
-
};
|