suneditor 3.0.0-beta.3 → 3.0.0-beta.30

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 (241) hide show
  1. package/CONTRIBUTING.md +8 -8
  2. package/README.md +44 -49
  3. package/dist/suneditor.min.css +1 -1
  4. package/dist/suneditor.min.js +1 -1
  5. package/package.json +95 -53
  6. package/src/assets/design/color.css +2 -2
  7. package/src/assets/design/size.css +2 -0
  8. package/src/assets/icons/defaultIcons.js +16 -1
  9. package/src/assets/suneditor-contents.css +9 -8
  10. package/src/assets/suneditor.css +29 -26
  11. package/src/core/{section → base}/actives.js +20 -12
  12. package/src/core/base/history.js +4 -4
  13. package/src/core/class/char.js +10 -10
  14. package/src/core/class/component.js +146 -57
  15. package/src/core/class/format.js +94 -2458
  16. package/src/core/class/html.js +187 -129
  17. package/src/core/class/inline.js +1853 -0
  18. package/src/core/class/listFormat.js +582 -0
  19. package/src/core/class/menu.js +14 -3
  20. package/src/core/class/nodeTransform.js +9 -14
  21. package/src/core/class/offset.js +162 -197
  22. package/src/core/class/selection.js +137 -34
  23. package/src/core/class/toolbar.js +73 -52
  24. package/src/core/class/ui.js +11 -11
  25. package/src/core/class/viewer.js +56 -55
  26. package/src/core/config/context.js +122 -0
  27. package/src/core/config/frameContext.js +204 -0
  28. package/src/core/config/options.js +639 -0
  29. package/src/core/editor.js +181 -108
  30. package/src/core/event/actions/index.js +229 -0
  31. package/src/core/event/effects/common.registry.js +60 -0
  32. package/src/core/event/effects/keydown.registry.js +551 -0
  33. package/src/core/event/effects/ruleHelpers.js +145 -0
  34. package/src/core/{base → event}/eventManager.js +119 -201
  35. package/src/core/event/executor.js +21 -0
  36. package/src/core/{base/eventHandlers → event/handlers}/handler_toolbar.js +4 -4
  37. package/src/core/{base/eventHandlers → event/handlers}/handler_ww_dragDrop.js +2 -2
  38. package/src/core/event/handlers/handler_ww_input.js +77 -0
  39. package/src/core/event/handlers/handler_ww_key.js +228 -0
  40. package/src/core/{base/eventHandlers → event/handlers}/handler_ww_mouse.js +3 -3
  41. package/src/core/event/ports.js +211 -0
  42. package/src/core/event/reducers/keydown.reducer.js +89 -0
  43. package/src/core/event/rules/keydown.rule.arrow.js +54 -0
  44. package/src/core/event/rules/keydown.rule.backspace.js +202 -0
  45. package/src/core/event/rules/keydown.rule.delete.js +126 -0
  46. package/src/core/event/rules/keydown.rule.enter.js +144 -0
  47. package/src/core/event/rules/keydown.rule.tab.js +29 -0
  48. package/src/core/section/constructor.js +79 -388
  49. package/src/core/section/documentType.js +47 -26
  50. package/src/core/util/instanceCheck.js +59 -0
  51. package/src/editorInjector/_classes.js +4 -0
  52. package/src/editorInjector/_core.js +17 -7
  53. package/src/editorInjector/index.js +10 -2
  54. package/src/events.js +6 -0
  55. package/src/helper/clipboard.js +24 -10
  56. package/src/helper/converter.js +17 -12
  57. package/src/helper/dom/domCheck.js +22 -3
  58. package/src/helper/dom/domQuery.js +91 -45
  59. package/src/helper/dom/domUtils.js +93 -19
  60. package/src/helper/dom/index.js +4 -0
  61. package/src/helper/env.js +11 -7
  62. package/src/helper/keyCodeMap.js +4 -3
  63. package/src/langs/ckb.js +1 -1
  64. package/src/langs/cs.js +1 -1
  65. package/src/langs/da.js +1 -1
  66. package/src/langs/de.js +1 -1
  67. package/src/langs/en.js +1 -1
  68. package/src/langs/es.js +1 -1
  69. package/src/langs/fa.js +1 -1
  70. package/src/langs/fr.js +1 -1
  71. package/src/langs/he.js +1 -1
  72. package/src/langs/hu.js +1 -1
  73. package/src/langs/it.js +1 -1
  74. package/src/langs/ja.js +1 -1
  75. package/src/langs/km.js +1 -1
  76. package/src/langs/ko.js +1 -1
  77. package/src/langs/lv.js +1 -1
  78. package/src/langs/nl.js +1 -1
  79. package/src/langs/pl.js +1 -1
  80. package/src/langs/pt_br.js +10 -10
  81. package/src/langs/ro.js +1 -1
  82. package/src/langs/ru.js +1 -1
  83. package/src/langs/se.js +1 -1
  84. package/src/langs/tr.js +1 -1
  85. package/src/langs/uk.js +1 -1
  86. package/src/langs/ur.js +1 -1
  87. package/src/langs/zh_cn.js +1 -1
  88. package/src/modules/ApiManager.js +25 -18
  89. package/src/modules/Browser.js +52 -61
  90. package/src/modules/ColorPicker.js +37 -38
  91. package/src/modules/Controller.js +85 -79
  92. package/src/modules/Figure.js +275 -187
  93. package/src/modules/FileManager.js +86 -92
  94. package/src/modules/HueSlider.js +67 -35
  95. package/src/modules/Modal.js +84 -77
  96. package/src/modules/ModalAnchorEditor.js +62 -79
  97. package/src/modules/SelectMenu.js +89 -86
  98. package/src/plugins/browser/audioGallery.js +9 -5
  99. package/src/plugins/browser/fileBrowser.js +10 -6
  100. package/src/plugins/browser/fileGallery.js +9 -5
  101. package/src/plugins/browser/imageGallery.js +9 -5
  102. package/src/plugins/browser/videoGallery.js +11 -6
  103. package/src/plugins/command/blockquote.js +1 -0
  104. package/src/plugins/command/exportPDF.js +11 -8
  105. package/src/plugins/command/fileUpload.js +41 -29
  106. package/src/plugins/command/list_bulleted.js +2 -1
  107. package/src/plugins/command/list_numbered.js +2 -1
  108. package/src/plugins/dropdown/align.js +8 -2
  109. package/src/plugins/dropdown/backgroundColor.js +19 -11
  110. package/src/plugins/dropdown/font.js +15 -9
  111. package/src/plugins/dropdown/fontColor.js +19 -11
  112. package/src/plugins/dropdown/formatBlock.js +7 -2
  113. package/src/plugins/dropdown/hr.js +7 -3
  114. package/src/plugins/dropdown/layout.js +6 -2
  115. package/src/plugins/dropdown/lineHeight.js +8 -3
  116. package/src/plugins/dropdown/list.js +2 -1
  117. package/src/plugins/dropdown/paragraphStyle.js +15 -11
  118. package/src/plugins/dropdown/{table.js → table/index.js} +514 -362
  119. package/src/plugins/dropdown/template.js +6 -2
  120. package/src/plugins/dropdown/textStyle.js +7 -3
  121. package/src/plugins/field/mention.js +33 -27
  122. package/src/plugins/input/fontSize.js +44 -37
  123. package/src/plugins/input/pageNavigator.js +3 -2
  124. package/src/plugins/modal/audio.js +90 -85
  125. package/src/plugins/modal/drawing.js +58 -66
  126. package/src/plugins/modal/embed.js +193 -180
  127. package/src/plugins/modal/image.js +441 -439
  128. package/src/plugins/modal/link.js +31 -8
  129. package/src/plugins/modal/math.js +23 -22
  130. package/src/plugins/modal/video.js +233 -230
  131. package/src/plugins/popup/anchor.js +24 -18
  132. package/src/suneditor.js +69 -24
  133. package/src/typedef.js +42 -19
  134. package/types/assets/icons/defaultIcons.d.ts +8 -0
  135. package/types/core/class/char.d.ts +1 -1
  136. package/types/core/class/component.d.ts +29 -7
  137. package/types/core/class/format.d.ts +4 -354
  138. package/types/core/class/html.d.ts +13 -4
  139. package/types/core/class/inline.d.ts +263 -0
  140. package/types/core/class/listFormat.d.ts +135 -0
  141. package/types/core/class/menu.d.ts +10 -2
  142. package/types/core/class/offset.d.ts +24 -26
  143. package/types/core/class/selection.d.ts +2 -0
  144. package/types/core/class/toolbar.d.ts +24 -11
  145. package/types/core/class/ui.d.ts +1 -1
  146. package/types/core/class/viewer.d.ts +1 -1
  147. package/types/core/config/context.d.ts +157 -0
  148. package/types/core/config/frameContext.d.ts +367 -0
  149. package/types/core/config/options.d.ts +1119 -0
  150. package/types/core/editor.d.ts +101 -66
  151. package/types/core/event/actions/index.d.ts +47 -0
  152. package/types/core/event/effects/common.registry.d.ts +50 -0
  153. package/types/core/event/effects/keydown.registry.d.ts +73 -0
  154. package/types/core/event/effects/ruleHelpers.d.ts +31 -0
  155. package/types/core/{base → event}/eventManager.d.ts +15 -46
  156. package/types/core/event/executor.d.ts +6 -0
  157. package/types/core/event/handlers/handler_ww_input.d.ts +41 -0
  158. package/types/core/{base/eventHandlers/handler_ww_key_input.d.ts → event/handlers/handler_ww_key.d.ts} +4 -6
  159. package/types/core/event/ports.d.ts +255 -0
  160. package/types/core/event/reducers/keydown.reducer.d.ts +75 -0
  161. package/types/core/event/rules/keydown.rule.arrow.d.ts +8 -0
  162. package/types/core/event/rules/keydown.rule.backspace.d.ts +9 -0
  163. package/types/core/event/rules/keydown.rule.delete.d.ts +9 -0
  164. package/types/core/event/rules/keydown.rule.enter.d.ts +9 -0
  165. package/types/core/event/rules/keydown.rule.tab.d.ts +9 -0
  166. package/types/core/section/constructor.d.ts +101 -631
  167. package/types/core/section/documentType.d.ts +14 -4
  168. package/types/core/util/instanceCheck.d.ts +50 -0
  169. package/types/editorInjector/_classes.d.ts +4 -0
  170. package/types/editorInjector/_core.d.ts +17 -7
  171. package/types/editorInjector/index.d.ts +10 -2
  172. package/types/events.d.ts +1 -0
  173. package/types/helper/clipboard.d.ts +2 -2
  174. package/types/helper/converter.d.ts +6 -9
  175. package/types/helper/dom/domCheck.d.ts +7 -0
  176. package/types/helper/dom/domQuery.d.ts +19 -8
  177. package/types/helper/dom/domUtils.d.ts +24 -2
  178. package/types/helper/dom/index.d.ts +86 -1
  179. package/types/helper/env.d.ts +6 -1
  180. package/types/helper/index.d.ts +7 -1
  181. package/types/helper/keyCodeMap.d.ts +3 -3
  182. package/types/index.d.ts +23 -117
  183. package/types/langs/index.d.ts +2 -2
  184. package/types/modules/ApiManager.d.ts +1 -8
  185. package/types/modules/Browser.d.ts +4 -62
  186. package/types/modules/ColorPicker.d.ts +4 -21
  187. package/types/modules/Controller.d.ts +8 -64
  188. package/types/modules/Figure.d.ts +54 -50
  189. package/types/modules/FileManager.d.ts +1 -13
  190. package/types/modules/HueSlider.d.ts +13 -3
  191. package/types/modules/Modal.d.ts +0 -43
  192. package/types/modules/ModalAnchorEditor.d.ts +0 -73
  193. package/types/modules/SelectMenu.d.ts +0 -85
  194. package/types/modules/index.d.ts +3 -3
  195. package/types/plugins/browser/audioGallery.d.ts +29 -18
  196. package/types/plugins/browser/fileBrowser.d.ts +38 -27
  197. package/types/plugins/browser/fileGallery.d.ts +29 -18
  198. package/types/plugins/browser/imageGallery.d.ts +24 -16
  199. package/types/plugins/browser/videoGallery.d.ts +29 -18
  200. package/types/plugins/command/blockquote.d.ts +1 -0
  201. package/types/plugins/command/exportPDF.d.ts +18 -18
  202. package/types/plugins/command/fileUpload.d.ts +65 -45
  203. package/types/plugins/command/list_bulleted.d.ts +1 -0
  204. package/types/plugins/command/list_numbered.d.ts +1 -0
  205. package/types/plugins/dropdown/align.d.ts +13 -8
  206. package/types/plugins/dropdown/backgroundColor.d.ts +30 -19
  207. package/types/plugins/dropdown/font.d.ts +13 -12
  208. package/types/plugins/dropdown/fontColor.d.ts +30 -19
  209. package/types/plugins/dropdown/formatBlock.d.ts +13 -8
  210. package/types/plugins/dropdown/hr.d.ts +15 -11
  211. package/types/plugins/dropdown/layout.d.ts +15 -11
  212. package/types/plugins/dropdown/lineHeight.d.ts +16 -11
  213. package/types/plugins/dropdown/list.d.ts +1 -0
  214. package/types/plugins/dropdown/paragraphStyle.d.ts +31 -27
  215. package/types/plugins/dropdown/table/index.d.ts +582 -0
  216. package/types/plugins/dropdown/table.d.ts +41 -86
  217. package/types/plugins/dropdown/template.d.ts +15 -11
  218. package/types/plugins/dropdown/textStyle.d.ts +19 -11
  219. package/types/plugins/field/mention.d.ts +58 -56
  220. package/types/plugins/index.d.ts +38 -38
  221. package/types/plugins/input/fontSize.d.ts +46 -50
  222. package/types/plugins/modal/audio.d.ts +26 -56
  223. package/types/plugins/modal/drawing.d.ts +0 -85
  224. package/types/plugins/modal/embed.d.ts +15 -79
  225. package/types/plugins/modal/image.d.ts +24 -136
  226. package/types/plugins/modal/link.d.ts +34 -15
  227. package/types/plugins/modal/math.d.ts +0 -16
  228. package/types/plugins/modal/video.d.ts +17 -86
  229. package/types/plugins/popup/anchor.d.ts +1 -8
  230. package/types/suneditor.d.ts +70 -19
  231. package/types/typedef.d.ts +60 -46
  232. package/src/core/base/eventHandlers/handler_ww_key_input.js +0 -1200
  233. package/src/core/section/context.js +0 -102
  234. package/types/core/section/context.d.ts +0 -45
  235. package/types/langs/_Lang.d.ts +0 -194
  236. /package/src/core/{base/eventHandlers → event/handlers}/handler_ww_clipboard.js +0 -0
  237. /package/types/core/{section → base}/actives.d.ts +0 -0
  238. /package/types/core/{base/eventHandlers → event/handlers}/handler_toolbar.d.ts +0 -0
  239. /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_clipboard.d.ts +0 -0
  240. /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_dragDrop.d.ts +0 -0
  241. /package/types/core/{base/eventHandlers → event/handlers}/handler_ww_mouse.d.ts +0 -0
@@ -55,7 +55,7 @@ UI.prototype = {
55
55
  * @param {__se__FrameContext|null} fc Frame context
56
56
  */
57
57
  setEditorStyle(style, fc) {
58
- fc = fc || this.editor.frameContext;
58
+ fc ||= this.frameContext;
59
59
 
60
60
  const fo = fc.get('options');
61
61
  fo.set('editorStyle', style);
@@ -105,8 +105,8 @@ UI.prototype = {
105
105
  applyTheme(e.get('wysiwyg'));
106
106
  });
107
107
 
108
- applyTheme(this.context.get('statusbar._wrapper'));
109
- applyTheme(this.context.get('toolbar._wrapper'));
108
+ applyTheme(this.context.get('statusbar_wrapper'));
109
+ applyTheme(this.context.get('toolbar_wrapper'));
110
110
  },
111
111
 
112
112
  /**
@@ -116,7 +116,7 @@ UI.prototype = {
116
116
  * @param {string|undefined} rootKey Root key
117
117
  */
118
118
  readOnly(value, rootKey) {
119
- const fc = rootKey ? this.frameRoots.get(rootKey) : this.editor.frameContext;
119
+ const fc = rootKey ? this.frameRoots.get(rootKey) : this.frameContext;
120
120
 
121
121
  fc.set('isReadOnly', !!value);
122
122
  dom.utils.setDisabled(this.editor._controllerOnDisabledButtons, !!value);
@@ -148,7 +148,7 @@ UI.prototype = {
148
148
  * @param {string|undefined} rootKey Root key
149
149
  */
150
150
  disable(rootKey) {
151
- const fc = rootKey ? this.frameRoots.get(rootKey) : this.editor.frameContext;
151
+ const fc = rootKey ? this.frameRoots.get(rootKey) : this.frameContext;
152
152
 
153
153
  this.toolbar.disable();
154
154
  this._offCurrentController();
@@ -170,7 +170,7 @@ UI.prototype = {
170
170
  * @param {string|undefined} rootKey Root key
171
171
  */
172
172
  enable(rootKey) {
173
- const fc = rootKey ? this.frameRoots.get(rootKey) : this.editor.frameContext;
173
+ const fc = rootKey ? this.frameRoots.get(rootKey) : this.frameContext;
174
174
 
175
175
  this.toolbar.enable();
176
176
  fc.get('wysiwyg').setAttribute('contenteditable', true);
@@ -189,7 +189,7 @@ UI.prototype = {
189
189
  * @param {string|undefined} rootKey Root key
190
190
  */
191
191
  show(rootKey) {
192
- const fc = rootKey ? this.frameRoots.get(rootKey) : this.editor.frameContext;
192
+ const fc = rootKey ? this.frameRoots.get(rootKey) : this.frameContext;
193
193
  const topAreaStyle = fc.get('topArea').style;
194
194
  if (topAreaStyle.display === 'none') topAreaStyle.display = 'block';
195
195
  },
@@ -200,7 +200,7 @@ UI.prototype = {
200
200
  * @param {string|undefined} rootKey Root key
201
201
  */
202
202
  hide(rootKey) {
203
- const fc = rootKey ? this.frameRoots.get(rootKey) : this.editor.frameContext;
203
+ const fc = rootKey ? this.frameRoots.get(rootKey) : this.frameContext;
204
204
  fc.get('topArea').style.display = 'none';
205
205
  },
206
206
 
@@ -270,7 +270,7 @@ UI.prototype = {
270
270
  if (type) dom.utils.addClass(this.alertModal, `se-alert-${type}`);
271
271
 
272
272
  if (this._closeSignal) this._alertInner.addEventListener('click', this._closeListener[1]);
273
- if (this._bindClose) this._bindClose = this.eventManager.removeGlobalEvent(this._bindClose);
273
+ this._bindClose &&= this.eventManager.removeGlobalEvent(this._bindClose);
274
274
  this._bindClose = this.eventManager.addGlobalEvent('keydown', this._closeListener[0]);
275
275
 
276
276
  this._alertArea.style.display = 'block';
@@ -286,7 +286,7 @@ UI.prototype = {
286
286
  dom.utils.removeClass(this.alertModal, 'se-alert-*');
287
287
  this._alertArea.style.display = 'none';
288
288
  if (this._closeSignal) this._alertInner.removeEventListener('click', this._closeListener[1]);
289
- if (this._bindClose) this._bindClose = this.eventManager.removeGlobalEvent(this._bindClose);
289
+ this._bindClose &&= this.eventManager.removeGlobalEvent(this._bindClose);
290
290
  },
291
291
 
292
292
  /**
@@ -332,7 +332,7 @@ UI.prototype = {
332
332
  */
333
333
  _visibleControllers(value, lineBreakShow) {
334
334
  const visible = value ? '' : 'hidden';
335
- const breakerVisible = lineBreakShow ?? visible ? '' : 'hidden';
335
+ const breakerVisible = (lineBreakShow ?? visible) ? '' : 'hidden';
336
336
 
337
337
  const cont = this.editor.opendControllers;
338
338
  for (let i = 0, c; i < cont.length; i++) {
@@ -5,6 +5,8 @@
5
5
  import CoreInjector from '../../editorInjector/_core';
6
6
  import { dom, env, converter, numbers } from '../../helper';
7
7
 
8
+ const { _w, _d } = env;
9
+
8
10
  /**
9
11
  * @typedef {Omit<Viewer & Partial<__se__EditorInjector>, 'viewer'>} ViewerThis
10
12
  */
@@ -41,7 +43,7 @@ Viewer.prototype = {
41
43
  * @param {boolean=} value true/false, If undefined toggle the codeView mode.
42
44
  */
43
45
  codeView(value) {
44
- const fc = this.editor.frameContext;
46
+ const fc = this.frameContext;
45
47
  if (value === undefined) value = !fc.get('isCodeView');
46
48
  if (value === fc.get('isCodeView')) return;
47
49
 
@@ -61,7 +63,7 @@ Viewer.prototype = {
61
63
 
62
64
  if (fc.get('isFullScreen')) {
63
65
  codeFrame.style.height = '100%';
64
- } else if (this.editor.frameOptions.get('height') === 'auto' && !this.options.get('hasCodeMirror')) {
66
+ } else if (this.frameOptions.get('height') === 'auto' && !this.options.get('hasCodeMirror')) {
65
67
  codeFrame.style.height = codeFrame.scrollHeight > 0 ? codeFrame.scrollHeight + 'px' : 'auto';
66
68
  }
67
69
 
@@ -72,8 +74,8 @@ Viewer.prototype = {
72
74
  if (!fc.get('isFullScreen')) {
73
75
  this.editor._notHideToolbar = true;
74
76
  if (this.editor.isBalloon) {
75
- this.context.get('toolbar._arrow').style.display = 'none';
76
- this.context.get('toolbar.main').style.left = '';
77
+ this.context.get('toolbar_arrow').style.display = 'none';
78
+ this.context.get('toolbar_main').style.left = '';
77
79
  this.editor.isInline = this.toolbar._isInline = true;
78
80
  this.editor.isBalloon = this.toolbar._isBalloon = false;
79
81
  this.toolbar._showInline();
@@ -96,12 +98,12 @@ Viewer.prototype = {
96
98
  codeWrapper.style.setProperty('display', 'none', 'important');
97
99
  wysiwygFrame.style.display = 'block';
98
100
 
99
- if (this.editor.frameOptions.get('height') === 'auto' && !this.options.get('hasCodeMirror')) fc.get('code').style.height = '0px';
101
+ if (this.frameOptions.get('height') === 'auto' && !this.options.get('hasCodeMirror')) fc.get('code').style.height = '0px';
100
102
 
101
103
  if (!fc.get('isFullScreen')) {
102
104
  this.editor._notHideToolbar = false;
103
105
  if (/balloon/.test(this.options.get('mode'))) {
104
- this.context.get('toolbar._arrow').style.display = '';
106
+ this.context.get('toolbar_arrow').style.display = '';
105
107
  this.editor.isInline = this.toolbar._isInline = false;
106
108
  this.editor.isBalloon = this.toolbar._isBalloon = true;
107
109
  this.eventManager._hideToolbar();
@@ -122,7 +124,7 @@ Viewer.prototype = {
122
124
  dom.utils.setDisabled(this.editor._codeViewDisabledButtons, value);
123
125
 
124
126
  // document type
125
- if (fc.has('documentType-use-header')) {
127
+ if (fc.has('documentType_use_header')) {
126
128
  if (value) {
127
129
  fc.get('documentTypeInner').style.display = 'none';
128
130
  } else {
@@ -141,20 +143,20 @@ Viewer.prototype = {
141
143
  * @param {boolean=} value true/false, If undefined toggle the codeView mode.
142
144
  */
143
145
  fullScreen(value) {
144
- const fc = this.editor.frameContext;
146
+ const fc = this.frameContext;
145
147
  if (value === undefined) value = !fc.get('isFullScreen');
146
148
  if (value === fc.get('isFullScreen')) return;
147
149
 
148
150
  fc.set('isFullScreen', value);
149
151
  const topArea = fc.get('topArea');
150
- const toolbar = this.context.get('toolbar.main');
152
+ const toolbar = this.context.get('toolbar_main');
151
153
  const editorArea = fc.get('wrapper');
152
154
  const wysiwygFrame = fc.get('wysiwygFrame');
153
155
  const codeWrapper = fc.get('codeWrapper');
154
156
  const code = fc.get('code');
155
157
  const codeNumbers = fc.get('codeNumbers');
156
- const isCodeView = this.editor.frameContext.get('isCodeView');
157
- const arrow = this.context.get('toolbar._arrow');
158
+ const isCodeView = this.frameContext.get('isCodeView');
159
+ const arrow = this.context.get('toolbar_arrow');
158
160
 
159
161
  this.ui._offCurrentController();
160
162
  const wasToolbarHidden = toolbar.style.display === 'none' || (this.editor.isInline && !this.editor.toolbar._inlineToolbarAttr.isShow);
@@ -188,7 +190,7 @@ Viewer.prototype = {
188
190
  topArea.style.width = '100%';
189
191
  topArea.style.maxWidth = '100%';
190
192
  topArea.style.height = '100%';
191
- topArea.style.zIndex = '2147483646';
193
+ topArea.style.zIndex = '2147483639';
192
194
 
193
195
  if (fc.get('_stickyDummy').style.display !== 'none' && fc.get('_stickyDummy').style.display !== '') {
194
196
  this.fullScreenSticky = true;
@@ -196,12 +198,12 @@ Viewer.prototype = {
196
198
  dom.utils.removeClass(toolbar, 'se-toolbar-sticky');
197
199
  }
198
200
 
199
- this.bodyOverflow = this._d.body.style.overflow;
200
- this._d.body.style.overflow = 'hidden';
201
+ this.bodyOverflow = _d.body.style.overflow;
202
+ _d.body.style.overflow = 'hidden';
201
203
 
202
204
  // frame
203
205
  editorArea.style.cssText = toolbar.style.cssText = '';
204
- wysiwygFrame.style.cssText = (wysiwygFrame.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/) || [''])[0] + this.editor.frameOptions.get('_defaultStyles').editor + (isCodeView ? 'display: none;' : '');
206
+ wysiwygFrame.style.cssText = (wysiwygFrame.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/) || [''])[0] + this.frameOptions.get('_defaultStyles').editor + (isCodeView ? 'display: none;' : '');
205
207
 
206
208
  // code wrapper
207
209
  codeWrapper.style.cssText = (codeWrapper.style.cssText.match(/\s?display(\s+)?:(\s+)?[a-zA-Z]+;/) || [''])[0] + `display: ${!isCodeView ? 'none' : 'flex'} !important;`;
@@ -216,10 +218,10 @@ Viewer.prototype = {
216
218
  toolbar.style.position = 'relative';
217
219
  toolbar.style.display = 'block';
218
220
 
219
- this.fullScreenInnerHeight = this._w.innerHeight - toolbar.offsetHeight;
221
+ this.fullScreenInnerHeight = _w.innerHeight - toolbar.offsetHeight;
220
222
  editorArea.style.height = this.fullScreenInnerHeight - (fc.has('statusbar') ? fc.get('statusbar').offsetHeight : 0) - this.options.get('fullScreenOffset') + 'px';
221
223
 
222
- if (this.editor.frameOptions.get('iframe') && this.editor.frameOptions.get('height') === 'auto') {
224
+ if (this.frameOptions.get('iframe') && this.frameOptions.get('height') === 'auto') {
223
225
  editorArea.style.overflow = 'auto';
224
226
  this.editor._iframeAutoHeight(fc);
225
227
  }
@@ -247,9 +249,9 @@ Viewer.prototype = {
247
249
  editorArea.style.cssText = this.editorAreaOriginCssText;
248
250
  topArea.style.cssText = this._originCssText;
249
251
  if (arrow) arrow.style.cssText = this.arrowOriginCssText;
250
- this._d.body.style.overflow = this.bodyOverflow;
252
+ _d.body.style.overflow = this.bodyOverflow;
251
253
 
252
- if (this.editor.frameOptions.get('height') === 'auto' && !this.options.get('hasCodeMirror')) this._codeViewAutoHeight(fc.get('code'), fc.get('codeNumbers'), true);
254
+ if (this.frameOptions.get('height') === 'auto' && !this.options.get('hasCodeMirror')) this._codeViewAutoHeight(fc.get('code'), fc.get('codeNumbers'), true);
253
255
 
254
256
  if (this.toolbarParent) {
255
257
  this.toolbarParent.appendChild(toolbar);
@@ -295,7 +297,7 @@ Viewer.prototype = {
295
297
  * @param {boolean=} value true/false, If undefined toggle the codeView mode.
296
298
  */
297
299
  showBlocks(value) {
298
- const fc = this.editor.frameContext;
300
+ const fc = this.frameContext;
299
301
  if (value === undefined) value = !fc.get('isShowBlocks');
300
302
  fc.set('isShowBlocks', !!value);
301
303
 
@@ -316,7 +318,7 @@ Viewer.prototype = {
316
318
  * @description Set the active class to the button of the toolbar
317
319
  */
318
320
  _setButtonsActive() {
319
- const fc = this.editor.frameContext;
321
+ const fc = this.frameContext;
320
322
 
321
323
  // codeView
322
324
  if (fc.get('isCodeView')) {
@@ -355,12 +357,12 @@ Viewer.prototype = {
355
357
  print() {
356
358
  /** @type {HTMLIFrameElement} */
357
359
  const iframe = dom.utils.createElement('IFRAME', { style: 'display: none;' });
358
- this._d.body.appendChild(iframe);
360
+ _d.body.appendChild(iframe);
359
361
 
360
- const innerPadding = this._w.getComputedStyle(this.editor.frameContext.get('wysiwyg')).padding;
362
+ const innerPadding = _w.getComputedStyle(this.frameContext.get('wysiwyg')).padding;
361
363
  const contentHTML = this.options.get('printTemplate') ? this.options.get('printTemplate').replace(/\{\{\s*contents\s*\}\}/i, this.html.get()) : this.html.get();
362
364
  const printDocument = dom.query.getIframeDocument(iframe);
363
- const wDoc = this.editor.frameContext.get('_wd');
365
+ const wDoc = this.frameContext.get('_wd');
364
366
  const rtlClass = this.options.get('_rtl') ? ' se-rtl' : '';
365
367
  const pageCSS = /*html*/ `
366
368
  <style>
@@ -370,12 +372,12 @@ Viewer.prototype = {
370
372
  }
371
373
  </style>`;
372
374
 
373
- if (this.editor.frameOptions.get('iframe')) {
375
+ if (this.frameOptions.get('iframe')) {
374
376
  const arrts = this.options.get('printClass')
375
377
  ? 'class="' + this.options.get('printClass') + rtlClass + '"'
376
- : this.editor.frameOptions.get('iframe_fullPage')
377
- ? dom.utils.getAttributesToString(wDoc.body, ['contenteditable'])
378
- : 'class="' + this.options.get('_editableClass') + rtlClass + '"';
378
+ : this.frameOptions.get('iframe_fullPage')
379
+ ? dom.utils.getAttributesToString(wDoc.body, ['contenteditable'])
380
+ : 'class="' + this.options.get('_editableClass') + rtlClass + '"';
379
381
 
380
382
  printDocument.write(/*html*/ `
381
383
  <!DOCTYPE html>
@@ -389,8 +391,8 @@ Viewer.prototype = {
389
391
  </body>
390
392
  </html>`);
391
393
  } else {
392
- const links = this._d.head.getElementsByTagName('link');
393
- const styles = this._d.head.getElementsByTagName('style');
394
+ const links = _d.head.getElementsByTagName('link');
395
+ const styles = _d.head.getElementsByTagName('style');
394
396
  let linkHTML = '';
395
397
  for (let i = 0, len = links.length; i < len; i++) {
396
398
  linkHTML += links[i].outerHTML;
@@ -413,7 +415,7 @@ Viewer.prototype = {
413
415
  }
414
416
 
415
417
  this.ui.showLoading();
416
- this._w.setTimeout(() => {
418
+ _w.setTimeout(() => {
417
419
  try {
418
420
  iframe.focus();
419
421
  // Edge, Chromium
@@ -448,16 +450,16 @@ Viewer.prototype = {
448
450
  this.ui._offCurrentModal();
449
451
 
450
452
  const contentHTML = this.options.get('previewTemplate') ? this.options.get('previewTemplate').replace(/\{\{\s*contents\s*\}\}/i, this.html.get({ withFrame: true })) : this.html.get({ withFrame: true });
451
- const windowObject = this._w.open('', '_blank');
452
- const wDoc = this.editor.frameContext.get('_wd');
453
+ const windowObject = _w.open('', '_blank');
454
+ const wDoc = this.frameContext.get('_wd');
453
455
  const rtlClass = this.options.get('_rtl') ? ' se-rtl' : '';
454
456
 
455
- if (this.editor.frameOptions.get('iframe')) {
457
+ if (this.frameOptions.get('iframe')) {
456
458
  const arrts = this.options.get('printClass')
457
459
  ? 'class="' + this.options.get('printClass') + rtlClass + '"'
458
- : this.editor.frameOptions.get('iframe_fullPage')
459
- ? dom.utils.getAttributesToString(wDoc.body, ['contenteditable'])
460
- : 'class="' + this.options.get('_editableClass') + rtlClass + '"';
460
+ : this.frameOptions.get('iframe_fullPage')
461
+ ? dom.utils.getAttributesToString(wDoc.body, ['contenteditable'])
462
+ : 'class="' + this.options.get('_editableClass') + rtlClass + '"';
461
463
 
462
464
  windowObject.document.write(/*html*/ `<!DOCTYPE html>
463
465
  <html>
@@ -472,8 +474,8 @@ Viewer.prototype = {
472
474
  </body>
473
475
  </html>`);
474
476
  } else {
475
- const links = this._d.head.getElementsByTagName('link');
476
- const styles = this._d.head.getElementsByTagName('style');
477
+ const links = _d.head.getElementsByTagName('link');
478
+ const styles = _d.head.getElementsByTagName('style');
477
479
  let linkHTML = '';
478
480
  for (let i = 0, len = links.length; i < len; i++) {
479
481
  linkHTML += links[i].outerHTML;
@@ -504,10 +506,9 @@ Viewer.prototype = {
504
506
  * - Updates the editor's height dynamically when in full-screen mode.
505
507
  */
506
508
  _resetFullScreenHeight() {
507
- if (this.editor.frameContext.get('isFullScreen')) {
508
- this.fullScreenInnerHeight +=
509
- this._w.innerHeight - this.context.get('toolbar.main').offsetHeight - (this.editor.frameContext.has('statusbar') ? this.editor.frameContext.get('statusbar').offsetHeight : 0) - this.fullScreenInnerHeight;
510
- this.editor.frameContext.get('wrapper').style.height = this.fullScreenInnerHeight + 'px';
509
+ if (this.frameContext.get('isFullScreen')) {
510
+ this.fullScreenInnerHeight += _w.innerHeight - this.context.get('toolbar_main').offsetHeight - (this.frameContext.has('statusbar') ? this.frameContext.get('statusbar').offsetHeight : 0) - this.fullScreenInnerHeight;
511
+ this.frameContext.get('wrapper').style.height = this.fullScreenInnerHeight + 'px';
511
512
  return true;
512
513
  }
513
514
  },
@@ -521,7 +522,7 @@ Viewer.prototype = {
521
522
  * @param {string|undefined} rootKey Root key
522
523
  */
523
524
  _codeMirrorEditor(key, value, rootKey) {
524
- const fo = rootKey ? this.frameRoots.get(rootKey).get('options') : this.editor.frameOptions;
525
+ const fo = rootKey ? this.frameRoots.get(rootKey).get('options') : this.frameOptions;
525
526
  switch (key) {
526
527
  case 'set':
527
528
  if (fo.has('codeMirror5Editor')) {
@@ -565,7 +566,7 @@ Viewer.prototype = {
565
566
  if (this.options.get('hasCodeMirror')) {
566
567
  this._codeMirrorEditor('set', value, null);
567
568
  } else {
568
- this.editor.frameContext.get('code').value = value;
569
+ this.frameContext.get('code').value = value;
569
570
  }
570
571
  },
571
572
 
@@ -578,7 +579,7 @@ Viewer.prototype = {
578
579
  if (this.options.get('hasCodeMirror')) {
579
580
  return this._codeMirrorEditor('get', null, null);
580
581
  } else {
581
- return this.editor.frameContext.get('code').value;
582
+ return this.frameContext.get('code').value;
582
583
  }
583
584
  },
584
585
 
@@ -590,8 +591,8 @@ Viewer.prototype = {
590
591
  _setCodeDataToEditor() {
591
592
  const code_html = this._getCodeView();
592
593
 
593
- if (this.editor.frameOptions.get('iframe_fullPage')) {
594
- const wDoc = this.editor.frameContext.get('_wd');
594
+ if (this.frameOptions.get('iframe_fullPage')) {
595
+ const wDoc = this.frameContext.get('_wd');
595
596
  const parseDocument = new DOMParser().parseFromString(code_html, 'text/html');
596
597
 
597
598
  if (!this.options.get('__allowedScriptTag')) {
@@ -606,8 +607,8 @@ Viewer.prototype = {
606
607
  }
607
608
 
608
609
  let headers = parseDocument.head.innerHTML;
609
- if (!parseDocument.head.querySelector('link[rel="stylesheet"]') || (this.editor.frameOptions.get('height') === 'auto' && !parseDocument.head.querySelector('style'))) {
610
- headers += converter._setIframeStyleLinks(this.editor.frameOptions.get('iframe_cssFileName')) + converter._setAutoHeightStyle(this.editor.frameOptions.get('height'));
610
+ if (!parseDocument.head.querySelector('link[rel="stylesheet"]') || (this.frameOptions.get('height') === 'auto' && !parseDocument.head.querySelector('style'))) {
611
+ headers += converter._setIframeStyleLinks(this.frameOptions.get('iframe_cssFileName')) + converter._setAutoHeightStyle(this.frameOptions.get('height'));
611
612
  }
612
613
 
613
614
  wDoc.head.innerHTML = headers;
@@ -625,7 +626,7 @@ Viewer.prototype = {
625
626
  }
626
627
  }
627
628
  } else {
628
- this.editor.frameContext.get('wysiwyg').innerHTML =
629
+ this.frameContext.get('wysiwyg').innerHTML =
629
630
  code_html.length > 0
630
631
  ? this.html.clean(code_html, { forceFormat: true, whitelist: null, blacklist: null, _freeCodeViewMode: this.options.get('freeCodeViewMode') })
631
632
  : '<' + this.options.get('defaultLine') + '><br></' + this.options.get('defaultLine') + '>';
@@ -638,12 +639,12 @@ Viewer.prototype = {
638
639
  * @description Convert the data of the WYSIWYG area and put it in the code view area.
639
640
  */
640
641
  _setEditorDataToCodeView() {
641
- const codeContent = this.html._convertToCode(this.editor.frameContext.get('wysiwyg'), false);
642
+ const codeContent = this.html._convertToCode(this.frameContext.get('wysiwyg'), false);
642
643
  let codeValue = '';
643
644
 
644
- if (this.editor.frameOptions.get('iframe_fullPage')) {
645
- const attrs = dom.utils.getAttributesToString(this.editor.frameContext.get('_wd').body, null);
646
- codeValue = '<!DOCTYPE html>\n<html>\n' + this.editor.frameContext.get('_wd').head.outerHTML.replace(/>(?!\n)/g, '>\n') + '<body ' + attrs + '>\n' + codeContent + '</body>\n</html>';
645
+ if (this.frameOptions.get('iframe_fullPage')) {
646
+ const attrs = dom.utils.getAttributesToString(this.frameContext.get('_wd').body, null);
647
+ codeValue = '<!DOCTYPE html>\n<html>\n' + this.frameContext.get('_wd').head.outerHTML.replace(/>(?!\n)/g, '>\n') + '<body ' + attrs + '>\n' + codeContent + '</body>\n</html>';
647
648
  } else {
648
649
  codeValue = codeContent;
649
650
  }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * ================================================================================================================================
3
+ * === CONTEXT TYPES : Store
4
+ * =================================================================================================================================
5
+ */
6
+
7
+ /**
8
+ * ================================================================================================================================
9
+ * @typedef {Object} ContextStore
10
+ *
11
+ * This object stores **global editor-level UI references** for a SunEditor instance.
12
+ *
13
+ * - Primarily manages **toolbar, menu tray, and status bar containers**.
14
+ * - Used by the editor to control **sticky behavior, sub-toolbars, and global layout**.
15
+ * - Shared across all frames in a multi-frame editor (unlike FrameContextStore which is per-frame).
16
+ * -----------------
17
+ *
18
+ * === Main UI Containers ===
19
+ * @property {HTMLElement} menuTray - The **top menu tray** that holds buttons, dropdowns, or custom menus.
20
+ * @property {HTMLElement} toolbar_main - The **main toolbar** element containing editor actions.
21
+ * @property {HTMLElement} toolbar_buttonTray - The **container for main toolbar buttons**.
22
+ * @property {HTMLElement} toolbar_arrow - The **arrow indicator** in the toolbar (used for dropdown/tool menu navigation).
23
+ * @property {HTMLElement} [toolbar_wrapper] - The **wrapper for the main toolbar and editor frame** (groups UI together).
24
+ *
25
+ * === Sub-Toolbar (Contextual/Balloon) ===
26
+ * @property {HTMLElement} [toolbar_sub_main] - The **sub-toolbar** element (used for contextual or balloon toolbars).
27
+ * @property {HTMLElement} [toolbar_sub_buttonTray] - The **container for sub-toolbar buttons**.
28
+ * @property {HTMLElement} [toolbar_sub_arrow] - The **arrow indicator** in the sub-toolbar.
29
+ * @property {HTMLElement} [toolbar_sub_wrapper] - The **wrapper for the sub-toolbar**, containing its structure.
30
+ *
31
+ * === Status Bar ===
32
+ * @property {HTMLElement} [statusbar_wrapper] - The **wrapper for the status bar** (footer area for resize handles, info, etc.).
33
+ *
34
+ * === Sticky Mode Helpers ===
35
+ * @property {HTMLElement} [_stickyDummy] - A **dummy placeholder** used when the toolbar is in sticky mode (to prevent layout shift).
36
+ * ================================================================================================================================
37
+ */
38
+
39
+ /** --+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-- */
40
+
41
+ /**
42
+ * ================================================================================================================================
43
+ * === UTILITIES : Manage Context Map
44
+ * =================================================================================================================================
45
+ */
46
+
47
+ /**
48
+ * @description Creates a context map of commonly accessed DOM elements for the editor.
49
+ * @param {Element} toolbar - Main toolbar element.
50
+ * @param {Element|null} toolbarContainer - Container element for the toolbar.
51
+ * @param {Element} menuTray - Main menu tray element.
52
+ * @param {Element|null} subbar - Sub-toolbar element.
53
+ * @param {Element|null} statusbarContainer - Status bar container element.
54
+ * @returns {__se__Context} - A map of key DOM nodes used throughout the editor.
55
+ */
56
+ export function CreateContext(toolbar, toolbarContainer, menuTray, subbar, statusbarContainer) {
57
+ const m = new Map([
58
+ ['menuTray', menuTray],
59
+ ['toolbar_main', toolbar],
60
+ ['toolbar_buttonTray', toolbar.querySelector('.se-btn-tray')],
61
+ ['toolbar_arrow', toolbar.querySelector('.se-arrow')]
62
+ ]);
63
+
64
+ if (subbar) {
65
+ m.set('toolbar_sub_main', subbar);
66
+ m.set('toolbar_sub_buttonTray', subbar.querySelector('.se-btn-tray'));
67
+ m.set('toolbar_sub_arrow', subbar.querySelector('.se-arrow'));
68
+ m.set('toolbar_sub_wrapper', subbar.parentElement.parentElement);
69
+ }
70
+
71
+ if (toolbarContainer) {
72
+ m.set('toolbar_wrapper', toolbarContainer.querySelector('.sun-editor'));
73
+ m.set('_stickyDummy', toolbarContainer.querySelector('.se-toolbar-sticky-dummy'));
74
+ }
75
+
76
+ if (statusbarContainer) {
77
+ m.set('statusbar_wrapper', statusbarContainer.querySelector('.sun-editor'));
78
+ }
79
+
80
+ return /** @type {__se__Context} */ (m);
81
+ }
82
+
83
+ /**
84
+ * @typedef {Object} ContextUtil
85
+ * @property {(k: keyof ContextStore) => HTMLElement|null} get - Get a DOM element from the context by key.
86
+ * @property {(k: keyof ContextStore, v: HTMLElement) => void} set - Set a DOM element in the context by key.
87
+ * @property {(k: keyof ContextStore) => boolean} has - Check if a key exists in the context.
88
+ * @property {(k: keyof ContextStore) => boolean} delete - Delete a key from the context.
89
+ * @property {() => Object<keyof ContextStore, HTMLElement|null>} [getAll] - Get all DOM elements in the context as an object.
90
+ * @property {() => void} clear - Clear all elements in the context.
91
+ */
92
+
93
+ /**
94
+ * @description Creates a utility wrapper for editor base options.
95
+ * - Provides get, set, has, getAll, and setMany methods with internal Map support.
96
+ * @param {*} editor - The editor instance
97
+ * @returns {ContextUtil}
98
+ */
99
+ export function ContextUtil(editor) {
100
+ const store = editor.__context;
101
+
102
+ return {
103
+ get(k) {
104
+ return store.get(k);
105
+ },
106
+ set(k, v) {
107
+ return store.set(k, v);
108
+ },
109
+ has(k) {
110
+ return store.has(k);
111
+ },
112
+ delete(k) {
113
+ return store.delete(k);
114
+ },
115
+ getAll() {
116
+ return Object.fromEntries(store.entries());
117
+ },
118
+ clear() {
119
+ store.clear();
120
+ }
121
+ };
122
+ }