suneditor 2.41.3 → 2.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -24
- package/dist/css/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +2 -2
- package/package.json +1 -1
- package/src/assets/css/suneditor.css +25 -6
- package/src/assets/defaultIcons.js +2 -0
- package/src/lang/Lang.d.ts +3 -1
- package/src/lang/ckb.js +2 -0
- package/src/lang/da.js +2 -0
- package/src/lang/de.js +2 -0
- package/src/lang/en.js +2 -0
- package/src/lang/es.js +2 -0
- package/src/lang/fr.js +10 -8
- package/src/lang/he.js +2 -0
- package/src/lang/it.js +2 -0
- package/src/lang/ja.js +2 -0
- package/src/lang/ko.js +2 -0
- package/src/lang/lv.js +2 -0
- package/src/lang/nl.js +2 -0
- package/src/lang/pl.js +2 -0
- package/src/lang/pt_br.js +2 -0
- package/src/lang/ro.js +2 -0
- package/src/lang/ru.js +2 -0
- package/src/lang/se.js +2 -0
- package/src/lang/ua.js +2 -0
- package/src/lang/zh_cn.js +2 -0
- package/src/lib/constructor.js +50 -11
- package/src/lib/context.js +4 -1
- package/src/lib/core.d.ts +86 -11
- package/src/lib/core.js +555 -147
- package/src/lib/util.d.ts +24 -1
- package/src/lib/util.js +64 -15
- package/src/options.d.ts +63 -8
- package/src/plugins/dialog/audio.js +5 -5
- package/src/plugins/dialog/image.js +30 -20
- package/src/plugins/dialog/video.js +13 -13
- package/src/plugins/fileBrowser/imageGallery.js +2 -3
- package/src/plugins/modules/_anchor.js +6 -4
- package/src/plugins/modules/component.d.ts +1 -1
- package/src/plugins/modules/fileBrowser.js +6 -1
- package/src/plugins/modules/fileManager.js +1 -3
- package/src/plugins/modules/resizing.js +11 -6
- package/src/plugins/submenu/align.js +32 -27
- package/src/plugins/submenu/font.js +1 -1
- package/src/plugins/submenu/horizontalRule.js +19 -25
|
@@ -121,12 +121,13 @@ export default {
|
|
|
121
121
|
on: function (contextAnchor, update) {
|
|
122
122
|
if (!update) {
|
|
123
123
|
this.plugins.anchor.init.call(this, contextAnchor);
|
|
124
|
-
contextAnchor.anchorText.value = this.getSelection().toString();
|
|
124
|
+
contextAnchor.anchorText.value = this.getSelection().toString().trim();
|
|
125
|
+
contextAnchor.newWindowCheck.checked = this.options.linkTargetNewWindow;
|
|
125
126
|
} else if (contextAnchor.linkAnchor) {
|
|
126
127
|
this.context.dialog.updateModal = true;
|
|
127
|
-
const href = contextAnchor.linkAnchor.href;
|
|
128
|
+
const href = this.options.linkNoPrefix ? contextAnchor.linkAnchor.href.replace(contextAnchor.linkAnchor.origin + '/', '') : contextAnchor.linkAnchor.href;
|
|
128
129
|
contextAnchor.linkValue = contextAnchor.preview.textContent = contextAnchor.urlInput.value = /\#.+$/.test(href) ? href.substr(href.lastIndexOf('#')) : href;
|
|
129
|
-
contextAnchor.anchorText.value = contextAnchor.linkAnchor.textContent
|
|
130
|
+
contextAnchor.anchorText.value = contextAnchor.linkAnchor.textContent || contextAnchor.linkAnchor.getAttribute('alt');
|
|
130
131
|
contextAnchor.newWindowCheck.checked = (/_blank/i.test(contextAnchor.linkAnchor.target) ? true : false);
|
|
131
132
|
contextAnchor.downloadCheck.checked = contextAnchor.linkAnchor.download;
|
|
132
133
|
}
|
|
@@ -293,9 +294,10 @@ export default {
|
|
|
293
294
|
setLinkPreview: function (context, value) {
|
|
294
295
|
const preview = context.preview;
|
|
295
296
|
const protocol = this.options.linkProtocol;
|
|
297
|
+
const noPrefix = this.options.linkNoPrefix;
|
|
296
298
|
const reservedProtocol = /^(mailto\:|tel\:|sms\:|https*\:\/\/|#)/.test(value);
|
|
297
299
|
const sameProtocol = !protocol ? false : this._w.RegExp('^' + value.substr(0, protocol.length)).test(protocol);
|
|
298
|
-
context.linkValue = preview.textContent = !value ? '' : (protocol && !reservedProtocol && !sameProtocol) ? protocol + value : reservedProtocol ? value : /^www\./.test(value) ? 'http://' + value : this.context.anchor.host + (/^\//.test(value) ? '' : '/') + value;
|
|
300
|
+
context.linkValue = preview.textContent = !value ? '' : noPrefix ? value : (protocol && !reservedProtocol && !sameProtocol) ? protocol + value : reservedProtocol ? value : /^www\./.test(value) ? 'http://' + value : this.context.anchor.host + (/^\//.test(value) ? '' : '/') + value;
|
|
299
301
|
|
|
300
302
|
if (value.indexOf('#') === 0) {
|
|
301
303
|
context.bookmark.style.display = 'block';
|
|
@@ -229,7 +229,12 @@
|
|
|
229
229
|
this.plugins.fileBrowser._xmlHttp = null;
|
|
230
230
|
if (xmlHttp.status === 200) {
|
|
231
231
|
try {
|
|
232
|
-
|
|
232
|
+
const res = JSON.parse(xmlHttp.responseText);
|
|
233
|
+
if (res.result.length > 0) {
|
|
234
|
+
this.plugins.fileBrowser._drawListItem.call(this, res.result, true);
|
|
235
|
+
} else if (res.nullMessage) {
|
|
236
|
+
this.context.fileBrowser.list.innerHTML = res.nullMessage;
|
|
237
|
+
}
|
|
233
238
|
} catch (e) {
|
|
234
239
|
throw Error('[SUNEDITOR.fileBrowser.drawList.fail] cause : "' + e.message + '"');
|
|
235
240
|
} finally {
|
|
@@ -28,8 +28,6 @@
|
|
|
28
28
|
_checkMediaComponent: function (tag) {
|
|
29
29
|
if (/IMG/i.test(tag)) {
|
|
30
30
|
return !/FIGURE/i.test(tag.parentElement.nodeName) || !/FIGURE/i.test(tag.parentElement.parentElement.nodeName);
|
|
31
|
-
} else if (/VIDEO/i.test(tag)) {
|
|
32
|
-
return !/FIGURE/i.test(tag.parentElement.nodeName);
|
|
33
31
|
}
|
|
34
32
|
return true;
|
|
35
33
|
},
|
|
@@ -98,7 +96,7 @@
|
|
|
98
96
|
checkInfo: function (pluginName, tagNames, uploadEventHandler, modifyHandler, resizing) {
|
|
99
97
|
let tags = [];
|
|
100
98
|
for (let i = 0, len = tagNames.length; i < len; i++) {
|
|
101
|
-
tags = tags.concat([].slice.call(this.context.element.wysiwyg.
|
|
99
|
+
tags = tags.concat([].slice.call(this.context.element.wysiwyg.querySelectorAll(tagNames[i] + ':not([data-se-embed="true"])')));
|
|
102
100
|
}
|
|
103
101
|
|
|
104
102
|
const fileManagerPlugin = this.plugins.fileManager;
|
|
@@ -437,11 +437,16 @@
|
|
|
437
437
|
}
|
|
438
438
|
|
|
439
439
|
// align icon
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
440
|
+
if (contextPlugin._alignHide) {
|
|
441
|
+
contextResizing.alignButton.style.display = 'none';
|
|
442
|
+
} else {
|
|
443
|
+
contextResizing.alignButton.style.display = '';
|
|
444
|
+
const alignList = contextResizing.alignMenuList;
|
|
445
|
+
this.util.changeElement(contextResizing.alignButton.firstElementChild, contextResizing.alignIcons[align]);
|
|
446
|
+
for (let i = 0, len = alignList.length; i < len; i++) {
|
|
447
|
+
if (alignList[i].getAttribute('data-value') === align) this.util.addClass(alignList[i], 'on');
|
|
448
|
+
else this.util.removeClass(alignList[i], 'on');
|
|
449
|
+
}
|
|
445
450
|
}
|
|
446
451
|
|
|
447
452
|
// percentage active
|
|
@@ -478,7 +483,7 @@
|
|
|
478
483
|
}
|
|
479
484
|
|
|
480
485
|
this.setControllerPosition(contextResizing.resizeButton, resizeContainer, 'bottom', addOffset);
|
|
481
|
-
this.controllersOn(resizeContainer, contextResizing.resizeButton, this.util.setDisabledButtons.bind(this, false, this.resizingDisabledButtons), targetElement, plugin);
|
|
486
|
+
this.controllersOn(resizeContainer, contextResizing.resizeButton, this.util.setDisabledButtons.bind(this.util, false, this.resizingDisabledButtons), targetElement, plugin);
|
|
482
487
|
this.util.setDisabledButtons(true, this.resizingDisabledButtons);
|
|
483
488
|
|
|
484
489
|
contextResizing._resize_w = w;
|
|
@@ -15,9 +15,10 @@ export default {
|
|
|
15
15
|
const context = core.context;
|
|
16
16
|
context.align = {
|
|
17
17
|
targetButton: targetElement,
|
|
18
|
+
_itemMenu: null,
|
|
18
19
|
_alignList: null,
|
|
19
20
|
currentAlign: '',
|
|
20
|
-
defaultDir: core.options.rtl ? 'right' : 'left',
|
|
21
|
+
defaultDir: core.options.rtl ? 'right' : 'left',
|
|
21
22
|
icons: {
|
|
22
23
|
justify: icons.align_justify,
|
|
23
24
|
left: icons.align_left,
|
|
@@ -28,7 +29,7 @@ export default {
|
|
|
28
29
|
|
|
29
30
|
/** set submenu */
|
|
30
31
|
let listDiv = this.setSubmenu(core);
|
|
31
|
-
let listUl = listDiv.querySelector('ul');
|
|
32
|
+
let listUl = context.align._itemMenu = listDiv.querySelector('ul');
|
|
32
33
|
|
|
33
34
|
/** add event listeners */
|
|
34
35
|
listUl.addEventListener('click', this.pickup.bind(core));
|
|
@@ -45,36 +46,24 @@ export default {
|
|
|
45
46
|
const lang = core.lang;
|
|
46
47
|
const icons = core.icons;
|
|
47
48
|
const listDiv = core.util.createElement('DIV');
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
'
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
'</li>';
|
|
49
|
+
const alignItems = core.options.alignItems;
|
|
50
|
+
|
|
51
|
+
let html = '';
|
|
52
|
+
for (let i = 0, item, text; i < alignItems.length; i++) {
|
|
53
|
+
item = alignItems[i];
|
|
54
|
+
text = lang.toolbar['align' + item.charAt(0).toUpperCase() + item.slice(1)];
|
|
55
|
+
html += '<li>' +
|
|
56
|
+
'<button type="button" class="se-btn-list se-btn-align" data-value="' + item + '" title="' + text + '">' +
|
|
57
|
+
'<span class="se-list-icon">' + icons['align_' + item] + '</span>' + text +
|
|
58
|
+
'</button>' +
|
|
59
|
+
'</li>';
|
|
60
|
+
}
|
|
61
61
|
|
|
62
62
|
listDiv.className = 'se-submenu se-list-layer se-list-align';
|
|
63
63
|
listDiv.innerHTML = '' +
|
|
64
64
|
'<div class="se-list-inner">' +
|
|
65
65
|
'<ul class="se-list-basic">' +
|
|
66
|
-
|
|
67
|
-
'<li>' +
|
|
68
|
-
'<button type="button" class="se-btn-list se-btn-align" data-command="justifycenter" data-value="center" title="' + lang.toolbar.alignCenter + '">' +
|
|
69
|
-
'<span class="se-list-icon">' + icons.align_center + '</span>' + lang.toolbar.alignCenter +
|
|
70
|
-
'</button>' +
|
|
71
|
-
'</li>' +
|
|
72
|
-
(leftDir? rightMenu : leftMenu) +
|
|
73
|
-
'<li>' +
|
|
74
|
-
'<button type="button" class="se-btn-list se-btn-align" data-command="justifyfull" data-value="justify" title="' + lang.toolbar.alignJustify + '">' +
|
|
75
|
-
'<span class="se-list-icon">' + icons.align_justify + '</span>' + lang.toolbar.alignJustify +
|
|
76
|
-
'</button>' +
|
|
77
|
-
'</li>' +
|
|
66
|
+
html +
|
|
78
67
|
'</ul>' +
|
|
79
68
|
'</div>';
|
|
80
69
|
|
|
@@ -125,6 +114,22 @@ export default {
|
|
|
125
114
|
}
|
|
126
115
|
},
|
|
127
116
|
|
|
117
|
+
exchangeDir: function () {
|
|
118
|
+
const dir = this.options.rtl ? 'right' : 'left';
|
|
119
|
+
if (!this.context.align || this.context.align.defaultDir === dir) return;
|
|
120
|
+
|
|
121
|
+
this.context.align.defaultDir = dir;
|
|
122
|
+
let menu = this.context.align._itemMenu;
|
|
123
|
+
let leftBtn = menu.querySelector('[data-value="left"]');
|
|
124
|
+
let rightBtn = menu.querySelector('[data-value="right"]');
|
|
125
|
+
if (leftBtn && rightBtn) {
|
|
126
|
+
const lp = leftBtn.parentElement;
|
|
127
|
+
const rp = rightBtn.parentElement;
|
|
128
|
+
lp.appendChild(rightBtn);
|
|
129
|
+
rp.appendChild(leftBtn);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
|
|
128
133
|
pickup: function (e) {
|
|
129
134
|
e.preventDefault();
|
|
130
135
|
e.stopPropagation();
|
|
@@ -78,7 +78,7 @@ export default {
|
|
|
78
78
|
if (!element) {
|
|
79
79
|
const font = this.hasFocus ? this.wwComputedStyle.fontFamily : this.lang.toolbar.font;
|
|
80
80
|
this.util.changeTxt(target, font);
|
|
81
|
-
this.util.changeTxt(tooltip, this.hasFocus ? this.lang.toolbar.font + ' (' + font + ')' : font);
|
|
81
|
+
this.util.changeTxt(tooltip, this.hasFocus ? this.lang.toolbar.font + (font ? ' (' + font + ')' : '') : font);
|
|
82
82
|
} else if (element.style && element.style.fontFamily.length > 0) {
|
|
83
83
|
const selectFont = element.style.fontFamily.replace(/["']/g,'');
|
|
84
84
|
this.util.changeTxt(target, selectFont);
|
|
@@ -31,26 +31,22 @@ export default {
|
|
|
31
31
|
setSubmenu: function (core) {
|
|
32
32
|
const lang = core.lang;
|
|
33
33
|
const listDiv = core.util.createElement('DIV');
|
|
34
|
-
|
|
34
|
+
const items = core.options.hrItems || [{name: lang.toolbar.hr_solid, class: '__se__solid'}, {name: lang.toolbar.hr_dashed, class: '__se__dashed'}, {name: lang.toolbar.hr_dotted, class: '__se__dotted'}];
|
|
35
|
+
|
|
36
|
+
let list = '';
|
|
37
|
+
for (let i = 0, len = items.length; i < len; i++) {
|
|
38
|
+
list += '<li>' +
|
|
39
|
+
'<button type="button" class="se-btn-list btn_line" data-command="horizontalRule" data-value="' + items[i].class + '" title="' + items[i].name + '">' +
|
|
40
|
+
'<hr' + (items[i].class ? ' class="' + items[i].class + '"' : '') + (items[i].style ? ' style="' + items[i].style + '"' : '') + '/>' +
|
|
41
|
+
'</button>' +
|
|
42
|
+
'</li>';
|
|
43
|
+
}
|
|
44
|
+
|
|
35
45
|
listDiv.className = 'se-submenu se-list-layer se-list-line';
|
|
36
46
|
listDiv.innerHTML = '' +
|
|
37
47
|
'<div class="se-list-inner">' +
|
|
38
48
|
'<ul class="se-list-basic">' +
|
|
39
|
-
|
|
40
|
-
'<button type="button" class="se-btn-list btn_line" data-command="horizontalRule" data-value="solid" title="' + lang.toolbar.hr_solid + '">' +
|
|
41
|
-
'<hr style="border-width: 1px 0 0; border-style: solid none none; border-color: black; border-image: initial; height: 1px;" />' +
|
|
42
|
-
'</button>' +
|
|
43
|
-
'</li>' +
|
|
44
|
-
'<li>' +
|
|
45
|
-
'<button type="button" class="se-btn-list btn_line" data-command="horizontalRule" data-value="dotted" title="' + lang.toolbar.hr_dotted + '">' +
|
|
46
|
-
'<hr style="border-width: 1px 0 0; border-style: dotted none none; border-color: black; border-image: initial; height: 1px;" />' +
|
|
47
|
-
'</button>' +
|
|
48
|
-
'</li>' +
|
|
49
|
-
'<li>' +
|
|
50
|
-
'<button type="button" class="se-btn-list btn_line" data-command="horizontalRule" data-value="dashed" title="' + lang.toolbar.hr_dashed + '">' +
|
|
51
|
-
'<hr style="border-width: 1px 0 0; border-style: dashed none none; border-color: black; border-image: initial; height: 1px;" />' +
|
|
52
|
-
'</button>' +
|
|
53
|
-
'</li>' +
|
|
49
|
+
list +
|
|
54
50
|
'</ul>' +
|
|
55
51
|
'</div>';
|
|
56
52
|
|
|
@@ -74,11 +70,9 @@ export default {
|
|
|
74
70
|
return false;
|
|
75
71
|
},
|
|
76
72
|
|
|
77
|
-
appendHr: function (
|
|
78
|
-
const oHr = this.util.createElement('HR');
|
|
79
|
-
oHr.className = className;
|
|
73
|
+
appendHr: function (hrTemp) {
|
|
80
74
|
this.focus();
|
|
81
|
-
return this.insertComponent(
|
|
75
|
+
return this.insertComponent(hrTemp.cloneNode(false), false, true, false);
|
|
82
76
|
},
|
|
83
77
|
|
|
84
78
|
horizontalRulePick: function (e) {
|
|
@@ -86,16 +80,16 @@ export default {
|
|
|
86
80
|
e.stopPropagation();
|
|
87
81
|
|
|
88
82
|
let target = e.target;
|
|
89
|
-
let
|
|
83
|
+
let command = target.getAttribute('data-command');
|
|
90
84
|
|
|
91
|
-
while (!
|
|
92
|
-
value = target.getAttribute('data-value');
|
|
85
|
+
while (!command && !/UL/i.test(target.tagName)) {
|
|
93
86
|
target = target.parentNode;
|
|
87
|
+
command = target.getAttribute('data-command');
|
|
94
88
|
}
|
|
95
89
|
|
|
96
|
-
if (!
|
|
90
|
+
if (!command) return;
|
|
97
91
|
|
|
98
|
-
const oNode = this.plugins.horizontalRule.appendHr.call(this,
|
|
92
|
+
const oNode = this.plugins.horizontalRule.appendHr.call(this, target.firstElementChild);
|
|
99
93
|
if (oNode) {
|
|
100
94
|
this.setRange(oNode, 0, oNode, 0);
|
|
101
95
|
this.submenuOff();
|