pageturn 0.1.0 → 0.2.0
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/CHANGELOG.md +41 -0
- package/README.md +179 -4
- package/dist/astro.js +0 -2
- package/dist/chunks/chunk-3ABPYO7H.js +43 -0
- package/dist/chunks/chunk-6FXXBNAF.js +197 -0
- package/dist/chunks/chunk-AEOAXMU3.js +33 -0
- package/dist/chunks/chunk-BOM5VXA5.js +167 -0
- package/dist/chunks/chunk-C3T7BGNG.js +30 -0
- package/dist/chunks/chunk-FYSSNYA4.js +17 -0
- package/dist/chunks/chunk-JHM7F4CH.js +172 -0
- package/dist/chunks/chunk-LM3XLSCW.js +799 -0
- package/dist/chunks/{chunk-QJ7GGFM4.js → chunk-YAL4MNCU.js} +4 -6
- package/dist/core.js +4 -3
- package/dist/dev/chunks/chunk-3JAWIMHB.js +184 -0
- package/dist/dev/chunks/chunk-3SU4CIKL.js +799 -0
- package/dist/dev/chunks/chunk-AEOAXMU3.js +33 -0
- package/dist/dev/chunks/chunk-C3T7BGNG.js +30 -0
- package/dist/dev/chunks/chunk-FYSSNYA4.js +17 -0
- package/dist/dev/chunks/chunk-I4SBUABE.js +175 -0
- package/dist/dev/chunks/chunk-U3XN54YY.js +219 -0
- package/dist/dev/chunks/chunk-Y6TD2T53.js +43 -0
- package/dist/dev/chunks/chunk-YAL4MNCU.js +22 -0
- package/dist/dev/core.js +19 -0
- package/dist/dev/index.js +21 -0
- package/dist/dev/morph-markup.js +34 -0
- package/dist/dev/morph.js +457 -0
- package/dist/dev/native.js +3 -0
- package/dist/dev/next.js +79 -0
- package/dist/dev/nuxt-plugin.js +24 -0
- package/dist/dev/prefetch.js +2 -0
- package/dist/dev/react-router.js +46 -0
- package/dist/dev/router.js +9 -0
- package/dist/dev/sveltekit.js +32 -0
- package/dist/dev/testing.js +48 -0
- package/dist/dev/turbo.js +49 -0
- package/dist/dev/vue.js +11 -0
- package/dist/head-core.js +1 -1
- package/dist/head-string.js +6 -6
- package/dist/head.js +1 -1
- package/dist/index.js +6 -5
- package/dist/morph-head.js +1 -1
- package/dist/morph-markup.js +11 -9
- package/dist/morph.js +145 -287
- package/dist/native.js +3 -2
- package/dist/next.js +79 -0
- package/dist/nuxt-plugin.js +24 -0
- package/dist/nuxt.js +34 -0
- package/dist/pageturn-morph.js +1 -1
- package/dist/pageturn.js +1 -1
- package/dist/prefetch.js +2 -2
- package/dist/react-router.js +46 -0
- package/dist/router.js +5 -183
- package/dist/sveltekit-server.js +22 -0
- package/dist/sveltekit.js +32 -0
- package/dist/testing.js +12 -22
- package/dist/turbo.js +49 -0
- package/dist/types/astro/integration.d.ts +0 -4
- package/dist/types/common/dev.d.ts +6 -0
- package/dist/types/common/page.d.ts +5 -0
- package/dist/types/common/registry.d.ts +3 -1
- package/dist/types/next/next.d.ts +27 -0
- package/dist/types/nuxt/module.d.ts +32 -0
- package/dist/types/react-router/react-router.d.ts +12 -0
- package/dist/types/router/router.d.ts +4 -2
- package/dist/types/sveltekit/server.d.ts +21 -0
- package/dist/types/sveltekit/sveltekit.d.ts +32 -0
- package/dist/types/turbo/turbo.d.ts +1 -0
- package/dist/types/vue/vue.d.ts +36 -0
- package/dist/vue.js +11 -0
- package/package.json +102 -23
- package/dist/chunks/chunk-237GNQNZ.js +0 -37
- package/dist/chunks/chunk-7LMNJ25V.js +0 -244
- package/dist/chunks/chunk-QC36TQP3.js +0 -24
- package/dist/chunks/chunk-WTHN3UIQ.js +0 -1000
- package/dist/chunks/chunk-YBAP3PHO.js +0 -247
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/common/page.ts
|
|
2
|
+
var inBrowser = typeof document < "u", navigationEntry = () => performance.getEntriesByType("navigation")[0];
|
|
3
|
+
function afterDomContentLoaded(run) {
|
|
4
|
+
let entry = navigationEntry();
|
|
5
|
+
(entry ? entry.domContentLoadedEventStart > 0 : document.readyState !== "loading") ? run() : document.addEventListener("DOMContentLoaded", run, { once: !0 });
|
|
6
|
+
}
|
|
7
|
+
var reduced;
|
|
8
|
+
function reducesMotion() {
|
|
9
|
+
return reduced ??= matchMedia("(prefers-reduced-motion: reduce)"), reduced.matches;
|
|
10
|
+
}
|
|
11
|
+
function notShownAnew() {
|
|
12
|
+
window.pageturn && (window.pageturn.l = !0), delete document.documentElement.dataset.turnEntering;
|
|
13
|
+
}
|
|
14
|
+
var FOCUS_BACK = /* @__PURE__ */ Symbol.for("pageturn.focusBack"), shared = globalThis;
|
|
15
|
+
function giveFocusTo(element, options) {
|
|
16
|
+
shared[FOCUS_BACK] = element;
|
|
17
|
+
try {
|
|
18
|
+
element.focus(options);
|
|
19
|
+
} finally {
|
|
20
|
+
delete shared[FOCUS_BACK];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
var isFocusGivenBack = (element) => shared[FOCUS_BACK] === element;
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
inBrowser,
|
|
27
|
+
navigationEntry,
|
|
28
|
+
afterDomContentLoaded,
|
|
29
|
+
reducesMotion,
|
|
30
|
+
notShownAnew,
|
|
31
|
+
giveFocusTo,
|
|
32
|
+
isFocusGivenBack
|
|
33
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import {
|
|
2
|
+
inBrowser
|
|
3
|
+
} from "./chunk-AEOAXMU3.js";
|
|
4
|
+
import {
|
|
5
|
+
registry
|
|
6
|
+
} from "./chunk-YAL4MNCU.js";
|
|
7
|
+
|
|
8
|
+
// src/default-move/native.ts
|
|
9
|
+
var nextSwap;
|
|
10
|
+
!registry.a && inBrowser && (addEventListener("pageswap", (event) => {
|
|
11
|
+
let transition = event.viewTransition;
|
|
12
|
+
nextSwap === null ? transition?.skipTransition() : nextSwap && transition?.types.add(nextSwap), nextSwap = void 0;
|
|
13
|
+
}), registry.a = {
|
|
14
|
+
v(move, to) {
|
|
15
|
+
let store = window.pageturn?.j;
|
|
16
|
+
return store && window.pageturn?.a && "CSSViewTransitionRule" in window && getComputedStyle(document.documentElement).getPropertyValue("--pageturn-native").trim() !== "" ? (store.h(
|
|
17
|
+
{
|
|
18
|
+
move,
|
|
19
|
+
data: null,
|
|
20
|
+
from: location.pathname,
|
|
21
|
+
at: Date.now(),
|
|
22
|
+
a: !0
|
|
23
|
+
},
|
|
24
|
+
to
|
|
25
|
+
), store.i(null), nextSwap = move, !0) : !1;
|
|
26
|
+
},
|
|
27
|
+
c: (value) => {
|
|
28
|
+
nextSwap = value;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
registry
|
|
3
|
+
} from "./chunk-YAL4MNCU.js";
|
|
4
|
+
|
|
5
|
+
// src/prefetch/prefetch.ts
|
|
6
|
+
var asked = /* @__PURE__ */ new Set();
|
|
7
|
+
registry.u ??= (to) => {
|
|
8
|
+
let address = to.href.split("#")[0] ?? to.href;
|
|
9
|
+
if (asked.has(address)) return;
|
|
10
|
+
let connection = navigator.connection;
|
|
11
|
+
if (connection?.saveData || /2g/.test(connection?.effectiveType ?? ""))
|
|
12
|
+
return;
|
|
13
|
+
asked.add(address);
|
|
14
|
+
let link = document.createElement("link");
|
|
15
|
+
link.relList.supports("prefetch") ? (link.rel = "prefetch", link.href = address, document.head.append(link)) : fetch(address, { priority: "low" }).catch(() => {
|
|
16
|
+
});
|
|
17
|
+
};
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addressOf,
|
|
3
|
+
choose,
|
|
4
|
+
followArrival,
|
|
5
|
+
leave,
|
|
6
|
+
readSession,
|
|
7
|
+
returnArrival,
|
|
8
|
+
tellArrival,
|
|
9
|
+
turnOf,
|
|
10
|
+
warn,
|
|
11
|
+
writeSession
|
|
12
|
+
} from "./chunk-3JAWIMHB.js";
|
|
13
|
+
import {
|
|
14
|
+
inBrowser,
|
|
15
|
+
reducesMotion
|
|
16
|
+
} from "./chunk-AEOAXMU3.js";
|
|
17
|
+
import {
|
|
18
|
+
registry
|
|
19
|
+
} from "./chunk-YAL4MNCU.js";
|
|
20
|
+
|
|
21
|
+
// src/router/router.ts
|
|
22
|
+
var ENTRIES_KEY = "pageturn:router:entries", KEPT_ENTRIES = 50, CLICK_FRESH_MS = 1e3, INERT = {
|
|
23
|
+
left: Promise.resolve(),
|
|
24
|
+
swapped() {
|
|
25
|
+
},
|
|
26
|
+
cancelled() {
|
|
27
|
+
}
|
|
28
|
+
}, current = null, shown = inBrowser ? location.href : "", lastClick = null;
|
|
29
|
+
inBrowser && (registry.w = !0, addEventListener(
|
|
30
|
+
"click",
|
|
31
|
+
(event) => {
|
|
32
|
+
let link = event.composedPath().find((target) => target instanceof HTMLAnchorElement);
|
|
33
|
+
link && (lastClick = { link, at: Date.now() });
|
|
34
|
+
},
|
|
35
|
+
!0
|
|
36
|
+
));
|
|
37
|
+
function keyOf(url) {
|
|
38
|
+
let api = window.navigation, here = api?.currentEntry;
|
|
39
|
+
for (let entry of here ? [here, api.entries()[here.index - 1]] : [])
|
|
40
|
+
if (entry?.url && addressOf(new URL(entry.url)) === addressOf(url))
|
|
41
|
+
return entry.key;
|
|
42
|
+
return addressOf(url);
|
|
43
|
+
}
|
|
44
|
+
var readEntries = () => readSession(ENTRIES_KEY) ?? {};
|
|
45
|
+
function writeEntry(key, entry) {
|
|
46
|
+
let { [key]: _, ...entries } = readEntries(), kept = Object.entries(entries).slice(1 - KEPT_ENTRIES);
|
|
47
|
+
writeSession(ENTRIES_KEY, {
|
|
48
|
+
...Object.fromEntries(kept),
|
|
49
|
+
...entry ? { [key]: entry } : {}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function reportOf(from) {
|
|
53
|
+
let { e: report } = registry;
|
|
54
|
+
if (!report && !window.pageturn?.arrival) return null;
|
|
55
|
+
let data = null;
|
|
56
|
+
try {
|
|
57
|
+
data = report?.({ decline: () => registry.f }) ?? null;
|
|
58
|
+
} catch (error) {
|
|
59
|
+
reportError(error);
|
|
60
|
+
}
|
|
61
|
+
let isNone = data === registry.f;
|
|
62
|
+
return {
|
|
63
|
+
from: from.pathname,
|
|
64
|
+
at: Date.now(),
|
|
65
|
+
data: isNone ? null : data,
|
|
66
|
+
...isNone ? { none: !0 } : {}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function clickedTo(to) {
|
|
70
|
+
let click = lastClick;
|
|
71
|
+
return click && Date.now() - click.at < CLICK_FRESH_MS && addressOf(new URL(click.link.href)) === addressOf(to) ? click.link : null;
|
|
72
|
+
}
|
|
73
|
+
function startNavigation(start) {
|
|
74
|
+
if (!inBrowser) return INERT;
|
|
75
|
+
let to = new URL(start.to, location.href);
|
|
76
|
+
if (!window.pageturn || window.top !== window || reducesMotion() || // The same path and query: a place in the page (#…), not another page.
|
|
77
|
+
addressOf(to) === addressOf(new URL(shown)))
|
|
78
|
+
return shown = to.href, INERT;
|
|
79
|
+
current && end(current, "superseded");
|
|
80
|
+
let from = new URL(shown), playing = {
|
|
81
|
+
via: start.via,
|
|
82
|
+
to,
|
|
83
|
+
from,
|
|
84
|
+
leftKey: start.via === "history" ? "" : keyOf(from),
|
|
85
|
+
e: reportOf(from)
|
|
86
|
+
};
|
|
87
|
+
current = playing;
|
|
88
|
+
let drive = {
|
|
89
|
+
left: Promise.resolve(),
|
|
90
|
+
swapped: () => swapped(playing),
|
|
91
|
+
cancelled: () => {
|
|
92
|
+
current === playing && end(playing, "cancelled");
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
if (start.via === "history") return drive;
|
|
96
|
+
let clicked = start.via === "link" ? start.link ?? clickedTo(to) : null, visit = {
|
|
97
|
+
link: clicked ?? Object.assign(document.createElement("a"), { href: to.href }),
|
|
98
|
+
via: clicked ? "link" : "script",
|
|
99
|
+
from,
|
|
100
|
+
to,
|
|
101
|
+
canHandOver: !0
|
|
102
|
+
}, name = start.move !== void 0 ? start.move : clicked ? choose(visit) : registry.settings.defaultMove;
|
|
103
|
+
if (name === null) return drive;
|
|
104
|
+
let turn = turnOf(visit, name);
|
|
105
|
+
return document.dispatchEvent(
|
|
106
|
+
new CustomEvent("pageturn:leaving", { cancelable: !0, detail: turn })
|
|
107
|
+
) ? (playing.turn = turn, {
|
|
108
|
+
...drive,
|
|
109
|
+
left: leave(turn, (played) => {
|
|
110
|
+
playing.turn = played;
|
|
111
|
+
}).then((handover) => {
|
|
112
|
+
current === playing && (playing.handover = handover);
|
|
113
|
+
})
|
|
114
|
+
}) : drive;
|
|
115
|
+
}
|
|
116
|
+
function swapped(playing) {
|
|
117
|
+
if (current !== playing) return;
|
|
118
|
+
current = null;
|
|
119
|
+
let reached = new URL(location.href);
|
|
120
|
+
shown = reached.href;
|
|
121
|
+
let published = window.pageturn;
|
|
122
|
+
if (!published) return;
|
|
123
|
+
try {
|
|
124
|
+
document.documentElement.matches(":active-view-transition") && warn(
|
|
125
|
+
"transition",
|
|
126
|
+
"the router plays its own view transition while pageturn plays a move: turn the router's view transitions off where pageturn plays."
|
|
127
|
+
);
|
|
128
|
+
} catch {
|
|
129
|
+
}
|
|
130
|
+
published.endArrival(), delete document.documentElement.dataset.turnLeaving;
|
|
131
|
+
let arrival = null;
|
|
132
|
+
if (playing.via === "history")
|
|
133
|
+
arrival = returnArrival(
|
|
134
|
+
readEntries()[keyOf(reached)] ?? null,
|
|
135
|
+
playing.e
|
|
136
|
+
);
|
|
137
|
+
else {
|
|
138
|
+
let { turn, handover } = playing;
|
|
139
|
+
turn && handover && handover.arriveAs !== null && (arrival = {
|
|
140
|
+
move: handover.arriveAs ?? turn.move,
|
|
141
|
+
via: "link",
|
|
142
|
+
from: playing.from.pathname,
|
|
143
|
+
data: handover.data ?? null,
|
|
144
|
+
remembered: null,
|
|
145
|
+
reported: null
|
|
146
|
+
}), writeEntry(
|
|
147
|
+
playing.leftKey,
|
|
148
|
+
turn && handover?.returnAs ? {
|
|
149
|
+
move: turn.move,
|
|
150
|
+
to: reached.pathname,
|
|
151
|
+
returnAs: handover.returnAs,
|
|
152
|
+
remember: handover.remember ?? null
|
|
153
|
+
} : null
|
|
154
|
+
), document.documentElement.dataset.turnEntering = "";
|
|
155
|
+
}
|
|
156
|
+
published.arrival = arrival, arrival && published.t?.(arrival), followArrival(), arrival && tellArrival(arrival);
|
|
157
|
+
}
|
|
158
|
+
function end(playing, reason) {
|
|
159
|
+
current = null, delete document.documentElement.dataset.turnLeaving;
|
|
160
|
+
let { turn } = playing;
|
|
161
|
+
if (!turn) return;
|
|
162
|
+
let stay = { reason, handover: playing.handover ?? null };
|
|
163
|
+
try {
|
|
164
|
+
registry.b.get(turn.move)?.stay?.(turn, stay);
|
|
165
|
+
} catch (error) {
|
|
166
|
+
reportError(error);
|
|
167
|
+
}
|
|
168
|
+
document.dispatchEvent(
|
|
169
|
+
new CustomEvent("pageturn:stayed", { detail: { turn, stay } })
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export {
|
|
174
|
+
startNavigation
|
|
175
|
+
};
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import {
|
|
2
|
+
STORE_VERSION,
|
|
3
|
+
addressOf,
|
|
4
|
+
choose,
|
|
5
|
+
followArrival,
|
|
6
|
+
leave,
|
|
7
|
+
stopFollowing,
|
|
8
|
+
tellArrival,
|
|
9
|
+
turnOf,
|
|
10
|
+
warn
|
|
11
|
+
} from "./chunk-3JAWIMHB.js";
|
|
12
|
+
import {
|
|
13
|
+
inBrowser,
|
|
14
|
+
reducesMotion
|
|
15
|
+
} from "./chunk-AEOAXMU3.js";
|
|
16
|
+
import {
|
|
17
|
+
registry
|
|
18
|
+
} from "./chunk-YAL4MNCU.js";
|
|
19
|
+
|
|
20
|
+
// src/kernel/kernel.ts
|
|
21
|
+
var store, current = null, stuckTimer;
|
|
22
|
+
function install() {
|
|
23
|
+
if (!inBrowser) return;
|
|
24
|
+
let published = window.pageturn?.j;
|
|
25
|
+
if (registry.g || published?.m !== STORE_VERSION) {
|
|
26
|
+
!registry.g && !window.pageturn && warn(
|
|
27
|
+
"head",
|
|
28
|
+
"the head script is not on this page, so links navigate with no move. Put it first in <head>, before any other script (see the README)."
|
|
29
|
+
);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
store = published, registry.g = !0, reducesMotion() && warn(
|
|
33
|
+
"motion",
|
|
34
|
+
"prefers-reduced-motion is on: pageturn plays nothing, and links navigate as they would without it."
|
|
35
|
+
), addEventListener("click", putClickLast, !0), addEventListener("pointerdown", pressed, !0), addEventListener("pagehide", pageHidden, !0), addEventListener("pageshow", pageShown), followArrival();
|
|
36
|
+
}
|
|
37
|
+
function putClickLast() {
|
|
38
|
+
clickedAt = addressOf(location), removeEventListener("click", clicked), addEventListener("click", clicked);
|
|
39
|
+
}
|
|
40
|
+
var clickedAt = "";
|
|
41
|
+
function linkIn(event) {
|
|
42
|
+
for (let target of event.composedPath()) {
|
|
43
|
+
if (target instanceof HTMLAnchorElement)
|
|
44
|
+
return target.hasAttribute("href") ? target : null;
|
|
45
|
+
if (target instanceof SVGAElement) return null;
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
function isEditable(event) {
|
|
50
|
+
let [target] = event.composedPath();
|
|
51
|
+
return target instanceof HTMLElement && target.isContentEditable;
|
|
52
|
+
}
|
|
53
|
+
function destinationOf(link) {
|
|
54
|
+
let target = link.target || document.querySelector("base[target]")?.getAttribute("target");
|
|
55
|
+
if (target && target !== "_self" || link.hasAttribute("download"))
|
|
56
|
+
return null;
|
|
57
|
+
let to = new URL(link.href), isThisPage = to.pathname === location.pathname && to.search === location.search;
|
|
58
|
+
return to.origin === location.origin && !isThisPage ? to : null;
|
|
59
|
+
}
|
|
60
|
+
function prefetch(to) {
|
|
61
|
+
registry.settings.prefetch && registry.u?.(to);
|
|
62
|
+
}
|
|
63
|
+
function pressed(event) {
|
|
64
|
+
if (event.button !== 0 || isEditable(event)) return;
|
|
65
|
+
let link = linkIn(event), to = link && destinationOf(link);
|
|
66
|
+
to && prefetch(to);
|
|
67
|
+
}
|
|
68
|
+
function watchRouter(event) {
|
|
69
|
+
let link = linkIn(event), to = link && new URL(link.href);
|
|
70
|
+
!to || to.origin !== location.origin || addressOf(to) === clickedAt || setTimeout(() => {
|
|
71
|
+
registry.w || addressOf(location) !== addressOf(to) || warn(
|
|
72
|
+
"router",
|
|
73
|
+
`a client router took the link to ${to.pathname}, so pageturn plays nothing on it. Use pageturn's adapter for that router (see the README), or pageturn/router.`
|
|
74
|
+
);
|
|
75
|
+
}, 300);
|
|
76
|
+
}
|
|
77
|
+
function clicked(event) {
|
|
78
|
+
if (event.defaultPrevented && watchRouter(event), event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || isEditable(event))
|
|
79
|
+
return;
|
|
80
|
+
let link = linkIn(event), to = link && destinationOf(link);
|
|
81
|
+
if (!link || !to) return;
|
|
82
|
+
if (current) {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (store.n(), event.detail === 0 && prefetch(to), reducesMotion()) return;
|
|
87
|
+
let { a: native } = registry, visit = {
|
|
88
|
+
link,
|
|
89
|
+
via: "link",
|
|
90
|
+
from: new URL(location.href),
|
|
91
|
+
to,
|
|
92
|
+
canHandOver: store.q()
|
|
93
|
+
}, name = choose(visit);
|
|
94
|
+
if (name === null) {
|
|
95
|
+
native?.c(null);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
let turn = turnOf(visit, name);
|
|
99
|
+
if (!document.dispatchEvent(
|
|
100
|
+
new CustomEvent("pageturn:leaving", { cancelable: !0, detail: turn })
|
|
101
|
+
)) {
|
|
102
|
+
native?.c(null);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (name === registry.settings.defaultMove && !registry.b.get(name)?.leave && native?.v(name, to))
|
|
106
|
+
return;
|
|
107
|
+
event.preventDefault();
|
|
108
|
+
let playing = { turn };
|
|
109
|
+
current = playing, leave(turn, (played) => {
|
|
110
|
+
playing.turn = played;
|
|
111
|
+
}).then((handover) => depart(playing, handover));
|
|
112
|
+
}
|
|
113
|
+
function depart(playing, handover) {
|
|
114
|
+
if (current !== playing || playing.handover !== void 0) return;
|
|
115
|
+
let { turn } = playing;
|
|
116
|
+
playing.handover = handover, handover && handover.arriveAs !== null && store.h(
|
|
117
|
+
{
|
|
118
|
+
move: handover.arriveAs ?? turn.move,
|
|
119
|
+
data: handover.data ?? null,
|
|
120
|
+
from: location.pathname,
|
|
121
|
+
at: Date.now()
|
|
122
|
+
},
|
|
123
|
+
turn.to
|
|
124
|
+
), playing.entry = handover?.returnAs ? {
|
|
125
|
+
move: turn.move,
|
|
126
|
+
to: turn.to.pathname,
|
|
127
|
+
returnAs: handover.returnAs,
|
|
128
|
+
remember: handover.remember ?? null
|
|
129
|
+
} : null, store.i(playing.entry), registry.a?.c(null), location.assign(turn.to.href), stuckTimer = setTimeout(
|
|
130
|
+
() => endWithoutDeparture(playing, "stuck"),
|
|
131
|
+
registry.settings.stuckTimeout
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
function endWithoutDeparture(playing, reason) {
|
|
135
|
+
if (current !== playing) return;
|
|
136
|
+
current = null, clearTimeout(stuckTimer), registry.a?.c(void 0), delete document.documentElement.dataset.turnLeaving;
|
|
137
|
+
let stay = { reason, handover: playing.handover ?? null };
|
|
138
|
+
try {
|
|
139
|
+
registry.b.get(playing.turn.move)?.stay?.(playing.turn, stay);
|
|
140
|
+
} catch (error) {
|
|
141
|
+
reportError(error);
|
|
142
|
+
}
|
|
143
|
+
document.dispatchEvent(
|
|
144
|
+
new CustomEvent("pageturn:stayed", {
|
|
145
|
+
detail: { turn: playing.turn, stay }
|
|
146
|
+
})
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
function pageHidden() {
|
|
150
|
+
clearTimeout(stuckTimer), stopFollowing();
|
|
151
|
+
let { e: report } = registry;
|
|
152
|
+
if (!report && !window.pageturn?.arrival) return;
|
|
153
|
+
let data = null;
|
|
154
|
+
try {
|
|
155
|
+
data = report?.({ decline: () => registry.f }) ?? null;
|
|
156
|
+
} catch (error) {
|
|
157
|
+
reportError(error);
|
|
158
|
+
}
|
|
159
|
+
let isNone = data === registry.f;
|
|
160
|
+
store.p({
|
|
161
|
+
from: location.pathname,
|
|
162
|
+
at: Date.now(),
|
|
163
|
+
data: isNone ? null : data,
|
|
164
|
+
...isNone ? { none: !0 } : {}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function pageShown(event) {
|
|
168
|
+
if (!event.persisted) return;
|
|
169
|
+
registry.a?.c(void 0);
|
|
170
|
+
let playing = current, published = window.pageturn;
|
|
171
|
+
if (!published) return;
|
|
172
|
+
let entry = playing ? playing.entry ?? null : store.r(), arrival2 = store.s(entry, store.o());
|
|
173
|
+
published.arrival = arrival2, arrival2 && (published.t?.(arrival2), published.k?.skipTransition(), followArrival()), playing && endWithoutDeparture(playing, "returned"), arrival2 && tellArrival(arrival2);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/kernel/core.ts
|
|
177
|
+
function defineMove(name, move) {
|
|
178
|
+
let stored = move;
|
|
179
|
+
registry.b.set(name, stored);
|
|
180
|
+
let reached = inBrowser ? window.pageturn?.arrival : null;
|
|
181
|
+
return reached?.move === name && stored.arrive && queueMicrotask(() => {
|
|
182
|
+
registry.b.get(name) === stored && tellArrival(reached);
|
|
183
|
+
}), () => {
|
|
184
|
+
registry.b.get(name) === stored && registry.b.delete(name);
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
function chooseMove(chooser) {
|
|
188
|
+
let stored = chooser;
|
|
189
|
+
return registry.d.push(stored), () => {
|
|
190
|
+
let index = registry.d.indexOf(stored);
|
|
191
|
+
index >= 0 && registry.d.splice(index, 1);
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function arrival() {
|
|
195
|
+
return inBrowser && window.pageturn?.arrival || null;
|
|
196
|
+
}
|
|
197
|
+
function endArrival(move) {
|
|
198
|
+
inBrowser && window.pageturn?.endArrival(move);
|
|
199
|
+
}
|
|
200
|
+
function whenLeft(report) {
|
|
201
|
+
let stored = report;
|
|
202
|
+
return registry.e = stored, () => {
|
|
203
|
+
registry.e === stored && (registry.e = null);
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function configure(settings) {
|
|
207
|
+
for (let [key, value] of Object.entries(settings))
|
|
208
|
+
value !== void 0 && Object.assign(registry.settings, { [key]: value });
|
|
209
|
+
}
|
|
210
|
+
install();
|
|
211
|
+
|
|
212
|
+
export {
|
|
213
|
+
defineMove,
|
|
214
|
+
chooseMove,
|
|
215
|
+
arrival,
|
|
216
|
+
endArrival,
|
|
217
|
+
whenLeft,
|
|
218
|
+
configure
|
|
219
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
startNavigation
|
|
3
|
+
} from "./chunk-I4SBUABE.js";
|
|
4
|
+
import {
|
|
5
|
+
inBrowser
|
|
6
|
+
} from "./chunk-AEOAXMU3.js";
|
|
7
|
+
|
|
8
|
+
// src/vue/vue.ts
|
|
9
|
+
function pageturn(router, options = {}) {
|
|
10
|
+
if (!inBrowser) return () => {
|
|
11
|
+
};
|
|
12
|
+
let current = null, popped = !1, cancel = () => {
|
|
13
|
+
current?.cancelled(), current = null;
|
|
14
|
+
}, stops = [
|
|
15
|
+
// Back and Forward: the router's history says so before its guards run.
|
|
16
|
+
router.options.history.listen((_to, _from, info) => {
|
|
17
|
+
popped = info.type === "pop";
|
|
18
|
+
}),
|
|
19
|
+
router.beforeEach((to, from) => {
|
|
20
|
+
let via = popped ? "history" : "link";
|
|
21
|
+
popped = !1, from.matched.length !== 0 && (current = startNavigation({ to: router.resolve(to).href, via }));
|
|
22
|
+
}),
|
|
23
|
+
router.beforeResolve(() => current?.left),
|
|
24
|
+
router.afterEach((_to, _from, failure) => {
|
|
25
|
+
let turn = current;
|
|
26
|
+
if (current = null, !turn) return;
|
|
27
|
+
if (failure) {
|
|
28
|
+
turn.cancelled();
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
let swap = () => turn.swapped();
|
|
32
|
+
options.whenShown ? options.whenShown(swap) : queueMicrotask(swap);
|
|
33
|
+
}),
|
|
34
|
+
router.onError(cancel)
|
|
35
|
+
];
|
|
36
|
+
return () => {
|
|
37
|
+
for (let stop of stops) stop();
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export {
|
|
42
|
+
pageturn
|
|
43
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/common/registry.ts
|
|
2
|
+
var KEY = /* @__PURE__ */ Symbol.for("pageturn.registry"), holder = globalThis;
|
|
3
|
+
holder[KEY] ??= {
|
|
4
|
+
b: /* @__PURE__ */ new Map(),
|
|
5
|
+
d: [],
|
|
6
|
+
e: null,
|
|
7
|
+
settings: {
|
|
8
|
+
defaultMove: "page",
|
|
9
|
+
prefetch: !0,
|
|
10
|
+
leaveTimeout: 4e3,
|
|
11
|
+
stuckTimeout: 4e3,
|
|
12
|
+
arrivalEnds: "animations"
|
|
13
|
+
},
|
|
14
|
+
g: !1,
|
|
15
|
+
f: Object.freeze({})
|
|
16
|
+
};
|
|
17
|
+
var registry = holder[KEY], isDeclined = (answer) => answer === registry.f;
|
|
18
|
+
|
|
19
|
+
export {
|
|
20
|
+
registry,
|
|
21
|
+
isDeclined
|
|
22
|
+
};
|
package/dist/dev/core.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
arrival,
|
|
3
|
+
chooseMove,
|
|
4
|
+
configure,
|
|
5
|
+
defineMove,
|
|
6
|
+
endArrival,
|
|
7
|
+
whenLeft
|
|
8
|
+
} from "./chunks/chunk-U3XN54YY.js";
|
|
9
|
+
import "./chunks/chunk-3JAWIMHB.js";
|
|
10
|
+
import "./chunks/chunk-AEOAXMU3.js";
|
|
11
|
+
import "./chunks/chunk-YAL4MNCU.js";
|
|
12
|
+
export {
|
|
13
|
+
arrival,
|
|
14
|
+
chooseMove,
|
|
15
|
+
configure,
|
|
16
|
+
defineMove,
|
|
17
|
+
endArrival,
|
|
18
|
+
whenLeft
|
|
19
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import "./chunks/chunk-FYSSNYA4.js";
|
|
2
|
+
import "./chunks/chunk-C3T7BGNG.js";
|
|
3
|
+
import {
|
|
4
|
+
arrival,
|
|
5
|
+
chooseMove,
|
|
6
|
+
configure,
|
|
7
|
+
defineMove,
|
|
8
|
+
endArrival,
|
|
9
|
+
whenLeft
|
|
10
|
+
} from "./chunks/chunk-U3XN54YY.js";
|
|
11
|
+
import "./chunks/chunk-3JAWIMHB.js";
|
|
12
|
+
import "./chunks/chunk-AEOAXMU3.js";
|
|
13
|
+
import "./chunks/chunk-YAL4MNCU.js";
|
|
14
|
+
export {
|
|
15
|
+
arrival,
|
|
16
|
+
chooseMove,
|
|
17
|
+
configure,
|
|
18
|
+
defineMove,
|
|
19
|
+
endArrival,
|
|
20
|
+
whenLeft
|
|
21
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
back,
|
|
3
|
+
defineMorph,
|
|
4
|
+
isDefined,
|
|
5
|
+
seen
|
|
6
|
+
} from "./chunks/chunk-3SU4CIKL.js";
|
|
7
|
+
import "./chunks/chunk-U3XN54YY.js";
|
|
8
|
+
import "./chunks/chunk-3JAWIMHB.js";
|
|
9
|
+
import {
|
|
10
|
+
afterDomContentLoaded,
|
|
11
|
+
inBrowser
|
|
12
|
+
} from "./chunks/chunk-AEOAXMU3.js";
|
|
13
|
+
import "./chunks/chunk-YAL4MNCU.js";
|
|
14
|
+
|
|
15
|
+
// src/morph/markup.ts
|
|
16
|
+
var ATTRIBUTE = "data-turn-morph";
|
|
17
|
+
function morphsFromMarkup() {
|
|
18
|
+
let names = new Set(
|
|
19
|
+
[...document.querySelectorAll(`[${ATTRIBUTE}]`)].map(
|
|
20
|
+
(element) => element.getAttribute(ATTRIBUTE) ?? ""
|
|
21
|
+
)
|
|
22
|
+
);
|
|
23
|
+
for (let name of names) {
|
|
24
|
+
if (!name || isDefined(name)) continue;
|
|
25
|
+
let selector = `[${ATTRIBUTE}="${CSS.escape(name)}"]`;
|
|
26
|
+
defineMorph(name, {
|
|
27
|
+
from: (link) => link.querySelector(selector) ?? link.closest(selector),
|
|
28
|
+
to: selector,
|
|
29
|
+
find: seen(),
|
|
30
|
+
use: [back()]
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
inBrowser && afterDomContentLoaded(morphsFromMarkup);
|