Repository: swup/swup
Pull request #732 (2023-07-20 12:30:51)

Hooks
- `hooks.trigger()` → `hooks.call()`
- `hooks.execute()` → `hooks.run()` (this is private to the `Hooks` class)
- Fix `hooks.replace()` to allow nesting of default handlers when replaced multiple times



Patch:
diff --git a/src/Swup.ts b/src/Swup.ts
index e9cb2e1..0f4e030 100644
--- a/src/Swup.ts
+++ b/src/Swup.ts
@@ -152,13 +152,13 @@ export default class Swup {
 		await nextTick();
 
 		// Trigger enable hook
-		await this.hooks.trigger('enable', undefined, () => {
+		await this.hooks.call('enable', undefined, () => {
 			// Add swup-enabled class to html tag
 			document.documentElement.classList.add('swup-enabled');
 		});
 
 		// Trigger page view hook
-		await this.hooks.trigger('page:view', { url: this.currentPageUrl, title: document.title });
+		await this.hooks.call('page:view', { url: this.currentPageUrl, title: document.title });
 	}
 
 	async destroy() {
@@ -175,7 +175,7 @@ export default class Swup {
 		this.options.plugins.forEach((plugin) => this.unuse(plugin));
 
 		// trigger disable hook
-		await this.hooks.trigger('disable', undefined, () => {
+		await this.hooks.call('disable', undefined, () => {
 			// remove swup-enabled class from html tag
 			document.documentElement.classList.remove('swup-enabled');
 		});
@@ -219,7 +219,7 @@ export default class Swup {
 
 		// Exit early if control key pressed
 		if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
-			this.hooks.trigger('link:newtab', { href });
+			this.hooks.call('link:newtab', { href });
 			return;
 		}
 
@@ -228,7 +228,7 @@ export default class Swup {
 			return;
 		}
 
-		this.hooks.triggerSync('link:click', { el, event }, () => {
+		this.hooks.callSync('link:click', { el, event }, () => {
 			const from = this.context.from.url ?? '';
 
 			event.preventDefault();
@@ -237,7 +237,7 @@ export default class Swup {
 			if (!url || url === from) {
 				if (hash) {
 					updateHistoryRecord(url + hash);
-					this.hooks.triggerSync(
+					this.hooks.callSync(
 						'link:anchor',
 						{ hash, options: { behavior: 'auto' } },
 						(context, { hash, options }) => {
@@ -248,7 +248,7 @@ export default class Swup {
 						}
 					);
 				} else {
-					this.hooks.triggerSync('link:self', undefined, (context) => {
+					this.hooks.callSync('link:self', undefined, (context) => {
 						if (!context.scroll.reset) return;
 						window.scroll({ top: 0, left: 0, behavior: 'auto' });
 					});
@@ -318,7 +318,7 @@ export default class Swup {
 		// 	event.preventDefault();
 		// }
 
-		this.hooks.triggerSync('history:popstate', { event }, () => {
+		this.hooks.callSync('history:popstate', { event }, () => {
 			this.performVisit(url);
 		});
 	}
diff --git a/src/modules/Cache.ts b/src/modules/Cache.ts
index aa33b7a..d520d36 100755
--- a/src/modules/Cache.ts
+++ b/src/modules/Cache.ts
@@ -43,7 +43,7 @@ export class Cache {
 		url = this.resolve(url);
 		page = { ...page, url };
 		this.pages.set(url, page);
-		this.swup.hooks.triggerSync('cache:set', { page });
+		this.swup.hooks.callSync('cache:set', { page });
 	}
 
 	/** Update a cache record, overwriting or adding custom data. */
@@ -61,7 +61,7 @@ export class Cache {
 	/** Empty the cache. */
 	public clear(): void {
 		this.pages.clear();
-		this.swup.hooks.triggerSync('cache:clear');
+		this.swup.hooks.callSync('cache:clear');
 	}
 
 	/** Remove all cache entries that return true for a given predicate function.  */
diff --git a/src/modules/Hooks.ts b/src/modules/Hooks.ts
index 92da990..e6ac907 100644
--- a/src/modules/Hooks.ts
+++ b/src/modules/Hooks.ts
@@ -67,6 +67,7 @@ export type HookRegistration<T extends HookName> = {
 	id: number;
 	hook: T;
 	handler: Handler<T>;
+	defaultHandler?: Handler<T>;
 } & HookOptions;
 
 type HookLedger<T extends HookName> = Map<Handler<T>, HookRegistration<T>>;
@@ -278,15 +279,15 @@ export class Hooks {
 	 * @param defaultHandler A default implementation of this hook to execute
 	 * @returns The resolved return value of the executed default handler
 	 */
-	async trigger<T extends HookName>(
+	async call<T extends HookName>(
 		hook: T,
 		args?: HookArguments<T>,
 		defaultHandler?: Handler<T>
 	): Promise<any> {
-		const { before, handler, after, replaced } = this.getHandlers(hook, defaultHandler);
-		await this.execute(before, args);
-		const [result] = await this.execute(handler, args, replaced ? defaultHandler : undefined);
-		await this.execute(after, args);
+		const { before, handler, after } = this.getHandlers(hook, defaultHandler);
+		await this.run(before, args);
+		const [result] = await this.run(handler, args);
+		await this.run(after, args);
 		this.dispatchDomEvent(hook, args);
 		return result;
 	}
@@ -299,15 +300,15 @@ export class Hooks {
 	 * @param defaultHandler A default implementation of this hook to execute
 	 * @returns The (possibly unresolved) return value of the executed default handler
 	 */
-	triggerSync<T extends HookName>(
+	callSync<T extends HookName>(
 		hook: T,
 		args?: HookArguments<T>,
 		defaultHandler?: Handler<T>
 	): any {
-		const { before, after, handler, replaced } = this.getHandlers(hook, defaultHandler);
-		this.executeSync(before, args);
-		const [result] = this.executeSync(handler, args, replaced ? defaultHandler : undefined);
-		this.executeSync(after, args);
+		const { before, handler, after } = this.getHandlers(hook, defaultHandler);
+		this.runSync(before, args);
+		const [result] = this.runSync(handler, args);
+		this.runSync(after, args);
 		this.dispatchDomEvent(hook, args);
 		return result;
 	}
@@ -317,13 +318,12 @@ export class Hooks {
 	 * @param registrations The registrations (handler + options) to execute
 	 * @param args Arguments to pass to the handler
 	 */
-	async execute<T extends HookName>(
+	private async run<T extends HookName>(
 		registrations: HookRegistration<T>[],
-		args?: HookArguments<T>,
-		defaultHandler?: Handler<T>
+		args?: HookArguments<T>
 	): Promise<any> {
 		const results = [];
-		for (const { hook, handler, once } of registrations) {
+		for (const { hook, handler, defaultHandler, once } of registrations) {
 			const result = await runAsPromise(handler, [this.swup.context, args, defaultHandler]);
 			results.push(result);
 			if (once) {
@@ -338,13 +338,12 @@ export class Hooks {
 	 * @param registrations The registrations (handler + options) to execute
 	 * @param args Arguments to pass to the handler
 	 */
-	executeSync<T extends HookName>(
+	private runSync<T extends HookName>(
 		registrations: HookRegistration<T>[],
-		args?: HookArguments<T>,
-		defaultHandler?: Handler<T>
+		args?: HookArguments<T>
 	): any[] {
 		const results = [];
-		for (const { hook, handler, once } of registrations) {
+		for (const { hook, handler, defaultHandler, once } of registrations) {
 			const result = handler(this.swup.context, args as HookArguments<T>, defaultHandler);
 			results.push(result);
 			if (isPromise(result)) {
@@ -367,7 +366,7 @@ export class Hooks {
 	 * @returns An object with the handlers sorted into `before` and `after` arrays,
 	 *          as well as a flag indicating if the original handler was replaced
 	 */
-	getHandlers<T extends HookName>(hook: T, defaultHandler?: Handler<T>) {
+	private getHandlers<T extends HookName>(hook: T, defaultHandler?: Handler<T>) {
 		const ledger = this.get(hook);
 		if (!ledger) {
 			return { found: false, before: [], handler: [], after: [], replaced: false };
@@ -376,16 +375,34 @@ export class Hooks {
 		const sort = this.sortRegistrations;
 		const registrations = Array.from(ledger.values());
 
+		// Filter into before, after, and replace handlers
 		const before = registrations.filter(({ before, replace }) => before && !replace).sort(sort);
 		const replace = registrations.filter(({ replace }) => replace).sort(sort);
 		const after = registrations.filter(({ before, replace }) => !before && !replace).sort(sort);
 		const replaced = replace.length > 0;
 
+		// Define main handler registration
+		// This is an array to allow passing it into hooks.run() directly
 		let handler: HookRegistration<T>[] = [];
-		if (replaced) {
-			handler = [{ id: 0, hook, handler: replace[0].handler }];
-		} else if (defaultHandler) {
+		if (defaultHandler) {
 			handler = [{ id: 0, hook, handler: defaultHandler }];
+			if (replaced) {
+				const index = replace.length - 1;
+				const replacingHandler = replace[index].handler;
+				const createDefaultHandler = (index: number): Handler<T> | undefined => {
+					const next = replace[index - 1];
+					if (next) {
+						return (context, args) =>
+							next.handler(context, args, createDefaultHandler(index - 1));
+					} else {
+						return defaultHandler;
+					}
+				};
+				const nestedDefaultHandler = createDefaultHandler(index);
+				handler = [
+					{ id: 0, hook, handler: replacingHandler, defaultHandler: nestedDefaultHandler }
+				];
+			}
 		}
 
 		return { found: true, before, handler, after, replaced };
@@ -397,7 +414,10 @@ export class Hooks {
 	 * @param b The other registration object to compare with
 	 * @returns The sort direction
 	 */
-	sortRegistrations<T extends HookName>(a: HookRegistration<T>, b: HookRegistration<T>): number {
+	private sortRegistrations<T extends HookName>(
+		a: HookRegistration<T>,
+		b: HookRegistration<T>
+	): number {
 		const priority = (a.priority ?? 0) - (b.priority ?? 0);
 		const id = a.id - b.id;
 		return priority || id || 0;
@@ -407,7 +427,7 @@ export class Hooks {
 	 * Dispatch a custom event on the `document` for a hook. Prefixed with `swup:`
 	 * @param hook Name of the hook.
 	 */
-	dispatchDomEvent<T extends HookName>(hook: T, args?: HookArguments<T>): void {
+	private dispatchDomEvent<T extends HookName>(hook: T, args?: HookArguments<T>): void {
 		const detail = { hook, args, context: this.swup.context };
 		document.dispatchEvent(new CustomEvent(`swup:${hook}`, { detail }));
 	}
diff --git a/src/modules/animatePageIn.ts b/src/modules/animatePageIn.ts
index 0e823ec..a5e4e84 100755
--- a/src/modules/animatePageIn.ts
+++ b/src/modules/animatePageIn.ts
@@ -10,7 +10,7 @@ export const animatePageIn = async function (this: Swup) {
 		return;
 	}
 
-	const animation = this.hooks.trigger(
+	const animation = this.hooks.call(
 		'animation:in:await',
 		{ skip: false },
 		async (context, { skip }) => {
@@ -21,11 +21,11 @@ export const animatePageIn = async function (this: Swup) {
 
 	await nextTick();
 
-	await this.hooks.trigger('animation:in:start', undefined, () => {
+	await this.hooks.call('animation:in:start', undefined, () => {
 		this.classes.remove('is-animating');
 	});
 
 	await animation;
 
-	await this.hooks.trigger('animation:in:end');
+	await this.hooks.call('animation:in:end');
 };
diff --git a/src/modules/animatePageOut.ts b/src/modules/animatePageOut.ts
index a806d17..df94976 100755
--- a/src/modules/animatePageOut.ts
+++ b/src/modules/animatePageOut.ts
@@ -7,11 +7,11 @@ import { classify } from '../helpers.js';
  */
 export const animatePageOut = async function (this: Swup) {
 	if (!this.context.animation.animate) {
-		await this.hooks.trigger('animation:skip');
+		await this.hooks.call('animation:skip');
 		return;
 	}
 
-	await this.hooks.trigger('animation:out:start', undefined, () => {
+	await this.hooks.call('animation:out:start', undefined, () => {
 		this.classes.add('is-changing', 'is-leaving', 'is-animating');
 		if (this.context.history.popstate) {
 			this.classes.add('is-popstate');
@@ -21,10 +21,10 @@ export const animatePageOut = async function (this: Swup) {
 		}
 	});
 
-	await this.hooks.trigger('animation:out:await', { skip: false }, async (context, { skip }) => {
+	await this.hooks.call('animation:out:await', { skip: false }, async (context, { skip }) => {
 		if (skip) return;
 		await this.awaitAnimations({ selector: context.animation.selector });
 	});
 
-	await this.hooks.trigger('animation:out:end');
+	await this.hooks.call('animation:out:end');
 };
diff --git a/src/modules/fetchPage.ts b/src/modules/fetchPage.ts
index acf5162..3872bb4 100644
--- a/src/modules/fetchPage.ts
+++ b/src/modules/fetchPage.ts
@@ -36,7 +36,7 @@ export async function fetchPage(
 	if (this.cache.has(url)) {
 		const page = this.cache.get(url) as PageData;
 		if (options.triggerHooks !== false) {
-			await this.hooks.trigger('page:load', { page, cache: true });
+			await this.hooks.call('page:load', { page, cache: true });
 		}
 		return page;
 	}
@@ -45,7 +45,7 @@ export async function fetchPage(
 	options = { ...options, headers };
 
 	// Allow hooking before this and returning a custom response-like object (e.g. custom fetch implementation)
-	const response: Response = await this.hooks.trigger(
+	const response: Response = await this.hooks.call(
 		'fetch:request',
 		{ url, options },
 		(context, { url, options }) => fetch(url, options)
@@ -55,7 +55,7 @@ export async function fetchPage(
 	const html = await response.text();
 
 	if (status === 500) {
-		this.hooks.trigger('fetch:error', { status, response, url: responseUrl });
+		this.hooks.call('fetch:error', { status, response, url: responseUrl });
 		throw new FetchError(`Server error: ${responseUrl}`, { status, url: responseUrl });
 	}
 
@@ -73,7 +73,7 @@ export async function fetchPage(
 	}
 
 	if (options.triggerHooks !== false) {
-		await this.hooks.trigger('page:load', { page, cache: false });
+		await this.hooks.call('page:load', { page, cache: false });
 	}
 
 	return page;
diff --git a/src/modules/renderPage.ts b/src/modules/renderPage.ts
index 3dfbf92..39e4cd4 100755
--- a/src/modules/renderPage.ts
+++ b/src/modules/renderPage.ts
@@ -32,7 +32,7 @@ export const renderPage = async function (this: Swup, requestedUrl: string, page
 	this.context.to.html = html;
 
 	// replace content: allow handlers and plugins to overwrite paga data and containers
-	await this.hooks.trigger('content:replace', { page }, (context, { page }) => {
+	await this.hooks.call('content:replace', { page }, (context, { page }) => {
 		const success = this.replaceContent(page, { containers: context.containers });
 		if (!success) {
 			throw new Error('[swup] Container mismatch, aborting');
@@ -46,7 +46,7 @@ export const renderPage = async function (this: Swup, requestedUrl: string, page
 		}
 	});
 
-	await this.hooks.trigger(
+	await this.hooks.call(
 		'content:scroll',
 		{ options: { behavior: 'auto' } },
 		(context, { options }) => {
@@ -63,7 +63,7 @@ export const renderPage = async function (this: Swup, requestedUrl: string, page
 		}
 	);
 
-	await this.hooks.trigger('page:view', { url: this.currentPageUrl, title: document.title });
+	await this.hooks.call('page:view', { url: this.currentPageUrl, title: document.title });
 
 	// empty cache if it's disabled (in case preload plugin filled it)
 	if (!this.options.cache) {
diff --git a/src/modules/visit.ts b/src/modules/visit.ts
index 0d411cc..932b164 100755
--- a/src/modules/visit.ts
+++ b/src/modules/visit.ts
@@ -84,10 +84,10 @@ export async function performVisit(
 	}
 
 	try {
-		await this.hooks.trigger('visit:start');
+		await this.hooks.call('visit:start');
 
 		// Begin fetching page
-		const pagePromise = this.hooks.trigger(
+		const pagePromise = this.hooks.call(
 			'page:request',
 			{ url: this.context.to.url, options },
 			async (context, { options }) => await this.fetchPage(context.to.url as string, options)
@@ -123,7 +123,7 @@ export async function performVisit(
 		await this.animatePageIn();
 
 		// Finalize visit
-		await this.hooks.trigger('visit:end', undefined, () => this.classes.clear());
+		await this.hooks.call('visit:end', undefined, () => this.classes.clear());
 
 		// Reset context after visit?
 		// if (this.context.to && this.isSameResolvedUrl(this.context.to.url, requestedUrl)) {


Test patch:
diff --git a/src/modules/__test__/cache.test.ts b/src/modules/__test__/cache.test.ts
index 5161155..19c9b1b 100644
--- a/src/modules/__test__/cache.test.ts
+++ b/src/modules/__test__/cache.test.ts
@@ -126,7 +126,7 @@ describe('Types', () => {
 		// @ts-expect-no-error
 		swup.hooks.on('history:popstate', (ctx: Context, { event: PopStateEvent }) => {});
 		// @ts-expect-no-error
-		await swup.hooks.trigger('history:popstate', { event: new PopStateEvent('') });
+		await swup.hooks.call('history:popstate', { event: new PopStateEvent('') });
 
 		try {
 			// @ts-expect-error
diff --git a/src/modules/__test__/hooks.test.ts b/src/modules/__test__/hooks.test.ts
index fc25e1c..4a77ea4 100644
--- a/src/modules/__test__/hooks.test.ts
+++ b/src/modules/__test__/hooks.test.ts
@@ -37,14 +37,14 @@ describe('Hook registry', () => {
 		swup.hooks.on('enable', handler1);
 		swup.hooks.on('enable', handler2);
 
-		await swup.hooks.trigger('enable');
+		await swup.hooks.call('enable');
 
 		expect(handler1).toBeCalledTimes(1);
 		expect(handler2).toBeCalledTimes(1);
 
 		swup.hooks.off('enable', handler2);
 
-		await swup.hooks.trigger('enable');
+		await swup.hooks.call('enable');
 
 		expect(handler1).toBeCalledTimes(2);
 		expect(handler2).toBeCalledTimes(1);
@@ -60,14 +60,14 @@ describe('Hook registry', () => {
 
 		expect(unregister1).toBeTypeOf('function');
 
-		await swup.hooks.trigger('enable');
+		await swup.hooks.call('enable');
 
 		expect(handler1).toBeCalledTimes(1);
 		expect(handler2).toBeCalledTimes(1);
 
 		unregister2();
 
-		await swup.hooks.trigger('enable');
+		await swup.hooks.call('enable');
 
 		expect(handler1).toBeCalledTimes(2);
 		expect(handler2).toBeCalledTimes(1);
@@ -79,7 +79,7 @@ describe('Hook registry', () => {
 
 		swup.hooks.on('enable', handler);
 
-		await swup.hooks.trigger('enable');
+		await swup.hooks.call('enable');
 
 		expect(handler).toBeCalledTimes(1);
 	});
@@ -90,8 +90,8 @@ describe('Hook registry', () => {
 
 		swup.hooks.on('enable', handler, { once: true });
 
-		await swup.hooks.trigger('enable', undefined, () => {});
-		await swup.hooks.trigger('enable', undefined, () => {});
+		await swup.hooks.call('enable', undefined, () => {});
+		await swup.hooks.call('enable', undefined, () => {});
 
 		expect(handler).toBeCalledTimes(1);
 	});
@@ -102,8 +102,8 @@ describe('Hook registry', () => {
 
 		swup.hooks.once('enable', handler);
 
-		await swup.hooks.trigger('enable', undefined, () => {});
-		await swup.hooks.trigger('enable', undefined, () => {});
+		await swup.hooks.call('enable', undefined, () => {});
+		await swup.hooks.call('enable', undefined, () => {});
 
 		expect(handler).toBeCalledTimes(1);
 	});
@@ -112,7 +112,7 @@ describe('Hook registry', () => {
 		const swup = new Swup();
 		const handler = vi.fn();
 
-		await swup.hooks.trigger('enable', undefined, handler);
+		await swup.hooks.call('enable', undefined, handler);
 
 		expect(handler).toBeCalledTimes(1);
 	});
@@ -140,7 +140,7 @@ describe('Hook registry', () => {
 		swup.hooks.on('disable', handlers.normal, {});
 		swup.hooks.on('disable', handlers.after, {});
 
-		await swup.hooks.trigger('disable', undefined, handlers.original);
+		await swup.hooks.call('disable', undefined, handlers.original);
 
 		expect(called).toEqual(['before', 'original', 'normal', 'after']);
 	});
@@ -187,7 +187,7 @@ describe('Hook registry', () => {
 		swup.hooks.on('disable', handlers['8'], { priority: 4 });
 		swup.hooks.on('disable', handlers['7'], { priority: 4 });
 
-		await swup.hooks.trigger('disable', undefined, handlers['5']);
+		await swup.hooks.call('disable', undefined, handlers['5']);
 
 		expect(called).toEqual([2, 1, 5, 9, 4, 3, 8, 7]);
 	});
@@ -199,23 +199,76 @@ describe('Hook registry', () => {
 
 		swup.hooks.on('enable', customHandler, { replace: true });
 
-		await swup.hooks.trigger('enable', undefined, defaultHandler);
+		await swup.hooks.call('enable', undefined, defaultHandler);
 
+		expect(defaultHandler).toBeCalledTimes(0);
 		expect(customHandler).toBeCalledTimes(1);
+	});
+
+	it('should only execute the last replacing handler', async () => {
+		const swup = new Swup();
+		const firstHandler = vi.fn();
+		const secondHandler = vi.fn();
+		const defaultHandler = vi.fn();
+
+		swup.hooks.on('enable', firstHandler, { replace: true });
+		swup.hooks.on('enable', secondHandler, { replace: true });
+
+		await swup.hooks.call('enable', undefined, defaultHandler);
+
 		expect(defaultHandler).toBeCalledTimes(0);
+		expect(firstHandler).toBeCalledTimes(0);
+		expect(secondHandler).toBeCalledTimes(1);
 	});
 
 	it('should pass original handler into replacing handlers', async () => {
 		const swup = new Swup();
-		const customHandler = vi.fn();
+		const args = { foo: 'bar' };
+		const customHandler = vi.fn((c, a, handler) => handler(c, args));
 		const defaultHandler = vi.fn();
 		const ctx = swup.context;
 
 		swup.hooks.on('enable', customHandler, { replace: true });
 
-		await swup.hooks.trigger('enable', undefined, defaultHandler);
+		await swup.hooks.call('enable', undefined, defaultHandler);
 
 		expect(customHandler).toBeCalledWith(ctx, undefined, defaultHandler);
+		expect(defaultHandler).toBeCalledWith(ctx, args);
+	});
+
+	it('should return result of replacing handler', async () => {
+		const swup = new Swup();
+		const customHandler = vi.fn(async () => 'foo');
+		const defaultHandler = vi.fn(async () => 'bar');
+
+		swup.hooks.on('enable', customHandler, { replace: true });
+
+		const result = await swup.hooks.call('enable', undefined, defaultHandler);
+
+		expect(result).toEqual('foo');
+	});
+
+	it('should pass previous handler into nested replacing handlers', async () => {
+		const swup = new Swup();
+		const args1 = { foo: 'bar' };
+		const args2 = { foo: 'baz' };
+		const args3 = { foo: 'bag' };
+		const defaultHandler = vi.fn();
+		const firstHandler = vi.fn((c, a, handler) => handler(c, args1));
+		const secondHandler = vi.fn((c, a, handler) => handler(c, args2));
+		const thirdHandler = vi.fn((c, a, handler) => handler(c, args3, handler));
+		const ctx = swup.context;
+
+		swup.hooks.on('enable', firstHandler, { replace: true });
+		swup.hooks.on('enable', secondHandler, { replace: true });
+		swup.hooks.on('enable', thirdHandler, { replace: true });
+
+		await swup.hooks.call('enable', undefined, defaultHandler);
+
+		expect(defaultHandler).toBeCalledWith(ctx, args1);
+		expect(thirdHandler).toBeCalledWith(ctx, undefined, expect.any(Function));
+		expect(secondHandler).toBeCalledWith(ctx, args3, expect.any(Function));
+		expect(firstHandler).toBeCalledWith(ctx, args2, expect.any(Function));
 	});
 
 	it('should not pass original handler into normal handlers', async () => {
@@ -226,7 +279,7 @@ describe('Hook registry', () => {
 
 		swup.hooks.on('enable', listener);
 
-		await swup.hooks.trigger('enable', undefined, handler);
+		await swup.hooks.call('enable', undefined, handler);
 
 		expect(listener).toBeCalledWith(ctx, undefined, undefined);
 	});
@@ -238,7 +291,7 @@ describe('Hook registry', () => {
 		const args = { event: new PopStateEvent('') };
 
 		swup.hooks.on('history:popstate', handler);
-		await swup.hooks.trigger('history:popstate', args);
+		await swup.hooks.call('history:popstate', args);
 
 		expect(handler).toBeCalledTimes(1);
 		expect(handler).toBeCalledWith(ctx, args, undefined);
@@ -255,13 +308,13 @@ describe('Types', () => {
 			(ctx: Context, { event }: { event: PopStateEvent }) => {}
 		);
 		// @ts-expect-no-error
-		await swup.hooks.trigger('history:popstate', { event: new PopStateEvent('') });
+		await swup.hooks.call('history:popstate', { event: new PopStateEvent('') });
 
 		// @ts-expect-error
 		swup.hooks.on('history:popstate', ({ event: MouseEvent }) => {});
 		// @ts-expect-error
 		swup.hooks.on('history:popstate', (ctx: Context, { event }: { event: MouseEvent }) => {});
 		// @ts-expect-error
-		await swup.hooks.trigger('history:popstate', { event: new MouseEvent('') });
+		await swup.hooks.call('history:popstate', { event: new MouseEvent('') });
 	});
 });
diff --git a/src/modules/__test__/replaceContent.test.ts b/src/modules/__test__/replaceContent.test.ts
index 8613382..7e01197 100644
--- a/src/modules/__test__/replaceContent.test.ts
+++ b/src/modules/__test__/replaceContent.test.ts
@@ -36,7 +36,6 @@ describe('replaceContent', () => {
 			<div id="container-3" data-from="current"></div>
 		`);
 
-		console.debug(document.documentElement.querySelector('#container-1'));
 		const page = mockPage(/*html*/ `
 			<div id="container-1" data-from="incoming"></div>
 			<div id="container-2" data-from="incoming"></div>`);