smartrte-core 0.2.1 → 1.0.0-beta.2
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 +16 -0
- package/README.md +23 -0
- package/dist/command.d.ts +8 -8
- package/dist/editor.d.ts +32 -0
- package/dist/editor.js +121 -0
- package/dist/foundation/annotations/index.d.ts +2 -0
- package/dist/foundation/annotations/index.js +2 -0
- package/dist/foundation/annotations/range.d.ts +54 -0
- package/dist/foundation/annotations/range.js +158 -0
- package/dist/foundation/annotations/types.d.ts +33 -0
- package/dist/foundation/annotations/types.js +1 -0
- package/dist/foundation/atom/commands.d.ts +11 -0
- package/dist/foundation/atom/commands.js +118 -0
- package/dist/foundation/atom/composition.d.ts +8 -0
- package/dist/foundation/atom/composition.js +22 -0
- package/dist/foundation/atom/declarations.d.ts +2 -0
- package/dist/foundation/atom/declarations.js +17 -0
- package/dist/foundation/atom/formats.d.ts +24 -0
- package/dist/foundation/atom/formats.js +105 -0
- package/dist/foundation/atom/index.d.ts +10 -0
- package/dist/foundation/atom/index.js +10 -0
- package/dist/foundation/atom/lifecycle.d.ts +12 -0
- package/dist/foundation/atom/lifecycle.js +41 -0
- package/dist/foundation/atom/persistence.d.ts +3 -0
- package/dist/foundation/atom/persistence.js +20 -0
- package/dist/foundation/atom/plugin.d.ts +20 -0
- package/dist/foundation/atom/plugin.js +55 -0
- package/dist/foundation/atom/schema.d.ts +3 -0
- package/dist/foundation/atom/schema.js +29 -0
- package/dist/foundation/atom/security.d.ts +10 -0
- package/dist/foundation/atom/security.js +20 -0
- package/dist/foundation/atom/selection.d.ts +3 -0
- package/dist/foundation/atom/selection.js +4 -0
- package/dist/foundation/atom/types.d.ts +47 -0
- package/dist/foundation/atom/types.js +1 -0
- package/dist/foundation/block/commands.d.ts +17 -0
- package/dist/foundation/block/commands.js +197 -0
- package/dist/foundation/block/formats.d.ts +33 -0
- package/dist/foundation/block/formats.js +57 -0
- package/dist/foundation/block/index.d.ts +5 -0
- package/dist/foundation/block/index.js +5 -0
- package/dist/foundation/block/input.d.ts +19 -0
- package/dist/foundation/block/input.js +67 -0
- package/dist/foundation/block/plugin.d.ts +26 -0
- package/dist/foundation/block/plugin.js +79 -0
- package/dist/foundation/block/schema.d.ts +49 -0
- package/dist/foundation/block/schema.js +27 -0
- package/dist/foundation/block/types.d.ts +40 -0
- package/dist/foundation/block/types.js +1 -0
- package/dist/foundation/boundaries.d.ts +11 -0
- package/dist/foundation/boundaries.js +117 -0
- package/dist/foundation/clipboard/detection.d.ts +3 -0
- package/dist/foundation/clipboard/detection.js +29 -0
- package/dist/foundation/clipboard/diagnostics.d.ts +24 -0
- package/dist/foundation/clipboard/diagnostics.js +59 -0
- package/dist/foundation/clipboard/index.d.ts +8 -0
- package/dist/foundation/clipboard/index.js +8 -0
- package/dist/foundation/clipboard/insertion.d.ts +22 -0
- package/dist/foundation/clipboard/insertion.js +210 -0
- package/dist/foundation/clipboard/normalizers.d.ts +8 -0
- package/dist/foundation/clipboard/normalizers.js +229 -0
- package/dist/foundation/clipboard/pipeline.d.ts +13 -0
- package/dist/foundation/clipboard/pipeline.js +58 -0
- package/dist/foundation/clipboard/sanitizer.d.ts +3 -0
- package/dist/foundation/clipboard/sanitizer.js +58 -0
- package/dist/foundation/clipboard/serialization.d.ts +5 -0
- package/dist/foundation/clipboard/serialization.js +33 -0
- package/dist/foundation/clipboard/transfer.d.ts +11 -0
- package/dist/foundation/clipboard/transfer.js +108 -0
- package/dist/foundation/clipboard/types.d.ts +65 -0
- package/dist/foundation/clipboard/types.js +1 -0
- package/dist/foundation/collab/index.d.ts +3 -0
- package/dist/foundation/collab/index.js +3 -0
- package/dist/foundation/collab/rebase.d.ts +28 -0
- package/dist/foundation/collab/rebase.js +82 -0
- package/dist/foundation/collab/transform.d.ts +73 -0
- package/dist/foundation/collab/transform.js +251 -0
- package/dist/foundation/collab/types.d.ts +52 -0
- package/dist/foundation/collab/types.js +1 -0
- package/dist/foundation/comments/fromSelection.d.ts +16 -0
- package/dist/foundation/comments/fromSelection.js +24 -0
- package/dist/foundation/comments/index.d.ts +3 -0
- package/dist/foundation/comments/index.js +3 -0
- package/dist/foundation/comments/rebase.d.ts +31 -0
- package/dist/foundation/comments/rebase.js +43 -0
- package/dist/foundation/comments/types.d.ts +37 -0
- package/dist/foundation/comments/types.js +1 -0
- package/dist/foundation/diff/documentDiff.d.ts +12 -0
- package/dist/foundation/diff/documentDiff.js +148 -0
- package/dist/foundation/diff/index.d.ts +3 -0
- package/dist/foundation/diff/index.js +3 -0
- package/dist/foundation/diff/textDiff.d.ts +12 -0
- package/dist/foundation/diff/textDiff.js +114 -0
- package/dist/foundation/diff/types.d.ts +74 -0
- package/dist/foundation/diff/types.js +1 -0
- package/dist/foundation/editor.d.ts +138 -0
- package/dist/foundation/editor.js +398 -0
- package/dist/foundation/formats/codec.d.ts +45 -0
- package/dist/foundation/formats/codec.js +1 -0
- package/dist/foundation/formats/docx/export.d.ts +4 -0
- package/dist/foundation/formats/docx/export.js +285 -0
- package/dist/foundation/formats/docx/import.d.ts +9 -0
- package/dist/foundation/formats/docx/import.js +37 -0
- package/dist/foundation/formats/docx/nestingGuard.d.ts +40 -0
- package/dist/foundation/formats/docx/nestingGuard.js +66 -0
- package/dist/foundation/formats/docx/portableAtoms.d.ts +4 -0
- package/dist/foundation/formats/docx/portableAtoms.js +66 -0
- package/dist/foundation/formats/docx/styledImport.d.ts +10 -0
- package/dist/foundation/formats/docx/styledImport.js +205 -0
- package/dist/foundation/formats/featureCodecs.d.ts +37 -0
- package/dist/foundation/formats/featureCodecs.js +69 -0
- package/dist/foundation/formats/fidelity.d.ts +31 -0
- package/dist/foundation/formats/fidelity.js +123 -0
- package/dist/foundation/formats/index.d.ts +7 -0
- package/dist/foundation/formats/index.js +7 -0
- package/dist/foundation/formats/pdf/format.d.ts +29 -0
- package/dist/foundation/formats/pdf/format.js +190 -0
- package/dist/foundation/history.d.ts +20 -0
- package/dist/foundation/history.js +121 -0
- package/dist/foundation/identity.d.ts +8 -0
- package/dist/foundation/identity.js +30 -0
- package/dist/foundation/index.d.ts +30 -0
- package/dist/foundation/index.js +30 -0
- package/dist/foundation/list/commands.d.ts +28 -0
- package/dist/foundation/list/commands.js +422 -0
- package/dist/foundation/list/formats.d.ts +21 -0
- package/dist/foundation/list/formats.js +813 -0
- package/dist/foundation/list/index.d.ts +8 -0
- package/dist/foundation/list/index.js +8 -0
- package/dist/foundation/list/input.d.ts +35 -0
- package/dist/foundation/list/input.js +320 -0
- package/dist/foundation/list/plugin.d.ts +21 -0
- package/dist/foundation/list/plugin.js +71 -0
- package/dist/foundation/list/presets.d.ts +16 -0
- package/dist/foundation/list/presets.js +21 -0
- package/dist/foundation/list/schema.d.ts +35 -0
- package/dist/foundation/list/schema.js +29 -0
- package/dist/foundation/list/shadow.d.ts +54 -0
- package/dist/foundation/list/shadow.js +75 -0
- package/dist/foundation/list/shadowCorpus.d.ts +10 -0
- package/dist/foundation/list/shadowCorpus.js +41 -0
- package/dist/foundation/list/types.d.ts +50 -0
- package/dist/foundation/list/types.js +1 -0
- package/dist/foundation/mapping.d.ts +11 -0
- package/dist/foundation/mapping.js +40 -0
- package/dist/foundation/marks/canonical.d.ts +9 -0
- package/dist/foundation/marks/canonical.js +72 -0
- package/dist/foundation/marks/commands.d.ts +21 -0
- package/dist/foundation/marks/commands.js +136 -0
- package/dist/foundation/marks/dom.d.ts +2 -0
- package/dist/foundation/marks/dom.js +46 -0
- package/dist/foundation/marks/editor.d.ts +8 -0
- package/dist/foundation/marks/editor.js +50 -0
- package/dist/foundation/marks/formats.d.ts +37 -0
- package/dist/foundation/marks/formats.js +49 -0
- package/dist/foundation/marks/hardBreak.d.ts +8 -0
- package/dist/foundation/marks/hardBreak.js +80 -0
- package/dist/foundation/marks/index.d.ts +11 -0
- package/dist/foundation/marks/index.js +11 -0
- package/dist/foundation/marks/normalization.d.ts +2 -0
- package/dist/foundation/marks/normalization.js +49 -0
- package/dist/foundation/marks/plugin.d.ts +14 -0
- package/dist/foundation/marks/plugin.js +63 -0
- package/dist/foundation/marks/resolveMarkRun.d.ts +8 -0
- package/dist/foundation/marks/resolveMarkRun.js +47 -0
- package/dist/foundation/marks/schema.d.ts +167 -0
- package/dist/foundation/marks/schema.js +50 -0
- package/dist/foundation/marks/stored.d.ts +2 -0
- package/dist/foundation/marks/stored.js +31 -0
- package/dist/foundation/marks/types.d.ts +40 -0
- package/dist/foundation/marks/types.js +1 -0
- package/dist/foundation/modelDom.d.ts +38 -0
- package/dist/foundation/modelDom.js +327 -0
- package/dist/foundation/normalization.d.ts +22 -0
- package/dist/foundation/normalization.js +132 -0
- package/dist/foundation/operations.d.ts +28 -0
- package/dist/foundation/operations.js +568 -0
- package/dist/foundation/plugin/builtins.d.ts +10 -0
- package/dist/foundation/plugin/builtins.js +27 -0
- package/dist/foundation/plugin/dispatch.d.ts +33 -0
- package/dist/foundation/plugin/dispatch.js +34 -0
- package/dist/foundation/plugin/index.d.ts +4 -0
- package/dist/foundation/plugin/index.js +4 -0
- package/dist/foundation/plugin/registry.d.ts +36 -0
- package/dist/foundation/plugin/registry.js +115 -0
- package/dist/foundation/plugin/types.d.ts +141 -0
- package/dist/foundation/plugin/types.js +13 -0
- package/dist/foundation/positions.d.ts +20 -0
- package/dist/foundation/positions.js +121 -0
- package/dist/foundation/schema.d.ts +57 -0
- package/dist/foundation/schema.js +371 -0
- package/dist/foundation/schemaBuilder.d.ts +41 -0
- package/dist/foundation/schemaBuilder.js +96 -0
- package/dist/foundation/scope/index.d.ts +2 -0
- package/dist/foundation/scope/index.js +2 -0
- package/dist/foundation/scope/resolveScope.d.ts +13 -0
- package/dist/foundation/scope/resolveScope.js +860 -0
- package/dist/foundation/scope/types.d.ts +122 -0
- package/dist/foundation/scope/types.js +1 -0
- package/dist/foundation/security/urlPolicy.d.ts +21 -0
- package/dist/foundation/security/urlPolicy.js +75 -0
- package/dist/foundation/structural/contentTarget.d.ts +21 -0
- package/dist/foundation/structural/contentTarget.js +51 -0
- package/dist/foundation/structural/index.d.ts +2 -0
- package/dist/foundation/structural/index.js +2 -0
- package/dist/foundation/structural/move.d.ts +7 -0
- package/dist/foundation/structural/move.js +35 -0
- package/dist/foundation/suggestions/index.d.ts +3 -0
- package/dist/foundation/suggestions/index.js +3 -0
- package/dist/foundation/suggestions/inline.d.ts +64 -0
- package/dist/foundation/suggestions/inline.js +116 -0
- package/dist/foundation/suggestions/structural.d.ts +40 -0
- package/dist/foundation/suggestions/structural.js +47 -0
- package/dist/foundation/suggestions/types.d.ts +19 -0
- package/dist/foundation/suggestions/types.js +1 -0
- package/dist/foundation/surface/index.d.ts +3 -0
- package/dist/foundation/surface/index.js +3 -0
- package/dist/foundation/surface/input.d.ts +127 -0
- package/dist/foundation/surface/input.js +1761 -0
- package/dist/foundation/surface/renderer.d.ts +84 -0
- package/dist/foundation/surface/renderer.js +974 -0
- package/dist/foundation/surface/types.d.ts +48 -0
- package/dist/foundation/surface/types.js +1 -0
- package/dist/foundation/table/commands.d.ts +31 -0
- package/dist/foundation/table/commands.js +470 -0
- package/dist/foundation/table/formats.d.ts +27 -0
- package/dist/foundation/table/formats.js +40 -0
- package/dist/foundation/table/grid.d.ts +8 -0
- package/dist/foundation/table/grid.js +178 -0
- package/dist/foundation/table/index.d.ts +6 -0
- package/dist/foundation/table/index.js +6 -0
- package/dist/foundation/table/plugin.d.ts +23 -0
- package/dist/foundation/table/plugin.js +119 -0
- package/dist/foundation/table/schema.d.ts +2 -0
- package/dist/foundation/table/schema.js +38 -0
- package/dist/foundation/table/selection.d.ts +7 -0
- package/dist/foundation/table/selection.js +35 -0
- package/dist/foundation/table/types.d.ts +109 -0
- package/dist/foundation/table/types.js +1 -0
- package/dist/foundation/transactions.d.ts +41 -0
- package/dist/foundation/transactions.js +90 -0
- package/dist/foundation/types.d.ts +261 -0
- package/dist/foundation/types.js +1 -0
- package/dist/foundation/versioning/diffVersions.d.ts +5 -0
- package/dist/foundation/versioning/diffVersions.js +3 -0
- package/dist/foundation/versioning/index.d.ts +2 -0
- package/dist/foundation/versioning/index.js +2 -0
- package/dist/foundation/versioning/types.d.ts +17 -0
- package/dist/foundation/versioning/types.js +1 -0
- package/dist/history.d.ts +20 -0
- package/dist/history.js +165 -0
- package/dist/html/compatibility.js +7 -1
- package/dist/index.d.ts +1 -14
- package/dist/index.js +9 -14
- package/dist/legacy/index.d.ts +45 -0
- package/dist/legacy/index.js +45 -0
- package/dist/legacyCommands/alignment.d.ts +20 -0
- package/dist/{commands → legacyCommands}/alignment.js +17 -0
- package/dist/legacyCommands/blocks.d.ts +14 -0
- package/dist/legacyCommands/blocks.js +105 -0
- package/dist/legacyCommands/checklist.d.ts +11 -0
- package/dist/legacyCommands/checklist.js +45 -0
- package/dist/legacyCommands/code.d.ts +15 -0
- package/dist/{commands → legacyCommands}/code.js +25 -1
- package/dist/legacyCommands/formula.d.ts +7 -0
- package/dist/legacyCommands/formula.js +67 -0
- package/dist/legacyCommands/inlineAtoms.d.ts +7 -0
- package/dist/legacyCommands/inlineAtoms.js +58 -0
- package/dist/legacyCommands/list.d.ts +38 -0
- package/dist/legacyCommands/list.js +477 -0
- package/dist/{commands → legacyCommands}/marks.d.ts +3 -0
- package/dist/{commands → legacyCommands}/marks.js +28 -11
- package/dist/legacyCommands/media.d.ts +31 -0
- package/dist/legacyCommands/media.js +205 -0
- package/dist/legacyCommands/move.d.ts +14 -0
- package/dist/legacyCommands/move.js +91 -0
- package/dist/legacyCommands/table.d.ts +91 -0
- package/dist/legacyCommands/table.js +547 -0
- package/dist/listPresets.d.ts +12 -0
- package/dist/listPresets.js +6 -0
- package/dist/listScope.d.ts +27 -0
- package/dist/listScope.js +104 -0
- package/dist/markdown/compatibility.d.ts +2 -0
- package/dist/markdown/compatibility.js +94 -2
- package/dist/marks.d.ts +5 -5
- package/dist/model.d.ts +65 -9
- package/dist/plugin.d.ts +15 -0
- package/dist/plugin.js +31 -0
- package/dist/plugins/alignment.d.ts +3 -0
- package/dist/plugins/alignment.js +6 -0
- package/dist/plugins/basicFormatting.d.ts +9 -0
- package/dist/plugins/basicFormatting.js +24 -0
- package/dist/plugins/blockType.d.ts +3 -0
- package/dist/plugins/blockType.js +6 -0
- package/dist/plugins/blockquote.d.ts +3 -0
- package/dist/plugins/blockquote.js +6 -0
- package/dist/plugins/checklist.d.ts +3 -0
- package/dist/plugins/checklist.js +10 -0
- package/dist/plugins/codeBlock.d.ts +3 -0
- package/dist/plugins/codeBlock.js +6 -0
- package/dist/plugins/formula.d.ts +3 -0
- package/dist/plugins/formula.js +9 -0
- package/dist/plugins/list.d.ts +3 -0
- package/dist/plugins/list.js +10 -0
- package/dist/plugins/media.d.ts +3 -0
- package/dist/plugins/media.js +12 -0
- package/dist/plugins/move.d.ts +3 -0
- package/dist/plugins/move.js +9 -0
- package/dist/plugins/table.d.ts +3 -0
- package/dist/plugins/table.js +22 -0
- package/dist/preset.d.ts +12 -0
- package/dist/preset.js +40 -0
- package/dist/schema.d.ts +22 -0
- package/dist/schema.js +333 -0
- package/dist/security/urlPolicy.d.ts +1 -17
- package/dist/security/urlPolicy.js +3 -69
- package/dist/selection.d.ts +1 -1
- package/dist/selectionMapping.d.ts +4 -0
- package/dist/selectionMapping.js +222 -0
- package/dist/table.d.ts +3 -3
- package/dist/transaction.d.ts +35 -12
- package/dist/transaction.js +174 -28
- package/dist/tree.d.ts +8 -2
- package/dist/tree.js +44 -0
- package/package.json +27 -8
- package/dist/commands/alignment.d.ts +0 -18
- package/dist/commands/code.d.ts +0 -13
- package/dist/commands/list.d.ts +0 -20
- package/dist/commands/list.js +0 -52
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { safeFormulaSource, sanitizeAtomSource } from "./security.js";
|
|
2
|
+
const positiveDimensions = (attrs) => [attrs.width, attrs.height].every((value) => value === undefined || Number.isFinite(value) && Number(value) > 0 && Number(value) <= 100000);
|
|
3
|
+
const imageValid = (attrs) => typeof attrs.alt === "string"
|
|
4
|
+
&& (attrs.alt.length > 0 || attrs.decorative === true)
|
|
5
|
+
&& positiveDimensions(attrs)
|
|
6
|
+
&& Boolean(sanitizeAtomSource(String(attrs.src || ""), { kind: "image", allowBlobPreview: attrs.status === "pending" }));
|
|
7
|
+
const formulaValid = (attrs) => safeFormulaSource(attrs.source) && (attrs.notation === "latex" || attrs.notation === "mathml");
|
|
8
|
+
const mediaValid = (kind) => (attrs) => positiveDimensions(attrs)
|
|
9
|
+
&& Boolean(sanitizeAtomSource(String(attrs.src || ""), { kind, allowBlobPreview: attrs.status === "pending" }));
|
|
10
|
+
export const atomDeclarations = [
|
|
11
|
+
{ type: "image", kind: "image", group: "inline", validate: imageValid },
|
|
12
|
+
{ type: "block_image", kind: "image", group: "block", validate: imageValid },
|
|
13
|
+
{ type: "formula", kind: "formula", group: "inline", validate: formulaValid },
|
|
14
|
+
{ type: "block_formula", kind: "formula", group: "block", validate: formulaValid },
|
|
15
|
+
{ type: "video", kind: "video", group: "block", validate: mediaValid("video") },
|
|
16
|
+
{ type: "audio", kind: "audio", group: "block", validate: mediaValid("audio") },
|
|
17
|
+
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import "katex/contrib/mhchem";
|
|
2
|
+
import type { SmartElementNode } from "../types.js";
|
|
3
|
+
export declare const atomToHtml: (node: SmartElementNode, options?: {
|
|
4
|
+
renderFormulaHtml?: boolean;
|
|
5
|
+
}) => string;
|
|
6
|
+
export declare const atomFromHtmlElement: (element: Element) => SmartElementNode | null;
|
|
7
|
+
export declare const atomToMarkdown: (node: SmartElementNode) => string;
|
|
8
|
+
export interface AtomDocxRun {
|
|
9
|
+
readonly kind: "image" | "text";
|
|
10
|
+
readonly source: string;
|
|
11
|
+
readonly alt?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Matches packages/core/src/foundation/formats/docx/export.ts's actual
|
|
15
|
+
* behavior (SS2.1): formulas are written as literal LaTeX text inside an
|
|
16
|
+
* <m:oMath> zone, not translated to real OMML and not rendered as an
|
|
17
|
+
* image. Word will show the raw LaTeX string, not typeset math - this is
|
|
18
|
+
* `kind: "text"`, not `"image"`, to describe that honestly.
|
|
19
|
+
*/
|
|
20
|
+
export declare const atomToDocx: (node: SmartElementNode) => AtomDocxRun;
|
|
21
|
+
export declare const atomToPdf: (node: SmartElementNode) => {
|
|
22
|
+
kind: "image" | "text";
|
|
23
|
+
value: string;
|
|
24
|
+
};
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import katex from "katex";
|
|
2
|
+
// Registers \ce{...} chemistry-equation notation on the shared katex module
|
|
3
|
+
// instance, matching surface/renderer.ts's own live-render import - a
|
|
4
|
+
// formula baked here via renderFormulaHtml must support the exact same
|
|
5
|
+
// notation the live editor does, or a chemistry entry would render live but
|
|
6
|
+
// fall back to plain text in the exported/baked HTML.
|
|
7
|
+
import "katex/contrib/mhchem";
|
|
8
|
+
import { createNodeId } from "../identity.js";
|
|
9
|
+
import { sanitizeAtomSource } from "./security.js";
|
|
10
|
+
const escape = (value) => String(value ?? "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
11
|
+
const attr = (name, value) => value === undefined ? "" : ` ${name}="${escape(value)}"`;
|
|
12
|
+
const dimensions = (node) => `${attr("width", node.attrs?.width)}${attr("height", node.attrs?.height)}`;
|
|
13
|
+
// Mirrors surface/renderer.ts's KATEX_OPTIONS and try/catch-to-plain-text
|
|
14
|
+
// fallback exactly - a formula that fails to render live must fail the same
|
|
15
|
+
// way when baked into exported HTML, not throw and abort the whole export.
|
|
16
|
+
const KATEX_OPTIONS = { trust: false, strict: "error" };
|
|
17
|
+
const renderFormulaToHtml = (source) => {
|
|
18
|
+
try {
|
|
19
|
+
return katex.renderToString(source, KATEX_OPTIONS);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return escape(source);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
export const atomToHtml = (node, options) => {
|
|
26
|
+
if (node.type === "image" || node.type === "block_image") {
|
|
27
|
+
const src = sanitizeAtomSource(String(node.attrs?.src || ""), { kind: "image", allowBlobPreview: node.attrs?.status === "pending" }) || "";
|
|
28
|
+
return `<img data-smart-id="${escape(node.id)}" data-smart-type="${node.type}" src="${escape(src)}" alt="${escape(node.attrs?.alt)}"${dimensions(node)}${attr("data-smart-status", node.attrs?.status || "ready")}${node.attrs?.decorative === true ? ' data-smart-decorative="true"' : ""}${attr("data-smart-align", node.attrs?.align)}>`;
|
|
29
|
+
}
|
|
30
|
+
if (node.type === "formula" || node.type === "block_formula") {
|
|
31
|
+
const tag = node.type === "formula" ? "span" : "div";
|
|
32
|
+
const source = String(node.attrs?.source || "");
|
|
33
|
+
// The rendered KaTeX HTML is purely a self-contained visual convenience
|
|
34
|
+
// for consumers that display this HTML string directly without also
|
|
35
|
+
// running katex.render() against it themselves (docs/bugs/
|
|
36
|
+
// formula-not-rendered-in-static-html-consumers.md) - data-smart-formula
|
|
37
|
+
// stays the single source of truth for round-tripping back into the
|
|
38
|
+
// model (list/formats.ts's parser reads the attribute, never this
|
|
39
|
+
// inner content), so baking this in can never desync source vs. render.
|
|
40
|
+
const inner = options?.renderFormulaHtml ? renderFormulaToHtml(source) : "";
|
|
41
|
+
return `<${tag} data-smart-id="${escape(node.id)}" data-smart-type="${node.type}" data-smart-notation="${escape(node.attrs?.notation || "latex")}" data-smart-formula="${escape(source)}" role="math" aria-label="${escape(`Mathematical formula: ${source}`)}">${inner}</${tag}>`;
|
|
42
|
+
}
|
|
43
|
+
if (node.type === "video" || node.type === "audio") {
|
|
44
|
+
const src = sanitizeAtomSource(String(node.attrs?.src || ""), { kind: node.type }) || "";
|
|
45
|
+
return `<${node.type} data-smart-id="${escape(node.id)}" data-smart-type="${node.type}" src="${escape(src)}" controls${dimensions(node)}${node.type === "video" ? attr("poster", node.attrs?.poster) : ""}></${node.type}>`;
|
|
46
|
+
}
|
|
47
|
+
if (node.type === "divider")
|
|
48
|
+
return `<hr data-smart-id="${escape(node.id)}" data-smart-type="divider">`;
|
|
49
|
+
throw new Error(`Unsupported atom type "${node.type}".`);
|
|
50
|
+
};
|
|
51
|
+
export const atomFromHtmlElement = (element) => {
|
|
52
|
+
const declared = element.getAttribute("data-smart-type");
|
|
53
|
+
const type = declared || (element.tagName === "IMG" ? "image" : element.tagName.toLowerCase());
|
|
54
|
+
const id = element.getAttribute("data-smart-id") || createNodeId();
|
|
55
|
+
const number = (name) => { const value = Number(element.getAttribute(name)); return Number.isFinite(value) && value > 0 ? value : undefined; };
|
|
56
|
+
if (type === "image" || type === "block_image") {
|
|
57
|
+
const src = sanitizeAtomSource(element.getAttribute("src"), { kind: "image" });
|
|
58
|
+
if (!src)
|
|
59
|
+
return null;
|
|
60
|
+
return { type, id, attrs: { src, alt: element.getAttribute("alt") || "", status: element.getAttribute("data-smart-status") || "ready", ...(element.getAttribute("data-smart-decorative") === "true" ? { decorative: true } : {}), ...(element.getAttribute("data-smart-align") ? { align: element.getAttribute("data-smart-align") } : {}), ...(number("width") ? { width: number("width") } : {}), ...(number("height") ? { height: number("height") } : {}) } };
|
|
61
|
+
}
|
|
62
|
+
if (type === "formula" || type === "block_formula") {
|
|
63
|
+
return { type, id, attrs: { source: element.getAttribute("data-smart-formula") || "", notation: element.getAttribute("data-smart-notation") === "mathml" ? "mathml" : "latex" } };
|
|
64
|
+
}
|
|
65
|
+
if (type === "video" || type === "audio") {
|
|
66
|
+
const src = sanitizeAtomSource(element.getAttribute("src"), { kind: type });
|
|
67
|
+
if (!src)
|
|
68
|
+
return null;
|
|
69
|
+
return { type, id, attrs: { src, status: "ready", ...(type === "video" && element.getAttribute("poster") ? { poster: element.getAttribute("poster") } : {}), ...(number("width") ? { width: number("width") } : {}), ...(number("height") ? { height: number("height") } : {}) } };
|
|
70
|
+
}
|
|
71
|
+
if (type === "divider" || element.tagName === "HR")
|
|
72
|
+
return { type: "divider", id };
|
|
73
|
+
return null;
|
|
74
|
+
};
|
|
75
|
+
export const atomToMarkdown = (node) => {
|
|
76
|
+
if (node.type === "image" || node.type === "block_image")
|
|
77
|
+
return `})`;
|
|
78
|
+
if (node.type === "formula" || node.type === "block_formula")
|
|
79
|
+
return node.type === "formula" ? `$${String(node.attrs?.source || "")}$` : `$$\n${String(node.attrs?.source || "")}\n$$`;
|
|
80
|
+
// Media is unsupported in Markdown. Preserve a readable link instead of dropping content.
|
|
81
|
+
if (node.type === "video" || node.type === "audio")
|
|
82
|
+
return `[${node.type}: ${String(node.attrs?.src || "")}](${String(node.attrs?.src || "")})`;
|
|
83
|
+
if (node.type === "divider")
|
|
84
|
+
return "---";
|
|
85
|
+
return "";
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Matches packages/core/src/foundation/formats/docx/export.ts's actual
|
|
89
|
+
* behavior (SS2.1): formulas are written as literal LaTeX text inside an
|
|
90
|
+
* <m:oMath> zone, not translated to real OMML and not rendered as an
|
|
91
|
+
* image. Word will show the raw LaTeX string, not typeset math - this is
|
|
92
|
+
* `kind: "text"`, not `"image"`, to describe that honestly.
|
|
93
|
+
*/
|
|
94
|
+
export const atomToDocx = (node) => node.type === "formula" || node.type === "block_formula"
|
|
95
|
+
? { kind: "text", source: String(node.attrs?.source || "") }
|
|
96
|
+
: node.type === "image" || node.type === "block_image"
|
|
97
|
+
? { kind: "image", source: String(node.attrs?.src || ""), alt: String(node.attrs?.alt || "") }
|
|
98
|
+
: node.type === "divider"
|
|
99
|
+
? { kind: "text", source: "---" }
|
|
100
|
+
: { kind: "text", source: `[${node.type}: ${String(node.attrs?.src || "")}]` };
|
|
101
|
+
export const atomToPdf = (node) => node.type === "formula" || node.type === "block_formula" ? { kind: "text", value: String(node.attrs?.source || "") }
|
|
102
|
+
: node.type === "video" ? { kind: "image", value: String(node.attrs?.poster || node.attrs?.src || "") }
|
|
103
|
+
: node.type === "image" || node.type === "block_image" ? { kind: "image", value: String(node.attrs?.src || "") }
|
|
104
|
+
: node.type === "divider" ? { kind: "text", value: "---" }
|
|
105
|
+
: { kind: "text", value: String(node.attrs?.src || "") };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./types.js";
|
|
2
|
+
export * from "./schema.js";
|
|
3
|
+
export * from "./security.js";
|
|
4
|
+
export * from "./declarations.js";
|
|
5
|
+
export * from "./commands.js";
|
|
6
|
+
export * from "./composition.js";
|
|
7
|
+
export * from "./persistence.js";
|
|
8
|
+
export * from "./lifecycle.js";
|
|
9
|
+
export * from "./selection.js";
|
|
10
|
+
export * from "./formats.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./types.js";
|
|
2
|
+
export * from "./schema.js";
|
|
3
|
+
export * from "./security.js";
|
|
4
|
+
export * from "./declarations.js";
|
|
5
|
+
export * from "./commands.js";
|
|
6
|
+
export * from "./composition.js";
|
|
7
|
+
export * from "./persistence.js";
|
|
8
|
+
export * from "./lifecycle.js";
|
|
9
|
+
export * from "./selection.js";
|
|
10
|
+
export * from "./formats.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FoundationEditor } from "../editor.js";
|
|
2
|
+
export interface AtomUploadCompletion {
|
|
3
|
+
readonly src?: string;
|
|
4
|
+
readonly id?: string;
|
|
5
|
+
readonly error?: string;
|
|
6
|
+
}
|
|
7
|
+
/** Applies upload completion outside the insertion transaction and never resurrects deleted nodes. */
|
|
8
|
+
export declare const completeAtomUpload: (editor: FoundationEditor, nodeId: string, completion: AtomUploadCompletion) => boolean;
|
|
9
|
+
export declare const runAtomUpload: (editor: FoundationEditor, nodeId: string, upload: () => Promise<{
|
|
10
|
+
src: string;
|
|
11
|
+
id?: string;
|
|
12
|
+
}>) => Promise<boolean>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { isTextNode } from "../identity.js";
|
|
2
|
+
import { atomDeclarations } from "./declarations.js";
|
|
3
|
+
import { sanitizeAtomSource } from "./security.js";
|
|
4
|
+
/** Applies upload completion outside the insertion transaction and never resurrects deleted nodes. */
|
|
5
|
+
export const completeAtomUpload = (editor, nodeId, completion) => {
|
|
6
|
+
const resolved = editor.positions.positionOf(nodeId);
|
|
7
|
+
if (!resolved)
|
|
8
|
+
return false;
|
|
9
|
+
const index = resolved.kind === "inline" ? (() => {
|
|
10
|
+
let offset = 0;
|
|
11
|
+
for (let childIndex = 0; childIndex < (resolved.parent.children?.length || 0); childIndex += 1) {
|
|
12
|
+
const child = resolved.parent.children[childIndex];
|
|
13
|
+
if (!isTextNode(child) && child.id === nodeId && offset === resolved.pos.offset)
|
|
14
|
+
return childIndex;
|
|
15
|
+
offset += isTextNode(child) ? child.text.length : 1;
|
|
16
|
+
}
|
|
17
|
+
return -1;
|
|
18
|
+
})() : resolved.pos.offset;
|
|
19
|
+
const node = resolved.parent.children?.[index];
|
|
20
|
+
if (!node || isTextNode(node) || node.id !== nodeId)
|
|
21
|
+
return false;
|
|
22
|
+
const before = node.attrs || {};
|
|
23
|
+
const declaration = atomDeclarations.find((entry) => entry.type === node.type);
|
|
24
|
+
const safeSource = completion.src && declaration && declaration.kind !== "formula"
|
|
25
|
+
? sanitizeAtomSource(completion.src, { kind: declaration.kind }) : null;
|
|
26
|
+
const after = safeSource
|
|
27
|
+
? { ...before, src: safeSource, status: "ready", ...(completion.id ? { uploadId: completion.id } : { uploadId: undefined }), error: undefined }
|
|
28
|
+
: { ...before, status: "error", uploadId: undefined, error: completion.error || "Upload failed" };
|
|
29
|
+
editor.transact((transaction) => transaction.operations.push({
|
|
30
|
+
type: "setNodeAttributes", pos: { path: [...resolved.pos.path, index], offset: 0 }, before, after: Object.fromEntries(Object.entries(after).filter(([, value]) => value !== undefined)),
|
|
31
|
+
}), { source: "api", addToHistory: false });
|
|
32
|
+
return true;
|
|
33
|
+
};
|
|
34
|
+
export const runAtomUpload = async (editor, nodeId, upload) => {
|
|
35
|
+
try {
|
|
36
|
+
return completeAtomUpload(editor, nodeId, await upload());
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
return completeAtomUpload(editor, nodeId, { error: error instanceof Error ? error.message : "Upload failed" });
|
|
40
|
+
}
|
|
41
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { isTextNode } from "../identity.js";
|
|
2
|
+
export const assertNoBlobAtomUrls = (envelope) => {
|
|
3
|
+
const visit = (node) => {
|
|
4
|
+
if (isTextNode(node))
|
|
5
|
+
return;
|
|
6
|
+
if (node.attrs?.status === "pending")
|
|
7
|
+
throw new Error(`Cannot persist pending atom "${node.id}"; wait for completion or cancel it.`);
|
|
8
|
+
for (const key of ["src", "poster"]) {
|
|
9
|
+
if (typeof node.attrs?.[key] === "string" && /^blob:/i.test(node.attrs[key])) {
|
|
10
|
+
throw new Error(`Cannot persist transient blob URL from ${node.type}.${key}.`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
node.children?.forEach(visit);
|
|
14
|
+
};
|
|
15
|
+
visit(envelope.document);
|
|
16
|
+
};
|
|
17
|
+
export const serializePersistedEditorDocument = (envelope) => {
|
|
18
|
+
assertNoBlobAtomUrls(envelope);
|
|
19
|
+
return JSON.stringify(envelope);
|
|
20
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type PluginCommand } from "../plugin/types.js";
|
|
2
|
+
import { atomDeclarations } from "./declarations.js";
|
|
3
|
+
/**
|
|
4
|
+
* Wraps the four existing, already-tested atom commands (atom/commands.ts)
|
|
5
|
+
* with the description Phase 10's doc generation needs. Six atom node
|
|
6
|
+
* types (image, block_image, formula, block_formula, video, audio, per
|
|
7
|
+
* atomDeclarations) share these same four generic commands via
|
|
8
|
+
* `declaration`/`attrs` params, the same way marks' seven commands cover
|
|
9
|
+
* every mark type - there is no per-atom-type command to convert
|
|
10
|
+
* separately.
|
|
11
|
+
*
|
|
12
|
+
* MediaProvider/mediaPicker (packages/react/src/mediaProvider.ts) are left
|
|
13
|
+
* exactly as they are - direct CanonicalAuthorityEditor props, already
|
|
14
|
+
* working - rather than routed through this manifest. They are a
|
|
15
|
+
* react-layer upload/picker concern orthogonal to the core command surface
|
|
16
|
+
* atom.insert consumes (a MediaProvider's job ends at producing a URL;
|
|
17
|
+
* atom.insert takes it from there like any other src).
|
|
18
|
+
*/
|
|
19
|
+
export declare const atomPluginCommands: Record<string, PluginCommand>;
|
|
20
|
+
export { atomDeclarations };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { definePluginCommand } from "../plugin/types.js";
|
|
2
|
+
import { atomCommands } from "./commands.js";
|
|
3
|
+
import { atomDeclarations } from "./declarations.js";
|
|
4
|
+
/**
|
|
5
|
+
* Wraps the four existing, already-tested atom commands (atom/commands.ts)
|
|
6
|
+
* with the description Phase 10's doc generation needs. Six atom node
|
|
7
|
+
* types (image, block_image, formula, block_formula, video, audio, per
|
|
8
|
+
* atomDeclarations) share these same four generic commands via
|
|
9
|
+
* `declaration`/`attrs` params, the same way marks' seven commands cover
|
|
10
|
+
* every mark type - there is no per-atom-type command to convert
|
|
11
|
+
* separately.
|
|
12
|
+
*
|
|
13
|
+
* MediaProvider/mediaPicker (packages/react/src/mediaProvider.ts) are left
|
|
14
|
+
* exactly as they are - direct CanonicalAuthorityEditor props, already
|
|
15
|
+
* working - rather than routed through this manifest. They are a
|
|
16
|
+
* react-layer upload/picker concern orthogonal to the core command surface
|
|
17
|
+
* atom.insert consumes (a MediaProvider's job ends at producing a URL;
|
|
18
|
+
* atom.insert takes it from there like any other src).
|
|
19
|
+
*/
|
|
20
|
+
export const atomPluginCommands = {
|
|
21
|
+
"atom.insert": definePluginCommand({
|
|
22
|
+
id: "atom.insert", run: atomCommands["atom.insert"],
|
|
23
|
+
description: "Inserts an atom node (image, formula, video, or audio) at the given position.",
|
|
24
|
+
options: {
|
|
25
|
+
declaration: { description: "Which atom type to insert, from atomDeclarations (schema.ts).", required: true },
|
|
26
|
+
nodeId: { description: "Caller-provided id for the new node.", required: true },
|
|
27
|
+
attrs: { description: "The new node's attributes (e.g. src, alt for an image).", required: true },
|
|
28
|
+
ownerId: { description: "The inline container to insert into - required for inline atoms." },
|
|
29
|
+
offset: { description: "The inline offset to insert at." },
|
|
30
|
+
parentId: { description: "The block container to insert into - required for block atoms." },
|
|
31
|
+
index: { description: "The block index to insert at." },
|
|
32
|
+
},
|
|
33
|
+
}),
|
|
34
|
+
"atom.update": definePluginCommand({
|
|
35
|
+
id: "atom.update", run: atomCommands["atom.update"],
|
|
36
|
+
description: "Updates the selected atom's attributes.",
|
|
37
|
+
options: { attrs: { description: "The new attributes.", required: true } },
|
|
38
|
+
}),
|
|
39
|
+
"atom.delete": definePluginCommand({
|
|
40
|
+
id: "atom.delete", run: atomCommands["atom.delete"],
|
|
41
|
+
description: "Deletes the selected atom.",
|
|
42
|
+
}),
|
|
43
|
+
"atom.resize": definePluginCommand({
|
|
44
|
+
id: "atom.resize", run: atomCommands["atom.resize"],
|
|
45
|
+
description: "Resizes the selected atom, optionally preserving its aspect ratio.",
|
|
46
|
+
options: {
|
|
47
|
+
width: { description: "The new width.", required: true },
|
|
48
|
+
height: { description: "The new height.", required: true },
|
|
49
|
+
minWidth: { description: "A minimum width to clamp to." },
|
|
50
|
+
minHeight: { description: "A minimum height to clamp to." },
|
|
51
|
+
preserveAspectRatio: { description: "Whether to scale height proportionally to width (or vice versa)." },
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
54
|
+
};
|
|
55
|
+
export { atomDeclarations };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const optionalString = { validate: (value) => typeof value === "string" };
|
|
2
|
+
const requiredString = { required: true, validate: (value) => typeof value === "string" };
|
|
3
|
+
const dimension = { validate: (value) => Number.isFinite(value) && Number(value) > 0 && Number(value) <= 100000 };
|
|
4
|
+
const status = { default: "ready", validate: (value) => value === "pending" || value === "ready" || value === "error" };
|
|
5
|
+
const imageAttrs = {
|
|
6
|
+
src: requiredString, alt: requiredString, width: dimension, height: dimension,
|
|
7
|
+
status, uploadId: optionalString, error: optionalString, decorative: { validate: (value) => typeof value === "boolean" },
|
|
8
|
+
align: { validate: (value) => value === "center" || value === "left" || value === "right" },
|
|
9
|
+
};
|
|
10
|
+
const formulaAttrs = {
|
|
11
|
+
source: requiredString,
|
|
12
|
+
notation: { required: true, default: "latex", validate: (value) => value === "latex" || value === "mathml" },
|
|
13
|
+
error: optionalString,
|
|
14
|
+
};
|
|
15
|
+
const mediaAttrs = { src: requiredString, poster: optionalString, width: dimension, height: dimension, status, uploadId: optionalString, error: optionalString };
|
|
16
|
+
/** Inline and block variants are distinct because schema groups are static. */
|
|
17
|
+
export const atomNodeSpecs = [
|
|
18
|
+
{ type: "image", group: "inline", atomic: true, selectable: true, marks: "", attributes: imageAttrs },
|
|
19
|
+
{ type: "block_image", group: "block", atomic: true, selectable: true, marks: "", attributes: imageAttrs },
|
|
20
|
+
{ type: "formula", group: "inline", atomic: true, selectable: true, marks: "", attributes: formulaAttrs },
|
|
21
|
+
{ type: "block_formula", group: "block", atomic: true, selectable: true, marks: "", attributes: formulaAttrs },
|
|
22
|
+
{ type: "video", group: "block", atomic: true, selectable: true, marks: "", attributes: mediaAttrs },
|
|
23
|
+
{ type: "audio", group: "block", atomic: true, selectable: true, marks: "", attributes: mediaAttrs },
|
|
24
|
+
// A horizontal rule (<hr>) - no content, no attrs, just a block-level
|
|
25
|
+
// separator atom. Previously unrecognized entirely (parseBlock had no
|
|
26
|
+
// case for "hr"), so every pasted <hr> fell to the generic
|
|
27
|
+
// "unrecognized tag" fallback and rendered as "[Unsupported: hr]".
|
|
28
|
+
{ type: "divider", group: "block", atomic: true, selectable: true, marks: "" },
|
|
29
|
+
];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AtomDeclaration } from "./types.js";
|
|
2
|
+
export declare const SAFE_IMAGE_MIME_TYPES: Set<string>;
|
|
3
|
+
export declare const SAFE_AUDIO_MIME_TYPES: Set<string>;
|
|
4
|
+
export declare const SAFE_VIDEO_MIME_TYPES: Set<string>;
|
|
5
|
+
export declare const validateAtomMime: (kind: AtomDeclaration["kind"], mime: string) => boolean;
|
|
6
|
+
export declare const sanitizeAtomSource: (value: string | undefined | null, options: {
|
|
7
|
+
kind: AtomDeclaration["kind"];
|
|
8
|
+
allowBlobPreview?: boolean;
|
|
9
|
+
}) => string | null;
|
|
10
|
+
export declare const safeFormulaSource: (source: unknown) => source is string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { sanitizeResourceUrl } from "../security/urlPolicy.js";
|
|
2
|
+
export const SAFE_IMAGE_MIME_TYPES = new Set(["image/png", "image/jpeg", "image/gif", "image/webp", "image/avif", "image/svg+xml"]);
|
|
3
|
+
const SAFE_IMAGE_DATA_MIME_TYPES = new Set(["image/png", "image/jpeg", "image/gif", "image/webp", "image/avif"]);
|
|
4
|
+
export const SAFE_AUDIO_MIME_TYPES = new Set(["audio/mpeg", "audio/mp4", "audio/ogg", "audio/wav", "audio/webm"]);
|
|
5
|
+
export const SAFE_VIDEO_MIME_TYPES = new Set(["video/mp4", "video/webm", "video/ogg"]);
|
|
6
|
+
export const validateAtomMime = (kind, mime) => {
|
|
7
|
+
const normalized = mime.trim().toLowerCase().split(";", 1)[0];
|
|
8
|
+
if (kind === "image")
|
|
9
|
+
return SAFE_IMAGE_MIME_TYPES.has(normalized);
|
|
10
|
+
if (kind === "audio")
|
|
11
|
+
return SAFE_AUDIO_MIME_TYPES.has(normalized);
|
|
12
|
+
if (kind === "video")
|
|
13
|
+
return SAFE_VIDEO_MIME_TYPES.has(normalized);
|
|
14
|
+
return false;
|
|
15
|
+
};
|
|
16
|
+
export const sanitizeAtomSource = (value, options) => sanitizeResourceUrl(value, {
|
|
17
|
+
allowBlob: options.allowBlobPreview === true,
|
|
18
|
+
allowedDataMimeTypes: options.kind === "image" ? SAFE_IMAGE_DATA_MIME_TYPES : new Set(),
|
|
19
|
+
});
|
|
20
|
+
export const safeFormulaSource = (source) => typeof source === "string" && source.length > 0 && source.length <= 100000 && !/[\u0000]/.test(source);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Attrs, SmartDocument, SmartOperation, SmartSchema } from "../types.js";
|
|
2
|
+
import type { PositionLookup, ResolvedScope } from "../scope/types.js";
|
|
3
|
+
export type AtomKind = "image" | "formula" | "video" | "audio";
|
|
4
|
+
export type AtomStatus = "pending" | "ready" | "error";
|
|
5
|
+
export interface AtomDeclaration {
|
|
6
|
+
readonly type: string;
|
|
7
|
+
readonly kind: AtomKind;
|
|
8
|
+
readonly group: "inline" | "block";
|
|
9
|
+
readonly validate: (attrs: Attrs) => boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface AtomCommandContext {
|
|
12
|
+
readonly schema: SmartSchema;
|
|
13
|
+
readonly positions: PositionLookup;
|
|
14
|
+
}
|
|
15
|
+
export type AtomCommand<P> = (document: SmartDocument, scope: ResolvedScope, params: P, ctx: AtomCommandContext) => SmartOperation[];
|
|
16
|
+
export interface InsertAtomParams {
|
|
17
|
+
readonly declaration: AtomDeclaration;
|
|
18
|
+
readonly nodeId: string;
|
|
19
|
+
readonly attrs: Attrs;
|
|
20
|
+
/** Required for inline atoms. */
|
|
21
|
+
readonly ownerId?: string;
|
|
22
|
+
readonly offset?: number;
|
|
23
|
+
/** Required for block atoms. */
|
|
24
|
+
readonly parentId?: string;
|
|
25
|
+
readonly index?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface UpdateAtomParams {
|
|
28
|
+
readonly attrs: Attrs;
|
|
29
|
+
}
|
|
30
|
+
export interface ResizeAtomParams {
|
|
31
|
+
readonly width: number;
|
|
32
|
+
readonly height: number;
|
|
33
|
+
readonly minWidth?: number;
|
|
34
|
+
readonly minHeight?: number;
|
|
35
|
+
readonly preserveAspectRatio?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface CompositionAtomToken {
|
|
38
|
+
readonly kind: "atom";
|
|
39
|
+
readonly nodeId: string;
|
|
40
|
+
readonly atomType: string;
|
|
41
|
+
}
|
|
42
|
+
export interface CompositionTextToken {
|
|
43
|
+
readonly kind: "text";
|
|
44
|
+
readonly text: string;
|
|
45
|
+
readonly marks: readonly import("../types.js").SmartMark[];
|
|
46
|
+
}
|
|
47
|
+
export type CompositionToken = CompositionAtomToken | CompositionTextToken;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { BlockCommand, IndentBlocksParams, MoveBlocksParams, OutdentBlocksParams, SetBlockAttributesParams, SetBlockTypeParams, UnwrapBlocksParams, WrapBlocksParams } from "./types.js";
|
|
2
|
+
export declare const setBlockTypeCommand: BlockCommand<SetBlockTypeParams>;
|
|
3
|
+
export declare const wrapBlocks: BlockCommand<WrapBlocksParams>;
|
|
4
|
+
export declare const unwrapBlocks: BlockCommand<UnwrapBlocksParams>;
|
|
5
|
+
export declare const setBlockAttributes: BlockCommand<SetBlockAttributesParams>;
|
|
6
|
+
export declare const moveBlockCommand: BlockCommand<MoveBlocksParams>;
|
|
7
|
+
export declare const indentBlockCommand: BlockCommand<IndentBlocksParams>;
|
|
8
|
+
export declare const outdentBlockCommand: BlockCommand<OutdentBlocksParams>;
|
|
9
|
+
export declare const blockCommands: {
|
|
10
|
+
readonly "block.setType": BlockCommand<SetBlockTypeParams>;
|
|
11
|
+
readonly "block.wrap": BlockCommand<WrapBlocksParams>;
|
|
12
|
+
readonly "block.unwrap": BlockCommand<UnwrapBlocksParams>;
|
|
13
|
+
readonly "block.setAttributes": BlockCommand<SetBlockAttributesParams>;
|
|
14
|
+
readonly "block.move": BlockCommand<MoveBlocksParams>;
|
|
15
|
+
readonly "block.indent": BlockCommand<IndentBlocksParams>;
|
|
16
|
+
readonly "block.outdent": BlockCommand<OutdentBlocksParams>;
|
|
17
|
+
};
|