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
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: '代码',
@@ -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
 
@@ -117,7 +119,10 @@ class Browser {
117
119
  this.headers = params.headers;
118
120
  this.searchUrl = params.searchUrl;
119
121
  this.searchHeaders = params.searchHeaders;
120
- this.drawItemHandler = (params.drawItemHandler || DrawItems).bind({ thumbnail: params.thumbnail, props: params.props || [] });
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
  }
@@ -208,7 +223,8 @@ class Browser {
208
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
  /**
@@ -247,7 +263,11 @@ class Browser {
247
263
  if (this.searchUrl) {
248
264
  this.keyword = keyword;
249
265
  const sep = this.searchUrl.includes('?') ? '&' : '?';
250
- this.#drawFileList(this.searchUrl + sep + 'keyword=' + _w.encodeURIComponent(keyword), this.searchHeaders, false);
266
+ this.#drawFileList(
267
+ this.searchUrl + sep + 'keyword=' + _w.encodeURIComponent(keyword),
268
+ this.searchHeaders,
269
+ false,
270
+ );
251
271
  } else {
252
272
  this.keyword = keyword.toLowerCase();
253
273
  this.#drawListItem(this.#allItems.length > 0 ? this.#allItems : this.items, false);
@@ -283,7 +303,9 @@ class Browser {
283
303
  */
284
304
  tagfilter(items) {
285
305
  const selectedTags = this.selectedTags;
286
- 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)));
287
309
  }
288
310
 
289
311
  /**
@@ -307,7 +329,13 @@ class Browser {
307
329
  * @param {boolean} pageLoading - Indicates if this is a paginated request.
308
330
  */
309
331
  #drawFileList(url, headers, pageLoading) {
310
- this.apiManager.call({ method: 'GET', url, headers, callBack: this.#CallBackGet.bind(this), errorCallBack: this.#CallBackError.bind(this) });
332
+ this.apiManager.call({
333
+ method: 'GET',
334
+ url,
335
+ headers,
336
+ callBack: this.#CallBackGet.bind(this),
337
+ errorCallBack: this.#CallBackError.bind(this),
338
+ });
311
339
  if (!pageLoading) {
312
340
  this.sideOpenBtn.style.display = 'none';
313
341
  this.showBrowserLoading();
@@ -404,7 +432,9 @@ class Browser {
404
432
  this.side.appendChild(sideInner);
405
433
 
406
434
  if (this.folderDefaultPath) {
407
- const openFolder = /** @type {HTMLButtonElement} */ (sideInner.querySelector(`[data-command="${this.folderDefaultPath}"]`));
435
+ const openFolder = /** @type {HTMLButtonElement} */ (
436
+ sideInner.querySelector(`[data-command="${this.folderDefaultPath}"]`)
437
+ );
408
438
  openFolder.click();
409
439
  if (this.folderDefaultPath.includes('/')) {
410
440
  dom.utils.removeClass(openFolder.parentElement, 'se-menu-hidden');
@@ -485,7 +515,10 @@ class Browser {
485
515
  );
486
516
  const folderDiv = dom.utils.createElement('div', { class: 'se-menu-folder' }, folderLabel);
487
517
 
488
- 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
+ );
489
522
  const childContainer = document.createElement('div');
490
523
  dom.utils.addClass(childContainer, expanded ? 'se-menu-child' : 'se-menu-child|se-menu-hidden');
491
524
  this.#createFolderList(item.children, childContainer, depth + 1);
@@ -493,7 +526,11 @@ class Browser {
493
526
 
494
527
  parentElement.appendChild(folderDiv);
495
528
  } else {
496
- 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
+ );
497
534
  if (parentElement === this.sideInner) {
498
535
  const folderDiv = dom.utils.createElement('div', { class: 'se-menu-folder' }, folderLabel);
499
536
  parentElement.appendChild(folderDiv);
@@ -529,7 +566,9 @@ class Browser {
529
566
  */
530
567
  #CallBackError(res, xmlHttp) {
531
568
  this.closeBrowserLoading();
532
- 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
+ );
533
572
  }
534
573
 
535
574
  /**
@@ -666,7 +705,12 @@ class Browser {
666
705
  const text = el.textContent;
667
706
  const idx = text.toLowerCase().indexOf(keyword);
668
707
  if (idx > -1) {
669
- 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);
670
714
  }
671
715
  }
672
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);