@richscripts/richtexteditor 2.14.1 → 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 (237) 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 +7001 -1078
  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 +7001 -1078
  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 +47 -8
  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 +6 -6
  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 +62 -3
  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 +130 -50
  229. package/richtexteditor/rte-headless.js +19 -4
  230. package/richtexteditor/rte-webcomponent.js +89 -16
  231. package/richtexteditor/rte.js +132 -52
  232. package/scripts/build-angular.mjs +97 -0
  233. package/svelte/index.d.ts +2 -1
  234. package/svelte/index.js +80 -9
  235. package/vue/index.js +130 -34
  236. package/angular/component.ts +0 -297
  237. package/angular/index.ts +0 -24
@@ -54,19 +54,27 @@
54
54
  if (!global.customElements || !global.HTMLElement) return;
55
55
  if (global.customElements.get("rich-text-editor")) return;
56
56
 
57
- var OBSERVED = ["value", "readonly", "disabled", "height", "width", "toolbar", "name"];
57
+ var OBSERVED = ["value", "readonly", "disabled", "required", "height", "width", "toolbar", "name"];
58
58
 
59
59
  function RichTextEditorElement() {
60
60
  var self = Reflect.construct(HTMLElement, [], RichTextEditorElement);
61
61
  self._editor = null;
62
62
  self._value = "";
63
63
  self._host = null;
64
+ self._mountBoundary = null;
64
65
  self._ready = null;
65
66
  self._resolveReady = null;
66
67
  self._isReady = false;
67
68
  self._everConnected = false;
68
69
  self._internals = null;
69
70
  self._fallbackInput = null;
71
+ self._valueSet = false;
72
+ self._defaultValue = "";
73
+ self._formDisabled = false;
74
+ self._configReadOnly = false;
75
+ self._readyTimer = null;
76
+ self._nativeSurface = null;
77
+ self._nativeInput = null;
70
78
  try { if (self.attachInternals) self._internals = self.attachInternals(); } catch (e) {}
71
79
  return self;
72
80
  }
@@ -93,6 +101,7 @@
93
101
  return this._value;
94
102
  },
95
103
  set: function (html) {
104
+ if (!this._settingAttributeValue) this._valueSet = true;
96
105
  this._value = html == null ? "" : String(html);
97
106
  if (this._editor) {
98
107
  try { this._editor.setHTMLCode(this._value); } catch (e) {}
@@ -135,6 +144,19 @@
135
144
 
136
145
  proto.connectedCallback = function () {
137
146
  if (this._editor) return;
147
+ // Parser-created elements connect before their child markup has been
148
+ // parsed. Wait for the initial document before consuming that seed.
149
+ if (!this._everConnected && document.readyState === "loading") {
150
+ if (!this._connectListener) {
151
+ var self = this;
152
+ this._connectListener = function () {
153
+ self._connectListener = null;
154
+ if (self.isConnected) self.connectedCallback();
155
+ };
156
+ document.addEventListener("DOMContentLoaded", this._connectListener, { once: true });
157
+ }
158
+ return;
159
+ }
138
160
  if (!global.RichTextEditor) {
139
161
  console.error("<rich-text-editor>: rte.js must be loaded before rte-webcomponent.js.");
140
162
  return;
@@ -144,7 +166,7 @@
144
166
  // the attribute still holds the ORIGINAL seed, so re-reading it here
145
167
  // silently threw the edits away and restored stale text. Found by the
146
168
  // unmount/remount check in the test suite.
147
- if (!this._everConnected && this.hasAttribute("value")) this._value = this.getAttribute("value") || "";
169
+ if (!this._everConnected && !this._valueSet && this.hasAttribute("value")) this._value = this.getAttribute("value") || "";
148
170
  if (!this._everConnected) {
149
171
  // <textarea>-style progressive enhancement: markup written between the
150
172
  // tags is the initial document when no value attribute seeds one. The
@@ -158,7 +180,8 @@
158
180
  else if (kid.nodeType === 3) seed += kid.data;
159
181
  try { this.removeChild(kid); } catch (e) { }
160
182
  }
161
- if (!this.hasAttribute("value") && seed.trim()) this._value = seed;
183
+ this._defaultValue = this.hasAttribute("value") ? this.getAttribute("value") || "" : seed;
184
+ if (!this._valueSet && !this.hasAttribute("value") && seed.trim()) this._value = seed;
162
185
  }
163
186
  this._everConnected = true;
164
187
 
@@ -168,8 +191,7 @@
168
191
  // style plugin the toolbar is unstyled and 43,000 px tall.
169
192
  if (this._shadowStylingAvailable()) {
170
193
  var root = this.shadowRoot || this.attachShadow({ mode: "open" });
171
- mount = document.createElement("div");
172
- root.appendChild(mount);
194
+ mount = root;
173
195
  }
174
196
  else {
175
197
  console.warn("<rich-text-editor shadow>: plugins/shadowdom.js is not loaded, so the " +
@@ -177,8 +199,18 @@
177
199
  }
178
200
  }
179
201
 
202
+ // Plugins can wrap the core host. Remove this owned boundary, not just
203
+ // the moved host, so reconnects cannot accumulate empty side panels.
204
+ this._mountBoundary = document.createElement("div");
205
+ mount.appendChild(this._mountBoundary);
180
206
  this._host = document.createElement("div");
181
- mount.appendChild(this._host);
207
+ // ElementInternals' validation anchor must be focusable. Without this,
208
+ // submitting an empty required editor logs "not focusable" and gives
209
+ // the user no route back to the invalid field.
210
+ this._host.tabIndex = -1;
211
+ var element = this;
212
+ this._host.addEventListener("focus", function () { element.focus(); });
213
+ this._mountBoundary.appendChild(this._host);
182
214
 
183
215
  var config = this._buildConfig();
184
216
  this._editor = new global.RichTextEditor(this._host, config);
@@ -188,6 +220,13 @@
188
220
  };
189
221
 
190
222
  proto.disconnectedCallback = function () {
223
+ if (this._connectListener) document.removeEventListener("DOMContentLoaded", this._connectListener);
224
+ this._connectListener = null;
225
+ if (this._readyTimer !== null) clearInterval(this._readyTimer);
226
+ this._readyTimer = null;
227
+ if (this._nativeSurface && this._nativeInput) this._nativeSurface.removeEventListener("input", this._nativeInput);
228
+ this._nativeSurface = null;
229
+ this._nativeInput = null;
191
230
  // An SPA router unmounts and remounts constantly; a leaked iframe per
192
231
  // navigation is a real memory bug, not a theoretical one.
193
232
  this._value = this.value;
@@ -195,7 +234,9 @@
195
234
  try { if (typeof this._editor.destroy === "function") this._editor.destroy(); } catch (e) {}
196
235
  this._editor = null;
197
236
  }
198
- if (this._host && this._host.parentNode) this._host.parentNode.removeChild(this._host);
237
+ if (this._mountBoundary && this._mountBoundary.parentNode) this._mountBoundary.parentNode.removeChild(this._mountBoundary);
238
+ else if (this._host && this._host.parentNode) this._host.parentNode.removeChild(this._host);
239
+ this._mountBoundary = null;
199
240
  this._host = null;
200
241
  this._ready = null;
201
242
  this._resolveReady = null;
@@ -208,12 +249,15 @@
208
249
  // Like <input value>, the attribute seeds the initial value; once the
209
250
  // user has typed, the property is the truth and setting the attribute
210
251
  // again is an explicit reset by the page.
211
- this.value = newValue || "";
252
+ this._defaultValue = newValue || "";
253
+ this._settingAttributeValue = true;
254
+ try { this.value = newValue || ""; }
255
+ finally { this._settingAttributeValue = false; }
212
256
  }
213
257
  else if (name === "readonly" || name === "disabled") {
214
258
  this._applyReadOnly();
215
259
  }
216
- else if (name === "name") {
260
+ else if (name === "name" || name === "required") {
217
261
  this._syncFormValue();
218
262
  }
219
263
  else if (this._editor) {
@@ -228,10 +272,14 @@
228
272
 
229
273
  // Called by the browser when the containing form is reset.
230
274
  proto.formResetCallback = function () {
231
- this.value = this.getAttribute("value") || "";
275
+ this.value = this._defaultValue;
232
276
  };
233
277
 
234
- proto.formDisabledCallback = function () { this._applyReadOnly(); };
278
+ proto.formDisabledCallback = function (disabled) {
279
+ this._formDisabled = !!disabled;
280
+ this._applyReadOnly();
281
+ this._syncFormValue();
282
+ };
235
283
 
236
284
  // -------------------------------------------------------------- behaviour
237
285
 
@@ -268,6 +316,7 @@
268
316
  if (this.hasAttribute("toolbar")) config.toolbar = this.getAttribute("toolbar");
269
317
  if (this.hasAttribute("height")) config.height = this.getAttribute("height");
270
318
  if (this.hasAttribute("width")) config.width = this.getAttribute("width");
319
+ this._configReadOnly = !!config.readOnly;
271
320
  if (this._isReadOnly()) config.readOnly = true;
272
321
  if (this._value) config.value = this._value;
273
322
  return config;
@@ -275,7 +324,7 @@
275
324
 
276
325
  proto._isReadOnly = function () {
277
326
  return this.hasAttribute("readonly") || this.hasAttribute("disabled")
278
- || !!(this._internals && this._internals.form && this._internals.form.disabled);
327
+ || this._formDisabled || this._configReadOnly;
279
328
  };
280
329
 
281
330
  proto._applyReadOnly = function () {
@@ -294,7 +343,9 @@
294
343
 
295
344
  proto._bind = function () {
296
345
  var self = this;
346
+ var editor = this._editor;
297
347
  var emit = function (type) {
348
+ if (self._editor !== editor || !self.isConnected) return;
298
349
  self._syncFormValue();
299
350
  // composed:true so a listener outside a shadow boundary still hears it.
300
351
  self.dispatchEvent(new Event(type, { bubbles: true, composed: true }));
@@ -311,12 +362,24 @@
311
362
 
312
363
  proto._waitForReady = function () {
313
364
  var self = this;
365
+ var editor = this._editor;
314
366
  var tries = 0;
315
- var timer = setInterval(function () {
367
+ this._readyTimer = setInterval(function () {
368
+ if (self._editor !== editor || !self.isConnected) {
369
+ clearInterval(self._readyTimer); self._readyTimer = null; return;
370
+ }
316
371
  var alive = false;
317
372
  try { alive = !!(self._editor && self._editor.getEditable()); } catch (e) {}
318
373
  if (alive || ++tries > 200) {
319
- clearInterval(timer);
374
+ clearInterval(self._readyTimer); self._readyTimer = null;
375
+ // A timeout is not readiness. Never resolve .ready with a null
376
+ // editor or apply stale content after disconnection.
377
+ if (!alive) return;
378
+ self._nativeSurface = editor.getEditable();
379
+ self._nativeInput = function () {
380
+ if (self._editor === editor && self.isConnected) self._syncFormValue();
381
+ };
382
+ self._nativeSurface.addEventListener("input", self._nativeInput);
320
383
  if (self._value) { try { self._editor.setHTMLCode(self._value); } catch (e) {} }
321
384
  self._applyReadOnly();
322
385
  self._syncFormValue();
@@ -336,7 +399,10 @@
336
399
  this._syncValidity(value);
337
400
  return;
338
401
  }
339
- if (!name) return;
402
+ if (!name) {
403
+ if (this._fallbackInput) this._fallbackInput.removeAttribute("name");
404
+ return;
405
+ }
340
406
  if (!this._fallbackInput) {
341
407
  this._fallbackInput = document.createElement("input");
342
408
  this._fallbackInput.type = "hidden";
@@ -344,6 +410,7 @@
344
410
  }
345
411
  this._fallbackInput.name = name;
346
412
  this._fallbackInput.value = value;
413
+ this._fallbackInput.disabled = this.hasAttribute("disabled") || this._formDisabled;
347
414
  };
348
415
 
349
416
  proto._syncValidity = function (value) {
@@ -352,7 +419,13 @@
352
419
  // "Empty" for a rich-text field means no text and no media — an empty
353
420
  // <p> is what the editor puts in a blank document, and treating that as
354
421
  // filled makes `required` meaningless.
355
- var empty = !String(value || "").replace(/<[^>]*>/g, "").replace(/&nbsp;|\s/g, "")
422
+ var text = document.createElement("div");
423
+ // Inert parsing decodes numeric and named entities without attaching
424
+ // user markup to the live page or fetching its media.
425
+ var template = document.createElement("template");
426
+ template.innerHTML = String(value || "");
427
+ text.textContent = template.content.textContent;
428
+ var empty = !text.textContent.replace(/\s/g, "")
356
429
  && !/<(img|table|iframe|video|audio|hr)\b/i.test(value || "");
357
430
  try {
358
431
  if (required && empty) this._internals.setValidity({ valueMissing: true }, "Please fill out this field.", this._host || this);