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
@@ -61,7 +61,15 @@ export function isTable(node: (Node | string) | null): node is HTMLTableElement;
61
61
  * @param {?Node|string} node The element or element name to check
62
62
  * @returns {node is HTMLTableElement|HTMLTableSectionElement|HTMLTableRowElement|HTMLTableCellElement|HTMLTableColElement|HTMLTableColElement}
63
63
  */
64
- export function isTableElements(node: (Node | string) | null): node is HTMLTableElement | HTMLTableSectionElement | HTMLTableRowElement | HTMLTableCellElement | HTMLTableColElement | HTMLTableColElement;
64
+ export function isTableElements(
65
+ node: (Node | string) | null,
66
+ ): node is
67
+ | HTMLTableElement
68
+ | HTMLTableSectionElement
69
+ | HTMLTableRowElement
70
+ | HTMLTableCellElement
71
+ | HTMLTableColElement
72
+ | HTMLTableColElement;
65
73
  /**
66
74
  * @description Check the node is a table cell (td, th)
67
75
  * @param {?Node|string} node The element or element name to check
@@ -91,7 +99,9 @@ export function isAnchor(node: (Node | string) | null): node is HTMLAnchorElemen
91
99
  * @param {?Node|string} node The element or element name to check
92
100
  * @returns {node is HTMLImageElement|HTMLIFrameElement|HTMLAudioElement|HTMLVideoElement|HTMLCanvasElement}
93
101
  */
94
- export function isMedia(node: (Node | string) | null): node is HTMLImageElement | HTMLIFrameElement | HTMLAudioElement | HTMLVideoElement | HTMLCanvasElement;
102
+ export function isMedia(
103
+ node: (Node | string) | null,
104
+ ): node is HTMLImageElement | HTMLIFrameElement | HTMLAudioElement | HTMLVideoElement | HTMLCanvasElement;
95
105
  /**
96
106
  * @description Check the node is a iframe tag
97
107
  * @param {?Node|string} node The element or element name to check
@@ -40,7 +40,10 @@ export function getNodeFromPath<T extends Node>(offsets: Array<number>, parentNo
40
40
  * @param {?(current: *) => boolean} validation Conditional function
41
41
  * @returns {T|null}
42
42
  */
43
- export function getChildNode<T extends HTMLElement>(element: Node, validation: ((current: any) => boolean) | null): T | null;
43
+ export function getChildNode<T extends HTMLElement>(
44
+ element: Node,
45
+ validation: ((current: any) => boolean) | null,
46
+ ): T | null;
44
47
  /**
45
48
  * @template {HTMLElement} T
46
49
  * @description Get all `children` of the argument value element (Without text nodes)
@@ -49,7 +52,11 @@ export function getChildNode<T extends HTMLElement>(element: Node, validation: (
49
52
  * @param {?number} depth Number of child levels to depth.
50
53
  * @returns {Array<T>}
51
54
  */
52
- export function getListChildren<T extends HTMLElement>(element: Node, validation: ((current: any) => boolean) | null, depth: number | null): Array<T>;
55
+ export function getListChildren<T extends HTMLElement>(
56
+ element: Node,
57
+ validation: ((current: any) => boolean) | null,
58
+ depth: number | null,
59
+ ): Array<T>;
53
60
  /**
54
61
  * @template {Node} T
55
62
  * @description Get all `childNodes` of the argument value element (Include text nodes)
@@ -60,7 +67,11 @@ export function getListChildren<T extends HTMLElement>(element: Node, validation
60
67
  * @example
61
68
  * const allNodes = dom.query.getListChildNodes(container, (node) => node.nodeType === 3);
62
69
  */
63
- export function getListChildNodes<T extends Node>(element: Node, validation: ((current: any) => boolean) | null, depth: number | null): Array<T>;
70
+ export function getListChildNodes<T extends Node>(
71
+ element: Node,
72
+ validation: ((current: any) => boolean) | null,
73
+ depth: number | null,
74
+ ): Array<T>;
64
75
  /**
65
76
  * @description Returns the number of parents nodes.
66
77
  * - `0` when the parent node is the WYSIWYG area.
@@ -115,7 +126,11 @@ export function compareElements(
115
126
  * @param {?number} [depth] Number of parent levels to depth.
116
127
  * @returns {T|null} Not found: `null`
117
128
  */
118
- export function getParentElement<T extends HTMLElement>(element: Node, query: string | ((current: any) => boolean) | Node, depth?: number | null): T | null;
129
+ export function getParentElement<T extends HTMLElement>(
130
+ element: Node,
131
+ query: string | ((current: any) => boolean) | Node,
132
+ depth?: number | null,
133
+ ): T | null;
119
134
  /**
120
135
  * @template {HTMLElement} T
121
136
  * @description Gets all ancestors of the argument value.
@@ -127,7 +142,11 @@ export function getParentElement<T extends HTMLElement>(element: Node, query: st
127
142
  * @param {?number} [depth] Number of parent levels to depth.
128
143
  * @returns {Array<T>} Returned in an array in order.
129
144
  */
130
- export function getParentElements<T extends HTMLElement>(element: Node, query: string | ((current: any) => boolean) | Node, depth?: number | null): Array<T>;
145
+ export function getParentElements<T extends HTMLElement>(
146
+ element: Node,
147
+ query: string | ((current: any) => boolean) | Node,
148
+ depth?: number | null,
149
+ ): Array<T>;
131
150
  /**
132
151
  * @template {HTMLElement} T
133
152
  * @description Gets the element with `data-command` attribute among the parent elements.
@@ -156,7 +175,11 @@ export function getEventTarget<T extends HTMLElement>(event: Event): T | null;
156
175
  * const firstLeaf = dom.query.getEdgeChild(container, (n) => n.nodeType === 3, false);
157
176
  * const lastLeaf = dom.query.getEdgeChild(container, (n) => n.nodeType === 3, true);
158
177
  */
159
- export function getEdgeChild<T extends Node>(node: Node, query: string | ((current: any) => boolean) | Node, last: boolean): T | null;
178
+ export function getEdgeChild<T extends Node>(
179
+ node: Node,
180
+ query: string | ((current: any) => boolean) | Node,
181
+ last: boolean,
182
+ ): T | null;
160
183
  /**
161
184
  * @description Get edge child nodes of the argument value.
162
185
  * - 1. The first node of all the child nodes of the `first` element is returned.
@@ -197,7 +220,12 @@ export function getNextDeepestNode<T extends Node>(node: Node, ceiling?: Node |
197
220
  * @param {?(current: *) => boolean} [validate] Validation function
198
221
  * @returns {number}
199
222
  */
200
- export function findTextIndexOnLine(line: Node, offsetContainer: Node, offset: number, validate?: ((current: any) => boolean) | null): number;
223
+ export function findTextIndexOnLine(
224
+ line: Node,
225
+ offsetContainer: Node,
226
+ offset: number,
227
+ validate?: ((current: any) => boolean) | null,
228
+ ): number;
201
229
  /**
202
230
  * @description Find the end index of a sequence of at least minTabSize consecutive non-breaking spaces or spaces
203
231
  * - which are interpreted as a tab key, occurring after a given base index in a text string.
@@ -53,7 +53,10 @@ export function getAttributesToString(element: Node, exceptAttrs: Array<string>
53
53
  * @param {?(current: *) => boolean} validation Conditional function
54
54
  * @returns {Array<Node>|null}
55
55
  */
56
- export function arrayFilter(array: SunEditor.NodeCollection, validation: ((current: any) => boolean) | null): Array<Node> | null;
56
+ export function arrayFilter(
57
+ array: SunEditor.NodeCollection,
58
+ validation: ((current: any) => boolean) | null,
59
+ ): Array<Node> | null;
57
60
  /**
58
61
  * @description Get the item from the array that matches the condition.
59
62
  * @param {SunEditor.NodeCollection} array Array to get item
@@ -9,10 +9,10 @@ export class PluginBrowser extends Base {
9
9
  /**
10
10
  * @abstract
11
11
  * @description Executes the method that is called when a `Browser` module is opened.
12
- * @param {?(target: Node) => *} [onSelectfunction] - Method to be executed after selecting an item in the gallery
12
+ * @param {?(target: *) => *} [onSelectfunction] - Method to be executed after selecting an item in the gallery
13
13
  * @returns {void}
14
14
  */
15
- open(onSelectfunction?: ((target: Node) => any) | null): void;
15
+ open(onSelectfunction?: ((target: any) => any) | null): void;
16
16
  /**
17
17
  * @abstract
18
18
  * @description Executes the method that is called when a `Browser` module is closed.
@@ -118,7 +118,6 @@ export type _Lang = {
118
118
  math_modal_title: string;
119
119
  maxSize: string;
120
120
  mediaGallery: string;
121
- autocomplete: string;
122
121
  menu_bordered: string;
123
122
  menu_code: string;
124
123
  menu_neon: string;
@@ -78,7 +78,7 @@ declare class ColorPicker {
78
78
  * @description Displays or resets the currently selected color at color list.
79
79
  * @param {Node|string} nodeOrColor Current Selected node
80
80
  * @param {Node} target target
81
- * @param {?(current: Node) => boolean} [stopCondition] - A function used to stop traversing parent nodes while finding the color.
81
+ * @param {?(current: *) => boolean} [stopCondition] - A function used to stop traversing parent nodes while finding the color.
82
82
  * - When this function returns `true`, the traversal ends at that node.
83
83
  * - e.g., `(node) => this.format.isLine(node)` stops at line-level elements like <p>, <div>.
84
84
  * @example
@@ -88,7 +88,7 @@ declare class ColorPicker {
88
88
  * // Initialize with a color string directly (e.g., from a table cell style)
89
89
  * this.colorPicker.init(color?.value || '', button);
90
90
  */
91
- init(nodeOrColor: Node | string, target: Node, stopCondition?: ((current: Node) => boolean) | null): void;
91
+ init(nodeOrColor: Node | string, target: Node, stopCondition?: ((current: any) => boolean) | null): void;
92
92
  /**
93
93
  * @description Store color values
94
94
  * @param {string} hexColorStr Hax color value
@@ -46,6 +46,11 @@ export type ControllerParams = {
46
46
  * Method to be called when the controller is closed.
47
47
  */
48
48
  initMethod?: () => void;
49
+ /**
50
+ * Called on ESC before the controller closes. Return `true`
51
+ * to keep it open (e.g. when an inner sub-panel should absorb the ESC instead).
52
+ */
53
+ escGuard?: () => boolean;
49
54
  /**
50
55
  * If `true`, When the `controller` is opened, buttons without the `se-component-enabled` class are disabled.
51
56
  */
@@ -93,6 +98,8 @@ export type ControllerParams = {
93
98
  * @property {"top"|"bottom"} [position="bottom"] Controller position
94
99
  * @property {boolean} [isWWTarget=true] If the controller is in the WYSIWYG area, set it to `true`.
95
100
  * @property {() => void} [initMethod=null] Method to be called when the controller is closed.
101
+ * @property {() => boolean} [escGuard=null] Called on ESC before the controller closes. Return `true`
102
+ * to keep it open (e.g. when an inner sub-panel should absorb the ESC instead).
96
103
  * @property {boolean} [disabled=false] If `true`, When the `controller` is opened, buttons without the `se-component-enabled` class are disabled.
97
104
  * @property {Array<Controller|HTMLElement>} [parents=[]] The parent `controller` instance array when `controller` is opened nested.
98
105
  * @property {boolean} [parentsHide=false] If `true`, the parent element is hidden when the controller is opened.
@@ -96,11 +96,28 @@ export type FigureTargetInfo = {
96
96
  /**
97
97
  * Figure control button type
98
98
  */
99
- export type FigureControlButton = 'mirror_h' | 'mirror_v' | 'rotate_l' | 'rotate_r' | 'caption' | 'revert' | 'edit' | 'copy' | 'remove' | 'as' | 'align' | 'onalign' | 'onresize';
99
+ export type FigureControlButton =
100
+ | 'mirror_h'
101
+ | 'mirror_v'
102
+ | 'rotate_l'
103
+ | 'rotate_r'
104
+ | 'caption'
105
+ | 'revert'
106
+ | 'edit'
107
+ | 'copy'
108
+ | 'remove'
109
+ | 'as'
110
+ | 'align'
111
+ | 'onalign'
112
+ | 'onresize';
100
113
  /**
101
114
  * Figure control resize value type (auto, or percentage numbers)
102
115
  */
103
- export type FigureControlResize = `resize_auto,${number}` | `resize_auto,${number},${number}` | `resize_auto,${number},${number},${number}` | `resize_auto,${number},${number},${number},${number}`;
116
+ export type FigureControlResize =
117
+ | `resize_auto,${number}`
118
+ | `resize_auto,${number},${number}`
119
+ | `resize_auto,${number},${number},${number}`
120
+ | `resize_auto,${number},${number},${number},${number}`;
104
121
  /**
105
122
  * Figure control custom action object
106
123
  */
@@ -513,7 +530,12 @@ declare class Figure {
513
530
  * // Replace with anchor cover (e.g., image wrapped in a link)
514
531
  * this.figure.retainFigureFormat(container, this.#element, anchorEl, this.fileManager);
515
532
  */
516
- retainFigureFormat(container: Node, originEl: Node, anchorCover: Node, fileManagerInst?: import('../manager/FileManager').default): void;
533
+ retainFigureFormat(
534
+ container: Node,
535
+ originEl: Node,
536
+ anchorCover: Node,
537
+ fileManagerInst?: import('../manager/FileManager').default,
538
+ ): void;
517
539
  /**
518
540
  * @description Initialize the transform style (rotation) of the element.
519
541
  * @param {?Node} [node] Target element, default is the current element
@@ -532,7 +554,12 @@ declare class Figure {
532
554
  * // Apply size without additional rotation (deg=0 preserves current rotation)
533
555
  * this.figure.setTransform(oFrame, width, height, 0);
534
556
  */
535
- setTransform(node: Node, width: (string | number) | null, height: (string | number) | null, deg: number | null): void;
557
+ setTransform(
558
+ node: Node,
559
+ width: (string | number) | null,
560
+ height: (string | number) | null,
561
+ deg: number | null,
562
+ ): void;
536
563
  /**
537
564
  * @internal
538
565
  * @description Displays or hides the resize handles of the figure component.
@@ -0,0 +1,262 @@
1
+ import type {} from '../../typedef';
2
+ /**
3
+ * @description Resolve an icon spec to an HTML string. Accepts a key from `$.icons`,
4
+ * a raw HTML snippet (anything starting with `<`), or empty.
5
+ * @param {string} icon
6
+ * @param {Object} icons
7
+ * @returns {string}
8
+ */
9
+ export function resolveIconHTML(icon: string, icons: any): string;
10
+ /**
11
+ * @description Build the canonical command-menu row HTML. Single source of truth for the
12
+ * BlockHandle action menu and the SlashCommand menu, so they look identical.
13
+ * @param {string} label
14
+ * @param {string} iconHTML
15
+ * @returns {string}
16
+ */
17
+ export function buildRowHTML(label: string, iconHTML: string): string;
18
+ export default CommandMenu;
19
+ export type CommandMenuItem = {
20
+ /**
21
+ * - Optional identifier.
22
+ */
23
+ key?: string;
24
+ /**
25
+ * - Display label.
26
+ */
27
+ title: string;
28
+ /**
29
+ * - `$.icons` key or raw HTML snippet.
30
+ */
31
+ icon?: string;
32
+ /**
33
+ * - Extra search terms (used by the filter).
34
+ */
35
+ keywords?: string[];
36
+ /**
37
+ * - Custom callback. The second
38
+ * argument is the host-supplied context (e.g. `{block}` for BlockHandle, `{triggerChar, query}` for SlashCommand).
39
+ */
40
+ action: (arg0: SunEditor.Deps, arg1: any) => void | Promise<void>;
41
+ };
42
+ export type SubmenuChild = {
43
+ /**
44
+ * - Owning plugin key.
45
+ */
46
+ pluginName: string;
47
+ /**
48
+ * - The original toolbar dropdown button element. Passed to `plugin.action(element)` on click.
49
+ */
50
+ element: HTMLElement;
51
+ };
52
+ export type ResolvedItem = {
53
+ kind: 'custom' | 'plugin' | 'submenu' | 'dropdownFree';
54
+ title: string;
55
+ iconHTML: string;
56
+ /**
57
+ * - Lower-cased haystack for substring filtering.
58
+ */
59
+ search: string;
60
+ raw?: CommandMenuItem;
61
+ /**
62
+ * - Plugin key.
63
+ */
64
+ name?: string;
65
+ /**
66
+ * - Plugin type (`'modal'`, `'command'`, etc.).
67
+ */
68
+ type?: string;
69
+ command?: string;
70
+ /**
71
+ * - For `kind: 'submenu'` — clickable child rows (one per dropdown item).
72
+ */
73
+ children?: SubmenuChild[];
74
+ /**
75
+ * - For `kind: 'submenu'` — HTML for each child row.
76
+ */
77
+ childMenus?: string[];
78
+ };
79
+ export type CommandMenuParams = {
80
+ /**
81
+ * - Raw menu entries.
82
+ */
83
+ items: Array<string | CommandMenuItem>;
84
+ /**
85
+ * Caller-provided plugin/button resolver. Inject `ResolveButton` from `core/section/constructor`.
86
+ * Injected (not imported) because this module lives under `src/modules/` and cannot import from `src/core/*`.
87
+ */
88
+ resolveButton: (
89
+ arg0: string,
90
+ arg1: any,
91
+ arg2: any,
92
+ arg3: any,
93
+ arg4: any,
94
+ ) => {
95
+ title: string;
96
+ icon: string;
97
+ type: string;
98
+ command: string;
99
+ } | null;
100
+ /**
101
+ * - Base SelectMenu params (`position`, `minWidth`, `keydownTarget`, etc.).
102
+ */
103
+ selectMenuParams: any;
104
+ /**
105
+ * - Optional renderer
106
+ * applied to custom (object) items only. Plugin-string items always render with `buildRowHTML`.
107
+ */
108
+ renderCustomItem?: (
109
+ arg0: CommandMenuItem,
110
+ arg1: {
111
+ icons: any;
112
+ },
113
+ ) => string;
114
+ };
115
+ /**
116
+ * @typedef {Object} CommandMenuItem
117
+ * @property {string} [key] - Optional identifier.
118
+ * @property {string} title - Display label.
119
+ * @property {string} [icon] - `$.icons` key or raw HTML snippet.
120
+ * @property {string[]} [keywords] - Extra search terms (used by the filter).
121
+ * @property {function(SunEditor.Deps, *): void | Promise<void>} action - Custom callback. The second
122
+ * argument is the host-supplied context (e.g. `{block}` for BlockHandle, `{triggerChar, query}` for SlashCommand).
123
+ */
124
+ /**
125
+ * @typedef {Object} SubmenuChild
126
+ * @property {string} pluginName - Owning plugin key.
127
+ * @property {HTMLElement} element - The original toolbar dropdown button element. Passed to `plugin.action(element)` on click.
128
+ */
129
+ /**
130
+ * @typedef {Object} ResolvedItem
131
+ * @property {'custom'|'plugin'|'submenu'|'dropdownFree'} kind
132
+ * @property {string} title
133
+ * @property {string} iconHTML
134
+ * @property {string} search - Lower-cased haystack for substring filtering.
135
+ * @property {CommandMenuItem} [raw]
136
+ * @property {string} [name] - Plugin key.
137
+ * @property {string} [type] - Plugin type (`'modal'`, `'command'`, etc.).
138
+ * @property {string} [command]
139
+ * @property {SubmenuChild[]} [children] - For `kind: 'submenu'` — clickable child rows (one per dropdown item).
140
+ * @property {string[]} [childMenus] - For `kind: 'submenu'` — HTML for each child row.
141
+ */
142
+ /**
143
+ * @typedef {Object} CommandMenuParams
144
+ * @property {Array<string | CommandMenuItem>} items - Raw menu entries.
145
+ * @property {function(string, Object, *, Object, Object): ({title: string, icon: string, type: string, command: string} | null)} resolveButton
146
+ * Caller-provided plugin/button resolver. Inject `ResolveButton` from `core/section/constructor`.
147
+ * Injected (not imported) because this module lives under `src/modules/` and cannot import from `src/core/*`.
148
+ * @property {Object} selectMenuParams - Base SelectMenu params (`position`, `minWidth`, `keydownTarget`, etc.).
149
+ * @property {function(CommandMenuItem, { icons: Object }): string} [renderCustomItem] - Optional renderer
150
+ * applied to custom (object) items only. Plugin-string items always render with `buildRowHTML`.
151
+ */
152
+ /**
153
+ * @class
154
+ * @description Shared command-menu module used by BlockHandle and SlashCommand.
155
+ * - Owns the underlying `SelectMenu`, renders rows with the canonical BlockHandle row HTML.
156
+ * - Supports four item kinds:
157
+ * - `'custom'` — user-defined `{title, icon?, action}` invoked with `($, hostContext)`.
158
+ * - `'plugin'` — plain plugin (modal/browser/command/popup) dispatched via `plugin.open/show/action`.
159
+ * - `'submenu'` — dropdown plugin auto-expanded inline (children come from `$.menu.itemsMap`).
160
+ * - `'dropdownFree'` — dropdown-free plugin (e.g. `fontColor`, `table`) shown with a submenu arrow
161
+ * and an attached hover flyout that reuses the plugin's toolbar dropdown DOM.
162
+ * - Handles blur prevention on mousedown, hover flyout lifecycle, and click-to-toggle for dropdown-free.
163
+ *
164
+ * Host responsibilities (kept outside this module):
165
+ * - Pre-dispatch side effects (BlockHandle: `expandRangeToFullLines`; SlashCommand: delete trigger text).
166
+ * - Anchor element selection (BlockHandle anchors to the drag button; SlashCommand to a Controller wrapper).
167
+ * - Context object for custom-item actions.
168
+ */
169
+ declare class CommandMenu {
170
+ /**
171
+ * @constructor
172
+ * @param {*} _host - Reserved for future host-aware behavior (kept for API symmetry with `Modal`/`Controller`).
173
+ * @param {SunEditor.Deps} $ - Deps bag.
174
+ * @param {CommandMenuParams} params
175
+ */
176
+ constructor(_host: any, $: SunEditor.Deps, params: CommandMenuParams);
177
+ /** @type {SelectMenu} */
178
+ selectMenu: SelectMenu;
179
+ /**
180
+ * @description Bind the menu to a reference element and register the click handler.
181
+ * @param {HTMLElement} referElement
182
+ * @param {(item: ResolvedItem|null) => void} onSelect - Called with the resolved item picked by the user.
183
+ * Hosts run their pre-dispatch hook here (delete trigger, etc.) and then call `dispatch(item, ctx)`.
184
+ * @param {{ class?: string, style?: string }} [attr]
185
+ */
186
+ attach(
187
+ referElement: HTMLElement,
188
+ onSelect: (item: ResolvedItem | null) => void,
189
+ attr?: {
190
+ class?: string;
191
+ style?: string;
192
+ },
193
+ ): void;
194
+ /**
195
+ * @description Replace the items list (e.g. when host options change). Invalidates the resolved cache.
196
+ * @param {Array<string | CommandMenuItem>} items
197
+ */
198
+ setItems(items: Array<string | CommandMenuItem>): void;
199
+ /**
200
+ * @description Lazily normalize raw items. Lazy because plugin instances (`$.plugins`) may not
201
+ * be available during the host's constructor.
202
+ * @returns {ResolvedItem[]}
203
+ */
204
+ getItems(): ResolvedItem[];
205
+ /**
206
+ * @description Case-insensitive substring filter on `title + keywords + plugin name`.
207
+ * Empty query returns all items (up to `limit`).
208
+ * @param {string} query
209
+ * @param {number} [limit=Infinity]
210
+ * @returns {ResolvedItem[]}
211
+ */
212
+ filter(query: string, limit?: number): ResolvedItem[];
213
+ /**
214
+ * @description Build row HTML for a list of resolved items.
215
+ * @param {ResolvedItem[]} items
216
+ * @returns {string[]}
217
+ */
218
+ renderRows(items: ResolvedItem[]): string[];
219
+ /**
220
+ * @description Populate the SelectMenu rows.
221
+ * @param {ResolvedItem[]} items
222
+ */
223
+ createRows(items: ResolvedItem[]): void;
224
+ /**
225
+ * @description Open the SelectMenu. Lazily (re-)registers menu rows into
226
+ * `commandDispatcher.targets` so `selectionState.update` paints the `active` class on them through
227
+ * @param {string} [position]
228
+ */
229
+ open(position?: string): void;
230
+ /**
231
+ * @description Close the SelectMenu. Also unregisters menu rows from `commandDispatcher.targets`
232
+ */
233
+ close(): void;
234
+ /**
235
+ * @description Whether a sub-panel (native submenu or dropdown-free flyout) is currently open.
236
+ * Lets an owning Controller keep the menu open on ESC and close only the sub-panel.
237
+ * @returns {boolean}
238
+ */
239
+ hasOpenSubPanel(): boolean;
240
+ /**
241
+ * @description Highlight a row.
242
+ * @param {number} index
243
+ */
244
+ setItem(index: number): void;
245
+ /**
246
+ * @description Soft-hide / soft-show without changing open state. Pass-through.
247
+ * @param {boolean} hidden
248
+ */
249
+ setHidden(hidden: boolean): void;
250
+ get isOpen(): boolean;
251
+ /**
252
+ * @description Dispatch a resolved item. For custom items, calls `raw.action($, ctx)`. For plugin
253
+ * items, routes to `plugin.open/show/action` or `commandDispatcher.run` (built-ins). For dropdown-free
254
+ * items, toggles the hover flyout
255
+ * @param {ResolvedItem | SubmenuChild | null} item
256
+ * @param {*} [ctx] - Context passed to custom-item `action` (host-specific shape).
257
+ * @returns {boolean} `true` if a plugin was dispatched
258
+ */
259
+ dispatch(item: ResolvedItem | SubmenuChild | null, ctx?: any): boolean;
260
+ #private;
261
+ }
262
+ import SelectMenu from './SelectMenu.js';
@@ -30,6 +30,12 @@ export type SelectMenuParams = {
30
30
  * Optional method to call when the menu is closed
31
31
  */
32
32
  closeMethod?: () => void;
33
+ /**
34
+ * Optional owner hook invoked on ESC before the menu closes.
35
+ * Return `true` if it dismissed an owner-managed sub-panel (e.g. CommandMenu's flyout), so ESC only
36
+ * closes that sub-panel and keeps the menu open.
37
+ */
38
+ subEscMethod?: () => boolean;
33
39
  /**
34
40
  * Optional max-height CSS value (e.g. `"200px"`). Enables scrolling when items exceed this height.
35
41
  */
@@ -38,6 +44,14 @@ export type SelectMenuParams = {
38
44
  * Optional min-width CSS value (e.g. `"130px"`).
39
45
  */
40
46
  minWidth?: string;
47
+ /**
48
+ * Optional override for the keyboard navigation target. By default `on()` listens
49
+ * - on the iframe `contentWindow` (`_ww`) when the refer isn't an input — appropriate when the
50
+ * - refer is inside the wysiwyg. Set this to `window` (parent) for menus whose refer lives in
51
+ * - the parent doc (e.g. BlockHandle's dragBtn in `carrierWrapper`). Also avoids
52
+ * - cross-origin/sandboxed iframe `addEventListener` errors.
53
+ */
54
+ keydownTarget?: any;
41
55
  };
42
56
  /**
43
57
  * @typedef {Object} SelectMenuParams
@@ -52,8 +66,16 @@ export type SelectMenuParams = {
52
66
  * @property {number} [splitNum=0] Optional split number for horizontal positioning; defines how many items per row
53
67
  * @property {() => void} [openMethod] Optional method to call when the menu is opened
54
68
  * @property {() => void} [closeMethod] Optional method to call when the menu is closed
69
+ * @property {() => boolean} [subEscMethod] Optional owner hook invoked on ESC before the menu closes.
70
+ * Return `true` if it dismissed an owner-managed sub-panel (e.g. CommandMenu's flyout), so ESC only
71
+ * closes that sub-panel and keeps the menu open.
55
72
  * @property {string} [maxHeight] Optional max-height CSS value (e.g. `"200px"`). Enables scrolling when items exceed this height.
56
73
  * @property {string} [minWidth] Optional min-width CSS value (e.g. `"130px"`).
74
+ * @property {*} [keydownTarget] Optional override for the keyboard navigation target. By default `on()` listens
75
+ * - on the iframe `contentWindow` (`_ww`) when the refer isn't an input — appropriate when the
76
+ * - refer is inside the wysiwyg. Set this to `window` (parent) for menus whose refer lives in
77
+ * - the parent doc (e.g. BlockHandle's dragBtn in `carrierWrapper`). Also avoids
78
+ * - cross-origin/sandboxed iframe `addEventListener` errors.
57
79
  */
58
80
  /**
59
81
  * @class
@@ -81,14 +103,28 @@ declare class SelectMenu {
81
103
  horizontal: boolean;
82
104
  openMethod: () => void;
83
105
  closeMethod: () => void;
106
+ subEscMethod: () => boolean;
84
107
  maxHeight: string;
85
108
  minWidth: string;
86
109
  /**
87
110
  * @description Creates the select menu items.
88
- * @param {Array<string>|SunEditor.NodeCollection} items - Command list of selectable items.
89
- * @param {Array<string>|SunEditor.NodeCollection} [menus] - Optional list of menu display elements; defaults to `items`.
111
+ * @param {Array<*>} items - Selectable items.
112
+ * - Plain entry: any value (string/object); passed to the `selectMethod` callback when picked.
113
+ * - Submenu entry: `{ children: Array<*>, childMenus?: Array<string|HTMLElement> }` —
114
+ * `children` are the child values delivered to `selectMethod` on selection; `childMenus`
115
+ * is the optional display content for each child (HTML string or `HTMLElement`). When
116
+ * omitted, `children` doubles as the display content.
117
+ * @param {Array<string>|SunEditor.NodeCollection} [menus] - Optional list of display elements
118
+ * (HTML strings or nodes) for the top-level rows. Defaults to `items`. For submenu entries
119
+ * this controls the parent row's content; child rows use `childMenus` (or `children`).
120
+ * @example
121
+ * // Submenu — "List" opens a hover submenu of UL/OL options
122
+ * selectMenu.create(
123
+ * [{ children: ['ul', 'ol'], childMenus: ['<i>•</i> Bulleted', '<i>1.</i> Numbered'] }],
124
+ * ['List']
125
+ * );
90
126
  */
91
- create(items: Array<string> | SunEditor.NodeCollection, menus?: Array<string> | SunEditor.NodeCollection): void;
127
+ create(items: Array<any>, menus?: Array<string> | SunEditor.NodeCollection): void;
92
128
  /**
93
129
  * @description Initializes the select menu and attaches it to a reference element.
94
130
  * @param {Node} referElement - The element that triggers the select menu.
@@ -125,6 +161,17 @@ declare class SelectMenu {
125
161
  * selectMenu.open('', '[data-command="' + this.align + '"]');
126
162
  */
127
163
  open(position?: string | null, onItemQuerySelector?: string | null): void;
164
+ /**
165
+ * @description Re-runs positioning using the same direction the menu was opened with.
166
+ * Use when the reference element has moved (e.g. scroll repositioned the trigger) but
167
+ * the menu should stay open and follow.
168
+ */
169
+ reposition(): void;
170
+ /**
171
+ * @description Soft-hide / soft-show without changing open state.
172
+ * close listeners (outside click, ESC) keep working, but is visually hidden until the trigger comes back.
173
+ */
174
+ setHidden(hidden: any): void;
128
175
  /**
129
176
  * @description Select menu close
130
177
  */
@@ -140,6 +187,12 @@ declare class SelectMenu {
140
187
  * @param {number} index Item index
141
188
  */
142
189
  setItem(index: number): void;
190
+ /**
191
+ * @description Whether a native submenu is currently open. Used by owners (e.g. a Controller) to
192
+ * let ESC dismiss only the open submenu instead of the whole menu.
193
+ * @returns {boolean}
194
+ */
195
+ hasOpenSubmenu(): boolean;
143
196
  _onItem: Element;
144
197
  #private;
145
198
  }
@@ -1,4 +1,5 @@
1
1
  import type {} from '../../typedef';
2
2
  export { default as _DragHandle } from './_DragHandle.js';
3
+ export { default as CommandMenu } from './CommandMenu.js';
3
4
  export { default as ModalAnchorEditor } from './ModalAnchorEditor.js';
4
5
  export { default as SelectMenu } from './SelectMenu.js';
@@ -81,7 +81,7 @@ declare class AudioGallery extends PluginBrowser {
81
81
  */
82
82
  constructor(kernel: SunEditor.Kernel, pluginOptions: AudioGalleryPluginOptions);
83
83
  title: any;
84
- onSelectfunction: (target: Node) => any;
84
+ onSelectfunction: (target: any) => any;
85
85
  browser: Browser;
86
86
  #private;
87
87
  }
@@ -115,7 +115,7 @@ declare class FileBrowser extends PluginBrowser {
115
115
  */
116
116
  constructor(kernel: SunEditor.Kernel, pluginOptions: FileBrowserPluginOptions);
117
117
  title: any;
118
- onSelectfunction: (target: Node) => any;
118
+ onSelectfunction: (target: any) => any;
119
119
  browser: Browser;
120
120
  #private;
121
121
  }
@@ -83,7 +83,7 @@ declare class FileGallery extends PluginBrowser {
83
83
  */
84
84
  constructor(kernel: SunEditor.Kernel, pluginOptions: FileGalleryPluginOptions);
85
85
  title: any;
86
- onSelectfunction: (target: Node) => any;
86
+ onSelectfunction: (target: any) => any;
87
87
  browser: Browser;
88
88
  #private;
89
89
  }
@@ -78,7 +78,7 @@ declare class ImageGallery extends PluginBrowser {
78
78
  */
79
79
  constructor(kernel: SunEditor.Kernel, pluginOptions: ImageGalleryPluginOptions);
80
80
  title: any;
81
- onSelectfunction: (target: Node) => any;
81
+ onSelectfunction: (target: any) => any;
82
82
  browser: Browser;
83
83
  width: any;
84
84
  height: any;