@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.
Files changed (238) hide show
  1. package/README.md +173 -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 +33 -54
  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 +58 -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 +7113 -1111
  17. package/richtexteditor/all_plugins.min.js +62 -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 +1017 -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 +1023 -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 +1023 -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 +1023 -2
  60. package/richtexteditor/lang/rte-lang-ja.js +1023 -2
  61. package/richtexteditor/lang/rte-lang-kn.js +1 -0
  62. package/richtexteditor/lang/rte-lang-ko.js +1023 -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 +1023 -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 +1023 -2
  78. package/richtexteditor/lang/rte-lang-pt.js +1023 -2
  79. package/richtexteditor/lang/rte-lang-ro.js +1 -0
  80. package/richtexteditor/lang/rte-lang-ru.js +1023 -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 +1017 -2
  101. package/richtexteditor/lang/rte-lang-zh-Hant.js +1017 -2
  102. package/richtexteditor/plugins/a11yenhance.js +2 -1
  103. package/richtexteditor/plugins/a11yenhance.min.js +1 -1
  104. package/richtexteditor/plugins/accessibilitychecker.js +252 -60
  105. package/richtexteditor/plugins/accessibilitychecker.min.js +1 -1
  106. package/richtexteditor/plugins/aitoolkit.js +966 -303
  107. package/richtexteditor/plugins/aitoolkit.min.js +7 -7
  108. package/richtexteditor/plugins/all_plugins.js +7113 -1111
  109. package/richtexteditor/plugins/all_plugins.min.js +62 -59
  110. package/richtexteditor/plugins/autocorrect.js +66 -31
  111. package/richtexteditor/plugins/autocorrect.min.js +1 -1
  112. package/richtexteditor/plugins/autoembed.js +17 -0
  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 +458 -59
  123. package/richtexteditor/plugins/comments.min.js +4 -3
  124. package/richtexteditor/plugins/contentminimap.js +25 -6
  125. package/richtexteditor/plugins/contentminimap.min.js +1 -1
  126. package/richtexteditor/plugins/crossreference.js +1 -1
  127. package/richtexteditor/plugins/crossreference.min.js +1 -1
  128. package/richtexteditor/plugins/dialoga11y.js +26 -4
  129. package/richtexteditor/plugins/dialoga11y.min.js +1 -1
  130. package/richtexteditor/plugins/dictation.js +1 -1
  131. package/richtexteditor/plugins/documentimport.js +220 -51
  132. package/richtexteditor/plugins/documentimport.min.js +4 -4
  133. package/richtexteditor/plugins/documentoutline.js +88 -38
  134. package/richtexteditor/plugins/documentoutline.min.js +1 -1
  135. package/richtexteditor/plugins/docxexport.js +204 -32
  136. package/richtexteditor/plugins/docxexport.min.js +2 -2
  137. package/richtexteditor/plugins/draghandle.js +267 -3
  138. package/richtexteditor/plugins/draghandle.min.js +1 -1
  139. package/richtexteditor/plugins/emailtoolkit.js +28 -14
  140. package/richtexteditor/plugins/emailtoolkit.min.js +1 -1
  141. package/richtexteditor/plugins/emojiautocomplete.js +110 -56
  142. package/richtexteditor/plugins/emojiautocomplete.min.js +1 -1
  143. package/richtexteditor/plugins/footnotes.js +65 -11
  144. package/richtexteditor/plugins/footnotes.min.js +1 -1
  145. package/richtexteditor/plugins/formatpainter.js +10 -0
  146. package/richtexteditor/plugins/formatpainter.min.js +1 -1
  147. package/richtexteditor/plugins/formattingmarks.js +53 -8
  148. package/richtexteditor/plugins/formattingmarks.min.js +1 -1
  149. package/richtexteditor/plugins/gapcursor.js +60 -0
  150. package/richtexteditor/plugins/gapcursor.min.js +1 -1
  151. package/richtexteditor/plugins/ghostcomplete.js +1 -1
  152. package/richtexteditor/plugins/html2pdf.js +1 -1
  153. package/richtexteditor/plugins/html2pdf.min.js +1 -1
  154. package/richtexteditor/plugins/imageeditor.js +12 -6
  155. package/richtexteditor/plugins/imageeditor.min.js +1 -1
  156. package/richtexteditor/plugins/importstyles.js +1 -1
  157. package/richtexteditor/plugins/inlinecode.js +25 -0
  158. package/richtexteditor/plugins/inlinecode.min.js +1 -1
  159. package/richtexteditor/plugins/insertcode.js +21 -3
  160. package/richtexteditor/plugins/insertcode.min.js +4 -4
  161. package/richtexteditor/plugins/insertemoji.js +112 -15
  162. package/richtexteditor/plugins/insertemoji.min.js +1 -1
  163. package/richtexteditor/plugins/insertgallery.js +42 -36
  164. package/richtexteditor/plugins/insertgallery.min.js +1 -1
  165. package/richtexteditor/plugins/inserttemplate.js +33 -17
  166. package/richtexteditor/plugins/inserttemplate.min.js +1 -1
  167. package/richtexteditor/plugins/keyboarda11y.js +66 -3
  168. package/richtexteditor/plugins/keyboarda11y.min.js +1 -1
  169. package/richtexteditor/plugins/layouttable.js +20 -0
  170. package/richtexteditor/plugins/layouttable.min.js +1 -1
  171. package/richtexteditor/plugins/linkchecker.js +29 -9
  172. package/richtexteditor/plugins/linkchecker.min.js +1 -1
  173. package/richtexteditor/plugins/localdraft.js +51 -7
  174. package/richtexteditor/plugins/localdraft.min.js +1 -1
  175. package/richtexteditor/plugins/markdownexport.js +159 -0
  176. package/richtexteditor/plugins/markdownexport.min.js +2 -2
  177. package/richtexteditor/plugins/mathdialog.js +11 -5
  178. package/richtexteditor/plugins/mathdialog.min.js +1 -1
  179. package/richtexteditor/plugins/mentionplugin.js +88 -25
  180. package/richtexteditor/plugins/mentionplugin.min.js +1 -1
  181. package/richtexteditor/plugins/mermaiddiagram.js +9 -3
  182. package/richtexteditor/plugins/mermaiddiagram.min.js +2 -2
  183. package/richtexteditor/plugins/multilevellist.js +4 -0
  184. package/richtexteditor/plugins/multilevellist.min.js +1 -1
  185. package/richtexteditor/plugins/pdfexport.js +235 -35
  186. package/richtexteditor/plugins/pdfexport.min.js +12 -12
  187. package/richtexteditor/plugins/permanentpen.js +3 -3
  188. package/richtexteditor/plugins/permanentpen.min.js +1 -1
  189. package/richtexteditor/plugins/readabilitystats.js +25 -11
  190. package/richtexteditor/plugins/readabilitystats.min.js +1 -1
  191. package/richtexteditor/plugins/readaloud.js +29 -15
  192. package/richtexteditor/plugins/readaloud.min.js +1 -1
  193. package/richtexteditor/plugins/restrictedediting.js +166 -0
  194. package/richtexteditor/plugins/restrictedediting.min.js +2 -2
  195. package/richtexteditor/plugins/revisionhistory.js +169 -37
  196. package/richtexteditor/plugins/revisionhistory.min.js +3 -3
  197. package/richtexteditor/plugins/rubyannotation.js +19 -9
  198. package/richtexteditor/plugins/rubyannotation.min.js +1 -1
  199. package/richtexteditor/plugins/sanitizer.js +86 -4
  200. package/richtexteditor/plugins/sanitizer.min.js +1 -1
  201. package/richtexteditor/plugins/slashcommand.js +30 -16
  202. package/richtexteditor/plugins/slashcommand.min.js +2 -2
  203. package/richtexteditor/plugins/smartchips.js +36 -22
  204. package/richtexteditor/plugins/smartchips.min.js +2 -2
  205. package/richtexteditor/plugins/spellcheck.js +17 -8
  206. package/richtexteditor/plugins/spellcheck.min.js +2 -2
  207. package/richtexteditor/plugins/stateinspector.js +19 -9
  208. package/richtexteditor/plugins/stateinspector.min.js +2 -2
  209. package/richtexteditor/plugins/structured-content-bridge.js +56 -24
  210. package/richtexteditor/plugins/structured-content-bridge.min.js +7 -7
  211. package/richtexteditor/plugins/tableofcontents.js +5 -2
  212. package/richtexteditor/plugins/tableofcontents.min.js +1 -1
  213. package/richtexteditor/plugins/tabletools.js +388 -3
  214. package/richtexteditor/plugins/tabletools.min.js +1 -1
  215. package/richtexteditor/plugins/textdirection.js +18 -5
  216. package/richtexteditor/plugins/textdirection.min.js +1 -1
  217. package/richtexteditor/plugins/textpartlanguage.js +161 -32
  218. package/richtexteditor/plugins/textpartlanguage.min.js +1 -1
  219. package/richtexteditor/plugins/todolist.js +90 -6
  220. package/richtexteditor/plugins/todolist.min.js +1 -1
  221. package/richtexteditor/plugins/trackedchanges.js +1812 -25
  222. package/richtexteditor/plugins/trackedchanges.min.js +5 -3
  223. package/richtexteditor/plugins/wordexport.js +2 -2
  224. package/richtexteditor/plugins/yjscollab.js +9 -4
  225. package/richtexteditor/plugins/yjscollab.min.js +1 -1
  226. package/richtexteditor/plugins/zz_richtextbox_dialog_style.js +22 -13
  227. package/richtexteditor/plugins/zz_richtextbox_dialog_style.min.js +1 -1
  228. package/richtexteditor/rte-config.js +131 -50
  229. package/richtexteditor/rte-headless.js +19 -4
  230. package/richtexteditor/rte-webcomponent.js +89 -16
  231. package/richtexteditor/rte.js +133 -52
  232. package/richtexteditor/runtime/colorpicker_more_ns.htm +93 -16
  233. package/scripts/build-angular.mjs +97 -0
  234. package/svelte/index.d.ts +2 -1
  235. package/svelte/index.js +80 -9
  236. package/vue/index.js +130 -34
  237. package/angular/component.ts +0 -297
  238. package/angular/index.ts +0 -24
@@ -4,17 +4,28 @@
4
4
  <meta http-equiv="Page-Exit" content="blendTrans(Duration=0.1)" />
5
5
 
6
6
  <script type="text/javascript">
7
+ // Call the editor directly when this frame may. Opened from disk (file://) every frame
8
+ // is its own origin and the direct call throws a SecurityError - which used to abort this
9
+ // page's load before it drew Recent, and made OK do nothing. Post a message instead; the
10
+ // editor's Color Picker listens for this frame's messages.
11
+ function callPicker(method, value) {
12
+ try { parent.rtecolorpicker[method](value); return; }
13
+ catch (e) { }
14
+ try { parent.postMessage({ rtecolorpicker: method, value: value }, "*"); }
15
+ catch (e) { }
16
+ }
7
17
  function updateColor(c) {
8
- parent.rtecolorpicker.update(c);
18
+ callPicker("update", c);
9
19
  }
10
20
  function selectColor(c) {
11
- parent.rtecolorpicker.select(c);
21
+ callPicker("select", c);
12
22
  }
13
23
  function selectCancel() {
14
- parent.rtecolorpicker.cancel();
24
+ callPicker("cancel");
15
25
  }
16
26
  function setCallback(cb) {
17
- parent.rtecolorpicker.setCallback(cb);
27
+ try { parent.rtecolorpicker.setCallback(cb); }
28
+ catch (e) { }
18
29
  }
19
30
  </script>
20
31
 
@@ -121,12 +132,14 @@
121
132
 
122
133
  }
123
134
 
124
- if (top.dialogArguments) {
125
- if (typeof (top.dialogArguments) == 'object') {
126
- if (top.dialogArguments.onchange) {
127
- firecolorchange = top.dialogArguments.onchange;
128
- _origincolor = top.dialogArguments.color;
129
- _editor = top.dialogArguments.editor;
135
+ var _dialogArguments = null;
136
+ try { _dialogArguments = top.dialogArguments; } catch (e) { } // cross-origin from disk
137
+ if (_dialogArguments) {
138
+ if (typeof (_dialogArguments) == 'object') {
139
+ if (_dialogArguments.onchange) {
140
+ firecolorchange = _dialogArguments.onchange;
141
+ _origincolor = _dialogArguments.color;
142
+ _editor = _dialogArguments.editor;
130
143
  }
131
144
  }
132
145
  }
@@ -313,7 +326,8 @@
313
326
  msg.SelectAColor = "Select a color:";
314
327
  msg.OKButton = "OK";
315
328
  msg.CancelButton = "Cancel";
316
- msg.Recent = "Recent";
329
+ msg.Recent = "Recent colors";
330
+ msg.RecentEmpty = "Colors you apply will appear here.";
317
331
  msg.WebSafeWarning = "Warning: not a web safe color";
318
332
  msg.WebSafeClick = "Click to select web safe color";
319
333
  msg.HsbHue = "H:";
@@ -392,11 +406,17 @@
392
406
  frm.ColorType[new Number(GetCookie("ColorMode") || 0)].checked = true;
393
407
  ColorMode_Changed(e);
394
408
 
395
- var recent = GetCookie("RecentColors") || "";
409
+ // The editor passes its list (every colour it applied, from anywhere); fall back to
410
+ // the shared storage for a page opened some other way.
411
+ var recent = GetQuery("Recent") || GetCookie("RecentColors") || "";
412
+ recent = String(recent).toUpperCase().replace(/[^0-9A-F]/g, "");
413
+ recent = recent.substring(0, recent.length - recent.length % 6);
396
414
 
397
415
  var RecentTooltip = msg.RecentTooltip;
416
+ var recentShown = 0;
398
417
  for (var i = 1; i < 33; i++)
399
- if (recent.length / 6 >= i) {
418
+ if (recent.length / 6 >= i && i <= 24) {
419
+ recentShown++;
400
420
  hex = recent.substr((i - 1) * 6, 6);
401
421
  var rgb = HexToRgb(hex);
402
422
  var title = formatString(msg.RecentTooltip, hex, rgb[0], rgb[1], rgb[2]);
@@ -410,8 +430,13 @@
410
430
  recentColor.onkeydown = pnlRecent_KeyDown;
411
431
  }
412
432
  else
413
- document.getElementById("pnlRecent" + i).style.border = "0px";
414
- //Hide(document.all["pnlRecent" + i]);
433
+ document.getElementById("pnlRecent" + i).className = "recent-empty";
434
+ if (!recentShown) {
435
+ var none = document.createElement("span");
436
+ none.id = "pnlRecentNone";
437
+ none.innerText = msg.RecentEmpty;
438
+ document.getElementById("pnlRecent").appendChild(none);
439
+ }
415
440
  }
416
441
 
417
442
  function pnlRecent_Click(e) {
@@ -2421,6 +2446,56 @@ Elements
2421
2446
  margin: 0;
2422
2447
  text-align: center;
2423
2448
  }
2449
+
2450
+ /* Recent colors: only the swatches there are, rounded, in a grid - not 32 sunken empty
2451
+ boxes. Up to 24 (three rows) fit the space. */
2452
+ #colorpickerpanel #pnlRecentBorder {
2453
+ display: none;
2454
+ }
2455
+
2456
+ #colorpickerpanel #lblRecent {
2457
+ width: 160px;
2458
+ }
2459
+
2460
+ #colorpickerpanel #pnlRecent {
2461
+ display: grid;
2462
+ grid-template-columns: repeat(8, 16px);
2463
+ grid-auto-rows: 16px;
2464
+ gap: 4px;
2465
+ align-content: start;
2466
+ height: 72px;
2467
+ }
2468
+
2469
+ #colorpickerpanel #pnlRecent DIV {
2470
+ position: static;
2471
+ width: 16px;
2472
+ height: 16px;
2473
+ box-sizing: border-box;
2474
+ border: 1px solid rgba(0, 0, 0, .22);
2475
+ border-radius: 3px;
2476
+ cursor: pointer;
2477
+ transition: transform .1s, box-shadow .1s;
2478
+ }
2479
+
2480
+ #colorpickerpanel #pnlRecent DIV:hover {
2481
+ transform: scale(1.2);
2482
+ box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
2483
+ }
2484
+
2485
+ #colorpickerpanel #pnlRecent DIV:focus-visible {
2486
+ outline: 2px solid #1a73e8;
2487
+ outline-offset: 1px;
2488
+ }
2489
+
2490
+ #colorpickerpanel #pnlRecent DIV.recent-empty {
2491
+ display: none;
2492
+ }
2493
+
2494
+ #pnlRecentNone {
2495
+ grid-column: 1 / -1;
2496
+ font: 11px/1.35 Arial, sans-serif;
2497
+ color: #6b7280;
2498
+ }
2424
2499
  </style>
2425
2500
  <title>CustomColor</title>
2426
2501
  </head>
@@ -2683,7 +2758,9 @@ Elements
2683
2758
  <script>
2684
2759
 
2685
2760
  new function () {
2686
- var editor = parent.rtecolorpickereditor;
2761
+ var editor = null;
2762
+ try { editor = parent.rtecolorpickereditor; } catch (e) { } // cross-origin from disk: keep English
2763
+ if (!editor || !editor.getLangText) return;
2687
2764
  var ns = document.getElementsByTagName("*");
2688
2765
  for (var i = 0; i < ns.length; i++) {
2689
2766
  var n = ns[i];
@@ -0,0 +1,97 @@
1
+ // Build a partial-Ivy ESM entry point. Never publishes or changes editor core.
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import os from 'node:os';
5
+ import { createRequire } from 'node:module';
6
+ import { spawnSync } from 'node:child_process';
7
+ import { createHash } from 'node:crypto';
8
+ const packageRoot = path.resolve(import.meta.dirname, '..');
9
+ const repoRoot = path.dirname(packageRoot);
10
+ const sha256 = data => createHash('sha256').update(data).digest('hex');
11
+ // npm may repack an installed distribution. It contains validated generated
12
+ // output, not the maintainer-only TypeScript sources/toolchain.
13
+ try { await fs.access(path.join(packageRoot, 'angular/component.ts')); }
14
+ catch (error) {
15
+ if (error.code !== 'ENOENT') throw error;
16
+ const manifest = JSON.parse(await fs.readFile(path.join(packageRoot, 'angular/build-manifest.json'), 'utf8'));
17
+ for (const [file, expected] of Object.entries(manifest.outputs)) {
18
+ if (sha256(await fs.readFile(path.join(packageRoot, file))) !== expected.sha256) throw new Error('Invalid prebuilt Angular output: ' + file);
19
+ }
20
+ for (const [file, expected] of Object.entries(manifest.sources)) {
21
+ let data;
22
+ try { data = await fs.readFile(path.join(packageRoot, file)); }
23
+ catch (readError) { if (readError.code === 'ENOENT') continue; throw readError; }
24
+ if (sha256(data) !== expected) throw new Error('Angular dependency changed; rebuild from the repository: ' + file);
25
+ }
26
+ console.log('Verified prebuilt Angular entry point');
27
+ process.exit(0);
28
+ }
29
+ const ownRequire = createRequire(path.join(packageRoot, 'package.json'));
30
+ let toolRequire = ownRequire;
31
+ try { toolRequire.resolve('@angular/compiler-cli/package.json'); }
32
+ catch {
33
+ // The downloadable Angular demo already has this pinned toolchain installed
34
+ // in a repository checkout. Published consumers do not run this build step.
35
+ toolRequire = createRequire(path.join(repoRoot, 'Demos/rte-ng-ts/package.json'));
36
+ }
37
+ const compilerPackage = toolRequire.resolve('@angular/compiler-cli/package.json');
38
+ const compilerInfo = JSON.parse(await fs.readFile(compilerPackage, 'utf8'));
39
+ const compilerDir = path.dirname(compilerPackage);
40
+ const compilerBin = path.resolve(compilerDir, compilerInfo.bin.ngc);
41
+ const angularScope = path.dirname(path.dirname(toolRequire.resolve('@angular/core/package.json')));
42
+ const rxjs = path.dirname(toolRequire.resolve('rxjs/package.json'));
43
+ const stage = await fs.mkdtemp(path.join(os.tmpdir(), 'rte-angular-apf-'));
44
+ const config = {
45
+ compilerOptions: {
46
+ target: 'ES2022', module: 'ES2022', moduleResolution: 'bundler',
47
+ experimentalDecorators: true, strict: true, declaration: true,
48
+ skipLibCheck: false, noEmitOnError: true, types: [],
49
+ rootDir: packageRoot, outDir: path.join(stage, 'out'), baseUrl: packageRoot,
50
+ paths: { '@angular/*': [path.join(angularScope, '*')], rxjs: [rxjs], 'rxjs/*': [path.join(rxjs, '*')] }
51
+ },
52
+ angularCompilerOptions: { strictTemplates: true, compilationMode: 'partial' },
53
+ files: [path.join(packageRoot, 'angular/index.ts')]
54
+ };
55
+ const configFile = path.join(stage, 'tsconfig.json');
56
+ await fs.writeFile(configFile, JSON.stringify(config, null, 2));
57
+ const result = spawnSync(process.execPath, [compilerBin, '-p', configFile], { cwd: packageRoot, encoding: 'utf8', windowsHide: true, timeout: 120000 });
58
+ process.stdout.write(result.stdout || ''); process.stderr.write(result.stderr || '');
59
+ if (result.status !== 0) throw new Error('Angular partial compilation failed; staging retained at ' + stage);
60
+ const esbuild = toolRequire('esbuild');
61
+ const bundled = await esbuild.build({
62
+ entryPoints: [path.join(stage, 'out/angular/index.js')],
63
+ bundle: true, write: false, format: 'esm', platform: 'browser', target: 'es2022',
64
+ charset: 'utf8', minifyWhitespace: true, legalComments: 'eof',
65
+ banner: { js: '// Generated Angular partial-Ivy entry. See package license.' },
66
+ external: ['@angular/*'],
67
+ plugins: [{ name: 'rte-shared-runtime', setup(build) {
68
+ build.onResolve({ filter: /^\.\.\/integrations\/shared(?:\.js)?$/ }, () => ({ path: path.join(packageRoot, 'integrations/shared.js') }));
69
+ } }]
70
+ });
71
+ let declarations = await fs.readFile(path.join(stage, 'out/angular/component.d.ts'), 'utf8');
72
+ const indexDeclarations = await fs.readFile(path.join(stage, 'out/angular/index.d.ts'), 'utf8');
73
+ const ts = toolRequire('typescript');
74
+ const indexAst = ts.createSourceFile('index.d.ts', indexDeclarations, ts.ScriptTarget.Latest, true);
75
+ const componentExport = indexAst.statements.find(s => ts.isExportDeclaration(s) && s.moduleSpecifier?.text === './component');
76
+ if (!componentExport) throw new Error('Missing generated component export');
77
+ declarations += '\n' + indexDeclarations.slice(0, componentExport.getFullStart()) + indexDeclarations.slice(componentExport.getEnd());
78
+ if (!declarations.includes('ɵɵComponentDeclaration') || !bundled.outputFiles[0].text.includes('ɵɵngDeclareComponent')) throw new Error('Partial-Ivy metadata is required');
79
+ const sources = {};
80
+ for (const file of ['angular/component.ts', 'angular/index.ts', 'integrations/shared.js', 'integrations/shared.d.ts', 'index.d.ts', 'scripts/build-angular.mjs']) sources[file] = sha256(await fs.readFile(path.join(packageRoot, file)));
81
+ const outputs = { 'angular/index.mjs': bundled.outputFiles[0].text, 'angular/index.d.ts': declarations };
82
+ async function writeIfChanged(file, data) {
83
+ try { if (await fs.readFile(file, 'utf8') === data) return; }
84
+ catch (error) { if (error.code !== 'ENOENT') throw error; }
85
+ await fs.writeFile(file, data);
86
+ }
87
+ // Save the existing public declarations before first replacing them with
88
+ // compiler-generated metadata. This is a local migration backup, not payload.
89
+ const backup = path.join(stage, 'previous-index.d.ts');
90
+ await fs.mkdir(path.dirname(backup), { recursive: true });
91
+ try { await fs.copyFile(path.join(packageRoot, 'angular/index.d.ts'), backup, (await import('node:fs')).constants.COPYFILE_EXCL); }
92
+ catch (error) { if (error.code !== 'EEXIST') throw error; }
93
+ for (const [file, data] of Object.entries(outputs)) await writeIfChanged(path.join(packageRoot, file), data);
94
+ const manifest = { angularCompiler: compilerInfo.version, typescript: ts.version, esbuild: esbuild.version, sources,
95
+ outputs: Object.fromEntries(Object.entries(outputs).map(([file, data]) => [file, { bytes: Buffer.byteLength(data), sha256: sha256(data) }])) };
96
+ await writeIfChanged(path.join(packageRoot, 'angular/build-manifest.json'), JSON.stringify(manifest, null, 2) + '\n');
97
+ console.log('Built Angular partial-Ivy ESM + metadata declarations', JSON.stringify(manifest.outputs));
package/svelte/index.d.ts CHANGED
@@ -4,7 +4,8 @@ import type { HeadlessController, HeadlessEditorOptions, HeadlessState } from ".
4
4
  export interface SvelteEditorOptions extends HeadlessEditorOptions {
5
5
  onReady?: (editor: HeadlessController) => void;
6
6
  onUpdate?: (state: HeadlessState) => void;
7
- onChange?: (...args: any[]) => void;
7
+ /** Called with the controller as this; may flush final native input synchronously on unmount. */
8
+ onChange?: (this: HeadlessController, ...args: any[]) => void;
8
9
  onError?: (error: unknown) => void;
9
10
  }
10
11
 
package/svelte/index.js CHANGED
@@ -11,8 +11,10 @@
11
11
  * let state = {};
12
12
  * </script>
13
13
  *
14
- * <button on:mousedown|preventDefault={() => editor.run("bold")}
15
- * class:is-active={state.bold}>B</button>
14
+ * <button type="button" disabled={!editor} aria-pressed={!!state.bold}
15
+ * on:pointerdown|preventDefault
16
+ * on:click={() => editor && editor.run("bold")}
17
+ * class:is-active={state.bold}>Bold</button>
16
18
  *
17
19
  * <div use:richTextEditor={{
18
20
  * value: "<p>Hello</p>",
@@ -21,34 +23,103 @@
21
23
  * }}></div>
22
24
  */
23
25
  var headless = require("../headless");
26
+ var initializationScope = require("../integrations/initialization-scope");
27
+ var nativeMounts = require("../integrations/native-mount");
24
28
 
25
29
  function richTextEditor(node, options) {
26
30
  options = options || {};
27
31
  var controller = null;
28
32
  var current = options;
33
+ var disposed = false;
34
+ var pendingScope = null;
35
+ var lastKnownHtml = null;
36
+ var mountBoundary = null;
37
+ var nativeMount = null;
29
38
 
30
- headless.createHeadlessEditor(node, options)
39
+ function releaseController(ctl) {
40
+ if (ctl) { try { ctl.destroy(); } catch (e) { /* Continue lifecycle cleanup. */ } }
41
+ nativeMounts.releaseNativeMount(ctl && ctl.editor, nativeMount);
42
+ nativeMount = null;
43
+ var boundary = mountBoundary;
44
+ mountBoundary = null;
45
+ if (boundary && boundary.parentNode) boundary.parentNode.removeChild(boundary);
46
+ }
47
+
48
+ // Route synchronous setup errors through onError too, and avoid creating
49
+ // an editor when an action is destroyed before the first microtask.
50
+ Promise.resolve().then(function () {
51
+ if (disposed) return null;
52
+ pendingScope = initializationScope.createInitializationScope(current.signal);
53
+ // Keep native form-control conversion unchanged for legacy callers.
54
+ if (/^(INPUT|TEXTAREA)$/i.test(node.tagName || "")) {
55
+ return headless.createHeadlessEditor(node, Object.assign({}, current, { signal: pendingScope.signal }));
56
+ }
57
+ // The action node belongs to Svelte. Plugins may reparent their own
58
+ // host, so contain all generated shells in a removable private subtree.
59
+ mountBoundary = node.ownerDocument.createElement("div");
60
+ var editorMount = node.ownerDocument.createElement("div");
61
+ mountBoundary.appendChild(editorMount);
62
+ node.appendChild(mountBoundary);
63
+ nativeMount = nativeMounts.captureNativeMount(editorMount);
64
+ return headless.createHeadlessEditor(editorMount, Object.assign({}, current, { signal: pendingScope.signal }));
65
+ })
31
66
  .then(function (ctl) {
67
+ if (pendingScope) pendingScope.complete();
68
+ if (!ctl) return;
69
+ if (disposed) { releaseController(ctl); return; }
32
70
  controller = ctl;
33
- if (current.onUpdate) { ctl.on("update", current.onUpdate); }
34
- if (current.onChange) { ctl.on("change", current.onChange); }
35
- if (current.onReady) { current.onReady(ctl); }
71
+ if (current.value != null && current.value !== ctl.getHTML()) ctl.setHTML(current.value);
72
+ lastKnownHtml = ctl.getHTML();
73
+ // Stable relays read the latest options. Svelte can replace event
74
+ // callbacks without remounting the action or leaving stale closures.
75
+ ctl.on("update", function () {
76
+ if (!disposed && typeof current.onUpdate === "function") current.onUpdate.apply(ctl, arguments);
77
+ });
78
+ ctl.on("change", function () {
79
+ if (!disposed && typeof current.onChange === "function") {
80
+ lastKnownHtml = ctl.getHTML();
81
+ current.onChange.apply(ctl, arguments);
82
+ }
83
+ });
84
+ if (typeof current.onReady === "function") current.onReady(ctl);
36
85
  })
37
86
  .catch(function (error) {
38
- if (current.onError) { current.onError(error); }
87
+ if (pendingScope) pendingScope.complete();
88
+ var ctl = controller;
89
+ controller = null;
90
+ releaseController(ctl);
91
+ if (!disposed && typeof current.onError === "function") current.onError(error);
39
92
  });
40
93
 
41
94
  return {
42
95
  update: function (next) {
96
+ if (disposed) return;
97
+ var previous = current;
43
98
  current = next || {};
44
99
  // keep content in sync if the bound value changes
45
- if (controller && next && next.value != null && next.value !== controller.getHTML()) {
100
+ if (controller && next && next.value != null && next.value !== previous.value && next.value !== controller.getHTML()) {
46
101
  controller.setHTML(next.value);
102
+ lastKnownHtml = controller.getHTML();
47
103
  }
48
104
  },
49
105
  destroy: function () {
50
- if (controller) { controller.destroy(); }
106
+ if (disposed) return;
107
+ disposed = true;
108
+ if (pendingScope) pendingScope.dispose();
109
+ var ctl = controller;
51
110
  controller = null;
111
+ try {
112
+ // Core change is deferred; an action can unmount in the same
113
+ // turn as the last native input. Deliver that value once while
114
+ // the controller is still readable, before destroying it.
115
+ if (ctl && typeof current.onChange === "function") {
116
+ var finalHtml = ctl.getHTML();
117
+ if (finalHtml !== lastKnownHtml) {
118
+ lastKnownHtml = finalHtml;
119
+ current.onChange.call(ctl, ctl.editor);
120
+ }
121
+ }
122
+ } finally { releaseController(ctl); }
52
123
  }
53
124
  };
54
125
  }
package/vue/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  var vue = require("vue");
2
2
  var shared = require("../integrations/shared");
3
3
  var headless = require("../headless");
4
+ var initializationScope = require("../integrations/initialization-scope");
5
+ var nativeMounts = require("../integrations/native-mount");
4
6
 
5
7
  function editorMethodAccessor(editorRef, name, emptyValue) {
6
8
  return function () {
@@ -24,6 +26,7 @@ var RichTextEditorVue = vue.defineComponent({
24
26
  type: Boolean,
25
27
  default: true
26
28
  },
29
+ changeDelay: { type: Number, default: 120 },
27
30
  config: {
28
31
  type: Object,
29
32
  default: function () {
@@ -52,8 +55,47 @@ var RichTextEditorVue = vue.defineComponent({
52
55
  var hostRef = vue.ref(null);
53
56
  var editorRef = vue.ref(null);
54
57
  var changeHandler = null;
58
+ var blurHandler = null;
55
59
  var emitChange = null;
56
60
  var lastEmitted;
61
+ var disposed = false;
62
+ var writingValue = false;
63
+ var lastKnownHtml = null;
64
+ var nativeMount = null;
65
+
66
+ function emitCurrentValue() {
67
+ var editor = editorRef.value;
68
+ if (!editor) return;
69
+ var nextValue = shared.getEditorValue(editor, props.valueFormat);
70
+ var html = typeof nextValue === "string" ? nextValue : (typeof nextValue.html === "string" ? nextValue.html : editor.getHTMLCode());
71
+ if (html === lastKnownHtml) return;
72
+ lastKnownHtml = html;
73
+ lastEmitted = nextValue;
74
+ context.emit("update:modelValue", nextValue);
75
+ if (editorRef.value === editor) context.emit("change", nextValue, editor);
76
+ }
77
+
78
+ function releaseEditor() {
79
+ if (emitChange) emitChange.cancel();
80
+ emitChange = null;
81
+ var editor = editorRef.value;
82
+ var handler = changeHandler;
83
+ editorRef.value = null;
84
+ changeHandler = null;
85
+ if (editor && blurHandler && typeof editor.detachEvent === "function") {
86
+ try { editor.detachEvent("blur", blurHandler); } catch (e) { /* Continue cleanup. */ }
87
+ }
88
+ blurHandler = null;
89
+ if (editor && handler && typeof editor.detachEvent === "function") {
90
+ try { editor.detachEvent("change", handler); } catch (e) { /* Continue cleanup. */ }
91
+ }
92
+ if (editor && typeof editor.destroy === "function") {
93
+ try { editor.destroy(); } catch (e) { /* Continue cleanup. */ }
94
+ }
95
+ nativeMounts.releaseNativeMount(editor, nativeMount);
96
+ nativeMount = null;
97
+ if (hostRef.value) hostRef.value.innerHTML = "";
98
+ }
57
99
 
58
100
  function syncEditor(nextValue) {
59
101
  if (!editorRef.value) {
@@ -62,11 +104,15 @@ var RichTextEditorVue = vue.defineComponent({
62
104
 
63
105
  var nextHtml = shared.normalizeStructuredContent(nextValue);
64
106
  if (editorRef.value.getHTMLCode() !== nextHtml) {
65
- shared.setEditorValue(editorRef.value, nextValue, props.valueFormat);
107
+ writingValue = true;
108
+ try { shared.setEditorValue(editorRef.value, nextValue, props.valueFormat); }
109
+ finally { writingValue = false; }
66
110
  }
111
+ if (editorRef.value) lastKnownHtml = editorRef.value.getHTMLCode();
67
112
  }
68
113
 
69
114
  vue.onMounted(async function () {
115
+ if (disposed) return;
70
116
  try {
71
117
  if (props.autoload === false) {
72
118
  shared.installStructuredContentBridge();
@@ -74,34 +120,54 @@ var RichTextEditorVue = vue.defineComponent({
74
120
  await shared.loadRichTextEditorAssets({ basePath: props.assetBasePath });
75
121
  }
76
122
 
77
- if (!hostRef.value) {
123
+ if (disposed || !hostRef.value) {
78
124
  return;
79
125
  }
80
126
 
81
- var editor = shared.createEditor(hostRef.value, props.config || {});
127
+ var editorMount = hostRef.value;
128
+ // Preserve legacy native form-control conversion. Block roots
129
+ // stay Vue-owned while plugins wrap only a disposable child.
130
+ if (!/^(INPUT|TEXTAREA)$/i.test(editorMount.tagName || "")) {
131
+ editorMount = hostRef.value.ownerDocument.createElement("div");
132
+ hostRef.value.appendChild(editorMount);
133
+ }
134
+ nativeMount = nativeMounts.captureNativeMount(editorMount);
135
+ var editor = shared.createEditor(editorMount, props.config || {});
136
+ if (disposed) {
137
+ try { editor.destroy(); } catch (e) { /* Continue cleanup. */ }
138
+ nativeMounts.releaseNativeMount(editor, nativeMount);
139
+ nativeMount = null;
140
+ return;
141
+ }
82
142
  editorRef.value = editor;
83
143
 
84
144
  var initialValue = props.modelValue !== undefined ? props.modelValue : props.defaultValue;
85
145
  if (initialValue !== undefined) {
86
146
  shared.setEditorValue(editor, initialValue, props.valueFormat);
87
147
  }
148
+ if (disposed) return;
149
+ lastKnownHtml = editor.getHTMLCode();
88
150
 
89
151
  // Coalesce: the editor fires `change` per keystroke and
90
152
  // getEditorValue serialises the whole document (78 ms on a
91
153
  // 3000-paragraph document). See shared.createChangeCoalescer.
92
- emitChange = shared.createChangeCoalescer(function () {
93
- var nextValue = shared.getEditorValue(editor, props.valueFormat);
94
- lastEmitted = nextValue;
95
- context.emit("update:modelValue", nextValue);
96
- context.emit("change", nextValue, editor);
97
- }, props.changeDelay == null ? 120 : props.changeDelay);
154
+ emitChange = shared.createChangeCoalescer(emitCurrentValue, props.changeDelay == null ? 120 : props.changeDelay);
98
155
 
99
- changeHandler = function () { emitChange(); };
156
+ changeHandler = function () { if (!disposed && !writingValue && emitChange) emitChange(); };
100
157
 
101
158
  editor.attachEvent("change", changeHandler);
159
+ blurHandler = function () {
160
+ if (disposed || writingValue) return;
161
+ if (emitChange) emitChange.flush();
162
+ emitCurrentValue();
163
+ };
164
+ editor.attachEvent("blur", blurHandler);
102
165
  context.emit("ready", editor);
103
166
  } catch (error) {
104
- context.emit("error", error);
167
+ if (!disposed) {
168
+ releaseEditor();
169
+ context.emit("error", error);
170
+ }
105
171
  }
106
172
  });
107
173
 
@@ -126,23 +192,14 @@ var RichTextEditorVue = vue.defineComponent({
126
192
  });
127
193
 
128
194
  vue.onBeforeUnmount(function () {
129
- var ed = editorRef.value;
130
- if (ed) {
131
- // Flush first, or the last keystroke before teardown is lost.
132
- if (emitChange) { emitChange.flush(); }
133
- if (changeHandler && typeof ed.detachEvent === "function") {
134
- ed.detachEvent("change", changeHandler);
135
- }
136
- if (typeof ed.destroy === "function") {
137
- try { ed.destroy(); } catch (e) { /* ignore */ }
138
- }
139
- }
140
-
141
- if (hostRef.value) {
142
- hostRef.value.innerHTML = "";
143
- }
144
-
145
- editorRef.value = null;
195
+ if (disposed) return;
196
+ disposed = true;
197
+ try {
198
+ if (emitChange) emitChange.flush();
199
+ // Core itself can defer change; preserve native input even if
200
+ // no wrapper timer was scheduled before the view unmounted.
201
+ if (changeHandler) emitCurrentValue();
202
+ } finally { releaseEditor(); }
146
203
  });
147
204
 
148
205
  function pluginAccessor(name) {
@@ -252,25 +309,64 @@ function useRichTextEditor(options) {
252
309
  var editor = vue.shallowRef(null);
253
310
  var state = vue.ref({});
254
311
  var controller = null;
312
+ var disposed = false;
313
+ var pendingScope = null;
314
+ var activeHost = null;
315
+ var nativeMount = null;
316
+
317
+ function releaseController() {
318
+ var owned = controller;
319
+ controller = null;
320
+ if (editor.value === owned) editor.value = null;
321
+ if (owned) { try { owned.destroy(); } catch (e) { /* Continue cleanup. */ } }
322
+ nativeMounts.releaseNativeMount(owned && owned.editor, nativeMount);
323
+ nativeMount = null;
324
+ if (activeHost && !editor.value) activeHost.innerHTML = "";
325
+ }
255
326
 
256
327
  vue.onMounted(function () {
257
- headless.createHeadlessEditor(mountRef.value, options)
328
+ activeHost = mountRef.value;
329
+ Promise.resolve().then(function () {
330
+ if (disposed) return null;
331
+ if (!activeHost) throw new Error("useRichTextEditor: render mountRef before initialization.");
332
+ pendingScope = initializationScope.createInitializationScope(options.signal);
333
+ var editorMount = activeHost;
334
+ if (!/^(INPUT|TEXTAREA)$/i.test(editorMount.tagName || "")) {
335
+ editorMount = activeHost.ownerDocument.createElement("div");
336
+ activeHost.appendChild(editorMount);
337
+ }
338
+ nativeMount = nativeMounts.captureNativeMount(editorMount);
339
+ return headless.createHeadlessEditor(editorMount, Object.assign({}, options, { signal: pendingScope.signal }));
340
+ })
258
341
  .then(function (ctl) {
342
+ if (pendingScope) pendingScope.complete();
343
+ if (!ctl) return;
344
+ if (disposed) { try { ctl.destroy(); } finally { nativeMounts.releaseNativeMount(ctl.editor, nativeMount); nativeMount = null; } return; }
259
345
  controller = ctl;
260
346
  editor.value = ctl;
347
+ if (options.value != null && options.value !== ctl.getHTML()) ctl.setHTML(options.value);
261
348
  state.value = ctl.state();
262
- ctl.on("update", function (snapshot) { state.value = snapshot; });
349
+ ctl.on("update", function (snapshot) { if (!disposed) state.value = snapshot; });
263
350
  if (options.onReady) { options.onReady(ctl); }
264
351
  })
265
352
  .catch(function (error) {
266
- if (options.onError) { options.onError(error); }
353
+ if (pendingScope) pendingScope.complete();
354
+ if (!disposed) {
355
+ releaseController();
356
+ if (options.onError) options.onError(error);
357
+ }
267
358
  });
268
359
  });
269
360
 
270
361
  vue.onBeforeUnmount(function () {
271
- if (controller) { controller.destroy(); }
272
- controller = null;
273
- editor.value = null;
362
+ if (disposed) return;
363
+ disposed = true;
364
+ if (pendingScope) pendingScope.dispose();
365
+ releaseController();
366
+ });
367
+
368
+ vue.watch(function () { return options.value; }, function (value) {
369
+ if (!disposed && controller && value != null && value !== controller.getHTML()) controller.setHTML(value);
274
370
  });
275
371
 
276
372
  return { mountRef: mountRef, editor: editor, state: state };