swup 4.0.0-rc.14 → 4.0.0-rc.21
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 +100 -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 +62 -54
- package/dist/types/helpers/Location.d.ts +10 -7
- package/dist/types/helpers/delegateEvent.d.ts +3 -5
- package/dist/types/helpers/matchPath.d.ts +3 -0
- package/dist/types/helpers.d.ts +7 -10
- package/dist/types/index.d.ts +9 -6
- package/dist/types/modules/Cache.d.ts +15 -15
- 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__/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 +6 -3
- package/dist/types/modules/fetchPage.d.ts +24 -4
- package/dist/types/modules/getAnchorElement.d.ts +8 -0
- package/dist/types/modules/leavePage.d.ts +6 -3
- package/dist/types/modules/plugins.d.ts +12 -5
- package/dist/types/modules/renderPage.d.ts +7 -7
- 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/dist/types/utils.d.ts +1 -1
- package/package.json +7 -6
- package/src/Swup.ts +83 -65
- package/src/__test__/index.test.ts +3 -3
- package/src/helpers/Location.ts +2 -2
- package/src/helpers/delegateEvent.ts +2 -2
- package/src/helpers.ts +0 -1
- package/src/index.ts +34 -4
- package/src/modules/Cache.ts +2 -2
- package/src/modules/Classes.ts +48 -0
- package/src/modules/Context.ts +49 -19
- package/src/modules/Hooks.ts +103 -83
- package/src/modules/__test__/cache.test.ts +6 -6
- package/src/modules/__test__/hooks.test.ts +111 -40
- package/src/modules/__test__/replaceContent.test.ts +92 -0
- package/src/modules/{getAnimationPromises.ts → awaitAnimations.ts} +13 -18
- package/src/modules/enterPage.ts +21 -17
- package/src/modules/fetchPage.ts +12 -12
- package/src/modules/getAnchorElement.ts +2 -1
- package/src/modules/leavePage.ts +16 -12
- package/src/modules/plugins.ts +11 -8
- package/src/modules/renderPage.ts +28 -18
- package/src/modules/replaceContent.ts +24 -16
- package/src/modules/visit.ts +143 -0
- package/src/utils/index.ts +1 -2
- 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/destroy.d.ts +0 -2
- package/dist/types/modules/enable.d.ts +0 -2
- 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/handleLinkToSamePage.d.ts +0 -2
- package/dist/types/modules/isSameResolvedUrl.d.ts +0 -8
- package/dist/types/modules/linkClickHandler.d.ts +0 -3
- package/dist/types/modules/loadPage.d.ts +0 -12
- package/dist/types/modules/off.d.ts +0 -3
- package/dist/types/modules/on.d.ts +0 -5
- package/dist/types/modules/popStateHandler.d.ts +0 -2
- package/dist/types/modules/resolveUrl.d.ts +0 -7
- package/dist/types/modules/shouldIgnoreVisit.d.ts +0 -4
- package/dist/types/modules/transitions.d.ts +0 -6
- package/dist/types/modules/triggerEvent.d.ts +0 -3
- package/dist/types/modules/triggerWillOpenNewWindow.d.ts +0 -2
- package/dist/types/modules/updateTransition.d.ts +0 -2
- package/readme.md +0 -78
- package/src/helpers/cleanupAnimationClasses.ts +0 -8
- package/src/modules/loadPage.ts +0 -99
- /package/dist/types/{modules/__test__/events.test.d.ts → helpers/__test__/matchPath.test.d.ts} +0 -0
- /package/dist/types/modules/__test__/{fetchPage.test.d.ts → cache.test.d.ts} +0 -0
package/src/modules/Hooks.ts
CHANGED
|
@@ -4,33 +4,33 @@ import Swup, { Options } from '../Swup.js';
|
|
|
4
4
|
import { isPromise, runAsPromise } from '../utils.js';
|
|
5
5
|
import { Context } from './Context.js';
|
|
6
6
|
import { FetchOptions, PageData } from './fetchPage.js';
|
|
7
|
-
import { AnimationDirection } from './
|
|
7
|
+
import { AnimationDirection } from './awaitAnimations.js';
|
|
8
8
|
|
|
9
9
|
export interface HookDefinitions {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
10
|
+
'animation:out:start': undefined;
|
|
11
|
+
'animation:out:end': undefined;
|
|
12
|
+
'animation:in:start': undefined;
|
|
13
|
+
'animation:in:end': undefined;
|
|
14
|
+
'animation:skip': undefined;
|
|
15
|
+
'animation:await': { direction: AnimationDirection };
|
|
16
|
+
'cache:clear': undefined;
|
|
17
|
+
'cache:set': { page: PageData };
|
|
18
|
+
'content:replace': { page: PageData };
|
|
19
|
+
'content:scroll': { options: ScrollIntoViewOptions };
|
|
20
|
+
'enable': undefined;
|
|
21
|
+
'disable': undefined;
|
|
22
|
+
'fetch:request': { url: string; options: FetchOptions };
|
|
23
|
+
'fetch:error': { url: string; status: number; response: Response };
|
|
24
|
+
'history:popstate': { event: PopStateEvent };
|
|
25
|
+
'link:click': { el: HTMLAnchorElement; event: DelegateEvent<MouseEvent> };
|
|
26
|
+
'link:self': undefined;
|
|
27
|
+
'link:anchor': { hash: string; options: ScrollIntoViewOptions };
|
|
28
|
+
'link:newtab': { href: string };
|
|
29
|
+
'page:request': { url: string; options: FetchOptions };
|
|
30
|
+
'page:load': { page: PageData; cache?: boolean };
|
|
31
|
+
'page:view': { url: string; title: string };
|
|
32
|
+
'visit:start': undefined;
|
|
33
|
+
'visit:end': undefined;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export type HookArguments<T extends HookName> = HookDefinitions[T];
|
|
@@ -38,18 +38,28 @@ export type HookArguments<T extends HookName> = HookDefinitions[T];
|
|
|
38
38
|
export type HookName = keyof HookDefinitions;
|
|
39
39
|
|
|
40
40
|
export type Handler<T extends HookName> = (
|
|
41
|
+
/** The global context object for the current visit */
|
|
41
42
|
context: Context,
|
|
42
|
-
|
|
43
|
+
/** The local arguments passed into the handler */
|
|
44
|
+
args: HookArguments<T>,
|
|
45
|
+
/** The default handler to be executed, available if replacing an internal hook handler */
|
|
46
|
+
defaultHandler?: Handler<T>
|
|
43
47
|
) => Promise<any> | void;
|
|
44
48
|
|
|
45
49
|
export type Handlers = {
|
|
46
50
|
[K in HookName]: Handler<K>[];
|
|
47
51
|
};
|
|
48
52
|
|
|
53
|
+
export type HookUnregister = () => void;
|
|
54
|
+
|
|
49
55
|
export type HookOptions = {
|
|
56
|
+
/** Execute the hook once, then remove the handler */
|
|
50
57
|
once?: boolean;
|
|
58
|
+
/** Execute the hook before the internal default handler */
|
|
51
59
|
before?: boolean;
|
|
60
|
+
/** Set a priority for when to execute this hook. Lower numbers execute first. Default: `0` */
|
|
52
61
|
priority?: number;
|
|
62
|
+
/** Replace the internal default handler with this hook handler */
|
|
53
63
|
replace?: boolean;
|
|
54
64
|
};
|
|
55
65
|
|
|
@@ -79,30 +89,30 @@ export class Hooks {
|
|
|
79
89
|
// Can we deduplicate this somehow? Or make it error when not in sync with HookDefinitions?
|
|
80
90
|
// https://stackoverflow.com/questions/53387838/how-to-ensure-an-arrays-values-the-keys-of-a-typescript-interface/53395649
|
|
81
91
|
readonly hooks: HookName[] = [
|
|
82
|
-
'
|
|
83
|
-
'
|
|
84
|
-
'
|
|
85
|
-
'
|
|
86
|
-
'
|
|
87
|
-
'
|
|
88
|
-
'
|
|
89
|
-
'
|
|
90
|
-
'
|
|
91
|
-
'
|
|
92
|
-
'
|
|
93
|
-
'
|
|
94
|
-
'
|
|
95
|
-
'
|
|
96
|
-
'
|
|
97
|
-
'
|
|
98
|
-
'
|
|
99
|
-
'
|
|
100
|
-
'
|
|
101
|
-
'
|
|
102
|
-
'
|
|
103
|
-
'
|
|
104
|
-
'
|
|
105
|
-
'
|
|
92
|
+
'animation:out:start',
|
|
93
|
+
'animation:out:end',
|
|
94
|
+
'animation:in:start',
|
|
95
|
+
'animation:in:end',
|
|
96
|
+
'animation:skip',
|
|
97
|
+
'animation:await',
|
|
98
|
+
'cache:clear',
|
|
99
|
+
'cache:set',
|
|
100
|
+
'content:replace',
|
|
101
|
+
'content:scroll',
|
|
102
|
+
'enable',
|
|
103
|
+
'disable',
|
|
104
|
+
'fetch:request',
|
|
105
|
+
'fetch:error',
|
|
106
|
+
'history:popstate',
|
|
107
|
+
'link:click',
|
|
108
|
+
'link:self',
|
|
109
|
+
'link:anchor',
|
|
110
|
+
'link:newtab',
|
|
111
|
+
'page:request',
|
|
112
|
+
'page:load',
|
|
113
|
+
'page:view',
|
|
114
|
+
'visit:start',
|
|
115
|
+
'visit:end'
|
|
106
116
|
];
|
|
107
117
|
|
|
108
118
|
constructor(swup: Swup) {
|
|
@@ -140,9 +150,8 @@ export class Hooks {
|
|
|
140
150
|
const ledger = this.registry.get(hook);
|
|
141
151
|
if (ledger) {
|
|
142
152
|
return ledger;
|
|
143
|
-
} else {
|
|
144
|
-
console.error(`Unknown hook '${hook}'`);
|
|
145
153
|
}
|
|
154
|
+
console.error(`Unknown hook '${hook}'`);
|
|
146
155
|
}
|
|
147
156
|
|
|
148
157
|
/**
|
|
@@ -162,21 +171,26 @@ export class Hooks {
|
|
|
162
171
|
* - `before`: Execute the handler before the default handler
|
|
163
172
|
* - `priority`: Specify the order in which the handlers are executed
|
|
164
173
|
* - `replace`: Replace the default handler with this handler
|
|
165
|
-
* @returns
|
|
174
|
+
* @returns A function to unregister the handler
|
|
166
175
|
*/
|
|
167
|
-
on<T extends HookName>(hook: T, handler: Handler<T>):
|
|
168
|
-
on<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions):
|
|
169
|
-
on<T extends HookName>(
|
|
176
|
+
on<T extends HookName>(hook: T, handler: Handler<T>): HookUnregister;
|
|
177
|
+
on<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions): HookUnregister;
|
|
178
|
+
on<T extends HookName>(
|
|
179
|
+
hook: T,
|
|
180
|
+
handler: Handler<T>,
|
|
181
|
+
options: HookOptions = {}
|
|
182
|
+
): HookUnregister {
|
|
170
183
|
const ledger = this.get(hook);
|
|
171
184
|
if (!ledger) {
|
|
172
185
|
console.warn(`Hook '${hook}' not found.`);
|
|
173
|
-
return
|
|
186
|
+
return () => {};
|
|
174
187
|
}
|
|
175
188
|
|
|
176
189
|
const id = ledger.size + 1;
|
|
177
190
|
const registration: HookRegistration<T> = { ...options, id, hook, handler };
|
|
178
191
|
ledger.set(handler, registration);
|
|
179
|
-
|
|
192
|
+
|
|
193
|
+
return () => this.off(hook, handler);
|
|
180
194
|
}
|
|
181
195
|
|
|
182
196
|
/**
|
|
@@ -185,16 +199,16 @@ export class Hooks {
|
|
|
185
199
|
* @param hook Name of the hook to listen for
|
|
186
200
|
* @param handler The handler function to execute
|
|
187
201
|
* @param options Any other event options (see `hooks.on()` for details)
|
|
188
|
-
* @returns
|
|
202
|
+
* @returns A function to unregister the handler
|
|
189
203
|
* @see on
|
|
190
204
|
*/
|
|
191
|
-
before<T extends HookName>(hook: T, handler: Handler<T>):
|
|
192
|
-
before<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions):
|
|
205
|
+
before<T extends HookName>(hook: T, handler: Handler<T>): HookUnregister;
|
|
206
|
+
before<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions): HookUnregister;
|
|
193
207
|
before<T extends HookName>(
|
|
194
208
|
hook: T,
|
|
195
209
|
handler: Handler<T>,
|
|
196
210
|
options: HookOptions = {}
|
|
197
|
-
):
|
|
211
|
+
): HookUnregister {
|
|
198
212
|
return this.on(hook, handler, { ...options, before: true });
|
|
199
213
|
}
|
|
200
214
|
|
|
@@ -204,16 +218,16 @@ export class Hooks {
|
|
|
204
218
|
* @param hook Name of the hook to listen for
|
|
205
219
|
* @param handler The handler function to execute instead of the default handler
|
|
206
220
|
* @param options Any other event options (see `hooks.on()` for details)
|
|
207
|
-
* @returns
|
|
221
|
+
* @returns A function to unregister the handler
|
|
208
222
|
* @see on
|
|
209
223
|
*/
|
|
210
|
-
replace<T extends HookName>(hook: T, handler: Handler<T>):
|
|
211
|
-
replace<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions):
|
|
224
|
+
replace<T extends HookName>(hook: T, handler: Handler<T>): HookUnregister;
|
|
225
|
+
replace<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions): HookUnregister;
|
|
212
226
|
replace<T extends HookName>(
|
|
213
227
|
hook: T,
|
|
214
228
|
handler: Handler<T>,
|
|
215
229
|
options: HookOptions = {}
|
|
216
|
-
):
|
|
230
|
+
): HookUnregister {
|
|
217
231
|
return this.on(hook, handler, { ...options, replace: true });
|
|
218
232
|
}
|
|
219
233
|
|
|
@@ -225,9 +239,13 @@ export class Hooks {
|
|
|
225
239
|
* @param options Any other event options (see `hooks.on()` for details)
|
|
226
240
|
* @see on
|
|
227
241
|
*/
|
|
228
|
-
once<T extends HookName>(hook: T, handler: Handler<T>):
|
|
229
|
-
once<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions):
|
|
230
|
-
once<T extends HookName>(
|
|
242
|
+
once<T extends HookName>(hook: T, handler: Handler<T>): HookUnregister;
|
|
243
|
+
once<T extends HookName>(hook: T, handler: Handler<T>, options: HookOptions): HookUnregister;
|
|
244
|
+
once<T extends HookName>(
|
|
245
|
+
hook: T,
|
|
246
|
+
handler: Handler<T>,
|
|
247
|
+
options: HookOptions = {}
|
|
248
|
+
): HookUnregister {
|
|
231
249
|
return this.on(hook, handler, { ...options, once: true });
|
|
232
250
|
}
|
|
233
251
|
|
|
@@ -241,7 +259,6 @@ export class Hooks {
|
|
|
241
259
|
off<T extends HookName>(hook: T, handler: Handler<T>): void;
|
|
242
260
|
off<T extends HookName>(hook: T, handler?: Handler<T>): void {
|
|
243
261
|
const ledger = this.get(hook);
|
|
244
|
-
|
|
245
262
|
if (ledger && handler) {
|
|
246
263
|
const deleted = ledger.delete(handler);
|
|
247
264
|
if (!deleted) {
|
|
@@ -265,11 +282,11 @@ export class Hooks {
|
|
|
265
282
|
args?: HookArguments<T>,
|
|
266
283
|
defaultHandler?: Handler<T>
|
|
267
284
|
): Promise<any> {
|
|
268
|
-
const { before, handler, after } = this.getHandlers(hook, defaultHandler);
|
|
285
|
+
const { before, handler, after, replaced } = this.getHandlers(hook, defaultHandler);
|
|
269
286
|
await this.execute(before, args);
|
|
270
|
-
const [result] = await this.execute(handler, args);
|
|
287
|
+
const [result] = await this.execute(handler, args, replaced ? defaultHandler : undefined);
|
|
271
288
|
await this.execute(after, args);
|
|
272
|
-
this.dispatchDomEvent(hook);
|
|
289
|
+
this.dispatchDomEvent(hook, args);
|
|
273
290
|
return result;
|
|
274
291
|
}
|
|
275
292
|
|
|
@@ -286,11 +303,11 @@ export class Hooks {
|
|
|
286
303
|
args?: HookArguments<T>,
|
|
287
304
|
defaultHandler?: Handler<T>
|
|
288
305
|
): any {
|
|
289
|
-
const { before, after, handler } = this.getHandlers(hook, defaultHandler);
|
|
306
|
+
const { before, after, handler, replaced } = this.getHandlers(hook, defaultHandler);
|
|
290
307
|
this.executeSync(before, args);
|
|
291
|
-
const [result] = this.executeSync(handler, args);
|
|
308
|
+
const [result] = this.executeSync(handler, args, replaced ? defaultHandler : undefined);
|
|
292
309
|
this.executeSync(after, args);
|
|
293
|
-
this.dispatchDomEvent(hook);
|
|
310
|
+
this.dispatchDomEvent(hook, args);
|
|
294
311
|
return result;
|
|
295
312
|
}
|
|
296
313
|
|
|
@@ -301,11 +318,12 @@ export class Hooks {
|
|
|
301
318
|
*/
|
|
302
319
|
async execute<T extends HookName>(
|
|
303
320
|
registrations: HookRegistration<T>[],
|
|
304
|
-
args?: HookArguments<T
|
|
321
|
+
args?: HookArguments<T>,
|
|
322
|
+
defaultHandler?: Handler<T>
|
|
305
323
|
): Promise<any> {
|
|
306
324
|
const results = [];
|
|
307
325
|
for (const { hook, handler, once } of registrations) {
|
|
308
|
-
const result = await runAsPromise(handler, [this.swup.context, args]);
|
|
326
|
+
const result = await runAsPromise(handler, [this.swup.context, args, defaultHandler]);
|
|
309
327
|
results.push(result);
|
|
310
328
|
if (once) {
|
|
311
329
|
this.off(hook, handler);
|
|
@@ -321,11 +339,12 @@ export class Hooks {
|
|
|
321
339
|
*/
|
|
322
340
|
executeSync<T extends HookName>(
|
|
323
341
|
registrations: HookRegistration<T>[],
|
|
324
|
-
args?: HookArguments<T
|
|
342
|
+
args?: HookArguments<T>,
|
|
343
|
+
defaultHandler?: Handler<T>
|
|
325
344
|
): any[] {
|
|
326
345
|
const results = [];
|
|
327
346
|
for (const { hook, handler, once } of registrations) {
|
|
328
|
-
const result = handler(this.swup.context, args as HookArguments<T
|
|
347
|
+
const result = handler(this.swup.context, args as HookArguments<T>, defaultHandler);
|
|
329
348
|
results.push(result);
|
|
330
349
|
if (isPromise(result)) {
|
|
331
350
|
console.warn(
|
|
@@ -378,7 +397,7 @@ export class Hooks {
|
|
|
378
397
|
* @returns The sort direction
|
|
379
398
|
*/
|
|
380
399
|
sortRegistrations<T extends HookName>(a: HookRegistration<T>, b: HookRegistration<T>): number {
|
|
381
|
-
const priority = (
|
|
400
|
+
const priority = (a.priority ?? 0) - (b.priority ?? 0);
|
|
382
401
|
const id = a.id - b.id;
|
|
383
402
|
return priority || id || 0;
|
|
384
403
|
}
|
|
@@ -387,7 +406,8 @@ export class Hooks {
|
|
|
387
406
|
* Trigger a custom event on the `document`. Prefixed with `swup:`
|
|
388
407
|
* @param hook Name of the hook to trigger.
|
|
389
408
|
*/
|
|
390
|
-
dispatchDomEvent<T extends HookName>(hook: T): void {
|
|
391
|
-
|
|
409
|
+
dispatchDomEvent<T extends HookName>(hook: T, args?: HookArguments<T>): void {
|
|
410
|
+
const detail = { hook, args, context: this.swup.context };
|
|
411
|
+
document.dispatchEvent(new CustomEvent(`swup:${hook}`, { detail }));
|
|
392
412
|
}
|
|
393
413
|
}
|
|
@@ -77,18 +77,18 @@ describe('Cache', () => {
|
|
|
77
77
|
it('should trigger a hook on set', () => {
|
|
78
78
|
const handler = vi.fn();
|
|
79
79
|
|
|
80
|
-
swup.hooks.on('
|
|
80
|
+
swup.hooks.on('cache:set', handler);
|
|
81
81
|
|
|
82
82
|
cache.set(page1.url, page1);
|
|
83
83
|
|
|
84
84
|
expect(handler).toBeCalledTimes(1);
|
|
85
|
-
expect(handler).toBeCalledWith(ctx, { page: page1 });
|
|
85
|
+
expect(handler).toBeCalledWith(ctx, { page: page1 }, undefined);
|
|
86
86
|
});
|
|
87
87
|
|
|
88
88
|
it('should allow augmenting cache entries on save', () => {
|
|
89
89
|
const now = Date.now();
|
|
90
90
|
|
|
91
|
-
swup.hooks.on('
|
|
91
|
+
swup.hooks.on('cache:set', (_, { page }) => {
|
|
92
92
|
const ttl: CacheTtlData = { ttl: 1000, created: now };
|
|
93
93
|
cache.update(page.url, ttl as AugmentedCacheData);
|
|
94
94
|
});
|
|
@@ -101,7 +101,7 @@ describe('Cache', () => {
|
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
it('should allow manual pruning', () => {
|
|
104
|
-
swup.hooks.on('
|
|
104
|
+
swup.hooks.on('cache:set', (_, { page }) => {
|
|
105
105
|
cache.update(page.url, { index: cache.size } as AugmentedCacheData);
|
|
106
106
|
});
|
|
107
107
|
|
|
@@ -124,9 +124,9 @@ describe('Types', () => {
|
|
|
124
124
|
const cache = new Cache(swup);
|
|
125
125
|
|
|
126
126
|
// @ts-expect-no-error
|
|
127
|
-
swup.hooks.on('
|
|
127
|
+
swup.hooks.on('history:popstate', (ctx: Context, { event: PopStateEvent }) => {});
|
|
128
128
|
// @ts-expect-no-error
|
|
129
|
-
await swup.hooks.trigger('
|
|
129
|
+
await swup.hooks.trigger('history:popstate', { event: new PopStateEvent('') });
|
|
130
130
|
|
|
131
131
|
try {
|
|
132
132
|
// @ts-expect-error
|
|
@@ -4,7 +4,7 @@ import { Handler, Hooks } from '../Hooks.js';
|
|
|
4
4
|
import { Context } from '../Context.js';
|
|
5
5
|
|
|
6
6
|
describe('Hook registry', () => {
|
|
7
|
-
it('should add
|
|
7
|
+
it('should add handlers', () => {
|
|
8
8
|
const swup = new Swup();
|
|
9
9
|
const handler = vi.fn();
|
|
10
10
|
|
|
@@ -16,8 +16,8 @@ describe('Hook registry', () => {
|
|
|
16
16
|
};
|
|
17
17
|
const hooks = new HooksWithAccess(swup);
|
|
18
18
|
|
|
19
|
-
hooks.on('
|
|
20
|
-
const ledger = hooks.getRegistry().get('
|
|
19
|
+
hooks.on('enable', handler);
|
|
20
|
+
const ledger = hooks.getRegistry().get('enable');
|
|
21
21
|
|
|
22
22
|
expect(ledger).toBeDefined();
|
|
23
23
|
expect(ledger).toBeInstanceOf(Map);
|
|
@@ -29,22 +29,57 @@ describe('Hook registry', () => {
|
|
|
29
29
|
expect(registration?.handler).toEqual(handler);
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
it('should
|
|
32
|
+
it('should remove handlers', async () => {
|
|
33
33
|
const swup = new Swup();
|
|
34
|
-
const
|
|
34
|
+
const handler1 = vi.fn();
|
|
35
|
+
const handler2 = vi.fn();
|
|
36
|
+
|
|
37
|
+
swup.hooks.on('enable', handler1);
|
|
38
|
+
swup.hooks.on('enable', handler2);
|
|
39
|
+
|
|
40
|
+
await swup.hooks.trigger('enable');
|
|
41
|
+
|
|
42
|
+
expect(handler1).toBeCalledTimes(1);
|
|
43
|
+
expect(handler2).toBeCalledTimes(1);
|
|
44
|
+
|
|
45
|
+
swup.hooks.off('enable', handler2);
|
|
46
|
+
|
|
47
|
+
await swup.hooks.trigger('enable');
|
|
48
|
+
|
|
49
|
+
expect(handler1).toBeCalledTimes(2);
|
|
50
|
+
expect(handler2).toBeCalledTimes(1);
|
|
51
|
+
});
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
it('should return a function to unregister the handler', async () => {
|
|
54
|
+
const swup = new Swup();
|
|
55
|
+
const handler1 = vi.fn();
|
|
56
|
+
const handler2 = vi.fn();
|
|
57
|
+
|
|
58
|
+
const unregister1 = swup.hooks.on('enable', handler1);
|
|
59
|
+
const unregister2 = swup.hooks.on('enable', handler2);
|
|
60
|
+
|
|
61
|
+
expect(unregister1).toBeTypeOf('function');
|
|
62
|
+
|
|
63
|
+
await swup.hooks.trigger('enable');
|
|
37
64
|
|
|
38
|
-
expect(
|
|
65
|
+
expect(handler1).toBeCalledTimes(1);
|
|
66
|
+
expect(handler2).toBeCalledTimes(1);
|
|
67
|
+
|
|
68
|
+
unregister2();
|
|
69
|
+
|
|
70
|
+
await swup.hooks.trigger('enable');
|
|
71
|
+
|
|
72
|
+
expect(handler1).toBeCalledTimes(2);
|
|
73
|
+
expect(handler2).toBeCalledTimes(1);
|
|
39
74
|
});
|
|
40
75
|
|
|
41
76
|
it('should trigger custom handlers', async () => {
|
|
42
77
|
const swup = new Swup();
|
|
43
78
|
const handler = vi.fn();
|
|
44
79
|
|
|
45
|
-
swup.hooks.on('
|
|
80
|
+
swup.hooks.on('enable', handler);
|
|
46
81
|
|
|
47
|
-
await swup.hooks.trigger('
|
|
82
|
+
await swup.hooks.trigger('enable');
|
|
48
83
|
|
|
49
84
|
expect(handler).toBeCalledTimes(1);
|
|
50
85
|
});
|
|
@@ -53,10 +88,10 @@ describe('Hook registry', () => {
|
|
|
53
88
|
const swup = new Swup();
|
|
54
89
|
const handler = vi.fn();
|
|
55
90
|
|
|
56
|
-
swup.hooks.on('
|
|
91
|
+
swup.hooks.on('enable', handler, { once: true });
|
|
57
92
|
|
|
58
|
-
await swup.hooks.trigger('
|
|
59
|
-
await swup.hooks.trigger('
|
|
93
|
+
await swup.hooks.trigger('enable', undefined, () => {});
|
|
94
|
+
await swup.hooks.trigger('enable', undefined, () => {});
|
|
60
95
|
|
|
61
96
|
expect(handler).toBeCalledTimes(1);
|
|
62
97
|
});
|
|
@@ -65,10 +100,10 @@ describe('Hook registry', () => {
|
|
|
65
100
|
const swup = new Swup();
|
|
66
101
|
const handler = vi.fn();
|
|
67
102
|
|
|
68
|
-
swup.hooks.once('
|
|
103
|
+
swup.hooks.once('enable', handler);
|
|
69
104
|
|
|
70
|
-
await swup.hooks.trigger('
|
|
71
|
-
await swup.hooks.trigger('
|
|
105
|
+
await swup.hooks.trigger('enable', undefined, () => {});
|
|
106
|
+
await swup.hooks.trigger('enable', undefined, () => {});
|
|
72
107
|
|
|
73
108
|
expect(handler).toBeCalledTimes(1);
|
|
74
109
|
});
|
|
@@ -77,7 +112,7 @@ describe('Hook registry', () => {
|
|
|
77
112
|
const swup = new Swup();
|
|
78
113
|
const handler = vi.fn();
|
|
79
114
|
|
|
80
|
-
await swup.hooks.trigger('
|
|
115
|
+
await swup.hooks.trigger('enable', undefined, handler);
|
|
81
116
|
|
|
82
117
|
expect(handler).toBeCalledTimes(1);
|
|
83
118
|
});
|
|
@@ -101,11 +136,11 @@ describe('Hook registry', () => {
|
|
|
101
136
|
}
|
|
102
137
|
};
|
|
103
138
|
|
|
104
|
-
swup.hooks.on('
|
|
105
|
-
swup.hooks.on('
|
|
106
|
-
swup.hooks.on('
|
|
139
|
+
swup.hooks.on('disable', handlers.before, { before: true });
|
|
140
|
+
swup.hooks.on('disable', handlers.normal, {});
|
|
141
|
+
swup.hooks.on('disable', handlers.after, {});
|
|
107
142
|
|
|
108
|
-
await swup.hooks.trigger('
|
|
143
|
+
await swup.hooks.trigger('disable', undefined, handlers.original);
|
|
109
144
|
|
|
110
145
|
expect(called).toEqual(['before', 'original', 'normal', 'after']);
|
|
111
146
|
});
|
|
@@ -132,44 +167,77 @@ describe('Hook registry', () => {
|
|
|
132
167
|
},
|
|
133
168
|
6: () => {
|
|
134
169
|
called.push(6);
|
|
170
|
+
},
|
|
171
|
+
7: () => {
|
|
172
|
+
called.push(7);
|
|
173
|
+
},
|
|
174
|
+
8: () => {
|
|
175
|
+
called.push(8);
|
|
135
176
|
}
|
|
136
177
|
};
|
|
137
178
|
|
|
138
|
-
swup.hooks.on('
|
|
139
|
-
swup.hooks.on('
|
|
140
|
-
swup.hooks.on('
|
|
141
|
-
swup.hooks.on('
|
|
142
|
-
swup.hooks.on('
|
|
179
|
+
swup.hooks.on('disable', handlers['1'], { priority: 2, before: true });
|
|
180
|
+
swup.hooks.on('disable', handlers['2'], { priority: -1, before: true });
|
|
181
|
+
swup.hooks.on('disable', handlers['3'], { priority: 1 });
|
|
182
|
+
swup.hooks.on('disable', handlers['4']);
|
|
183
|
+
swup.hooks.on('disable', handlers['8'], { priority: 4 });
|
|
184
|
+
swup.hooks.on('disable', handlers['7'], { priority: 4 });
|
|
143
185
|
|
|
144
|
-
await swup.hooks.trigger('
|
|
186
|
+
await swup.hooks.trigger('disable', undefined, handlers['5']);
|
|
145
187
|
|
|
146
|
-
expect(called).toEqual([2, 1,
|
|
188
|
+
expect(called).toEqual([2, 1, 5, 4, 3, 8, 7]);
|
|
147
189
|
});
|
|
148
190
|
|
|
149
191
|
it('should allow replacing original handlers', async () => {
|
|
192
|
+
const swup = new Swup();
|
|
193
|
+
const customHandler = vi.fn();
|
|
194
|
+
const defaultHandler = vi.fn();
|
|
195
|
+
|
|
196
|
+
swup.hooks.on('enable', customHandler, { replace: true });
|
|
197
|
+
|
|
198
|
+
await swup.hooks.trigger('enable', undefined, defaultHandler);
|
|
199
|
+
|
|
200
|
+
expect(customHandler).toBeCalledTimes(1);
|
|
201
|
+
expect(defaultHandler).toBeCalledTimes(0);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it('should pass original handler into replacing handlers', async () => {
|
|
205
|
+
const swup = new Swup();
|
|
206
|
+
const customHandler = vi.fn();
|
|
207
|
+
const defaultHandler = vi.fn();
|
|
208
|
+
const ctx = swup.context;
|
|
209
|
+
|
|
210
|
+
swup.hooks.on('enable', customHandler, { replace: true });
|
|
211
|
+
|
|
212
|
+
await swup.hooks.trigger('enable', undefined, defaultHandler);
|
|
213
|
+
|
|
214
|
+
expect(customHandler).toBeCalledWith(ctx, undefined, defaultHandler);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it('should not pass original handler into normal handlers', async () => {
|
|
150
218
|
const swup = new Swup();
|
|
151
219
|
const listener = vi.fn();
|
|
152
220
|
const handler = vi.fn();
|
|
221
|
+
const ctx = swup.context;
|
|
153
222
|
|
|
154
|
-
swup.hooks.on('
|
|
223
|
+
swup.hooks.on('enable', listener);
|
|
155
224
|
|
|
156
|
-
await swup.hooks.trigger('
|
|
225
|
+
await swup.hooks.trigger('enable', undefined, handler);
|
|
157
226
|
|
|
158
|
-
expect(
|
|
159
|
-
expect(listener).toBeCalledTimes(1);
|
|
227
|
+
expect(listener).toBeCalledWith(ctx, undefined, undefined);
|
|
160
228
|
});
|
|
161
229
|
|
|
162
230
|
it('should trigger event handler with context and args', async () => {
|
|
163
231
|
const swup = new Swup();
|
|
164
|
-
const handler: Handler<'
|
|
232
|
+
const handler: Handler<'history:popstate'> = vi.fn();
|
|
165
233
|
const ctx = swup.context;
|
|
166
234
|
const args = { event: new PopStateEvent('') };
|
|
167
235
|
|
|
168
|
-
swup.hooks.on('
|
|
169
|
-
await swup.hooks.trigger('
|
|
236
|
+
swup.hooks.on('history:popstate', handler);
|
|
237
|
+
await swup.hooks.trigger('history:popstate', args);
|
|
170
238
|
|
|
171
239
|
expect(handler).toBeCalledTimes(1);
|
|
172
|
-
expect(handler).toBeCalledWith(ctx, args);
|
|
240
|
+
expect(handler).toBeCalledWith(ctx, args, undefined);
|
|
173
241
|
});
|
|
174
242
|
});
|
|
175
243
|
|
|
@@ -178,15 +246,18 @@ describe('Types', () => {
|
|
|
178
246
|
const swup = new Swup();
|
|
179
247
|
|
|
180
248
|
// @ts-expect-no-error
|
|
181
|
-
swup.hooks.on(
|
|
249
|
+
swup.hooks.on(
|
|
250
|
+
'history:popstate',
|
|
251
|
+
(ctx: Context, { event }: { event: PopStateEvent }) => {}
|
|
252
|
+
);
|
|
182
253
|
// @ts-expect-no-error
|
|
183
|
-
await swup.hooks.trigger('
|
|
254
|
+
await swup.hooks.trigger('history:popstate', { event: new PopStateEvent('') });
|
|
184
255
|
|
|
185
256
|
// @ts-expect-error
|
|
186
|
-
swup.hooks.on('
|
|
257
|
+
swup.hooks.on('history:popstate', ({ event: MouseEvent }) => {});
|
|
187
258
|
// @ts-expect-error
|
|
188
|
-
swup.hooks.on('
|
|
259
|
+
swup.hooks.on('history:popstate', (ctx: Context, { event }: { event: MouseEvent }) => {});
|
|
189
260
|
// @ts-expect-error
|
|
190
|
-
await swup.hooks.trigger('
|
|
261
|
+
await swup.hooks.trigger('history:popstate', { event: new MouseEvent('') });
|
|
191
262
|
});
|
|
192
263
|
});
|