quoin-editor 1.8.0 → 2.0.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 +10 -1
- package/MIGRATION.md +137 -23
- package/README.md +8 -2
- package/dist/ai.cjs +34 -34
- package/dist/ai.js +3 -3
- package/dist/catalogue.cjs +21 -21
- package/dist/catalogue.js +12 -12
- package/dist/{chunk-VWYPO6SX.js → chunk-2UKI26JA.js} +5 -5
- package/dist/chunk-2UKI26JA.js.map +1 -0
- package/dist/{chunk-B3OBM6I4.cjs → chunk-4PIJC4FD.cjs} +16 -16
- package/dist/{chunk-5OZX2LV4.js → chunk-5X52BAZB.js} +5 -5
- package/dist/{chunk-5OZX2LV4.js.map → chunk-5X52BAZB.js.map} +1 -1
- package/dist/{chunk-PVFSJXYQ.cjs → chunk-5YAJZSTI.cjs} +18 -18
- package/dist/{chunk-53CNYRVQ.cjs → chunk-66OPHDFA.cjs} +50 -50
- package/dist/{chunk-EZX37R5D.js → chunk-6BVE46K7.js} +4 -4
- package/dist/{chunk-EZX37R5D.js.map → chunk-6BVE46K7.js.map} +1 -1
- package/dist/{chunk-MMS4D4MK.cjs → chunk-77CNOLHY.cjs} +3 -3
- package/dist/{chunk-DXUDBPG5.js → chunk-B4VCDJSA.js} +5 -5
- package/dist/{chunk-DXUDBPG5.js.map → chunk-B4VCDJSA.js.map} +1 -1
- package/dist/{chunk-4MCYQHFL.cjs → chunk-BYYCD54G.cjs} +2 -2
- package/dist/{chunk-BA5WXBGE.cjs → chunk-CJVJNMOB.cjs} +107 -101
- package/dist/{chunk-TQHFGSTT.cjs → chunk-D6CIIWCU.cjs} +30 -30
- package/dist/{chunk-NCDMQCZR.js → chunk-EU5IGKMP.js} +3 -3
- package/dist/{chunk-NCDMQCZR.js.map → chunk-EU5IGKMP.js.map} +1 -1
- package/dist/{chunk-7X3T7VXV.cjs → chunk-HOSDMHK6.cjs} +25 -25
- package/dist/{chunk-XKYNINUX.cjs → chunk-IKZSCTRF.cjs} +3 -3
- package/dist/{chunk-D4L5FINK.js → chunk-IW4TMECB.js} +3 -3
- package/dist/{chunk-D4L5FINK.js.map → chunk-IW4TMECB.js.map} +1 -1
- package/dist/{chunk-MRHDPXQ7.js → chunk-J2SVYBTC.js} +6 -6
- package/dist/chunk-J2SVYBTC.js.map +1 -0
- package/dist/{chunk-PHQMHXNG.js → chunk-KQPZTSW3.js} +4 -4
- package/dist/{chunk-PHQMHXNG.js.map → chunk-KQPZTSW3.js.map} +1 -1
- package/dist/{chunk-YVPZDTVZ.cjs → chunk-LEICOZYK.cjs} +2 -2
- package/dist/{chunk-SP4F5F6V.js → chunk-M77A3EGD.js} +3 -3
- package/dist/{chunk-SP4F5F6V.js.map → chunk-M77A3EGD.js.map} +1 -1
- package/dist/{chunk-VM567D6O.js → chunk-MAS4AEF4.js} +4 -4
- package/dist/{chunk-VM567D6O.js.map → chunk-MAS4AEF4.js.map} +1 -1
- package/dist/{chunk-EZWJRBQT.cjs → chunk-NFO3W644.cjs} +19 -19
- package/dist/{chunk-MSWA5ZZM.js → chunk-NL5J77VD.js} +202 -202
- package/dist/chunk-NL5J77VD.js.map +1 -0
- package/dist/{chunk-53FJFYBR.cjs → chunk-V4WQG7FR.cjs} +64 -64
- package/dist/{chunk-WOGCD7JN.js → chunk-YABGWOAV.js} +3 -3
- package/dist/{chunk-WOGCD7JN.js.map → chunk-YABGWOAV.js.map} +1 -1
- package/dist/{chunk-P6HC7RUN.cjs → chunk-Z6LAARPB.cjs} +199 -204
- package/dist/{chunk-Y4EJ6UBV.js → chunk-ZN5DHNSL.js} +15 -9
- package/dist/chunk-ZN5DHNSL.js.map +1 -0
- package/dist/comments.cjs +30 -30
- package/dist/comments.js +3 -3
- package/dist/diagram.cjs +6 -6
- package/dist/diagram.js +3 -3
- package/dist/embed.cjs +5 -5
- package/dist/embed.js +3 -3
- package/dist/emoji.cjs +6 -6
- package/dist/emoji.js +3 -3
- package/dist/find.cjs +7 -7
- package/dist/find.js +3 -3
- package/dist/headless.cjs +11 -31
- package/dist/headless.d.cts +4 -41
- package/dist/headless.d.ts +4 -41
- package/dist/headless.js +1 -1
- package/dist/highlight.cjs +3 -3
- package/dist/highlight.js +2 -2
- package/dist/index.cjs +23 -43
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/math.cjs +6 -6
- package/dist/math.js +4 -4
- package/dist/mention.cjs +6 -6
- package/dist/mention.js +4 -4
- package/dist/presence.cjs +12 -12
- package/dist/presence.js +3 -3
- package/dist/source.cjs +2 -2
- package/dist/source.js +2 -2
- package/dist/stats.cjs +6 -6
- package/dist/stats.js +3 -3
- package/dist/styles.css +2 -2
- package/dist/table.cjs +22 -22
- package/dist/table.js +3 -3
- package/dist/toc.cjs +6 -6
- package/dist/toc.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-MRHDPXQ7.js.map +0 -1
- package/dist/chunk-MSWA5ZZM.js.map +0 -1
- package/dist/chunk-VWYPO6SX.js.map +0 -1
- package/dist/chunk-Y4EJ6UBV.js.map +0 -1
|
@@ -23,25 +23,6 @@ function useEditorState(controller, selector, isEqual = Object.is) {
|
|
|
23
23
|
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
// src/view/selection/selection-decorations.ts
|
|
27
|
-
var SELECTED = { class: "quoin-selected" };
|
|
28
|
-
function isCrossSelection(selection) {
|
|
29
|
-
if (selection?.kind !== "text") return false;
|
|
30
|
-
const { anchor, head } = selection;
|
|
31
|
-
return anchor.block !== head.block || anchor.region !== head.region;
|
|
32
|
-
}
|
|
33
|
-
function selectionDecorations(state, mode) {
|
|
34
|
-
if (mode !== "decorations" || !isCrossSelection(state.selection)) return [];
|
|
35
|
-
return markRanges(state).map(({ block, region, from, to }) => ({
|
|
36
|
-
kind: "inline",
|
|
37
|
-
block,
|
|
38
|
-
region,
|
|
39
|
-
from,
|
|
40
|
-
to,
|
|
41
|
-
attrs: SELECTED
|
|
42
|
-
}));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
26
|
// src/view/dom/attributes.ts
|
|
46
27
|
var sortedEntries = (attrs) => dataAttributes(attrs, "");
|
|
47
28
|
function setAttributes(element, attrs, prefix = "") {
|
|
@@ -837,6 +818,25 @@ function caretPosAt(controller, host, x, y) {
|
|
|
837
818
|
// src/view/selection/native-interaction.ts
|
|
838
819
|
var NATIVE_INTERACTION = "data-quoin-native";
|
|
839
820
|
|
|
821
|
+
// src/view/selection/selection-decorations.ts
|
|
822
|
+
var SELECTED = { class: "quoin-selected" };
|
|
823
|
+
function isCrossSelection(selection) {
|
|
824
|
+
if (selection?.kind !== "text") return false;
|
|
825
|
+
const { anchor, head } = selection;
|
|
826
|
+
return anchor.block !== head.block || anchor.region !== head.region;
|
|
827
|
+
}
|
|
828
|
+
function selectionDecorations(state, mode) {
|
|
829
|
+
if (mode !== "decorations" || !isCrossSelection(state.selection)) return [];
|
|
830
|
+
return markRanges(state).map(({ block, region, from, to }) => ({
|
|
831
|
+
kind: "inline",
|
|
832
|
+
block,
|
|
833
|
+
region,
|
|
834
|
+
from,
|
|
835
|
+
to,
|
|
836
|
+
attrs: SELECTED
|
|
837
|
+
}));
|
|
838
|
+
}
|
|
839
|
+
|
|
840
840
|
// src/view/selection/cross-block-pointer.ts
|
|
841
841
|
var DRAGGING = "data-quoin-dragging";
|
|
842
842
|
var DRAG_DISTANCE = 4;
|
|
@@ -1033,7 +1033,7 @@ function inPlace(element, change) {
|
|
|
1033
1033
|
change();
|
|
1034
1034
|
for (const { at, left, top } of before) {
|
|
1035
1035
|
const now = scrollOf(at);
|
|
1036
|
-
if (now.left !== left || now.top !== top) at.scrollTo({ left, top, behavior: "instant" });
|
|
1036
|
+
if (now.left !== left || now.top !== top) at.scrollTo?.({ left, top, behavior: "instant" });
|
|
1037
1037
|
}
|
|
1038
1038
|
}
|
|
1039
1039
|
|
|
@@ -1154,7 +1154,7 @@ function createNodeReveal(element) {
|
|
|
1154
1154
|
show(selection, local) {
|
|
1155
1155
|
const block = nodeOf(selection);
|
|
1156
1156
|
if (block !== null && block !== pressed && (block !== shown || local && block === owed)) {
|
|
1157
|
-
element(block)?.scrollIntoView({ block: "nearest" });
|
|
1157
|
+
element(block)?.scrollIntoView?.({ block: "nearest" });
|
|
1158
1158
|
}
|
|
1159
1159
|
if (local) owed = null;
|
|
1160
1160
|
shown = block;
|
|
@@ -2156,7 +2156,7 @@ function lineInView(host, last) {
|
|
|
2156
2156
|
const line = lineEdgeRect(host, last);
|
|
2157
2157
|
const view = host.ownerDocument.defaultView;
|
|
2158
2158
|
if (!line || !view || line.top >= 0 && line.bottom <= view.innerHeight) return line;
|
|
2159
|
-
host.scrollIntoView({ block: "nearest" });
|
|
2159
|
+
host.scrollIntoView?.({ block: "nearest" });
|
|
2160
2160
|
return lineEdgeRect(host, last);
|
|
2161
2161
|
}
|
|
2162
2162
|
function caretAtGoal(controller, host, at, y) {
|
|
@@ -2779,49 +2779,17 @@ function useQuoinEditor(options) {
|
|
|
2779
2779
|
useEffect(() => () => controller.destroy(), [controller]);
|
|
2780
2780
|
return controller;
|
|
2781
2781
|
}
|
|
2782
|
-
function useReadOnly(controller) {
|
|
2783
|
-
const subscribe = useCallback((notify) => controller.subscribeReadOnly(notify), [controller]);
|
|
2784
|
-
const read = useCallback(() => controller.readOnly, [controller]);
|
|
2785
|
-
return useSyncExternalStore(subscribe, read, read);
|
|
2786
|
-
}
|
|
2787
|
-
function SelectionSink({ label = "Selected content", blockLabel }) {
|
|
2788
|
-
const controller = useViewController();
|
|
2789
|
-
const ref = useRef(null);
|
|
2790
|
-
const readOnly = useReadOnly(controller);
|
|
2791
|
-
const name = useEditorState(
|
|
2792
|
-
controller,
|
|
2793
|
-
useCallback((state) => selectedBlockName(state, blockLabel), [blockLabel])
|
|
2794
|
-
);
|
|
2795
|
-
useIsomorphicLayoutEffect(() => {
|
|
2796
|
-
const sink = ref.current;
|
|
2797
|
-
return sink ? controller.registerSink(sink) : void 0;
|
|
2798
|
-
}, [controller]);
|
|
2799
|
-
return /* @__PURE__ */ jsx(
|
|
2800
|
-
"div",
|
|
2801
|
-
{
|
|
2802
|
-
ref,
|
|
2803
|
-
contentEditable: !readOnly,
|
|
2804
|
-
suppressContentEditableWarning: true,
|
|
2805
|
-
role: "textbox",
|
|
2806
|
-
"aria-label": name || label,
|
|
2807
|
-
inputMode: name === null ? void 0 : "none",
|
|
2808
|
-
"aria-multiline": name === null ? "true" : void 0,
|
|
2809
|
-
"aria-readonly": readOnly ? "true" : void 0,
|
|
2810
|
-
tabIndex: -1,
|
|
2811
|
-
spellCheck: false,
|
|
2812
|
-
"data-quoin-sink": "",
|
|
2813
|
-
onFocus: () => {
|
|
2814
|
-
if (heldBySink(controller.editor.state.selection)) focusSink(controller);
|
|
2815
|
-
}
|
|
2816
|
-
}
|
|
2817
|
-
);
|
|
2818
|
-
}
|
|
2819
2782
|
var headingPlaceholder = (_state, { type, attrs }) => type === "MARKDOWN" && attrs.kind === "heading" ? `Heading ${headingLevel(attrs.level)}` : void 0;
|
|
2820
2783
|
var BlockPlaceholderContext = createContext(headingPlaceholder);
|
|
2821
2784
|
function regionPlaceholder(state, blockId, region, placeholderOf) {
|
|
2822
2785
|
const block = blockById(state.doc, blockId);
|
|
2823
2786
|
return block !== void 0 && primaryRegion(state.schema, block) === region ? placeholderOf(state, block) : void 0;
|
|
2824
2787
|
}
|
|
2788
|
+
function useReadOnly(controller) {
|
|
2789
|
+
const subscribe = useCallback((notify) => controller.subscribeReadOnly(notify), [controller]);
|
|
2790
|
+
const read = useCallback(() => controller.readOnly, [controller]);
|
|
2791
|
+
return useSyncExternalStore(subscribe, read, read);
|
|
2792
|
+
}
|
|
2825
2793
|
var samePainted = (a, b) => a.inline === b.inline && a.placeholder === b.placeholder && sameDecorations(a.decorations, b.decorations);
|
|
2826
2794
|
function EditableRegion({ block, region, label, id, placeholder, className }) {
|
|
2827
2795
|
const controller = useViewController();
|
|
@@ -2868,6 +2836,178 @@ function EditableRegion({ block, region, label, id, placeholder, className }) {
|
|
|
2868
2836
|
}
|
|
2869
2837
|
);
|
|
2870
2838
|
}
|
|
2839
|
+
var BLOCK_ERROR = "Block could not be drawn";
|
|
2840
|
+
var BlockErrorContext = createContext({ label: BLOCK_ERROR });
|
|
2841
|
+
var BlockDomIdScope = createContext("quoin");
|
|
2842
|
+
function useBlockDomId() {
|
|
2843
|
+
const scope = useContext(BlockDomIdScope);
|
|
2844
|
+
return useCallback((block) => `${scope}-${encodeURIComponent(block)}`, [scope]);
|
|
2845
|
+
}
|
|
2846
|
+
function useRegionDomId(block, region) {
|
|
2847
|
+
return `${useBlockDomId()(block)}/${encodeURIComponent(region)}`;
|
|
2848
|
+
}
|
|
2849
|
+
function EmptyDocumentHost({ placeholder, label = "Paragraph" }) {
|
|
2850
|
+
const controller = useViewController();
|
|
2851
|
+
const ref = useRef(null);
|
|
2852
|
+
const readOnly = useReadOnly(controller);
|
|
2853
|
+
useIsomorphicLayoutEffect(() => {
|
|
2854
|
+
const host = ref.current;
|
|
2855
|
+
if (host === null) return void 0;
|
|
2856
|
+
renderInline(host, [], []);
|
|
2857
|
+
return controller.registerEmptyHost(host);
|
|
2858
|
+
}, [controller]);
|
|
2859
|
+
return /* @__PURE__ */ jsx(
|
|
2860
|
+
"div",
|
|
2861
|
+
{
|
|
2862
|
+
ref,
|
|
2863
|
+
contentEditable: !readOnly,
|
|
2864
|
+
suppressContentEditableWarning: true,
|
|
2865
|
+
role: "textbox",
|
|
2866
|
+
"aria-multiline": "true",
|
|
2867
|
+
"aria-readonly": readOnly ? "true" : void 0,
|
|
2868
|
+
"aria-label": label,
|
|
2869
|
+
"data-quoin-host": "",
|
|
2870
|
+
"data-quoin-empty": "",
|
|
2871
|
+
"data-placeholder": readOnly ? void 0 : placeholder,
|
|
2872
|
+
"aria-placeholder": readOnly ? void 0 : placeholder,
|
|
2873
|
+
spellCheck: true,
|
|
2874
|
+
onClick: () => ref.current?.focus()
|
|
2875
|
+
}
|
|
2876
|
+
);
|
|
2877
|
+
}
|
|
2878
|
+
|
|
2879
|
+
// src/view/react/focus-owners.ts
|
|
2880
|
+
var focusOwners = /* @__PURE__ */ new WeakMap();
|
|
2881
|
+
|
|
2882
|
+
// src/view/selection/selection-announcement.ts
|
|
2883
|
+
var SILENCE = { key: "", message: "" };
|
|
2884
|
+
function selectionAnnouncement({ doc, selection }, blocksSelected) {
|
|
2885
|
+
if (selection === null || selection.kind === "text" && !isCrossSelection(selection)) return SILENCE;
|
|
2886
|
+
if (selection.kind === "node") return { key: `node:${selection.block}`, message: blocksSelected(1) };
|
|
2887
|
+
const anchor = selection.kind === "blocks" ? selection.anchor : selection.anchor.block;
|
|
2888
|
+
const head = selection.kind === "blocks" ? selection.head : selection.head.block;
|
|
2889
|
+
const first = doc.index.get(anchor);
|
|
2890
|
+
const last = doc.index.get(head);
|
|
2891
|
+
if (first === void 0 || last === void 0) return SILENCE;
|
|
2892
|
+
const count = drawnBlockCount(doc, Math.min(first, last), Math.max(first, last) + 1);
|
|
2893
|
+
return { key: `${selection.kind}:${anchor}:${head}`, message: blocksSelected(count) };
|
|
2894
|
+
}
|
|
2895
|
+
function heardNow({ editor, announcer, engagement }, blocksSelected) {
|
|
2896
|
+
const spoken = announcer.current();
|
|
2897
|
+
if (spoken !== null) return { key: `said:${spoken.serial}`, message: spoken.message };
|
|
2898
|
+
return engagement.engaged ? selectionAnnouncement(editor.state, blocksSelected) : SILENCE;
|
|
2899
|
+
}
|
|
2900
|
+
function LiveRegion({ blocksSelected }) {
|
|
2901
|
+
const controller = useViewController();
|
|
2902
|
+
const subscribe = useCallback(
|
|
2903
|
+
(notify) => {
|
|
2904
|
+
const stopState = controller.editor.subscribe(() => notify());
|
|
2905
|
+
const stopSpoken = controller.announcer.subscribe(notify);
|
|
2906
|
+
const stopEngaged = controller.engagement.subscribe(notify);
|
|
2907
|
+
return () => {
|
|
2908
|
+
stopState();
|
|
2909
|
+
stopSpoken();
|
|
2910
|
+
stopEngaged();
|
|
2911
|
+
};
|
|
2912
|
+
},
|
|
2913
|
+
[controller]
|
|
2914
|
+
);
|
|
2915
|
+
const read = useMemo(() => {
|
|
2916
|
+
let last = SILENCE;
|
|
2917
|
+
return () => {
|
|
2918
|
+
const next = heardNow(controller, blocksSelected);
|
|
2919
|
+
if (next.key !== last.key || next.message !== last.message) last = next;
|
|
2920
|
+
return last;
|
|
2921
|
+
};
|
|
2922
|
+
}, [controller, blocksSelected]);
|
|
2923
|
+
const { key, message } = useSyncExternalStore(subscribe, read, read);
|
|
2924
|
+
return /* @__PURE__ */ jsx("div", { className: "quoin-visually-hidden", role: "status", "aria-live": "polite", "aria-atomic": "true", children: message !== "" && /* @__PURE__ */ jsx("span", { children: message }, key) });
|
|
2925
|
+
}
|
|
2926
|
+
function SelectionSink({ label = "Selected content", blockLabel }) {
|
|
2927
|
+
const controller = useViewController();
|
|
2928
|
+
const ref = useRef(null);
|
|
2929
|
+
const readOnly = useReadOnly(controller);
|
|
2930
|
+
const name = useEditorState(
|
|
2931
|
+
controller,
|
|
2932
|
+
useCallback((state) => selectedBlockName(state, blockLabel), [blockLabel])
|
|
2933
|
+
);
|
|
2934
|
+
useIsomorphicLayoutEffect(() => {
|
|
2935
|
+
const sink = ref.current;
|
|
2936
|
+
return sink ? controller.registerSink(sink) : void 0;
|
|
2937
|
+
}, [controller]);
|
|
2938
|
+
return /* @__PURE__ */ jsx(
|
|
2939
|
+
"div",
|
|
2940
|
+
{
|
|
2941
|
+
ref,
|
|
2942
|
+
contentEditable: !readOnly,
|
|
2943
|
+
suppressContentEditableWarning: true,
|
|
2944
|
+
role: "textbox",
|
|
2945
|
+
"aria-label": name || label,
|
|
2946
|
+
inputMode: name === null ? void 0 : "none",
|
|
2947
|
+
"aria-multiline": name === null ? "true" : void 0,
|
|
2948
|
+
"aria-readonly": readOnly ? "true" : void 0,
|
|
2949
|
+
tabIndex: -1,
|
|
2950
|
+
spellCheck: false,
|
|
2951
|
+
"data-quoin-sink": "",
|
|
2952
|
+
onFocus: () => {
|
|
2953
|
+
if (heldBySink(controller.editor.state.selection)) focusSink(controller);
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2956
|
+
);
|
|
2957
|
+
}
|
|
2958
|
+
|
|
2959
|
+
// src/view/react/SelectionWriter.tsx
|
|
2960
|
+
function SelectionWriter() {
|
|
2961
|
+
const controller = useViewController();
|
|
2962
|
+
const state = useEditorState(controller, wholeState);
|
|
2963
|
+
useIsomorphicLayoutEffect(() => controller.afterRender(), [controller, state]);
|
|
2964
|
+
return null;
|
|
2965
|
+
}
|
|
2966
|
+
var UNSUPPORTED_BLOCK = "Unsupported block";
|
|
2967
|
+
var UnsupportedBlockLabel = createContext(UNSUPPORTED_BLOCK);
|
|
2968
|
+
var Boundary = class extends Component {
|
|
2969
|
+
state = { block: this.props.block, renderer: this.props.renderer, failed: false };
|
|
2970
|
+
static getDerivedStateFromError() {
|
|
2971
|
+
return { failed: true };
|
|
2972
|
+
}
|
|
2973
|
+
static getDerivedStateFromProps(props, state) {
|
|
2974
|
+
const same = props.block === state.block && props.renderer === state.renderer;
|
|
2975
|
+
return same ? null : { block: props.block, renderer: props.renderer, failed: false };
|
|
2976
|
+
}
|
|
2977
|
+
componentDidCatch(error) {
|
|
2978
|
+
this.props.report?.(error instanceof Error ? error : new Error(String(error)));
|
|
2979
|
+
}
|
|
2980
|
+
render() {
|
|
2981
|
+
if (!this.state.failed) return this.props.children;
|
|
2982
|
+
const { label } = this.props;
|
|
2983
|
+
return /* @__PURE__ */ jsx("div", { className: "quoin-void", contentEditable: false, role: "group", "aria-label": label, children: label });
|
|
2984
|
+
}
|
|
2985
|
+
};
|
|
2986
|
+
function BlockErrorBoundary({ block, renderer, children }) {
|
|
2987
|
+
const { label, report } = useContext(BlockErrorContext);
|
|
2988
|
+
return /* @__PURE__ */ jsx(Boundary, { block, renderer, label, report, children });
|
|
2989
|
+
}
|
|
2990
|
+
|
|
2991
|
+
// src/view/react/block-status.ts
|
|
2992
|
+
function within(state, index, ends) {
|
|
2993
|
+
const [anchor, head] = ends.map((id) => state.doc.index.get(id));
|
|
2994
|
+
if (anchor === void 0 || head === void 0) return false;
|
|
2995
|
+
return index >= Math.min(anchor, head) && index <= Math.max(anchor, head);
|
|
2996
|
+
}
|
|
2997
|
+
function covers(state, id, index) {
|
|
2998
|
+
const { doc, schema, selection } = state;
|
|
2999
|
+
if (selection === null) return false;
|
|
3000
|
+
if (selection.kind === "node") return selection.block === id;
|
|
3001
|
+
if (selection.kind === "blocks") return within(state, index, [selection.anchor, selection.head]);
|
|
3002
|
+
if (!isCrossSelection(selection) || isTextFlow(schema, doc.blocks[index])) return false;
|
|
3003
|
+
return within(state, index, [selection.anchor.block, selection.head.block]);
|
|
3004
|
+
}
|
|
3005
|
+
function blockStatus(state, id, choices = NO_CHOICES) {
|
|
3006
|
+
const index = state.doc.index.get(id);
|
|
3007
|
+
if (index === void 0) return "plain";
|
|
3008
|
+
if (isHiddenAt(state.doc, index, choices)) return "hidden";
|
|
3009
|
+
return covers(state, id, index) ? "selected" : "plain";
|
|
3010
|
+
}
|
|
2871
3011
|
var CalloutBlock = ({ block }) => {
|
|
2872
3012
|
const tone = typeof block.attrs.tone === "string" && block.attrs.tone !== "" ? block.attrs.tone : "info";
|
|
2873
3013
|
return /* @__PURE__ */ jsx("div", { className: "quoin-callout", "data-tone": tone, children: /* @__PURE__ */ jsx(EditableRegion, { block: block.id, region: "body", label: `Callout, ${tone}` }) });
|
|
@@ -3023,8 +3163,6 @@ var ToggleBlock = ({ block, controller }) => {
|
|
|
3023
3163
|
/* @__PURE__ */ jsx(EditableRegion, { block: block.id, region: "text", label: "Toggle" })
|
|
3024
3164
|
] });
|
|
3025
3165
|
};
|
|
3026
|
-
var UNSUPPORTED_BLOCK = "Unsupported block";
|
|
3027
|
-
var UnsupportedBlockLabel = createContext(UNSUPPORTED_BLOCK);
|
|
3028
3166
|
var defaultRenderers = {
|
|
3029
3167
|
MARKDOWN: MarkdownBlock,
|
|
3030
3168
|
CALLOUT: CalloutBlock,
|
|
@@ -3035,59 +3173,6 @@ var VoidBlockFallback = ({ block }) => {
|
|
|
3035
3173
|
if (block.type === "DIVIDER") return /* @__PURE__ */ jsx("div", { className: "quoin-void", contentEditable: false, role: "separator" });
|
|
3036
3174
|
return /* @__PURE__ */ jsx("div", { className: "quoin-void", contentEditable: false, role: "group", "aria-label": label, children: label });
|
|
3037
3175
|
};
|
|
3038
|
-
var BLOCK_ERROR = "Block could not be drawn";
|
|
3039
|
-
var BlockErrorContext = createContext({ label: BLOCK_ERROR });
|
|
3040
|
-
var Boundary = class extends Component {
|
|
3041
|
-
state = { block: this.props.block, renderer: this.props.renderer, failed: false };
|
|
3042
|
-
static getDerivedStateFromError() {
|
|
3043
|
-
return { failed: true };
|
|
3044
|
-
}
|
|
3045
|
-
static getDerivedStateFromProps(props, state) {
|
|
3046
|
-
const same = props.block === state.block && props.renderer === state.renderer;
|
|
3047
|
-
return same ? null : { block: props.block, renderer: props.renderer, failed: false };
|
|
3048
|
-
}
|
|
3049
|
-
componentDidCatch(error) {
|
|
3050
|
-
this.props.report?.(error instanceof Error ? error : new Error(String(error)));
|
|
3051
|
-
}
|
|
3052
|
-
render() {
|
|
3053
|
-
if (!this.state.failed) return this.props.children;
|
|
3054
|
-
const { label } = this.props;
|
|
3055
|
-
return /* @__PURE__ */ jsx("div", { className: "quoin-void", contentEditable: false, role: "group", "aria-label": label, children: label });
|
|
3056
|
-
}
|
|
3057
|
-
};
|
|
3058
|
-
function BlockErrorBoundary({ block, renderer, children }) {
|
|
3059
|
-
const { label, report } = useContext(BlockErrorContext);
|
|
3060
|
-
return /* @__PURE__ */ jsx(Boundary, { block, renderer, label, report, children });
|
|
3061
|
-
}
|
|
3062
|
-
var BlockDomIdScope = createContext("quoin");
|
|
3063
|
-
function useBlockDomId() {
|
|
3064
|
-
const scope = useContext(BlockDomIdScope);
|
|
3065
|
-
return useCallback((block) => `${scope}-${encodeURIComponent(block)}`, [scope]);
|
|
3066
|
-
}
|
|
3067
|
-
function useRegionDomId(block, region) {
|
|
3068
|
-
return `${useBlockDomId()(block)}/${encodeURIComponent(region)}`;
|
|
3069
|
-
}
|
|
3070
|
-
|
|
3071
|
-
// src/view/react/block-status.ts
|
|
3072
|
-
function within(state, index, ends) {
|
|
3073
|
-
const [anchor, head] = ends.map((id) => state.doc.index.get(id));
|
|
3074
|
-
if (anchor === void 0 || head === void 0) return false;
|
|
3075
|
-
return index >= Math.min(anchor, head) && index <= Math.max(anchor, head);
|
|
3076
|
-
}
|
|
3077
|
-
function covers(state, id, index) {
|
|
3078
|
-
const { doc, schema, selection } = state;
|
|
3079
|
-
if (selection === null) return false;
|
|
3080
|
-
if (selection.kind === "node") return selection.block === id;
|
|
3081
|
-
if (selection.kind === "blocks") return within(state, index, [selection.anchor, selection.head]);
|
|
3082
|
-
if (!isCrossSelection(selection) || isTextFlow(schema, doc.blocks[index])) return false;
|
|
3083
|
-
return within(state, index, [selection.anchor.block, selection.head.block]);
|
|
3084
|
-
}
|
|
3085
|
-
function blockStatus(state, id, choices = NO_CHOICES) {
|
|
3086
|
-
const index = state.doc.index.get(id);
|
|
3087
|
-
if (index === void 0) return "plain";
|
|
3088
|
-
if (isHiddenAt(state.doc, index, choices)) return "hidden";
|
|
3089
|
-
return covers(state, id, index) ? "selected" : "plain";
|
|
3090
|
-
}
|
|
3091
3176
|
var unwatched = () => () => {
|
|
3092
3177
|
};
|
|
3093
3178
|
function useEngaged(controller, watching) {
|
|
@@ -3141,91 +3226,6 @@ var BlockShell = memo(function BlockShell2({ block, renderers }) {
|
|
|
3141
3226
|
}
|
|
3142
3227
|
);
|
|
3143
3228
|
});
|
|
3144
|
-
function EmptyDocumentHost({ placeholder, label = "Paragraph" }) {
|
|
3145
|
-
const controller = useViewController();
|
|
3146
|
-
const ref = useRef(null);
|
|
3147
|
-
const readOnly = useReadOnly(controller);
|
|
3148
|
-
useIsomorphicLayoutEffect(() => {
|
|
3149
|
-
const host = ref.current;
|
|
3150
|
-
if (host === null) return void 0;
|
|
3151
|
-
renderInline(host, [], []);
|
|
3152
|
-
return controller.registerEmptyHost(host);
|
|
3153
|
-
}, [controller]);
|
|
3154
|
-
return /* @__PURE__ */ jsx(
|
|
3155
|
-
"div",
|
|
3156
|
-
{
|
|
3157
|
-
ref,
|
|
3158
|
-
contentEditable: !readOnly,
|
|
3159
|
-
suppressContentEditableWarning: true,
|
|
3160
|
-
role: "textbox",
|
|
3161
|
-
"aria-multiline": "true",
|
|
3162
|
-
"aria-readonly": readOnly ? "true" : void 0,
|
|
3163
|
-
"aria-label": label,
|
|
3164
|
-
"data-quoin-host": "",
|
|
3165
|
-
"data-quoin-empty": "",
|
|
3166
|
-
"data-placeholder": readOnly ? void 0 : placeholder,
|
|
3167
|
-
"aria-placeholder": readOnly ? void 0 : placeholder,
|
|
3168
|
-
spellCheck: true,
|
|
3169
|
-
onClick: () => ref.current?.focus()
|
|
3170
|
-
}
|
|
3171
|
-
);
|
|
3172
|
-
}
|
|
3173
|
-
|
|
3174
|
-
// src/view/react/focus-owners.ts
|
|
3175
|
-
var focusOwners = /* @__PURE__ */ new WeakMap();
|
|
3176
|
-
|
|
3177
|
-
// src/view/selection/selection-announcement.ts
|
|
3178
|
-
var SILENCE = { key: "", message: "" };
|
|
3179
|
-
function selectionAnnouncement({ doc, selection }, blocksSelected) {
|
|
3180
|
-
if (selection === null || selection.kind === "text" && !isCrossSelection(selection)) return SILENCE;
|
|
3181
|
-
if (selection.kind === "node") return { key: `node:${selection.block}`, message: blocksSelected(1) };
|
|
3182
|
-
const anchor = selection.kind === "blocks" ? selection.anchor : selection.anchor.block;
|
|
3183
|
-
const head = selection.kind === "blocks" ? selection.head : selection.head.block;
|
|
3184
|
-
const first = doc.index.get(anchor);
|
|
3185
|
-
const last = doc.index.get(head);
|
|
3186
|
-
if (first === void 0 || last === void 0) return SILENCE;
|
|
3187
|
-
const count = drawnBlockCount(doc, Math.min(first, last), Math.max(first, last) + 1);
|
|
3188
|
-
return { key: `${selection.kind}:${anchor}:${head}`, message: blocksSelected(count) };
|
|
3189
|
-
}
|
|
3190
|
-
function heardNow({ editor, announcer, engagement }, blocksSelected) {
|
|
3191
|
-
const spoken = announcer.current();
|
|
3192
|
-
if (spoken !== null) return { key: `said:${spoken.serial}`, message: spoken.message };
|
|
3193
|
-
return engagement.engaged ? selectionAnnouncement(editor.state, blocksSelected) : SILENCE;
|
|
3194
|
-
}
|
|
3195
|
-
function LiveRegion({ blocksSelected }) {
|
|
3196
|
-
const controller = useViewController();
|
|
3197
|
-
const subscribe = useCallback(
|
|
3198
|
-
(notify) => {
|
|
3199
|
-
const stopState = controller.editor.subscribe(() => notify());
|
|
3200
|
-
const stopSpoken = controller.announcer.subscribe(notify);
|
|
3201
|
-
const stopEngaged = controller.engagement.subscribe(notify);
|
|
3202
|
-
return () => {
|
|
3203
|
-
stopState();
|
|
3204
|
-
stopSpoken();
|
|
3205
|
-
stopEngaged();
|
|
3206
|
-
};
|
|
3207
|
-
},
|
|
3208
|
-
[controller]
|
|
3209
|
-
);
|
|
3210
|
-
const read = useMemo(() => {
|
|
3211
|
-
let last = SILENCE;
|
|
3212
|
-
return () => {
|
|
3213
|
-
const next = heardNow(controller, blocksSelected);
|
|
3214
|
-
if (next.key !== last.key || next.message !== last.message) last = next;
|
|
3215
|
-
return last;
|
|
3216
|
-
};
|
|
3217
|
-
}, [controller, blocksSelected]);
|
|
3218
|
-
const { key, message } = useSyncExternalStore(subscribe, read, read);
|
|
3219
|
-
return /* @__PURE__ */ jsx("div", { className: "quoin-visually-hidden", role: "status", "aria-live": "polite", "aria-atomic": "true", children: message !== "" && /* @__PURE__ */ jsx("span", { children: message }, key) });
|
|
3220
|
-
}
|
|
3221
|
-
|
|
3222
|
-
// src/view/react/SelectionWriter.tsx
|
|
3223
|
-
function SelectionWriter() {
|
|
3224
|
-
const controller = useViewController();
|
|
3225
|
-
const state = useEditorState(controller, wholeState);
|
|
3226
|
-
useIsomorphicLayoutEffect(() => controller.afterRender(), [controller, state]);
|
|
3227
|
-
return null;
|
|
3228
|
-
}
|
|
3229
3229
|
function useBlockElements(blocks, renderers) {
|
|
3230
3230
|
const [made] = useState(() => /* @__PURE__ */ new WeakMap());
|
|
3231
3231
|
return blocks.map((block) => {
|
|
@@ -3289,6 +3289,6 @@ function EditorView({
|
|
|
3289
3289
|
) });
|
|
3290
3290
|
}
|
|
3291
3291
|
|
|
3292
|
-
export { BlockErrorContext,
|
|
3293
|
-
//# sourceMappingURL=chunk-
|
|
3294
|
-
//# sourceMappingURL=chunk-
|
|
3292
|
+
export { BlockErrorContext, EditableRegion, EditorView, NATIVE_INTERACTION, NODE_ENTRY, TaskCheckbox, ToggleChevron, ViewController, caretClientRect, caretFromPoint, createAutoScroll, dispatchSelection, domMapOf, domToPos, drawnBlockCount, focusOwners, handleCopy, hostKey, isComposingKey, isOnFirstLine, isOnLastLine, lineEdgeRect, listen, moveToNeighbour, neighbourBlock, onBlock, posToDom, regionInline, renderInline, textDiff, useBlockDomId, useEditorState, useIsomorphicLayoutEffect, useOrderedNumber, useQuoinEditor, useReadOnly, useRegionDomId, useToggleOpen, useViewController, visibleBlockIndexes, wholeState };
|
|
3293
|
+
//# sourceMappingURL=chunk-NL5J77VD.js.map
|
|
3294
|
+
//# sourceMappingURL=chunk-NL5J77VD.js.map
|