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
package/dist/preset.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { alignmentPlugin } from "./plugins/alignment.js";
|
|
2
|
+
import { basicFormattingPlugin } from "./plugins/basicFormatting.js";
|
|
3
|
+
import { blockquotePlugin } from "./plugins/blockquote.js";
|
|
4
|
+
import { blockTypePlugin } from "./plugins/blockType.js";
|
|
5
|
+
import { checklistPlugin } from "./plugins/checklist.js";
|
|
6
|
+
import { codeBlockPlugin } from "./plugins/codeBlock.js";
|
|
7
|
+
import { formulaPlugin } from "./plugins/formula.js";
|
|
8
|
+
import { listPlugin } from "./plugins/list.js";
|
|
9
|
+
import { mediaPlugin } from "./plugins/media.js";
|
|
10
|
+
import { movePlugin } from "./plugins/move.js";
|
|
11
|
+
import { tablePlugin } from "./plugins/table.js";
|
|
12
|
+
const features = {
|
|
13
|
+
basicFormatting: basicFormattingPlugin,
|
|
14
|
+
blockType: blockTypePlugin,
|
|
15
|
+
alignment: alignmentPlugin,
|
|
16
|
+
list: listPlugin,
|
|
17
|
+
checklist: checklistPlugin,
|
|
18
|
+
blockquote: blockquotePlugin,
|
|
19
|
+
codeBlock: codeBlockPlugin,
|
|
20
|
+
table: tablePlugin,
|
|
21
|
+
media: mediaPlugin,
|
|
22
|
+
formula: formulaPlugin,
|
|
23
|
+
move: movePlugin,
|
|
24
|
+
};
|
|
25
|
+
const featureOrder = Object.keys(features);
|
|
26
|
+
/**
|
|
27
|
+
* Creates the standard model plugin set.
|
|
28
|
+
*
|
|
29
|
+
* Features default to enabled. Disabling `list` also disables `checklist`,
|
|
30
|
+
* because checklist commands depend on list structure. Applications can append
|
|
31
|
+
* custom plugins to the returned array before constructing an editor.
|
|
32
|
+
*/
|
|
33
|
+
export const createCorePlugins = (config = {}) => {
|
|
34
|
+
const enabled = (id) => config[id] !== false;
|
|
35
|
+
return featureOrder
|
|
36
|
+
.filter((id) => enabled(id))
|
|
37
|
+
.filter((id) => id !== "checklist" || enabled("list"))
|
|
38
|
+
.map((id) => features[id]);
|
|
39
|
+
};
|
|
40
|
+
export const corePlugins = createCorePlugins();
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Path, type LegacySmartDocument } from "./model.js";
|
|
2
|
+
export interface SchemaIssue {
|
|
3
|
+
path: Path;
|
|
4
|
+
code: string;
|
|
5
|
+
message: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SchemaValidationResult {
|
|
8
|
+
valid: boolean;
|
|
9
|
+
issues: SchemaIssue[];
|
|
10
|
+
}
|
|
11
|
+
export interface SmartSchemaExtension {
|
|
12
|
+
id: string;
|
|
13
|
+
normalize?: (document: LegacySmartDocument) => LegacySmartDocument;
|
|
14
|
+
validate?: (document: LegacySmartDocument) => SchemaIssue[];
|
|
15
|
+
}
|
|
16
|
+
export interface LegacySmartSchema {
|
|
17
|
+
extensions: readonly SmartSchemaExtension[];
|
|
18
|
+
}
|
|
19
|
+
export declare const createSmartSchema: (extensions?: readonly SmartSchemaExtension[]) => LegacySmartSchema;
|
|
20
|
+
export declare const defaultSmartSchema: LegacySmartSchema;
|
|
21
|
+
export declare const normalizeSmartDocument: (document: LegacySmartDocument, schema?: LegacySmartSchema) => LegacySmartDocument;
|
|
22
|
+
export declare const validateSmartDocument: (document: LegacySmartDocument, schema?: LegacySmartSchema) => SchemaValidationResult;
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
import { paragraph, } from "./model.js";
|
|
2
|
+
import { isSmartListPreset } from "./listPresets.js";
|
|
3
|
+
export const createSmartSchema = (extensions = []) => {
|
|
4
|
+
const ids = new Set();
|
|
5
|
+
extensions.forEach((extension) => {
|
|
6
|
+
if (!extension.id.trim())
|
|
7
|
+
throw new Error("Schema extension id cannot be empty.");
|
|
8
|
+
if (ids.has(extension.id))
|
|
9
|
+
throw new Error(`Duplicate schema extension id "${extension.id}".`);
|
|
10
|
+
ids.add(extension.id);
|
|
11
|
+
});
|
|
12
|
+
return { extensions: [...extensions] };
|
|
13
|
+
};
|
|
14
|
+
export const defaultSmartSchema = createSmartSchema();
|
|
15
|
+
const listStyles = new Set([
|
|
16
|
+
"disc",
|
|
17
|
+
"circle",
|
|
18
|
+
"square",
|
|
19
|
+
"decimal",
|
|
20
|
+
"decimal-leading-zero",
|
|
21
|
+
"lower-alpha",
|
|
22
|
+
"upper-alpha",
|
|
23
|
+
"lower-roman",
|
|
24
|
+
"upper-roman",
|
|
25
|
+
]);
|
|
26
|
+
const markKey = (mark) => JSON.stringify(mark);
|
|
27
|
+
const normalizedIndent = (value) => Number.isInteger(value) && (value || 0) > 0 ? Math.min(value || 0, 10) : undefined;
|
|
28
|
+
const normalizeMarks = (marks) => {
|
|
29
|
+
if (!marks?.length)
|
|
30
|
+
return undefined;
|
|
31
|
+
const seen = new Set();
|
|
32
|
+
const normalized = marks.filter((mark) => {
|
|
33
|
+
const key = markKey(mark);
|
|
34
|
+
if (seen.has(key))
|
|
35
|
+
return false;
|
|
36
|
+
seen.add(key);
|
|
37
|
+
return true;
|
|
38
|
+
});
|
|
39
|
+
return normalized.length ? normalized : undefined;
|
|
40
|
+
};
|
|
41
|
+
const normalizeText = (node) => {
|
|
42
|
+
const marks = normalizeMarks(node.marks);
|
|
43
|
+
return marks ? { type: "text", text: String(node.text ?? ""), marks } : { type: "text", text: String(node.text ?? "") };
|
|
44
|
+
};
|
|
45
|
+
const normalizeInlineImage = (node) => {
|
|
46
|
+
const width = Number.isFinite(node.width) && (node.width || 0) > 0 ? node.width : undefined;
|
|
47
|
+
const height = Number.isFinite(node.height) && (node.height || 0) > 0 ? node.height : undefined;
|
|
48
|
+
return {
|
|
49
|
+
type: "inlineImage",
|
|
50
|
+
src: String(node.src ?? ""),
|
|
51
|
+
...(node.alt ? { alt: String(node.alt) } : {}),
|
|
52
|
+
...(node.title ? { title: String(node.title) } : {}),
|
|
53
|
+
...(width ? { width } : {}),
|
|
54
|
+
...(height ? { height } : {}),
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
const normalizeInlineChildren = (children) => {
|
|
58
|
+
const normalized = (children || []).map((node) => {
|
|
59
|
+
if (node.type === "text")
|
|
60
|
+
return normalizeText(node);
|
|
61
|
+
if (node.type === "formula") {
|
|
62
|
+
return {
|
|
63
|
+
type: "formula",
|
|
64
|
+
value: String(node.value ?? ""),
|
|
65
|
+
...(node.displayText ? { displayText: String(node.displayText) } : {}),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return normalizeInlineImage(node);
|
|
69
|
+
});
|
|
70
|
+
return normalized.length ? normalized : [{ type: "text", text: "" }];
|
|
71
|
+
};
|
|
72
|
+
const normalizeListItem = (item) => {
|
|
73
|
+
const children = (item.children || []).map(normalizeBlock);
|
|
74
|
+
return {
|
|
75
|
+
type: "listItem",
|
|
76
|
+
...(item.alignment ? { alignment: item.alignment } : {}),
|
|
77
|
+
...(typeof item.checked === "boolean" ? { checked: item.checked } : {}),
|
|
78
|
+
children: children.length ? children : [paragraph()],
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
const normalizeCell = (cell) => {
|
|
82
|
+
const children = (cell.children || []).map(normalizeBlock);
|
|
83
|
+
const colspan = Number.isInteger(cell.colspan) && (cell.colspan || 0) > 1 ? cell.colspan : undefined;
|
|
84
|
+
const rowspan = Number.isInteger(cell.rowspan) && (cell.rowspan || 0) > 1 ? cell.rowspan : undefined;
|
|
85
|
+
return {
|
|
86
|
+
type: cell.type === "tableHeaderCell" ? "tableHeaderCell" : "tableCell",
|
|
87
|
+
...(colspan ? { colspan } : {}),
|
|
88
|
+
...(rowspan ? { rowspan } : {}),
|
|
89
|
+
...(cell.backgroundColor ? { backgroundColor: String(cell.backgroundColor) } : {}),
|
|
90
|
+
...(cell.textColor ? { textColor: String(cell.textColor) } : {}),
|
|
91
|
+
...(cell.border ? { border: String(cell.border) } : {}),
|
|
92
|
+
children: children.length ? children : [paragraph()],
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
const normalizeBlock = (block) => {
|
|
96
|
+
if (block.type === "paragraph") {
|
|
97
|
+
return {
|
|
98
|
+
type: "paragraph",
|
|
99
|
+
...(block.alignment ? { alignment: block.alignment } : {}),
|
|
100
|
+
...(normalizedIndent(block.indent) ? { indent: normalizedIndent(block.indent) } : {}),
|
|
101
|
+
children: normalizeInlineChildren(block.children),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (block.type === "heading") {
|
|
105
|
+
const level = Math.max(1, Math.min(6, Number(block.level) || 1));
|
|
106
|
+
return {
|
|
107
|
+
type: "heading",
|
|
108
|
+
level,
|
|
109
|
+
...(block.alignment ? { alignment: block.alignment } : {}),
|
|
110
|
+
...(normalizedIndent(block.indent) ? { indent: normalizedIndent(block.indent) } : {}),
|
|
111
|
+
children: normalizeInlineChildren(block.children),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (block.type === "list") {
|
|
115
|
+
const children = (block.children || []).map(normalizeListItem);
|
|
116
|
+
return {
|
|
117
|
+
type: "list",
|
|
118
|
+
...(normalizedIndent(block.indent) ? { indent: normalizedIndent(block.indent) } : {}),
|
|
119
|
+
style: listStyles.has(block.style) ? block.style : "disc",
|
|
120
|
+
...(isSmartListPreset(block.preset) ? { preset: block.preset } : {}),
|
|
121
|
+
...(block.checklist ? { checklist: true } : {}),
|
|
122
|
+
...(block.checklist && block.strikeCompleted ? { strikeCompleted: true } : {}),
|
|
123
|
+
children: children.length ? children : [normalizeListItem({ type: "listItem", children: [] })],
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
if (block.type === "blockquote") {
|
|
127
|
+
const children = (block.children || []).map(normalizeBlock);
|
|
128
|
+
return {
|
|
129
|
+
type: "blockquote",
|
|
130
|
+
...(block.alignment ? { alignment: block.alignment } : {}),
|
|
131
|
+
...(normalizedIndent(block.indent) ? { indent: normalizedIndent(block.indent) } : {}),
|
|
132
|
+
children: children.length ? children : [paragraph()],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (block.type === "codeBlock") {
|
|
136
|
+
return {
|
|
137
|
+
type: "codeBlock",
|
|
138
|
+
...(block.alignment ? { alignment: block.alignment } : {}),
|
|
139
|
+
...(normalizedIndent(block.indent) ? { indent: normalizedIndent(block.indent) } : {}),
|
|
140
|
+
text: String(block.text ?? ""),
|
|
141
|
+
...(block.language ? { language: block.language } : {}),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (block.type === "image") {
|
|
145
|
+
const width = Number.isFinite(block.width) && (block.width || 0) > 0 ? block.width : undefined;
|
|
146
|
+
const height = Number.isFinite(block.height) && (block.height || 0) > 0 ? block.height : undefined;
|
|
147
|
+
return {
|
|
148
|
+
type: "image",
|
|
149
|
+
...(normalizedIndent(block.indent) ? { indent: normalizedIndent(block.indent) } : {}),
|
|
150
|
+
src: String(block.src ?? ""),
|
|
151
|
+
...(block.alt ? { alt: String(block.alt) } : {}),
|
|
152
|
+
...(block.title ? { title: String(block.title) } : {}),
|
|
153
|
+
...(width ? { width } : {}),
|
|
154
|
+
...(height ? { height } : {}),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
if (block.type === "media") {
|
|
158
|
+
return {
|
|
159
|
+
type: "media",
|
|
160
|
+
...(normalizedIndent(block.indent) ? { indent: normalizedIndent(block.indent) } : {}),
|
|
161
|
+
src: String(block.src ?? ""),
|
|
162
|
+
mediaType: block.mediaType === "audio" || block.mediaType === "file" ? block.mediaType : "video",
|
|
163
|
+
...(block.title ? { title: String(block.title) } : {}),
|
|
164
|
+
...(block.mimeType ? { mimeType: String(block.mimeType) } : {}),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const rows = (block.children || []).map((row) => {
|
|
168
|
+
const cells = (row.children || []).map(normalizeCell);
|
|
169
|
+
return {
|
|
170
|
+
type: "tableRow",
|
|
171
|
+
...(Number.isFinite(row.heightPx) && (row.heightPx || 0) >= 30
|
|
172
|
+
? { heightPx: Number(row.heightPx) }
|
|
173
|
+
: {}),
|
|
174
|
+
children: cells,
|
|
175
|
+
};
|
|
176
|
+
});
|
|
177
|
+
const normalizedRows = rows.map((row, rowIndex) => {
|
|
178
|
+
if (row.children.length)
|
|
179
|
+
return row;
|
|
180
|
+
const coveredByRowspan = rows.slice(0, rowIndex).some((previous, previousIndex) => previous.children.some((cell) => (cell.rowspan || 1) > rowIndex - previousIndex));
|
|
181
|
+
return coveredByRowspan
|
|
182
|
+
? row
|
|
183
|
+
: { ...row, children: [normalizeCell({ type: "tableCell", children: [] })] };
|
|
184
|
+
});
|
|
185
|
+
return {
|
|
186
|
+
type: "table",
|
|
187
|
+
...(normalizedIndent(block.indent) ? { indent: normalizedIndent(block.indent) } : {}),
|
|
188
|
+
...(block.columnWidths?.length
|
|
189
|
+
? { columnWidths: block.columnWidths.map((width) => Math.max(60, Number(width) || 60)) }
|
|
190
|
+
: {}),
|
|
191
|
+
children: normalizedRows.length
|
|
192
|
+
? normalizedRows
|
|
193
|
+
: [{ type: "tableRow", children: [normalizeCell({ type: "tableCell", children: [] })] }],
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
const normalizeBuiltInDocument = (document) => {
|
|
197
|
+
const children = (document.children || []).map(normalizeBlock);
|
|
198
|
+
return { type: "doc", children: children.length ? children : [paragraph()] };
|
|
199
|
+
};
|
|
200
|
+
export const normalizeSmartDocument = (document, schema = defaultSmartSchema) => schema.extensions.reduce((current, extension) => normalizeBuiltInDocument(extension.normalize ? extension.normalize(current) : current), normalizeBuiltInDocument(document));
|
|
201
|
+
const issue = (issues, path, code, message) => {
|
|
202
|
+
issues.push({ path: [...path], code, message });
|
|
203
|
+
};
|
|
204
|
+
const validateTextChildren = (children, path, issues) => {
|
|
205
|
+
if (!children.length)
|
|
206
|
+
issue(issues, path, "empty-inline-container", "Inline containers require at least one inline node.");
|
|
207
|
+
children.forEach((node, index) => {
|
|
208
|
+
const nodePath = [...path, index];
|
|
209
|
+
if (node.type === "formula") {
|
|
210
|
+
if (!node.value)
|
|
211
|
+
issue(issues, nodePath, "empty-formula", "Formula atoms require a value.");
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
if (node.type === "inlineImage") {
|
|
215
|
+
if (!node.src)
|
|
216
|
+
issue(issues, nodePath, "missing-inline-image-source", "Inline images require a source.");
|
|
217
|
+
if (node.width !== undefined && (!Number.isFinite(node.width) || node.width <= 0)) {
|
|
218
|
+
issue(issues, nodePath, "invalid-inline-image-width", "Inline image width must be positive.");
|
|
219
|
+
}
|
|
220
|
+
if (node.height !== undefined && (!Number.isFinite(node.height) || node.height <= 0)) {
|
|
221
|
+
issue(issues, nodePath, "invalid-inline-image-height", "Inline image height must be positive.");
|
|
222
|
+
}
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (typeof node.text !== "string") {
|
|
226
|
+
issue(issues, nodePath, "invalid-text-node", "Text nodes require string content.");
|
|
227
|
+
}
|
|
228
|
+
const keys = (node.marks || []).map(markKey);
|
|
229
|
+
if (new Set(keys).size !== keys.length) {
|
|
230
|
+
issue(issues, nodePath, "duplicate-mark", "A text node cannot contain duplicate marks.");
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
};
|
|
234
|
+
const validateBlock = (block, path, issues) => {
|
|
235
|
+
if (block.type === "paragraph" || block.type === "heading") {
|
|
236
|
+
if (block.type === "heading" && (!Number.isInteger(block.level) || block.level < 1 || block.level > 6)) {
|
|
237
|
+
issue(issues, path, "invalid-heading-level", "Heading level must be between 1 and 6.");
|
|
238
|
+
}
|
|
239
|
+
validateTextChildren(block.children, path, issues);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (block.type === "list") {
|
|
243
|
+
if (!listStyles.has(block.style))
|
|
244
|
+
issue(issues, path, "invalid-list-style", "List style is not supported.");
|
|
245
|
+
if (block.preset !== undefined && !isSmartListPreset(block.preset))
|
|
246
|
+
issue(issues, path, "invalid-list-preset", "List preset is not supported.");
|
|
247
|
+
if (!block.children.length)
|
|
248
|
+
issue(issues, path, "empty-list", "Lists require at least one list item.");
|
|
249
|
+
block.children.forEach((item, itemIndex) => {
|
|
250
|
+
const itemPath = [...path, itemIndex];
|
|
251
|
+
if (item.type !== "listItem")
|
|
252
|
+
issue(issues, itemPath, "invalid-list-child", "Lists may only contain list items.");
|
|
253
|
+
if (!item.children.length)
|
|
254
|
+
issue(issues, itemPath, "empty-list-item", "List items require block content.");
|
|
255
|
+
item.children.forEach((child, childIndex) => validateBlock(child, [...itemPath, childIndex], issues));
|
|
256
|
+
});
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if (block.type === "blockquote") {
|
|
260
|
+
if (!block.children.length)
|
|
261
|
+
issue(issues, path, "empty-blockquote", "Blockquotes require block content.");
|
|
262
|
+
block.children.forEach((child, index) => validateBlock(child, [...path, index], issues));
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (block.type === "codeBlock") {
|
|
266
|
+
if (typeof block.text !== "string")
|
|
267
|
+
issue(issues, path, "invalid-code-text", "Code block text must be a string.");
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (block.type === "image") {
|
|
271
|
+
if (!block.src)
|
|
272
|
+
issue(issues, path, "missing-image-source", "Images require a source.");
|
|
273
|
+
if (block.width !== undefined && (!Number.isFinite(block.width) || block.width <= 0)) {
|
|
274
|
+
issue(issues, path, "invalid-image-width", "Image width must be positive.");
|
|
275
|
+
}
|
|
276
|
+
if (block.height !== undefined && (!Number.isFinite(block.height) || block.height <= 0)) {
|
|
277
|
+
issue(issues, path, "invalid-image-height", "Image height must be positive.");
|
|
278
|
+
}
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (block.type === "media") {
|
|
282
|
+
if (!block.src)
|
|
283
|
+
issue(issues, path, "missing-media-source", "Media requires a source.");
|
|
284
|
+
if (!["audio", "video", "file"].includes(block.mediaType)) {
|
|
285
|
+
issue(issues, path, "invalid-media-type", "Media type is not supported.");
|
|
286
|
+
}
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
if (block.type === "table") {
|
|
290
|
+
if (!block.children.length)
|
|
291
|
+
issue(issues, path, "empty-table", "Tables require at least one row.");
|
|
292
|
+
block.children.forEach((row, rowIndex) => {
|
|
293
|
+
const rowPath = [...path, rowIndex];
|
|
294
|
+
if (row.type !== "tableRow")
|
|
295
|
+
issue(issues, rowPath, "invalid-table-child", "Tables may only contain rows.");
|
|
296
|
+
const coveredByRowspan = block.children.slice(0, rowIndex).some((previous, previousIndex) => previous.children.some((cell) => (cell.rowspan || 1) > rowIndex - previousIndex));
|
|
297
|
+
if (!row.children.length && !coveredByRowspan) {
|
|
298
|
+
issue(issues, rowPath, "empty-table-row", "Table rows require a cell or coverage from a rowspan.");
|
|
299
|
+
}
|
|
300
|
+
row.children.forEach((cell, cellIndex) => {
|
|
301
|
+
const cellPath = [...rowPath, cellIndex];
|
|
302
|
+
if (cell.type !== "tableCell" && cell.type !== "tableHeaderCell") {
|
|
303
|
+
issue(issues, cellPath, "invalid-row-child", "Table rows may only contain cells.");
|
|
304
|
+
}
|
|
305
|
+
if (!cell.children.length)
|
|
306
|
+
issue(issues, cellPath, "empty-table-cell", "Table cells require block content.");
|
|
307
|
+
if (cell.colspan !== undefined && (!Number.isInteger(cell.colspan) || cell.colspan < 1)) {
|
|
308
|
+
issue(issues, cellPath, "invalid-colspan", "Cell colspan must be a positive integer.");
|
|
309
|
+
}
|
|
310
|
+
if (cell.rowspan !== undefined && (!Number.isInteger(cell.rowspan) || cell.rowspan < 1)) {
|
|
311
|
+
issue(issues, cellPath, "invalid-rowspan", "Cell rowspan must be a positive integer.");
|
|
312
|
+
}
|
|
313
|
+
cell.children.forEach((child, childIndex) => validateBlock(child, [...cellPath, childIndex], issues));
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
export const validateSmartDocument = (document, schema = defaultSmartSchema) => {
|
|
319
|
+
const issues = [];
|
|
320
|
+
if (document.type !== "doc")
|
|
321
|
+
issue(issues, [], "invalid-root", "The document root must have type doc.");
|
|
322
|
+
if (!Array.isArray(document.children) || !document.children.length) {
|
|
323
|
+
issue(issues, [], "empty-document", "The document requires at least one block.");
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
document.children.forEach((block, index) => validateBlock(block, [index], issues));
|
|
327
|
+
}
|
|
328
|
+
schema.extensions.forEach((extension) => {
|
|
329
|
+
if (extension.validate)
|
|
330
|
+
issues.push(...extension.validate(document));
|
|
331
|
+
});
|
|
332
|
+
return { valid: issues.length === 0, issues };
|
|
333
|
+
};
|
|
@@ -1,17 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
href: string;
|
|
3
|
-
target?: string;
|
|
4
|
-
}
|
|
5
|
-
export type NormalizedLinkKind = "url" | "email" | "phone" | "anchor" | "invalid";
|
|
6
|
-
export interface NormalizedLinkResult {
|
|
7
|
-
kind: NormalizedLinkKind;
|
|
8
|
-
href: string | null;
|
|
9
|
-
input: string;
|
|
10
|
-
}
|
|
11
|
-
export declare const normalizeLinkInput: (input: string | undefined | null) => NormalizedLinkResult;
|
|
12
|
-
export declare const sanitizeLinkHref: (href: string | undefined | null) => string | null;
|
|
13
|
-
export declare const sanitizeLinkTarget: (target: string | undefined) => string | undefined;
|
|
14
|
-
export declare const sanitizeLinkAttrs: (input: {
|
|
15
|
-
href?: string;
|
|
16
|
-
target?: string;
|
|
17
|
-
}) => SafeLinkAttrs | null;
|
|
1
|
+
export * from "../foundation/security/urlPolicy.js";
|
|
@@ -1,69 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const phonePattern = /^\+?[\d\s().-]{7,}$/;
|
|
5
|
-
const normalizePhone = (value) => {
|
|
6
|
-
const hasLeadingPlus = value.trim().startsWith("+");
|
|
7
|
-
const digits = value.replace(/[^\d]/g, "");
|
|
8
|
-
if (digits.length < 7)
|
|
9
|
-
return null;
|
|
10
|
-
return `${hasLeadingPlus ? "+" : ""}${digits}`;
|
|
11
|
-
};
|
|
12
|
-
const normalizeMailto = (value) => {
|
|
13
|
-
const email = value.slice("mailto:".length).trim();
|
|
14
|
-
return emailPattern.test(email) ? `mailto:${email}` : null;
|
|
15
|
-
};
|
|
16
|
-
const normalizeTel = (value) => {
|
|
17
|
-
const phone = normalizePhone(value.slice("tel:".length));
|
|
18
|
-
return phone ? `tel:${phone}` : null;
|
|
19
|
-
};
|
|
20
|
-
export const normalizeLinkInput = (input) => {
|
|
21
|
-
const trimmed = input?.trim() || "";
|
|
22
|
-
if (!trimmed)
|
|
23
|
-
return { kind: "invalid", href: null, input: "" };
|
|
24
|
-
if (/^mailto:/i.test(trimmed)) {
|
|
25
|
-
const href = normalizeMailto(trimmed);
|
|
26
|
-
return { kind: href ? "email" : "invalid", href, input: trimmed };
|
|
27
|
-
}
|
|
28
|
-
if (/^tel:/i.test(trimmed)) {
|
|
29
|
-
const href = normalizeTel(trimmed);
|
|
30
|
-
return { kind: href ? "phone" : "invalid", href, input: trimmed };
|
|
31
|
-
}
|
|
32
|
-
if (emailPattern.test(trimmed)) {
|
|
33
|
-
return { kind: "email", href: `mailto:${trimmed}`, input: trimmed };
|
|
34
|
-
}
|
|
35
|
-
const phone = normalizePhone(trimmed);
|
|
36
|
-
if (phone && (trimmed.startsWith("+") || phonePattern.test(trimmed))) {
|
|
37
|
-
return { kind: "phone", href: `tel:${phone}`, input: trimmed };
|
|
38
|
-
}
|
|
39
|
-
if (/^#[A-Za-z][\w:.-]*$/.test(trimmed)) {
|
|
40
|
-
return { kind: "anchor", href: trimmed, input: trimmed };
|
|
41
|
-
}
|
|
42
|
-
if (bareDomainPattern.test(trimmed)) {
|
|
43
|
-
return { kind: "url", href: `https://${trimmed}`, input: trimmed };
|
|
44
|
-
}
|
|
45
|
-
try {
|
|
46
|
-
const parsed = new URL(trimmed);
|
|
47
|
-
return {
|
|
48
|
-
kind: allowedProtocols.has(parsed.protocol) ? "url" : "invalid",
|
|
49
|
-
href: allowedProtocols.has(parsed.protocol) ? trimmed : null,
|
|
50
|
-
input: trimmed,
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
return { kind: "invalid", href: null, input: trimmed };
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
export const sanitizeLinkHref = (href) => {
|
|
58
|
-
return normalizeLinkInput(href).href;
|
|
59
|
-
};
|
|
60
|
-
export const sanitizeLinkTarget = (target) => {
|
|
61
|
-
const trimmed = target?.trim();
|
|
62
|
-
return trimmed || undefined;
|
|
63
|
-
};
|
|
64
|
-
export const sanitizeLinkAttrs = (input) => {
|
|
65
|
-
const href = sanitizeLinkHref(input.href);
|
|
66
|
-
if (!href)
|
|
67
|
-
return null;
|
|
68
|
-
return { href, target: sanitizeLinkTarget(input.target) };
|
|
69
|
-
};
|
|
1
|
+
// Legacy compatibility entry point. The canonical implementation lives inside
|
|
2
|
+
// the foundation boundary so mark commands do not depend on root contracts.
|
|
3
|
+
export * from "../foundation/security/urlPolicy.js";
|
package/dist/selection.d.ts
CHANGED
|
@@ -27,4 +27,4 @@ export interface SmartCellSelection {
|
|
|
27
27
|
export interface SmartAllSelection {
|
|
28
28
|
type: "all";
|
|
29
29
|
}
|
|
30
|
-
export type
|
|
30
|
+
export type LegacySmartSelection = SmartTextSelection | SmartNodeSelection | SmartCellSelection | SmartAllSelection;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { LegacySmartDocument } from "./model.js";
|
|
2
|
+
import type { LegacySmartSelection } from "./selection.js";
|
|
3
|
+
import type { LegacySmartOperation } from "./transaction.js";
|
|
4
|
+
export declare const mapSelectionThroughOperation: (selection: LegacySmartSelection, operation: LegacySmartOperation, documentBefore: LegacySmartDocument) => LegacySmartSelection;
|