summaryrefslogtreecommitdiff
path: root/node_modules/swup/src/modules/plugins.ts
blob: 299d7cb3e2723b7fe27480c50ab08ddeebecfd09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import type Swup from '../Swup.js';

export type Plugin = {
	/** Identify as a swup plugin */
	isSwupPlugin: true;
	/** Name of this plugin */
	name: string;
	/** Version of this plugin. Currently not in use, defined here for backward compatiblity. */
	version?: string;
	/** The swup instance that mounted this plugin */
	swup?: Swup;
	/** Version requirements of this plugin. Example: `{ swup: '>=4' }` */
	requires?: Record<string, string | string[]>;
	/** Run on mount */
	mount: () => void;
	/** Run on unmount */
	unmount: () => void;
	_beforeMount?: () => void;
	_afterUnmount?: () => void;
	_checkRequirements?: () => boolean;
};

const isSwupPlugin = (maybeInvalidPlugin: unknown): maybeInvalidPlugin is Plugin => {
	// @ts-ignore: this might be anything, object or no
	return Boolean(maybeInvalidPlugin?.isSwupPlugin);
};

/** Install a plugin. */
export const use = function (this: Swup, plugin: unknown) {
	if (!isSwupPlugin(plugin)) {
		console.error('Not a swup plugin instance', plugin);
		return;
	}

	plugin.swup = this;
	if (plugin._checkRequirements) {
		if (!plugin._checkRequirements()) {
			return;
		}
	}
	if (plugin._beforeMount) {
		plugin._beforeMount();
	}
	plugin.mount();

	this.plugins.push(plugin);

	return this.plugins;
};

/** Uninstall a plugin. */
export function unuse(this: Swup, pluginOrName: Plugin | string) {
	const plugin = this.findPlugin(pluginOrName);
	if (!plugin) {
		console.error('No such plugin', plugin);
		return;
	}

	plugin.unmount();
	if (plugin._afterUnmount) {
		plugin._afterUnmount();
	}

	this.plugins = this.plugins.filter((p) => p !== plugin);

	return this.plugins;
}

/** Find a plugin by name or reference. */
export function findPlugin(this: Swup, pluginOrName: Plugin | string) {
	return this.plugins.find(
		(plugin) =>
			plugin === pluginOrName ||
			plugin.name === pluginOrName ||
			plugin.name === `Swup${String(pluginOrName)}`
	);
}