@owomark/view 0.1.6 → 0.1.8
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/README.md +1 -1
- package/dist/.build-manifest.json +78 -0
- package/dist/{chunk-WA6XHBZS.js → chunk-656BO747.js} +1 -0
- package/dist/{chunk-KHKPOH74.js → chunk-BPOZMVU7.js} +1 -1
- package/dist/index.d.ts +17 -11
- package/dist/index.js +475 -91
- package/dist/internal/virtual/height-estimator.d.ts +1 -1
- package/dist/internal/virtual/height-estimator.js +1 -1
- package/dist/internal/virtual/viewport-manager.js +1 -1
- package/dist/preview-render.worker.js +369 -0
- package/dist/{types-DsL_4tUb.d.ts → types-D4TVpyP7.d.ts} +20 -10
- package/package.json +2 -2
- package/src/style.css +2 -0
- package/src/theme/cards.css +50 -0
- package/src/theme/dark.css +2 -0
- package/src/theme/light.css +2 -0
- package/src/theme/owomark.css +6 -0
- package/src/theme/preview.css +15 -0
- package/src/theme/toolbar.css +104 -0
package/dist/index.js
CHANGED
|
@@ -7,27 +7,27 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
FALLBACK_BLOCK_HEIGHT,
|
|
9
9
|
estimateBlockHeight
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-BPOZMVU7.js";
|
|
11
11
|
import {
|
|
12
12
|
VirtualViewportManager,
|
|
13
13
|
createSkeletonHtml,
|
|
14
14
|
ensureSkeletonStyles
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
|
|
17
|
-
// src/editor.ts
|
|
18
|
-
import { createDomAdapter } from "@owomark/core/internal/dom-adapter";
|
|
15
|
+
} from "./chunk-656BO747.js";
|
|
19
16
|
|
|
20
17
|
// src/view-engine.ts
|
|
21
18
|
import {
|
|
22
|
-
readSelection,
|
|
23
|
-
restoreSelection,
|
|
24
|
-
invalidateBlockCache,
|
|
25
19
|
linearToVirtual,
|
|
26
20
|
virtualToLinear,
|
|
27
21
|
getBlockStartOffset,
|
|
28
22
|
tokenizeBlock
|
|
29
23
|
} from "@owomark/core";
|
|
30
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
readSelection,
|
|
26
|
+
restoreSelection,
|
|
27
|
+
invalidateBlockCache,
|
|
28
|
+
createBlockElement,
|
|
29
|
+
updateBlockElement
|
|
30
|
+
} from "@owomark/core/browser";
|
|
31
31
|
|
|
32
32
|
// src/dom/slash-menu.ts
|
|
33
33
|
var MENU_GAP = 4;
|
|
@@ -635,22 +635,6 @@ function createOwoMarkView(core, element) {
|
|
|
635
635
|
engine.mount(element);
|
|
636
636
|
return engine;
|
|
637
637
|
}
|
|
638
|
-
function createOwoMarkVanillaEditor() {
|
|
639
|
-
const adapter = createDomAdapter();
|
|
640
|
-
let slashMenu = null;
|
|
641
|
-
return {
|
|
642
|
-
...adapter,
|
|
643
|
-
mount(element) {
|
|
644
|
-
adapter.mount(element);
|
|
645
|
-
slashMenu = createSlashMenuOverlay(element, adapter.getCore());
|
|
646
|
-
},
|
|
647
|
-
destroy() {
|
|
648
|
-
slashMenu?.destroy();
|
|
649
|
-
slashMenu = null;
|
|
650
|
-
adapter.destroy();
|
|
651
|
-
}
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
638
|
|
|
655
639
|
// src/dom/patcher.ts
|
|
656
640
|
var BLOCK_ATTR = "data-preview-block";
|
|
@@ -794,6 +778,11 @@ var PreviewDomPatcher = class {
|
|
|
794
778
|
createBlockWrapper(doc, block) {
|
|
795
779
|
const wrapper = doc.createElement("div");
|
|
796
780
|
wrapper.setAttribute(BLOCK_ATTR, block.blockId);
|
|
781
|
+
if ("style" in wrapper && wrapper.style) {
|
|
782
|
+
wrapper.style.display = "flow-root";
|
|
783
|
+
} else {
|
|
784
|
+
wrapper.setAttribute("style", "display: flow-root;");
|
|
785
|
+
}
|
|
797
786
|
this.updateBlockAttributes(wrapper, block);
|
|
798
787
|
return wrapper;
|
|
799
788
|
}
|
|
@@ -811,63 +800,13 @@ var PreviewDomPatcher = class {
|
|
|
811
800
|
};
|
|
812
801
|
|
|
813
802
|
// src/renderer/registry.ts
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
function createRendererRegistry() {
|
|
822
|
-
const renderers = /* @__PURE__ */ new Map();
|
|
823
|
-
const metadata = /* @__PURE__ */ new Map();
|
|
824
|
-
for (const { kind, meta } of DEFAULT_HEAVY_KINDS) {
|
|
825
|
-
metadata.set(kind, meta);
|
|
826
|
-
}
|
|
827
|
-
return {
|
|
828
|
-
get(kind) {
|
|
829
|
-
return renderers.get(kind) ?? null;
|
|
830
|
-
},
|
|
831
|
-
register(kind, renderer) {
|
|
832
|
-
renderers.set(kind, renderer);
|
|
833
|
-
if (!metadata.has(kind)) {
|
|
834
|
-
metadata.set(kind, {
|
|
835
|
-
mode: renderer.mode,
|
|
836
|
-
priority: renderer.priority
|
|
837
|
-
});
|
|
838
|
-
}
|
|
839
|
-
},
|
|
840
|
-
unregister(kind) {
|
|
841
|
-
renderers.delete(kind);
|
|
842
|
-
},
|
|
843
|
-
registerMetadata(kind, meta) {
|
|
844
|
-
metadata.set(kind, meta);
|
|
845
|
-
},
|
|
846
|
-
isHeavy(kind) {
|
|
847
|
-
const meta = metadata.get(kind);
|
|
848
|
-
if (meta?.heavy) return true;
|
|
849
|
-
const def = renderers.get(kind);
|
|
850
|
-
return def?.priority === "deferred" || false;
|
|
851
|
-
},
|
|
852
|
-
getMode(kind) {
|
|
853
|
-
const def = renderers.get(kind);
|
|
854
|
-
if (def) return def.mode;
|
|
855
|
-
return metadata.get(kind)?.mode ?? null;
|
|
856
|
-
},
|
|
857
|
-
getPriority(kind) {
|
|
858
|
-
const def = renderers.get(kind);
|
|
859
|
-
if (def) return def.priority;
|
|
860
|
-
return metadata.get(kind)?.priority ?? null;
|
|
861
|
-
},
|
|
862
|
-
listRegistered() {
|
|
863
|
-
const kinds = /* @__PURE__ */ new Set([
|
|
864
|
-
...renderers.keys(),
|
|
865
|
-
...metadata.keys()
|
|
866
|
-
]);
|
|
867
|
-
return Array.from(kinds);
|
|
868
|
-
}
|
|
869
|
-
};
|
|
870
|
-
}
|
|
803
|
+
import {
|
|
804
|
+
CARDS_FAMILY_CUSTOM_BLOCK_KEY as CARDS_FAMILY_CUSTOM_BLOCK_KEY2,
|
|
805
|
+
runtimeBlockRegistry
|
|
806
|
+
} from "@owomark/core";
|
|
807
|
+
|
|
808
|
+
// src/renderer/side-annotation-renderer.ts
|
|
809
|
+
import { SIDE_ANNOTATION_RENDERER_KEY_BY_TYPE } from "@owomark/core/semantic/syntax";
|
|
871
810
|
|
|
872
811
|
// src/renderer/default-renderer.ts
|
|
873
812
|
function escapeHtml(text) {
|
|
@@ -877,6 +816,39 @@ var SAFE_URL_PATTERN = /^(?:https?:|mailto:|#|\/)/i;
|
|
|
877
816
|
function sanitizeUrl(url) {
|
|
878
817
|
return SAFE_URL_PATTERN.test(url) ? url : "";
|
|
879
818
|
}
|
|
819
|
+
function stripCommonBlockquotePrefixes(raw) {
|
|
820
|
+
let lines = raw.split("\n");
|
|
821
|
+
let depth = 0;
|
|
822
|
+
while (lines.length > 0 && lines.every((line) => line.trim() === "" || /^ {0,3}>\s?/.test(line))) {
|
|
823
|
+
lines = lines.map((line) => line.trim() === "" ? line : line.replace(/^ {0,3}>\s?/, ""));
|
|
824
|
+
depth += 1;
|
|
825
|
+
}
|
|
826
|
+
return {
|
|
827
|
+
depth,
|
|
828
|
+
content: lines.join("\n")
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
function wrapInBlockquotes(content, depth) {
|
|
832
|
+
let wrapped = content;
|
|
833
|
+
for (let index = 0; index < depth; index += 1) {
|
|
834
|
+
wrapped = `<blockquote>${wrapped}</blockquote>`;
|
|
835
|
+
}
|
|
836
|
+
return wrapped;
|
|
837
|
+
}
|
|
838
|
+
function extractHeadingText(raw) {
|
|
839
|
+
const { depth, content } = stripCommonBlockquotePrefixes(raw);
|
|
840
|
+
const setextMatch = content.match(/^([^\n]+)\n {0,3}(?:=+|-+)\s*$/);
|
|
841
|
+
if (setextMatch) {
|
|
842
|
+
return {
|
|
843
|
+
depth,
|
|
844
|
+
text: setextMatch[1]
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
return {
|
|
848
|
+
depth,
|
|
849
|
+
text: content.replace(/^#{1,6}\s*/, "")
|
|
850
|
+
};
|
|
851
|
+
}
|
|
880
852
|
function renderInline(text) {
|
|
881
853
|
let html = escapeHtml(text);
|
|
882
854
|
html = html.replace(/`([^`]+)`/g, "<code>$1</code>");
|
|
@@ -897,8 +869,8 @@ function renderBlockDefault(block) {
|
|
|
897
869
|
}
|
|
898
870
|
case "heading": {
|
|
899
871
|
const level = block.headingLevel ?? 1;
|
|
900
|
-
const text = block.raw
|
|
901
|
-
return `<h${level}>${renderInline(text)}</h${level}
|
|
872
|
+
const { depth, text } = extractHeadingText(block.raw);
|
|
873
|
+
return wrapInBlockquotes(`<h${level}>${renderInline(text)}</h${level}>`, depth);
|
|
902
874
|
}
|
|
903
875
|
case "code-fence": {
|
|
904
876
|
const lines = block.raw.split("\n");
|
|
@@ -940,6 +912,409 @@ function renderBlockDefault(block) {
|
|
|
940
912
|
}
|
|
941
913
|
}
|
|
942
914
|
|
|
915
|
+
// src/renderer/side-annotation-renderer.ts
|
|
916
|
+
function escapeHtml2(text) {
|
|
917
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
918
|
+
}
|
|
919
|
+
function escapeAttribute(text) {
|
|
920
|
+
return escapeHtml2(text).replace(/'/g, "'");
|
|
921
|
+
}
|
|
922
|
+
function svgSegment(className, width, height, body, extraAttrs = "") {
|
|
923
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}" class="${className}"${extraAttrs}>${body}</svg>`;
|
|
924
|
+
}
|
|
925
|
+
function stretchLineDiv() {
|
|
926
|
+
return '<div class="side-svg-line"></div>';
|
|
927
|
+
}
|
|
928
|
+
function segmented(width, axisPx, segments, extraClass = "") {
|
|
929
|
+
const className = ["side-annotation-svg", "side-svg-segmented", extraClass].filter(Boolean).join(" ");
|
|
930
|
+
return `<div class="${className}" style="width:${width};--side-svg-axis:${axisPx}px">${segments.join("")}</div>`;
|
|
931
|
+
}
|
|
932
|
+
function svgPath(d, extra = "") {
|
|
933
|
+
return `<path d="${d}" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"${extra}></path>`;
|
|
934
|
+
}
|
|
935
|
+
function svgLine(x1, y1, x2, y2, extra = "") {
|
|
936
|
+
return `<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"${extra}></line>`;
|
|
937
|
+
}
|
|
938
|
+
function svgPolyline(points, extra = "") {
|
|
939
|
+
return `<polyline points="${points}" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="square" stroke-linejoin="miter" shape-rendering="geometricPrecision"${extra}></polyline>`;
|
|
940
|
+
}
|
|
941
|
+
function makeSvgForSideType(sideType, orphan) {
|
|
942
|
+
const rendererKey = SIDE_ANNOTATION_RENDERER_KEY_BY_TYPE[sideType] ?? sideType;
|
|
943
|
+
if (orphan) {
|
|
944
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="4" viewBox="0 0 4 100" preserveAspectRatio="none" class="side-annotation-svg side-svg-vline">${svgLine(2, "2", 2, "98", ' vector-effect="non-scaling-stroke"')}</svg>`;
|
|
945
|
+
}
|
|
946
|
+
switch (rendererKey) {
|
|
947
|
+
case "brace":
|
|
948
|
+
return segmented("12px", 6, [
|
|
949
|
+
svgSegment("side-svg-cap", 12, 6, svgPath("M 1 0.75 C 3.5 0.75, 6 2.5, 6 5.25")),
|
|
950
|
+
stretchLineDiv(),
|
|
951
|
+
svgSegment("side-svg-beak", 12, 8, svgPath("M 6 0 C 6 2.5, 11 4, 11 4 C 11 4, 6 5.5, 6 8")),
|
|
952
|
+
stretchLineDiv(),
|
|
953
|
+
svgSegment("side-svg-cap", 12, 6, svgPath("M 6 0.75 C 6 3.5, 3.5 5.25, 1 5.25"))
|
|
954
|
+
]);
|
|
955
|
+
case "left-brace":
|
|
956
|
+
return segmented("12px", 6, [
|
|
957
|
+
svgSegment("side-svg-cap", 12, 6, svgPath("M 11 0.75 C 8.5 0.75, 6 2.5, 6 5.25")),
|
|
958
|
+
stretchLineDiv(),
|
|
959
|
+
svgSegment("side-svg-beak", 12, 8, svgPath("M 6 0 C 6 2.5, 1 4, 1 4 C 1 4, 6 5.5, 6 8")),
|
|
960
|
+
stretchLineDiv(),
|
|
961
|
+
svgSegment("side-svg-cap", 12, 6, svgPath("M 6 0.75 C 6 3.5, 8.5 5.25, 11 5.25"))
|
|
962
|
+
]);
|
|
963
|
+
case "bracket":
|
|
964
|
+
return segmented("8px", 4, [
|
|
965
|
+
svgSegment("side-svg-cap", 8, 6, svgPolyline("1,0.75 4,0.75 4,5.25")),
|
|
966
|
+
stretchLineDiv(),
|
|
967
|
+
svgSegment("side-svg-cap", 8, 6, svgPolyline("4,0.75 4,5.25 1,5.25"))
|
|
968
|
+
], "side-svg-bracket");
|
|
969
|
+
case "left-bracket":
|
|
970
|
+
return segmented("8px", 4, [
|
|
971
|
+
svgSegment("side-svg-cap", 8, 6, svgPolyline("7,0.75 4,0.75 4,5.25")),
|
|
972
|
+
stretchLineDiv(),
|
|
973
|
+
svgSegment("side-svg-cap", 8, 6, svgPolyline("4,0.75 4,5.25 7,5.25"))
|
|
974
|
+
], "side-svg-left-bracket");
|
|
975
|
+
case "line":
|
|
976
|
+
case "warning":
|
|
977
|
+
case "question":
|
|
978
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="4" viewBox="0 0 4 100" preserveAspectRatio="none" class="side-annotation-svg side-svg-vline">${svgLine(2, "2", 2, "98", ' vector-effect="non-scaling-stroke"')}</svg>`;
|
|
979
|
+
case "dash":
|
|
980
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="4" viewBox="0 0 20 4" class="side-annotation-svg side-svg-dash">${svgLine(1, "2", 19, "2")}</svg>`;
|
|
981
|
+
case "arrow":
|
|
982
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="16" viewBox="0 0 24 16" class="side-annotation-svg side-svg-arrow">${svgPath("M 1 8 L 20 8 M 16 3 L 21 8 L 16 13")}</svg>`;
|
|
983
|
+
case "fat-arrow":
|
|
984
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="16" viewBox="0 0 24 16" class="side-annotation-svg side-svg-fat-arrow">${svgPath("M 1 5 L 16 5 M 1 11 L 16 11 M 15 2 L 22 8 L 15 14")}</svg>`;
|
|
985
|
+
case "wave-arrow":
|
|
986
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="28" height="16" viewBox="0 0 28 16" class="side-annotation-svg side-svg-wave-arrow">${svgPath("M 1 8 C 4 3, 8 13, 12 8 C 16 3, 20 8, 20 8 M 18 3 L 23 8 L 18 13")}</svg>`;
|
|
987
|
+
case "brace-arrow":
|
|
988
|
+
return segmented("12px", 6, [
|
|
989
|
+
svgSegment("side-svg-cap", 12, 6, svgPath("M 1 0.75 C 3.5 0.75, 6 2.5, 6 5.25")),
|
|
990
|
+
stretchLineDiv(),
|
|
991
|
+
svgSegment("side-svg-beak", 12, 8, `${svgLine(6, "0", 6, "8", ' stroke-linecap="square" shape-rendering="geometricPrecision"')}${svgPath("M 6 4 L 19 4 M 16 1.5 L 20 4 L 16 6.5")}`, ' overflow="visible"'),
|
|
992
|
+
stretchLineDiv(),
|
|
993
|
+
svgSegment("side-svg-cap", 12, 6, svgPath("M 6 0.75 C 6 3.5, 3.5 5.25, 1 5.25"))
|
|
994
|
+
], "side-svg-compound-arrow");
|
|
995
|
+
case "brace-fat-arrow":
|
|
996
|
+
return segmented("12px", 6, [
|
|
997
|
+
svgSegment("side-svg-cap", 12, 6, svgPath("M 1 0.75 C 3.5 0.75, 6 2.5, 6 5.25")),
|
|
998
|
+
stretchLineDiv(),
|
|
999
|
+
svgSegment("side-svg-beak", 12, 8, `${svgLine(6, "0", 6, "8", ' stroke-linecap="square" shape-rendering="geometricPrecision"')}${svgPath("M 6 2.5 L 14 2.5 M 6 5.5 L 14 5.5 M 13 0.5 L 18 4 L 13 7.5")}`, ' overflow="visible"'),
|
|
1000
|
+
stretchLineDiv(),
|
|
1001
|
+
svgSegment("side-svg-cap", 12, 6, svgPath("M 6 0.75 C 6 3.5, 3.5 5.25, 1 5.25"))
|
|
1002
|
+
], "side-svg-compound-arrow");
|
|
1003
|
+
case "bracket-arrow":
|
|
1004
|
+
return segmented("8px", 4, [
|
|
1005
|
+
svgSegment("side-svg-cap", 8, 6, svgPolyline("1,0.75 4,0.75 4,5.25")),
|
|
1006
|
+
stretchLineDiv(),
|
|
1007
|
+
svgSegment("side-svg-beak", 8, 8, `${svgLine(4, "0", 4, "8", ' stroke-linecap="square" shape-rendering="geometricPrecision"')}${svgPath("M 4 4 L 17 4 M 14 1.5 L 18 4 L 14 6.5")}`, ' overflow="visible"'),
|
|
1008
|
+
stretchLineDiv(),
|
|
1009
|
+
svgSegment("side-svg-cap", 8, 6, svgPolyline("4,0.75 4,5.25 1,5.25"))
|
|
1010
|
+
], "side-svg-bracket side-svg-compound-arrow");
|
|
1011
|
+
case "bracket-fat-arrow":
|
|
1012
|
+
return segmented("8px", 4, [
|
|
1013
|
+
svgSegment("side-svg-cap", 8, 6, svgPolyline("1,0.75 4,0.75 4,5.25")),
|
|
1014
|
+
stretchLineDiv(),
|
|
1015
|
+
svgSegment("side-svg-beak", 8, 8, `${svgLine(4, "0", 4, "8", ' stroke-linecap="square" shape-rendering="geometricPrecision"')}${svgPath("M 4 2.5 L 13 2.5 M 4 5.5 L 13 5.5 M 12 0.5 L 17 4 L 12 7.5")}`, ' overflow="visible"'),
|
|
1016
|
+
stretchLineDiv(),
|
|
1017
|
+
svgSegment("side-svg-cap", 8, 6, svgPolyline("4,0.75 4,5.25 1,5.25"))
|
|
1018
|
+
], "side-svg-bracket side-svg-compound-arrow");
|
|
1019
|
+
case "line-arrow":
|
|
1020
|
+
return segmented("4px", 2, [
|
|
1021
|
+
stretchLineDiv(),
|
|
1022
|
+
svgSegment("side-svg-beak", 4, 8, `${svgLine(2, "0", 2, "8", ' stroke-linecap="square" shape-rendering="geometricPrecision"')}${svgPath("M 2 4 L 15 4 M 12 1.5 L 16 4 L 12 6.5")}`, ' overflow="visible"'),
|
|
1023
|
+
stretchLineDiv()
|
|
1024
|
+
], "side-svg-compound-arrow");
|
|
1025
|
+
case "line-fat-arrow":
|
|
1026
|
+
return segmented("4px", 2, [
|
|
1027
|
+
stretchLineDiv(),
|
|
1028
|
+
svgSegment("side-svg-beak", 4, 8, `${svgLine(2, "0", 2, "8", ' stroke-linecap="square" shape-rendering="geometricPrecision"')}${svgPath("M 2 2.5 L 11 2.5 M 2 5.5 L 11 5.5 M 10 0.5 L 15 4 L 10 7.5")}`, ' overflow="visible"'),
|
|
1029
|
+
stretchLineDiv()
|
|
1030
|
+
], "side-svg-compound-arrow");
|
|
1031
|
+
case "brace-warning":
|
|
1032
|
+
case "brace-question":
|
|
1033
|
+
return makeSvgForSideType("brace", false);
|
|
1034
|
+
default:
|
|
1035
|
+
return "";
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
function toPreviewKind(type) {
|
|
1039
|
+
switch (type) {
|
|
1040
|
+
case "heading":
|
|
1041
|
+
return "heading";
|
|
1042
|
+
case "unordered-list":
|
|
1043
|
+
return "unordered-list";
|
|
1044
|
+
case "ordered-list":
|
|
1045
|
+
return "ordered-list";
|
|
1046
|
+
case "blockquote":
|
|
1047
|
+
return "blockquote";
|
|
1048
|
+
case "code-fence":
|
|
1049
|
+
return "code-fence";
|
|
1050
|
+
case "thematic-break":
|
|
1051
|
+
return "thematic-break";
|
|
1052
|
+
case "math-block":
|
|
1053
|
+
return "math-block";
|
|
1054
|
+
case "table":
|
|
1055
|
+
return "table";
|
|
1056
|
+
case "html-block":
|
|
1057
|
+
return "html-block";
|
|
1058
|
+
default:
|
|
1059
|
+
return "paragraph";
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
function renderMainBlocks(block) {
|
|
1063
|
+
const rawMembers = Array.isArray(block.attributes?.mainBlocks) ? block.attributes?.mainBlocks : [];
|
|
1064
|
+
return rawMembers.map((entry, index) => {
|
|
1065
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
1066
|
+
return "";
|
|
1067
|
+
}
|
|
1068
|
+
const type = typeof entry.type === "string" ? entry.type : "paragraph";
|
|
1069
|
+
const raw = typeof entry.raw === "string" ? entry.raw : "";
|
|
1070
|
+
const memberBlock = {
|
|
1071
|
+
blockId: `${block.blockId}:member:${index}`,
|
|
1072
|
+
kind: toPreviewKind(type),
|
|
1073
|
+
raw,
|
|
1074
|
+
startLine: block.startLine,
|
|
1075
|
+
endLine: block.endLine,
|
|
1076
|
+
renderKey: `${block.renderKey}:member:${index}`
|
|
1077
|
+
};
|
|
1078
|
+
if (type === "heading" && typeof entry.headingLevel === "number") {
|
|
1079
|
+
memberBlock.headingLevel = entry.headingLevel;
|
|
1080
|
+
}
|
|
1081
|
+
if (type === "code-fence" && typeof entry.language === "string") {
|
|
1082
|
+
memberBlock.language = entry.language;
|
|
1083
|
+
}
|
|
1084
|
+
return renderBlockDefault(memberBlock);
|
|
1085
|
+
}).join("");
|
|
1086
|
+
}
|
|
1087
|
+
function isSideAnnotationPreviewBlock(block) {
|
|
1088
|
+
return block.kind === "custom" && block.attributes?.customBlockKey === "side-annotation";
|
|
1089
|
+
}
|
|
1090
|
+
function renderSideAnnotationPreviewBlock(block) {
|
|
1091
|
+
if (!isSideAnnotationPreviewBlock(block)) {
|
|
1092
|
+
return `<div>${escapeHtml2(block.raw)}</div>`;
|
|
1093
|
+
}
|
|
1094
|
+
const sideType = typeof block.attributes?.sideType === "string" ? block.attributes.sideType : "plain";
|
|
1095
|
+
const annotationText = typeof block.attributes?.annotationText === "string" ? block.attributes.annotationText : "";
|
|
1096
|
+
const orphan = Boolean(block.attributes?.orphan);
|
|
1097
|
+
const className = ["side-annotation", `side-type-${sideType}`, orphan ? "side-orphan" : ""].filter(Boolean).join(" ");
|
|
1098
|
+
const asideClass = ["side-annotation-aside", orphan ? "side-annotation-orphan" : ""].filter(Boolean).join(" ");
|
|
1099
|
+
const decoration = makeSvgForSideType(sideType, orphan);
|
|
1100
|
+
const mainHtml = renderMainBlocks(block);
|
|
1101
|
+
const textHtml = annotationText ? `<span class="side-annotation-text">${escapeHtml2(annotationText)}</span>` : "";
|
|
1102
|
+
return [
|
|
1103
|
+
`<div class="${className}" data-side-type="${escapeAttribute(sideType)}"${orphan ? ' data-side-orphan="true"' : ""}${annotationText ? ` data-side-text="${escapeAttribute(annotationText)}"` : ""}>`,
|
|
1104
|
+
`<div class="side-annotation-main">${mainHtml}</div>`,
|
|
1105
|
+
`<div class="${asideClass}">${decoration}${textHtml}</div>`,
|
|
1106
|
+
"</div>"
|
|
1107
|
+
].join("");
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// src/renderer/cards-renderer.ts
|
|
1111
|
+
import {
|
|
1112
|
+
CARDS_FAMILY_CUSTOM_BLOCK_KEY,
|
|
1113
|
+
isCardsFamilyAttributes,
|
|
1114
|
+
parseMarkdownToDocument
|
|
1115
|
+
} from "@owomark/core";
|
|
1116
|
+
function escapeHtml3(text) {
|
|
1117
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1118
|
+
}
|
|
1119
|
+
function isCardsFamilyPreviewBlock(block) {
|
|
1120
|
+
return block.kind === "custom" && block.attributes?.customBlockKey === CARDS_FAMILY_CUSTOM_BLOCK_KEY && isCardsFamilyAttributes(block.attributes);
|
|
1121
|
+
}
|
|
1122
|
+
function renderCardBody(markdown) {
|
|
1123
|
+
if (!markdown.trim()) {
|
|
1124
|
+
return "";
|
|
1125
|
+
}
|
|
1126
|
+
const nestedBlocks = parseMarkdownToDocument(markdown).previewBlocks;
|
|
1127
|
+
return nestedBlocks.map((nestedBlock) => {
|
|
1128
|
+
if (isCardsFamilyPreviewBlock(nestedBlock)) {
|
|
1129
|
+
return renderCardsFamilyPreviewBlock(nestedBlock);
|
|
1130
|
+
}
|
|
1131
|
+
if (nestedBlock.kind === "custom" && nestedBlock.attributes?.customBlockKey === "side-annotation") {
|
|
1132
|
+
return renderSideAnnotationPreviewBlock(nestedBlock);
|
|
1133
|
+
}
|
|
1134
|
+
return renderBlockDefault(nestedBlock);
|
|
1135
|
+
}).join("");
|
|
1136
|
+
}
|
|
1137
|
+
function renderCardsFamilyPreviewBlock(block) {
|
|
1138
|
+
if (!isCardsFamilyPreviewBlock(block)) {
|
|
1139
|
+
throw new Error("[owomark/view] cards renderer requires a cards-family preview block");
|
|
1140
|
+
}
|
|
1141
|
+
const attributes = block.attributes;
|
|
1142
|
+
const cardsHtml = attributes.cards.map((card) => {
|
|
1143
|
+
const toneAttr = card.tone ? ` data-owo-card-tone="${card.tone}"` : "";
|
|
1144
|
+
const toneClass = card.tone ? ` owo-card-tone-${card.tone}` : "";
|
|
1145
|
+
const titleHtml = card.title ? `<header class="owo-card-title">${escapeHtml3(card.title)}</header>` : "";
|
|
1146
|
+
const bodyHtml = renderCardBody(card.bodyMarkdown);
|
|
1147
|
+
return [
|
|
1148
|
+
`<article class="owo-card${toneClass}" data-owo-card${toneAttr}>`,
|
|
1149
|
+
titleHtml,
|
|
1150
|
+
`<div class="owo-card-body">${bodyHtml}</div>`,
|
|
1151
|
+
"</article>"
|
|
1152
|
+
].join("");
|
|
1153
|
+
}).join("");
|
|
1154
|
+
return [
|
|
1155
|
+
`<section class="owo-cards" data-owo-cards data-owo-cards-cols="${attributes.layout.cols}">`,
|
|
1156
|
+
cardsHtml,
|
|
1157
|
+
"</section>"
|
|
1158
|
+
].join("");
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
// src/renderer/registry.ts
|
|
1162
|
+
function normalizeTarget(target) {
|
|
1163
|
+
const normalized = {
|
|
1164
|
+
kind: target.kind,
|
|
1165
|
+
customBlockKey: target.customBlockKey ?? null
|
|
1166
|
+
};
|
|
1167
|
+
if (normalized.kind === "custom" && !normalized.customBlockKey) {
|
|
1168
|
+
throw new Error("[owomark/view] custom renderer targets must declare customBlockKey");
|
|
1169
|
+
}
|
|
1170
|
+
return normalized;
|
|
1171
|
+
}
|
|
1172
|
+
function resolveTargetFromLookup(lookup) {
|
|
1173
|
+
if ("blockId" in lookup) {
|
|
1174
|
+
const block = lookup;
|
|
1175
|
+
if (block.kind === "custom") {
|
|
1176
|
+
const customBlockKey = typeof block.attributes?.customBlockKey === "string" ? block.attributes.customBlockKey : null;
|
|
1177
|
+
if (!customBlockKey) {
|
|
1178
|
+
return {
|
|
1179
|
+
kind: "custom",
|
|
1180
|
+
customBlockKey: null
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
return {
|
|
1184
|
+
kind: "custom",
|
|
1185
|
+
customBlockKey
|
|
1186
|
+
};
|
|
1187
|
+
}
|
|
1188
|
+
return {
|
|
1189
|
+
kind: block.kind
|
|
1190
|
+
};
|
|
1191
|
+
}
|
|
1192
|
+
return normalizeTarget(lookup);
|
|
1193
|
+
}
|
|
1194
|
+
function toSpecificKey(target) {
|
|
1195
|
+
return target.kind === "custom" ? `custom:${target.customBlockKey}` : `kind:${target.kind}`;
|
|
1196
|
+
}
|
|
1197
|
+
function createRendererRegistry() {
|
|
1198
|
+
const renderers = /* @__PURE__ */ new Map();
|
|
1199
|
+
const metadata = /* @__PURE__ */ new Map();
|
|
1200
|
+
const targets = /* @__PURE__ */ new Map();
|
|
1201
|
+
for (const descriptor of runtimeBlockRegistry.list()) {
|
|
1202
|
+
const target = {
|
|
1203
|
+
kind: descriptor.previewKind,
|
|
1204
|
+
customBlockKey: descriptor.customBlockKey ?? null
|
|
1205
|
+
};
|
|
1206
|
+
const key = toSpecificKey(target);
|
|
1207
|
+
metadata.set(key, {
|
|
1208
|
+
mode: descriptor.rendererMode,
|
|
1209
|
+
priority: descriptor.rendererPriority,
|
|
1210
|
+
heavy: descriptor.heavy
|
|
1211
|
+
});
|
|
1212
|
+
targets.set(key, target);
|
|
1213
|
+
}
|
|
1214
|
+
renderers.set("custom:side-annotation", {
|
|
1215
|
+
mode: metadata.get("custom:side-annotation")?.mode ?? "html-worker-safe",
|
|
1216
|
+
priority: metadata.get("custom:side-annotation")?.priority ?? "realtime",
|
|
1217
|
+
version: "builtin-side-annotation-v1",
|
|
1218
|
+
workerRendererId: "builtin:side-annotation",
|
|
1219
|
+
render(block) {
|
|
1220
|
+
return {
|
|
1221
|
+
kind: "html",
|
|
1222
|
+
html: renderSideAnnotationPreviewBlock(block)
|
|
1223
|
+
};
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
targets.set("custom:side-annotation", {
|
|
1227
|
+
kind: "custom",
|
|
1228
|
+
customBlockKey: "side-annotation"
|
|
1229
|
+
});
|
|
1230
|
+
renderers.set(`custom:${CARDS_FAMILY_CUSTOM_BLOCK_KEY2}`, {
|
|
1231
|
+
mode: "html-worker-safe",
|
|
1232
|
+
priority: "realtime",
|
|
1233
|
+
version: "builtin-cards-family-v1",
|
|
1234
|
+
render(block) {
|
|
1235
|
+
return {
|
|
1236
|
+
kind: "html",
|
|
1237
|
+
html: renderCardsFamilyPreviewBlock(block)
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
1241
|
+
metadata.set(`custom:${CARDS_FAMILY_CUSTOM_BLOCK_KEY2}`, {
|
|
1242
|
+
mode: "html-worker-safe",
|
|
1243
|
+
priority: "realtime"
|
|
1244
|
+
});
|
|
1245
|
+
targets.set(`custom:${CARDS_FAMILY_CUSTOM_BLOCK_KEY2}`, {
|
|
1246
|
+
kind: "custom",
|
|
1247
|
+
customBlockKey: CARDS_FAMILY_CUSTOM_BLOCK_KEY2
|
|
1248
|
+
});
|
|
1249
|
+
function getMetadata(target) {
|
|
1250
|
+
if (target.kind === "custom" && !target.customBlockKey) {
|
|
1251
|
+
return null;
|
|
1252
|
+
}
|
|
1253
|
+
const specificKey = toSpecificKey(target);
|
|
1254
|
+
return metadata.get(specificKey) ?? null;
|
|
1255
|
+
}
|
|
1256
|
+
function getRenderer(target) {
|
|
1257
|
+
if (target.kind === "custom" && !target.customBlockKey) {
|
|
1258
|
+
return null;
|
|
1259
|
+
}
|
|
1260
|
+
const specificKey = toSpecificKey(target);
|
|
1261
|
+
return renderers.get(specificKey) ?? null;
|
|
1262
|
+
}
|
|
1263
|
+
return {
|
|
1264
|
+
get(lookup) {
|
|
1265
|
+
return getRenderer(resolveTargetFromLookup(lookup));
|
|
1266
|
+
},
|
|
1267
|
+
register(targetLike, renderer) {
|
|
1268
|
+
const target = normalizeTarget(targetLike);
|
|
1269
|
+
const key = toSpecificKey(target);
|
|
1270
|
+
renderers.set(key, renderer);
|
|
1271
|
+
targets.set(key, target);
|
|
1272
|
+
if (!metadata.has(key)) {
|
|
1273
|
+
metadata.set(key, {
|
|
1274
|
+
mode: renderer.mode,
|
|
1275
|
+
priority: renderer.priority
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1278
|
+
},
|
|
1279
|
+
unregister(targetLike) {
|
|
1280
|
+
const key = toSpecificKey(normalizeTarget(targetLike));
|
|
1281
|
+
renderers.delete(key);
|
|
1282
|
+
},
|
|
1283
|
+
registerMetadata(targetLike, meta) {
|
|
1284
|
+
const target = normalizeTarget(targetLike);
|
|
1285
|
+
const key = toSpecificKey(target);
|
|
1286
|
+
metadata.set(key, meta);
|
|
1287
|
+
targets.set(key, target);
|
|
1288
|
+
},
|
|
1289
|
+
isHeavy(lookup) {
|
|
1290
|
+
const target = resolveTargetFromLookup(lookup);
|
|
1291
|
+
const meta = getMetadata(target);
|
|
1292
|
+
if (meta?.heavy) return true;
|
|
1293
|
+
const def = getRenderer(target);
|
|
1294
|
+
return def?.priority === "deferred" || false;
|
|
1295
|
+
},
|
|
1296
|
+
getMode(lookup) {
|
|
1297
|
+
const target = resolveTargetFromLookup(lookup);
|
|
1298
|
+
const def = getRenderer(target);
|
|
1299
|
+
if (def) return def.mode;
|
|
1300
|
+
return getMetadata(target)?.mode ?? null;
|
|
1301
|
+
},
|
|
1302
|
+
getPriority(lookup) {
|
|
1303
|
+
const target = resolveTargetFromLookup(lookup);
|
|
1304
|
+
const def = getRenderer(target);
|
|
1305
|
+
if (def) return def.priority;
|
|
1306
|
+
return getMetadata(target)?.priority ?? null;
|
|
1307
|
+
},
|
|
1308
|
+
listRegistered() {
|
|
1309
|
+
const keys = /* @__PURE__ */ new Set([
|
|
1310
|
+
...renderers.keys(),
|
|
1311
|
+
...metadata.keys()
|
|
1312
|
+
]);
|
|
1313
|
+
return Array.from(keys).map((key) => targets.get(key)).filter((target) => target != null);
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
|
|
943
1318
|
// src/strategies/shared.ts
|
|
944
1319
|
var scheduleIdle = typeof globalThis.requestIdleCallback === "function" ? (fn) => globalThis.requestIdleCallback(fn) : (fn) => setTimeout(fn, 1);
|
|
945
1320
|
var cancelIdle = typeof globalThis.cancelIdleCallback === "function" ? (id) => globalThis.cancelIdleCallback(id) : (id) => clearTimeout(id);
|
|
@@ -970,7 +1345,7 @@ function cancelAllIdle(pendingIdleIds) {
|
|
|
970
1345
|
pendingIdleIds.length = 0;
|
|
971
1346
|
}
|
|
972
1347
|
function isDeferred(block, registry) {
|
|
973
|
-
const def = registry.get(block
|
|
1348
|
+
const def = registry.get(block);
|
|
974
1349
|
return def?.priority === "deferred";
|
|
975
1350
|
}
|
|
976
1351
|
function createRenderBlockFull(registry, renderCache, externalRenderBlock, scheduler) {
|
|
@@ -979,9 +1354,14 @@ function createRenderBlockFull(registry, renderCache, externalRenderBlock, sched
|
|
|
979
1354
|
...baseContext,
|
|
980
1355
|
sourceLineOffset: block.startLine - 1
|
|
981
1356
|
};
|
|
982
|
-
|
|
1357
|
+
if (externalRenderBlock && block.kind === "custom") {
|
|
1358
|
+
const html2 = await externalRenderBlock(block, context);
|
|
1359
|
+
renderCache.set(block.renderKey, html2);
|
|
1360
|
+
return { kind: "html", html: html2 };
|
|
1361
|
+
}
|
|
1362
|
+
const customRenderer = registry.get(block);
|
|
983
1363
|
if (customRenderer) {
|
|
984
|
-
if (customRenderer.mode === "html-worker-safe" && customRenderer.
|
|
1364
|
+
if (customRenderer.mode === "html-worker-safe" && customRenderer.workerRendererId && scheduler) {
|
|
985
1365
|
try {
|
|
986
1366
|
const html2 = await scheduler.submitWorkerTask(block, customRenderer, context);
|
|
987
1367
|
renderCache.set(block.renderKey, html2);
|
|
@@ -1708,7 +2088,8 @@ function createPreviewTaskScheduler(options) {
|
|
|
1708
2088
|
}
|
|
1709
2089
|
const scheduler = {
|
|
1710
2090
|
submitWorkerTask(block, rendererDef, context) {
|
|
1711
|
-
|
|
2091
|
+
const rendererId = rendererDef.workerRendererId;
|
|
2092
|
+
if (permanentlyFailed || !rendererId) {
|
|
1712
2093
|
return Promise.reject(new Error("Worker unavailable"));
|
|
1713
2094
|
}
|
|
1714
2095
|
const slot = getLeastBusySlot();
|
|
@@ -1723,7 +2104,7 @@ function createPreviewTaskScheduler(options) {
|
|
|
1723
2104
|
type: "render",
|
|
1724
2105
|
taskId,
|
|
1725
2106
|
block: serializeBlock(block),
|
|
1726
|
-
|
|
2107
|
+
rendererId,
|
|
1727
2108
|
context: {
|
|
1728
2109
|
version: context.version,
|
|
1729
2110
|
themeKey: context.themeKey,
|
|
@@ -1879,7 +2260,6 @@ export {
|
|
|
1879
2260
|
THEME_DARK_CLASS,
|
|
1880
2261
|
THEME_LIGHT_CLASS,
|
|
1881
2262
|
createOwoMarkPreviewEngine,
|
|
1882
|
-
createOwoMarkVanillaEditor,
|
|
1883
2263
|
createOwoMarkView,
|
|
1884
2264
|
createPreviewTaskScheduler,
|
|
1885
2265
|
createRendererRegistry,
|
|
@@ -1887,5 +2267,9 @@ export {
|
|
|
1887
2267
|
createViewEngine,
|
|
1888
2268
|
ensureSkeletonStyles,
|
|
1889
2269
|
getThemeClassName,
|
|
1890
|
-
|
|
2270
|
+
isCardsFamilyPreviewBlock,
|
|
2271
|
+
isSideAnnotationPreviewBlock,
|
|
2272
|
+
renderBlockDefault,
|
|
2273
|
+
renderCardsFamilyPreviewBlock,
|
|
2274
|
+
renderSideAnnotationPreviewBlock
|
|
1891
2275
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PreviewBlock } from '@owomark/core';
|
|
2
|
-
import { P as PreviewRendererRegistry } from '../../types-
|
|
2
|
+
import { P as PreviewRendererRegistry } from '../../types-D4TVpyP7.js';
|
|
3
3
|
|
|
4
4
|
declare function estimateBlockHeight(block: PreviewBlock, registry?: PreviewRendererRegistry): number;
|
|
5
5
|
|