suneditor 3.0.0-beta.2 → 3.0.0-beta.3
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/dist/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +1 -1
- package/src/assets/design/color.css +11 -1
- package/src/assets/suneditor.css +17 -12
- package/src/core/base/eventHandlers/handler_ww_dragDrop.js +4 -2
- package/src/core/base/eventHandlers/handler_ww_key_input.js +1 -1
- package/src/core/base/eventManager.js +61 -30
- package/src/core/class/char.js +3 -2
- package/src/core/class/component.js +17 -3
- package/src/core/class/format.js +13 -2
- package/src/core/class/html.js +58 -26
- package/src/core/class/selection.js +1 -8
- package/src/core/class/toolbar.js +2 -1
- package/src/core/class/ui.js +3 -1
- package/src/core/editor.js +124 -58
- package/src/core/section/actives.js +48 -23
- package/src/core/section/constructor.js +92 -78
- package/src/events.js +12 -0
- package/src/helper/converter.js +23 -1
- package/src/helper/dom/domCheck.js +2 -2
- package/src/modules/Controller.js +25 -5
- package/src/plugins/dropdown/formatBlock.js +4 -13
- package/src/themes/dark.css +11 -1
- package/types/core/base/eventManager.d.ts +16 -0
- package/types/core/class/char.d.ts +2 -1
- package/types/core/class/component.d.ts +1 -0
- package/types/core/class/format.d.ts +8 -1
- package/types/core/class/html.d.ts +8 -0
- package/types/core/class/ui.d.ts +1 -1
- package/types/core/editor.d.ts +7 -2
- package/types/core/section/constructor.d.ts +7 -0
- package/types/events.d.ts +2 -0
- package/types/helper/converter.d.ts +9 -0
- package/types/helper/index.d.ts +1 -0
- package/types/plugins/dropdown/formatBlock.d.ts +2 -2
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, OPTION_FIXED_FLAG } from './section/constructor';
|
|
2
|
+
import Constructor, { InitOptions, UpdateButton, CreateShortcuts, CreateStatusbar, OPTION_FRAME_FIXED_FLAG, 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';
|
|
@@ -383,11 +383,17 @@ function Editor(multiTargets, options) {
|
|
|
383
383
|
this._notHideToolbar = false;
|
|
384
384
|
|
|
385
385
|
/**
|
|
386
|
-
* @description Variables for controlling
|
|
386
|
+
* @description Variables for controlling blur events
|
|
387
387
|
* @type {boolean}
|
|
388
388
|
*/
|
|
389
389
|
this._preventBlur = false;
|
|
390
390
|
|
|
391
|
+
/**
|
|
392
|
+
* @description Variables for controlling focus events
|
|
393
|
+
* @type {boolean}
|
|
394
|
+
*/
|
|
395
|
+
this._preventFocus = false;
|
|
396
|
+
|
|
391
397
|
/**
|
|
392
398
|
* @description Variables for controlling selection change events
|
|
393
399
|
*/
|
|
@@ -762,37 +768,39 @@ Editor.prototype = {
|
|
|
762
768
|
* @param {EditorInitOptions_editor} newOptions Options
|
|
763
769
|
*/
|
|
764
770
|
resetOptions(newOptions) {
|
|
765
|
-
const _keys = Object.keys;
|
|
766
771
|
this.viewer.codeView(false);
|
|
767
772
|
this.viewer.showBlocks(false);
|
|
768
773
|
|
|
769
|
-
const
|
|
774
|
+
const rootDiff = new Map();
|
|
775
|
+
const frameRoots = this.frameRoots;
|
|
776
|
+
const newRoots = [];
|
|
777
|
+
const newRootKeys = new Map();
|
|
778
|
+
|
|
779
|
+
// frame roots
|
|
780
|
+
const nRoot = {};
|
|
781
|
+
for (const k in newOptions) {
|
|
782
|
+
if (OPTION_FRAME_FIXED_FLAG[k] === undefined) continue;
|
|
783
|
+
nRoot[k] = newOptions[k];
|
|
784
|
+
delete newOptions[k];
|
|
785
|
+
}
|
|
786
|
+
for (const rootKey of frameRoots.keys()) {
|
|
787
|
+
newOptions[rootKey || ''] = { ...nRoot, ...newOptions[rootKey || ''] };
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// check reoption validation
|
|
791
|
+
const newOptionKeys = Object.keys(newOptions);
|
|
770
792
|
CheckResetKeys(newOptionKeys, this.plugins, '');
|
|
771
793
|
if (newOptionKeys.length === 0) return;
|
|
772
794
|
|
|
795
|
+
if (frameRoots.size === 1) {
|
|
796
|
+
newOptionKeys.unshift(null);
|
|
797
|
+
}
|
|
798
|
+
|
|
773
799
|
// option merge
|
|
774
|
-
const
|
|
775
|
-
const rootKeys = this.rootKeys;
|
|
776
|
-
const frameRoots = this.frameRoots;
|
|
777
|
-
const newRoots = [];
|
|
778
|
-
const newRootKeys = {};
|
|
779
|
-
this._originOptions = [newOptions, this._originOptions].reduce(function (init, option) {
|
|
800
|
+
const _originOptions = [this._originOptions, newOptions].reduce((init, option) => {
|
|
780
801
|
for (const key in option) {
|
|
781
|
-
if (
|
|
782
|
-
|
|
783
|
-
const newKeys = _keys(nro);
|
|
784
|
-
CheckResetKeys(newKeys, null, key + '.');
|
|
785
|
-
if (newKeys.length === 0) continue;
|
|
786
|
-
|
|
787
|
-
rootDiff[key] = new Map();
|
|
788
|
-
const o = frameRoots.get(key).get('options').get('_origin');
|
|
789
|
-
for (const rk in nro) {
|
|
790
|
-
const roV = nro[rk];
|
|
791
|
-
if (!newKeys.includes(rk) || o[rk] === roV) continue;
|
|
792
|
-
rootDiff[key].set(GetResetDiffKey(rk), true);
|
|
793
|
-
o[rk] = roV;
|
|
794
|
-
}
|
|
795
|
-
newRoots.push((newRootKeys[key] = { options: o }));
|
|
802
|
+
if (frameRoots.has(key || null)) {
|
|
803
|
+
RestoreFrameOptions(key, option, frameRoots, rootDiff, newRootKeys, newRoots);
|
|
796
804
|
} else {
|
|
797
805
|
init[key] = option[key];
|
|
798
806
|
}
|
|
@@ -802,17 +810,25 @@ Editor.prototype = {
|
|
|
802
810
|
|
|
803
811
|
// init options
|
|
804
812
|
const options = this.options;
|
|
805
|
-
const
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
813
|
+
const newO = InitOptions(_originOptions, newRoots, this.plugins);
|
|
814
|
+
const newOptionMap = newO.o;
|
|
815
|
+
const newFrameMap = newO.frameMap;
|
|
816
|
+
/** --------- [root start] --------- */
|
|
817
|
+
for (let i = 0, len = newOptionKeys.length, k; i < len; i++) {
|
|
818
|
+
k = newOptionKeys[i] || null;
|
|
819
|
+
|
|
820
|
+
if (newRootKeys.has(k)) {
|
|
821
|
+
const diff = rootDiff.get(k);
|
|
810
822
|
const fc = frameRoots.get(k);
|
|
811
823
|
const originOptions = fc.get('options');
|
|
812
|
-
const newRootOptions =
|
|
824
|
+
const newRootOptions = newFrameMap.get(k);
|
|
813
825
|
|
|
814
|
-
//
|
|
815
|
-
|
|
826
|
+
// --- set options : fc ---
|
|
827
|
+
fc.set('options', newRootOptions);
|
|
828
|
+
|
|
829
|
+
// statusbar-changed
|
|
830
|
+
if (diff.has('statusbar-changed')) {
|
|
831
|
+
// statusbar
|
|
816
832
|
dom.utils.removeItem(fc.get('statusbar'));
|
|
817
833
|
if (newRootOptions.get('statusbar')) {
|
|
818
834
|
const statusbar = CreateStatusbar(newRootOptions, null).statusbar;
|
|
@@ -824,6 +840,10 @@ Editor.prototype = {
|
|
|
824
840
|
newRootOptions.set('__statusbarEvent', null);
|
|
825
841
|
UpdateStatusbarContext(null, fc);
|
|
826
842
|
}
|
|
843
|
+
// charCounter
|
|
844
|
+
if (fc.get('statusbar')) {
|
|
845
|
+
this.char.display(fc);
|
|
846
|
+
}
|
|
827
847
|
}
|
|
828
848
|
|
|
829
849
|
// iframe's options
|
|
@@ -834,6 +854,7 @@ Editor.prototype = {
|
|
|
834
854
|
for (const origin_k in originAttr) frame.removeAttribute(origin_k, originAttr[origin_k]);
|
|
835
855
|
for (const new_k in newAttr) frame.setAttribute(new_k, newAttr[new_k]);
|
|
836
856
|
}
|
|
857
|
+
|
|
837
858
|
if (diff.has('iframe_cssFileName')) {
|
|
838
859
|
const docHead = fc.get('_wd').head;
|
|
839
860
|
const links = docHead.getElementsByTagName('link');
|
|
@@ -844,11 +865,12 @@ Editor.prototype = {
|
|
|
844
865
|
while (newLinks[0]) docHead.insertBefore(newLinks[0], sTag);
|
|
845
866
|
}
|
|
846
867
|
|
|
847
|
-
|
|
848
|
-
|
|
868
|
+
if (diff.has('placeholder')) {
|
|
869
|
+
fc.get('placeholder').textContent = newRootOptions.get('placeholder');
|
|
870
|
+
}
|
|
849
871
|
|
|
850
872
|
// frame styles
|
|
851
|
-
this.ui.setEditorStyle(newRootOptions.get('
|
|
873
|
+
this.ui.setEditorStyle(newRootOptions.get('editorStyle'), fc);
|
|
852
874
|
|
|
853
875
|
// frame attributes
|
|
854
876
|
const frame = fc.get('wysiwyg');
|
|
@@ -859,25 +881,47 @@ Editor.prototype = {
|
|
|
859
881
|
|
|
860
882
|
continue;
|
|
861
883
|
}
|
|
862
|
-
/** --------- root end --------- */
|
|
884
|
+
/** --------- [root end] --------- */
|
|
863
885
|
|
|
864
|
-
|
|
886
|
+
// --- set options ---
|
|
887
|
+
options.set(k, newOptionMap.get(k));
|
|
865
888
|
|
|
866
|
-
/**
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
889
|
+
/** Options that require a function call */
|
|
890
|
+
switch (k) {
|
|
891
|
+
case 'theme': {
|
|
892
|
+
this.ui.setTheme(options.get('theme'));
|
|
893
|
+
break;
|
|
894
|
+
}
|
|
895
|
+
case 'events': {
|
|
896
|
+
const events = options.get('events');
|
|
897
|
+
for (const name in events) {
|
|
898
|
+
this.events[name] = events[name];
|
|
899
|
+
}
|
|
900
|
+
break;
|
|
901
|
+
}
|
|
902
|
+
case 'autoStyleify': {
|
|
903
|
+
this.html.__resetAutoStyleify(options.get('autoStyleify'));
|
|
904
|
+
break;
|
|
905
|
+
}
|
|
906
|
+
case 'textDirection': {
|
|
907
|
+
this.setDir(options.get('_rtl') ? 'ltr' : 'rtl');
|
|
908
|
+
break;
|
|
909
|
+
}
|
|
910
|
+
case 'historyStackDelayTime': {
|
|
911
|
+
this.history.resetDelayTime(options.get('historyStackDelayTime'));
|
|
912
|
+
break;
|
|
913
|
+
}
|
|
914
|
+
case 'defaultLineBreakFormat': {
|
|
915
|
+
this.format.__resetBrLineBreak(options.get('defaultLineBreakFormat'));
|
|
916
|
+
}
|
|
876
917
|
}
|
|
877
918
|
}
|
|
878
919
|
|
|
879
920
|
/** apply options */
|
|
880
|
-
//
|
|
921
|
+
// _origin
|
|
922
|
+
this._originOptions = _originOptions;
|
|
923
|
+
|
|
924
|
+
// --- [toolbar] ---
|
|
881
925
|
const toolbar = this.context.get('toolbar.main');
|
|
882
926
|
// width
|
|
883
927
|
if (/inline|balloon/i.test(options.get('mode')) && newOptionKeys.includes('toolbar_width')) {
|
|
@@ -886,6 +930,8 @@ Editor.prototype = {
|
|
|
886
930
|
// hide
|
|
887
931
|
if (options.get('toolbar_hide')) {
|
|
888
932
|
toolbar.style.display = 'none';
|
|
933
|
+
} else {
|
|
934
|
+
toolbar.style.display = '';
|
|
889
935
|
}
|
|
890
936
|
// shortcuts hint
|
|
891
937
|
if (options.get('shortcutsHint')) {
|
|
@@ -894,11 +940,6 @@ Editor.prototype = {
|
|
|
894
940
|
dom.utils.addClass(toolbar, 'se-shortcut-hide');
|
|
895
941
|
}
|
|
896
942
|
|
|
897
|
-
// theme
|
|
898
|
-
if (this._originOptions.theme !== (newOptions.theme ?? this._originOptions.theme)) {
|
|
899
|
-
this.ui.setTheme(newOptions.theme);
|
|
900
|
-
}
|
|
901
|
-
|
|
902
943
|
this.effectNode = null;
|
|
903
944
|
this._setFrameInfo(this.frameRoots.get(this.status.rootKey));
|
|
904
945
|
},
|
|
@@ -1444,7 +1485,7 @@ Editor.prototype = {
|
|
|
1444
1485
|
|
|
1445
1486
|
/**
|
|
1446
1487
|
* @private
|
|
1447
|
-
* @description Caches shortcut keys for commands.
|
|
1488
|
+
* @description Caches custom(starts with "_") shortcut keys for commands.
|
|
1448
1489
|
*/
|
|
1449
1490
|
__cachingShortcuts() {
|
|
1450
1491
|
const shortcuts = this.options.get('shortcuts');
|
|
@@ -1689,16 +1730,41 @@ Editor.prototype = {
|
|
|
1689
1730
|
Constructor: Editor
|
|
1690
1731
|
};
|
|
1691
1732
|
|
|
1733
|
+
function RestoreFrameOptions(key, option, frameRoots, rootDiff, newRootKeys, newRoots) {
|
|
1734
|
+
const nro = option[key];
|
|
1735
|
+
const newKeys = Object.keys(nro);
|
|
1736
|
+
CheckResetKeys(newKeys, null, key + '.');
|
|
1737
|
+
if (newKeys.length === 0) return false;
|
|
1738
|
+
|
|
1739
|
+
const rootKey = key || null;
|
|
1740
|
+
rootDiff.set(rootKey, new Map());
|
|
1741
|
+
|
|
1742
|
+
const o = frameRoots.get(rootKey).get('options').get('_origin');
|
|
1743
|
+
const no = {};
|
|
1744
|
+
const hasOwn = Object.prototype.hasOwnProperty;
|
|
1745
|
+
for (const rk in nro) {
|
|
1746
|
+
if (!hasOwn.call(OPTION_FRAME_FIXED_FLAG, rk)) continue;
|
|
1747
|
+
const roV = nro[rk];
|
|
1748
|
+
if (!newKeys.includes(rk) || o[rk] === roV) continue;
|
|
1749
|
+
rootDiff.get(rootKey).set(GetResetDiffKey(rk), true);
|
|
1750
|
+
no[rk] = roV;
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
const newO = { ...o, ...no };
|
|
1754
|
+
newRootKeys.set(rootKey, new Map(Object.entries(newO)));
|
|
1755
|
+
newRoots.push({ key: rootKey, options: newO });
|
|
1756
|
+
}
|
|
1757
|
+
|
|
1692
1758
|
function GetResetDiffKey(key) {
|
|
1693
|
-
if (/^statusbar
|
|
1759
|
+
if (/^statusbar|^charCounter/.test(key)) return 'statusbar-changed';
|
|
1694
1760
|
return key;
|
|
1695
1761
|
}
|
|
1696
1762
|
|
|
1697
1763
|
function CheckResetKeys(keys, plugins, root) {
|
|
1698
1764
|
for (let i = 0, len = keys.length, k; i < len; i++) {
|
|
1699
1765
|
k = keys[i];
|
|
1700
|
-
if (OPTION_FIXED_FLAG[k] === 'fixed' || (plugins && plugins[k])) {
|
|
1701
|
-
console.warn(`[SUNEDITOR.warn.resetOptions] "[${root + k}]"
|
|
1766
|
+
if (OPTION_FIXED_FLAG[k] === 'fixed' || OPTION_FRAME_FIXED_FLAG[k] === 'fixed' || (plugins && plugins[k])) {
|
|
1767
|
+
console.warn(`[SUNEDITOR.warn.resetOptions] The "[${root + k}]" option cannot be changed after the editor is created.`);
|
|
1702
1768
|
keys.splice(i--, 1);
|
|
1703
1769
|
len--;
|
|
1704
1770
|
}
|
|
@@ -31,6 +31,35 @@ const __RemoveCopyformt = function (ww, button) {
|
|
|
31
31
|
return true;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* @private
|
|
36
|
+
* @description Finds the first and last child elements in a selection area.
|
|
37
|
+
* @param {Element} selectArea Selection area element
|
|
38
|
+
* @returns {{ first: Node, last: Node}} Object containing the first and last child elements
|
|
39
|
+
*/
|
|
40
|
+
const __findFirstAndLast = function (selectArea) {
|
|
41
|
+
const isContentLess = dom.check.isContentLess;
|
|
42
|
+
const isTable = dom.check.isTable;
|
|
43
|
+
const first =
|
|
44
|
+
dom.query.getEdgeChild(
|
|
45
|
+
dom.query.getEdgeChild(selectArea, (current) => !isContentLess(current), false),
|
|
46
|
+
(current) => {
|
|
47
|
+
return current.childNodes.length === 0 || current.nodeType === 3 || isTable(current);
|
|
48
|
+
},
|
|
49
|
+
false
|
|
50
|
+
) || selectArea.firstChild;
|
|
51
|
+
const last =
|
|
52
|
+
dom.query.getEdgeChild(
|
|
53
|
+
selectArea.lastChild,
|
|
54
|
+
(current) => {
|
|
55
|
+
return current.childNodes.length === 0 || current.nodeType === 3 || isTable(current);
|
|
56
|
+
},
|
|
57
|
+
true
|
|
58
|
+
) || selectArea.lastChild;
|
|
59
|
+
|
|
60
|
+
return { first, last };
|
|
61
|
+
};
|
|
62
|
+
|
|
34
63
|
/**
|
|
35
64
|
* @description List of commands that trigger active event handling in the editor.
|
|
36
65
|
* - These commands typically apply inline formatting or structural changes.
|
|
@@ -77,39 +106,35 @@ export function SELECT_ALL(editor) {
|
|
|
77
106
|
// select all
|
|
78
107
|
const scopeTagList = scopeSelectionTags.filter((tagName) => tagName !== prevScopeTagName);
|
|
79
108
|
const scopeBaseTag = dom.query.getParentElement(prevScopeTag || editor.selection.getNode(), (current) => scopeTagList.includes(current.nodeName?.toLowerCase()));
|
|
80
|
-
const selectArea = scopeBaseTag || ww;
|
|
81
109
|
|
|
82
|
-
let
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
selectArea.lastChild,
|
|
93
|
-
(current) => {
|
|
94
|
-
return current.childNodes.length === 0 || current.nodeType === 3 || dom.check.isTable(current);
|
|
95
|
-
},
|
|
96
|
-
true
|
|
97
|
-
) || selectArea.lastChild;
|
|
110
|
+
let selectArea = scopeBaseTag || ww;
|
|
111
|
+
let { first, last } = __findFirstAndLast(selectArea);
|
|
112
|
+
|
|
113
|
+
if (!first || !last) return;
|
|
114
|
+
|
|
115
|
+
const isZeroWidth = dom.check.isZeroWidth;
|
|
116
|
+
while (isZeroWidth(first) && isZeroWidth(last) && selectArea !== ww) {
|
|
117
|
+
selectArea = selectArea.parentElement;
|
|
118
|
+
({ first, last } = __findFirstAndLast(dom.query.getParentElement(selectArea, (current) => scopeTagList.includes(current.nodeName?.toLowerCase())) || ww));
|
|
119
|
+
}
|
|
98
120
|
|
|
99
121
|
if (!first || !last) return;
|
|
100
122
|
|
|
101
|
-
|
|
102
|
-
|
|
123
|
+
let info = null;
|
|
124
|
+
if (dom.check.isMedia(first) || (info = editor.component.get(first.parentElement)) || dom.check.isTableElements(first)) {
|
|
103
125
|
const br = dom.utils.createElement('BR');
|
|
104
126
|
const format = dom.utils.createElement(editor.options.get('defaultLine'), null, br);
|
|
105
127
|
first = info ? info.container || info.cover : first;
|
|
106
|
-
first.
|
|
128
|
+
first.parentElement.insertBefore(format, first);
|
|
107
129
|
first = br;
|
|
108
130
|
}
|
|
109
131
|
|
|
110
|
-
if (dom.check.isMedia(last) || editor.component.
|
|
111
|
-
|
|
112
|
-
|
|
132
|
+
if (dom.check.isMedia(last) || (info = editor.component.get(last.parentElement)) || dom.check.isTableElements(last)) {
|
|
133
|
+
const br = dom.utils.createElement('BR');
|
|
134
|
+
const format = dom.utils.createElement(editor.options.get('defaultLine'), null, br);
|
|
135
|
+
last = info ? info.container || info.cover : last;
|
|
136
|
+
last.parentElement.appendChild(format);
|
|
137
|
+
last = br;
|
|
113
138
|
}
|
|
114
139
|
|
|
115
140
|
editor.toolbar._showBalloon(editor.selection.setRange(first, 0, last, last.textContent.length));
|
|
@@ -224,107 +224,115 @@ const RETAIN_STYLE_MODE = ['repeat', 'always', 'none'];
|
|
|
224
224
|
* @typedef {EditorBaseOptions & EditorFrameOptions} EditorInitOptions
|
|
225
225
|
*/
|
|
226
226
|
|
|
227
|
+
/** ------------- [OPTIONS FRAG] ------------- */
|
|
227
228
|
/**
|
|
228
229
|
* @description For all EditorInitOptions keys, only boolean | null values are allowed.
|
|
229
230
|
* - 'fixed' → Immutable / null → Resettable.
|
|
230
231
|
* @type {Partial<Record<keyof EditorInitOptions, "fixed" | true>>}
|
|
231
232
|
*/
|
|
232
|
-
export const
|
|
233
|
+
export const OPTION_FRAME_FIXED_FLAG = {
|
|
233
234
|
value: 'fixed',
|
|
234
|
-
placeholder:
|
|
235
|
-
editableFrameAttributes:
|
|
236
|
-
width:
|
|
237
|
-
minWidth:
|
|
238
|
-
maxWidth:
|
|
239
|
-
height:
|
|
240
|
-
minHeight:
|
|
241
|
-
maxHeight:
|
|
242
|
-
editorStyle:
|
|
235
|
+
placeholder: true,
|
|
236
|
+
editableFrameAttributes: true,
|
|
237
|
+
width: true,
|
|
238
|
+
minWidth: true,
|
|
239
|
+
maxWidth: true,
|
|
240
|
+
height: true,
|
|
241
|
+
minHeight: true,
|
|
242
|
+
maxHeight: true,
|
|
243
|
+
editorStyle: true,
|
|
243
244
|
iframe: 'fixed',
|
|
244
|
-
iframe_fullPage:
|
|
245
|
-
iframe_attributes:
|
|
246
|
-
iframe_cssFileName:
|
|
247
|
-
statusbar:
|
|
248
|
-
statusbar_showPathLabel:
|
|
249
|
-
statusbar_resizeEnable:
|
|
250
|
-
charCounter:
|
|
251
|
-
charCounter_max:
|
|
252
|
-
charCounter_label:
|
|
253
|
-
charCounter_type:
|
|
254
|
-
|
|
255
|
-
|
|
245
|
+
iframe_fullPage: 'fixed',
|
|
246
|
+
iframe_attributes: true,
|
|
247
|
+
iframe_cssFileName: true,
|
|
248
|
+
statusbar: true,
|
|
249
|
+
statusbar_showPathLabel: true,
|
|
250
|
+
statusbar_resizeEnable: 'fixed',
|
|
251
|
+
charCounter: true,
|
|
252
|
+
charCounter_max: true,
|
|
253
|
+
charCounter_label: true,
|
|
254
|
+
charCounter_type: true
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* @description For all EditorInitOptions keys, only boolean | null values are allowed.
|
|
258
|
+
* - 'fixed' → Immutable / null → Resettable.
|
|
259
|
+
* @type {Partial<Record<keyof EditorInitOptions, "fixed" | true>>}
|
|
260
|
+
*/
|
|
261
|
+
export const OPTION_FIXED_FLAG = {
|
|
262
|
+
plugins: 'fixed',
|
|
263
|
+
excludedPlugins: 'fixed',
|
|
256
264
|
buttonList: 'fixed',
|
|
257
|
-
v2Migration:
|
|
258
|
-
strictMode:
|
|
265
|
+
v2Migration: 'fixed',
|
|
266
|
+
strictMode: 'fixed',
|
|
259
267
|
mode: 'fixed',
|
|
260
268
|
type: 'fixed',
|
|
261
|
-
theme:
|
|
269
|
+
theme: true,
|
|
262
270
|
lang: 'fixed',
|
|
263
271
|
fontSizeUnits: 'fixed',
|
|
264
|
-
allowedClassName:
|
|
265
|
-
closeModalOutsideClick:
|
|
266
|
-
copyFormatKeepOn:
|
|
267
|
-
syncTabIndent:
|
|
268
|
-
tabDisable:
|
|
269
|
-
autoLinkify:
|
|
270
|
-
autoStyleify:
|
|
271
|
-
scrollToOptions:
|
|
272
|
-
componentScrollToOptions:
|
|
273
|
-
retainStyleMode:
|
|
274
|
-
allowedExtraTags:
|
|
275
|
-
events:
|
|
272
|
+
allowedClassName: 'fixed',
|
|
273
|
+
closeModalOutsideClick: 'fixed',
|
|
274
|
+
copyFormatKeepOn: true,
|
|
275
|
+
syncTabIndent: true,
|
|
276
|
+
tabDisable: true,
|
|
277
|
+
autoLinkify: true,
|
|
278
|
+
autoStyleify: true,
|
|
279
|
+
scrollToOptions: true,
|
|
280
|
+
componentScrollToOptions: true,
|
|
281
|
+
retainStyleMode: true,
|
|
282
|
+
allowedExtraTags: 'fixed',
|
|
283
|
+
events: true,
|
|
276
284
|
__textStyleTags: 'fixed',
|
|
277
285
|
textStyleTags: 'fixed',
|
|
278
286
|
convertTextTags: 'fixed',
|
|
279
|
-
__tagStyles:
|
|
287
|
+
__tagStyles: 'fixed',
|
|
280
288
|
tagStyles: 'fixed',
|
|
281
289
|
spanStyles: 'fixed',
|
|
282
290
|
lineStyles: 'fixed',
|
|
283
|
-
textDirection:
|
|
284
|
-
reverseButtons:
|
|
285
|
-
historyStackDelayTime:
|
|
286
|
-
lineAttrReset:
|
|
287
|
-
printClass:
|
|
291
|
+
textDirection: true,
|
|
292
|
+
reverseButtons: 'fixed',
|
|
293
|
+
historyStackDelayTime: true,
|
|
294
|
+
lineAttrReset: true,
|
|
295
|
+
printClass: true,
|
|
288
296
|
defaultLine: 'fixed',
|
|
289
|
-
defaultLineBreakFormat:
|
|
290
|
-
scopeSelectionTags:
|
|
297
|
+
defaultLineBreakFormat: true,
|
|
298
|
+
scopeSelectionTags: true,
|
|
291
299
|
__defaultElementWhitelist: 'fixed',
|
|
292
300
|
elementWhitelist: 'fixed',
|
|
293
301
|
elementBlacklist: 'fixed',
|
|
294
302
|
__defaultAttributeWhitelist: 'fixed',
|
|
295
303
|
attributeWhitelist: 'fixed',
|
|
296
304
|
attributeBlacklist: 'fixed',
|
|
297
|
-
__defaultFormatLine:
|
|
305
|
+
__defaultFormatLine: 'fixed',
|
|
298
306
|
formatLine: 'fixed',
|
|
299
|
-
__defaultFormatBrLine:
|
|
307
|
+
__defaultFormatBrLine: 'fixed',
|
|
300
308
|
formatBrLine: 'fixed',
|
|
301
309
|
__defaultFormatClosureBrLine: 'fixed',
|
|
302
310
|
formatClosureBrLine: 'fixed',
|
|
303
|
-
__defaultFormatBlock:
|
|
311
|
+
__defaultFormatBlock: 'fixed',
|
|
304
312
|
formatBlock: 'fixed',
|
|
305
|
-
__defaultFormatClosureBlock:
|
|
313
|
+
__defaultFormatClosureBlock: 'fixed',
|
|
306
314
|
formatClosureBlock: 'fixed',
|
|
307
|
-
allowedEmptyTags:
|
|
308
|
-
toolbar_width:
|
|
315
|
+
allowedEmptyTags: true,
|
|
316
|
+
toolbar_width: true,
|
|
309
317
|
toolbar_container: 'fixed',
|
|
310
|
-
toolbar_sticky:
|
|
311
|
-
toolbar_hide:
|
|
318
|
+
toolbar_sticky: true,
|
|
319
|
+
toolbar_hide: true,
|
|
312
320
|
subToolbar: 'fixed',
|
|
313
321
|
statusbar_container: 'fixed',
|
|
314
|
-
shortcutsHint:
|
|
322
|
+
shortcutsHint: true,
|
|
315
323
|
shortcutsDisable: 'fixed',
|
|
316
324
|
shortcuts: 'fixed',
|
|
317
|
-
fullScreenOffset:
|
|
318
|
-
previewTemplate:
|
|
319
|
-
printTemplate:
|
|
320
|
-
componentAutoSelect:
|
|
321
|
-
defaultUrlProtocol:
|
|
322
|
-
allUsedStyles:
|
|
323
|
-
toastMessageTime:
|
|
325
|
+
fullScreenOffset: true,
|
|
326
|
+
previewTemplate: true,
|
|
327
|
+
printTemplate: true,
|
|
328
|
+
componentAutoSelect: true,
|
|
329
|
+
defaultUrlProtocol: true,
|
|
330
|
+
allUsedStyles: 'fixed',
|
|
331
|
+
toastMessageTime: true,
|
|
324
332
|
icons: 'fixed',
|
|
325
|
-
freeCodeViewMode:
|
|
326
|
-
__lineFormatFilter:
|
|
327
|
-
__pluginRetainFilter:
|
|
333
|
+
freeCodeViewMode: true,
|
|
334
|
+
__lineFormatFilter: true,
|
|
335
|
+
__pluginRetainFilter: true,
|
|
328
336
|
__listCommonStyle: 'fixed',
|
|
329
337
|
externalLibs: 'fixed'
|
|
330
338
|
};
|
|
@@ -438,7 +446,7 @@ function Constructor(editorTargets, options) {
|
|
|
438
446
|
const to = optionMap.frameMap.get(editTarget.key);
|
|
439
447
|
const top_div = dom.utils.createElement('DIV', { class: 'sun-editor' + o.get('_themeClass') + (o.get('_rtl') ? ' se-rtl' : '') });
|
|
440
448
|
const container = dom.utils.createElement('DIV', { class: 'se-container' });
|
|
441
|
-
const editor_div = dom.utils.createElement('DIV', { class: 'se-wrapper' + (o.get('type') === 'document' ? ' se-type-document' : '') });
|
|
449
|
+
const editor_div = dom.utils.createElement('DIV', { class: 'se-wrapper' + (o.get('type') === 'document' ? ' se-type-document' : '') + (o.get('_type_options').includes('header') ? ' se-type-document-header' : '') });
|
|
442
450
|
|
|
443
451
|
container.appendChild(dom.utils.createElement('DIV', { class: 'se-toolbar-shadow' }));
|
|
444
452
|
|
|
@@ -574,13 +582,16 @@ export function CreateShortcuts(command, button, values, keyMap, rc, reverseKeys
|
|
|
574
582
|
plugin = null;
|
|
575
583
|
method = a[a.length - 1].trim?.();
|
|
576
584
|
if (method.startsWith('~')) {
|
|
585
|
+
// plugin key, method
|
|
577
586
|
plugin = command;
|
|
578
587
|
method = a.pop().trim().substring(1);
|
|
579
|
-
} else if (method.startsWith('
|
|
588
|
+
} else if (method.startsWith('$~')) {
|
|
589
|
+
// custom key, plugin method
|
|
580
590
|
const a_ = a.pop().trim().substring(2).split('.');
|
|
581
591
|
plugin = a_[0];
|
|
582
592
|
method = a_[1];
|
|
583
593
|
} else if (method.startsWith('$')) {
|
|
594
|
+
// directly method
|
|
584
595
|
_i = 1;
|
|
585
596
|
method = values[i + 2];
|
|
586
597
|
} else {
|
|
@@ -613,13 +624,16 @@ export function CreateShortcuts(command, button, values, keyMap, rc, reverseKeys
|
|
|
613
624
|
}
|
|
614
625
|
}
|
|
615
626
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
627
|
+
v = v.split('|');
|
|
628
|
+
for (let j = 0, len = v.length; j < len; j++) {
|
|
629
|
+
k = c ? v[j] + (s ? '1000' : '') : v[j];
|
|
630
|
+
if (!keyMap.has(k)) {
|
|
631
|
+
r = rc.indexOf(command);
|
|
632
|
+
r = r === -1 ? '' : numbers.isOdd(r) ? rc[r + 1] : rc[r - 1];
|
|
633
|
+
if (r) reverseKeys.push(k);
|
|
621
634
|
|
|
622
|
-
|
|
635
|
+
keyMap.set(k, { c, s, edge, space, enter, textTrigger, plugin, command, method, r, type: button?.getAttribute('data-type'), button, key: k });
|
|
636
|
+
}
|
|
623
637
|
}
|
|
624
638
|
|
|
625
639
|
if (!(t = values[i + 1])) continue;
|
|
@@ -809,7 +823,7 @@ export function InitOptions(options, editorTargets, plugins) {
|
|
|
809
823
|
/** whitelist, blacklist */
|
|
810
824
|
// default line
|
|
811
825
|
o.set('defaultLine', typeof options.defaultLine === 'string' && options.defaultLine.length > 0 ? options.defaultLine : 'p');
|
|
812
|
-
o.set('
|
|
826
|
+
o.set('defaultLineBreakFormat', options.defaultLineBreakFormat || 'line');
|
|
813
827
|
o.set('scopeSelectionTags', options.scopeSelectionTags || DEFAULT_SCOPE_SELECTION_TAGS.split('|'));
|
|
814
828
|
// element
|
|
815
829
|
const elw = (typeof options.elementWhitelist === 'string' ? options.elementWhitelist : '').toLowerCase();
|
|
@@ -926,9 +940,9 @@ export function InitOptions(options, editorTargets, plugins) {
|
|
|
926
940
|
list_numbered: ['!+1.+_+~shortcut', ''],
|
|
927
941
|
list_bulleted: ['!+*.+_+~shortcut', ''],
|
|
928
942
|
// custom
|
|
929
|
-
_h1: ['c+s+Digit1
|
|
930
|
-
_h2: ['c+s+Digit2
|
|
931
|
-
_h3: ['c+s+Digit3
|
|
943
|
+
_h1: ['c+s+Digit1|Numpad1+$~formatBlock.applyHeaderByShortcut', ''],
|
|
944
|
+
_h2: ['c+s+Digit2|Numpad2+$~formatBlock.applyHeaderByShortcut', ''],
|
|
945
|
+
_h3: ['c+s+Digit3|Numpad3+$~formatBlock.applyHeaderByShortcut', '']
|
|
932
946
|
},
|
|
933
947
|
options.shortcuts || {}
|
|
934
948
|
].reduce((_default, _new) => {
|
|
@@ -1115,6 +1129,7 @@ function InitFrameOptions(o, origin) {
|
|
|
1115
1129
|
fo.set('height', height ? (numbers.is(height) ? height + 'px' : height) : 'auto');
|
|
1116
1130
|
fo.set('minHeight', (numbers.is(minHeight) ? minHeight + 'px' : minHeight) || '');
|
|
1117
1131
|
fo.set('maxHeight', (numbers.is(maxHeight) ? maxHeight + 'px' : maxHeight) || '');
|
|
1132
|
+
fo.set('editorStyle', editorStyle);
|
|
1118
1133
|
fo.set('_defaultStyles', converter._setDefaultOptionStyle(fo, typeof editorStyle === 'string' ? editorStyle : ''));
|
|
1119
1134
|
// iframe
|
|
1120
1135
|
fo.set('iframe', !!(iframe_fullPage || iframe));
|
|
@@ -1175,9 +1190,8 @@ function _initTargetElements(key, options, topDiv, targetOptions) {
|
|
|
1175
1190
|
|
|
1176
1191
|
// textarea for code view
|
|
1177
1192
|
const textarea = dom.utils.createElement('TEXTAREA', { class: 'se-wrapper-inner se-code-viewer', style: editorStyles.frame });
|
|
1178
|
-
|
|
1193
|
+
const placeholder = dom.utils.createElement('SPAN', { class: 'se-placeholder' });
|
|
1179
1194
|
if (targetOptions.get('placeholder')) {
|
|
1180
|
-
placeholder = dom.utils.createElement('SPAN', { class: 'se-placeholder' });
|
|
1181
1195
|
placeholder.textContent = targetOptions.get('placeholder');
|
|
1182
1196
|
}
|
|
1183
1197
|
|