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
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { query, queryAll } from '../utils.js';
|
|
2
|
-
|
|
3
|
-
export type PageHtmlData = {
|
|
4
|
-
title: string;
|
|
5
|
-
originalContent: string;
|
|
6
|
-
blocks: string[];
|
|
7
|
-
pageClass?: string;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export const getDataFromHtml = (html: string, containers: string[]): PageHtmlData => {
|
|
11
|
-
let fakeDom = document.createElement('html');
|
|
12
|
-
fakeDom.innerHTML = html;
|
|
13
|
-
let blocks: string[] = [];
|
|
14
|
-
|
|
15
|
-
containers.forEach((selector) => {
|
|
16
|
-
if (query(selector, fakeDom) == null) {
|
|
17
|
-
console.warn(`[swup] Container ${selector} not found on page.`);
|
|
18
|
-
return null;
|
|
19
|
-
} else {
|
|
20
|
-
if (queryAll(selector).length !== queryAll(selector, fakeDom).length) {
|
|
21
|
-
console.warn(`[swup] Mismatched number of containers found on new page.`);
|
|
22
|
-
}
|
|
23
|
-
queryAll(selector).forEach((item, index) => {
|
|
24
|
-
queryAll(selector, fakeDom)[index].setAttribute('data-swup', String(blocks.length));
|
|
25
|
-
blocks.push(queryAll(selector, fakeDom)[index].outerHTML);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const title = query('title', fakeDom)?.innerText || '';
|
|
31
|
-
const pageClass = query('body', fakeDom)?.className;
|
|
32
|
-
|
|
33
|
-
// to prevent memory leaks
|
|
34
|
-
fakeDom.innerHTML = '';
|
|
35
|
-
// @ts-ignore don't want to type it as possible null, since it's created at the top of the function always
|
|
36
|
-
fakeDom = null;
|
|
37
|
-
|
|
38
|
-
return { title, pageClass, blocks, originalContent: html };
|
|
39
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { query, queryAll } from '../utils.js';
|
|
2
|
-
|
|
3
|
-
export const markSwupElements = (element: Element, containers: string[]): void => {
|
|
4
|
-
let blocks = 0;
|
|
5
|
-
|
|
6
|
-
containers.forEach((selector) => {
|
|
7
|
-
if (query(selector, element) == null) {
|
|
8
|
-
console.warn(`[swup] Container ${selector} not found on page.`);
|
|
9
|
-
} else {
|
|
10
|
-
queryAll(selector).forEach((item: Element, index: number) => {
|
|
11
|
-
queryAll(selector, element)[index].setAttribute('data-swup', String(blocks));
|
|
12
|
-
blocks++;
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
};
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import Swup from '../../Swup.js';
|
|
3
|
-
import { Handler } from '../events.js';
|
|
4
|
-
|
|
5
|
-
describe('events', () => {
|
|
6
|
-
it('should add event handlers to handlers array', () => {
|
|
7
|
-
const swup = new Swup();
|
|
8
|
-
const handler = vi.fn();
|
|
9
|
-
|
|
10
|
-
swup.on('enabled', handler);
|
|
11
|
-
|
|
12
|
-
expect(swup._handlers.enabled.indexOf(handler)).toBe(0);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
it('should remove event handlers from handlers array', () => {
|
|
16
|
-
const swup = new Swup();
|
|
17
|
-
const handler = vi.fn();
|
|
18
|
-
|
|
19
|
-
swup.on('enabled', handler);
|
|
20
|
-
swup.on('animationInDone', handler);
|
|
21
|
-
swup.on('animationInStart', handler);
|
|
22
|
-
|
|
23
|
-
expect(swup._handlers.enabled.indexOf(handler)).toBe(0);
|
|
24
|
-
expect(swup._handlers.animationInDone.indexOf(handler)).toBe(0);
|
|
25
|
-
expect(swup._handlers.animationInStart.indexOf(handler)).toBe(0);
|
|
26
|
-
|
|
27
|
-
swup.off('enabled', handler);
|
|
28
|
-
expect(swup._handlers.enabled.indexOf(handler)).toBe(-1);
|
|
29
|
-
|
|
30
|
-
swup.off('animationInDone');
|
|
31
|
-
expect(swup._handlers.animationInDone.indexOf(handler)).toBe(-1);
|
|
32
|
-
|
|
33
|
-
swup.off();
|
|
34
|
-
expect(swup._handlers.animationInStart.indexOf(handler)).toBe(-1);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('should trigger event handler', () => {
|
|
38
|
-
const swup = new Swup();
|
|
39
|
-
const handler = vi.fn();
|
|
40
|
-
|
|
41
|
-
swup.on('enabled', handler);
|
|
42
|
-
|
|
43
|
-
swup.triggerEvent('enabled');
|
|
44
|
-
|
|
45
|
-
expect(handler).toBeCalledTimes(1);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should trigger event handler with event', () => {
|
|
49
|
-
const swup = new Swup();
|
|
50
|
-
const handler: Handler<'popState'> = vi.fn();
|
|
51
|
-
const event = new PopStateEvent('');
|
|
52
|
-
|
|
53
|
-
swup.on('popState', handler);
|
|
54
|
-
swup.triggerEvent('popState', event);
|
|
55
|
-
|
|
56
|
-
expect(handler).toBeCalledWith(event);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('types work and error when necessary', () => {
|
|
60
|
-
const swup = new Swup();
|
|
61
|
-
|
|
62
|
-
// @ts-expect-no-error
|
|
63
|
-
swup.on('popState', (event: PopStateEvent) => {});
|
|
64
|
-
// @ts-expect-no-error
|
|
65
|
-
swup.triggerEvent('popState', new PopStateEvent(''));
|
|
66
|
-
|
|
67
|
-
// @ts-expect-error
|
|
68
|
-
swup.on('popState', (event: MouseEvent) => {});
|
|
69
|
-
// @ts-expect-error
|
|
70
|
-
swup.triggerEvent('popState', new MouseEvent(''));
|
|
71
|
-
});
|
|
72
|
-
});
|
package/src/modules/events.ts
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import Swup from '../Swup.js';
|
|
2
|
-
import { DelegateEvent } from 'delegate-it';
|
|
3
|
-
|
|
4
|
-
type HandlersEventMap = {
|
|
5
|
-
animationInDone: undefined;
|
|
6
|
-
animationInStart: undefined;
|
|
7
|
-
animationOutDone: undefined;
|
|
8
|
-
animationOutStart: undefined;
|
|
9
|
-
animationSkipped: undefined;
|
|
10
|
-
clickLink: DelegateEvent<MouseEvent>;
|
|
11
|
-
contentReplaced: PopStateEvent | undefined;
|
|
12
|
-
disabled: undefined;
|
|
13
|
-
enabled: undefined;
|
|
14
|
-
openPageInNewTab: DelegateEvent<MouseEvent>;
|
|
15
|
-
pageLoaded: undefined;
|
|
16
|
-
pageRetrievedFromCache: undefined;
|
|
17
|
-
pageView: PopStateEvent | undefined;
|
|
18
|
-
popState: PopStateEvent;
|
|
19
|
-
samePage: DelegateEvent<MouseEvent>;
|
|
20
|
-
samePageWithHash: DelegateEvent<MouseEvent>;
|
|
21
|
-
serverError: undefined;
|
|
22
|
-
transitionStart: PopStateEvent | undefined;
|
|
23
|
-
transitionEnd: PopStateEvent | undefined;
|
|
24
|
-
willReplaceContent: PopStateEvent | undefined;
|
|
25
|
-
};
|
|
26
|
-
type AvailableEventNames = keyof HandlersEventMap;
|
|
27
|
-
|
|
28
|
-
export type Handler<T extends keyof HandlersEventMap> = (event: HandlersEventMap[T]) => void;
|
|
29
|
-
export type Handlers = {
|
|
30
|
-
[Key in keyof HandlersEventMap]: Handler<Key>[];
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
export function on<TEventType extends AvailableEventNames>(
|
|
34
|
-
this: Swup,
|
|
35
|
-
event: TEventType,
|
|
36
|
-
handler: Handler<TEventType>
|
|
37
|
-
): void {
|
|
38
|
-
const eventHandlers = this._handlers[event] as Handler<TEventType>[];
|
|
39
|
-
|
|
40
|
-
if (eventHandlers) {
|
|
41
|
-
eventHandlers.push(handler);
|
|
42
|
-
} else {
|
|
43
|
-
console.warn(`Unsupported event ${event}.`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function off<TEventType extends AvailableEventNames>(
|
|
48
|
-
this: Swup,
|
|
49
|
-
event?: TEventType,
|
|
50
|
-
handler?: Handler<TEventType>
|
|
51
|
-
) {
|
|
52
|
-
if (event && handler) {
|
|
53
|
-
const eventHandlers = this._handlers[event] as Handler<TEventType>[];
|
|
54
|
-
// Remove specific handler
|
|
55
|
-
if (eventHandlers.includes(handler)) {
|
|
56
|
-
(this._handlers[event] as Handler<TEventType>[]) = eventHandlers.filter(
|
|
57
|
-
(h) => h !== handler
|
|
58
|
-
);
|
|
59
|
-
} else {
|
|
60
|
-
console.warn(`Handler for event '${event}' not found.`);
|
|
61
|
-
}
|
|
62
|
-
} else if (event) {
|
|
63
|
-
// Remove all handlers for specific event
|
|
64
|
-
this._handlers[event] = [];
|
|
65
|
-
} else {
|
|
66
|
-
// Remove all handlers for all events
|
|
67
|
-
Object.keys(this._handlers).forEach((event) => {
|
|
68
|
-
this._handlers[event as keyof HandlersEventMap] = [];
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function triggerEvent<TEventType extends AvailableEventNames>(
|
|
74
|
-
this: Swup,
|
|
75
|
-
eventName: TEventType,
|
|
76
|
-
originalEvent?: HandlersEventMap[TEventType]
|
|
77
|
-
): void {
|
|
78
|
-
const eventHandlers = this._handlers[eventName] as Handler<TEventType>[];
|
|
79
|
-
|
|
80
|
-
// call saved handlers with "on" method and pass originalEvent object if available
|
|
81
|
-
eventHandlers.forEach((handler) => {
|
|
82
|
-
try {
|
|
83
|
-
handler(originalEvent as HandlersEventMap[TEventType]);
|
|
84
|
-
} catch (error) {
|
|
85
|
-
console.error(error);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// trigger event on document with prefix "swup:"
|
|
90
|
-
const event = new CustomEvent(`swup:${eventName}`, { detail: eventName });
|
|
91
|
-
document.dispatchEvent(event);
|
|
92
|
-
}
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import { queryAll, toMs } from '../utils.js';
|
|
2
|
-
import Swup from '../Swup.js';
|
|
3
|
-
|
|
4
|
-
// Transition property/event sniffing
|
|
5
|
-
let transitionProp = 'transition';
|
|
6
|
-
let transitionEndEvent = 'transitionend';
|
|
7
|
-
let animationProp = 'animation';
|
|
8
|
-
let animationEndEvent = 'animationend';
|
|
9
|
-
|
|
10
|
-
if (window.ontransitionend === undefined && window.onwebkittransitionend !== undefined) {
|
|
11
|
-
transitionProp = 'WebkitTransition';
|
|
12
|
-
transitionEndEvent = 'webkitTransitionEnd';
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (window.onanimationend === undefined && window.onwebkitanimationend !== undefined) {
|
|
16
|
-
animationProp = 'WebkitAnimation';
|
|
17
|
-
animationEndEvent = 'webkitAnimationEnd';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function getAnimationPromises(
|
|
21
|
-
this: Swup,
|
|
22
|
-
// we don't use this argument, but JS plugin depends on it with
|
|
23
|
-
// its own version of getAnimationPromises, so it must be specified when
|
|
24
|
-
// getAnimationPromises is being used
|
|
25
|
-
animationType: 'in' | 'out'
|
|
26
|
-
): Promise<void>[] {
|
|
27
|
-
const selector = this.options.animationSelector;
|
|
28
|
-
|
|
29
|
-
// Allow usage of swup without animations
|
|
30
|
-
if (selector === false) {
|
|
31
|
-
// Use array of a single resolved promise instead of an empty array to allow
|
|
32
|
-
// possible future use with Promise.race() which requires an actual value
|
|
33
|
-
return [Promise.resolve()];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const animatedElements = queryAll(selector, document.body);
|
|
37
|
-
|
|
38
|
-
// Warn if no elements match the animationSelector, but keep things going
|
|
39
|
-
if (!animatedElements.length) {
|
|
40
|
-
console.warn(`[swup] No elements found matching animationSelector \`${selector}\``);
|
|
41
|
-
return [Promise.resolve()];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const animationPromises = animatedElements
|
|
45
|
-
.map((element) => getAnimationPromiseForElement(element))
|
|
46
|
-
.filter(Boolean) as Promise<void>[];
|
|
47
|
-
|
|
48
|
-
if (!animationPromises.length) {
|
|
49
|
-
console.warn(
|
|
50
|
-
`[swup] No CSS animation duration defined on elements matching \`${selector}\``
|
|
51
|
-
);
|
|
52
|
-
return [Promise.resolve()];
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return animationPromises;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const isTransitionOrAnimationEvent = (event: any): event is TransitionEvent | AnimationEvent =>
|
|
59
|
-
[transitionEndEvent, animationEndEvent].includes(event.type);
|
|
60
|
-
|
|
61
|
-
function getAnimationPromiseForElement(element: Element): Promise<void> | undefined {
|
|
62
|
-
const { type, timeout, propCount } = getTransitionInfo(element);
|
|
63
|
-
|
|
64
|
-
// Resolve immediately if no transition defined
|
|
65
|
-
if (!type || !timeout) {
|
|
66
|
-
return undefined;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return new Promise((resolve) => {
|
|
70
|
-
const endEvent = type === 'transition' ? transitionEndEvent : animationEndEvent;
|
|
71
|
-
const startTime = performance.now();
|
|
72
|
-
let propsTransitioned = 0;
|
|
73
|
-
|
|
74
|
-
const end = () => {
|
|
75
|
-
element.removeEventListener(endEvent, onEnd);
|
|
76
|
-
resolve();
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const onEnd: EventListener = (event) => {
|
|
80
|
-
// Skip transitions on child elements
|
|
81
|
-
if (event.target !== element) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (!isTransitionOrAnimationEvent(event)) {
|
|
86
|
-
throw new Error('Not a transition or animation event.');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Skip transitions that happened before we started listening
|
|
90
|
-
const elapsedTime = (performance.now() - startTime) / 1000;
|
|
91
|
-
if (elapsedTime < event.elapsedTime) {
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// End if all properties have transitioned
|
|
96
|
-
if (++propsTransitioned >= propCount) {
|
|
97
|
-
end();
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
setTimeout(() => {
|
|
102
|
-
if (propsTransitioned < propCount) {
|
|
103
|
-
end();
|
|
104
|
-
}
|
|
105
|
-
}, timeout + 1);
|
|
106
|
-
|
|
107
|
-
element.addEventListener(endEvent, onEnd);
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export function getTransitionInfo(
|
|
112
|
-
element: Element,
|
|
113
|
-
expectedType: 'animation' | 'transition' | null = null
|
|
114
|
-
) {
|
|
115
|
-
const styles = window.getComputedStyle(element);
|
|
116
|
-
|
|
117
|
-
// not sure what to do about the below mess other than casting, but it's a mess
|
|
118
|
-
const transitionDelay = `${transitionProp}Delay` as keyof CSSStyleDeclaration;
|
|
119
|
-
const transitionDuration = `${transitionProp}Duration` as keyof CSSStyleDeclaration;
|
|
120
|
-
const animationDelay = `${animationProp}Delay` as keyof CSSStyleDeclaration;
|
|
121
|
-
const animationDuration = `${animationProp}Duration` as keyof CSSStyleDeclaration;
|
|
122
|
-
|
|
123
|
-
const transitionDelays = (
|
|
124
|
-
styles[transitionDelay] as CSSStyleDeclaration['transitionDelay']
|
|
125
|
-
).split(', ');
|
|
126
|
-
const transitionDurations = (
|
|
127
|
-
(styles[transitionDuration] || '') as CSSStyleDeclaration['transitionDuration']
|
|
128
|
-
).split(', ');
|
|
129
|
-
const transitionTimeout = calculateTimeout(transitionDelays, transitionDurations);
|
|
130
|
-
|
|
131
|
-
const animationDelays = (
|
|
132
|
-
(styles[animationDelay] || '') as CSSStyleDeclaration['animationDelay']
|
|
133
|
-
).split(', ');
|
|
134
|
-
const animationDurations = (
|
|
135
|
-
(styles[animationDuration] || '') as CSSStyleDeclaration['animationDuration']
|
|
136
|
-
).split(', ');
|
|
137
|
-
const animationTimeout = calculateTimeout(animationDelays, animationDurations);
|
|
138
|
-
|
|
139
|
-
let type: string | null = '';
|
|
140
|
-
let timeout = 0;
|
|
141
|
-
let propCount = 0;
|
|
142
|
-
|
|
143
|
-
if (expectedType === 'transition') {
|
|
144
|
-
if (transitionTimeout > 0) {
|
|
145
|
-
type = 'transition';
|
|
146
|
-
timeout = transitionTimeout;
|
|
147
|
-
propCount = transitionDurations.length;
|
|
148
|
-
}
|
|
149
|
-
} else if (expectedType === 'animation') {
|
|
150
|
-
if (animationTimeout > 0) {
|
|
151
|
-
type = 'animation';
|
|
152
|
-
timeout = animationTimeout;
|
|
153
|
-
propCount = animationDurations.length;
|
|
154
|
-
}
|
|
155
|
-
} else {
|
|
156
|
-
timeout = Math.max(transitionTimeout, animationTimeout);
|
|
157
|
-
type =
|
|
158
|
-
timeout > 0
|
|
159
|
-
? transitionTimeout > animationTimeout
|
|
160
|
-
? 'transition'
|
|
161
|
-
: 'animation'
|
|
162
|
-
: null;
|
|
163
|
-
propCount = type
|
|
164
|
-
? type === 'transition'
|
|
165
|
-
? transitionDurations.length
|
|
166
|
-
: animationDurations.length
|
|
167
|
-
: 0;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return {
|
|
171
|
-
type,
|
|
172
|
-
timeout,
|
|
173
|
-
propCount
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
function calculateTimeout(delays: string[], durations: string[]) {
|
|
178
|
-
while (delays.length < durations.length) {
|
|
179
|
-
delays = delays.concat(delays);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
return Math.max(...durations.map((duration, i) => toMs(duration) + toMs(delays[i])));
|
|
183
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { getDataFromHtml } from '../helpers.js';
|
|
2
|
-
import Swup from '../Swup.js';
|
|
3
|
-
import { PageHtmlData } from '../helpers/getDataFromHtml.js';
|
|
4
|
-
|
|
5
|
-
export type PageData = PageHtmlData & {
|
|
6
|
-
responseURL: string;
|
|
7
|
-
};
|
|
8
|
-
export const getPageData = function (this: Swup, request: XMLHttpRequest): PageData | null {
|
|
9
|
-
// this method can be replaced in case other content than html is expected to be received from server
|
|
10
|
-
// this function should always return { title, pageClass, originalContent, blocks, responseURL }
|
|
11
|
-
// in case page has invalid structure - return null
|
|
12
|
-
const html = request.responseText;
|
|
13
|
-
const pageHtmlData = getDataFromHtml(html, this.options.containers);
|
|
14
|
-
|
|
15
|
-
if (!pageHtmlData) {
|
|
16
|
-
console.warn('[swup] Received page is invalid.');
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
...pageHtmlData,
|
|
22
|
-
responseURL: request.responseURL || window.location.href
|
|
23
|
-
};
|
|
24
|
-
};
|
package/src/modules/loadPage.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { classify, createHistoryRecord, updateHistoryRecord, getCurrentUrl } from '../helpers.js';
|
|
2
|
-
import Swup from '../Swup.js';
|
|
3
|
-
import { PageRecord } from './Cache.js';
|
|
4
|
-
|
|
5
|
-
export type HistoryAction = 'push' | 'replace';
|
|
6
|
-
|
|
7
|
-
export type TransitionOptions = {
|
|
8
|
-
url: string;
|
|
9
|
-
customTransition?: string;
|
|
10
|
-
history?: HistoryAction;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export type PageLoadOptions = {
|
|
14
|
-
url: string;
|
|
15
|
-
customTransition?: string;
|
|
16
|
-
history?: HistoryAction;
|
|
17
|
-
event?: PopStateEvent;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export function loadPage(this: Swup, data: TransitionOptions) {
|
|
21
|
-
const { url } = data;
|
|
22
|
-
|
|
23
|
-
// Check if the visit should be ignored
|
|
24
|
-
if (this.shouldIgnoreVisit(url)) {
|
|
25
|
-
window.location.href = url;
|
|
26
|
-
} else {
|
|
27
|
-
this.performPageLoad(data);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function performPageLoad(this: Swup, data: PageLoadOptions) {
|
|
32
|
-
const { url, event, customTransition, history: historyAction = 'push' } = data ?? {};
|
|
33
|
-
|
|
34
|
-
const isHistoryVisit = event instanceof PopStateEvent;
|
|
35
|
-
const skipTransition = this.shouldSkipTransition({ url, event });
|
|
36
|
-
|
|
37
|
-
this.triggerEvent('transitionStart', event);
|
|
38
|
-
|
|
39
|
-
// set transition object
|
|
40
|
-
this.updateTransition(getCurrentUrl(), url, customTransition);
|
|
41
|
-
if (customTransition != null) {
|
|
42
|
-
document.documentElement.classList.add(`to-${classify(customTransition)}`);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// start/skip animation
|
|
46
|
-
const animationPromises = this.leavePage({ event, skipTransition });
|
|
47
|
-
|
|
48
|
-
// Load page data
|
|
49
|
-
const fetchPromise = this.fetchPage(data);
|
|
50
|
-
|
|
51
|
-
// create history record if this is not a popstate call (with or without anchor)
|
|
52
|
-
if (!isHistoryVisit) {
|
|
53
|
-
const historyUrl = url + (this.scrollToElement || '');
|
|
54
|
-
if (historyAction === 'replace') {
|
|
55
|
-
updateHistoryRecord(historyUrl);
|
|
56
|
-
} else {
|
|
57
|
-
createHistoryRecord(historyUrl);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
this.currentPageUrl = getCurrentUrl();
|
|
62
|
-
|
|
63
|
-
// when everything is ready, render the page
|
|
64
|
-
Promise.all<PageRecord | void>([fetchPromise, ...animationPromises])
|
|
65
|
-
.then(([pageData]) => {
|
|
66
|
-
this.renderPage(pageData as PageRecord, { event, skipTransition });
|
|
67
|
-
})
|
|
68
|
-
.catch((errorUrl) => {
|
|
69
|
-
// Return early if errorUrl is not defined (probably aborted preload request)
|
|
70
|
-
if (errorUrl === undefined) return;
|
|
71
|
-
|
|
72
|
-
// Rewrite `skipPopStateHandling` to redirect manually when `history.go` is processed
|
|
73
|
-
this.options.skipPopStateHandling = () => {
|
|
74
|
-
window.location = errorUrl;
|
|
75
|
-
return true;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
// Go back to the actual page we're still at
|
|
79
|
-
history.go(-1);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import Swup from '../Swup.js';
|
|
2
|
-
|
|
3
|
-
export function updateTransition(this: Swup, from: string, to: string, custom?: string): void {
|
|
4
|
-
this.transition = { from, to, custom };
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function shouldSkipTransition(this: Swup, { event }: { url?: string; event?: Event }) {
|
|
8
|
-
const isHistoryVisit = event instanceof PopStateEvent;
|
|
9
|
-
return !!(isHistoryVisit && !this.options.animateHistoryBrowsing);
|
|
10
|
-
}
|
/package/dist/types/{modules/__test__/events.test.d.ts → helpers/__test__/matchPath.test.d.ts}
RENAMED
|
File without changes
|