@richscripts/richtexteditor 2.14.1 → 2.16.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.
Files changed (244) hide show
  1. package/README.md +182 -10
  2. package/angular/build-manifest.json +23 -0
  3. package/angular/index.d.ts +71 -76
  4. package/angular/index.mjs +2 -0
  5. package/angular/package.json +4 -0
  6. package/headless/index.d.ts +3 -1
  7. package/headless/index.js +72 -16
  8. package/index.d.ts +40 -52
  9. package/integrations/initialization-scope.js +27 -0
  10. package/integrations/native-mount.js +30 -0
  11. package/integrations/shared.d.ts +23 -1
  12. package/integrations/shared.js +68 -22
  13. package/package.json +25 -3
  14. package/react/index.js +118 -37
  15. package/react/index.mjs +29 -0
  16. package/richtexteditor/all_plugins.js +8816 -2373
  17. package/richtexteditor/all_plugins.min.js +77 -59
  18. package/richtexteditor/lang/emoji/LICENSE-CLDR.txt +41 -0
  19. package/richtexteditor/lang/emoji/rte-emoji-de.js +3 -0
  20. package/richtexteditor/lang/emoji/rte-emoji-es.js +3 -0
  21. package/richtexteditor/lang/emoji/rte-emoji-fr.js +3 -0
  22. package/richtexteditor/lang/emoji/rte-emoji-it.js +3 -0
  23. package/richtexteditor/lang/emoji/rte-emoji-ja.js +3 -0
  24. package/richtexteditor/lang/emoji/rte-emoji-ko.js +3 -0
  25. package/richtexteditor/lang/emoji/rte-emoji-nl.js +3 -0
  26. package/richtexteditor/lang/emoji/rte-emoji-pt-pt.js +3 -0
  27. package/richtexteditor/lang/emoji/rte-emoji-pt.js +3 -0
  28. package/richtexteditor/lang/emoji/rte-emoji-ru.js +3 -0
  29. package/richtexteditor/lang/emoji/rte-emoji-zh-Hans.js +3 -0
  30. package/richtexteditor/lang/emoji/rte-emoji-zh-Hant.js +3 -0
  31. package/richtexteditor/lang/rte-lang-af.js +1 -0
  32. package/richtexteditor/lang/rte-lang-ar.js +1 -0
  33. package/richtexteditor/lang/rte-lang-bg.js +1 -0
  34. package/richtexteditor/lang/rte-lang-bn.js +1 -0
  35. package/richtexteditor/lang/rte-lang-bs.js +1 -0
  36. package/richtexteditor/lang/rte-lang-ca.js +1 -0
  37. package/richtexteditor/lang/rte-lang-cs.js +1 -0
  38. package/richtexteditor/lang/rte-lang-cy.js +1 -0
  39. package/richtexteditor/lang/rte-lang-da.js +1 -0
  40. package/richtexteditor/lang/rte-lang-de.js +1050 -2
  41. package/richtexteditor/lang/rte-lang-el.js +1 -0
  42. package/richtexteditor/lang/rte-lang-en.js +1 -0
  43. package/richtexteditor/lang/rte-lang-es.js +1056 -2
  44. package/richtexteditor/lang/rte-lang-et.js +1 -0
  45. package/richtexteditor/lang/rte-lang-fa.js +1 -0
  46. package/richtexteditor/lang/rte-lang-fi.js +1 -0
  47. package/richtexteditor/lang/rte-lang-fil.js +1 -0
  48. package/richtexteditor/lang/rte-lang-fj.js +1 -0
  49. package/richtexteditor/lang/rte-lang-fr.js +1056 -2
  50. package/richtexteditor/lang/rte-lang-ga.js +1 -0
  51. package/richtexteditor/lang/rte-lang-gu.js +1 -0
  52. package/richtexteditor/lang/rte-lang-he.js +1 -0
  53. package/richtexteditor/lang/rte-lang-hi.js +1 -0
  54. package/richtexteditor/lang/rte-lang-hr.js +1 -0
  55. package/richtexteditor/lang/rte-lang-ht.js +1 -0
  56. package/richtexteditor/lang/rte-lang-hu.js +1 -0
  57. package/richtexteditor/lang/rte-lang-id.js +1 -0
  58. package/richtexteditor/lang/rte-lang-is.js +1 -0
  59. package/richtexteditor/lang/rte-lang-it.js +1056 -2
  60. package/richtexteditor/lang/rte-lang-ja.js +1056 -2
  61. package/richtexteditor/lang/rte-lang-kn.js +1 -0
  62. package/richtexteditor/lang/rte-lang-ko.js +1056 -2
  63. package/richtexteditor/lang/rte-lang-lt.js +1 -0
  64. package/richtexteditor/lang/rte-lang-lv.js +1 -0
  65. package/richtexteditor/lang/rte-lang-mg.js +1 -0
  66. package/richtexteditor/lang/rte-lang-mi.js +1 -0
  67. package/richtexteditor/lang/rte-lang-ml.js +1 -0
  68. package/richtexteditor/lang/rte-lang-mr.js +1 -0
  69. package/richtexteditor/lang/rte-lang-ms.js +1 -0
  70. package/richtexteditor/lang/rte-lang-mt.js +1 -0
  71. package/richtexteditor/lang/rte-lang-mww.js +1 -0
  72. package/richtexteditor/lang/rte-lang-nb.js +1 -0
  73. package/richtexteditor/lang/rte-lang-nl.js +1056 -2
  74. package/richtexteditor/lang/rte-lang-otq.js +1 -0
  75. package/richtexteditor/lang/rte-lang-pa.js +1 -0
  76. package/richtexteditor/lang/rte-lang-pl.js +1 -0
  77. package/richtexteditor/lang/rte-lang-pt-pt.js +1056 -2
  78. package/richtexteditor/lang/rte-lang-pt.js +1056 -2
  79. package/richtexteditor/lang/rte-lang-ro.js +1 -0
  80. package/richtexteditor/lang/rte-lang-ru.js +1056 -2
  81. package/richtexteditor/lang/rte-lang-sk.js +1 -0
  82. package/richtexteditor/lang/rte-lang-sl.js +1 -0
  83. package/richtexteditor/lang/rte-lang-sm.js +1 -0
  84. package/richtexteditor/lang/rte-lang-sr-Cyrl.js +1 -0
  85. package/richtexteditor/lang/rte-lang-sr-Latn.js +1 -0
  86. package/richtexteditor/lang/rte-lang-sv.js +1 -0
  87. package/richtexteditor/lang/rte-lang-sw.js +1 -0
  88. package/richtexteditor/lang/rte-lang-ta.js +1 -0
  89. package/richtexteditor/lang/rte-lang-te.js +1 -0
  90. package/richtexteditor/lang/rte-lang-th.js +1 -0
  91. package/richtexteditor/lang/rte-lang-tlh-Latn.js +1 -0
  92. package/richtexteditor/lang/rte-lang-tlh-Piqd.js +1 -0
  93. package/richtexteditor/lang/rte-lang-to.js +1 -0
  94. package/richtexteditor/lang/rte-lang-tr.js +1 -0
  95. package/richtexteditor/lang/rte-lang-ty.js +1 -0
  96. package/richtexteditor/lang/rte-lang-uk.js +1 -0
  97. package/richtexteditor/lang/rte-lang-ur.js +1 -0
  98. package/richtexteditor/lang/rte-lang-vi.js +1 -0
  99. package/richtexteditor/lang/rte-lang-yua.js +1 -0
  100. package/richtexteditor/lang/rte-lang-zh-Hans.js +1050 -2
  101. package/richtexteditor/lang/rte-lang-zh-Hant.js +1050 -2
  102. package/richtexteditor/plugins/a11yenhance.js +4 -1
  103. package/richtexteditor/plugins/a11yenhance.min.js +1 -1
  104. package/richtexteditor/plugins/accessibilitychecker.js +256 -64
  105. package/richtexteditor/plugins/accessibilitychecker.min.js +1 -1
  106. package/richtexteditor/plugins/aitoolkit.js +1057 -386
  107. package/richtexteditor/plugins/aitoolkit.min.js +7 -7
  108. package/richtexteditor/plugins/all_plugins.js +8816 -2373
  109. package/richtexteditor/plugins/all_plugins.min.js +77 -59
  110. package/richtexteditor/plugins/autocorrect.js +66 -31
  111. package/richtexteditor/plugins/autocorrect.min.js +1 -1
  112. package/richtexteditor/plugins/autoembed.js +18 -1
  113. package/richtexteditor/plugins/autoembed.min.js +1 -1
  114. package/richtexteditor/plugins/blocktypes.js +18 -9
  115. package/richtexteditor/plugins/blocktypes.min.js +1 -1
  116. package/richtexteditor/plugins/bookmarkcard.js +12 -5
  117. package/richtexteditor/plugins/bookmarkcard.min.js +2 -2
  118. package/richtexteditor/plugins/changecase.js +72 -19
  119. package/richtexteditor/plugins/changecase.min.js +1 -1
  120. package/richtexteditor/plugins/charlimit.js +62 -2
  121. package/richtexteditor/plugins/charlimit.min.js +2 -2
  122. package/richtexteditor/plugins/comments.js +460 -61
  123. package/richtexteditor/plugins/comments.min.js +4 -3
  124. package/richtexteditor/plugins/contentminimap.js +28 -9
  125. package/richtexteditor/plugins/contentminimap.min.js +1 -1
  126. package/richtexteditor/plugins/crdt-engine.js +27 -1
  127. package/richtexteditor/plugins/crossreference.js +1 -1
  128. package/richtexteditor/plugins/crossreference.min.js +1 -1
  129. package/richtexteditor/plugins/dialoga11y.js +26 -4
  130. package/richtexteditor/plugins/dialoga11y.min.js +1 -1
  131. package/richtexteditor/plugins/dictation.js +1 -1
  132. package/richtexteditor/plugins/documentimport.js +250 -59
  133. package/richtexteditor/plugins/documentimport.min.js +4 -4
  134. package/richtexteditor/plugins/documentoutline.js +47 -8
  135. package/richtexteditor/plugins/documentoutline.min.js +1 -1
  136. package/richtexteditor/plugins/docxexport.js +233 -32
  137. package/richtexteditor/plugins/docxexport.min.js +2 -2
  138. package/richtexteditor/plugins/draghandle.js +267 -3
  139. package/richtexteditor/plugins/draghandle.min.js +1 -1
  140. package/richtexteditor/plugins/emailtoolkit.js +28 -14
  141. package/richtexteditor/plugins/emailtoolkit.min.js +1 -1
  142. package/richtexteditor/plugins/emojiautocomplete.js +111 -57
  143. package/richtexteditor/plugins/emojiautocomplete.min.js +1 -1
  144. package/richtexteditor/plugins/footnotes.js +65 -11
  145. package/richtexteditor/plugins/footnotes.min.js +1 -1
  146. package/richtexteditor/plugins/formatpainter.js +10 -0
  147. package/richtexteditor/plugins/formatpainter.min.js +1 -1
  148. package/richtexteditor/plugins/formattingmarks.js +6 -6
  149. package/richtexteditor/plugins/formattingmarks.min.js +1 -1
  150. package/richtexteditor/plugins/gapcursor.js +60 -0
  151. package/richtexteditor/plugins/gapcursor.min.js +1 -1
  152. package/richtexteditor/plugins/ghostcomplete.js +1 -1
  153. package/richtexteditor/plugins/html2pdf.js +8 -8
  154. package/richtexteditor/plugins/html2pdf.min.js +1 -1
  155. package/richtexteditor/plugins/imageeditor.js +31 -12
  156. package/richtexteditor/plugins/imageeditor.min.js +1 -1
  157. package/richtexteditor/plugins/importstyles.js +1 -1
  158. package/richtexteditor/plugins/inlinecode.js +25 -0
  159. package/richtexteditor/plugins/inlinecode.min.js +1 -1
  160. package/richtexteditor/plugins/insertcode.js +29 -11
  161. package/richtexteditor/plugins/insertcode.min.js +6 -6
  162. package/richtexteditor/plugins/insertemoji.js +113 -16
  163. package/richtexteditor/plugins/insertemoji.min.js +1 -1
  164. package/richtexteditor/plugins/insertgallery.js +46 -40
  165. package/richtexteditor/plugins/insertgallery.min.js +1 -1
  166. package/richtexteditor/plugins/inserttemplate.js +43 -19
  167. package/richtexteditor/plugins/inserttemplate.min.js +1 -1
  168. package/richtexteditor/plugins/keyboarda11y.js +66 -3
  169. package/richtexteditor/plugins/keyboarda11y.min.js +1 -1
  170. package/richtexteditor/plugins/layouttable.js +20 -0
  171. package/richtexteditor/plugins/layouttable.min.js +1 -1
  172. package/richtexteditor/plugins/linkchecker.js +29 -9
  173. package/richtexteditor/plugins/linkchecker.min.js +1 -1
  174. package/richtexteditor/plugins/localdraft.js +51 -7
  175. package/richtexteditor/plugins/localdraft.min.js +1 -1
  176. package/richtexteditor/plugins/markdownexport.js +159 -0
  177. package/richtexteditor/plugins/markdownexport.min.js +2 -2
  178. package/richtexteditor/plugins/mathdialog.js +11 -5
  179. package/richtexteditor/plugins/mathdialog.min.js +1 -1
  180. package/richtexteditor/plugins/mentionplugin.js +90 -27
  181. package/richtexteditor/plugins/mentionplugin.min.js +1 -1
  182. package/richtexteditor/plugins/mermaiddiagram.js +14 -8
  183. package/richtexteditor/plugins/mermaiddiagram.min.js +2 -2
  184. package/richtexteditor/plugins/multilevellist.js +4 -0
  185. package/richtexteditor/plugins/multilevellist.min.js +1 -1
  186. package/richtexteditor/plugins/nodetypes.js +1 -1
  187. package/richtexteditor/plugins/nodetypes.min.js +1 -1
  188. package/richtexteditor/plugins/pagination.js +2 -2
  189. package/richtexteditor/plugins/pagination.min.js +1 -1
  190. package/richtexteditor/plugins/pdfexport.js +1752 -1167
  191. package/richtexteditor/plugins/pdfexport.min.js +28 -13
  192. package/richtexteditor/plugins/permanentpen.js +3 -3
  193. package/richtexteditor/plugins/permanentpen.min.js +1 -1
  194. package/richtexteditor/plugins/readabilitystats.js +25 -11
  195. package/richtexteditor/plugins/readabilitystats.min.js +1 -1
  196. package/richtexteditor/plugins/readaloud.js +30 -16
  197. package/richtexteditor/plugins/readaloud.min.js +1 -1
  198. package/richtexteditor/plugins/restrictedediting.js +166 -0
  199. package/richtexteditor/plugins/restrictedediting.min.js +2 -2
  200. package/richtexteditor/plugins/revisionhistory.js +173 -41
  201. package/richtexteditor/plugins/revisionhistory.min.js +3 -3
  202. package/richtexteditor/plugins/rubyannotation.js +21 -11
  203. package/richtexteditor/plugins/rubyannotation.min.js +1 -1
  204. package/richtexteditor/plugins/sanitizer.js +119 -7
  205. package/richtexteditor/plugins/sanitizer.min.js +1 -1
  206. package/richtexteditor/plugins/slashcommand.js +32 -18
  207. package/richtexteditor/plugins/slashcommand.min.js +2 -2
  208. package/richtexteditor/plugins/smartchips.js +39 -25
  209. package/richtexteditor/plugins/smartchips.min.js +2 -2
  210. package/richtexteditor/plugins/spellcheck.js +20 -11
  211. package/richtexteditor/plugins/spellcheck.min.js +2 -2
  212. package/richtexteditor/plugins/stateinspector.js +21 -11
  213. package/richtexteditor/plugins/stateinspector.min.js +2 -2
  214. package/richtexteditor/plugins/structured-content-bridge.js +90 -32
  215. package/richtexteditor/plugins/structured-content-bridge.min.js +8 -8
  216. package/richtexteditor/plugins/tableofcontents.js +5 -2
  217. package/richtexteditor/plugins/tableofcontents.min.js +1 -1
  218. package/richtexteditor/plugins/tabletools.js +388 -3
  219. package/richtexteditor/plugins/tabletools.min.js +1 -1
  220. package/richtexteditor/plugins/textdirection.js +19 -6
  221. package/richtexteditor/plugins/textdirection.min.js +1 -1
  222. package/richtexteditor/plugins/textpartlanguage.js +161 -32
  223. package/richtexteditor/plugins/textpartlanguage.min.js +1 -1
  224. package/richtexteditor/plugins/todolist.js +90 -6
  225. package/richtexteditor/plugins/todolist.min.js +1 -1
  226. package/richtexteditor/plugins/trackedchanges.js +1812 -25
  227. package/richtexteditor/plugins/trackedchanges.min.js +5 -3
  228. package/richtexteditor/plugins/wordexport.js +2 -2
  229. package/richtexteditor/plugins/yjscollab.js +11 -6
  230. package/richtexteditor/plugins/yjscollab.min.js +1 -1
  231. package/richtexteditor/plugins/zz_richtextbox_dialog_style.js +22 -13
  232. package/richtexteditor/plugins/zz_richtextbox_dialog_style.min.js +1 -1
  233. package/richtexteditor/rte-config.js +144 -86
  234. package/richtexteditor/rte-headless.js +19 -4
  235. package/richtexteditor/rte-watchdog.js +3 -1
  236. package/richtexteditor/rte-webcomponent.js +91 -16
  237. package/richtexteditor/rte.js +146 -88
  238. package/richtexteditor/runtime/colorpicker_more_ns.htm +3 -1
  239. package/scripts/build-angular.mjs +97 -0
  240. package/svelte/index.d.ts +2 -1
  241. package/svelte/index.js +80 -9
  242. package/vue/index.js +130 -34
  243. package/angular/component.ts +0 -297
  244. package/angular/index.ts +0 -24
package/index.d.ts CHANGED
@@ -1057,6 +1057,19 @@ export interface RichTextEditorInstance {
1057
1057
  * editor-specific commands (`source`, `fullscreen`, `ai-ask`, …).
1058
1058
  */
1059
1059
  execCommand(command: RichTextEditorCommand, value?: unknown): unknown;
1060
+ /** Record an undo checkpoint around a custom DOM edit. */
1061
+ recordUndo(): void;
1062
+ /** Set the selected ordered list's start (including zero). False outside a list. */
1063
+ setListStart(start: number): boolean;
1064
+ /** Continue from the nearest preceding sibling ordered list. False if unavailable. */
1065
+ continueListNumbering(): boolean;
1066
+ /** Toggle the selected table's caption. False outside a table. */
1067
+ toggleTableCaption(): boolean;
1068
+ /** Cancel pending uploads; late callbacks cannot change the document. */
1069
+ cancelUploads(reason?: string): number;
1070
+ getPendingUploadCount(): number;
1071
+ /** Upload embedded data-image URLs through the configured handler. */
1072
+ uploadEmbeddedImages(done?: (summary: { uploaded: number; failed: number; skipped: number; errors: string[] }) => void): void;
1060
1073
  /** Returns true when the command is enabled in the current selection context. */
1061
1074
  isCommandEnabled(command: RichTextEditorCommand): boolean;
1062
1075
  /** Returns true when the command's effect is currently active (e.g. selection is bold). */
@@ -1330,9 +1343,6 @@ export interface RichTextEditorInstance {
1330
1343
 
1331
1344
  toMarkdown?(): string;
1332
1345
  fromMarkdown?(markdown: string): unknown;
1333
- getMarkdown?(): string;
1334
- copyAsMarkdown?(): unknown;
1335
- downloadMarkdown?(filename?: string): unknown;
1336
1346
 
1337
1347
  // ---- Export ----
1338
1348
 
@@ -1342,10 +1352,6 @@ export interface RichTextEditorInstance {
1342
1352
  exportPdf?(options?: Record<string, unknown>): unknown;
1343
1353
  getDocxBlob?(options?: Record<string, unknown>): Blob | Promise<Blob>;
1344
1354
  exportToDocx?(filename?: string, options?: Record<string, unknown>): unknown;
1345
- exportToWord?(options?: RichTextEditorWordExportOptions): unknown;
1346
- downloadWord?(filename?: string, options?: RichTextEditorWordExportOptions): unknown;
1347
- getWordDocument?(options?: RichTextEditorWordExportOptions): string;
1348
- getEmailHTML?(options?: Record<string, unknown>): string;
1349
1355
 
1350
1356
  // ---- Formatting marks and inline code ----
1351
1357
 
@@ -1384,8 +1390,6 @@ export interface RichTextEditorInstance {
1384
1390
  announce?(text: string, options?: { assertive?: boolean }): unknown;
1385
1391
  /** Moves focus to the first toolbar button (the documented Escape hatch target). */
1386
1392
  focusToolbar?(): unknown;
1387
- applyAccessibilityMetadata?(): unknown;
1388
- applyDialogAccessibility?(dialog?: HTMLElement): unknown;
1389
1393
  ensureStyleSheetLive?(doc: Document, style: HTMLStyleElement, id: string, cssText: string): unknown;
1390
1394
 
1391
1395
  // ---- Toolbar / dialog building blocks ----
@@ -1402,49 +1406,6 @@ export interface RichTextEditorInstance {
1402
1406
 
1403
1407
  insertTableOfContents?(): unknown;
1404
1408
  toggleWatermark?(): unknown;
1405
- readAloud?(): unknown;
1406
- stopReadAloud?(): unknown;
1407
- showShortcuts?(): unknown;
1408
- openFindDialog?(): unknown;
1409
- openImportDialog?(): unknown;
1410
- importFile?(file: File, options?: RichTextEditorImportOptions): unknown;
1411
- htmlFromImportText?(text: string, filename?: string): string;
1412
- embedUrl?(url: string): unknown;
1413
- renderMath?(): unknown;
1414
- applyMathMarkup?(): unknown;
1415
- renderDiagrams?(): unknown;
1416
- getReadabilityStats?(): Record<string, unknown>;
1417
- countSyllables?(word: string): number;
1418
- getFootnotes?(): unknown[];
1419
- getCharCount?(): number;
1420
- getWordCount?(): number;
1421
- getRemainingChars?(): number;
1422
- isOverLimit?(): boolean;
1423
- getCommentsOnly?(): boolean;
1424
- setCommentsOnly?(on: boolean): unknown;
1425
- setFocusMode?(on: boolean): unknown;
1426
- toggleFocusMode?(): unknown;
1427
- isFocusMode?(): boolean;
1428
- setTypewriterMode?(on: boolean): unknown;
1429
- toggleTypewriterMode?(): unknown;
1430
- isTypewriterMode?(): boolean;
1431
- saveLocalDraft?(): unknown;
1432
- restoreLocalDraft?(): unknown;
1433
- hasLocalDraft?(): boolean;
1434
- getLocalDraft?(): unknown;
1435
- clearLocalDraft?(): unknown;
1436
- requestGhostText?(): unknown;
1437
- acceptGhostText?(): unknown;
1438
- dismissGhostText?(): unknown;
1439
- hasGhostText?(): boolean;
1440
- setGhostTextResolver?(resolver: (context: unknown) => unknown): unknown;
1441
- foldAtCaret?(): unknown;
1442
- toggleHeadingFold?(el?: HTMLElement): unknown;
1443
- unfoldAll?(): unknown;
1444
- findHighlight?(text: string): unknown;
1445
- getSelectedControl?(): HTMLElement | null;
1446
- getSelectedText?(): string;
1447
- getDocument?(): Document;
1448
1409
 
1449
1410
  // ---- Tables ----
1450
1411
 
@@ -1688,7 +1649,25 @@ export interface RichTextEditorInstance {
1688
1649
  // Constructor
1689
1650
  // =====================
1690
1651
 
1652
+ export type RichTextEditorUploadCallback = (url: string | null, error?: string) => void;
1653
+ export type RichTextEditorUploadHandle = void | (() => void) | { abort(): void };
1654
+ export type RichTextEditorUploadHandler = (
1655
+ file: File,
1656
+ callback: RichTextEditorUploadCallback,
1657
+ index?: number,
1658
+ files?: File[]
1659
+ ) => RichTextEditorUploadHandle;
1660
+
1691
1661
  export interface RichTextEditorConfig {
1662
+ /** Custom uploader; return an abort handle if requests can be cancelled. */
1663
+ file_upload_handler?: RichTextEditorUploadHandler;
1664
+ /** Scan embedded images and upload through the handler; default false. */
1665
+ automaticUploads?: boolean;
1666
+ automaticUploadsDelay?: number;
1667
+ /** Extra upload attempts after the first; default zero. */
1668
+ uploadRetryCount?: number;
1669
+ /** Initial retry delay in milliseconds; doubles on subsequent retries. */
1670
+ uploadRetryDelay?: number;
1692
1671
  toolbar?: string | string[];
1693
1672
  height?: string | number;
1694
1673
  width?: string | number;
@@ -2067,6 +2046,15 @@ declare global {
2067
2046
  interface Window {
2068
2047
  RichTextEditor: RichTextEditorConstructor;
2069
2048
  RTE_DefaultConfig?: RichTextEditorConfig;
2049
+ /**
2050
+ * The editor's Trusted Types policy, "richtexteditor", for plugins that write HTML or a script URL to a sink.
2051
+ * Under CSP `require-trusted-types-for 'script'` the results are TrustedHTML / TrustedScriptURL; without Trusted
2052
+ * Types they are the input unchanged. Typed as string so they assign to innerHTML and src.
2053
+ */
2054
+ RTE_TrustedTypes?: {
2055
+ html(value: string): string;
2056
+ scriptURL(value: string): string;
2057
+ };
2070
2058
  }
2071
2059
  }
2072
2060
 
@@ -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 };
@@ -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
- ): RichTextEditorInstance;
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
  ): {
@@ -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) || 1;
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, "&quot;");
2533
+ return escapeHtml(value === undefined || value === null ? "" : String(value)).replace(/"/g, "&quot;");
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 < 1) {
3187
- issues.push(createValidationIssue(path + ".attrs.start", "Ordered lists require a positive numeric start value."));
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) {
@@ -3796,6 +3797,16 @@ function repairAccessibilityIssue(value, issue, options) {
3796
3797
  return workingDocument;
3797
3798
  }
3798
3799
 
3800
+ // A queued repair is not permission to overwrite newer author edits. The
3801
+ // same problem must still exist at this node in the current document.
3802
+ var stillPresent = auditAccessibility(workingDocument).issues.some(function (currentIssue) {
3803
+ return currentIssue.code === normalizedIssue.code &&
3804
+ resolveAccessibilityIssueNodePath(currentIssue) === nodePath;
3805
+ });
3806
+ if (!stillPresent) {
3807
+ return workingDocument;
3808
+ }
3809
+
3799
3810
  if (normalizedIssue.code === "image-missing-alt") {
3800
3811
  var altText = normalizePlainText(normalizedOptions.altText);
3801
3812
  if (!altText) {
@@ -3919,12 +3930,12 @@ function getMarkdownListMatch(line) {
3919
3930
  };
3920
3931
  }
3921
3932
 
3922
- var orderedMatch = /^(\s*)(\d+)\.\s+(.*)$/.exec(line);
3933
+ var orderedMatch = /^(\s*)(\d{1,9})\.\s+(.*)$/.exec(line);
3923
3934
  if (orderedMatch) {
3924
3935
  return {
3925
3936
  indent: orderedMatch[1].length,
3926
3937
  ordered: true,
3927
- start: parseInt(orderedMatch[2], 10) || 1,
3938
+ start: parseInt(orderedMatch[2], 10),
3928
3939
  text: orderedMatch[3],
3929
3940
  marker: orderedMatch[2] + ".",
3930
3941
  contentIndent: orderedMatch[1].length + orderedMatch[2].length + 2,
@@ -4914,8 +4925,13 @@ function serializeMarkdownBlocks(nodes) {
4914
4925
 
4915
4926
  if (node.type === "bulletList" || node.type === "orderedList") {
4916
4927
  var listParts = [];
4917
- var start = node.type === "orderedList" && node.attrs && node.attrs.start ? parseInt(node.attrs.start, 10) || 1 : 1;
4928
+ var start = node.type === "orderedList" && node.attrs && node.attrs.start !== undefined ? parseInt(node.attrs.start, 10) : 1;
4929
+ if (!isFinite(start)) start = 1;
4918
4930
  var listItems = node.content || [];
4931
+ if (node.type === "orderedList" && (start < 0 || start + Math.max(0, listItems.length - 1) > 999999999)) {
4932
+ parts.push(serializeNode(node, false));
4933
+ continue;
4934
+ }
4919
4935
  for (var itemIndex = 0; itemIndex < listItems.length; itemIndex++) {
4920
4936
  var prefix = node.type === "orderedList" ? (start + itemIndex) + ". " : "- ";
4921
4937
  listParts.push(serializeMarkdownListItem(listItems[itemIndex].content || [], prefix));
@@ -5060,15 +5076,28 @@ function installStructuredContentBridge() {
5060
5076
  }
5061
5077
 
5062
5078
  function ensureStylesheet(href) {
5063
- if (document.querySelector('link[data-rte-style="' + href + '"]')) {
5064
- return;
5065
- }
5066
-
5067
- var link = document.createElement("link");
5068
- link.rel = "stylesheet";
5069
- link.href = href;
5070
- link.setAttribute("data-rte-style", href);
5071
- document.head.appendChild(link);
5079
+ return new Promise(function (resolve, reject) {
5080
+ var existing = document.querySelector('link[data-rte-style="' + href + '"]');
5081
+ if (existing && (existing.getAttribute("data-rte-loaded") === "true" || existing.sheet)) {
5082
+ resolve();
5083
+ return;
5084
+ }
5085
+ var link = existing || document.createElement("link");
5086
+ link.addEventListener("load", function () {
5087
+ link.setAttribute("data-rte-loaded", "true");
5088
+ resolve();
5089
+ }, { once: true });
5090
+ link.addEventListener("error", function () {
5091
+ if (link.parentNode) link.parentNode.removeChild(link);
5092
+ reject(new Error("Failed to load " + href));
5093
+ }, { once: true });
5094
+ if (!existing) {
5095
+ link.rel = "stylesheet";
5096
+ link.href = href;
5097
+ link.setAttribute("data-rte-style", href);
5098
+ document.head.appendChild(link);
5099
+ }
5100
+ });
5072
5101
  }
5073
5102
 
5074
5103
  function loadScript(src) {
@@ -5098,6 +5127,9 @@ function loadScript(src) {
5098
5127
  resolve(script);
5099
5128
  };
5100
5129
  script.onerror = function () {
5130
+ // A failed tag will never fire load again. Let an explicit retry
5131
+ // create a fresh request, without removing successfully loaded core.
5132
+ if (script.parentNode) script.parentNode.removeChild(script);
5101
5133
  reject(new Error("Failed to load " + src));
5102
5134
  };
5103
5135
 
@@ -5114,18 +5146,32 @@ function loadRichTextEditorAssets(options) {
5114
5146
 
5115
5147
  var basePath = trimTrailingSlash(options && options.basePath ? options.basePath : "/richtexteditor");
5116
5148
 
5117
- if (window.RichTextEditor) {
5149
+ // Core becomes global before plugins finish. All concurrent mounts must
5150
+ // await the same complete attempt rather than treating core as readiness.
5151
+ if (pendingLoadsByBasePath[basePath]) {
5152
+ return pendingLoadsByBasePath[basePath];
5153
+ }
5154
+
5155
+ if (window.RichTextEditor && !failedLoadsByBasePath[basePath]) {
5118
5156
  return Promise.resolve(installStructuredContentBridge());
5119
5157
  }
5120
5158
 
5121
5159
  if (!pendingLoadsByBasePath[basePath]) {
5122
- ensureStylesheet(basePath + "/rte_theme_default.css");
5123
- pendingLoadsByBasePath[basePath] = loadScript(basePath + "/rte.js")
5160
+ var themeReady = ensureStylesheet(basePath + "/rte_theme_default.css");
5161
+ var scriptsReady = loadScript(basePath + "/rte.js")
5124
5162
  .then(function () {
5163
+ if (window.RTE_DefaultConfig) window.RTE_DefaultConfig.url_base = basePath;
5125
5164
  return loadScript(basePath + "/plugins/all_plugins.js");
5126
- })
5165
+ });
5166
+ pendingLoadsByBasePath[basePath] = Promise.all([themeReady, scriptsReady])
5127
5167
  .then(function () {
5168
+ delete failedLoadsByBasePath[basePath];
5128
5169
  return installStructuredContentBridge();
5170
+ })
5171
+ .catch(function (error) {
5172
+ delete pendingLoadsByBasePath[basePath];
5173
+ failedLoadsByBasePath[basePath] = true;
5174
+ throw error;
5129
5175
  });
5130
5176
  }
5131
5177
 
package/package.json CHANGED
@@ -3,13 +3,15 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "2.14.1",
6
+ "version": "2.16.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.ts"
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
  },