swup 2.0.19 → 3.0.0-rc.1

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.
Files changed (152) hide show
  1. package/dist/helpers.cjs +2 -0
  2. package/dist/helpers.cjs.map +1 -0
  3. package/dist/helpers.modern.js +2 -0
  4. package/dist/helpers.modern.js.map +1 -0
  5. package/dist/helpers.module.js +2 -0
  6. package/dist/helpers.module.js.map +1 -0
  7. package/dist/index.cjs +2 -0
  8. package/dist/index.cjs.map +1 -0
  9. package/dist/index.modern.js +2 -0
  10. package/dist/index.modern.js.map +1 -0
  11. package/dist/index.module.js +2 -0
  12. package/dist/index.module.js.map +1 -0
  13. package/dist/index.umd.js +3 -0
  14. package/dist/index.umd.js.map +1 -0
  15. package/dist/src/config/version.d.ts +5 -0
  16. package/dist/src/helpers/Location.d.ts +31 -0
  17. package/dist/src/helpers/classify.d.ts +2 -0
  18. package/dist/src/helpers/cleanupAnimationClasses.d.ts +2 -0
  19. package/dist/src/helpers/createHistoryRecord.d.ts +2 -0
  20. package/dist/src/helpers/delegateEvent.d.ts +8 -0
  21. package/dist/src/helpers/fetch.d.ts +6 -0
  22. package/dist/src/helpers/getCurrentUrl.d.ts +4 -0
  23. package/dist/src/helpers/getDataFromHtml.d.ts +8 -0
  24. package/dist/src/helpers/index.d.ts +11 -0
  25. package/dist/src/helpers/markSwupElements.d.ts +2 -0
  26. package/dist/src/helpers/updateHistoryRecord.d.ts +2 -0
  27. package/dist/src/helpers/versionSatisfies.d.ts +12 -0
  28. package/dist/src/helpers.d.ts +1 -0
  29. package/dist/src/index.d.ts +97 -0
  30. package/dist/src/modules/Cache.d.ts +20 -0
  31. package/dist/src/modules/enterPage.d.ts +6 -0
  32. package/dist/src/modules/getAnchorElement.d.ts +2 -0
  33. package/dist/src/modules/getAnimationPromises.d.ts +7 -0
  34. package/dist/src/modules/getPageData.d.ts +7 -0
  35. package/dist/src/modules/leavePage.d.ts +7 -0
  36. package/dist/src/modules/loadPage.d.ts +4 -0
  37. package/dist/src/modules/off.d.ts +4 -0
  38. package/dist/src/modules/on.d.ts +4 -0
  39. package/dist/src/modules/plugins.d.ts +13 -0
  40. package/dist/src/modules/renderPage.d.ts +7 -0
  41. package/dist/src/modules/replaceContent.d.ts +17 -0
  42. package/dist/src/modules/triggerEvent.d.ts +4 -0
  43. package/dist/src/modules/updateTransition.d.ts +3 -0
  44. package/dist/src/src/config/version.d.ts +5 -0
  45. package/dist/src/src/helpers/Location.d.ts +31 -0
  46. package/dist/src/src/helpers/classify.d.ts +2 -0
  47. package/dist/src/src/helpers/cleanupAnimationClasses.d.ts +2 -0
  48. package/dist/src/src/helpers/createHistoryRecord.d.ts +2 -0
  49. package/dist/src/src/helpers/delegateEvent.d.ts +8 -0
  50. package/dist/src/src/helpers/fetch.d.ts +6 -0
  51. package/dist/src/src/helpers/getCurrentUrl.d.ts +4 -0
  52. package/dist/src/src/helpers/getDataFromHtml.d.ts +8 -0
  53. package/dist/src/src/helpers/index.d.ts +11 -0
  54. package/dist/src/src/helpers/markSwupElements.d.ts +2 -0
  55. package/dist/src/src/helpers/updateHistoryRecord.d.ts +2 -0
  56. package/dist/src/src/helpers/versionSatisfies.d.ts +12 -0
  57. package/dist/src/src/helpers.d.ts +1 -0
  58. package/dist/src/src/index.d.ts +103 -0
  59. package/dist/src/src/modules/Cache.d.ts +20 -0
  60. package/dist/src/src/modules/enterPage.d.ts +6 -0
  61. package/dist/src/src/modules/getAnchorElement.d.ts +2 -0
  62. package/dist/src/src/modules/getAnimationPromises.d.ts +7 -0
  63. package/dist/src/src/modules/getPageData.d.ts +7 -0
  64. package/dist/src/src/modules/leavePage.d.ts +7 -0
  65. package/dist/src/src/modules/loadPage.d.ts +7 -0
  66. package/dist/src/src/modules/off.d.ts +4 -0
  67. package/dist/src/src/modules/on.d.ts +6 -0
  68. package/dist/src/src/modules/plugins.d.ts +14 -0
  69. package/dist/src/src/modules/renderPage.d.ts +7 -0
  70. package/dist/src/src/modules/replaceContent.d.ts +17 -0
  71. package/dist/src/src/modules/triggerEvent.d.ts +4 -0
  72. package/dist/src/src/modules/updateTransition.d.ts +3 -0
  73. package/dist/src/src/utils/index.d.ts +5 -0
  74. package/dist/src/src/utils.d.ts +1 -0
  75. package/dist/src/types.d.ts +12 -0
  76. package/dist/src/utils/index.d.ts +5 -0
  77. package/dist/src/utils.d.ts +1 -0
  78. package/dist/types.cjs +2 -0
  79. package/dist/types.cjs.map +1 -0
  80. package/dist/types.modern.js +2 -0
  81. package/dist/types.modern.js.map +1 -0
  82. package/dist/types.module.js +2 -0
  83. package/dist/types.module.js.map +1 -0
  84. package/dist/utils.cjs +2 -0
  85. package/dist/utils.cjs.map +1 -0
  86. package/dist/utils.modern.js +2 -0
  87. package/dist/utils.modern.js.map +1 -0
  88. package/dist/utils.module.js +2 -0
  89. package/dist/utils.module.js.map +1 -0
  90. package/package.json +41 -23
  91. package/readme.md +52 -36
  92. package/src/config/version.ts +13 -0
  93. package/src/helpers/Location.ts +44 -0
  94. package/src/helpers/classify.ts +13 -0
  95. package/src/helpers/cleanupAnimationClasses.ts +10 -0
  96. package/src/helpers/createHistoryRecord.ts +14 -0
  97. package/src/helpers/delegateEvent.ts +23 -0
  98. package/src/helpers/fetch.ts +35 -0
  99. package/src/helpers/getCurrentUrl.ts +5 -0
  100. package/src/helpers/getDataFromHtml.ts +41 -0
  101. package/src/helpers/index.ts +11 -0
  102. package/src/helpers/markSwupElements.ts +18 -0
  103. package/src/helpers/updateHistoryRecord.ts +18 -0
  104. package/src/helpers/versionSatisfies.ts +50 -0
  105. package/src/helpers.ts +4 -0
  106. package/src/index.ts +369 -0
  107. package/src/modules/Cache.ts +57 -0
  108. package/src/modules/enterPage.ts +28 -0
  109. package/src/modules/fetchPage.ts +35 -0
  110. package/src/modules/getAnchorElement.ts +19 -0
  111. package/src/modules/getAnimationPromises.ts +176 -0
  112. package/src/modules/getPageData.ts +26 -0
  113. package/src/modules/leavePage.ts +33 -0
  114. package/src/modules/loadPage.ts +54 -0
  115. package/src/modules/off.ts +23 -0
  116. package/src/modules/on.ts +35 -0
  117. package/src/modules/plugins.ts +58 -0
  118. package/src/modules/renderPage.ts +52 -0
  119. package/src/modules/replaceContent.ts +28 -0
  120. package/src/modules/triggerEvent.ts +23 -0
  121. package/src/modules/updateTransition.ts +7 -0
  122. package/src/utils/index.ts +32 -0
  123. package/src/utils.ts +4 -0
  124. package/.editorconfig +0 -19
  125. package/cypress.config.js +0 -14
  126. package/dist/swup.js +0 -1524
  127. package/dist/swup.min.js +0 -1
  128. package/lib/helpers/Link.js +0 -56
  129. package/lib/helpers/classify.js +0 -18
  130. package/lib/helpers/cleanupAnimationClasses.js +0 -18
  131. package/lib/helpers/createHistoryRecord.js +0 -14
  132. package/lib/helpers/fetch.js +0 -41
  133. package/lib/helpers/getCurrentUrl.js +0 -10
  134. package/lib/helpers/getDataFromHtml.js +0 -43
  135. package/lib/helpers/index.js +0 -64
  136. package/lib/helpers/markSwupElements.js +0 -24
  137. package/lib/helpers/normalizeUrl.js +0 -17
  138. package/lib/helpers/transitionEnd.js +0 -14
  139. package/lib/helpers/transitionProperty.js +0 -14
  140. package/lib/index.js +0 -305
  141. package/lib/modules/Cache.js +0 -66
  142. package/lib/modules/getAnchorElement.js +0 -25
  143. package/lib/modules/getAnimationPromises.js +0 -43
  144. package/lib/modules/getPageData.js +0 -26
  145. package/lib/modules/loadPage.js +0 -123
  146. package/lib/modules/off.js +0 -34
  147. package/lib/modules/on.js +0 -14
  148. package/lib/modules/plugins.js +0 -54
  149. package/lib/modules/renderPage.js +0 -76
  150. package/lib/modules/triggerEvent.js +0 -21
  151. package/lib/modules/updateTransition.js +0 -15
  152. package/lib/utils/index.js +0 -32
@@ -0,0 +1,26 @@
1
+ import { getDataFromHtml } from '../helpers.js';
2
+ import Swup from '../index.js';
3
+ import { PageHtmlData } from '../helpers/getDataFromHtml.js';
4
+
5
+ export type PageData = PageHtmlData & {
6
+ responseURL: string;
7
+ };
8
+ 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
+ };
25
+
26
+ export default getPageData;
@@ -0,0 +1,33 @@
1
+ import Swup from '../index.js';
2
+ import { TransitionOptions } from './loadPage.js';
3
+
4
+ const leavePage = function(
5
+ this: Swup,
6
+ data: TransitionOptions,
7
+ { popstate, skipTransition }: { popstate: PopStateEvent | null; skipTransition?: boolean } = {
8
+ popstate: null
9
+ }
10
+ ) {
11
+ if (skipTransition) {
12
+ this.triggerEvent('animationSkipped');
13
+ return [Promise.resolve()];
14
+ }
15
+
16
+ this.triggerEvent('animationOutStart');
17
+
18
+ // handle classes
19
+ document.documentElement.classList.add('is-changing', 'is-leaving', 'is-animating');
20
+ if (popstate) {
21
+ document.documentElement.classList.add('is-popstate');
22
+ }
23
+
24
+ // animation promise stuff
25
+ const animationPromises: Promise<void>[] = this.getAnimationPromises('out');
26
+ Promise.all(animationPromises).then(() => {
27
+ this.triggerEvent('animationOutDone');
28
+ });
29
+
30
+ return animationPromises;
31
+ };
32
+
33
+ export default leavePage;
@@ -0,0 +1,54 @@
1
+ import { classify, createHistoryRecord, getCurrentUrl } from '../helpers.js';
2
+ import Swup from '../index.js';
3
+
4
+ export type TransitionOptions = {
5
+ url: string;
6
+ customTransition?: string;
7
+ };
8
+
9
+ const loadPage = function(this: Swup, data: TransitionOptions, popstate: PopStateEvent | null) {
10
+ const { url, customTransition } = data;
11
+ const skipTransition = !!(popstate && !this.options.animateHistoryBrowsing);
12
+
13
+ this.triggerEvent('transitionStart', popstate || undefined);
14
+
15
+ // set transition object
16
+ this.updateTransition(getCurrentUrl(), url, customTransition);
17
+ if (customTransition != null) {
18
+ document.documentElement.classList.add(`to-${classify(customTransition)}`);
19
+ }
20
+
21
+ // start/skip animation
22
+ const animationPromises = this.leavePage(data, { popstate, skipTransition });
23
+
24
+ // create history record if this is not a popstate call (with or without anchor)
25
+ if (!popstate) {
26
+ createHistoryRecord(url + (this.scrollToElement || ''));
27
+ }
28
+
29
+ this.currentPageUrl = getCurrentUrl();
30
+
31
+ // Load page data
32
+ const fetchPromise = this.fetchPage(data);
33
+
34
+ // when everything is ready, render the page
35
+ Promise.all([fetchPromise, ...animationPromises])
36
+ .then(([pageData]) => {
37
+ this.renderPage(pageData, { popstate, skipTransition });
38
+ })
39
+ .catch((errorUrl) => {
40
+ // Return early if errorUrl is not defined (probably aborted preload request)
41
+ if (errorUrl === undefined) return;
42
+
43
+ // Rewrite `skipPopStateHandling` to redirect manually when `history.go` is processed
44
+ this.options.skipPopStateHandling = () => {
45
+ window.location = errorUrl;
46
+ return true;
47
+ };
48
+
49
+ // Go back to the actual page we're still at
50
+ history.go(-1);
51
+ });
52
+ };
53
+
54
+ export default loadPage;
@@ -0,0 +1,23 @@
1
+ import Swup from '../index.js';
2
+ import { EventType, Handler } from './on.js';
3
+
4
+ const off = function off(this: Swup, event?: EventType, handler?: Handler) {
5
+ if (event && handler) {
6
+ // Remove specific handler
7
+ if (this._handlers[event].includes(handler)) {
8
+ this._handlers[event] = this._handlers[event].filter((h) => h !== handler);
9
+ } else {
10
+ console.warn(`Handler for event '${event}' not found.`);
11
+ }
12
+ } else if (event) {
13
+ // Remove all handlers for specific event
14
+ this._handlers[event] = [];
15
+ } else {
16
+ // Remove all handlers for all events
17
+ Object.keys(this._handlers).forEach((event) => {
18
+ this._handlers[event as EventType] = [];
19
+ });
20
+ }
21
+ };
22
+
23
+ export default off;
@@ -0,0 +1,35 @@
1
+ import Swup from '../index.js';
2
+
3
+ export type EventType =
4
+ | 'animationInDone'
5
+ | 'animationInStart'
6
+ | 'animationOutDone'
7
+ | 'animationOutStart'
8
+ | 'animationSkipped'
9
+ | 'clickLink'
10
+ | 'contentReplaced'
11
+ | 'disabled'
12
+ | 'enabled'
13
+ | 'openPageInNewTab'
14
+ | 'pageLoaded'
15
+ | 'pageRetrievedFromCache'
16
+ | 'pageView'
17
+ | 'popState'
18
+ | 'samePage'
19
+ | 'samePageWithHash'
20
+ | 'serverError'
21
+ | 'transitionStart'
22
+ | 'transitionEnd'
23
+ | 'willReplaceContent';
24
+ export type Handler = (event?: Event) => void;
25
+ export type Handlers = Record<EventType, Handler[]>;
26
+
27
+ const on = function on(this: Swup, event: EventType, handler: Handler) {
28
+ if (this._handlers[event]) {
29
+ this._handlers[event].push(handler);
30
+ } else {
31
+ console.warn(`Unsupported event ${event}.`);
32
+ }
33
+ };
34
+
35
+ export default on;
@@ -0,0 +1,58 @@
1
+ import Swup from '../index.js';
2
+
3
+ // this should probably just be imported from @swup/plugin, but it doesn't have type defs now
4
+ export type Plugin = {
5
+ name: string;
6
+ mount: () => void;
7
+ unmount: () => void;
8
+ isSwupPlugin: true;
9
+ swup?: Swup;
10
+
11
+ // these are possibly undefined for backward compatibility
12
+ _beforeMount?: () => void;
13
+ _afterUnmount?: () => void;
14
+ _checkRequirements?: () => boolean;
15
+ };
16
+
17
+ export const use = function(this: Swup, plugin: Plugin) {
18
+ if (!plugin.isSwupPlugin) {
19
+ console.error('Not a swup plugin instance', plugin);
20
+ return;
21
+ }
22
+
23
+ plugin.swup = this;
24
+ if (plugin._checkRequirements) {
25
+ if (!plugin._checkRequirements()) {
26
+ return;
27
+ }
28
+ }
29
+ if (plugin._beforeMount) {
30
+ plugin._beforeMount();
31
+ }
32
+ plugin.mount();
33
+
34
+ this.plugins.push(plugin);
35
+
36
+ return this.plugins;
37
+ };
38
+
39
+ export function unuse(this: Swup, pluginOrName: Plugin | string) {
40
+ const plugin = this.findPlugin(pluginOrName);
41
+ if (!plugin) {
42
+ console.error('No such plugin', plugin);
43
+ return;
44
+ }
45
+
46
+ plugin.unmount();
47
+ if (plugin._afterUnmount) {
48
+ plugin._afterUnmount();
49
+ }
50
+
51
+ this.plugins = this.plugins.filter((p) => p !== plugin);
52
+
53
+ return this.plugins;
54
+ }
55
+
56
+ export function findPlugin(this: Swup, pluginOrName: Plugin | string) {
57
+ return this.plugins.find((plugin) => plugin === pluginOrName || plugin.name === pluginOrName);
58
+ }
@@ -0,0 +1,52 @@
1
+ import { Location, updateHistoryRecord, getCurrentUrl } from '../helpers.js';
2
+ import Swup from '../index.js';
3
+ import { PageRecord } from './Cache.js';
4
+
5
+ const renderPage = function(
6
+ this: Swup,
7
+ page: PageRecord,
8
+ { popstate, skipTransition }: { popstate: PopStateEvent | null; skipTransition?: boolean } = {
9
+ popstate: null
10
+ }
11
+ ) {
12
+ document.documentElement.classList.remove('is-leaving');
13
+
14
+ // do nothing if another page was requested in the meantime
15
+ if (!this.isSameResolvedUrl(getCurrentUrl(), page.url)) {
16
+ return;
17
+ }
18
+
19
+ const { url } = Location.fromUrl(page.responseURL);
20
+
21
+ // update cache and state if the url was redirected
22
+ if (!this.isSameResolvedUrl(getCurrentUrl(), url)) {
23
+ this.cache.cacheUrl({ ...page, url });
24
+ this.currentPageUrl = getCurrentUrl();
25
+ updateHistoryRecord(url);
26
+ }
27
+
28
+ // only add for page loads with transitions
29
+ if (!skipTransition) {
30
+ document.documentElement.classList.add('is-rendering');
31
+ }
32
+
33
+ this.triggerEvent('willReplaceContent', popstate || undefined);
34
+
35
+ this.replaceContent(page).then(() => {
36
+ this.triggerEvent('contentReplaced', popstate || undefined);
37
+ this.triggerEvent('pageView', popstate || undefined);
38
+
39
+ // empty cache if it's disabled (in case preload plugin filled it)
40
+ if (!this.options.cache) {
41
+ this.cache.empty();
42
+ }
43
+
44
+ // Perform in transition
45
+ this.enterPage({ popstate: popstate || undefined, skipTransition });
46
+
47
+ // reset scroll-to element
48
+ this.scrollToElement = null;
49
+ });
50
+ };
51
+
52
+ export default renderPage;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Perform the replacement of content after loading a page.
3
+ *
4
+ * This method can be replaced or augmented by plugins to allow pausing.
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.
9
+ *
10
+ * @param {object} page The page object
11
+ * @returns Promise
12
+ */
13
+ const replaceContent = function({ blocks, title }: { blocks: string[]; title: string }) {
14
+ // Replace content blocks
15
+ blocks.forEach((html, i) => {
16
+ // we know the block exists at this point
17
+ const block = document.body.querySelector(`[data-swup="${i}"]`)!;
18
+ block.outerHTML = html;
19
+ });
20
+
21
+ // Update browser title
22
+ document.title = title;
23
+
24
+ // Return a Promise to allow plugins to defer
25
+ return Promise.resolve();
26
+ };
27
+
28
+ export default replaceContent;
@@ -0,0 +1,23 @@
1
+ import { EventType } from './on.js';
2
+ import Swup from '../index.js';
3
+
4
+ const triggerEvent = function(
5
+ this: Swup,
6
+ eventName: EventType,
7
+ originalEvent?: PopStateEvent | MouseEvent
8
+ ): void {
9
+ // call saved handlers with "on" method and pass originalEvent object if available
10
+ this._handlers[eventName].forEach((handler) => {
11
+ try {
12
+ handler(originalEvent);
13
+ } catch (error) {
14
+ console.error(error);
15
+ }
16
+ });
17
+
18
+ // trigger event on document with prefix "swup:"
19
+ const event = new CustomEvent(`swup:${eventName}`, { detail: eventName });
20
+ document.dispatchEvent(event);
21
+ };
22
+
23
+ export default triggerEvent;
@@ -0,0 +1,7 @@
1
+ import Swup from '../index.js';
2
+
3
+ const updateTransition = function(this: Swup, from: string, to: string, custom?: string): void {
4
+ this.transition = { from, to, custom };
5
+ };
6
+
7
+ export default updateTransition;
@@ -0,0 +1,32 @@
1
+ export const query = (selector: string, context: Document | Element = document) => {
2
+ return context.querySelector<HTMLElement>(selector);
3
+ };
4
+
5
+ export const queryAll = (
6
+ selector: string,
7
+ context: Document | Element = document
8
+ ): HTMLElement[] => {
9
+ return Array.from(context.querySelectorAll(selector));
10
+ };
11
+
12
+ export const nextTick = (callback: () => void) => {
13
+ requestAnimationFrame(() => {
14
+ requestAnimationFrame(() => {
15
+ callback();
16
+ });
17
+ });
18
+ };
19
+
20
+ export const escapeCssIdentifier = (ident: string) => {
21
+ // @ts-ignore this is for support check, so it's correct that TS complains
22
+ if (window.CSS && window.CSS.escape) {
23
+ return CSS.escape(ident);
24
+ } else {
25
+ return ident;
26
+ }
27
+ };
28
+
29
+ // Fix for Chrome below v61 formatting CSS floats with comma in some locales
30
+ export const toMs = (s: string) => {
31
+ return Number(s.slice(0, -1).replace(',', '.')) * 1000;
32
+ };
package/src/utils.ts ADDED
@@ -0,0 +1,4 @@
1
+ // Re-export all utils to allow custom package export path
2
+ // e.g. import { queryAll } from 'swup/utils'
3
+
4
+ export * from './utils/index.js';
package/.editorconfig DELETED
@@ -1,19 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- charset = utf-8
5
- end_of_line = lf
6
- trim_trailing_whitespace = true
7
- insert_final_newline = true
8
- max_line_length = 100
9
-
10
- [*.{js,mjs}]
11
- indent_style = tab
12
- indent_size = 4
13
-
14
- [*.{json,md,yaml,yml}]
15
- indent_style = space
16
- indent_size = 2
17
-
18
- [*.md]
19
- trim_trailing_whitespace = false
package/cypress.config.js DELETED
@@ -1,14 +0,0 @@
1
- const { defineConfig } = require('cypress')
2
-
3
- module.exports = defineConfig({
4
- projectId: 'dpucip',
5
- e2e: {
6
- baseUrl: 'http://localhost:8274',
7
- specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
8
- chromeWebSecurity: false,
9
- setupNodeEvents(on, config) {
10
- require('@cypress/code-coverage/task')(on, config)
11
- return config
12
- }
13
- }
14
- })