suneditor 3.1.4 → 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 (216) 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 +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 -93
  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 +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 +83 -2
  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/ColorPicker.d.ts +2 -2
  197. package/types/modules/contract/Controller.d.ts +7 -0
  198. package/types/modules/contract/Figure.d.ts +31 -4
  199. package/types/modules/ui/CommandMenu.d.ts +262 -0
  200. package/types/modules/ui/SelectMenu.d.ts +56 -3
  201. package/types/modules/ui/index.d.ts +1 -0
  202. package/types/plugins/browser/audioGallery.d.ts +1 -1
  203. package/types/plugins/browser/fileBrowser.d.ts +1 -1
  204. package/types/plugins/browser/fileGallery.d.ts +1 -1
  205. package/types/plugins/browser/imageGallery.d.ts +1 -1
  206. package/types/plugins/browser/videoGallery.d.ts +1 -1
  207. package/types/plugins/dropdown/align.d.ts +1 -1
  208. package/types/plugins/dropdown/blockStyle.d.ts +3 -1
  209. package/types/plugins/dropdown/table/index.d.ts +4 -1
  210. package/types/plugins/dropdown/table/services/table.clipboard.d.ts +5 -1
  211. package/types/plugins/dropdown/table/services/table.grid.d.ts +10 -2
  212. package/types/plugins/field/autocomplete.d.ts +0 -1
  213. package/types/plugins/field/slashCommand.d.ts +165 -0
  214. package/types/plugins/index.d.ts +3 -0
  215. package/types/plugins/modal/link.d.ts +4 -1
  216. package/types/typedef.d.ts +48 -23
@@ -27,9 +27,22 @@ class Font extends PluginDropdown {
27
27
  this.title = this.$.lang.font;
28
28
  this.inner = '<span class="se-txt">' + this.$.lang.font + '</span>' + this.$.icons.arrow_down;
29
29
 
30
- // create HTML
31
- const fontList = pluginOptions.items || ['Arial', 'Comic Sans MS', 'Courier New', 'Impact', 'Georgia', 'tahoma', 'Trebuchet MS', 'Verdana'];
32
- const menu = CreateHTML(this.$, fontList);
30
+ // create menu from items
31
+ const fontList = pluginOptions.items || [
32
+ 'Arial',
33
+ 'Comic Sans MS',
34
+ 'Courier New',
35
+ 'Impact',
36
+ 'Georgia',
37
+ 'tahoma',
38
+ 'Trebuchet MS',
39
+ 'Verdana',
40
+ ];
41
+ const prependHTML = `<li><button type="button" class="se-btn se-btn-list default_value" data-command="" title="${this.$.lang.default}" aria-label="${this.$.lang.default}">${this.$.lang.default}</button></li><li class="se-btn-list se-sub-list"><span></span></li>`;
42
+ const menu = this.$.menu.initDropdownTarget(Font, CreateItems(fontList), {
43
+ className: 'se-list-font-family',
44
+ prependHTML,
45
+ });
33
46
 
34
47
  // members
35
48
  this.currentFont = '';
@@ -37,9 +50,6 @@ class Font extends PluginDropdown {
37
50
  this.fontArray = fontList;
38
51
 
39
52
  this.#defaultValue = /** @type {HTMLSpanElement} */ (menu.querySelector('.se-sub-list span'));
40
-
41
- // init
42
- this.$.menu.initDropdownTarget(Font, menu);
43
53
  }
44
54
 
45
55
  /**
@@ -52,9 +62,14 @@ class Font extends PluginDropdown {
52
62
 
53
63
  let fontFamily = '';
54
64
  if (!element) {
55
- const font = this.$.store.get('hasFocus') ? this.$.frameContext.get('wwComputedStyle').fontFamily : this.$.lang.font;
65
+ const font = this.$.store.get('hasFocus')
66
+ ? this.$.frameContext.get('wwComputedStyle').fontFamily
67
+ : this.$.lang.font;
56
68
  dom.utils.changeTxt(targetText, font);
57
- dom.utils.changeTxt(tooltip, this.$.store.get('hasFocus') ? this.$.lang.font + (font ? ' (' + font + ')' : '') : font);
69
+ dom.utils.changeTxt(
70
+ tooltip,
71
+ this.$.store.get('hasFocus') ? this.$.lang.font + (font ? ' (' + font + ')' : '') : font,
72
+ );
58
73
  } else if (this.$.format.isLine(element)) {
59
74
  return undefined;
60
75
  } else if ((fontFamily = dom.utils.getStyle(element, 'fontFamily'))) {
@@ -122,34 +137,19 @@ class Font extends PluginDropdown {
122
137
  }
123
138
 
124
139
  /**
125
- * @param {SunEditor.Deps} $ - Kernel dependencies
126
140
  * @param {string[]} fontList - Font name list
127
- * @returns {HTMLElement}
141
+ * @returns {Array<import('../../core/logic/panel/menu').DropdownItem>}
128
142
  */
129
- function CreateHTML({ lang }, fontList) {
130
- let list = /*html*/ `
131
- <div class="se-list-inner">
132
- <ul class="se-list-basic">
133
- <li>
134
- <button type="button" class="se-btn se-btn-list default_value" data-command="" title="${lang.default}" aria-label="${lang.default}">
135
- ${lang.default}
136
- </button>
137
- </li>
138
- <li class="se-btn-list se-sub-list"><span></span></li>`;
139
-
140
- for (let i = 0, len = fontList.length, font, text; i < len; i++) {
141
- font = fontList[i];
142
- text = font.split(',')[0];
143
- list += /*html*/ `
144
- <li>
145
- <button type="button" class="se-btn se-btn-list" data-command="${font}" data-txt="${text}" title="${text}" aria-label="${text}" style="font-family:${font};">${text}</button>
146
- </li>`;
147
- }
148
- list += /*html*/ `
149
- </ul>
150
- </div>`;
151
-
152
- return dom.utils.createElement('DIV', { class: 'se-dropdown se-list-layer se-list-font-family' }, list);
143
+ function CreateItems(fontList) {
144
+ return fontList.map((font) => {
145
+ const text = font.split(',')[0];
146
+ return {
147
+ command: font,
148
+ title: text,
149
+ innerHTML: text,
150
+ attrs: { 'data-txt': text, style: `font-family:${font};` },
151
+ };
152
+ });
153
153
  }
154
154
 
155
155
  export default Font;
@@ -39,14 +39,13 @@ class HR extends PluginDropdown {
39
39
  this.title = this.$.lang.horizontalLine;
40
40
  this.icon = 'horizontal_line';
41
41
 
42
- // create HTML
43
- const HRMenus = CreateHTML(this.$, pluginOptions.items);
42
+ // create menu from items
43
+ const menu = this.$.menu.initDropdownTarget(HR, CreateItems(this.$, pluginOptions.items), {
44
+ className: 'se-list-line',
45
+ });
44
46
 
45
47
  // members
46
- this.list = HRMenus.querySelectorAll('button');
47
-
48
- // init
49
- this.$.menu.initDropdownTarget(HR, HRMenus);
48
+ this.list = menu.querySelectorAll('button');
50
49
  }
51
50
 
52
51
  /**
@@ -117,47 +116,20 @@ class HR extends PluginDropdown {
117
116
  /**
118
117
  * @param {SunEditor.Deps} $ - Kernel dependencies
119
118
  * @param {Array<{name: string, class: string, style?: string}>} [HRItems] - HR style items
120
- * @returns {HTMLElement}
119
+ * @returns {Array<import('../../core/logic/panel/menu').DropdownItem>}
121
120
  */
122
- function CreateHTML({ lang }, HRItems) {
121
+ function CreateItems({ lang }, HRItems) {
123
122
  const items = HRItems || [
124
- {
125
- name: lang.hr_solid,
126
- class: '__se__solid',
127
- style: null,
128
- },
129
- {
130
- name: lang.hr_dashed,
131
- class: '__se__dashed',
132
- style: null,
133
- },
134
- {
135
- name: lang.hr_dotted,
136
- class: '__se__dotted',
137
- style: null,
138
- },
123
+ { name: lang.hr_solid, class: '__se__solid', style: null },
124
+ { name: lang.hr_dashed, class: '__se__dashed', style: null },
125
+ { name: lang.hr_dotted, class: '__se__dotted', style: null },
139
126
  ];
140
127
 
141
- let list = '';
142
- for (let i = 0, len = items.length; i < len; i++) {
143
- list += /*html*/ `
144
- <li>
145
- <button type="button" class="se-btn se-btn-list" data-command="hr" title="${items[i].name}" aria-label="${items[i].name}">
146
- <hr${items[i].class ? ` class="${items[i].class}"` : ''}${items[i].style ? ` style="${items[i].style}"` : ''}/>
147
- </button>
148
- </li>`;
149
- }
150
-
151
- return dom.utils.createElement(
152
- 'DIV',
153
- {
154
- class: 'se-dropdown se-list-layer se-list-line',
155
- },
156
- /*html*/ `
157
- <div class="se-list-inner">
158
- <ul class="se-list-basic">${list}</ul>
159
- </div>`,
160
- );
128
+ return items.map((item) => ({
129
+ command: 'hr',
130
+ title: item.name,
131
+ innerHTML: `<hr${item.class ? ` class="${item.class}"` : ''}${item.style ? ` style="${item.style}"` : ''}/>`,
132
+ }));
161
133
  }
162
134
 
163
135
  export default HR;
@@ -1,5 +1,4 @@
1
1
  import { PluginDropdown } from '../../interfaces';
2
- import { dom } from '../../helper';
3
2
 
4
3
  /**
5
4
  * @typedef {Object} LayoutPluginOptions
@@ -32,11 +31,8 @@ class Layout extends PluginDropdown {
32
31
  this.selectedIndex = -1;
33
32
  this.items = pluginOptions.items;
34
33
 
35
- // create HTML
36
- const menu = CreateHTML(this.items);
37
-
38
- // init
39
- this.$.menu.initDropdownTarget(Layout, menu);
34
+ // create menu from items
35
+ this.$.menu.initDropdownTarget(Layout, CreateItems(this.items));
40
36
  }
41
37
 
42
38
  /**
@@ -60,32 +56,19 @@ class Layout extends PluginDropdown {
60
56
 
61
57
  /**
62
58
  * @param {Array<{name: string, html: string}>} layoutList - Layout items
63
- * @returns {HTMLElement}
59
+ * @returns {Array<import('../../core/logic/panel/menu').DropdownItem>}
64
60
  */
65
- function CreateHTML(layoutList) {
61
+ function CreateItems(layoutList) {
66
62
  if (!layoutList || layoutList.length === 0) {
67
63
  console.warn('[SUNEDITOR.plugins.layout.warn] To use the "layout" plugin, please define the "layouts" option.');
68
64
  }
69
65
 
70
- let list = /*html*/ `
71
- <div class="se-dropdown se-list-inner">
72
- <ul class="se-list-basic">`;
73
-
74
- for (let i = 0, len = (layoutList || []).length, t; i < len; i++) {
75
- t = layoutList[i];
76
- list += /*html*/ `
77
- <li>
78
- <button type="button" class="se-btn se-btn-list" data-command="layout" data-value="${i}" title="${t.name}" aria-label="${t.name}">
79
- ${t.name}
80
- </button>
81
- </li>`;
82
- }
83
-
84
- list += /*html*/ `
85
- </ul>
86
- </div>`;
87
-
88
- return dom.utils.createElement('DIV', { class: 'se-list-layer' }, list);
66
+ return (layoutList || []).map((t, i) => ({
67
+ command: 'layout',
68
+ value: String(i),
69
+ title: t.name,
70
+ innerHTML: t.name,
71
+ }));
89
72
  }
90
73
 
91
74
  export default Layout;
@@ -30,17 +30,15 @@ class LineHeight extends PluginDropdown {
30
30
  this.title = this.$.lang.lineHeight;
31
31
  this.icon = 'line_height';
32
32
 
33
- // create HTML
34
- const menu = CreateHTML(this.$, pluginOptions.items);
33
+ // create menu from items
34
+ const prependHTML = `<li><button type="button" class="se-btn se-btn-list default_value" data-command="" title="${this.$.lang.default}" aria-label="${this.$.lang.default}">${this.$.lang.default}</button></li><li class="se-btn-list se-sub-list"><span></span></li>`;
35
+ const menu = this.$.menu.initDropdownTarget(LineHeight, CreateItems(pluginOptions.items), { prependHTML });
35
36
 
36
37
  // members
37
38
  this.sizeList = menu.querySelectorAll('li button');
38
39
  this.currentSize = null;
39
40
 
40
41
  this.#defaultValue = /** @type {HTMLSpanElement} */ (menu.querySelector('.se-sub-list span'));
41
-
42
- // init
43
- this.$.menu.initDropdownTarget(LineHeight, menu);
44
42
  }
45
43
 
46
44
  /**
@@ -108,11 +106,10 @@ class LineHeight extends PluginDropdown {
108
106
  }
109
107
 
110
108
  /**
111
- * @param {SunEditor.Deps} $ - Kernel dependencies
112
109
  * @param {Array<{text: string, value: string}>} [items] - Line height items
113
- * @returns {HTMLElement}
110
+ * @returns {Array<import('../../core/logic/panel/menu').DropdownItem>}
114
111
  */
115
- function CreateHTML({ lang }, items) {
112
+ function CreateItems(items) {
116
113
  const sizeList = items || [
117
114
  { text: '1', value: '1em' },
118
115
  { text: '1.2', value: '1.2em' },
@@ -120,31 +117,11 @@ function CreateHTML({ lang }, items) {
120
117
  { text: '2', value: '2em' },
121
118
  ];
122
119
 
123
- let list = /*html*/ `
124
- <div class="se-list-inner">
125
- <ul class="se-list-basic">
126
- <li>
127
- <button type="button" class="se-btn se-btn-list default_value" data-command="" title="${lang.default}" aria-label="${lang.default}">
128
- ${lang.default}
129
- </button>
130
- </li>
131
- <li class="se-btn-list se-sub-list"><span></span></li>`;
132
-
133
- for (let i = 0, len = sizeList.length, size; i < len; i++) {
134
- size = sizeList[i];
135
- list += /*html*/ `
136
- <li>
137
- <button type="button" class="se-btn se-btn-list" data-command="${size.value}" title="${size.text}" aria-label="${size.text}">
138
- ${size.text}
139
- </button>
140
- </li>`;
141
- }
142
-
143
- list += /*html*/ `
144
- </ul>
145
- </div>`;
146
-
147
- return dom.utils.createElement('DIV', { class: 'se-dropdown se-list-layer' }, list);
120
+ return sizeList.map((size) => ({
121
+ command: size.value,
122
+ title: size.text,
123
+ innerHTML: size.text,
124
+ }));
148
125
  }
149
126
 
150
127
  export default LineHeight;
@@ -22,18 +22,15 @@ class List extends PluginDropdown {
22
22
  this.title = this.$.lang.list;
23
23
  this.icon = 'list_numbered';
24
24
 
25
- // create HTML
26
- const menu = CreateHTML(this.$);
27
-
28
25
  // members
29
- this.#listItems = menu.querySelectorAll('li button');
30
26
  this.#listIcons = {
31
27
  bulleted: this.$.icons.list_bulleted,
32
28
  numbered: this.$.icons.list_numbered,
33
29
  };
34
30
 
35
- // init
36
- this.$.menu.initDropdownTarget(List, menu);
31
+ // create menu from items
32
+ const menu = this.$.menu.initDropdownTarget(List, CreateItems(this.$));
33
+ this.#listItems = menu.querySelectorAll('li button');
37
34
  }
38
35
 
39
36
  /**
@@ -97,26 +94,23 @@ class List extends PluginDropdown {
97
94
 
98
95
  /**
99
96
  * @param {SunEditor.Deps} $ - Kernel dependencies
100
- * @returns {HTMLElement}
97
+ * @returns {Array<import('../../core/logic/panel/menu').DropdownItem>}
101
98
  */
102
- function CreateHTML({ lang, icons }) {
103
- const html = /*html*/ `
104
- <div class="se-list-inner">
105
- <ul class="se-list-basic">
106
- <li>
107
- <button type="button" class="se-btn se-btn-list se-tooltip se-icon-flip-rtl" data-command="ol" title="${lang.numberedList}" aria-label="${lang.numberedList}">
108
- ${icons.list_numbered}
109
- </button>
110
- </li>
111
- <li>
112
- <button type="button" class="se-btn se-btn-list se-tooltip se-icon-flip-rtl" data-command="ul" title="${lang.bulletedList}" aria-label="${lang.bulletedList}">
113
- ${icons.list_bulleted}
114
- </button>
115
- </li>
116
- </ul>
117
- </div>`;
118
-
119
- return dom.utils.createElement('DIV', { class: 'se-dropdown se-list-layer' }, html);
99
+ function CreateItems({ lang, icons }) {
100
+ return [
101
+ {
102
+ command: 'ol',
103
+ title: lang.numberedList,
104
+ innerHTML: icons.list_numbered,
105
+ className: 'se-tooltip se-icon-flip-rtl',
106
+ },
107
+ {
108
+ command: 'ul',
109
+ title: lang.bulletedList,
110
+ innerHTML: icons.list_bulleted,
111
+ className: 'se-tooltip se-icon-flip-rtl',
112
+ },
113
+ ];
120
114
  }
121
115
 
122
116
  export default List;
@@ -35,14 +35,13 @@ class ParagraphStyle extends PluginDropdown {
35
35
  this.title = this.$.lang.paragraphStyle;
36
36
  this.icon = 'paragraph_style';
37
37
 
38
- // create HTML
39
- const menu = CreateHTML(this.$, pluginOptions.items);
38
+ // create menu from items
39
+ const menu = this.$.menu.initDropdownTarget(ParagraphStyle, CreateItems(this.$, pluginOptions.items), {
40
+ className: 'se-list-format',
41
+ });
40
42
 
41
43
  // members
42
44
  this.classList = menu.querySelectorAll('li button');
43
-
44
- // init
45
- this.$.menu.initDropdownTarget(ParagraphStyle, menu);
46
45
  }
47
46
 
48
47
  /**
@@ -88,9 +87,9 @@ class ParagraphStyle extends PluginDropdown {
88
87
  /**
89
88
  * @param {SunEditor.Deps} $ - Kernel dependencies
90
89
  * @param {Array<string|{name: string, class: string, _class?: string}>} [items] - Paragraph style items
91
- * @returns {HTMLElement}
90
+ * @returns {Array<import('../../core/logic/panel/menu').DropdownItem>}
92
91
  */
93
- function CreateHTML({ lang }, items) {
92
+ function CreateItems({ lang }, items) {
94
93
  const defaultList = {
95
94
  spaced: {
96
95
  name: lang.menu_spaced,
@@ -109,12 +108,9 @@ function CreateHTML({ lang }, items) {
109
108
  },
110
109
  };
111
110
  const paragraphStyles = !items || items.length === 0 ? ['spaced', 'bordered', 'neon'] : items;
111
+ const result = [];
112
112
 
113
- let list = /*html*/ `
114
- <div class="se-list-inner">
115
- <ul class="se-list-basic">`;
116
-
117
- for (let i = 0, len = paragraphStyles.length, p, name, attrs, _class; i < len; i++) {
113
+ for (let i = 0, len = paragraphStyles.length, p, name, attrs; i < len; i++) {
118
114
  p = paragraphStyles[i];
119
115
 
120
116
  if (typeof p === 'string') {
@@ -125,20 +121,16 @@ function CreateHTML({ lang }, items) {
125
121
 
126
122
  name = p.name;
127
123
  attrs = p.class ? ` class="${p.class}"` : '';
128
- _class = p._class;
129
-
130
- list += /*html*/ `
131
- <li>
132
- <button type="button" class="se-btn se-btn-list${_class ? ' ' + _class : ''}" data-command="${p.class}" title="${name}" aria-label="${name}">
133
- <div${attrs}>${name}</div>
134
- </button>
135
- </li>`;
124
+
125
+ result.push({
126
+ command: p.class,
127
+ title: name,
128
+ innerHTML: `<div${attrs}>${name}</div>`,
129
+ className: p._class || undefined,
130
+ });
136
131
  }
137
- list += /*html*/ `
138
- </ul>
139
- </div>`;
140
132
 
141
- return dom.utils.createElement('DIV', { class: 'se-dropdown se-list-layer se-list-format' }, list);
133
+ return result;
142
134
  }
143
135
 
144
136
  export default ParagraphStyle;
@@ -4,7 +4,13 @@ import { Controller, Figure } from '../../../modules/contract';
4
4
  import { _DragHandle } from '../../../modules/ui';
5
5
 
6
6
  import * as Constants from './shared/table.constants';
7
- import { CreateCellsString, GetMaxColumns, IsResizeEls, IsTableCaption, GetLogicalCellIndex } from './shared/table.utils';
7
+ import {
8
+ CreateCellsString,
9
+ GetMaxColumns,
10
+ IsResizeEls,
11
+ IsTableCaption,
12
+ GetLogicalCellIndex,
13
+ } from './shared/table.utils';
8
14
  import { CreateHTML, CreateHTML_controller_table, CreateHTML_controller_cell } from './render/table.html';
9
15
 
10
16
  import TableCellService from './services/table.cell';
@@ -89,10 +95,18 @@ class Table extends PluginDropdownFree {
89
95
  const controller_cell = CreateHTML_controller_cell(this.$, this.cellControllerTop);
90
96
 
91
97
  this.$.contextProvider.applyToRoots((e) => {
92
- e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: Constants.RESIZE_CELL_CLASS.replace(/^\./, '') }));
93
- e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: Constants.RESIZE_CELL_PREV_CLASS.replace(/^\./, '') }));
94
- e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: Constants.RESIZE_ROW_CLASS.replace(/^\./, '') }));
95
- e.get('wrapper').appendChild(dom.utils.createElement('DIV', { class: Constants.RESIZE_ROW_PREV_CLASS.replace(/^\./, '') }));
98
+ e.get('wrapper').appendChild(
99
+ dom.utils.createElement('DIV', { class: Constants.RESIZE_CELL_CLASS.replace(/^\./, '') }),
100
+ );
101
+ e.get('wrapper').appendChild(
102
+ dom.utils.createElement('DIV', { class: Constants.RESIZE_CELL_PREV_CLASS.replace(/^\./, '') }),
103
+ );
104
+ e.get('wrapper').appendChild(
105
+ dom.utils.createElement('DIV', { class: Constants.RESIZE_ROW_CLASS.replace(/^\./, '') }),
106
+ );
107
+ e.get('wrapper').appendChild(
108
+ dom.utils.createElement('DIV', { class: Constants.RESIZE_ROW_PREV_CLASS.replace(/^\./, '') }),
109
+ );
96
110
  });
97
111
 
98
112
  // members - Controller
@@ -175,7 +189,12 @@ class Table extends PluginDropdownFree {
175
189
 
176
190
  this.#maxWidth = this.state.figureElement?.style.width === '100%';
177
191
  this.#fixedColumn = dom.utils.hasClass(target, 'se-table-layout-fixed') || target.style.tableLayout === 'fixed';
178
- this.styleService.setTableLayout(this.#maxWidth ? 'width|column' : 'width', this.#maxWidth, this.#fixedColumn, true);
192
+ this.styleService.setTableLayout(
193
+ this.#maxWidth ? 'width|column' : 'width',
194
+ this.#maxWidth,
195
+ this.#fixedColumn,
196
+ true,
197
+ );
179
198
 
180
199
  if (_DragHandle.get('__overInfo') === ON_OVER_COMPONENT) return;
181
200
 
@@ -185,12 +204,22 @@ class Table extends PluginDropdownFree {
185
204
  // controller open
186
205
  const btnDisabled = this.state.selectedCells?.length > 1;
187
206
  const figureEl = dom.query.getParentElement(target, dom.check.isFigure);
188
- this.controller_table.open(figureEl, null, { isWWTarget: false, initMethod: null, addOffset: null, disabled: btnDisabled });
207
+ this.controller_table.open(figureEl, null, {
208
+ isWWTarget: false,
209
+ initMethod: null,
210
+ addOffset: null,
211
+ disabled: btnDisabled,
212
+ });
189
213
 
190
214
  if (!this.state.fixedCell) return;
191
215
 
192
216
  this.cellService.setUnMergeButton();
193
- this.controller_cell.open(this.state.tdElement, this.cellControllerTop ? figureEl : null, { isWWTarget: false, initMethod: null, addOffset: null, disabled: btnDisabled });
217
+ this.controller_cell.open(this.state.tdElement, this.cellControllerTop ? figureEl : null, {
218
+ isWWTarget: false,
219
+ initMethod: null,
220
+ addOffset: null,
221
+ disabled: btnDisabled,
222
+ });
194
223
  }
195
224
 
196
225
  /**
@@ -253,7 +282,7 @@ class Table extends PluginDropdownFree {
253
282
  if (domParserBody.childElementCount !== 1) return;
254
283
 
255
284
  const componentInfo = this.$.component.get(domParserBody.firstElementChild);
256
- if (componentInfo.pluginName !== Table.key) return;
285
+ if (componentInfo?.pluginName !== Table.key) return;
257
286
 
258
287
  const copyTable = /** @type {HTMLTableElement} */ (componentInfo.target);
259
288
  const selectedCells = this.clipboardService.pasteTableCellMatrix(copyTable, targetCell);
@@ -278,7 +307,9 @@ class Table extends PluginDropdownFree {
278
307
  /** @param {HTMLTableElement} element */
279
308
  method: (element) => {
280
309
  const ColgroupEl = element.querySelector('colgroup');
281
- let FigureEl = /** @type {HTMLElement} */ (dom.check.isFigure(element.parentNode) ? element.parentNode : null);
310
+ let FigureEl = /** @type {HTMLElement} */ (
311
+ dom.check.isFigure(element.parentNode) ? element.parentNode : null
312
+ );
282
313
 
283
314
  // create colgroup
284
315
  if (!ColgroupEl) {
@@ -318,7 +349,9 @@ class Table extends PluginDropdownFree {
318
349
  if (existingWidth === null) {
319
350
  colWidths[targetColIndex] = `width: ${cellWidth};`;
320
351
  } else {
321
- const existingPxWidth = parseFloat(existingWidth.replace('width: ', '').replace(';', ''));
352
+ const existingPxWidth = parseFloat(
353
+ existingWidth.replace('width: ', '').replace(';', ''),
354
+ );
322
355
  if (colSpan === 1 && currentPxWidth !== existingPxWidth) {
323
356
  colWidths[targetColIndex] = `width: ${cellWidth};`;
324
357
  }
@@ -370,7 +403,10 @@ class Table extends PluginDropdownFree {
370
403
  } else {
371
404
  const scrollTypeClass = `se-scroll-figure-${this.figureScroll}`;
372
405
  dom.utils.addClass(FigureEl, scrollTypeClass);
373
- dom.utils.removeClass(FigureEl, this.figureScrollList.filter((v) => v !== scrollTypeClass).join('|'));
406
+ dom.utils.removeClass(
407
+ FigureEl,
408
+ this.figureScrollList.filter((v) => v !== scrollTypeClass).join('|'),
409
+ );
374
410
  }
375
411
  },
376
412
  };
@@ -463,7 +499,13 @@ class Table extends PluginDropdownFree {
463
499
 
464
500
  const keyCode = event.code;
465
501
  const isTab = keyCodeMap.isTab(keyCode);
466
- if (this.$.ui.selectMenuOn || this.resizeService.isResizing() || (!isTab && this.#_s) || keyCodeMap.isCtrl(event)) return;
502
+ if (
503
+ this.$.ui.selectMenuOn ||
504
+ this.resizeService.isResizing() ||
505
+ (!isTab && this.#_s) ||
506
+ keyCodeMap.isCtrl(event)
507
+ )
508
+ return;
467
509
 
468
510
  if (!this.cellControllerTop) {
469
511
  this.controller_cell.hide();
@@ -547,7 +589,10 @@ class Table extends PluginDropdownFree {
547
589
  */
548
590
  onKeyUp({ line }) {
549
591
  this.#_s = false;
550
- if (this.state.isShiftPressed && dom.query.getParentElement(line, dom.check.isTableCell) === this.state.fixedCell) {
592
+ if (
593
+ this.state.isShiftPressed &&
594
+ dom.query.getParentElement(line, dom.check.isTableCell) === this.state.fixedCell
595
+ ) {
551
596
  this.selectionService.deleteStyleSelectedCells();
552
597
  this._editorEnable(true);
553
598
  this.#initService();
@@ -760,7 +805,8 @@ class Table extends PluginDropdownFree {
760
805
  this.setState('tdElement', tdElement);
761
806
  if (this.state.fixedCell === tdElement) dom.utils.addClass(tdElement, 'se-selected-cell-focus');
762
807
  if (!this.state.selectedCells?.length) this.setState('selectedCells', [tdElement]);
763
- const tableElement = this.state.selectedTable || this._element || dom.query.getParentElement(tdElement, 'TABLE');
808
+ const tableElement =
809
+ this.state.selectedTable || this._element || dom.query.getParentElement(tdElement, 'TABLE');
764
810
  this.$.component.select(tableElement, Table.key, { isInput: true });
765
811
  }
766
812
 
@@ -807,7 +853,13 @@ class Table extends PluginDropdownFree {
807
853
  * @param {Node} target - The target figure element.
808
854
  */
809
855
  #figureOpen(target) {
810
- this.figure.open(target, { nonResizing: true, nonSizeInfo: true, nonBorder: true, figureTarget: true, infoOnly: false });
856
+ this.figure.open(target, {
857
+ nonResizing: true,
858
+ nonSizeInfo: true,
859
+ nonBorder: true,
860
+ figureTarget: true,
861
+ infoOnly: false,
862
+ });
811
863
  }
812
864
 
813
865
  /**
@@ -885,7 +937,10 @@ class Table extends PluginDropdownFree {
885
937
  scrollTypeClass = ` se-scroll-figure-${this.figureScroll}`;
886
938
  }
887
939
 
888
- const figure = dom.utils.createElement('FIGURE', { class: 'se-flex-component se-input-component' + scrollTypeClass, style: 'width: 100%;' });
940
+ const figure = dom.utils.createElement('FIGURE', {
941
+ class: 'se-flex-component se-input-component' + scrollTypeClass,
942
+ style: 'width: 100%;',
943
+ });
889
944
  figure.appendChild(oTable);
890
945
  this.#maxWidth = true;
891
946
 
@@ -158,7 +158,9 @@ export function CreateHTML_controller_cell({ lang, icons }, cellControllerTop) {
158
158
  * @returns {TableCtrlProps}
159
159
  */
160
160
  export function CreateHTML_controller_properties({ lang, icons, options }) {
161
- const alignItems = options.get('_rtl') ? ['right', 'center', 'left', 'justify'] : ['left', 'center', 'right', 'justify'];
161
+ const alignItems = options.get('_rtl')
162
+ ? ['right', 'center', 'left', 'justify']
163
+ : ['left', 'center', 'right', 'justify'];
162
164
  let alignHtml = '';
163
165
  for (let i = 0, item, text; i < alignItems.length; i++) {
164
166
  item = alignItems[i];