suneditor 3.1.4 → 3.2.1

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 (217) 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 +481 -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 +162 -30
  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 +84 -2
  22. package/src/core/event/handlers/handler_ww_key.js +82 -21
  23. package/src/core/event/handlers/handler_ww_mouse.js +45 -8
  24. package/src/core/event/ports.js +27 -13
  25. package/src/core/event/reducers/keydown.reducer.js +33 -5
  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 +350 -72
  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 +46 -4
  57. package/src/core/section/constructor.js +537 -106
  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 +58 -14
  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 +156 -36
  98. package/src/modules/contract/HueSlider.js +27 -4
  99. package/src/modules/contract/Modal.js +50 -10
  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 +33 -6
  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 +2 -1
  106. package/src/plugins/browser/fileBrowser.js +9 -2
  107. package/src/plugins/browser/fileGallery.js +2 -1
  108. package/src/plugins/browser/imageGallery.js +18 -3
  109. package/src/plugins/browser/videoGallery.js +13 -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 +92 -22
  143. package/src/plugins/modal/image/index.js +114 -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 +13 -3
  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 +11 -4
  173. package/types/core/event/reducers/keydown.reducer.d.ts +12 -3
  174. package/types/core/event/rules/keydown.rule.backspace.d.ts +6 -1
  175. package/types/core/kernel/store.d.ts +4 -1
  176. package/types/core/logic/dom/format.d.ts +32 -14
  177. package/types/core/logic/dom/html.d.ts +11 -3
  178. package/types/core/logic/dom/nodeTransform.d.ts +6 -6
  179. package/types/core/logic/panel/blockHandle.d.ts +64 -0
  180. package/types/core/logic/panel/blockResolver.d.ts +50 -0
  181. package/types/core/logic/panel/menu.d.ts +72 -3
  182. package/types/core/logic/shell/commandDispatcher.d.ts +8 -0
  183. package/types/core/logic/shell/component.d.ts +5 -3
  184. package/types/core/logic/shell/shortcuts.d.ts +10 -1
  185. package/types/core/logic/shell/ui.d.ts +7 -1
  186. package/types/core/schema/context.d.ts +7 -1
  187. package/types/core/schema/frameContext.d.ts +36 -4
  188. package/types/core/schema/options.d.ts +83 -2
  189. package/types/core/section/constructor.d.ts +38 -1
  190. package/types/events.d.ts +208 -32
  191. package/types/helper/converter.d.ts +4 -2
  192. package/types/helper/dom/domCheck.d.ts +12 -2
  193. package/types/helper/dom/domQuery.d.ts +35 -7
  194. package/types/helper/dom/domUtils.d.ts +4 -1
  195. package/types/interfaces/plugins.d.ts +2 -2
  196. package/types/langs/_Lang.d.ts +0 -1
  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/SelectMenu.d.ts +56 -3
  202. package/types/modules/ui/index.d.ts +1 -0
  203. package/types/plugins/browser/audioGallery.d.ts +1 -1
  204. package/types/plugins/browser/fileBrowser.d.ts +1 -1
  205. package/types/plugins/browser/fileGallery.d.ts +1 -1
  206. package/types/plugins/browser/imageGallery.d.ts +1 -1
  207. package/types/plugins/browser/videoGallery.d.ts +1 -1
  208. package/types/plugins/dropdown/align.d.ts +1 -1
  209. package/types/plugins/dropdown/blockStyle.d.ts +3 -1
  210. package/types/plugins/dropdown/table/index.d.ts +4 -1
  211. package/types/plugins/dropdown/table/services/table.clipboard.d.ts +5 -1
  212. package/types/plugins/dropdown/table/services/table.grid.d.ts +10 -2
  213. package/types/plugins/field/autocomplete.d.ts +0 -1
  214. package/types/plugins/field/slashCommand.d.ts +165 -0
  215. package/types/plugins/index.d.ts +3 -0
  216. package/types/plugins/modal/link.d.ts +4 -1
  217. 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,30 +59,29 @@ 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);
68
- // focus temp element
69
- const focusTemp = /** @type {HTMLInputElement} */ (
70
- dom.utils.createElement('INPUT', {
71
- type: 'text',
72
- id: editorFormFieldPrefix + '-focus-temp',
73
- class: '__se__focus__temp__',
74
- autocomplete: 'off',
75
- 'aria-hidden': 'true',
76
- style: 'position: fixed !important; top: -10000px !important; left: -10000px !important; display: block !important; width: 0 !important; height: 0 !important; margin: 0 !important; padding: 0 !important;',
77
- })
78
- );
79
- focusTemp.tabIndex = 0;
80
- editor_carrier_wrapper.appendChild(focusTemp);
81
79
 
82
80
  // modal
83
- const modal = dom.utils.createElement('DIV', { class: 'se-modal se-modal-area sun-editor-common', popover: 'manual' });
81
+ const modal = dom.utils.createElement('DIV', {
82
+ class: 'se-modal se-modal-area sun-editor-common',
83
+ popover: 'manual',
84
+ });
84
85
  const modal_back = dom.utils.createElement('DIV', { class: 'se-modal-back' });
85
86
  const modal_inner = dom.utils.createElement('DIV', { class: 'se-modal-inner' });
86
87
  modal.appendChild(modal_back);
@@ -88,7 +89,11 @@ function Constructor(editorTargets, options) {
88
89
  editor_carrier_wrapper.appendChild(modal);
89
90
 
90
91
  // alert
91
- const alert = dom.utils.createElement('DIV', { class: 'se-alert se-modal-area sun-editor-common', style: 'display: none;', popover: 'manual' });
92
+ const alert = dom.utils.createElement('DIV', {
93
+ class: 'se-alert se-modal-area sun-editor-common',
94
+ style: 'display: none;',
95
+ popover: 'manual',
96
+ });
92
97
  const alert_back = dom.utils.createElement('DIV', { class: 'se-modal-back' });
93
98
  const alert_inner = dom.utils.createElement('DIV', { class: 'se-modal-inner' });
94
99
  alert.appendChild(alert_back);
@@ -147,9 +152,22 @@ function Constructor(editorTargets, options) {
147
152
  for (let i = 0, len = editorTargets.length; i < len; i++) {
148
153
  const editTarget = editorTargets[i];
149
154
  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' : '') });
155
+ const top_div = dom.utils.createElement('DIV', {
156
+ class: 'sun-editor' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : ''),
157
+ });
151
158
  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' : '') });
159
+ const isBlockHandle = !!o.get('blockHandle');
160
+ const editor_div = dom.utils.createElement('DIV', {
161
+ class:
162
+ 'se-wrapper' +
163
+ (isBlockHandle ? ' se-mode-block' : '') +
164
+ (o.get('type') === 'document' ? ' se-type-document' : '') +
165
+ (o.get('_type_options').includes('header') ? ' se-type-document-header' : ''),
166
+ });
167
+
168
+ const editorInnerW = to.get('innerWidth');
169
+ if (editorInnerW && editorInnerW !== 'auto')
170
+ editor_div.style.setProperty('--se-editor-inner-width', editorInnerW);
153
171
 
154
172
  container.appendChild(dom.utils.createElement('DIV', { class: 'se-toolbar-shadow' }));
155
173
 
@@ -162,8 +180,16 @@ function Constructor(editorTargets, options) {
162
180
  let textarea = initElements.codeView;
163
181
 
164
182
  // 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);
183
+ const line_breaker_t = dom.utils.createElement(
184
+ 'DIV',
185
+ { class: 'se-line-breaker-component se-line-breaker-component-t', title: lang.insertLine },
186
+ icons.line_break,
187
+ );
188
+ const line_breaker_b = dom.utils.createElement(
189
+ 'DIV',
190
+ { class: 'se-line-breaker-component se-line-breaker-component-b', title: lang.insertLine },
191
+ icons.line_break,
192
+ );
167
193
 
168
194
  editor_div.appendChild(line_breaker_t);
169
195
  editor_div.appendChild(line_breaker_b);
@@ -177,7 +203,9 @@ function Constructor(editorTargets, options) {
177
203
  if (statusbar) {
178
204
  if (statusbarContainer) {
179
205
  if (!default_status_bar) {
180
- statusbarContainer.appendChild(dom.utils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') }, statusbar));
206
+ statusbarContainer.appendChild(
207
+ dom.utils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') }, statusbar),
208
+ );
181
209
  default_status_bar = statusbar;
182
210
  }
183
211
  } else {
@@ -205,7 +233,14 @@ function Constructor(editorTargets, options) {
205
233
  // add line nubers
206
234
  const codeNumbers = dom.utils.createElement(
207
235
  'TEXTAREA',
208
- { id: editorFormFieldPrefix + '-code-view-line-' + (key || 'default'), class: 'se-code-view-line', readonly: 'true', autocomplete: 'off', 'aria-hidden': 'true', tabindex: '-1' },
236
+ {
237
+ id: editorFormFieldPrefix + '-code-view-line-' + (key || 'default'),
238
+ class: 'se-code-view-line',
239
+ readonly: 'true',
240
+ autocomplete: 'off',
241
+ 'aria-hidden': 'true',
242
+ tabindex: '-1',
243
+ },
209
244
  null,
210
245
  );
211
246
  codeWrapper.insertBefore(codeNumbers, textarea);
@@ -221,7 +256,14 @@ function Constructor(editorTargets, options) {
221
256
  markdownTextarea = initElements.markdownView;
222
257
  const markdownNumbers = dom.utils.createElement(
223
258
  'TEXTAREA',
224
- { id: editorFormFieldPrefix + '-markdown-view-line-' + (key || 'default'), class: 'se-markdown-view-line', readonly: 'true', autocomplete: 'off', 'aria-hidden': 'true', tabindex: '-1' },
259
+ {
260
+ id: editorFormFieldPrefix + '-markdown-view-line-' + (key || 'default'),
261
+ class: 'se-markdown-view-line',
262
+ readonly: 'true',
263
+ autocomplete: 'off',
264
+ 'aria-hidden': 'true',
265
+ tabindex: '-1',
266
+ },
225
267
  null,
226
268
  );
227
269
  markdownWrapper = dom.utils.createElement('DIV', { class: 'se-markdown-wrapper' });
@@ -234,7 +276,11 @@ function Constructor(editorTargets, options) {
234
276
  // document type
235
277
  const documentTypeInner = { inner: null, page: null, pageMirror: null };
236
278
  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>');
279
+ documentTypeInner.inner = dom.utils.createElement(
280
+ 'DIV',
281
+ { class: 'se-document-lines', style: `height: ${to.get('height')};` },
282
+ '<div class="se-document-lines-inner"></div>',
283
+ );
238
284
  }
239
285
  if (o.get('_type_options').includes('page')) {
240
286
  documentTypeInner.page = dom.utils.createElement('DIV', { class: 'se-document-page' }, null);
@@ -248,12 +294,46 @@ function Constructor(editorTargets, options) {
248
294
  );
249
295
  }
250
296
 
297
+ // block handle
298
+ let blockHandleArea = null;
299
+ if (isBlockHandle) {
300
+ blockHandleArea = dom.utils.createElement('DIV', { class: 'se-block-handle-area' });
301
+
302
+ const blockHandleGroup = dom.utils.createElement('DIV', { class: 'se-block-handle' });
303
+ const blockHandlePlus = dom.utils.createElement(
304
+ 'DIV',
305
+ { class: 'se-block-handle-btn se-block-handle-plus' },
306
+ icons.plus,
307
+ );
308
+ const blockHandleDrag = dom.utils.createElement(
309
+ 'DIV',
310
+ { class: 'se-block-handle-btn se-block-handle-drag' },
311
+ icons.dragHandle,
312
+ );
313
+ blockHandleGroup.appendChild(blockHandlePlus);
314
+ blockHandleGroup.appendChild(blockHandleDrag);
315
+
316
+ blockHandleArea.appendChild(blockHandleGroup);
317
+ }
318
+
251
319
  // set container
252
320
  top_div.appendChild(container);
253
321
  rootKeys.push(key);
254
322
  frameRoots.set(
255
323
  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),
324
+ CreateFrameContext(
325
+ { target: editTarget.target, key: editTarget.key, options: to },
326
+ top_div,
327
+ wysiwyg_div,
328
+ codeWrapper,
329
+ textarea,
330
+ markdownWrapper,
331
+ markdownTextarea,
332
+ default_status_bar || statusbar,
333
+ documentTypeInner,
334
+ blockHandleArea,
335
+ key,
336
+ ),
257
337
  );
258
338
  }
259
339
  /** frame - root set - end -------------------------------------------------------------- */
@@ -261,7 +341,9 @@ function Constructor(editorTargets, options) {
261
341
  // toolbar container
262
342
  const toolbar_container = o.get('toolbar_container');
263
343
  if (toolbar_container) {
264
- const top_div = dom.utils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : '') });
344
+ const top_div = dom.utils.createElement('DIV', {
345
+ class: 'sun-editor' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : ''),
346
+ });
265
347
  const container = dom.utils.createElement('DIV', { class: 'se-container' });
266
348
  container.appendChild(toolbar);
267
349
  if (subbar) container.appendChild(subbar);
@@ -311,7 +393,11 @@ export function CreateShortcuts(command, button, values, keyMap, rc, reverseKeys
311
393
  if (!values || values.length < 2) return;
312
394
  const tooptip = button?.querySelector('.se-tooltip-text');
313
395
 
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) {
396
+ for (
397
+ let i = 0, a, v, c, s, edge, space, enter, textTrigger, plugin, method, t, k, r, _i;
398
+ i < values.length;
399
+ i += 2 + _i
400
+ ) {
315
401
  _i = 0;
316
402
  a = values[i].split('+');
317
403
 
@@ -368,7 +454,21 @@ export function CreateShortcuts(command, button, values, keyMap, rc, reverseKeys
368
454
  r = r === -1 ? '' : numbers.isOdd(r) ? rc[r + 1] : rc[r - 1];
369
455
  if (r) reverseKeys.add(k);
370
456
 
371
- keyMap.set(k, { c, s, edge, space, enter, textTrigger, plugin, command, method, r, type: button?.getAttribute('data-type'), button, key: k });
457
+ keyMap.set(k, {
458
+ c,
459
+ s,
460
+ edge,
461
+ space,
462
+ enter,
463
+ textTrigger,
464
+ plugin,
465
+ command,
466
+ method,
467
+ r,
468
+ type: button?.getAttribute('data-type'),
469
+ button,
470
+ key: k,
471
+ });
372
472
  }
373
473
  }
374
474
 
@@ -384,7 +484,11 @@ export function CreateShortcuts(command, button, values, keyMap, rc, reverseKeys
384
484
  * @param {string} shortcut
385
485
  */
386
486
  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>');
487
+ const tooltip = dom.utils.createElement(
488
+ 'SPAN',
489
+ { class: 'se-shortcut' },
490
+ env.cmdIcon + (shift ? env.shiftIcon : '') + '+<span class="se-shortcut-key">' + shortcut + '</span>',
491
+ );
388
492
  const prevTooltip = tooptipBtn.querySelector('.se-shortcut');
389
493
 
390
494
  if (prevTooltip) {
@@ -434,7 +538,10 @@ export function InitOptions(options, editorTargets, plugins) {
434
538
 
435
539
  /** Multi root */
436
540
  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.');
541
+ if (!options.toolbar_container && !/inline|balloon/i.test(options.mode))
542
+ throw Error(
543
+ '[SUNEDITOR.create.fail] In multi root, The "mode" option cannot be "classic" without using the "toolbar_container" option.',
544
+ );
438
545
  }
439
546
 
440
547
  // migration data-.+
@@ -459,13 +566,27 @@ export function InitOptions(options, editorTargets, plugins) {
459
566
  const [modeBase, modePart] = (options.mode || 'classic').split(':');
460
567
  o.set('mode', modeBase); // classic, inline, balloon, balloon-always
461
568
  o.set('_toolbar_bottom', modePart === 'bottom' && /^(classic|inline)$/i.test(modeBase));
569
+ o.set(
570
+ 'blockHandle',
571
+ options.blockHandle ? (typeof options.blockHandle === 'object' ? options.blockHandle : {}) : null,
572
+ );
462
573
  o.set('type', options.type?.split(':')[0] || ''); // document:header,page
463
574
  o.set('theme', options.theme || '');
464
575
  o.set('_themeClass', options.theme ? ` se-theme-${options.theme}` : '');
465
576
  o.set('_type_options', options.type?.split(':')[1] || '');
466
577
  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}`));
578
+ o.set(
579
+ 'fontSizeUnits',
580
+ Array.isArray(options.fontSizeUnits) && options.fontSizeUnits.length > 0
581
+ ? options.fontSizeUnits.map((v) => v.toLowerCase())
582
+ : DEFAULTS.SIZE_UNITS,
583
+ );
584
+ o.set(
585
+ 'allowedClassName',
586
+ new RegExp(
587
+ `${options.allowedClassName && typeof options.allowedClassName === 'string' ? options.allowedClassName + '|' : ''}${DEFAULTS.CLASS_NAME}`,
588
+ ),
589
+ );
469
590
  o.set('closeModalOutsideClick', !!options.closeModalOutsideClick);
470
591
 
471
592
  // format
@@ -474,11 +595,16 @@ export function InitOptions(options, editorTargets, plugins) {
474
595
 
475
596
  // auto convert on paste
476
597
  o.set('autoLinkify', options.autoLinkify ?? !!plugins.link);
477
- o.set('autoStyleify', Array.isArray(options.autoStyleify) ? options.autoStyleify : ['bold', 'underline', 'italic', 'strike']);
598
+ o.set(
599
+ 'autoStyleify',
600
+ Array.isArray(options.autoStyleify) ? options.autoStyleify : ['bold', 'underline', 'italic', 'strike'],
601
+ );
478
602
 
479
603
  let retainStyleMode = options.retainStyleMode || 'repeat';
480
604
  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'.`);
605
+ console.error(
606
+ `Invalid retainStyleMode: ${retainStyleMode}. Valid options are ${DEFAULTS.RETAIN_STYLE_MODE.join(', ')}. Using default 'repeat'.`,
607
+ );
482
608
  retainStyleMode = 'repeat';
483
609
  }
484
610
  o.set('retainStyleMode', retainStyleMode);
@@ -493,7 +619,11 @@ export function InitOptions(options, editorTargets, plugins) {
493
619
  o.set('events', options.events || {});
494
620
 
495
621
  // text style tags
496
- o.set('textStyleTags', (typeof options.__textStyleTags === 'string' ? options.__textStyleTags : DEFAULTS.TEXT_STYLE_TAGS) + (options.textStyleTags ? '|' + options.textStyleTags : ''));
622
+ o.set(
623
+ 'textStyleTags',
624
+ (typeof options.__textStyleTags === 'string' ? options.__textStyleTags : DEFAULTS.TEXT_STYLE_TAGS) +
625
+ (options.textStyleTags ? '|' + options.textStyleTags : ''),
626
+ );
497
627
  const textTags = _mergeObject(
498
628
  {
499
629
  bold: 'strong',
@@ -509,12 +639,15 @@ export function InitOptions(options, editorTargets, plugins) {
509
639
  o.set('_textStyleTags', Object.values(textTags).concat(['span', 'li']));
510
640
  o.set(
511
641
  '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
- }, {}),
642
+ [{ ...DEFAULTS.TAG_STYLES, ...(options.__tagStyles || {}) }, options.tagStyles || {}].reduce(
643
+ (_default, _new) => {
644
+ for (const key in _new) {
645
+ _default[key] = _new[key];
646
+ }
647
+ return _default;
648
+ },
649
+ {},
650
+ ),
518
651
  );
519
652
  o.set('_defaultStyleTagMap', {
520
653
  strong: textTags.bold,
@@ -560,36 +693,79 @@ export function InitOptions(options, editorTargets, plugins) {
560
693
  o.set('reverseCommands', ['indent-outdent'].concat(options.reverseButtons || []));
561
694
  o.set('_reverseCommandArray', ('-' + o.get('reverseCommands').join('-')).split('-'));
562
695
  if (numbers.isEven(o.get('_reverseCommandArray').length)) {
563
- console.warn('[SUNEDITOR.create.warning] The "reverseCommands" option is invalid, Shortcuts key may not work properly.');
696
+ console.warn(
697
+ '[SUNEDITOR.create.warning] The "reverseCommands" option is invalid, Shortcuts key may not work properly.',
698
+ );
564
699
  }
565
700
 
566
701
  // etc
567
- o.set('historyStackDelayTime', typeof options.historyStackDelayTime === 'number' ? options.historyStackDelayTime : 400);
568
- o.set('historyStackSize', typeof options.historyStackSize === 'number' && options.historyStackSize > 0 ? options.historyStackSize : 100);
569
- o.set('_editableClass', 'sun-editor-editable' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : '') + (o.get('type') === 'document' ? ' se-type-document-editable-a4' : ''));
570
- o.set('lineAttrReset', ['id'].concat(options.lineAttrReset && typeof options.lineAttrReset === 'string' ? options.lineAttrReset.toLowerCase().split('|') : []));
571
- o.set('printClass', typeof options.printClass === 'string' ? options.printClass + ' ' + o.get('_editableClass') : null);
702
+ o.set(
703
+ 'historyStackDelayTime',
704
+ typeof options.historyStackDelayTime === 'number' ? options.historyStackDelayTime : 400,
705
+ );
706
+ o.set(
707
+ 'historyStackSize',
708
+ typeof options.historyStackSize === 'number' && options.historyStackSize > 0 ? options.historyStackSize : 100,
709
+ );
710
+ o.set(
711
+ '_editableClass',
712
+ 'sun-editor-editable' +
713
+ o.get('_themeClass') +
714
+ (o.get('_rtl') ? ' se-rtl' : '') +
715
+ (o.get('type') === 'document' ? ' se-type-document-editable-a4' : ''),
716
+ );
717
+ o.set(
718
+ 'lineAttrReset',
719
+ ['id'].concat(
720
+ options.lineAttrReset && typeof options.lineAttrReset === 'string'
721
+ ? options.lineAttrReset.toLowerCase().split('|')
722
+ : [],
723
+ ),
724
+ );
725
+ o.set(
726
+ 'printClass',
727
+ typeof options.printClass === 'string' ? options.printClass + ' ' + o.get('_editableClass') : null,
728
+ );
572
729
 
573
730
  /** whitelist, blacklist */
574
731
  // default line
575
- o.set('defaultLine', typeof options.defaultLine === 'string' && options.defaultLine.length > 0 ? options.defaultLine : 'p');
732
+ o.set(
733
+ 'defaultLine',
734
+ typeof options.defaultLine === 'string' && options.defaultLine.length > 0 ? options.defaultLine : 'p',
735
+ );
576
736
  o.set('defaultLineBreakFormat', options.defaultLineBreakFormat || 'line');
577
737
  o.set('scopeSelectionTags', options.scopeSelectionTags || DEFAULTS.SCOPE_SELECTION_TAGS);
578
738
  // element
579
739
  const elw = (typeof options.elementWhitelist === 'string' ? options.elementWhitelist : '').toLowerCase();
580
740
  const mjxEls = o.get('externalLibs').mathjax ? DEFAULTS.CLASS_MJX + '|' : '';
581
741
  o.set('elementWhitelist', elw + (elw ? '|' : '') + mjxEls + o.get('_allowedExtraTag'));
582
- const elb = _createBlacklist((typeof options.elementBlacklist === 'string' ? options.elementBlacklist : '').toLowerCase(), o.get('defaultLine'));
742
+ const elb = _createBlacklist(
743
+ (typeof options.elementBlacklist === 'string' ? options.elementBlacklist : '').toLowerCase(),
744
+ o.get('defaultLine'),
745
+ );
583
746
  o.set('elementBlacklist', elb + (elb ? '|' : '') + o.get('_disallowedExtraTag'));
584
747
  // attribute
585
- o.set('attributeWhitelist', !options.attributeWhitelist || typeof options.attributeWhitelist !== 'object' ? null : options.attributeWhitelist);
586
- o.set('attributeBlacklist', !options.attributeBlacklist || typeof options.attributeBlacklist !== 'object' ? null : options.attributeBlacklist);
748
+ o.set(
749
+ 'attributeWhitelist',
750
+ !options.attributeWhitelist || typeof options.attributeWhitelist !== 'object'
751
+ ? null
752
+ : options.attributeWhitelist,
753
+ );
754
+ o.set(
755
+ 'attributeBlacklist',
756
+ !options.attributeBlacklist || typeof options.attributeBlacklist !== 'object'
757
+ ? null
758
+ : options.attributeBlacklist,
759
+ );
587
760
  // format tag
588
761
  o.set(
589
762
  'formatClosureBrLine',
590
763
  _createFormatInfo(
591
764
  options.formatClosureBrLine,
592
- (options.__defaultFormatClosureBrLine = typeof options.__defaultFormatClosureBrLine === 'string' ? options.__defaultFormatClosureBrLine : DEFAULTS.FORMAT_CLOSURE_BR_LINE).toLowerCase(),
765
+ (options.__defaultFormatClosureBrLine =
766
+ typeof options.__defaultFormatClosureBrLine === 'string'
767
+ ? options.__defaultFormatClosureBrLine
768
+ : DEFAULTS.FORMAT_CLOSURE_BR_LINE).toLowerCase(),
593
769
  o.get('elementBlacklist'),
594
770
  ),
595
771
  );
@@ -597,7 +773,10 @@ export function InitOptions(options, editorTargets, plugins) {
597
773
  'formatBrLine',
598
774
  _createFormatInfo(
599
775
  (options.formatBrLine || '') + '|' + o.get('formatClosureBrLine').str,
600
- (options.__defaultFormatBrLine = typeof options.__defaultFormatBrLine === 'string' ? options.__defaultFormatBrLine : DEFAULTS.FORMAT_BR_LINE).toLowerCase(),
776
+ (options.__defaultFormatBrLine =
777
+ typeof options.__defaultFormatBrLine === 'string'
778
+ ? options.__defaultFormatBrLine
779
+ : DEFAULTS.FORMAT_BR_LINE).toLowerCase(),
601
780
  o.get('elementBlacklist'),
602
781
  ),
603
782
  );
@@ -605,21 +784,29 @@ export function InitOptions(options, editorTargets, plugins) {
605
784
  'formatLine',
606
785
  _createFormatInfo(
607
786
  DEFAULTS.REQUIRED_FORMAT_LINE + '|' + (options.formatLine || '') + '|' + o.get('formatBrLine').str,
608
- (options.__defaultFormatLine = typeof options.__defaultFormatLine === 'string' ? options.__defaultFormatLine : DEFAULTS.FORMAT_LINE).toLowerCase(),
787
+ (options.__defaultFormatLine =
788
+ typeof options.__defaultFormatLine === 'string'
789
+ ? options.__defaultFormatLine
790
+ : DEFAULTS.FORMAT_LINE).toLowerCase(),
609
791
  o.get('elementBlacklist'),
610
792
  ),
611
793
  );
612
794
 
613
795
  // Error - default line
614
796
  if (!o.get('formatLine').reg.test(o.get('defaultLine'))) {
615
- throw Error(`[SUNEDITOR.create.fail] The "defaultLine(${o.get('defaultLine')})" option must be included in the "formatLine(${o.get('formatLine').str})" option.`);
797
+ throw Error(
798
+ `[SUNEDITOR.create.fail] The "defaultLine(${o.get('defaultLine')})" option must be included in the "formatLine(${o.get('formatLine').str})" option.`,
799
+ );
616
800
  }
617
801
 
618
802
  o.set(
619
803
  'formatClosureBlock',
620
804
  _createFormatInfo(
621
805
  options.formatClosureBlock,
622
- (options.__defaultFormatClosureBlock = typeof options.__defaultFormatClosureBlock === 'string' ? options.__defaultFormatClosureBlock : DEFAULTS.FORMAT_CLOSURE_BLOCK).toLowerCase(),
806
+ (options.__defaultFormatClosureBlock =
807
+ typeof options.__defaultFormatClosureBlock === 'string'
808
+ ? options.__defaultFormatClosureBlock
809
+ : DEFAULTS.FORMAT_CLOSURE_BLOCK).toLowerCase(),
623
810
  o.get('elementBlacklist'),
624
811
  ),
625
812
  );
@@ -627,22 +814,64 @@ export function InitOptions(options, editorTargets, plugins) {
627
814
  'formatBlock',
628
815
  _createFormatInfo(
629
816
  (options.formatBlock || '') + '|' + o.get('formatClosureBlock').str,
630
- (options.__defaultFormatBlock = typeof options.__defaultFormatBlock === 'string' ? options.__defaultFormatBlock : DEFAULTS.FORMAT_BLOCK).toLowerCase(),
817
+ (options.__defaultFormatBlock =
818
+ typeof options.__defaultFormatBlock === 'string'
819
+ ? options.__defaultFormatBlock
820
+ : DEFAULTS.FORMAT_BLOCK).toLowerCase(),
631
821
  o.get('elementBlacklist'),
632
822
  ),
633
823
  );
634
824
 
635
- o.set('allowedEmptyTags', DEFAULTS.ALLOWED_EMPTY_NODE_LIST + (options.allowedEmptyTags ? ', ' + options.allowedEmptyTags : ''));
825
+ o.set(
826
+ 'allowedEmptyTags',
827
+ DEFAULTS.ALLOWED_EMPTY_NODE_LIST + (options.allowedEmptyTags ? ', ' + options.allowedEmptyTags : ''),
828
+ );
636
829
 
637
830
  /** __defaults */
638
- o.set('__defaultElementWhitelist', DEFAULTS.REQUIRED_ELEMENT_WHITELIST + '|' + (typeof options.__defaultElementWhitelist === 'string' ? options.__defaultElementWhitelist : DEFAULTS.ELEMENT_WHITELIST).toLowerCase());
639
- o.set('__defaultAttributeWhitelist', (typeof options.__defaultAttributeWhitelist === 'string' ? options.__defaultAttributeWhitelist : DEFAULTS.ATTRIBUTE_WHITELIST).toLowerCase());
831
+ o.set(
832
+ '__defaultElementWhitelist',
833
+ DEFAULTS.REQUIRED_ELEMENT_WHITELIST +
834
+ '|' +
835
+ (typeof options.__defaultElementWhitelist === 'string'
836
+ ? options.__defaultElementWhitelist
837
+ : DEFAULTS.ELEMENT_WHITELIST
838
+ ).toLowerCase(),
839
+ );
840
+ o.set(
841
+ '__defaultAttributeWhitelist',
842
+ (typeof options.__defaultAttributeWhitelist === 'string'
843
+ ? options.__defaultAttributeWhitelist
844
+ : DEFAULTS.ATTRIBUTE_WHITELIST
845
+ ).toLowerCase(),
846
+ );
640
847
  // --- create element whitelist (__defaultElementWhiteList + elementWhitelist + format[line, BrLine, Block, Closureblock, ClosureBrLine] - elementBlacklist)
641
848
  o.set('_editorElementWhitelist', o.get('elementWhitelist') === '*' ? '*' : _createWhitelist(o));
642
849
 
643
850
  /** Toolbar */
644
- o.set('toolbar_width', options.toolbar_width ? (numbers.is(options.toolbar_width) ? options.toolbar_width + 'px' : options.toolbar_width) : 'auto');
645
- 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);
851
+ o.set(
852
+ 'toolbar_width',
853
+ options.toolbar_width
854
+ ? numbers.is(options.toolbar_width)
855
+ ? options.toolbar_width + 'px'
856
+ : options.toolbar_width
857
+ : 'auto',
858
+ );
859
+ o.set(
860
+ 'toolbar_innerWidth',
861
+ options.toolbar_innerWidth
862
+ ? numbers.is(options.toolbar_innerWidth)
863
+ ? options.toolbar_innerWidth + 'px'
864
+ : options.toolbar_innerWidth
865
+ : '',
866
+ );
867
+ o.set(
868
+ 'toolbar_container',
869
+ options.toolbar_container && !/inline/i.test(o.get('mode'))
870
+ ? typeof options.toolbar_container === 'string'
871
+ ? _d.querySelector(options.toolbar_container)
872
+ : options.toolbar_container
873
+ : null,
874
+ );
646
875
 
647
876
  const _stickyOpt = options.toolbar_sticky;
648
877
  const _isBalloon = /balloon/i.test(o.get('mode'));
@@ -664,10 +893,15 @@ export function InitOptions(options, editorTargets, plugins) {
664
893
  const subbar = options.subToolbar;
665
894
  if (subbar?.buttonList?.length > 0) {
666
895
  if (/balloon/.test(o.get('mode'))) {
667
- console.warn('[SUNEDITOR.create.subToolbar.fail] When the "mode" option is "balloon-*", the "subToolbar" option is omitted.');
896
+ console.warn(
897
+ '[SUNEDITOR.create.subToolbar.fail] When the "mode" option is "balloon-*", the "subToolbar" option is omitted.',
898
+ );
668
899
  } else {
669
900
  o.set('_subMode', subbar.mode || 'balloon');
670
- o.set('toolbar_sub_width', subbar.width ? (numbers.is(subbar.width) ? subbar.width + 'px' : subbar.width) : 'auto');
901
+ o.set(
902
+ 'toolbar_sub_width',
903
+ subbar.width ? (numbers.is(subbar.width) ? subbar.width + 'px' : subbar.width) : 'auto',
904
+ );
671
905
  subButtons = o.get('_rtl') ? subbar.buttonList.reverse() : subbar.buttonList;
672
906
  o.set('buttons_sub', new Set(subButtons.toString().split(',')));
673
907
  }
@@ -676,7 +910,10 @@ export function InitOptions(options, editorTargets, plugins) {
676
910
  /** root options */
677
911
  const frameMap = new Map();
678
912
  for (let i = 0, len = editorTargets.length; i < len; i++) {
679
- frameMap.set(editorTargets[i].key, InitFrameOptions(editorTargets[i].options || /** @type {SunEditor.InitFrameOptions} */ ({}), options));
913
+ frameMap.set(
914
+ editorTargets[i].key,
915
+ InitFrameOptions(editorTargets[i].options || /** @type {SunEditor.InitFrameOptions} */ ({}), options),
916
+ );
680
917
  }
681
918
 
682
919
  /** Key actions */
@@ -718,12 +955,24 @@ export function InitOptions(options, editorTargets, plugins) {
718
955
  o.set('shortcuts', shortcuts);
719
956
 
720
957
  /** View */
721
- o.set('fullScreenOffset', options.fullScreenOffset === undefined ? 0 : numbers.is(options.fullScreenOffset) ? numbers.get(options.fullScreenOffset, 0) : 0);
958
+ o.set(
959
+ 'fullScreenOffset',
960
+ options.fullScreenOffset === undefined
961
+ ? 0
962
+ : numbers.is(options.fullScreenOffset)
963
+ ? numbers.get(options.fullScreenOffset, 0)
964
+ : 0,
965
+ );
722
966
  o.set('previewTemplate', typeof options.previewTemplate === 'string' ? options.previewTemplate : null);
723
967
  o.set('printTemplate', typeof options.printTemplate === 'string' ? options.printTemplate : null);
724
968
 
725
969
  /** --- Media select */
726
- o.set('componentInsertBehavior', ['auto', 'select', 'line', 'none'].includes(options.componentInsertBehavior) ? options.componentInsertBehavior : 'auto');
970
+ o.set(
971
+ 'componentInsertBehavior',
972
+ ['auto', 'select', 'line', 'none'].includes(options.componentInsertBehavior)
973
+ ? options.componentInsertBehavior
974
+ : 'auto',
975
+ );
727
976
 
728
977
  /** --- Url input protocol */
729
978
  o.set('defaultUrlProtocol', typeof options.defaultUrlProtocol === 'string' ? options.defaultUrlProtocol : null);
@@ -736,13 +985,18 @@ export function InitOptions(options, editorTargets, plugins) {
736
985
  if (cm.src) {
737
986
  o.set('codeMirrorEditor', true);
738
987
  } else {
739
- 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');
988
+ console.warn(
989
+ '[SUNEDITOR.options.externalLibs.codeMirror.fail] The codeMirror option is set incorrectly. See: https://github.com/ARA-developer/suneditor/blob/develop/guide/external-libraries.md',
990
+ );
740
991
  o.set('codeMirror', null);
741
992
  }
742
993
  }
743
994
 
744
995
  /** Private options */
745
- o.set('__listCommonStyle', options.__listCommonStyle || ['fontSize', 'color', 'fontFamily', 'fontWeight', 'fontStyle']);
996
+ o.set(
997
+ '__listCommonStyle',
998
+ options.__listCommonStyle || ['fontSize', 'color', 'fontFamily', 'fontWeight', 'fontStyle'],
999
+ );
746
1000
 
747
1001
  /** --- Icons ------------------------------------------------------------------------------------------ */
748
1002
  const icons =
@@ -768,7 +1022,8 @@ export function InitOptions(options, editorTargets, plugins) {
768
1022
  for (let i = 0, len = _ls.length; i < len; i++) {
769
1023
  allUsedStyles.add(_ls[i]);
770
1024
  }
771
- const _aus = (typeof options.allUsedStyles === 'string' ? options.allUsedStyles.split('|') : options.allUsedStyles) || [];
1025
+ const _aus =
1026
+ (typeof options.allUsedStyles === 'string' ? options.allUsedStyles.split('|') : options.allUsedStyles) || [];
772
1027
  for (let i = 0, len = _aus.length; i < len; i++) {
773
1028
  allUsedStyles.add(_aus[i]);
774
1029
  }
@@ -782,7 +1037,10 @@ export function InitOptions(options, editorTargets, plugins) {
782
1037
  v: (options.value = typeof options.value === 'string' ? options.value : null),
783
1038
  buttons: o.get('_rtl') ? buttonList.reverse() : buttonList,
784
1039
  subButtons: subButtons,
785
- statusbarContainer: typeof options.statusbar_container === 'string' ? _d.querySelector(options.statusbar_container) : options.statusbar_container,
1040
+ statusbarContainer:
1041
+ typeof options.statusbar_container === 'string'
1042
+ ? _d.querySelector(options.statusbar_container)
1043
+ : options.statusbar_container,
786
1044
  frameMap: frameMap,
787
1045
  };
788
1046
  }
@@ -804,20 +1062,28 @@ export function CreateStatusbar(targetOptions, statusbar) {
804
1062
  statusbar ||= dom.utils.createElement('DIV', { class: 'se-status-bar sun-editor-common' });
805
1063
 
806
1064
  /** navigation */
807
- navigation = statusbar.querySelector('.se-navigation') || dom.utils.createElement('DIV', { class: 'se-navigation sun-editor-common' });
1065
+ navigation =
1066
+ statusbar.querySelector('.se-navigation') ||
1067
+ dom.utils.createElement('DIV', { class: 'se-navigation sun-editor-common' });
808
1068
  statusbar.appendChild(navigation);
809
1069
 
810
1070
  /** word counter (left) */
811
1071
  if (targetOptions.get('wordCounter')) {
812
- wordWrapper = statusbar.querySelector('.se-word-counter-wrapper') || dom.utils.createElement('DIV', { class: 'se-word-counter-wrapper' });
1072
+ wordWrapper =
1073
+ statusbar.querySelector('.se-word-counter-wrapper') ||
1074
+ dom.utils.createElement('DIV', { class: 'se-word-counter-wrapper' });
813
1075
 
814
1076
  if (targetOptions.get('wordCounter_label')) {
815
- const wordLabel = wordWrapper.querySelector('.se-word-label') || dom.utils.createElement('SPAN', { class: 'se-word-label' });
1077
+ const wordLabel =
1078
+ wordWrapper.querySelector('.se-word-label') ||
1079
+ dom.utils.createElement('SPAN', { class: 'se-word-label' });
816
1080
  wordLabel.textContent = targetOptions.get('wordCounter_label');
817
1081
  wordWrapper.appendChild(wordLabel);
818
1082
  }
819
1083
 
820
- wordCounter = wordWrapper.querySelector('.se-word-counter') || dom.utils.createElement('SPAN', { class: 'se-word-counter' });
1084
+ wordCounter =
1085
+ wordWrapper.querySelector('.se-word-counter') ||
1086
+ dom.utils.createElement('SPAN', { class: 'se-word-counter' });
821
1087
  wordCounter.textContent = '0';
822
1088
  wordWrapper.appendChild(wordCounter);
823
1089
 
@@ -826,24 +1092,32 @@ export function CreateStatusbar(targetOptions, statusbar) {
826
1092
 
827
1093
  /** char counter (right) */
828
1094
  if (targetOptions.get('charCounter')) {
829
- charWrapper = statusbar.querySelector('.se-char-counter-wrapper') || dom.utils.createElement('DIV', { class: 'se-char-counter-wrapper' });
1095
+ charWrapper =
1096
+ statusbar.querySelector('.se-char-counter-wrapper') ||
1097
+ dom.utils.createElement('DIV', { class: 'se-char-counter-wrapper' });
830
1098
 
831
1099
  if (targetOptions.get('wordCounter') && charWrapper.className.indexOf('se-with-word-counter') === -1) {
832
1100
  charWrapper.className += ' se-with-word-counter';
833
1101
  }
834
1102
 
835
1103
  if (targetOptions.get('charCounter_label')) {
836
- const charLabel = charWrapper.querySelector('.se-char-label') || dom.utils.createElement('SPAN', { class: 'se-char-label' });
1104
+ const charLabel =
1105
+ charWrapper.querySelector('.se-char-label') ||
1106
+ dom.utils.createElement('SPAN', { class: 'se-char-label' });
837
1107
  charLabel.textContent = targetOptions.get('charCounter_label');
838
1108
  charWrapper.appendChild(charLabel);
839
1109
  }
840
1110
 
841
- charCounter = charWrapper.querySelector('.se-char-counter') || dom.utils.createElement('SPAN', { class: 'se-char-counter' });
1111
+ charCounter =
1112
+ charWrapper.querySelector('.se-char-counter') ||
1113
+ dom.utils.createElement('SPAN', { class: 'se-char-counter' });
842
1114
  charCounter.textContent = '0';
843
1115
  charWrapper.appendChild(charCounter);
844
1116
 
845
1117
  if (targetOptions.get('charCounter_max') > 0) {
846
- const char_max = charWrapper.querySelector('.se-char-max') || dom.utils.createElement('SPAN', { class: 'se-char-max' });
1118
+ const char_max =
1119
+ charWrapper.querySelector('.se-char-max') ||
1120
+ dom.utils.createElement('SPAN', { class: 'se-char-max' });
847
1121
  char_max.textContent = ' / ' + targetOptions.get('charCounter_max');
848
1122
  charWrapper.appendChild(char_max);
849
1123
  }
@@ -877,10 +1151,13 @@ function InitFrameOptions(o, origin) {
877
1151
  // members
878
1152
  const value = o.value === undefined ? origin.value : o.value;
879
1153
  const placeholder = o.placeholder === undefined ? origin.placeholder : o.placeholder;
880
- const editableFrameAttributes = o.editableFrameAttributes === undefined ? origin.editableFrameAttributes : o.editableFrameAttributes;
1154
+ const placeholder_line = o.placeholder_line === undefined ? origin.placeholder_line : o.placeholder_line;
1155
+ const editableFrameAttributes =
1156
+ o.editableFrameAttributes === undefined ? origin.editableFrameAttributes : o.editableFrameAttributes;
881
1157
  const width = o.width === undefined ? origin.width : o.width;
882
1158
  const minWidth = o.minWidth === undefined ? origin.minWidth : o.minWidth;
883
1159
  const maxWidth = o.maxWidth === undefined ? origin.maxWidth : o.maxWidth;
1160
+ const innerWidth = o.innerWidth === undefined ? origin.innerWidth : o.innerWidth;
884
1161
  const height = o.height === undefined ? origin.height : o.height;
885
1162
  const minHeight = o.minHeight === undefined ? origin.minHeight : o.minHeight;
886
1163
  const maxHeight = o.maxHeight === undefined ? origin.maxHeight : o.maxHeight;
@@ -890,23 +1167,36 @@ function InitFrameOptions(o, origin) {
890
1167
  const iframe_attributes = o.iframe_attributes === undefined ? origin.iframe_attributes : o.iframe_attributes;
891
1168
  const iframe_cssFileName = o.iframe_cssFileName === undefined ? origin.iframe_cssFileName : o.iframe_cssFileName;
892
1169
  const statusbar = barContainer || o.statusbar === undefined ? origin.statusbar : o.statusbar;
893
- const statusbar_showPathLabel = barContainer || o.statusbar_showPathLabel === undefined ? origin.statusbar_showPathLabel : o.statusbar_showPathLabel;
894
- const statusbar_resizeEnable = barContainer ? false : o.statusbar_resizeEnable === undefined ? origin.statusbar_resizeEnable : o.statusbar_resizeEnable;
1170
+ const statusbar_showPathLabel =
1171
+ barContainer || o.statusbar_showPathLabel === undefined
1172
+ ? origin.statusbar_showPathLabel
1173
+ : o.statusbar_showPathLabel;
1174
+ const statusbar_resizeEnable = barContainer
1175
+ ? false
1176
+ : o.statusbar_resizeEnable === undefined
1177
+ ? origin.statusbar_resizeEnable
1178
+ : o.statusbar_resizeEnable;
895
1179
  const charCounter = barContainer || o.charCounter === undefined ? origin.charCounter : o.charCounter;
896
- const charCounter_max = barContainer || o.charCounter_max === undefined ? origin.charCounter_max : o.charCounter_max;
897
- const charCounter_label = barContainer || o.charCounter_label === undefined ? origin.charCounter_label : o.charCounter_label;
898
- const charCounter_type = barContainer || o.charCounter_type === undefined ? origin.charCounter_type : o.charCounter_type;
1180
+ const charCounter_max =
1181
+ barContainer || o.charCounter_max === undefined ? origin.charCounter_max : o.charCounter_max;
1182
+ const charCounter_label =
1183
+ barContainer || o.charCounter_label === undefined ? origin.charCounter_label : o.charCounter_label;
1184
+ const charCounter_type =
1185
+ barContainer || o.charCounter_type === undefined ? origin.charCounter_type : o.charCounter_type;
899
1186
  const wordCounter = barContainer || o.wordCounter === undefined ? origin.wordCounter : o.wordCounter;
900
- const wordCounter_label = barContainer || o.wordCounter_label === undefined ? origin.wordCounter_label : o.wordCounter_label;
1187
+ const wordCounter_label =
1188
+ barContainer || o.wordCounter_label === undefined ? origin.wordCounter_label : o.wordCounter_label;
901
1189
 
902
1190
  // value
903
1191
  fo.set('value', value);
904
1192
  fo.set('placeholder', placeholder);
1193
+ fo.set('placeholder_line', placeholder_line);
905
1194
  fo.set('editableFrameAttributes', { spellcheck: 'false', ...editableFrameAttributes });
906
1195
  // styles
907
1196
  fo.set('width', width ? String(numbers.is(width) ? width + 'px' : width) : '100%');
908
1197
  fo.set('minWidth', minWidth ? String(numbers.is(minWidth) ? minWidth + 'px' : minWidth) : '');
909
1198
  fo.set('maxWidth', maxWidth ? String(numbers.is(maxWidth) ? maxWidth + 'px' : maxWidth) : '');
1199
+ fo.set('innerWidth', innerWidth ? String(numbers.is(innerWidth) ? innerWidth + 'px' : innerWidth) : '');
910
1200
  fo.set('height', height ? String(numbers.is(height) ? height + 'px' : height) : 'auto');
911
1201
  fo.set('minHeight', minHeight ? String(numbers.is(minHeight) ? minHeight + 'px' : minHeight) : '');
912
1202
  fo.set('maxHeight', maxHeight ? String(numbers.is(maxHeight) ? maxHeight + 'px' : maxHeight) : '');
@@ -916,12 +1206,23 @@ function InitFrameOptions(o, origin) {
916
1206
  fo.set('iframe', !!(iframe_fullPage || iframe));
917
1207
  fo.set('iframe_fullPage', !!iframe_fullPage);
918
1208
  fo.set('iframe_attributes', iframe_attributes || {});
919
- fo.set('iframe_cssFileName', iframe ? (typeof iframe_cssFileName === 'string' ? [iframe_cssFileName] : iframe_cssFileName) || ['suneditor'] : null);
1209
+ fo.set(
1210
+ 'iframe_cssFileName',
1211
+ iframe
1212
+ ? (typeof iframe_cssFileName === 'string' ? [iframe_cssFileName] : iframe_cssFileName) || ['suneditor']
1213
+ : null,
1214
+ );
920
1215
  // status bar
921
1216
  const hasStatusbar = statusbar === undefined ? true : !!statusbar;
922
1217
  fo.set('statusbar', hasStatusbar);
923
- fo.set('statusbar_showPathLabel', !hasStatusbar ? false : typeof statusbar_showPathLabel === 'boolean' ? statusbar_showPathLabel : true);
924
- fo.set('statusbar_resizeEnable', !hasStatusbar ? false : statusbar_resizeEnable === undefined ? true : !!statusbar_resizeEnable);
1218
+ fo.set(
1219
+ 'statusbar_showPathLabel',
1220
+ !hasStatusbar ? false : typeof statusbar_showPathLabel === 'boolean' ? statusbar_showPathLabel : true,
1221
+ );
1222
+ fo.set(
1223
+ 'statusbar_resizeEnable',
1224
+ !hasStatusbar ? false : statusbar_resizeEnable === undefined ? true : !!statusbar_resizeEnable,
1225
+ );
925
1226
  // status bar - character count
926
1227
  fo.set('charCounter', charCounter_max > 0 ? true : typeof charCounter === 'boolean' ? charCounter : false);
927
1228
  fo.set('charCounter_max', numbers.is(charCounter_max) && charCounter_max > -1 ? charCounter_max * 1 : null);
@@ -951,7 +1252,9 @@ function _initTargetElements(key, options, topDiv, targetOptions, formFieldPrefi
951
1252
  /** editor */
952
1253
  // wysiwyg div or iframe
953
1254
  const wysiwygDiv = dom.utils.createElement(!targetOptions.get('iframe') ? 'DIV' : 'IFRAME', {
954
- class: 'se-wrapper-inner se-wrapper-wysiwyg' + (options.get('type') === 'document' ? ' se-type-document-iframe-a4' : ''),
1255
+ class:
1256
+ 'se-wrapper-inner se-wrapper-wysiwyg' +
1257
+ (options.get('type') === 'document' ? ' se-type-document-iframe-a4' : ''),
955
1258
  'data-root-key': key,
956
1259
  });
957
1260
 
@@ -997,10 +1300,20 @@ function _initTargetElements(key, options, topDiv, targetOptions, formFieldPrefi
997
1300
  }
998
1301
 
999
1302
  // textarea for code view
1000
- const textarea = dom.utils.createElement('TEXTAREA', { id: formFieldPrefix + '-code-viewer-' + (key || 'default'), class: 'se-wrapper-inner se-code-viewer', style: editorStyles.frame, autocomplete: 'off' });
1303
+ const textarea = dom.utils.createElement('TEXTAREA', {
1304
+ id: formFieldPrefix + '-code-viewer-' + (key || 'default'),
1305
+ class: 'se-wrapper-inner se-code-viewer',
1306
+ style: editorStyles.frame,
1307
+ autocomplete: 'off',
1308
+ });
1001
1309
 
1002
1310
  // textarea for markdown view
1003
- const markdownTextarea = dom.utils.createElement('TEXTAREA', { id: formFieldPrefix + '-markdown-viewer-' + (key || 'default'), class: 'se-wrapper-inner se-markdown-viewer', style: editorStyles.frame, autocomplete: 'off' });
1311
+ const markdownTextarea = dom.utils.createElement('TEXTAREA', {
1312
+ id: formFieldPrefix + '-markdown-viewer-' + (key || 'default'),
1313
+ class: 'se-wrapper-inner se-markdown-viewer',
1314
+ style: editorStyles.frame,
1315
+ autocomplete: 'off',
1316
+ });
1004
1317
 
1005
1318
  const placeholder = dom.utils.createElement('SPAN', { class: 'se-placeholder' });
1006
1319
  if (targetOptions.get('placeholder')) {
@@ -1080,7 +1393,9 @@ function _createBlacklist(blacklist, defaultLine) {
1080
1393
  if (v !== defaultLine) {
1081
1394
  return true;
1082
1395
  } else {
1083
- console.warn(`[SUNEDITOR.constructor.createBlacklist.warn] defaultLine("<${defaultLine}>") cannot be included in the blacklist and will be removed.`);
1396
+ console.warn(
1397
+ `[SUNEDITOR.constructor.createBlacklist.warn] defaultLine("<${defaultLine}>") cannot be included in the blacklist and will be removed.`,
1398
+ );
1084
1399
  return false;
1085
1400
  }
1086
1401
  })
@@ -1114,7 +1429,19 @@ function _createFormatInfo(value, defaultValue, blacklist) {
1114
1429
  */
1115
1430
  function _createWhitelist(o) {
1116
1431
  const blacklist = o.get('elementBlacklist').split('|');
1117
- const whitelist = (o.get('__defaultElementWhitelist') + '|' + o.get('elementWhitelist') + '|' + o.get('formatLine').str + '|' + o.get('formatBrLine').str + '|' + o.get('formatClosureBlock').str + '|' + o.get('formatClosureBrLine').str)
1432
+ const whitelist = (
1433
+ o.get('__defaultElementWhitelist') +
1434
+ '|' +
1435
+ o.get('elementWhitelist') +
1436
+ '|' +
1437
+ o.get('formatLine').str +
1438
+ '|' +
1439
+ o.get('formatBrLine').str +
1440
+ '|' +
1441
+ o.get('formatClosureBlock').str +
1442
+ '|' +
1443
+ o.get('formatClosureBrLine').str
1444
+ )
1118
1445
  .replace(/(^\||\|$)/g, '')
1119
1446
  .split('|')
1120
1447
  .filter((v, i, a) => v && a.indexOf(v) === i && !blacklist.includes(v));
@@ -1122,6 +1449,59 @@ function _createWhitelist(o) {
1122
1449
  return whitelist.join('|');
1123
1450
  }
1124
1451
 
1452
+ /**
1453
+ * @description Toolbar variant — sizes the button row to its content and centers it.
1454
+ * - When `value` is a CSS length (e.g. `"500px"`, `"740px"`): the row is capped at that width.
1455
+ * @param {?HTMLElement} el Target element (`.se-btn-tray`)
1456
+ * @param {string} value CSS length, `'auto'` for center-only, or empty for no constraint
1457
+ */
1458
+ function _applyToolbarInnerWidth(el, value) {
1459
+ if (!el || !value) return;
1460
+ if (value !== 'auto') el.style.maxWidth = value;
1461
+ el.style.width = 'max-content';
1462
+ el.style.marginLeft = 'auto';
1463
+ el.style.marginRight = 'auto';
1464
+ }
1465
+
1466
+ /**
1467
+ * @description Resolves a button key to its toolbar metadata.
1468
+ * Checks plugins first, then falls back to the default button list.
1469
+ * Same resolution logic as `CreateToolBar`.
1470
+ * @param {string} key Button name
1471
+ * @param {?Object<string, *>} plugins Plugin instances
1472
+ * @param {SunEditor.Options} options Options map
1473
+ * @param {Object<string, string>} icons Icons
1474
+ * @param {Object<string, string>} lang Language object
1475
+ * @returns {{className: string, title: string, command: string, type: string, icon: string}|null}
1476
+ */
1477
+ export function ResolveButton(key, plugins, options, icons, lang) {
1478
+ const plugin = plugins?.[key];
1479
+ if (plugin) {
1480
+ const s = typeof plugin === 'function' ? plugin : plugin.constructor;
1481
+ return {
1482
+ className: plugin.className || s.className || '',
1483
+ title: lang[plugin.title] || plugin.title || lang[s.title] || s.title || key,
1484
+ command: key,
1485
+ type: plugin.type || s.type || '',
1486
+ icon: icons[plugin.icon] || plugin.icon || icons[s.icon] || s.icon || '',
1487
+ };
1488
+ }
1489
+
1490
+ const defaults = _defaultButtons(options.get('_rtl'), icons, lang);
1491
+ const def = defaults[key];
1492
+ if (def) {
1493
+ return {
1494
+ className: def[0],
1495
+ title: def[1],
1496
+ command: def[2],
1497
+ type: def[3],
1498
+ icon: def[4],
1499
+ };
1500
+ }
1501
+
1502
+ return null;
1503
+ }
1504
+
1125
1505
  /**
1126
1506
  * @description SunEditor's default button list
1127
1507
  * @param {boolean} isRTL `rtl`
@@ -1141,7 +1521,13 @@ function _defaultButtons(isRTL, icons, lang) {
1141
1521
  fullScreen: ['se-code-view-enabled se-component-enabled', lang.fullScreen, 'fullScreen', '', icons.expansion],
1142
1522
  showBlocks: ['', lang.showBlocks, 'showBlocks', '', icons.show_blocks],
1143
1523
  codeView: ['se-code-view-enabled se-component-enabled', lang.codeView, 'codeView', '', icons.code_view],
1144
- markdownView: ['se-code-view-enabled se-component-enabled', lang.markdownView, 'markdownView', '', icons.markdown_view],
1524
+ markdownView: [
1525
+ 'se-code-view-enabled se-component-enabled',
1526
+ lang.markdownView,
1527
+ 'markdownView',
1528
+ '',
1529
+ icons.markdown_view,
1530
+ ],
1145
1531
  undo: ['se-component-enabled', lang.undo, 'undo', '', icons.undo],
1146
1532
  redo: ['se-component-enabled', lang.redo, 'redo', '', icons.redo],
1147
1533
  preview: ['se-component-enabled', lang.preview, 'preview', '', icons.preview],
@@ -1249,7 +1635,10 @@ export function UpdateButton(element, plugin, icons, lang) {
1249
1635
  } else {
1250
1636
  element.innerHTML = noneInner
1251
1637
  ? ''
1252
- : (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>';
1638
+ : (plugin.inner || icons[plugin.icon] || plugin.icon || '<span class="se-icon-text">!</span>') +
1639
+ '<span class="se-tooltip-inner"><span class="se-tooltip-text">' +
1640
+ (lang[plugin.title] || plugin.title) +
1641
+ '</span></span>';
1253
1642
  }
1254
1643
 
1255
1644
  element.setAttribute('aria-label', plugin.title);
@@ -1351,7 +1740,14 @@ export function CreateToolBar(buttonList, plugins, options, icons, lang, isUpdat
1351
1740
  modules = [plugin.className, plugin.title, button, plugin.type, plugin.innerHTML, plugin._disabled];
1352
1741
  } else if (typeof plugin === 'object') {
1353
1742
  const originFnc = plugin.constructor;
1354
- modules = [plugin.className || originFnc.className, plugin.title || originFnc.title, button, plugin.type || originFnc.type, plugin.innerHTML || originFnc.innerHTML, plugin._disabled || originFnc._disabled];
1743
+ modules = [
1744
+ plugin.className || originFnc.className,
1745
+ plugin.title || originFnc.title,
1746
+ button,
1747
+ plugin.type || originFnc.type,
1748
+ plugin.innerHTML || originFnc.innerHTML,
1749
+ plugin._disabled || originFnc._disabled,
1750
+ ];
1355
1751
  } else {
1356
1752
  // align
1357
1753
  if (/^-/.test(button)) {
@@ -1374,26 +1770,52 @@ export function CreateToolBar(buttonList, plugins, options, icons, lang, isUpdat
1374
1770
  moreCommand = '__se__more_' + i;
1375
1771
  const title = matched[1].trim();
1376
1772
  const innerHTML = matched[2].trim();
1377
- modules = ['se-btn-more', /^lang\./i.test(title) ? lang[title.replace(/^lang\./i, '')] : title, moreCommand, 'MORE', innerHTML];
1773
+ modules = [
1774
+ 'se-btn-more',
1775
+ /^lang\./i.test(title) ? lang[title.replace(/^lang\./i, '')] : title,
1776
+ moreCommand,
1777
+ 'MORE',
1778
+ innerHTML,
1779
+ ];
1378
1780
  } else if (button === '|') {
1379
1781
  // separator vertical
1380
1782
  modules = ['se-toolbar-separator-vertical', '', '', 'separator', ''];
1381
1783
  } else {
1382
1784
  // default command
1383
1785
  if (button === 'copy' && !env.isClipboardSupported) {
1384
- console.warn('[SUNEDITOR.constructor.warn] Clipboard is not supported in this browser. : [copy] button is not rendered.');
1786
+ console.warn(
1787
+ '[SUNEDITOR.constructor.warn] Clipboard is not supported in this browser. : [copy] button is not rendered.',
1788
+ );
1385
1789
  }
1386
1790
  modules = defaultButtonList[button];
1387
1791
  }
1388
1792
 
1389
1793
  if (!modules) {
1390
- if (!plugin) throw Error(`[SUNEDITOR.create.toolbar.fail] The button name of a plugin that does not exist. [${button}]`);
1794
+ if (!plugin)
1795
+ throw Error(
1796
+ `[SUNEDITOR.create.toolbar.fail] The button name of a plugin that does not exist. [${button}]`,
1797
+ );
1391
1798
  plugin = typeof plugin === 'object' ? plugin.constructor : plugin;
1392
- modules = [plugin.className, plugin.title, plugin.key, plugin.type, plugin.innerHTML, plugin._disabled];
1799
+ modules = [
1800
+ plugin.className,
1801
+ plugin.title,
1802
+ plugin.key,
1803
+ plugin.type,
1804
+ plugin.innerHTML,
1805
+ plugin._disabled,
1806
+ ];
1393
1807
  }
1394
1808
  }
1395
1809
 
1396
- buttonElement = _createButton(modules[0], modules[1], modules[2], modules[3], modules[4], modules[5], icons);
1810
+ buttonElement = _createButton(
1811
+ modules[0],
1812
+ modules[1],
1813
+ modules[2],
1814
+ modules[3],
1815
+ modules[4],
1816
+ modules[5],
1817
+ icons,
1818
+ );
1397
1819
  (more ? moreContainer : moduleElement.ul).appendChild(buttonElement.li);
1398
1820
 
1399
1821
  if (plugin) {
@@ -1414,7 +1836,10 @@ export function CreateToolBar(buttonList, plugins, options, icons, lang, isUpdat
1414
1836
  moreContainer = dom.utils.createElement('DIV');
1415
1837
  moreContainer.className = 'se-more-layer ' + moreCommand;
1416
1838
  moreContainer.setAttribute('data-ref', moreCommand);
1417
- moreContainer.innerHTML = '<div class="se-more-form"><ul class="se-menu-list"' + (align ? ' style="float: ' + align + ';"' : '') + '></ul></div>';
1839
+ moreContainer.innerHTML =
1840
+ '<div class="se-more-form"><ul class="se-menu-list"' +
1841
+ (align ? ' style="float: ' + align + ';"' : '') +
1842
+ '></ul></div>';
1418
1843
  moreLayer.appendChild(moreContainer);
1419
1844
  moreContainer = moreContainer.firstElementChild.firstElementChild;
1420
1845
  }
@@ -1452,8 +1877,14 @@ export function CreateToolBar(buttonList, plugins, options, icons, lang, isUpdat
1452
1877
  if (moreLayer.children.length > 0) buttonTray.appendChild(moreLayer);
1453
1878
  if (responsiveButtons.length > 0) responsiveButtons.unshift(buttonList);
1454
1879
 
1880
+ _applyToolbarInnerWidth(buttonTray, options.get('toolbar_innerWidth'));
1881
+
1455
1882
  // rendering toolbar
1456
- const tool_bar = dom.utils.createElement('DIV', { class: 'se-toolbar sun-editor-common' + (!options.get('shortcutsHint') ? ' se-shortcut-hide' : '') }, buttonTray);
1883
+ const tool_bar = dom.utils.createElement(
1884
+ 'DIV',
1885
+ { class: 'se-toolbar sun-editor-common' + (!options.get('shortcutsHint') ? ' se-shortcut-hide' : '') },
1886
+ buttonTray,
1887
+ );
1457
1888
 
1458
1889
  if (options.get('toolbar_hide')) tool_bar.style.display = 'none';
1459
1890