suneditor 3.0.0-beta.1 → 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 +166 -29
- package/README.md +13 -1
- package/dist/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +13 -5
- package/src/assets/{variables.css → design/color.css} +34 -58
- 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/suneditor-contents.css +1 -1
- package/src/assets/suneditor.css +24 -17
- package/src/core/base/eventHandlers/handler_ww_key_input.js +15 -15
- package/src/core/base/eventHandlers/handler_ww_mouse.js +1 -1
- package/src/core/base/eventManager.js +21 -9
- package/src/core/class/component.js +21 -11
- package/src/core/class/menu.js +19 -0
- package/src/core/editor.js +3 -3
- package/src/core/section/actives.js +42 -4
- package/src/core/section/constructor.js +116 -41
- package/src/core/section/documentType.js +2 -2
- package/src/events.js +13 -1
- package/src/helper/dom/domCheck.js +10 -0
- package/src/modules/Figure.js +6 -6
- package/src/modules/FileManager.js +1 -1
- package/src/plugins/command/fileUpload.js +3 -3
- package/src/plugins/dropdown/table.js +51 -18
- package/src/plugins/modal/audio.js +2 -2
- package/src/plugins/modal/embed.js +2 -2
- package/src/plugins/modal/image.js +3 -3
- package/src/plugins/modal/math.js +2 -2
- package/src/plugins/modal/video.js +1 -1
- package/src/plugins/popup/anchor.js +1 -1
- package/src/suneditor.js +1 -1
- package/src/themes/dark.css +78 -45
- package/types/core/base/eventManager.d.ts +7 -0
- package/types/core/class/component.d.ts +12 -3
- package/types/core/class/menu.d.ts +8 -0
- package/types/core/section/constructor.d.ts +160 -149
- package/types/events.d.ts +1 -0
- package/types/helper/dom/domCheck.d.ts +7 -0
- package/types/helper/index.d.ts +1 -0
- package/types/index.d.ts +1 -1
- package/types/plugins/dropdown/table.d.ts +1 -0
- package/.eslintignore +0 -7
- package/.eslintrc.json +0 -81
- /package/src/assets/icons/{_default.js → defaultIcons.js} +0 -0
- /package/types/assets/icons/{_default.d.ts → defaultIcons.d.ts} +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import CoreInjector from '../../editorInjector/_core';
|
|
6
|
-
import { dom, env, numbers, unicode, keyCodeMap } from '../../helper';
|
|
6
|
+
import { dom, env, numbers, unicode, keyCodeMap, converter } from '../../helper';
|
|
7
7
|
import { Figure, _DragHandle } from '../../modules';
|
|
8
8
|
|
|
9
9
|
const { _w, ON_OVER_COMPONENT, isMobile } = env;
|
|
@@ -220,12 +220,10 @@ Component.prototype = {
|
|
|
220
220
|
* @description The component(media, file component, table, etc) is selected and the resizing module is called.
|
|
221
221
|
* @param {Node} element Target element
|
|
222
222
|
* @param {string} pluginName The plugin name for the selected target.
|
|
223
|
-
* @param {
|
|
224
|
-
* @param {boolean} [
|
|
223
|
+
* @param {Object} [options] Options
|
|
224
|
+
* @param {boolean} [options.isInput=false] Whether the target is an input component.(table)
|
|
225
225
|
*/
|
|
226
|
-
select(element, pluginName, isInput
|
|
227
|
-
if (!force && element === this.currentTarget && this.editor.currentControllerName === this.currentPluginName) return;
|
|
228
|
-
|
|
226
|
+
select(element, pluginName, { isInput = false } = {}) {
|
|
229
227
|
const info = this.get(element);
|
|
230
228
|
if (!info || dom.check.isUneditable(dom.query.getParentElement(element, this.is.bind(this))) || dom.check.isUneditable(element)) return false;
|
|
231
229
|
|
|
@@ -267,7 +265,10 @@ Component.prototype = {
|
|
|
267
265
|
if (__overInfo !== ON_OVER_COMPONENT) this.__addGlobalEvent();
|
|
268
266
|
if (!info.isFile) this.__addNotFileGlobalEvent();
|
|
269
267
|
}, 0);
|
|
270
|
-
|
|
268
|
+
|
|
269
|
+
converter.debounce(() => {
|
|
270
|
+
dom.utils.addClass(info.container, 'se-component-selected');
|
|
271
|
+
}, 0)();
|
|
271
272
|
|
|
272
273
|
if (!isBreakComponent && __overInfo !== ON_OVER_COMPONENT) {
|
|
273
274
|
// set zero width space
|
|
@@ -299,7 +300,7 @@ Component.prototype = {
|
|
|
299
300
|
dragHandle.style.opacity = 0;
|
|
300
301
|
dragHandle.style.width = w + 'px';
|
|
301
302
|
dragHandle.style.height = h + 'px';
|
|
302
|
-
dragHandle.style.top = top
|
|
303
|
+
dragHandle.style.top = top + 'px';
|
|
303
304
|
dragHandle.style.left = left + 'px';
|
|
304
305
|
|
|
305
306
|
_DragHandle.set('__dragHandler', dragHandle);
|
|
@@ -416,8 +417,15 @@ Component.prototype = {
|
|
|
416
417
|
this.editor._preventBlur = false;
|
|
417
418
|
_DragHandle.set('__overInfo', null);
|
|
418
419
|
this._removeDragEvent();
|
|
419
|
-
|
|
420
|
-
|
|
420
|
+
|
|
421
|
+
if (this.currentInfo) {
|
|
422
|
+
const infoContainer = this.currentInfo.container;
|
|
423
|
+
const infoCover = this.currentInfo.cover;
|
|
424
|
+
converter.debounce(() => {
|
|
425
|
+
dom.utils.removeClass(infoContainer, 'se-component-selected');
|
|
426
|
+
dom.utils.removeClass(infoCover, 'se-figure-over-selected');
|
|
427
|
+
}, 0)();
|
|
428
|
+
}
|
|
421
429
|
|
|
422
430
|
const { frameContext } = this.editor;
|
|
423
431
|
frameContext.get('lineBreaker_t').style.display = frameContext.get('lineBreaker_b').style.display = 'none';
|
|
@@ -483,6 +491,7 @@ Component.prototype = {
|
|
|
483
491
|
else dom.utils.addClass(lb_t, 'se-on-selected');
|
|
484
492
|
|
|
485
493
|
t_style.display = 'block';
|
|
494
|
+
t_style.visibility = '';
|
|
486
495
|
} else {
|
|
487
496
|
t_style.display = 'none';
|
|
488
497
|
}
|
|
@@ -508,6 +517,7 @@ Component.prototype = {
|
|
|
508
517
|
else dom.utils.addClass(lb_b, 'se-on-selected');
|
|
509
518
|
|
|
510
519
|
b_style.display = 'block';
|
|
520
|
+
b_style.visibility = '';
|
|
511
521
|
} else {
|
|
512
522
|
b_style.display = 'none';
|
|
513
523
|
}
|
|
@@ -637,7 +647,7 @@ function OnDragClick(e) {
|
|
|
637
647
|
|
|
638
648
|
const dragInst = _DragHandle.get('__dragInst');
|
|
639
649
|
this._removeDragEvent();
|
|
640
|
-
this.select(dragInst.currentTarget, dragInst.currentPluginName
|
|
650
|
+
this.select(dragInst.currentTarget, dragInst.currentPluginName);
|
|
641
651
|
}
|
|
642
652
|
|
|
643
653
|
/**
|
package/src/core/class/menu.js
CHANGED
|
@@ -45,6 +45,10 @@ function Menu(editor) {
|
|
|
45
45
|
this._bindClose_dropdown_key = null;
|
|
46
46
|
this._bindClose_cons_mouse = null;
|
|
47
47
|
this.currentDropdownPlugin = null;
|
|
48
|
+
|
|
49
|
+
// eventManager member (viewport)
|
|
50
|
+
this.__menuBtn = null;
|
|
51
|
+
this.__menuContainer = null;
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
Menu.prototype = {
|
|
@@ -115,6 +119,8 @@ Menu.prototype = {
|
|
|
115
119
|
this.__removeGlobalEvent();
|
|
116
120
|
this.index = -1;
|
|
117
121
|
this.menus = [];
|
|
122
|
+
this.__menuBtn = null;
|
|
123
|
+
this.__menuContainer = null;
|
|
118
124
|
|
|
119
125
|
if (this.currentDropdown) {
|
|
120
126
|
this.currentDropdownName = '';
|
|
@@ -187,6 +193,19 @@ Menu.prototype = {
|
|
|
187
193
|
this.offset.setRelPosition(menu, this.carrierWrapper, element.parentElement, dom.query.getParentElement(element, '.se-toolbar'), false);
|
|
188
194
|
|
|
189
195
|
menu.style.visibility = '';
|
|
196
|
+
|
|
197
|
+
this.__menuBtn = element;
|
|
198
|
+
this.__menuContainer = menu;
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* @private
|
|
203
|
+
* @this {MenuThis}
|
|
204
|
+
* @description Restore the last menu position using previously stored button and menu elements.
|
|
205
|
+
*/
|
|
206
|
+
_restoreMenuPosition() {
|
|
207
|
+
if (!this.__menuBtn || !this.__menuContainer) return;
|
|
208
|
+
this._setMenuPosition(this.__menuBtn, this.__menuContainer);
|
|
190
209
|
},
|
|
191
210
|
|
|
192
211
|
/**
|
package/src/core/editor.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { env, converter, dom, numbers } from '../helper';
|
|
2
|
-
import Constructor, { InitOptions, UpdateButton, CreateShortcuts, CreateStatusbar,
|
|
2
|
+
import Constructor, { InitOptions, UpdateButton, CreateShortcuts, CreateStatusbar, OPTION_FIXED_FLAG } from './section/constructor';
|
|
3
3
|
import { UpdateStatusbarContext } from './section/context';
|
|
4
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';
|
|
@@ -971,7 +971,7 @@ Editor.prototype = {
|
|
|
971
971
|
|
|
972
972
|
const fileComponentInfo = this.component.get(focusEl);
|
|
973
973
|
if (fileComponentInfo) {
|
|
974
|
-
this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName
|
|
974
|
+
this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName);
|
|
975
975
|
} else if (focusEl) {
|
|
976
976
|
if (focusEl.nodeType !== 3) {
|
|
977
977
|
focusEl = dom.query.getEdgeChild(
|
|
@@ -1697,7 +1697,7 @@ function GetResetDiffKey(key) {
|
|
|
1697
1697
|
function CheckResetKeys(keys, plugins, root) {
|
|
1698
1698
|
for (let i = 0, len = keys.length, k; i < len; i++) {
|
|
1699
1699
|
k = keys[i];
|
|
1700
|
-
if (
|
|
1700
|
+
if (OPTION_FIXED_FLAG[k] === 'fixed' || (plugins && plugins[k])) {
|
|
1701
1701
|
console.warn(`[SUNEDITOR.warn.resetOptions] "[${root + k}]" options not available in resetOptions have no effect.`);
|
|
1702
1702
|
keys.splice(i--, 1);
|
|
1703
1703
|
len--;
|
|
@@ -52,11 +52,49 @@ export const BASIC_COMMANDS = ACTIVE_EVENT_COMMANDS.concat(['undo', 'redo', 'sav
|
|
|
52
52
|
export function SELECT_ALL(editor) {
|
|
53
53
|
editor.ui._offCurrentController();
|
|
54
54
|
editor.menu.containerOff();
|
|
55
|
-
const figcaption = dom.query.getParentElement(editor.selection.getNode(), 'FIGCAPTION');
|
|
56
|
-
const selectArea = figcaption || editor.frameContext.get('wysiwyg');
|
|
57
55
|
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
// check all tags
|
|
57
|
+
const ww = editor.frameContext.get('wysiwyg');
|
|
58
|
+
let prevScopeTag = null;
|
|
59
|
+
let prevScopeTagName = '';
|
|
60
|
+
const scopeSelectionTags = editor.options.get('scopeSelectionTags');
|
|
61
|
+
const range = editor.selection.getRange();
|
|
62
|
+
if (!range.collapsed) {
|
|
63
|
+
let commonNode = range.commonAncestorContainer;
|
|
64
|
+
let commonNodeName = commonNode.nodeName?.toLowerCase();
|
|
65
|
+
|
|
66
|
+
while (commonNode && ((!commonNode.nextSibling && !commonNode.previousSibling && !scopeSelectionTags.includes(commonNodeName)) || dom.check.isContentLess(commonNodeName)) && commonNode !== ww) {
|
|
67
|
+
commonNode = commonNode.parentElement;
|
|
68
|
+
commonNodeName = commonNode.nodeName?.toLowerCase();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (scopeSelectionTags.includes(commonNodeName)) {
|
|
72
|
+
prevScopeTag = commonNode;
|
|
73
|
+
prevScopeTagName = commonNodeName;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// select all
|
|
78
|
+
const scopeTagList = scopeSelectionTags.filter((tagName) => tagName !== prevScopeTagName);
|
|
79
|
+
const scopeBaseTag = dom.query.getParentElement(prevScopeTag || editor.selection.getNode(), (current) => scopeTagList.includes(current.nodeName?.toLowerCase()));
|
|
80
|
+
const selectArea = scopeBaseTag || ww;
|
|
81
|
+
|
|
82
|
+
let first =
|
|
83
|
+
dom.query.getEdgeChild(
|
|
84
|
+
dom.query.getEdgeChild(selectArea, (current) => !dom.check.isContentLess(current), false),
|
|
85
|
+
(current) => {
|
|
86
|
+
return current.childNodes.length === 0 || current.nodeType === 3 || dom.check.isTable(current);
|
|
87
|
+
},
|
|
88
|
+
false
|
|
89
|
+
) || selectArea.firstChild;
|
|
90
|
+
let last =
|
|
91
|
+
dom.query.getEdgeChild(
|
|
92
|
+
selectArea.lastChild,
|
|
93
|
+
(current) => {
|
|
94
|
+
return current.childNodes.length === 0 || current.nodeType === 3 || dom.check.isTable(current);
|
|
95
|
+
},
|
|
96
|
+
true
|
|
97
|
+
) || selectArea.lastChild;
|
|
60
98
|
|
|
61
99
|
if (!first || !last) return;
|
|
62
100
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import _icons from '../../assets/icons/
|
|
1
|
+
import _icons from '../../assets/icons/defaultIcons';
|
|
2
2
|
import _defaultLang from '../../langs/en';
|
|
3
3
|
import { CreateContext, CreateFrameContext } from './context';
|
|
4
4
|
import { dom, numbers, converter, env } from '../../helper';
|
|
@@ -24,6 +24,9 @@ const DEFAULT_ELEMENT_WHITELIST =
|
|
|
24
24
|
'p|pre|blockquote|h1|h2|h3|h4|h5|h6|ol|ul|li|hr|figure|figcaption|img|iframe|audio|video|source|table|thead|tbody|tr|th|td|caption|a|b|strong|var|i|em|u|ins|s|span|strike|del|sub|sup|code|svg|path|details|summary';
|
|
25
25
|
const DEFAULT_TEXT_STYLE_TAGS = 'strong|span|font|b|var|i|em|u|ins|s|strike|del|sub|sup|mark|a|label|code|summary';
|
|
26
26
|
|
|
27
|
+
/* scopeSelectionTags */
|
|
28
|
+
const DEFAULT_SCOPE_SELECTION_TAGS = 'td|table|li|ol|ul|pre|figcaption|blockquote|dl|dt|dd';
|
|
29
|
+
|
|
27
30
|
const _video_audio_attr = '|controls|autoplay|loop|muted|poster|preload|playsinline|volume|crossorigin|disableRemotePlayback|controlsList';
|
|
28
31
|
const _iframe_attr = '|allowfullscreen|sandbox|loading|allow|referrerpolicy|frameborder|scrolling';
|
|
29
32
|
const DEFAULT_ATTRIBUTE_WHITELIST = 'contenteditable|target|href|title|download|rel|src|alt|class|type|colspan|rowspan' + _video_audio_attr + _iframe_attr;
|
|
@@ -69,42 +72,6 @@ const DEFAULT_CONTENT_STYLES =
|
|
|
69
72
|
|
|
70
73
|
const RETAIN_STYLE_MODE = ['repeat', 'always', 'none'];
|
|
71
74
|
|
|
72
|
-
export const RO_UNAVAILABD = [
|
|
73
|
-
'mode',
|
|
74
|
-
'type',
|
|
75
|
-
'externalLibs',
|
|
76
|
-
'iframe',
|
|
77
|
-
'convertTextTags',
|
|
78
|
-
'textStyleTags',
|
|
79
|
-
'fontSizeUnits',
|
|
80
|
-
'spanStyles',
|
|
81
|
-
'lineStyles',
|
|
82
|
-
'tagStyles',
|
|
83
|
-
'reverseCommands',
|
|
84
|
-
'shortcutsDisable',
|
|
85
|
-
'shortcuts',
|
|
86
|
-
'buttonList',
|
|
87
|
-
'subToolbar',
|
|
88
|
-
'toolbar_container',
|
|
89
|
-
'statusbar_container',
|
|
90
|
-
'elementWhitelist',
|
|
91
|
-
'elementBlacklist',
|
|
92
|
-
'attributeWhitelist',
|
|
93
|
-
'attributeBlacklist',
|
|
94
|
-
'defaultLine',
|
|
95
|
-
'formatClosureBrLine',
|
|
96
|
-
'formatBrLine',
|
|
97
|
-
'formatLine',
|
|
98
|
-
'formatClosureBlock',
|
|
99
|
-
'formatBlock',
|
|
100
|
-
'__defaultElementWhitelist',
|
|
101
|
-
'__defaultAttributeWhitelist',
|
|
102
|
-
'__listCommonStyle',
|
|
103
|
-
'icons',
|
|
104
|
-
'lang',
|
|
105
|
-
'codeMirror'
|
|
106
|
-
];
|
|
107
|
-
|
|
108
75
|
/**
|
|
109
76
|
* @typedef {Object} EditorFrameOptions
|
|
110
77
|
* @property {string} [value=""] - Initial value for the editor.
|
|
@@ -185,6 +152,7 @@ export const RO_UNAVAILABD = [
|
|
|
185
152
|
* - Formats that include "line", such as "Quote", still operate on a "line" basis.
|
|
186
153
|
* - ● suneditor processes work in "line" units.
|
|
187
154
|
* - ● When set to "br", performance may decrease when editing a lot of data.
|
|
155
|
+
* @property {Array<string>} [scopeSelectionTags=["td", "table", "li", "ol", "ul", "pre", "figcaption", "blockquote", "dl", "dt", "dd"]] - Tags treated as whole units when selecting all content.
|
|
188
156
|
* @property {string} [__defaultElementWhitelist="br|div"] - Default allowed HTML elements. The default values are maintained.
|
|
189
157
|
* @property {string} [elementWhitelist=""] - Allowed HTML elements. Delimiter: "|" (e.g. "p|div", "*").
|
|
190
158
|
* @property {string} [elementBlacklist=""] - Disallowed HTML elements. Delimiter: "|" (e.g. "script|style").
|
|
@@ -248,13 +216,119 @@ export const RO_UNAVAILABD = [
|
|
|
248
216
|
* - For example, when changing the font size or color of a list item (`<li>`),
|
|
249
217
|
* - these styles will be applied to the `<li>` tag instead of wrapping the content inside additional tags.
|
|
250
218
|
* @property {Object<string, *>} [externalLibs] - External libraries like CodeMirror or MathJax.
|
|
251
|
-
*
|
|
219
|
+
*
|
|
220
|
+
* @property {Object<string, *>} [Dynamic_pluginOptions] - Dynamic plugin options, where the key is the plugin name and the value is its configuration.
|
|
252
221
|
*/
|
|
253
222
|
|
|
254
223
|
/**
|
|
255
224
|
* @typedef {EditorBaseOptions & EditorFrameOptions} EditorInitOptions
|
|
256
225
|
*/
|
|
257
226
|
|
|
227
|
+
/**
|
|
228
|
+
* @description For all EditorInitOptions keys, only boolean | null values are allowed.
|
|
229
|
+
* - 'fixed' → Immutable / null → Resettable.
|
|
230
|
+
* @type {Partial<Record<keyof EditorInitOptions, "fixed" | true>>}
|
|
231
|
+
*/
|
|
232
|
+
export const OPTION_FIXED_FLAG = {
|
|
233
|
+
value: 'fixed',
|
|
234
|
+
placeholder: 'fixed',
|
|
235
|
+
editableFrameAttributes: null,
|
|
236
|
+
width: null,
|
|
237
|
+
minWidth: null,
|
|
238
|
+
maxWidth: null,
|
|
239
|
+
height: null,
|
|
240
|
+
minHeight: null,
|
|
241
|
+
maxHeight: null,
|
|
242
|
+
editorStyle: null,
|
|
243
|
+
iframe: 'fixed',
|
|
244
|
+
iframe_fullPage: null,
|
|
245
|
+
iframe_attributes: null,
|
|
246
|
+
iframe_cssFileName: null,
|
|
247
|
+
statusbar: null,
|
|
248
|
+
statusbar_showPathLabel: null,
|
|
249
|
+
statusbar_resizeEnable: null,
|
|
250
|
+
charCounter: null,
|
|
251
|
+
charCounter_max: null,
|
|
252
|
+
charCounter_label: null,
|
|
253
|
+
charCounter_type: null,
|
|
254
|
+
plugins: null,
|
|
255
|
+
excludedPlugins: null,
|
|
256
|
+
buttonList: 'fixed',
|
|
257
|
+
v2Migration: null,
|
|
258
|
+
strictMode: null,
|
|
259
|
+
mode: 'fixed',
|
|
260
|
+
type: 'fixed',
|
|
261
|
+
theme: null,
|
|
262
|
+
lang: 'fixed',
|
|
263
|
+
fontSizeUnits: 'fixed',
|
|
264
|
+
allowedClassName: null,
|
|
265
|
+
closeModalOutsideClick: null,
|
|
266
|
+
copyFormatKeepOn: null,
|
|
267
|
+
syncTabIndent: null,
|
|
268
|
+
tabDisable: null,
|
|
269
|
+
autoLinkify: null,
|
|
270
|
+
autoStyleify: null,
|
|
271
|
+
scrollToOptions: null,
|
|
272
|
+
componentScrollToOptions: null,
|
|
273
|
+
retainStyleMode: null,
|
|
274
|
+
allowedExtraTags: null,
|
|
275
|
+
events: null,
|
|
276
|
+
__textStyleTags: 'fixed',
|
|
277
|
+
textStyleTags: 'fixed',
|
|
278
|
+
convertTextTags: 'fixed',
|
|
279
|
+
__tagStyles: null,
|
|
280
|
+
tagStyles: 'fixed',
|
|
281
|
+
spanStyles: 'fixed',
|
|
282
|
+
lineStyles: 'fixed',
|
|
283
|
+
textDirection: null,
|
|
284
|
+
reverseButtons: null,
|
|
285
|
+
historyStackDelayTime: null,
|
|
286
|
+
lineAttrReset: null,
|
|
287
|
+
printClass: null,
|
|
288
|
+
defaultLine: 'fixed',
|
|
289
|
+
defaultLineBreakFormat: null,
|
|
290
|
+
scopeSelectionTags: null,
|
|
291
|
+
__defaultElementWhitelist: 'fixed',
|
|
292
|
+
elementWhitelist: 'fixed',
|
|
293
|
+
elementBlacklist: 'fixed',
|
|
294
|
+
__defaultAttributeWhitelist: 'fixed',
|
|
295
|
+
attributeWhitelist: 'fixed',
|
|
296
|
+
attributeBlacklist: 'fixed',
|
|
297
|
+
__defaultFormatLine: null,
|
|
298
|
+
formatLine: 'fixed',
|
|
299
|
+
__defaultFormatBrLine: null,
|
|
300
|
+
formatBrLine: 'fixed',
|
|
301
|
+
__defaultFormatClosureBrLine: 'fixed',
|
|
302
|
+
formatClosureBrLine: 'fixed',
|
|
303
|
+
__defaultFormatBlock: null,
|
|
304
|
+
formatBlock: 'fixed',
|
|
305
|
+
__defaultFormatClosureBlock: null,
|
|
306
|
+
formatClosureBlock: 'fixed',
|
|
307
|
+
allowedEmptyTags: null,
|
|
308
|
+
toolbar_width: null,
|
|
309
|
+
toolbar_container: 'fixed',
|
|
310
|
+
toolbar_sticky: null,
|
|
311
|
+
toolbar_hide: null,
|
|
312
|
+
subToolbar: 'fixed',
|
|
313
|
+
statusbar_container: 'fixed',
|
|
314
|
+
shortcutsHint: null,
|
|
315
|
+
shortcutsDisable: 'fixed',
|
|
316
|
+
shortcuts: 'fixed',
|
|
317
|
+
fullScreenOffset: null,
|
|
318
|
+
previewTemplate: null,
|
|
319
|
+
printTemplate: null,
|
|
320
|
+
componentAutoSelect: null,
|
|
321
|
+
defaultUrlProtocol: null,
|
|
322
|
+
allUsedStyles: null,
|
|
323
|
+
toastMessageTime: null,
|
|
324
|
+
icons: 'fixed',
|
|
325
|
+
freeCodeViewMode: null,
|
|
326
|
+
__lineFormatFilter: null,
|
|
327
|
+
__pluginRetainFilter: null,
|
|
328
|
+
__listCommonStyle: 'fixed',
|
|
329
|
+
externalLibs: 'fixed'
|
|
330
|
+
};
|
|
331
|
+
|
|
258
332
|
/**
|
|
259
333
|
* @description Creates a new SunEditor instance with specified options.
|
|
260
334
|
* @param {Array<{target: Element, key: *, options: EditorFrameOptions}>} editorTargets - Target element or multi-root object.
|
|
@@ -424,10 +498,10 @@ function Constructor(editorTargets, options) {
|
|
|
424
498
|
|
|
425
499
|
// document type
|
|
426
500
|
const documentTypeInner = { inner: null, page: null, pageMirror: null };
|
|
427
|
-
if (o.get('
|
|
501
|
+
if (o.get('_type_options').includes('header')) {
|
|
428
502
|
documentTypeInner.inner = dom.utils.createElement('DIV', { class: 'se-document-lines', style: `height: ${to.get('height')};` }, '<div class="se-document-lines-inner"></div>');
|
|
429
503
|
}
|
|
430
|
-
if (o.get('
|
|
504
|
+
if (o.get('_type_options').includes('page')) {
|
|
431
505
|
documentTypeInner.page = dom.utils.createElement('DIV', { class: 'se-document-page' }, null);
|
|
432
506
|
documentTypeInner.pageMirror = dom.utils.createElement(
|
|
433
507
|
'DIV',
|
|
@@ -619,7 +693,7 @@ export function InitOptions(options, editorTargets, plugins) {
|
|
|
619
693
|
o.set('type', options.type?.split(':')[0] || ''); // document:header,page
|
|
620
694
|
o.set('theme', options.theme || '');
|
|
621
695
|
o.set('_themeClass', options.theme ? ` se-theme-${options.theme}` : '');
|
|
622
|
-
o.set('
|
|
696
|
+
o.set('_type_options', options.type?.split(':')[1] || '');
|
|
623
697
|
o.set('externalLibs', options.externalLibs || {});
|
|
624
698
|
o.set('fontSizeUnits', Array.isArray(options.fontSizeUnits) && options.fontSizeUnits.length > 0 ? options.fontSizeUnits.map((v) => v.toLowerCase()) : DEFAULT_SIZE_UNITS);
|
|
625
699
|
o.set('allowedClassName', new RegExp(`${options.allowedClassName && typeof options.allowedClassName === 'string' ? options.allowedClassName + '|' : ''}${DEFAULT_CLASS_NAME}`));
|
|
@@ -736,6 +810,7 @@ export function InitOptions(options, editorTargets, plugins) {
|
|
|
736
810
|
// default line
|
|
737
811
|
o.set('defaultLine', typeof options.defaultLine === 'string' && options.defaultLine.length > 0 ? options.defaultLine : 'p');
|
|
738
812
|
o.set('_defaultBrLineBreak', options.defaultLineBreakFormat === 'br');
|
|
813
|
+
o.set('scopeSelectionTags', options.scopeSelectionTags || DEFAULT_SCOPE_SELECTION_TAGS.split('|'));
|
|
739
814
|
// element
|
|
740
815
|
const elw = (typeof options.elementWhitelist === 'string' ? options.elementWhitelist : '').toLowerCase();
|
|
741
816
|
const mjxEls = o.get('externalLibs').mathjax ? DEFAULT_CLASS_MJX + '|' : '';
|
|
@@ -43,8 +43,8 @@ function DocumentType(editor, fc) {
|
|
|
43
43
|
this.pages = [];
|
|
44
44
|
this.pages_line = [];
|
|
45
45
|
this.prevScrollTop = 0;
|
|
46
|
-
this.useHeader = editor.options.get('
|
|
47
|
-
this.usePage = editor.options.get('
|
|
46
|
+
this.useHeader = editor.options.get('_type_options').includes('header');
|
|
47
|
+
this.usePage = editor.options.get('_type_options').includes('page');
|
|
48
48
|
this.navigatorButtons = [];
|
|
49
49
|
this.pageNavigator = null;
|
|
50
50
|
this._mirror = fc.get('documentTypePageMirror');
|
package/src/events.js
CHANGED
|
@@ -606,5 +606,17 @@ export default {
|
|
|
606
606
|
* @param {EmbedInfo} params.info - info object
|
|
607
607
|
* @param {(newInfo?: EmbedInfo|null) => void} params.handler - handler function
|
|
608
608
|
*/
|
|
609
|
-
onEmbedInputBefore: null
|
|
609
|
+
onEmbedInputBefore: null,
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* @description Called before the embed is deleted
|
|
613
|
+
* @param {Object} params
|
|
614
|
+
* @param {__se__EditorCore} params.editor - The root editor instance
|
|
615
|
+
* @param {HTMLElement} params.element - target element
|
|
616
|
+
* @param {HTMLElement} params.container - target's container element (div)
|
|
617
|
+
* @param {string} params.align - align value
|
|
618
|
+
* @param {string} params.url - embed url
|
|
619
|
+
* @returns {Promise<boolean>}
|
|
620
|
+
*/
|
|
621
|
+
onEmbedDeleteBefore: null
|
|
610
622
|
};
|
|
@@ -162,6 +162,15 @@ export function isFigure(node) {
|
|
|
162
162
|
return /^FIGURE$/i.test(typeof node === 'string' ? node : node?.nodeName);
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
+
/**
|
|
166
|
+
* @description Checks whether the given node is a content-less (void) HTML tag
|
|
167
|
+
* @param {?Node|string} node The element or element name to check
|
|
168
|
+
* @returns {boolean}
|
|
169
|
+
*/
|
|
170
|
+
export function isContentLess(node) {
|
|
171
|
+
return /^(BR|COLGROUP|COL|THEAD|TBODY|TFOOT|TR|AREA|BASE|EMBED|HR|IMG|INPUT|KEYGEN|LINK|META|PARAM|SOURCE|TRACK|WBR)$/i.test(typeof node === 'string' ? node : node?.nodeName);
|
|
172
|
+
}
|
|
173
|
+
|
|
165
174
|
/**
|
|
166
175
|
* @description Check the line element is empty.
|
|
167
176
|
* @param {Node} node "line" element node
|
|
@@ -281,6 +290,7 @@ const check = {
|
|
|
281
290
|
isMedia,
|
|
282
291
|
isIFrame,
|
|
283
292
|
isFigure,
|
|
293
|
+
isContentLess,
|
|
284
294
|
isEmptyLine,
|
|
285
295
|
isWysiwygFrame,
|
|
286
296
|
isNonEditable,
|
package/src/modules/Figure.js
CHANGED
|
@@ -652,7 +652,7 @@ class Figure extends EditorInjector {
|
|
|
652
652
|
*/
|
|
653
653
|
_asFormatChange(figureinfo, w, h) {
|
|
654
654
|
const kind = this.kind;
|
|
655
|
-
figureinfo.target.onload = () => this.component.select(figureinfo.target, kind
|
|
655
|
+
figureinfo.target.onload = () => this.component.select(figureinfo.target, kind);
|
|
656
656
|
|
|
657
657
|
this._setFigureInfo(figureinfo);
|
|
658
658
|
|
|
@@ -745,7 +745,7 @@ class Figure extends EditorInjector {
|
|
|
745
745
|
|
|
746
746
|
this.history.push(false);
|
|
747
747
|
if (!/^remove|caption$/.test(command)) {
|
|
748
|
-
this.component.select(element, this.kind
|
|
748
|
+
this.component.select(element, this.kind);
|
|
749
749
|
}
|
|
750
750
|
}
|
|
751
751
|
|
|
@@ -1318,7 +1318,7 @@ class Figure extends EditorInjector {
|
|
|
1318
1318
|
}
|
|
1319
1319
|
|
|
1320
1320
|
this.history.push(false);
|
|
1321
|
-
this.component.select(this._element, this.kind
|
|
1321
|
+
this.component.select(this._element, this.kind);
|
|
1322
1322
|
}
|
|
1323
1323
|
|
|
1324
1324
|
/**
|
|
@@ -1328,7 +1328,7 @@ class Figure extends EditorInjector {
|
|
|
1328
1328
|
#ContainerResizingESC(e) {
|
|
1329
1329
|
if (!keyCodeMap.isEsc(e.code)) return;
|
|
1330
1330
|
this._offResizeEvent();
|
|
1331
|
-
this.component.select(this._element, this.kind
|
|
1331
|
+
this.component.select(this._element, this.kind);
|
|
1332
1332
|
}
|
|
1333
1333
|
|
|
1334
1334
|
/**
|
|
@@ -1337,7 +1337,7 @@ class Figure extends EditorInjector {
|
|
|
1337
1337
|
#SetMenuAlign(value) {
|
|
1338
1338
|
this.setAlign(this._element, value);
|
|
1339
1339
|
this.selectMenu_align.close();
|
|
1340
|
-
this.component.select(this._element, this.kind
|
|
1340
|
+
this.component.select(this._element, this.kind);
|
|
1341
1341
|
}
|
|
1342
1342
|
|
|
1343
1343
|
/**
|
|
@@ -1367,7 +1367,7 @@ class Figure extends EditorInjector {
|
|
|
1367
1367
|
}
|
|
1368
1368
|
|
|
1369
1369
|
this.selectMenu_resize.close();
|
|
1370
|
-
this.component.select(this._element, this.kind
|
|
1370
|
+
this.component.select(this._element, this.kind);
|
|
1371
1371
|
}
|
|
1372
1372
|
|
|
1373
1373
|
#OffFigureContainer() {
|
|
@@ -202,7 +202,7 @@ class FileManager extends CoreInjector {
|
|
|
202
202
|
el.scrollIntoView(this.options.get('componentScrollToOptions'));
|
|
203
203
|
const comp = this.component.get(el);
|
|
204
204
|
if (comp) {
|
|
205
|
-
this.component.select(comp.target, comp.pluginName
|
|
205
|
+
this.component.select(comp.target, comp.pluginName);
|
|
206
206
|
} else if (typeof this.inst.select === 'function') {
|
|
207
207
|
this.inst.select(el);
|
|
208
208
|
}
|
|
@@ -184,7 +184,7 @@ class FileUpload extends EditorInjector {
|
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
this.controller.close();
|
|
187
|
-
this.component.select(this._element, FileUpload.key
|
|
187
|
+
this.component.select(this._element, FileUpload.key);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
/**
|
|
@@ -321,7 +321,7 @@ class FileUpload extends EditorInjector {
|
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
this.history.push(false);
|
|
324
|
-
this.component.select(target, FileUpload.key
|
|
324
|
+
this.component.select(target, FileUpload.key);
|
|
325
325
|
}
|
|
326
326
|
|
|
327
327
|
/**
|
|
@@ -368,7 +368,7 @@ class FileUpload extends EditorInjector {
|
|
|
368
368
|
const line = this.format.addLine(figure.container, null);
|
|
369
369
|
if (line) this.selection.setRange(line, 0, line, 0);
|
|
370
370
|
} else {
|
|
371
|
-
this.component.select(a, FileUpload.key
|
|
371
|
+
this.component.select(a, FileUpload.key);
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
374
|
|