suneditor 3.0.0-alpha.9 → 3.0.0-beta.2
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/CONTRIBUTING.md +170 -22
- package/{LICENSE.txt → LICENSE} +9 -9
- package/README.md +168 -30
- package/dist/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +47 -21
- package/src/assets/design/color.css +121 -0
- package/src/assets/design/index.css +3 -0
- package/src/assets/design/size.css +35 -0
- package/src/assets/design/typography.css +37 -0
- package/src/assets/icons/defaultIcons.js +232 -0
- package/src/assets/suneditor-contents.css +181 -46
- package/src/assets/suneditor.css +1403 -650
- package/src/core/base/eventHandlers/handler_toolbar.js +35 -14
- package/src/core/base/eventHandlers/handler_ww_clipboard.js +23 -4
- package/src/core/base/eventHandlers/handler_ww_dragDrop.js +49 -10
- package/src/core/base/eventHandlers/handler_ww_key_input.js +422 -224
- package/src/core/base/eventHandlers/handler_ww_mouse.js +83 -36
- package/src/core/base/eventManager.js +520 -179
- package/src/core/base/history.js +95 -41
- package/src/core/class/char.js +26 -11
- package/src/core/class/component.js +345 -137
- package/src/core/class/format.js +683 -519
- package/src/core/class/html.js +485 -305
- package/src/core/class/menu.js +133 -47
- package/src/core/class/nodeTransform.js +90 -71
- package/src/core/class/offset.js +408 -92
- package/src/core/class/selection.js +216 -106
- package/src/core/class/shortcuts.js +68 -8
- package/src/core/class/toolbar.js +106 -116
- package/src/core/class/ui.js +422 -0
- package/src/core/class/viewer.js +178 -74
- package/src/core/editor.js +496 -389
- package/src/core/section/actives.js +123 -27
- package/src/core/section/constructor.js +615 -206
- 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/events.js +622 -0
- package/src/helper/clipboard.js +59 -0
- package/src/helper/converter.js +202 -26
- package/src/helper/dom/domCheck.js +304 -0
- package/src/helper/dom/domQuery.js +669 -0
- package/src/helper/dom/domUtils.js +557 -0
- package/src/helper/dom/index.js +12 -0
- package/src/helper/env.js +46 -56
- package/src/helper/index.js +10 -4
- package/src/helper/keyCodeMap.js +183 -0
- package/src/helper/numbers.js +12 -8
- package/src/helper/unicode.js +9 -5
- package/src/langs/ckb.js +74 -4
- package/src/langs/cs.js +72 -2
- package/src/langs/da.js +73 -3
- package/src/langs/de.js +73 -4
- package/src/langs/en.js +23 -3
- package/src/langs/es.js +73 -4
- package/src/langs/fa.js +75 -3
- package/src/langs/fr.js +73 -3
- package/src/langs/he.js +73 -4
- package/src/langs/hu.js +230 -0
- package/src/langs/index.js +7 -3
- package/src/langs/it.js +70 -1
- package/src/langs/ja.js +72 -4
- package/src/langs/km.js +230 -0
- package/src/langs/ko.js +22 -2
- package/src/langs/lv.js +74 -5
- package/src/langs/nl.js +73 -4
- package/src/langs/pl.js +73 -4
- package/src/langs/pt_br.js +70 -1
- package/src/langs/ro.js +74 -5
- package/src/langs/ru.js +73 -4
- package/src/langs/se.js +73 -4
- package/src/langs/tr.js +73 -1
- package/src/langs/{ua.js → uk.js} +75 -6
- package/src/langs/ur.js +77 -8
- package/src/langs/zh_cn.js +74 -5
- 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 +273 -142
- package/src/modules/Figure.js +925 -484
- package/src/modules/FileManager.js +121 -69
- package/src/modules/HueSlider.js +113 -61
- package/src/modules/Modal.js +291 -122
- package/src/modules/ModalAnchorEditor.js +383 -234
- 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 +229 -162
- package/src/plugins/command/list_bulleted.js +83 -47
- package/src/plugins/command/list_numbered.js +83 -47
- package/src/plugins/dropdown/align.js +66 -54
- package/src/plugins/dropdown/backgroundColor.js +63 -49
- package/src/plugins/dropdown/font.js +71 -47
- package/src/plugins/dropdown/fontColor.js +63 -48
- package/src/plugins/dropdown/formatBlock.js +70 -33
- package/src/plugins/dropdown/hr.js +92 -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 +2003 -813
- package/src/plugins/dropdown/template.js +38 -26
- package/src/plugins/dropdown/textStyle.js +43 -31
- package/src/plugins/field/mention.js +147 -86
- 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 +358 -173
- package/src/plugins/modal/drawing.js +531 -0
- package/src/plugins/modal/embed.js +886 -0
- package/src/plugins/modal/image.js +674 -362
- package/src/plugins/modal/link.js +100 -71
- package/src/plugins/modal/math.js +367 -167
- package/src/plugins/modal/video.js +691 -335
- package/src/plugins/popup/anchor.js +222 -0
- package/src/suneditor.js +50 -13
- package/src/themes/dark.css +122 -0
- package/src/typedef.js +130 -0
- package/types/assets/icons/defaultIcons.d.ts +153 -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 +385 -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 +212 -0
- package/types/core/class/format.d.ts +616 -0
- package/types/core/class/html.d.ts +422 -0
- package/types/core/class/menu.d.ts +126 -0
- package/types/core/class/nodeTransform.d.ts +93 -0
- package/types/core/class/offset.d.ts +522 -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 +164 -0
- package/types/core/class/viewer.d.ts +140 -0
- package/types/core/editor.d.ts +610 -0
- package/types/core/section/actives.d.ts +46 -0
- package/types/core/section/constructor.d.ts +777 -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/events.d.ts +273 -0
- package/types/helper/clipboard.d.ts +12 -0
- package/types/helper/converter.d.ts +197 -0
- package/types/helper/dom/domCheck.d.ts +189 -0
- package/types/helper/dom/domQuery.d.ts +223 -0
- package/types/helper/dom/domUtils.d.ts +226 -0
- package/types/helper/dom/index.d.ts +9 -0
- package/types/helper/env.d.ts +132 -0
- package/types/helper/index.d.ts +174 -0
- package/types/helper/keyCodeMap.d.ts +110 -0
- package/types/helper/numbers.d.ts +46 -0
- package/types/helper/unicode.d.ts +28 -0
- package/types/index.d.ts +120 -0
- package/{typings/Lang.d.ts → types/langs/_Lang.d.ts} +173 -103
- package/types/langs/ckb.d.ts +3 -0
- package/types/langs/cs.d.ts +3 -0
- package/types/langs/da.d.ts +3 -0
- package/types/langs/de.d.ts +3 -0
- package/types/langs/en.d.ts +3 -0
- package/types/langs/es.d.ts +3 -0
- package/types/langs/fa.d.ts +3 -0
- package/types/langs/fr.d.ts +3 -0
- package/types/langs/he.d.ts +3 -0
- package/types/langs/hu.d.ts +3 -0
- package/types/langs/index.d.ts +54 -0
- package/types/langs/it.d.ts +3 -0
- package/types/langs/ja.d.ts +3 -0
- package/types/langs/km.d.ts +3 -0
- package/types/langs/ko.d.ts +3 -0
- package/types/langs/lv.d.ts +3 -0
- package/types/langs/nl.d.ts +3 -0
- package/types/langs/pl.d.ts +3 -0
- package/types/langs/pt_br.d.ts +3 -0
- package/types/langs/ro.d.ts +3 -0
- package/types/langs/ru.d.ts +3 -0
- package/types/langs/se.d.ts +3 -0
- package/types/langs/tr.d.ts +3 -0
- package/types/langs/uk.d.ts +3 -0
- package/types/langs/ur.d.ts +3 -0
- package/types/langs/zh_cn.d.ts +3 -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 +251 -0
- package/types/modules/Figure.d.ts +517 -0
- package/types/modules/FileManager.d.ts +202 -0
- package/types/modules/HueSlider.d.ts +136 -0
- package/types/modules/Modal.d.ts +111 -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 +46 -0
- package/types/plugins/command/list_numbered.d.ts +46 -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 +54 -0
- package/types/plugins/dropdown/hr.d.ts +71 -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 +627 -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.d.ts +233 -0
- package/.eslintignore +0 -7
- package/.eslintrc.json +0 -64
- package/src/assets/icons/_default.js +0 -194
- package/src/core/base/events.js +0 -320
- 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/editor.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { env, converter,
|
|
2
|
-
import Constructor, { InitOptions, UpdateButton, CreateShortcuts, CreateStatusbar,
|
|
1
|
+
import { env, converter, dom, numbers } from '../helper';
|
|
2
|
+
import Constructor, { InitOptions, UpdateButton, CreateShortcuts, CreateStatusbar, OPTION_FIXED_FLAG } from './section/constructor';
|
|
3
3
|
import { UpdateStatusbarContext } from './section/context';
|
|
4
|
-
import { BASIC_COMMANDS, ACTIVE_EVENT_COMMANDS, SELECT_ALL, DIR_BTN_ACTIVE, SAVE, COPY_FORMAT, FONT_STYLE } from './section/actives';
|
|
4
|
+
import { BASIC_COMMANDS, ACTIVE_EVENT_COMMANDS, SELECT_ALL, DIR_BTN_ACTIVE, SAVE, COPY_FORMAT, FONT_STYLE, PAGE_BREAK } from './section/actives';
|
|
5
5
|
import History from './base/history';
|
|
6
6
|
import EventManager from './base/eventManager';
|
|
7
|
-
import Events from '
|
|
7
|
+
import Events from '../events';
|
|
8
|
+
import DocumentType from './section/documentType';
|
|
8
9
|
|
|
9
10
|
// class injector
|
|
10
11
|
import ClassInjector from '../editorInjector/_classes';
|
|
@@ -16,11 +17,11 @@ import Format from './class/format';
|
|
|
16
17
|
import HTML from './class/html';
|
|
17
18
|
import Menu from './class/menu';
|
|
18
19
|
import NodeTransform from './class/nodeTransform';
|
|
19
|
-
import Notice from './class/notice';
|
|
20
20
|
import Offset from './class/offset';
|
|
21
|
-
import
|
|
21
|
+
import Selection_ from './class/selection';
|
|
22
22
|
import Shortcuts from './class/shortcuts';
|
|
23
23
|
import Toolbar from './class/toolbar';
|
|
24
|
+
import UI from './class/ui';
|
|
24
25
|
import Viewer from './class/viewer';
|
|
25
26
|
|
|
26
27
|
const COMMAND_BUTTONS = '.se-menu-list .se-toolbar-btn[data-command]';
|
|
@@ -28,24 +29,57 @@ const DISABLE_BUTTONS_CODEVIEW = `${COMMAND_BUTTONS}:not([class~="se-code-view-e
|
|
|
28
29
|
const DISABLE_BUTTONS_CONTROLLER = `${COMMAND_BUTTONS}:not([class~="se-component-enabled"]):not([data-type="MORE"])`;
|
|
29
30
|
|
|
30
31
|
/**
|
|
32
|
+
* @typedef {import('./section/constructor').EditorInitOptions} EditorInitOptions_editor
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @typedef {import('./section/constructor').EditorFrameOptions} EditorFrameOptions_editor
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @typedef {import('../modules/Controller').ControllerInfo} ControllerInfo_editor
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @constructor
|
|
31
45
|
* @description SunEditor constructor function.
|
|
32
|
-
* @param {Array
|
|
33
|
-
* @param {
|
|
34
|
-
* @returns {Object}
|
|
46
|
+
* @param {Array<{target: Element, key: *, options: EditorFrameOptions_editor}>} multiTargets Target element
|
|
47
|
+
* @param {EditorInitOptions_editor} options options
|
|
35
48
|
*/
|
|
36
|
-
|
|
49
|
+
function Editor(multiTargets, options) {
|
|
37
50
|
const _d = multiTargets[0].target.ownerDocument || env._d;
|
|
38
51
|
const _w = _d.defaultView || env._w;
|
|
39
52
|
const product = Constructor(multiTargets, options);
|
|
40
53
|
|
|
41
|
-
|
|
54
|
+
/**
|
|
55
|
+
* @description Frame root key array
|
|
56
|
+
* @type {Array<*>}
|
|
57
|
+
*/
|
|
42
58
|
this.rootKeys = product.rootKeys;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @description Frame root map
|
|
62
|
+
* @type {Map<*, __se__FrameContext>}
|
|
63
|
+
*/
|
|
43
64
|
this.frameRoots = product.frameRoots;
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @description Editor context object
|
|
68
|
+
* @type {__se__Context}
|
|
69
|
+
*/
|
|
44
70
|
this.context = product.context;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @description Current focusing frame context
|
|
74
|
+
* @type {__se__FrameContext}
|
|
75
|
+
*/
|
|
45
76
|
this.frameContext = new Map();
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @description Current focusing frame context options
|
|
80
|
+
* @type {__se__FrameOptions}
|
|
81
|
+
*/
|
|
46
82
|
this.frameOptions = new Map();
|
|
47
|
-
this._lineBreaker_t = null;
|
|
48
|
-
this._lineBreaker_b = null;
|
|
49
83
|
|
|
50
84
|
/**
|
|
51
85
|
* @description Document object
|
|
@@ -61,55 +95,49 @@ const Editor = function (multiTargets, options) {
|
|
|
61
95
|
|
|
62
96
|
/**
|
|
63
97
|
* @description Controllers carrier
|
|
98
|
+
* @type {HTMLElement}
|
|
64
99
|
*/
|
|
65
100
|
this.carrierWrapper = product.carrierWrapper;
|
|
66
101
|
|
|
67
102
|
/**
|
|
68
103
|
* @description Editor options
|
|
69
|
-
* @type {
|
|
104
|
+
* @type {Map<string, *>}
|
|
70
105
|
*/
|
|
71
106
|
this.options = product.options;
|
|
72
107
|
|
|
73
108
|
/**
|
|
74
109
|
* @description Plugins
|
|
75
|
-
* @type {Object
|
|
110
|
+
* @type {Object<string, *>}
|
|
76
111
|
*/
|
|
77
112
|
this.plugins = product.plugins || {};
|
|
78
113
|
|
|
79
114
|
/**
|
|
80
115
|
* @description Events object, call by triggerEvent function
|
|
81
|
-
* @type {Object
|
|
116
|
+
* @type {Object<string, *>}
|
|
82
117
|
*/
|
|
83
118
|
this.events = null;
|
|
84
119
|
|
|
85
120
|
/**
|
|
86
121
|
* @description Call the event function by injecting self: this.
|
|
87
|
-
* @type {
|
|
122
|
+
* @type {(eventName: string, ...args: *) => Promise<*>}
|
|
88
123
|
*/
|
|
89
124
|
this.triggerEvent = null;
|
|
90
125
|
|
|
91
126
|
/**
|
|
92
127
|
* @description Default icons object
|
|
93
|
-
* @type {Object
|
|
128
|
+
* @type {Object<string, string>}
|
|
94
129
|
*/
|
|
95
130
|
this.icons = product.icons;
|
|
96
131
|
|
|
97
132
|
/**
|
|
98
133
|
* @description loaded language
|
|
99
|
-
* @type {Object
|
|
134
|
+
* @type {Object<string, *>}
|
|
100
135
|
*/
|
|
101
136
|
this.lang = product.lang;
|
|
102
137
|
|
|
103
138
|
/**
|
|
104
139
|
* @description Variables used internally in editor operation
|
|
105
|
-
* @
|
|
106
|
-
* @property {number} tabSize Indent size of tab (4)
|
|
107
|
-
* @property {number} indentSize Indent size (25)px
|
|
108
|
-
* @property {number} codeIndentSize Indent size of Code view mode (2)
|
|
109
|
-
* @property {Array} currentNodes An element array of the current cursor's node structure
|
|
110
|
-
* @property {Array} currentNodesMap An element name array of the current cursor's node structure
|
|
111
|
-
* @property {boolean} componentSelected Boolean value of whether component is selected
|
|
112
|
-
* @property {number} rootKey Current root key
|
|
140
|
+
* @type {__se__EditorStatus}
|
|
113
141
|
*/
|
|
114
142
|
this.status = {
|
|
115
143
|
hasFocus: false,
|
|
@@ -118,155 +146,286 @@ const Editor = function (multiTargets, options) {
|
|
|
118
146
|
codeIndentSize: 2,
|
|
119
147
|
currentNodes: [],
|
|
120
148
|
currentNodesMap: [],
|
|
121
|
-
|
|
149
|
+
onSelected: false,
|
|
122
150
|
rootKey: product.rootId,
|
|
123
|
-
_range: null
|
|
151
|
+
_range: null,
|
|
152
|
+
_onMousedown: false
|
|
124
153
|
};
|
|
125
154
|
|
|
126
155
|
/**
|
|
127
156
|
* @description Is classic mode?
|
|
157
|
+
* @type {boolean}
|
|
128
158
|
*/
|
|
129
|
-
this.isClassic =
|
|
159
|
+
this.isClassic = false;
|
|
130
160
|
|
|
131
161
|
/**
|
|
132
162
|
* @description Is inline mode?
|
|
163
|
+
* @type {boolean}
|
|
133
164
|
*/
|
|
134
|
-
this.isInline =
|
|
165
|
+
this.isInline = false;
|
|
135
166
|
|
|
136
167
|
/**
|
|
137
168
|
* @description Is balloon|balloon-always mode?
|
|
169
|
+
* @type {boolean}
|
|
138
170
|
*/
|
|
139
|
-
this.isBalloon =
|
|
171
|
+
this.isBalloon = false;
|
|
140
172
|
|
|
141
173
|
/**
|
|
142
174
|
* @description Is balloon-always mode?
|
|
175
|
+
* @type {boolean}
|
|
143
176
|
*/
|
|
144
|
-
this.isBalloonAlways =
|
|
177
|
+
this.isBalloonAlways = false;
|
|
145
178
|
|
|
146
179
|
/**
|
|
147
180
|
* @description Is subToolbar balloon|balloon-always mode?
|
|
181
|
+
* @type {boolean}
|
|
148
182
|
*/
|
|
149
|
-
this.isSubBalloon =
|
|
183
|
+
this.isSubBalloon = false;
|
|
150
184
|
|
|
151
185
|
/**
|
|
152
186
|
* @description Is subToolbar balloon-always mode?
|
|
187
|
+
* @type {boolean}
|
|
153
188
|
*/
|
|
154
|
-
this.isSubBalloonAlways =
|
|
189
|
+
this.isSubBalloonAlways = false;
|
|
155
190
|
|
|
156
|
-
// ----- Properties not shared with _core -----
|
|
157
191
|
/**
|
|
158
192
|
* @description All command buttons map
|
|
193
|
+
* @type {Map<string, HTMLElement>}
|
|
159
194
|
*/
|
|
160
195
|
this.allCommandButtons = new Map();
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @description All command buttons map
|
|
199
|
+
* @type {Map<string, HTMLElement>}
|
|
200
|
+
*/
|
|
161
201
|
this.subAllCommandButtons = new Map();
|
|
162
202
|
|
|
163
203
|
/**
|
|
164
204
|
* @description Shoutcuts key map
|
|
205
|
+
* @type {Map<string, *>}
|
|
165
206
|
*/
|
|
166
207
|
this.shortcutsKeyMap = new Map();
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @description Shoutcuts reverse key array
|
|
211
|
+
* - An array of key codes generated with the reverseButtons option, used to reverse the action for a specific key combination.
|
|
212
|
+
* @type {Array<string>}
|
|
213
|
+
*/
|
|
167
214
|
this.reverseKeys = [];
|
|
168
215
|
|
|
169
216
|
/**
|
|
170
217
|
* @description A map with the plugin's buttons having an "active" method and the default command buttons with an "active" action.
|
|
171
|
-
* Each button is contained in an array.
|
|
218
|
+
* - Each button is contained in an array.
|
|
219
|
+
* @type {Map<string, Array<HTMLButtonElement>>}
|
|
172
220
|
*/
|
|
173
221
|
this.commandTargets = new Map();
|
|
174
222
|
|
|
175
223
|
/**
|
|
176
224
|
* @description Plugins array with "active" method.
|
|
177
|
-
* "activeCommands" runs the "add" method when creating the editor.
|
|
225
|
+
* - "activeCommands" runs the "add" method when creating the editor.
|
|
226
|
+
* @type {Array<string>}
|
|
178
227
|
*/
|
|
179
228
|
this.activeCommands = null;
|
|
180
229
|
|
|
181
230
|
/**
|
|
182
231
|
* @description The selection node (selection.getNode()) to which the effect was last applied
|
|
232
|
+
* @type {Node|null}
|
|
183
233
|
*/
|
|
184
234
|
this.effectNode = null;
|
|
185
235
|
|
|
236
|
+
/**
|
|
237
|
+
* @description Currently open "Modal" instance
|
|
238
|
+
* @type {*}
|
|
239
|
+
*/
|
|
240
|
+
this.opendModal = null;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* @description Currently open "Controller" info array
|
|
244
|
+
* @type {Array<ControllerInfo_editor>}
|
|
245
|
+
*/
|
|
246
|
+
this.opendControllers = [];
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @description Currently open "Controller" caller plugin name
|
|
250
|
+
*/
|
|
251
|
+
this.currentControllerName = '';
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @description Currently open "Browser" instance
|
|
255
|
+
* @type {*}
|
|
256
|
+
*/
|
|
257
|
+
this.opendBrowser = null;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @description Whether "SelectMenu" is open
|
|
261
|
+
* @type {boolean}
|
|
262
|
+
*/
|
|
263
|
+
this.selectMenuOn = false;
|
|
264
|
+
|
|
265
|
+
// ------ base ------
|
|
266
|
+
/** @description History class instance @type {ReturnType<typeof import('./base/history').default>} */
|
|
267
|
+
this.history = null;
|
|
268
|
+
/** @description EventManager class instance @type {import('./base/eventManager').default} */
|
|
269
|
+
this.eventManager = null;
|
|
270
|
+
|
|
271
|
+
// ------ class ------
|
|
272
|
+
/** @description Toolbar class instance @type {import('./class/toolbar').default} */
|
|
273
|
+
this.toolbar = null;
|
|
274
|
+
/** @description Sub-Toolbar class instance @type {import('./class/toolbar').default|null} */
|
|
275
|
+
this.subToolbar = null;
|
|
276
|
+
/** @description Char class instance @type {import('./class/char').default} */
|
|
277
|
+
this.char = null;
|
|
278
|
+
/** @description Component class instance @type {import('./class/component').default} */
|
|
279
|
+
this.component = null;
|
|
280
|
+
/** @description Format class instance @type {import('./class/format').default} */
|
|
281
|
+
this.format = null;
|
|
282
|
+
/** @description HTML class instance @type {import('./class/html').default} */
|
|
283
|
+
this.html = null;
|
|
284
|
+
/** @description Menu class instance @type {import('./class/menu').default} */
|
|
285
|
+
this.menu = null;
|
|
286
|
+
/** @description NodeTransform class instance @type {import('./class/nodeTransform').default} */
|
|
287
|
+
this.nodeTransform = null;
|
|
288
|
+
/** @description Offset class instance @type {import('./class/offset').default} */
|
|
289
|
+
this.offset = null;
|
|
290
|
+
/** @description Selection class instance @type {import('./class/selection').default} */
|
|
291
|
+
this.selection = null;
|
|
292
|
+
/** @description Shortcuts class instance @type {import('./class/shortcuts').default} */
|
|
293
|
+
this.shortcuts = null;
|
|
294
|
+
/** @description UI class instance @type {import('./class/ui').default} */
|
|
295
|
+
this.ui = null;
|
|
296
|
+
/** @description Viewer class instance @type {import('./class/viewer').default} */
|
|
297
|
+
this.viewer = null;
|
|
298
|
+
|
|
186
299
|
// ------------------------------------------------------- private properties -------------------------------------------------------
|
|
300
|
+
/**
|
|
301
|
+
* @description Line breaker (top)
|
|
302
|
+
* @type {HTMLElement}
|
|
303
|
+
*/
|
|
304
|
+
this._lineBreaker_t = null;
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* @description Line breaker (bottom)
|
|
308
|
+
* @type {HTMLElement}
|
|
309
|
+
*/
|
|
310
|
+
this._lineBreaker_b = null;
|
|
311
|
+
|
|
187
312
|
/**
|
|
188
313
|
* @description Closest ShadowRoot to editor if found
|
|
189
314
|
* @type {ShadowRoot}
|
|
190
|
-
* @private
|
|
191
315
|
*/
|
|
192
316
|
this._shadowRoot = null;
|
|
193
317
|
|
|
194
318
|
/**
|
|
195
319
|
* @description Plugin call event map
|
|
196
|
-
* @
|
|
320
|
+
* @type {Map<string, Array<((...args: *) => *) & { index: number }>>}
|
|
197
321
|
*/
|
|
198
322
|
this._onPluginEvents = null;
|
|
199
323
|
|
|
200
324
|
/**
|
|
201
325
|
* @description Copy format info
|
|
202
|
-
*
|
|
326
|
+
* - eventManager.__cacheStyleNodes copied
|
|
327
|
+
* @type {Array<Node>|null}
|
|
203
328
|
*/
|
|
204
329
|
this._onCopyFormatInfo = null;
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* @description Copy format init method
|
|
333
|
+
* @type {(...args: *) => *|null}
|
|
334
|
+
*/
|
|
205
335
|
this._onCopyFormatInitMethod = null;
|
|
206
336
|
|
|
207
337
|
/**
|
|
208
|
-
* @description Controller
|
|
209
|
-
* @
|
|
338
|
+
* @description Controller target's frame div (editor.frameContext.get('topArea'))
|
|
339
|
+
* @type {HTMLElement|null}
|
|
210
340
|
*/
|
|
211
|
-
this.opendModal = null;
|
|
212
|
-
this.opendControllers = [];
|
|
213
|
-
this.currentControllerName = '';
|
|
214
341
|
this._controllerTargetContext = null;
|
|
215
|
-
this.selectMenuOn = false;
|
|
216
|
-
this._backWrapper = product.carrierWrapper.querySelector('.se-back-wrapper');
|
|
217
342
|
|
|
343
|
+
/**
|
|
344
|
+
* @description List of buttons that are disabled when "controller" is opened
|
|
345
|
+
* @type {Array<HTMLButtonElement|HTMLInputElement>}
|
|
346
|
+
*/
|
|
218
347
|
this._controllerOnDisabledButtons = [];
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* @description List of buttons that are disabled when "codeView" mode opened
|
|
351
|
+
* @type {Array<HTMLButtonElement|HTMLInputElement>}
|
|
352
|
+
*/
|
|
219
353
|
this._codeViewDisabledButtons = [];
|
|
220
354
|
|
|
221
355
|
/**
|
|
222
|
-
* @description
|
|
223
|
-
* @
|
|
356
|
+
* @description List of buttons to run plugins in the toolbar
|
|
357
|
+
* @type {Array<HTMLElement>}
|
|
224
358
|
*/
|
|
225
359
|
this._pluginCallButtons = product.pluginCallButtons;
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* @description List of buttons to run plugins in the Sub-Toolbar
|
|
363
|
+
* @type {Array<HTMLElement>}
|
|
364
|
+
*/
|
|
226
365
|
this._pluginCallButtons_sub = product.pluginCallButtons_sub;
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* @description Responsive Toolbar Button Structure array
|
|
369
|
+
* @type {Array<*>}
|
|
370
|
+
*/
|
|
227
371
|
this._responsiveButtons = product.responsiveButtons;
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* @description Responsive Sub-Toolbar Button Structure array
|
|
375
|
+
* @type {Array<*>}
|
|
376
|
+
*/
|
|
228
377
|
this._responsiveButtons_sub = product.responsiveButtons_sub;
|
|
229
378
|
|
|
230
379
|
/**
|
|
231
380
|
* @description Variable that controls the "blur" event in the editor of inline or balloon mode when the focus is moved to dropdown
|
|
232
|
-
* @
|
|
381
|
+
* @type {boolean}
|
|
233
382
|
*/
|
|
234
383
|
this._notHideToolbar = false;
|
|
235
384
|
|
|
236
385
|
/**
|
|
237
386
|
* @description Variables for controlling focus and blur events
|
|
238
|
-
* @
|
|
387
|
+
* @type {boolean}
|
|
239
388
|
*/
|
|
240
|
-
this.
|
|
389
|
+
this._preventBlur = false;
|
|
241
390
|
|
|
242
391
|
/**
|
|
243
|
-
* @description
|
|
244
|
-
|
|
392
|
+
* @description Variables for controlling selection change events
|
|
393
|
+
*/
|
|
394
|
+
this._preventSelection = false;
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* @description If true, initialize all indexes of image, video information
|
|
398
|
+
* @type {boolean}
|
|
245
399
|
*/
|
|
246
400
|
this._componentsInfoInit = true;
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* @description If true, reset all indexes of image, video information
|
|
404
|
+
* @type {boolean}
|
|
405
|
+
*/
|
|
247
406
|
this._componentsInfoReset = false;
|
|
248
407
|
|
|
249
408
|
/**
|
|
250
409
|
* @description plugin retainFormat info Map()
|
|
251
|
-
* @
|
|
410
|
+
* @type {Map<string, ((...args: *) => *)>}
|
|
252
411
|
*/
|
|
253
412
|
this._MELInfo = null;
|
|
254
413
|
|
|
255
414
|
/**
|
|
256
415
|
* @description Properties for managing files in the "FileManager" module
|
|
257
|
-
* @
|
|
416
|
+
* @type {Array<*>}
|
|
258
417
|
*/
|
|
259
418
|
this._fileInfoPluginsCheck = null;
|
|
260
419
|
|
|
261
420
|
/**
|
|
262
421
|
* @description Properties for managing files in the "FileManager" module
|
|
263
|
-
* @
|
|
422
|
+
* @type {Array<*>}
|
|
264
423
|
*/
|
|
265
424
|
this._fileInfoPluginsReset = null;
|
|
266
425
|
|
|
267
426
|
/**
|
|
268
427
|
* @description Variables for file component management
|
|
269
|
-
* @
|
|
428
|
+
* @type {Object<string, *>}
|
|
270
429
|
*/
|
|
271
430
|
this._fileManager = {
|
|
272
431
|
tags: null,
|
|
@@ -274,34 +433,38 @@ const Editor = function (multiTargets, options) {
|
|
|
274
433
|
pluginRegExp: null,
|
|
275
434
|
pluginMap: null
|
|
276
435
|
};
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* @description Variables for managing the components
|
|
439
|
+
* @type {Array<*>}
|
|
440
|
+
*/
|
|
277
441
|
this._componentManager = [];
|
|
278
442
|
|
|
279
443
|
/**
|
|
280
444
|
* @description Current Figure container.
|
|
281
|
-
* @
|
|
445
|
+
* @type {HTMLElement|null}
|
|
282
446
|
*/
|
|
283
447
|
this._figureContainer = null;
|
|
284
448
|
|
|
285
449
|
/**
|
|
286
450
|
* @description Origin options
|
|
287
|
-
* @
|
|
451
|
+
* @type {EditorInitOptions_editor}
|
|
288
452
|
*/
|
|
289
453
|
this._originOptions = options;
|
|
290
454
|
|
|
291
455
|
/** ----- Create editor ------------------------------------------------------------ */
|
|
292
456
|
this.__Create(options);
|
|
293
|
-
}
|
|
457
|
+
}
|
|
294
458
|
|
|
295
459
|
Editor.prototype = {
|
|
296
460
|
/**
|
|
297
461
|
* @description If the plugin is not added, add the plugin and call the 'add' function.
|
|
298
|
-
* If the plugin is added call callBack function.
|
|
462
|
+
* - If the plugin is added call callBack function.
|
|
299
463
|
* @param {string} pluginName The name of the plugin to call
|
|
300
|
-
* @param {Array
|
|
301
|
-
* @param {
|
|
302
|
-
* @param {object} shortcuts this.options.get('shortcuts')
|
|
464
|
+
* @param {?Array<HTMLElement>} targets Plugin target button (This is not necessary if you have a button list when creating the editor)
|
|
465
|
+
* @param {?Object<string, *>} pluginOptions Plugin's options
|
|
303
466
|
*/
|
|
304
|
-
registerPlugin(pluginName, targets, pluginOptions
|
|
467
|
+
registerPlugin(pluginName, targets, pluginOptions) {
|
|
305
468
|
let plugin = this.plugins[pluginName];
|
|
306
469
|
if (!plugin) {
|
|
307
470
|
throw Error(`[SUNEDITOR.registerPlugin.fail] The called plugin does not exist or is in an invalid format. (pluginName: "${pluginName}")`);
|
|
@@ -312,7 +475,7 @@ Editor.prototype = {
|
|
|
312
475
|
|
|
313
476
|
if (targets) {
|
|
314
477
|
for (let i = 0, len = targets.length; i < len; i++) {
|
|
315
|
-
UpdateButton(targets[i], plugin, this.icons, this.lang
|
|
478
|
+
UpdateButton(targets[i], plugin, this.icons, this.lang);
|
|
316
479
|
}
|
|
317
480
|
|
|
318
481
|
if (!this.activeCommands.includes(pluginName) && typeof this.plugins[pluginName].active === 'function') {
|
|
@@ -325,13 +488,13 @@ Editor.prototype = {
|
|
|
325
488
|
* @description Run plugin calls and basic commands.
|
|
326
489
|
* @param {string} command Command string
|
|
327
490
|
* @param {string} type Display type string ('command', 'dropdown', 'modal', 'container')
|
|
328
|
-
* @param {
|
|
491
|
+
* @param {?Node=} button The element of command button
|
|
329
492
|
*/
|
|
330
493
|
run(command, type, button) {
|
|
331
494
|
if (type) {
|
|
332
495
|
if (/more/i.test(type)) {
|
|
333
|
-
const toolbar =
|
|
334
|
-
const toolInst =
|
|
496
|
+
const toolbar = dom.query.getParentElement(button, '.se-toolbar');
|
|
497
|
+
const toolInst = dom.utils.hasClass(toolbar, 'se-toolbar-sub') ? this.subToolbar : this.toolbar;
|
|
335
498
|
if (button !== toolInst.currentMoreLayerActiveButton) {
|
|
336
499
|
const layer = toolbar.querySelector('.' + command);
|
|
337
500
|
if (layer) {
|
|
@@ -339,7 +502,7 @@ Editor.prototype = {
|
|
|
339
502
|
toolInst._showBalloon();
|
|
340
503
|
toolInst._showInline();
|
|
341
504
|
}
|
|
342
|
-
|
|
505
|
+
dom.utils.addClass(button, 'on');
|
|
343
506
|
} else if (toolInst.currentMoreLayerActiveButton) {
|
|
344
507
|
toolInst._moreLayerOff();
|
|
345
508
|
toolInst._showBalloon();
|
|
@@ -355,7 +518,7 @@ Editor.prototype = {
|
|
|
355
518
|
return;
|
|
356
519
|
}
|
|
357
520
|
|
|
358
|
-
if (this.frameContext.get('isReadOnly') &&
|
|
521
|
+
if (this.frameContext.get('isReadOnly') && dom.utils.arrayIncludes(this._controllerOnDisabledButtons, button)) return;
|
|
359
522
|
if (/dropdown/.test(type) && (this.menu.targetMap[command] === null || button !== this.menu.currentDropdownActiveButton)) {
|
|
360
523
|
this.menu.dropdownOn(button);
|
|
361
524
|
return;
|
|
@@ -364,8 +527,10 @@ Editor.prototype = {
|
|
|
364
527
|
return;
|
|
365
528
|
} else if (/command/.test(type)) {
|
|
366
529
|
this.plugins[command].action(button);
|
|
367
|
-
} else if (/
|
|
530
|
+
} else if (/browser/.test(type)) {
|
|
368
531
|
this.plugins[command].open(null);
|
|
532
|
+
} else if (/popup/.test(type)) {
|
|
533
|
+
this.plugins[command].show();
|
|
369
534
|
}
|
|
370
535
|
} else if (command) {
|
|
371
536
|
this.commandHandler(command, button);
|
|
@@ -381,24 +546,27 @@ Editor.prototype = {
|
|
|
381
546
|
|
|
382
547
|
/**
|
|
383
548
|
* @description Execute default command of command button
|
|
384
|
-
* (selectAll, codeView, fullScreen, indent, outdent, undo, redo, removeFormat, print, preview, showBlocks, save, bold, underline, italic, strike, subscript, superscript, copy, cut, paste)
|
|
549
|
+
* - (selectAll, codeView, fullScreen, indent, outdent, undo, redo, removeFormat, print, preview, showBlocks, save, bold, underline, italic, strike, subscript, superscript, copy, cut, paste)
|
|
385
550
|
* @param {string} command Property of command button (data-value)
|
|
386
|
-
* @param {
|
|
551
|
+
* @param {?Node=} button Command button
|
|
552
|
+
* @returns {Promise<void>}
|
|
387
553
|
*/
|
|
388
554
|
async commandHandler(command, button) {
|
|
389
555
|
if (this.frameContext.get('isReadOnly') && !/copy|cut|selectAll|codeView|fullScreen|print|preview|showBlocks/.test(command)) return;
|
|
390
556
|
|
|
391
557
|
switch (command) {
|
|
392
|
-
case 'copy':
|
|
393
|
-
case 'cut':
|
|
394
|
-
this.execCommand(command);
|
|
395
|
-
break;
|
|
396
|
-
case 'paste':
|
|
397
|
-
// @todo
|
|
398
|
-
break;
|
|
399
558
|
case 'selectAll':
|
|
400
559
|
SELECT_ALL(this);
|
|
401
560
|
break;
|
|
561
|
+
case 'copy': {
|
|
562
|
+
const range = this.selection.getRange();
|
|
563
|
+
if (range.collapsed) break;
|
|
564
|
+
|
|
565
|
+
const container = dom.utils.createElement('div', null, range.cloneContents());
|
|
566
|
+
await this.html.copy(container.innerHTML);
|
|
567
|
+
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
402
570
|
case 'newDocument':
|
|
403
571
|
this.html.set(`<${this.options.get('defaultLine')}><br></${this.options.get('defaultLine')}>`);
|
|
404
572
|
this.focus();
|
|
@@ -423,7 +591,7 @@ Editor.prototype = {
|
|
|
423
591
|
this.history.redo();
|
|
424
592
|
break;
|
|
425
593
|
case 'removeFormat':
|
|
426
|
-
this.format.
|
|
594
|
+
this.format.removeInlineElement();
|
|
427
595
|
this.focus();
|
|
428
596
|
break;
|
|
429
597
|
case 'print':
|
|
@@ -450,6 +618,15 @@ Editor.prototype = {
|
|
|
450
618
|
case 'copyFormat':
|
|
451
619
|
COPY_FORMAT(this, button);
|
|
452
620
|
break;
|
|
621
|
+
case 'pageBreak':
|
|
622
|
+
PAGE_BREAK(this);
|
|
623
|
+
break;
|
|
624
|
+
case 'pageUp':
|
|
625
|
+
this.frameContext.get('documentType').pageUp();
|
|
626
|
+
break;
|
|
627
|
+
case 'pageDown':
|
|
628
|
+
this.frameContext.get('documentType').pageDown();
|
|
629
|
+
break;
|
|
453
630
|
default:
|
|
454
631
|
FONT_STYLE(this, command);
|
|
455
632
|
}
|
|
@@ -457,36 +634,38 @@ Editor.prototype = {
|
|
|
457
634
|
|
|
458
635
|
/**
|
|
459
636
|
* @description Execute "editor.run" with command button.
|
|
460
|
-
* @param {
|
|
637
|
+
* @param {Node} target Command target
|
|
461
638
|
*/
|
|
462
639
|
runFromTarget(target) {
|
|
463
|
-
|
|
464
|
-
|
|
640
|
+
if (dom.check.isInputElement(target)) return;
|
|
641
|
+
|
|
642
|
+
const targetBtn = /** @type {HTMLButtonElement} */ (dom.query.getCommandTarget(target));
|
|
643
|
+
if (!targetBtn) return;
|
|
465
644
|
|
|
466
|
-
const command =
|
|
467
|
-
const type =
|
|
645
|
+
const command = targetBtn.getAttribute('data-command');
|
|
646
|
+
const type = targetBtn.getAttribute('data-type');
|
|
468
647
|
|
|
469
648
|
if (!command && !type) return;
|
|
470
|
-
if (
|
|
649
|
+
if (targetBtn.disabled) return;
|
|
471
650
|
|
|
472
651
|
this.run(command, type, target);
|
|
473
652
|
},
|
|
474
653
|
|
|
475
654
|
/**
|
|
476
655
|
* @description It is executed by inserting the button of commandTargets as the argument value of the "f" function.
|
|
477
|
-
* "
|
|
656
|
+
* - "func" is called as long as the button array's length.
|
|
478
657
|
* @param {string} cmd data-command
|
|
479
|
-
* @param {
|
|
658
|
+
* @param {(...args: *) => *} func Function.
|
|
480
659
|
*/
|
|
481
|
-
applyCommandTargets(cmd,
|
|
660
|
+
applyCommandTargets(cmd, func) {
|
|
482
661
|
if (this.commandTargets.has(cmd)) {
|
|
483
|
-
this.commandTargets.get(cmd).forEach(
|
|
662
|
+
this.commandTargets.get(cmd).forEach(func);
|
|
484
663
|
}
|
|
485
664
|
},
|
|
486
665
|
|
|
487
666
|
/**
|
|
488
|
-
* @description
|
|
489
|
-
* @param {
|
|
667
|
+
* @description Execute a function by traversing all root targets.
|
|
668
|
+
* @param {(...args: *) => *} f Function
|
|
490
669
|
*/
|
|
491
670
|
applyFrameRoots(f) {
|
|
492
671
|
this.frameRoots.forEach(f);
|
|
@@ -494,14 +673,14 @@ Editor.prototype = {
|
|
|
494
673
|
|
|
495
674
|
/**
|
|
496
675
|
* @description Checks if the content of the editor is empty.
|
|
497
|
-
* Display criteria for "placeholder".
|
|
498
|
-
* @param {
|
|
676
|
+
* - Display criteria for "placeholder".
|
|
677
|
+
* @param {?__se__FrameContext=} fc Frame context, if not present, currently selected frame context.
|
|
499
678
|
* @returns {boolean}
|
|
500
679
|
*/
|
|
501
680
|
isEmpty(fc) {
|
|
502
681
|
fc = fc || this.frameContext;
|
|
503
682
|
const wysiwyg = fc.get('wysiwyg');
|
|
504
|
-
return
|
|
683
|
+
return dom.check.isZeroWidth(wysiwyg.textContent) && !wysiwyg.querySelector(this.options.get('allowedEmptyTags')) && (wysiwyg.innerText.match(/\n/g) || '').length <= 1;
|
|
505
684
|
},
|
|
506
685
|
|
|
507
686
|
/**
|
|
@@ -514,7 +693,7 @@ Editor.prototype = {
|
|
|
514
693
|
|
|
515
694
|
try {
|
|
516
695
|
this.options.set('_rtl', rtl);
|
|
517
|
-
this._offCurrentController();
|
|
696
|
+
this.ui._offCurrentController();
|
|
518
697
|
|
|
519
698
|
const fc = this.frameContext;
|
|
520
699
|
const plugins = this.plugins;
|
|
@@ -526,18 +705,18 @@ Editor.prototype = {
|
|
|
526
705
|
const statusbarWrapper = this.context.get('statusbar._wrapper');
|
|
527
706
|
if (rtl) {
|
|
528
707
|
this.applyFrameRoots((e) => {
|
|
529
|
-
|
|
708
|
+
dom.utils.addClass([e.get('topArea'), e.get('wysiwyg'), e.get('documentTypePageMirror')], 'se-rtl');
|
|
530
709
|
});
|
|
531
|
-
|
|
710
|
+
dom.utils.addClass([this.carrierWrapper, toolbarWrapper, statusbarWrapper], 'se-rtl');
|
|
532
711
|
} else {
|
|
533
712
|
this.applyFrameRoots((e) => {
|
|
534
|
-
|
|
713
|
+
dom.utils.removeClass([e.get('topArea'), e.get('wysiwyg'), e.get('documentTypePageMirror')], 'se-rtl');
|
|
535
714
|
});
|
|
536
|
-
|
|
715
|
+
dom.utils.removeClass([this.carrierWrapper, toolbarWrapper, statusbarWrapper], 'se-rtl');
|
|
537
716
|
}
|
|
538
717
|
|
|
539
|
-
const lineNodes =
|
|
540
|
-
return this.format.isLine(current) && (current.style.marginRight || current.style.marginLeft || current.style.textAlign);
|
|
718
|
+
const lineNodes = dom.query.getListChildren(fc.get('wysiwyg'), (current) => {
|
|
719
|
+
return this.format.isLine(current) && !!(current.style.marginRight || current.style.marginLeft || current.style.textAlign);
|
|
541
720
|
});
|
|
542
721
|
|
|
543
722
|
for (let i = 0, n, l, r; (n = lineNodes[i]); i++) {
|
|
@@ -557,6 +736,16 @@ Editor.prototype = {
|
|
|
557
736
|
|
|
558
737
|
DIR_BTN_ACTIVE(this, rtl);
|
|
559
738
|
|
|
739
|
+
// document type
|
|
740
|
+
if (fc.has('documentType-use-header')) {
|
|
741
|
+
if (rtl) fc.get('wrapper').appendChild(fc.get('documentTypeInner'));
|
|
742
|
+
else fc.get('wrapper').insertBefore(fc.get('documentTypeInner'), fc.get('wysiwygFrame'));
|
|
743
|
+
}
|
|
744
|
+
if (fc.has('documentType-use-page')) {
|
|
745
|
+
if (rtl) fc.get('wrapper').insertBefore(fc.get('documentTypePage'), fc.get('wysiwygFrame'));
|
|
746
|
+
else fc.get('wrapper').appendChild(fc.get('documentTypePage'));
|
|
747
|
+
}
|
|
748
|
+
|
|
560
749
|
if (this.isBalloon) this.toolbar._showBalloon();
|
|
561
750
|
else if (this.isSubBalloon) this.subToolbar._showBalloon();
|
|
562
751
|
} catch (e) {
|
|
@@ -570,7 +759,7 @@ Editor.prototype = {
|
|
|
570
759
|
|
|
571
760
|
/**
|
|
572
761
|
* @description Add or reset option property (Editor is reloaded)
|
|
573
|
-
* @param {
|
|
762
|
+
* @param {EditorInitOptions_editor} newOptions Options
|
|
574
763
|
*/
|
|
575
764
|
resetOptions(newOptions) {
|
|
576
765
|
const _keys = Object.keys;
|
|
@@ -624,7 +813,7 @@ Editor.prototype = {
|
|
|
624
813
|
|
|
625
814
|
// statusbar
|
|
626
815
|
if (diff.has('statusbar')) {
|
|
627
|
-
|
|
816
|
+
dom.utils.removeItem(fc.get('statusbar'));
|
|
628
817
|
if (newRootOptions.get('statusbar')) {
|
|
629
818
|
const statusbar = CreateStatusbar(newRootOptions, null).statusbar;
|
|
630
819
|
fc.get('container').appendChild(statusbar);
|
|
@@ -659,7 +848,7 @@ Editor.prototype = {
|
|
|
659
848
|
fc.set('options', newRootOptions);
|
|
660
849
|
|
|
661
850
|
// frame styles
|
|
662
|
-
this.setEditorStyle(newRootOptions.get('_defaultStyles'), fc);
|
|
851
|
+
this.ui.setEditorStyle(newRootOptions.get('_defaultStyles'), fc);
|
|
663
852
|
|
|
664
853
|
// frame attributes
|
|
665
854
|
const frame = fc.get('wysiwyg');
|
|
@@ -700,9 +889,14 @@ Editor.prototype = {
|
|
|
700
889
|
}
|
|
701
890
|
// shortcuts hint
|
|
702
891
|
if (options.get('shortcutsHint')) {
|
|
703
|
-
|
|
892
|
+
dom.utils.removeClass(toolbar, 'se-shortcut-hide');
|
|
704
893
|
} else {
|
|
705
|
-
|
|
894
|
+
dom.utils.addClass(toolbar, 'se-shortcut-hide');
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// theme
|
|
898
|
+
if (this._originOptions.theme !== (newOptions.theme ?? this._originOptions.theme)) {
|
|
899
|
+
this.ui.setTheme(newOptions.theme);
|
|
706
900
|
}
|
|
707
901
|
|
|
708
902
|
this.effectNode = null;
|
|
@@ -711,7 +905,7 @@ Editor.prototype = {
|
|
|
711
905
|
|
|
712
906
|
/**
|
|
713
907
|
* @description Change the current root index.
|
|
714
|
-
* @param {
|
|
908
|
+
* @param {*} rootKey
|
|
715
909
|
*/
|
|
716
910
|
changeFrameContext(rootKey) {
|
|
717
911
|
if (rootKey === this.status.rootKey) return;
|
|
@@ -724,8 +918,8 @@ Editor.prototype = {
|
|
|
724
918
|
/**
|
|
725
919
|
* @description javascript execCommand
|
|
726
920
|
* @param {string} command javascript execCommand function property
|
|
727
|
-
* @param {
|
|
728
|
-
* @param {string
|
|
921
|
+
* @param {boolean=} showDefaultUI javascript execCommand function property
|
|
922
|
+
* @param {string=} value javascript execCommand function property
|
|
729
923
|
*/
|
|
730
924
|
execCommand(command, showDefaultUI, value) {
|
|
731
925
|
this.frameContext.get('_wd').execCommand(command, showDefaultUI, command === 'formatBlock' ? '<' + value + '>' : value);
|
|
@@ -734,23 +928,23 @@ Editor.prototype = {
|
|
|
734
928
|
|
|
735
929
|
/**
|
|
736
930
|
* @description Focus to wysiwyg area
|
|
737
|
-
* @param {
|
|
931
|
+
* @param {*} rootKey Root index
|
|
738
932
|
*/
|
|
739
933
|
focus(rootKey) {
|
|
740
934
|
if (rootKey) this.changeFrameContext(rootKey);
|
|
741
935
|
if (this.frameContext.get('wysiwygFrame').style.display === 'none') return;
|
|
742
|
-
this.
|
|
936
|
+
this._preventBlur = false;
|
|
743
937
|
|
|
744
938
|
if (this.frameOptions.get('iframe') || !this.frameContext.get('wysiwyg').contains(this.selection.getNode())) {
|
|
745
939
|
this._nativeFocus();
|
|
746
940
|
} else {
|
|
747
941
|
try {
|
|
748
942
|
const range = this.selection.getRange();
|
|
749
|
-
if (range.startContainer === range.endContainer &&
|
|
750
|
-
const currentNode = range.commonAncestorContainer.children[range.startOffset];
|
|
943
|
+
if (range.startContainer === range.endContainer && dom.check.isWysiwygFrame(range.startContainer)) {
|
|
944
|
+
const currentNode = /** @type {HTMLElement} */ (range.commonAncestorContainer).children[range.startOffset];
|
|
751
945
|
if (!this.format.isLine(currentNode) && !this.component.is(currentNode)) {
|
|
752
|
-
const br =
|
|
753
|
-
const format =
|
|
946
|
+
const br = dom.utils.createElement('BR');
|
|
947
|
+
const format = dom.utils.createElement(this.options.get('defaultLine'), null, br);
|
|
754
948
|
this.frameContext.get('wysiwyg').insertBefore(format, currentNode);
|
|
755
949
|
this.selection.setRange(br, 0, br, 0);
|
|
756
950
|
return;
|
|
@@ -768,19 +962,19 @@ Editor.prototype = {
|
|
|
768
962
|
|
|
769
963
|
/**
|
|
770
964
|
* @description If "focusEl" is a component, then that component is selected; if it is a format element, the last text is selected
|
|
771
|
-
* If "focusEdge" is null, then selected last element
|
|
772
|
-
* @param {
|
|
965
|
+
* - If "focusEdge" is null, then selected last element
|
|
966
|
+
* @param {?Node=} focusEl Focus element
|
|
773
967
|
*/
|
|
774
968
|
focusEdge(focusEl) {
|
|
775
|
-
this.
|
|
969
|
+
this._preventBlur = false;
|
|
776
970
|
if (!focusEl) focusEl = this.frameContext.get('wysiwyg').lastElementChild;
|
|
777
971
|
|
|
778
972
|
const fileComponentInfo = this.component.get(focusEl);
|
|
779
973
|
if (fileComponentInfo) {
|
|
780
|
-
this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName
|
|
974
|
+
this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName);
|
|
781
975
|
} else if (focusEl) {
|
|
782
976
|
if (focusEl.nodeType !== 3) {
|
|
783
|
-
focusEl =
|
|
977
|
+
focusEl = dom.query.getEdgeChild(
|
|
784
978
|
focusEl,
|
|
785
979
|
function (current) {
|
|
786
980
|
return current.childNodes.length === 0 || current.nodeType === 3;
|
|
@@ -806,163 +1000,6 @@ Editor.prototype = {
|
|
|
806
1000
|
}
|
|
807
1001
|
},
|
|
808
1002
|
|
|
809
|
-
/**
|
|
810
|
-
* @description Set "options.get('editorStyle')" style.
|
|
811
|
-
* Define the style of the edit area
|
|
812
|
-
* It can also be defined with the "setOptions" method, but the "setEditorStyle" method does not render the editor again.
|
|
813
|
-
* @param {string} style Style string
|
|
814
|
-
* @param {FrameContext|null} fc Frame context
|
|
815
|
-
*/
|
|
816
|
-
setEditorStyle(style, fc) {
|
|
817
|
-
fc = fc || this.frameContext;
|
|
818
|
-
const fo = fc.get('options');
|
|
819
|
-
|
|
820
|
-
const newStyles = converter._setDefaultOptionStyle(fo, style);
|
|
821
|
-
fo.set('_defaultStyles', newStyles);
|
|
822
|
-
|
|
823
|
-
// top area
|
|
824
|
-
fc.get('topArea').style.cssText = newStyles.top;
|
|
825
|
-
|
|
826
|
-
// code view
|
|
827
|
-
const code = fc.get('code');
|
|
828
|
-
code.style.cssText = fo.get('_defaultStyles').frame;
|
|
829
|
-
code.style.display = 'none';
|
|
830
|
-
|
|
831
|
-
// wysiwyg frame
|
|
832
|
-
if (!fo.get('iframe')) {
|
|
833
|
-
fc.get('wysiwygFrame').style.cssText = newStyles.frame + newStyles.editor;
|
|
834
|
-
} else {
|
|
835
|
-
fc.get('wysiwygFrame').style.cssText = newStyles.frame;
|
|
836
|
-
fc.get('wysiwyg').style.cssText = newStyles.editor;
|
|
837
|
-
}
|
|
838
|
-
},
|
|
839
|
-
|
|
840
|
-
/**
|
|
841
|
-
* @description Switch to or off "ReadOnly" mode.
|
|
842
|
-
* @param {boolean} value "readOnly" boolean value.
|
|
843
|
-
* @param {string|undefined} rootKey Root key
|
|
844
|
-
*/
|
|
845
|
-
readOnly(value, rootKey) {
|
|
846
|
-
const fc = rootKey ? this.frameRoots.get(rootKey) : this.frameContext;
|
|
847
|
-
|
|
848
|
-
fc.set('isReadOnly', !!value);
|
|
849
|
-
domUtils.setDisabled(this._controllerOnDisabledButtons, !!value);
|
|
850
|
-
|
|
851
|
-
if (value) {
|
|
852
|
-
this._offCurrentController();
|
|
853
|
-
this._offCurrentModal();
|
|
854
|
-
|
|
855
|
-
if (this.toolbar?.currentMoreLayerActiveButton?.disabled) this.toolbar.moreLayerOff();
|
|
856
|
-
if (this.subToolbar?.currentMoreLayerActiveButton?.disabled) this.subToolbar.moreLayerOff();
|
|
857
|
-
if (this.menu?.currentDropdownActiveButton?.disabled) this.menu.dropdownOff();
|
|
858
|
-
if (this.menu?.currentContainerActiveButton?.disabled) this.menu.containerOff();
|
|
859
|
-
if (this.modalForm) this.plugins.modal.close.call(this);
|
|
860
|
-
|
|
861
|
-
fc.get('code').setAttribute('readOnly', 'true');
|
|
862
|
-
domUtils.addClass(fc.get('wysiwygFrame'), 'se-read-only');
|
|
863
|
-
} else {
|
|
864
|
-
fc.get('code').removeAttribute('readOnly');
|
|
865
|
-
domUtils.removeClass(fc.get('wysiwygFrame'), 'se-read-only');
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
if (this.options.get('hasCodeMirror')) {
|
|
869
|
-
this.viewer._codeMirrorEditor('readonly', !!value, rootKey);
|
|
870
|
-
}
|
|
871
|
-
},
|
|
872
|
-
|
|
873
|
-
/**
|
|
874
|
-
* @description Disable the suneditor
|
|
875
|
-
* @param {string|undefined} rootKey Root key
|
|
876
|
-
*/
|
|
877
|
-
disable(rootKey) {
|
|
878
|
-
const fc = rootKey ? this.frameRoots.get(rootKey) : this.frameContext;
|
|
879
|
-
|
|
880
|
-
this.toolbar.disable();
|
|
881
|
-
this._offCurrentController();
|
|
882
|
-
this._offCurrentModal();
|
|
883
|
-
|
|
884
|
-
if (this.modalForm) this.plugins.modal.close.call(this);
|
|
885
|
-
|
|
886
|
-
fc.get('wysiwyg').setAttribute('contenteditable', false);
|
|
887
|
-
fc.set('isDisabled', true);
|
|
888
|
-
|
|
889
|
-
if (this.options.get('hasCodeMirror')) {
|
|
890
|
-
this.viewer._codeMirrorEditor('readonly', true, rootKey);
|
|
891
|
-
} else {
|
|
892
|
-
fc.get('code').setAttribute('disabled', true);
|
|
893
|
-
}
|
|
894
|
-
},
|
|
895
|
-
|
|
896
|
-
/**
|
|
897
|
-
* @description Enable the suneditor
|
|
898
|
-
* @param {string|undefined} rootKey Root key
|
|
899
|
-
*/
|
|
900
|
-
enable(rootKey) {
|
|
901
|
-
const fc = rootKey ? this.frameRoots.get(rootKey) : this.frameContext;
|
|
902
|
-
|
|
903
|
-
this.toolbar.enable();
|
|
904
|
-
fc.get('wysiwyg').setAttribute('contenteditable', true);
|
|
905
|
-
fc.set('isDisabled', false);
|
|
906
|
-
|
|
907
|
-
if (this.options.get('hasCodeMirror')) {
|
|
908
|
-
this.viewer._codeMirrorEditor('readonly', false, rootKey);
|
|
909
|
-
} else {
|
|
910
|
-
fc.get('code').removeAttribute('disabled');
|
|
911
|
-
}
|
|
912
|
-
},
|
|
913
|
-
|
|
914
|
-
/**
|
|
915
|
-
* @description Show the suneditor
|
|
916
|
-
* @param {string|undefined} rootKey Root key
|
|
917
|
-
*/
|
|
918
|
-
show(rootKey) {
|
|
919
|
-
const fc = rootKey ? this.frameRoots.get(rootKey) : this.frameContext;
|
|
920
|
-
const topAreaStyle = fc.get('topArea').style;
|
|
921
|
-
if (topAreaStyle.display === 'none') topAreaStyle.display = 'block';
|
|
922
|
-
},
|
|
923
|
-
|
|
924
|
-
/**
|
|
925
|
-
* @description Hide the suneditor
|
|
926
|
-
* @param {string|undefined} rootKey Root key
|
|
927
|
-
*/
|
|
928
|
-
hide(rootKey) {
|
|
929
|
-
const fc = rootKey ? this.frameRoots.get(rootKey) : this.frameContext;
|
|
930
|
-
fc.get('topArea').style.display = 'none';
|
|
931
|
-
},
|
|
932
|
-
|
|
933
|
-
/**
|
|
934
|
-
* @description Show loading box
|
|
935
|
-
* @param {string|undefined} rootKey Root key
|
|
936
|
-
*/
|
|
937
|
-
showLoading(rootKey) {
|
|
938
|
-
(rootKey ? this.frameRoots.get(rootKey).get('container') : this.carrierWrapper).querySelector('.se-loading-box').style.display = 'block';
|
|
939
|
-
},
|
|
940
|
-
|
|
941
|
-
/**
|
|
942
|
-
* @description Hide loading box
|
|
943
|
-
* @param {string|undefined} rootKey Root key
|
|
944
|
-
*/
|
|
945
|
-
hideLoading(rootKey) {
|
|
946
|
-
(rootKey ? this.frameRoots.get(rootKey).get('container') : this.carrierWrapper).querySelector('.se-loading-box').style.display = 'none';
|
|
947
|
-
},
|
|
948
|
-
|
|
949
|
-
/**
|
|
950
|
-
* @description Activate the transparent background "div" so that other elements are not affected during resizing.
|
|
951
|
-
* @param {cursor} cursor cursor css property
|
|
952
|
-
*/
|
|
953
|
-
enableBackWrapper(cursor) {
|
|
954
|
-
this._backWrapper.style.cursor = cursor;
|
|
955
|
-
this._backWrapper.style.display = 'block';
|
|
956
|
-
},
|
|
957
|
-
|
|
958
|
-
/**
|
|
959
|
-
* @description Disabled background "div"
|
|
960
|
-
*/
|
|
961
|
-
disableBackWrapper() {
|
|
962
|
-
this._backWrapper.style.display = 'none';
|
|
963
|
-
this._backWrapper.style.cursor = 'default';
|
|
964
|
-
},
|
|
965
|
-
|
|
966
1003
|
/**
|
|
967
1004
|
* @description Destroy the suneditor
|
|
968
1005
|
*/
|
|
@@ -979,12 +1016,12 @@ Editor.prototype = {
|
|
|
979
1016
|
}
|
|
980
1017
|
|
|
981
1018
|
/** remove element */
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1019
|
+
dom.utils.removeItem(this.carrierWrapper);
|
|
1020
|
+
dom.utils.removeItem(this.context.get('toolbar._wrapper'));
|
|
1021
|
+
dom.utils.removeItem(this.context.get('toolbar.sub._wrapper'));
|
|
1022
|
+
dom.utils.removeItem(this.context.get('statusbar._wrapper'));
|
|
986
1023
|
this.applyFrameRoots((e) => {
|
|
987
|
-
|
|
1024
|
+
dom.utils.removeItem(e.get('topArea'));
|
|
988
1025
|
e.get('options').clear();
|
|
989
1026
|
e.clear();
|
|
990
1027
|
});
|
|
@@ -1007,7 +1044,7 @@ Editor.prototype = {
|
|
|
1007
1044
|
delete obj[k];
|
|
1008
1045
|
}
|
|
1009
1046
|
|
|
1010
|
-
obj = ['eventManager', 'char', 'component', 'format', 'html', 'menu', 'nodeTransform', '
|
|
1047
|
+
obj = ['eventManager', 'char', 'component', 'format', 'html', 'menu', 'nodeTransform', 'offset', 'selection', 'shortcuts', 'toolbar', 'ui', 'viewer'];
|
|
1011
1048
|
for (let i = 0, len = obj.length, c; i < len; i++) {
|
|
1012
1049
|
c = this[obj[i]];
|
|
1013
1050
|
for (const k in c) {
|
|
@@ -1031,8 +1068,9 @@ Editor.prototype = {
|
|
|
1031
1068
|
|
|
1032
1069
|
/** ----- private methods ----------------------------------------------------------------------------------------------------------------------------- */
|
|
1033
1070
|
/**
|
|
1071
|
+
* @private
|
|
1034
1072
|
* @description Set frameContext, frameOptions
|
|
1035
|
-
* @param {
|
|
1073
|
+
* @param {__se__FrameContext} rt Root target[key] FrameContext
|
|
1036
1074
|
*/
|
|
1037
1075
|
_setFrameInfo(rt) {
|
|
1038
1076
|
this.frameContext = rt;
|
|
@@ -1043,68 +1081,8 @@ Editor.prototype = {
|
|
|
1043
1081
|
},
|
|
1044
1082
|
|
|
1045
1083
|
/**
|
|
1046
|
-
* @description visible controllers
|
|
1047
|
-
* @param {boolean} value hidden/show
|
|
1048
|
-
* @param {boolean?} lineBreakShow Line break hidden/show (default: Follows the value "value".)
|
|
1049
1084
|
* @private
|
|
1050
|
-
*/
|
|
1051
|
-
_visibleControllers(value, lineBreakShow) {
|
|
1052
|
-
const visible = value ? '' : 'hidden';
|
|
1053
|
-
const breakerVisible = lineBreakShow ?? visible ? '' : 'hidden';
|
|
1054
|
-
|
|
1055
|
-
const cont = this.opendControllers;
|
|
1056
|
-
for (let i = 0, c; i < cont.length; i++) {
|
|
1057
|
-
c = cont[i];
|
|
1058
|
-
if (c.form) c.form.style.visibility = visible;
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
this._lineBreaker_t.style.visibility = breakerVisible;
|
|
1062
|
-
this._lineBreaker_b.style.visibility = breakerVisible;
|
|
1063
|
-
},
|
|
1064
|
-
|
|
1065
|
-
/**
|
|
1066
|
-
* @description Off current controllers
|
|
1067
|
-
* @private
|
|
1068
|
-
*/
|
|
1069
|
-
_offCurrentController() {
|
|
1070
|
-
this.__offControllers();
|
|
1071
|
-
this.component.__deselect();
|
|
1072
|
-
},
|
|
1073
|
-
|
|
1074
|
-
/**
|
|
1075
|
-
* @description Off controllers
|
|
1076
|
-
* @private
|
|
1077
|
-
*/
|
|
1078
|
-
__offControllers() {
|
|
1079
|
-
const cont = this.opendControllers;
|
|
1080
|
-
const fixedCont = [];
|
|
1081
|
-
for (let i = 0, c; i < cont.length; i++) {
|
|
1082
|
-
c = cont[i];
|
|
1083
|
-
if (c.fixed) {
|
|
1084
|
-
fixedCont.push(c);
|
|
1085
|
-
continue;
|
|
1086
|
-
}
|
|
1087
|
-
if (typeof c.inst.close === 'function') c.inst.close();
|
|
1088
|
-
if (c.form) c.form.style.display = 'none';
|
|
1089
|
-
}
|
|
1090
|
-
this.opendControllers = fixedCont;
|
|
1091
|
-
this.currentControllerName = '';
|
|
1092
|
-
this._antiBlur = false;
|
|
1093
|
-
},
|
|
1094
|
-
|
|
1095
|
-
/**
|
|
1096
|
-
* @description Off current modal
|
|
1097
|
-
* @private
|
|
1098
|
-
*/
|
|
1099
|
-
_offCurrentModal() {
|
|
1100
|
-
if (this.opendModal) {
|
|
1101
|
-
this.opendModal.close();
|
|
1102
|
-
}
|
|
1103
|
-
},
|
|
1104
|
-
|
|
1105
|
-
/**
|
|
1106
1085
|
* @description Focus to wysiwyg area using "native focus function"
|
|
1107
|
-
* @private
|
|
1108
1086
|
*/
|
|
1109
1087
|
_nativeFocus() {
|
|
1110
1088
|
this.selection.__focus();
|
|
@@ -1112,8 +1090,9 @@ Editor.prototype = {
|
|
|
1112
1090
|
},
|
|
1113
1091
|
|
|
1114
1092
|
/**
|
|
1115
|
-
* @description Check the components such as image and video and modify them according to the format.
|
|
1116
1093
|
* @private
|
|
1094
|
+
* @description Check the components such as image and video and modify them according to the format.
|
|
1095
|
+
* @param {boolean} loaded If true, the component is loaded.
|
|
1117
1096
|
*/
|
|
1118
1097
|
_checkComponents(loaded) {
|
|
1119
1098
|
for (let i = 0, len = this._fileInfoPluginsCheck.length; i < len; i++) {
|
|
@@ -1122,8 +1101,8 @@ Editor.prototype = {
|
|
|
1122
1101
|
},
|
|
1123
1102
|
|
|
1124
1103
|
/**
|
|
1125
|
-
* @description Initialize the information of the components.
|
|
1126
1104
|
* @private
|
|
1105
|
+
* @description Initialize the information of the components.
|
|
1127
1106
|
*/
|
|
1128
1107
|
_resetComponents() {
|
|
1129
1108
|
for (let i = 0, len = this._fileInfoPluginsReset.length; i < len; i++) {
|
|
@@ -1132,31 +1111,54 @@ Editor.prototype = {
|
|
|
1132
1111
|
},
|
|
1133
1112
|
|
|
1134
1113
|
/**
|
|
1114
|
+
* @private
|
|
1135
1115
|
* @description Initializ wysiwyg area (Only called from core._init)
|
|
1136
|
-
* @param {
|
|
1116
|
+
* @param {__se__FrameContext} e frameContext
|
|
1137
1117
|
* @param {string} value initial html string
|
|
1138
|
-
* @private
|
|
1139
1118
|
*/
|
|
1140
1119
|
_initWysiwygArea(e, value) {
|
|
1120
|
+
// set content
|
|
1141
1121
|
e.get('wysiwyg').innerHTML =
|
|
1142
|
-
this.html.clean(typeof value === 'string' ? value : (/^TEXTAREA$/i.test(e.get('originElement').nodeName) ? e.get('originElement').value : e.get('originElement').innerHTML) || '',
|
|
1143
|
-
|
|
1144
|
-
|
|
1122
|
+
this.html.clean(typeof value === 'string' ? value : (/^TEXTAREA$/i.test(e.get('originElement').nodeName) ? e.get('originElement').value : e.get('originElement').innerHTML) || '', {
|
|
1123
|
+
forceFormat: true,
|
|
1124
|
+
whitelist: null,
|
|
1125
|
+
blacklist: null,
|
|
1126
|
+
_freeCodeViewMode: this.options.get('freeCodeViewMode')
|
|
1127
|
+
}) || '<' + this.options.get('defaultLine') + '><br></' + this.options.get('defaultLine') + '>';
|
|
1128
|
+
|
|
1129
|
+
// char counter
|
|
1145
1130
|
if (e.has('charCounter')) e.get('charCounter').textContent = this.char.getLength();
|
|
1131
|
+
|
|
1132
|
+
// document type init
|
|
1133
|
+
if (this.options.get('type') === 'document') {
|
|
1134
|
+
e.set('documentType', new DocumentType(this, e));
|
|
1135
|
+
if (e.get('documentType').useHeader) {
|
|
1136
|
+
e.set('documentType-use-header', true);
|
|
1137
|
+
}
|
|
1138
|
+
if (e.get('documentType').usePage) {
|
|
1139
|
+
e.set('documentType-use-page', true);
|
|
1140
|
+
e.get('documentTypePageMirror').innerHTML = e.get('wysiwyg').innerHTML;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1146
1143
|
},
|
|
1147
1144
|
|
|
1148
1145
|
/**
|
|
1149
|
-
* @description Called when there are changes to tags in the wysiwyg region.
|
|
1150
1146
|
* @private
|
|
1147
|
+
* @description Called when there are changes to tags in the wysiwyg region.
|
|
1148
|
+
* @param {__se__FrameContext} fc - Frame context object
|
|
1151
1149
|
*/
|
|
1152
1150
|
_resourcesStateChange(fc) {
|
|
1153
1151
|
this._iframeAutoHeight(fc);
|
|
1154
1152
|
this._checkPlaceholder(fc);
|
|
1153
|
+
if (this.options.get('type') === 'document' && fc.get('documentType').usePage) {
|
|
1154
|
+
fc.get('documentTypePageMirror').innerHTML = fc.get('wysiwyg').innerHTML;
|
|
1155
|
+
}
|
|
1155
1156
|
},
|
|
1156
1157
|
|
|
1157
1158
|
/**
|
|
1158
|
-
* @description Modify the height value of the iframe when the height of the iframe is automatic.
|
|
1159
1159
|
* @private
|
|
1160
|
+
* @description Modify the height value of the iframe when the height of the iframe is automatic.
|
|
1161
|
+
* @param {__se__FrameContext} fc - Frame context object
|
|
1160
1162
|
*/
|
|
1161
1163
|
_iframeAutoHeight(fc) {
|
|
1162
1164
|
const autoFrame = fc.get('_iframeAuto');
|
|
@@ -1172,6 +1174,13 @@ Editor.prototype = {
|
|
|
1172
1174
|
}
|
|
1173
1175
|
},
|
|
1174
1176
|
|
|
1177
|
+
/**
|
|
1178
|
+
* @private
|
|
1179
|
+
* @description Call the "onResizeEditor" event
|
|
1180
|
+
* @param {__se__FrameContext} fc - Frame context object
|
|
1181
|
+
* @param {number} h - Height value
|
|
1182
|
+
* @param {ResizeObserverEntry} resizeObserverEntry - ResizeObserverEntry object
|
|
1183
|
+
*/
|
|
1175
1184
|
__callResizeFunction(fc, h, resizeObserverEntry) {
|
|
1176
1185
|
h =
|
|
1177
1186
|
h === -1
|
|
@@ -1183,11 +1192,17 @@ Editor.prototype = {
|
|
|
1183
1192
|
this.triggerEvent('onResizeEditor', { height: h, prevHeight: fc.get('_editorHeight'), frameContext: fc, observerEntry: resizeObserverEntry });
|
|
1184
1193
|
fc.set('_editorHeight', h);
|
|
1185
1194
|
}
|
|
1195
|
+
|
|
1196
|
+
// document type page
|
|
1197
|
+
if (fc.has('documentType-use-page')) {
|
|
1198
|
+
fc.get('documentType').resizePage();
|
|
1199
|
+
}
|
|
1186
1200
|
},
|
|
1187
1201
|
|
|
1188
1202
|
/**
|
|
1189
|
-
* @description Set display property when there is placeholder.
|
|
1190
1203
|
* @private
|
|
1204
|
+
* @description Set display property when there is placeholder.
|
|
1205
|
+
* @param {?__se__FrameContext=} fc - Frame context object, If null fc is this.frameContext
|
|
1191
1206
|
*/
|
|
1192
1207
|
_checkPlaceholder(fc) {
|
|
1193
1208
|
fc = fc || this.frameContext;
|
|
@@ -1208,8 +1223,9 @@ Editor.prototype = {
|
|
|
1208
1223
|
},
|
|
1209
1224
|
|
|
1210
1225
|
/**
|
|
1211
|
-
* @description Initializ editor
|
|
1212
1226
|
* @private
|
|
1227
|
+
* @description Initializ editor
|
|
1228
|
+
* @param {EditorInitOptions_editor} options Options
|
|
1213
1229
|
*/
|
|
1214
1230
|
__editorInit(options) {
|
|
1215
1231
|
this.applyFrameRoots((e) => {
|
|
@@ -1253,8 +1269,9 @@ Editor.prototype = {
|
|
|
1253
1269
|
},
|
|
1254
1270
|
|
|
1255
1271
|
/**
|
|
1256
|
-
* @description Initializ core variable
|
|
1257
1272
|
* @private
|
|
1273
|
+
* @description Initializ core variable
|
|
1274
|
+
* @param {EditorInitOptions_editor} options Options
|
|
1258
1275
|
*/
|
|
1259
1276
|
__init(options) {
|
|
1260
1277
|
// file components
|
|
@@ -1278,20 +1295,19 @@ Editor.prototype = {
|
|
|
1278
1295
|
['onKeyUp', []],
|
|
1279
1296
|
['onFocus', []],
|
|
1280
1297
|
['onBlur', []],
|
|
1281
|
-
['
|
|
1298
|
+
['onPaste', []],
|
|
1299
|
+
['onFilePasteAndDrop', []]
|
|
1282
1300
|
]);
|
|
1283
1301
|
this._fileManager.tags = [];
|
|
1284
1302
|
this._fileManager.pluginMap = {};
|
|
1285
1303
|
this._fileManager.tagAttrs = {};
|
|
1286
1304
|
|
|
1287
1305
|
const plugins = this.plugins;
|
|
1288
|
-
const isArray = Array.isArray;
|
|
1289
|
-
const shortcuts = this.options.get('shortcuts');
|
|
1290
1306
|
const filePluginRegExp = [];
|
|
1291
1307
|
let plugin;
|
|
1292
1308
|
for (const key in plugins) {
|
|
1293
|
-
this.registerPlugin(key, this._pluginCallButtons[key], options[key]
|
|
1294
|
-
this.registerPlugin(key, this._pluginCallButtons_sub[key], options[key]
|
|
1309
|
+
this.registerPlugin(key, this._pluginCallButtons[key], options[key]);
|
|
1310
|
+
this.registerPlugin(key, this._pluginCallButtons_sub[key], options[key]);
|
|
1295
1311
|
plugin = this.plugins[key];
|
|
1296
1312
|
|
|
1297
1313
|
// Filemanager
|
|
@@ -1299,7 +1315,7 @@ Editor.prototype = {
|
|
|
1299
1315
|
const fm = plugin.__fileManagement;
|
|
1300
1316
|
this._fileInfoPluginsCheck.push(fm._checkInfo.bind(fm));
|
|
1301
1317
|
this._fileInfoPluginsReset.push(fm._resetInfo.bind(fm));
|
|
1302
|
-
if (isArray(fm.tagNames)) {
|
|
1318
|
+
if (Array.isArray(fm.tagNames)) {
|
|
1303
1319
|
const tagNames = fm.tagNames;
|
|
1304
1320
|
this._fileManager.tags = this._fileManager.tags.concat(tagNames);
|
|
1305
1321
|
filePluginRegExp.push(key);
|
|
@@ -1317,7 +1333,7 @@ Editor.prototype = {
|
|
|
1317
1333
|
if (typeof plugin.constructor.component === 'function') {
|
|
1318
1334
|
this._componentManager.push(
|
|
1319
1335
|
function (launcher, element) {
|
|
1320
|
-
if (!(element = launcher.component?.call(this, element))) return null;
|
|
1336
|
+
if (!element || !(element = launcher.component?.call(this, element))) return null;
|
|
1321
1337
|
return {
|
|
1322
1338
|
target: element,
|
|
1323
1339
|
pluginName: launcher.key,
|
|
@@ -1344,6 +1360,24 @@ Editor.prototype = {
|
|
|
1344
1360
|
}
|
|
1345
1361
|
}
|
|
1346
1362
|
|
|
1363
|
+
if (this.options.get('buttons').has('pageBreak') || this.options.get('buttons_sub')?.has('pageBreak')) {
|
|
1364
|
+
this._componentManager.push((element) => {
|
|
1365
|
+
if (!element || !dom.utils.hasClass(element, 'se-page-break')) return null;
|
|
1366
|
+
return {
|
|
1367
|
+
target: element,
|
|
1368
|
+
launcher: {
|
|
1369
|
+
destroy: (target) => {
|
|
1370
|
+
const focusEl = target.previousElementSibling || target.nextElementSibling;
|
|
1371
|
+
dom.utils.removeItem(target);
|
|
1372
|
+
// focus
|
|
1373
|
+
this.focusEdge(focusEl);
|
|
1374
|
+
this.history.push(false);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
};
|
|
1378
|
+
});
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1347
1381
|
this._fileManager.regExp = new RegExp(`^(${this._fileManager.tags.join('|') || '\\^'})$`, 'i');
|
|
1348
1382
|
this._fileManager.pluginRegExp = new RegExp(`^(${filePluginRegExp.length === 0 ? '\\^' : filePluginRegExp.join('|')})$`, 'i');
|
|
1349
1383
|
|
|
@@ -1351,11 +1385,12 @@ Editor.prototype = {
|
|
|
1351
1385
|
delete this._pluginCallButtons_sub;
|
|
1352
1386
|
|
|
1353
1387
|
this.__cachingButtons();
|
|
1388
|
+
this.__cachingShortcuts();
|
|
1354
1389
|
},
|
|
1355
1390
|
|
|
1356
1391
|
/**
|
|
1357
|
-
* @description Caching basic buttons to use
|
|
1358
1392
|
* @private
|
|
1393
|
+
* @description Caching basic buttons to use
|
|
1359
1394
|
*/
|
|
1360
1395
|
__cachingButtons() {
|
|
1361
1396
|
const ctx = this.context;
|
|
@@ -1366,6 +1401,11 @@ Editor.prototype = {
|
|
|
1366
1401
|
}
|
|
1367
1402
|
},
|
|
1368
1403
|
|
|
1404
|
+
/**
|
|
1405
|
+
* @private
|
|
1406
|
+
* @description Set the disabled button list
|
|
1407
|
+
* - this._codeViewDisabledButtons, this._controllerOnDisabledButtons
|
|
1408
|
+
*/
|
|
1369
1409
|
__setDisabledButtons() {
|
|
1370
1410
|
const ctx = this.context;
|
|
1371
1411
|
|
|
@@ -1379,8 +1419,10 @@ Editor.prototype = {
|
|
|
1379
1419
|
},
|
|
1380
1420
|
|
|
1381
1421
|
/**
|
|
1382
|
-
* @description Save the current buttons
|
|
1383
1422
|
* @private
|
|
1423
|
+
* @description Save the current buttons
|
|
1424
|
+
* @param {Map<string, Element>} cmdButtons Command button map
|
|
1425
|
+
* @param {Element} tray Button tray
|
|
1384
1426
|
*/
|
|
1385
1427
|
__saveCommandButtons(cmdButtons, tray) {
|
|
1386
1428
|
const currentButtons = tray.querySelectorAll(COMMAND_BUTTONS);
|
|
@@ -1390,7 +1432,7 @@ Editor.prototype = {
|
|
|
1390
1432
|
const reverseKeys = this.reverseKeys;
|
|
1391
1433
|
|
|
1392
1434
|
for (let i = 0, len = currentButtons.length, e, c; i < len; i++) {
|
|
1393
|
-
e = currentButtons[i];
|
|
1435
|
+
e = /** @type {HTMLButtonElement} */ (currentButtons[i]);
|
|
1394
1436
|
c = e.getAttribute('data-command');
|
|
1395
1437
|
// command set
|
|
1396
1438
|
cmdButtons.set(c, e);
|
|
@@ -1400,6 +1442,27 @@ Editor.prototype = {
|
|
|
1400
1442
|
}
|
|
1401
1443
|
},
|
|
1402
1444
|
|
|
1445
|
+
/**
|
|
1446
|
+
* @private
|
|
1447
|
+
* @description Caches shortcut keys for commands.
|
|
1448
|
+
*/
|
|
1449
|
+
__cachingShortcuts() {
|
|
1450
|
+
const shortcuts = this.options.get('shortcuts');
|
|
1451
|
+
const reverseCommandArray = this.options.get('_reverseCommandArray');
|
|
1452
|
+
const keyMap = this.shortcutsKeyMap;
|
|
1453
|
+
const reverseKeys = this.reverseKeys;
|
|
1454
|
+
for (const key of Object.keys(shortcuts)) {
|
|
1455
|
+
if (!key.startsWith('_')) continue;
|
|
1456
|
+
CreateShortcuts('', null, shortcuts[key], keyMap, reverseCommandArray, reverseKeys);
|
|
1457
|
+
}
|
|
1458
|
+
},
|
|
1459
|
+
|
|
1460
|
+
/**
|
|
1461
|
+
* @private
|
|
1462
|
+
* @description Sets command target elements.
|
|
1463
|
+
* @param {string} cmd - The command identifier.
|
|
1464
|
+
* @param {HTMLButtonElement} target - The associated command button.
|
|
1465
|
+
*/
|
|
1403
1466
|
__setCommandTargets(cmd, target) {
|
|
1404
1467
|
if (!cmd || !target) return;
|
|
1405
1468
|
|
|
@@ -1413,6 +1476,13 @@ Editor.prototype = {
|
|
|
1413
1476
|
}
|
|
1414
1477
|
},
|
|
1415
1478
|
|
|
1479
|
+
/**
|
|
1480
|
+
* @private
|
|
1481
|
+
* @description Configures the document properties of an iframe editor.
|
|
1482
|
+
* @param {HTMLIFrameElement} frame - The editor iframe.
|
|
1483
|
+
* @param {Map<string, *>} originOptions - The original options.
|
|
1484
|
+
* @param {__se__FrameOptions} targetOptions - The new options.
|
|
1485
|
+
*/
|
|
1416
1486
|
__setIframeDocument(frame, originOptions, targetOptions) {
|
|
1417
1487
|
frame.setAttribute('scrolling', 'auto');
|
|
1418
1488
|
frame.contentDocument.head.innerHTML =
|
|
@@ -1420,9 +1490,14 @@ Editor.prototype = {
|
|
|
1420
1490
|
converter._setIframeStyleLinks(targetOptions.get('iframe_cssFileName')) +
|
|
1421
1491
|
converter._setAutoHeightStyle(targetOptions.get('height'));
|
|
1422
1492
|
frame.contentDocument.body.className = originOptions.get('_editableClass');
|
|
1423
|
-
frame.contentDocument.body.setAttribute('contenteditable', true);
|
|
1493
|
+
frame.contentDocument.body.setAttribute('contenteditable', 'true');
|
|
1424
1494
|
},
|
|
1425
1495
|
|
|
1496
|
+
/**
|
|
1497
|
+
* @private
|
|
1498
|
+
* @description Set the FrameContext parameters and options
|
|
1499
|
+
* @param {__se__FrameContext} e - Frame context object
|
|
1500
|
+
*/
|
|
1426
1501
|
__setEditorParams(e) {
|
|
1427
1502
|
const frameOptions = e.get('options');
|
|
1428
1503
|
const _w = this._w;
|
|
@@ -1463,10 +1538,16 @@ Editor.prototype = {
|
|
|
1463
1538
|
}
|
|
1464
1539
|
},
|
|
1465
1540
|
|
|
1541
|
+
/**
|
|
1542
|
+
* @private
|
|
1543
|
+
* @description Registers and initializes editor classes.
|
|
1544
|
+
*/
|
|
1466
1545
|
__registerClass() {
|
|
1467
1546
|
// use events
|
|
1468
|
-
this.events = { ...Events
|
|
1547
|
+
this.events = { ...Events, ...this.options.get('events') };
|
|
1469
1548
|
this.triggerEvent = async (eventName, eventData) => {
|
|
1549
|
+
// [iframe] wysiwyg is disabled, the event is not called.
|
|
1550
|
+
if (eventData?.frameContext?.get('wysiwyg').getAttribute('contenteditable') === 'false') return false;
|
|
1470
1551
|
const eventHandler = this.events[eventName];
|
|
1471
1552
|
if (typeof eventHandler === 'function') {
|
|
1472
1553
|
return await eventHandler({ editor: this, ...eventData });
|
|
@@ -1483,10 +1564,9 @@ Editor.prototype = {
|
|
|
1483
1564
|
// util classes
|
|
1484
1565
|
this.offset = new Offset(this);
|
|
1485
1566
|
this.shortcuts = new Shortcuts(this);
|
|
1486
|
-
this.notice = new Notice(this);
|
|
1487
1567
|
// main classes
|
|
1488
1568
|
this.toolbar = new Toolbar(this, { keyName: 'toolbar', balloon: this.isBalloon, balloonAlways: this.isBalloonAlways, inline: this.isInline, res: this._responsiveButtons });
|
|
1489
|
-
if (this.options.has('_subMode'))
|
|
1569
|
+
if (this.options.has('_subMode')) {
|
|
1490
1570
|
this.subToolbar = new Toolbar(this, {
|
|
1491
1571
|
keyName: 'toolbar.sub',
|
|
1492
1572
|
balloon: this.isSubBalloon,
|
|
@@ -1494,13 +1574,15 @@ Editor.prototype = {
|
|
|
1494
1574
|
inline: false,
|
|
1495
1575
|
res: this._responsiveButtons_sub
|
|
1496
1576
|
});
|
|
1497
|
-
|
|
1577
|
+
}
|
|
1578
|
+
this.selection = new Selection_(this);
|
|
1498
1579
|
this.html = new HTML(this);
|
|
1499
1580
|
this.nodeTransform = new NodeTransform(this);
|
|
1500
1581
|
this.component = new Component(this);
|
|
1501
1582
|
this.format = new Format(this);
|
|
1502
1583
|
this.menu = new Menu(this);
|
|
1503
1584
|
this.char = new Char(this);
|
|
1585
|
+
this.ui = new UI(this);
|
|
1504
1586
|
this.viewer = new Viewer(this);
|
|
1505
1587
|
|
|
1506
1588
|
// register classes to the eventManager
|
|
@@ -1512,26 +1594,39 @@ Editor.prototype = {
|
|
|
1512
1594
|
ClassInjector.call(this.html, this);
|
|
1513
1595
|
ClassInjector.call(this.menu, this);
|
|
1514
1596
|
ClassInjector.call(this.nodeTransform, this);
|
|
1597
|
+
ClassInjector.call(this.offset, this);
|
|
1515
1598
|
ClassInjector.call(this.selection, this);
|
|
1599
|
+
ClassInjector.call(this.shortcuts, this);
|
|
1516
1600
|
ClassInjector.call(this.toolbar, this);
|
|
1601
|
+
ClassInjector.call(this.ui, this);
|
|
1517
1602
|
ClassInjector.call(this.viewer, this);
|
|
1518
1603
|
if (this.options.has('_subMode')) ClassInjector.call(this.subToolbar, this);
|
|
1519
1604
|
|
|
1520
1605
|
// delete self reference
|
|
1521
|
-
delete this.
|
|
1522
|
-
delete this.
|
|
1523
|
-
delete this.
|
|
1524
|
-
delete this.
|
|
1525
|
-
delete this.
|
|
1526
|
-
delete this.
|
|
1527
|
-
delete this.
|
|
1528
|
-
delete this.
|
|
1529
|
-
delete this.
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1606
|
+
delete this.eventManager['eventManager'];
|
|
1607
|
+
delete this.char['char'];
|
|
1608
|
+
delete this.component['component'];
|
|
1609
|
+
delete this.format['format'];
|
|
1610
|
+
delete this.html['html'];
|
|
1611
|
+
delete this.menu['menu'];
|
|
1612
|
+
delete this.nodeTransform['nodeTransform'];
|
|
1613
|
+
delete this.offset['offset'];
|
|
1614
|
+
delete this.selection['selection'];
|
|
1615
|
+
delete this.shortcuts['shortcuts'];
|
|
1616
|
+
delete this.toolbar['toolbar'];
|
|
1617
|
+
delete this.ui['ui'];
|
|
1618
|
+
delete this.viewer['viewer'];
|
|
1619
|
+
if (this.subToolbar) delete this.subToolbar['subToolbar'];
|
|
1620
|
+
|
|
1621
|
+
this._responsiveButtons = this._responsiveButtons_sub = null;
|
|
1533
1622
|
},
|
|
1534
1623
|
|
|
1624
|
+
/**
|
|
1625
|
+
* @private
|
|
1626
|
+
* @description Creates the editor instance and initializes components.
|
|
1627
|
+
* @param {EditorInitOptions_editor} originOptions - The initial editor options.
|
|
1628
|
+
* @returns {Promise<void>}
|
|
1629
|
+
*/
|
|
1535
1630
|
async __Create(originOptions) {
|
|
1536
1631
|
// set modes
|
|
1537
1632
|
this.isInline = /inline/i.test(this.options.get('mode'));
|
|
@@ -1570,6 +1665,18 @@ Editor.prototype = {
|
|
|
1570
1665
|
|
|
1571
1666
|
this.applyFrameRoots((e) => {
|
|
1572
1667
|
e.get('wrapper').appendChild(e.get('wysiwygFrame'));
|
|
1668
|
+
|
|
1669
|
+
// document type
|
|
1670
|
+
if (e.get('documentTypeInner')) {
|
|
1671
|
+
if (this.options.get('_rtl')) e.get('wrapper').appendChild(e.get('documentTypeInner'));
|
|
1672
|
+
else e.get('wrapper').insertBefore(e.get('documentTypeInner'), e.get('wysiwygFrame'));
|
|
1673
|
+
}
|
|
1674
|
+
if (e.get('documentTypePage')) {
|
|
1675
|
+
if (this.options.get('_rtl')) e.get('wrapper').insertBefore(e.get('documentTypePage'), e.get('wysiwygFrame'));
|
|
1676
|
+
else e.get('wrapper').appendChild(e.get('documentTypePage'));
|
|
1677
|
+
// page mirror
|
|
1678
|
+
e.get('wrapper').appendChild(e.get('documentTypePageMirror'));
|
|
1679
|
+
}
|
|
1573
1680
|
});
|
|
1574
1681
|
|
|
1575
1682
|
if (iframePromises.length > 0) {
|
|
@@ -1590,7 +1697,7 @@ function GetResetDiffKey(key) {
|
|
|
1590
1697
|
function CheckResetKeys(keys, plugins, root) {
|
|
1591
1698
|
for (let i = 0, len = keys.length, k; i < len; i++) {
|
|
1592
1699
|
k = keys[i];
|
|
1593
|
-
if (
|
|
1700
|
+
if (OPTION_FIXED_FLAG[k] === 'fixed' || (plugins && plugins[k])) {
|
|
1594
1701
|
console.warn(`[SUNEDITOR.warn.resetOptions] "[${root + k}]" options not available in resetOptions have no effect.`);
|
|
1595
1702
|
keys.splice(i--, 1);
|
|
1596
1703
|
len--;
|