camox 0.40.0 → 0.41.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.
- package/dist/components/PlatformLabel.js +62 -0
- package/dist/core/components/lexical/GradientNode.js +126 -0
- package/dist/core/components/lexical/InlineLexicalEditor.js +37 -56
- package/dist/core/components/lexical/InlineStylesPlugin.js +183 -0
- package/dist/core/components/lexical/SelectionBroadcaster.js +49 -46
- package/dist/core/components/lexical/SidebarLexicalEditor.js +197 -151
- package/dist/core/components/lexical/editorConfig.js +25 -7
- package/dist/core/components/lexical/selectTextLink.js +21 -0
- package/dist/core/createApp.d.ts +30 -17
- package/dist/core/createApp.js +14 -3
- package/dist/core/createBlock.d.ts +2 -2
- package/dist/core/createBlock.js +17 -28
- package/dist/core/createLayout.d.ts +48 -4
- package/dist/core/createLayout.js +51 -23
- package/dist/core/derivedRoutes.js +36 -0
- package/dist/core/editing/BlockEditingRuntime.js +4 -4
- package/dist/core/editing/CompleteBlockEditingRuntime.js +5 -5
- package/dist/core/editing/createEditableBlock.d.ts +9 -8
- package/dist/core/editing/createEditableBlock.js +265 -403
- package/dist/core/hooks/useIsEditable.js +4 -7
- package/dist/core/hooks/useRequireDraftSource.js +7 -11
- package/dist/core/lib/lexicalReact.d.ts +1 -26
- package/dist/core/lib/lexicalReact.js +46 -60
- package/dist/core/lib/lexicalState.js +164 -81
- package/dist/core/lib/modifierFormats.js +4 -15
- package/dist/core/lib/textStyles.d.ts +27 -0
- package/dist/core/lib/textStyles.js +47 -0
- package/dist/features/navigation/navigation.d.ts +2 -0
- package/dist/features/navigation/navigation.js +51 -46
- package/dist/features/page/DerivedPageContent.js +61 -0
- package/dist/features/page/PublishedPageContent.js +52 -83
- package/dist/features/page/SharedLayoutContent.js +66 -0
- package/dist/features/preview/CamoxPreview.d.ts +16 -1
- package/dist/features/preview/CamoxPreview.js +246 -290
- package/dist/features/preview/DerivedPreview.js +134 -0
- package/dist/features/preview/EditablePageExperience.js +25 -8
- package/dist/features/preview/components/AddBlockSidebar.js +43 -33
- package/dist/features/preview/components/AssetLightbox.js +1 -1
- package/dist/features/preview/components/BlockActionsPopover.js +8 -8
- package/dist/features/preview/components/BlockThumbnail.js +192 -0
- package/dist/features/preview/components/CreatePageModal.js +123 -115
- package/dist/features/preview/components/DerivedLayoutDialog.js +100 -0
- package/dist/features/preview/components/DerivedLayoutSidebar.d.ts +5 -0
- package/dist/features/preview/components/DerivedLayoutSidebar.js +160 -0
- package/dist/features/preview/components/DerivedPageInfoSidebar.js +57 -0
- package/dist/features/preview/components/FieldToolbar.js +42 -20
- package/dist/features/preview/components/Frame.js +133 -140
- package/dist/features/preview/components/LeftSidebar.js +42 -38
- package/dist/features/preview/components/LinkFieldEditor.js +3 -4
- package/dist/features/preview/components/MobilePreviewDrawer.js +4 -4
- package/dist/features/preview/components/Overlays.js +59 -47
- package/dist/features/preview/components/PageEditorSidebar.js +194 -203
- package/dist/features/preview/components/PageInfoSidebar.js +63 -55
- package/dist/features/preview/components/PageNavigatorSidebar.js +34 -483
- package/dist/features/preview/components/PagePicker.js +205 -153
- package/dist/features/preview/components/PageTree.js +366 -340
- package/dist/features/preview/components/PreviewActivation.js +78 -0
- package/dist/features/preview/components/PreviewPanel.js +98 -68
- package/dist/features/preview/components/PreviewToolbar.js +224 -241
- package/dist/features/preview/components/PreviewToolbarSpacer.js +43 -0
- package/dist/features/preview/components/PublicationRow.js +425 -0
- package/dist/features/preview/components/PublishDialog.js +180 -97
- package/dist/features/preview/components/RightSidebar.js +19 -34
- package/dist/features/preview/components/previewStyles.js +8 -0
- package/dist/features/preview/components/useUpdateBlockPosition.js +7 -13
- package/dist/features/preview/previewConstants.js +8 -0
- package/dist/features/preview/previewStore.js +18 -39
- package/dist/features/preview/publication.js +71 -0
- package/dist/features/provider/AuthenticatedCamoxProvider.js +2 -1
- package/dist/features/provider/CoreCamoxProvider.js +11 -2
- package/dist/features/provider/LocalhostPreviewProvider.js +6 -7
- package/dist/features/provider/useAdminShortcuts.js +5 -4
- package/dist/features/routes/pageRuntime.d.ts +10 -0
- package/dist/features/routes/pageRuntime.js +7 -9
- package/dist/features/runtime/PreviewDocumentContext.js +7 -0
- package/dist/features/runtime/RuntimeChrome.js +149 -0
- package/dist/features/runtime/SharedChromeContext.js +7 -0
- package/dist/features/runtime/navigationRequest.js +21 -0
- package/dist/features/runtime/navigationTarget.js +23 -0
- package/dist/features/runtime/pageApp.js +196 -121
- package/dist/features/runtime/pageNavigation.js +79 -130
- package/dist/features/runtime/runtime.d.ts +11 -0
- package/dist/features/runtime/runtime.js +183 -47
- package/dist/features/runtime/studioApp.d.ts +2 -11
- package/dist/features/runtime/studioApp.js +14 -177
- package/dist/features/studio/CamoxStudio.js +27 -13
- package/dist/features/studio/components/Navbar.js +80 -74
- package/dist/features/studio/components/UserButton.js +4 -4
- package/dist/features/studio/studioTheme.js +25 -0
- package/dist/features/studio/useTheme.js +94 -109
- package/dist/features/vite/appGeneration.js +12 -3
- package/dist/features/vite/definitionsSync.js +4 -2
- package/dist/features/vite/layoutGeneration.js +38 -0
- package/dist/features/vite/runtimeDev.js +3 -1
- package/dist/lib/auth.js +15 -13
- package/dist/lib/normalized-data.js +4 -4
- package/dist/lib/platform.js +13 -0
- package/dist/lib/utils.js +90 -38
- package/dist/studio-overlays.css +5 -40
- package/dist/studio.css +1 -1
- package/package.json +8 -4
- package/skills/camox/SKILL.md +2 -0
- package/skills/camox/references/block-definitions.md +31 -12
- package/skills/camox/references/layout-definitions.md +2 -0
- package/dist/core/lib/modifiers.js +0 -24
- package/dist/features/preview/components/DraftSwitchDialog.js +0 -66
- package/dist/features/preview/previewQueryFns.js +0 -23
- package/dist/features/runtime/studioNavigation.js +0 -120
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { PLATFORM_LABEL_CSS, bootstrapPlatform } from "../lib/platform.js";
|
|
2
|
+
import { c } from "react/compiler-runtime";
|
|
3
|
+
import { useLayoutEffect } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
|
|
6
|
+
//#region src/components/PlatformLabel.tsx
|
|
7
|
+
/** Both variants exist during SSR; the head bootstrap selects one before paint. */
|
|
8
|
+
function PlatformLabel(t0) {
|
|
9
|
+
const $ = c(10);
|
|
10
|
+
if ($[0] !== "aae56b4e6a643d5e25aadf2956d9637046ab5dac1ced5206ee77f664834bbaa3") {
|
|
11
|
+
for (let $i = 0; $i < 10; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
12
|
+
$[0] = "aae56b4e6a643d5e25aadf2956d9637046ab5dac1ced5206ee77f664834bbaa3";
|
|
13
|
+
}
|
|
14
|
+
const { mac, other } = t0;
|
|
15
|
+
let t1;
|
|
16
|
+
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
|
17
|
+
t1 = [];
|
|
18
|
+
$[1] = t1;
|
|
19
|
+
} else t1 = $[1];
|
|
20
|
+
useLayoutEffect(bootstrapPlatform, t1);
|
|
21
|
+
let t2;
|
|
22
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
23
|
+
t2 = /* @__PURE__ */ jsx("style", {
|
|
24
|
+
"data-camox-studio": true,
|
|
25
|
+
children: PLATFORM_LABEL_CSS
|
|
26
|
+
});
|
|
27
|
+
$[2] = t2;
|
|
28
|
+
} else t2 = $[2];
|
|
29
|
+
let t3;
|
|
30
|
+
if ($[3] !== mac) {
|
|
31
|
+
t3 = /* @__PURE__ */ jsx("span", {
|
|
32
|
+
className: "camox-platform-mac",
|
|
33
|
+
children: mac
|
|
34
|
+
});
|
|
35
|
+
$[3] = mac;
|
|
36
|
+
$[4] = t3;
|
|
37
|
+
} else t3 = $[4];
|
|
38
|
+
let t4;
|
|
39
|
+
if ($[5] !== other) {
|
|
40
|
+
t4 = /* @__PURE__ */ jsx("span", {
|
|
41
|
+
className: "camox-platform-other",
|
|
42
|
+
children: other
|
|
43
|
+
});
|
|
44
|
+
$[5] = other;
|
|
45
|
+
$[6] = t4;
|
|
46
|
+
} else t4 = $[6];
|
|
47
|
+
let t5;
|
|
48
|
+
if ($[7] !== t3 || $[8] !== t4) {
|
|
49
|
+
t5 = /* @__PURE__ */ jsxs("span", { children: [
|
|
50
|
+
t2,
|
|
51
|
+
t3,
|
|
52
|
+
t4
|
|
53
|
+
] });
|
|
54
|
+
$[7] = t3;
|
|
55
|
+
$[8] = t4;
|
|
56
|
+
$[9] = t5;
|
|
57
|
+
} else t5 = $[9];
|
|
58
|
+
return t5;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//#endregion
|
|
62
|
+
export { PlatformLabel };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { $applyNodeReplacement, $copyNode, $getSelection, $isElementNode, $isRangeSelection, $isTextNode, ElementNode } from "lexical";
|
|
2
|
+
|
|
3
|
+
//#region src/core/components/lexical/GradientNode.ts
|
|
4
|
+
var GradientNode = class GradientNode extends ElementNode {
|
|
5
|
+
static getType() {
|
|
6
|
+
return "gradient";
|
|
7
|
+
}
|
|
8
|
+
static clone(node) {
|
|
9
|
+
return new GradientNode(node.__key);
|
|
10
|
+
}
|
|
11
|
+
static importJSON(value) {
|
|
12
|
+
return $createGradientNode().updateFromJSON(value);
|
|
13
|
+
}
|
|
14
|
+
static importDOM() {
|
|
15
|
+
return { span: (element) => element.hasAttribute("data-camox-gradient") ? {
|
|
16
|
+
conversion: () => ({ node: $createGradientNode() }),
|
|
17
|
+
priority: 1
|
|
18
|
+
} : null };
|
|
19
|
+
}
|
|
20
|
+
createDOM() {
|
|
21
|
+
const span = document.createElement("span");
|
|
22
|
+
span.dataset.camoxGradient = "";
|
|
23
|
+
return span;
|
|
24
|
+
}
|
|
25
|
+
updateDOM() {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
isInline() {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
canBeEmpty() {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
canInsertTextBefore() {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
canInsertTextAfter() {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
function $createGradientNode() {
|
|
42
|
+
return $applyNodeReplacement(new GradientNode());
|
|
43
|
+
}
|
|
44
|
+
function $getGradient(node) {
|
|
45
|
+
let current = node;
|
|
46
|
+
while (current) {
|
|
47
|
+
if (current instanceof GradientNode) return current;
|
|
48
|
+
current = current.getParent();
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
function $selectionHasGradient() {
|
|
53
|
+
const selection = $getSelection();
|
|
54
|
+
if (!$isRangeSelection(selection)) return false;
|
|
55
|
+
if (selection.isCollapsed()) return !!$getGradient(selection.anchor.getNode());
|
|
56
|
+
const texts = selection.getNodes().filter($isTextNode);
|
|
57
|
+
return texts.length > 0 && texts.every((node) => !!$getGradient(node));
|
|
58
|
+
}
|
|
59
|
+
/** Isolate a selected leaf without removing gradient from its unselected siblings. */
|
|
60
|
+
function $removeGradientFrom(node) {
|
|
61
|
+
const gradient = $getGradient(node);
|
|
62
|
+
if (!gradient) return;
|
|
63
|
+
let branch = node;
|
|
64
|
+
while (branch.getKey() !== gradient.getKey()) {
|
|
65
|
+
const parent = branch.getParentOrThrow();
|
|
66
|
+
const before = branch.getPreviousSiblings();
|
|
67
|
+
const after = branch.getNextSiblings();
|
|
68
|
+
if (before.length) {
|
|
69
|
+
const clone = $copyNode(parent);
|
|
70
|
+
parent.insertBefore(clone);
|
|
71
|
+
clone.append(...before);
|
|
72
|
+
}
|
|
73
|
+
if (after.length) {
|
|
74
|
+
const clone = $copyNode(parent);
|
|
75
|
+
parent.insertAfter(clone);
|
|
76
|
+
clone.append(...after);
|
|
77
|
+
}
|
|
78
|
+
branch = parent;
|
|
79
|
+
}
|
|
80
|
+
for (const child of gradient.getChildren()) gradient.insertBefore(child);
|
|
81
|
+
gradient.remove();
|
|
82
|
+
}
|
|
83
|
+
function $toggleGradient() {
|
|
84
|
+
const selection = $getSelection();
|
|
85
|
+
if (!$isRangeSelection(selection) || selection.isCollapsed()) return;
|
|
86
|
+
const remove = $selectionHasGradient();
|
|
87
|
+
const nodes = selection.extract().filter((node) => $isTextNode(node) || node.getType() === "linebreak");
|
|
88
|
+
for (const node of nodes) {
|
|
89
|
+
if (remove) {
|
|
90
|
+
$removeGradientFrom(node);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if ($getGradient(node)) continue;
|
|
94
|
+
const previous = node.getPreviousSibling();
|
|
95
|
+
if (previous instanceof GradientNode) {
|
|
96
|
+
previous.append(node);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const gradient = $createGradientNode();
|
|
100
|
+
node.insertBefore(gradient);
|
|
101
|
+
gradient.append(node);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Keep one background across adjacent runs, including after formatting changes. */
|
|
105
|
+
function $normalizeGradient(node) {
|
|
106
|
+
const parent = node.getParent();
|
|
107
|
+
if (parent instanceof GradientNode) {
|
|
108
|
+
for (const child of node.getChildren()) node.insertBefore(child);
|
|
109
|
+
node.remove();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const next = node.getNextSibling();
|
|
113
|
+
if (next instanceof GradientNode) {
|
|
114
|
+
node.append(...next.getChildren());
|
|
115
|
+
next.remove();
|
|
116
|
+
}
|
|
117
|
+
if ($isElementNode(parent) && parent.getType() === "link" && parent.getChildrenSize() === 1) {
|
|
118
|
+
const children = node.getChildren();
|
|
119
|
+
parent.insertBefore(node);
|
|
120
|
+
parent.append(...children);
|
|
121
|
+
node.append(parent);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
//#endregion
|
|
126
|
+
export { $normalizeGradient, $selectionHasGradient, $toggleGradient, GradientNode };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { isHttpTextLinkTarget } from "../../lib/textLinks.js";
|
|
2
|
-
import { useFrame } from "../../../features/preview/components/Frame.js";
|
|
3
2
|
import { lexicalStateToMarkdown } from "../../lib/lexicalState.js";
|
|
3
|
+
import { useFrame } from "../../../features/preview/components/Frame.js";
|
|
4
4
|
import { createEditorConfig, normalizeLexicalState } from "./editorConfig.js";
|
|
5
|
+
import { InlineStylesPlugin } from "./InlineStylesPlugin.js";
|
|
5
6
|
import { InlineContentEditable } from "./InlineContentEditable.js";
|
|
6
7
|
import { SelectionBroadcaster } from "./SelectionBroadcaster.js";
|
|
7
8
|
import { c } from "react/compiler-runtime";
|
|
@@ -19,9 +20,9 @@ import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_LOW, INSERT_LINE_BRE
|
|
|
19
20
|
//#region src/core/components/lexical/InlineLexicalEditor.tsx
|
|
20
21
|
function ExternalStateSync(t0) {
|
|
21
22
|
const $ = c(8);
|
|
22
|
-
if ($[0] !== "
|
|
23
|
+
if ($[0] !== "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b") {
|
|
23
24
|
for (let $i = 0; $i < 8; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
24
|
-
$[0] = "
|
|
25
|
+
$[0] = "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b";
|
|
25
26
|
}
|
|
26
27
|
const { externalState } = t0;
|
|
27
28
|
const [editor] = useLexicalComposerContext();
|
|
@@ -78,9 +79,9 @@ function ExternalStateSync(t0) {
|
|
|
78
79
|
}
|
|
79
80
|
function EscapeHandler() {
|
|
80
81
|
const $ = c(4);
|
|
81
|
-
if ($[0] !== "
|
|
82
|
+
if ($[0] !== "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b") {
|
|
82
83
|
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
83
|
-
$[0] = "
|
|
84
|
+
$[0] = "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b";
|
|
84
85
|
}
|
|
85
86
|
const [editor] = useLexicalComposerContext();
|
|
86
87
|
let t0;
|
|
@@ -103,9 +104,9 @@ function EscapeHandler() {
|
|
|
103
104
|
}
|
|
104
105
|
function EnterAsLineBreakHandler() {
|
|
105
106
|
const $ = c(4);
|
|
106
|
-
if ($[0] !== "
|
|
107
|
+
if ($[0] !== "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b") {
|
|
107
108
|
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
108
|
-
$[0] = "
|
|
109
|
+
$[0] = "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b";
|
|
109
110
|
}
|
|
110
111
|
const [editor] = useLexicalComposerContext();
|
|
111
112
|
let t0;
|
|
@@ -129,9 +130,9 @@ function EnterAsLineBreakHandler() {
|
|
|
129
130
|
}
|
|
130
131
|
function PasteUrlAsLinkHandler() {
|
|
131
132
|
const $ = c(4);
|
|
132
|
-
if ($[0] !== "
|
|
133
|
+
if ($[0] !== "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b") {
|
|
133
134
|
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
134
|
-
$[0] = "
|
|
135
|
+
$[0] = "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b";
|
|
135
136
|
}
|
|
136
137
|
const [editor] = useLexicalComposerContext();
|
|
137
138
|
let t0;
|
|
@@ -160,9 +161,9 @@ function PasteUrlAsLinkHandler() {
|
|
|
160
161
|
}
|
|
161
162
|
function FocusBlurHandler(t0) {
|
|
162
163
|
const $ = c(6);
|
|
163
|
-
if ($[0] !== "
|
|
164
|
+
if ($[0] !== "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b") {
|
|
164
165
|
for (let $i = 0; $i < 6; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
165
|
-
$[0] = "
|
|
166
|
+
$[0] = "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b";
|
|
166
167
|
}
|
|
167
168
|
const { onFocus, onBlur } = t0;
|
|
168
169
|
const [editor] = useLexicalComposerContext();
|
|
@@ -195,40 +196,19 @@ function FocusBlurHandler(t0) {
|
|
|
195
196
|
React.useEffect(t1, t2);
|
|
196
197
|
return null;
|
|
197
198
|
}
|
|
198
|
-
function
|
|
199
|
-
const $ = c(4);
|
|
200
|
-
if ($[0] !== "c4ca5d751d9d53a7ad565939bb5b4c4c82ea51c5bc23aeca481e23d8515243a2") {
|
|
201
|
-
for (let $i = 0; $i < 4; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
202
|
-
$[0] = "c4ca5d751d9d53a7ad565939bb5b4c4c82ea51c5bc23aeca481e23d8515243a2";
|
|
203
|
-
}
|
|
204
|
-
const [editor] = useLexicalComposerContext();
|
|
205
|
-
let t0;
|
|
206
|
-
let t1;
|
|
207
|
-
if ($[1] !== editor) {
|
|
208
|
-
t0 = () => editor.registerRootListener(_temp);
|
|
209
|
-
t1 = [editor];
|
|
210
|
-
$[1] = editor;
|
|
211
|
-
$[2] = t0;
|
|
212
|
-
$[3] = t1;
|
|
213
|
-
} else {
|
|
214
|
-
t0 = $[2];
|
|
215
|
-
t1 = $[3];
|
|
216
|
-
}
|
|
217
|
-
React.useEffect(t0, t1);
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
function _temp(root) {
|
|
221
|
-
if (!root) return;
|
|
222
|
-
const doc = root.ownerDocument;
|
|
223
|
-
if (doc.getElementById("camox-editable-text-link-styles")) return;
|
|
224
|
-
const style = doc.createElement("style");
|
|
225
|
-
style.id = "camox-editable-text-link-styles";
|
|
226
|
-
style.textContent = ".camox-text-link { text-decoration-line: underline; }";
|
|
227
|
-
doc.head.appendChild(style);
|
|
228
|
-
}
|
|
229
|
-
function InlineLexicalEditor({ initialState, externalState, onChange, onFocus, onBlur }) {
|
|
199
|
+
function InlineLexicalEditor({ initialState, externalState, onChange, onFocus, onBlur, textStyle, linkStyle, pages, fallbackHref }) {
|
|
230
200
|
const { window: iframeWindow } = useFrame();
|
|
231
201
|
const timerRef = React.useRef(null);
|
|
202
|
+
const pendingMarkdownRef = React.useRef(null);
|
|
203
|
+
const onChangeRef = React.useRef(onChange);
|
|
204
|
+
onChangeRef.current = onChange;
|
|
205
|
+
const flushChange = React.useCallback(() => {
|
|
206
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
207
|
+
timerRef.current = null;
|
|
208
|
+
const markdown = pendingMarkdownRef.current;
|
|
209
|
+
pendingMarkdownRef.current = null;
|
|
210
|
+
if (markdown !== null) onChangeRef.current(markdown);
|
|
211
|
+
}, []);
|
|
232
212
|
const isFocusedRef = React.useRef(false);
|
|
233
213
|
const editedDuringFocusRef = React.useRef(false);
|
|
234
214
|
const config = React.useMemo(() => createEditorConfig(initialState), []);
|
|
@@ -236,26 +216,22 @@ function InlineLexicalEditor({ initialState, externalState, onChange, onFocus, o
|
|
|
236
216
|
if (!isFocusedRef.current) return;
|
|
237
217
|
editedDuringFocusRef.current = true;
|
|
238
218
|
if (timerRef.current) clearTimeout(timerRef.current);
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}, [onChange]);
|
|
219
|
+
pendingMarkdownRef.current = lexicalStateToMarkdown(editorState.toJSON());
|
|
220
|
+
timerRef.current = window.setTimeout(flushChange, 300);
|
|
221
|
+
}, [flushChange]);
|
|
243
222
|
const handleFocus = React.useCallback(() => {
|
|
244
223
|
isFocusedRef.current = true;
|
|
245
224
|
editedDuringFocusRef.current = false;
|
|
246
225
|
onFocus();
|
|
247
226
|
}, [onFocus]);
|
|
248
227
|
const handleBlur = React.useCallback(() => {
|
|
228
|
+
flushChange();
|
|
249
229
|
isFocusedRef.current = false;
|
|
250
230
|
const wasEdited = editedDuringFocusRef.current;
|
|
251
231
|
editedDuringFocusRef.current = false;
|
|
252
232
|
onBlur(wasEdited);
|
|
253
|
-
}, [onBlur]);
|
|
254
|
-
React.useEffect(() =>
|
|
255
|
-
return () => {
|
|
256
|
-
if (timerRef.current) clearTimeout(timerRef.current);
|
|
257
|
-
};
|
|
258
|
-
}, []);
|
|
233
|
+
}, [onBlur, flushChange]);
|
|
234
|
+
React.useEffect(() => flushChange, [flushChange]);
|
|
259
235
|
return /* @__PURE__ */ jsxs(LexicalComposer, {
|
|
260
236
|
initialConfig: config,
|
|
261
237
|
children: [
|
|
@@ -277,16 +253,21 @@ function InlineLexicalEditor({ initialState, externalState, onChange, onFocus, o
|
|
|
277
253
|
onFocus: handleFocus,
|
|
278
254
|
onBlur: handleBlur
|
|
279
255
|
}),
|
|
280
|
-
/* @__PURE__ */ jsx(
|
|
256
|
+
/* @__PURE__ */ jsx(InlineStylesPlugin, {
|
|
257
|
+
textStyle,
|
|
258
|
+
linkStyle,
|
|
259
|
+
pages,
|
|
260
|
+
fallbackHref
|
|
261
|
+
}),
|
|
281
262
|
iframeWindow && /* @__PURE__ */ jsx(SelectionBroadcaster, { targetWindow: iframeWindow })
|
|
282
263
|
]
|
|
283
264
|
});
|
|
284
265
|
}
|
|
285
266
|
function LexicalErrorBoundary(t0) {
|
|
286
267
|
const $ = c(3);
|
|
287
|
-
if ($[0] !== "
|
|
268
|
+
if ($[0] !== "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b") {
|
|
288
269
|
for (let $i = 0; $i < 3; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
289
|
-
$[0] = "
|
|
270
|
+
$[0] = "b0541f4280871b1a808d1959e8ce88626b23577e7b86258a9337e3475a84264b";
|
|
290
271
|
}
|
|
291
272
|
const { children } = t0;
|
|
292
273
|
let t1;
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { getPageIdFromTextLinkTarget, isHttpTextLinkTarget, resolveTextLinkHref, shouldOpenTextLinkInNewTab } from "../../lib/textLinks.js";
|
|
2
|
+
import { getGradientStyle, getTextAppearance } from "../../lib/textStyles.js";
|
|
3
|
+
import { $normalizeGradient, GradientNode } from "./GradientNode.js";
|
|
4
|
+
import { c } from "react/compiler-runtime";
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { $isLinkNode } from "@lexical/link";
|
|
7
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
8
|
+
import { $getRoot, $isElementNode, $isTextNode } from "lexical";
|
|
9
|
+
|
|
10
|
+
//#region src/core/components/lexical/InlineStylesPlugin.tsx
|
|
11
|
+
const unitless = new Set([
|
|
12
|
+
"animationIterationCount",
|
|
13
|
+
"aspectRatio",
|
|
14
|
+
"borderImageOutset",
|
|
15
|
+
"borderImageSlice",
|
|
16
|
+
"borderImageWidth",
|
|
17
|
+
"boxFlex",
|
|
18
|
+
"boxFlexGroup",
|
|
19
|
+
"boxOrdinalGroup",
|
|
20
|
+
"columnCount",
|
|
21
|
+
"columns",
|
|
22
|
+
"fillOpacity",
|
|
23
|
+
"flex",
|
|
24
|
+
"flexGrow",
|
|
25
|
+
"flexPositive",
|
|
26
|
+
"flexShrink",
|
|
27
|
+
"flexNegative",
|
|
28
|
+
"flexOrder",
|
|
29
|
+
"fontWeight",
|
|
30
|
+
"gridArea",
|
|
31
|
+
"gridColumn",
|
|
32
|
+
"gridColumnEnd",
|
|
33
|
+
"gridColumnStart",
|
|
34
|
+
"gridColumnSpan",
|
|
35
|
+
"gridRow",
|
|
36
|
+
"gridRowEnd",
|
|
37
|
+
"gridRowStart",
|
|
38
|
+
"gridRowSpan",
|
|
39
|
+
"lineClamp",
|
|
40
|
+
"lineHeight",
|
|
41
|
+
"opacity",
|
|
42
|
+
"order",
|
|
43
|
+
"orphans",
|
|
44
|
+
"scale",
|
|
45
|
+
"floodOpacity",
|
|
46
|
+
"stopOpacity",
|
|
47
|
+
"strokeDasharray",
|
|
48
|
+
"strokeDashoffset",
|
|
49
|
+
"strokeMiterlimit",
|
|
50
|
+
"strokeOpacity",
|
|
51
|
+
"strokeWidth",
|
|
52
|
+
"tabSize",
|
|
53
|
+
"widows",
|
|
54
|
+
"zIndex",
|
|
55
|
+
"zoom"
|
|
56
|
+
]);
|
|
57
|
+
/** Only manages appearance attributes; Lexical retains ownership of the editable tree. */
|
|
58
|
+
function InlineStylesPlugin(options) {
|
|
59
|
+
const $ = c(13);
|
|
60
|
+
if ($[0] !== "9e9ec32bc10d3e8c9e669fba8eed46eaf4d41dffba75b558500fddddf9ab14e2") {
|
|
61
|
+
for (let $i = 0; $i < 13; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
62
|
+
$[0] = "9e9ec32bc10d3e8c9e669fba8eed46eaf4d41dffba75b558500fddddf9ab14e2";
|
|
63
|
+
}
|
|
64
|
+
const [editor] = useLexicalComposerContext();
|
|
65
|
+
let t0;
|
|
66
|
+
if ($[1] !== editor || $[2] !== options) {
|
|
67
|
+
t0 = () => {
|
|
68
|
+
const previous = /* @__PURE__ */ new Map();
|
|
69
|
+
const apply = function apply(dom, appearance) {
|
|
70
|
+
const old = previous.get(dom);
|
|
71
|
+
old?.classes.forEach((name) => dom.classList.remove(name));
|
|
72
|
+
old?.properties.forEach((name_0) => dom.style.removeProperty(name_0));
|
|
73
|
+
const classes = appearance.className?.split(/\s+/).filter(Boolean) ?? [];
|
|
74
|
+
classes.forEach((name_1) => dom.classList.add(name_1));
|
|
75
|
+
const properties = [];
|
|
76
|
+
for (const [key, value] of Object.entries(appearance.style ?? {})) {
|
|
77
|
+
if (value == null) continue;
|
|
78
|
+
const property = key.startsWith("--") ? key : key.replace(/[A-Z]/g, _temp).replace(/^ms-/, "-ms-");
|
|
79
|
+
const unprefixedKey = key.replace(/^(Webkit|Moz|ms|O)([A-Z])/, _temp2);
|
|
80
|
+
const cssValue = typeof value === "number" && value !== 0 && !unitless.has(unprefixedKey) && !key.startsWith("--") ? `${value}px` : String(value);
|
|
81
|
+
dom.style.setProperty(property, cssValue);
|
|
82
|
+
properties.push(property);
|
|
83
|
+
}
|
|
84
|
+
previous.set(dom, {
|
|
85
|
+
classes,
|
|
86
|
+
properties
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
const sync = function sync() {
|
|
90
|
+
editor.getEditorState().read(() => {
|
|
91
|
+
function visit(node) {
|
|
92
|
+
const dom_0 = editor.getElementByKey(node.getKey());
|
|
93
|
+
if (dom_0 && $isTextNode(node)) apply(dom_0, getTextAppearance(node.getFormat(), options));
|
|
94
|
+
if (dom_0 && node instanceof GradientNode) apply(dom_0, getGradientStyle(options));
|
|
95
|
+
if (dom_0 && $isLinkNode(node)) {
|
|
96
|
+
const target = node.getURL();
|
|
97
|
+
const href = resolveTextLinkHref(target, options.pages, options.fallbackHref ?? "#") ?? "#";
|
|
98
|
+
const appearance_0 = options.linkStyle?.({
|
|
99
|
+
target,
|
|
100
|
+
href,
|
|
101
|
+
external: isHttpTextLinkTarget(target),
|
|
102
|
+
pageId: getPageIdFromTextLinkTarget(target) ?? void 0
|
|
103
|
+
});
|
|
104
|
+
apply(dom_0, {
|
|
105
|
+
className: appearance_0?.className,
|
|
106
|
+
style: {
|
|
107
|
+
textDecorationLine: "underline",
|
|
108
|
+
...appearance_0?.style
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
dom_0.setAttribute("href", href);
|
|
112
|
+
dom_0.dataset.camoxLinkTarget = target;
|
|
113
|
+
if (shouldOpenTextLinkInNewTab(target)) {
|
|
114
|
+
dom_0.setAttribute("target", "_blank");
|
|
115
|
+
dom_0.setAttribute("rel", "noreferrer");
|
|
116
|
+
} else {
|
|
117
|
+
dom_0.removeAttribute("target");
|
|
118
|
+
dom_0.removeAttribute("rel");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if ($isElementNode(node)) node.getChildren().forEach(visit);
|
|
122
|
+
}
|
|
123
|
+
visit($getRoot());
|
|
124
|
+
});
|
|
125
|
+
for (const dom_1 of previous.keys()) if (!editor.getRootElement()?.contains(dom_1)) previous.delete(dom_1);
|
|
126
|
+
};
|
|
127
|
+
const unregister = editor.registerUpdateListener(sync);
|
|
128
|
+
const unregisterRoot = editor.registerRootListener(sync);
|
|
129
|
+
sync();
|
|
130
|
+
return () => {
|
|
131
|
+
unregister();
|
|
132
|
+
unregisterRoot();
|
|
133
|
+
for (const [dom_2, old_0] of previous) {
|
|
134
|
+
old_0.classes.forEach((name_2) => dom_2.classList.remove(name_2));
|
|
135
|
+
old_0.properties.forEach((name_3) => dom_2.style.removeProperty(name_3));
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
$[1] = editor;
|
|
140
|
+
$[2] = options;
|
|
141
|
+
$[3] = t0;
|
|
142
|
+
} else t0 = $[3];
|
|
143
|
+
let t1;
|
|
144
|
+
if ($[4] !== editor || $[5] !== options.fallbackHref || $[6] !== options.linkStyle || $[7] !== options.pages || $[8] !== options.textStyle) {
|
|
145
|
+
t1 = [
|
|
146
|
+
editor,
|
|
147
|
+
options.textStyle,
|
|
148
|
+
options.linkStyle,
|
|
149
|
+
options.pages,
|
|
150
|
+
options.fallbackHref
|
|
151
|
+
];
|
|
152
|
+
$[4] = editor;
|
|
153
|
+
$[5] = options.fallbackHref;
|
|
154
|
+
$[6] = options.linkStyle;
|
|
155
|
+
$[7] = options.pages;
|
|
156
|
+
$[8] = options.textStyle;
|
|
157
|
+
$[9] = t1;
|
|
158
|
+
} else t1 = $[9];
|
|
159
|
+
React.useLayoutEffect(t0, t1);
|
|
160
|
+
let t2;
|
|
161
|
+
let t3;
|
|
162
|
+
if ($[10] !== editor) {
|
|
163
|
+
t2 = () => editor.registerNodeTransform(GradientNode, $normalizeGradient);
|
|
164
|
+
t3 = [editor];
|
|
165
|
+
$[10] = editor;
|
|
166
|
+
$[11] = t2;
|
|
167
|
+
$[12] = t3;
|
|
168
|
+
} else {
|
|
169
|
+
t2 = $[11];
|
|
170
|
+
t3 = $[12];
|
|
171
|
+
}
|
|
172
|
+
React.useEffect(t2, t3);
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
function _temp2(_, _prefix, letter_0) {
|
|
176
|
+
return letter_0.toLowerCase();
|
|
177
|
+
}
|
|
178
|
+
function _temp(letter) {
|
|
179
|
+
return `-${letter.toLowerCase()}`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
//#endregion
|
|
183
|
+
export { InlineStylesPlugin };
|