suneditor 2.41.3 → 2.42.0
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/README.md +107 -24
- package/dist/css/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +2 -2
- package/package.json +1 -1
- package/src/assets/css/suneditor.css +25 -6
- package/src/assets/defaultIcons.js +2 -0
- package/src/lang/Lang.d.ts +3 -1
- package/src/lang/ckb.js +2 -0
- package/src/lang/da.js +2 -0
- package/src/lang/de.js +2 -0
- package/src/lang/en.js +2 -0
- package/src/lang/es.js +2 -0
- package/src/lang/fr.js +10 -8
- package/src/lang/he.js +2 -0
- package/src/lang/it.js +2 -0
- package/src/lang/ja.js +2 -0
- package/src/lang/ko.js +2 -0
- package/src/lang/lv.js +2 -0
- package/src/lang/nl.js +2 -0
- package/src/lang/pl.js +2 -0
- package/src/lang/pt_br.js +2 -0
- package/src/lang/ro.js +2 -0
- package/src/lang/ru.js +2 -0
- package/src/lang/se.js +2 -0
- package/src/lang/ua.js +2 -0
- package/src/lang/zh_cn.js +2 -0
- package/src/lib/constructor.js +50 -11
- package/src/lib/context.js +4 -1
- package/src/lib/core.d.ts +86 -11
- package/src/lib/core.js +555 -147
- package/src/lib/util.d.ts +24 -1
- package/src/lib/util.js +64 -15
- package/src/options.d.ts +63 -8
- package/src/plugins/dialog/audio.js +5 -5
- package/src/plugins/dialog/image.js +30 -20
- package/src/plugins/dialog/video.js +13 -13
- package/src/plugins/fileBrowser/imageGallery.js +2 -3
- package/src/plugins/modules/_anchor.js +6 -4
- package/src/plugins/modules/component.d.ts +1 -1
- package/src/plugins/modules/fileBrowser.js +6 -1
- package/src/plugins/modules/fileManager.js +1 -3
- package/src/plugins/modules/resizing.js +11 -6
- package/src/plugins/submenu/align.js +32 -27
- package/src/plugins/submenu/font.js +1 -1
- package/src/plugins/submenu/horizontalRule.js +19 -25
package/src/lib/core.js
CHANGED
|
@@ -39,6 +39,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
39
39
|
_d: _d,
|
|
40
40
|
_w: _w,
|
|
41
41
|
_parser: new _w.DOMParser(),
|
|
42
|
+
_prevRtl: options.rtl,
|
|
42
43
|
|
|
43
44
|
/**
|
|
44
45
|
* @description Document object of the iframe if created as an iframe || _d
|
|
@@ -82,7 +83,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
82
83
|
/**
|
|
83
84
|
* @description Computed style of the wysiwyg area (window.getComputedStyle(context.element.wysiwyg))
|
|
84
85
|
*/
|
|
85
|
-
wwComputedStyle:
|
|
86
|
+
wwComputedStyle: null,
|
|
86
87
|
|
|
87
88
|
/**
|
|
88
89
|
* @description Notice object
|
|
@@ -222,6 +223,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
222
223
|
*/
|
|
223
224
|
_htmlCheckWhitelistRegExp: null,
|
|
224
225
|
|
|
226
|
+
/**
|
|
227
|
+
* @description Tag blacklist RegExp object used in "_consistencyCheckOfHTML" method
|
|
228
|
+
* @private
|
|
229
|
+
*/
|
|
230
|
+
_htmlCheckBlacklistRegExp: null,
|
|
231
|
+
|
|
225
232
|
/**
|
|
226
233
|
* @description RegExp when using check disallowd tags. (b, i, ins, strike, s)
|
|
227
234
|
* @private
|
|
@@ -234,12 +241,24 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
234
241
|
*/
|
|
235
242
|
editorTagsWhitelistRegExp: null,
|
|
236
243
|
|
|
244
|
+
/**
|
|
245
|
+
* @description Editor tags blacklist (RegExp object)
|
|
246
|
+
* util.createTagsBlacklist(options.tagsBlacklist)
|
|
247
|
+
*/
|
|
248
|
+
editorTagsBlacklistRegExp: null,
|
|
249
|
+
|
|
237
250
|
/**
|
|
238
251
|
* @description Tag whitelist when pasting (RegExp object)
|
|
239
252
|
* util.createTagsWhitelist(options.pasteTagsWhitelist)
|
|
240
253
|
*/
|
|
241
254
|
pasteTagsWhitelistRegExp: null,
|
|
242
255
|
|
|
256
|
+
/**
|
|
257
|
+
* @description Tag blacklist when pasting (RegExp object)
|
|
258
|
+
* util.createTagsBlacklist(options.pasteTagsBlacklist)
|
|
259
|
+
*/
|
|
260
|
+
pasteTagsBlacklistRegExp: null,
|
|
261
|
+
|
|
243
262
|
/**
|
|
244
263
|
* @description Boolean value of whether the editor has focus
|
|
245
264
|
*/
|
|
@@ -261,12 +280,24 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
261
280
|
*/
|
|
262
281
|
_attributesWhitelistRegExp: null,
|
|
263
282
|
|
|
283
|
+
/**
|
|
284
|
+
* @description Attributes blacklist used by the cleanHTML method
|
|
285
|
+
* @private
|
|
286
|
+
*/
|
|
287
|
+
_attributesBlacklistRegExp: null,
|
|
288
|
+
|
|
264
289
|
/**
|
|
265
290
|
* @description Attributes of tags whitelist used by the cleanHTML method
|
|
266
291
|
* @private
|
|
267
292
|
*/
|
|
268
293
|
_attributesTagsWhitelist: null,
|
|
269
294
|
|
|
295
|
+
/**
|
|
296
|
+
* @description Attributes of tags blacklist used by the cleanHTML method
|
|
297
|
+
* @private
|
|
298
|
+
*/
|
|
299
|
+
_attributesTagsBlacklist: null,
|
|
300
|
+
|
|
270
301
|
/**
|
|
271
302
|
* @description binded controllersOff method
|
|
272
303
|
* @private
|
|
@@ -414,6 +445,24 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
414
445
|
*/
|
|
415
446
|
commandMap: null,
|
|
416
447
|
|
|
448
|
+
/**
|
|
449
|
+
* @description CSS properties related to style tags
|
|
450
|
+
* @private
|
|
451
|
+
*/
|
|
452
|
+
_commandMapStyles: {
|
|
453
|
+
STRONG: ['font-weight'],
|
|
454
|
+
U: ['text-decoration'],
|
|
455
|
+
EM: ['font-style'],
|
|
456
|
+
DEL: ['text-decoration']
|
|
457
|
+
},
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* @description Contains pairs of all "data-commands" and "elements" setted in toolbar over time
|
|
461
|
+
* Used primarily to save and recover button states after the toolbar re-creation
|
|
462
|
+
* Updates each "_cachingButtons()" invocation
|
|
463
|
+
*/
|
|
464
|
+
allCommandButtons: null,
|
|
465
|
+
|
|
417
466
|
/**
|
|
418
467
|
* @description Style button related to edit area
|
|
419
468
|
* @property {Element} fullScreen fullScreen button element
|
|
@@ -471,6 +520,40 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
471
520
|
_lineBreakDir: ''
|
|
472
521
|
},
|
|
473
522
|
|
|
523
|
+
/**
|
|
524
|
+
* @description Save the current buttons states to "allCommandButtons" object
|
|
525
|
+
*/
|
|
526
|
+
saveButtonStates: function () {
|
|
527
|
+
if (!this.allCommandButtons) this.allCommandButtons = {};
|
|
528
|
+
|
|
529
|
+
const currentButtons = this.context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]');
|
|
530
|
+
for (let i = 0, element, command; i < currentButtons.length; i++) {
|
|
531
|
+
element = currentButtons[i];
|
|
532
|
+
command = element.getAttribute('data-command');
|
|
533
|
+
|
|
534
|
+
this.allCommandButtons[command] = element;
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* @description Recover the current buttons states from "allCommandButtons" object
|
|
540
|
+
*/
|
|
541
|
+
recoverButtonStates: function () {
|
|
542
|
+
if (this.allCommandButtons) {
|
|
543
|
+
const currentButtons = this.context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]');
|
|
544
|
+
for (let i = 0, button, command, oldButton; i < currentButtons.length; i++) {
|
|
545
|
+
button = currentButtons[i];
|
|
546
|
+
command = button.getAttribute('data-command');
|
|
547
|
+
|
|
548
|
+
oldButton = this.allCommandButtons[command];
|
|
549
|
+
if (oldButton) {
|
|
550
|
+
button.parentElement.replaceChild(oldButton, button);
|
|
551
|
+
if (this.context.tool[command]) this.context.tool[command] = oldButton;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
|
|
474
557
|
/**
|
|
475
558
|
* @description If the plugin is not added, add the plugin and call the 'add' function.
|
|
476
559
|
* If the plugin is added call callBack function.
|
|
@@ -559,7 +642,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
559
642
|
},
|
|
560
643
|
|
|
561
644
|
/**
|
|
562
|
-
* @description
|
|
645
|
+
* @description Enable submenu
|
|
563
646
|
* @param {Element} element Submenu's button element to call
|
|
564
647
|
*/
|
|
565
648
|
submenuOn: function (element) {
|
|
@@ -598,7 +681,19 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
598
681
|
},
|
|
599
682
|
|
|
600
683
|
/**
|
|
601
|
-
* @description
|
|
684
|
+
* @description Disable more layer
|
|
685
|
+
*/
|
|
686
|
+
moreLayerOff: function() {
|
|
687
|
+
if (this._moreLayerActiveButton) {
|
|
688
|
+
const layer = context.element.toolbar.querySelector('.' + this._moreLayerActiveButton.getAttribute('data-command'));
|
|
689
|
+
layer.style.display = 'none';
|
|
690
|
+
util.removeClass(this._moreLayerActiveButton, 'on');
|
|
691
|
+
this._moreLayerActiveButton = null;
|
|
692
|
+
}
|
|
693
|
+
},
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* @description Enable container
|
|
602
697
|
* @param {Element} element Container's button element to call
|
|
603
698
|
*/
|
|
604
699
|
containerOn: function (element) {
|
|
@@ -868,14 +963,21 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
868
963
|
* @description Focus to wysiwyg area using "native focus function"
|
|
869
964
|
*/
|
|
870
965
|
nativeFocus: function () {
|
|
966
|
+
this.__focus();
|
|
967
|
+
this._editorRange();
|
|
968
|
+
},
|
|
969
|
+
|
|
970
|
+
/**
|
|
971
|
+
* @description Focus method
|
|
972
|
+
* @private
|
|
973
|
+
*/
|
|
974
|
+
__focus: function () {
|
|
871
975
|
const caption = util.getParentElement(this.getSelectionNode(), 'figcaption');
|
|
872
976
|
if (caption) {
|
|
873
977
|
caption.focus();
|
|
874
978
|
} else {
|
|
875
979
|
context.element.wysiwyg.focus();
|
|
876
980
|
}
|
|
877
|
-
|
|
878
|
-
this._editorRange();
|
|
879
981
|
},
|
|
880
982
|
|
|
881
983
|
/**
|
|
@@ -980,8 +1082,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
980
1082
|
}
|
|
981
1083
|
|
|
982
1084
|
selection.addRange(range);
|
|
983
|
-
this.
|
|
984
|
-
if (options.iframe) this.
|
|
1085
|
+
this._rangeInfo(range, this.getSelection());
|
|
1086
|
+
if (options.iframe) this.__focus();
|
|
985
1087
|
|
|
986
1088
|
return range;
|
|
987
1089
|
},
|
|
@@ -1074,7 +1176,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1074
1176
|
const selection = this.getSelection();
|
|
1075
1177
|
if (!selection) return null;
|
|
1076
1178
|
let range = null;
|
|
1077
|
-
let selectionNode = null;
|
|
1078
1179
|
|
|
1079
1180
|
if (selection.rangeCount > 0) {
|
|
1080
1181
|
range = selection.getRangeAt(0);
|
|
@@ -1082,6 +1183,20 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1082
1183
|
range = this._createDefaultRange();
|
|
1083
1184
|
}
|
|
1084
1185
|
|
|
1186
|
+
if (util.isFormatElement(range.endContainer) && range.endOffset === 0) {
|
|
1187
|
+
range = this.setRange(range.startContainer, range.startOffset, range.startContainer, range.startContainer.length);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
this._rangeInfo(range, selection);
|
|
1191
|
+
},
|
|
1192
|
+
|
|
1193
|
+
/**
|
|
1194
|
+
* @description Set "range" and "selection" info.
|
|
1195
|
+
* @param {Object} range range object.
|
|
1196
|
+
* @param {Object} selection selection object.
|
|
1197
|
+
*/
|
|
1198
|
+
_rangeInfo: function (range, selection) {
|
|
1199
|
+
let selectionNode = null;
|
|
1085
1200
|
this._variable._range = range;
|
|
1086
1201
|
|
|
1087
1202
|
if (range.collapsed) {
|
|
@@ -1145,19 +1260,19 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1145
1260
|
|
|
1146
1261
|
if (util.isFormatElement(startCon)) {
|
|
1147
1262
|
if (!startCon.childNodes[startOff]) {
|
|
1148
|
-
startCon = startCon.lastChild;
|
|
1263
|
+
startCon = startCon.lastChild || startCon;
|
|
1149
1264
|
startOff = startCon.textContent.length;
|
|
1150
1265
|
} else {
|
|
1151
|
-
startCon = startCon.childNodes[startOff];
|
|
1266
|
+
startCon = startCon.childNodes[startOff] || startCon;
|
|
1152
1267
|
startOff = 0;
|
|
1153
1268
|
}
|
|
1154
1269
|
while (startCon && startCon.nodeType === 1 && startCon.firstChild) {
|
|
1155
|
-
startCon = startCon.firstChild;
|
|
1270
|
+
startCon = startCon.firstChild || startCon;
|
|
1156
1271
|
startOff = 0;
|
|
1157
1272
|
}
|
|
1158
1273
|
}
|
|
1159
1274
|
if (util.isFormatElement(endCon)) {
|
|
1160
|
-
endCon = endCon.childNodes[endOff] || endCon.lastChild;
|
|
1275
|
+
endCon = endCon.childNodes[endOff] || endCon.lastChild || endCon;
|
|
1161
1276
|
while (endCon && endCon.nodeType === 1 && endCon.lastChild) {
|
|
1162
1277
|
endCon = endCon.lastChild;
|
|
1163
1278
|
}
|
|
@@ -1255,7 +1370,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1255
1370
|
if (util.isWysiwygDiv(range.startContainer)) {
|
|
1256
1371
|
const children = context.element.wysiwyg.children;
|
|
1257
1372
|
if (children.length === 0) return [];
|
|
1258
|
-
|
|
1259
1373
|
this.setRange(children[0], 0, children[children.length - 1], children[children.length - 1].textContent.trim().length);
|
|
1260
1374
|
range = this.getRange();
|
|
1261
1375
|
}
|
|
@@ -1397,7 +1511,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1397
1511
|
* @returns {Element}
|
|
1398
1512
|
*/
|
|
1399
1513
|
appendFormatTag: function (element, formatNode) {
|
|
1400
|
-
if (!element.parentNode) return null;
|
|
1514
|
+
if (!element || !element.parentNode) return null;
|
|
1401
1515
|
|
|
1402
1516
|
const currentFormatEl = util.getFormatElement(this.getSelectionNode(), null);
|
|
1403
1517
|
let oFormat = null;
|
|
@@ -1451,9 +1565,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1451
1565
|
if (formatEl && util.onlyZeroWidthSpace(formatEl)) util.removeItem(formatEl);
|
|
1452
1566
|
}
|
|
1453
1567
|
|
|
1454
|
-
this.setRange(element, 0, element, 0);
|
|
1455
|
-
|
|
1456
1568
|
if (!notSelect) {
|
|
1569
|
+
this.setRange(element, 0, element, 0);
|
|
1570
|
+
|
|
1457
1571
|
const fileComponentInfo = this.getFileComponent(element);
|
|
1458
1572
|
if (fileComponentInfo) {
|
|
1459
1573
|
this.selectComponent(fileComponentInfo.target, fileComponentInfo.pluginName);
|
|
@@ -1592,8 +1706,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1592
1706
|
const startOff = range.startOffset;
|
|
1593
1707
|
const endOff = range.endOffset;
|
|
1594
1708
|
const formatRange = range.startContainer === commonCon && util.isFormatElement(commonCon);
|
|
1595
|
-
const startCon = formatRange ? (commonCon.childNodes[startOff] || commonCon.childNodes[0]) : range.startContainer;
|
|
1596
|
-
const endCon = formatRange ? (commonCon.childNodes[endOff] || commonCon.childNodes[commonCon.childNodes.length - 1]) : range.endContainer;
|
|
1709
|
+
const startCon = formatRange ? (commonCon.childNodes[startOff] || commonCon.childNodes[0] || range.startContainer) : range.startContainer;
|
|
1710
|
+
const endCon = formatRange ? (commonCon.childNodes[endOff] || commonCon.childNodes[commonCon.childNodes.length - 1] || range.endContainer) : range.endContainer;
|
|
1597
1711
|
let parentNode, originAfter = null;
|
|
1598
1712
|
|
|
1599
1713
|
if (!afterNode) {
|
|
@@ -2712,7 +2826,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
2712
2826
|
for (let i = endLength - 1, newRange; i > 0; i--) {
|
|
2713
2827
|
newNode = appendNode.cloneNode(false);
|
|
2714
2828
|
newRange = this._nodeChange_middleLine(lineNodes[i], newNode, validation, isRemoveFormat, isRemoveNode, _removeCheck, end.container);
|
|
2715
|
-
if (newRange.endContainer) {
|
|
2829
|
+
if (newRange.endContainer && newRange.ancestor.contains(newRange.endContainer)) {
|
|
2716
2830
|
end.ancestor = null;
|
|
2717
2831
|
end.container = newRange.endContainer;
|
|
2718
2832
|
}
|
|
@@ -3987,7 +4101,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
3987
4101
|
return {
|
|
3988
4102
|
ancestor: pNode,
|
|
3989
4103
|
container: container,
|
|
3990
|
-
offset: offset
|
|
4104
|
+
offset: container.nodeType === 1 && offset === 1 ? container.childNodes.length : offset
|
|
3991
4105
|
};
|
|
3992
4106
|
},
|
|
3993
4107
|
|
|
@@ -4000,19 +4114,27 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4000
4114
|
actionCall: function (command, display, target) {
|
|
4001
4115
|
// call plugins
|
|
4002
4116
|
if (display) {
|
|
4003
|
-
if (/more/i.test(display)
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
if (
|
|
4007
|
-
(
|
|
4008
|
-
|
|
4117
|
+
if (/more/i.test(display)) {
|
|
4118
|
+
if (target !== this._moreLayerActiveButton) {
|
|
4119
|
+
const layer = context.element.toolbar.querySelector('.' + command);
|
|
4120
|
+
if (layer) {
|
|
4121
|
+
if (this._moreLayerActiveButton) this.moreLayerOff();
|
|
4122
|
+
|
|
4123
|
+
this._moreLayerActiveButton = target;
|
|
4124
|
+
layer.style.display = 'block';
|
|
4125
|
+
|
|
4126
|
+
event._showToolbarBalloon();
|
|
4127
|
+
event._showToolbarInline();
|
|
4009
4128
|
}
|
|
4010
4129
|
util.addClass(target, 'on');
|
|
4011
|
-
|
|
4012
|
-
layer.
|
|
4130
|
+
} else {
|
|
4131
|
+
const layer = context.element.toolbar.querySelector('.' + this._moreLayerActiveButton.getAttribute('data-command'));
|
|
4132
|
+
if (layer) {
|
|
4133
|
+
this.moreLayerOff();
|
|
4013
4134
|
|
|
4014
|
-
|
|
4015
|
-
|
|
4135
|
+
event._showToolbarBalloon();
|
|
4136
|
+
event._showToolbarInline();
|
|
4137
|
+
}
|
|
4016
4138
|
}
|
|
4017
4139
|
return;
|
|
4018
4140
|
}
|
|
@@ -4022,7 +4144,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4022
4144
|
return;
|
|
4023
4145
|
}
|
|
4024
4146
|
|
|
4025
|
-
if (this.isReadOnly) return;
|
|
4147
|
+
if (this.isReadOnly && util.arrayIncludes(this.resizingDisabledButtons, target)) return;
|
|
4026
4148
|
if (/submenu/.test(display) && (this._menuTray[command] === null || target !== this.submenuActiveButton)) {
|
|
4027
4149
|
this.callPlugin(command, this.submenuOn.bind(this, target), target);
|
|
4028
4150
|
return;
|
|
@@ -4039,17 +4161,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4039
4161
|
this.commandHandler(target, command);
|
|
4040
4162
|
}
|
|
4041
4163
|
|
|
4042
|
-
if (/
|
|
4043
|
-
const layer = context.element.toolbar.querySelector('.' + this._moreLayerActiveButton.getAttribute('data-command'));
|
|
4044
|
-
if (layer) {
|
|
4045
|
-
util.removeClass(this._moreLayerActiveButton, 'on');
|
|
4046
|
-
this._moreLayerActiveButton = null;
|
|
4047
|
-
layer.style.display = 'none';
|
|
4048
|
-
|
|
4049
|
-
event._showToolbarBalloon();
|
|
4050
|
-
event._showToolbarInline();
|
|
4051
|
-
}
|
|
4052
|
-
} else if (/submenu/.test(display)) {
|
|
4164
|
+
if (/submenu/.test(display)) {
|
|
4053
4165
|
this.submenuOff();
|
|
4054
4166
|
} else if (!/command/.test(display)) {
|
|
4055
4167
|
this.submenuOff();
|
|
@@ -4073,6 +4185,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4073
4185
|
case 'paste':
|
|
4074
4186
|
break;
|
|
4075
4187
|
case 'selectAll':
|
|
4188
|
+
this.containerOff();
|
|
4076
4189
|
const wysiwyg = context.element.wysiwyg;
|
|
4077
4190
|
let first = util.getChildElement(wysiwyg.firstChild, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, false) || wysiwyg.firstChild;
|
|
4078
4191
|
let last = util.getChildElement(wysiwyg.lastChild, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, true) || wysiwyg.lastChild;
|
|
@@ -4124,6 +4237,15 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4124
4237
|
case 'showBlocks':
|
|
4125
4238
|
this.toggleDisplayBlocks();
|
|
4126
4239
|
break;
|
|
4240
|
+
case 'dir':
|
|
4241
|
+
this.setDir(options.rtl ? 'ltr' : 'rtl');
|
|
4242
|
+
break;
|
|
4243
|
+
case 'dir_ltr':
|
|
4244
|
+
this.setDir('ltr');
|
|
4245
|
+
break;
|
|
4246
|
+
case 'dir_rtl':
|
|
4247
|
+
this.setDir('rtl');
|
|
4248
|
+
break;
|
|
4127
4249
|
case 'save':
|
|
4128
4250
|
if (typeof options.callBackSave === 'function') {
|
|
4129
4251
|
options.callBackSave(this.getContents(false), this._variable.isChanged);
|
|
@@ -4150,7 +4272,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4150
4272
|
removeNode = 'SUB';
|
|
4151
4273
|
}
|
|
4152
4274
|
|
|
4153
|
-
this.nodeChange(cmd, null, [removeNode], false);
|
|
4275
|
+
this.nodeChange(cmd, this._commandMapStyles[command] || null, [removeNode], false);
|
|
4154
4276
|
this.focus();
|
|
4155
4277
|
}
|
|
4156
4278
|
},
|
|
@@ -4230,7 +4352,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4230
4352
|
util.setDisabledButtons(!isCodeView, this.codeViewDisabledButtons);
|
|
4231
4353
|
|
|
4232
4354
|
if (isCodeView) {
|
|
4233
|
-
this._setCodeDataToEditor();
|
|
4355
|
+
if (!util.isNonEditable(context.element.wysiwygFrame)) this._setCodeDataToEditor();
|
|
4234
4356
|
context.element.wysiwygFrame.scrollTop = 0;
|
|
4235
4357
|
context.element.code.style.display = 'none';
|
|
4236
4358
|
context.element.wysiwygFrame.style.display = 'block';
|
|
@@ -4256,14 +4378,18 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4256
4378
|
util.removeClass(this._styleCommandMap.codeView, 'active');
|
|
4257
4379
|
|
|
4258
4380
|
// history stack
|
|
4259
|
-
|
|
4260
|
-
|
|
4381
|
+
if (!util.isNonEditable(context.element.wysiwygFrame)) {
|
|
4382
|
+
this.history.push(false);
|
|
4383
|
+
this.history._resetCachingButton();
|
|
4384
|
+
}
|
|
4261
4385
|
} else {
|
|
4262
4386
|
this._setEditorDataToCodeView();
|
|
4263
4387
|
this._variable._codeOriginCssText = this._variable._codeOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/, 'display: block');
|
|
4264
4388
|
this._variable._wysiwygOriginCssText = this._variable._wysiwygOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/, 'display: none');
|
|
4265
4389
|
|
|
4266
|
-
if (
|
|
4390
|
+
if (this._variable.isFullScreen) context.element.code.style.height = '100%';
|
|
4391
|
+
else if (options.height === 'auto' && !options.codeMirrorEditor) context.element.code.style.height = context.element.code.scrollHeight > 0 ? (context.element.code.scrollHeight + 'px') : 'auto';
|
|
4392
|
+
|
|
4267
4393
|
if (options.codeMirrorEditor) options.codeMirrorEditor.refresh();
|
|
4268
4394
|
|
|
4269
4395
|
this._variable.isCodeView = true;
|
|
@@ -4309,7 +4435,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4309
4435
|
}
|
|
4310
4436
|
}
|
|
4311
4437
|
|
|
4312
|
-
|
|
4438
|
+
let headers = parseDocument.head.innerHTML;
|
|
4439
|
+
if (!parseDocument.head.querySelector('link[rel="stylesheet"]') || (this.options.height === 'auto' && !parseDocument.head.querySelector('style'))) {
|
|
4440
|
+
headers += util._setIframeCssTags(this.options);
|
|
4441
|
+
}
|
|
4442
|
+
|
|
4443
|
+
this._wd.head.innerHTML = headers;
|
|
4313
4444
|
this._wd.body.innerHTML = this.convertContentsForEditor(parseDocument.body.innerHTML);
|
|
4314
4445
|
|
|
4315
4446
|
const attrs = parseDocument.body.attributes;
|
|
@@ -4333,7 +4464,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4333
4464
|
* @private
|
|
4334
4465
|
*/
|
|
4335
4466
|
_setEditorDataToCodeView: function () {
|
|
4336
|
-
const codeContents = this.convertHTMLForCodeView(context.element.wysiwyg);
|
|
4467
|
+
const codeContents = this.convertHTMLForCodeView(context.element.wysiwyg, false);
|
|
4337
4468
|
let codeValue = '';
|
|
4338
4469
|
|
|
4339
4470
|
if (options.fullPage) {
|
|
@@ -4351,7 +4482,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4351
4482
|
|
|
4352
4483
|
/**
|
|
4353
4484
|
* @description Changes to full screen or default screen
|
|
4354
|
-
* @param {Element} element full screen button
|
|
4485
|
+
* @param {Element|null} element full screen button
|
|
4355
4486
|
*/
|
|
4356
4487
|
toggleFullScreen: function (element) {
|
|
4357
4488
|
const topArea = context.element.topArea;
|
|
@@ -4361,6 +4492,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4361
4492
|
const code = context.element.code;
|
|
4362
4493
|
const _var = this._variable;
|
|
4363
4494
|
this.controllersOff();
|
|
4495
|
+
|
|
4496
|
+
const wasToolbarHidden = (toolbar.style.display === 'none' || (this._isInline && !this._inlineToolbarAttr.isShow));
|
|
4364
4497
|
|
|
4365
4498
|
if (!_var.isFullScreen) {
|
|
4366
4499
|
_var.isFullScreen = true;
|
|
@@ -4406,7 +4539,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4406
4539
|
_var.innerHeight_fullScreen = (_w.innerHeight - toolbar.offsetHeight);
|
|
4407
4540
|
editorArea.style.height = (_var.innerHeight_fullScreen - options.fullScreenOffset) + 'px';
|
|
4408
4541
|
|
|
4409
|
-
util.changeElement(element.firstElementChild, icons.reduction);
|
|
4542
|
+
if (element) util.changeElement(element.firstElementChild, icons.reduction);
|
|
4410
4543
|
|
|
4411
4544
|
if (options.iframe && options.height === 'auto') {
|
|
4412
4545
|
editorArea.style.overflow = 'auto';
|
|
@@ -4425,6 +4558,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4425
4558
|
topArea.style.cssText = _var._originCssText;
|
|
4426
4559
|
_d.body.style.overflow = _var._bodyOverflow;
|
|
4427
4560
|
|
|
4561
|
+
if (options.height === 'auto' && !options.codeMirrorEditor) event._codeViewAutoHeight();
|
|
4562
|
+
|
|
4428
4563
|
if (!!options.toolbarContainer) options.toolbarContainer.appendChild(toolbar);
|
|
4429
4564
|
|
|
4430
4565
|
if (options.stickyToolbar > -1) {
|
|
@@ -4443,12 +4578,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4443
4578
|
if (!!options.toolbarContainer) util.removeClass(toolbar, 'se-toolbar-balloon');
|
|
4444
4579
|
|
|
4445
4580
|
event.onScroll_window();
|
|
4446
|
-
util.changeElement(element.firstElementChild, icons.expansion);
|
|
4581
|
+
if (element) util.changeElement(element.firstElementChild, icons.expansion);
|
|
4447
4582
|
|
|
4448
4583
|
context.element.topArea.style.marginTop = '';
|
|
4449
4584
|
util.removeClass(this._styleCommandMap.fullScreen, 'active');
|
|
4450
4585
|
}
|
|
4451
4586
|
|
|
4587
|
+
if (wasToolbarHidden) functions.toolbar.hide();
|
|
4588
|
+
|
|
4452
4589
|
// user event
|
|
4453
4590
|
if (typeof functions.toggleFullScreen === 'function') functions.toggleFullScreen(this._variable.isFullScreen, this);
|
|
4454
4591
|
},
|
|
@@ -4571,6 +4708,70 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4571
4708
|
}
|
|
4572
4709
|
},
|
|
4573
4710
|
|
|
4711
|
+
/**
|
|
4712
|
+
* @description Set direction to "rtl" or "ltr".
|
|
4713
|
+
* @param {String} dir "rtl" or "ltr"
|
|
4714
|
+
*/
|
|
4715
|
+
setDir: function (dir) {
|
|
4716
|
+
const rtl = dir === 'rtl';
|
|
4717
|
+
const changeDir = this._prevRtl !== rtl;
|
|
4718
|
+
this._prevRtl = options.rtl = rtl;
|
|
4719
|
+
|
|
4720
|
+
if (changeDir) {
|
|
4721
|
+
// align buttons
|
|
4722
|
+
if (this.plugins.align) {
|
|
4723
|
+
this.plugins.align.exchangeDir.call(this);
|
|
4724
|
+
}
|
|
4725
|
+
// indent buttons
|
|
4726
|
+
if (context.tool.indent) util.changeElement(context.tool.indent.firstElementChild, icons.indent);
|
|
4727
|
+
if (context.tool.outdent) util.changeElement(context.tool.outdent.firstElementChild, icons.outdent);
|
|
4728
|
+
}
|
|
4729
|
+
|
|
4730
|
+
const el = context.element;
|
|
4731
|
+
if (rtl) {
|
|
4732
|
+
util.addClass(el.topArea, 'se-rtl');
|
|
4733
|
+
util.addClass(el.wysiwygFrame, 'se-rtl');
|
|
4734
|
+
} else {
|
|
4735
|
+
util.removeClass(el.topArea, 'se-rtl');
|
|
4736
|
+
util.removeClass(el.wysiwygFrame, 'se-rtl');
|
|
4737
|
+
}
|
|
4738
|
+
|
|
4739
|
+
const lineNodes = util.getListChildren(el.wysiwyg, function (current) {
|
|
4740
|
+
return util.isFormatElement(current) && (current.style.marginRight || current.style.marginLeft || current.style.textAlign);
|
|
4741
|
+
});
|
|
4742
|
+
|
|
4743
|
+
for (let i = 0, len = lineNodes.length, n, l, r; i < len; i++) {
|
|
4744
|
+
n = lineNodes[i];
|
|
4745
|
+
// indent margin
|
|
4746
|
+
r = n.style.marginRight;
|
|
4747
|
+
l = n.style.marginLeft;
|
|
4748
|
+
if (r || l) {
|
|
4749
|
+
n.style.marginRight = l;
|
|
4750
|
+
n.style.marginLeft = r;
|
|
4751
|
+
}
|
|
4752
|
+
// text align
|
|
4753
|
+
r = n.style.textAlign;
|
|
4754
|
+
if (r === 'left') n.style.textAlign = 'right';
|
|
4755
|
+
else if (r === 'right') n.style.textAlign = 'left';
|
|
4756
|
+
}
|
|
4757
|
+
|
|
4758
|
+
const tool = context.tool;
|
|
4759
|
+
if (tool.dir) {
|
|
4760
|
+
util.changeTxt(tool.dir.querySelector('.se-tooltip-text'), lang.toolbar[options.rtl ? 'dir_ltr' : 'dir_rtl']);
|
|
4761
|
+
util.changeElement(tool.dir.firstElementChild, icons[options.rtl ? 'dir_ltr' : 'dir_rtl']);
|
|
4762
|
+
}
|
|
4763
|
+
|
|
4764
|
+
if (tool.dir_ltr) {
|
|
4765
|
+
if (rtl) util.removeClass(tool.dir_ltr, 'active');
|
|
4766
|
+
else util.addClass(tool.dir_ltr, 'active');
|
|
4767
|
+
}
|
|
4768
|
+
|
|
4769
|
+
if (tool.dir_rtl) {
|
|
4770
|
+
if (rtl) util.addClass(tool.dir_rtl, 'active');
|
|
4771
|
+
else util.removeClass(tool.dir_rtl, 'active');
|
|
4772
|
+
}
|
|
4773
|
+
},
|
|
4774
|
+
|
|
4574
4775
|
/**
|
|
4575
4776
|
* @description Sets the HTML string
|
|
4576
4777
|
* @param {String|undefined} html HTML string
|
|
@@ -4586,7 +4787,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4586
4787
|
// history stack
|
|
4587
4788
|
this.history.push(false);
|
|
4588
4789
|
} else {
|
|
4589
|
-
const value = this.convertHTMLForCodeView(convertValue);
|
|
4790
|
+
const value = this.convertHTMLForCodeView(convertValue, false);
|
|
4590
4791
|
this._setCodeView(value);
|
|
4591
4792
|
}
|
|
4592
4793
|
},
|
|
@@ -4607,7 +4808,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4607
4808
|
* @returns {Object}
|
|
4608
4809
|
*/
|
|
4609
4810
|
getContents: function (onlyContents) {
|
|
4610
|
-
const contents = context.element.wysiwyg
|
|
4811
|
+
const contents = this.convertHTMLForCodeView(context.element.wysiwyg, true);
|
|
4611
4812
|
const renderHTML = util.createElement('DIV');
|
|
4612
4813
|
renderHTML.innerHTML = contents;
|
|
4613
4814
|
|
|
@@ -4690,7 +4891,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4690
4891
|
.replace(/\n/g, '')
|
|
4691
4892
|
.replace(/<(script|style)[\s\S]*>[\s\S]*<\/(script|style)>/gi, '')
|
|
4692
4893
|
.replace(/<[a-z0-9]+\:[a-z0-9]+[^>^\/]*>[^>]*<\/[a-z0-9]+\:[a-z0-9]+>/gi, '')
|
|
4693
|
-
.replace(this.editorTagsWhitelistRegExp, '')
|
|
4894
|
+
.replace(this.editorTagsWhitelistRegExp, '')
|
|
4895
|
+
.replace(this.editorTagsBlacklistRegExp, '');
|
|
4694
4896
|
},
|
|
4695
4897
|
|
|
4696
4898
|
/**
|
|
@@ -4705,18 +4907,28 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4705
4907
|
if (/^<[a-z0-9]+\:[a-z0-9]+/i.test(m)) return m;
|
|
4706
4908
|
|
|
4707
4909
|
let v = null;
|
|
4708
|
-
const
|
|
4709
|
-
|
|
4910
|
+
const tagName = t.match(/(?!<)[a-zA-Z0-9\-]+/)[0].toLowerCase();
|
|
4911
|
+
|
|
4912
|
+
// blacklist
|
|
4913
|
+
const bAttr = this._attributesTagsBlacklist[tagName];
|
|
4914
|
+
if (bAttr) m = m.replace(bAttr, '');
|
|
4915
|
+
else m = m.replace(this._attributesBlacklistRegExp, '');
|
|
4916
|
+
|
|
4917
|
+
// whitelist
|
|
4918
|
+
const wAttr = this._attributesTagsWhitelist[tagName];
|
|
4919
|
+
if (wAttr) v = m.match(wAttr);
|
|
4710
4920
|
else v = m.match(this._attributesWhitelistRegExp);
|
|
4711
4921
|
|
|
4922
|
+
// anchor
|
|
4712
4923
|
if (!lowLevelCheck || /<a\b/i.test(t)) {
|
|
4713
|
-
const sv = m.match(/id\s*=\s*(?:"|')[^"']*(?:"|')/);
|
|
4924
|
+
const sv = m.match(/(?:(?:id|name)\s*=\s*(?:"|')[^"']*(?:"|'))/g);
|
|
4714
4925
|
if (sv) {
|
|
4715
4926
|
if (!v) v = [];
|
|
4716
4927
|
v.push(sv[0]);
|
|
4717
4928
|
}
|
|
4718
4929
|
}
|
|
4719
4930
|
|
|
4931
|
+
// span
|
|
4720
4932
|
if ((!lowLevelCheck || /<span/i.test(t)) && (!v || !/style=/i.test(v.toString()))) {
|
|
4721
4933
|
const sv = m.match(/style\s*=\s*(?:"|')[^"']*(?:"|')/);
|
|
4722
4934
|
if (sv) {
|
|
@@ -4725,6 +4937,29 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4725
4937
|
}
|
|
4726
4938
|
}
|
|
4727
4939
|
|
|
4940
|
+
// img
|
|
4941
|
+
if (/<img/i.test(t)) {
|
|
4942
|
+
let w = '', h = '';
|
|
4943
|
+
const sv = m.match(/style\s*=\s*(?:"|')[^"']*(?:"|')/);
|
|
4944
|
+
if (!v) v = [];
|
|
4945
|
+
if (sv) {
|
|
4946
|
+
w = sv[0].match(/width:(.+);/);
|
|
4947
|
+
w = util.getNumber(w ? w[1] : '', -1) || '';
|
|
4948
|
+
h = sv[0].match(/height:(.+);/);
|
|
4949
|
+
h = util.getNumber(h ? h[1] : '', -1) || '';
|
|
4950
|
+
}
|
|
4951
|
+
|
|
4952
|
+
if (!w || !h) {
|
|
4953
|
+
const avw = m.match(/width\s*=\s*((?:"|')[^"']*(?:"|'))/);
|
|
4954
|
+
const avh = m.match(/height\s*=\s*((?:"|')[^"']*(?:"|'))/);
|
|
4955
|
+
if (avw || avh) {
|
|
4956
|
+
w = !w ? util.getNumber(avw ? avw[1] : '') || '' : w;
|
|
4957
|
+
h = !h ? util.getNumber(avh ? avh[1] : '') || '' : h;
|
|
4958
|
+
}
|
|
4959
|
+
}
|
|
4960
|
+
v.push('data-origin="' + (w + ',' + h) + '"');
|
|
4961
|
+
}
|
|
4962
|
+
|
|
4728
4963
|
if (v) {
|
|
4729
4964
|
for (let i = 0, len = v.length; i < len; i++) {
|
|
4730
4965
|
if (lowLevelCheck && /^class="(?!(__se__|se-|katex))/.test(v[i])) continue;
|
|
@@ -4740,14 +4975,16 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4740
4975
|
* @param {String} html HTML string
|
|
4741
4976
|
* @param {String|RegExp|null} whitelist Regular expression of allowed tags.
|
|
4742
4977
|
* RegExp object is create by util.createTagsWhitelist method. (core.pasteTagsWhitelistRegExp)
|
|
4978
|
+
* @param {String|RegExp|null} blacklist Regular expression of disallowed tags.
|
|
4979
|
+
* RegExp object is create by util.createTagsBlacklist method. (core.pasteTagsBlacklistRegExp)
|
|
4743
4980
|
* @returns {String}
|
|
4744
4981
|
*/
|
|
4745
|
-
cleanHTML: function (html, whitelist) {
|
|
4982
|
+
cleanHTML: function (html, whitelist, blacklist) {
|
|
4746
4983
|
html = this._deleteDisallowedTags(this._parser.parseFromString(html, 'text/html').body.innerHTML).replace(/(<[a-zA-Z0-9\-]+)[^>]*(?=>)/g, this._cleanTags.bind(this, true));
|
|
4747
4984
|
|
|
4748
4985
|
const dom = _d.createRange().createContextualFragment(html);
|
|
4749
4986
|
try {
|
|
4750
|
-
util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, true);
|
|
4987
|
+
util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, this._htmlCheckBlacklistRegExp, true);
|
|
4751
4988
|
} catch (error) {
|
|
4752
4989
|
console.warn('[SUNEDITOR.cleanHTML.consistencyCheck.fail] ' + error);
|
|
4753
4990
|
}
|
|
@@ -4783,7 +5020,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4783
5020
|
}
|
|
4784
5021
|
|
|
4785
5022
|
cleanHTML = util.htmlRemoveWhiteSpace(cleanHTML);
|
|
4786
|
-
|
|
5023
|
+
if (!cleanHTML) {
|
|
5024
|
+
cleanHTML = html;
|
|
5025
|
+
} else {
|
|
5026
|
+
if (whitelist) cleanHTML = cleanHTML.replace(typeof whitelist === 'string' ? util.createTagsWhitelist(whitelist) : whitelist, '');
|
|
5027
|
+
if (blacklist) cleanHTML = cleanHTML.replace(typeof blacklist === 'string' ? util.createTagsBlacklist(blacklist) : blacklist, '');
|
|
5028
|
+
}
|
|
5029
|
+
|
|
5030
|
+
return this._tagConvertor(cleanHTML);
|
|
4787
5031
|
},
|
|
4788
5032
|
|
|
4789
5033
|
/**
|
|
@@ -4796,7 +5040,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4796
5040
|
const dom = _d.createRange().createContextualFragment(contents);
|
|
4797
5041
|
|
|
4798
5042
|
try {
|
|
4799
|
-
util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, false);
|
|
5043
|
+
util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, this._htmlCheckBlacklistRegExp, false);
|
|
4800
5044
|
} catch (error) {
|
|
4801
5045
|
console.warn('[SUNEDITOR.convertContentsForEditor.consistencyCheck.fail] ' + error);
|
|
4802
5046
|
}
|
|
@@ -4817,8 +5061,20 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4817
5061
|
|
|
4818
5062
|
const domTree = dom.childNodes;
|
|
4819
5063
|
let cleanHTML = '';
|
|
4820
|
-
for (let i = 0,
|
|
4821
|
-
|
|
5064
|
+
for (let i = 0, t, p; i < domTree.length; i++) {
|
|
5065
|
+
t = domTree[i];
|
|
5066
|
+
if (!util.isFormatElement(t) && !util.isComponent(t) && !util.isMedia(t)) {
|
|
5067
|
+
if (!p) p = util.createElement(options.defaultTag);
|
|
5068
|
+
p.appendChild(t);
|
|
5069
|
+
i--;
|
|
5070
|
+
if (domTree[i + 1] && !util.isFormatElement(domTree[i + 1])) {
|
|
5071
|
+
continue;
|
|
5072
|
+
} else {
|
|
5073
|
+
t = p;
|
|
5074
|
+
p = null;
|
|
5075
|
+
}
|
|
5076
|
+
}
|
|
5077
|
+
cleanHTML += this._makeLine(t, true);
|
|
4822
5078
|
}
|
|
4823
5079
|
|
|
4824
5080
|
if (cleanHTML.length === 0) return '<' + options.defaultTag + '><br></' + options.defaultTag + '>';
|
|
@@ -4830,28 +5086,30 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4830
5086
|
/**
|
|
4831
5087
|
* @description Converts wysiwyg area element into a format that can be placed in an editor of code view mode
|
|
4832
5088
|
* @param {Element|String} html WYSIWYG element (context.element.wysiwyg) or HTML string.
|
|
5089
|
+
* @param {Boolean} comp If true, does not line break and indentation of tags.
|
|
4833
5090
|
* @returns {String}
|
|
4834
5091
|
*/
|
|
4835
|
-
convertHTMLForCodeView: function (html) {
|
|
5092
|
+
convertHTMLForCodeView: function (html, comp) {
|
|
4836
5093
|
let returnHTML = '';
|
|
4837
5094
|
const wRegExp = _w.RegExp;
|
|
4838
5095
|
const brReg = new wRegExp('^(BLOCKQUOTE|PRE|TABLE|THEAD|TBODY|TR|TH|TD|OL|UL|IMG|IFRAME|VIDEO|AUDIO|FIGURE|FIGCAPTION|HR|BR|CANVAS|SELECT)$', 'i');
|
|
4839
5096
|
const wDoc = typeof html === 'string' ? _d.createRange().createContextualFragment(html) : html;
|
|
4840
5097
|
const isFormat = function (current) { return this.isFormatElement(current) || this.isComponent(current); }.bind(util);
|
|
5098
|
+
const brChar = comp ? '' : '\n';
|
|
4841
5099
|
|
|
4842
|
-
let indentSize = this._variable.codeIndent * 1;
|
|
5100
|
+
let indentSize = comp ? 0 : this._variable.codeIndent * 1;
|
|
4843
5101
|
indentSize = indentSize > 0 ? new _w.Array(indentSize + 1).join(' ') : '';
|
|
4844
5102
|
|
|
4845
|
-
(function recursionFunc (element, indent
|
|
5103
|
+
(function recursionFunc (element, indent) {
|
|
4846
5104
|
const children = element.childNodes;
|
|
4847
5105
|
const elementRegTest = brReg.test(element.nodeName);
|
|
4848
5106
|
const elementIndent = (elementRegTest ? indent : '');
|
|
4849
5107
|
|
|
4850
|
-
for (let i = 0, len = children.length, node, br, nodeRegTest, tag, tagIndent; i < len; i++) {
|
|
5108
|
+
for (let i = 0, len = children.length, node, br, lineBR, nodeRegTest, tag, tagIndent; i < len; i++) {
|
|
4851
5109
|
node = children[i];
|
|
4852
5110
|
nodeRegTest = brReg.test(node.nodeName);
|
|
4853
|
-
br = nodeRegTest ?
|
|
4854
|
-
lineBR = isFormat(node) && !elementRegTest && !/^(TH|TD)$/i.test(element.nodeName) ?
|
|
5111
|
+
br = nodeRegTest ? brChar : '';
|
|
5112
|
+
lineBR = isFormat(node) && !elementRegTest && !/^(TH|TD)$/i.test(element.nodeName) ? brChar : '';
|
|
4855
5113
|
|
|
4856
5114
|
if (node.nodeType === 8) {
|
|
4857
5115
|
returnHTML += '\n<!-- ' + node.textContent.trim() + ' -->' + br;
|
|
@@ -4862,7 +5120,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4862
5120
|
continue;
|
|
4863
5121
|
}
|
|
4864
5122
|
if (node.childNodes.length === 0) {
|
|
4865
|
-
returnHTML += (/^HR$/i.test(node.nodeName) ?
|
|
5123
|
+
returnHTML += (/^HR$/i.test(node.nodeName) ? brChar : '') + (/^PRE$/i.test(node.parentElement.nodeName) && /^BR$/i.test(node.nodeName) ? '' : elementIndent) + node.outerHTML + br;
|
|
4866
5124
|
continue;
|
|
4867
5125
|
}
|
|
4868
5126
|
|
|
@@ -4873,12 +5131,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4873
5131
|
tagIndent = elementIndent || nodeRegTest ? indent : '';
|
|
4874
5132
|
returnHTML += (lineBR || (elementRegTest ? '' : br)) + tagIndent + node.outerHTML.match(wRegExp('<' + tag + '[^>]*>', 'i'))[0] + br;
|
|
4875
5133
|
recursionFunc(node, indent + indentSize, '');
|
|
4876
|
-
returnHTML += (/\n$/.test(returnHTML) ? tagIndent : '') + '</' + tag + '>' + (lineBR || br || elementRegTest ?
|
|
5134
|
+
returnHTML += (/\n$/.test(returnHTML) ? tagIndent : '') + '</' + tag + '>' + (lineBR || br || elementRegTest ? brChar : '' || /^(TH|TD)$/i.test(node.nodeName) ? brChar : '');
|
|
4877
5135
|
}
|
|
4878
5136
|
}
|
|
4879
|
-
}(wDoc, ''
|
|
5137
|
+
}(wDoc, ''));
|
|
4880
5138
|
|
|
4881
|
-
return returnHTML.trim() +
|
|
5139
|
+
return returnHTML.trim() + brChar;
|
|
4882
5140
|
},
|
|
4883
5141
|
|
|
4884
5142
|
/**
|
|
@@ -5058,9 +5316,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5058
5316
|
if (activePlugins.indexOf(key) > -1) {
|
|
5059
5317
|
plugins[key].active.call(this, null);
|
|
5060
5318
|
} else if (commandMap.OUTDENT && /^OUTDENT$/i.test(key)) {
|
|
5061
|
-
if (!
|
|
5319
|
+
if (!util.isImportantDisabled(commandMap.OUTDENT)) commandMap.OUTDENT.setAttribute('disabled', true);
|
|
5062
5320
|
} else if (commandMap.INDENT && /^INDENT$/i.test(key)) {
|
|
5063
|
-
if (!
|
|
5321
|
+
if (!util.isImportantDisabled(commandMap.INDENT)) commandMap.INDENT.removeAttribute('disabled');
|
|
5064
5322
|
} else {
|
|
5065
5323
|
util.removeClass(commandMap[key], 'active');
|
|
5066
5324
|
}
|
|
@@ -5078,6 +5336,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5078
5336
|
this._ww = options.iframe ? context.element.wysiwygFrame.contentWindow : _w;
|
|
5079
5337
|
this._wd = _d;
|
|
5080
5338
|
this._charTypeHTML = options.charCounterType === 'byte-html';
|
|
5339
|
+
this.wwComputedStyle = _w.getComputedStyle(context.element.wysiwyg);
|
|
5081
5340
|
|
|
5082
5341
|
if (!options.iframe && typeof _w.ShadowRoot === 'function') {
|
|
5083
5342
|
let child = context.element.wysiwygFrame;
|
|
@@ -5103,30 +5362,56 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5103
5362
|
this._disallowedTextTagsRegExp = disallowTextTags.length === 0 ? null : new wRegExp('(<\\/?)(' + disallowTextTags.join('|') + ')\\b\\s*([^>^<]+)?\\s*(?=>)', 'gi');
|
|
5104
5363
|
|
|
5105
5364
|
// set whitelist
|
|
5365
|
+
const getRegList = function (str, str2) { return !str ? '^' : (str === '*' ? '[a-z-]+' : (!str2 ? str : (str + '|' + str2))); };
|
|
5366
|
+
// tags
|
|
5106
5367
|
const defaultAttr = 'contenteditable|colspan|rowspan|target|href|download|rel|src|alt|class|type|controls|data-format|data-size|data-file-size|data-file-name|data-origin|data-align|data-image-link|data-rotate|data-proportion|data-percentage|origin-size|data-exp|data-font-size';
|
|
5107
|
-
this._allowHTMLComments = options._editorTagsWhitelist.indexOf('//') > -1;
|
|
5108
|
-
|
|
5109
|
-
this.
|
|
5110
|
-
this.
|
|
5111
|
-
|
|
5368
|
+
this._allowHTMLComments = options._editorTagsWhitelist.indexOf('//') > -1 || options._editorTagsWhitelist === '*';
|
|
5369
|
+
// html check
|
|
5370
|
+
this._htmlCheckWhitelistRegExp = new wRegExp('^(' + getRegList(options._editorTagsWhitelist.replace('|//', ''), '') + ')$', 'i');
|
|
5371
|
+
this._htmlCheckBlacklistRegExp = new wRegExp('^(' + (options.tagsBlacklist || '^') + ')$', 'i');
|
|
5372
|
+
// tags
|
|
5373
|
+
this.editorTagsWhitelistRegExp = util.createTagsWhitelist(getRegList(options._editorTagsWhitelist.replace('|//', '|<!--|-->'), ''));
|
|
5374
|
+
this.editorTagsBlacklistRegExp = util.createTagsBlacklist(options.tagsBlacklist.replace('|//', '|<!--|-->'));
|
|
5375
|
+
// paste tags
|
|
5376
|
+
this.pasteTagsWhitelistRegExp = util.createTagsWhitelist(getRegList(options.pasteTagsWhitelist, ''));
|
|
5377
|
+
this.pasteTagsBlacklistRegExp = util.createTagsBlacklist(options.pasteTagsBlacklist);
|
|
5378
|
+
// attributes
|
|
5112
5379
|
const regEndStr = '\\s*=\\s*(\")[^\"]*\\1';
|
|
5113
|
-
const
|
|
5114
|
-
|
|
5380
|
+
const _wAttr = options.attributesWhitelist;
|
|
5381
|
+
let tagsAttr = {};
|
|
5115
5382
|
let allAttr = '';
|
|
5116
|
-
if (!!
|
|
5117
|
-
for (let k in
|
|
5118
|
-
if (!util.hasOwn(
|
|
5383
|
+
if (!!_wAttr) {
|
|
5384
|
+
for (let k in _wAttr) {
|
|
5385
|
+
if (!util.hasOwn(_wAttr, k) || /^on[a-z]+$/i.test(_wAttr[k])) continue;
|
|
5119
5386
|
if (k === 'all') {
|
|
5120
|
-
allAttr =
|
|
5387
|
+
allAttr = getRegList(_wAttr[k], defaultAttr);
|
|
5121
5388
|
} else {
|
|
5122
|
-
tagsAttr[k] = new wRegExp('(?:' +
|
|
5389
|
+
tagsAttr[k] = new wRegExp('\\s(?:' + getRegList(_wAttr[k], '') + ')' + regEndStr, 'ig');
|
|
5123
5390
|
}
|
|
5124
5391
|
}
|
|
5125
5392
|
}
|
|
5126
|
-
|
|
5127
|
-
this._attributesWhitelistRegExp = new wRegExp('(?:' + allAttr
|
|
5393
|
+
|
|
5394
|
+
this._attributesWhitelistRegExp = new wRegExp('\\s(?:' + (allAttr || defaultAttr) + ')' + regEndStr, 'ig');
|
|
5128
5395
|
this._attributesTagsWhitelist = tagsAttr;
|
|
5129
5396
|
|
|
5397
|
+
// blacklist
|
|
5398
|
+
const _bAttr = options.attributesBlacklist;
|
|
5399
|
+
tagsAttr = {};
|
|
5400
|
+
allAttr = '';
|
|
5401
|
+
if (!!_bAttr) {
|
|
5402
|
+
for (let k in _bAttr) {
|
|
5403
|
+
if (!util.hasOwn(_bAttr, k)) continue;
|
|
5404
|
+
if (k === 'all') {
|
|
5405
|
+
allAttr = getRegList(_bAttr[k], '');
|
|
5406
|
+
} else {
|
|
5407
|
+
tagsAttr[k] = new wRegExp('\\s(?:' + getRegList(_bAttr[k], '') + ')' + regEndStr, 'ig');
|
|
5408
|
+
}
|
|
5409
|
+
}
|
|
5410
|
+
}
|
|
5411
|
+
|
|
5412
|
+
this._attributesBlacklistRegExp = new wRegExp('\\s(?:' + (allAttr || '^') + ')' + regEndStr, 'ig');
|
|
5413
|
+
this._attributesTagsBlacklist = tagsAttr;
|
|
5414
|
+
|
|
5130
5415
|
// set modes
|
|
5131
5416
|
this._isInline = /inline/i.test(options.mode);
|
|
5132
5417
|
this._isBalloon = /balloon|balloon-always/i.test(options.mode);
|
|
@@ -5204,6 +5489,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5204
5489
|
}
|
|
5205
5490
|
|
|
5206
5491
|
this._initWysiwygArea(reload, _initHTML);
|
|
5492
|
+
this.setDir(options.rtl ? 'rtl' : 'ltr');
|
|
5207
5493
|
},
|
|
5208
5494
|
|
|
5209
5495
|
/**
|
|
@@ -5211,9 +5497,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5211
5497
|
* @private
|
|
5212
5498
|
*/
|
|
5213
5499
|
_cachingButtons: function () {
|
|
5214
|
-
this.codeViewDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-code-view-enabled"])');
|
|
5500
|
+
this.codeViewDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-code-view-enabled"]):not([data-display="MORE"])');
|
|
5215
5501
|
this.resizingDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-resizing-enabled"]):not([data-display="MORE"])');
|
|
5216
5502
|
|
|
5503
|
+
this.saveButtonStates();
|
|
5504
|
+
|
|
5217
5505
|
const tool = context.tool;
|
|
5218
5506
|
this.commandMap = {
|
|
5219
5507
|
SUB: tool.subscript,
|
|
@@ -5311,7 +5599,15 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5311
5599
|
let focusNode, offset, format;
|
|
5312
5600
|
|
|
5313
5601
|
const fileComponent = util.getParentElement(commonCon, util.isComponent);
|
|
5314
|
-
if (fileComponent && !util.isTable(fileComponent))
|
|
5602
|
+
if (fileComponent && !util.isTable(fileComponent)) {
|
|
5603
|
+
return;
|
|
5604
|
+
} else if (commonCon.nodeType === 1 && commonCon.getAttribute('data-se-embed') === 'true') {
|
|
5605
|
+
let el = commonCon.nextElementSibling;
|
|
5606
|
+
if (!util.isFormatElement(el)) el = this.appendFormatTag(commonCon, options.defaultTag);
|
|
5607
|
+
this.setRange(el.firstChild, 0, el.firstChild, 0);
|
|
5608
|
+
return;
|
|
5609
|
+
}
|
|
5610
|
+
|
|
5315
5611
|
if ((util.isRangeFormatElement(startCon) || util.isWysiwygDiv(startCon)) && (util.isComponent(startCon.children[range.startOffset]) || util.isComponent(startCon.children[range.startOffset - 1]))) return;
|
|
5316
5612
|
if (util.getParentElement(commonCon, util.isNotCheckingNode)) return null;
|
|
5317
5613
|
|
|
@@ -5566,9 +5862,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5566
5862
|
}
|
|
5567
5863
|
}
|
|
5568
5864
|
|
|
5569
|
-
if (
|
|
5865
|
+
if (util.isFormatElement(element)) {
|
|
5570
5866
|
/* Outdent */
|
|
5571
|
-
if (commandMapNodes.indexOf('OUTDENT') === -1 && commandMap.OUTDENT) {
|
|
5867
|
+
if (commandMapNodes.indexOf('OUTDENT') === -1 && commandMap.OUTDENT && !util.isImportantDisabled(commandMap.OUTDENT)) {
|
|
5572
5868
|
if (util.isListCell(element) || (element.style[marginDir] && util.getNumber(element.style[marginDir], 0) > 0)) {
|
|
5573
5869
|
commandMapNodes.push('OUTDENT');
|
|
5574
5870
|
commandMap.OUTDENT.removeAttribute('disabled');
|
|
@@ -5576,7 +5872,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5576
5872
|
}
|
|
5577
5873
|
|
|
5578
5874
|
/* Indent */
|
|
5579
|
-
if (commandMapNodes.indexOf('INDENT') === -1 && commandMap.INDENT) {
|
|
5875
|
+
if (commandMapNodes.indexOf('INDENT') === -1 && commandMap.INDENT && !util.isImportantDisabled(commandMap.INDENT)) {
|
|
5580
5876
|
commandMapNodes.push('INDENT');
|
|
5581
5877
|
if (util.isListCell(element) && !element.previousElementSibling) {
|
|
5582
5878
|
commandMap.INDENT.setAttribute('disabled', true);
|
|
@@ -5663,6 +5959,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5663
5959
|
|
|
5664
5960
|
onMouseDown_wysiwyg: function (e) {
|
|
5665
5961
|
if (core.isReadOnly || util.isNonEditable(context.element.wysiwyg)) return;
|
|
5962
|
+
core._editorRange();
|
|
5666
5963
|
|
|
5667
5964
|
// user event
|
|
5668
5965
|
if (typeof functions.onMouseDown === 'function' && functions.onMouseDown(e, core) === false) return;
|
|
@@ -6497,6 +6794,44 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
6497
6794
|
|
|
6498
6795
|
temp = !temp ? newFormat.firstChild : temp.appendChild(newFormat.firstChild);
|
|
6499
6796
|
core.setRange(temp, 0, temp, 0);
|
|
6797
|
+
break;
|
|
6798
|
+
} else if (options.lineAttrReset && formatEl) {
|
|
6799
|
+
e.preventDefault();
|
|
6800
|
+
e.stopPropagation();
|
|
6801
|
+
|
|
6802
|
+
let newEl;
|
|
6803
|
+
if (!range.collapsed) {
|
|
6804
|
+
const isMultiLine = util.getFormatElement(range.startContainer, null) !== util.getFormatElement(range.endContainer, null);
|
|
6805
|
+
const r = core.removeNode();
|
|
6806
|
+
if (isMultiLine) {
|
|
6807
|
+
newEl = util.getFormatElement(r.container, null);
|
|
6808
|
+
|
|
6809
|
+
if (!r.prevContainer) {
|
|
6810
|
+
const newFormat = formatEl.cloneNode(false);
|
|
6811
|
+
newFormat.innerHTML = '<br>';
|
|
6812
|
+
newEl.parentNode.insertBefore(newFormat, newEl);
|
|
6813
|
+
} else if (newEl !== formatEl && newEl.nextElementSibling === formatEl) {
|
|
6814
|
+
newEl = formatEl;
|
|
6815
|
+
}
|
|
6816
|
+
} else {
|
|
6817
|
+
newEl = util.splitElement(r.container, r.offset, 0);
|
|
6818
|
+
}
|
|
6819
|
+
} else {
|
|
6820
|
+
newEl = util.splitElement(range.endContainer, range.endOffset, 0);
|
|
6821
|
+
}
|
|
6822
|
+
|
|
6823
|
+
const resetAttr = options.lineAttrReset === '*' ? null : options.lineAttrReset;
|
|
6824
|
+
const attrs = newEl.attributes;
|
|
6825
|
+
let i = 0;
|
|
6826
|
+
while (attrs[i]) {
|
|
6827
|
+
if (resetAttr && resetAttr.test(attrs[i].name)) {
|
|
6828
|
+
i++;
|
|
6829
|
+
continue;
|
|
6830
|
+
}
|
|
6831
|
+
newEl.removeAttribute(attrs[i].name);
|
|
6832
|
+
}
|
|
6833
|
+
core.setRange(newEl.firstChild, 0, newEl.firstChild, 0);
|
|
6834
|
+
|
|
6500
6835
|
break;
|
|
6501
6836
|
}
|
|
6502
6837
|
|
|
@@ -6918,6 +7253,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
6918
7253
|
},
|
|
6919
7254
|
|
|
6920
7255
|
_codeViewAutoHeight: function () {
|
|
7256
|
+
if (core._variable.isFullScreen) return;
|
|
6921
7257
|
context.element.code.style.height = context.element.code.scrollHeight + 'px';
|
|
6922
7258
|
},
|
|
6923
7259
|
|
|
@@ -6987,6 +7323,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
6987
7323
|
}
|
|
6988
7324
|
},
|
|
6989
7325
|
|
|
7326
|
+
onSave_wysiwyg: function (content) {
|
|
7327
|
+
// user event
|
|
7328
|
+
if (typeof functions.onSave === 'function') {
|
|
7329
|
+
functions.onSave(content, core);
|
|
7330
|
+
return;
|
|
7331
|
+
}
|
|
7332
|
+
},
|
|
7333
|
+
|
|
6990
7334
|
onCut_wysiwyg: function (e) {
|
|
6991
7335
|
const clipboardData = util.isIE ? _w.clipboardData : e.clipboardData;
|
|
6992
7336
|
|
|
@@ -7088,7 +7432,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7088
7432
|
} else {
|
|
7089
7433
|
cleanData = (plainText === cleanData ? plainText : cleanData).replace(/\n/g, '<br>');
|
|
7090
7434
|
}
|
|
7091
|
-
cleanData = core.cleanHTML(cleanData, core.pasteTagsWhitelistRegExp);
|
|
7435
|
+
cleanData = core.cleanHTML(cleanData, core.pasteTagsWhitelistRegExp, core.pasteTagsBlacklistRegExp);
|
|
7092
7436
|
} else {
|
|
7093
7437
|
cleanData = util._HTMLConvertor(plainText).replace(/\n/g, '<br>');
|
|
7094
7438
|
}
|
|
@@ -7239,7 +7583,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7239
7583
|
|
|
7240
7584
|
/** resizingBar */
|
|
7241
7585
|
if (context.element.resizingBar) {
|
|
7242
|
-
if (/\d+/.test(options.height)) {
|
|
7586
|
+
if (/\d+/.test(options.height) && options.resizeEnable) {
|
|
7243
7587
|
context.element.resizingBar.addEventListener('mousedown', event.onMouseDown_resizingBar, false);
|
|
7244
7588
|
} else {
|
|
7245
7589
|
util.addClass(context.element.resizingBar, 'se-resizing-none');
|
|
@@ -7351,6 +7695,13 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7351
7695
|
*/
|
|
7352
7696
|
onChange: null,
|
|
7353
7697
|
|
|
7698
|
+
/**
|
|
7699
|
+
* @description Event functions
|
|
7700
|
+
* @param {String} contents Current contents
|
|
7701
|
+
* @param {Object} core Core object
|
|
7702
|
+
*/
|
|
7703
|
+
onSave: null,
|
|
7704
|
+
|
|
7354
7705
|
/**
|
|
7355
7706
|
* @description Event functions (drop, paste)
|
|
7356
7707
|
* When false is returned, the default behavior is stopped.
|
|
@@ -7569,6 +7920,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7569
7920
|
*/
|
|
7570
7921
|
onResizeEditor: null,
|
|
7571
7922
|
|
|
7923
|
+
/**
|
|
7924
|
+
* @description Called after the "setToolbarButtons" invocation.
|
|
7925
|
+
* Can be used to tweak buttons properties (useful for custom buttons)
|
|
7926
|
+
* @param {Array} buttonList Button list
|
|
7927
|
+
* @param {Object} core Core object
|
|
7928
|
+
*/
|
|
7929
|
+
onSetToolbarButtons: null,
|
|
7930
|
+
|
|
7572
7931
|
/**
|
|
7573
7932
|
* @description Reset the buttons on the toolbar. (Editor is not reloaded)
|
|
7574
7933
|
* You cannot set a new plugin for the button.
|
|
@@ -7577,10 +7936,10 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7577
7936
|
setToolbarButtons: function (buttonList) {
|
|
7578
7937
|
core.submenuOff();
|
|
7579
7938
|
core.containerOff();
|
|
7939
|
+
core.moreLayerOff();
|
|
7580
7940
|
|
|
7581
7941
|
const newToolbar = _Constructor._createToolBar(_d, buttonList, core.plugins, options);
|
|
7582
7942
|
_responsiveButtons = newToolbar.responsiveButtons;
|
|
7583
|
-
core._moreLayerActiveButton = null;
|
|
7584
7943
|
event._setResponsiveToolbar();
|
|
7585
7944
|
|
|
7586
7945
|
context.element.toolbar.replaceChild(newToolbar._buttonTray, context.element._buttonTray);
|
|
@@ -7589,32 +7948,15 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7589
7948
|
context.element = newContext.element;
|
|
7590
7949
|
context.tool = newContext.tool;
|
|
7591
7950
|
if (options.iframe) context.element.wysiwyg = core._wd.body;
|
|
7951
|
+
|
|
7952
|
+
core.recoverButtonStates();
|
|
7953
|
+
|
|
7592
7954
|
core._cachingButtons();
|
|
7593
7955
|
core.history._resetCachingButton();
|
|
7594
7956
|
|
|
7595
|
-
core.activePlugins = [];
|
|
7596
|
-
const oldCallButtons = pluginCallButtons;
|
|
7597
|
-
pluginCallButtons = newToolbar.pluginCallButtons;
|
|
7598
|
-
let plugin, button, oldButton;
|
|
7599
|
-
for (let key in pluginCallButtons) {
|
|
7600
|
-
if (!util.hasOwn(pluginCallButtons, key)) continue;
|
|
7601
|
-
plugin = plugins[key];
|
|
7602
|
-
button = pluginCallButtons[key];
|
|
7603
|
-
if (plugin.active && button) {
|
|
7604
|
-
oldButton = oldCallButtons[key];
|
|
7605
|
-
core.callPlugin(key, null, oldButton || button);
|
|
7606
|
-
if (oldButton) {
|
|
7607
|
-
button.parentElement.replaceChild(oldButton, button);
|
|
7608
|
-
pluginCallButtons[key] = oldButton;
|
|
7609
|
-
}
|
|
7610
|
-
}
|
|
7611
|
-
}
|
|
7612
|
-
|
|
7613
7957
|
if (core.hasFocus) event._applyTagEffects();
|
|
7614
|
-
|
|
7615
|
-
if (
|
|
7616
|
-
if (core._variable.isFullScreen) util.addClass(core._styleCommandMap.fullScreen, 'active');
|
|
7617
|
-
if (util.hasClass(context.element.wysiwyg, 'se-show-block')) util.addClass(core._styleCommandMap.showBlocks, 'active');
|
|
7958
|
+
if (core.isReadOnly) util.setDisabledButtons(true, core.resizingDisabledButtons);
|
|
7959
|
+
if (typeof functions.onSetToolbarButtons === 'function') functions.onSetToolbarButtons(newToolbar._buttonTray.querySelectorAll('button'), core);
|
|
7618
7960
|
},
|
|
7619
7961
|
|
|
7620
7962
|
/**
|
|
@@ -7650,7 +7992,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7650
7992
|
const _initHTML = el.wysiwyg.innerHTML;
|
|
7651
7993
|
|
|
7652
7994
|
// set option
|
|
7653
|
-
const cons = _Constructor._setOptions(mergeOptions, context, options);
|
|
7995
|
+
const cons = _Constructor._setOptions(mergeOptions, context, options);
|
|
7654
7996
|
|
|
7655
7997
|
if (cons.callButtons) {
|
|
7656
7998
|
pluginCallButtons = cons.callButtons;
|
|
@@ -7726,10 +8068,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7726
8068
|
},
|
|
7727
8069
|
|
|
7728
8070
|
/**
|
|
7729
|
-
* @description Copying the contents of the editor to the original textarea
|
|
8071
|
+
* @description Copying the contents of the editor to the original textarea and execute onSave callback
|
|
7730
8072
|
*/
|
|
7731
8073
|
save: function () {
|
|
7732
|
-
|
|
8074
|
+
const contents = core.getContents(false);
|
|
8075
|
+
context.element.originElement.value = contents;
|
|
8076
|
+
event.onSave_wysiwyg(contents, core);
|
|
7733
8077
|
},
|
|
7734
8078
|
|
|
7735
8079
|
/**
|
|
@@ -7823,7 +8167,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7823
8167
|
*/
|
|
7824
8168
|
insertHTML: function (html, notCleaningData, checkCharCount, rangeSelection) {
|
|
7825
8169
|
if (typeof html === 'string') {
|
|
7826
|
-
if (!notCleaningData) html = core.cleanHTML(html, null);
|
|
8170
|
+
if (!notCleaningData) html = core.cleanHTML(html, null, null);
|
|
7827
8171
|
try {
|
|
7828
8172
|
const dom = _d.createRange().createContextualFragment(html);
|
|
7829
8173
|
const domTree = dom.childNodes;
|
|
@@ -7903,7 +8247,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7903
8247
|
wysiwyg.appendChild(children[i]);
|
|
7904
8248
|
}
|
|
7905
8249
|
} else {
|
|
7906
|
-
core._setCodeView(core._getCodeView() + '\n' + core.convertHTMLForCodeView(convertValue));
|
|
8250
|
+
core._setCodeView(core._getCodeView() + '\n' + core.convertHTMLForCodeView(convertValue, false));
|
|
7907
8251
|
}
|
|
7908
8252
|
|
|
7909
8253
|
// history stack
|
|
@@ -7917,44 +8261,52 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7917
8261
|
readOnly: function (value) {
|
|
7918
8262
|
core.isReadOnly = value;
|
|
7919
8263
|
|
|
8264
|
+
util.setDisabledButtons(!!value, core.resizingDisabledButtons);
|
|
8265
|
+
|
|
7920
8266
|
if (value) {
|
|
8267
|
+
/** off menus */
|
|
8268
|
+
core.controllersOff();
|
|
8269
|
+
if (core.submenuActiveButton && core.submenuActiveButton.disabled) core.submenuOff();
|
|
8270
|
+
if (core._moreLayerActiveButton && core._moreLayerActiveButton.disabled) core.moreLayerOff();
|
|
8271
|
+
if (core.containerActiveButton && core.containerActiveButton.disabled) core.containerOff();
|
|
8272
|
+
if (core.modalForm) core.plugins.dialog.close.call(core);
|
|
8273
|
+
|
|
7921
8274
|
context.element.code.setAttribute("readOnly", "true");
|
|
7922
8275
|
} else {
|
|
7923
8276
|
context.element.code.removeAttribute("readOnly");
|
|
7924
8277
|
}
|
|
7925
8278
|
|
|
7926
|
-
util.setDisabledButtons(!!value, core.resizingDisabledButtons);
|
|
7927
8279
|
if (options.codeMirrorEditor) options.codeMirrorEditor.setOption('readOnly', !!value);
|
|
7928
8280
|
},
|
|
7929
8281
|
|
|
7930
8282
|
/**
|
|
7931
8283
|
* @description Disable the suneditor
|
|
7932
8284
|
*/
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
8285
|
+
disable: function () {
|
|
8286
|
+
this.toolbar.disable();
|
|
8287
|
+
this.wysiwyg.disable();
|
|
8288
|
+
},
|
|
7937
8289
|
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
8290
|
+
/**
|
|
8291
|
+
* @description Provided for backward compatibility and will be removed in 3.0.0 version
|
|
8292
|
+
*/
|
|
8293
|
+
disabled: function () {
|
|
8294
|
+
this.disable();
|
|
7943
8295
|
},
|
|
7944
8296
|
|
|
7945
8297
|
/**
|
|
7946
8298
|
* @description Enable the suneditor
|
|
7947
8299
|
*/
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
8300
|
+
enable: function () {
|
|
8301
|
+
this.toolbar.enable();
|
|
8302
|
+
this.wysiwyg.enable();
|
|
8303
|
+
},
|
|
7952
8304
|
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
8305
|
+
/**
|
|
8306
|
+
* @description Provided for backward compatibility and will be removed in 3.0.0 version
|
|
8307
|
+
*/
|
|
8308
|
+
enabled: function () {
|
|
8309
|
+
this.enable();
|
|
7958
8310
|
},
|
|
7959
8311
|
|
|
7960
8312
|
/**
|
|
@@ -8011,17 +8363,36 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
8011
8363
|
/**
|
|
8012
8364
|
* @description Disable the toolbar
|
|
8013
8365
|
*/
|
|
8014
|
-
|
|
8366
|
+
disable: function () {
|
|
8367
|
+
/** off menus */
|
|
8368
|
+
core.submenuOff();
|
|
8369
|
+
core.moreLayerOff();
|
|
8370
|
+
core.containerOff();
|
|
8371
|
+
|
|
8015
8372
|
context.tool.cover.style.display = 'block';
|
|
8016
8373
|
},
|
|
8017
8374
|
|
|
8375
|
+
/**
|
|
8376
|
+
* @description Provided for backward compatibility and will be removed in 3.0.0 version
|
|
8377
|
+
*/
|
|
8378
|
+
disabled: function () {
|
|
8379
|
+
this.disable();
|
|
8380
|
+
},
|
|
8381
|
+
|
|
8018
8382
|
/**
|
|
8019
8383
|
* @description Enable the toolbar
|
|
8020
8384
|
*/
|
|
8021
|
-
|
|
8385
|
+
enable: function () {
|
|
8022
8386
|
context.tool.cover.style.display = 'none';
|
|
8023
8387
|
},
|
|
8024
8388
|
|
|
8389
|
+
/**
|
|
8390
|
+
* @description Provided for backward compatibility and will be removed in 3.0.0 version
|
|
8391
|
+
*/
|
|
8392
|
+
enabled: function () {
|
|
8393
|
+
this.enable();
|
|
8394
|
+
},
|
|
8395
|
+
|
|
8025
8396
|
/**
|
|
8026
8397
|
* @description Show the toolbar
|
|
8027
8398
|
*/
|
|
@@ -8045,7 +8416,44 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
8045
8416
|
context.element._stickyDummy.style.display = 'none';
|
|
8046
8417
|
}
|
|
8047
8418
|
},
|
|
8048
|
-
}
|
|
8419
|
+
},
|
|
8420
|
+
|
|
8421
|
+
/**
|
|
8422
|
+
* @description Wysiwyg methods
|
|
8423
|
+
*/
|
|
8424
|
+
wysiwyg: {
|
|
8425
|
+
/**
|
|
8426
|
+
* @description Disable the wysiwyg area
|
|
8427
|
+
*/
|
|
8428
|
+
disable: function () {
|
|
8429
|
+
/** off menus */
|
|
8430
|
+
core.controllersOff();
|
|
8431
|
+
if (core.modalForm) core.plugins.dialog.close.call(core);
|
|
8432
|
+
|
|
8433
|
+
context.element.wysiwyg.setAttribute('contenteditable', false);
|
|
8434
|
+
core.isDisabled = true;
|
|
8435
|
+
|
|
8436
|
+
if (options.codeMirrorEditor) {
|
|
8437
|
+
options.codeMirrorEditor.setOption('readOnly', true);
|
|
8438
|
+
} else {
|
|
8439
|
+
context.element.code.setAttribute('disabled', 'disabled');
|
|
8440
|
+
}
|
|
8441
|
+
},
|
|
8442
|
+
|
|
8443
|
+
/**
|
|
8444
|
+
* @description Enable the wysiwyg area
|
|
8445
|
+
*/
|
|
8446
|
+
enable: function () {
|
|
8447
|
+
context.element.wysiwyg.setAttribute('contenteditable', true);
|
|
8448
|
+
core.isDisabled = false;
|
|
8449
|
+
|
|
8450
|
+
if (options.codeMirrorEditor) {
|
|
8451
|
+
options.codeMirrorEditor.setOption('readOnly', false);
|
|
8452
|
+
} else {
|
|
8453
|
+
context.element.code.removeAttribute('disabled');
|
|
8454
|
+
}
|
|
8455
|
+
},
|
|
8456
|
+
}
|
|
8049
8457
|
};
|
|
8050
8458
|
|
|
8051
8459
|
/************ Core init ************/
|