suneditor 3.1.3 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/dist/suneditor-contents.min.css +1 -1
  2. package/dist/suneditor.min.css +28 -1
  3. package/dist/suneditor.min.js +1 -1
  4. package/package.json +2 -1
  5. package/src/assets/design/color.css +12 -0
  6. package/src/assets/design/size.css +9 -2
  7. package/src/assets/icons/defaultIcons.js +96 -47
  8. package/src/assets/suneditor-contents.css +3 -2
  9. package/src/assets/suneditor.css +480 -31
  10. package/src/core/config/contextProvider.js +2 -1
  11. package/src/core/config/eventManager.js +41 -2
  12. package/src/core/config/optionProvider.js +23 -2
  13. package/src/core/editor.js +32 -14
  14. package/src/core/event/actions/index.js +76 -9
  15. package/src/core/event/effects/common.registry.js +2 -1
  16. package/src/core/event/effects/keydown.registry.js +169 -33
  17. package/src/core/event/effects/ruleHelpers.js +20 -6
  18. package/src/core/event/eventOrchestrator.js +136 -23
  19. package/src/core/event/handlers/handler_toolbar.js +4 -2
  20. package/src/core/event/handlers/handler_ww_dragDrop.js +10 -0
  21. package/src/core/event/handlers/handler_ww_input.js +9 -2
  22. package/src/core/event/handlers/handler_ww_key.js +86 -17
  23. package/src/core/event/handlers/handler_ww_mouse.js +45 -8
  24. package/src/core/event/ports.js +23 -5
  25. package/src/core/event/reducers/keydown.reducer.js +15 -2
  26. package/src/core/event/rules/keydown.rule.arrow.js +12 -2
  27. package/src/core/event/rules/keydown.rule.backspace.js +110 -15
  28. package/src/core/event/rules/keydown.rule.delete.js +62 -7
  29. package/src/core/event/rules/keydown.rule.enter.js +62 -31
  30. package/src/core/event/support/defaultLineManager.js +9 -2
  31. package/src/core/event/support/selectionState.js +13 -3
  32. package/src/core/kernel/coreKernel.js +1 -0
  33. package/src/core/logic/dom/char.js +13 -3
  34. package/src/core/logic/dom/format.js +171 -39
  35. package/src/core/logic/dom/html.js +357 -87
  36. package/src/core/logic/dom/inline.js +229 -34
  37. package/src/core/logic/dom/listFormat.js +111 -20
  38. package/src/core/logic/dom/nodeTransform.js +36 -11
  39. package/src/core/logic/dom/offset.js +116 -31
  40. package/src/core/logic/dom/selection.js +147 -29
  41. package/src/core/logic/panel/blockHandle.js +785 -0
  42. package/src/core/logic/panel/blockResolver.js +278 -0
  43. package/src/core/logic/panel/finder.js +16 -6
  44. package/src/core/logic/panel/menu.js +119 -18
  45. package/src/core/logic/panel/toolbar.js +75 -19
  46. package/src/core/logic/panel/viewer.js +76 -20
  47. package/src/core/logic/shell/_commandExecutor.js +44 -9
  48. package/src/core/logic/shell/commandDispatcher.js +46 -4
  49. package/src/core/logic/shell/component.js +102 -25
  50. package/src/core/logic/shell/focusManager.js +13 -3
  51. package/src/core/logic/shell/history.js +21 -6
  52. package/src/core/logic/shell/pluginManager.js +21 -13
  53. package/src/core/logic/shell/shortcuts.js +9 -1
  54. package/src/core/logic/shell/ui.js +139 -37
  55. package/src/core/schema/frameContext.js +34 -3
  56. package/src/core/schema/options.js +61 -19
  57. package/src/core/section/constructor.js +537 -103
  58. package/src/core/section/documentType.js +35 -6
  59. package/src/helper/converter.js +24 -7
  60. package/src/helper/dom/domCheck.js +25 -5
  61. package/src/helper/dom/domQuery.js +2 -1
  62. package/src/helper/dom/domUtils.js +17 -4
  63. package/src/helper/env.js +11 -2
  64. package/src/helper/keyCodeMap.js +6 -2
  65. package/src/helper/markdown.js +24 -5
  66. package/src/helper/msOffice.js +9 -2
  67. package/src/interfaces/plugins.js +1 -1
  68. package/src/langs/ckb.js +0 -1
  69. package/src/langs/cs.js +0 -1
  70. package/src/langs/da.js +0 -1
  71. package/src/langs/de.js +0 -1
  72. package/src/langs/en.js +0 -1
  73. package/src/langs/es.js +0 -1
  74. package/src/langs/fa.js +0 -1
  75. package/src/langs/fr.js +0 -1
  76. package/src/langs/he.js +0 -1
  77. package/src/langs/hu.js +0 -1
  78. package/src/langs/index.js +27 -1
  79. package/src/langs/it.js +0 -1
  80. package/src/langs/ja.js +0 -1
  81. package/src/langs/km.js +0 -1
  82. package/src/langs/ko.js +0 -1
  83. package/src/langs/lv.js +0 -1
  84. package/src/langs/nl.js +0 -1
  85. package/src/langs/pl.js +0 -1
  86. package/src/langs/pt_br.js +0 -1
  87. package/src/langs/ro.js +0 -1
  88. package/src/langs/ru.js +0 -1
  89. package/src/langs/se.js +0 -1
  90. package/src/langs/tr.js +0 -1
  91. package/src/langs/uk.js +0 -1
  92. package/src/langs/ur.js +0 -1
  93. package/src/langs/zh_cn.js +0 -1
  94. package/src/modules/contract/Browser.js +68 -23
  95. package/src/modules/contract/ColorPicker.js +12 -4
  96. package/src/modules/contract/Controller.js +37 -7
  97. package/src/modules/contract/Figure.js +159 -36
  98. package/src/modules/contract/HueSlider.js +27 -4
  99. package/src/modules/contract/Modal.js +62 -11
  100. package/src/modules/manager/FileManager.js +50 -8
  101. package/src/modules/ui/CommandMenu.js +597 -0
  102. package/src/modules/ui/ModalAnchorEditor.js +41 -9
  103. package/src/modules/ui/SelectMenu.js +481 -36
  104. package/src/modules/ui/index.js +1 -0
  105. package/src/plugins/browser/audioGallery.js +8 -1
  106. package/src/plugins/browser/fileBrowser.js +15 -2
  107. package/src/plugins/browser/fileGallery.js +8 -1
  108. package/src/plugins/browser/imageGallery.js +24 -3
  109. package/src/plugins/browser/videoGallery.js +19 -4
  110. package/src/plugins/command/blockquote.js +6 -1
  111. package/src/plugins/command/codeBlock.js +43 -5
  112. package/src/plugins/command/exportPDF.js +20 -4
  113. package/src/plugins/command/fileUpload.js +46 -11
  114. package/src/plugins/command/list_bulleted.js +6 -1
  115. package/src/plugins/command/list_numbered.js +6 -1
  116. package/src/plugins/dropdown/align.js +21 -33
  117. package/src/plugins/dropdown/backgroundColor.js +10 -2
  118. package/src/plugins/dropdown/blockStyle.js +17 -22
  119. package/src/plugins/dropdown/font.js +34 -34
  120. package/src/plugins/dropdown/hr.js +15 -43
  121. package/src/plugins/dropdown/layout.js +10 -27
  122. package/src/plugins/dropdown/lineHeight.js +10 -33
  123. package/src/plugins/dropdown/list.js +19 -25
  124. package/src/plugins/dropdown/paragraphStyle.js +16 -24
  125. package/src/plugins/dropdown/table/index.js +72 -17
  126. package/src/plugins/dropdown/table/render/table.html.js +3 -1
  127. package/src/plugins/dropdown/table/services/table.cell.js +33 -7
  128. package/src/plugins/dropdown/table/services/table.clipboard.js +5 -1
  129. package/src/plugins/dropdown/table/services/table.grid.js +40 -9
  130. package/src/plugins/dropdown/table/services/table.resize.js +55 -11
  131. package/src/plugins/dropdown/table/services/table.selection.js +27 -7
  132. package/src/plugins/dropdown/table/services/table.style.js +120 -20
  133. package/src/plugins/dropdown/template.js +13 -29
  134. package/src/plugins/dropdown/textStyle.js +22 -35
  135. package/src/plugins/field/autocomplete.js +8 -4
  136. package/src/plugins/field/slashCommand.js +297 -0
  137. package/src/plugins/index.js +3 -0
  138. package/src/plugins/input/fontSize.js +37 -8
  139. package/src/plugins/input/pageNavigator.js +7 -1
  140. package/src/plugins/modal/audio.js +71 -17
  141. package/src/plugins/modal/drawing.js +41 -11
  142. package/src/plugins/modal/embed.js +132 -22
  143. package/src/plugins/modal/image/index.js +115 -28
  144. package/src/plugins/modal/image/services/image.size.js +9 -2
  145. package/src/plugins/modal/image/services/image.upload.js +38 -4
  146. package/src/plugins/modal/link.js +9 -2
  147. package/src/plugins/modal/math.js +10 -2
  148. package/src/plugins/modal/video/index.js +112 -26
  149. package/src/plugins/modal/video/render/video.html.js +4 -1
  150. package/src/plugins/modal/video/services/video.size.js +15 -4
  151. package/src/plugins/modal/video/services/video.upload.js +10 -2
  152. package/src/plugins/popup/anchor.js +14 -2
  153. package/src/suneditor.js +8 -2
  154. package/src/themes/cobalt.css +12 -0
  155. package/src/themes/cream.css +12 -0
  156. package/src/themes/dark.css +12 -0
  157. package/src/themes/midnight.css +12 -0
  158. package/src/typedef.js +32 -21
  159. package/types/assets/icons/defaultIcons.d.ts +1 -0
  160. package/types/core/config/contextProvider.d.ts +7 -1
  161. package/types/core/config/eventManager.d.ts +37 -4
  162. package/types/core/config/optionProvider.d.ts +5 -1
  163. package/types/core/event/actions/index.d.ts +44 -6
  164. package/types/core/event/effects/keydown.registry.d.ts +37 -7
  165. package/types/core/event/effects/ruleHelpers.d.ts +6 -1
  166. package/types/core/event/eventOrchestrator.d.ts +6 -1
  167. package/types/core/event/handlers/handler_ww_clipboard.d.ts +15 -3
  168. package/types/core/event/handlers/handler_ww_dragDrop.d.ts +14 -2
  169. package/types/core/event/handlers/handler_ww_input.d.ts +10 -2
  170. package/types/core/event/handlers/handler_ww_key.d.ts +10 -2
  171. package/types/core/event/handlers/handler_ww_mouse.d.ts +25 -5
  172. package/types/core/event/ports.d.ts +7 -2
  173. package/types/core/event/rules/keydown.rule.backspace.d.ts +6 -1
  174. package/types/core/kernel/store.d.ts +4 -1
  175. package/types/core/logic/dom/format.d.ts +32 -14
  176. package/types/core/logic/dom/html.d.ts +11 -3
  177. package/types/core/logic/dom/nodeTransform.d.ts +6 -6
  178. package/types/core/logic/panel/blockHandle.d.ts +64 -0
  179. package/types/core/logic/panel/blockResolver.d.ts +50 -0
  180. package/types/core/logic/panel/menu.d.ts +72 -3
  181. package/types/core/logic/shell/commandDispatcher.d.ts +8 -0
  182. package/types/core/logic/shell/component.d.ts +5 -3
  183. package/types/core/logic/shell/shortcuts.d.ts +10 -1
  184. package/types/core/logic/shell/ui.d.ts +7 -1
  185. package/types/core/schema/context.d.ts +7 -1
  186. package/types/core/schema/frameContext.d.ts +36 -4
  187. package/types/core/schema/options.d.ts +110 -37
  188. package/types/core/section/constructor.d.ts +38 -1
  189. package/types/events.d.ts +208 -32
  190. package/types/helper/converter.d.ts +4 -2
  191. package/types/helper/dom/domCheck.d.ts +12 -2
  192. package/types/helper/dom/domQuery.d.ts +35 -7
  193. package/types/helper/dom/domUtils.d.ts +4 -1
  194. package/types/interfaces/plugins.d.ts +2 -2
  195. package/types/langs/_Lang.d.ts +0 -1
  196. package/types/modules/contract/Browser.d.ts +7 -7
  197. package/types/modules/contract/ColorPicker.d.ts +2 -2
  198. package/types/modules/contract/Controller.d.ts +7 -0
  199. package/types/modules/contract/Figure.d.ts +31 -4
  200. package/types/modules/ui/CommandMenu.d.ts +262 -0
  201. package/types/modules/ui/ModalAnchorEditor.d.ts +6 -1
  202. package/types/modules/ui/SelectMenu.d.ts +56 -3
  203. package/types/modules/ui/index.d.ts +1 -0
  204. package/types/plugins/browser/audioGallery.d.ts +17 -1
  205. package/types/plugins/browser/fileBrowser.d.ts +17 -1
  206. package/types/plugins/browser/fileGallery.d.ts +17 -1
  207. package/types/plugins/browser/imageGallery.d.ts +17 -1
  208. package/types/plugins/browser/videoGallery.d.ts +17 -1
  209. package/types/plugins/dropdown/align.d.ts +1 -1
  210. package/types/plugins/dropdown/blockStyle.d.ts +3 -1
  211. package/types/plugins/dropdown/table/index.d.ts +4 -1
  212. package/types/plugins/dropdown/table/services/table.clipboard.d.ts +5 -1
  213. package/types/plugins/dropdown/table/services/table.grid.d.ts +10 -2
  214. package/types/plugins/field/autocomplete.d.ts +0 -1
  215. package/types/plugins/field/slashCommand.d.ts +165 -0
  216. package/types/plugins/index.d.ts +3 -0
  217. package/types/plugins/modal/embed.d.ts +34 -0
  218. package/types/plugins/modal/link.d.ts +4 -1
  219. package/types/typedef.d.ts +48 -23
package/src/langs/tr.js CHANGED
@@ -134,7 +134,6 @@
134
134
  math_modal_title: 'Matematik',
135
135
  maxSize: 'En Büyük Boyut',
136
136
  mediaGallery: 'Medya galerisi',
137
- autocomplete: 'Otomatik Tamamlama',
138
137
  mention: 'Belirtmek',
139
138
  menu_bordered: 'Çerçeveli',
140
139
  menu_code: 'Kod',
package/src/langs/uk.js CHANGED
@@ -134,7 +134,6 @@
134
134
  math_modal_title: 'Формула',
135
135
  maxSize: 'Ширина за розміром сторінки',
136
136
  mediaGallery: 'Медіа галерея',
137
- autocomplete: 'Автозаповнення',
138
137
  mention: 'Згадати',
139
138
  menu_bordered: 'З лініями',
140
139
  menu_code: 'Код',
package/src/langs/ur.js CHANGED
@@ -134,7 +134,6 @@
134
134
  math_modal_title: 'ریاضی',
135
135
  maxSize: 'زیادہ سے زیادہ سائز',
136
136
  mediaGallery: 'میڈیا گیلری',
137
- autocomplete: 'خود بخود مکمل',
138
137
  mention: 'تذکرہ',
139
138
  menu_bordered: 'سرحدی',
140
139
  menu_code: 'کوڈ',
@@ -134,7 +134,6 @@
134
134
  math_modal_title: '数学',
135
135
  maxSize: '最大尺寸',
136
136
  mediaGallery: '媒体库',
137
- autocomplete: '自动完成',
138
137
  mention: '提到',
139
138
  menu_bordered: '边界线',
140
139
  menu_code: '代码',
@@ -40,7 +40,7 @@ import ApiManager from '../manager/ApiManager';
40
40
  * ]
41
41
  * }
42
42
  * ```
43
- * @property {Object<string, string>} [searchUrlHeader] - File server search http header. Optional. Can be overridden in browser.
43
+ * @property {Object<string, string>} [searchHeaders] - File server search http header. Optional. Can be overridden in browser.
44
44
  * @property {string} [listClass] - Class name of list div. Required. Can be overridden in browser.
45
45
  * @property {(item: BrowserFile) => string} [drawItemHandler] - Function that returns HTML string for rendering each file item. Required. Can be overridden in browser.
46
46
  * ```js
@@ -93,7 +93,9 @@ class Browser {
93
93
 
94
94
  // create HTML
95
95
  this.useSearch = params.useSearch ?? true;
96
- const browserFrame = dom.utils.createElement('DIV', { class: 'se-browser sun-editor-common' + (params.className ? ` ${params.className}` : '') });
96
+ const browserFrame = dom.utils.createElement('DIV', {
97
+ class: 'se-browser sun-editor-common' + (params.className ? ` ${params.className}` : ''),
98
+ });
97
99
  const contentHTML = CreateHTMLInfos(this.#$, this.useSearch);
98
100
  const content = contentHTML.html;
99
101
 
@@ -114,10 +116,13 @@ class Browser {
114
116
  this.listClass = params.listClass || 'se-preview-list';
115
117
  this.directData = params.data;
116
118
  this.url = params.url;
117
- this.urlHeader = params.headers;
119
+ this.headers = params.headers;
118
120
  this.searchUrl = params.searchUrl;
119
- this.searchUrlHeader = params.searchUrlHeader;
120
- this.drawItemHandler = (params.drawItemHandler || DrawItems).bind({ thumbnail: params.thumbnail, props: params.props || [] });
121
+ this.searchHeaders = params.searchHeaders;
122
+ this.drawItemHandler = (params.drawItemHandler || DrawItems).bind({
123
+ thumbnail: params.thumbnail,
124
+ props: params.props || [],
125
+ });
121
126
  this.selectorHandler = params.selectorHandler;
122
127
  this.columnSize = params.columnSize || 4;
123
128
  this.expand = params.expand ?? 1;
@@ -159,13 +164,23 @@ class Browser {
159
164
  this.#$.eventManager.addEvent(this.side, 'click', this.#OnClickSide.bind(this));
160
165
  this.#$.eventManager.addEvent(content, 'mousedown', this.#OnMouseDown_browser.bind(this));
161
166
  this.#$.eventManager.addEvent(content, 'click', this.#OnClick_browser.bind(this));
162
- this.#$.eventManager.addEvent((this.sideOpenBtn = /** @type {HTMLButtonElement} */ (browserFrame.querySelector('.se-side-open-btn'))), 'click', this.#SideOpen.bind(this));
163
- this.#$.eventManager.addEvent([this.header, browserFrame.querySelector('.se-browser-main')], 'mousedown', this.#SideClose.bind(this));
167
+ this.#$.eventManager.addEvent(
168
+ (this.sideOpenBtn = /** @type {HTMLButtonElement} */ (browserFrame.querySelector('.se-side-open-btn'))),
169
+ 'click',
170
+ this.#SideOpen.bind(this),
171
+ );
172
+ this.#$.eventManager.addEvent(
173
+ [this.header, browserFrame.querySelector('.se-browser-main')],
174
+ 'mousedown',
175
+ this.#SideClose.bind(this),
176
+ );
164
177
 
165
178
  // search
166
179
  const searchForm = browserFrame.querySelector('form.se-browser-search-form');
167
180
  this.#searchInput = /** @type {HTMLInputElement} */ (searchForm?.querySelector('input[type="text"]'));
168
- this.#searchClearBtn = /** @type {HTMLButtonElement} */ (browserFrame.querySelector('.se-browser-search-clear'));
181
+ this.#searchClearBtn = /** @type {HTMLButtonElement} */ (
182
+ browserFrame.querySelector('.se-browser-search-clear')
183
+ );
169
184
  this.#$.eventManager.addEvent(searchForm, 'submit', this.#Search.bind(this));
170
185
  this.#$.eventManager.addEvent(this.#searchClearBtn, 'click', this.#ClearSearch.bind(this));
171
186
  }
@@ -176,7 +191,7 @@ class Browser {
176
191
  * @param {string} [params.listClass] - Class name of list div. If not, use `this.listClass`.
177
192
  * @param {string} [params.title] - File browser window title. If not, use `this.title`.
178
193
  * @param {string} [params.url] - File server url. If not, use `this.url`.
179
- * @param {Object<string, string>} [params.urlHeader] - File server http header. If not, use `this.urlHeader`.
194
+ * @param {Object<string, string>} [params.headers] - File server http header. If not, use `this.headers`.
180
195
  * @example
181
196
  * // Open with default settings (configured at construction):
182
197
  * this.browser.open();
@@ -185,7 +200,7 @@ class Browser {
185
200
  * this.browser.open({
186
201
  * title: 'Select a video',
187
202
  * url: '/api/videos',
188
- * urlHeader: { Authorization: 'Bearer token' },
203
+ * headers: { Authorization: 'Bearer token' },
189
204
  * });
190
205
  */
191
206
  open(params = {}) {
@@ -205,10 +220,11 @@ class Browser {
205
220
  if (this.directData) {
206
221
  this.#drowItems(this.directData);
207
222
  } else {
208
- this.#drawFileList(params.url || this.url, params.urlHeader || this.urlHeader, false);
223
+ this.#drawFileList(params.url || this.url, params.headers || this.headers, false);
209
224
  }
210
225
 
211
- this.body.style.maxHeight = dom.utils.getClientSize().h - (this.#$.offset.getGlobal(this.body).top - _w.scrollY) - 20 + 'px';
226
+ this.body.style.maxHeight =
227
+ dom.utils.getClientSize().h - (this.#$.offset.getGlobal(this.body).top - _w.scrollY) - 20 + 'px';
212
228
  }
213
229
 
214
230
  /**
@@ -246,7 +262,12 @@ class Browser {
246
262
  search(keyword) {
247
263
  if (this.searchUrl) {
248
264
  this.keyword = keyword;
249
- this.#drawFileList(this.searchUrl + '?keyword=' + keyword, this.searchUrlHeader, false);
265
+ const sep = this.searchUrl.includes('?') ? '&' : '?';
266
+ this.#drawFileList(
267
+ this.searchUrl + sep + 'keyword=' + _w.encodeURIComponent(keyword),
268
+ this.searchHeaders,
269
+ false,
270
+ );
250
271
  } else {
251
272
  this.keyword = keyword.toLowerCase();
252
273
  this.#drawListItem(this.#allItems.length > 0 ? this.#allItems : this.items, false);
@@ -282,7 +303,9 @@ class Browser {
282
303
  */
283
304
  tagfilter(items) {
284
305
  const selectedTags = this.selectedTags;
285
- return selectedTags.length === 0 ? items : items.filter((item) => !Array.isArray(item.tag) || item.tag.some((tag) => selectedTags.includes(tag)));
306
+ return selectedTags.length === 0
307
+ ? items
308
+ : items.filter((item) => !Array.isArray(item.tag) || item.tag.some((tag) => selectedTags.includes(tag)));
286
309
  }
287
310
 
288
311
  /**
@@ -302,11 +325,17 @@ class Browser {
302
325
  /**
303
326
  * @description Fetches the file list from the server.
304
327
  * @param {string} url - The file server URL.
305
- * @param {Object<string, string>} urlHeader - The HTTP headers for the request.
328
+ * @param {Object<string, string>} headers - The HTTP headers for the request.
306
329
  * @param {boolean} pageLoading - Indicates if this is a paginated request.
307
330
  */
308
- #drawFileList(url, urlHeader, pageLoading) {
309
- this.apiManager.call({ method: 'GET', url, headers: urlHeader, callBack: this.#CallBackGet.bind(this), errorCallBack: this.#CallBackError.bind(this) });
331
+ #drawFileList(url, headers, pageLoading) {
332
+ this.apiManager.call({
333
+ method: 'GET',
334
+ url,
335
+ headers,
336
+ callBack: this.#CallBackGet.bind(this),
337
+ errorCallBack: this.#CallBackError.bind(this),
338
+ });
310
339
  if (!pageLoading) {
311
340
  this.sideOpenBtn.style.display = 'none';
312
341
  this.showBrowserLoading();
@@ -403,7 +432,9 @@ class Browser {
403
432
  this.side.appendChild(sideInner);
404
433
 
405
434
  if (this.folderDefaultPath) {
406
- const openFolder = /** @type {HTMLButtonElement} */ (sideInner.querySelector(`[data-command="${this.folderDefaultPath}"]`));
435
+ const openFolder = /** @type {HTMLButtonElement} */ (
436
+ sideInner.querySelector(`[data-command="${this.folderDefaultPath}"]`)
437
+ );
407
438
  openFolder.click();
408
439
  if (this.folderDefaultPath.includes('/')) {
409
440
  dom.utils.removeClass(openFolder.parentElement, 'se-menu-hidden');
@@ -484,7 +515,10 @@ class Browser {
484
515
  );
485
516
  const folderDiv = dom.utils.createElement('div', { class: 'se-menu-folder' }, folderLabel);
486
517
 
487
- folderLabel.insertBefore(dom.utils.createElement('button', null, expanded ? this.openArrow : this.closeArrow), folderLabel.firstElementChild);
518
+ folderLabel.insertBefore(
519
+ dom.utils.createElement('button', null, expanded ? this.openArrow : this.closeArrow),
520
+ folderLabel.firstElementChild,
521
+ );
488
522
  const childContainer = document.createElement('div');
489
523
  dom.utils.addClass(childContainer, expanded ? 'se-menu-child' : 'se-menu-child|se-menu-hidden');
490
524
  this.#createFolderList(item.children, childContainer, depth + 1);
@@ -492,7 +526,11 @@ class Browser {
492
526
 
493
527
  parentElement.appendChild(folderDiv);
494
528
  } else {
495
- const folderLabel = dom.utils.createElement('div', { 'data-command': item.key, 'aria-label': item.name, class: 'se-menu-folder-item' }, `<span class="se-menu-icon">${this.icon_item}</span><span>${item.name}</span>`);
529
+ const folderLabel = dom.utils.createElement(
530
+ 'div',
531
+ { 'data-command': item.key, 'aria-label': item.name, class: 'se-menu-folder-item' },
532
+ `<span class="se-menu-icon">${this.icon_item}</span><span>${item.name}</span>`,
533
+ );
496
534
  if (parentElement === this.sideInner) {
497
535
  const folderDiv = dom.utils.createElement('div', { class: 'se-menu-folder' }, folderLabel);
498
536
  parentElement.appendChild(folderDiv);
@@ -528,7 +566,9 @@ class Browser {
528
566
  */
529
567
  #CallBackError(res, xmlHttp) {
530
568
  this.closeBrowserLoading();
531
- throw Error(`[SUNEDITOR.browser.get.serverException] status: ${xmlHttp.status}, response: ${res.errorMessage || xmlHttp.responseText}`);
569
+ throw Error(
570
+ `[SUNEDITOR.browser.get.serverException] status: ${xmlHttp.status}, response: ${res.errorMessage || xmlHttp.responseText}`,
571
+ );
532
572
  }
533
573
 
534
574
  /**
@@ -601,7 +641,7 @@ class Browser {
601
641
  this.selectedTags = [];
602
642
 
603
643
  if (typeof data === 'string') {
604
- this.#drawFileList(data, this.urlHeader, true);
644
+ this.#drawFileList(data, this.headers, true);
605
645
  } else {
606
646
  this.#drawListItem(data, true);
607
647
  }
@@ -665,7 +705,12 @@ class Browser {
665
705
  const text = el.textContent;
666
706
  const idx = text.toLowerCase().indexOf(keyword);
667
707
  if (idx > -1) {
668
- el.innerHTML = text.substring(0, idx) + '<mark>' + text.substring(idx, idx + keyword.length) + '</mark>' + text.substring(idx + keyword.length);
708
+ el.innerHTML =
709
+ text.substring(0, idx) +
710
+ '<mark>' +
711
+ text.substring(idx, idx + keyword.length) +
712
+ '</mark>' +
713
+ text.substring(idx + keyword.length);
669
714
  }
670
715
  }
671
716
  }
@@ -120,7 +120,11 @@ class ColorPicker {
120
120
  if (!params.disableHEXInput) {
121
121
  this.hueSlider = new HueSlider(this, $, params.hueSliderOptions, 'se-dropdown');
122
122
  // hue open
123
- this.#$.eventManager.addEvent(this.target.querySelector('.__se_hue'), 'click', this.#OnColorPalette.bind(this));
123
+ this.#$.eventManager.addEvent(
124
+ this.target.querySelector('.__se_hue'),
125
+ 'click',
126
+ this.#OnColorPalette.bind(this),
127
+ );
124
128
  this.#$.eventManager.addEvent(this.inputElement, 'input', this.#OnChangeInput.bind(this));
125
129
  this.#$.eventManager.addEvent(this.target.querySelector('form'), 'submit', this.#Submit.bind(this));
126
130
  }
@@ -140,7 +144,7 @@ class ColorPicker {
140
144
  * @description Displays or resets the currently selected color at color list.
141
145
  * @param {Node|string} nodeOrColor Current Selected node
142
146
  * @param {Node} target target
143
- * @param {?(current: Node) => boolean} [stopCondition] - A function used to stop traversing parent nodes while finding the color.
147
+ * @param {?(current: *) => boolean} [stopCondition] - A function used to stop traversing parent nodes while finding the color.
144
148
  * - When this function returns `true`, the traversal ends at that node.
145
149
  * - e.g., `(node) => this.format.isLine(node)` stops at line-level elements like <p>, <div>.
146
150
  * @example
@@ -154,7 +158,9 @@ class ColorPicker {
154
158
  this.targetButton = target;
155
159
  if (typeof stopCondition !== 'function') stopCondition = () => false;
156
160
 
157
- let fillColor = (typeof nodeOrColor === 'string' ? nodeOrColor : this.#getColorInNode(nodeOrColor, stopCondition)) || this.defaultColor;
161
+ let fillColor =
162
+ (typeof nodeOrColor === 'string' ? nodeOrColor : this.#getColorInNode(nodeOrColor, stopCondition)) ||
163
+ this.defaultColor;
158
164
  fillColor = converter.isHexColor(fillColor) ? fillColor : converter.rgb2hex(fillColor) || fillColor || '';
159
165
 
160
166
  const colorList = this.colorList;
@@ -248,7 +254,9 @@ class ColorPicker {
248
254
  return parseInt(a, 10);
249
255
  });
250
256
  dom.utils.removeItem(temp);
251
- return colors.length >= 3 ? '#' + ((1 << 24) + (colors[0] << 16) + (colors[1] << 8) + colors[2]).toString(16).substring(1) : '';
257
+ return colors.length >= 3
258
+ ? '#' + ((1 << 24) + (colors[0] << 16) + (colors[1] << 8) + colors[2]).toString(16).substring(1)
259
+ : '';
252
260
  }
253
261
 
254
262
  #OnColorPalette() {
@@ -25,6 +25,8 @@ const ADD_OFFSET_VALUE = { left: 0, right: 0, top: 0 };
25
25
  * @property {"top"|"bottom"} [position="bottom"] Controller position
26
26
  * @property {boolean} [isWWTarget=true] If the controller is in the WYSIWYG area, set it to `true`.
27
27
  * @property {() => void} [initMethod=null] Method to be called when the controller is closed.
28
+ * @property {() => boolean} [escGuard=null] Called on ESC before the controller closes. Return `true`
29
+ * to keep it open (e.g. when an inner sub-panel should absorb the ESC instead).
28
30
  * @property {boolean} [disabled=false] If `true`, When the `controller` is opened, buttons without the `se-component-enabled` class are disabled.
29
31
  * @property {Array<Controller|HTMLElement>} [parents=[]] The parent `controller` instance array when `controller` is opened nested.
30
32
  * @property {boolean} [parentsHide=false] If `true`, the parent element is hidden when the controller is opened.
@@ -45,6 +47,7 @@ class Controller {
45
47
  #$;
46
48
 
47
49
  #initMethod;
50
+ #escGuard;
48
51
  #globalEventHandlers;
49
52
 
50
53
  #addOffset = ADD_OFFSET_VALUE;
@@ -98,7 +101,11 @@ class Controller {
98
101
  this.__offset = {};
99
102
 
100
103
  this.#initMethod = typeof params.initMethod === 'function' ? params.initMethod : null;
101
- this.#globalEventHandlers = { keydown: this.#CloseListener_keydown.bind(this), mousedown: this.#CloseListener_mousedown.bind(this) };
104
+ this.#escGuard = typeof params.escGuard === 'function' ? params.escGuard : null;
105
+ this.#globalEventHandlers = {
106
+ keydown: this.#CloseListener_keydown.bind(this),
107
+ mousedown: this.#CloseListener_mousedown.bind(this),
108
+ };
102
109
 
103
110
  for (const parent of this.parents) {
104
111
  if (dom.check.isElement(parent)) {
@@ -293,7 +300,8 @@ class Controller {
293
300
  * @description Reposition controller on scroll event
294
301
  */
295
302
  _scrollReposition() {
296
- if (this.form.hasAttribute('data-se-hidden-by-parent') || this.form.hasAttribute('data-se-hidden-by-children')) return;
303
+ if (this.form.hasAttribute('data-se-hidden-by-parent') || this.form.hasAttribute('data-se-hidden-by-children'))
304
+ return;
297
305
  if (this.#setControllerPosition(this.form, this.currentPositionTarget, false)) {
298
306
  _w.setTimeout(() => {
299
307
  this.#childrenSync('show');
@@ -368,7 +376,14 @@ class Controller {
368
376
  notInCarrier: !this.#$.contextProvider.carrierWrapper.contains(form),
369
377
  };
370
378
 
371
- if ((await this.#$.eventManager.triggerEvent('onBeforeShowController', { caller: this.kind, frameContext: this.#$.frameContext, info })) === false) return;
379
+ if (
380
+ (await this.#$.eventManager.triggerEvent('onBeforeShowController', {
381
+ caller: this.kind,
382
+ frameContext: this.#$.frameContext,
383
+ info,
384
+ })) === false
385
+ )
386
+ return;
372
387
 
373
388
  form.style.display = 'block';
374
389
  if (this.#$.contextProvider.shadowRoot) {
@@ -388,7 +403,11 @@ class Controller {
388
403
  this.isOpen = true;
389
404
 
390
405
  this.host.controllerOn?.(form, target);
391
- this.#$.eventManager.triggerEvent('onShowController', { caller: this.kind, frameContext: this.#$.frameContext, info });
406
+ this.#$.eventManager.triggerEvent('onShowController', {
407
+ caller: this.kind,
408
+ frameContext: this.#$.frameContext,
409
+ info,
410
+ });
392
411
  }
393
412
 
394
413
  /**
@@ -403,7 +422,9 @@ class Controller {
403
422
  this.#$.ui.setControllerOnDisabledButtons(false);
404
423
  this.#$.ui.offControllerContext();
405
424
 
406
- this.#$.frameContext.get('lineBreaker_t').style.display = this.#$.frameContext.get('lineBreaker_b').style.display = 'none';
425
+ this.#$.frameContext.get('lineBreaker_t').style.display = this.#$.frameContext.get(
426
+ 'lineBreaker_b',
427
+ ).style.display = 'none';
407
428
  this.#$.store.set('_lastSelectionNode', null);
408
429
  this.#$.ui.currentControllerName = '';
409
430
  this.#$.store.set('_preventBlur', false);
@@ -477,7 +498,11 @@ class Controller {
477
498
  #addGlobalEvent() {
478
499
  this.#removeGlobalEvent();
479
500
  this.#bindClose_key = this.#$.eventManager.addGlobalEvent('keydown', this.#globalEventHandlers.keydown, true);
480
- this.#bindClose_mouse = this.#$.eventManager.addGlobalEvent(isMobile ? 'click' : 'mousedown', this.#globalEventHandlers.mousedown, true);
501
+ this.#bindClose_mouse = this.#$.eventManager.addGlobalEvent(
502
+ isMobile ? 'click' : 'mousedown',
503
+ this.#globalEventHandlers.mousedown,
504
+ true,
505
+ );
481
506
  }
482
507
 
483
508
  /**
@@ -526,7 +551,11 @@ class Controller {
526
551
  }
527
552
 
528
553
  const _element = this.host._element;
529
- return !isParentForm && (!!dom.query.getParentElement(target, '.se-controller') || (this.#$.component.isInline(_element) ? target === _element : target?.contains(_element)));
554
+ return (
555
+ !isParentForm &&
556
+ (!!dom.query.getParentElement(target, '.se-controller') ||
557
+ (this.#$.component.isInline(_element) ? target === _element : target?.contains(_element)))
558
+ );
530
559
  }
531
560
 
532
561
  /**
@@ -584,6 +613,7 @@ class Controller {
584
613
  if (this.#$.pluginManager.fileInfo.pluginRegExp.test(this.kind)) return;
585
614
  } else {
586
615
  if (this.#__childrenControllers__.some(({ isOpen }) => isOpen)) return;
616
+ if (this.#escGuard?.()) return;
587
617
  }
588
618
 
589
619
  this.#PostCloseEvent(eventTarget);