suneditor 2.41.2 → 2.43.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 +116 -28
- package/dist/css/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +2 -2
- package/package.json +4 -4
- package/src/assets/css/suneditor-contents.css +1 -1
- package/src/assets/css/suneditor.css +27 -7
- 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 +3 -1
- package/src/lib/constructor.js +68 -16
- package/src/lib/context.js +5 -1
- package/src/lib/core.d.ts +88 -12
- package/src/lib/core.js +789 -212
- package/src/lib/util.d.ts +24 -1
- package/src/lib/util.js +105 -18
- package/src/options.d.ts +79 -9
- package/src/plugins/dialog/audio.js +5 -5
- package/src/plugins/dialog/image.js +30 -20
- package/src/plugins/dialog/link.js +1 -0
- package/src/plugins/dialog/video.js +16 -15
- package/src/plugins/fileBrowser/imageGallery.js +2 -3
- package/src/plugins/modules/_anchor.js +24 -15
- 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/fontSize.js +1 -1
- package/src/plugins/submenu/horizontalRule.js +19 -25
- package/src/plugins/submenu/list.js +13 -5
- package/src/plugins/submenu/template.js +5 -2
package/src/lib/core.js
CHANGED
|
@@ -39,6 +39,10 @@ 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,
|
|
43
|
+
_editorHeight: 0,
|
|
44
|
+
_listCamel: options.__listCommonStyle,
|
|
45
|
+
_listKebab: util.camelToKebabCase(options.__listCommonStyle),
|
|
42
46
|
|
|
43
47
|
/**
|
|
44
48
|
* @description Document object of the iframe if created as an iframe || _d
|
|
@@ -82,7 +86,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
82
86
|
/**
|
|
83
87
|
* @description Computed style of the wysiwyg area (window.getComputedStyle(context.element.wysiwyg))
|
|
84
88
|
*/
|
|
85
|
-
wwComputedStyle:
|
|
89
|
+
wwComputedStyle: null,
|
|
86
90
|
|
|
87
91
|
/**
|
|
88
92
|
* @description Notice object
|
|
@@ -222,6 +226,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
222
226
|
*/
|
|
223
227
|
_htmlCheckWhitelistRegExp: null,
|
|
224
228
|
|
|
229
|
+
/**
|
|
230
|
+
* @description Tag blacklist RegExp object used in "_consistencyCheckOfHTML" method
|
|
231
|
+
* @private
|
|
232
|
+
*/
|
|
233
|
+
_htmlCheckBlacklistRegExp: null,
|
|
234
|
+
|
|
225
235
|
/**
|
|
226
236
|
* @description RegExp when using check disallowd tags. (b, i, ins, strike, s)
|
|
227
237
|
* @private
|
|
@@ -234,12 +244,24 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
234
244
|
*/
|
|
235
245
|
editorTagsWhitelistRegExp: null,
|
|
236
246
|
|
|
247
|
+
/**
|
|
248
|
+
* @description Editor tags blacklist (RegExp object)
|
|
249
|
+
* util.createTagsBlacklist(options.tagsBlacklist)
|
|
250
|
+
*/
|
|
251
|
+
editorTagsBlacklistRegExp: null,
|
|
252
|
+
|
|
237
253
|
/**
|
|
238
254
|
* @description Tag whitelist when pasting (RegExp object)
|
|
239
255
|
* util.createTagsWhitelist(options.pasteTagsWhitelist)
|
|
240
256
|
*/
|
|
241
257
|
pasteTagsWhitelistRegExp: null,
|
|
242
258
|
|
|
259
|
+
/**
|
|
260
|
+
* @description Tag blacklist when pasting (RegExp object)
|
|
261
|
+
* util.createTagsBlacklist(options.pasteTagsBlacklist)
|
|
262
|
+
*/
|
|
263
|
+
pasteTagsBlacklistRegExp: null,
|
|
264
|
+
|
|
243
265
|
/**
|
|
244
266
|
* @description Boolean value of whether the editor has focus
|
|
245
267
|
*/
|
|
@@ -261,12 +283,24 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
261
283
|
*/
|
|
262
284
|
_attributesWhitelistRegExp: null,
|
|
263
285
|
|
|
286
|
+
/**
|
|
287
|
+
* @description Attributes blacklist used by the cleanHTML method
|
|
288
|
+
* @private
|
|
289
|
+
*/
|
|
290
|
+
_attributesBlacklistRegExp: null,
|
|
291
|
+
|
|
264
292
|
/**
|
|
265
293
|
* @description Attributes of tags whitelist used by the cleanHTML method
|
|
266
294
|
* @private
|
|
267
295
|
*/
|
|
268
296
|
_attributesTagsWhitelist: null,
|
|
269
297
|
|
|
298
|
+
/**
|
|
299
|
+
* @description Attributes of tags blacklist used by the cleanHTML method
|
|
300
|
+
* @private
|
|
301
|
+
*/
|
|
302
|
+
_attributesTagsBlacklist: null,
|
|
303
|
+
|
|
270
304
|
/**
|
|
271
305
|
* @description binded controllersOff method
|
|
272
306
|
* @private
|
|
@@ -414,6 +448,24 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
414
448
|
*/
|
|
415
449
|
commandMap: null,
|
|
416
450
|
|
|
451
|
+
/**
|
|
452
|
+
* @description CSS properties related to style tags
|
|
453
|
+
* @private
|
|
454
|
+
*/
|
|
455
|
+
_commandMapStyles: {
|
|
456
|
+
STRONG: ['font-weight'],
|
|
457
|
+
U: ['text-decoration'],
|
|
458
|
+
EM: ['font-style'],
|
|
459
|
+
DEL: ['text-decoration']
|
|
460
|
+
},
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* @description Contains pairs of all "data-commands" and "elements" setted in toolbar over time
|
|
464
|
+
* Used primarily to save and recover button states after the toolbar re-creation
|
|
465
|
+
* Updates each "_cachingButtons()" invocation
|
|
466
|
+
*/
|
|
467
|
+
allCommandButtons: null,
|
|
468
|
+
|
|
417
469
|
/**
|
|
418
470
|
* @description Style button related to edit area
|
|
419
471
|
* @property {Element} fullScreen fullScreen button element
|
|
@@ -471,6 +523,40 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
471
523
|
_lineBreakDir: ''
|
|
472
524
|
},
|
|
473
525
|
|
|
526
|
+
/**
|
|
527
|
+
* @description Save the current buttons states to "allCommandButtons" object
|
|
528
|
+
*/
|
|
529
|
+
saveButtonStates: function () {
|
|
530
|
+
if (!this.allCommandButtons) this.allCommandButtons = {};
|
|
531
|
+
|
|
532
|
+
const currentButtons = this.context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]');
|
|
533
|
+
for (let i = 0, element, command; i < currentButtons.length; i++) {
|
|
534
|
+
element = currentButtons[i];
|
|
535
|
+
command = element.getAttribute('data-command');
|
|
536
|
+
|
|
537
|
+
this.allCommandButtons[command] = element;
|
|
538
|
+
}
|
|
539
|
+
},
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* @description Recover the current buttons states from "allCommandButtons" object
|
|
543
|
+
*/
|
|
544
|
+
recoverButtonStates: function () {
|
|
545
|
+
if (this.allCommandButtons) {
|
|
546
|
+
const currentButtons = this.context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]');
|
|
547
|
+
for (let i = 0, button, command, oldButton; i < currentButtons.length; i++) {
|
|
548
|
+
button = currentButtons[i];
|
|
549
|
+
command = button.getAttribute('data-command');
|
|
550
|
+
|
|
551
|
+
oldButton = this.allCommandButtons[command];
|
|
552
|
+
if (oldButton) {
|
|
553
|
+
button.parentElement.replaceChild(oldButton, button);
|
|
554
|
+
if (this.context.tool[command]) this.context.tool[command] = oldButton;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
|
|
474
560
|
/**
|
|
475
561
|
* @description If the plugin is not added, add the plugin and call the 'add' function.
|
|
476
562
|
* If the plugin is added call callBack function.
|
|
@@ -559,7 +645,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
559
645
|
},
|
|
560
646
|
|
|
561
647
|
/**
|
|
562
|
-
* @description
|
|
648
|
+
* @description Enable submenu
|
|
563
649
|
* @param {Element} element Submenu's button element to call
|
|
564
650
|
*/
|
|
565
651
|
submenuOn: function (element) {
|
|
@@ -598,7 +684,19 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
598
684
|
},
|
|
599
685
|
|
|
600
686
|
/**
|
|
601
|
-
* @description
|
|
687
|
+
* @description Disable more layer
|
|
688
|
+
*/
|
|
689
|
+
moreLayerOff: function() {
|
|
690
|
+
if (this._moreLayerActiveButton) {
|
|
691
|
+
const layer = context.element.toolbar.querySelector('.' + this._moreLayerActiveButton.getAttribute('data-command'));
|
|
692
|
+
layer.style.display = 'none';
|
|
693
|
+
util.removeClass(this._moreLayerActiveButton, 'on');
|
|
694
|
+
this._moreLayerActiveButton = null;
|
|
695
|
+
}
|
|
696
|
+
},
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* @description Enable container
|
|
602
700
|
* @param {Element} element Container's button element to call
|
|
603
701
|
*/
|
|
604
702
|
containerOn: function (element) {
|
|
@@ -868,14 +966,21 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
868
966
|
* @description Focus to wysiwyg area using "native focus function"
|
|
869
967
|
*/
|
|
870
968
|
nativeFocus: function () {
|
|
969
|
+
this.__focus();
|
|
970
|
+
this._editorRange();
|
|
971
|
+
},
|
|
972
|
+
|
|
973
|
+
/**
|
|
974
|
+
* @description Focus method
|
|
975
|
+
* @private
|
|
976
|
+
*/
|
|
977
|
+
__focus: function () {
|
|
871
978
|
const caption = util.getParentElement(this.getSelectionNode(), 'figcaption');
|
|
872
979
|
if (caption) {
|
|
873
980
|
caption.focus();
|
|
874
981
|
} else {
|
|
875
982
|
context.element.wysiwyg.focus();
|
|
876
983
|
}
|
|
877
|
-
|
|
878
|
-
this._editorRange();
|
|
879
984
|
},
|
|
880
985
|
|
|
881
986
|
/**
|
|
@@ -954,12 +1059,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
954
1059
|
if (startOff > startCon.textContent.length) startOff = startCon.textContent.length;
|
|
955
1060
|
if (endOff > endCon.textContent.length) endOff = endCon.textContent.length;
|
|
956
1061
|
if (util.isFormatElement(startCon)) {
|
|
957
|
-
startCon = startCon.childNodes[startOff] || startCon;
|
|
958
|
-
startOff = 0;
|
|
1062
|
+
startCon = startCon.childNodes[startOff] || startCon.childNodes[startOff - 1] || startCon;
|
|
1063
|
+
startOff = startOff > 0 ? startCon.nodeType === 1 ? 1 : startCon.textContent ? startCon.textContent.length : 0 : 0;
|
|
959
1064
|
}
|
|
960
1065
|
if (util.isFormatElement(endCon)) {
|
|
961
|
-
endCon = endCon.childNodes[endOff] || endCon;
|
|
962
|
-
endOff =
|
|
1066
|
+
endCon = endCon.childNodes[endOff] || endCon.childNodes[endOff - 1] || endCon;
|
|
1067
|
+
endOff = endOff > 0 ? endCon.nodeType === 1 ? 1 : endCon.textContent ? endCon.textContent.length : 0 : 0;
|
|
963
1068
|
}
|
|
964
1069
|
|
|
965
1070
|
const range = this._wd.createRange();
|
|
@@ -980,8 +1085,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
980
1085
|
}
|
|
981
1086
|
|
|
982
1087
|
selection.addRange(range);
|
|
983
|
-
this.
|
|
984
|
-
if (options.iframe) this.
|
|
1088
|
+
this._rangeInfo(range, this.getSelection());
|
|
1089
|
+
if (options.iframe) this.__focus();
|
|
985
1090
|
|
|
986
1091
|
return range;
|
|
987
1092
|
},
|
|
@@ -1074,7 +1179,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1074
1179
|
const selection = this.getSelection();
|
|
1075
1180
|
if (!selection) return null;
|
|
1076
1181
|
let range = null;
|
|
1077
|
-
let selectionNode = null;
|
|
1078
1182
|
|
|
1079
1183
|
if (selection.rangeCount > 0) {
|
|
1080
1184
|
range = selection.getRangeAt(0);
|
|
@@ -1082,6 +1186,20 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1082
1186
|
range = this._createDefaultRange();
|
|
1083
1187
|
}
|
|
1084
1188
|
|
|
1189
|
+
if (util.isFormatElement(range.endContainer) && range.endOffset === 0) {
|
|
1190
|
+
range = this.setRange(range.startContainer, range.startOffset, range.startContainer, range.startContainer.length);
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
this._rangeInfo(range, selection);
|
|
1194
|
+
},
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* @description Set "range" and "selection" info.
|
|
1198
|
+
* @param {Object} range range object.
|
|
1199
|
+
* @param {Object} selection selection object.
|
|
1200
|
+
*/
|
|
1201
|
+
_rangeInfo: function (range, selection) {
|
|
1202
|
+
let selectionNode = null;
|
|
1085
1203
|
this._variable._range = range;
|
|
1086
1204
|
|
|
1087
1205
|
if (range.collapsed) {
|
|
@@ -1145,19 +1263,19 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1145
1263
|
|
|
1146
1264
|
if (util.isFormatElement(startCon)) {
|
|
1147
1265
|
if (!startCon.childNodes[startOff]) {
|
|
1148
|
-
startCon = startCon.lastChild;
|
|
1266
|
+
startCon = startCon.lastChild || startCon;
|
|
1149
1267
|
startOff = startCon.textContent.length;
|
|
1150
1268
|
} else {
|
|
1151
|
-
startCon = startCon.childNodes[startOff];
|
|
1269
|
+
startCon = startCon.childNodes[startOff] || startCon;
|
|
1152
1270
|
startOff = 0;
|
|
1153
1271
|
}
|
|
1154
1272
|
while (startCon && startCon.nodeType === 1 && startCon.firstChild) {
|
|
1155
|
-
startCon = startCon.firstChild;
|
|
1273
|
+
startCon = startCon.firstChild || startCon;
|
|
1156
1274
|
startOff = 0;
|
|
1157
1275
|
}
|
|
1158
1276
|
}
|
|
1159
1277
|
if (util.isFormatElement(endCon)) {
|
|
1160
|
-
endCon = endCon.childNodes[endOff] || endCon.lastChild;
|
|
1278
|
+
endCon = endCon.childNodes[endOff] || endCon.lastChild || endCon;
|
|
1161
1279
|
while (endCon && endCon.nodeType === 1 && endCon.lastChild) {
|
|
1162
1280
|
endCon = endCon.lastChild;
|
|
1163
1281
|
}
|
|
@@ -1255,7 +1373,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1255
1373
|
if (util.isWysiwygDiv(range.startContainer)) {
|
|
1256
1374
|
const children = context.element.wysiwyg.children;
|
|
1257
1375
|
if (children.length === 0) return [];
|
|
1258
|
-
|
|
1259
1376
|
this.setRange(children[0], 0, children[children.length - 1], children[children.length - 1].textContent.trim().length);
|
|
1260
1377
|
range = this.getRange();
|
|
1261
1378
|
}
|
|
@@ -1397,7 +1514,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1397
1514
|
* @returns {Element}
|
|
1398
1515
|
*/
|
|
1399
1516
|
appendFormatTag: function (element, formatNode) {
|
|
1400
|
-
if (!element.parentNode) return null;
|
|
1517
|
+
if (!element || !element.parentNode) return null;
|
|
1401
1518
|
|
|
1402
1519
|
const currentFormatEl = util.getFormatElement(this.getSelectionNode(), null);
|
|
1403
1520
|
let oFormat = null;
|
|
@@ -1451,9 +1568,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1451
1568
|
if (formatEl && util.onlyZeroWidthSpace(formatEl)) util.removeItem(formatEl);
|
|
1452
1569
|
}
|
|
1453
1570
|
|
|
1454
|
-
this.setRange(element, 0, element, 0);
|
|
1455
|
-
|
|
1456
1571
|
if (!notSelect) {
|
|
1572
|
+
this.setRange(element, 0, element, 0);
|
|
1573
|
+
|
|
1457
1574
|
const fileComponentInfo = this.getFileComponent(element);
|
|
1458
1575
|
if (fileComponentInfo) {
|
|
1459
1576
|
this.selectComponent(fileComponentInfo.target, fileComponentInfo.pluginName);
|
|
@@ -1592,8 +1709,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1592
1709
|
const startOff = range.startOffset;
|
|
1593
1710
|
const endOff = range.endOffset;
|
|
1594
1711
|
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;
|
|
1712
|
+
const startCon = formatRange ? (commonCon.childNodes[startOff] || commonCon.childNodes[0] || range.startContainer) : range.startContainer;
|
|
1713
|
+
const endCon = formatRange ? (commonCon.childNodes[endOff] || commonCon.childNodes[commonCon.childNodes.length - 1] || range.endContainer) : range.endContainer;
|
|
1597
1714
|
let parentNode, originAfter = null;
|
|
1598
1715
|
|
|
1599
1716
|
if (!afterNode) {
|
|
@@ -1762,7 +1879,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
1762
1879
|
this.setRange(oNode, newRange.startOffset, oNode, newRange.endOffset);
|
|
1763
1880
|
|
|
1764
1881
|
return newRange;
|
|
1765
|
-
} else if (!util.isBreak(oNode) && util.isFormatElement(parentNode)) {
|
|
1882
|
+
} else if (!util.isBreak(oNode) && !util.isListCell(oNode) && util.isFormatElement(parentNode)) {
|
|
1766
1883
|
let zeroWidth = null;
|
|
1767
1884
|
if (!oNode.previousSibling || util.isBreak(oNode.previousSibling)) {
|
|
1768
1885
|
zeroWidth = util.createTextNode(util.zeroWidthSpace);
|
|
@@ -2471,8 +2588,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
2471
2588
|
let endCon = range.endContainer;
|
|
2472
2589
|
let endOff = range.endOffset;
|
|
2473
2590
|
|
|
2474
|
-
if ((isRemoveFormat && range.collapsed && util.isFormatElement(startCon.parentNode)
|
|
2475
|
-
|
|
2591
|
+
if ((isRemoveFormat && range.collapsed && util.isFormatElement(startCon.parentNode)) || (startCon === endCon && startCon.nodeType === 1 && util.isNonEditable(startCon))) {
|
|
2592
|
+
const format = startCon.parentNode;
|
|
2593
|
+
if (!util.isListCell(format) || !util.getValues(format.style).some(function(k) { return this._listKebab.indexOf(k) > -1; }.bind(this))) return;
|
|
2476
2594
|
}
|
|
2477
2595
|
|
|
2478
2596
|
if (range.collapsed && !isRemoveFormat) {
|
|
@@ -2692,6 +2810,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
2692
2810
|
|
|
2693
2811
|
// one line
|
|
2694
2812
|
if (oneLine) {
|
|
2813
|
+
this._resetCommonListCell(lineNodes[0], styleArray);
|
|
2695
2814
|
const newRange = this._nodeChange_oneLine(lineNodes[0], newNode, validation, startCon, startOff, endCon, endOff, isRemoveFormat, isRemoveNode, range.collapsed, _removeCheck, _getMaintainedNode, _isMaintainedNode);
|
|
2696
2815
|
start.container = newRange.startContainer;
|
|
2697
2816
|
start.offset = newRange.startOffset;
|
|
@@ -2704,15 +2823,17 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
2704
2823
|
} else { // multi line
|
|
2705
2824
|
// end
|
|
2706
2825
|
if (endLength > 0) {
|
|
2826
|
+
this._resetCommonListCell(lineNodes[endLength], styleArray);
|
|
2707
2827
|
newNode = appendNode.cloneNode(false);
|
|
2708
2828
|
end = this._nodeChange_endLine(lineNodes[endLength], newNode, validation, endCon, endOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode);
|
|
2709
2829
|
}
|
|
2710
2830
|
|
|
2711
2831
|
// mid
|
|
2712
2832
|
for (let i = endLength - 1, newRange; i > 0; i--) {
|
|
2833
|
+
this._resetCommonListCell(lineNodes[i], styleArray);
|
|
2713
2834
|
newNode = appendNode.cloneNode(false);
|
|
2714
2835
|
newRange = this._nodeChange_middleLine(lineNodes[i], newNode, validation, isRemoveFormat, isRemoveNode, _removeCheck, end.container);
|
|
2715
|
-
if (newRange.endContainer) {
|
|
2836
|
+
if (newRange.endContainer && newRange.ancestor.contains(newRange.endContainer)) {
|
|
2716
2837
|
end.ancestor = null;
|
|
2717
2838
|
end.container = newRange.endContainer;
|
|
2718
2839
|
}
|
|
@@ -2720,6 +2841,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
2720
2841
|
}
|
|
2721
2842
|
|
|
2722
2843
|
// start
|
|
2844
|
+
this._resetCommonListCell(lineNodes[0], styleArray);
|
|
2723
2845
|
newNode = appendNode.cloneNode(false);
|
|
2724
2846
|
start = this._nodeChange_startLine(lineNodes[0], newNode, validation, startCon, startOff, isRemoveFormat, isRemoveNode, _removeCheck, _getMaintainedNode, _isMaintainedNode, end.container);
|
|
2725
2847
|
|
|
@@ -2748,35 +2870,99 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
2748
2870
|
this.history.push(false);
|
|
2749
2871
|
},
|
|
2750
2872
|
|
|
2873
|
+
_resetCommonListCell: function (el, styleArray) {
|
|
2874
|
+
if (!util.isListCell(el)) return;
|
|
2875
|
+
if (!styleArray) styleArray = this._listKebab;
|
|
2876
|
+
|
|
2877
|
+
const children = util.getArrayItem((el).childNodes, function (current) { return !util.isBreak(current); }, true);
|
|
2878
|
+
const elStyles = el.style;
|
|
2879
|
+
|
|
2880
|
+
const ec = [], ek = [], elKeys = util.getValues(elStyles);
|
|
2881
|
+
for (let i = 0, len = this._listKebab.length; i < len; i++) {
|
|
2882
|
+
if (elKeys.indexOf(this._listKebab[i]) > -1 && styleArray.indexOf(this._listKebab[i]) > -1) {
|
|
2883
|
+
ec.push(this._listCamel[i]);
|
|
2884
|
+
ek.push(this._listKebab[i]);
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2888
|
+
if (!ec.length) return;
|
|
2889
|
+
|
|
2890
|
+
// reset cell style---
|
|
2891
|
+
const refer = util.createElement('SPAN');
|
|
2892
|
+
for (let i = 0, len = ec.length; i < len; i++) {
|
|
2893
|
+
refer.style[ec[i]] = elStyles[ek[i]];
|
|
2894
|
+
elStyles.removeProperty(ek[i]);
|
|
2895
|
+
}
|
|
2896
|
+
|
|
2897
|
+
let sel = refer.cloneNode(false);
|
|
2898
|
+
let r = null;
|
|
2899
|
+
for (let i = 0, len = children.length, c, s; i < len; i++) {
|
|
2900
|
+
c = children[i];
|
|
2901
|
+
s = util.getValues(c.style);
|
|
2902
|
+
if (s.length === 0 || (ec.some(function (k) {return s.indexOf(k) === -1;}) && s.some(function(k) {ec.indexOf(k) > -1;}))) {
|
|
2903
|
+
r = c.nextSibling;
|
|
2904
|
+
sel.appendChild(c);
|
|
2905
|
+
} else if (sel.childNodes.length > 0) {
|
|
2906
|
+
el.insertBefore(sel, r);
|
|
2907
|
+
sel = refer.cloneNode(false);
|
|
2908
|
+
r = null;
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
|
|
2912
|
+
if (sel.childNodes.length > 0) el.insertBefore(sel, r);
|
|
2913
|
+
if (!elStyles.length) el.removeAttribute('style');
|
|
2914
|
+
},
|
|
2915
|
+
|
|
2751
2916
|
/**
|
|
2752
2917
|
* @description If certain styles are applied to all child nodes of the list cell, the style of the list cell is also changed. (bold, color, size)
|
|
2753
2918
|
* @param {Element} el List cell element. <li>
|
|
2754
2919
|
* @param {Element|null} child Variable for recursive call. ("null" on the first call)
|
|
2920
|
+
* @param {Array|null} styleArray Style array
|
|
2755
2921
|
* @private
|
|
2756
2922
|
*/
|
|
2757
2923
|
_setCommonListStyle: function (el, child) {
|
|
2758
2924
|
if (!util.isListCell(el)) return;
|
|
2759
|
-
if (!child) el.removeAttribute('style');
|
|
2760
2925
|
|
|
2761
2926
|
const children = util.getArrayItem((child || el).childNodes, function (current) { return !util.isBreak(current); }, true);
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2927
|
+
child = children[0];
|
|
2928
|
+
|
|
2929
|
+
if (!child || children.length > 1 || child.nodeType !== 1) return;
|
|
2930
|
+
|
|
2931
|
+
// set cell style---
|
|
2932
|
+
const commonStyleElements = [];
|
|
2933
|
+
const childStyle = child.style;
|
|
2934
|
+
const elStyle = el.style;
|
|
2765
2935
|
|
|
2766
|
-
|
|
2767
|
-
|
|
2936
|
+
// bold, italic
|
|
2937
|
+
if (options._textTagsMap[child.nodeName.toLowerCase()] === this._defaultCommand.bold.toLowerCase()) elStyle.fontWeight = 'bold'; // bold
|
|
2938
|
+
else if (childStyle.fontWeight) elStyle.fontWeight = childStyle.fontWeight;
|
|
2939
|
+
if (options._textTagsMap[child.nodeName.toLowerCase()] === this._defaultCommand.italic.toLowerCase()) elStyle.fontStyle = 'italic'; // italic
|
|
2940
|
+
else if (childStyle.fontStyle) elStyle.fontStyle = childStyle.fontStyle;
|
|
2768
2941
|
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
if (
|
|
2773
|
-
|
|
2942
|
+
// styles
|
|
2943
|
+
const cKeys = util.getValues(childStyle);
|
|
2944
|
+
for (let i = 0, len = this._listCamel.length; i < len; i++) {
|
|
2945
|
+
if (cKeys.indexOf(this._listKebab[i]) > -1) {
|
|
2946
|
+
elStyle[this._listCamel[i]] = childStyle[this._listCamel[i]];
|
|
2947
|
+
childStyle.removeProperty(this._listKebab[i]);
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
|
|
2951
|
+
// remove child
|
|
2952
|
+
if (!childStyle.length) commonStyleElements.push(child);
|
|
2774
2953
|
|
|
2775
|
-
|
|
2776
|
-
if (childStyle.color) elStyle.color = childStyle.color; // color
|
|
2777
|
-
if (childStyle.fontSize) elStyle.fontSize = childStyle.fontSize; // size
|
|
2954
|
+
this._setCommonListStyle(el, child);
|
|
2778
2955
|
|
|
2779
|
-
|
|
2956
|
+
// common style
|
|
2957
|
+
for (let i = 0, len = commonStyleElements.length, n, ch, p; i < len; i++) {
|
|
2958
|
+
n = commonStyleElements[i];
|
|
2959
|
+
ch = n.childNodes;
|
|
2960
|
+
p = n.parentNode;
|
|
2961
|
+
n = n.nextSibling;
|
|
2962
|
+
while (ch.length > 0) {
|
|
2963
|
+
p.insertBefore(ch[0], n);
|
|
2964
|
+
}
|
|
2965
|
+
util.removeItem(commonStyleElements[i]);
|
|
2780
2966
|
}
|
|
2781
2967
|
},
|
|
2782
2968
|
|
|
@@ -2869,6 +3055,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
2869
3055
|
util.copyTagAttributes(parentCon, newInnerNode);
|
|
2870
3056
|
|
|
2871
3057
|
return {
|
|
3058
|
+
ancestor: element,
|
|
2872
3059
|
startContainer: startCon,
|
|
2873
3060
|
startOffset: startOff,
|
|
2874
3061
|
endContainer: endCon,
|
|
@@ -3987,7 +4174,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
3987
4174
|
return {
|
|
3988
4175
|
ancestor: pNode,
|
|
3989
4176
|
container: container,
|
|
3990
|
-
offset: offset
|
|
4177
|
+
offset: container.nodeType === 1 && offset === 1 ? container.childNodes.length : offset
|
|
3991
4178
|
};
|
|
3992
4179
|
},
|
|
3993
4180
|
|
|
@@ -4000,19 +4187,27 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4000
4187
|
actionCall: function (command, display, target) {
|
|
4001
4188
|
// call plugins
|
|
4002
4189
|
if (display) {
|
|
4003
|
-
if (/more/i.test(display)
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
if (
|
|
4007
|
-
(
|
|
4008
|
-
|
|
4190
|
+
if (/more/i.test(display)) {
|
|
4191
|
+
if (target !== this._moreLayerActiveButton) {
|
|
4192
|
+
const layer = context.element.toolbar.querySelector('.' + command);
|
|
4193
|
+
if (layer) {
|
|
4194
|
+
if (this._moreLayerActiveButton) this.moreLayerOff();
|
|
4195
|
+
|
|
4196
|
+
this._moreLayerActiveButton = target;
|
|
4197
|
+
layer.style.display = 'block';
|
|
4198
|
+
|
|
4199
|
+
event._showToolbarBalloon();
|
|
4200
|
+
event._showToolbarInline();
|
|
4009
4201
|
}
|
|
4010
4202
|
util.addClass(target, 'on');
|
|
4011
|
-
|
|
4012
|
-
layer.
|
|
4203
|
+
} else {
|
|
4204
|
+
const layer = context.element.toolbar.querySelector('.' + this._moreLayerActiveButton.getAttribute('data-command'));
|
|
4205
|
+
if (layer) {
|
|
4206
|
+
this.moreLayerOff();
|
|
4013
4207
|
|
|
4014
|
-
|
|
4015
|
-
|
|
4208
|
+
event._showToolbarBalloon();
|
|
4209
|
+
event._showToolbarInline();
|
|
4210
|
+
}
|
|
4016
4211
|
}
|
|
4017
4212
|
return;
|
|
4018
4213
|
}
|
|
@@ -4022,7 +4217,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4022
4217
|
return;
|
|
4023
4218
|
}
|
|
4024
4219
|
|
|
4025
|
-
if (this.isReadOnly) return;
|
|
4220
|
+
if (this.isReadOnly && util.arrayIncludes(this.resizingDisabledButtons, target)) return;
|
|
4026
4221
|
if (/submenu/.test(display) && (this._menuTray[command] === null || target !== this.submenuActiveButton)) {
|
|
4027
4222
|
this.callPlugin(command, this.submenuOn.bind(this, target), target);
|
|
4028
4223
|
return;
|
|
@@ -4039,17 +4234,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4039
4234
|
this.commandHandler(target, command);
|
|
4040
4235
|
}
|
|
4041
4236
|
|
|
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)) {
|
|
4237
|
+
if (/submenu/.test(display)) {
|
|
4053
4238
|
this.submenuOff();
|
|
4054
4239
|
} else if (!/command/.test(display)) {
|
|
4055
4240
|
this.submenuOff();
|
|
@@ -4073,6 +4258,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4073
4258
|
case 'paste':
|
|
4074
4259
|
break;
|
|
4075
4260
|
case 'selectAll':
|
|
4261
|
+
this.containerOff();
|
|
4076
4262
|
const wysiwyg = context.element.wysiwyg;
|
|
4077
4263
|
let first = util.getChildElement(wysiwyg.firstChild, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, false) || wysiwyg.firstChild;
|
|
4078
4264
|
let last = util.getChildElement(wysiwyg.lastChild, function (current) { return current.childNodes.length === 0 || current.nodeType === 3; }, true) || wysiwyg.lastChild;
|
|
@@ -4124,6 +4310,15 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4124
4310
|
case 'showBlocks':
|
|
4125
4311
|
this.toggleDisplayBlocks();
|
|
4126
4312
|
break;
|
|
4313
|
+
case 'dir':
|
|
4314
|
+
this.setDir(options.rtl ? 'ltr' : 'rtl');
|
|
4315
|
+
break;
|
|
4316
|
+
case 'dir_ltr':
|
|
4317
|
+
this.setDir('ltr');
|
|
4318
|
+
break;
|
|
4319
|
+
case 'dir_rtl':
|
|
4320
|
+
this.setDir('rtl');
|
|
4321
|
+
break;
|
|
4127
4322
|
case 'save':
|
|
4128
4323
|
if (typeof options.callBackSave === 'function') {
|
|
4129
4324
|
options.callBackSave(this.getContents(false), this._variable.isChanged);
|
|
@@ -4150,7 +4345,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4150
4345
|
removeNode = 'SUB';
|
|
4151
4346
|
}
|
|
4152
4347
|
|
|
4153
|
-
this.nodeChange(cmd, null, [removeNode], false);
|
|
4348
|
+
this.nodeChange(cmd, this._commandMapStyles[command] || null, [removeNode], false);
|
|
4154
4349
|
this.focus();
|
|
4155
4350
|
}
|
|
4156
4351
|
},
|
|
@@ -4230,7 +4425,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4230
4425
|
util.setDisabledButtons(!isCodeView, this.codeViewDisabledButtons);
|
|
4231
4426
|
|
|
4232
4427
|
if (isCodeView) {
|
|
4233
|
-
this._setCodeDataToEditor();
|
|
4428
|
+
if (!util.isNonEditable(context.element.wysiwygFrame)) this._setCodeDataToEditor();
|
|
4234
4429
|
context.element.wysiwygFrame.scrollTop = 0;
|
|
4235
4430
|
context.element.code.style.display = 'none';
|
|
4236
4431
|
context.element.wysiwygFrame.style.display = 'block';
|
|
@@ -4256,14 +4451,18 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4256
4451
|
util.removeClass(this._styleCommandMap.codeView, 'active');
|
|
4257
4452
|
|
|
4258
4453
|
// history stack
|
|
4259
|
-
|
|
4260
|
-
|
|
4454
|
+
if (!util.isNonEditable(context.element.wysiwygFrame)) {
|
|
4455
|
+
this.history.push(false);
|
|
4456
|
+
this.history._resetCachingButton();
|
|
4457
|
+
}
|
|
4261
4458
|
} else {
|
|
4262
4459
|
this._setEditorDataToCodeView();
|
|
4263
4460
|
this._variable._codeOriginCssText = this._variable._codeOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/, 'display: block');
|
|
4264
4461
|
this._variable._wysiwygOriginCssText = this._variable._wysiwygOriginCssText.replace(/(\s?display(\s+)?:(\s+)?)[a-zA-Z]+(?=;)/, 'display: none');
|
|
4265
4462
|
|
|
4266
|
-
if (
|
|
4463
|
+
if (this._variable.isFullScreen) context.element.code.style.height = '100%';
|
|
4464
|
+
else if (options.height === 'auto' && !options.codeMirrorEditor) context.element.code.style.height = context.element.code.scrollHeight > 0 ? (context.element.code.scrollHeight + 'px') : 'auto';
|
|
4465
|
+
|
|
4267
4466
|
if (options.codeMirrorEditor) options.codeMirrorEditor.refresh();
|
|
4268
4467
|
|
|
4269
4468
|
this._variable.isCodeView = true;
|
|
@@ -4309,7 +4508,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4309
4508
|
}
|
|
4310
4509
|
}
|
|
4311
4510
|
|
|
4312
|
-
|
|
4511
|
+
let headers = parseDocument.head.innerHTML;
|
|
4512
|
+
if (!parseDocument.head.querySelector('link[rel="stylesheet"]') || (this.options.height === 'auto' && !parseDocument.head.querySelector('style'))) {
|
|
4513
|
+
headers += util._setIframeCssTags(this.options);
|
|
4514
|
+
}
|
|
4515
|
+
|
|
4516
|
+
this._wd.head.innerHTML = headers;
|
|
4313
4517
|
this._wd.body.innerHTML = this.convertContentsForEditor(parseDocument.body.innerHTML);
|
|
4314
4518
|
|
|
4315
4519
|
const attrs = parseDocument.body.attributes;
|
|
@@ -4333,7 +4537,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4333
4537
|
* @private
|
|
4334
4538
|
*/
|
|
4335
4539
|
_setEditorDataToCodeView: function () {
|
|
4336
|
-
const codeContents = this.convertHTMLForCodeView(context.element.wysiwyg);
|
|
4540
|
+
const codeContents = this.convertHTMLForCodeView(context.element.wysiwyg, false);
|
|
4337
4541
|
let codeValue = '';
|
|
4338
4542
|
|
|
4339
4543
|
if (options.fullPage) {
|
|
@@ -4351,7 +4555,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4351
4555
|
|
|
4352
4556
|
/**
|
|
4353
4557
|
* @description Changes to full screen or default screen
|
|
4354
|
-
* @param {Element} element full screen button
|
|
4558
|
+
* @param {Element|null} element full screen button
|
|
4355
4559
|
*/
|
|
4356
4560
|
toggleFullScreen: function (element) {
|
|
4357
4561
|
const topArea = context.element.topArea;
|
|
@@ -4361,6 +4565,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4361
4565
|
const code = context.element.code;
|
|
4362
4566
|
const _var = this._variable;
|
|
4363
4567
|
this.controllersOff();
|
|
4568
|
+
|
|
4569
|
+
const wasToolbarHidden = (toolbar.style.display === 'none' || (this._isInline && !this._inlineToolbarAttr.isShow));
|
|
4364
4570
|
|
|
4365
4571
|
if (!_var.isFullScreen) {
|
|
4366
4572
|
_var.isFullScreen = true;
|
|
@@ -4406,7 +4612,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4406
4612
|
_var.innerHeight_fullScreen = (_w.innerHeight - toolbar.offsetHeight);
|
|
4407
4613
|
editorArea.style.height = (_var.innerHeight_fullScreen - options.fullScreenOffset) + 'px';
|
|
4408
4614
|
|
|
4409
|
-
util.changeElement(element.firstElementChild, icons.reduction);
|
|
4615
|
+
if (element) util.changeElement(element.firstElementChild, icons.reduction);
|
|
4410
4616
|
|
|
4411
4617
|
if (options.iframe && options.height === 'auto') {
|
|
4412
4618
|
editorArea.style.overflow = 'auto';
|
|
@@ -4425,6 +4631,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4425
4631
|
topArea.style.cssText = _var._originCssText;
|
|
4426
4632
|
_d.body.style.overflow = _var._bodyOverflow;
|
|
4427
4633
|
|
|
4634
|
+
if (options.height === 'auto' && !options.codeMirrorEditor) event._codeViewAutoHeight();
|
|
4635
|
+
|
|
4428
4636
|
if (!!options.toolbarContainer) options.toolbarContainer.appendChild(toolbar);
|
|
4429
4637
|
|
|
4430
4638
|
if (options.stickyToolbar > -1) {
|
|
@@ -4443,12 +4651,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4443
4651
|
if (!!options.toolbarContainer) util.removeClass(toolbar, 'se-toolbar-balloon');
|
|
4444
4652
|
|
|
4445
4653
|
event.onScroll_window();
|
|
4446
|
-
util.changeElement(element.firstElementChild, icons.expansion);
|
|
4654
|
+
if (element) util.changeElement(element.firstElementChild, icons.expansion);
|
|
4447
4655
|
|
|
4448
4656
|
context.element.topArea.style.marginTop = '';
|
|
4449
4657
|
util.removeClass(this._styleCommandMap.fullScreen, 'active');
|
|
4450
4658
|
}
|
|
4451
4659
|
|
|
4660
|
+
if (wasToolbarHidden) functions.toolbar.hide();
|
|
4661
|
+
|
|
4452
4662
|
// user event
|
|
4453
4663
|
if (typeof functions.toggleFullScreen === 'function') functions.toggleFullScreen(this._variable.isFullScreen, this);
|
|
4454
4664
|
},
|
|
@@ -4501,8 +4711,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4501
4711
|
_w.setTimeout(function () {
|
|
4502
4712
|
try {
|
|
4503
4713
|
iframe.focus();
|
|
4504
|
-
// IE or Edge
|
|
4505
|
-
if (util.isIE_Edge || !!_d.documentMode || !!_w.StyleMedia) {
|
|
4714
|
+
// IE or Edge, Chromium
|
|
4715
|
+
if (util.isIE_Edge || util.isChromium || !!_d.documentMode || !!_w.StyleMedia) {
|
|
4506
4716
|
try {
|
|
4507
4717
|
iframe.contentWindow.document.execCommand('print', false, null);
|
|
4508
4718
|
} catch (e) {
|
|
@@ -4571,6 +4781,70 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4571
4781
|
}
|
|
4572
4782
|
},
|
|
4573
4783
|
|
|
4784
|
+
/**
|
|
4785
|
+
* @description Set direction to "rtl" or "ltr".
|
|
4786
|
+
* @param {String} dir "rtl" or "ltr"
|
|
4787
|
+
*/
|
|
4788
|
+
setDir: function (dir) {
|
|
4789
|
+
const rtl = dir === 'rtl';
|
|
4790
|
+
const changeDir = this._prevRtl !== rtl;
|
|
4791
|
+
this._prevRtl = options.rtl = rtl;
|
|
4792
|
+
|
|
4793
|
+
if (changeDir) {
|
|
4794
|
+
// align buttons
|
|
4795
|
+
if (this.plugins.align) {
|
|
4796
|
+
this.plugins.align.exchangeDir.call(this);
|
|
4797
|
+
}
|
|
4798
|
+
// indent buttons
|
|
4799
|
+
if (context.tool.indent) util.changeElement(context.tool.indent.firstElementChild, icons.indent);
|
|
4800
|
+
if (context.tool.outdent) util.changeElement(context.tool.outdent.firstElementChild, icons.outdent);
|
|
4801
|
+
}
|
|
4802
|
+
|
|
4803
|
+
const el = context.element;
|
|
4804
|
+
if (rtl) {
|
|
4805
|
+
util.addClass(el.topArea, 'se-rtl');
|
|
4806
|
+
util.addClass(el.wysiwygFrame, 'se-rtl');
|
|
4807
|
+
} else {
|
|
4808
|
+
util.removeClass(el.topArea, 'se-rtl');
|
|
4809
|
+
util.removeClass(el.wysiwygFrame, 'se-rtl');
|
|
4810
|
+
}
|
|
4811
|
+
|
|
4812
|
+
const lineNodes = util.getListChildren(el.wysiwyg, function (current) {
|
|
4813
|
+
return util.isFormatElement(current) && (current.style.marginRight || current.style.marginLeft || current.style.textAlign);
|
|
4814
|
+
});
|
|
4815
|
+
|
|
4816
|
+
for (let i = 0, len = lineNodes.length, n, l, r; i < len; i++) {
|
|
4817
|
+
n = lineNodes[i];
|
|
4818
|
+
// indent margin
|
|
4819
|
+
r = n.style.marginRight;
|
|
4820
|
+
l = n.style.marginLeft;
|
|
4821
|
+
if (r || l) {
|
|
4822
|
+
n.style.marginRight = l;
|
|
4823
|
+
n.style.marginLeft = r;
|
|
4824
|
+
}
|
|
4825
|
+
// text align
|
|
4826
|
+
r = n.style.textAlign;
|
|
4827
|
+
if (r === 'left') n.style.textAlign = 'right';
|
|
4828
|
+
else if (r === 'right') n.style.textAlign = 'left';
|
|
4829
|
+
}
|
|
4830
|
+
|
|
4831
|
+
const tool = context.tool;
|
|
4832
|
+
if (tool.dir) {
|
|
4833
|
+
util.changeTxt(tool.dir.querySelector('.se-tooltip-text'), lang.toolbar[options.rtl ? 'dir_ltr' : 'dir_rtl']);
|
|
4834
|
+
util.changeElement(tool.dir.firstElementChild, icons[options.rtl ? 'dir_ltr' : 'dir_rtl']);
|
|
4835
|
+
}
|
|
4836
|
+
|
|
4837
|
+
if (tool.dir_ltr) {
|
|
4838
|
+
if (rtl) util.removeClass(tool.dir_ltr, 'active');
|
|
4839
|
+
else util.addClass(tool.dir_ltr, 'active');
|
|
4840
|
+
}
|
|
4841
|
+
|
|
4842
|
+
if (tool.dir_rtl) {
|
|
4843
|
+
if (rtl) util.addClass(tool.dir_rtl, 'active');
|
|
4844
|
+
else util.removeClass(tool.dir_rtl, 'active');
|
|
4845
|
+
}
|
|
4846
|
+
},
|
|
4847
|
+
|
|
4574
4848
|
/**
|
|
4575
4849
|
* @description Sets the HTML string
|
|
4576
4850
|
* @param {String|undefined} html HTML string
|
|
@@ -4586,7 +4860,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4586
4860
|
// history stack
|
|
4587
4861
|
this.history.push(false);
|
|
4588
4862
|
} else {
|
|
4589
|
-
const value = this.convertHTMLForCodeView(convertValue);
|
|
4863
|
+
const value = this.convertHTMLForCodeView(convertValue, false);
|
|
4590
4864
|
this._setCodeView(value);
|
|
4591
4865
|
}
|
|
4592
4866
|
},
|
|
@@ -4607,7 +4881,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4607
4881
|
* @returns {Object}
|
|
4608
4882
|
*/
|
|
4609
4883
|
getContents: function (onlyContents) {
|
|
4610
|
-
const contents = context.element.wysiwyg
|
|
4884
|
+
const contents = this.convertHTMLForCodeView(context.element.wysiwyg, true);
|
|
4611
4885
|
const renderHTML = util.createElement('DIV');
|
|
4612
4886
|
renderHTML.innerHTML = contents;
|
|
4613
4887
|
|
|
@@ -4627,6 +4901,16 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4627
4901
|
}
|
|
4628
4902
|
},
|
|
4629
4903
|
|
|
4904
|
+
/**
|
|
4905
|
+
* @description Gets the current contents with containing parent div(div.sun-editor-editable).
|
|
4906
|
+
* <div class="sun-editor-editable">{contents}</div>
|
|
4907
|
+
* @param {Boolean} onlyContents Return only the contents of the body without headers when the "fullPage" option is true
|
|
4908
|
+
* @returns {Object}
|
|
4909
|
+
*/
|
|
4910
|
+
getFullContents: function (onlyContents) {
|
|
4911
|
+
return '<div class="sun-editor-editable' + options.rtl ? ' se-rtl' : '' + '">' + this.getContents(onlyContents) + '</div>';
|
|
4912
|
+
},
|
|
4913
|
+
|
|
4630
4914
|
/**
|
|
4631
4915
|
* @description Returns HTML string according to tag type and configuration.
|
|
4632
4916
|
* Use only "cleanHTML"
|
|
@@ -4690,7 +4974,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4690
4974
|
.replace(/\n/g, '')
|
|
4691
4975
|
.replace(/<(script|style)[\s\S]*>[\s\S]*<\/(script|style)>/gi, '')
|
|
4692
4976
|
.replace(/<[a-z0-9]+\:[a-z0-9]+[^>^\/]*>[^>]*<\/[a-z0-9]+\:[a-z0-9]+>/gi, '')
|
|
4693
|
-
.replace(this.editorTagsWhitelistRegExp, '')
|
|
4977
|
+
.replace(this.editorTagsWhitelistRegExp, '')
|
|
4978
|
+
.replace(this.editorTagsBlacklistRegExp, '');
|
|
4694
4979
|
},
|
|
4695
4980
|
|
|
4696
4981
|
/**
|
|
@@ -4705,18 +4990,28 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4705
4990
|
if (/^<[a-z0-9]+\:[a-z0-9]+/i.test(m)) return m;
|
|
4706
4991
|
|
|
4707
4992
|
let v = null;
|
|
4708
|
-
const
|
|
4709
|
-
|
|
4993
|
+
const tagName = t.match(/(?!<)[a-zA-Z0-9\-]+/)[0].toLowerCase();
|
|
4994
|
+
|
|
4995
|
+
// blacklist
|
|
4996
|
+
const bAttr = this._attributesTagsBlacklist[tagName];
|
|
4997
|
+
if (bAttr) m = m.replace(bAttr, '');
|
|
4998
|
+
else m = m.replace(this._attributesBlacklistRegExp, '');
|
|
4999
|
+
|
|
5000
|
+
// whitelist
|
|
5001
|
+
const wAttr = this._attributesTagsWhitelist[tagName];
|
|
5002
|
+
if (wAttr) v = m.match(wAttr);
|
|
4710
5003
|
else v = m.match(this._attributesWhitelistRegExp);
|
|
4711
5004
|
|
|
5005
|
+
// anchor
|
|
4712
5006
|
if (!lowLevelCheck || /<a\b/i.test(t)) {
|
|
4713
|
-
const sv = m.match(/id\s*=\s*(?:"|')[^"']*(?:"|')/);
|
|
5007
|
+
const sv = m.match(/(?:(?:id|name)\s*=\s*(?:"|')[^"']*(?:"|'))/g);
|
|
4714
5008
|
if (sv) {
|
|
4715
5009
|
if (!v) v = [];
|
|
4716
5010
|
v.push(sv[0]);
|
|
4717
5011
|
}
|
|
4718
5012
|
}
|
|
4719
5013
|
|
|
5014
|
+
// span
|
|
4720
5015
|
if ((!lowLevelCheck || /<span/i.test(t)) && (!v || !/style=/i.test(v.toString()))) {
|
|
4721
5016
|
const sv = m.match(/style\s*=\s*(?:"|')[^"']*(?:"|')/);
|
|
4722
5017
|
if (sv) {
|
|
@@ -4725,6 +5020,29 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4725
5020
|
}
|
|
4726
5021
|
}
|
|
4727
5022
|
|
|
5023
|
+
// img
|
|
5024
|
+
if (/<img/i.test(t)) {
|
|
5025
|
+
let w = '', h = '';
|
|
5026
|
+
const sv = m.match(/style\s*=\s*(?:"|')[^"']*(?:"|')/);
|
|
5027
|
+
if (!v) v = [];
|
|
5028
|
+
if (sv) {
|
|
5029
|
+
w = sv[0].match(/width:(.+);/);
|
|
5030
|
+
w = util.getNumber(w ? w[1] : '', -1) || '';
|
|
5031
|
+
h = sv[0].match(/height:(.+);/);
|
|
5032
|
+
h = util.getNumber(h ? h[1] : '', -1) || '';
|
|
5033
|
+
}
|
|
5034
|
+
|
|
5035
|
+
if (!w || !h) {
|
|
5036
|
+
const avw = m.match(/width\s*=\s*((?:"|')[^"']*(?:"|'))/);
|
|
5037
|
+
const avh = m.match(/height\s*=\s*((?:"|')[^"']*(?:"|'))/);
|
|
5038
|
+
if (avw || avh) {
|
|
5039
|
+
w = !w ? util.getNumber(avw ? avw[1] : '') || '' : w;
|
|
5040
|
+
h = !h ? util.getNumber(avh ? avh[1] : '') || '' : h;
|
|
5041
|
+
}
|
|
5042
|
+
}
|
|
5043
|
+
v.push('data-origin="' + (w + ',' + h) + '"');
|
|
5044
|
+
}
|
|
5045
|
+
|
|
4728
5046
|
if (v) {
|
|
4729
5047
|
for (let i = 0, len = v.length; i < len; i++) {
|
|
4730
5048
|
if (lowLevelCheck && /^class="(?!(__se__|se-|katex))/.test(v[i])) continue;
|
|
@@ -4740,14 +5058,16 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4740
5058
|
* @param {String} html HTML string
|
|
4741
5059
|
* @param {String|RegExp|null} whitelist Regular expression of allowed tags.
|
|
4742
5060
|
* RegExp object is create by util.createTagsWhitelist method. (core.pasteTagsWhitelistRegExp)
|
|
5061
|
+
* @param {String|RegExp|null} blacklist Regular expression of disallowed tags.
|
|
5062
|
+
* RegExp object is create by util.createTagsBlacklist method. (core.pasteTagsBlacklistRegExp)
|
|
4743
5063
|
* @returns {String}
|
|
4744
5064
|
*/
|
|
4745
|
-
cleanHTML: function (html, whitelist) {
|
|
5065
|
+
cleanHTML: function (html, whitelist, blacklist) {
|
|
4746
5066
|
html = this._deleteDisallowedTags(this._parser.parseFromString(html, 'text/html').body.innerHTML).replace(/(<[a-zA-Z0-9\-]+)[^>]*(?=>)/g, this._cleanTags.bind(this, true));
|
|
4747
5067
|
|
|
4748
5068
|
const dom = _d.createRange().createContextualFragment(html);
|
|
4749
5069
|
try {
|
|
4750
|
-
util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, true);
|
|
5070
|
+
util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, this._htmlCheckBlacklistRegExp, true);
|
|
4751
5071
|
} catch (error) {
|
|
4752
5072
|
console.warn('[SUNEDITOR.cleanHTML.consistencyCheck.fail] ' + error);
|
|
4753
5073
|
}
|
|
@@ -4783,7 +5103,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4783
5103
|
}
|
|
4784
5104
|
|
|
4785
5105
|
cleanHTML = util.htmlRemoveWhiteSpace(cleanHTML);
|
|
4786
|
-
|
|
5106
|
+
if (!cleanHTML) {
|
|
5107
|
+
cleanHTML = html;
|
|
5108
|
+
} else {
|
|
5109
|
+
if (whitelist) cleanHTML = cleanHTML.replace(typeof whitelist === 'string' ? util.createTagsWhitelist(whitelist) : whitelist, '');
|
|
5110
|
+
if (blacklist) cleanHTML = cleanHTML.replace(typeof blacklist === 'string' ? util.createTagsBlacklist(blacklist) : blacklist, '');
|
|
5111
|
+
}
|
|
5112
|
+
|
|
5113
|
+
return this._tagConvertor(cleanHTML);
|
|
4787
5114
|
},
|
|
4788
5115
|
|
|
4789
5116
|
/**
|
|
@@ -4796,7 +5123,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4796
5123
|
const dom = _d.createRange().createContextualFragment(contents);
|
|
4797
5124
|
|
|
4798
5125
|
try {
|
|
4799
|
-
util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, false);
|
|
5126
|
+
util._consistencyCheckOfHTML(dom, this._htmlCheckWhitelistRegExp, this._htmlCheckBlacklistRegExp, false);
|
|
4800
5127
|
} catch (error) {
|
|
4801
5128
|
console.warn('[SUNEDITOR.convertContentsForEditor.consistencyCheck.fail] ' + error);
|
|
4802
5129
|
}
|
|
@@ -4816,10 +5143,29 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4816
5143
|
}
|
|
4817
5144
|
|
|
4818
5145
|
const domTree = dom.childNodes;
|
|
4819
|
-
let cleanHTML = '';
|
|
4820
|
-
for (let i = 0,
|
|
4821
|
-
|
|
5146
|
+
let cleanHTML = '', p = null;
|
|
5147
|
+
for (let i = 0, t; i < domTree.length; i++) {
|
|
5148
|
+
t = domTree[i];
|
|
5149
|
+
|
|
5150
|
+
if (!util.isFormatElement(t) && !util.isComponent(t) && !util.isMedia(t)) {
|
|
5151
|
+
if (!p) p = util.createElement(options.defaultTag);
|
|
5152
|
+
p.appendChild(t);
|
|
5153
|
+
i--;
|
|
5154
|
+
if (domTree[i + 1] && !util.isFormatElement(domTree[i + 1])) {
|
|
5155
|
+
continue;
|
|
5156
|
+
} else {
|
|
5157
|
+
t = p;
|
|
5158
|
+
p = null;
|
|
5159
|
+
}
|
|
5160
|
+
}
|
|
5161
|
+
|
|
5162
|
+
if (p) {
|
|
5163
|
+
cleanHTML += this._makeLine(p, true);
|
|
5164
|
+
p = null;
|
|
5165
|
+
}
|
|
5166
|
+
cleanHTML += this._makeLine(t, true);
|
|
4822
5167
|
}
|
|
5168
|
+
if (p) cleanHTML += this._makeLine(p, true);
|
|
4823
5169
|
|
|
4824
5170
|
if (cleanHTML.length === 0) return '<' + options.defaultTag + '><br></' + options.defaultTag + '>';
|
|
4825
5171
|
|
|
@@ -4830,28 +5176,30 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4830
5176
|
/**
|
|
4831
5177
|
* @description Converts wysiwyg area element into a format that can be placed in an editor of code view mode
|
|
4832
5178
|
* @param {Element|String} html WYSIWYG element (context.element.wysiwyg) or HTML string.
|
|
5179
|
+
* @param {Boolean} comp If true, does not line break and indentation of tags.
|
|
4833
5180
|
* @returns {String}
|
|
4834
5181
|
*/
|
|
4835
|
-
convertHTMLForCodeView: function (html) {
|
|
5182
|
+
convertHTMLForCodeView: function (html, comp) {
|
|
4836
5183
|
let returnHTML = '';
|
|
4837
5184
|
const wRegExp = _w.RegExp;
|
|
4838
5185
|
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
5186
|
const wDoc = typeof html === 'string' ? _d.createRange().createContextualFragment(html) : html;
|
|
4840
5187
|
const isFormat = function (current) { return this.isFormatElement(current) || this.isComponent(current); }.bind(util);
|
|
5188
|
+
const brChar = comp ? '' : '\n';
|
|
4841
5189
|
|
|
4842
|
-
let indentSize = this._variable.codeIndent * 1;
|
|
5190
|
+
let indentSize = comp ? 0 : this._variable.codeIndent * 1;
|
|
4843
5191
|
indentSize = indentSize > 0 ? new _w.Array(indentSize + 1).join(' ') : '';
|
|
4844
5192
|
|
|
4845
|
-
(function recursionFunc (element, indent
|
|
5193
|
+
(function recursionFunc (element, indent) {
|
|
4846
5194
|
const children = element.childNodes;
|
|
4847
5195
|
const elementRegTest = brReg.test(element.nodeName);
|
|
4848
5196
|
const elementIndent = (elementRegTest ? indent : '');
|
|
4849
5197
|
|
|
4850
|
-
for (let i = 0, len = children.length, node, br, nodeRegTest, tag, tagIndent; i < len; i++) {
|
|
5198
|
+
for (let i = 0, len = children.length, node, br, lineBR, nodeRegTest, tag, tagIndent; i < len; i++) {
|
|
4851
5199
|
node = children[i];
|
|
4852
5200
|
nodeRegTest = brReg.test(node.nodeName);
|
|
4853
|
-
br = nodeRegTest ?
|
|
4854
|
-
lineBR = isFormat(node) && !elementRegTest && !/^(TH|TD)$/i.test(element.nodeName) ?
|
|
5201
|
+
br = nodeRegTest ? brChar : '';
|
|
5202
|
+
lineBR = isFormat(node) && !elementRegTest && !/^(TH|TD)$/i.test(element.nodeName) ? brChar : '';
|
|
4855
5203
|
|
|
4856
5204
|
if (node.nodeType === 8) {
|
|
4857
5205
|
returnHTML += '\n<!-- ' + node.textContent.trim() + ' -->' + br;
|
|
@@ -4862,7 +5210,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4862
5210
|
continue;
|
|
4863
5211
|
}
|
|
4864
5212
|
if (node.childNodes.length === 0) {
|
|
4865
|
-
returnHTML += (/^HR$/i.test(node.nodeName) ?
|
|
5213
|
+
returnHTML += (/^HR$/i.test(node.nodeName) ? brChar : '') + (/^PRE$/i.test(node.parentElement.nodeName) && /^BR$/i.test(node.nodeName) ? '' : elementIndent) + node.outerHTML + br;
|
|
4866
5214
|
continue;
|
|
4867
5215
|
}
|
|
4868
5216
|
|
|
@@ -4873,12 +5221,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4873
5221
|
tagIndent = elementIndent || nodeRegTest ? indent : '';
|
|
4874
5222
|
returnHTML += (lineBR || (elementRegTest ? '' : br)) + tagIndent + node.outerHTML.match(wRegExp('<' + tag + '[^>]*>', 'i'))[0] + br;
|
|
4875
5223
|
recursionFunc(node, indent + indentSize, '');
|
|
4876
|
-
returnHTML += (/\n$/.test(returnHTML) ? tagIndent : '') + '</' + tag + '>' + (lineBR || br || elementRegTest ?
|
|
5224
|
+
returnHTML += (/\n$/.test(returnHTML) ? tagIndent : '') + '</' + tag + '>' + (lineBR || br || elementRegTest ? brChar : '' || /^(TH|TD)$/i.test(node.nodeName) ? brChar : '');
|
|
4877
5225
|
}
|
|
4878
5226
|
}
|
|
4879
|
-
}(wDoc, ''
|
|
5227
|
+
}(wDoc, ''));
|
|
4880
5228
|
|
|
4881
|
-
return returnHTML.trim() +
|
|
5229
|
+
return returnHTML.trim() + brChar;
|
|
4882
5230
|
},
|
|
4883
5231
|
|
|
4884
5232
|
/**
|
|
@@ -4980,6 +5328,36 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
4980
5328
|
return /byte/.test(charCounterType) ? util.getByteLength(content) : content.length;
|
|
4981
5329
|
},
|
|
4982
5330
|
|
|
5331
|
+
/**
|
|
5332
|
+
* @description Reset buttons of the responsive toolbar.
|
|
5333
|
+
*/
|
|
5334
|
+
resetResponsiveToolbar: function () {
|
|
5335
|
+
core.controllersOff();
|
|
5336
|
+
|
|
5337
|
+
const responsiveSize = event._responsiveButtonSize;
|
|
5338
|
+
if (responsiveSize) {
|
|
5339
|
+
let w = 0;
|
|
5340
|
+
if ((core._isBalloon || core._isInline) && options.toolbarWidth === 'auto') {
|
|
5341
|
+
w = context.element.topArea.offsetWidth;
|
|
5342
|
+
} else {
|
|
5343
|
+
w = context.element.toolbar.offsetWidth;
|
|
5344
|
+
}
|
|
5345
|
+
|
|
5346
|
+
let responsiveWidth = 'default';
|
|
5347
|
+
for (let i = 1, len = responsiveSize.length; i < len; i++) {
|
|
5348
|
+
if (w < responsiveSize[i]) {
|
|
5349
|
+
responsiveWidth = responsiveSize[i] + '';
|
|
5350
|
+
break;
|
|
5351
|
+
}
|
|
5352
|
+
}
|
|
5353
|
+
|
|
5354
|
+
if (event._responsiveCurrentSize !== responsiveWidth) {
|
|
5355
|
+
event._responsiveCurrentSize = responsiveWidth;
|
|
5356
|
+
functions.setToolbarButtons(event._responsiveButtons[responsiveWidth]);
|
|
5357
|
+
}
|
|
5358
|
+
}
|
|
5359
|
+
},
|
|
5360
|
+
|
|
4983
5361
|
/**
|
|
4984
5362
|
* @description Set the char count to charCounter element textContent.
|
|
4985
5363
|
* @private
|
|
@@ -5058,9 +5436,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5058
5436
|
if (activePlugins.indexOf(key) > -1) {
|
|
5059
5437
|
plugins[key].active.call(this, null);
|
|
5060
5438
|
} else if (commandMap.OUTDENT && /^OUTDENT$/i.test(key)) {
|
|
5061
|
-
if (!
|
|
5439
|
+
if (!util.isImportantDisabled(commandMap.OUTDENT)) commandMap.OUTDENT.setAttribute('disabled', true);
|
|
5062
5440
|
} else if (commandMap.INDENT && /^INDENT$/i.test(key)) {
|
|
5063
|
-
if (!
|
|
5441
|
+
if (!util.isImportantDisabled(commandMap.INDENT)) commandMap.INDENT.removeAttribute('disabled');
|
|
5064
5442
|
} else {
|
|
5065
5443
|
util.removeClass(commandMap[key], 'active');
|
|
5066
5444
|
}
|
|
@@ -5078,6 +5456,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5078
5456
|
this._ww = options.iframe ? context.element.wysiwygFrame.contentWindow : _w;
|
|
5079
5457
|
this._wd = _d;
|
|
5080
5458
|
this._charTypeHTML = options.charCounterType === 'byte-html';
|
|
5459
|
+
this.wwComputedStyle = _w.getComputedStyle(context.element.wysiwyg);
|
|
5460
|
+
this._editorHeight = context.element.wysiwygFrame.offsetHeight;
|
|
5081
5461
|
|
|
5082
5462
|
if (!options.iframe && typeof _w.ShadowRoot === 'function') {
|
|
5083
5463
|
let child = context.element.wysiwygFrame;
|
|
@@ -5103,30 +5483,56 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5103
5483
|
this._disallowedTextTagsRegExp = disallowTextTags.length === 0 ? null : new wRegExp('(<\\/?)(' + disallowTextTags.join('|') + ')\\b\\s*([^>^<]+)?\\s*(?=>)', 'gi');
|
|
5104
5484
|
|
|
5105
5485
|
// set whitelist
|
|
5486
|
+
const getRegList = function (str, str2) { return !str ? '^' : (str === '*' ? '[a-z-]+' : (!str2 ? str : (str + '|' + str2))); };
|
|
5487
|
+
// tags
|
|
5106
5488
|
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
|
-
|
|
5489
|
+
this._allowHTMLComments = options._editorTagsWhitelist.indexOf('//') > -1 || options._editorTagsWhitelist === '*';
|
|
5490
|
+
// html check
|
|
5491
|
+
this._htmlCheckWhitelistRegExp = new wRegExp('^(' + getRegList(options._editorTagsWhitelist.replace('|//', ''), '') + ')$', 'i');
|
|
5492
|
+
this._htmlCheckBlacklistRegExp = new wRegExp('^(' + (options.tagsBlacklist || '^') + ')$', 'i');
|
|
5493
|
+
// tags
|
|
5494
|
+
this.editorTagsWhitelistRegExp = util.createTagsWhitelist(getRegList(options._editorTagsWhitelist.replace('|//', '|<!--|-->'), ''));
|
|
5495
|
+
this.editorTagsBlacklistRegExp = util.createTagsBlacklist(options.tagsBlacklist.replace('|//', '|<!--|-->'));
|
|
5496
|
+
// paste tags
|
|
5497
|
+
this.pasteTagsWhitelistRegExp = util.createTagsWhitelist(getRegList(options.pasteTagsWhitelist, ''));
|
|
5498
|
+
this.pasteTagsBlacklistRegExp = util.createTagsBlacklist(options.pasteTagsBlacklist);
|
|
5499
|
+
// attributes
|
|
5112
5500
|
const regEndStr = '\\s*=\\s*(\")[^\"]*\\1';
|
|
5113
|
-
const
|
|
5114
|
-
|
|
5501
|
+
const _wAttr = options.attributesWhitelist;
|
|
5502
|
+
let tagsAttr = {};
|
|
5115
5503
|
let allAttr = '';
|
|
5116
|
-
if (!!
|
|
5117
|
-
for (let k in
|
|
5118
|
-
if (!util.hasOwn(
|
|
5504
|
+
if (!!_wAttr) {
|
|
5505
|
+
for (let k in _wAttr) {
|
|
5506
|
+
if (!util.hasOwn(_wAttr, k) || /^on[a-z]+$/i.test(_wAttr[k])) continue;
|
|
5119
5507
|
if (k === 'all') {
|
|
5120
|
-
allAttr =
|
|
5508
|
+
allAttr = getRegList(_wAttr[k], defaultAttr);
|
|
5121
5509
|
} else {
|
|
5122
|
-
tagsAttr[k] = new wRegExp('(?:' +
|
|
5510
|
+
tagsAttr[k] = new wRegExp('\\s(?:' + getRegList(_wAttr[k], '') + ')' + regEndStr, 'ig');
|
|
5123
5511
|
}
|
|
5124
5512
|
}
|
|
5125
5513
|
}
|
|
5126
|
-
|
|
5127
|
-
this._attributesWhitelistRegExp = new wRegExp('(?:' + allAttr
|
|
5514
|
+
|
|
5515
|
+
this._attributesWhitelistRegExp = new wRegExp('\\s(?:' + (allAttr || defaultAttr) + ')' + regEndStr, 'ig');
|
|
5128
5516
|
this._attributesTagsWhitelist = tagsAttr;
|
|
5129
5517
|
|
|
5518
|
+
// blacklist
|
|
5519
|
+
const _bAttr = options.attributesBlacklist;
|
|
5520
|
+
tagsAttr = {};
|
|
5521
|
+
allAttr = '';
|
|
5522
|
+
if (!!_bAttr) {
|
|
5523
|
+
for (let k in _bAttr) {
|
|
5524
|
+
if (!util.hasOwn(_bAttr, k)) continue;
|
|
5525
|
+
if (k === 'all') {
|
|
5526
|
+
allAttr = getRegList(_bAttr[k], '');
|
|
5527
|
+
} else {
|
|
5528
|
+
tagsAttr[k] = new wRegExp('\\s(?:' + getRegList(_bAttr[k], '') + ')' + regEndStr, 'ig');
|
|
5529
|
+
}
|
|
5530
|
+
}
|
|
5531
|
+
}
|
|
5532
|
+
|
|
5533
|
+
this._attributesBlacklistRegExp = new wRegExp('\\s(?:' + (allAttr || '^') + ')' + regEndStr, 'ig');
|
|
5534
|
+
this._attributesTagsBlacklist = tagsAttr;
|
|
5535
|
+
|
|
5130
5536
|
// set modes
|
|
5131
5537
|
this._isInline = /inline/i.test(options.mode);
|
|
5132
5538
|
this._isBalloon = /balloon|balloon-always/i.test(options.mode);
|
|
@@ -5154,7 +5560,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5154
5560
|
if (!util.hasOwn(plugins, key)) continue;
|
|
5155
5561
|
plugin = plugins[key];
|
|
5156
5562
|
button = pluginCallButtons[key];
|
|
5157
|
-
if (plugin.active && button) {
|
|
5563
|
+
if ((plugin.active || plugin.action) && button) {
|
|
5158
5564
|
this.callPlugin(key, null, button);
|
|
5159
5565
|
}
|
|
5160
5566
|
if (typeof plugin.checkFileInfo === 'function' && typeof plugin.resetFileInfo === 'function') {
|
|
@@ -5180,8 +5586,8 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5180
5586
|
|
|
5181
5587
|
this.managedTagsInfo.query = managedClass.toString();
|
|
5182
5588
|
this._fileManager.queryString = this._fileManager.tags.join(',');
|
|
5183
|
-
this._fileManager.regExp = new wRegExp('^(' + this._fileManager.tags.join('|') + ')$', 'i');
|
|
5184
|
-
this._fileManager.pluginRegExp = new wRegExp('^(' + (filePluginRegExp.length === 0 ? '
|
|
5589
|
+
this._fileManager.regExp = new wRegExp('^(' + (this._fileManager.tags.join('|') || '^') + ')$', 'i');
|
|
5590
|
+
this._fileManager.pluginRegExp = new wRegExp('^(' + (filePluginRegExp.length === 0 ? '^' : filePluginRegExp.join('|')) + ')$', 'i');
|
|
5185
5591
|
|
|
5186
5592
|
// cache editor's element
|
|
5187
5593
|
this._variable._originCssText = context.element.topArea.style.cssText;
|
|
@@ -5204,6 +5610,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5204
5610
|
}
|
|
5205
5611
|
|
|
5206
5612
|
this._initWysiwygArea(reload, _initHTML);
|
|
5613
|
+
this.setDir(options.rtl ? 'rtl' : 'ltr');
|
|
5207
5614
|
},
|
|
5208
5615
|
|
|
5209
5616
|
/**
|
|
@@ -5211,9 +5618,11 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5211
5618
|
* @private
|
|
5212
5619
|
*/
|
|
5213
5620
|
_cachingButtons: function () {
|
|
5214
|
-
this.codeViewDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-code-view-enabled"])');
|
|
5621
|
+
this.codeViewDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-code-view-enabled"]):not([data-display="MORE"])');
|
|
5215
5622
|
this.resizingDisabledButtons = context.element._buttonTray.querySelectorAll('.se-menu-list button[data-display]:not([class~="se-resizing-enabled"]):not([data-display="MORE"])');
|
|
5216
5623
|
|
|
5624
|
+
this.saveButtonStates();
|
|
5625
|
+
|
|
5217
5626
|
const tool = context.tool;
|
|
5218
5627
|
this.commandMap = {
|
|
5219
5628
|
SUB: tool.subscript,
|
|
@@ -5271,7 +5680,21 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5271
5680
|
*/
|
|
5272
5681
|
_iframeAutoHeight: function () {
|
|
5273
5682
|
if (this._iframeAuto) {
|
|
5274
|
-
_w.setTimeout(function () {
|
|
5683
|
+
_w.setTimeout(function () {
|
|
5684
|
+
const h = core._iframeAuto.offsetHeight;
|
|
5685
|
+
context.element.wysiwygFrame.style.height = h + 'px';
|
|
5686
|
+
if (util.isIE) core.__callResizeFunction(h, null);
|
|
5687
|
+
});
|
|
5688
|
+
} else if (util.isIE) {
|
|
5689
|
+
core.__callResizeFunction(context.element.wysiwygFrame.offsetHeight, null);
|
|
5690
|
+
}
|
|
5691
|
+
},
|
|
5692
|
+
|
|
5693
|
+
__callResizeFunction(h, resizeObserverEntry) {
|
|
5694
|
+
h = h === -1 ? resizeObserverEntry.borderBoxSize[0].blockSize : h;
|
|
5695
|
+
if (this._editorHeight !== h) {
|
|
5696
|
+
if (typeof functions.onResizeEditor === 'function') functions.onResizeEditor(h, this._editorHeight, core, resizeObserverEntry);
|
|
5697
|
+
this._editorHeight = h;
|
|
5275
5698
|
}
|
|
5276
5699
|
},
|
|
5277
5700
|
|
|
@@ -5311,7 +5734,15 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5311
5734
|
let focusNode, offset, format;
|
|
5312
5735
|
|
|
5313
5736
|
const fileComponent = util.getParentElement(commonCon, util.isComponent);
|
|
5314
|
-
if (fileComponent && !util.isTable(fileComponent))
|
|
5737
|
+
if (fileComponent && !util.isTable(fileComponent)) {
|
|
5738
|
+
return;
|
|
5739
|
+
} else if (commonCon.nodeType === 1 && commonCon.getAttribute('data-se-embed') === 'true') {
|
|
5740
|
+
let el = commonCon.nextElementSibling;
|
|
5741
|
+
if (!util.isFormatElement(el)) el = this.appendFormatTag(commonCon, options.defaultTag);
|
|
5742
|
+
this.setRange(el.firstChild, 0, el.firstChild, 0);
|
|
5743
|
+
return;
|
|
5744
|
+
}
|
|
5745
|
+
|
|
5315
5746
|
if ((util.isRangeFormatElement(startCon) || util.isWysiwygDiv(startCon)) && (util.isComponent(startCon.children[range.startOffset]) || util.isComponent(startCon.children[range.startOffset - 1]))) return;
|
|
5316
5747
|
if (util.getParentElement(commonCon, util.isNotCheckingNode)) return null;
|
|
5317
5748
|
|
|
@@ -5407,6 +5838,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5407
5838
|
this._resourcesStateChange();
|
|
5408
5839
|
|
|
5409
5840
|
_w.setTimeout(function () {
|
|
5841
|
+
// observer
|
|
5842
|
+
if (event._resizeObserver) event._resizeObserver.observe(context.element.wysiwygFrame);
|
|
5843
|
+
if (event._toolbarObserver) event._toolbarObserver.observe(context.element._toolbarShadow);
|
|
5410
5844
|
// user event
|
|
5411
5845
|
if (typeof functions.onload === 'function') functions.onload(core, reload);
|
|
5412
5846
|
});
|
|
@@ -5423,6 +5857,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5423
5857
|
_top: contextEl.topArea,
|
|
5424
5858
|
_relative: contextEl.relative,
|
|
5425
5859
|
_toolBar: contextEl.toolbar,
|
|
5860
|
+
_toolbarShadow: contextEl._toolbarShadow,
|
|
5426
5861
|
_menuTray: contextEl._menuTray,
|
|
5427
5862
|
_editorArea: contextEl.editorArea,
|
|
5428
5863
|
_wysiwygArea: contextEl.wysiwygFrame,
|
|
@@ -5525,7 +5960,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5525
5960
|
break;
|
|
5526
5961
|
}
|
|
5527
5962
|
|
|
5528
|
-
if (!command) return
|
|
5963
|
+
if (!command) return keyStr === 'B'; // chromium - bold disabled
|
|
5529
5964
|
|
|
5530
5965
|
core.commandHandler(core.commandMap[command], command);
|
|
5531
5966
|
return true;
|
|
@@ -5566,9 +6001,9 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5566
6001
|
}
|
|
5567
6002
|
}
|
|
5568
6003
|
|
|
5569
|
-
if (
|
|
6004
|
+
if (util.isFormatElement(element)) {
|
|
5570
6005
|
/* Outdent */
|
|
5571
|
-
if (commandMapNodes.indexOf('OUTDENT') === -1 && commandMap.OUTDENT) {
|
|
6006
|
+
if (commandMapNodes.indexOf('OUTDENT') === -1 && commandMap.OUTDENT && !util.isImportantDisabled(commandMap.OUTDENT)) {
|
|
5572
6007
|
if (util.isListCell(element) || (element.style[marginDir] && util.getNumber(element.style[marginDir], 0) > 0)) {
|
|
5573
6008
|
commandMapNodes.push('OUTDENT');
|
|
5574
6009
|
commandMap.OUTDENT.removeAttribute('disabled');
|
|
@@ -5576,7 +6011,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5576
6011
|
}
|
|
5577
6012
|
|
|
5578
6013
|
/* Indent */
|
|
5579
|
-
if (commandMapNodes.indexOf('INDENT') === -1 && commandMap.INDENT) {
|
|
6014
|
+
if (commandMapNodes.indexOf('INDENT') === -1 && commandMap.INDENT && !util.isImportantDisabled(commandMap.INDENT)) {
|
|
5580
6015
|
commandMapNodes.push('INDENT');
|
|
5581
6016
|
if (util.isListCell(element) && !element.previousElementSibling) {
|
|
5582
6017
|
commandMap.INDENT.setAttribute('disabled', true);
|
|
@@ -5589,7 +6024,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5589
6024
|
}
|
|
5590
6025
|
|
|
5591
6026
|
/** default active buttons [strong, ins, em, del, sub, sup] */
|
|
5592
|
-
if (classOnCheck.test(nodeName)) {
|
|
6027
|
+
if (classOnCheck && classOnCheck.test(nodeName)) {
|
|
5593
6028
|
commandMapNodes.push(nodeName);
|
|
5594
6029
|
util.addClass(commandMap[nodeName], 'active');
|
|
5595
6030
|
}
|
|
@@ -5663,6 +6098,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5663
6098
|
|
|
5664
6099
|
onMouseDown_wysiwyg: function (e) {
|
|
5665
6100
|
if (core.isReadOnly || util.isNonEditable(context.element.wysiwyg)) return;
|
|
6101
|
+
core._editorRange();
|
|
5666
6102
|
|
|
5667
6103
|
// user event
|
|
5668
6104
|
if (typeof functions.onMouseDown === 'function' && functions.onMouseDown(e, core) === false) return;
|
|
@@ -5708,7 +6144,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
5708
6144
|
}
|
|
5709
6145
|
|
|
5710
6146
|
const figcaption = util.getParentElement(targetElement, 'FIGCAPTION');
|
|
5711
|
-
if (util.isNonEditable(figcaption)) {
|
|
6147
|
+
if (figcaption && (util.isNonEditable(figcaption) || !figcaption.getAttribute("contenteditable"))) {
|
|
5712
6148
|
e.preventDefault();
|
|
5713
6149
|
figcaption.setAttribute('contenteditable', true);
|
|
5714
6150
|
figcaption.focus();
|
|
@@ -6497,6 +6933,45 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
6497
6933
|
|
|
6498
6934
|
temp = !temp ? newFormat.firstChild : temp.appendChild(newFormat.firstChild);
|
|
6499
6935
|
core.setRange(temp, 0, temp, 0);
|
|
6936
|
+
break;
|
|
6937
|
+
} else if (options.lineAttrReset && formatEl && !util.isListCell(formatEl)) {
|
|
6938
|
+
e.preventDefault();
|
|
6939
|
+
e.stopPropagation();
|
|
6940
|
+
|
|
6941
|
+
let newEl;
|
|
6942
|
+
if (!range.collapsed) {
|
|
6943
|
+
const isMultiLine = util.getFormatElement(range.startContainer, null) !== util.getFormatElement(range.endContainer, null);
|
|
6944
|
+
const r = core.removeNode();
|
|
6945
|
+
if (isMultiLine) {
|
|
6946
|
+
newEl = util.getFormatElement(r.container, null);
|
|
6947
|
+
|
|
6948
|
+
if (!r.prevContainer) {
|
|
6949
|
+
const newFormat = formatEl.cloneNode(false);
|
|
6950
|
+
newFormat.innerHTML = '<br>';
|
|
6951
|
+
newEl.parentNode.insertBefore(newFormat, newEl);
|
|
6952
|
+
} else if (newEl !== formatEl && newEl.nextElementSibling === formatEl) {
|
|
6953
|
+
newEl = formatEl;
|
|
6954
|
+
}
|
|
6955
|
+
} else {
|
|
6956
|
+
newEl = util.splitElement(r.container, r.offset, 0);
|
|
6957
|
+
}
|
|
6958
|
+
} else {
|
|
6959
|
+
if (util.onlyZeroWidthSpace(formatEl)) newEl = core.appendFormatTag(formatEl, formatEl.cloneNode(false));
|
|
6960
|
+
else newEl = util.splitElement(range.endContainer, range.endOffset, 0);
|
|
6961
|
+
}
|
|
6962
|
+
|
|
6963
|
+
const resetAttr = options.lineAttrReset === '*' ? null : options.lineAttrReset;
|
|
6964
|
+
const attrs = newEl.attributes;
|
|
6965
|
+
let i = 0;
|
|
6966
|
+
while (attrs[i]) {
|
|
6967
|
+
if (resetAttr && resetAttr.test(attrs[i].name)) {
|
|
6968
|
+
i++;
|
|
6969
|
+
continue;
|
|
6970
|
+
}
|
|
6971
|
+
newEl.removeAttribute(attrs[i].name);
|
|
6972
|
+
}
|
|
6973
|
+
core.setRange(newEl.firstChild, 0, newEl.firstChild, 0);
|
|
6974
|
+
|
|
6500
6975
|
break;
|
|
6501
6976
|
}
|
|
6502
6977
|
|
|
@@ -6742,7 +7217,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
6742
7217
|
onFocus_wysiwyg: function (e) {
|
|
6743
7218
|
if (core._antiBlur) return;
|
|
6744
7219
|
core.hasFocus = true;
|
|
6745
|
-
event._applyTagEffects
|
|
7220
|
+
_w.setTimeout(event._applyTagEffects);
|
|
6746
7221
|
|
|
6747
7222
|
if (core._isInline) event._showToolbarInline();
|
|
6748
7223
|
|
|
@@ -6772,7 +7247,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
6772
7247
|
core.submenuOff();
|
|
6773
7248
|
core.controllersOff();
|
|
6774
7249
|
|
|
6775
|
-
const prevHeight = util.getNumber(context.element.wysiwygFrame.style.height, 0);
|
|
6776
7250
|
core._variable.resizeClientY = e.clientY;
|
|
6777
7251
|
context.element.resizeBackground.style.display = 'block';
|
|
6778
7252
|
|
|
@@ -6780,7 +7254,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
6780
7254
|
context.element.resizeBackground.style.display = 'none';
|
|
6781
7255
|
_d.removeEventListener('mousemove', event._resize_editor);
|
|
6782
7256
|
_d.removeEventListener('mouseup', closureFunc);
|
|
6783
|
-
if (typeof functions.onResizeEditor === 'function') functions.onResizeEditor(util.getNumber(context.element.wysiwygFrame.style.height, 0), prevHeight, core);
|
|
6784
7257
|
}
|
|
6785
7258
|
|
|
6786
7259
|
_d.addEventListener('mousemove', event._resize_editor);
|
|
@@ -6789,35 +7262,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
6789
7262
|
|
|
6790
7263
|
_resize_editor: function (e) {
|
|
6791
7264
|
const resizeInterval = context.element.editorArea.offsetHeight + (e.clientY - core._variable.resizeClientY);
|
|
6792
|
-
|
|
7265
|
+
const h = (resizeInterval < core._variable.minResizingSize ? core._variable.minResizingSize : resizeInterval);
|
|
7266
|
+
context.element.wysiwygFrame.style.height = context.element.code.style.height = h + 'px';
|
|
6793
7267
|
core._variable.resizeClientY = e.clientY;
|
|
7268
|
+
if (util.isIE) core.__callResizeFunction(h, null);
|
|
6794
7269
|
},
|
|
6795
7270
|
|
|
6796
7271
|
onResize_window: function () {
|
|
6797
|
-
core.
|
|
6798
|
-
|
|
6799
|
-
const responsiveSize = event._responsiveButtonSize;
|
|
6800
|
-
if (responsiveSize) {
|
|
6801
|
-
let w = 0;
|
|
6802
|
-
if ((core._isBalloon || core._isInline) && options.toolbarWidth === 'auto') {
|
|
6803
|
-
w = context.element.topArea.offsetWidth;
|
|
6804
|
-
} else {
|
|
6805
|
-
w = context.element.toolbar.offsetWidth;
|
|
6806
|
-
}
|
|
6807
|
-
|
|
6808
|
-
let responsiveWidth = 'default';
|
|
6809
|
-
for (let i = 1, len = responsiveSize.length; i < len; i++) {
|
|
6810
|
-
if (w < responsiveSize[i]) {
|
|
6811
|
-
responsiveWidth = responsiveSize[i] + '';
|
|
6812
|
-
break;
|
|
6813
|
-
}
|
|
6814
|
-
}
|
|
6815
|
-
|
|
6816
|
-
if (event._responsiveCurrentSize !== responsiveWidth) {
|
|
6817
|
-
event._responsiveCurrentSize = responsiveWidth;
|
|
6818
|
-
functions.setToolbarButtons(event._responsiveButtons[responsiveWidth]);
|
|
6819
|
-
}
|
|
6820
|
-
}
|
|
7272
|
+
if (util.isIE) core.resetResponsiveToolbar();
|
|
6821
7273
|
|
|
6822
7274
|
if (context.element.toolbar.offsetWidth === 0) return;
|
|
6823
7275
|
|
|
@@ -6918,6 +7370,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
6918
7370
|
},
|
|
6919
7371
|
|
|
6920
7372
|
_codeViewAutoHeight: function () {
|
|
7373
|
+
if (core._variable.isFullScreen) return;
|
|
6921
7374
|
context.element.code.style.height = context.element.code.scrollHeight + 'px';
|
|
6922
7375
|
},
|
|
6923
7376
|
|
|
@@ -6987,6 +7440,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
6987
7440
|
}
|
|
6988
7441
|
},
|
|
6989
7442
|
|
|
7443
|
+
onSave_wysiwyg: function (content) {
|
|
7444
|
+
// user event
|
|
7445
|
+
if (typeof functions.onSave === 'function') {
|
|
7446
|
+
functions.onSave(content, core);
|
|
7447
|
+
return;
|
|
7448
|
+
}
|
|
7449
|
+
},
|
|
7450
|
+
|
|
6990
7451
|
onCut_wysiwyg: function (e) {
|
|
6991
7452
|
const clipboardData = util.isIE ? _w.clipboardData : e.clipboardData;
|
|
6992
7453
|
|
|
@@ -7088,7 +7549,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7088
7549
|
} else {
|
|
7089
7550
|
cleanData = (plainText === cleanData ? plainText : cleanData).replace(/\n/g, '<br>');
|
|
7090
7551
|
}
|
|
7091
|
-
cleanData = core.cleanHTML(cleanData, core.pasteTagsWhitelistRegExp);
|
|
7552
|
+
cleanData = core.cleanHTML(cleanData, core.pasteTagsWhitelistRegExp, core.pasteTagsBlacklistRegExp);
|
|
7092
7553
|
} else {
|
|
7093
7554
|
cleanData = util._HTMLConvertor(plainText).replace(/\n/g, '<br>');
|
|
7094
7555
|
}
|
|
@@ -7121,11 +7582,39 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7121
7582
|
}
|
|
7122
7583
|
|
|
7123
7584
|
if (cleanData) {
|
|
7585
|
+
if (util.isListCell(util.getFormatElement(core.getSelectionNode(), null))) {
|
|
7586
|
+
const dom = (_d.createRange().createContextualFragment(cleanData));
|
|
7587
|
+
if (dom.childNodes[0].nodeType === 1) {
|
|
7588
|
+
cleanData = event._convertListCell(dom);
|
|
7589
|
+
}
|
|
7590
|
+
}
|
|
7124
7591
|
functions.insertHTML(cleanData, true, false);
|
|
7125
7592
|
return false;
|
|
7126
7593
|
}
|
|
7127
7594
|
},
|
|
7128
7595
|
|
|
7596
|
+
_convertListCell: function (dom) {
|
|
7597
|
+
const domTree = dom.childNodes;
|
|
7598
|
+
let html = '';
|
|
7599
|
+
|
|
7600
|
+
for (let i = 0, len = domTree.length, node; i < len; i++) {
|
|
7601
|
+
node = domTree[i];
|
|
7602
|
+
if (node.nodeType === 1) {
|
|
7603
|
+
if (util.isFormatElement(node)) {
|
|
7604
|
+
html += '<li>' +(node.innerHTML.trim() || '<br>') + '</li>';
|
|
7605
|
+
} else if (util.isRangeFormatElement(node) && !util.isTable(node)) {
|
|
7606
|
+
html += event._convertListCell(node);
|
|
7607
|
+
} else {
|
|
7608
|
+
html += '<li>' + node.outerHTML + '</li>';
|
|
7609
|
+
}
|
|
7610
|
+
} else {
|
|
7611
|
+
html += '<li>' + (node.textContent || '<br>') + '</li>';
|
|
7612
|
+
}
|
|
7613
|
+
}
|
|
7614
|
+
|
|
7615
|
+
return html;
|
|
7616
|
+
},
|
|
7617
|
+
|
|
7129
7618
|
onMouseMove_wysiwyg: function (e) {
|
|
7130
7619
|
if (core.isDisabled || core.isReadOnly) return false;
|
|
7131
7620
|
const component = util.getParentElement(e.target, util.isComponent);
|
|
@@ -7196,8 +7685,15 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7196
7685
|
core.history.push(false);
|
|
7197
7686
|
},
|
|
7198
7687
|
|
|
7688
|
+
_resizeObserver: null,
|
|
7689
|
+
_toolbarObserver: null,
|
|
7199
7690
|
_addEvent: function () {
|
|
7200
7691
|
const eventWysiwyg = options.iframe ? core._ww : context.element.wysiwyg;
|
|
7692
|
+
if (!util.isIE) {
|
|
7693
|
+
this._resizeObserver = new _w.ResizeObserver(function(entries) {
|
|
7694
|
+
core.__callResizeFunction(-1, entries[0]);
|
|
7695
|
+
});
|
|
7696
|
+
}
|
|
7201
7697
|
|
|
7202
7698
|
/** toolbar event */
|
|
7203
7699
|
context.element.toolbar.addEventListener('mousedown', event._buttonsEventHandler, false);
|
|
@@ -7239,18 +7735,20 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7239
7735
|
|
|
7240
7736
|
/** resizingBar */
|
|
7241
7737
|
if (context.element.resizingBar) {
|
|
7242
|
-
if (/\d+/.test(options.height)) {
|
|
7738
|
+
if (/\d+/.test(options.height) && options.resizeEnable) {
|
|
7243
7739
|
context.element.resizingBar.addEventListener('mousedown', event.onMouseDown_resizingBar, false);
|
|
7244
7740
|
} else {
|
|
7245
7741
|
util.addClass(context.element.resizingBar, 'se-resizing-none');
|
|
7246
7742
|
}
|
|
7247
7743
|
}
|
|
7248
7744
|
|
|
7249
|
-
/**
|
|
7745
|
+
/** set response toolbar */
|
|
7250
7746
|
event._setResponsiveToolbar();
|
|
7251
|
-
_w.removeEventListener('resize', event.onResize_window);
|
|
7252
|
-
_w.removeEventListener('scroll', event.onScroll_window);
|
|
7253
7747
|
|
|
7748
|
+
/** responsive toolbar observer */
|
|
7749
|
+
if (!util.isIE) this._toolbarObserver = new _w.ResizeObserver(core.resetResponsiveToolbar);
|
|
7750
|
+
|
|
7751
|
+
/** window event */
|
|
7254
7752
|
_w.addEventListener('resize', event.onResize_window, false);
|
|
7255
7753
|
if (options.stickyToolbar > -1) {
|
|
7256
7754
|
_w.addEventListener('scroll', event.onScroll_window, false);
|
|
@@ -7283,7 +7781,6 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7283
7781
|
event._lineBreakerBind = null;
|
|
7284
7782
|
|
|
7285
7783
|
eventWysiwyg.removeEventListener('touchstart', event.onMouseDown_wysiwyg, {passive: true, useCapture: false});
|
|
7286
|
-
|
|
7287
7784
|
eventWysiwyg.removeEventListener('focus', event.onFocus_wysiwyg);
|
|
7288
7785
|
eventWysiwyg.removeEventListener('blur', event.onBlur_wysiwyg);
|
|
7289
7786
|
|
|
@@ -7295,6 +7792,16 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7295
7792
|
context.element.resizingBar.removeEventListener('mousedown', event.onMouseDown_resizingBar);
|
|
7296
7793
|
}
|
|
7297
7794
|
|
|
7795
|
+
if (event._resizeObserver) {
|
|
7796
|
+
event._resizeObserver.unobserve(context.element.wysiwygFrame);
|
|
7797
|
+
event._resizeObserver = null;
|
|
7798
|
+
}
|
|
7799
|
+
|
|
7800
|
+
if (event._toolbarObserver) {
|
|
7801
|
+
event._toolbarObserver.unobserve(context.element._toolbarShadow);
|
|
7802
|
+
event._toolbarObserver = null;
|
|
7803
|
+
}
|
|
7804
|
+
|
|
7298
7805
|
_w.removeEventListener('resize', event.onResize_window);
|
|
7299
7806
|
_w.removeEventListener('scroll', event.onScroll_window);
|
|
7300
7807
|
},
|
|
@@ -7351,6 +7858,13 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7351
7858
|
*/
|
|
7352
7859
|
onChange: null,
|
|
7353
7860
|
|
|
7861
|
+
/**
|
|
7862
|
+
* @description Event functions
|
|
7863
|
+
* @param {String} contents Current contents
|
|
7864
|
+
* @param {Object} core Core object
|
|
7865
|
+
*/
|
|
7866
|
+
onSave: null,
|
|
7867
|
+
|
|
7354
7868
|
/**
|
|
7355
7869
|
* @description Event functions (drop, paste)
|
|
7356
7870
|
* When false is returned, the default behavior is stopped.
|
|
@@ -7569,6 +8083,14 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7569
8083
|
*/
|
|
7570
8084
|
onResizeEditor: null,
|
|
7571
8085
|
|
|
8086
|
+
/**
|
|
8087
|
+
* @description Called after the "setToolbarButtons" invocation.
|
|
8088
|
+
* Can be used to tweak buttons properties (useful for custom buttons)
|
|
8089
|
+
* @param {Array} buttonList Button list
|
|
8090
|
+
* @param {Object} core Core object
|
|
8091
|
+
*/
|
|
8092
|
+
onSetToolbarButtons: null,
|
|
8093
|
+
|
|
7572
8094
|
/**
|
|
7573
8095
|
* @description Reset the buttons on the toolbar. (Editor is not reloaded)
|
|
7574
8096
|
* You cannot set a new plugin for the button.
|
|
@@ -7577,10 +8099,10 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7577
8099
|
setToolbarButtons: function (buttonList) {
|
|
7578
8100
|
core.submenuOff();
|
|
7579
8101
|
core.containerOff();
|
|
8102
|
+
core.moreLayerOff();
|
|
7580
8103
|
|
|
7581
8104
|
const newToolbar = _Constructor._createToolBar(_d, buttonList, core.plugins, options);
|
|
7582
8105
|
_responsiveButtons = newToolbar.responsiveButtons;
|
|
7583
|
-
core._moreLayerActiveButton = null;
|
|
7584
8106
|
event._setResponsiveToolbar();
|
|
7585
8107
|
|
|
7586
8108
|
context.element.toolbar.replaceChild(newToolbar._buttonTray, context.element._buttonTray);
|
|
@@ -7589,32 +8111,15 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7589
8111
|
context.element = newContext.element;
|
|
7590
8112
|
context.tool = newContext.tool;
|
|
7591
8113
|
if (options.iframe) context.element.wysiwyg = core._wd.body;
|
|
8114
|
+
|
|
8115
|
+
core.recoverButtonStates();
|
|
8116
|
+
|
|
7592
8117
|
core._cachingButtons();
|
|
7593
8118
|
core.history._resetCachingButton();
|
|
7594
8119
|
|
|
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
8120
|
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');
|
|
8121
|
+
if (core.isReadOnly) util.setDisabledButtons(true, core.resizingDisabledButtons);
|
|
8122
|
+
if (typeof functions.onSetToolbarButtons === 'function') functions.onSetToolbarButtons(newToolbar._buttonTray.querySelectorAll('button'), core);
|
|
7618
8123
|
},
|
|
7619
8124
|
|
|
7620
8125
|
/**
|
|
@@ -7650,7 +8155,7 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7650
8155
|
const _initHTML = el.wysiwyg.innerHTML;
|
|
7651
8156
|
|
|
7652
8157
|
// set option
|
|
7653
|
-
const cons = _Constructor._setOptions(mergeOptions, context, options);
|
|
8158
|
+
const cons = _Constructor._setOptions(mergeOptions, context, options);
|
|
7654
8159
|
|
|
7655
8160
|
if (cons.callButtons) {
|
|
7656
8161
|
pluginCallButtons = cons.callButtons;
|
|
@@ -7726,10 +8231,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7726
8231
|
},
|
|
7727
8232
|
|
|
7728
8233
|
/**
|
|
7729
|
-
* @description Copying the contents of the editor to the original textarea
|
|
8234
|
+
* @description Copying the contents of the editor to the original textarea and execute onSave callback
|
|
7730
8235
|
*/
|
|
7731
8236
|
save: function () {
|
|
7732
|
-
|
|
8237
|
+
const contents = core.getContents(false);
|
|
8238
|
+
context.element.originElement.value = contents;
|
|
8239
|
+
event.onSave_wysiwyg(contents, core);
|
|
7733
8240
|
},
|
|
7734
8241
|
|
|
7735
8242
|
/**
|
|
@@ -7822,8 +8329,10 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7822
8329
|
* @param {Boolean} rangeSelection If true, range select the inserted node.
|
|
7823
8330
|
*/
|
|
7824
8331
|
insertHTML: function (html, notCleaningData, checkCharCount, rangeSelection) {
|
|
8332
|
+
if (!context.element.wysiwygFrame.contains(core.getSelection().focusNode)) core.focus();
|
|
8333
|
+
|
|
7825
8334
|
if (typeof html === 'string') {
|
|
7826
|
-
if (!notCleaningData) html = core.cleanHTML(html, null);
|
|
8335
|
+
if (!notCleaningData) html = core.cleanHTML(html, null, null);
|
|
7827
8336
|
try {
|
|
7828
8337
|
const dom = _d.createRange().createContextualFragment(html);
|
|
7829
8338
|
const domTree = dom.childNodes;
|
|
@@ -7900,10 +8409,12 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7900
8409
|
const wysiwyg = context.element.wysiwyg;
|
|
7901
8410
|
const children = temp.children;
|
|
7902
8411
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
7903
|
-
|
|
8412
|
+
if (children[i]) {
|
|
8413
|
+
wysiwyg.appendChild(children[i]);
|
|
8414
|
+
}
|
|
7904
8415
|
}
|
|
7905
8416
|
} else {
|
|
7906
|
-
core._setCodeView(core._getCodeView() + '\n' + core.convertHTMLForCodeView(convertValue));
|
|
8417
|
+
core._setCodeView(core._getCodeView() + '\n' + core.convertHTMLForCodeView(convertValue, false));
|
|
7907
8418
|
}
|
|
7908
8419
|
|
|
7909
8420
|
// history stack
|
|
@@ -7917,44 +8428,54 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
7917
8428
|
readOnly: function (value) {
|
|
7918
8429
|
core.isReadOnly = value;
|
|
7919
8430
|
|
|
8431
|
+
util.setDisabledButtons(!!value, core.resizingDisabledButtons);
|
|
8432
|
+
|
|
7920
8433
|
if (value) {
|
|
8434
|
+
/** off menus */
|
|
8435
|
+
core.controllersOff();
|
|
8436
|
+
if (core.submenuActiveButton && core.submenuActiveButton.disabled) core.submenuOff();
|
|
8437
|
+
if (core._moreLayerActiveButton && core._moreLayerActiveButton.disabled) core.moreLayerOff();
|
|
8438
|
+
if (core.containerActiveButton && core.containerActiveButton.disabled) core.containerOff();
|
|
8439
|
+
if (core.modalForm) core.plugins.dialog.close.call(core);
|
|
8440
|
+
|
|
7921
8441
|
context.element.code.setAttribute("readOnly", "true");
|
|
8442
|
+
util.addClass(context.element.wysiwygFrame, 'se-read-only');
|
|
7922
8443
|
} else {
|
|
7923
8444
|
context.element.code.removeAttribute("readOnly");
|
|
8445
|
+
util.removeClass(context.element.wysiwygFrame, 'se-read-only');
|
|
7924
8446
|
}
|
|
7925
8447
|
|
|
7926
|
-
util.setDisabledButtons(!!value, core.resizingDisabledButtons);
|
|
7927
8448
|
if (options.codeMirrorEditor) options.codeMirrorEditor.setOption('readOnly', !!value);
|
|
7928
8449
|
},
|
|
7929
8450
|
|
|
7930
8451
|
/**
|
|
7931
8452
|
* @description Disable the suneditor
|
|
7932
8453
|
*/
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
8454
|
+
disable: function () {
|
|
8455
|
+
this.toolbar.disable();
|
|
8456
|
+
this.wysiwyg.disable();
|
|
8457
|
+
},
|
|
7937
8458
|
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
8459
|
+
/**
|
|
8460
|
+
* @description Provided for backward compatibility and will be removed in 3.0.0 version
|
|
8461
|
+
*/
|
|
8462
|
+
disabled: function () {
|
|
8463
|
+
this.disable();
|
|
7943
8464
|
},
|
|
7944
8465
|
|
|
7945
8466
|
/**
|
|
7946
8467
|
* @description Enable the suneditor
|
|
7947
8468
|
*/
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
8469
|
+
enable: function () {
|
|
8470
|
+
this.toolbar.enable();
|
|
8471
|
+
this.wysiwyg.enable();
|
|
8472
|
+
},
|
|
7952
8473
|
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
8474
|
+
/**
|
|
8475
|
+
* @description Provided for backward compatibility and will be removed in 3.0.0 version
|
|
8476
|
+
*/
|
|
8477
|
+
enabled: function () {
|
|
8478
|
+
this.enable();
|
|
7958
8479
|
},
|
|
7959
8480
|
|
|
7960
8481
|
/**
|
|
@@ -8011,17 +8532,36 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
8011
8532
|
/**
|
|
8012
8533
|
* @description Disable the toolbar
|
|
8013
8534
|
*/
|
|
8014
|
-
|
|
8535
|
+
disable: function () {
|
|
8536
|
+
/** off menus */
|
|
8537
|
+
core.submenuOff();
|
|
8538
|
+
core.moreLayerOff();
|
|
8539
|
+
core.containerOff();
|
|
8540
|
+
|
|
8015
8541
|
context.tool.cover.style.display = 'block';
|
|
8016
8542
|
},
|
|
8017
8543
|
|
|
8544
|
+
/**
|
|
8545
|
+
* @description Provided for backward compatibility and will be removed in 3.0.0 version
|
|
8546
|
+
*/
|
|
8547
|
+
disabled: function () {
|
|
8548
|
+
this.disable();
|
|
8549
|
+
},
|
|
8550
|
+
|
|
8018
8551
|
/**
|
|
8019
8552
|
* @description Enable the toolbar
|
|
8020
8553
|
*/
|
|
8021
|
-
|
|
8554
|
+
enable: function () {
|
|
8022
8555
|
context.tool.cover.style.display = 'none';
|
|
8023
8556
|
},
|
|
8024
8557
|
|
|
8558
|
+
/**
|
|
8559
|
+
* @description Provided for backward compatibility and will be removed in 3.0.0 version
|
|
8560
|
+
*/
|
|
8561
|
+
enabled: function () {
|
|
8562
|
+
this.enable();
|
|
8563
|
+
},
|
|
8564
|
+
|
|
8025
8565
|
/**
|
|
8026
8566
|
* @description Show the toolbar
|
|
8027
8567
|
*/
|
|
@@ -8045,7 +8585,44 @@ export default function (context, pluginCallButtons, plugins, lang, options, _re
|
|
|
8045
8585
|
context.element._stickyDummy.style.display = 'none';
|
|
8046
8586
|
}
|
|
8047
8587
|
},
|
|
8048
|
-
}
|
|
8588
|
+
},
|
|
8589
|
+
|
|
8590
|
+
/**
|
|
8591
|
+
* @description Wysiwyg methods
|
|
8592
|
+
*/
|
|
8593
|
+
wysiwyg: {
|
|
8594
|
+
/**
|
|
8595
|
+
* @description Disable the wysiwyg area
|
|
8596
|
+
*/
|
|
8597
|
+
disable: function () {
|
|
8598
|
+
/** off menus */
|
|
8599
|
+
core.controllersOff();
|
|
8600
|
+
if (core.modalForm) core.plugins.dialog.close.call(core);
|
|
8601
|
+
|
|
8602
|
+
context.element.wysiwyg.setAttribute('contenteditable', false);
|
|
8603
|
+
core.isDisabled = true;
|
|
8604
|
+
|
|
8605
|
+
if (options.codeMirrorEditor) {
|
|
8606
|
+
options.codeMirrorEditor.setOption('readOnly', true);
|
|
8607
|
+
} else {
|
|
8608
|
+
context.element.code.setAttribute('disabled', 'disabled');
|
|
8609
|
+
}
|
|
8610
|
+
},
|
|
8611
|
+
|
|
8612
|
+
/**
|
|
8613
|
+
* @description Enable the wysiwyg area
|
|
8614
|
+
*/
|
|
8615
|
+
enable: function () {
|
|
8616
|
+
context.element.wysiwyg.setAttribute('contenteditable', true);
|
|
8617
|
+
core.isDisabled = false;
|
|
8618
|
+
|
|
8619
|
+
if (options.codeMirrorEditor) {
|
|
8620
|
+
options.codeMirrorEditor.setOption('readOnly', false);
|
|
8621
|
+
} else {
|
|
8622
|
+
context.element.code.removeAttribute('disabled');
|
|
8623
|
+
}
|
|
8624
|
+
},
|
|
8625
|
+
}
|
|
8049
8626
|
};
|
|
8050
8627
|
|
|
8051
8628
|
/************ Core init ************/
|