smartrte-react 0.3.5 → 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 +14 -0
- package/README.md +106 -14
- package/dist/adapters/domChecklistCommandBridge.js +1 -1
- package/dist/adapters/domCommandBridge.d.ts +2 -2
- package/dist/adapters/domCommandBridge.js +2 -2
- package/dist/adapters/domInlineAtomCommandBridge.d.ts +10 -9
- package/dist/adapters/domInlineAtomCommandBridge.js +154 -50
- package/dist/adapters/domInlineImageCommandBridge.d.ts +7 -7
- package/dist/adapters/domInlineImageCommandBridge.js +6 -72
- package/dist/adapters/domMoveCommandBridge.js +1 -1
- package/dist/adapters/domSelectionBridge.d.ts +3 -3
- package/dist/adapters/domSmartDocument.d.ts +4 -4
- package/dist/adapters/domSmartDocument.js +2 -2
- package/dist/adapters/domTableCommandBridge.d.ts +42 -16
- package/dist/adapters/domTableCommandBridge.js +203 -173
- package/dist/adapters/internalFlags.d.ts +0 -8
- package/dist/adapters/internalFlags.js +0 -24
- package/dist/adapters/legacyListShadowComparator.d.ts +1 -1
- package/dist/adapters/legacyListShadowComparator.js +1 -1
- package/dist/adapters/pdfPrint.d.ts +8 -0
- package/dist/adapters/pdfPrint.js +22 -0
- package/dist/adapters/shadowMode.d.ts +3 -3
- package/dist/adapters/shadowMode.js +1 -1
- package/dist/canonicalEditorRuntime.d.ts +53 -1
- package/dist/canonicalEditorRuntime.js +61 -4
- package/dist/capabilityPresets.d.ts +27 -0
- package/dist/capabilityPresets.js +21 -0
- package/dist/collabTransport.d.ts +66 -0
- package/dist/collabTransport.js +1 -0
- package/dist/commentProvider.d.ts +24 -0
- package/dist/commentProvider.js +1 -0
- package/dist/components/CanonicalAuthorityEditor.d.ts +35 -1
- package/dist/components/CanonicalAuthorityEditor.js +1086 -112
- package/dist/components/ClassicEditorAuthority.d.ts +93 -22
- package/dist/components/ClassicEditorAuthority.js +11 -43
- package/dist/components/ColorPickerPopover.d.ts +39 -0
- package/dist/components/ColorPickerPopover.js +285 -0
- package/dist/components/CommentMarkers.d.ts +25 -0
- package/dist/components/CommentMarkers.js +105 -0
- package/dist/components/CommentThreadPanel.d.ts +26 -0
- package/dist/components/CommentThreadPanel.js +47 -0
- package/dist/components/ContextMenu.d.ts +23 -0
- package/dist/components/ContextMenu.js +141 -0
- package/dist/components/FormulaLibraryPopover.d.ts +16 -0
- package/dist/components/FormulaLibraryPopover.js +107 -0
- package/dist/components/LinkEditorPopover.d.ts +3 -1
- package/dist/components/LinkEditorPopover.js +22 -6
- package/dist/components/MediaManager.d.ts +4 -20
- package/dist/components/MediaManager.js +35 -6
- package/dist/components/MediaOverlay.d.ts +36 -0
- package/dist/components/MediaOverlay.js +163 -0
- package/dist/components/SpecialCharacterPopover.d.ts +18 -0
- package/dist/components/SpecialCharacterPopover.js +99 -0
- package/dist/components/StructuralSuggestionMarkers.d.ts +20 -0
- package/dist/components/StructuralSuggestionMarkers.js +56 -0
- package/dist/components/SuggestionPanel.d.ts +26 -0
- package/dist/components/SuggestionPanel.js +33 -0
- package/dist/components/TableBorderPopover.d.ts +59 -0
- package/dist/components/TableBorderPopover.js +147 -0
- package/dist/components/TableResizeHandles.d.ts +25 -0
- package/dist/components/TableResizeHandles.js +301 -0
- package/dist/components/TableSizePickerPopover.d.ts +16 -0
- package/dist/components/TableSizePickerPopover.js +126 -0
- package/dist/components/ToolbarPrimitives.d.ts +129 -0
- package/dist/components/ToolbarPrimitives.js +146 -0
- package/dist/components/VersionHistoryPanel.d.ts +9 -0
- package/dist/components/VersionHistoryPanel.js +157 -0
- package/dist/formulaLibrary.d.ts +31 -0
- package/dist/formulaLibrary.js +90 -0
- package/dist/index.d.ts +22 -24
- package/dist/index.js +14 -11
- package/dist/mediaManagerAdapter.d.ts +12 -0
- package/dist/mediaManagerAdapter.js +34 -0
- package/dist/mediaProvider.d.ts +21 -1
- package/dist/specialCharacters.d.ts +22 -0
- package/dist/specialCharacters.js +86 -0
- package/dist/standalone/classic-editor-embed.js +19 -12
- package/dist/suggestionProvider.d.ts +17 -0
- package/dist/suggestionProvider.js +1 -0
- package/dist/theme.d.ts +1 -1
- package/dist/theme.js +150 -20
- package/dist/versionProvider.d.ts +29 -0
- package/dist/versionProvider.js +1 -0
- package/package.json +28 -14
- package/dist/adapters/canonicalInlineCommandBridge.d.ts +0 -15
- package/dist/adapters/canonicalInlineCommandBridge.js +0 -269
- package/dist/adapters/canonicalListCommandBridge.d.ts +0 -26
- package/dist/adapters/canonicalListCommandBridge.js +0 -430
- package/dist/adapters/coreBold.d.ts +0 -5
- package/dist/adapters/coreBold.js +0 -3
- package/dist/adapters/documentFormats.d.ts +0 -26
- package/dist/adapters/documentFormats.js +0 -49
- package/dist/adapters/docxFormat.d.ts +0 -5
- package/dist/adapters/docxFormat.js +0 -272
- package/dist/adapters/domBlockCommandBridge.d.ts +0 -19
- package/dist/adapters/domBlockCommandBridge.js +0 -79
- package/dist/adapters/inlineMarkCoreExecution.d.ts +0 -9
- package/dist/adapters/inlineMarkCoreExecution.js +0 -25
- package/dist/adapters/pdfFormat.d.ts +0 -23
- package/dist/adapters/pdfFormat.js +0 -204
- package/dist/adapters/portableDocxAtoms.d.ts +0 -4
- package/dist/adapters/portableDocxAtoms.js +0 -58
- package/dist/adapters/styledDocxFormat.d.ts +0 -8
- package/dist/adapters/styledDocxFormat.js +0 -190
- package/dist/builtInFormatDefinitions.d.ts +0 -5
- package/dist/builtInFormatDefinitions.js +0 -82
- package/dist/canonicalAuthorityFlag.d.ts +0 -32
- package/dist/canonicalAuthorityFlag.js +0 -49
- package/dist/canonicalClipboardRuntime.d.ts +0 -15
- package/dist/canonicalClipboardRuntime.js +0 -76
- package/dist/components/ClassicEditor.d.ts +0 -76
- package/dist/components/ClassicEditor.js +0 -6729
- package/dist/editorController.d.ts +0 -78
- package/dist/editorController.js +0 -298
- package/dist/formatFidelity.d.ts +0 -14
- package/dist/formatFidelity.js +0 -107
- package/dist/formatRuntime.d.ts +0 -50
- package/dist/formatRuntime.js +0 -20
- package/dist/pluginRuntime.d.ts +0 -68
- package/dist/pluginRuntime.js +0 -78
- package/dist/standalone/editor.js +0 -1068
- package/dist/test-harness/atomShadowComparator.d.ts +0 -14
- package/dist/test-harness/atomShadowComparator.js +0 -63
- package/dist/test-harness/blockShadowComparator.d.ts +0 -30
- package/dist/test-harness/blockShadowComparator.js +0 -140
- package/dist/test-harness/clipboardShadowComparator.d.ts +0 -12
- package/dist/test-harness/clipboardShadowComparator.js +0 -46
- package/dist/test-harness/inlineShadowComparator.d.ts +0 -32
- package/dist/test-harness/inlineShadowComparator.js +0 -152
- package/dist/test-harness/legacyAtomEngine.d.ts +0 -10
- package/dist/test-harness/legacyAtomEngine.js +0 -15
- package/dist/test-harness/legacyBlockEngine.d.ts +0 -31
- package/dist/test-harness/legacyBlockEngine.js +0 -31
- package/dist/test-harness/legacyClipboardEngine.d.ts +0 -14
- package/dist/test-harness/legacyClipboardEngine.js +0 -67
- package/dist/test-harness/legacyInlineEngine.d.ts +0 -19
- package/dist/test-harness/legacyInlineEngine.js +0 -49
- package/dist/test-harness/legacyTableEngine.d.ts +0 -12
- package/dist/test-harness/legacyTableEngine.js +0 -25
- package/dist/test-harness/tableShadowComparator.d.ts +0 -29
- package/dist/test-harness/tableShadowComparator.js +0 -101
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import type { SmartDocument, SmartEditorState, SmartRtePlugin, SmartSelection, SmartTransaction } from "smartrte-core";
|
|
2
|
-
import { type DomCommandResult } from "./adapters/domCommandBridge.js";
|
|
3
|
-
import { type DomBlockCommand } from "./adapters/domBlockCommandBridge.js";
|
|
4
|
-
import { type DomInlineImageInput } from "./adapters/domInlineImageCommandBridge.js";
|
|
5
|
-
import { type DomFormulaInput } from "./adapters/domInlineAtomCommandBridge.js";
|
|
6
|
-
import { type DomTableCommand } from "./adapters/domTableCommandBridge.js";
|
|
7
|
-
export interface DomEditorControllerSnapshot {
|
|
8
|
-
document: SmartDocument;
|
|
9
|
-
selection: SmartSelection | null;
|
|
10
|
-
html: string;
|
|
11
|
-
}
|
|
12
|
-
export interface DomEditorControllerChange {
|
|
13
|
-
commandId: string;
|
|
14
|
-
snapshot: DomEditorControllerSnapshot;
|
|
15
|
-
}
|
|
16
|
-
export type DomEditorControllerListener = (change: DomEditorControllerChange) => void;
|
|
17
|
-
interface DomHistorySnapshot {
|
|
18
|
-
html: string;
|
|
19
|
-
selection: SmartSelection | null;
|
|
20
|
-
version: number;
|
|
21
|
-
canonical?: {
|
|
22
|
-
forward: SmartTransaction;
|
|
23
|
-
inverse: SmartTransaction;
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Owns the canonical boundary between a contenteditable root and SmartDocument.
|
|
28
|
-
*
|
|
29
|
-
* React remains responsible for rendering UI and legacy DOM-only commands while
|
|
30
|
-
* model commands, document snapshots, serialization, and replacement flow
|
|
31
|
-
* through this controller.
|
|
32
|
-
*/
|
|
33
|
-
export declare class DomEditorController {
|
|
34
|
-
private root;
|
|
35
|
-
private plugins;
|
|
36
|
-
private readOnly;
|
|
37
|
-
private readonly listeners;
|
|
38
|
-
private readonly undoStack;
|
|
39
|
-
private readonly redoStack;
|
|
40
|
-
private historyLimit;
|
|
41
|
-
private mutationVersion;
|
|
42
|
-
private canonicalState;
|
|
43
|
-
bindRoot(root: HTMLElement | null): this;
|
|
44
|
-
configure(options: {
|
|
45
|
-
plugins?: readonly SmartRtePlugin[];
|
|
46
|
-
readOnly?: boolean;
|
|
47
|
-
historyLimit?: number;
|
|
48
|
-
}): this;
|
|
49
|
-
snapshot(): DomEditorControllerSnapshot | null;
|
|
50
|
-
getDocument(): SmartDocument;
|
|
51
|
-
getState(): SmartEditorState | null;
|
|
52
|
-
canExecute<Input>(commandId: string, input?: Input): boolean;
|
|
53
|
-
recordHistorySnapshot(html?: string): boolean;
|
|
54
|
-
discardLastHistorySnapshot(expectedHtml?: string): boolean;
|
|
55
|
-
restoreHistory(direction: "undo" | "redo"): DomHistorySnapshot | null;
|
|
56
|
-
historyStatus(): {
|
|
57
|
-
undo: number;
|
|
58
|
-
redo: number;
|
|
59
|
-
canonicalUndo: number;
|
|
60
|
-
canonicalRedo: number;
|
|
61
|
-
};
|
|
62
|
-
execute<Input>(commandId: string, input?: Input): DomCommandResult | null;
|
|
63
|
-
executeBlockCommand(blocks: readonly HTMLElement[], command: DomBlockCommand): HTMLElement[] | null;
|
|
64
|
-
executeChecklistItemCommand(list: HTMLElement, item: HTMLElement, checked?: boolean): HTMLElement | null;
|
|
65
|
-
insertInlineImage(input: DomInlineImageInput): HTMLImageElement | null;
|
|
66
|
-
updateInlineImage(image: HTMLImageElement, input: Omit<DomInlineImageInput, "src">): boolean;
|
|
67
|
-
insertFormula(input: DomFormulaInput): HTMLElement | null;
|
|
68
|
-
deleteInlineAtom(atom: HTMLElement): boolean;
|
|
69
|
-
executeTableCommand(table: HTMLTableElement, command: DomTableCommand): HTMLTableElement | null;
|
|
70
|
-
insertTable(rows: number, columns: number, headerRow?: boolean): HTMLTableElement | null;
|
|
71
|
-
removeTable(table: HTMLTableElement): boolean;
|
|
72
|
-
replaceDocument(document: SmartDocument, selection?: SmartSelection): boolean;
|
|
73
|
-
subscribe(listener: DomEditorControllerListener): () => boolean;
|
|
74
|
-
private emitLocalizedChange;
|
|
75
|
-
private promoteHistoryEntry;
|
|
76
|
-
}
|
|
77
|
-
export declare const createDomEditorController: () => DomEditorController;
|
|
78
|
-
export {};
|
package/dist/editorController.js
DELETED
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
import { applyTransaction, invertTransaction } from "smartrte-core";
|
|
2
|
-
import { createSmartEditor } from "smartrte-core";
|
|
3
|
-
import { executeDomCommand } from "./adapters/domCommandBridge.js";
|
|
4
|
-
import { executeDomBlockCommand, } from "./adapters/domBlockCommandBridge.js";
|
|
5
|
-
import { executeDomChecklistItemCommand } from "./adapters/domChecklistCommandBridge.js";
|
|
6
|
-
import { executeDomInlineImageCommand, executeDomInlineImageUpdate, } from "./adapters/domInlineImageCommandBridge.js";
|
|
7
|
-
import { executeDomFormulaInsert, executeDomInlineAtomDelete, } from "./adapters/domInlineAtomCommandBridge.js";
|
|
8
|
-
import { executeDomTableCommand, executeDomTableRemoval, } from "./adapters/domTableCommandBridge.js";
|
|
9
|
-
import { restoreSelectionToDom, selectionFromDom } from "./adapters/domSelectionBridge.js";
|
|
10
|
-
import { serializeSmartDocument, smartDocumentFromEditorRoot, smartDocumentFromHtml, } from "./adapters/domSmartDocument.js";
|
|
11
|
-
/**
|
|
12
|
-
* Owns the canonical boundary between a contenteditable root and SmartDocument.
|
|
13
|
-
*
|
|
14
|
-
* React remains responsible for rendering UI and legacy DOM-only commands while
|
|
15
|
-
* model commands, document snapshots, serialization, and replacement flow
|
|
16
|
-
* through this controller.
|
|
17
|
-
*/
|
|
18
|
-
export class DomEditorController {
|
|
19
|
-
constructor() {
|
|
20
|
-
this.root = null;
|
|
21
|
-
this.plugins = [];
|
|
22
|
-
this.readOnly = false;
|
|
23
|
-
this.listeners = new Set();
|
|
24
|
-
this.undoStack = [];
|
|
25
|
-
this.redoStack = [];
|
|
26
|
-
this.historyLimit = 100;
|
|
27
|
-
this.mutationVersion = 0;
|
|
28
|
-
this.canonicalState = null;
|
|
29
|
-
}
|
|
30
|
-
bindRoot(root) {
|
|
31
|
-
this.root = root;
|
|
32
|
-
return this;
|
|
33
|
-
}
|
|
34
|
-
configure(options) {
|
|
35
|
-
if (options.plugins)
|
|
36
|
-
this.plugins = options.plugins;
|
|
37
|
-
if (options.readOnly !== undefined)
|
|
38
|
-
this.readOnly = options.readOnly;
|
|
39
|
-
if (options.historyLimit !== undefined) {
|
|
40
|
-
this.historyLimit = Math.max(1, Math.floor(options.historyLimit));
|
|
41
|
-
}
|
|
42
|
-
return this;
|
|
43
|
-
}
|
|
44
|
-
snapshot() {
|
|
45
|
-
if (!this.root)
|
|
46
|
-
return null;
|
|
47
|
-
const { document } = smartDocumentFromEditorRoot(this.root);
|
|
48
|
-
const selection = selectionFromDom(this.root, this.root.ownerDocument.defaultView?.getSelection() || null);
|
|
49
|
-
const snapshot = {
|
|
50
|
-
document,
|
|
51
|
-
selection,
|
|
52
|
-
html: serializeSmartDocument(document),
|
|
53
|
-
};
|
|
54
|
-
this.canonicalState = selection ? { document, selection } : null;
|
|
55
|
-
return snapshot;
|
|
56
|
-
}
|
|
57
|
-
getDocument() {
|
|
58
|
-
return this.snapshot()?.document || { type: "doc", children: [] };
|
|
59
|
-
}
|
|
60
|
-
getState() {
|
|
61
|
-
const snapshot = this.snapshot();
|
|
62
|
-
return snapshot?.selection
|
|
63
|
-
? { document: snapshot.document, selection: snapshot.selection }
|
|
64
|
-
: null;
|
|
65
|
-
}
|
|
66
|
-
canExecute(commandId, input) {
|
|
67
|
-
if (!this.root || this.readOnly)
|
|
68
|
-
return false;
|
|
69
|
-
const state = this.getState();
|
|
70
|
-
if (!state)
|
|
71
|
-
return false;
|
|
72
|
-
return createSmartEditor({
|
|
73
|
-
state,
|
|
74
|
-
plugins: [...this.plugins],
|
|
75
|
-
readOnly: this.readOnly,
|
|
76
|
-
}).canExecute(commandId, input);
|
|
77
|
-
}
|
|
78
|
-
recordHistorySnapshot(html) {
|
|
79
|
-
if (!this.root || this.readOnly)
|
|
80
|
-
return false;
|
|
81
|
-
const snapshot = this.snapshot();
|
|
82
|
-
const entry = {
|
|
83
|
-
html: html ?? this.root.innerHTML,
|
|
84
|
-
selection: snapshot?.selection || null,
|
|
85
|
-
version: this.mutationVersion,
|
|
86
|
-
};
|
|
87
|
-
if (this.undoStack[this.undoStack.length - 1]?.html === entry.html)
|
|
88
|
-
return false;
|
|
89
|
-
this.undoStack.push(entry);
|
|
90
|
-
this.promoteHistoryEntry(entry, snapshot);
|
|
91
|
-
if (this.undoStack.length > this.historyLimit)
|
|
92
|
-
this.undoStack.shift();
|
|
93
|
-
this.redoStack.length = 0;
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
discardLastHistorySnapshot(expectedHtml) {
|
|
97
|
-
const latest = this.undoStack[this.undoStack.length - 1];
|
|
98
|
-
if (!latest || expectedHtml !== undefined && latest.html !== expectedHtml)
|
|
99
|
-
return false;
|
|
100
|
-
this.undoStack.pop();
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
restoreHistory(direction) {
|
|
104
|
-
if (!this.root || this.readOnly)
|
|
105
|
-
return null;
|
|
106
|
-
const from = direction === "undo" ? this.undoStack : this.redoStack;
|
|
107
|
-
const to = direction === "undo" ? this.redoStack : this.undoStack;
|
|
108
|
-
let entry;
|
|
109
|
-
while (from.length) {
|
|
110
|
-
const candidate = from.pop();
|
|
111
|
-
if (candidate.html !== this.root.innerHTML) {
|
|
112
|
-
entry = candidate;
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
if (!entry)
|
|
117
|
-
return null;
|
|
118
|
-
const current = this.snapshot();
|
|
119
|
-
if (entry.canonical && current) {
|
|
120
|
-
const transaction = direction === "undo"
|
|
121
|
-
? entry.canonical.inverse
|
|
122
|
-
: entry.canonical.forward;
|
|
123
|
-
this.canonicalState = applyTransaction({ document: current.document, selection: current.selection || { type: "all" } }, transaction);
|
|
124
|
-
}
|
|
125
|
-
to.push({
|
|
126
|
-
html: this.root.innerHTML,
|
|
127
|
-
selection: current?.selection || null,
|
|
128
|
-
canonical: entry.canonical,
|
|
129
|
-
version: this.mutationVersion,
|
|
130
|
-
});
|
|
131
|
-
this.root.innerHTML = entry.html;
|
|
132
|
-
this.mutationVersion += 1;
|
|
133
|
-
if (entry.selection)
|
|
134
|
-
restoreSelectionToDom(this.root, entry.selection);
|
|
135
|
-
return entry;
|
|
136
|
-
}
|
|
137
|
-
historyStatus() {
|
|
138
|
-
return {
|
|
139
|
-
undo: this.undoStack.length,
|
|
140
|
-
redo: this.redoStack.length,
|
|
141
|
-
canonicalUndo: this.undoStack.filter((entry) => entry.canonical).length,
|
|
142
|
-
canonicalRedo: this.redoStack.filter((entry) => entry.canonical).length,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
execute(commandId, input) {
|
|
146
|
-
if (!this.root || this.readOnly)
|
|
147
|
-
return null;
|
|
148
|
-
const result = executeDomCommand({
|
|
149
|
-
root: this.root,
|
|
150
|
-
plugins: [...this.plugins],
|
|
151
|
-
commandId,
|
|
152
|
-
input,
|
|
153
|
-
});
|
|
154
|
-
if (!result)
|
|
155
|
-
return null;
|
|
156
|
-
this.emitLocalizedChange(commandId);
|
|
157
|
-
return result;
|
|
158
|
-
}
|
|
159
|
-
executeBlockCommand(blocks, command) {
|
|
160
|
-
if (!this.root || this.readOnly || blocks.some((block) => !this.root.contains(block))) {
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
const replacements = executeDomBlockCommand(blocks, command);
|
|
164
|
-
if (!replacements)
|
|
165
|
-
return null;
|
|
166
|
-
this.emitLocalizedChange(command.id);
|
|
167
|
-
return replacements;
|
|
168
|
-
}
|
|
169
|
-
executeChecklistItemCommand(list, item, checked) {
|
|
170
|
-
if (!this.root ||
|
|
171
|
-
this.readOnly ||
|
|
172
|
-
!this.root.contains(list) ||
|
|
173
|
-
!list.contains(item)) {
|
|
174
|
-
return null;
|
|
175
|
-
}
|
|
176
|
-
const result = executeDomChecklistItemCommand(list, item, checked);
|
|
177
|
-
if (!result)
|
|
178
|
-
return null;
|
|
179
|
-
this.emitLocalizedChange("checklist.set-checked");
|
|
180
|
-
return result;
|
|
181
|
-
}
|
|
182
|
-
insertInlineImage(input) {
|
|
183
|
-
if (!this.root || this.readOnly)
|
|
184
|
-
return null;
|
|
185
|
-
const image = executeDomInlineImageCommand(this.root, input);
|
|
186
|
-
if (!image)
|
|
187
|
-
return null;
|
|
188
|
-
this.emitLocalizedChange("image.insert-inline");
|
|
189
|
-
return image;
|
|
190
|
-
}
|
|
191
|
-
updateInlineImage(image, input) {
|
|
192
|
-
if (!this.root || this.readOnly || !this.root.contains(image))
|
|
193
|
-
return false;
|
|
194
|
-
if (!executeDomInlineImageUpdate(this.root, image, input))
|
|
195
|
-
return false;
|
|
196
|
-
this.emitLocalizedChange("image.update-inline");
|
|
197
|
-
return true;
|
|
198
|
-
}
|
|
199
|
-
insertFormula(input) {
|
|
200
|
-
if (!this.root || this.readOnly)
|
|
201
|
-
return null;
|
|
202
|
-
const formula = executeDomFormulaInsert(this.root, input);
|
|
203
|
-
if (!formula)
|
|
204
|
-
return null;
|
|
205
|
-
this.emitLocalizedChange("formula.insert");
|
|
206
|
-
return formula;
|
|
207
|
-
}
|
|
208
|
-
deleteInlineAtom(atom) {
|
|
209
|
-
if (!this.root || this.readOnly || !this.root.contains(atom))
|
|
210
|
-
return false;
|
|
211
|
-
const commandId = atom.hasAttribute("data-formula") ? "formula.delete" : "image.delete-inline";
|
|
212
|
-
if (!executeDomInlineAtomDelete(this.root, atom))
|
|
213
|
-
return false;
|
|
214
|
-
this.emitLocalizedChange(commandId);
|
|
215
|
-
return true;
|
|
216
|
-
}
|
|
217
|
-
executeTableCommand(table, command) {
|
|
218
|
-
if (!this.root || this.readOnly || !this.root.contains(table))
|
|
219
|
-
return null;
|
|
220
|
-
const replacement = executeDomTableCommand(table, command);
|
|
221
|
-
if (!replacement)
|
|
222
|
-
return null;
|
|
223
|
-
this.emitLocalizedChange(command.id);
|
|
224
|
-
return replacement;
|
|
225
|
-
}
|
|
226
|
-
insertTable(rows, columns, headerRow = false) {
|
|
227
|
-
if (!this.root || this.readOnly)
|
|
228
|
-
return null;
|
|
229
|
-
const snapshot = this.snapshot();
|
|
230
|
-
if (!snapshot?.selection || snapshot.selection.type !== "text")
|
|
231
|
-
return null;
|
|
232
|
-
const topLevelIndex = snapshot.selection.anchor.path[0];
|
|
233
|
-
if (!Number.isInteger(topLevelIndex))
|
|
234
|
-
return null;
|
|
235
|
-
const path = [Math.min(topLevelIndex + 1, snapshot.document.children.length)];
|
|
236
|
-
const result = this.execute("table.insert", { path, rows, columns, headerRow });
|
|
237
|
-
if (!result)
|
|
238
|
-
return null;
|
|
239
|
-
const candidate = this.root.children[path[0]];
|
|
240
|
-
if (candidate instanceof HTMLTableElement)
|
|
241
|
-
return candidate;
|
|
242
|
-
return candidate?.querySelector("table") || null;
|
|
243
|
-
}
|
|
244
|
-
removeTable(table) {
|
|
245
|
-
if (!this.root || this.readOnly || !this.root.contains(table))
|
|
246
|
-
return false;
|
|
247
|
-
if (!executeDomTableRemoval(table))
|
|
248
|
-
return false;
|
|
249
|
-
this.emitLocalizedChange("table.remove");
|
|
250
|
-
return true;
|
|
251
|
-
}
|
|
252
|
-
replaceDocument(document, selection) {
|
|
253
|
-
if (!this.root || this.readOnly)
|
|
254
|
-
return false;
|
|
255
|
-
this.root.innerHTML = serializeSmartDocument(document);
|
|
256
|
-
if (selection)
|
|
257
|
-
restoreSelectionToDom(this.root, selection);
|
|
258
|
-
return true;
|
|
259
|
-
}
|
|
260
|
-
subscribe(listener) {
|
|
261
|
-
this.listeners.add(listener);
|
|
262
|
-
return () => this.listeners.delete(listener);
|
|
263
|
-
}
|
|
264
|
-
emitLocalizedChange(commandId) {
|
|
265
|
-
const snapshot = this.snapshot();
|
|
266
|
-
if (snapshot) {
|
|
267
|
-
const latest = this.undoStack[this.undoStack.length - 1];
|
|
268
|
-
if (latest?.version === this.mutationVersion) {
|
|
269
|
-
this.promoteHistoryEntry(latest, snapshot, commandId);
|
|
270
|
-
}
|
|
271
|
-
this.mutationVersion += 1;
|
|
272
|
-
this.listeners.forEach((listener) => listener({ commandId, snapshot }));
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
promoteHistoryEntry(entry, after, commandId = "dom.canonical") {
|
|
276
|
-
if (!this.root || !after || entry.canonical || entry.html === this.root.innerHTML)
|
|
277
|
-
return;
|
|
278
|
-
const beforeDocument = smartDocumentFromHtml(entry.html, this.root.ownerDocument);
|
|
279
|
-
if (JSON.stringify(beforeDocument) === JSON.stringify(after.document))
|
|
280
|
-
return;
|
|
281
|
-
const beforeSelection = entry.selection || { type: "all" };
|
|
282
|
-
const afterSelection = after.selection || { type: "all" };
|
|
283
|
-
const forward = {
|
|
284
|
-
id: commandId,
|
|
285
|
-
source: "user",
|
|
286
|
-
operations: [{ type: "replaceNode", path: [], node: after.document }],
|
|
287
|
-
selectionBefore: beforeSelection,
|
|
288
|
-
selectionAfter: afterSelection,
|
|
289
|
-
addToHistory: true,
|
|
290
|
-
timestamp: Date.now(),
|
|
291
|
-
};
|
|
292
|
-
entry.canonical = {
|
|
293
|
-
forward,
|
|
294
|
-
inverse: invertTransaction({ document: beforeDocument, selection: beforeSelection }, forward),
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
export const createDomEditorController = () => new DomEditorController();
|
package/dist/formatFidelity.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
export type FidelityFormat = "html" | "markdown" | "docx" | "pdf";
|
|
2
|
-
export type FidelityLevel = "full" | "semantic" | "lossy" | "unsupported";
|
|
3
|
-
export type FidelityFeature = "inline-marks" | "colors-fonts-sizes" | "headings-alignment" | "blockquote-code" | "lists" | "checklists" | "tables" | "links" | "images-media" | "formulas" | "special-characters";
|
|
4
|
-
export interface FormatFidelityCapability {
|
|
5
|
-
level: FidelityLevel;
|
|
6
|
-
note: string;
|
|
7
|
-
}
|
|
8
|
-
export interface FeatureFidelityContract {
|
|
9
|
-
feature: FidelityFeature;
|
|
10
|
-
formats: Record<FidelityFormat, FormatFidelityCapability>;
|
|
11
|
-
}
|
|
12
|
-
/** Public, test-enforced compatibility contract for built-in document formats. */
|
|
13
|
-
export declare const builtInFormatFidelity: readonly FeatureFidelityContract[];
|
|
14
|
-
export declare const getFormatFidelity: (feature: FidelityFeature, format: FidelityFormat) => FormatFidelityCapability;
|
package/dist/formatFidelity.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
const capability = (level, note) => ({
|
|
2
|
-
level,
|
|
3
|
-
note,
|
|
4
|
-
});
|
|
5
|
-
/** Public, test-enforced compatibility contract for built-in document formats. */
|
|
6
|
-
export const builtInFormatFidelity = [
|
|
7
|
-
{
|
|
8
|
-
feature: "inline-marks",
|
|
9
|
-
formats: {
|
|
10
|
-
html: capability("full", "Canonical marks round-trip."),
|
|
11
|
-
markdown: capability("semantic", "Bold, italic, strike, code, and links round-trip; underline is lossy."),
|
|
12
|
-
docx: capability("semantic", "Supported Word run properties round-trip through the canonical importer."),
|
|
13
|
-
pdf: capability("lossy", "Visual emphasis is inferred from extracted font metadata."),
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
feature: "colors-fonts-sizes",
|
|
18
|
-
formats: {
|
|
19
|
-
html: capability("full", "Inline style marks round-trip."),
|
|
20
|
-
markdown: capability("unsupported", "Portable Markdown has no standard representation."),
|
|
21
|
-
docx: capability("semantic", "Colors and sizes are supported; font-family fidelity depends on importer styles."),
|
|
22
|
-
pdf: capability("lossy", "Font size/style are inferred; colors are extraction-dependent."),
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
feature: "headings-alignment",
|
|
27
|
-
formats: {
|
|
28
|
-
html: capability("full", "Levels, alignment, and indentation round-trip."),
|
|
29
|
-
markdown: capability("lossy", "Heading levels round-trip; alignment and indentation do not."),
|
|
30
|
-
docx: capability("semantic", "Heading styles, alignment, and indentation are emitted."),
|
|
31
|
-
pdf: capability("lossy", "Levels and alignment are inferred geometrically."),
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
feature: "blockquote-code",
|
|
36
|
-
formats: {
|
|
37
|
-
html: capability("full", "Canonical block structure round-trips."),
|
|
38
|
-
markdown: capability("semantic", "Portable blockquote and code syntax round-trip."),
|
|
39
|
-
docx: capability("lossy", "Structure is represented with paragraph styling."),
|
|
40
|
-
pdf: capability("lossy", "Export is visual and import reconstruction is heuristic."),
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
feature: "lists",
|
|
45
|
-
formats: {
|
|
46
|
-
html: capability("full", "Nested list structure and styles round-trip."),
|
|
47
|
-
markdown: capability("semantic", "Nested ordered and unordered structure round-trips; custom markers are lossy."),
|
|
48
|
-
docx: capability("semantic", "Nested lists export with native Word numbering definitions and level metadata."),
|
|
49
|
-
pdf: capability("lossy", "List structure is inferred from extracted markers."),
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
feature: "checklists",
|
|
54
|
-
formats: {
|
|
55
|
-
html: capability("full", "Checked state uses canonical data attributes."),
|
|
56
|
-
markdown: capability("semantic", "GFM task-list state round-trips."),
|
|
57
|
-
docx: capability("lossy", "Checklist semantics currently degrade to visible list content."),
|
|
58
|
-
pdf: capability("lossy", "Checklist semantics are visual only."),
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
feature: "tables",
|
|
63
|
-
formats: {
|
|
64
|
-
html: capability("full", "Spans, headers, colors, borders, and dimensions round-trip."),
|
|
65
|
-
markdown: capability("lossy", "GFM tables preserve text but not spans, dimensions, colors, or borders."),
|
|
66
|
-
docx: capability("semantic", "Table structure and column spans export; advanced layout remains partial."),
|
|
67
|
-
pdf: capability("lossy", "Export is visual and import uses column-position heuristics."),
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
feature: "links",
|
|
72
|
-
formats: {
|
|
73
|
-
html: capability("full", "Safe href and target semantics round-trip."),
|
|
74
|
-
markdown: capability("semantic", "Href and label round-trip; target metadata is lossy."),
|
|
75
|
-
docx: capability("semantic", "Links export as native external Word hyperlink relationships; target behavior is advisory."),
|
|
76
|
-
pdf: capability("lossy", "Links are visual text in the current print/export path."),
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
feature: "images-media",
|
|
81
|
-
formats: {
|
|
82
|
-
html: capability("semantic", "Images, audio, and video round-trip; host-only metadata may be lossy."),
|
|
83
|
-
markdown: capability("lossy", "Inline images round-trip; audio and video are unsupported."),
|
|
84
|
-
docx: capability("semantic", "Data-URL PNG, JPEG, and GIF images embed natively; remote and unsupported sources retain portable markers."),
|
|
85
|
-
pdf: capability("lossy", "Export is visual; semantic media import is unsupported."),
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
feature: "formulas",
|
|
90
|
-
formats: {
|
|
91
|
-
html: capability("full", "Formula source is stored canonically."),
|
|
92
|
-
markdown: capability("semantic", "Dollar-delimited formula source round-trips."),
|
|
93
|
-
docx: capability("semantic", "Formulas emit native OMML linear math and retain a hidden portable source marker for canonical round-trip."),
|
|
94
|
-
pdf: capability("lossy", "Rendered output is visual; source cannot be reconstructed reliably."),
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
feature: "special-characters",
|
|
99
|
-
formats: {
|
|
100
|
-
html: capability("full", "Unicode text round-trips."),
|
|
101
|
-
markdown: capability("full", "Unicode text round-trips."),
|
|
102
|
-
docx: capability("full", "Unicode text is emitted as Word text."),
|
|
103
|
-
pdf: capability("semantic", "Depends on font embedding and extractor Unicode maps."),
|
|
104
|
-
},
|
|
105
|
-
},
|
|
106
|
-
];
|
|
107
|
-
export const getFormatFidelity = (feature, format) => builtInFormatFidelity.find((entry) => entry.feature === feature).formats[format];
|
package/dist/formatRuntime.d.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { SmartDocument } from "smartrte-core";
|
|
2
|
-
export type BuiltInDocumentFormat = "html" | "markdown" | "docx" | "pdf";
|
|
3
|
-
export type EditorDocumentFormat = BuiltInDocumentFormat | (string & {});
|
|
4
|
-
export type EditorFormatConfig = Partial<Record<EditorDocumentFormat, boolean>>;
|
|
5
|
-
export interface EditorFormatImportContext {
|
|
6
|
-
ownerDocument: Document;
|
|
7
|
-
}
|
|
8
|
-
export interface EditorFormatImportResult {
|
|
9
|
-
document: SmartDocument;
|
|
10
|
-
layoutHtml?: string;
|
|
11
|
-
preserveColors?: boolean;
|
|
12
|
-
preserveDocumentLayout?: boolean;
|
|
13
|
-
}
|
|
14
|
-
export type EditorFormatExportResult = {
|
|
15
|
-
kind: "text";
|
|
16
|
-
filename: string;
|
|
17
|
-
mediaType: string;
|
|
18
|
-
content: string;
|
|
19
|
-
} | {
|
|
20
|
-
kind: "blob";
|
|
21
|
-
filename: string;
|
|
22
|
-
content: Blob;
|
|
23
|
-
} | {
|
|
24
|
-
kind: "handled";
|
|
25
|
-
};
|
|
26
|
-
export interface EditorFormatExportContext {
|
|
27
|
-
ownerDocument: Document;
|
|
28
|
-
hostWindow: Window;
|
|
29
|
-
}
|
|
30
|
-
export interface EditorFormatDefinition {
|
|
31
|
-
id: EditorDocumentFormat;
|
|
32
|
-
label: string;
|
|
33
|
-
extension: string;
|
|
34
|
-
accept?: string;
|
|
35
|
-
canImport: boolean;
|
|
36
|
-
canExport: boolean;
|
|
37
|
-
confirmImportWhenNotEmpty?: boolean;
|
|
38
|
-
importFile?: (file: File, context: EditorFormatImportContext) => Promise<EditorFormatImportResult>;
|
|
39
|
-
exportDocument?: (document: SmartDocument, context: EditorFormatExportContext) => EditorFormatExportResult | Promise<EditorFormatExportResult>;
|
|
40
|
-
}
|
|
41
|
-
export interface EditorFormatRuntime {
|
|
42
|
-
formats: readonly EditorFormatDefinition[];
|
|
43
|
-
imports: readonly EditorFormatDefinition[];
|
|
44
|
-
exports: readonly EditorFormatDefinition[];
|
|
45
|
-
has: (format: string) => boolean;
|
|
46
|
-
get: (format: string) => EditorFormatDefinition | undefined;
|
|
47
|
-
canImport: (format: string) => boolean;
|
|
48
|
-
canExport: (format: string) => boolean;
|
|
49
|
-
}
|
|
50
|
-
export declare const createEditorFormatRuntime: (config?: EditorFormatConfig, replacements?: readonly EditorFormatDefinition[]) => EditorFormatRuntime;
|
package/dist/formatRuntime.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { createBuiltInFormatDefinitions } from "./builtInFormatDefinitions.js";
|
|
2
|
-
export const createEditorFormatRuntime = (config = {}, replacements = createBuiltInFormatDefinitions()) => {
|
|
3
|
-
const seen = new Set();
|
|
4
|
-
replacements.forEach((format) => {
|
|
5
|
-
if (seen.has(format.id))
|
|
6
|
-
throw new Error(`Duplicate editor format "${format.id}".`);
|
|
7
|
-
seen.add(format.id);
|
|
8
|
-
});
|
|
9
|
-
const formats = replacements.filter((format) => config[format.id] !== false);
|
|
10
|
-
const byId = new Map(formats.map((format) => [format.id, format]));
|
|
11
|
-
return {
|
|
12
|
-
formats,
|
|
13
|
-
imports: formats.filter((format) => format.canImport),
|
|
14
|
-
exports: formats.filter((format) => format.canExport),
|
|
15
|
-
has: (format) => byId.has(format),
|
|
16
|
-
get: (format) => byId.get(format),
|
|
17
|
-
canImport: (format) => Boolean(byId.get(format)?.canImport),
|
|
18
|
-
canExport: (format) => Boolean(byId.get(format)?.canExport),
|
|
19
|
-
};
|
|
20
|
-
};
|
package/dist/pluginRuntime.d.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { type CoreFeatureConfig, type CoreFeatureId, type SmartRtePlugin } from "smartrte-core";
|
|
2
|
-
import type { ReactNode } from "react";
|
|
3
|
-
import type { EditorFormatDefinition } from "./formatRuntime.js";
|
|
4
|
-
export type ReactEditorFeatureConfig = CoreFeatureConfig;
|
|
5
|
-
export interface ReactCommandContributionContext {
|
|
6
|
-
root: HTMLElement | null;
|
|
7
|
-
selection: Selection | null;
|
|
8
|
-
readOnly: boolean;
|
|
9
|
-
canExecute: (commandId: string, input?: unknown) => boolean;
|
|
10
|
-
}
|
|
11
|
-
export interface ReactCommandContribution {
|
|
12
|
-
id: string;
|
|
13
|
-
commandId: string;
|
|
14
|
-
input?: unknown;
|
|
15
|
-
order?: number;
|
|
16
|
-
isVisible?: (context: ReactCommandContributionContext) => boolean;
|
|
17
|
-
isEnabled?: (context: ReactCommandContributionContext) => boolean;
|
|
18
|
-
isActive?: (context: ReactCommandContributionContext) => boolean;
|
|
19
|
-
}
|
|
20
|
-
export interface ReactToolbarContribution extends ReactCommandContribution {
|
|
21
|
-
label: string;
|
|
22
|
-
title?: string;
|
|
23
|
-
placement?: "main" | "insert" | "more";
|
|
24
|
-
icon?: ReactNode;
|
|
25
|
-
}
|
|
26
|
-
export interface ReactKeyboardShortcutContribution extends ReactCommandContribution {
|
|
27
|
-
key: string;
|
|
28
|
-
primary?: boolean;
|
|
29
|
-
alt?: boolean;
|
|
30
|
-
shift?: boolean;
|
|
31
|
-
}
|
|
32
|
-
export interface ReactContextMenuContext {
|
|
33
|
-
root: HTMLElement;
|
|
34
|
-
target: HTMLElement;
|
|
35
|
-
selection: Selection | null;
|
|
36
|
-
}
|
|
37
|
-
export interface ReactContextMenuContribution extends ReactCommandContribution {
|
|
38
|
-
label: string;
|
|
39
|
-
when?: (context: ReactContextMenuContext) => boolean;
|
|
40
|
-
}
|
|
41
|
-
export interface ReactPluginUi {
|
|
42
|
-
toolbar?: readonly ReactToolbarContribution[];
|
|
43
|
-
shortcuts?: readonly ReactKeyboardShortcutContribution[];
|
|
44
|
-
contextMenu?: readonly ReactContextMenuContribution[];
|
|
45
|
-
formats?: readonly EditorFormatDefinition[];
|
|
46
|
-
}
|
|
47
|
-
export type ReactEditorPlugin = SmartRtePlugin & {
|
|
48
|
-
react?: ReactPluginUi;
|
|
49
|
-
};
|
|
50
|
-
export interface ReactEditorPluginRuntime {
|
|
51
|
-
plugins: readonly SmartRtePlugin[];
|
|
52
|
-
featureIds: ReadonlySet<CoreFeatureId>;
|
|
53
|
-
toolbar: readonly ReactToolbarContribution[];
|
|
54
|
-
shortcuts: readonly ReactKeyboardShortcutContribution[];
|
|
55
|
-
contextMenu: readonly ReactContextMenuContribution[];
|
|
56
|
-
formats: readonly EditorFormatDefinition[];
|
|
57
|
-
hasFeature: (feature: CoreFeatureId) => boolean;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Resolves one authoritative plugin set for both React UI availability and
|
|
61
|
-
* core command execution. Passing `plugins` creates an exact custom runtime;
|
|
62
|
-
* otherwise the standard plugin preset is filtered by `features`.
|
|
63
|
-
*/
|
|
64
|
-
export declare const createReactEditorPluginRuntime: (options?: {
|
|
65
|
-
features?: ReactEditorFeatureConfig;
|
|
66
|
-
plugins?: readonly ReactEditorPlugin[];
|
|
67
|
-
}) => ReactEditorPluginRuntime;
|
|
68
|
-
export declare const matchesPluginShortcut: (event: Pick<KeyboardEvent, "key" | "metaKey" | "ctrlKey" | "altKey" | "shiftKey">, shortcut: ReactKeyboardShortcutContribution) => boolean;
|