suneditor 3.0.0-beta.3 → 3.0.0-beta.30

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 (241) hide show
  1. package/CONTRIBUTING.md +8 -8
  2. package/README.md +44 -49
  3. package/dist/suneditor.min.css +1 -1
  4. package/dist/suneditor.min.js +1 -1
  5. package/package.json +95 -53
  6. package/src/assets/design/color.css +2 -2
  7. package/src/assets/design/size.css +2 -0
  8. package/src/assets/icons/defaultIcons.js +16 -1
  9. package/src/assets/suneditor-contents.css +9 -8
  10. package/src/assets/suneditor.css +29 -26
  11. package/src/core/{section → base}/actives.js +20 -12
  12. package/src/core/base/history.js +4 -4
  13. package/src/core/class/char.js +10 -10
  14. package/src/core/class/component.js +146 -57
  15. package/src/core/class/format.js +94 -2458
  16. package/src/core/class/html.js +187 -129
  17. package/src/core/class/inline.js +1853 -0
  18. package/src/core/class/listFormat.js +582 -0
  19. package/src/core/class/menu.js +14 -3
  20. package/src/core/class/nodeTransform.js +9 -14
  21. package/src/core/class/offset.js +162 -197
  22. package/src/core/class/selection.js +137 -34
  23. package/src/core/class/toolbar.js +73 -52
  24. package/src/core/class/ui.js +11 -11
  25. package/src/core/class/viewer.js +56 -55
  26. package/src/core/config/context.js +122 -0
  27. package/src/core/config/frameContext.js +204 -0
  28. package/src/core/config/options.js +639 -0
  29. package/src/core/editor.js +181 -108
  30. package/src/core/event/actions/index.js +229 -0
  31. package/src/core/event/effects/common.registry.js +60 -0
  32. package/src/core/event/effects/keydown.registry.js +551 -0
  33. package/src/core/event/effects/ruleHelpers.js +145 -0
  34. package/src/core/{base → event}/eventManager.js +119 -201
  35. package/src/core/event/executor.js +21 -0
  36. package/src/core/{base/eventHandlers → event/handlers}/handler_toolbar.js +4 -4
  37. package/src/core/{base/eventHandlers → event/handlers}/handler_ww_dragDrop.js +2 -2
  38. package/src/core/event/handlers/handler_ww_input.js +77 -0
  39. package/src/core/event/handlers/handler_ww_key.js +228 -0
  40. package/src/core/{base/eventHandlers → event/handlers}/handler_ww_mouse.js +3 -3
  41. package/src/core/event/ports.js +211 -0
  42. package/src/core/event/reducers/keydown.reducer.js +89 -0
  43. package/src/core/event/rules/keydown.rule.arrow.js +54 -0
  44. package/src/core/event/rules/keydown.rule.backspace.js +202 -0
  45. package/src/core/event/rules/keydown.rule.delete.js +126 -0
  46. package/src/core/event/rules/keydown.rule.enter.js +144 -0
  47. package/src/core/event/rules/keydown.rule.tab.js +29 -0
  48. package/src/core/section/constructor.js +79 -388
  49. package/src/core/section/documentType.js +47 -26
  50. package/src/core/util/instanceCheck.js +59 -0
  51. package/src/editorInjector/_classes.js +4 -0
  52. package/src/editorInjector/_core.js +17 -7
  53. package/src/editorInjector/index.js +10 -2
  54. package/src/events.js +6 -0
  55. package/src/helper/clipboard.js +24 -10
  56. package/src/helper/converter.js +17 -12
  57. package/src/helper/dom/domCheck.js +22 -3
  58. package/src/helper/dom/domQuery.js +91 -45
  59. package/src/helper/dom/domUtils.js +93 -19
  60. package/src/helper/dom/index.js +4 -0
  61. package/src/helper/env.js +11 -7
  62. package/src/helper/keyCodeMap.js +4 -3
  63. package/src/langs/ckb.js +1 -1
  64. package/src/langs/cs.js +1 -1
  65. package/src/langs/da.js +1 -1
  66. package/src/langs/de.js +1 -1
  67. package/src/langs/en.js +1 -1
  68. package/src/langs/es.js +1 -1
  69. package/src/langs/fa.js +1 -1
  70. package/src/langs/fr.js +1 -1
  71. package/src/langs/he.js +1 -1
  72. package/src/langs/hu.js +1 -1
  73. package/src/langs/it.js +1 -1
  74. package/src/langs/ja.js +1 -1
  75. package/src/langs/km.js +1 -1
  76. package/src/langs/ko.js +1 -1
  77. package/src/langs/lv.js +1 -1
  78. package/src/langs/nl.js +1 -1
  79. package/src/langs/pl.js +1 -1
  80. package/src/langs/pt_br.js +10 -10
  81. package/src/langs/ro.js +1 -1
  82. package/src/langs/ru.js +1 -1
  83. package/src/langs/se.js +1 -1
  84. package/src/langs/tr.js +1 -1
  85. package/src/langs/uk.js +1 -1
  86. package/src/langs/ur.js +1 -1
  87. package/src/langs/zh_cn.js +1 -1
  88. package/src/modules/ApiManager.js +25 -18
  89. package/src/modules/Browser.js +52 -61
  90. package/src/modules/ColorPicker.js +37 -38
  91. package/src/modules/Controller.js +85 -79
  92. package/src/modules/Figure.js +275 -187
  93. package/src/modules/FileManager.js +86 -92
  94. package/src/modules/HueSlider.js +67 -35
  95. package/src/modules/Modal.js +84 -77
  96. package/src/modules/ModalAnchorEditor.js +62 -79
  97. package/src/modules/SelectMenu.js +89 -86
  98. package/src/plugins/browser/audioGallery.js +9 -5
  99. package/src/plugins/browser/fileBrowser.js +10 -6
  100. package/src/plugins/browser/fileGallery.js +9 -5
  101. package/src/plugins/browser/imageGallery.js +9 -5
  102. package/src/plugins/browser/videoGallery.js +11 -6
  103. package/src/plugins/command/blockquote.js +1 -0
  104. package/src/plugins/command/exportPDF.js +11 -8
  105. package/src/plugins/command/fileUpload.js +41 -29
  106. package/src/plugins/command/list_bulleted.js +2 -1
  107. package/src/plugins/command/list_numbered.js +2 -1
  108. package/src/plugins/dropdown/align.js +8 -2
  109. package/src/plugins/dropdown/backgroundColor.js +19 -11
  110. package/src/plugins/dropdown/font.js +15 -9
  111. package/src/plugins/dropdown/fontColor.js +19 -11
  112. package/src/plugins/dropdown/formatBlock.js +7 -2
  113. package/src/plugins/dropdown/hr.js +7 -3
  114. package/src/plugins/dropdown/layout.js +6 -2
  115. package/src/plugins/dropdown/lineHeight.js +8 -3
  116. package/src/plugins/dropdown/list.js +2 -1
  117. package/src/plugins/dropdown/paragraphStyle.js +15 -11
  118. package/src/plugins/dropdown/{table.js → table/index.js} +514 -362
  119. package/src/plugins/dropdown/template.js +6 -2
  120. package/src/plugins/dropdown/textStyle.js +7 -3
  121. package/src/plugins/field/mention.js +33 -27
  122. package/src/plugins/input/fontSize.js +44 -37
  123. package/src/plugins/input/pageNavigator.js +3 -2
  124. package/src/plugins/modal/audio.js +90 -85
  125. package/src/plugins/modal/drawing.js +58 -66
  126. package/src/plugins/modal/embed.js +193 -180
  127. package/src/plugins/modal/image.js +441 -439
  128. package/src/plugins/modal/link.js +31 -8
  129. package/src/plugins/modal/math.js +23 -22
  130. package/src/plugins/modal/video.js +233 -230
  131. package/src/plugins/popup/anchor.js +24 -18
  132. package/src/suneditor.js +69 -24
  133. package/src/typedef.js +42 -19
  134. package/types/assets/icons/defaultIcons.d.ts +8 -0
  135. package/types/core/class/char.d.ts +1 -1
  136. package/types/core/class/component.d.ts +29 -7
  137. package/types/core/class/format.d.ts +4 -354
  138. package/types/core/class/html.d.ts +13 -4
  139. package/types/core/class/inline.d.ts +263 -0
  140. package/types/core/class/listFormat.d.ts +135 -0
  141. package/types/core/class/menu.d.ts +10 -2
  142. package/types/core/class/offset.d.ts +24 -26
  143. package/types/core/class/selection.d.ts +2 -0
  144. package/types/core/class/toolbar.d.ts +24 -11
  145. package/types/core/class/ui.d.ts +1 -1
  146. package/types/core/class/viewer.d.ts +1 -1
  147. package/types/core/config/context.d.ts +157 -0
  148. package/types/core/config/frameContext.d.ts +367 -0
  149. package/types/core/config/options.d.ts +1119 -0
  150. package/types/core/editor.d.ts +101 -66
  151. package/types/core/event/actions/index.d.ts +47 -0
  152. package/types/core/event/effects/common.registry.d.ts +50 -0
  153. package/types/core/event/effects/keydown.registry.d.ts +73 -0
  154. package/types/core/event/effects/ruleHelpers.d.ts +31 -0
  155. package/types/core/{base → event}/eventManager.d.ts +15 -46
  156. package/types/core/event/executor.d.ts +6 -0
  157. package/types/core/event/handlers/handler_ww_input.d.ts +41 -0
  158. package/types/core/{base/eventHandlers/handler_ww_key_input.d.ts → event/handlers/handler_ww_key.d.ts} +4 -6
  159. package/types/core/event/ports.d.ts +255 -0
  160. package/types/core/event/reducers/keydown.reducer.d.ts +75 -0
  161. package/types/core/event/rules/keydown.rule.arrow.d.ts +8 -0
  162. package/types/core/event/rules/keydown.rule.backspace.d.ts +9 -0
  163. package/types/core/event/rules/keydown.rule.delete.d.ts +9 -0
  164. package/types/core/event/rules/keydown.rule.enter.d.ts +9 -0
  165. package/types/core/event/rules/keydown.rule.tab.d.ts +9 -0
  166. package/types/core/section/constructor.d.ts +101 -631
  167. package/types/core/section/documentType.d.ts +14 -4
  168. package/types/core/util/instanceCheck.d.ts +50 -0
  169. package/types/editorInjector/_classes.d.ts +4 -0
  170. package/types/editorInjector/_core.d.ts +17 -7
  171. package/types/editorInjector/index.d.ts +10 -2
  172. package/types/events.d.ts +1 -0
  173. package/types/helper/clipboard.d.ts +2 -2
  174. package/types/helper/converter.d.ts +6 -9
  175. package/types/helper/dom/domCheck.d.ts +7 -0
  176. package/types/helper/dom/domQuery.d.ts +19 -8
  177. package/types/helper/dom/domUtils.d.ts +24 -2
  178. package/types/helper/dom/index.d.ts +86 -1
  179. package/types/helper/env.d.ts +6 -1
  180. package/types/helper/index.d.ts +7 -1
  181. package/types/helper/keyCodeMap.d.ts +3 -3
  182. package/types/index.d.ts +23 -117
  183. package/types/langs/index.d.ts +2 -2
  184. package/types/modules/ApiManager.d.ts +1 -8
  185. package/types/modules/Browser.d.ts +4 -62
  186. package/types/modules/ColorPicker.d.ts +4 -21
  187. package/types/modules/Controller.d.ts +8 -64
  188. package/types/modules/Figure.d.ts +54 -50
  189. package/types/modules/FileManager.d.ts +1 -13
  190. package/types/modules/HueSlider.d.ts +13 -3
  191. package/types/modules/Modal.d.ts +0 -43
  192. package/types/modules/ModalAnchorEditor.d.ts +0 -73
  193. package/types/modules/SelectMenu.d.ts +0 -85
  194. package/types/modules/index.d.ts +3 -3
  195. package/types/plugins/browser/audioGallery.d.ts +29 -18
  196. package/types/plugins/browser/fileBrowser.d.ts +38 -27
  197. package/types/plugins/browser/fileGallery.d.ts +29 -18
  198. package/types/plugins/browser/imageGallery.d.ts +24 -16
  199. package/types/plugins/browser/videoGallery.d.ts +29 -18
  200. package/types/plugins/command/blockquote.d.ts +1 -0
  201. package/types/plugins/command/exportPDF.d.ts +18 -18
  202. package/types/plugins/command/fileUpload.d.ts +65 -45
  203. package/types/plugins/command/list_bulleted.d.ts +1 -0
  204. package/types/plugins/command/list_numbered.d.ts +1 -0
  205. package/types/plugins/dropdown/align.d.ts +13 -8
  206. package/types/plugins/dropdown/backgroundColor.d.ts +30 -19
  207. package/types/plugins/dropdown/font.d.ts +13 -12
  208. package/types/plugins/dropdown/fontColor.d.ts +30 -19
  209. package/types/plugins/dropdown/formatBlock.d.ts +13 -8
  210. package/types/plugins/dropdown/hr.d.ts +15 -11
  211. package/types/plugins/dropdown/layout.d.ts +15 -11
  212. package/types/plugins/dropdown/lineHeight.d.ts +16 -11
  213. package/types/plugins/dropdown/list.d.ts +1 -0
  214. package/types/plugins/dropdown/paragraphStyle.d.ts +31 -27
  215. package/types/plugins/dropdown/table/index.d.ts +582 -0
  216. package/types/plugins/dropdown/table.d.ts +41 -86
  217. package/types/plugins/dropdown/template.d.ts +15 -11
  218. package/types/plugins/dropdown/textStyle.d.ts +19 -11
  219. package/types/plugins/field/mention.d.ts +58 -56
  220. package/types/plugins/index.d.ts +38 -38
  221. package/types/plugins/input/fontSize.d.ts +46 -50
  222. package/types/plugins/modal/audio.d.ts +26 -56
  223. package/types/plugins/modal/drawing.d.ts +0 -85
  224. package/types/plugins/modal/embed.d.ts +15 -79
  225. package/types/plugins/modal/image.d.ts +24 -136
  226. package/types/plugins/modal/link.d.ts +34 -15
  227. package/types/plugins/modal/math.d.ts +0 -16
  228. package/types/plugins/modal/video.d.ts +17 -86
  229. package/types/plugins/popup/anchor.d.ts +1 -8
  230. package/types/suneditor.d.ts +70 -19
  231. package/types/typedef.d.ts +60 -46
  232. package/src/core/base/eventHandlers/handler_ww_key_input.js +0 -1200
  233. package/src/core/section/context.js +0 -102
  234. package/types/core/section/context.d.ts +0 -45
  235. package/types/langs/_Lang.d.ts +0 -194
  236. /package/src/core/{base/eventHandlers → event/handlers}/handler_ww_clipboard.js +0 -0
  237. /package/types/core/{section → base}/actives.d.ts +0 -0
  238. /package/types/core/{base/eventHandlers → event/handlers}/handler_toolbar.d.ts +0 -0
  239. /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_clipboard.d.ts +0 -0
  240. /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_dragDrop.d.ts +0 -0
  241. /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_mouse.d.ts +0 -0
@@ -130,9 +130,11 @@ DocumentType.prototype = {
130
130
  this._rePageTimeout = _w.setTimeout(async () => {
131
131
  await dom.utils.waitForMediaLoad(this._mirror, 1500);
132
132
 
133
- const mirrorHeight = this._mirror.scrollHeight;
134
- const pageBreaks = this._mirror.querySelectorAll('.se-page-break');
133
+ const heightGap = this.ww.scrollHeight > this._mirror.scrollHeight ? this.ww.scrollHeight - this._mirror.scrollHeight : 0;
134
+ const mirrorHeight = this._mirror.scrollHeight + heightGap;
135
+ const pageBreaks = this.ww.querySelectorAll('.se-page-break');
135
136
  if (!force && this.pageHeight === mirrorHeight && this.pageBreaksCnt === pageBreaks.length) return;
137
+
136
138
  this.pageHeight = mirrorHeight;
137
139
  this.pageBreaksCnt = pageBreaks.length;
138
140
 
@@ -145,18 +147,12 @@ DocumentType.prototype = {
145
147
  for (let i = 0; i < pageBreaks.length; i++) {
146
148
  const breakPosition = pageBreaks[i].offsetTop;
147
149
  const sectionHeight = breakPosition - lastBreakPosition;
148
-
149
- if (sectionHeight % A4_PAGE_HEIGHT !== 0) {
150
- additionalPages++;
151
- }
152
-
150
+ if (sectionHeight % A4_PAGE_HEIGHT !== 0) additionalPages++;
153
151
  lastBreakPosition = breakPosition;
154
152
  }
155
153
 
156
154
  const lastSectionHeight = mirrorHeight - lastBreakPosition;
157
- if (lastSectionHeight > 0 && lastSectionHeight % A4_PAGE_HEIGHT !== 0) {
158
- additionalPages++;
159
- }
155
+ if (lastSectionHeight > 0 && lastSectionHeight % A4_PAGE_HEIGHT !== 0) additionalPages++;
160
156
  }
161
157
 
162
158
  const scrollTop = this.isAutoHeight ? 0 : this._getWWScrollTop();
@@ -165,28 +161,21 @@ DocumentType.prototype = {
165
161
  const pages = [];
166
162
 
167
163
  for (let i = 0; i < pageBreaks.length; i++) {
168
- pages.push({ number: i, top: pageBreaks[i].offsetTop + pageBreakHeight - scrollTop });
164
+ pages.push({ number: i, top: pageBreaks[i].offsetTop + pageBreakHeight / 2 - scrollTop });
169
165
  }
170
166
 
171
- // A4 position
172
167
  this._mirrorCache = 0;
173
168
  const chr = this.ww.children;
174
169
  const mChr = this._mirror.children;
175
170
  this._initializeCache(mChr);
171
+
176
172
  pages.push({ number: 0, top: 0 });
173
+
177
174
  for (let i = 1, t = 0; i < totalPages; i++) {
178
175
  t += A4_PAGE_HEIGHT + (i === 1 ? this._paddingTop + this._paddingBottom : this._paddingTop);
179
- if (!pages.some((p) => Math.abs(p.top - t) < 1)) {
180
- const { ci, cm, ch } = this._getElementAtPosition(t, mChr);
181
- const el = chr[ci];
182
- if (!el) break;
183
-
184
- if (chr[this._mirrorCache]) {
185
- t += numbers.get(_w.getComputedStyle(chr[this._mirrorCache]).marginBottom);
186
- }
187
-
188
- const elBottom = el.offsetTop + el.offsetHeight;
189
- const top = elBottom + cm + (el.offsetHeight - ch);
176
+ if (!pages.some((p) => Math.abs(p.top - t) < 3)) {
177
+ const top = this._calcPageBreakTop(t, chr, mChr);
178
+ if (top === null) break;
190
179
  pages.push({ number: i, top });
191
180
  }
192
181
  }
@@ -202,11 +191,21 @@ DocumentType.prototype = {
202
191
  pages.sort((a, b) => a.top - b.top);
203
192
  this.page.innerHTML = '';
204
193
  this.pages = [];
194
+
205
195
  for (let i = 0, t; i < totalPages; i++) {
206
196
  if (!pages[i]) continue;
207
197
  t = pages[i].top;
208
198
  if (mirrorHeight < t) break;
209
- const pageNumber = dom.utils.createElement('DIV', { style: `top:${t - scrollTop}px`, innerHTML: String(i + 1) }, `<div class="se-document-page-line" style="width: ${wwWidth}px;"></div>${i + 1}`);
199
+
200
+ const pageNumber = dom.utils.createElement(
201
+ 'DIV',
202
+ {
203
+ style: `top:${t - scrollTop}px`,
204
+ innerHTML: String(i + 1)
205
+ },
206
+ `<div class="se-document-page-line" style="width: ${wwWidth}px;"></div>${i + 1}`
207
+ );
208
+
210
209
  this.page.appendChild(pageNumber);
211
210
  this.pages.push(pageNumber);
212
211
  }
@@ -217,6 +216,28 @@ DocumentType.prototype = {
217
216
  }, 400);
218
217
  },
219
218
 
219
+ /**
220
+ * @private
221
+ * @description Calculates and compensates for the vertical gap between the rendered content (current page)
222
+ * - and the mirrored preview page due to differences in width and layout.
223
+ * @param {number} t - The initial top position value to be adjusted.
224
+ * @param {HTMLElement[]} chr - The elements array in the current (main) page.
225
+ * @param {HTMLElement[]} mChr - The elements array in the mirrored page.
226
+ * @returns {number|null} - The adjusted top value.
227
+ */
228
+ _calcPageBreakTop(t, chr, mChr) {
229
+ const { ci } = this._getElementAtPosition(t, mChr);
230
+ const mel = mChr[ci];
231
+ const el = chr[ci];
232
+ if (!mel || !el) return null;
233
+
234
+ const offsetDiff = el.offsetTop - mel.offsetTop;
235
+ const heightDiff = el.offsetHeight - mel.offsetHeight;
236
+
237
+ const top = t + offsetDiff + heightDiff / 2;
238
+ return Math.round(top);
239
+ },
240
+
220
241
  /**
221
242
  * @private
222
243
  * @description Initializes the cache for document elements.
@@ -242,7 +263,7 @@ DocumentType.prototype = {
242
263
  * @private
243
264
  * @description Retrieves the element at a given position.
244
265
  * @param {number} pageTop - The vertical position to check.
245
- * @param {NodeList} mChr - List of mirrored elements.
266
+ * @param {HTMLElement[]} mChr - List of mirrored elements.
246
267
  * @returns {{ci: number, cm: number, ch: number}} The closest element and its related data.
247
268
  * - ci: The index of the closest element.
248
269
  * - cm: The distance between the top of the closest element and the given position.
@@ -441,7 +462,7 @@ DocumentType.prototype = {
441
462
  const scrollTop = i === 0 && !this.isAutoHeight ? 0 : c.offsetTop - this.page.offsetTop - c.offsetHeight + globalTop;
442
463
  this._applyPageScroll(scrollTop, () => {
443
464
  if (this.editor.toolbar._sticky) {
444
- this.displayPage.scrollTo({ top: scrollTop - this.context.get('toolbar.main').offsetHeight, behavior: 'smooth' });
465
+ this.displayPage.scrollTo({ top: scrollTop - this.context.get('toolbar_main').offsetHeight, behavior: 'smooth' });
445
466
  }
446
467
  });
447
468
 
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @typedef {InstanceCheck} InstanceCheckThis
3
+ */
4
+
5
+ /**
6
+ * @constructor
7
+ * @this {InstanceCheck}
8
+ * @description iframe-safe instanceof check utility class
9
+ * @param {__se__EditorCore} editor - The root editor instance
10
+ */
11
+ function InstanceCheck(editor) {
12
+ this.editor = editor;
13
+ }
14
+
15
+ InstanceCheck.prototype = {
16
+ /**
17
+ * @param {*} obj
18
+ * @returns {obj is Node}
19
+ */
20
+ isNode(obj) {
21
+ return obj instanceof this._getFrameWindow().Node;
22
+ },
23
+
24
+ /**
25
+ * @param {*} obj
26
+ * @returns {obj is Element}
27
+ */
28
+ isElement(obj) {
29
+ return obj instanceof this._getFrameWindow().Element;
30
+ },
31
+
32
+ /**
33
+ * @param {*} obj
34
+ * @returns {obj is Range}
35
+ */
36
+ isRange(obj) {
37
+ return obj instanceof this._getFrameWindow().Range;
38
+ },
39
+
40
+ /**
41
+ * @param {*} obj
42
+ * @returns {obj is Selection}
43
+ */
44
+ isSelection(obj) {
45
+ return obj instanceof this._getFrameWindow().Selection;
46
+ },
47
+
48
+ /**
49
+ * @private
50
+ * @returns {window}
51
+ */
52
+ _getFrameWindow() {
53
+ return this.editor.frameContext.get('_ww');
54
+ },
55
+
56
+ constructor: InstanceCheck
57
+ };
58
+
59
+ export default InstanceCheck;
@@ -17,6 +17,10 @@ function ClassInjector(editor) {
17
17
  this.format = editor.format;
18
18
  /** @description HTML class instance @type {__se__EditorCore['html']} */
19
19
  this.html = editor.html;
20
+ /** @description Inline format class instance @type {__se__EditorCore['inline']} */
21
+ this.inline = editor.inline;
22
+ /** @description List format class instance @type {__se__EditorCore['listFormat']} */
23
+ this.listFormat = editor.listFormat;
20
24
  /** @description Menu class instance @type {__se__EditorCore['menu']} */
21
25
  this.menu = editor.menu;
22
26
  /** @description NodeTransform class instance @type {__se__EditorCore['nodeTransform']} */
@@ -15,6 +15,11 @@ export default function CoreInjector(editor) {
15
15
  * @type {__se__EditorCore['eventManager']}
16
16
  */
17
17
  this.eventManager = editor.eventManager;
18
+ /**
19
+ * @description The util/instanceCheck instance.
20
+ * @type {__se__EditorCore['instanceCheck']}
21
+ */
22
+ this.instanceCheck = editor.instanceCheck;
18
23
  /**
19
24
  * @description The history manager instance.
20
25
  * @type {__se__EditorCore['history']}
@@ -48,12 +53,22 @@ export default function CoreInjector(editor) {
48
53
  */
49
54
  this.status = editor.status;
50
55
  /**
51
- * @description The editor's context map.
56
+ * @description The editor's [frame] context utility object.
57
+ * @type {__se__EditorCore['frameContext']}
58
+ */
59
+ this.frameContext = editor.frameContext;
60
+ /**
61
+ * @description The editor's [frame] options utility object.
62
+ * @type {__se__EditorCore['frameOptions']}
63
+ */
64
+ this.frameOptions = editor.frameOptions;
65
+ /**
66
+ * @description The editor's context utility object.
52
67
  * @type {__se__EditorCore['context']}
53
68
  */
54
69
  this.context = editor.context;
55
70
  /**
56
- * @description The editor's options map.
71
+ * @description The editor's options utility object.
57
72
  * @type {__se__EditorCore['options']}
58
73
  */
59
74
  this.options = editor.options;
@@ -84,9 +99,4 @@ export default function CoreInjector(editor) {
84
99
  * @type {Document}
85
100
  */
86
101
  this._d = editor._d;
87
- /**
88
- * @description The shadow root object (if any).
89
- * @type {__se__EditorCore['_shadowRoot']}
90
- */
91
- this._shadowRoot = editor._shadowRoot;
92
102
  }
@@ -11,6 +11,8 @@ function EditorInjector(editor) {
11
11
  this.editor;
12
12
  /** @type {import('./_core').default['eventManager']} */
13
13
  this.eventManager;
14
+ /** @type {import('./_core').default['instanceCheck']} */
15
+ this.instanceCheck;
14
16
  /** @type {import('./_core').default['history']} */
15
17
  this.history;
16
18
  /** @type {import('./_core').default['events']} */
@@ -23,6 +25,10 @@ function EditorInjector(editor) {
23
25
  this.plugins;
24
26
  /** @type {import('./_core').default['status']} */
25
27
  this.status;
28
+ /** @type {import('./_core').default['frameContext']} */
29
+ this.frameContext = editor.frameContext;
30
+ /** @type {import('./_core').default['frameOptions']} */
31
+ this.frameOptions = editor.frameOptions;
26
32
  /** @type {import('./_core').default['context']} */
27
33
  this.context;
28
34
  /** @type {import('./_core').default['options']} */
@@ -37,8 +43,6 @@ function EditorInjector(editor) {
37
43
  this._w;
38
44
  /** @type {import('./_core').default['_d']} */
39
45
  this._d;
40
- /** @type {import('./_core').default['_shadowRoot']} */
41
- this._shadowRoot;
42
46
 
43
47
  // ClassInjector props
44
48
  /** @type {import('./_classes').default['toolbar']} */
@@ -53,6 +57,10 @@ function EditorInjector(editor) {
53
57
  this.format;
54
58
  /** @type {import('./_classes').default['html']} */
55
59
  this.html;
60
+ /** @type {import('./_classes').default['inline']} */
61
+ this.inline;
62
+ /** @type {import('./_classes').default['listFormat']} */
63
+ this.listFormat;
56
64
  /** @type {import('./_classes').default['menu']} */
57
65
  this.menu;
58
66
  /** @type {import('./_classes').default['nodeTransform']} */
package/src/events.js CHANGED
@@ -131,6 +131,12 @@ export default {
131
131
  */
132
132
  onClick: null,
133
133
 
134
+ /**
135
+ * @description Event call back function
136
+ * @param {BaseEvent} params
137
+ */
138
+ onBeforeInput: null,
139
+
134
140
  /**
135
141
  * @description Event call back function
136
142
  * @param {BaseEvent} params
@@ -9,12 +9,12 @@ import { isElement } from './dom/domCheck';
9
9
  * - Iframe is replaced with a placeholder : <div data-se-iframe-holder-src="iframe.src">[iframe: iframe.src]</div>
10
10
  * - "iframe placeholder" is re-rendered in html.clean when pasted into the editor.
11
11
  * @param {Element|Text|string} content Content to be copied to the clipboard
12
- * @returns {Promise<void>}
12
+ * @returns {Promise<void|false>} If it fails, it returns false.
13
13
  */
14
14
  export async function write(content) {
15
15
  if (!isClipboardSupported) {
16
16
  console.error('Clipboard is not supported in this browser.');
17
- return;
17
+ return false;
18
18
  }
19
19
 
20
20
  let htmlString = '';
@@ -44,14 +44,28 @@ export async function write(content) {
44
44
  plainText = content.textContent;
45
45
  }
46
46
 
47
- /* eslint-disable-next-line compat/compat */
48
- await navigator.clipboard.write([
49
- /* eslint-disable-next-line compat/compat */
50
- new ClipboardItem({
51
- 'text/html': new Blob([htmlString], { type: 'text/html' }),
52
- 'text/plain': new Blob([plainText], { type: 'text/plain' })
53
- })
54
- ]);
47
+ try {
48
+ await navigator.clipboard.write([
49
+ /* eslint-disable-next-line compat/compat */
50
+ new ClipboardItem({
51
+ 'text/html': new Blob([htmlString], { type: 'text/html' }),
52
+ 'text/plain': new Blob([plainText], { type: 'text/plain' })
53
+ })
54
+ ]);
55
+ } catch {
56
+ console.warn('[SUNEDITOR.copy.warn] This browser is not supported Clipboard API');
57
+ try {
58
+ await navigator.clipboard.writeText(plainText || stripHtml(htmlString));
59
+ } catch (err) {
60
+ console.error('[SUNEDITOR.copy.fail] ' + err);
61
+ }
62
+ }
63
+ }
64
+
65
+ function stripHtml(html) {
66
+ const div = document.createElement('div');
67
+ div.innerHTML = html;
68
+ return div.textContent || div.innerText || '';
55
69
  }
56
70
 
57
71
  export default {
@@ -1,15 +1,14 @@
1
1
  import { _d, _w } from './env';
2
2
 
3
- const URLPattern = /https?:\/\/[^\s]+/g;
4
3
  const FONT_VALUES_MAP = {
5
- 'xx-small': 1,
6
- 'x-small': 2,
7
- small: 3,
8
- medium: 4,
9
- large: 5,
10
- 'x-large': 6,
11
- 'xx-large': 7,
12
- 'xxx-large': 8
4
+ 'xx-small': 0.5625,
5
+ 'x-small': 0.625,
6
+ small: 0.8333,
7
+ medium: 1,
8
+ large: 1.125,
9
+ 'x-large': 1.5,
10
+ 'xx-large': 2,
11
+ 'xxx-large': 2.5
13
12
  };
14
13
 
15
14
  function NodeToJson(node) {
@@ -200,7 +199,7 @@ export function getValues(obj) {
200
199
  ? []
201
200
  : Object.keys(obj).map(function (i) {
202
201
  return obj[i];
203
- });
202
+ });
204
203
  }
205
204
 
206
205
  /**
@@ -350,7 +349,7 @@ export function rgb2hex(rgba) {
350
349
 
351
350
  return `#${r}${g}${b}${a}`;
352
351
  } else {
353
- return '';
352
+ return rgba;
354
353
  }
355
354
  }
356
355
 
@@ -377,6 +376,8 @@ export function getWidthInPercentage(target, parentTarget) {
377
376
  * @returns {boolean} Return true if the text node is converted to an anchor node
378
377
  */
379
378
  export function textToAnchor(node) {
379
+ const URLPattern = /https?:\/\/[^\s]+/g;
380
+
380
381
  if (node.nodeType === 3 && URLPattern.test(node.textContent) && !/^A$/i.test(node.parentNode?.nodeName)) {
381
382
  const textContent = node.textContent;
382
383
  const fragment = _d.createDocumentFragment();
@@ -468,11 +469,15 @@ export function addUrlQuery(url, query) {
468
469
  return url;
469
470
  }
470
471
 
472
+ /**
473
+ * @typedef {import('../core/config/options').OptionStyleResult} OptionStyleResult_converter
474
+ */
475
+
471
476
  /**
472
477
  * @description Converts options-related styles and returns them for each frame.
473
478
  * @param {Map<string, *>} fo editor.frameOptions
474
479
  * @param {string} cssText Style string
475
- * @returns {{top: string, frame: string, editor: string}}
480
+ * @returns {OptionStyleResult_converter}
476
481
  * @private
477
482
  */
478
483
  export function _setDefaultOptionStyle(fo, cssText) {
@@ -12,7 +12,16 @@ import domUtils from './domUtils';
12
12
  */
13
13
  export function isZeroWidth(text) {
14
14
  if (text === null || text === undefined) return false;
15
- if (typeof text !== 'string') text = text.textContent;
15
+ if (typeof text !== 'string') {
16
+ if (isElement(text)) {
17
+ const children = text.children;
18
+ for (let i = 0, len = children.length; i < len; i++) {
19
+ const child = children[i];
20
+ if (!isContentLess(child)) return false;
21
+ }
22
+ }
23
+ text = text.textContent;
24
+ }
16
25
  return text === '' || onlyZeroWidthRegExp.test(text);
17
26
  }
18
27
 
@@ -24,7 +33,7 @@ export function isZeroWidth(text) {
24
33
  * @returns {boolean}
25
34
  */
26
35
  export function isEdgePoint(container, offset, dir) {
27
- return (dir !== 'end' && offset === 0) || ((!dir || dir !== 'front') && !container.nodeValue && offset === 1) || ((!dir || dir === 'end') && container.nodeValue && offset >= container.nodeValue.length);
36
+ return (dir !== 'end' && offset === 0) || ((!dir || dir !== 'front') && !container.nodeValue && offset <= 1) || ((!dir || dir === 'end') && container.nodeValue && offset >= container.nodeValue.length);
28
37
  }
29
38
 
30
39
  /**
@@ -182,6 +191,15 @@ export function isEmptyLine(node) {
182
191
  return !el.querySelector('IMG, IFRAME, AUDIO, VIDEO, CANVAS, TABLE') && (el.children.length <= 1 || isBreak(el.firstElementChild)) && isZeroWidth(el.textContent);
183
192
  }
184
193
 
194
+ /**
195
+ * @description Checks if the given node is a container component (class "se-component-container").
196
+ * @param {Node} element
197
+ * @returns {boolean} True if the node is a container component, otherwise false.
198
+ */
199
+ export function isComponentContainer(element) {
200
+ return domUtils.hasClass(element, 'se-component|se-flex-component');
201
+ }
202
+
185
203
  /**
186
204
  * @description It is judged whether it is the edit region top div element or iframe's body tag.
187
205
  * @param {?Node} node The node to check
@@ -208,7 +226,7 @@ export function isNonEditable(node) {
208
226
  export function isSpanWithoutAttr(node) {
209
227
  if (node?.nodeType !== 1) return false;
210
228
  const el = /** @type {HTMLElement} */ (node);
211
- return /^SPAN$/i.test(el.nodeName) && !el.className && !el.style.cssText;
229
+ return /^SPAN$/i.test(el.nodeName) && !el.className && el.style.length === 0;
212
230
  }
213
231
 
214
232
  /**
@@ -292,6 +310,7 @@ const check = {
292
310
  isFigure,
293
311
  isContentLess,
294
312
  isEmptyLine,
313
+ isComponentContainer,
295
314
  isWysiwygFrame,
296
315
  isNonEditable,
297
316
  isSpanWithoutAttr,