suneditor 3.0.0-alpha.2 → 3.0.0-alpha.20

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 (306) hide show
  1. package/.eslintrc.json +4 -3
  2. package/CONTRIBUTING.md +4 -2
  3. package/README.md +19 -11
  4. package/README_V3_TEMP.md +705 -0
  5. package/dist/suneditor.min.css +1 -0
  6. package/dist/suneditor.min.js +1 -0
  7. package/example.md +587 -0
  8. package/package.json +15 -9
  9. package/src/assets/icons/_default.js +166 -131
  10. package/src/assets/{suneditor-content.css → suneditor-contents.css} +182 -45
  11. package/src/assets/suneditor.css +1195 -556
  12. package/src/assets/variables.css +138 -0
  13. package/src/core/base/eventHandlers/handler_toolbar.js +35 -14
  14. package/src/core/base/eventHandlers/handler_ww_clipboard.js +29 -4
  15. package/src/core/base/eventHandlers/handler_ww_dragDrop.js +59 -15
  16. package/src/core/base/eventHandlers/handler_ww_key_input.js +426 -212
  17. package/src/core/base/eventHandlers/handler_ww_mouse.js +108 -32
  18. package/src/core/base/eventManager.js +540 -209
  19. package/src/core/base/events.js +616 -320
  20. package/src/core/base/history.js +93 -39
  21. package/src/core/class/char.js +29 -13
  22. package/src/core/class/component.js +332 -145
  23. package/src/core/class/format.js +671 -509
  24. package/src/core/class/html.js +504 -290
  25. package/src/core/class/menu.js +114 -47
  26. package/src/core/class/nodeTransform.js +111 -66
  27. package/src/core/class/offset.js +409 -105
  28. package/src/core/class/selection.js +220 -108
  29. package/src/core/class/shortcuts.js +68 -8
  30. package/src/core/class/toolbar.js +106 -116
  31. package/src/core/class/ui.js +330 -0
  32. package/src/core/class/viewer.js +178 -74
  33. package/src/core/editor.js +489 -384
  34. package/src/core/section/actives.js +118 -22
  35. package/src/core/section/constructor.js +504 -170
  36. package/src/core/section/context.js +28 -23
  37. package/src/core/section/documentType.js +561 -0
  38. package/src/editorInjector/_classes.js +19 -5
  39. package/src/editorInjector/_core.js +71 -7
  40. package/src/editorInjector/index.js +63 -1
  41. package/src/helper/converter.js +137 -19
  42. package/src/helper/dom/domCheck.js +294 -0
  43. package/src/helper/dom/domQuery.js +609 -0
  44. package/src/helper/dom/domUtils.js +533 -0
  45. package/src/helper/dom/index.js +12 -0
  46. package/src/helper/env.js +42 -19
  47. package/src/helper/index.js +7 -4
  48. package/src/helper/keyCodeMap.js +183 -0
  49. package/src/helper/numbers.js +8 -8
  50. package/src/helper/unicode.js +5 -5
  51. package/src/langs/ckb.js +69 -3
  52. package/src/langs/cs.js +67 -1
  53. package/src/langs/da.js +68 -2
  54. package/src/langs/de.js +68 -3
  55. package/src/langs/en.js +29 -1
  56. package/src/langs/es.js +68 -3
  57. package/src/langs/fa.js +70 -2
  58. package/src/langs/fr.js +68 -2
  59. package/src/langs/he.js +68 -3
  60. package/src/langs/hu.js +226 -0
  61. package/src/langs/index.js +3 -2
  62. package/src/langs/it.js +65 -0
  63. package/src/langs/ja.js +68 -3
  64. package/src/langs/ko.js +66 -1
  65. package/src/langs/lv.js +68 -3
  66. package/src/langs/nl.js +68 -3
  67. package/src/langs/pl.js +68 -3
  68. package/src/langs/pt_br.js +65 -0
  69. package/src/langs/ro.js +69 -4
  70. package/src/langs/ru.js +68 -3
  71. package/src/langs/se.js +68 -3
  72. package/src/langs/tr.js +68 -0
  73. package/src/langs/ua.js +68 -3
  74. package/src/langs/ur.js +71 -6
  75. package/src/langs/zh_cn.js +69 -4
  76. package/src/modules/ApiManager.js +77 -54
  77. package/src/modules/Browser.js +667 -0
  78. package/src/modules/ColorPicker.js +162 -102
  79. package/src/modules/Controller.js +233 -136
  80. package/src/modules/Figure.js +913 -489
  81. package/src/modules/FileManager.js +141 -72
  82. package/src/modules/HueSlider.js +113 -61
  83. package/src/modules/Modal.js +292 -113
  84. package/src/modules/ModalAnchorEditor.js +380 -230
  85. package/src/modules/SelectMenu.js +270 -168
  86. package/src/modules/_DragHandle.js +2 -1
  87. package/src/modules/index.js +3 -3
  88. package/src/plugins/browser/audioGallery.js +83 -0
  89. package/src/plugins/browser/fileBrowser.js +103 -0
  90. package/src/plugins/browser/fileGallery.js +83 -0
  91. package/src/plugins/browser/imageGallery.js +81 -0
  92. package/src/plugins/browser/videoGallery.js +103 -0
  93. package/src/plugins/command/blockquote.js +40 -27
  94. package/src/plugins/command/exportPDF.js +134 -0
  95. package/src/plugins/command/fileUpload.js +226 -158
  96. package/src/plugins/command/list_bulleted.js +93 -47
  97. package/src/plugins/command/list_numbered.js +93 -47
  98. package/src/plugins/dropdown/align.js +66 -54
  99. package/src/plugins/dropdown/backgroundColor.js +76 -45
  100. package/src/plugins/dropdown/font.js +71 -47
  101. package/src/plugins/dropdown/fontColor.js +78 -46
  102. package/src/plugins/dropdown/formatBlock.js +74 -33
  103. package/src/plugins/dropdown/hr.js +102 -51
  104. package/src/plugins/dropdown/layout.js +37 -26
  105. package/src/plugins/dropdown/lineHeight.js +54 -38
  106. package/src/plugins/dropdown/list.js +60 -45
  107. package/src/plugins/dropdown/paragraphStyle.js +51 -30
  108. package/src/plugins/dropdown/table.js +1269 -777
  109. package/src/plugins/dropdown/template.js +38 -26
  110. package/src/plugins/dropdown/textStyle.js +43 -31
  111. package/src/plugins/field/mention.js +144 -82
  112. package/src/plugins/index.js +32 -6
  113. package/src/plugins/input/fontSize.js +161 -108
  114. package/src/plugins/input/pageNavigator.js +70 -0
  115. package/src/plugins/modal/audio.js +341 -169
  116. package/src/plugins/modal/drawing.js +530 -0
  117. package/src/plugins/modal/embed.js +886 -0
  118. package/src/plugins/modal/image.js +673 -358
  119. package/src/plugins/modal/link.js +100 -71
  120. package/src/plugins/modal/math.js +384 -168
  121. package/src/plugins/modal/video.js +693 -336
  122. package/src/plugins/popup/anchor.js +222 -0
  123. package/src/suneditor.js +54 -12
  124. package/src/themes/dark.css +85 -0
  125. package/src/typedef.js +86 -0
  126. package/types/assets/icons/_default.d.ts +152 -0
  127. package/types/core/base/eventHandlers/handler_toolbar.d.ts +41 -0
  128. package/types/core/base/eventHandlers/handler_ww_clipboard.d.ts +40 -0
  129. package/types/core/base/eventHandlers/handler_ww_dragDrop.d.ts +35 -0
  130. package/types/core/base/eventHandlers/handler_ww_key_input.d.ts +45 -0
  131. package/types/core/base/eventHandlers/handler_ww_mouse.d.ts +39 -0
  132. package/types/core/base/eventManager.d.ts +377 -0
  133. package/types/core/base/events.d.ts +297 -0
  134. package/types/core/base/history.d.ts +81 -0
  135. package/types/core/class/char.d.ts +60 -0
  136. package/types/core/class/component.d.ts +259 -0
  137. package/types/core/class/format.d.ts +615 -0
  138. package/types/core/class/html.d.ts +377 -0
  139. package/types/core/class/menu.d.ts +118 -0
  140. package/types/core/class/nodeTransform.d.ts +93 -0
  141. package/types/core/class/offset.d.ts +512 -0
  142. package/types/core/class/selection.d.ts +188 -0
  143. package/types/core/class/shortcuts.d.ts +142 -0
  144. package/types/core/class/toolbar.d.ts +189 -0
  145. package/types/core/class/ui.d.ts +144 -0
  146. package/types/core/class/viewer.d.ts +140 -0
  147. package/types/core/editor.d.ts +606 -0
  148. package/types/core/section/actives.d.ts +46 -0
  149. package/types/core/section/constructor.d.ts +748 -0
  150. package/types/core/section/context.d.ts +45 -0
  151. package/types/core/section/documentType.d.ts +178 -0
  152. package/types/editorInjector/_classes.d.ts +41 -0
  153. package/types/editorInjector/_core.d.ts +92 -0
  154. package/types/editorInjector/index.d.ts +71 -0
  155. package/types/helper/converter.d.ts +150 -0
  156. package/types/helper/dom/domCheck.d.ts +182 -0
  157. package/types/helper/dom/domQuery.d.ts +214 -0
  158. package/types/helper/dom/domUtils.d.ts +211 -0
  159. package/types/helper/dom/index.d.ts +9 -0
  160. package/types/helper/env.d.ts +149 -0
  161. package/types/helper/index.d.ts +163 -0
  162. package/types/helper/keyCodeMap.d.ts +110 -0
  163. package/types/helper/numbers.d.ts +43 -0
  164. package/types/helper/unicode.d.ts +28 -0
  165. package/types/index.d.ts +0 -0
  166. package/{typings/Lang.d.ts → types/langs/_Lang.d.ts} +170 -103
  167. package/types/langs/ckb.d.ts +384 -0
  168. package/types/langs/cs.d.ts +384 -0
  169. package/types/langs/da.d.ts +384 -0
  170. package/types/langs/de.d.ts +384 -0
  171. package/types/langs/en.d.ts +384 -0
  172. package/types/langs/es.d.ts +384 -0
  173. package/types/langs/fa.d.ts +384 -0
  174. package/types/langs/fr.d.ts +384 -0
  175. package/types/langs/he.d.ts +384 -0
  176. package/types/langs/hu.d.ts +384 -0
  177. package/types/langs/index.d.ts +48 -0
  178. package/types/langs/it.d.ts +384 -0
  179. package/types/langs/ja.d.ts +384 -0
  180. package/types/langs/ko.d.ts +384 -0
  181. package/types/langs/lv.d.ts +384 -0
  182. package/types/langs/nl.d.ts +384 -0
  183. package/types/langs/pl.d.ts +384 -0
  184. package/types/langs/pt_br.d.ts +384 -0
  185. package/types/langs/ro.d.ts +384 -0
  186. package/types/langs/ru.d.ts +384 -0
  187. package/types/langs/se.d.ts +384 -0
  188. package/types/langs/tr.d.ts +384 -0
  189. package/types/langs/ua.d.ts +384 -0
  190. package/types/langs/ur.d.ts +384 -0
  191. package/types/langs/zh_cn.d.ts +384 -0
  192. package/types/modules/ApiManager.d.ts +125 -0
  193. package/types/modules/Browser.d.ts +326 -0
  194. package/types/modules/ColorPicker.d.ts +131 -0
  195. package/types/modules/Controller.d.ts +231 -0
  196. package/types/modules/Figure.d.ts +504 -0
  197. package/types/modules/FileManager.d.ts +202 -0
  198. package/types/modules/HueSlider.d.ts +136 -0
  199. package/types/modules/Modal.d.ts +117 -0
  200. package/types/modules/ModalAnchorEditor.d.ts +236 -0
  201. package/types/modules/SelectMenu.d.ts +194 -0
  202. package/types/modules/_DragHandle.d.ts +7 -0
  203. package/types/modules/index.d.ts +26 -0
  204. package/types/plugins/browser/audioGallery.d.ts +55 -0
  205. package/types/plugins/browser/fileBrowser.d.ts +64 -0
  206. package/types/plugins/browser/fileGallery.d.ts +55 -0
  207. package/types/plugins/browser/imageGallery.d.ts +51 -0
  208. package/types/plugins/browser/videoGallery.d.ts +57 -0
  209. package/types/plugins/command/blockquote.d.ts +28 -0
  210. package/types/plugins/command/exportPDF.d.ts +46 -0
  211. package/types/plugins/command/fileUpload.d.ts +156 -0
  212. package/types/plugins/command/list_bulleted.d.ts +56 -0
  213. package/types/plugins/command/list_numbered.d.ts +56 -0
  214. package/types/plugins/dropdown/align.d.ts +60 -0
  215. package/types/plugins/dropdown/backgroundColor.d.ts +63 -0
  216. package/types/plugins/dropdown/font.d.ts +54 -0
  217. package/types/plugins/dropdown/fontColor.d.ts +63 -0
  218. package/types/plugins/dropdown/formatBlock.d.ts +58 -0
  219. package/types/plugins/dropdown/hr.d.ts +81 -0
  220. package/types/plugins/dropdown/layout.d.ts +40 -0
  221. package/types/plugins/dropdown/lineHeight.d.ts +50 -0
  222. package/types/plugins/dropdown/list.d.ts +39 -0
  223. package/types/plugins/dropdown/paragraphStyle.d.ts +54 -0
  224. package/types/plugins/dropdown/table.d.ts +579 -0
  225. package/types/plugins/dropdown/template.d.ts +40 -0
  226. package/types/plugins/dropdown/textStyle.d.ts +41 -0
  227. package/types/plugins/field/mention.d.ts +102 -0
  228. package/types/plugins/index.d.ts +107 -0
  229. package/types/plugins/input/fontSize.d.ts +170 -0
  230. package/types/plugins/input/pageNavigator.d.ts +28 -0
  231. package/types/plugins/modal/audio.d.ts +269 -0
  232. package/types/plugins/modal/drawing.d.ts +246 -0
  233. package/types/plugins/modal/embed.d.ts +387 -0
  234. package/types/plugins/modal/image.d.ts +451 -0
  235. package/types/plugins/modal/link.d.ts +128 -0
  236. package/types/plugins/modal/math.d.ts +193 -0
  237. package/types/plugins/modal/video.d.ts +485 -0
  238. package/types/plugins/popup/anchor.d.ts +56 -0
  239. package/types/suneditor.d.ts +51 -0
  240. package/types/typedef-global.d.ts +144 -0
  241. package/src/core/class/notice.js +0 -42
  242. package/src/helper/domUtils.js +0 -1177
  243. package/src/modules/FileBrowser.js +0 -271
  244. package/src/plugins/command/exportPdf.js +0 -168
  245. package/src/plugins/fileBrowser/imageGallery.js +0 -81
  246. package/src/themes/test.css +0 -61
  247. package/typings/CommandPlugin.d.ts +0 -8
  248. package/typings/DialogPlugin.d.ts +0 -20
  249. package/typings/FileBrowserPlugin.d.ts +0 -30
  250. package/typings/Module.d.ts +0 -15
  251. package/typings/Plugin.d.ts +0 -42
  252. package/typings/SubmenuPlugin.d.ts +0 -8
  253. package/typings/_classes.d.ts +0 -17
  254. package/typings/_colorPicker.d.ts +0 -60
  255. package/typings/_core.d.ts +0 -55
  256. package/typings/align.d.ts +0 -5
  257. package/typings/audio.d.ts +0 -5
  258. package/typings/backgroundColor.d.ts +0 -5
  259. package/typings/blockquote.d.ts +0 -5
  260. package/typings/char.d.ts +0 -39
  261. package/typings/component.d.ts +0 -38
  262. package/typings/context.d.ts +0 -39
  263. package/typings/converter.d.ts +0 -33
  264. package/typings/dialog.d.ts +0 -28
  265. package/typings/domUtils.d.ts +0 -361
  266. package/typings/editor.d.ts +0 -7
  267. package/typings/editor.ts +0 -542
  268. package/typings/env.d.ts +0 -70
  269. package/typings/eventManager.d.ts +0 -37
  270. package/typings/events.d.ts +0 -262
  271. package/typings/fileBrowser.d.ts +0 -42
  272. package/typings/fileManager.d.ts +0 -67
  273. package/typings/font.d.ts +0 -5
  274. package/typings/fontColor.d.ts +0 -5
  275. package/typings/fontSize.d.ts +0 -5
  276. package/typings/format.d.ts +0 -191
  277. package/typings/formatBlock.d.ts +0 -5
  278. package/typings/history.d.ts +0 -48
  279. package/typings/horizontalRule.d.ts +0 -5
  280. package/typings/image.d.ts +0 -5
  281. package/typings/imageGallery.d.ts +0 -5
  282. package/typings/index.d.ts +0 -21
  283. package/typings/index.modules.d.ts +0 -11
  284. package/typings/index.plugins.d.ts +0 -58
  285. package/typings/lineHeight.d.ts +0 -5
  286. package/typings/link.d.ts +0 -5
  287. package/typings/list.d.ts +0 -5
  288. package/typings/math.d.ts +0 -5
  289. package/typings/mediaContainer.d.ts +0 -25
  290. package/typings/mention.d.ts +0 -5
  291. package/typings/node.d.ts +0 -57
  292. package/typings/notice.d.ts +0 -16
  293. package/typings/numbers.d.ts +0 -29
  294. package/typings/offset.d.ts +0 -24
  295. package/typings/options.d.ts +0 -589
  296. package/typings/paragraphStyle.d.ts +0 -5
  297. package/typings/resizing.d.ts +0 -141
  298. package/typings/selection.d.ts +0 -94
  299. package/typings/shortcuts.d.ts +0 -13
  300. package/typings/suneditor.d.ts +0 -9
  301. package/typings/table.d.ts +0 -5
  302. package/typings/template.d.ts +0 -5
  303. package/typings/textStyle.d.ts +0 -5
  304. package/typings/toolbar.d.ts +0 -32
  305. package/typings/unicode.d.ts +0 -25
  306. package/typings/video.d.ts +0 -5
@@ -2,90 +2,169 @@
2
2
  * @fileoverview Offset class
3
3
  */
4
4
 
5
- import { getParentElement, isWysiwygFrame, hasClass, addClass, removeClass, getClientSize } from '../../helper/domUtils';
6
- import { domUtils, numbers } from '../../helper';
5
+ import CoreInjector from '../../editorInjector/_core';
6
+ import { getParentElement } from '../../helper/dom/domQuery';
7
+ import { isWysiwygFrame, isElement } from '../../helper/dom/domCheck';
8
+ import { hasClass, addClass, removeClass, getClientSize } from '../../helper/dom/domUtils';
9
+ import { numbers } from '../../helper';
7
10
  import { _w, _d } from '../../helper/env';
8
11
 
9
- const Offset = function (editor) {
10
- this.editor = editor;
11
- this.options = editor.options;
12
- this.context = editor.context;
12
+ /**
13
+ * @typedef {Omit<Offset & Partial<__se__EditorInjector>, 'offset'>} OffsetThis
14
+ */
15
+
16
+ /**
17
+ * @typedef {Object} RectsInfo Bounding rectangle information of the selection range.
18
+ * @property {number} rects.left - The left position of the selection.
19
+ * @property {number} rects.right - The right position of the selection.
20
+ * @property {number} rects.top - The top position of the selection.
21
+ * @property {number} rects.bottom - The bottom position of the selection.
22
+ * @property {boolean} [rects.noText] - Whether the selection contains text.
23
+ * @property {number} [rects.width] - The width of the selection.
24
+ * @property {number} [rects.height] - The height of the selection.
25
+ */
26
+
27
+ /**
28
+ * @typedef {Object} OffsetInfo
29
+ * @property {number} top - The vertical position of the node relative to the entire document, including iframe offsets.
30
+ * @property {number} left - The horizontal position of the node relative to the entire document, including iframe offsets.
31
+ */
32
+
33
+ /**
34
+ * @typedef {Object} OffsetLocalInfo
35
+ * @property {number} top - The vertical position of the node relative to the WYSIWYG editor.
36
+ * @property {number} left - The horizontal position of the node relative to the WYSIWYG editor.
37
+ * @property {number} scrollX - The horizontal scroll offset inside the WYSIWYG editor.
38
+ * @property {number} scrollY - The vertical scroll offset inside the WYSIWYG editor.
39
+ */
40
+
41
+ /**
42
+ * @typedef {Object} OffsetGlobalInfo
43
+ * @property {number} top - The vertical position of the element relative to the entire document.
44
+ * @property {number} left - The horizontal position of the element relative to the entire document.
45
+ * @property {number} width - The total width of the element, including its content, padding, and border.
46
+ * @property {number} height - The total height of the element, including its content, padding, and border.
47
+ * @property {number} scrollTop - The amount of vertical scrolling applied to the element.
48
+ * @property {number} scrollLeft - The amount of horizontal scrolling applied to the element.
49
+ */
50
+
51
+ /**
52
+ * @typedef {Object} OffsetGlobalScrollInfo
53
+ * @property {number} top - Total vertical scroll distance
54
+ * @property {number} left - Total horizontal scroll distance
55
+ * @property {number} width - Total width including scrollable area
56
+ * @property {number} height - Total height including scrollable area
57
+ * @property {number} x - Horizontal offset from the top reference element
58
+ * @property {number} y - Vertical offset from the top reference element
59
+ * @property {HTMLElement|Window|null} ohOffsetEl - Element or window used as the vertical scroll reference
60
+ * @property {HTMLElement|Window|null} owOffsetEl - Element or window used as the horizontal scroll reference
61
+ * @property {number} oh - Height of the vertical scrollable area (clientHeight)
62
+ * @property {number} ow - Width of the horizontal scrollable area (clientWidth)
63
+ * @property {boolean} heightEditorRefer - Indicates if the vertical scroll reference is the editor area
64
+ * @property {boolean} widthEditorRefer - Indicates if the horizontal scroll reference is the editor area
65
+ * @property {number} ts - Top position of the height offset element relative to the viewport
66
+ * @property {number} ls - Left position of the width offset element relative to the viewport
67
+ */
68
+
69
+ /**
70
+ * @typedef {Object} OffsetWWScrollInfo
71
+ * @property {number} top - The vertical scroll offset inside the WYSIWYG editor.
72
+ * @property {number} left - The horizontal scroll offset inside the WYSIWYG editor.
73
+ * @property {number} width - The total width of the WYSIWYG editor's scrollable area.
74
+ * @property {number} height - The total height of the WYSIWYG editor's scrollable area.
75
+ * @property {number} bottom - The sum of `top` and `height`, representing the bottom-most scrollable position.
76
+ * @property {RectsInfo} rects - The bounding rectangle of the editor's visible area.
77
+ */
78
+
79
+ /**
80
+ * @constructor
81
+ * @this {OffsetThis}
82
+ * @description Offset class, get the position of the element
83
+ * @param {__se__EditorCore} editor - The root editor instance
84
+ */
85
+ function Offset(editor) {
86
+ CoreInjector.call(this, editor);
87
+
88
+ // members
13
89
  this._scrollEvent = null;
14
90
  this._elTop = 0;
15
91
  this._scrollY = 0;
16
92
  this._isFixed = false;
17
- };
93
+ }
18
94
 
19
95
  Offset.prototype = {
20
96
  /**
21
- * @description Returns the offset and size of the argument, "target" relative to the editor.
22
- * @param {Node} target Target node
23
- * @returns {{w:number, h:number, t:number, l:number, scrollX:number, scrollY:number}}
97
+ * @this {OffsetThis}
98
+ * @description Gets the position just outside the argument's internal editor (wysiwygFrame).
99
+ * @param {Node} node Target node.
100
+ * @returns {OffsetInfo} Position relative to the editor frame.
24
101
  */
25
- getSize(target) {
26
- const eventWysiwyg = this.editor.frameContext.get('eventWysiwyg');
102
+ get(node) {
27
103
  const wFrame = this.editor.frameContext.get('wysiwygFrame');
28
- const offset = this.get(target);
29
- const frameOffset = this.get(wFrame);
30
- const w = target.offsetWidth - 1;
31
- const h = target.offsetHeight - 1;
32
- const t = offset.top - (this.editor.frameOptions.get('iframe') ? frameOffset.top : 0);
33
- const l = offset.left - (this.editor.frameOptions.get('iframe') ? frameOffset.left + (eventWysiwyg.scrollX || eventWysiwyg.scrollLeft || 0) : 0) - wFrame.scrollLeft;
104
+ const iframe = /iframe/i.test(wFrame?.nodeName);
105
+ const off = this.getLocal(node);
34
106
 
35
107
  return {
36
- w,
37
- h,
38
- t,
39
- l,
40
- scrollX: eventWysiwyg.scrollX || eventWysiwyg.scrollLeft || 0,
41
- scrollY: eventWysiwyg.scrollY || eventWysiwyg.scrollTop || 0
108
+ left: off.left + (iframe ? wFrame.parentElement.offsetLeft : 0),
109
+ top: off.top + (iframe ? wFrame.parentElement.offsetTop : 0)
42
110
  };
43
111
  },
44
112
 
45
113
  /**
46
- * @description Returns the position of the argument, "this.editor.frameContext.get('wrapper')" to inside the editor.Returns the position of the element in "this.editor.frameContext.get('wrapper')".
47
- * @param {Node} node Target node
48
- * @returns {{top:boolean, left:boolean}}
114
+ * @this {OffsetThis}
115
+ * @description Gets the position inside the internal editor of the argument.
116
+ * @param {Node} node Target node.
117
+ * @returns {OffsetLocalInfo} Position relative to the WYSIWYG editor.
49
118
  */
50
- get(node) {
119
+ getLocal(node) {
51
120
  let offsetLeft = 0;
52
121
  let offsetTop = 0;
53
- let offsetElement = node.nodeType === 3 ? node.parentElement : node;
122
+ let l = 0;
123
+ let t = 0;
124
+ let offsetElement = /** @type {HTMLElement} */ (node.nodeType === 3 ? node.parentElement : node);
54
125
  const wysiwyg = getParentElement(node, isWysiwygFrame.bind(this));
55
126
  const self = offsetElement;
56
127
 
57
128
  while (offsetElement && !hasClass(offsetElement, 'se-wrapper') && offsetElement !== wysiwyg) {
58
129
  offsetLeft += offsetElement.offsetLeft - (self !== offsetElement ? offsetElement.scrollLeft : 0);
59
130
  offsetTop += offsetElement.offsetTop + (self !== offsetElement ? offsetElement.scrollTop : 0);
60
- offsetElement = offsetElement.offsetParent;
131
+ offsetElement = /** @type {HTMLElement} */ (offsetElement.offsetParent);
61
132
  }
62
133
 
63
- const wFrame = this.editor.frameContext.get('wysiwygFrame');
64
- const iframe = /iframe/i.test(wFrame?.nodeName);
134
+ const wwFrame = this.editor.frameContext.get('wysiwygFrame');
135
+ if (this.editor.frameContext.get('wysiwyg').contains(node)) {
136
+ l = wwFrame.offsetLeft;
137
+ t = wwFrame.offsetTop;
138
+ }
65
139
 
140
+ const eventWysiwyg = this.editor.frameContext.get('eventWysiwyg');
66
141
  return {
67
- left: offsetLeft + (iframe ? wFrame.parentElement.offsetLeft : 0),
68
- top: offsetTop - (wysiwyg ? wysiwyg.scrollTop : 0) + (iframe ? wFrame.parentElement.offsetTop : 0)
142
+ left: offsetLeft + l,
143
+ top: offsetTop + t - (wysiwyg ? wysiwyg.scrollTop : 0),
144
+ scrollX: eventWysiwyg.scrollX || eventWysiwyg.scrollLeft || 0,
145
+ scrollY: eventWysiwyg.scrollY || eventWysiwyg.scrollTop || 0
69
146
  };
70
147
  },
71
148
 
72
149
  /**
73
- * @description Returns the position of the argument, relative to global document. {left:0, top:0, scroll: 0}
74
- * @param {Element} element Target element
75
- * @returns {{top:boolean, left:boolean}}
150
+ * @this {OffsetThis}
151
+ * @description Returns the position of the argument relative to the global document.
152
+ * @param {?Node=} node Target element.
153
+ * @returns {OffsetGlobalInfo} Global position and scroll values.
76
154
  */
77
- getGlobal(element) {
155
+ getGlobal(node) {
78
156
  const topArea = this.editor.frameContext.get('topArea');
79
157
  const wFrame = this.editor.frameContext.get('wysiwygFrame');
80
158
 
81
159
  let isTop = false;
82
160
  let targetAbs = false;
83
- if (!element) element = topArea;
84
- if (element === topArea) isTop = true;
85
- if (!isTop && element.nodeType === 1) {
86
- targetAbs = _w.getComputedStyle(element).position === 'absolute';
161
+ if (!node) node = topArea;
162
+ if (node === topArea) isTop = true;
163
+ if (!isTop && isElement(node)) {
164
+ targetAbs = _w.getComputedStyle(node).position === 'absolute';
87
165
  }
88
166
 
167
+ let element = /** @type {HTMLElement} */ (node);
89
168
  const w = element.offsetWidth;
90
169
  const h = element.offsetHeight;
91
170
  let t = 0,
@@ -98,15 +177,15 @@ Offset.prototype = {
98
177
  l += element.offsetLeft;
99
178
  st += element.scrollTop;
100
179
  sl += element.scrollLeft;
101
- element = element.offsetParent;
180
+ element = /** @type {HTMLElement} */ (element.offsetParent);
102
181
  }
103
182
 
104
- if (!targetAbs && !isTop && /^iframe$/i.test(wFrame.nodeName) && wFrame.contains(element)) {
183
+ if (!targetAbs && !isTop && /^iframe$/i.test(wFrame.nodeName) && this.editor.frameContext.get('wysiwyg').contains(element)) {
105
184
  element = this.editor.frameContext.get('wrapper');
106
185
  while (element) {
107
186
  t += element.offsetTop;
108
187
  l += element.offsetLeft;
109
- element = element.offsetParent;
188
+ element = /** @type {HTMLElement} */ (element.offsetParent);
110
189
  }
111
190
  }
112
191
 
@@ -121,20 +200,22 @@ Offset.prototype = {
121
200
  },
122
201
 
123
202
  /**
203
+ * @this {OffsetThis}
124
204
  * @description Gets the current editor-relative scroll offset.
125
- * @param {Element} element Target element
126
- * @returns {{top:boolean, left:boolean, width:boolean, height:boolean}}
205
+ * @param {?Node=} node Target element.
206
+ * @returns {OffsetGlobalScrollInfo} Global scroll information.
127
207
  */
128
- getGlobalScroll(element) {
208
+ getGlobalScroll(node) {
129
209
  const topArea = this.editor.frameContext.get('topArea');
130
210
  let isTop = false;
131
211
  let targetAbs = false;
132
- if (!element) element = topArea;
133
- if (element === topArea) isTop = true;
134
- if (!isTop && element.nodeType === 1) {
135
- targetAbs = _w.getComputedStyle(element).position === 'absolute';
212
+ if (!node) node = topArea;
213
+ if (node === topArea) isTop = true;
214
+ if (!isTop && isElement(node)) {
215
+ targetAbs = _w.getComputedStyle(node).position === 'absolute';
136
216
  }
137
217
 
218
+ const element = /** @type {HTMLElement} */ (node);
138
219
  let t = 0,
139
220
  l = 0,
140
221
  h = 0,
@@ -199,7 +280,7 @@ Offset.prototype = {
199
280
  }
200
281
  }
201
282
 
202
- el = this._shadowRoot?.host;
283
+ el = /** @type {HTMLElement} */ (this._shadowRoot?.host);
203
284
  if (el) ohOffsetEl = owOffsetEl = topArea;
204
285
  while (el) {
205
286
  t += el.scrollTop;
@@ -236,8 +317,8 @@ Offset.prototype = {
236
317
  const clientSize = getClientSize(this.editor.frameContext.get('_wd'));
237
318
  return {
238
319
  top: t,
239
- ts: ts,
240
320
  left: l,
321
+ ts: ts,
241
322
  ls: ls,
242
323
  width: w,
243
324
  height: h,
@@ -253,12 +334,13 @@ Offset.prototype = {
253
334
  },
254
335
 
255
336
  /**
337
+ * @this {OffsetThis}
256
338
  * @description Get the scroll info of the WYSIWYG area.
257
- * @returns {{top:boolean, left:boolean}}
339
+ * @returns {OffsetWWScrollInfo} Scroll information within the editor.
258
340
  */
259
341
  getWWScroll() {
260
342
  const eventWysiwyg = this.editor.frameContext.get('wysiwyg');
261
- const rects = this.editor.selection.getRects(eventWysiwyg, 'start').rects;
343
+ const rects = this.selection.getRects(eventWysiwyg, 'start').rects;
262
344
  const top = eventWysiwyg.scrollY || eventWysiwyg.scrollTop || 0;
263
345
  const height = eventWysiwyg.scrollHeight || 0;
264
346
 
@@ -272,6 +354,15 @@ Offset.prototype = {
272
354
  };
273
355
  },
274
356
 
357
+ /**
358
+ * @this {OffsetThis}
359
+ * @description Sets the relative position of an element
360
+ * @param {HTMLElement} element Element to position
361
+ * @param {HTMLElement} e_container Element's root container
362
+ * @param {HTMLElement} target Target element to position against
363
+ * @param {HTMLElement} t_container Target's root container
364
+ * @param {boolean} _reload Whether to reload position
365
+ */
275
366
  setRelPosition(element, e_container, target, t_container, _reload) {
276
367
  this._scrollY = _w.scrollY;
277
368
  let wy = 0;
@@ -281,7 +372,7 @@ Offset.prototype = {
281
372
  wy += this._scrollY;
282
373
  break;
283
374
  }
284
- } while (!domUtils.hasClass(tCon, 'sun-editor') && (tCon = tCon.parentElement));
375
+ } while (!hasClass(tCon, 'sun-editor') && (tCon = tCon.parentElement));
285
376
 
286
377
  if (!_reload) {
287
378
  this.__removeGlobalEvent();
@@ -302,7 +393,7 @@ Offset.prototype = {
302
393
  element.style.left = tcleft + 'px';
303
394
  }
304
395
  } else {
305
- const cw = t_container.offsetWidth;
396
+ const cw = t_container.offsetWidth + tcleft;
306
397
  const overLeft = cw <= ew ? 0 : cw - (tl + ew);
307
398
  if (overLeft < 0) element.style.left = `${tl + overLeft + tcleft}px`;
308
399
  else element.style.left = `${tl}px`;
@@ -317,10 +408,10 @@ Offset.prototype = {
317
408
  let offsetEl = target;
318
409
  while (offsetEl && offsetEl !== e_container) {
319
410
  bt += offsetEl.offsetTop;
320
- offsetEl = offsetEl.offsetParent;
411
+ offsetEl = /** @type {HTMLElement} */ (offsetEl.offsetParent);
321
412
  }
322
413
 
323
- const menuHeight_bottom = getClientSize(this.editor.frameContext.get('_wd')).h - (containerTop - scrollTop + bt + target.offsetHeight);
414
+ const menuHeight_bottom = getClientSize(_d).h - (containerTop - scrollTop + bt + target.offsetHeight);
324
415
  if (menuHeight_bottom < elHeight) {
325
416
  let menuTop = -1 * (elHeight - bt + 3);
326
417
  const insTop = containerTop - scrollTop + menuTop;
@@ -344,6 +435,18 @@ Offset.prototype = {
344
435
  }
345
436
  },
346
437
 
438
+ /**
439
+ * @this {OffsetThis}
440
+ * @description Sets the absolute position of an element
441
+ * @param {HTMLElement} element Element to position
442
+ * @param {HTMLElement} target Target element
443
+ * @param {Object} params Position parameters
444
+ * @param {boolean} [params.isWWTarget=false] Whether the target is within the editor's WYSIWYG area
445
+ * @param {{left:number, top:number}} [params.addOffset={left:0, top:0}] Additional offset
446
+ * @param {"bottom"|"top"} [params.position="bottom"] Position ('bottom'|'top')
447
+ * @param {*} params.inst Instance object of caller
448
+ * @returns {boolean} Success / Failure
449
+ */
347
450
  setAbsPosition(element, target, params) {
348
451
  const addOffset = params.addOffset || {
349
452
  left: 0,
@@ -358,14 +461,13 @@ Offset.prototype = {
358
461
  }
359
462
 
360
463
  const isWWTarget = this.editor.frameContext.get('wrapper').contains(target) || params.isWWTarget;
361
- const isCtrlTarget = domUtils.getParentElement(target, '.se-controller');
464
+ const isCtrlTarget = getParentElement(target, '.se-controller');
362
465
  const isTargetAbs = isWWTarget && !isCtrlTarget;
363
466
  const clientSize = getClientSize(_d);
364
467
  const wwScroll = isTargetAbs ? this.getWWScroll() : this._getWindowScroll();
365
- const targetRect = isCtrlTarget ? target.getBoundingClientRect() : this.editor.selection.getRects(target, 'start').rects;
468
+ const targetRect = isCtrlTarget ? target.getBoundingClientRect() : this.selection.getRects(target, 'start').rects;
366
469
  const targetOffset = this.getGlobal(target);
367
- const arrow = hasClass(element.firstElementChild, 'se-arrow') ? element.firstElementChild : null;
368
- const isIframe = isTargetAbs && this.editor.frameOptions.get('iframe');
470
+ const arrow = /** @type {HTMLElement} */ (hasClass(element.firstElementChild, 'se-arrow') ? element.firstElementChild : null);
369
471
 
370
472
  // top ----------------------------------------------------------------------------------------------------
371
473
  const ah = arrow ? arrow.offsetHeight : 0;
@@ -374,46 +476,11 @@ Offset.prototype = {
374
476
  // margin
375
477
  const tmtw = targetRect.top;
376
478
  const tmbw = clientSize.h - targetRect.bottom;
377
- let toolbarH = !this.editor.toolbar._sticky && (this.editor.isBalloon || this.editor.isInline) ? 0 : this.context.get('toolbar.main').offsetHeight;
378
- let rmt, rmb;
379
- if (this.editor.frameContext.get('isFullScreen')) {
380
- rmt = tmtw - toolbarH;
381
- rmb = tmbw;
382
- } else {
383
- const tMargin = targetRect.top;
384
- const bMargin = clientSize.h - targetRect.bottom;
385
-
386
- if (isIframe) {
387
- const editorOffset = this.getGlobal();
388
- const editorScroll = this.getGlobalScroll();
389
- const emt = editorOffset.top - editorScroll.top - editorScroll.ts;
390
- const editorH = this.editor.frameContext.get('topArea').offsetHeight;
391
- rmt = targetRect.top - emt;
392
- rmb = bMargin - (editorScroll.oh - (editorH + emt) + (this.editor.frameContext.get('statusbar')?.offsetHeight || 0));
393
- } else {
394
- const wst = !isTargetAbs && /\d+/.test(this.editor.frameOptions.get('height')) ? this.getGlobal(this.editor.frameContext.get('topArea')).top - _w.scrollY : 0;
395
- let st = wst;
396
- if (toolbarH > wst) {
397
- if (this.editor.toolbar._sticky) {
398
- st = toolbarH;
399
- toolbarH = 0;
400
- } else {
401
- st = wst + toolbarH;
402
- }
403
- } else if (this.options.get('toolbar_container')) {
404
- toolbarH = 0;
405
- }
406
-
407
- rmt = targetRect.top - st;
408
- rmb = wwScroll.rects.bottom - targetRect.bottom;
409
- }
479
+ const toolbarH = !this.editor.toolbar._sticky && (this.editor.isBalloon || this.editor.isInline) ? 0 : this.context.get('toolbar.main').offsetHeight;
410
480
 
411
- // display margin
412
- rmt = (rmt > 0 ? tMargin : rmt) - toolbarH;
413
- rmb = rmb > 0 ? bMargin : rmb;
414
- }
415
-
416
- if (isWWTarget && (rmb + targetH <= 0 || rmt + targetH <= 0)) return;
481
+ // check margin
482
+ const { rmt, rmb, rt } = this._getVMargin(tmtw, tmbw, toolbarH, clientSize, targetRect, isTargetAbs, wwScroll);
483
+ if (isWWTarget && (rmb + targetH <= 0 || rmt + rt + targetH <= 0)) return;
417
484
 
418
485
  let t = addOffset.top;
419
486
  let y = 0;
@@ -425,7 +492,7 @@ Offset.prototype = {
425
492
  if (y < 0) {
426
493
  arrowDir = 'down';
427
494
  t -= targetH + elH + ah * 2;
428
- y = rmt - (elH + ah);
495
+ y = toolbarH + rmt - (elH + ah);
429
496
  if (y < 0) {
430
497
  arrowDir = '';
431
498
  t -= y;
@@ -518,6 +585,213 @@ Offset.prototype = {
518
585
  return true;
519
586
  },
520
587
 
588
+ /**
589
+ * @this {OffsetThis}
590
+ * @description Sets the position of an element relative to a range
591
+ * @param {HTMLElement} element Element to position
592
+ * @param {?Range} range Range to position against.
593
+ * - if null, the current selection range is used
594
+ * @param {Object} [options={}] Position options
595
+ * @param {"bottom"|"top"} [options.position="bottom"] Position ('bottom'|'top')
596
+ * @param {number} [options.addTop=0] Additional top offset
597
+ * @returns {boolean} Success / Failure
598
+ */
599
+ setRangePosition(element, range, { position, addTop } = {}) {
600
+ element.style.top = '-10000px';
601
+ element.style.visibility = 'hidden';
602
+ element.style.display = 'block';
603
+
604
+ let positionTop = position === 'top';
605
+ range = range || this.selection.getRange();
606
+ const rectsObj = this.selection.getRects(range, positionTop ? 'start' : 'end');
607
+ positionTop = rectsObj.position === 'start';
608
+
609
+ const isFullScreen = this.editor.frameContext.get('isFullScreen');
610
+ const topArea = this.editor.frameContext.get('topArea');
611
+ const rects = rectsObj.rects;
612
+ const scrollLeft = isFullScreen ? 0 : rectsObj.scrollLeft;
613
+ const scrollTop = isFullScreen ? 0 : rectsObj.scrollTop;
614
+ const editorWidth = topArea.offsetWidth;
615
+ const offsets = this.getGlobal(topArea);
616
+ const editorLeft = offsets.left;
617
+ const toolbarWidth = element.offsetWidth;
618
+ const toolbarHeight = element.offsetHeight;
619
+
620
+ this._setOffsetOnRange(positionTop, rects, element, editorLeft, editorWidth, scrollLeft, scrollTop, addTop);
621
+ if (this.getGlobal(element).top - offsets.top < 0) {
622
+ positionTop = !positionTop;
623
+ this._setOffsetOnRange(positionTop, rects, element, editorLeft, editorWidth, scrollLeft, scrollTop, addTop);
624
+ }
625
+
626
+ if (toolbarWidth !== element.offsetWidth || toolbarHeight !== element.offsetHeight) {
627
+ this._setOffsetOnRange(positionTop, rects, element, editorLeft, editorWidth, scrollLeft, scrollTop, addTop);
628
+ }
629
+
630
+ // check margin
631
+ const isTargetAbs = !this.carrierWrapper.contains(element);
632
+ const clientSize = getClientSize(_d);
633
+ const wwScroll = isTargetAbs ? this.getWWScroll() : this._getWindowScroll();
634
+ const targetH = rects.height;
635
+ const tmtw = rects.top;
636
+ const tmbw = clientSize.h - rects.bottom;
637
+ const toolbarH = !this.editor.toolbar._sticky && (this.editor.isBalloon || this.editor.isInline) ? 0 : this.context.get('toolbar.main').offsetHeight;
638
+
639
+ const { rmt, rmb, rt } = this._getVMargin(tmtw, tmbw, toolbarH, clientSize, rects, isTargetAbs, wwScroll);
640
+ if (rmb + targetH <= 0 || rmt + rt + targetH <= 0) return;
641
+
642
+ _w.setTimeout(() => {
643
+ element.style.visibility = '';
644
+ }, 0);
645
+
646
+ return true;
647
+ },
648
+
649
+ /**
650
+ * @private
651
+ * @this {OffsetThis}
652
+ * @description Sets the position of an element relative to the selection range in the editor.
653
+ * - This method calculates the top and left offsets for the element, ensuring it
654
+ * - does not overflow the editor boundaries and adjusts the arrow positioning accordingly.
655
+ * @param {boolean} isDirTop - Determines whether the element should be positioned above (`true`) or below (`false`) the target.
656
+ * @param {RectsInfo} rects - Bounding rectangle information of the selection range.
657
+ * @param {HTMLElement} element - The element to be positioned.
658
+ * @param {number} editorLeft - The left position of the editor.
659
+ * @param {number} editorWidth - The width of the editor.
660
+ * @param {number} scrollLeft - The horizontal scroll offset.
661
+ * @param {number} scrollTop - The vertical scroll offset.
662
+ * @param {number} [addTop=0] - Additional top margin adjustment.
663
+ */
664
+ _setOffsetOnRange(isDirTop, rects, element, editorLeft, editorWidth, scrollLeft, scrollTop, addTop = 0) {
665
+ const padding = 1;
666
+ const arrow = /** @type {HTMLElement} */ (element.querySelector('.se-arrow '));
667
+ const arrowMargin = Math.round(arrow.offsetWidth / 2);
668
+ const elW = element.offsetWidth;
669
+ const elH = rects.noText && !isDirTop ? 0 : element.offsetHeight;
670
+
671
+ const absoluteLeft = (isDirTop ? rects.left : rects.right) - editorLeft - elW / 2 + scrollLeft;
672
+ const overRight = absoluteLeft + elW - editorWidth;
673
+
674
+ let t = (isDirTop ? rects.top - elH - arrowMargin : rects.bottom + arrowMargin) - (rects.noText ? 0 : addTop) + scrollTop;
675
+ const l = absoluteLeft < 0 ? padding : overRight < 0 ? absoluteLeft : absoluteLeft - overRight - padding - 1;
676
+
677
+ let resetTop = false;
678
+ const space = t + (isDirTop ? this.getGlobal(this.editor.frameContext.get('topArea')).top : element.offsetHeight - this.editor.frameContext.get('wysiwyg').offsetHeight);
679
+ if (!isDirTop && space > 0 && this._getPageBottomSpace() < space) {
680
+ isDirTop = true;
681
+ resetTop = true;
682
+ } else if (isDirTop && _d.documentElement.offsetTop > space) {
683
+ isDirTop = false;
684
+ resetTop = true;
685
+ }
686
+
687
+ if (resetTop) t = (isDirTop ? rects.top - elH - arrowMargin : rects.bottom + arrowMargin) - (rects.noText ? 0 : addTop) + scrollTop;
688
+
689
+ element.style.left = Math.floor(l) + 'px';
690
+ element.style.top = Math.floor(t) + 'px';
691
+
692
+ if (isDirTop) {
693
+ removeClass(arrow, 'se-arrow-up');
694
+ addClass(arrow, 'se-arrow-down');
695
+ } else {
696
+ removeClass(arrow, 'se-arrow-down');
697
+ addClass(arrow, 'se-arrow-up');
698
+ }
699
+
700
+ const arrow_left = Math.floor(elW / 2 + (absoluteLeft - l));
701
+ arrow.style.left = (arrow_left + arrowMargin > element.offsetWidth ? element.offsetWidth - arrowMargin : arrow_left < arrowMargin ? arrowMargin : arrow_left) + 'px';
702
+ },
703
+
704
+ /**
705
+ * @private
706
+ * @this {OffsetThis}
707
+ * @description Get available space from page bottom
708
+ * @returns {number} Available space
709
+ */
710
+ _getPageBottomSpace() {
711
+ const topArea = this.editor.frameContext.get('topArea');
712
+ return _d.documentElement.scrollHeight - (this.getGlobal(topArea).top + topArea.offsetHeight);
713
+ },
714
+
715
+ /**
716
+ * @private
717
+ * @this {OffsetThis}
718
+ * @description Calculates the vertical margin offsets for the target element relative to the editor frame.
719
+ * - This method determines the top and bottom margins based on various conditions such as
720
+ * - fullscreen mode, iframe usage, toolbar height, and scroll positions.
721
+ * @param {number} tmtw Top margin to window
722
+ * @param {number} tmbw Bottom margin to window
723
+ * @param {number} toolbarH Toolbar height
724
+ * @param {{w: number, h: number}} clientSize documentElement.clientWidth, documentElement.clientHeight
725
+ * @param {RectsInfo} targetRect Target rect object
726
+ * @param {boolean} isTargetAbs Is target absolute position
727
+ * @param {OffsetWWScrollInfo} wwScroll WYSIWYG scroll info
728
+ * @returns {{rmt:number, rmb:number, rt:number}} Margin values (rmt: top margin, rmb: bottom margin, rt: Toolbar height offset adjustment)
729
+ */
730
+ _getVMargin(tmtw, tmbw, toolbarH, clientSize, targetRect, isTargetAbs, wwScroll) {
731
+ let rmt = 0;
732
+ let rmb = 0;
733
+ let rt = 0;
734
+ if (this.editor.frameContext.get('isFullScreen')) {
735
+ rmt = tmtw - toolbarH;
736
+ rmb = tmbw;
737
+ } else {
738
+ const isIframe = isTargetAbs && this.editor.frameOptions.get('iframe');
739
+ const tMargin = targetRect.top;
740
+ const bMargin = clientSize.h - targetRect.bottom;
741
+ const editorOffset = this.getGlobal();
742
+ const editorScroll = this.getGlobalScroll();
743
+ const statusBarH = this.editor.frameContext.get('statusbar')?.offsetHeight || 0;
744
+
745
+ if (isIframe) {
746
+ const emt = editorOffset.top - editorScroll.top - editorScroll.ts;
747
+ const editorH = this.editor.frameContext.get('topArea').offsetHeight;
748
+ rmt = targetRect.top - emt;
749
+ rmb = bMargin - (editorScroll.oh - (editorH + emt) + statusBarH);
750
+ } else {
751
+ rt = !this.editor.toolbar._sticky && !this.options.get('toolbar_container') ? toolbarH : 0;
752
+ const wst = !isTargetAbs && /\d+/.test(this.editor.frameOptions.get('height')) ? editorOffset.top - _w.scrollY + rt : 0;
753
+ const wsb = !isTargetAbs && /\d+/.test(this.editor.frameOptions.get('height')) ? _w.innerHeight - (editorOffset.top + editorOffset.height - _w.scrollY) : 0;
754
+ let st = wst;
755
+ if (toolbarH > wst) {
756
+ if (this.editor.toolbar._sticky) {
757
+ st = toolbarH;
758
+ toolbarH = 0;
759
+ } else {
760
+ st = wst + toolbarH;
761
+ }
762
+ } else if (this.options.get('toolbar_container')) {
763
+ toolbarH = 0;
764
+ } else {
765
+ st = wst + (this.editor.toolbar._sticky ? toolbarH : 0);
766
+ }
767
+
768
+ rmt = targetRect.top - st;
769
+ rmb = wwScroll.rects.bottom - targetRect.bottom - wsb - statusBarH;
770
+ }
771
+
772
+ // display margin
773
+ rmt = (rmt > 0 ? tMargin : rmt) - toolbarH;
774
+ rmb = rmb > 0 ? bMargin : rmb;
775
+ }
776
+
777
+ return {
778
+ rmt,
779
+ rmb,
780
+ rt
781
+ };
782
+ },
783
+
784
+ /**
785
+ * @private
786
+ * @this {OffsetThis}
787
+ * @description Sets the visibility and direction of the arrow element.
788
+ * - This method applies the appropriate class (`se-arrow-up` or `se-arrow-down`)
789
+ * - based on the specified direction key and adjusts the visibility of the arrow.
790
+ * @param {HTMLElement} arrow - The arrow element to be updated.
791
+ * @param {string} key - The direction of the arrow. ("up"|"down"|"")
792
+ * - Accepts `'up'` for an upward arrow, `'down'` for a downward arrow,
793
+ * - or any other value to hide the arrow.
794
+ */
521
795
  _setArrow(arrow, key) {
522
796
  if (key === 'up') {
523
797
  if (arrow) arrow.style.visibility = '';
@@ -532,13 +806,29 @@ Offset.prototype = {
532
806
  }
533
807
  },
534
808
 
809
+ /**
810
+ * @private
811
+ * @this {OffsetThis}
812
+ * @description Retrieves the current window scroll position and viewport size.
813
+ * - Returns an object containing the scroll offsets, viewport dimensions, and boundary rects.
814
+ * @returns {{
815
+ * top: number,
816
+ * left: number,
817
+ * width: number,
818
+ * height: number,
819
+ * bottom: number,
820
+ * rects: RectsInfo
821
+ * }} An object with scroll and viewport information.
822
+ */
823
+
535
824
  _getWindowScroll() {
536
- const viewPort = domUtils.getClientSize();
825
+ const viewPort = getClientSize(_d);
537
826
  return {
538
827
  top: _w.scrollY,
539
828
  left: _w.scrollX,
540
829
  width: viewPort.w,
541
830
  height: viewPort.h,
831
+ bottom: _w.scrollY + viewPort.h,
542
832
  rects: {
543
833
  left: 0,
544
834
  top: 0,
@@ -549,6 +839,12 @@ Offset.prototype = {
549
839
  };
550
840
  },
551
841
 
842
+ /**
843
+ * @private
844
+ * @this {OffsetThis}
845
+ * @description Removes the global scroll event listener from the editor.
846
+ * - Resets related scroll tracking properties.
847
+ */
552
848
  __removeGlobalEvent() {
553
849
  if (this._scrollEvent) {
554
850
  this._scrollEvent = this.editor.eventManager.removeGlobalEvent(this._scrollEvent);
@@ -560,6 +856,14 @@ Offset.prototype = {
560
856
  constructor: Offset
561
857
  };
562
858
 
859
+ /**
860
+ * @private
861
+ * @this {OffsetThis}
862
+ * @param {HTMLElement} element - The element to check for a specific class name.
863
+ * @param {HTMLElement} e_container - The root container of the element.
864
+ * @param {HTMLElement} target - The target element to position against.
865
+ * @param {HTMLElement} t_container - The root container of the target element.
866
+ */
563
867
  function FixedScroll(element, e_container, target, t_container) {
564
868
  const isFixed = /^fixed$/i.test(_w.getComputedStyle(t_container).position);
565
869
  if (!this._isFixed) {