camox 0.68.0 → 0.69.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/dist/features/canvas/canvasFrameDocument.js +25 -2
- package/dist/features/canvas/useCanvasFrame.js +6 -2
- package/dist/features/preview/components/previewStyles.js +11 -2
- package/dist/features/provider/AuthenticatedCamoxProvider.js +33 -28
- package/dist/features/renderer/RendererApp.js +202 -154
- package/dist/features/renderer/RendererFrames.js +87 -55
- package/dist/features/renderer/definitionAnswers.js +1 -0
- package/dist/features/renderer/rendererHost.js +4 -0
- package/dist/features/renderer/studioConnection.js +9 -1
- package/dist/features/runtime/pageNavigation.js +93 -17
- package/dist/features/runtime/rendererClient.js +13 -6
- package/dist/features/studio/components/DraftsControl.js +116 -107
- package/dist/features/studio/components/LocalePicker.js +22 -4
- package/dist/features/studio/components/ReviewDraftSheet.js +2 -21
- package/dist/features/studio/viewSwitch.js +64 -0
- package/dist/lib/auth.js +5 -1
- package/dist/lib/draft-scope.js +28 -15
- package/dist/lib/studio-reads.js +46 -13
- package/dist/lib/view-switch.js +64 -0
- package/dist/package.js +1 -1
- package/dist/studio.css +1 -1
- package/package.json +4 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PREVIEW_PAUSED_ATTRIBUTE } from "../../core/lib/previewPaused.js";
|
|
2
|
-
import { EMPTY_PREVIEW_DOCUMENT, isSiteStyle } from "../preview/components/previewStyles.js";
|
|
2
|
+
import { EMPTY_PREVIEW_DOCUMENT, isSiteStyle, restyle } from "../preview/components/previewStyles.js";
|
|
3
3
|
|
|
4
4
|
//#region src/features/canvas/canvasFrameDocument.ts
|
|
5
5
|
/** Freezes CSS animations, including ones that start while the frame is paused. */
|
|
@@ -167,6 +167,29 @@ function createCanvasDocument(previewDocument, href) {
|
|
|
167
167
|
return `<!doctype html>${doc.documentElement.outerHTML}`;
|
|
168
168
|
}
|
|
169
169
|
/**
|
|
170
|
+
* Brings the document a Canvas frame loaded up to `canvasDocument`, which `createCanvasDocument`
|
|
171
|
+
* built for the same frame since, without loading it again: the frame keeps showing its page
|
|
172
|
+
* while another draft or locale's takes its place. Its links resolve against the new base, and
|
|
173
|
+
* it takes the new stylesheets, language and direction.
|
|
174
|
+
*/
|
|
175
|
+
function refreshCanvasDocument(frame, canvasDocument) {
|
|
176
|
+
const doc = frame.document;
|
|
177
|
+
const next = new DOMParser().parseFromString(canvasDocument, "text/html");
|
|
178
|
+
const href = next.querySelector("base")?.getAttribute("href");
|
|
179
|
+
const base = doc.querySelector("base");
|
|
180
|
+
if (href && base && base.getAttribute("href") !== href) base.setAttribute("href", href);
|
|
181
|
+
syncAttributes(doc.documentElement, next.documentElement);
|
|
182
|
+
syncAttributes(doc.body, next.body);
|
|
183
|
+
restyle(frame, canvasDocument);
|
|
184
|
+
}
|
|
185
|
+
/** Attributes of a Canvas frame's root and body the Canvas writes while it shows the frame. */
|
|
186
|
+
const CANVAS_ATTRIBUTES = /* @__PURE__ */ new Set(["style", PREVIEW_PAUSED_ATTRIBUTE]);
|
|
187
|
+
/** Gives `element` the attributes of `from`, but those the Canvas writes. */
|
|
188
|
+
function syncAttributes(element, from) {
|
|
189
|
+
for (const name of element.getAttributeNames()) if (!CANVAS_ATTRIBUTES.has(name) && !from.hasAttribute(name)) element.removeAttribute(name);
|
|
190
|
+
for (const { name, value } of from.attributes) if (!CANVAS_ATTRIBUTES.has(name) && element.getAttribute(name) !== value) element.setAttribute(name, value);
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
170
193
|
* Give a loaded document what `createCanvasDocument` builds into a Canvas frame's,
|
|
171
194
|
* for as long as it shows in the Canvas: no swipe navigation, CSS animations that
|
|
172
195
|
* pause with the frame, and a page as tall as its content. Returns how to undo
|
|
@@ -367,4 +390,4 @@ function observeCanvasDocument(iframe, root, viewportHeight, suspended = () => f
|
|
|
367
390
|
}
|
|
368
391
|
|
|
369
392
|
//#endregion
|
|
370
|
-
export { adaptCanvasStyleSheets, adoptCanvasDocument, canvasPageHref, canvasSeamCover, createCanvasDocument, logicalViewportValue, measureCanvasDocument, observeCanvasDocument, pauseCanvasDocument };
|
|
393
|
+
export { adaptCanvasStyleSheets, adoptCanvasDocument, canvasPageHref, canvasSeamCover, createCanvasDocument, logicalViewportValue, measureCanvasDocument, observeCanvasDocument, pauseCanvasDocument, refreshCanvasDocument };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NavigationProvider } from "../navigation/navigation.js";
|
|
2
2
|
import { FrameContext } from "../preview/components/Frame.js";
|
|
3
|
-
import { createCanvasDocument, observeCanvasDocument, pauseCanvasDocument } from "./canvasFrameDocument.js";
|
|
3
|
+
import { createCanvasDocument, observeCanvasDocument, pauseCanvasDocument, refreshCanvasDocument } from "./canvasFrameDocument.js";
|
|
4
4
|
import { useCanvasFrameInput } from "./useCanvasFrameInput.js";
|
|
5
5
|
import { c } from "react/compiler-runtime";
|
|
6
6
|
import * as React from "react";
|
|
@@ -28,9 +28,12 @@ function useCanvasFrame({ previewDocument, href, width, viewportHeight, mode })
|
|
|
28
28
|
const [failure, setFailure] = React.useState(null);
|
|
29
29
|
const live = mode === "live";
|
|
30
30
|
const resting = mode === "resting";
|
|
31
|
+
const frameWindow = React.useRef(null);
|
|
31
32
|
React.useEffect(() => {
|
|
32
33
|
try {
|
|
33
|
-
|
|
34
|
+
const built = createCanvasDocument(previewDocument, href);
|
|
35
|
+
if (frameWindow.current && previewDocument) return refreshCanvasDocument(frameWindow.current, built);
|
|
36
|
+
setSrcDoc(built);
|
|
34
37
|
} catch (error) {
|
|
35
38
|
setFailure(toError(error));
|
|
36
39
|
}
|
|
@@ -75,6 +78,7 @@ function useCanvasFrame({ previewDocument, href, width, viewportHeight, mode })
|
|
|
75
78
|
if (!root) throw new Error("The page preview document has no content root.");
|
|
76
79
|
if (root === mount) return;
|
|
77
80
|
root.replaceChildren();
|
|
81
|
+
frameWindow.current = root.ownerDocument.defaultView;
|
|
78
82
|
setMount(root);
|
|
79
83
|
setIframe(loaded);
|
|
80
84
|
} catch (error) {
|
|
@@ -13,14 +13,23 @@ const EMPTY_PREVIEW_DOCUMENT = "<!doctype html><html><head></head><body><div id=
|
|
|
13
13
|
*/
|
|
14
14
|
const SITE_STYLESHEETS = "link[rel~=\"stylesheet\"], style";
|
|
15
15
|
const siteStylesheetsOf = (head) => Array.from(head.querySelectorAll(SITE_STYLESHEETS)).filter((element) => element.parentElement === head && isSiteStyle(element) && !element.hasAttribute("data-precedence"));
|
|
16
|
+
/** The attributes of a site document's root that say how its page reads: its language and direction. */
|
|
17
|
+
const ROOT_ATTRIBUTES = ["lang", "dir"];
|
|
16
18
|
/**
|
|
17
19
|
* Gives a frame's document the site stylesheets of `html`, a site document: the ones it no
|
|
18
|
-
* longer has go, and its new ones are added, the rest of the frame left as it is.
|
|
20
|
+
* longer has go, and its new ones are added, the rest of the frame left as it is. Its root takes
|
|
21
|
+
* the document's language and direction, as a page in another locale has its own.
|
|
19
22
|
*/
|
|
20
23
|
function restyle(frame, html) {
|
|
21
24
|
const doc = frame.document;
|
|
22
25
|
const { DOMParser } = frame;
|
|
23
|
-
const
|
|
26
|
+
const parsed = new DOMParser().parseFromString(html, "text/html");
|
|
27
|
+
for (const name of ROOT_ATTRIBUTES) {
|
|
28
|
+
const value = parsed.documentElement.getAttribute(name);
|
|
29
|
+
if (value === null) doc.documentElement.removeAttribute(name);
|
|
30
|
+
else if (doc.documentElement.getAttribute(name) !== value) doc.documentElement.setAttribute(name, value);
|
|
31
|
+
}
|
|
32
|
+
const wanted = siteStylesheetsOf(parsed.head);
|
|
24
33
|
const held = siteStylesheetsOf(doc.head);
|
|
25
34
|
const wantedMarkup = new Set(wanted.map((element) => element.outerHTML));
|
|
26
35
|
const heldMarkup = new Set(held.map((element) => element.outerHTML));
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { useDraftScope } from "../../lib/draft-scope.js";
|
|
2
|
-
import { AuthContext, useAuthActions } from "../../lib/auth.js";
|
|
2
|
+
import { AuthContext, signedInUserId, useAuthActions } from "../../lib/auth.js";
|
|
3
3
|
import { reads, useReadQuery, useStudioCache } from "../../lib/studio-reads.js";
|
|
4
4
|
import { RevisionsContext, createRevisions } from "../../lib/revisions.js";
|
|
5
5
|
import { useAdminShortcuts } from "./useAdminShortcuts.js";
|
|
6
6
|
import { useApplyTheme, useThemeActions } from "../studio/useTheme.js";
|
|
7
7
|
import { usePreviewPagesActions, useShowCanvasAction } from "../preview/CamoxPreview.js";
|
|
8
8
|
import { useProjectRoom } from "../../lib/use-project-room.js";
|
|
9
|
+
import { useLeaveDraft } from "../studio/viewSwitch.js";
|
|
9
10
|
import { useNavbarActions } from "../studio/components/Navbar.js";
|
|
10
11
|
import { draftNoticeMessage } from "../studio/draftNotice.js";
|
|
11
12
|
import { CommandPalette, useCommandPaletteActions } from "./components/CommandPalette.js";
|
|
@@ -17,7 +18,7 @@ import studioCssUrl from "virtual:camox-studio-css";
|
|
|
17
18
|
|
|
18
19
|
//#region src/features/provider/AuthenticatedCamoxProvider.tsx
|
|
19
20
|
function AuthenticatedCamoxProvider(t0) {
|
|
20
|
-
const $ = c(
|
|
21
|
+
const $ = c(20);
|
|
21
22
|
const { children } = t0;
|
|
22
23
|
useAdminShortcuts();
|
|
23
24
|
useCommandPaletteActions();
|
|
@@ -26,7 +27,7 @@ function AuthenticatedCamoxProvider(t0) {
|
|
|
26
27
|
useNavbarActions();
|
|
27
28
|
usePreviewPagesActions();
|
|
28
29
|
useShowCanvasAction();
|
|
29
|
-
const { apiUrl, projectUuid } = React.useContext(AuthContext);
|
|
30
|
+
const { apiUrl, projectUuid, authClient } = React.useContext(AuthContext);
|
|
30
31
|
let t1;
|
|
31
32
|
if ($[0] !== projectUuid) {
|
|
32
33
|
t1 = reads.project({ projectUuid });
|
|
@@ -50,49 +51,53 @@ function AuthenticatedCamoxProvider(t0) {
|
|
|
50
51
|
}
|
|
51
52
|
React.useEffect(t2, t3);
|
|
52
53
|
const [revisions] = React.useState(createRevisions);
|
|
54
|
+
const leaveDraft = useLeaveDraft();
|
|
53
55
|
let t4;
|
|
54
|
-
if ($[5] !==
|
|
56
|
+
if ($[5] !== authClient || $[6] !== draftScope || $[7] !== leaveDraft || $[8] !== revisions) {
|
|
55
57
|
let t5;
|
|
56
|
-
if ($[
|
|
58
|
+
if ($[10] !== revisions) {
|
|
57
59
|
t5 = (revision) => revisions.announce(revision);
|
|
58
|
-
$[
|
|
59
|
-
$[
|
|
60
|
-
} else t5 = $[
|
|
60
|
+
$[10] = revisions;
|
|
61
|
+
$[11] = t5;
|
|
62
|
+
} else t5 = $[11];
|
|
61
63
|
t4 = {
|
|
62
64
|
onDraftEnded(ended) {
|
|
63
65
|
if (ended.draftId !== draftScope.current()) return;
|
|
66
|
+
if (ended.endedBy.id === signedInUserId(authClient)) return leaveDraft(ended);
|
|
64
67
|
draftScope.leave(ended, { notice: true });
|
|
65
68
|
},
|
|
66
69
|
onRevision: t5
|
|
67
70
|
};
|
|
68
|
-
$[5] =
|
|
69
|
-
$[6] =
|
|
70
|
-
$[7] =
|
|
71
|
-
|
|
71
|
+
$[5] = authClient;
|
|
72
|
+
$[6] = draftScope;
|
|
73
|
+
$[7] = leaveDraft;
|
|
74
|
+
$[8] = revisions;
|
|
75
|
+
$[9] = t4;
|
|
76
|
+
} else t4 = $[9];
|
|
72
77
|
useProjectRoom(apiUrl, project?.id, studioCache, t4);
|
|
73
78
|
const { resolvedTheme } = useApplyTheme();
|
|
74
79
|
let t5;
|
|
75
|
-
if ($[
|
|
80
|
+
if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
|
|
76
81
|
t5 = /* @__PURE__ */ jsx("link", {
|
|
77
82
|
rel: "stylesheet",
|
|
78
83
|
href: studioCssUrl,
|
|
79
84
|
"data-camox-studio": true
|
|
80
85
|
});
|
|
81
|
-
$[
|
|
82
|
-
} else t5 = $[
|
|
86
|
+
$[12] = t5;
|
|
87
|
+
} else t5 = $[12];
|
|
83
88
|
let t6;
|
|
84
|
-
if ($[
|
|
89
|
+
if ($[13] !== resolvedTheme) {
|
|
85
90
|
t6 = /* @__PURE__ */ jsx(Toaster, { theme: resolvedTheme });
|
|
86
|
-
$[
|
|
87
|
-
$[
|
|
88
|
-
} else t6 = $[
|
|
91
|
+
$[13] = resolvedTheme;
|
|
92
|
+
$[14] = t6;
|
|
93
|
+
} else t6 = $[14];
|
|
89
94
|
let t7;
|
|
90
|
-
if ($[
|
|
95
|
+
if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
|
|
91
96
|
t7 = /* @__PURE__ */ jsx(CommandPalette, {});
|
|
92
|
-
$[
|
|
93
|
-
} else t7 = $[
|
|
97
|
+
$[15] = t7;
|
|
98
|
+
} else t7 = $[15];
|
|
94
99
|
let t8;
|
|
95
|
-
if ($[
|
|
100
|
+
if ($[16] !== children || $[17] !== revisions || $[18] !== t6) {
|
|
96
101
|
t8 = /* @__PURE__ */ jsxs(RevisionsContext, {
|
|
97
102
|
value: revisions,
|
|
98
103
|
children: [
|
|
@@ -102,11 +107,11 @@ function AuthenticatedCamoxProvider(t0) {
|
|
|
102
107
|
t7
|
|
103
108
|
]
|
|
104
109
|
});
|
|
105
|
-
$[
|
|
106
|
-
$[
|
|
107
|
-
$[
|
|
108
|
-
$[
|
|
109
|
-
} else t8 = $[
|
|
110
|
+
$[16] = children;
|
|
111
|
+
$[17] = revisions;
|
|
112
|
+
$[18] = t6;
|
|
113
|
+
$[19] = t8;
|
|
114
|
+
} else t8 = $[19];
|
|
110
115
|
return t8;
|
|
111
116
|
}
|
|
112
117
|
function _temp(notice) {
|