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.
- package/.eslintrc.json +4 -3
- package/CONTRIBUTING.md +4 -2
- package/README.md +19 -11
- package/README_V3_TEMP.md +705 -0
- package/dist/suneditor.min.css +1 -0
- package/dist/suneditor.min.js +1 -0
- package/example.md +587 -0
- package/package.json +15 -9
- package/src/assets/icons/_default.js +166 -131
- package/src/assets/{suneditor-content.css → suneditor-contents.css} +182 -45
- package/src/assets/suneditor.css +1195 -556
- package/src/assets/variables.css +138 -0
- package/src/core/base/eventHandlers/handler_toolbar.js +35 -14
- package/src/core/base/eventHandlers/handler_ww_clipboard.js +29 -4
- package/src/core/base/eventHandlers/handler_ww_dragDrop.js +59 -15
- package/src/core/base/eventHandlers/handler_ww_key_input.js +426 -212
- package/src/core/base/eventHandlers/handler_ww_mouse.js +108 -32
- package/src/core/base/eventManager.js +540 -209
- package/src/core/base/events.js +616 -320
- package/src/core/base/history.js +93 -39
- package/src/core/class/char.js +29 -13
- package/src/core/class/component.js +332 -145
- package/src/core/class/format.js +671 -509
- package/src/core/class/html.js +504 -290
- package/src/core/class/menu.js +114 -47
- package/src/core/class/nodeTransform.js +111 -66
- package/src/core/class/offset.js +409 -105
- package/src/core/class/selection.js +220 -108
- package/src/core/class/shortcuts.js +68 -8
- package/src/core/class/toolbar.js +106 -116
- package/src/core/class/ui.js +330 -0
- package/src/core/class/viewer.js +178 -74
- package/src/core/editor.js +489 -384
- package/src/core/section/actives.js +118 -22
- package/src/core/section/constructor.js +504 -170
- package/src/core/section/context.js +28 -23
- package/src/core/section/documentType.js +561 -0
- package/src/editorInjector/_classes.js +19 -5
- package/src/editorInjector/_core.js +71 -7
- package/src/editorInjector/index.js +63 -1
- package/src/helper/converter.js +137 -19
- package/src/helper/dom/domCheck.js +294 -0
- package/src/helper/dom/domQuery.js +609 -0
- package/src/helper/dom/domUtils.js +533 -0
- package/src/helper/dom/index.js +12 -0
- package/src/helper/env.js +42 -19
- package/src/helper/index.js +7 -4
- package/src/helper/keyCodeMap.js +183 -0
- package/src/helper/numbers.js +8 -8
- package/src/helper/unicode.js +5 -5
- package/src/langs/ckb.js +69 -3
- package/src/langs/cs.js +67 -1
- package/src/langs/da.js +68 -2
- package/src/langs/de.js +68 -3
- package/src/langs/en.js +29 -1
- package/src/langs/es.js +68 -3
- package/src/langs/fa.js +70 -2
- package/src/langs/fr.js +68 -2
- package/src/langs/he.js +68 -3
- package/src/langs/hu.js +226 -0
- package/src/langs/index.js +3 -2
- package/src/langs/it.js +65 -0
- package/src/langs/ja.js +68 -3
- package/src/langs/ko.js +66 -1
- package/src/langs/lv.js +68 -3
- package/src/langs/nl.js +68 -3
- package/src/langs/pl.js +68 -3
- package/src/langs/pt_br.js +65 -0
- package/src/langs/ro.js +69 -4
- package/src/langs/ru.js +68 -3
- package/src/langs/se.js +68 -3
- package/src/langs/tr.js +68 -0
- package/src/langs/ua.js +68 -3
- package/src/langs/ur.js +71 -6
- package/src/langs/zh_cn.js +69 -4
- package/src/modules/ApiManager.js +77 -54
- package/src/modules/Browser.js +667 -0
- package/src/modules/ColorPicker.js +162 -102
- package/src/modules/Controller.js +233 -136
- package/src/modules/Figure.js +913 -489
- package/src/modules/FileManager.js +141 -72
- package/src/modules/HueSlider.js +113 -61
- package/src/modules/Modal.js +292 -113
- package/src/modules/ModalAnchorEditor.js +380 -230
- package/src/modules/SelectMenu.js +270 -168
- package/src/modules/_DragHandle.js +2 -1
- package/src/modules/index.js +3 -3
- package/src/plugins/browser/audioGallery.js +83 -0
- package/src/plugins/browser/fileBrowser.js +103 -0
- package/src/plugins/browser/fileGallery.js +83 -0
- package/src/plugins/browser/imageGallery.js +81 -0
- package/src/plugins/browser/videoGallery.js +103 -0
- package/src/plugins/command/blockquote.js +40 -27
- package/src/plugins/command/exportPDF.js +134 -0
- package/src/plugins/command/fileUpload.js +226 -158
- package/src/plugins/command/list_bulleted.js +93 -47
- package/src/plugins/command/list_numbered.js +93 -47
- package/src/plugins/dropdown/align.js +66 -54
- package/src/plugins/dropdown/backgroundColor.js +76 -45
- package/src/plugins/dropdown/font.js +71 -47
- package/src/plugins/dropdown/fontColor.js +78 -46
- package/src/plugins/dropdown/formatBlock.js +74 -33
- package/src/plugins/dropdown/hr.js +102 -51
- package/src/plugins/dropdown/layout.js +37 -26
- package/src/plugins/dropdown/lineHeight.js +54 -38
- package/src/plugins/dropdown/list.js +60 -45
- package/src/plugins/dropdown/paragraphStyle.js +51 -30
- package/src/plugins/dropdown/table.js +1269 -777
- package/src/plugins/dropdown/template.js +38 -26
- package/src/plugins/dropdown/textStyle.js +43 -31
- package/src/plugins/field/mention.js +144 -82
- package/src/plugins/index.js +32 -6
- package/src/plugins/input/fontSize.js +161 -108
- package/src/plugins/input/pageNavigator.js +70 -0
- package/src/plugins/modal/audio.js +341 -169
- package/src/plugins/modal/drawing.js +530 -0
- package/src/plugins/modal/embed.js +886 -0
- package/src/plugins/modal/image.js +673 -358
- package/src/plugins/modal/link.js +100 -71
- package/src/plugins/modal/math.js +384 -168
- package/src/plugins/modal/video.js +693 -336
- package/src/plugins/popup/anchor.js +222 -0
- package/src/suneditor.js +54 -12
- package/src/themes/dark.css +85 -0
- package/src/typedef.js +86 -0
- package/types/assets/icons/_default.d.ts +152 -0
- package/types/core/base/eventHandlers/handler_toolbar.d.ts +41 -0
- package/types/core/base/eventHandlers/handler_ww_clipboard.d.ts +40 -0
- package/types/core/base/eventHandlers/handler_ww_dragDrop.d.ts +35 -0
- package/types/core/base/eventHandlers/handler_ww_key_input.d.ts +45 -0
- package/types/core/base/eventHandlers/handler_ww_mouse.d.ts +39 -0
- package/types/core/base/eventManager.d.ts +377 -0
- package/types/core/base/events.d.ts +297 -0
- package/types/core/base/history.d.ts +81 -0
- package/types/core/class/char.d.ts +60 -0
- package/types/core/class/component.d.ts +259 -0
- package/types/core/class/format.d.ts +615 -0
- package/types/core/class/html.d.ts +377 -0
- package/types/core/class/menu.d.ts +118 -0
- package/types/core/class/nodeTransform.d.ts +93 -0
- package/types/core/class/offset.d.ts +512 -0
- package/types/core/class/selection.d.ts +188 -0
- package/types/core/class/shortcuts.d.ts +142 -0
- package/types/core/class/toolbar.d.ts +189 -0
- package/types/core/class/ui.d.ts +144 -0
- package/types/core/class/viewer.d.ts +140 -0
- package/types/core/editor.d.ts +606 -0
- package/types/core/section/actives.d.ts +46 -0
- package/types/core/section/constructor.d.ts +748 -0
- package/types/core/section/context.d.ts +45 -0
- package/types/core/section/documentType.d.ts +178 -0
- package/types/editorInjector/_classes.d.ts +41 -0
- package/types/editorInjector/_core.d.ts +92 -0
- package/types/editorInjector/index.d.ts +71 -0
- package/types/helper/converter.d.ts +150 -0
- package/types/helper/dom/domCheck.d.ts +182 -0
- package/types/helper/dom/domQuery.d.ts +214 -0
- package/types/helper/dom/domUtils.d.ts +211 -0
- package/types/helper/dom/index.d.ts +9 -0
- package/types/helper/env.d.ts +149 -0
- package/types/helper/index.d.ts +163 -0
- package/types/helper/keyCodeMap.d.ts +110 -0
- package/types/helper/numbers.d.ts +43 -0
- package/types/helper/unicode.d.ts +28 -0
- package/types/index.d.ts +0 -0
- package/{typings/Lang.d.ts → types/langs/_Lang.d.ts} +170 -103
- package/types/langs/ckb.d.ts +384 -0
- package/types/langs/cs.d.ts +384 -0
- package/types/langs/da.d.ts +384 -0
- package/types/langs/de.d.ts +384 -0
- package/types/langs/en.d.ts +384 -0
- package/types/langs/es.d.ts +384 -0
- package/types/langs/fa.d.ts +384 -0
- package/types/langs/fr.d.ts +384 -0
- package/types/langs/he.d.ts +384 -0
- package/types/langs/hu.d.ts +384 -0
- package/types/langs/index.d.ts +48 -0
- package/types/langs/it.d.ts +384 -0
- package/types/langs/ja.d.ts +384 -0
- package/types/langs/ko.d.ts +384 -0
- package/types/langs/lv.d.ts +384 -0
- package/types/langs/nl.d.ts +384 -0
- package/types/langs/pl.d.ts +384 -0
- package/types/langs/pt_br.d.ts +384 -0
- package/types/langs/ro.d.ts +384 -0
- package/types/langs/ru.d.ts +384 -0
- package/types/langs/se.d.ts +384 -0
- package/types/langs/tr.d.ts +384 -0
- package/types/langs/ua.d.ts +384 -0
- package/types/langs/ur.d.ts +384 -0
- package/types/langs/zh_cn.d.ts +384 -0
- package/types/modules/ApiManager.d.ts +125 -0
- package/types/modules/Browser.d.ts +326 -0
- package/types/modules/ColorPicker.d.ts +131 -0
- package/types/modules/Controller.d.ts +231 -0
- package/types/modules/Figure.d.ts +504 -0
- package/types/modules/FileManager.d.ts +202 -0
- package/types/modules/HueSlider.d.ts +136 -0
- package/types/modules/Modal.d.ts +117 -0
- package/types/modules/ModalAnchorEditor.d.ts +236 -0
- package/types/modules/SelectMenu.d.ts +194 -0
- package/types/modules/_DragHandle.d.ts +7 -0
- package/types/modules/index.d.ts +26 -0
- package/types/plugins/browser/audioGallery.d.ts +55 -0
- package/types/plugins/browser/fileBrowser.d.ts +64 -0
- package/types/plugins/browser/fileGallery.d.ts +55 -0
- package/types/plugins/browser/imageGallery.d.ts +51 -0
- package/types/plugins/browser/videoGallery.d.ts +57 -0
- package/types/plugins/command/blockquote.d.ts +28 -0
- package/types/plugins/command/exportPDF.d.ts +46 -0
- package/types/plugins/command/fileUpload.d.ts +156 -0
- package/types/plugins/command/list_bulleted.d.ts +56 -0
- package/types/plugins/command/list_numbered.d.ts +56 -0
- package/types/plugins/dropdown/align.d.ts +60 -0
- package/types/plugins/dropdown/backgroundColor.d.ts +63 -0
- package/types/plugins/dropdown/font.d.ts +54 -0
- package/types/plugins/dropdown/fontColor.d.ts +63 -0
- package/types/plugins/dropdown/formatBlock.d.ts +58 -0
- package/types/plugins/dropdown/hr.d.ts +81 -0
- package/types/plugins/dropdown/layout.d.ts +40 -0
- package/types/plugins/dropdown/lineHeight.d.ts +50 -0
- package/types/plugins/dropdown/list.d.ts +39 -0
- package/types/plugins/dropdown/paragraphStyle.d.ts +54 -0
- package/types/plugins/dropdown/table.d.ts +579 -0
- package/types/plugins/dropdown/template.d.ts +40 -0
- package/types/plugins/dropdown/textStyle.d.ts +41 -0
- package/types/plugins/field/mention.d.ts +102 -0
- package/types/plugins/index.d.ts +107 -0
- package/types/plugins/input/fontSize.d.ts +170 -0
- package/types/plugins/input/pageNavigator.d.ts +28 -0
- package/types/plugins/modal/audio.d.ts +269 -0
- package/types/plugins/modal/drawing.d.ts +246 -0
- package/types/plugins/modal/embed.d.ts +387 -0
- package/types/plugins/modal/image.d.ts +451 -0
- package/types/plugins/modal/link.d.ts +128 -0
- package/types/plugins/modal/math.d.ts +193 -0
- package/types/plugins/modal/video.d.ts +485 -0
- package/types/plugins/popup/anchor.d.ts +56 -0
- package/types/suneditor.d.ts +51 -0
- package/types/typedef-global.d.ts +144 -0
- package/src/core/class/notice.js +0 -42
- package/src/helper/domUtils.js +0 -1177
- package/src/modules/FileBrowser.js +0 -271
- package/src/plugins/command/exportPdf.js +0 -168
- package/src/plugins/fileBrowser/imageGallery.js +0 -81
- package/src/themes/test.css +0 -61
- package/typings/CommandPlugin.d.ts +0 -8
- package/typings/DialogPlugin.d.ts +0 -20
- package/typings/FileBrowserPlugin.d.ts +0 -30
- package/typings/Module.d.ts +0 -15
- package/typings/Plugin.d.ts +0 -42
- package/typings/SubmenuPlugin.d.ts +0 -8
- package/typings/_classes.d.ts +0 -17
- package/typings/_colorPicker.d.ts +0 -60
- package/typings/_core.d.ts +0 -55
- package/typings/align.d.ts +0 -5
- package/typings/audio.d.ts +0 -5
- package/typings/backgroundColor.d.ts +0 -5
- package/typings/blockquote.d.ts +0 -5
- package/typings/char.d.ts +0 -39
- package/typings/component.d.ts +0 -38
- package/typings/context.d.ts +0 -39
- package/typings/converter.d.ts +0 -33
- package/typings/dialog.d.ts +0 -28
- package/typings/domUtils.d.ts +0 -361
- package/typings/editor.d.ts +0 -7
- package/typings/editor.ts +0 -542
- package/typings/env.d.ts +0 -70
- package/typings/eventManager.d.ts +0 -37
- package/typings/events.d.ts +0 -262
- package/typings/fileBrowser.d.ts +0 -42
- package/typings/fileManager.d.ts +0 -67
- package/typings/font.d.ts +0 -5
- package/typings/fontColor.d.ts +0 -5
- package/typings/fontSize.d.ts +0 -5
- package/typings/format.d.ts +0 -191
- package/typings/formatBlock.d.ts +0 -5
- package/typings/history.d.ts +0 -48
- package/typings/horizontalRule.d.ts +0 -5
- package/typings/image.d.ts +0 -5
- package/typings/imageGallery.d.ts +0 -5
- package/typings/index.d.ts +0 -21
- package/typings/index.modules.d.ts +0 -11
- package/typings/index.plugins.d.ts +0 -58
- package/typings/lineHeight.d.ts +0 -5
- package/typings/link.d.ts +0 -5
- package/typings/list.d.ts +0 -5
- package/typings/math.d.ts +0 -5
- package/typings/mediaContainer.d.ts +0 -25
- package/typings/mention.d.ts +0 -5
- package/typings/node.d.ts +0 -57
- package/typings/notice.d.ts +0 -16
- package/typings/numbers.d.ts +0 -29
- package/typings/offset.d.ts +0 -24
- package/typings/options.d.ts +0 -589
- package/typings/paragraphStyle.d.ts +0 -5
- package/typings/resizing.d.ts +0 -141
- package/typings/selection.d.ts +0 -94
- package/typings/shortcuts.d.ts +0 -13
- package/typings/suneditor.d.ts +0 -9
- package/typings/table.d.ts +0 -5
- package/typings/template.d.ts +0 -5
- package/typings/textStyle.d.ts +0 -5
- package/typings/toolbar.d.ts +0 -32
- package/typings/unicode.d.ts +0 -25
- package/typings/video.d.ts +0 -5
package/src/core/class/offset.js
CHANGED
|
@@ -2,90 +2,169 @@
|
|
|
2
2
|
* @fileoverview Offset class
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
* @
|
|
22
|
-
* @
|
|
23
|
-
* @
|
|
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
|
-
|
|
26
|
-
const eventWysiwyg = this.editor.frameContext.get('eventWysiwyg');
|
|
102
|
+
get(node) {
|
|
27
103
|
const wFrame = this.editor.frameContext.get('wysiwygFrame');
|
|
28
|
-
const
|
|
29
|
-
const
|
|
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
|
-
|
|
37
|
-
|
|
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
|
-
* @
|
|
47
|
-
* @
|
|
48
|
-
* @
|
|
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
|
-
|
|
119
|
+
getLocal(node) {
|
|
51
120
|
let offsetLeft = 0;
|
|
52
121
|
let offsetTop = 0;
|
|
53
|
-
let
|
|
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
|
|
64
|
-
|
|
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 +
|
|
68
|
-
top: offsetTop - (wysiwyg ? wysiwyg.scrollTop : 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
|
-
* @
|
|
74
|
-
* @
|
|
75
|
-
* @
|
|
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(
|
|
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 (!
|
|
84
|
-
if (
|
|
85
|
-
if (!isTop &&
|
|
86
|
-
targetAbs = _w.getComputedStyle(
|
|
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) &&
|
|
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 {
|
|
126
|
-
* @returns {
|
|
205
|
+
* @param {?Node=} node Target element.
|
|
206
|
+
* @returns {OffsetGlobalScrollInfo} Global scroll information.
|
|
127
207
|
*/
|
|
128
|
-
getGlobalScroll(
|
|
208
|
+
getGlobalScroll(node) {
|
|
129
209
|
const topArea = this.editor.frameContext.get('topArea');
|
|
130
210
|
let isTop = false;
|
|
131
211
|
let targetAbs = false;
|
|
132
|
-
if (!
|
|
133
|
-
if (
|
|
134
|
-
if (!isTop &&
|
|
135
|
-
targetAbs = _w.getComputedStyle(
|
|
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 {
|
|
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.
|
|
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 (!
|
|
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(
|
|
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 =
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
412
|
-
|
|
413
|
-
|
|
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 =
|
|
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) {
|