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
|
@@ -3,39 +3,98 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import CoreInjector from '../../editorInjector/_core';
|
|
6
|
-
import {
|
|
6
|
+
import { dom, env, numbers, unicode, keyCodeMap } from '../../helper';
|
|
7
7
|
import { Figure, _DragHandle } from '../../modules';
|
|
8
8
|
|
|
9
|
-
const { _w, ON_OVER_COMPONENT } = env;
|
|
9
|
+
const { _w, ON_OVER_COMPONENT, isMobile } = env;
|
|
10
10
|
const DIR_KEYCODE = /^(3[7-9]|40)$/;
|
|
11
11
|
const DIR_UP_KEYCODE = /^3[7-8]$/;
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Omit<Component & Partial<__se__EditorInjector>, 'component'>} ComponentThis
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {Object} ComponentInfo
|
|
19
|
+
* @property {HTMLElement} target - The target element associated with the component.
|
|
20
|
+
* @property {string} pluginName - The name of the plugin related to the component.
|
|
21
|
+
* @property {Object<string, *>} options - Options related to the component.
|
|
22
|
+
* @property {HTMLElement} container - The main container element for the component.
|
|
23
|
+
* @property {?HTMLElement} cover - The cover element, if applicable.
|
|
24
|
+
* @property {?HTMLElement} inlineCover - The inline cover element, if applicable.
|
|
25
|
+
* @property {?HTMLElement} caption - The caption element, if applicable.
|
|
26
|
+
* @property {boolean} isFile - Whether the component is a file-related component.
|
|
27
|
+
* @property {?HTMLElement} launcher - The element that triggered the component, if applicable.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @constructor
|
|
32
|
+
* @this {ComponentThis}
|
|
33
|
+
* @description Class for managing components such as images and tables that are not in line format
|
|
34
|
+
* @param {__se__EditorCore} editor - The root editor instance
|
|
35
|
+
*/
|
|
36
|
+
function Component(editor) {
|
|
14
37
|
CoreInjector.call(this, editor);
|
|
15
38
|
|
|
16
|
-
|
|
39
|
+
/**
|
|
40
|
+
* @description The current component information, used copy, cut, and keydown events
|
|
41
|
+
* @type {ComponentInfo}
|
|
42
|
+
*/
|
|
17
43
|
this.info = null;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @description Component is selected
|
|
47
|
+
* @type {boolean}
|
|
48
|
+
*/
|
|
18
49
|
this.isSelected = false;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @description Currently selected component target
|
|
53
|
+
* @type {Node|null}
|
|
54
|
+
*/
|
|
19
55
|
this.currentTarget = null;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @description Currently selected component plugin instance
|
|
59
|
+
* @type {*}
|
|
60
|
+
*/
|
|
20
61
|
this.currentPlugin = null;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @description Currently selected component plugin name
|
|
65
|
+
* @type {*}
|
|
66
|
+
*/
|
|
21
67
|
this.currentPluginName = '';
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @description Currently selected component information
|
|
71
|
+
* @type {ComponentInfo|null}
|
|
72
|
+
*/
|
|
22
73
|
this.currentInfo = null;
|
|
74
|
+
|
|
75
|
+
/** @type {Object<string, (...args: *) => *>} */
|
|
23
76
|
this.__globalEvents = {
|
|
24
77
|
copy: OnCopy_component.bind(this),
|
|
25
78
|
cut: OnCut_component.bind(this),
|
|
26
79
|
keydown: OnKeyDown_component.bind(this),
|
|
27
80
|
mousedown: CloseListener_mousedown.bind(this)
|
|
28
81
|
};
|
|
82
|
+
/** @type {__se__GlobalEventInfo|void} */
|
|
29
83
|
this._bindClose_copy = null;
|
|
84
|
+
/** @type {__se__GlobalEventInfo|void} */
|
|
30
85
|
this._bindClose_cut = null;
|
|
86
|
+
/** @type {__se__GlobalEventInfo|void} */
|
|
31
87
|
this._bindClose_keydown = null;
|
|
88
|
+
/** @type {__se__GlobalEventInfo|void} */
|
|
32
89
|
this._bindClose_mousedown = null;
|
|
90
|
+
/** @type {__se__GlobalEventInfo|void} */
|
|
33
91
|
this._bindClose_touchstart = null;
|
|
92
|
+
/** @type {boolean} */
|
|
34
93
|
this.__selectionSelected = false;
|
|
35
94
|
|
|
36
95
|
this.editor.applyFrameRoots((e) => {
|
|
37
96
|
// drag
|
|
38
|
-
const dragHandle =
|
|
97
|
+
const dragHandle = dom.utils.createElement('DIV', { class: 'se-drag-handle', draggable: 'true' }, this.icons.selection);
|
|
39
98
|
e.get('wrapper').appendChild(dragHandle);
|
|
40
99
|
this.eventManager.addEvent(dragHandle, 'mouseenter', OnDragEnter.bind(this));
|
|
41
100
|
this.eventManager.addEvent(dragHandle, 'mouseleave', OnDragLeave.bind(this));
|
|
@@ -43,19 +102,22 @@ const Component = function (editor) {
|
|
|
43
102
|
this.eventManager.addEvent(dragHandle, 'dragend', OnDragEnd.bind(this));
|
|
44
103
|
this.eventManager.addEvent(dragHandle, 'click', OnDragClick.bind(this));
|
|
45
104
|
});
|
|
46
|
-
}
|
|
105
|
+
}
|
|
47
106
|
|
|
48
107
|
Component.prototype = {
|
|
49
108
|
/**
|
|
50
|
-
* @
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
* @param {
|
|
54
|
-
* @param {
|
|
55
|
-
* @
|
|
109
|
+
* @this {ComponentThis}
|
|
110
|
+
* @description Inserts an element and returns it. (Used for elements: table, hr, image, video)
|
|
111
|
+
* - If "element" is "HR", inserts and returns the new line.
|
|
112
|
+
* @param {Node} element Element to be inserted
|
|
113
|
+
* @param {Object} [options] Options
|
|
114
|
+
* @param {boolean} [options.skipCharCount=false] If true, it will be inserted even if "frameOptions.get('charCounter_max')" is exceeded.
|
|
115
|
+
* @param {boolean} [options.skipSelection=false] If true, do not automatically select the inserted component.
|
|
116
|
+
* @param {boolean} [options.skipHistory=false] If true, do not push to history.
|
|
117
|
+
* @returns {HTMLElement} The inserted element or new line (for HR)
|
|
56
118
|
*/
|
|
57
|
-
insert(element,
|
|
58
|
-
if (this.editor.frameContext.get('isReadOnly') || (!
|
|
119
|
+
insert(element, { skipCharCount, skipSelection, skipHistory } = {}) {
|
|
120
|
+
if (this.editor.frameContext.get('isReadOnly') || (!skipCharCount && !this.char.check(element))) {
|
|
59
121
|
return null;
|
|
60
122
|
}
|
|
61
123
|
|
|
@@ -66,45 +128,51 @@ Component.prototype = {
|
|
|
66
128
|
let oNode = null;
|
|
67
129
|
let formatEl = this.format.getLine(selectionNode, null);
|
|
68
130
|
|
|
69
|
-
if (
|
|
70
|
-
this.html.insertNode(element, isInline ? null : selectionNode === formatEl ? null : r.container.nextSibling, true);
|
|
71
|
-
if (!isInline && !element.nextSibling) element.parentNode.appendChild(
|
|
131
|
+
if (dom.check.isListCell(formatEl)) {
|
|
132
|
+
this.html.insertNode(element, { afterNode: isInline ? null : selectionNode === formatEl ? null : r.container.nextSibling, skipCharCount: true });
|
|
133
|
+
if (!isInline && !element.nextSibling) element.parentNode.appendChild(dom.utils.createElement('BR'));
|
|
72
134
|
} else {
|
|
73
|
-
if (this.selection.getRange().collapsed && (r.container.nodeType === 3 ||
|
|
74
|
-
const depthFormat =
|
|
75
|
-
oNode = this.nodeTransform.split(r.container, r.offset, !depthFormat ? 0 :
|
|
76
|
-
if (oNode) formatEl = oNode.previousSibling;
|
|
135
|
+
if (!isInline && this.selection.getRange().collapsed && (r.container.nodeType === 3 || dom.check.isBreak(r.container))) {
|
|
136
|
+
const depthFormat = dom.query.getParentElement(r.container, this.format.isBlock.bind(this.format));
|
|
137
|
+
oNode = this.nodeTransform.split(r.container, r.offset, !depthFormat ? 0 : dom.query.getNodeDepth(depthFormat) + 1);
|
|
138
|
+
if (oNode) formatEl = /** @type {HTMLElement} */ (oNode.previousSibling);
|
|
77
139
|
}
|
|
78
|
-
this.html.insertNode(element, isInline ? null : this.format.isBlock(formatEl) ? null : formatEl, true);
|
|
79
|
-
if (!isInline && formatEl &&
|
|
140
|
+
this.html.insertNode(element, { afterNode: isInline ? null : this.format.isBlock(formatEl) ? null : formatEl, skipCharCount: true });
|
|
141
|
+
if (!isInline && formatEl && dom.check.isZeroWidth(formatEl)) dom.utils.removeItem(formatEl);
|
|
80
142
|
}
|
|
81
143
|
|
|
82
144
|
if (isInline) {
|
|
83
|
-
const empty =
|
|
145
|
+
const empty = dom.utils.createTextNode(unicode.zeroWidthSpace);
|
|
84
146
|
element.parentNode.insertBefore(empty, element.nextSibling);
|
|
85
147
|
}
|
|
86
148
|
|
|
87
|
-
this.history.push(false);
|
|
149
|
+
if (!skipHistory) this.history.push(false);
|
|
88
150
|
|
|
89
|
-
if (!
|
|
151
|
+
if (!skipSelection) {
|
|
90
152
|
this.selection.setRange(element, 0, element, 0);
|
|
91
153
|
const fileComponentInfo = this.get(element);
|
|
92
154
|
if (fileComponentInfo) {
|
|
93
155
|
this.select(fileComponentInfo.target, fileComponentInfo.pluginName);
|
|
94
156
|
} else if (oNode) {
|
|
95
|
-
oNode =
|
|
157
|
+
oNode = dom.query.getEdgeChildNodes(oNode, null).sc || oNode;
|
|
96
158
|
this.selection.setRange(oNode, 0, oNode, 0);
|
|
97
159
|
}
|
|
98
160
|
}
|
|
99
161
|
|
|
100
|
-
|
|
162
|
+
// document type
|
|
163
|
+
if (this.editor.frameContext.has('documentType-use-header')) {
|
|
164
|
+
this.editor.frameContext.get('documentType').reHeader();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return /** @type {HTMLElement} */ (oNode || element);
|
|
101
168
|
},
|
|
102
169
|
|
|
103
170
|
/**
|
|
171
|
+
* @this {ComponentThis}
|
|
104
172
|
* @description Gets the file component and that plugin name
|
|
105
|
-
* return: {target, component, pluginName} | null
|
|
106
|
-
* @param {
|
|
107
|
-
* @returns {
|
|
173
|
+
* - return: {target, component, pluginName} | null
|
|
174
|
+
* @param {Node} element Target element (figure tag, component div, file tag)
|
|
175
|
+
* @returns {ComponentInfo|null}
|
|
108
176
|
*/
|
|
109
177
|
get(element) {
|
|
110
178
|
if (!element) return null;
|
|
@@ -113,10 +181,11 @@ Component.prototype = {
|
|
|
113
181
|
let pluginName = '';
|
|
114
182
|
let options = {};
|
|
115
183
|
let isFile = false;
|
|
184
|
+
let launcher = null;
|
|
116
185
|
|
|
117
186
|
if (this.is(element)) {
|
|
118
|
-
if (
|
|
119
|
-
if (/^FIGURE$/i.test(element.nodeName)) element = element.firstElementChild;
|
|
187
|
+
if (dom.utils.hasClass(element, 'se-component') && !dom.utils.hasClass(element, 'se-inline-component')) element = /** @type {HTMLElement} */ (element).firstElementChild || element;
|
|
188
|
+
if (/^FIGURE$/i.test(element.nodeName)) element = /** @type {HTMLElement} */ (element).firstElementChild;
|
|
120
189
|
if (!element) return null;
|
|
121
190
|
|
|
122
191
|
const comp = this.editor._componentManager.map((f) => f(element)).find((e) => e);
|
|
@@ -124,6 +193,7 @@ Component.prototype = {
|
|
|
124
193
|
target = comp.target;
|
|
125
194
|
pluginName = comp.pluginName;
|
|
126
195
|
options = comp.options;
|
|
196
|
+
launcher = comp.launcher;
|
|
127
197
|
}
|
|
128
198
|
|
|
129
199
|
if (!target && element.nodeName) {
|
|
@@ -135,6 +205,7 @@ Component.prototype = {
|
|
|
135
205
|
target = comp.target;
|
|
136
206
|
pluginName = comp.pluginName;
|
|
137
207
|
options = comp.options;
|
|
208
|
+
launcher = comp.launcher;
|
|
138
209
|
}
|
|
139
210
|
|
|
140
211
|
if (!target) {
|
|
@@ -148,25 +219,31 @@ Component.prototype = {
|
|
|
148
219
|
options,
|
|
149
220
|
container: figureInfo.container || figureInfo.cover || target,
|
|
150
221
|
cover: figureInfo.cover,
|
|
222
|
+
inlineCover: figureInfo.inlineCover,
|
|
151
223
|
caption: figureInfo.caption,
|
|
152
|
-
isFile
|
|
224
|
+
isFile,
|
|
225
|
+
launcher
|
|
153
226
|
});
|
|
154
227
|
},
|
|
155
228
|
|
|
156
229
|
/**
|
|
157
|
-
* @
|
|
158
|
-
* @
|
|
159
|
-
* @param {
|
|
230
|
+
* @this {ComponentThis}
|
|
231
|
+
* @description The component(media, file component, table, etc) is selected and the resizing module is called.
|
|
232
|
+
* @param {Node} element Target element
|
|
233
|
+
* @param {string} pluginName The plugin name for the selected target.
|
|
234
|
+
* @param {boolean=} isInput Whether the target is an input component.(table)
|
|
160
235
|
*/
|
|
161
236
|
select(element, pluginName, isInput) {
|
|
162
237
|
const info = this.get(element);
|
|
163
|
-
if (!info ||
|
|
238
|
+
if (!info || dom.check.isUneditable(dom.query.getParentElement(element, this.is.bind(this))) || dom.check.isUneditable(element)) return false;
|
|
164
239
|
|
|
165
|
-
const plugin = this.plugins[pluginName];
|
|
240
|
+
const plugin = info.launcher || this.plugins[pluginName];
|
|
166
241
|
if (!plugin) return;
|
|
167
242
|
|
|
168
243
|
if (!isInput && _DragHandle.get('__overInfo') !== ON_OVER_COMPONENT) {
|
|
169
|
-
this.editor.
|
|
244
|
+
if (this.editor.status._onMousedown) return;
|
|
245
|
+
|
|
246
|
+
this.editor._preventBlur = true;
|
|
170
247
|
this.__selectionSelected = true;
|
|
171
248
|
if (this.isInline(info.container)) {
|
|
172
249
|
this.selection.setRange(info.container, 0, info.container, 0);
|
|
@@ -182,7 +259,8 @@ Component.prototype = {
|
|
|
182
259
|
let isNonFigureComponent;
|
|
183
260
|
if (typeof plugin.select === 'function') isNonFigureComponent = plugin.select(element);
|
|
184
261
|
|
|
185
|
-
|
|
262
|
+
const isBreakComponent = dom.utils.hasClass(info.target, 'se-component-line-break');
|
|
263
|
+
if (isBreakComponent || (!isNonFigureComponent && !dom.utils.hasClass(info.container, 'se-inline-component'))) this._setComponentLineBreaker(/** @type {HTMLElement} */ (info.container || info.cover || element));
|
|
186
264
|
|
|
187
265
|
this.currentTarget = element;
|
|
188
266
|
this.currentPlugin = plugin;
|
|
@@ -197,38 +275,40 @@ Component.prototype = {
|
|
|
197
275
|
if (__overInfo !== ON_OVER_COMPONENT) this.__addGlobalEvent();
|
|
198
276
|
if (!info.isFile) this.__addNotFileGlobalEvent();
|
|
199
277
|
}, 0);
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (__overInfo !== ON_OVER_COMPONENT) {
|
|
203
|
-
domUtils.setDisabled(this.editor._controllerOnDisabledButtons, true);
|
|
278
|
+
dom.utils.addClass(info.container, 'se-component-selected');
|
|
204
279
|
|
|
280
|
+
if (!isBreakComponent && __overInfo !== ON_OVER_COMPONENT) {
|
|
205
281
|
// set zero width space
|
|
206
282
|
if (!this.isInline(info.container)) return;
|
|
207
283
|
|
|
208
284
|
const oNode = info.container;
|
|
209
285
|
let zeroWidth = null;
|
|
210
|
-
if (!oNode.previousSibling ||
|
|
211
|
-
zeroWidth =
|
|
286
|
+
if (!oNode.previousSibling || dom.check.isBreak(oNode.previousSibling)) {
|
|
287
|
+
zeroWidth = dom.utils.createTextNode(unicode.zeroWidthSpace);
|
|
212
288
|
oNode.parentNode.insertBefore(zeroWidth, oNode);
|
|
213
289
|
}
|
|
214
290
|
|
|
215
|
-
if (!oNode.nextSibling ||
|
|
216
|
-
zeroWidth =
|
|
291
|
+
if (!oNode.nextSibling || dom.check.isBreak(oNode.nextSibling)) {
|
|
292
|
+
zeroWidth = dom.utils.createTextNode(unicode.zeroWidthSpace);
|
|
217
293
|
oNode.parentNode.insertBefore(zeroWidth, oNode.nextSibling);
|
|
218
294
|
}
|
|
219
|
-
|
|
295
|
+
|
|
296
|
+
this.editor.status.onSelected = true;
|
|
297
|
+
} else if (isBreakComponent || !dom.utils.hasClass(info.container, 'se-input-component')) {
|
|
220
298
|
const dragHandle = this.editor.frameContext.get('wrapper').querySelector('.se-drag-handle');
|
|
221
|
-
|
|
222
|
-
this.
|
|
299
|
+
dom.utils.addClass(dragHandle, 'se-drag-handle-full');
|
|
300
|
+
this.ui._visibleControllers(false, false);
|
|
223
301
|
|
|
224
302
|
const sizeTarget = info.caption ? info.target : info.cover || info.container || info.target;
|
|
225
|
-
const
|
|
303
|
+
const w = sizeTarget.offsetWidth;
|
|
304
|
+
const h = sizeTarget.offsetHeight;
|
|
305
|
+
const { top, left } = this.offset.getLocal(sizeTarget);
|
|
226
306
|
|
|
227
307
|
dragHandle.style.opacity = 0;
|
|
228
308
|
dragHandle.style.width = w + 'px';
|
|
229
309
|
dragHandle.style.height = h + 'px';
|
|
230
|
-
dragHandle.style.top =
|
|
231
|
-
dragHandle.style.left =
|
|
310
|
+
dragHandle.style.top = top - 1 + 'px';
|
|
311
|
+
dragHandle.style.left = left + 'px';
|
|
232
312
|
|
|
233
313
|
_DragHandle.set('__dragHandler', dragHandle);
|
|
234
314
|
_DragHandle.set('__dragContainer', info.container);
|
|
@@ -238,51 +318,40 @@ Component.prototype = {
|
|
|
238
318
|
}
|
|
239
319
|
},
|
|
240
320
|
|
|
321
|
+
/**
|
|
322
|
+
* @this {ComponentThis}
|
|
323
|
+
* @description Deselects the selected component.
|
|
324
|
+
*/
|
|
241
325
|
deselect() {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const { frameContext } = this.editor;
|
|
249
|
-
frameContext.get('lineBreaker_t').style.display = frameContext.get('lineBreaker_b').style.display = 'none';
|
|
250
|
-
|
|
251
|
-
if (this.currentPlugin && typeof this.currentPlugin.deselect === 'function') {
|
|
252
|
-
this.currentPlugin.deselect(this.currentTarget);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
this.isSelected = false;
|
|
256
|
-
this.currentPlugin = null;
|
|
257
|
-
this.currentTarget = null;
|
|
258
|
-
this.currentPluginName = '';
|
|
259
|
-
this.currentInfo = null;
|
|
260
|
-
this.__removeGlobalEvent();
|
|
261
|
-
this.editor.__offControllers();
|
|
262
|
-
|
|
263
|
-
domUtils.setDisabled(this.editor._controllerOnDisabledButtons, false);
|
|
326
|
+
_w.setTimeout(() => {
|
|
327
|
+
this.editor.status.onSelected = false;
|
|
328
|
+
}, 0);
|
|
329
|
+
this.__deselect();
|
|
330
|
+
this.ui.setControllerOnDisabledButtons(false);
|
|
264
331
|
},
|
|
265
332
|
|
|
266
333
|
/**
|
|
334
|
+
* @this {ComponentThis}
|
|
267
335
|
* @description Determines if the specified node is a block component (e.g., img, iframe, video, audio, table) with the class "se-component"
|
|
268
|
-
* or a direct FIGURE node. This function checks if the node itself is a component
|
|
269
|
-
* or if it belongs to any components identified by the component manager.
|
|
336
|
+
* - or a direct FIGURE node. This function checks if the node itself is a component
|
|
337
|
+
* - or if it belongs to any components identified by the component manager.
|
|
270
338
|
* @param {Node} element The DOM node to check.
|
|
271
339
|
* @returns {boolean} True if the node is a block component or part of it, otherwise false.
|
|
272
340
|
*/
|
|
273
341
|
is(element) {
|
|
274
342
|
if (!element) return false;
|
|
275
343
|
|
|
276
|
-
if (/^FIGURE$/i.test(element.nodeName) ||
|
|
344
|
+
if (/^FIGURE$/i.test(element.nodeName) || dom.utils.hasClass(element, 'se-component')) return true;
|
|
277
345
|
if (this.editor._componentManager.find((f) => f(element))) return true;
|
|
278
346
|
|
|
279
347
|
return false;
|
|
280
348
|
},
|
|
281
349
|
|
|
282
350
|
/**
|
|
351
|
+
* @this {ComponentThis}
|
|
283
352
|
* @description Checks if the given node is an inline component (class "se-inline-component").
|
|
284
|
-
* If the node is a FIGURE, it checks the parent element instead.
|
|
285
|
-
* It also verifies whether the node is part of an inline component recognized by the component manager.
|
|
353
|
+
* - If the node is a FIGURE, it checks the parent element instead.
|
|
354
|
+
* - It also verifies whether the node is part of an inline component recognized by the component manager.
|
|
286
355
|
* @param {Node} element The DOM node to check.
|
|
287
356
|
* @returns {boolean} True if the node is an inline component or part of it, otherwise false.
|
|
288
357
|
*/
|
|
@@ -290,18 +359,19 @@ Component.prototype = {
|
|
|
290
359
|
if (!element) return false;
|
|
291
360
|
|
|
292
361
|
if (/^FIGURE$/i.test(element.nodeName)) element = element.parentElement;
|
|
293
|
-
if (
|
|
362
|
+
if (dom.utils.hasClass(element, 'se-inline-component')) return true;
|
|
294
363
|
|
|
295
364
|
const container = this.editor._componentManager.find((f) => f(element));
|
|
296
|
-
if (container &&
|
|
365
|
+
if (container && dom.utils.hasClass(element, 'se-inline-component')) return true;
|
|
297
366
|
|
|
298
367
|
return false;
|
|
299
368
|
},
|
|
300
369
|
|
|
301
370
|
/**
|
|
371
|
+
* @this {ComponentThis}
|
|
302
372
|
* @description Checks if the specified node qualifies as a basic component within the editor.
|
|
303
|
-
* This function verifies whether the node is recognized as a component by the `is` function, while also ensuring that it is not an inline component as determined by the `isInline` function.
|
|
304
|
-
* This is used to identify block-level elements or standalone components that are not part of the inline component classification.
|
|
373
|
+
* - This function verifies whether the node is recognized as a component by the `is` function, while also ensuring that it is not an inline component as determined by the `isInline` function.
|
|
374
|
+
* - This is used to identify block-level elements or standalone components that are not part of the inline component classification.
|
|
305
375
|
* @param {Node} element The DOM node to check.
|
|
306
376
|
* @returns {boolean} True if the node is a basic (non-inline) component, otherwise false.
|
|
307
377
|
*/
|
|
@@ -309,46 +379,91 @@ Component.prototype = {
|
|
|
309
379
|
return this.is(element) && !this.isInline(element);
|
|
310
380
|
},
|
|
311
381
|
|
|
382
|
+
/**
|
|
383
|
+
* @private
|
|
384
|
+
* @this {ComponentThis}
|
|
385
|
+
* @description Checks if the given element is a file component by matching its tag name against the file manager's regular expressions.
|
|
386
|
+
* - It also verifies whether the element has the required attributes based on the tag type.
|
|
387
|
+
* @param {Node} element The element to check.
|
|
388
|
+
* @returns {boolean} Returns true if the element is a file component, otherwise false.
|
|
389
|
+
*/
|
|
312
390
|
__isFiles(element) {
|
|
313
391
|
const nodeName = element.nodeName.toLowerCase();
|
|
314
|
-
return this.editor._fileManager.regExp.test(nodeName) && (!this.editor._fileManager.tagAttrs[nodeName] || this.editor._fileManager.tagAttrs[nodeName]?.every((v) => element.hasAttribute(v)));
|
|
392
|
+
return this.editor._fileManager.regExp.test(nodeName) && (!this.editor._fileManager.tagAttrs[nodeName] || this.editor._fileManager.tagAttrs[nodeName]?.every((v) => /** @type {HTMLElement} */ (element).hasAttribute(v)));
|
|
393
|
+
},
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @private
|
|
397
|
+
* @this {ComponentThis}
|
|
398
|
+
* @description Deselects the currently selected component, removing any selection effects and associated event listeners.
|
|
399
|
+
* - This method resets the selection state and hides UI elements related to the component selection.
|
|
400
|
+
*/
|
|
401
|
+
__deselect() {
|
|
402
|
+
this.editor._preventBlur = false;
|
|
403
|
+
_DragHandle.set('__overInfo', null);
|
|
404
|
+
this._removeDragEvent();
|
|
405
|
+
dom.utils.removeClass(this.currentInfo?.container, 'se-component-selected|');
|
|
406
|
+
dom.utils.removeClass(this.currentInfo?.cover, 'se-figure-over-selected');
|
|
407
|
+
|
|
408
|
+
const { frameContext } = this.editor;
|
|
409
|
+
frameContext.get('lineBreaker_t').style.display = frameContext.get('lineBreaker_b').style.display = 'none';
|
|
410
|
+
|
|
411
|
+
if (this.currentPlugin && typeof this.currentPlugin.deselect === 'function') {
|
|
412
|
+
this.currentPlugin.deselect(this.currentTarget);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
this.isSelected = false;
|
|
416
|
+
this.currentPlugin = null;
|
|
417
|
+
this.currentTarget = null;
|
|
418
|
+
this.currentPluginName = '';
|
|
419
|
+
this.currentInfo = null;
|
|
420
|
+
this.__removeGlobalEvent();
|
|
421
|
+
this.ui.__offControllers();
|
|
315
422
|
},
|
|
316
423
|
|
|
317
424
|
/**
|
|
318
|
-
* @description Set line breaker of component
|
|
319
|
-
* @param {Element} element Element tag
|
|
320
425
|
* @private
|
|
426
|
+
* @this {ComponentThis}
|
|
427
|
+
* @description Set line breaker of component
|
|
428
|
+
* @param {HTMLElement} element Element tag
|
|
321
429
|
*/
|
|
322
430
|
_setComponentLineBreaker(element) {
|
|
431
|
+
const _overInfo = _DragHandle.get('__overInfo') === ON_OVER_COMPONENT;
|
|
323
432
|
this.eventManager._lineBreakComp = null;
|
|
324
433
|
const info = this.get(element);
|
|
325
434
|
if (!info) return;
|
|
326
435
|
|
|
327
436
|
const fc = this.editor.frameContext;
|
|
328
437
|
const container = info.container;
|
|
329
|
-
const isNonSelected =
|
|
438
|
+
const isNonSelected = dom.utils.hasClass(container, 'se-flex-component');
|
|
330
439
|
const lb_t = fc.get('lineBreaker_t');
|
|
331
440
|
const lb_b = fc.get('lineBreaker_b');
|
|
332
441
|
const t_style = lb_t.style;
|
|
333
442
|
const b_style = lb_b.style;
|
|
334
443
|
const offsetTarget = container.offsetWidth < element.offsetWidth ? container : element;
|
|
335
444
|
const target = this.editor._figureContainer?.style.display === 'block' ? this.editor._figureContainer : offsetTarget;
|
|
336
|
-
const isList =
|
|
445
|
+
const isList = dom.check.isListCell(container.parentNode);
|
|
337
446
|
|
|
338
447
|
// top
|
|
339
448
|
let componentTop, w;
|
|
340
449
|
const isRtl = this.options.get('_rtl');
|
|
341
450
|
const dir = isRtl ? ['right', 'left'] : ['left', 'right'];
|
|
342
|
-
const {
|
|
451
|
+
const { top, left, scrollX, scrollY } = this.offset.getLocal(offsetTarget);
|
|
452
|
+
|
|
343
453
|
if (isList ? !container.previousSibling : !this.format.isLine(container.previousElementSibling)) {
|
|
344
|
-
const
|
|
454
|
+
const tlComputedStyle = _w.getComputedStyle(lb_t);
|
|
455
|
+
const tH = numbers.get(tlComputedStyle.height, 1);
|
|
345
456
|
this.eventManager._lineBreakComp = container;
|
|
346
|
-
componentTop =
|
|
457
|
+
componentTop = top;
|
|
347
458
|
w = target.offsetWidth / 2 / 2;
|
|
348
459
|
t_style.top = componentTop - scrollY - tH / 2 + 'px';
|
|
349
|
-
t_style[dir[0]] = (isNonSelected ?
|
|
460
|
+
t_style[dir[0]] = (isNonSelected ? left - numbers.get(tlComputedStyle.height, 0) / 2 : left + w) + 'px';
|
|
350
461
|
t_style[dir[1]] = '';
|
|
462
|
+
|
|
351
463
|
lb_t.setAttribute('data-offset', scrollY + ',' + scrollX);
|
|
464
|
+
if (_overInfo) dom.utils.removeClass(lb_t, 'se-on-selected');
|
|
465
|
+
else dom.utils.addClass(lb_t, 'se-on-selected');
|
|
466
|
+
|
|
352
467
|
t_style.display = 'block';
|
|
353
468
|
} else {
|
|
354
469
|
t_style.display = 'none';
|
|
@@ -362,22 +477,30 @@ Component.prototype = {
|
|
|
362
477
|
|
|
363
478
|
if (!componentTop) {
|
|
364
479
|
this.eventManager._lineBreakComp = container;
|
|
365
|
-
componentTop =
|
|
480
|
+
componentTop = top;
|
|
366
481
|
w = target.offsetWidth / 2 / 2;
|
|
367
482
|
}
|
|
368
483
|
|
|
369
484
|
b_style.top = componentTop + target.offsetHeight - scrollY - bH / 2 + 'px';
|
|
370
485
|
b_style.right = '';
|
|
371
|
-
b_style.left =
|
|
486
|
+
b_style.left = left + (isRtl ? 0 : target.offsetWidth) - (isNonSelected ? 0 : w) - (isNonSelected ? bW / 2 : bW) + 'px';
|
|
372
487
|
|
|
373
488
|
const bDir = 'left';
|
|
374
489
|
lb_b.setAttribute('data-offset', scrollY + ',' + bDir + ',' + scrollX);
|
|
490
|
+
if (_overInfo) dom.utils.removeClass(lb_b, 'se-on-selected');
|
|
491
|
+
else dom.utils.addClass(lb_b, 'se-on-selected');
|
|
492
|
+
|
|
375
493
|
b_style.display = 'block';
|
|
376
494
|
} else {
|
|
377
495
|
b_style.display = 'none';
|
|
378
496
|
}
|
|
379
497
|
},
|
|
380
498
|
|
|
499
|
+
/**
|
|
500
|
+
* @private
|
|
501
|
+
* @this {ComponentThis}
|
|
502
|
+
* @description Adds global event listeners for component interactions such as copy, cut, and keydown events.
|
|
503
|
+
*/
|
|
381
504
|
__addGlobalEvent() {
|
|
382
505
|
this.__removeGlobalEvent();
|
|
383
506
|
this._bindClose_copy = this.eventManager.addGlobalEvent('copy', this.__globalEvents.copy);
|
|
@@ -385,6 +508,11 @@ Component.prototype = {
|
|
|
385
508
|
this._bindClose_keydown = this.eventManager.addGlobalEvent('keydown', this.__globalEvents.keydown);
|
|
386
509
|
},
|
|
387
510
|
|
|
511
|
+
/**
|
|
512
|
+
* @private
|
|
513
|
+
* @this {ComponentThis}
|
|
514
|
+
* @description Removes global event listeners that were previously added for component interactions.
|
|
515
|
+
*/
|
|
388
516
|
__removeGlobalEvent() {
|
|
389
517
|
this.__removeNotFileGlobalEvent();
|
|
390
518
|
if (this._bindClose_copy) this._bindClose_copy = this.eventManager.removeGlobalEvent(this._bindClose_copy);
|
|
@@ -392,23 +520,38 @@ Component.prototype = {
|
|
|
392
520
|
if (this._bindClose_keydown) this._bindClose_keydown = this.eventManager.removeGlobalEvent(this._bindClose_keydown);
|
|
393
521
|
},
|
|
394
522
|
|
|
523
|
+
/**
|
|
524
|
+
* @private
|
|
525
|
+
* @this {ComponentThis}
|
|
526
|
+
* @description Adds global event listeners for non-file-related interactions such as mouse and touch events.
|
|
527
|
+
*/
|
|
395
528
|
__addNotFileGlobalEvent() {
|
|
396
529
|
this.__removeNotFileGlobalEvent();
|
|
397
|
-
this._bindClose_mousedown = this.eventManager.addGlobalEvent('mousedown', this.__globalEvents.mousedown, true);
|
|
398
|
-
this._bindClose_touchstart = this.eventManager.addGlobalEvent('touchstart', this.__globalEvents.mousedown, true);
|
|
530
|
+
if (!isMobile) this._bindClose_mousedown = this.eventManager.addGlobalEvent('mousedown', this.__globalEvents.mousedown, true);
|
|
531
|
+
else this._bindClose_touchstart = this.eventManager.addGlobalEvent('touchstart', this.__globalEvents.mousedown, true);
|
|
399
532
|
},
|
|
400
533
|
|
|
534
|
+
/**
|
|
535
|
+
* @private
|
|
536
|
+
* @this {ComponentThis}
|
|
537
|
+
* @description Removes global event listeners related to non-file interactions.
|
|
538
|
+
*/
|
|
401
539
|
__removeNotFileGlobalEvent() {
|
|
402
540
|
if (this._bindClose_mousedown) this._bindClose_mousedown = this.eventManager.removeGlobalEvent(this._bindClose_mousedown);
|
|
403
541
|
if (this._bindClose_touchstart) this._bindClose_touchstart = this.eventManager.removeGlobalEvent(this._bindClose_touchstart);
|
|
404
542
|
},
|
|
405
543
|
|
|
544
|
+
/**
|
|
545
|
+
* @private
|
|
546
|
+
* @this {ComponentThis}
|
|
547
|
+
* @description Removes drag-related events and resets drag-related states.
|
|
548
|
+
*/
|
|
406
549
|
_removeDragEvent() {
|
|
407
|
-
this.carrierWrapper.querySelector('.se-drag-cursor').style.left = '-10000px';
|
|
550
|
+
/** @type {HTMLElement} */ (this.carrierWrapper.querySelector('.se-drag-cursor')).style.left = '-10000px';
|
|
408
551
|
if (_DragHandle.get('__dragHandler')) _DragHandle.get('__dragHandler').style.display = 'none';
|
|
409
552
|
|
|
410
|
-
|
|
411
|
-
|
|
553
|
+
dom.utils.removeClass([_DragHandle.get('__dragHandler'), _DragHandle.get('__dragContainer')], 'se-dragging');
|
|
554
|
+
dom.utils.removeClass([_DragHandle.get('__dragCover'), _DragHandle.get('__dragContainer')], 'se-drag-over');
|
|
412
555
|
|
|
413
556
|
_DragHandle.set('__figureInst', null);
|
|
414
557
|
_DragHandle.set('__dragInst', null);
|
|
@@ -422,18 +565,28 @@ Component.prototype = {
|
|
|
422
565
|
constructor: Component
|
|
423
566
|
};
|
|
424
567
|
|
|
568
|
+
/**
|
|
569
|
+
* @this {ComponentThis}
|
|
570
|
+
*/
|
|
425
571
|
function OnDragEnter() {
|
|
426
|
-
this.editor.
|
|
427
|
-
this.
|
|
428
|
-
|
|
572
|
+
this.editor._preventBlur = true;
|
|
573
|
+
this.ui._visibleControllers(false, dom.utils.hasClass(_DragHandle.get('__dragHandler'), 'se-drag-handle-full'));
|
|
574
|
+
dom.utils.addClass(_DragHandle.get('__dragCover') || _DragHandle.get('__dragContainer'), 'se-drag-over');
|
|
429
575
|
}
|
|
430
576
|
|
|
577
|
+
/**
|
|
578
|
+
* @this {ComponentThis}
|
|
579
|
+
*/
|
|
431
580
|
function OnDragLeave() {
|
|
432
|
-
this.editor.
|
|
433
|
-
if (!
|
|
434
|
-
|
|
581
|
+
this.editor._preventBlur = false;
|
|
582
|
+
if (!dom.utils.hasClass(_DragHandle.get('__dragHandler'), 'se-drag-handle-full')) this.ui._visibleControllers(true, true);
|
|
583
|
+
dom.utils.removeClass([_DragHandle.get('__dragCover'), _DragHandle.get('__dragContainer')], 'se-drag-over');
|
|
435
584
|
}
|
|
436
585
|
|
|
586
|
+
/**
|
|
587
|
+
* @this {ComponentThis}
|
|
588
|
+
* @param {DragEvent} e - Drag event
|
|
589
|
+
*/
|
|
437
590
|
function OnDragStart(e) {
|
|
438
591
|
const cover = _DragHandle.get('__dragCover') || _DragHandle.get('__dragContainer');
|
|
439
592
|
|
|
@@ -442,29 +595,44 @@ function OnDragStart(e) {
|
|
|
442
595
|
return;
|
|
443
596
|
}
|
|
444
597
|
|
|
445
|
-
this.editor.
|
|
446
|
-
|
|
447
|
-
|
|
598
|
+
this.editor._preventBlur = false;
|
|
599
|
+
dom.utils.addClass(_DragHandle.get('__dragHandler'), 'se-dragging');
|
|
600
|
+
dom.utils.addClass(_DragHandle.get('__dragContainer'), 'se-dragging');
|
|
448
601
|
e.dataTransfer.setDragImage(cover, this.options.get('_rtl') ? cover.offsetWidth : -5, -5);
|
|
449
602
|
}
|
|
450
603
|
|
|
604
|
+
/**
|
|
605
|
+
* @this {ComponentThis}
|
|
606
|
+
*/
|
|
451
607
|
function OnDragEnd() {
|
|
452
|
-
this.editor.
|
|
453
|
-
|
|
608
|
+
this.editor._preventBlur = false;
|
|
609
|
+
dom.utils.removeClass([_DragHandle.get('__dragHandler'), _DragHandle.get('__dragContainer')], 'se-dragging');
|
|
454
610
|
this._removeDragEvent();
|
|
455
611
|
}
|
|
456
612
|
|
|
457
|
-
|
|
458
|
-
|
|
613
|
+
/**
|
|
614
|
+
* @this {ComponentThis}
|
|
615
|
+
* @param {MouseEvent} e - Mouse event
|
|
616
|
+
*/
|
|
617
|
+
function OnDragClick(e) {
|
|
618
|
+
const target = dom.query.getEventTarget(e);
|
|
619
|
+
if (!dom.utils.hasClass(target, 'se-drag-handle-full')) return;
|
|
620
|
+
|
|
459
621
|
const dragInst = _DragHandle.get('__dragInst');
|
|
622
|
+
this._removeDragEvent();
|
|
460
623
|
this.select(dragInst.currentTarget, dragInst.currentPluginName, false);
|
|
461
624
|
}
|
|
462
625
|
|
|
463
|
-
|
|
626
|
+
/**
|
|
627
|
+
* @this {ComponentThis}
|
|
628
|
+
* @param {MouseEvent} e - Mouse event
|
|
629
|
+
*/
|
|
630
|
+
function CloseListener_mousedown(e) {
|
|
631
|
+
const target = dom.query.getEventTarget(e);
|
|
464
632
|
if (
|
|
465
633
|
this.currentTarget?.contains(target) ||
|
|
466
|
-
|
|
467
|
-
|
|
634
|
+
dom.query.getParentElement(target, '.se-controller') ||
|
|
635
|
+
dom.utils.hasClass(target, 'se-drag-handle') ||
|
|
468
636
|
(this.currentPluginName === this.editor.currentControllerName && this.editor.opendControllers.some(({ form }) => form.contains(target)))
|
|
469
637
|
) {
|
|
470
638
|
return;
|
|
@@ -472,39 +640,52 @@ function CloseListener_mousedown({ target }) {
|
|
|
472
640
|
this.deselect();
|
|
473
641
|
}
|
|
474
642
|
|
|
643
|
+
/**
|
|
644
|
+
* @this {ComponentThis}
|
|
645
|
+
* @param {ClipboardEvent} e - Event object
|
|
646
|
+
*/
|
|
475
647
|
function OnCopy_component(e) {
|
|
476
|
-
|
|
648
|
+
const target = dom.query.getEventTarget(e);
|
|
649
|
+
if (dom.check.isInputElement(target) && dom.query.getParentElement(target, '.se-modal')) return;
|
|
477
650
|
|
|
478
651
|
const info = this.info;
|
|
479
652
|
if (!info) return;
|
|
480
653
|
|
|
481
654
|
SetClipboardComponent(e, info.container, e.clipboardData);
|
|
482
|
-
|
|
655
|
+
dom.utils.addClass(info.container, 'se-copy');
|
|
483
656
|
// copy effect
|
|
484
657
|
_w.setTimeout(() => {
|
|
485
|
-
|
|
658
|
+
dom.utils.removeClass(info.container, 'se-copy');
|
|
486
659
|
}, 120);
|
|
487
660
|
}
|
|
488
661
|
|
|
662
|
+
/**
|
|
663
|
+
* @this {ComponentThis}
|
|
664
|
+
* @param {ClipboardEvent} e - Event object
|
|
665
|
+
*/
|
|
489
666
|
function OnCut_component(e) {
|
|
490
667
|
const info = this.info;
|
|
491
668
|
if (!info) return;
|
|
492
669
|
|
|
493
670
|
SetClipboardComponent(e, info.container, e.clipboardData);
|
|
494
671
|
this.deselect();
|
|
495
|
-
|
|
672
|
+
dom.utils.removeItem(info.container);
|
|
496
673
|
}
|
|
497
674
|
|
|
498
|
-
|
|
675
|
+
/**
|
|
676
|
+
* @this {ComponentThis}
|
|
677
|
+
* @param {KeyboardEvent} e - Event object
|
|
678
|
+
*/
|
|
679
|
+
async function OnKeyDown_component(e) {
|
|
499
680
|
if (this.editor.selectMenuOn) return;
|
|
500
681
|
|
|
501
|
-
const keyCode = e.
|
|
502
|
-
const ctrl =
|
|
682
|
+
const keyCode = e.code;
|
|
683
|
+
const ctrl = keyCodeMap.isCtrl(e);
|
|
503
684
|
|
|
504
685
|
// redo, undo
|
|
505
686
|
if (ctrl) {
|
|
506
|
-
if (keyCode !==
|
|
507
|
-
const info = this.editor.shortcutsKeyMap.get(keyCode + (e.shiftKey ? 1000 :
|
|
687
|
+
if (keyCode !== 'ControlRight' && keyCode !== 'ControlLeft') {
|
|
688
|
+
const info = this.editor.shortcutsKeyMap.get(keyCode + (e.shiftKey ? '1000' : ''));
|
|
508
689
|
if (/^(redo|undo)$/.test(info?.c)) {
|
|
509
690
|
e.preventDefault();
|
|
510
691
|
e.stopPropagation();
|
|
@@ -514,29 +695,29 @@ function OnKeyDown_component(e) {
|
|
|
514
695
|
return;
|
|
515
696
|
}
|
|
516
697
|
|
|
517
|
-
// backspace, delete
|
|
518
|
-
if (keyCode
|
|
698
|
+
// backspace key, delete key
|
|
699
|
+
if (keyCodeMap.isRemoveKey(keyCode)) {
|
|
519
700
|
e.preventDefault();
|
|
520
701
|
e.stopPropagation();
|
|
521
702
|
if (typeof this.currentPlugin?.destroy === 'function') {
|
|
522
|
-
this.currentPlugin.destroy(this.currentTarget);
|
|
703
|
+
await this.currentPlugin.destroy(this.currentTarget);
|
|
523
704
|
this.deselect();
|
|
524
705
|
this.editor.focus();
|
|
525
706
|
return;
|
|
526
707
|
}
|
|
527
708
|
}
|
|
528
709
|
|
|
529
|
-
// enter
|
|
530
|
-
if (keyCode
|
|
710
|
+
// enter key
|
|
711
|
+
if (keyCodeMap.isEnter(keyCode)) {
|
|
531
712
|
e.preventDefault();
|
|
532
713
|
const compContext = this.currentInfo || this.get(this.currentTarget);
|
|
533
714
|
const container = compContext.container || compContext.target;
|
|
534
715
|
const sibling = container.previousElementSibling || container.nextElementSibling;
|
|
535
716
|
let newEl = null;
|
|
536
|
-
if (
|
|
537
|
-
newEl =
|
|
717
|
+
if (dom.check.isListCell(container.parentNode)) {
|
|
718
|
+
newEl = dom.utils.createElement('BR');
|
|
538
719
|
} else {
|
|
539
|
-
newEl =
|
|
720
|
+
newEl = dom.utils.createElement(this.format.isLine(sibling) ? sibling.nodeName : this.options.get('defaultLine'), null, '<br>');
|
|
540
721
|
}
|
|
541
722
|
|
|
542
723
|
const pluginName = this.currentPluginName;
|
|
@@ -557,21 +738,22 @@ function OnKeyDown_component(e) {
|
|
|
557
738
|
let offset = 1;
|
|
558
739
|
if (isInline) {
|
|
559
740
|
switch (keyCode) {
|
|
560
|
-
case
|
|
741
|
+
case 'ArrowLeft': // left
|
|
561
742
|
el = container.previousSibling;
|
|
562
743
|
offset = el?.nodeType === 3 ? el.textContent.length : 1;
|
|
563
744
|
break;
|
|
564
|
-
case
|
|
745
|
+
case 'ArrowRight': // right
|
|
565
746
|
el = container.nextSibling;
|
|
747
|
+
offset = 0;
|
|
566
748
|
break;
|
|
567
|
-
case
|
|
749
|
+
case 'ArrowUp': {
|
|
568
750
|
// up
|
|
569
751
|
const line = this.format.getLine(container, null);
|
|
570
752
|
el = line?.previousElementSibling;
|
|
571
753
|
offset = 0;
|
|
572
754
|
break;
|
|
573
755
|
}
|
|
574
|
-
case
|
|
756
|
+
case 'ArrowDown': {
|
|
575
757
|
// down
|
|
576
758
|
const line = this.format.getLine(container, null);
|
|
577
759
|
el = line?.nextElementSibling;
|
|
@@ -597,16 +779,21 @@ function OnKeyDown_component(e) {
|
|
|
597
779
|
e.preventDefault();
|
|
598
780
|
this.select(elComp.target, elComp.pluginName);
|
|
599
781
|
} else {
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
782
|
+
try {
|
|
783
|
+
this.editor._preventBlur = true;
|
|
784
|
+
e.stopPropagation();
|
|
785
|
+
e.preventDefault();
|
|
786
|
+
this.selection.setRange(el, offset, el, offset);
|
|
787
|
+
} finally {
|
|
788
|
+
this.editor._preventBlur = false;
|
|
789
|
+
}
|
|
603
790
|
}
|
|
604
791
|
|
|
605
792
|
return;
|
|
606
793
|
}
|
|
607
794
|
|
|
608
795
|
// ESC
|
|
609
|
-
if (keyCode
|
|
796
|
+
if (keyCodeMap.isEsc(keyCode)) {
|
|
610
797
|
this.deselect();
|
|
611
798
|
return;
|
|
612
799
|
}
|
|
@@ -616,8 +803,8 @@ function SetClipboardComponent(e, container, clipboardData) {
|
|
|
616
803
|
e.preventDefault();
|
|
617
804
|
e.stopPropagation();
|
|
618
805
|
const pasteContainer = container.cloneNode(true);
|
|
619
|
-
|
|
620
|
-
pasteContainer.querySelectorAll('.se-figure-selected').forEach((el) =>
|
|
806
|
+
dom.utils.removeClass(pasteContainer, 'se-component-selected');
|
|
807
|
+
pasteContainer.querySelectorAll('.se-figure-selected').forEach((el) => dom.utils.removeClass(el, 'se-figure-selected'));
|
|
621
808
|
clipboardData.setData('text/html', pasteContainer.outerHTML);
|
|
622
809
|
}
|
|
623
810
|
|