suneditor 3.1.3 → 3.2.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 (219) hide show
  1. package/dist/suneditor-contents.min.css +1 -1
  2. package/dist/suneditor.min.css +28 -1
  3. package/dist/suneditor.min.js +1 -1
  4. package/package.json +2 -1
  5. package/src/assets/design/color.css +12 -0
  6. package/src/assets/design/size.css +9 -2
  7. package/src/assets/icons/defaultIcons.js +96 -47
  8. package/src/assets/suneditor-contents.css +3 -2
  9. package/src/assets/suneditor.css +480 -31
  10. package/src/core/config/contextProvider.js +2 -1
  11. package/src/core/config/eventManager.js +41 -2
  12. package/src/core/config/optionProvider.js +23 -2
  13. package/src/core/editor.js +32 -14
  14. package/src/core/event/actions/index.js +76 -9
  15. package/src/core/event/effects/common.registry.js +2 -1
  16. package/src/core/event/effects/keydown.registry.js +169 -33
  17. package/src/core/event/effects/ruleHelpers.js +20 -6
  18. package/src/core/event/eventOrchestrator.js +136 -23
  19. package/src/core/event/handlers/handler_toolbar.js +4 -2
  20. package/src/core/event/handlers/handler_ww_dragDrop.js +10 -0
  21. package/src/core/event/handlers/handler_ww_input.js +9 -2
  22. package/src/core/event/handlers/handler_ww_key.js +86 -17
  23. package/src/core/event/handlers/handler_ww_mouse.js +45 -8
  24. package/src/core/event/ports.js +23 -5
  25. package/src/core/event/reducers/keydown.reducer.js +15 -2
  26. package/src/core/event/rules/keydown.rule.arrow.js +12 -2
  27. package/src/core/event/rules/keydown.rule.backspace.js +110 -15
  28. package/src/core/event/rules/keydown.rule.delete.js +62 -7
  29. package/src/core/event/rules/keydown.rule.enter.js +62 -31
  30. package/src/core/event/support/defaultLineManager.js +9 -2
  31. package/src/core/event/support/selectionState.js +13 -3
  32. package/src/core/kernel/coreKernel.js +1 -0
  33. package/src/core/logic/dom/char.js +13 -3
  34. package/src/core/logic/dom/format.js +171 -39
  35. package/src/core/logic/dom/html.js +357 -87
  36. package/src/core/logic/dom/inline.js +229 -34
  37. package/src/core/logic/dom/listFormat.js +111 -20
  38. package/src/core/logic/dom/nodeTransform.js +36 -11
  39. package/src/core/logic/dom/offset.js +116 -31
  40. package/src/core/logic/dom/selection.js +147 -29
  41. package/src/core/logic/panel/blockHandle.js +785 -0
  42. package/src/core/logic/panel/blockResolver.js +278 -0
  43. package/src/core/logic/panel/finder.js +16 -6
  44. package/src/core/logic/panel/menu.js +119 -18
  45. package/src/core/logic/panel/toolbar.js +75 -19
  46. package/src/core/logic/panel/viewer.js +76 -20
  47. package/src/core/logic/shell/_commandExecutor.js +44 -9
  48. package/src/core/logic/shell/commandDispatcher.js +46 -4
  49. package/src/core/logic/shell/component.js +102 -25
  50. package/src/core/logic/shell/focusManager.js +13 -3
  51. package/src/core/logic/shell/history.js +21 -6
  52. package/src/core/logic/shell/pluginManager.js +21 -13
  53. package/src/core/logic/shell/shortcuts.js +9 -1
  54. package/src/core/logic/shell/ui.js +139 -37
  55. package/src/core/schema/frameContext.js +34 -3
  56. package/src/core/schema/options.js +61 -19
  57. package/src/core/section/constructor.js +537 -103
  58. package/src/core/section/documentType.js +35 -6
  59. package/src/helper/converter.js +24 -7
  60. package/src/helper/dom/domCheck.js +25 -5
  61. package/src/helper/dom/domQuery.js +2 -1
  62. package/src/helper/dom/domUtils.js +17 -4
  63. package/src/helper/env.js +11 -2
  64. package/src/helper/keyCodeMap.js +6 -2
  65. package/src/helper/markdown.js +24 -5
  66. package/src/helper/msOffice.js +9 -2
  67. package/src/interfaces/plugins.js +1 -1
  68. package/src/langs/ckb.js +0 -1
  69. package/src/langs/cs.js +0 -1
  70. package/src/langs/da.js +0 -1
  71. package/src/langs/de.js +0 -1
  72. package/src/langs/en.js +0 -1
  73. package/src/langs/es.js +0 -1
  74. package/src/langs/fa.js +0 -1
  75. package/src/langs/fr.js +0 -1
  76. package/src/langs/he.js +0 -1
  77. package/src/langs/hu.js +0 -1
  78. package/src/langs/index.js +27 -1
  79. package/src/langs/it.js +0 -1
  80. package/src/langs/ja.js +0 -1
  81. package/src/langs/km.js +0 -1
  82. package/src/langs/ko.js +0 -1
  83. package/src/langs/lv.js +0 -1
  84. package/src/langs/nl.js +0 -1
  85. package/src/langs/pl.js +0 -1
  86. package/src/langs/pt_br.js +0 -1
  87. package/src/langs/ro.js +0 -1
  88. package/src/langs/ru.js +0 -1
  89. package/src/langs/se.js +0 -1
  90. package/src/langs/tr.js +0 -1
  91. package/src/langs/uk.js +0 -1
  92. package/src/langs/ur.js +0 -1
  93. package/src/langs/zh_cn.js +0 -1
  94. package/src/modules/contract/Browser.js +68 -23
  95. package/src/modules/contract/ColorPicker.js +12 -4
  96. package/src/modules/contract/Controller.js +37 -7
  97. package/src/modules/contract/Figure.js +159 -36
  98. package/src/modules/contract/HueSlider.js +27 -4
  99. package/src/modules/contract/Modal.js +62 -11
  100. package/src/modules/manager/FileManager.js +50 -8
  101. package/src/modules/ui/CommandMenu.js +597 -0
  102. package/src/modules/ui/ModalAnchorEditor.js +41 -9
  103. package/src/modules/ui/SelectMenu.js +481 -36
  104. package/src/modules/ui/index.js +1 -0
  105. package/src/plugins/browser/audioGallery.js +8 -1
  106. package/src/plugins/browser/fileBrowser.js +15 -2
  107. package/src/plugins/browser/fileGallery.js +8 -1
  108. package/src/plugins/browser/imageGallery.js +24 -3
  109. package/src/plugins/browser/videoGallery.js +19 -4
  110. package/src/plugins/command/blockquote.js +6 -1
  111. package/src/plugins/command/codeBlock.js +43 -5
  112. package/src/plugins/command/exportPDF.js +20 -4
  113. package/src/plugins/command/fileUpload.js +46 -11
  114. package/src/plugins/command/list_bulleted.js +6 -1
  115. package/src/plugins/command/list_numbered.js +6 -1
  116. package/src/plugins/dropdown/align.js +21 -33
  117. package/src/plugins/dropdown/backgroundColor.js +10 -2
  118. package/src/plugins/dropdown/blockStyle.js +17 -22
  119. package/src/plugins/dropdown/font.js +34 -34
  120. package/src/plugins/dropdown/hr.js +15 -43
  121. package/src/plugins/dropdown/layout.js +10 -27
  122. package/src/plugins/dropdown/lineHeight.js +10 -33
  123. package/src/plugins/dropdown/list.js +19 -25
  124. package/src/plugins/dropdown/paragraphStyle.js +16 -24
  125. package/src/plugins/dropdown/table/index.js +72 -17
  126. package/src/plugins/dropdown/table/render/table.html.js +3 -1
  127. package/src/plugins/dropdown/table/services/table.cell.js +33 -7
  128. package/src/plugins/dropdown/table/services/table.clipboard.js +5 -1
  129. package/src/plugins/dropdown/table/services/table.grid.js +40 -9
  130. package/src/plugins/dropdown/table/services/table.resize.js +55 -11
  131. package/src/plugins/dropdown/table/services/table.selection.js +27 -7
  132. package/src/plugins/dropdown/table/services/table.style.js +120 -20
  133. package/src/plugins/dropdown/template.js +13 -29
  134. package/src/plugins/dropdown/textStyle.js +22 -35
  135. package/src/plugins/field/autocomplete.js +8 -4
  136. package/src/plugins/field/slashCommand.js +297 -0
  137. package/src/plugins/index.js +3 -0
  138. package/src/plugins/input/fontSize.js +37 -8
  139. package/src/plugins/input/pageNavigator.js +7 -1
  140. package/src/plugins/modal/audio.js +71 -17
  141. package/src/plugins/modal/drawing.js +41 -11
  142. package/src/plugins/modal/embed.js +132 -22
  143. package/src/plugins/modal/image/index.js +115 -28
  144. package/src/plugins/modal/image/services/image.size.js +9 -2
  145. package/src/plugins/modal/image/services/image.upload.js +38 -4
  146. package/src/plugins/modal/link.js +9 -2
  147. package/src/plugins/modal/math.js +10 -2
  148. package/src/plugins/modal/video/index.js +112 -26
  149. package/src/plugins/modal/video/render/video.html.js +4 -1
  150. package/src/plugins/modal/video/services/video.size.js +15 -4
  151. package/src/plugins/modal/video/services/video.upload.js +10 -2
  152. package/src/plugins/popup/anchor.js +14 -2
  153. package/src/suneditor.js +8 -2
  154. package/src/themes/cobalt.css +12 -0
  155. package/src/themes/cream.css +12 -0
  156. package/src/themes/dark.css +12 -0
  157. package/src/themes/midnight.css +12 -0
  158. package/src/typedef.js +32 -21
  159. package/types/assets/icons/defaultIcons.d.ts +1 -0
  160. package/types/core/config/contextProvider.d.ts +7 -1
  161. package/types/core/config/eventManager.d.ts +37 -4
  162. package/types/core/config/optionProvider.d.ts +5 -1
  163. package/types/core/event/actions/index.d.ts +44 -6
  164. package/types/core/event/effects/keydown.registry.d.ts +37 -7
  165. package/types/core/event/effects/ruleHelpers.d.ts +6 -1
  166. package/types/core/event/eventOrchestrator.d.ts +6 -1
  167. package/types/core/event/handlers/handler_ww_clipboard.d.ts +15 -3
  168. package/types/core/event/handlers/handler_ww_dragDrop.d.ts +14 -2
  169. package/types/core/event/handlers/handler_ww_input.d.ts +10 -2
  170. package/types/core/event/handlers/handler_ww_key.d.ts +10 -2
  171. package/types/core/event/handlers/handler_ww_mouse.d.ts +25 -5
  172. package/types/core/event/ports.d.ts +7 -2
  173. package/types/core/event/rules/keydown.rule.backspace.d.ts +6 -1
  174. package/types/core/kernel/store.d.ts +4 -1
  175. package/types/core/logic/dom/format.d.ts +32 -14
  176. package/types/core/logic/dom/html.d.ts +11 -3
  177. package/types/core/logic/dom/nodeTransform.d.ts +6 -6
  178. package/types/core/logic/panel/blockHandle.d.ts +64 -0
  179. package/types/core/logic/panel/blockResolver.d.ts +50 -0
  180. package/types/core/logic/panel/menu.d.ts +72 -3
  181. package/types/core/logic/shell/commandDispatcher.d.ts +8 -0
  182. package/types/core/logic/shell/component.d.ts +5 -3
  183. package/types/core/logic/shell/shortcuts.d.ts +10 -1
  184. package/types/core/logic/shell/ui.d.ts +7 -1
  185. package/types/core/schema/context.d.ts +7 -1
  186. package/types/core/schema/frameContext.d.ts +36 -4
  187. package/types/core/schema/options.d.ts +110 -37
  188. package/types/core/section/constructor.d.ts +38 -1
  189. package/types/events.d.ts +208 -32
  190. package/types/helper/converter.d.ts +4 -2
  191. package/types/helper/dom/domCheck.d.ts +12 -2
  192. package/types/helper/dom/domQuery.d.ts +35 -7
  193. package/types/helper/dom/domUtils.d.ts +4 -1
  194. package/types/interfaces/plugins.d.ts +2 -2
  195. package/types/langs/_Lang.d.ts +0 -1
  196. package/types/modules/contract/Browser.d.ts +7 -7
  197. package/types/modules/contract/ColorPicker.d.ts +2 -2
  198. package/types/modules/contract/Controller.d.ts +7 -0
  199. package/types/modules/contract/Figure.d.ts +31 -4
  200. package/types/modules/ui/CommandMenu.d.ts +262 -0
  201. package/types/modules/ui/ModalAnchorEditor.d.ts +6 -1
  202. package/types/modules/ui/SelectMenu.d.ts +56 -3
  203. package/types/modules/ui/index.d.ts +1 -0
  204. package/types/plugins/browser/audioGallery.d.ts +17 -1
  205. package/types/plugins/browser/fileBrowser.d.ts +17 -1
  206. package/types/plugins/browser/fileGallery.d.ts +17 -1
  207. package/types/plugins/browser/imageGallery.d.ts +17 -1
  208. package/types/plugins/browser/videoGallery.d.ts +17 -1
  209. package/types/plugins/dropdown/align.d.ts +1 -1
  210. package/types/plugins/dropdown/blockStyle.d.ts +3 -1
  211. package/types/plugins/dropdown/table/index.d.ts +4 -1
  212. package/types/plugins/dropdown/table/services/table.clipboard.d.ts +5 -1
  213. package/types/plugins/dropdown/table/services/table.grid.d.ts +10 -2
  214. package/types/plugins/field/autocomplete.d.ts +0 -1
  215. package/types/plugins/field/slashCommand.d.ts +165 -0
  216. package/types/plugins/index.d.ts +3 -0
  217. package/types/plugins/modal/embed.d.ts +34 -0
  218. package/types/plugins/modal/link.d.ts +4 -1
  219. package/types/typedef.d.ts +48 -23
@@ -44,7 +44,9 @@ function Constructor(editorTargets, options) {
44
44
  if (options.plugins) {
45
45
  const excludedPlugins = options.excludedPlugins || [];
46
46
  const originPlugins = options.plugins;
47
- const pluginsValues = (Array.isArray(originPlugins) ? originPlugins : Object.keys(originPlugins)).filter((name) => !excludedPlugins.includes(name)).map((name) => originPlugins[name]);
47
+ const pluginsValues = (Array.isArray(originPlugins) ? originPlugins : Object.keys(originPlugins))
48
+ .filter((name) => !excludedPlugins.includes(name))
49
+ .map((name) => originPlugins[name]);
48
50
 
49
51
  for (let i = 0, len = pluginsValues.length, p; i < len; i++) {
50
52
  p = pluginsValues[i].default || pluginsValues[i];
@@ -57,11 +59,20 @@ function Constructor(editorTargets, options) {
57
59
  const o = optionMap.o;
58
60
  const icons = optionMap.i;
59
61
  const lang = optionMap.l;
60
- const loadingBox = dom.utils.createElement('DIV', { class: 'se-loading-box sun-editor-common' }, '<div class="se-loading-effect"></div>');
62
+ const loadingBox = dom.utils.createElement(
63
+ 'DIV',
64
+ { class: 'se-loading-box sun-editor-common' },
65
+ '<div class="se-loading-effect"></div>',
66
+ );
61
67
  const editorFormFieldPrefix = 'suneditor-' + ++editorInstanceId;
62
68
 
63
69
  /** --- carrier wrapper --------------------------------------------------------------- */
64
- const editor_carrier_wrapper = dom.utils.createElement('DIV', { class: 'sun-editor sun-editor-carrier-wrapper sun-editor-common' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : '') });
70
+ const editor_carrier_wrapper = dom.utils.createElement('DIV', {
71
+ class:
72
+ 'sun-editor sun-editor-carrier-wrapper sun-editor-common' +
73
+ o.get('_themeClass') +
74
+ (o.get('_rtl') ? ' se-rtl' : ''),
75
+ });
65
76
  // menuTray
66
77
  const menuTray = dom.utils.createElement('DIV', { class: 'se-menu-tray', popover: 'manual' });
67
78
  editor_carrier_wrapper.appendChild(menuTray);
@@ -80,7 +91,10 @@ function Constructor(editorTargets, options) {
80
91
  editor_carrier_wrapper.appendChild(focusTemp);
81
92
 
82
93
  // modal
83
- const modal = dom.utils.createElement('DIV', { class: 'se-modal se-modal-area sun-editor-common', popover: 'manual' });
94
+ const modal = dom.utils.createElement('DIV', {
95
+ class: 'se-modal se-modal-area sun-editor-common',
96
+ popover: 'manual',
97
+ });
84
98
  const modal_back = dom.utils.createElement('DIV', { class: 'se-modal-back' });
85
99
  const modal_inner = dom.utils.createElement('DIV', { class: 'se-modal-inner' });
86
100
  modal.appendChild(modal_back);
@@ -88,7 +102,11 @@ function Constructor(editorTargets, options) {
88
102
  editor_carrier_wrapper.appendChild(modal);
89
103
 
90
104
  // alert
91
- const alert = dom.utils.createElement('DIV', { class: 'se-alert se-modal-area sun-editor-common', style: 'display: none;', popover: 'manual' });
105
+ const alert = dom.utils.createElement('DIV', {
106
+ class: 'se-alert se-modal-area sun-editor-common',
107
+ style: 'display: none;',
108
+ popover: 'manual',
109
+ });
92
110
  const alert_back = dom.utils.createElement('DIV', { class: 'se-modal-back' });
93
111
  const alert_inner = dom.utils.createElement('DIV', { class: 'se-modal-inner' });
94
112
  alert.appendChild(alert_back);
@@ -147,9 +165,22 @@ function Constructor(editorTargets, options) {
147
165
  for (let i = 0, len = editorTargets.length; i < len; i++) {
148
166
  const editTarget = editorTargets[i];
149
167
  const to = optionMap.frameMap.get(editTarget.key);
150
- const top_div = dom.utils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : '') });
168
+ const top_div = dom.utils.createElement('DIV', {
169
+ class: 'sun-editor' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : ''),
170
+ });
151
171
  const container = dom.utils.createElement('DIV', { class: 'se-container' });
152
- const editor_div = dom.utils.createElement('DIV', { class: 'se-wrapper' + (o.get('type') === 'document' ? ' se-type-document' : '') + (o.get('_type_options').includes('header') ? ' se-type-document-header' : '') });
172
+ const isBlockHandle = !!o.get('blockHandle');
173
+ const editor_div = dom.utils.createElement('DIV', {
174
+ class:
175
+ 'se-wrapper' +
176
+ (isBlockHandle ? ' se-mode-block' : '') +
177
+ (o.get('type') === 'document' ? ' se-type-document' : '') +
178
+ (o.get('_type_options').includes('header') ? ' se-type-document-header' : ''),
179
+ });
180
+
181
+ const editorInnerW = to.get('innerWidth');
182
+ if (editorInnerW && editorInnerW !== 'auto')
183
+ editor_div.style.setProperty('--se-editor-inner-width', editorInnerW);
153
184
 
154
185
  container.appendChild(dom.utils.createElement('DIV', { class: 'se-toolbar-shadow' }));
155
186
 
@@ -162,8 +193,16 @@ function Constructor(editorTargets, options) {
162
193
  let textarea = initElements.codeView;
163
194
 
164
195
  // line breaker
165
- const line_breaker_t = dom.utils.createElement('DIV', { class: 'se-line-breaker-component se-line-breaker-component-t', title: lang.insertLine }, icons.line_break);
166
- const line_breaker_b = dom.utils.createElement('DIV', { class: 'se-line-breaker-component se-line-breaker-component-b', title: lang.insertLine }, icons.line_break);
196
+ const line_breaker_t = dom.utils.createElement(
197
+ 'DIV',
198
+ { class: 'se-line-breaker-component se-line-breaker-component-t', title: lang.insertLine },
199
+ icons.line_break,
200
+ );
201
+ const line_breaker_b = dom.utils.createElement(
202
+ 'DIV',
203
+ { class: 'se-line-breaker-component se-line-breaker-component-b', title: lang.insertLine },
204
+ icons.line_break,
205
+ );
167
206
 
168
207
  editor_div.appendChild(line_breaker_t);
169
208
  editor_div.appendChild(line_breaker_b);
@@ -177,7 +216,9 @@ function Constructor(editorTargets, options) {
177
216
  if (statusbar) {
178
217
  if (statusbarContainer) {
179
218
  if (!default_status_bar) {
180
- statusbarContainer.appendChild(dom.utils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') }, statusbar));
219
+ statusbarContainer.appendChild(
220
+ dom.utils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') }, statusbar),
221
+ );
181
222
  default_status_bar = statusbar;
182
223
  }
183
224
  } else {
@@ -205,7 +246,14 @@ function Constructor(editorTargets, options) {
205
246
  // add line nubers
206
247
  const codeNumbers = dom.utils.createElement(
207
248
  'TEXTAREA',
208
- { id: editorFormFieldPrefix + '-code-view-line-' + (key || 'default'), class: 'se-code-view-line', readonly: 'true', autocomplete: 'off', 'aria-hidden': 'true', tabindex: '-1' },
249
+ {
250
+ id: editorFormFieldPrefix + '-code-view-line-' + (key || 'default'),
251
+ class: 'se-code-view-line',
252
+ readonly: 'true',
253
+ autocomplete: 'off',
254
+ 'aria-hidden': 'true',
255
+ tabindex: '-1',
256
+ },
209
257
  null,
210
258
  );
211
259
  codeWrapper.insertBefore(codeNumbers, textarea);
@@ -221,7 +269,14 @@ function Constructor(editorTargets, options) {
221
269
  markdownTextarea = initElements.markdownView;
222
270
  const markdownNumbers = dom.utils.createElement(
223
271
  'TEXTAREA',
224
- { id: editorFormFieldPrefix + '-markdown-view-line-' + (key || 'default'), class: 'se-markdown-view-line', readonly: 'true', autocomplete: 'off', 'aria-hidden': 'true', tabindex: '-1' },
272
+ {
273
+ id: editorFormFieldPrefix + '-markdown-view-line-' + (key || 'default'),
274
+ class: 'se-markdown-view-line',
275
+ readonly: 'true',
276
+ autocomplete: 'off',
277
+ 'aria-hidden': 'true',
278
+ tabindex: '-1',
279
+ },
225
280
  null,
226
281
  );
227
282
  markdownWrapper = dom.utils.createElement('DIV', { class: 'se-markdown-wrapper' });
@@ -234,7 +289,11 @@ function Constructor(editorTargets, options) {
234
289
  // document type
235
290
  const documentTypeInner = { inner: null, page: null, pageMirror: null };
236
291
  if (o.get('_type_options').includes('header')) {
237
- documentTypeInner.inner = dom.utils.createElement('DIV', { class: 'se-document-lines', style: `height: ${to.get('height')};` }, '<div class="se-document-lines-inner"></div>');
292
+ documentTypeInner.inner = dom.utils.createElement(
293
+ 'DIV',
294
+ { class: 'se-document-lines', style: `height: ${to.get('height')};` },
295
+ '<div class="se-document-lines-inner"></div>',
296
+ );
238
297
  }
239
298
  if (o.get('_type_options').includes('page')) {
240
299
  documentTypeInner.page = dom.utils.createElement('DIV', { class: 'se-document-page' }, null);
@@ -248,12 +307,46 @@ function Constructor(editorTargets, options) {
248
307
  );
249
308
  }
250
309
 
310
+ // block handle
311
+ let blockHandleArea = null;
312
+ if (isBlockHandle) {
313
+ blockHandleArea = dom.utils.createElement('DIV', { class: 'se-block-handle-area' });
314
+
315
+ const blockHandleGroup = dom.utils.createElement('DIV', { class: 'se-block-handle' });
316
+ const blockHandlePlus = dom.utils.createElement(
317
+ 'DIV',
318
+ { class: 'se-block-handle-btn se-block-handle-plus' },
319
+ icons.plus,
320
+ );
321
+ const blockHandleDrag = dom.utils.createElement(
322
+ 'DIV',
323
+ { class: 'se-block-handle-btn se-block-handle-drag' },
324
+ icons.dragHandle,
325
+ );
326
+ blockHandleGroup.appendChild(blockHandlePlus);
327
+ blockHandleGroup.appendChild(blockHandleDrag);
328
+
329
+ blockHandleArea.appendChild(blockHandleGroup);
330
+ }
331
+
251
332
  // set container
252
333
  top_div.appendChild(container);
253
334
  rootKeys.push(key);
254
335
  frameRoots.set(
255
336
  key,
256
- CreateFrameContext({ target: editTarget.target, key: editTarget.key, options: to }, top_div, wysiwyg_div, codeWrapper, textarea, markdownWrapper, markdownTextarea, default_status_bar || statusbar, documentTypeInner, key),
337
+ CreateFrameContext(
338
+ { target: editTarget.target, key: editTarget.key, options: to },
339
+ top_div,
340
+ wysiwyg_div,
341
+ codeWrapper,
342
+ textarea,
343
+ markdownWrapper,
344
+ markdownTextarea,
345
+ default_status_bar || statusbar,
346
+ documentTypeInner,
347
+ blockHandleArea,
348
+ key,
349
+ ),
257
350
  );
258
351
  }
259
352
  /** frame - root set - end -------------------------------------------------------------- */
@@ -261,7 +354,9 @@ function Constructor(editorTargets, options) {
261
354
  // toolbar container
262
355
  const toolbar_container = o.get('toolbar_container');
263
356
  if (toolbar_container) {
264
- const top_div = dom.utils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : '') });
357
+ const top_div = dom.utils.createElement('DIV', {
358
+ class: 'sun-editor' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : ''),
359
+ });
265
360
  const container = dom.utils.createElement('DIV', { class: 'se-container' });
266
361
  container.appendChild(toolbar);
267
362
  if (subbar) container.appendChild(subbar);
@@ -311,7 +406,11 @@ export function CreateShortcuts(command, button, values, keyMap, rc, reverseKeys
311
406
  if (!values || values.length < 2) return;
312
407
  const tooptip = button?.querySelector('.se-tooltip-text');
313
408
 
314
- for (let i = 0, a, v, c, s, edge, space, enter, textTrigger, plugin, method, t, k, r, _i; i < values.length; i += 2 + _i) {
409
+ for (
410
+ let i = 0, a, v, c, s, edge, space, enter, textTrigger, plugin, method, t, k, r, _i;
411
+ i < values.length;
412
+ i += 2 + _i
413
+ ) {
315
414
  _i = 0;
316
415
  a = values[i].split('+');
317
416
 
@@ -368,7 +467,21 @@ export function CreateShortcuts(command, button, values, keyMap, rc, reverseKeys
368
467
  r = r === -1 ? '' : numbers.isOdd(r) ? rc[r + 1] : rc[r - 1];
369
468
  if (r) reverseKeys.add(k);
370
469
 
371
- keyMap.set(k, { c, s, edge, space, enter, textTrigger, plugin, command, method, r, type: button?.getAttribute('data-type'), button, key: k });
470
+ keyMap.set(k, {
471
+ c,
472
+ s,
473
+ edge,
474
+ space,
475
+ enter,
476
+ textTrigger,
477
+ plugin,
478
+ command,
479
+ method,
480
+ r,
481
+ type: button?.getAttribute('data-type'),
482
+ button,
483
+ key: k,
484
+ });
372
485
  }
373
486
  }
374
487
 
@@ -384,7 +497,11 @@ export function CreateShortcuts(command, button, values, keyMap, rc, reverseKeys
384
497
  * @param {string} shortcut
385
498
  */
386
499
  function _addTooltip(tooptipBtn, shift, shortcut) {
387
- const tooltip = dom.utils.createElement('SPAN', { class: 'se-shortcut' }, env.cmdIcon + (shift ? env.shiftIcon : '') + '+<span class="se-shortcut-key">' + shortcut + '</span>');
500
+ const tooltip = dom.utils.createElement(
501
+ 'SPAN',
502
+ { class: 'se-shortcut' },
503
+ env.cmdIcon + (shift ? env.shiftIcon : '') + '+<span class="se-shortcut-key">' + shortcut + '</span>',
504
+ );
388
505
  const prevTooltip = tooptipBtn.querySelector('.se-shortcut');
389
506
 
390
507
  if (prevTooltip) {
@@ -434,7 +551,10 @@ export function InitOptions(options, editorTargets, plugins) {
434
551
 
435
552
  /** Multi root */
436
553
  if (editorTargets.length > 1) {
437
- if (!options.toolbar_container && !/inline|balloon/i.test(options.mode)) throw Error('[SUNEDITOR.create.fail] In multi root, The "mode" option cannot be "classic" without using the "toolbar_container" option.');
554
+ if (!options.toolbar_container && !/inline|balloon/i.test(options.mode))
555
+ throw Error(
556
+ '[SUNEDITOR.create.fail] In multi root, The "mode" option cannot be "classic" without using the "toolbar_container" option.',
557
+ );
438
558
  }
439
559
 
440
560
  // migration data-.+
@@ -459,13 +579,27 @@ export function InitOptions(options, editorTargets, plugins) {
459
579
  const [modeBase, modePart] = (options.mode || 'classic').split(':');
460
580
  o.set('mode', modeBase); // classic, inline, balloon, balloon-always
461
581
  o.set('_toolbar_bottom', modePart === 'bottom' && /^(classic|inline)$/i.test(modeBase));
582
+ o.set(
583
+ 'blockHandle',
584
+ options.blockHandle ? (typeof options.blockHandle === 'object' ? options.blockHandle : {}) : null,
585
+ );
462
586
  o.set('type', options.type?.split(':')[0] || ''); // document:header,page
463
587
  o.set('theme', options.theme || '');
464
588
  o.set('_themeClass', options.theme ? ` se-theme-${options.theme}` : '');
465
589
  o.set('_type_options', options.type?.split(':')[1] || '');
466
590
  o.set('externalLibs', options.externalLibs || {});
467
- o.set('fontSizeUnits', Array.isArray(options.fontSizeUnits) && options.fontSizeUnits.length > 0 ? options.fontSizeUnits.map((v) => v.toLowerCase()) : DEFAULTS.SIZE_UNITS);
468
- o.set('allowedClassName', new RegExp(`${options.allowedClassName && typeof options.allowedClassName === 'string' ? options.allowedClassName + '|' : ''}${DEFAULTS.CLASS_NAME}`));
591
+ o.set(
592
+ 'fontSizeUnits',
593
+ Array.isArray(options.fontSizeUnits) && options.fontSizeUnits.length > 0
594
+ ? options.fontSizeUnits.map((v) => v.toLowerCase())
595
+ : DEFAULTS.SIZE_UNITS,
596
+ );
597
+ o.set(
598
+ 'allowedClassName',
599
+ new RegExp(
600
+ `${options.allowedClassName && typeof options.allowedClassName === 'string' ? options.allowedClassName + '|' : ''}${DEFAULTS.CLASS_NAME}`,
601
+ ),
602
+ );
469
603
  o.set('closeModalOutsideClick', !!options.closeModalOutsideClick);
470
604
 
471
605
  // format
@@ -474,11 +608,16 @@ export function InitOptions(options, editorTargets, plugins) {
474
608
 
475
609
  // auto convert on paste
476
610
  o.set('autoLinkify', options.autoLinkify ?? !!plugins.link);
477
- o.set('autoStyleify', Array.isArray(options.autoStyleify) ? options.autoStyleify : ['bold', 'underline', 'italic', 'strike']);
611
+ o.set(
612
+ 'autoStyleify',
613
+ Array.isArray(options.autoStyleify) ? options.autoStyleify : ['bold', 'underline', 'italic', 'strike'],
614
+ );
478
615
 
479
616
  let retainStyleMode = options.retainStyleMode || 'repeat';
480
617
  if (typeof retainStyleMode === 'string' && !DEFAULTS.RETAIN_STYLE_MODE.includes(retainStyleMode)) {
481
- console.error(`Invalid retainStyleMode: ${retainStyleMode}. Valid options are ${DEFAULTS.RETAIN_STYLE_MODE.join(', ')}. Using default 'repeat'.`);
618
+ console.error(
619
+ `Invalid retainStyleMode: ${retainStyleMode}. Valid options are ${DEFAULTS.RETAIN_STYLE_MODE.join(', ')}. Using default 'repeat'.`,
620
+ );
482
621
  retainStyleMode = 'repeat';
483
622
  }
484
623
  o.set('retainStyleMode', retainStyleMode);
@@ -493,7 +632,11 @@ export function InitOptions(options, editorTargets, plugins) {
493
632
  o.set('events', options.events || {});
494
633
 
495
634
  // text style tags
496
- o.set('textStyleTags', (typeof options.__textStyleTags === 'string' ? options.__textStyleTags : DEFAULTS.TEXT_STYLE_TAGS) + (options.textStyleTags ? '|' + options.textStyleTags : ''));
635
+ o.set(
636
+ 'textStyleTags',
637
+ (typeof options.__textStyleTags === 'string' ? options.__textStyleTags : DEFAULTS.TEXT_STYLE_TAGS) +
638
+ (options.textStyleTags ? '|' + options.textStyleTags : ''),
639
+ );
497
640
  const textTags = _mergeObject(
498
641
  {
499
642
  bold: 'strong',
@@ -509,15 +652,16 @@ export function InitOptions(options, editorTargets, plugins) {
509
652
  o.set('_textStyleTags', Object.values(textTags).concat(['span', 'li']));
510
653
  o.set(
511
654
  'tagStyles',
512
- [{ ...DEFAULTS.TAG_STYLES, ...(options.__tagStyles || {}) }, options.tagStyles || {}].reduce((_default, _new) => {
513
- for (const key in _new) {
514
- _default[key] = _new[key];
515
- }
516
- return _default;
517
- }, {}),
655
+ [{ ...DEFAULTS.TAG_STYLES, ...(options.__tagStyles || {}) }, options.tagStyles || {}].reduce(
656
+ (_default, _new) => {
657
+ for (const key in _new) {
658
+ _default[key] = _new[key];
659
+ }
660
+ return _default;
661
+ },
662
+ {},
663
+ ),
518
664
  );
519
- o.set('_textStylesRegExp', new RegExp(`\\s*[^-a-zA-Z](${DEFAULTS.SPAN_STYLES}${options.spanStyles ? '|' + options.spanStyles : ''})\\s*:[^;]+(?!;)*`, 'gi'));
520
- o.set('_lineStylesRegExp', new RegExp(`\\s*[^-a-zA-Z](${DEFAULTS.LINE_STYLES}${options.lineStyles ? '|' + options.lineStyles : ''})\\s*:[^;]+(?!;)*`, 'gi'));
521
665
  o.set('_defaultStyleTagMap', {
522
666
  strong: textTags.bold,
523
667
  b: textTags.bold,
@@ -562,36 +706,79 @@ export function InitOptions(options, editorTargets, plugins) {
562
706
  o.set('reverseCommands', ['indent-outdent'].concat(options.reverseButtons || []));
563
707
  o.set('_reverseCommandArray', ('-' + o.get('reverseCommands').join('-')).split('-'));
564
708
  if (numbers.isEven(o.get('_reverseCommandArray').length)) {
565
- console.warn('[SUNEDITOR.create.warning] The "reverseCommands" option is invalid, Shortcuts key may not work properly.');
709
+ console.warn(
710
+ '[SUNEDITOR.create.warning] The "reverseCommands" option is invalid, Shortcuts key may not work properly.',
711
+ );
566
712
  }
567
713
 
568
714
  // etc
569
- o.set('historyStackDelayTime', typeof options.historyStackDelayTime === 'number' ? options.historyStackDelayTime : 400);
570
- o.set('historyStackSize', typeof options.historyStackSize === 'number' && options.historyStackSize > 0 ? options.historyStackSize : 100);
571
- o.set('_editableClass', 'sun-editor-editable' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : '') + (o.get('type') === 'document' ? ' se-type-document-editable-a4' : ''));
572
- o.set('lineAttrReset', ['id'].concat(options.lineAttrReset && typeof options.lineAttrReset === 'string' ? options.lineAttrReset.toLowerCase().split('|') : []));
573
- o.set('printClass', typeof options.printClass === 'string' ? options.printClass + ' ' + o.get('_editableClass') : null);
715
+ o.set(
716
+ 'historyStackDelayTime',
717
+ typeof options.historyStackDelayTime === 'number' ? options.historyStackDelayTime : 400,
718
+ );
719
+ o.set(
720
+ 'historyStackSize',
721
+ typeof options.historyStackSize === 'number' && options.historyStackSize > 0 ? options.historyStackSize : 100,
722
+ );
723
+ o.set(
724
+ '_editableClass',
725
+ 'sun-editor-editable' +
726
+ o.get('_themeClass') +
727
+ (o.get('_rtl') ? ' se-rtl' : '') +
728
+ (o.get('type') === 'document' ? ' se-type-document-editable-a4' : ''),
729
+ );
730
+ o.set(
731
+ 'lineAttrReset',
732
+ ['id'].concat(
733
+ options.lineAttrReset && typeof options.lineAttrReset === 'string'
734
+ ? options.lineAttrReset.toLowerCase().split('|')
735
+ : [],
736
+ ),
737
+ );
738
+ o.set(
739
+ 'printClass',
740
+ typeof options.printClass === 'string' ? options.printClass + ' ' + o.get('_editableClass') : null,
741
+ );
574
742
 
575
743
  /** whitelist, blacklist */
576
744
  // default line
577
- o.set('defaultLine', typeof options.defaultLine === 'string' && options.defaultLine.length > 0 ? options.defaultLine : 'p');
745
+ o.set(
746
+ 'defaultLine',
747
+ typeof options.defaultLine === 'string' && options.defaultLine.length > 0 ? options.defaultLine : 'p',
748
+ );
578
749
  o.set('defaultLineBreakFormat', options.defaultLineBreakFormat || 'line');
579
750
  o.set('scopeSelectionTags', options.scopeSelectionTags || DEFAULTS.SCOPE_SELECTION_TAGS);
580
751
  // element
581
752
  const elw = (typeof options.elementWhitelist === 'string' ? options.elementWhitelist : '').toLowerCase();
582
753
  const mjxEls = o.get('externalLibs').mathjax ? DEFAULTS.CLASS_MJX + '|' : '';
583
754
  o.set('elementWhitelist', elw + (elw ? '|' : '') + mjxEls + o.get('_allowedExtraTag'));
584
- const elb = _createBlacklist((typeof options.elementBlacklist === 'string' ? options.elementBlacklist : '').toLowerCase(), o.get('defaultLine'));
755
+ const elb = _createBlacklist(
756
+ (typeof options.elementBlacklist === 'string' ? options.elementBlacklist : '').toLowerCase(),
757
+ o.get('defaultLine'),
758
+ );
585
759
  o.set('elementBlacklist', elb + (elb ? '|' : '') + o.get('_disallowedExtraTag'));
586
760
  // attribute
587
- o.set('attributeWhitelist', !options.attributeWhitelist || typeof options.attributeWhitelist !== 'object' ? null : options.attributeWhitelist);
588
- o.set('attributeBlacklist', !options.attributeBlacklist || typeof options.attributeBlacklist !== 'object' ? null : options.attributeBlacklist);
761
+ o.set(
762
+ 'attributeWhitelist',
763
+ !options.attributeWhitelist || typeof options.attributeWhitelist !== 'object'
764
+ ? null
765
+ : options.attributeWhitelist,
766
+ );
767
+ o.set(
768
+ 'attributeBlacklist',
769
+ !options.attributeBlacklist || typeof options.attributeBlacklist !== 'object'
770
+ ? null
771
+ : options.attributeBlacklist,
772
+ );
589
773
  // format tag
590
774
  o.set(
591
775
  'formatClosureBrLine',
592
776
  _createFormatInfo(
593
777
  options.formatClosureBrLine,
594
- (options.__defaultFormatClosureBrLine = typeof options.__defaultFormatClosureBrLine === 'string' ? options.__defaultFormatClosureBrLine : DEFAULTS.FORMAT_CLOSURE_BR_LINE).toLowerCase(),
778
+ (options.__defaultFormatClosureBrLine =
779
+ typeof options.__defaultFormatClosureBrLine === 'string'
780
+ ? options.__defaultFormatClosureBrLine
781
+ : DEFAULTS.FORMAT_CLOSURE_BR_LINE).toLowerCase(),
595
782
  o.get('elementBlacklist'),
596
783
  ),
597
784
  );
@@ -599,7 +786,10 @@ export function InitOptions(options, editorTargets, plugins) {
599
786
  'formatBrLine',
600
787
  _createFormatInfo(
601
788
  (options.formatBrLine || '') + '|' + o.get('formatClosureBrLine').str,
602
- (options.__defaultFormatBrLine = typeof options.__defaultFormatBrLine === 'string' ? options.__defaultFormatBrLine : DEFAULTS.FORMAT_BR_LINE).toLowerCase(),
789
+ (options.__defaultFormatBrLine =
790
+ typeof options.__defaultFormatBrLine === 'string'
791
+ ? options.__defaultFormatBrLine
792
+ : DEFAULTS.FORMAT_BR_LINE).toLowerCase(),
603
793
  o.get('elementBlacklist'),
604
794
  ),
605
795
  );
@@ -607,21 +797,29 @@ export function InitOptions(options, editorTargets, plugins) {
607
797
  'formatLine',
608
798
  _createFormatInfo(
609
799
  DEFAULTS.REQUIRED_FORMAT_LINE + '|' + (options.formatLine || '') + '|' + o.get('formatBrLine').str,
610
- (options.__defaultFormatLine = typeof options.__defaultFormatLine === 'string' ? options.__defaultFormatLine : DEFAULTS.FORMAT_LINE).toLowerCase(),
800
+ (options.__defaultFormatLine =
801
+ typeof options.__defaultFormatLine === 'string'
802
+ ? options.__defaultFormatLine
803
+ : DEFAULTS.FORMAT_LINE).toLowerCase(),
611
804
  o.get('elementBlacklist'),
612
805
  ),
613
806
  );
614
807
 
615
808
  // Error - default line
616
809
  if (!o.get('formatLine').reg.test(o.get('defaultLine'))) {
617
- throw Error(`[SUNEDITOR.create.fail] The "defaultLine(${o.get('defaultLine')})" option must be included in the "formatLine(${o.get('formatLine').str})" option.`);
810
+ throw Error(
811
+ `[SUNEDITOR.create.fail] The "defaultLine(${o.get('defaultLine')})" option must be included in the "formatLine(${o.get('formatLine').str})" option.`,
812
+ );
618
813
  }
619
814
 
620
815
  o.set(
621
816
  'formatClosureBlock',
622
817
  _createFormatInfo(
623
818
  options.formatClosureBlock,
624
- (options.__defaultFormatClosureBlock = typeof options.__defaultFormatClosureBlock === 'string' ? options.__defaultFormatClosureBlock : DEFAULTS.FORMAT_CLOSURE_BLOCK).toLowerCase(),
819
+ (options.__defaultFormatClosureBlock =
820
+ typeof options.__defaultFormatClosureBlock === 'string'
821
+ ? options.__defaultFormatClosureBlock
822
+ : DEFAULTS.FORMAT_CLOSURE_BLOCK).toLowerCase(),
625
823
  o.get('elementBlacklist'),
626
824
  ),
627
825
  );
@@ -629,22 +827,64 @@ export function InitOptions(options, editorTargets, plugins) {
629
827
  'formatBlock',
630
828
  _createFormatInfo(
631
829
  (options.formatBlock || '') + '|' + o.get('formatClosureBlock').str,
632
- (options.__defaultFormatBlock = typeof options.__defaultFormatBlock === 'string' ? options.__defaultFormatBlock : DEFAULTS.FORMAT_BLOCK).toLowerCase(),
830
+ (options.__defaultFormatBlock =
831
+ typeof options.__defaultFormatBlock === 'string'
832
+ ? options.__defaultFormatBlock
833
+ : DEFAULTS.FORMAT_BLOCK).toLowerCase(),
633
834
  o.get('elementBlacklist'),
634
835
  ),
635
836
  );
636
837
 
637
- o.set('allowedEmptyTags', DEFAULTS.ALLOWED_EMPTY_NODE_LIST + (options.allowedEmptyTags ? ', ' + options.allowedEmptyTags : ''));
838
+ o.set(
839
+ 'allowedEmptyTags',
840
+ DEFAULTS.ALLOWED_EMPTY_NODE_LIST + (options.allowedEmptyTags ? ', ' + options.allowedEmptyTags : ''),
841
+ );
638
842
 
639
843
  /** __defaults */
640
- o.set('__defaultElementWhitelist', DEFAULTS.REQUIRED_ELEMENT_WHITELIST + '|' + (typeof options.__defaultElementWhitelist === 'string' ? options.__defaultElementWhitelist : DEFAULTS.ELEMENT_WHITELIST).toLowerCase());
641
- o.set('__defaultAttributeWhitelist', (typeof options.__defaultAttributeWhitelist === 'string' ? options.__defaultAttributeWhitelist : DEFAULTS.ATTRIBUTE_WHITELIST).toLowerCase());
844
+ o.set(
845
+ '__defaultElementWhitelist',
846
+ DEFAULTS.REQUIRED_ELEMENT_WHITELIST +
847
+ '|' +
848
+ (typeof options.__defaultElementWhitelist === 'string'
849
+ ? options.__defaultElementWhitelist
850
+ : DEFAULTS.ELEMENT_WHITELIST
851
+ ).toLowerCase(),
852
+ );
853
+ o.set(
854
+ '__defaultAttributeWhitelist',
855
+ (typeof options.__defaultAttributeWhitelist === 'string'
856
+ ? options.__defaultAttributeWhitelist
857
+ : DEFAULTS.ATTRIBUTE_WHITELIST
858
+ ).toLowerCase(),
859
+ );
642
860
  // --- create element whitelist (__defaultElementWhiteList + elementWhitelist + format[line, BrLine, Block, Closureblock, ClosureBrLine] - elementBlacklist)
643
861
  o.set('_editorElementWhitelist', o.get('elementWhitelist') === '*' ? '*' : _createWhitelist(o));
644
862
 
645
863
  /** Toolbar */
646
- o.set('toolbar_width', options.toolbar_width ? (numbers.is(options.toolbar_width) ? options.toolbar_width + 'px' : options.toolbar_width) : 'auto');
647
- o.set('toolbar_container', options.toolbar_container && !/inline/i.test(o.get('mode')) ? (typeof options.toolbar_container === 'string' ? _d.querySelector(options.toolbar_container) : options.toolbar_container) : null);
864
+ o.set(
865
+ 'toolbar_width',
866
+ options.toolbar_width
867
+ ? numbers.is(options.toolbar_width)
868
+ ? options.toolbar_width + 'px'
869
+ : options.toolbar_width
870
+ : 'auto',
871
+ );
872
+ o.set(
873
+ 'toolbar_innerWidth',
874
+ options.toolbar_innerWidth
875
+ ? numbers.is(options.toolbar_innerWidth)
876
+ ? options.toolbar_innerWidth + 'px'
877
+ : options.toolbar_innerWidth
878
+ : '',
879
+ );
880
+ o.set(
881
+ 'toolbar_container',
882
+ options.toolbar_container && !/inline/i.test(o.get('mode'))
883
+ ? typeof options.toolbar_container === 'string'
884
+ ? _d.querySelector(options.toolbar_container)
885
+ : options.toolbar_container
886
+ : null,
887
+ );
648
888
 
649
889
  const _stickyOpt = options.toolbar_sticky;
650
890
  const _isBalloon = /balloon/i.test(o.get('mode'));
@@ -666,10 +906,15 @@ export function InitOptions(options, editorTargets, plugins) {
666
906
  const subbar = options.subToolbar;
667
907
  if (subbar?.buttonList?.length > 0) {
668
908
  if (/balloon/.test(o.get('mode'))) {
669
- console.warn('[SUNEDITOR.create.subToolbar.fail] When the "mode" option is "balloon-*", the "subToolbar" option is omitted.');
909
+ console.warn(
910
+ '[SUNEDITOR.create.subToolbar.fail] When the "mode" option is "balloon-*", the "subToolbar" option is omitted.',
911
+ );
670
912
  } else {
671
913
  o.set('_subMode', subbar.mode || 'balloon');
672
- o.set('toolbar_sub_width', subbar.width ? (numbers.is(subbar.width) ? subbar.width + 'px' : subbar.width) : 'auto');
914
+ o.set(
915
+ 'toolbar_sub_width',
916
+ subbar.width ? (numbers.is(subbar.width) ? subbar.width + 'px' : subbar.width) : 'auto',
917
+ );
673
918
  subButtons = o.get('_rtl') ? subbar.buttonList.reverse() : subbar.buttonList;
674
919
  o.set('buttons_sub', new Set(subButtons.toString().split(',')));
675
920
  }
@@ -678,7 +923,10 @@ export function InitOptions(options, editorTargets, plugins) {
678
923
  /** root options */
679
924
  const frameMap = new Map();
680
925
  for (let i = 0, len = editorTargets.length; i < len; i++) {
681
- frameMap.set(editorTargets[i].key, InitFrameOptions(editorTargets[i].options || /** @type {SunEditor.InitFrameOptions} */ ({}), options));
926
+ frameMap.set(
927
+ editorTargets[i].key,
928
+ InitFrameOptions(editorTargets[i].options || /** @type {SunEditor.InitFrameOptions} */ ({}), options),
929
+ );
682
930
  }
683
931
 
684
932
  /** Key actions */
@@ -720,12 +968,24 @@ export function InitOptions(options, editorTargets, plugins) {
720
968
  o.set('shortcuts', shortcuts);
721
969
 
722
970
  /** View */
723
- o.set('fullScreenOffset', options.fullScreenOffset === undefined ? 0 : numbers.is(options.fullScreenOffset) ? numbers.get(options.fullScreenOffset, 0) : 0);
971
+ o.set(
972
+ 'fullScreenOffset',
973
+ options.fullScreenOffset === undefined
974
+ ? 0
975
+ : numbers.is(options.fullScreenOffset)
976
+ ? numbers.get(options.fullScreenOffset, 0)
977
+ : 0,
978
+ );
724
979
  o.set('previewTemplate', typeof options.previewTemplate === 'string' ? options.previewTemplate : null);
725
980
  o.set('printTemplate', typeof options.printTemplate === 'string' ? options.printTemplate : null);
726
981
 
727
982
  /** --- Media select */
728
- o.set('componentInsertBehavior', ['auto', 'select', 'line', 'none'].includes(options.componentInsertBehavior) ? options.componentInsertBehavior : 'auto');
983
+ o.set(
984
+ 'componentInsertBehavior',
985
+ ['auto', 'select', 'line', 'none'].includes(options.componentInsertBehavior)
986
+ ? options.componentInsertBehavior
987
+ : 'auto',
988
+ );
729
989
 
730
990
  /** --- Url input protocol */
731
991
  o.set('defaultUrlProtocol', typeof options.defaultUrlProtocol === 'string' ? options.defaultUrlProtocol : null);
@@ -738,13 +998,18 @@ export function InitOptions(options, editorTargets, plugins) {
738
998
  if (cm.src) {
739
999
  o.set('codeMirrorEditor', true);
740
1000
  } else {
741
- console.warn('[SUNEDITOR.options.externalLibs.codeMirror.fail] The codeMirror option is set incorrectly. See: https://github.com/ARA-developer/suneditor/blob/develop/guide/external-libraries.md');
1001
+ console.warn(
1002
+ '[SUNEDITOR.options.externalLibs.codeMirror.fail] The codeMirror option is set incorrectly. See: https://github.com/ARA-developer/suneditor/blob/develop/guide/external-libraries.md',
1003
+ );
742
1004
  o.set('codeMirror', null);
743
1005
  }
744
1006
  }
745
1007
 
746
1008
  /** Private options */
747
- o.set('__listCommonStyle', options.__listCommonStyle || ['fontSize', 'color', 'fontFamily', 'fontWeight', 'fontStyle']);
1009
+ o.set(
1010
+ '__listCommonStyle',
1011
+ options.__listCommonStyle || ['fontSize', 'color', 'fontFamily', 'fontWeight', 'fontStyle'],
1012
+ );
748
1013
 
749
1014
  /** --- Icons ------------------------------------------------------------------------------------------ */
750
1015
  const icons =
@@ -760,25 +1025,18 @@ export function InitOptions(options, editorTargets, plugins) {
760
1025
 
761
1026
  /** Create all used styles */
762
1027
  const allUsedStyles = new Set(DEFAULTS.CONTENT_STYLES.split('|'));
763
- const _ss = options.spanStyles?.split('|') || [];
764
1028
  const _ls = o.get('__listCommonStyle');
765
- const _dts = DEFAULTS.SPAN_STYLES.split('|');
766
- for (let i = 0, len = _dts.length; i < len; i++) {
767
- allUsedStyles.add(_dts[i]);
768
- }
769
1029
  for (const _ts of Object.values(o.get('tagStyles'))) {
770
1030
  const _tss = _ts.split('|');
771
1031
  for (let i = 0, len = _tss.length; i < len; i++) {
772
1032
  allUsedStyles.add(_tss[i]);
773
1033
  }
774
1034
  }
775
- for (let i = 0, len = _ss.length; i < len; i++) {
776
- allUsedStyles.add(_ss[i]);
777
- }
778
1035
  for (let i = 0, len = _ls.length; i < len; i++) {
779
1036
  allUsedStyles.add(_ls[i]);
780
1037
  }
781
- const _aus = (typeof options.allUsedStyles === 'string' ? options.allUsedStyles.split('|') : options.allUsedStyles) || [];
1038
+ const _aus =
1039
+ (typeof options.allUsedStyles === 'string' ? options.allUsedStyles.split('|') : options.allUsedStyles) || [];
782
1040
  for (let i = 0, len = _aus.length; i < len; i++) {
783
1041
  allUsedStyles.add(_aus[i]);
784
1042
  }
@@ -792,7 +1050,10 @@ export function InitOptions(options, editorTargets, plugins) {
792
1050
  v: (options.value = typeof options.value === 'string' ? options.value : null),
793
1051
  buttons: o.get('_rtl') ? buttonList.reverse() : buttonList,
794
1052
  subButtons: subButtons,
795
- statusbarContainer: typeof options.statusbar_container === 'string' ? _d.querySelector(options.statusbar_container) : options.statusbar_container,
1053
+ statusbarContainer:
1054
+ typeof options.statusbar_container === 'string'
1055
+ ? _d.querySelector(options.statusbar_container)
1056
+ : options.statusbar_container,
796
1057
  frameMap: frameMap,
797
1058
  };
798
1059
  }
@@ -814,20 +1075,28 @@ export function CreateStatusbar(targetOptions, statusbar) {
814
1075
  statusbar ||= dom.utils.createElement('DIV', { class: 'se-status-bar sun-editor-common' });
815
1076
 
816
1077
  /** navigation */
817
- navigation = statusbar.querySelector('.se-navigation') || dom.utils.createElement('DIV', { class: 'se-navigation sun-editor-common' });
1078
+ navigation =
1079
+ statusbar.querySelector('.se-navigation') ||
1080
+ dom.utils.createElement('DIV', { class: 'se-navigation sun-editor-common' });
818
1081
  statusbar.appendChild(navigation);
819
1082
 
820
1083
  /** word counter (left) */
821
1084
  if (targetOptions.get('wordCounter')) {
822
- wordWrapper = statusbar.querySelector('.se-word-counter-wrapper') || dom.utils.createElement('DIV', { class: 'se-word-counter-wrapper' });
1085
+ wordWrapper =
1086
+ statusbar.querySelector('.se-word-counter-wrapper') ||
1087
+ dom.utils.createElement('DIV', { class: 'se-word-counter-wrapper' });
823
1088
 
824
1089
  if (targetOptions.get('wordCounter_label')) {
825
- const wordLabel = wordWrapper.querySelector('.se-word-label') || dom.utils.createElement('SPAN', { class: 'se-word-label' });
1090
+ const wordLabel =
1091
+ wordWrapper.querySelector('.se-word-label') ||
1092
+ dom.utils.createElement('SPAN', { class: 'se-word-label' });
826
1093
  wordLabel.textContent = targetOptions.get('wordCounter_label');
827
1094
  wordWrapper.appendChild(wordLabel);
828
1095
  }
829
1096
 
830
- wordCounter = wordWrapper.querySelector('.se-word-counter') || dom.utils.createElement('SPAN', { class: 'se-word-counter' });
1097
+ wordCounter =
1098
+ wordWrapper.querySelector('.se-word-counter') ||
1099
+ dom.utils.createElement('SPAN', { class: 'se-word-counter' });
831
1100
  wordCounter.textContent = '0';
832
1101
  wordWrapper.appendChild(wordCounter);
833
1102
 
@@ -836,24 +1105,32 @@ export function CreateStatusbar(targetOptions, statusbar) {
836
1105
 
837
1106
  /** char counter (right) */
838
1107
  if (targetOptions.get('charCounter')) {
839
- charWrapper = statusbar.querySelector('.se-char-counter-wrapper') || dom.utils.createElement('DIV', { class: 'se-char-counter-wrapper' });
1108
+ charWrapper =
1109
+ statusbar.querySelector('.se-char-counter-wrapper') ||
1110
+ dom.utils.createElement('DIV', { class: 'se-char-counter-wrapper' });
840
1111
 
841
1112
  if (targetOptions.get('wordCounter') && charWrapper.className.indexOf('se-with-word-counter') === -1) {
842
1113
  charWrapper.className += ' se-with-word-counter';
843
1114
  }
844
1115
 
845
1116
  if (targetOptions.get('charCounter_label')) {
846
- const charLabel = charWrapper.querySelector('.se-char-label') || dom.utils.createElement('SPAN', { class: 'se-char-label' });
1117
+ const charLabel =
1118
+ charWrapper.querySelector('.se-char-label') ||
1119
+ dom.utils.createElement('SPAN', { class: 'se-char-label' });
847
1120
  charLabel.textContent = targetOptions.get('charCounter_label');
848
1121
  charWrapper.appendChild(charLabel);
849
1122
  }
850
1123
 
851
- charCounter = charWrapper.querySelector('.se-char-counter') || dom.utils.createElement('SPAN', { class: 'se-char-counter' });
1124
+ charCounter =
1125
+ charWrapper.querySelector('.se-char-counter') ||
1126
+ dom.utils.createElement('SPAN', { class: 'se-char-counter' });
852
1127
  charCounter.textContent = '0';
853
1128
  charWrapper.appendChild(charCounter);
854
1129
 
855
1130
  if (targetOptions.get('charCounter_max') > 0) {
856
- const char_max = charWrapper.querySelector('.se-char-max') || dom.utils.createElement('SPAN', { class: 'se-char-max' });
1131
+ const char_max =
1132
+ charWrapper.querySelector('.se-char-max') ||
1133
+ dom.utils.createElement('SPAN', { class: 'se-char-max' });
857
1134
  char_max.textContent = ' / ' + targetOptions.get('charCounter_max');
858
1135
  charWrapper.appendChild(char_max);
859
1136
  }
@@ -887,10 +1164,13 @@ function InitFrameOptions(o, origin) {
887
1164
  // members
888
1165
  const value = o.value === undefined ? origin.value : o.value;
889
1166
  const placeholder = o.placeholder === undefined ? origin.placeholder : o.placeholder;
890
- const editableFrameAttributes = o.editableFrameAttributes === undefined ? origin.editableFrameAttributes : o.editableFrameAttributes;
1167
+ const placeholder_line = o.placeholder_line === undefined ? origin.placeholder_line : o.placeholder_line;
1168
+ const editableFrameAttributes =
1169
+ o.editableFrameAttributes === undefined ? origin.editableFrameAttributes : o.editableFrameAttributes;
891
1170
  const width = o.width === undefined ? origin.width : o.width;
892
1171
  const minWidth = o.minWidth === undefined ? origin.minWidth : o.minWidth;
893
1172
  const maxWidth = o.maxWidth === undefined ? origin.maxWidth : o.maxWidth;
1173
+ const innerWidth = o.innerWidth === undefined ? origin.innerWidth : o.innerWidth;
894
1174
  const height = o.height === undefined ? origin.height : o.height;
895
1175
  const minHeight = o.minHeight === undefined ? origin.minHeight : o.minHeight;
896
1176
  const maxHeight = o.maxHeight === undefined ? origin.maxHeight : o.maxHeight;
@@ -900,23 +1180,36 @@ function InitFrameOptions(o, origin) {
900
1180
  const iframe_attributes = o.iframe_attributes === undefined ? origin.iframe_attributes : o.iframe_attributes;
901
1181
  const iframe_cssFileName = o.iframe_cssFileName === undefined ? origin.iframe_cssFileName : o.iframe_cssFileName;
902
1182
  const statusbar = barContainer || o.statusbar === undefined ? origin.statusbar : o.statusbar;
903
- const statusbar_showPathLabel = barContainer || o.statusbar_showPathLabel === undefined ? origin.statusbar_showPathLabel : o.statusbar_showPathLabel;
904
- const statusbar_resizeEnable = barContainer ? false : o.statusbar_resizeEnable === undefined ? origin.statusbar_resizeEnable : o.statusbar_resizeEnable;
1183
+ const statusbar_showPathLabel =
1184
+ barContainer || o.statusbar_showPathLabel === undefined
1185
+ ? origin.statusbar_showPathLabel
1186
+ : o.statusbar_showPathLabel;
1187
+ const statusbar_resizeEnable = barContainer
1188
+ ? false
1189
+ : o.statusbar_resizeEnable === undefined
1190
+ ? origin.statusbar_resizeEnable
1191
+ : o.statusbar_resizeEnable;
905
1192
  const charCounter = barContainer || o.charCounter === undefined ? origin.charCounter : o.charCounter;
906
- const charCounter_max = barContainer || o.charCounter_max === undefined ? origin.charCounter_max : o.charCounter_max;
907
- const charCounter_label = barContainer || o.charCounter_label === undefined ? origin.charCounter_label : o.charCounter_label;
908
- const charCounter_type = barContainer || o.charCounter_type === undefined ? origin.charCounter_type : o.charCounter_type;
1193
+ const charCounter_max =
1194
+ barContainer || o.charCounter_max === undefined ? origin.charCounter_max : o.charCounter_max;
1195
+ const charCounter_label =
1196
+ barContainer || o.charCounter_label === undefined ? origin.charCounter_label : o.charCounter_label;
1197
+ const charCounter_type =
1198
+ barContainer || o.charCounter_type === undefined ? origin.charCounter_type : o.charCounter_type;
909
1199
  const wordCounter = barContainer || o.wordCounter === undefined ? origin.wordCounter : o.wordCounter;
910
- const wordCounter_label = barContainer || o.wordCounter_label === undefined ? origin.wordCounter_label : o.wordCounter_label;
1200
+ const wordCounter_label =
1201
+ barContainer || o.wordCounter_label === undefined ? origin.wordCounter_label : o.wordCounter_label;
911
1202
 
912
1203
  // value
913
1204
  fo.set('value', value);
914
1205
  fo.set('placeholder', placeholder);
1206
+ fo.set('placeholder_line', placeholder_line);
915
1207
  fo.set('editableFrameAttributes', { spellcheck: 'false', ...editableFrameAttributes });
916
1208
  // styles
917
1209
  fo.set('width', width ? String(numbers.is(width) ? width + 'px' : width) : '100%');
918
1210
  fo.set('minWidth', minWidth ? String(numbers.is(minWidth) ? minWidth + 'px' : minWidth) : '');
919
1211
  fo.set('maxWidth', maxWidth ? String(numbers.is(maxWidth) ? maxWidth + 'px' : maxWidth) : '');
1212
+ fo.set('innerWidth', innerWidth ? String(numbers.is(innerWidth) ? innerWidth + 'px' : innerWidth) : '');
920
1213
  fo.set('height', height ? String(numbers.is(height) ? height + 'px' : height) : 'auto');
921
1214
  fo.set('minHeight', minHeight ? String(numbers.is(minHeight) ? minHeight + 'px' : minHeight) : '');
922
1215
  fo.set('maxHeight', maxHeight ? String(numbers.is(maxHeight) ? maxHeight + 'px' : maxHeight) : '');
@@ -926,12 +1219,23 @@ function InitFrameOptions(o, origin) {
926
1219
  fo.set('iframe', !!(iframe_fullPage || iframe));
927
1220
  fo.set('iframe_fullPage', !!iframe_fullPage);
928
1221
  fo.set('iframe_attributes', iframe_attributes || {});
929
- fo.set('iframe_cssFileName', iframe ? (typeof iframe_cssFileName === 'string' ? [iframe_cssFileName] : iframe_cssFileName) || ['suneditor'] : null);
1222
+ fo.set(
1223
+ 'iframe_cssFileName',
1224
+ iframe
1225
+ ? (typeof iframe_cssFileName === 'string' ? [iframe_cssFileName] : iframe_cssFileName) || ['suneditor']
1226
+ : null,
1227
+ );
930
1228
  // status bar
931
1229
  const hasStatusbar = statusbar === undefined ? true : !!statusbar;
932
1230
  fo.set('statusbar', hasStatusbar);
933
- fo.set('statusbar_showPathLabel', !hasStatusbar ? false : typeof statusbar_showPathLabel === 'boolean' ? statusbar_showPathLabel : true);
934
- fo.set('statusbar_resizeEnable', !hasStatusbar ? false : statusbar_resizeEnable === undefined ? true : !!statusbar_resizeEnable);
1231
+ fo.set(
1232
+ 'statusbar_showPathLabel',
1233
+ !hasStatusbar ? false : typeof statusbar_showPathLabel === 'boolean' ? statusbar_showPathLabel : true,
1234
+ );
1235
+ fo.set(
1236
+ 'statusbar_resizeEnable',
1237
+ !hasStatusbar ? false : statusbar_resizeEnable === undefined ? true : !!statusbar_resizeEnable,
1238
+ );
935
1239
  // status bar - character count
936
1240
  fo.set('charCounter', charCounter_max > 0 ? true : typeof charCounter === 'boolean' ? charCounter : false);
937
1241
  fo.set('charCounter_max', numbers.is(charCounter_max) && charCounter_max > -1 ? charCounter_max * 1 : null);
@@ -961,7 +1265,9 @@ function _initTargetElements(key, options, topDiv, targetOptions, formFieldPrefi
961
1265
  /** editor */
962
1266
  // wysiwyg div or iframe
963
1267
  const wysiwygDiv = dom.utils.createElement(!targetOptions.get('iframe') ? 'DIV' : 'IFRAME', {
964
- class: 'se-wrapper-inner se-wrapper-wysiwyg' + (options.get('type') === 'document' ? ' se-type-document-iframe-a4' : ''),
1268
+ class:
1269
+ 'se-wrapper-inner se-wrapper-wysiwyg' +
1270
+ (options.get('type') === 'document' ? ' se-type-document-iframe-a4' : ''),
965
1271
  'data-root-key': key,
966
1272
  });
967
1273
 
@@ -1007,10 +1313,20 @@ function _initTargetElements(key, options, topDiv, targetOptions, formFieldPrefi
1007
1313
  }
1008
1314
 
1009
1315
  // textarea for code view
1010
- const textarea = dom.utils.createElement('TEXTAREA', { id: formFieldPrefix + '-code-viewer-' + (key || 'default'), class: 'se-wrapper-inner se-code-viewer', style: editorStyles.frame, autocomplete: 'off' });
1316
+ const textarea = dom.utils.createElement('TEXTAREA', {
1317
+ id: formFieldPrefix + '-code-viewer-' + (key || 'default'),
1318
+ class: 'se-wrapper-inner se-code-viewer',
1319
+ style: editorStyles.frame,
1320
+ autocomplete: 'off',
1321
+ });
1011
1322
 
1012
1323
  // textarea for markdown view
1013
- const markdownTextarea = dom.utils.createElement('TEXTAREA', { id: formFieldPrefix + '-markdown-viewer-' + (key || 'default'), class: 'se-wrapper-inner se-markdown-viewer', style: editorStyles.frame, autocomplete: 'off' });
1324
+ const markdownTextarea = dom.utils.createElement('TEXTAREA', {
1325
+ id: formFieldPrefix + '-markdown-viewer-' + (key || 'default'),
1326
+ class: 'se-wrapper-inner se-markdown-viewer',
1327
+ style: editorStyles.frame,
1328
+ autocomplete: 'off',
1329
+ });
1014
1330
 
1015
1331
  const placeholder = dom.utils.createElement('SPAN', { class: 'se-placeholder' });
1016
1332
  if (targetOptions.get('placeholder')) {
@@ -1090,7 +1406,9 @@ function _createBlacklist(blacklist, defaultLine) {
1090
1406
  if (v !== defaultLine) {
1091
1407
  return true;
1092
1408
  } else {
1093
- console.warn(`[SUNEDITOR.constructor.createBlacklist.warn] defaultLine("<${defaultLine}>") cannot be included in the blacklist and will be removed.`);
1409
+ console.warn(
1410
+ `[SUNEDITOR.constructor.createBlacklist.warn] defaultLine("<${defaultLine}>") cannot be included in the blacklist and will be removed.`,
1411
+ );
1094
1412
  return false;
1095
1413
  }
1096
1414
  })
@@ -1124,7 +1442,19 @@ function _createFormatInfo(value, defaultValue, blacklist) {
1124
1442
  */
1125
1443
  function _createWhitelist(o) {
1126
1444
  const blacklist = o.get('elementBlacklist').split('|');
1127
- const whitelist = (o.get('__defaultElementWhitelist') + '|' + o.get('elementWhitelist') + '|' + o.get('formatLine').str + '|' + o.get('formatBrLine').str + '|' + o.get('formatClosureBlock').str + '|' + o.get('formatClosureBrLine').str)
1445
+ const whitelist = (
1446
+ o.get('__defaultElementWhitelist') +
1447
+ '|' +
1448
+ o.get('elementWhitelist') +
1449
+ '|' +
1450
+ o.get('formatLine').str +
1451
+ '|' +
1452
+ o.get('formatBrLine').str +
1453
+ '|' +
1454
+ o.get('formatClosureBlock').str +
1455
+ '|' +
1456
+ o.get('formatClosureBrLine').str
1457
+ )
1128
1458
  .replace(/(^\||\|$)/g, '')
1129
1459
  .split('|')
1130
1460
  .filter((v, i, a) => v && a.indexOf(v) === i && !blacklist.includes(v));
@@ -1132,6 +1462,59 @@ function _createWhitelist(o) {
1132
1462
  return whitelist.join('|');
1133
1463
  }
1134
1464
 
1465
+ /**
1466
+ * @description Toolbar variant — sizes the button row to its content and centers it.
1467
+ * - When `value` is a CSS length (e.g. `"500px"`, `"740px"`): the row is capped at that width.
1468
+ * @param {?HTMLElement} el Target element (`.se-btn-tray`)
1469
+ * @param {string} value CSS length, `'auto'` for center-only, or empty for no constraint
1470
+ */
1471
+ function _applyToolbarInnerWidth(el, value) {
1472
+ if (!el || !value) return;
1473
+ if (value !== 'auto') el.style.maxWidth = value;
1474
+ el.style.width = 'max-content';
1475
+ el.style.marginLeft = 'auto';
1476
+ el.style.marginRight = 'auto';
1477
+ }
1478
+
1479
+ /**
1480
+ * @description Resolves a button key to its toolbar metadata.
1481
+ * Checks plugins first, then falls back to the default button list.
1482
+ * Same resolution logic as `CreateToolBar`.
1483
+ * @param {string} key Button name
1484
+ * @param {?Object<string, *>} plugins Plugin instances
1485
+ * @param {SunEditor.Options} options Options map
1486
+ * @param {Object<string, string>} icons Icons
1487
+ * @param {Object<string, string>} lang Language object
1488
+ * @returns {{className: string, title: string, command: string, type: string, icon: string}|null}
1489
+ */
1490
+ export function ResolveButton(key, plugins, options, icons, lang) {
1491
+ const plugin = plugins?.[key];
1492
+ if (plugin) {
1493
+ const s = typeof plugin === 'function' ? plugin : plugin.constructor;
1494
+ return {
1495
+ className: plugin.className || s.className || '',
1496
+ title: lang[plugin.title] || plugin.title || lang[s.title] || s.title || key,
1497
+ command: key,
1498
+ type: plugin.type || s.type || '',
1499
+ icon: icons[plugin.icon] || plugin.icon || icons[s.icon] || s.icon || '',
1500
+ };
1501
+ }
1502
+
1503
+ const defaults = _defaultButtons(options.get('_rtl'), icons, lang);
1504
+ const def = defaults[key];
1505
+ if (def) {
1506
+ return {
1507
+ className: def[0],
1508
+ title: def[1],
1509
+ command: def[2],
1510
+ type: def[3],
1511
+ icon: def[4],
1512
+ };
1513
+ }
1514
+
1515
+ return null;
1516
+ }
1517
+
1135
1518
  /**
1136
1519
  * @description SunEditor's default button list
1137
1520
  * @param {boolean} isRTL `rtl`
@@ -1151,7 +1534,13 @@ function _defaultButtons(isRTL, icons, lang) {
1151
1534
  fullScreen: ['se-code-view-enabled se-component-enabled', lang.fullScreen, 'fullScreen', '', icons.expansion],
1152
1535
  showBlocks: ['', lang.showBlocks, 'showBlocks', '', icons.show_blocks],
1153
1536
  codeView: ['se-code-view-enabled se-component-enabled', lang.codeView, 'codeView', '', icons.code_view],
1154
- markdownView: ['se-code-view-enabled se-component-enabled', lang.markdownView, 'markdownView', '', icons.markdown_view],
1537
+ markdownView: [
1538
+ 'se-code-view-enabled se-component-enabled',
1539
+ lang.markdownView,
1540
+ 'markdownView',
1541
+ '',
1542
+ icons.markdown_view,
1543
+ ],
1155
1544
  undo: ['se-component-enabled', lang.undo, 'undo', '', icons.undo],
1156
1545
  redo: ['se-component-enabled', lang.redo, 'redo', '', icons.redo],
1157
1546
  preview: ['se-component-enabled', lang.preview, 'preview', '', icons.preview],
@@ -1259,7 +1648,10 @@ export function UpdateButton(element, plugin, icons, lang) {
1259
1648
  } else {
1260
1649
  element.innerHTML = noneInner
1261
1650
  ? ''
1262
- : (plugin.inner || icons[plugin.icon] || plugin.icon || '<span class="se-icon-text">!</span>') + '<span class="se-tooltip-inner"><span class="se-tooltip-text">' + (lang[plugin.title] || plugin.title) + '</span></span>';
1651
+ : (plugin.inner || icons[plugin.icon] || plugin.icon || '<span class="se-icon-text">!</span>') +
1652
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' +
1653
+ (lang[plugin.title] || plugin.title) +
1654
+ '</span></span>';
1263
1655
  }
1264
1656
 
1265
1657
  element.setAttribute('aria-label', plugin.title);
@@ -1361,7 +1753,14 @@ export function CreateToolBar(buttonList, plugins, options, icons, lang, isUpdat
1361
1753
  modules = [plugin.className, plugin.title, button, plugin.type, plugin.innerHTML, plugin._disabled];
1362
1754
  } else if (typeof plugin === 'object') {
1363
1755
  const originFnc = plugin.constructor;
1364
- modules = [plugin.className || originFnc.className, plugin.title || originFnc.title, button, plugin.type || originFnc.type, plugin.innerHTML || originFnc.innerHTML, plugin._disabled || originFnc._disabled];
1756
+ modules = [
1757
+ plugin.className || originFnc.className,
1758
+ plugin.title || originFnc.title,
1759
+ button,
1760
+ plugin.type || originFnc.type,
1761
+ plugin.innerHTML || originFnc.innerHTML,
1762
+ plugin._disabled || originFnc._disabled,
1763
+ ];
1365
1764
  } else {
1366
1765
  // align
1367
1766
  if (/^-/.test(button)) {
@@ -1384,26 +1783,52 @@ export function CreateToolBar(buttonList, plugins, options, icons, lang, isUpdat
1384
1783
  moreCommand = '__se__more_' + i;
1385
1784
  const title = matched[1].trim();
1386
1785
  const innerHTML = matched[2].trim();
1387
- modules = ['se-btn-more', /^lang\./i.test(title) ? lang[title.replace(/^lang\./i, '')] : title, moreCommand, 'MORE', innerHTML];
1786
+ modules = [
1787
+ 'se-btn-more',
1788
+ /^lang\./i.test(title) ? lang[title.replace(/^lang\./i, '')] : title,
1789
+ moreCommand,
1790
+ 'MORE',
1791
+ innerHTML,
1792
+ ];
1388
1793
  } else if (button === '|') {
1389
1794
  // separator vertical
1390
1795
  modules = ['se-toolbar-separator-vertical', '', '', 'separator', ''];
1391
1796
  } else {
1392
1797
  // default command
1393
1798
  if (button === 'copy' && !env.isClipboardSupported) {
1394
- console.warn('[SUNEDITOR.constructor.warn] Clipboard is not supported in this browser. : [copy] button is not rendered.');
1799
+ console.warn(
1800
+ '[SUNEDITOR.constructor.warn] Clipboard is not supported in this browser. : [copy] button is not rendered.',
1801
+ );
1395
1802
  }
1396
1803
  modules = defaultButtonList[button];
1397
1804
  }
1398
1805
 
1399
1806
  if (!modules) {
1400
- if (!plugin) throw Error(`[SUNEDITOR.create.toolbar.fail] The button name of a plugin that does not exist. [${button}]`);
1807
+ if (!plugin)
1808
+ throw Error(
1809
+ `[SUNEDITOR.create.toolbar.fail] The button name of a plugin that does not exist. [${button}]`,
1810
+ );
1401
1811
  plugin = typeof plugin === 'object' ? plugin.constructor : plugin;
1402
- modules = [plugin.className, plugin.title, plugin.key, plugin.type, plugin.innerHTML, plugin._disabled];
1812
+ modules = [
1813
+ plugin.className,
1814
+ plugin.title,
1815
+ plugin.key,
1816
+ plugin.type,
1817
+ plugin.innerHTML,
1818
+ plugin._disabled,
1819
+ ];
1403
1820
  }
1404
1821
  }
1405
1822
 
1406
- buttonElement = _createButton(modules[0], modules[1], modules[2], modules[3], modules[4], modules[5], icons);
1823
+ buttonElement = _createButton(
1824
+ modules[0],
1825
+ modules[1],
1826
+ modules[2],
1827
+ modules[3],
1828
+ modules[4],
1829
+ modules[5],
1830
+ icons,
1831
+ );
1407
1832
  (more ? moreContainer : moduleElement.ul).appendChild(buttonElement.li);
1408
1833
 
1409
1834
  if (plugin) {
@@ -1424,7 +1849,10 @@ export function CreateToolBar(buttonList, plugins, options, icons, lang, isUpdat
1424
1849
  moreContainer = dom.utils.createElement('DIV');
1425
1850
  moreContainer.className = 'se-more-layer ' + moreCommand;
1426
1851
  moreContainer.setAttribute('data-ref', moreCommand);
1427
- moreContainer.innerHTML = '<div class="se-more-form"><ul class="se-menu-list"' + (align ? ' style="float: ' + align + ';"' : '') + '></ul></div>';
1852
+ moreContainer.innerHTML =
1853
+ '<div class="se-more-form"><ul class="se-menu-list"' +
1854
+ (align ? ' style="float: ' + align + ';"' : '') +
1855
+ '></ul></div>';
1428
1856
  moreLayer.appendChild(moreContainer);
1429
1857
  moreContainer = moreContainer.firstElementChild.firstElementChild;
1430
1858
  }
@@ -1462,8 +1890,14 @@ export function CreateToolBar(buttonList, plugins, options, icons, lang, isUpdat
1462
1890
  if (moreLayer.children.length > 0) buttonTray.appendChild(moreLayer);
1463
1891
  if (responsiveButtons.length > 0) responsiveButtons.unshift(buttonList);
1464
1892
 
1893
+ _applyToolbarInnerWidth(buttonTray, options.get('toolbar_innerWidth'));
1894
+
1465
1895
  // rendering toolbar
1466
- const tool_bar = dom.utils.createElement('DIV', { class: 'se-toolbar sun-editor-common' + (!options.get('shortcutsHint') ? ' se-shortcut-hide' : '') }, buttonTray);
1896
+ const tool_bar = dom.utils.createElement(
1897
+ 'DIV',
1898
+ { class: 'se-toolbar sun-editor-common' + (!options.get('shortcutsHint') ? ' se-shortcut-hide' : '') },
1899
+ buttonTray,
1900
+ );
1467
1901
 
1468
1902
  if (options.get('toolbar_hide')) tool_bar.style.display = 'none';
1469
1903