suneditor 3.0.0-rc.5 → 3.0.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 (118) hide show
  1. package/README.md +3 -2
  2. package/dist/suneditor-contents.min.css +1 -1
  3. package/dist/suneditor.min.css +1 -1
  4. package/dist/suneditor.min.js +1 -1
  5. package/package.json +2 -3
  6. package/src/assets/design/color.css +14 -2
  7. package/src/assets/design/typography.css +5 -0
  8. package/src/assets/icons/defaultIcons.js +22 -4
  9. package/src/assets/suneditor-contents.css +1 -1
  10. package/src/assets/suneditor.css +312 -18
  11. package/src/core/config/eventManager.js +6 -9
  12. package/src/core/editor.js +1 -1
  13. package/src/core/event/actions/index.js +5 -0
  14. package/src/core/event/effects/keydown.registry.js +25 -0
  15. package/src/core/event/eventOrchestrator.js +69 -2
  16. package/src/core/event/handlers/handler_ww_mouse.js +1 -0
  17. package/src/core/event/rules/keydown.rule.backspace.js +9 -1
  18. package/src/core/kernel/coreKernel.js +4 -0
  19. package/src/core/kernel/store.js +2 -0
  20. package/src/core/logic/dom/html.js +110 -11
  21. package/src/core/logic/dom/offset.js +89 -35
  22. package/src/core/logic/dom/selection.js +46 -19
  23. package/src/core/logic/panel/finder.js +982 -0
  24. package/src/core/logic/panel/menu.js +8 -6
  25. package/src/core/logic/panel/toolbar.js +112 -19
  26. package/src/core/logic/panel/viewer.js +214 -43
  27. package/src/core/logic/shell/_commandExecutor.js +7 -1
  28. package/src/core/logic/shell/commandDispatcher.js +1 -1
  29. package/src/core/logic/shell/component.js +5 -7
  30. package/src/core/logic/shell/history.js +24 -0
  31. package/src/core/logic/shell/shortcuts.js +3 -3
  32. package/src/core/logic/shell/ui.js +25 -26
  33. package/src/core/schema/frameContext.js +15 -1
  34. package/src/core/schema/options.js +75 -16
  35. package/src/core/section/constructor.js +61 -20
  36. package/src/core/section/documentType.js +1 -1
  37. package/src/events.js +12 -0
  38. package/src/helper/clipboard.js +1 -1
  39. package/src/helper/dom/domUtils.js +5 -14
  40. package/src/helper/index.js +3 -0
  41. package/src/helper/markdown.js +876 -0
  42. package/src/langs/ckb.js +9 -0
  43. package/src/langs/cs.js +9 -0
  44. package/src/langs/da.js +9 -0
  45. package/src/langs/de.js +9 -0
  46. package/src/langs/en.js +9 -0
  47. package/src/langs/es.js +9 -0
  48. package/src/langs/fa.js +9 -0
  49. package/src/langs/fr.js +9 -0
  50. package/src/langs/he.js +9 -0
  51. package/src/langs/hu.js +9 -0
  52. package/src/langs/it.js +9 -0
  53. package/src/langs/ja.js +9 -0
  54. package/src/langs/km.js +9 -0
  55. package/src/langs/ko.js +9 -0
  56. package/src/langs/lv.js +9 -0
  57. package/src/langs/nl.js +9 -0
  58. package/src/langs/pl.js +9 -0
  59. package/src/langs/pt_br.js +9 -0
  60. package/src/langs/ro.js +9 -0
  61. package/src/langs/ru.js +9 -0
  62. package/src/langs/se.js +9 -0
  63. package/src/langs/tr.js +9 -0
  64. package/src/langs/uk.js +9 -0
  65. package/src/langs/ur.js +9 -0
  66. package/src/langs/zh_cn.js +9 -0
  67. package/src/modules/contract/Controller.js +50 -39
  68. package/src/modules/manager/ApiManager.js +27 -4
  69. package/src/modules/manager/FileManager.js +1 -1
  70. package/src/modules/ui/SelectMenu.js +22 -11
  71. package/src/plugins/command/codeBlock.js +324 -0
  72. package/src/plugins/command/exportPDF.js +15 -3
  73. package/src/plugins/dropdown/blockStyle.js +1 -1
  74. package/src/plugins/dropdown/paragraphStyle.js +1 -2
  75. package/src/plugins/dropdown/table/render/table.html.js +1 -1
  76. package/src/plugins/dropdown/table/services/table.grid.js +16 -8
  77. package/src/plugins/dropdown/table/services/table.style.js +5 -9
  78. package/src/plugins/index.js +3 -0
  79. package/src/plugins/input/fontSize.js +4 -2
  80. package/src/plugins/modal/audio.js +2 -1
  81. package/src/plugins/modal/image/index.js +2 -1
  82. package/src/plugins/modal/math.js +2 -1
  83. package/src/plugins/modal/video/index.js +2 -1
  84. package/src/themes/cobalt.css +13 -4
  85. package/src/themes/cream.css +11 -2
  86. package/src/themes/dark.css +13 -4
  87. package/src/themes/midnight.css +13 -4
  88. package/src/typedef.js +4 -4
  89. package/types/assets/icons/defaultIcons.d.ts +12 -1
  90. package/types/core/config/eventManager.d.ts +6 -8
  91. package/types/core/event/actions/index.d.ts +1 -0
  92. package/types/core/event/effects/keydown.registry.d.ts +2 -0
  93. package/types/core/event/eventOrchestrator.d.ts +2 -1
  94. package/types/core/kernel/coreKernel.d.ts +5 -0
  95. package/types/core/kernel/store.d.ts +5 -0
  96. package/types/core/logic/dom/offset.d.ts +16 -3
  97. package/types/core/logic/dom/selection.d.ts +3 -3
  98. package/types/core/logic/panel/finder.d.ts +83 -0
  99. package/types/core/logic/panel/toolbar.d.ts +14 -1
  100. package/types/core/logic/panel/viewer.d.ts +22 -2
  101. package/types/core/logic/shell/shortcuts.d.ts +1 -1
  102. package/types/core/schema/frameContext.d.ts +22 -0
  103. package/types/core/schema/options.d.ts +153 -31
  104. package/types/events.d.ts +11 -0
  105. package/types/helper/dom/domUtils.d.ts +2 -2
  106. package/types/helper/index.d.ts +5 -0
  107. package/types/helper/markdown.d.ts +27 -0
  108. package/types/langs/_Lang.d.ts +9 -0
  109. package/types/modules/contract/Controller.d.ts +8 -1
  110. package/types/modules/ui/SelectMenu.d.ts +12 -0
  111. package/types/plugins/command/codeBlock.d.ts +53 -0
  112. package/types/plugins/index.d.ts +3 -0
  113. package/types/plugins/input/fontSize.d.ts +6 -2
  114. package/types/plugins/modal/audio.d.ts +4 -2
  115. package/types/plugins/modal/image/index.d.ts +3 -1
  116. package/types/plugins/modal/math.d.ts +3 -1
  117. package/types/plugins/modal/video/index.d.ts +3 -1
  118. package/types/typedef.d.ts +5 -2
@@ -193,8 +193,10 @@ export namespace DEFAULTS {
193
193
  * @property {{pluginName: string, we: boolean}|boolean} [__pluginRetainFilter=true] - Plugin retain filter configuration. (Internal use primarily)
194
194
  * - You can turn it off/on globally with `true`/`false` or set it per plugin.
195
195
  * ```js
196
- * // __pluginRetainFilter - disable filter for table plugin only
197
- * { __pluginRetainFilter: { table: false } }
196
+ * // disable filter for table plugin only
197
+ * {
198
+ * __pluginRetainFilter: { table: false }
199
+ * }
198
200
  * ```
199
201
  */
200
202
  /**
@@ -223,7 +225,7 @@ export namespace DEFAULTS {
223
225
  *
224
226
  * === Modes & Themes ===
225
227
  * @property {boolean} [v2Migration=false] - Enables migration mode for SunEditor v2.
226
- * @property {"classic"|"inline"|"balloon"|"balloon-always"} [mode="classic"] - Toolbar mode: `classic`, `inline`, `balloon`, `balloon-always`.
228
+ * @property {"classic"|"inline"|"balloon"|"balloon-always"|"classic:bottom"|"inline:bottom"} [mode="classic"] - Toolbar mode: `classic`, `inline`, `balloon`, `balloon-always`. Append `:bottom` to place toolbar at the bottom (e.g. `classic:bottom`, `inline:bottom`).
227
229
  * @property {string} [type=""] - Editor type. Use `"document"` for a document-style layout, with optional sub-types after `:`.
228
230
  * ```js
229
231
  * // type
@@ -257,7 +259,16 @@ export namespace DEFAULTS {
257
259
  * - `styleFilter`: Filters disallowed inline styles (`spanStyles`/`lineStyles`/`allUsedStyles`)
258
260
  * ```js
259
261
  * // disable only attribute and style filters
260
- * { strictMode: { tagFilter: true, formatFilter: true, classFilter: true, textStyleTagFilter: true, attrFilter: false, styleFilter: false } }
262
+ * {
263
+ * strictMode: {
264
+ * tagFilter: true,
265
+ * formatFilter: true,
266
+ * classFilter: true,
267
+ * textStyleTagFilter: true,
268
+ * attrFilter: false,
269
+ * styleFilter: false
270
+ * }
271
+ * }
261
272
  * ```
262
273
  * @property {Array<string>} [scopeSelectionTags=CONSTANTS.SCOPE_SELECTION_TAGS] - Tags treated as whole units when selecting all content.
263
274
  * - The default follows {@link DEFAULTS.SCOPE_SELECTION_TAGS}
@@ -287,7 +298,13 @@ export namespace DEFAULTS {
287
298
  * @property {{[key: string]: string|undefined}} [attributeWhitelist=null] - Specifies additional attributes to allow for each tag. `"*"` applies to all tags.
288
299
  * - Rules specified here will be merged into {@link PrivateBaseOptions.__defaultAttributeWhitelist}.
289
300
  * ```js
290
- * { attributeWhitelist: { a: 'href|target', img: 'src|alt', '*': 'id|data-*' } }
301
+ * {
302
+ * attributeWhitelist: {
303
+ * a: 'href|target',
304
+ * img: 'src|alt',
305
+ * '*': 'id|data-*'
306
+ * }
307
+ * }
291
308
  * ```
292
309
  * @property {{[key: string]: string|undefined}} [attributeBlacklist=null] - Specifies attributes to disallow by tag. `"*"` applies to all tags.
293
310
  * - Attributes specified here will eventually be removed even if they are allowed by other settings.
@@ -302,7 +319,14 @@ export namespace DEFAULTS {
302
319
  * - The default follows {@link PrivateBaseOptions.__textStyleTags}
303
320
  * @property {Object<string, string>} [convertTextTags={bold: "strong", underline: "u", italic: "em", strike: "del", subscript: "sub", superscript: "sup"}] - Maps text styles to specific HTML tags.
304
321
  * ```js
305
- * { convertTextTags: { bold: 'b', italic: 'i', underline: 'u', strike: 's' } }
322
+ * {
323
+ * convertTextTags: {
324
+ * bold: 'b',
325
+ * italic: 'i',
326
+ * underline: 'u',
327
+ * strike: 's'
328
+ * }
329
+ * }
306
330
  * ```
307
331
  * @property {string} [allUsedStyles] - Specifies additional styles to the list of allowed styles. Delimiter: `"|"`.
308
332
  * ```js
@@ -310,7 +334,12 @@ export namespace DEFAULTS {
310
334
  * ```
311
335
  * @property {Object<string, string>} [tagStyles={}] - Specifies allowed styles for HTML tags. Key is tag name(s), value is pipe-delimited allowed styles.
312
336
  * ```js
313
- * { tagStyles: { 'table|td': 'border|color|background-color', hr: 'border-top' } }
337
+ * {
338
+ * tagStyles: {
339
+ * 'table|td': 'border|color|background-color',
340
+ * hr: 'border-top'
341
+ * }
342
+ * }
314
343
  * ```
315
344
  * @property {string} [spanStyles=CONSTANTS.SPAN_STYLES] - Specifies allowed styles for the `span` tag.
316
345
  * - The default follows {@link DEFAULTS.SPAN_STYLES}
@@ -390,11 +419,16 @@ export namespace DEFAULTS {
390
419
  * @property {boolean} [shortcutsHint=true] - Displays shortcut hints in tooltips.
391
420
  * @property {boolean} [shortcutsDisable=false] - Disables keyboard shortcuts.
392
421
  * @property {{[key: string]: Array<string>|undefined}} [shortcuts={}] - Custom keyboard shortcuts.
393
- * Keys starting with `_` are user-defined custom shortcuts. Each value is an array of `[keyCombo, hintLabel]` pairs.
394
- * Key combos use `c` (Ctrl/Cmd), `s` (Shift), and `KeyEvent.code` values joined by `+`.
395
- * Use `$~pluginName.method` to call a specific plugin method.
422
+ * - Keys starting with `_` are user-defined custom shortcuts. Each value is an array of `[keyCombo, hintLabel]` pairs.
423
+ * - Key combos use `c` (Ctrl/Cmd), `s` (Shift), and `KeyEvent.code` values joined by `+`.
424
+ * - Use `$~pluginName.method` to call a specific plugin method.
396
425
  * ```js
397
- * { shortcuts: { bold: ['c+KeyB', 'B'], _h1: ['c+s+Digit1+$~blockStyle.applyHeaderByShortcut', ''] } }
426
+ * {
427
+ * shortcuts: {
428
+ * bold: ['c+KeyB', 'B'],
429
+ * _h1: ['c+s+Digit1+$~blockStyle.applyHeaderByShortcut', '']
430
+ * }
431
+ * }
398
432
  * ```
399
433
  * ///
400
434
  *
@@ -404,6 +438,7 @@ export namespace DEFAULTS {
404
438
  * - Default: `Boolean(plugins.link)` — determined by whether the `link` plugin is enabled.
405
439
  * @property {Array<string>} [autoStyleify=["bold", "underline", "italic", "strike"]] - Styles applied automatically on text input.
406
440
  * @property {number} [historyStackDelayTime=400] - Delay time for history stack updates (ms).
441
+ * @property {number} [historyStackSize=100] - Maximum number of history entries per root frame. Oldest entries are discarded when exceeded.
407
442
  * @property {string} [printClass=""] - Class name for printing.
408
443
  * @property {number} [fullScreenOffset=0] - Offset applied when entering fullscreen mode.
409
444
  * @property {?string} [previewTemplate=null] - Custom HTML template for preview mode. Use `{{ contents }}` as a placeholder for editor content.
@@ -421,24 +456,45 @@ export namespace DEFAULTS {
421
456
  * @property {?string} [defaultUrlProtocol=null] - Default URL protocol for links.
422
457
  * @property {Object<"copy", number>} [toastMessageTime={copy: 1500}] - Duration for displaying toast messages (ms).
423
458
  * @property {boolean} [freeCodeViewMode=false] - Enables free code view mode.
459
+ * @property {boolean} [finder_panel=true] - Shows the built-in Find/Replace panel UI.
460
+ * - The finder is always created internally; this option controls whether the panel is visible to users (Ctrl+F / Ctrl+H).
461
+ * @property {boolean} [finder_liveSearch=true] - Searches instantly as you type (debounced). When false, search runs only on Enter.
462
+ *
463
+ * ///
424
464
  *
425
465
  * === Dynamic Options ===
426
466
  * @property {Object<string, *>} [externalLibs] - External libraries like CodeMirror, KaTeX, or MathJax.
427
467
  * - See {@link https://github.com/ARA-developer/suneditor/blob/develop/guide/external-libraries.md External Libraries Guide}
428
468
  * ```js
429
- * { externalLibs: { katex: window.katex, codeMirror: { src: CodeMirror } } }
469
+ * {
470
+ * externalLibs: {
471
+ * katex: window.katex,
472
+ * codeMirror: { src: CodeMirror }
473
+ * }
474
+ * }
430
475
  * ```
431
476
  * @property {Object<string, boolean>} [allowedExtraTags=CONSTANTS.EXTRA_TAG_MAP] - Specifies extra allowed or disallowed tags. `true` to allow, `false` to disallow.
432
477
  * - The default follows {@link DEFAULTS.EXTRA_TAG_MAP}
433
478
  * ```js
434
- * { allowedExtraTags: { script: false, style: false, mark: true } }
479
+ * {
480
+ * allowedExtraTags: {
481
+ * script: false,
482
+ * style: false,
483
+ * mark: true
484
+ * }
485
+ * }
435
486
  * ```
436
487
  * ///
437
488
  *
438
489
  * === User Events ===
439
490
  * @property {SunEditor.Event.Handlers} [events] - User event handlers configuration.
440
491
  * ```js
441
- * { events: { onChange: (content) => console.log(content), onImageUploadBefore: (files, info) => true } }
492
+ * {
493
+ * events: {
494
+ * onChange: (content) => console.log(content),
495
+ * onImageUploadBefore: (files, info) => true
496
+ * }
497
+ * }
442
498
  * ```
443
499
  * ///
444
500
  *
@@ -449,6 +505,7 @@ export namespace DEFAULTS {
449
505
  * @property {import('../../plugins/browser/audioGallery.js').AudioGalleryPluginOptions} [audioGallery]
450
506
  * @property {import('../../plugins/dropdown/backgroundColor.js').BackgroundColorPluginOptions} [backgroundColor]
451
507
  * @property {import('../../plugins/dropdown/blockStyle.js').BlockStylePluginOptions} [blockStyle]
508
+ * @property {import('../../plugins/command/codeBlock.js').CodeBlockPluginOptions} [codeBlock]
452
509
  * @property {import('../../plugins/modal/drawing.js').DrawingPluginOptions} [drawing]
453
510
  * @property {import('../../plugins/modal/embed.js').EmbedPluginOptions} [embed]
454
511
  * @property {import('../../plugins/command/exportPDF.js').ExportPDFPluginOptions} [exportPDF]
@@ -507,7 +564,6 @@ export namespace DEFAULTS {
507
564
  * @property {*} [codeMirror] - CodeMirror configuration object from `externalLibs.codeMirror`.
508
565
  * @property {boolean} [codeMirrorEditor] - Whether CodeMirror is available (base-level flag). Frame-level stores the actual CM instance.
509
566
  * @property {boolean} [hasCodeMirror] - Uses CodeMirror for code view.
510
- *
511
567
  * @property {Set<string>} [allUsedStyles] - Processed set of all allowed CSS styles.
512
568
  * - Converted from user's `string` input ("|" delimited) to `Set<string>` in constructor.
513
569
  */
@@ -789,8 +845,10 @@ export type PrivateBaseOptions = {
789
845
  * - Plugin retain filter configuration. (Internal use primarily)
790
846
  * - You can turn it off/on globally with `true`/`false` or set it per plugin.
791
847
  * ```js
792
- * // __pluginRetainFilter - disable filter for table plugin only
793
- * { __pluginRetainFilter: { table: false } }
848
+ * // disable filter for table plugin only
849
+ * {
850
+ * __pluginRetainFilter: { table: false }
851
+ * }
794
852
  * ```
795
853
  */
796
854
  __pluginRetainFilter?:
@@ -843,9 +901,9 @@ export type EditorBaseOptions = {
843
901
  */
844
902
  v2Migration?: boolean;
845
903
  /**
846
- * - Toolbar mode: `classic`, `inline`, `balloon`, `balloon-always`.
904
+ * - Toolbar mode: `classic`, `inline`, `balloon`, `balloon-always`. Append `:bottom` to place toolbar at the bottom (e.g. `classic:bottom`, `inline:bottom`).
847
905
  */
848
- mode?: 'classic' | 'inline' | 'balloon' | 'balloon-always';
906
+ mode?: 'classic' | 'inline' | 'balloon' | 'balloon-always' | 'classic:bottom' | 'inline:bottom';
849
907
  /**
850
908
  * - Editor type. Use `"document"` for a document-style layout, with optional sub-types after `:`.
851
909
  * ```js
@@ -895,7 +953,16 @@ export type EditorBaseOptions = {
895
953
  * - `styleFilter`: Filters disallowed inline styles (`spanStyles`/`lineStyles`/`allUsedStyles`)
896
954
  * ```js
897
955
  * // disable only attribute and style filters
898
- * { strictMode: { tagFilter: true, formatFilter: true, classFilter: true, textStyleTagFilter: true, attrFilter: false, styleFilter: false } }
956
+ * {
957
+ * strictMode: {
958
+ * tagFilter: true,
959
+ * formatFilter: true,
960
+ * classFilter: true,
961
+ * textStyleTagFilter: true,
962
+ * attrFilter: false,
963
+ * styleFilter: false
964
+ * }
965
+ * }
899
966
  * ```
900
967
  */
901
968
  strictMode?:
@@ -949,7 +1016,13 @@ export type EditorBaseOptions = {
949
1016
  * - Specifies additional attributes to allow for each tag. `"*"` applies to all tags.
950
1017
  * - Rules specified here will be merged into {@link PrivateBaseOptions.__defaultAttributeWhitelist}.
951
1018
  * ```js
952
- * { attributeWhitelist: { a: 'href|target', img: 'src|alt', '*': 'id|data-*' } }
1019
+ * {
1020
+ * attributeWhitelist: {
1021
+ * a: 'href|target',
1022
+ * img: 'src|alt',
1023
+ * '*': 'id|data-*'
1024
+ * }
1025
+ * }
953
1026
  * ```
954
1027
  */
955
1028
  attributeWhitelist?: {
@@ -977,7 +1050,14 @@ export type EditorBaseOptions = {
977
1050
  /**
978
1051
  * - Maps text styles to specific HTML tags.
979
1052
  * ```js
980
- * { convertTextTags: { bold: 'b', italic: 'i', underline: 'u', strike: 's' } }
1053
+ * {
1054
+ * convertTextTags: {
1055
+ * bold: 'b',
1056
+ * italic: 'i',
1057
+ * underline: 'u',
1058
+ * strike: 's'
1059
+ * }
1060
+ * }
981
1061
  * ```
982
1062
  */
983
1063
  convertTextTags?: {
@@ -993,7 +1073,12 @@ export type EditorBaseOptions = {
993
1073
  /**
994
1074
  * - Specifies allowed styles for HTML tags. Key is tag name(s), value is pipe-delimited allowed styles.
995
1075
  * ```js
996
- * { tagStyles: { 'table|td': 'border|color|background-color', hr: 'border-top' } }
1076
+ * {
1077
+ * tagStyles: {
1078
+ * 'table|td': 'border|color|background-color',
1079
+ * hr: 'border-top'
1080
+ * }
1081
+ * }
997
1082
  * ```
998
1083
  */
999
1084
  tagStyles?: {
@@ -1145,11 +1230,16 @@ export type EditorBaseOptions = {
1145
1230
  shortcutsDisable?: boolean;
1146
1231
  /**
1147
1232
  * - Custom keyboard shortcuts.
1148
- * Keys starting with `_` are user-defined custom shortcuts. Each value is an array of `[keyCombo, hintLabel]` pairs.
1149
- * Key combos use `c` (Ctrl/Cmd), `s` (Shift), and `KeyEvent.code` values joined by `+`.
1150
- * Use `$~pluginName.method` to call a specific plugin method.
1233
+ * - Keys starting with `_` are user-defined custom shortcuts. Each value is an array of `[keyCombo, hintLabel]` pairs.
1234
+ * - Key combos use `c` (Ctrl/Cmd), `s` (Shift), and `KeyEvent.code` values joined by `+`.
1235
+ * - Use `$~pluginName.method` to call a specific plugin method.
1151
1236
  * ```js
1152
- * { shortcuts: { bold: ['c+KeyB', 'B'], _h1: ['c+s+Digit1+$~blockStyle.applyHeaderByShortcut', ''] } }
1237
+ * {
1238
+ * shortcuts: {
1239
+ * bold: ['c+KeyB', 'B'],
1240
+ * _h1: ['c+s+Digit1+$~blockStyle.applyHeaderByShortcut', '']
1241
+ * }
1242
+ * }
1153
1243
  * ```
1154
1244
  * ///
1155
1245
  *
@@ -1175,6 +1265,10 @@ export type EditorBaseOptions = {
1175
1265
  * - Delay time for history stack updates (ms).
1176
1266
  */
1177
1267
  historyStackDelayTime?: number;
1268
+ /**
1269
+ * - Maximum number of history entries per root frame. Oldest entries are discarded when exceeded.
1270
+ */
1271
+ historyStackSize?: number;
1178
1272
  /**
1179
1273
  * - Class name for printing.
1180
1274
  */
@@ -1214,14 +1308,30 @@ export type EditorBaseOptions = {
1214
1308
  toastMessageTime?: any;
1215
1309
  /**
1216
1310
  * - Enables free code view mode.
1311
+ */
1312
+ freeCodeViewMode?: boolean;
1313
+ /**
1314
+ * - Shows the built-in Find/Replace panel UI.
1315
+ * - The finder is always created internally; this option controls whether the panel is visible to users (Ctrl+F / Ctrl+H).
1316
+ */
1317
+ finder_panel?: boolean;
1318
+ /**
1319
+ * - Searches instantly as you type (debounced). When false, search runs only on Enter.
1320
+ *
1321
+ * ///
1217
1322
  *
1218
1323
  * === Dynamic Options ===
1219
1324
  */
1220
- freeCodeViewMode?: boolean;
1325
+ finder_liveSearch?: boolean;
1221
1326
  /**
1222
1327
  * - External libraries like CodeMirror, KaTeX, or MathJax.
1223
1328
  * - See {@link https://github.com/ARA-developer/suneditor/blob/develop/guide/external-libraries.md External Libraries Guide}```js
1224
- * { externalLibs: { katex: window.katex, codeMirror: { src: CodeMirror } } }
1329
+ * {
1330
+ * externalLibs: {
1331
+ * katex: window.katex,
1332
+ * codeMirror: { src: CodeMirror }
1333
+ * }
1334
+ * }
1225
1335
  * ```
1226
1336
  */
1227
1337
  externalLibs?: {
@@ -1230,7 +1340,13 @@ export type EditorBaseOptions = {
1230
1340
  /**
1231
1341
  * - Specifies extra allowed or disallowed tags. `true` to allow, `false` to disallow.
1232
1342
  * - The default follows {@link DEFAULTS.EXTRA_TAG_MAP}```js
1233
- * { allowedExtraTags: { script: false, style: false, mark: true } }
1343
+ * {
1344
+ * allowedExtraTags: {
1345
+ * script: false,
1346
+ * style: false,
1347
+ * mark: true
1348
+ * }
1349
+ * }
1234
1350
  * ```
1235
1351
  * ///
1236
1352
  *
@@ -1242,7 +1358,12 @@ export type EditorBaseOptions = {
1242
1358
  /**
1243
1359
  * - User event handlers configuration.
1244
1360
  * ```js
1245
- * { events: { onChange: (content) => console.log(content), onImageUploadBefore: (files, info) => true } }
1361
+ * {
1362
+ * events: {
1363
+ * onChange: (content) => console.log(content),
1364
+ * onImageUploadBefore: (files, info) => true
1365
+ * }
1366
+ * }
1246
1367
  * ```
1247
1368
  * ///
1248
1369
  *
@@ -1255,6 +1376,7 @@ export type EditorBaseOptions = {
1255
1376
  audioGallery?: import('../../plugins/browser/audioGallery.js').AudioGalleryPluginOptions;
1256
1377
  backgroundColor?: import('../../plugins/dropdown/backgroundColor.js').BackgroundColorPluginOptions;
1257
1378
  blockStyle?: import('../../plugins/dropdown/blockStyle.js').BlockStylePluginOptions;
1379
+ codeBlock?: import('../../plugins/command/codeBlock.js').CodeBlockPluginOptions;
1258
1380
  drawing?: import('../../plugins/modal/drawing.js').DrawingPluginOptions;
1259
1381
  embed?: import('../../plugins/modal/embed.js').EmbedPluginOptions;
1260
1382
  exportPDF?: import('../../plugins/command/exportPDF.js').ExportPDFPluginOptions;
package/types/events.d.ts CHANGED
@@ -239,6 +239,7 @@ export type EventHandlers = {
239
239
  onShowController?: typeof onShowController | null;
240
240
  onBeforeShowController?: typeof onBeforeShowController | null;
241
241
  onToggleCodeView?: typeof onToggleCodeView | null;
242
+ onToggleMarkdownView?: typeof onToggleMarkdownView | null;
242
243
  onToggleFullScreen?: typeof onToggleFullScreen | null;
243
244
  onResizeEditor?: typeof onResizeEditor | null;
244
245
  onSetToolbarButtons?: typeof onSetToolbarButtons | null;
@@ -554,6 +555,16 @@ declare function onBeforeShowController(params: { $: SunEditor.Deps; frameContex
554
555
  * @param {boolean} params.is - code view status
555
556
  */
556
557
  declare function onToggleCodeView(params: { $: SunEditor.Deps; frameContext: SunEditor.FrameContext; is: boolean }): void;
558
+ /**
559
+ * @callback
560
+ * @description Fired when the editor switches between WYSIWYG view and markdown view.
561
+ * The `is` parameter indicates whether markdown view is now active (`true`) or WYSIWYG view is active (`false`).
562
+ * @param {Object} params
563
+ * @param {SunEditor.Deps} params.$ - Kernel dependencies
564
+ * @param {SunEditor.FrameContext} params.frameContext - frame context
565
+ * @param {boolean} params.is - markdown view status
566
+ */
567
+ declare function onToggleMarkdownView(params: { $: SunEditor.Deps; frameContext: SunEditor.FrameContext; is: boolean }): void;
557
568
  /**
558
569
  * @callback
559
570
  * @description Fired when the editor enters or exits fullscreen mode.
@@ -176,9 +176,9 @@ export function removeClass(element: Node | SunEditor.NodeCollection, className:
176
176
  * @description Argument value If there is no class name, insert it and delete the class name if it exists
177
177
  * @param {Node} element Element to replace class name
178
178
  * @param {string} className Class name to be change
179
- * @returns {boolean|undefined}
179
+ * @param {boolean} [force] If true, adds the class; if false, removes it.
180
180
  */
181
- export function toggleClass(element: Node, className: string): boolean | undefined;
181
+ export function toggleClass(element: Node, className: string, force?: boolean): void;
182
182
  /**
183
183
  * @description Flash the class name of the argument value element for a certain time
184
184
  * @param {Node} element Element to flash class name
@@ -170,6 +170,10 @@ export const keyCodeMap: {
170
170
  export const clipboard: {
171
171
  write: typeof import('./clipboard').write;
172
172
  };
173
+ export const markdown: {
174
+ jsonToMarkdown: typeof import('./markdown').jsonToMarkdown;
175
+ markdownToHtml: typeof import('./markdown').markdownToHtml;
176
+ };
173
177
  declare namespace _default {
174
178
  export { env };
175
179
  export { unicode };
@@ -178,5 +182,6 @@ declare namespace _default {
178
182
  export { numbers };
179
183
  export { keyCodeMap };
180
184
  export { clipboard };
185
+ export { markdown };
181
186
  }
182
187
  export default _default;
@@ -0,0 +1,27 @@
1
+ import type {} from '../typedef';
2
+ /**
3
+ * @description Converts a JSON tree (from htmlToJson) to a Markdown string.
4
+ * @param {Object} jsonNode JSON node from htmlToJson
5
+ * @returns {string} Markdown string
6
+ * @example
7
+ * const json = htmlToJson('<p><strong>Hello</strong> World</p>');
8
+ * const md = jsonToMarkdown(json);
9
+ * // '**Hello** World\n\n'
10
+ */
11
+ export function jsonToMarkdown(jsonNode: any): string;
12
+ /**
13
+ * @description Parses a Markdown string into an HTML string.
14
+ * - HTML tags in the markdown are passed through as-is (for fallback elements).
15
+ * @param {string} md Markdown string
16
+ * @param {string} [defaultLine='p'] Default block element tag
17
+ * @returns {string} HTML string
18
+ * @example
19
+ * markdownToHtml('# Hello\n\n**bold** text');
20
+ * // '<h1>Hello</h1><p><strong>bold</strong> text</p>'
21
+ */
22
+ export function markdownToHtml(md: string, defaultLine?: string): string;
23
+ export default markdown;
24
+ declare namespace markdown {
25
+ export { jsonToMarkdown };
26
+ export { markdownToHtml };
27
+ }
@@ -110,6 +110,7 @@ export type _Lang = {
110
110
  link_modal_url: string;
111
111
  link_modal_relAttribute: string;
112
112
  list: string;
113
+ markdownView: string;
113
114
  math: string;
114
115
  math_modal_fontSizeLabel: string;
115
116
  math_modal_inputLabel: string;
@@ -171,6 +172,7 @@ export type _Lang = {
171
172
  tableProperties: string;
172
173
  tags: string;
173
174
  tag_blockquote: string;
175
+ codeBlock: string;
174
176
  tag_div: string;
175
177
  tag_h: string;
176
178
  tag_p: string;
@@ -189,6 +191,13 @@ export type _Lang = {
189
191
  video_modal_title: string;
190
192
  video_modal_url: string;
191
193
  width: string;
194
+ codeLanguage: string;
195
+ codeLanguage_none: string;
196
+ finder_matchCase: string;
197
+ finder_wholeWord: string;
198
+ finder_regex: string;
199
+ finder_prev: string;
200
+ finder_next: string;
192
201
  message_copy_success: string;
193
202
  message_copy_fail: string;
194
203
  };
@@ -150,9 +150,13 @@ declare class Controller {
150
150
  * @param {Node} [positionTarget] Position target element
151
151
  * @param {Object} [params={}] params
152
152
  * @param {boolean} [params.isWWTarget] If the controller is in the WYSIWYG area, set it to `true`.
153
+ * @param {boolean} [params.passive] If `true`, opens the controller visually without affecting editor state
154
+ * - (`_preventBlur`, `controlActive`, `onControllerContext`, `opendControllers`).
155
+ * - Used for lightweight, non-intrusive display such as hover-triggered UI (e.g., codeLang selector on `<pre>` hover).
156
+ * - Automatically set to `true` when opened during component hover selection (`ON_OVER_COMPONENT`).
153
157
  * @param {() => void} [params.initMethod] Method to be called when the controller is closed.
154
158
  * @param {boolean} [params.disabled] If `true`, When the `controller` is opened, buttons without the `se-component-enabled` class are disabled. (default: `this.disabled`)
155
- * @param {{left?: number, top?: number}} [params.addOffset] Additional offset values
159
+ * @param {{left?: number, right?:number, top?: number}} [params.addOffset] Additional offset values
156
160
  * @example
157
161
  * // Open controller on a target element with default options
158
162
  * this.controller.open(target);
@@ -168,15 +172,18 @@ declare class Controller {
168
172
  positionTarget?: Node,
169
173
  {
170
174
  isWWTarget,
175
+ passive,
171
176
  initMethod,
172
177
  disabled,
173
178
  addOffset,
174
179
  }?: {
175
180
  isWWTarget?: boolean;
181
+ passive?: boolean;
176
182
  initMethod?: () => void;
177
183
  disabled?: boolean;
178
184
  addOffset?: {
179
185
  left?: number;
186
+ right?: number;
180
187
  top?: number;
181
188
  };
182
189
  },
@@ -30,6 +30,14 @@ export type SelectMenuParams = {
30
30
  * Optional method to call when the menu is closed
31
31
  */
32
32
  closeMethod?: () => void;
33
+ /**
34
+ * Optional max-height CSS value (e.g. `"200px"`). Enables scrolling when items exceed this height.
35
+ */
36
+ maxHeight?: string;
37
+ /**
38
+ * Optional min-width CSS value (e.g. `"130px"`).
39
+ */
40
+ minWidth?: string;
33
41
  };
34
42
  /**
35
43
  * @typedef {Object} SelectMenuParams
@@ -44,6 +52,8 @@ export type SelectMenuParams = {
44
52
  * @property {number} [splitNum=0] Optional split number for horizontal positioning; defines how many items per row
45
53
  * @property {() => void} [openMethod] Optional method to call when the menu is opened
46
54
  * @property {() => void} [closeMethod] Optional method to call when the menu is closed
55
+ * @property {string} [maxHeight] Optional max-height CSS value (e.g. `"200px"`). Enables scrolling when items exceed this height.
56
+ * @property {string} [minWidth] Optional min-width CSS value (e.g. `"130px"`).
47
57
  */
48
58
  /**
49
59
  * @class
@@ -71,6 +81,8 @@ declare class SelectMenu {
71
81
  horizontal: boolean;
72
82
  openMethod: () => void;
73
83
  closeMethod: () => void;
84
+ maxHeight: string;
85
+ minWidth: string;
74
86
  /**
75
87
  * @description Creates the select menu items.
76
88
  * @param {Array<string>|SunEditor.NodeCollection} items - Command list of selectable items.
@@ -0,0 +1,53 @@
1
+ import type {} from '../../typedef';
2
+ export default CodeBlock;
3
+ export type CodeBlockPluginOptions = {
4
+ /**
5
+ * - List of selectable programming languages for code blocks.
6
+ * - Defaults to 21 common languages
7
+ * - [javascript, typescript, html, css, json, python, java, c, cpp, csharp, go, rust, ruby, php, swift, kotlin, sql, bash, markdown, xml, yaml].
8
+ * - Set to empty array `[]` to disable language selection UI entirely.
9
+ * ```js
10
+ * { codeBlock: { langs: ['javascript', 'python', 'html', 'css'] } }
11
+ * ```
12
+ */
13
+ langs?: Array<string>;
14
+ };
15
+ /**
16
+ * @typedef {Object} CodeBlockPluginOptions
17
+ * @property {Array<string>} [langs] - List of selectable programming languages for code blocks.
18
+ * - Defaults to 21 common languages
19
+ * - [javascript, typescript, html, css, json, python, java, c, cpp, csharp, go, rust, ruby, php, swift, kotlin, sql, bash, markdown, xml, yaml].
20
+ * - Set to empty array `[]` to disable language selection UI entirely.
21
+ * ```js
22
+ * { codeBlock: { langs: ['javascript', 'python', 'html', 'css'] } }
23
+ * ```
24
+ */
25
+ /**
26
+ * @class
27
+ * @implements {PluginDropdown}
28
+ * @description Code block plugin — toggles `<pre>` formatting with language selection.
29
+ * - Toolbar: command button (toggle `<pre>`) + optional dropdown (language list)
30
+ * - Hover UI: shows language selector on `<pre>` hover (Controller + SelectMenu)
31
+ * - I/O conversion: `<pre class="language-xxx">` ↔ `<pre><code class="language-xxx">`
32
+ */
33
+ declare class CodeBlock extends PluginCommand implements PluginDropdown {
34
+ /**
35
+ * @constructor
36
+ * @param {SunEditor.Kernel} kernel - The Kernel instance
37
+ * @param {CodeBlockPluginOptions} pluginOptions - Configuration options for the CodeBlock plugin.
38
+ */
39
+ constructor(kernel: SunEditor.Kernel, pluginOptions: CodeBlockPluginOptions);
40
+ title: any;
41
+ onMouseMove(params: SunEditor.HookParams.MouseEvent): void;
42
+ active(element: HTMLElement | null, target: HTMLElement | null): boolean | void;
43
+ on(target?: HTMLElement): void;
44
+ /** @hook Module.Controller */
45
+ controllerClose(): void;
46
+ /**
47
+ * @description Cleans up resources.
48
+ */
49
+ destroy(): void;
50
+ #private;
51
+ }
52
+ import { PluginDropdown } from '../../interfaces';
53
+ import { PluginCommand } from '../../interfaces';
@@ -1,6 +1,7 @@
1
1
  import type {} from '../typedef';
2
2
  declare namespace _default {
3
3
  export { blockquote };
4
+ export { codeBlock };
4
5
  export { exportPDF };
5
6
  export { fileUpload };
6
7
  export { list_bulleted };
@@ -42,6 +43,7 @@ import fileGallery from './browser/fileGallery';
42
43
  import imageGallery from './browser/imageGallery';
43
44
  import videoGallery from './browser/videoGallery';
44
45
  import blockquote from './command/blockquote';
46
+ import codeBlock from './command/codeBlock';
45
47
  import exportPDF from './command/exportPDF';
46
48
  import fileUpload from './command/fileUpload';
47
49
  import list_bulleted from './command/list_bulleted';
@@ -78,6 +80,7 @@ export {
78
80
  backgroundColor,
79
81
  blockquote,
80
82
  blockStyle,
83
+ codeBlock,
81
84
  drawing,
82
85
  embed,
83
86
  exportPDF,
@@ -13,10 +13,12 @@ export type FontSizePluginOptions = {
13
13
  showDefaultSizeLabel?: boolean;
14
14
  /**
15
15
  * - When `true`, displays increase and decrease buttons for font size adjustments.
16
+ * - Defaults to `false`. Always `false` when `sizeUnit` is `'text'` (ignored).
16
17
  */
17
18
  showIncDecControls?: boolean;
18
19
  /**
19
20
  * - When `true`, disables the direct font size input box.
21
+ * - Defaults to `true` when `sizeUnit` is `'text'`, otherwise `false`.
20
22
  */
21
23
  disableInput?: boolean;
22
24
  /**
@@ -43,8 +45,10 @@ export type FontSizePluginOptions = {
43
45
  * - Accepted values include: `'px'`, `'pt'`, `'em'`, `'rem'`, `'vw'`, `'vh'`, `'%'` or `'text'`.
44
46
  * - If `'text'` is used, a text-based font size list is applied.
45
47
  * @property {boolean} [showDefaultSizeLabel=true] - Determines whether the default size label is displayed in the dropdown menu.
46
- * @property {boolean} [showIncDecControls=false] - When `true`, displays increase and decrease buttons for font size adjustments.
47
- * @property {boolean} [disableInput=true] - When `true`, disables the direct font size input box.
48
+ * @property {boolean} [showIncDecControls] - When `true`, displays increase and decrease buttons for font size adjustments.
49
+ * - Defaults to `false`. Always `false` when `sizeUnit` is `'text'` (ignored).
50
+ * @property {boolean} [disableInput] - When `true`, disables the direct font size input box.
51
+ * - Defaults to `true` when `sizeUnit` is `'text'`, otherwise `false`.
48
52
  * @property {Object<string, {default: number, inc: number, min: number, max: number, list: Array<number>}>} [unitMap={}] - Override or extend the default unit mapping for font sizes.
49
53
  * Each key is a unit name (e.g., `'px'`, `'em'`). `default`: initial size, `inc`: step for inc/dec buttons, `min`/`max`: range limits, `list`: dropdown values.
50
54
  * When `sizeUnit` is `'text'`, list items use `{title: string, size: string}` instead of numbers.
@@ -14,7 +14,8 @@ export type AudioPluginOptions = {
14
14
  */
15
15
  createFileInput?: boolean;
16
16
  /**
17
- * - Whether to create a URL input element (default is `true` if file input is not created).
17
+ * - Whether to create a URL input element.
18
+ * - Defaults to `true`. Always `true` when `createFileInput` is `false`.
18
19
  */
19
20
  createUrlInput?: boolean;
20
21
  /**
@@ -67,7 +68,8 @@ export type AudioPluginOptions = {
67
68
  * @property {string} [defaultWidth="300px"] - The default width of the `AUDIO` tag.
68
69
  * @property {string} [defaultHeight="150px"] - The default height of the `AUDIO` tag.
69
70
  * @property {boolean} [createFileInput] - Whether to create a file input element.
70
- * @property {boolean} [createUrlInput] - Whether to create a URL input element (default is `true` if file input is not created).
71
+ * @property {boolean} [createUrlInput] - Whether to create a URL input element.
72
+ * - Defaults to `true`. Always `true` when `createFileInput` is `false`.
71
73
  * @property {string} [uploadUrl] - The URL to which files will be uploaded.
72
74
  * @property {Object<string, string>} [uploadHeaders] - Headers to include in the file upload request.
73
75
  * @property {number} [uploadSizeLimit] - The total upload size limit in bytes.