@richscripts/richtexteditor 2.14.0 → 2.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +173 -10
- package/angular/build-manifest.json +23 -0
- package/angular/index.d.ts +71 -76
- package/angular/index.mjs +2 -0
- package/angular/package.json +4 -0
- package/headless/index.d.ts +3 -1
- package/headless/index.js +72 -16
- package/index.d.ts +33 -54
- package/integrations/initialization-scope.js +27 -0
- package/integrations/native-mount.js +30 -0
- package/integrations/shared.d.ts +23 -1
- package/integrations/shared.js +58 -22
- package/package.json +25 -3
- package/react/index.js +118 -37
- package/react/index.mjs +29 -0
- package/richtexteditor/all_plugins.js +7113 -1111
- package/richtexteditor/all_plugins.min.js +62 -59
- package/richtexteditor/lang/emoji/LICENSE-CLDR.txt +41 -0
- package/richtexteditor/lang/emoji/rte-emoji-de.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-es.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-fr.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-it.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-ja.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-ko.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-nl.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-pt-pt.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-pt.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-ru.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-zh-Hans.js +3 -0
- package/richtexteditor/lang/emoji/rte-emoji-zh-Hant.js +3 -0
- package/richtexteditor/lang/rte-lang-af.js +1 -0
- package/richtexteditor/lang/rte-lang-ar.js +1 -0
- package/richtexteditor/lang/rte-lang-bg.js +1 -0
- package/richtexteditor/lang/rte-lang-bn.js +1 -0
- package/richtexteditor/lang/rte-lang-bs.js +1 -0
- package/richtexteditor/lang/rte-lang-ca.js +1 -0
- package/richtexteditor/lang/rte-lang-cs.js +1 -0
- package/richtexteditor/lang/rte-lang-cy.js +1 -0
- package/richtexteditor/lang/rte-lang-da.js +1 -0
- package/richtexteditor/lang/rte-lang-de.js +1017 -2
- package/richtexteditor/lang/rte-lang-el.js +1 -0
- package/richtexteditor/lang/rte-lang-en.js +1 -0
- package/richtexteditor/lang/rte-lang-es.js +1023 -2
- package/richtexteditor/lang/rte-lang-et.js +1 -0
- package/richtexteditor/lang/rte-lang-fa.js +1 -0
- package/richtexteditor/lang/rte-lang-fi.js +1 -0
- package/richtexteditor/lang/rte-lang-fil.js +1 -0
- package/richtexteditor/lang/rte-lang-fj.js +1 -0
- package/richtexteditor/lang/rte-lang-fr.js +1023 -2
- package/richtexteditor/lang/rte-lang-ga.js +1 -0
- package/richtexteditor/lang/rte-lang-gu.js +1 -0
- package/richtexteditor/lang/rte-lang-he.js +1 -0
- package/richtexteditor/lang/rte-lang-hi.js +1 -0
- package/richtexteditor/lang/rte-lang-hr.js +1 -0
- package/richtexteditor/lang/rte-lang-ht.js +1 -0
- package/richtexteditor/lang/rte-lang-hu.js +1 -0
- package/richtexteditor/lang/rte-lang-id.js +1 -0
- package/richtexteditor/lang/rte-lang-is.js +1 -0
- package/richtexteditor/lang/rte-lang-it.js +1023 -2
- package/richtexteditor/lang/rte-lang-ja.js +1023 -2
- package/richtexteditor/lang/rte-lang-kn.js +1 -0
- package/richtexteditor/lang/rte-lang-ko.js +1023 -2
- package/richtexteditor/lang/rte-lang-lt.js +1 -0
- package/richtexteditor/lang/rte-lang-lv.js +1 -0
- package/richtexteditor/lang/rte-lang-mg.js +1 -0
- package/richtexteditor/lang/rte-lang-mi.js +1 -0
- package/richtexteditor/lang/rte-lang-ml.js +1 -0
- package/richtexteditor/lang/rte-lang-mr.js +1 -0
- package/richtexteditor/lang/rte-lang-ms.js +1 -0
- package/richtexteditor/lang/rte-lang-mt.js +1 -0
- package/richtexteditor/lang/rte-lang-mww.js +1 -0
- package/richtexteditor/lang/rte-lang-nb.js +1 -0
- package/richtexteditor/lang/rte-lang-nl.js +1023 -2
- package/richtexteditor/lang/rte-lang-otq.js +1 -0
- package/richtexteditor/lang/rte-lang-pa.js +1 -0
- package/richtexteditor/lang/rte-lang-pl.js +1 -0
- package/richtexteditor/lang/rte-lang-pt-pt.js +1023 -2
- package/richtexteditor/lang/rte-lang-pt.js +1023 -2
- package/richtexteditor/lang/rte-lang-ro.js +1 -0
- package/richtexteditor/lang/rte-lang-ru.js +1023 -2
- package/richtexteditor/lang/rte-lang-sk.js +1 -0
- package/richtexteditor/lang/rte-lang-sl.js +1 -0
- package/richtexteditor/lang/rte-lang-sm.js +1 -0
- package/richtexteditor/lang/rte-lang-sr-Cyrl.js +1 -0
- package/richtexteditor/lang/rte-lang-sr-Latn.js +1 -0
- package/richtexteditor/lang/rte-lang-sv.js +1 -0
- package/richtexteditor/lang/rte-lang-sw.js +1 -0
- package/richtexteditor/lang/rte-lang-ta.js +1 -0
- package/richtexteditor/lang/rte-lang-te.js +1 -0
- package/richtexteditor/lang/rte-lang-th.js +1 -0
- package/richtexteditor/lang/rte-lang-tlh-Latn.js +1 -0
- package/richtexteditor/lang/rte-lang-tlh-Piqd.js +1 -0
- package/richtexteditor/lang/rte-lang-to.js +1 -0
- package/richtexteditor/lang/rte-lang-tr.js +1 -0
- package/richtexteditor/lang/rte-lang-ty.js +1 -0
- package/richtexteditor/lang/rte-lang-uk.js +1 -0
- package/richtexteditor/lang/rte-lang-ur.js +1 -0
- package/richtexteditor/lang/rte-lang-vi.js +1 -0
- package/richtexteditor/lang/rte-lang-yua.js +1 -0
- package/richtexteditor/lang/rte-lang-zh-Hans.js +1017 -2
- package/richtexteditor/lang/rte-lang-zh-Hant.js +1017 -2
- package/richtexteditor/plugins/a11yenhance.js +2 -1
- package/richtexteditor/plugins/a11yenhance.min.js +1 -1
- package/richtexteditor/plugins/accessibilitychecker.js +252 -60
- package/richtexteditor/plugins/accessibilitychecker.min.js +1 -1
- package/richtexteditor/plugins/aitoolkit.js +966 -303
- package/richtexteditor/plugins/aitoolkit.min.js +7 -7
- package/richtexteditor/plugins/all_plugins.js +7113 -1111
- package/richtexteditor/plugins/all_plugins.min.js +62 -59
- package/richtexteditor/plugins/autocorrect.js +66 -31
- package/richtexteditor/plugins/autocorrect.min.js +1 -1
- package/richtexteditor/plugins/autoembed.js +17 -0
- package/richtexteditor/plugins/autoembed.min.js +1 -1
- package/richtexteditor/plugins/blocktypes.js +18 -9
- package/richtexteditor/plugins/blocktypes.min.js +1 -1
- package/richtexteditor/plugins/bookmarkcard.js +12 -5
- package/richtexteditor/plugins/bookmarkcard.min.js +2 -2
- package/richtexteditor/plugins/changecase.js +72 -19
- package/richtexteditor/plugins/changecase.min.js +1 -1
- package/richtexteditor/plugins/charlimit.js +62 -2
- package/richtexteditor/plugins/charlimit.min.js +2 -2
- package/richtexteditor/plugins/comments.js +458 -59
- package/richtexteditor/plugins/comments.min.js +4 -3
- package/richtexteditor/plugins/contentminimap.js +25 -6
- package/richtexteditor/plugins/contentminimap.min.js +1 -1
- package/richtexteditor/plugins/crossreference.js +1 -1
- package/richtexteditor/plugins/crossreference.min.js +1 -1
- package/richtexteditor/plugins/dialoga11y.js +26 -4
- package/richtexteditor/plugins/dialoga11y.min.js +1 -1
- package/richtexteditor/plugins/dictation.js +1 -1
- package/richtexteditor/plugins/documentimport.js +220 -51
- package/richtexteditor/plugins/documentimport.min.js +4 -4
- package/richtexteditor/plugins/documentoutline.js +88 -38
- package/richtexteditor/plugins/documentoutline.min.js +1 -1
- package/richtexteditor/plugins/docxexport.js +204 -32
- package/richtexteditor/plugins/docxexport.min.js +2 -2
- package/richtexteditor/plugins/draghandle.js +267 -3
- package/richtexteditor/plugins/draghandle.min.js +1 -1
- package/richtexteditor/plugins/emailtoolkit.js +28 -14
- package/richtexteditor/plugins/emailtoolkit.min.js +1 -1
- package/richtexteditor/plugins/emojiautocomplete.js +110 -56
- package/richtexteditor/plugins/emojiautocomplete.min.js +1 -1
- package/richtexteditor/plugins/footnotes.js +65 -11
- package/richtexteditor/plugins/footnotes.min.js +1 -1
- package/richtexteditor/plugins/formatpainter.js +10 -0
- package/richtexteditor/plugins/formatpainter.min.js +1 -1
- package/richtexteditor/plugins/formattingmarks.js +53 -8
- package/richtexteditor/plugins/formattingmarks.min.js +1 -1
- package/richtexteditor/plugins/gapcursor.js +60 -0
- package/richtexteditor/plugins/gapcursor.min.js +1 -1
- package/richtexteditor/plugins/ghostcomplete.js +1 -1
- package/richtexteditor/plugins/html2pdf.js +1 -1
- package/richtexteditor/plugins/html2pdf.min.js +1 -1
- package/richtexteditor/plugins/imageeditor.js +12 -6
- package/richtexteditor/plugins/imageeditor.min.js +1 -1
- package/richtexteditor/plugins/importstyles.js +1 -1
- package/richtexteditor/plugins/inlinecode.js +25 -0
- package/richtexteditor/plugins/inlinecode.min.js +1 -1
- package/richtexteditor/plugins/insertcode.js +21 -3
- package/richtexteditor/plugins/insertcode.min.js +4 -4
- package/richtexteditor/plugins/insertemoji.js +112 -15
- package/richtexteditor/plugins/insertemoji.min.js +1 -1
- package/richtexteditor/plugins/insertgallery.js +42 -36
- package/richtexteditor/plugins/insertgallery.min.js +1 -1
- package/richtexteditor/plugins/inserttemplate.js +33 -17
- package/richtexteditor/plugins/inserttemplate.min.js +1 -1
- package/richtexteditor/plugins/keyboarda11y.js +66 -3
- package/richtexteditor/plugins/keyboarda11y.min.js +1 -1
- package/richtexteditor/plugins/layouttable.js +20 -0
- package/richtexteditor/plugins/layouttable.min.js +1 -1
- package/richtexteditor/plugins/linkchecker.js +29 -9
- package/richtexteditor/plugins/linkchecker.min.js +1 -1
- package/richtexteditor/plugins/localdraft.js +51 -7
- package/richtexteditor/plugins/localdraft.min.js +1 -1
- package/richtexteditor/plugins/markdownexport.js +159 -0
- package/richtexteditor/plugins/markdownexport.min.js +2 -2
- package/richtexteditor/plugins/mathdialog.js +11 -5
- package/richtexteditor/plugins/mathdialog.min.js +1 -1
- package/richtexteditor/plugins/mentionplugin.js +88 -25
- package/richtexteditor/plugins/mentionplugin.min.js +1 -1
- package/richtexteditor/plugins/mermaiddiagram.js +9 -3
- package/richtexteditor/plugins/mermaiddiagram.min.js +2 -2
- package/richtexteditor/plugins/multilevellist.js +4 -0
- package/richtexteditor/plugins/multilevellist.min.js +1 -1
- package/richtexteditor/plugins/pdfexport.js +235 -35
- package/richtexteditor/plugins/pdfexport.min.js +12 -12
- package/richtexteditor/plugins/permanentpen.js +3 -3
- package/richtexteditor/plugins/permanentpen.min.js +1 -1
- package/richtexteditor/plugins/readabilitystats.js +25 -11
- package/richtexteditor/plugins/readabilitystats.min.js +1 -1
- package/richtexteditor/plugins/readaloud.js +29 -15
- package/richtexteditor/plugins/readaloud.min.js +1 -1
- package/richtexteditor/plugins/restrictedediting.js +166 -0
- package/richtexteditor/plugins/restrictedediting.min.js +2 -2
- package/richtexteditor/plugins/revisionhistory.js +169 -37
- package/richtexteditor/plugins/revisionhistory.min.js +3 -3
- package/richtexteditor/plugins/rubyannotation.js +19 -9
- package/richtexteditor/plugins/rubyannotation.min.js +1 -1
- package/richtexteditor/plugins/sanitizer.js +86 -4
- package/richtexteditor/plugins/sanitizer.min.js +1 -1
- package/richtexteditor/plugins/slashcommand.js +30 -16
- package/richtexteditor/plugins/slashcommand.min.js +2 -2
- package/richtexteditor/plugins/smartchips.js +36 -22
- package/richtexteditor/plugins/smartchips.min.js +2 -2
- package/richtexteditor/plugins/spellcheck.js +17 -8
- package/richtexteditor/plugins/spellcheck.min.js +2 -2
- package/richtexteditor/plugins/stateinspector.js +19 -9
- package/richtexteditor/plugins/stateinspector.min.js +2 -2
- package/richtexteditor/plugins/structured-content-bridge.js +56 -24
- package/richtexteditor/plugins/structured-content-bridge.min.js +7 -7
- package/richtexteditor/plugins/tableofcontents.js +5 -2
- package/richtexteditor/plugins/tableofcontents.min.js +1 -1
- package/richtexteditor/plugins/tabletools.js +388 -3
- package/richtexteditor/plugins/tabletools.min.js +1 -1
- package/richtexteditor/plugins/textdirection.js +18 -5
- package/richtexteditor/plugins/textdirection.min.js +1 -1
- package/richtexteditor/plugins/textpartlanguage.js +161 -32
- package/richtexteditor/plugins/textpartlanguage.min.js +1 -1
- package/richtexteditor/plugins/todolist.js +90 -6
- package/richtexteditor/plugins/todolist.min.js +1 -1
- package/richtexteditor/plugins/trackedchanges.js +1812 -25
- package/richtexteditor/plugins/trackedchanges.min.js +5 -3
- package/richtexteditor/plugins/wordexport.js +2 -2
- package/richtexteditor/plugins/yjscollab.js +9 -4
- package/richtexteditor/plugins/yjscollab.min.js +1 -1
- package/richtexteditor/plugins/zz_richtextbox_dialog_style.js +22 -13
- package/richtexteditor/plugins/zz_richtextbox_dialog_style.min.js +1 -1
- package/richtexteditor/rte-config.js +131 -50
- package/richtexteditor/rte-headless.js +19 -4
- package/richtexteditor/rte-webcomponent.js +89 -16
- package/richtexteditor/rte.js +133 -52
- package/richtexteditor/runtime/colorpicker_more_ns.htm +93 -16
- package/scripts/build-angular.mjs +97 -0
- package/svelte/index.d.ts +2 -1
- package/svelte/index.js +80 -9
- package/vue/index.js +130 -34
- package/angular/component.ts +0 -297
- package/angular/index.ts +0 -24
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Private framework lifecycle helper. Never abort a caller's shared controller.
|
|
2
|
+
function createInitializationScope(parentSignal) {
|
|
3
|
+
var controller = typeof AbortController === "function" ? new AbortController() : null;
|
|
4
|
+
var disposed = false;
|
|
5
|
+
var forwardAbort = null;
|
|
6
|
+
function complete() {
|
|
7
|
+
if (parentSignal && forwardAbort) parentSignal.removeEventListener("abort", forwardAbort);
|
|
8
|
+
forwardAbort = null;
|
|
9
|
+
parentSignal = null;
|
|
10
|
+
}
|
|
11
|
+
if (controller && parentSignal) {
|
|
12
|
+
forwardAbort = function () { controller.abort(parentSignal.reason); };
|
|
13
|
+
if (parentSignal.aborted) forwardAbort();
|
|
14
|
+
else parentSignal.addEventListener("abort", forwardAbort, { once: true });
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
signal: controller ? controller.signal : parentSignal,
|
|
18
|
+
complete: complete,
|
|
19
|
+
dispose: function () {
|
|
20
|
+
if (disposed) return;
|
|
21
|
+
disposed = true;
|
|
22
|
+
complete();
|
|
23
|
+
if (controller) controller.abort();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
module.exports = { createInitializationScope: createInitializationScope };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Native inputs are converted into a sibling editor by the core. Frameworks
|
|
2
|
+
// remove their input, not that sibling; retain ownership of only the generated
|
|
3
|
+
// chrome and restore the input's original visibility during teardown.
|
|
4
|
+
function captureNativeMount(host) {
|
|
5
|
+
if (!host || !/^(INPUT|TEXTAREA)$/i.test(host.tagName || host.nodeName || "")) return null;
|
|
6
|
+
var previous = host.__rteIntegrationNativeMount;
|
|
7
|
+
var ownership = { host: host, parent: host.parentNode, display: previous ? previous.display : host.style && host.style.display,
|
|
8
|
+
hidden: previous ? previous.hidden : host.__rteHidden,
|
|
9
|
+
hadHidden: previous ? previous.hadHidden : Object.prototype.hasOwnProperty.call(host, "__rteHidden") };
|
|
10
|
+
host.__rteIntegrationNativeMount = ownership;
|
|
11
|
+
return ownership;
|
|
12
|
+
}
|
|
13
|
+
function releaseNativeMount(editor, ownership) {
|
|
14
|
+
if (!ownership) return;
|
|
15
|
+
var host = ownership.host, parent = ownership.parent, root = editor && editor.container;
|
|
16
|
+
if (root && root !== host && parent) {
|
|
17
|
+
while (root && root.parentNode !== parent) root = root.parentNode;
|
|
18
|
+
// Never remove the framework-owned input or a wrapper containing it.
|
|
19
|
+
var cursor = host, containsHost = false;
|
|
20
|
+
while (cursor) { if (cursor === root) { containsHost = true; break; } cursor = cursor.parentNode; }
|
|
21
|
+
if (root && root !== host && !containsHost && root.parentNode === parent) parent.removeChild(root);
|
|
22
|
+
}
|
|
23
|
+
if (host.__rteIntegrationNativeMount === ownership) {
|
|
24
|
+
if (host.style) host.style.display = ownership.display || "";
|
|
25
|
+
if (ownership.hadHidden) host.__rteHidden = ownership.hidden;
|
|
26
|
+
else delete host.__rteHidden;
|
|
27
|
+
delete host.__rteIntegrationNativeMount;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
module.exports = { captureNativeMount: captureNativeMount, releaseNativeMount: releaseNativeMount };
|
package/integrations/shared.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
RichTextEditorInstance,
|
|
10
10
|
RichTextEditorLinkAuditOptions,
|
|
11
11
|
RichTextEditorLinkAuditResult,
|
|
12
|
+
RichTextEditorPageSetup,
|
|
12
13
|
RichTextEditorStructuredDocument,
|
|
13
14
|
RichTextEditorStructuredNode,
|
|
14
15
|
RichTextEditorStructuredInput,
|
|
@@ -19,10 +20,24 @@ import type {
|
|
|
19
20
|
RichTextEditorValueFormat
|
|
20
21
|
} from "../index";
|
|
21
22
|
|
|
23
|
+
/** An instance after the structured-content bridge has been installed. */
|
|
24
|
+
export interface RichTextEditorBridgedInstance extends RichTextEditorInstance {
|
|
25
|
+
getJSON(): RichTextEditorStructuredDocument;
|
|
26
|
+
setJSON(value: RichTextEditorStructuredInput): this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface RichTextEditorChangeCoalescer {
|
|
30
|
+
(): void;
|
|
31
|
+
flush(): void;
|
|
32
|
+
cancel(): void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function createChangeCoalescer(emit: () => void, delay?: number): RichTextEditorChangeCoalescer;
|
|
36
|
+
|
|
22
37
|
export function createEditor(
|
|
23
38
|
element: string | Element,
|
|
24
39
|
config?: Record<string, unknown>
|
|
25
|
-
):
|
|
40
|
+
): RichTextEditorBridgedInstance;
|
|
26
41
|
|
|
27
42
|
export function auditAccessibility(
|
|
28
43
|
value: RichTextEditorStructuredInput
|
|
@@ -67,6 +82,13 @@ export function getDocumentMetrics(
|
|
|
67
82
|
}
|
|
68
83
|
): RichTextEditorDocumentMetrics;
|
|
69
84
|
|
|
85
|
+
export function getDocumentPageSetup(value: RichTextEditorStructuredInput): RichTextEditorPageSetup | null;
|
|
86
|
+
|
|
87
|
+
export function setDocumentPageSetup(
|
|
88
|
+
value: RichTextEditorStructuredInput,
|
|
89
|
+
pageSetup: RichTextEditorPageSetup | null
|
|
90
|
+
): RichTextEditorStructuredDocument;
|
|
91
|
+
|
|
70
92
|
export function getMarkdownShortcutAction(
|
|
71
93
|
value: string | null | undefined
|
|
72
94
|
): {
|
package/integrations/shared.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
var pendingLoadsByBasePath =
|
|
1
|
+
var pendingLoadsByBasePath = Object.create(null);
|
|
2
|
+
var failedLoadsByBasePath = Object.create(null);
|
|
2
3
|
|
|
3
4
|
var INLINE_CONTAINER_TAGS = {
|
|
4
5
|
a: true,
|
|
@@ -1789,7 +1790,7 @@ function parseBlockNode(node) {
|
|
|
1789
1790
|
}
|
|
1790
1791
|
var orderedListAttrs = {};
|
|
1791
1792
|
if (startValue) {
|
|
1792
|
-
orderedListAttrs.start = parseInt(startValue, 10)
|
|
1793
|
+
orderedListAttrs.start = (isFinite(parseInt(startValue, 10)) ? parseInt(startValue, 10) : 1);
|
|
1793
1794
|
}
|
|
1794
1795
|
if (orderedListType) {
|
|
1795
1796
|
orderedListAttrs.orderedListType = orderedListType;
|
|
@@ -2529,7 +2530,7 @@ function escapeHtml(value) {
|
|
|
2529
2530
|
}
|
|
2530
2531
|
|
|
2531
2532
|
function escapeAttribute(value) {
|
|
2532
|
-
return escapeHtml(value).replace(/"/g, """);
|
|
2533
|
+
return escapeHtml(value === undefined || value === null ? "" : String(value)).replace(/"/g, """);
|
|
2533
2534
|
}
|
|
2534
2535
|
|
|
2535
2536
|
function buildAttributeString(attrs) {
|
|
@@ -2782,7 +2783,7 @@ function serializeNode(node, inlineMode) {
|
|
|
2782
2783
|
|
|
2783
2784
|
if (node.type === "orderedList") {
|
|
2784
2785
|
var listAttrs = {};
|
|
2785
|
-
if (node.attrs && node.attrs.start) {
|
|
2786
|
+
if (node.attrs && node.attrs.start !== undefined && node.attrs.start !== null) {
|
|
2786
2787
|
listAttrs.start = node.attrs.start;
|
|
2787
2788
|
}
|
|
2788
2789
|
if (node.attrs) {
|
|
@@ -3183,8 +3184,8 @@ function validateNode(node, path, mode, issues) {
|
|
|
3183
3184
|
|
|
3184
3185
|
if (node.type === "bulletList" || node.type === "orderedList") {
|
|
3185
3186
|
if (node.type === "orderedList" && node.attrs && node.attrs.start !== undefined) {
|
|
3186
|
-
if (typeof node.attrs.start !== "number" || node.attrs.start
|
|
3187
|
-
issues.push(createValidationIssue(path + ".attrs.start", "Ordered lists require a
|
|
3187
|
+
if (typeof node.attrs.start !== "number" || !isFinite(node.attrs.start) || Math.floor(node.attrs.start) !== node.attrs.start || Math.abs(node.attrs.start) > 9007199254740991) {
|
|
3188
|
+
issues.push(createValidationIssue(path + ".attrs.start", "Ordered lists require a finite safe integer start value."));
|
|
3188
3189
|
}
|
|
3189
3190
|
}
|
|
3190
3191
|
if (node.type === "orderedList" && node.attrs && node.attrs.orderedListType !== undefined) {
|
|
@@ -3919,12 +3920,12 @@ function getMarkdownListMatch(line) {
|
|
|
3919
3920
|
};
|
|
3920
3921
|
}
|
|
3921
3922
|
|
|
3922
|
-
var orderedMatch = /^(\s*)(\d
|
|
3923
|
+
var orderedMatch = /^(\s*)(\d{1,9})\.\s+(.*)$/.exec(line);
|
|
3923
3924
|
if (orderedMatch) {
|
|
3924
3925
|
return {
|
|
3925
3926
|
indent: orderedMatch[1].length,
|
|
3926
3927
|
ordered: true,
|
|
3927
|
-
start: parseInt(orderedMatch[2], 10)
|
|
3928
|
+
start: parseInt(orderedMatch[2], 10),
|
|
3928
3929
|
text: orderedMatch[3],
|
|
3929
3930
|
marker: orderedMatch[2] + ".",
|
|
3930
3931
|
contentIndent: orderedMatch[1].length + orderedMatch[2].length + 2,
|
|
@@ -4914,8 +4915,13 @@ function serializeMarkdownBlocks(nodes) {
|
|
|
4914
4915
|
|
|
4915
4916
|
if (node.type === "bulletList" || node.type === "orderedList") {
|
|
4916
4917
|
var listParts = [];
|
|
4917
|
-
var start = node.type === "orderedList" && node.attrs && node.attrs.start ? parseInt(node.attrs.start, 10)
|
|
4918
|
+
var start = node.type === "orderedList" && node.attrs && node.attrs.start !== undefined ? parseInt(node.attrs.start, 10) : 1;
|
|
4919
|
+
if (!isFinite(start)) start = 1;
|
|
4918
4920
|
var listItems = node.content || [];
|
|
4921
|
+
if (node.type === "orderedList" && (start < 0 || start + Math.max(0, listItems.length - 1) > 999999999)) {
|
|
4922
|
+
parts.push(serializeNode(node, false));
|
|
4923
|
+
continue;
|
|
4924
|
+
}
|
|
4919
4925
|
for (var itemIndex = 0; itemIndex < listItems.length; itemIndex++) {
|
|
4920
4926
|
var prefix = node.type === "orderedList" ? (start + itemIndex) + ". " : "- ";
|
|
4921
4927
|
listParts.push(serializeMarkdownListItem(listItems[itemIndex].content || [], prefix));
|
|
@@ -5060,15 +5066,28 @@ function installStructuredContentBridge() {
|
|
|
5060
5066
|
}
|
|
5061
5067
|
|
|
5062
5068
|
function ensureStylesheet(href) {
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
5070
|
-
|
|
5071
|
-
|
|
5069
|
+
return new Promise(function (resolve, reject) {
|
|
5070
|
+
var existing = document.querySelector('link[data-rte-style="' + href + '"]');
|
|
5071
|
+
if (existing && (existing.getAttribute("data-rte-loaded") === "true" || existing.sheet)) {
|
|
5072
|
+
resolve();
|
|
5073
|
+
return;
|
|
5074
|
+
}
|
|
5075
|
+
var link = existing || document.createElement("link");
|
|
5076
|
+
link.addEventListener("load", function () {
|
|
5077
|
+
link.setAttribute("data-rte-loaded", "true");
|
|
5078
|
+
resolve();
|
|
5079
|
+
}, { once: true });
|
|
5080
|
+
link.addEventListener("error", function () {
|
|
5081
|
+
if (link.parentNode) link.parentNode.removeChild(link);
|
|
5082
|
+
reject(new Error("Failed to load " + href));
|
|
5083
|
+
}, { once: true });
|
|
5084
|
+
if (!existing) {
|
|
5085
|
+
link.rel = "stylesheet";
|
|
5086
|
+
link.href = href;
|
|
5087
|
+
link.setAttribute("data-rte-style", href);
|
|
5088
|
+
document.head.appendChild(link);
|
|
5089
|
+
}
|
|
5090
|
+
});
|
|
5072
5091
|
}
|
|
5073
5092
|
|
|
5074
5093
|
function loadScript(src) {
|
|
@@ -5098,6 +5117,9 @@ function loadScript(src) {
|
|
|
5098
5117
|
resolve(script);
|
|
5099
5118
|
};
|
|
5100
5119
|
script.onerror = function () {
|
|
5120
|
+
// A failed tag will never fire load again. Let an explicit retry
|
|
5121
|
+
// create a fresh request, without removing successfully loaded core.
|
|
5122
|
+
if (script.parentNode) script.parentNode.removeChild(script);
|
|
5101
5123
|
reject(new Error("Failed to load " + src));
|
|
5102
5124
|
};
|
|
5103
5125
|
|
|
@@ -5114,18 +5136,32 @@ function loadRichTextEditorAssets(options) {
|
|
|
5114
5136
|
|
|
5115
5137
|
var basePath = trimTrailingSlash(options && options.basePath ? options.basePath : "/richtexteditor");
|
|
5116
5138
|
|
|
5117
|
-
|
|
5139
|
+
// Core becomes global before plugins finish. All concurrent mounts must
|
|
5140
|
+
// await the same complete attempt rather than treating core as readiness.
|
|
5141
|
+
if (pendingLoadsByBasePath[basePath]) {
|
|
5142
|
+
return pendingLoadsByBasePath[basePath];
|
|
5143
|
+
}
|
|
5144
|
+
|
|
5145
|
+
if (window.RichTextEditor && !failedLoadsByBasePath[basePath]) {
|
|
5118
5146
|
return Promise.resolve(installStructuredContentBridge());
|
|
5119
5147
|
}
|
|
5120
5148
|
|
|
5121
5149
|
if (!pendingLoadsByBasePath[basePath]) {
|
|
5122
|
-
ensureStylesheet(basePath + "/rte_theme_default.css");
|
|
5123
|
-
|
|
5150
|
+
var themeReady = ensureStylesheet(basePath + "/rte_theme_default.css");
|
|
5151
|
+
var scriptsReady = loadScript(basePath + "/rte.js")
|
|
5124
5152
|
.then(function () {
|
|
5153
|
+
if (window.RTE_DefaultConfig) window.RTE_DefaultConfig.url_base = basePath;
|
|
5125
5154
|
return loadScript(basePath + "/plugins/all_plugins.js");
|
|
5126
|
-
})
|
|
5155
|
+
});
|
|
5156
|
+
pendingLoadsByBasePath[basePath] = Promise.all([themeReady, scriptsReady])
|
|
5127
5157
|
.then(function () {
|
|
5158
|
+
delete failedLoadsByBasePath[basePath];
|
|
5128
5159
|
return installStructuredContentBridge();
|
|
5160
|
+
})
|
|
5161
|
+
.catch(function (error) {
|
|
5162
|
+
delete pendingLoadsByBasePath[basePath];
|
|
5163
|
+
failedLoadsByBasePath[basePath] = true;
|
|
5164
|
+
throw error;
|
|
5129
5165
|
});
|
|
5130
5166
|
}
|
|
5131
5167
|
|
package/package.json
CHANGED
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "2.
|
|
6
|
+
"version": "2.15.0",
|
|
7
7
|
"description": "A full-featured JavaScript rich text editor (WYSIWYG) with toolbar, plugins, i18n support, a built-in AI Toolkit (Ask AI, AI Chat, AI Review drawer, BYOK resolver), structured content APIs (JSON/Markdown), and an optional collaboration / review stack: slash commands, @mentions, human-author Track Changes, threaded comments, revision history, and Yjs-backed presence. Ships first-class React, Vue, Angular and Svelte bindings, a headless \"bring your own UI\" core, and server-safe conversion helpers.",
|
|
8
8
|
"main": "./richtexteditor/rte.js",
|
|
9
9
|
"bin": {
|
|
10
10
|
"rte-migration-report": "./migration/cli.js"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
+
"build:angular": "node scripts/build-angular.mjs",
|
|
14
|
+
"prepack": "node scripts/build-angular.mjs",
|
|
13
15
|
"test:server": "node tests/run-all.test.js",
|
|
14
16
|
"test:admin": "node tests/run-all.test.js",
|
|
15
17
|
"test": "node tests/run-all.test.js",
|
|
@@ -28,10 +30,12 @@
|
|
|
28
30
|
},
|
|
29
31
|
"./angular": {
|
|
30
32
|
"types": "./angular/index.d.ts",
|
|
31
|
-
"default": "./angular/index.
|
|
33
|
+
"default": "./angular/index.mjs"
|
|
32
34
|
},
|
|
33
35
|
"./react": {
|
|
34
36
|
"types": "./react/index.d.ts",
|
|
37
|
+
"import": "./react/index.mjs",
|
|
38
|
+
"require": "./react/index.js",
|
|
35
39
|
"default": "./react/index.js"
|
|
36
40
|
},
|
|
37
41
|
"./vue": {
|
|
@@ -66,7 +70,11 @@
|
|
|
66
70
|
"./package.json": "./package.json"
|
|
67
71
|
},
|
|
68
72
|
"files": [
|
|
69
|
-
"angular",
|
|
73
|
+
"angular/*.mjs",
|
|
74
|
+
"angular/*.d.ts",
|
|
75
|
+
"angular/package.json",
|
|
76
|
+
"angular/build-manifest.json",
|
|
77
|
+
"scripts/build-angular.mjs",
|
|
70
78
|
"admin",
|
|
71
79
|
"headless",
|
|
72
80
|
"index.d.ts",
|
|
@@ -78,12 +86,26 @@
|
|
|
78
86
|
"svelte",
|
|
79
87
|
"vue"
|
|
80
88
|
],
|
|
89
|
+
"devDependencies": {
|
|
90
|
+
"@angular/common": "20.3.31",
|
|
91
|
+
"@angular/compiler": "20.3.31",
|
|
92
|
+
"@angular/compiler-cli": "20.3.31",
|
|
93
|
+
"@angular/core": "20.3.31",
|
|
94
|
+
"@angular/forms": "20.3.31",
|
|
95
|
+
"esbuild": "0.28.1",
|
|
96
|
+
"rxjs": "~7.8.2",
|
|
97
|
+
"typescript": "~5.9.3"
|
|
98
|
+
},
|
|
81
99
|
"peerDependencies": {
|
|
100
|
+
"@angular/core": ">=20.3.0",
|
|
101
|
+
"@angular/forms": ">=20.3.0",
|
|
82
102
|
"react": ">=18",
|
|
83
103
|
"svelte": ">=3",
|
|
84
104
|
"vue": ">=3"
|
|
85
105
|
},
|
|
86
106
|
"peerDependenciesMeta": {
|
|
107
|
+
"@angular/core": { "optional": true },
|
|
108
|
+
"@angular/forms": { "optional": true },
|
|
87
109
|
"react": {
|
|
88
110
|
"optional": true
|
|
89
111
|
},
|
package/react/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
1
3
|
var React = require("react");
|
|
2
4
|
var shared = require("../integrations/shared");
|
|
3
5
|
var headless = require("../headless");
|
|
6
|
+
var initializationScope = require("../integrations/initialization-scope");
|
|
4
7
|
|
|
5
8
|
function pluginAccessor(editorRef, name) {
|
|
6
9
|
return function () {
|
|
@@ -113,6 +116,9 @@ var RichTextEditorReact = React.forwardRef(function RichTextEditorReact(props, f
|
|
|
113
116
|
var editorRef = React.useRef(null);
|
|
114
117
|
var onChangeRef = React.useRef(props.onChange);
|
|
115
118
|
var lastEmittedRef = React.useRef(undefined);
|
|
119
|
+
var initialValueRef = React.useRef(props.value !== undefined ? props.value : props.defaultValue);
|
|
120
|
+
var lastKnownHtmlRef = React.useRef(null);
|
|
121
|
+
var writingValueRef = React.useRef(false);
|
|
116
122
|
// 0 disables coalescing and restores the pre-2.6 behaviour of emitting
|
|
117
123
|
// synchronously on every change.
|
|
118
124
|
var changeDelayRef = React.useRef(props.changeDelay == null ? 120 : props.changeDelay);
|
|
@@ -127,6 +133,7 @@ var RichTextEditorReact = React.forwardRef(function RichTextEditorReact(props, f
|
|
|
127
133
|
onErrorRef.current = props.onError;
|
|
128
134
|
formatRef.current = props.valueFormat || "html";
|
|
129
135
|
configRef.current = props.config || {};
|
|
136
|
+
initialValueRef.current = props.value !== undefined ? props.value : props.defaultValue;
|
|
130
137
|
});
|
|
131
138
|
|
|
132
139
|
React.useImperativeHandle(forwardedRef, function () {
|
|
@@ -136,8 +143,41 @@ var RichTextEditorReact = React.forwardRef(function RichTextEditorReact(props, f
|
|
|
136
143
|
React.useEffect(function () {
|
|
137
144
|
var disposed = false;
|
|
138
145
|
var changeHandler = null;
|
|
146
|
+
var blurHandler = null;
|
|
139
147
|
var emitChange = null;
|
|
140
148
|
var activeHost = hostRef.current;
|
|
149
|
+
var ownedEditor = null;
|
|
150
|
+
|
|
151
|
+
function emitCurrentValue() {
|
|
152
|
+
var editor = ownedEditor;
|
|
153
|
+
if (!editor || writingValueRef.current) return;
|
|
154
|
+
var value = shared.getEditorValue(editor, formatRef.current);
|
|
155
|
+
var html = typeof value === "string" ? value : (typeof value.html === "string" ? value.html : editor.getHTMLCode());
|
|
156
|
+
if (html === lastKnownHtmlRef.current) return;
|
|
157
|
+
lastKnownHtmlRef.current = html;
|
|
158
|
+
lastEmittedRef.current = value;
|
|
159
|
+
if (onChangeRef.current) onChangeRef.current(value, editor);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function releaseEditor() {
|
|
163
|
+
if (emitChange) emitChange.cancel();
|
|
164
|
+
emitChange = null;
|
|
165
|
+
var editor = ownedEditor;
|
|
166
|
+
ownedEditor = null;
|
|
167
|
+
if (editorRef.current === editor) editorRef.current = null;
|
|
168
|
+
if (editor && changeHandler && typeof editor.detachEvent === "function") {
|
|
169
|
+
try { editor.detachEvent("change", changeHandler); } catch (e) { /* Continue cleanup. */ }
|
|
170
|
+
}
|
|
171
|
+
changeHandler = null;
|
|
172
|
+
if (editor && blurHandler && typeof editor.detachEvent === "function") {
|
|
173
|
+
try { editor.detachEvent("blur", blurHandler); } catch (e) { /* Continue cleanup. */ }
|
|
174
|
+
}
|
|
175
|
+
blurHandler = null;
|
|
176
|
+
if (editor && typeof editor.destroy === "function") {
|
|
177
|
+
try { editor.destroy(); } catch (e) { /* Continue cleanup. */ }
|
|
178
|
+
}
|
|
179
|
+
if (activeHost && !editorRef.current) activeHost.innerHTML = "";
|
|
180
|
+
}
|
|
141
181
|
|
|
142
182
|
var readyPromise = props.autoload === false
|
|
143
183
|
? Promise.resolve().then(function () {
|
|
@@ -151,59 +191,60 @@ var RichTextEditorReact = React.forwardRef(function RichTextEditorReact(props, f
|
|
|
151
191
|
return;
|
|
152
192
|
}
|
|
153
193
|
|
|
154
|
-
|
|
194
|
+
// Plugins may wrap/move their container. Never give them the
|
|
195
|
+
// React-owned root: React removes that exact child on unmount.
|
|
196
|
+
var editorMount = activeHost.ownerDocument.createElement("div");
|
|
197
|
+
activeHost.appendChild(editorMount);
|
|
198
|
+
var editor = shared.createEditor(editorMount, configRef.current);
|
|
199
|
+
if (disposed) {
|
|
200
|
+
try { editor.destroy(); } catch (e) { /* Continue cleanup. */ }
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
ownedEditor = editor;
|
|
155
204
|
editorRef.current = editor;
|
|
156
205
|
|
|
157
|
-
var initialValue =
|
|
206
|
+
var initialValue = initialValueRef.current;
|
|
158
207
|
if (initialValue !== undefined) {
|
|
159
208
|
shared.setEditorValue(editor, initialValue, formatRef.current);
|
|
160
209
|
}
|
|
210
|
+
if (disposed) return;
|
|
211
|
+
lastKnownHtmlRef.current = editor.getHTMLCode();
|
|
212
|
+
lastEmittedRef.current = undefined;
|
|
161
213
|
|
|
162
214
|
// Serialise at most once per quiet period rather than once per
|
|
163
215
|
// keystroke. lastEmittedRef lets the value-sync effect below skip a
|
|
164
216
|
// SECOND full serialisation when the parent hands back exactly what
|
|
165
217
|
// we just emitted, which is the common controlled-component case.
|
|
166
|
-
emitChange = shared.createChangeCoalescer(
|
|
167
|
-
var value = shared.getEditorValue(editor, formatRef.current);
|
|
168
|
-
lastEmittedRef.current = value;
|
|
169
|
-
if (onChangeRef.current) {
|
|
170
|
-
onChangeRef.current(value, editor);
|
|
171
|
-
}
|
|
172
|
-
}, changeDelayRef.current);
|
|
218
|
+
emitChange = shared.createChangeCoalescer(emitCurrentValue, changeDelayRef.current);
|
|
173
219
|
|
|
174
|
-
changeHandler = function () { emitChange(); };
|
|
220
|
+
changeHandler = function () { if (!disposed && !writingValueRef.current && emitChange) emitChange(); };
|
|
175
221
|
|
|
176
222
|
editor.attachEvent("change", changeHandler);
|
|
223
|
+
blurHandler = function () {
|
|
224
|
+
if (disposed || writingValueRef.current) return;
|
|
225
|
+
if (emitChange) emitChange.flush();
|
|
226
|
+
emitCurrentValue();
|
|
227
|
+
};
|
|
228
|
+
editor.attachEvent("blur", blurHandler);
|
|
177
229
|
|
|
178
230
|
if (onReadyRef.current) {
|
|
179
231
|
onReadyRef.current(editor);
|
|
180
232
|
}
|
|
181
233
|
})
|
|
182
234
|
.catch(function (error) {
|
|
183
|
-
if (!disposed
|
|
184
|
-
|
|
235
|
+
if (!disposed) {
|
|
236
|
+
releaseEditor();
|
|
237
|
+
if (onErrorRef.current) onErrorRef.current(error);
|
|
185
238
|
}
|
|
186
239
|
});
|
|
187
240
|
|
|
188
241
|
return function () {
|
|
242
|
+
if (disposed) return;
|
|
189
243
|
disposed = true;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
if (changeHandler && typeof ed.detachEvent === "function") {
|
|
195
|
-
ed.detachEvent("change", changeHandler);
|
|
196
|
-
}
|
|
197
|
-
// Tear down the editor's instance-level global listeners so an
|
|
198
|
-
// unmount (or React 18 StrictMode's mount→unmount→mount) doesn't leak.
|
|
199
|
-
if (typeof ed.destroy === "function") {
|
|
200
|
-
try { ed.destroy(); } catch (e) { /* ignore */ }
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
if (activeHost) {
|
|
204
|
-
activeHost.innerHTML = "";
|
|
205
|
-
}
|
|
206
|
-
editorRef.current = null;
|
|
244
|
+
try {
|
|
245
|
+
if (emitChange) emitChange.flush();
|
|
246
|
+
if (changeHandler) emitCurrentValue();
|
|
247
|
+
} finally { releaseEditor(); }
|
|
207
248
|
};
|
|
208
249
|
}, []);
|
|
209
250
|
|
|
@@ -221,13 +262,18 @@ var RichTextEditorReact = React.forwardRef(function RichTextEditorReact(props, f
|
|
|
221
262
|
return;
|
|
222
263
|
}
|
|
223
264
|
if (editorRef.current.getHTMLCode() !== nextHtml) {
|
|
224
|
-
|
|
265
|
+
writingValueRef.current = true;
|
|
266
|
+
try { shared.setEditorValue(editorRef.current, props.value, props.valueFormat || "html"); }
|
|
267
|
+
finally { writingValueRef.current = false; }
|
|
225
268
|
}
|
|
269
|
+
if (editorRef.current) lastKnownHtmlRef.current = editorRef.current.getHTMLCode();
|
|
270
|
+
lastEmittedRef.current = undefined;
|
|
226
271
|
}, [props.value, props.valueFormat]);
|
|
227
272
|
|
|
228
273
|
var divProps = Object.assign({}, props);
|
|
229
274
|
delete divProps.assetBasePath;
|
|
230
275
|
delete divProps.autoload;
|
|
276
|
+
delete divProps.changeDelay;
|
|
231
277
|
delete divProps.config;
|
|
232
278
|
delete divProps.defaultValue;
|
|
233
279
|
delete divProps.onChange;
|
|
@@ -249,8 +295,9 @@ RichTextEditorReact.defaultProps = {
|
|
|
249
295
|
|
|
250
296
|
// ---- Headless hook: bring-your-own-UI, Tiptap-style ----
|
|
251
297
|
// const editor = useRichTextEditor({ value: "<p>Hi</p>" });
|
|
252
|
-
// <button
|
|
253
|
-
//
|
|
298
|
+
// <button type="button" onPointerDown={e => e.preventDefault()}
|
|
299
|
+
// onClick={() => editor.run("bold")} disabled={!editor.editor}
|
|
300
|
+
// aria-pressed={!!editor.state.bold}>Bold</button>
|
|
254
301
|
// <EditorContent editor={editor} />
|
|
255
302
|
function useRichTextEditor(options) {
|
|
256
303
|
var optionsRef = React.useRef(options || {});
|
|
@@ -259,32 +306,66 @@ function useRichTextEditor(options) {
|
|
|
259
306
|
var stateRef = React.useRef({});
|
|
260
307
|
var rerender = React.useReducer(function (c) { return (c + 1) | 0; }, 0)[1];
|
|
261
308
|
|
|
309
|
+
React.useEffect(function () { optionsRef.current = options || {}; });
|
|
310
|
+
|
|
262
311
|
React.useEffect(function () {
|
|
263
312
|
var disposed = false;
|
|
264
313
|
var ctl = null;
|
|
265
|
-
|
|
314
|
+
var pendingScope = null;
|
|
315
|
+
var activeHost = hostRef.current;
|
|
316
|
+
function releaseController() {
|
|
317
|
+
var owned = ctl;
|
|
318
|
+
ctl = null;
|
|
319
|
+
if (controllerRef.current === owned) controllerRef.current = null;
|
|
320
|
+
if (owned) { try { owned.destroy(); } catch (e) { /* Continue cleanup. */ } }
|
|
321
|
+
if (activeHost && !controllerRef.current) activeHost.innerHTML = "";
|
|
322
|
+
}
|
|
323
|
+
Promise.resolve().then(function () {
|
|
324
|
+
if (disposed) return null;
|
|
325
|
+
if (!activeHost) throw new Error("useRichTextEditor: render EditorContent before initialization.");
|
|
326
|
+
pendingScope = initializationScope.createInitializationScope(optionsRef.current.signal);
|
|
327
|
+
var editorMount = activeHost.ownerDocument.createElement("div");
|
|
328
|
+
activeHost.appendChild(editorMount);
|
|
329
|
+
return headless.createHeadlessEditor(editorMount, Object.assign({}, optionsRef.current, { signal: pendingScope.signal }));
|
|
330
|
+
})
|
|
266
331
|
.then(function (controller) {
|
|
332
|
+
if (pendingScope) pendingScope.complete();
|
|
333
|
+
if (!controller) return;
|
|
267
334
|
if (disposed) { controller.destroy(); return; }
|
|
268
335
|
ctl = controller;
|
|
269
336
|
controllerRef.current = controller;
|
|
337
|
+
var value = optionsRef.current.value;
|
|
338
|
+
if (value != null && value !== controller.getHTML()) controller.setHTML(value);
|
|
270
339
|
controller.on("update", function (snapshot) {
|
|
340
|
+
if (disposed) return;
|
|
271
341
|
stateRef.current = snapshot;
|
|
272
342
|
rerender();
|
|
273
343
|
});
|
|
274
344
|
stateRef.current = controller.state();
|
|
275
345
|
if (optionsRef.current.onReady) { optionsRef.current.onReady(controller); }
|
|
276
|
-
rerender();
|
|
346
|
+
if (!disposed) rerender();
|
|
277
347
|
})
|
|
278
348
|
.catch(function (error) {
|
|
279
|
-
if (
|
|
349
|
+
if (pendingScope) pendingScope.complete();
|
|
350
|
+
if (!disposed) {
|
|
351
|
+
releaseController();
|
|
352
|
+
if (optionsRef.current.onError) optionsRef.current.onError(error);
|
|
353
|
+
}
|
|
280
354
|
});
|
|
281
355
|
return function () {
|
|
356
|
+
if (disposed) return;
|
|
282
357
|
disposed = true;
|
|
283
|
-
if (
|
|
284
|
-
|
|
358
|
+
if (pendingScope) pendingScope.dispose();
|
|
359
|
+
releaseController();
|
|
285
360
|
};
|
|
286
361
|
}, []);
|
|
287
362
|
|
|
363
|
+
React.useEffect(function () {
|
|
364
|
+
var controller = controllerRef.current;
|
|
365
|
+
var value = options && options.value;
|
|
366
|
+
if (controller && value != null && value !== controller.getHTML()) controller.setHTML(value);
|
|
367
|
+
}, [options && options.value]);
|
|
368
|
+
|
|
288
369
|
return {
|
|
289
370
|
ref: hostRef,
|
|
290
371
|
get editor() { return controllerRef.current; }, // controller (null until ready)
|
package/react/index.mjs
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// A real ESM client boundary for React Server Component bundlers. Keep the CJS
|
|
4
|
+
// implementation available to require() consumers and conventional React SSR.
|
|
5
|
+
import bindings from "./index.js";
|
|
6
|
+
|
|
7
|
+
export const RichTextEditor = bindings.RichTextEditor;
|
|
8
|
+
export const RichTextEditorReact = bindings.RichTextEditorReact;
|
|
9
|
+
export const useRichTextEditor = bindings.useRichTextEditor;
|
|
10
|
+
export const EditorContent = bindings.EditorContent;
|
|
11
|
+
export const auditAccessibility = bindings.auditAccessibility;
|
|
12
|
+
export const auditLinks = bindings.auditLinks;
|
|
13
|
+
export const createStructuredDocument = bindings.createStructuredDocument;
|
|
14
|
+
export const createHeadlessEditor = bindings.createHeadlessEditor;
|
|
15
|
+
export const createStructuredContent = bindings.createStructuredContent;
|
|
16
|
+
export const fromMarkdown = bindings.fromMarkdown;
|
|
17
|
+
export const getDocumentPageSetup = bindings.getDocumentPageSetup;
|
|
18
|
+
export const getDocumentMetrics = bindings.getDocumentMetrics;
|
|
19
|
+
export const getDocumentOutline = bindings.getDocumentOutline;
|
|
20
|
+
export const getFootnotes = bindings.getFootnotes;
|
|
21
|
+
export const getTableOfContents = bindings.getTableOfContents;
|
|
22
|
+
export const getTextStatistics = bindings.getTextStatistics;
|
|
23
|
+
export const loadRichTextEditorAssets = bindings.loadRichTextEditorAssets;
|
|
24
|
+
export const renderHTML = bindings.renderHTML;
|
|
25
|
+
export const setDocumentPageSetup = bindings.setDocumentPageSetup;
|
|
26
|
+
export const syncTableOfContents = bindings.syncTableOfContents;
|
|
27
|
+
export const toMarkdown = bindings.toMarkdown;
|
|
28
|
+
export const validateStructuredContent = bindings.validateStructuredContent;
|
|
29
|
+
export default bindings;
|