suneditor 3.0.0-alpha.2 → 3.0.0-alpha.4
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 +1 -1
- package/dist/suneditor.min.css +1 -0
- package/dist/suneditor.min.js +1 -0
- package/package.json +4 -1
- package/src/assets/suneditor.css +10 -9
- package/src/core/base/eventHandlers/handler_ww_dragDrop.js +10 -5
- package/src/core/base/eventHandlers/handler_ww_key_input.js +28 -4
- package/src/core/base/eventManager.js +8 -2
- package/src/core/class/component.js +2 -2
- package/src/core/class/offset.js +32 -13
- package/src/core/class/selection.js +7 -5
- package/src/core/class/viewer.js +2 -2
- package/src/core/section/constructor.js +2 -5
- package/src/langs/en.js +11 -0
- package/src/langs/ko.js +48 -0
- package/src/modules/Controller.js +1 -1
- package/src/plugins/command/fileUpload.js +3 -3
- package/src/plugins/dropdown/table.js +4 -4
- package/src/plugins/modal/audio.js +5 -5
- package/src/plugins/modal/image.js +5 -5
- package/src/plugins/modal/video.js +5 -5
- /package/src/assets/{suneditor-content.css → suneditor-contents.css} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "suneditor",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.4",
|
|
4
4
|
"description": "Vanilla javascript based WYSIWYG web editor",
|
|
5
5
|
"author": "Yi JiHong",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"./src/assets/css/*.css"
|
|
10
10
|
],
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=14.0.0"
|
|
13
|
+
},
|
|
11
14
|
"scripts": {
|
|
12
15
|
"dev": "webpack-dev-server --config webpack/dev.js",
|
|
13
16
|
"start": "npm run dev",
|
package/src/assets/suneditor.css
CHANGED
|
@@ -480,6 +480,7 @@
|
|
|
480
480
|
/* default svg */
|
|
481
481
|
.sun-editor svg {
|
|
482
482
|
fill: currentColor;
|
|
483
|
+
vertical-align: baseline;
|
|
483
484
|
}
|
|
484
485
|
|
|
485
486
|
.sun-editor button > svg,
|
|
@@ -1148,8 +1149,8 @@
|
|
|
1148
1149
|
|
|
1149
1150
|
/* table resize */
|
|
1150
1151
|
/* table resize - ew */
|
|
1151
|
-
.sun-editor-editable table th:not(.se-selected-table-cell):hover::before,
|
|
1152
|
-
.sun-editor-editable table td:not(.se-selected-table-cell):hover::before {
|
|
1152
|
+
.sun-editor-editable[contenteditable='true'] table th:not(.se-selected-table-cell):hover::before,
|
|
1153
|
+
.sun-editor-editable[contenteditable='true'] table td:not(.se-selected-table-cell):hover::before {
|
|
1153
1154
|
content: '';
|
|
1154
1155
|
position: absolute;
|
|
1155
1156
|
top: 0;
|
|
@@ -1159,8 +1160,8 @@
|
|
|
1159
1160
|
background-color: transparent;
|
|
1160
1161
|
cursor: ew-resize;
|
|
1161
1162
|
}
|
|
1162
|
-
.sun-editor-editable table th:not(.se-selected-table-cell):hover::after,
|
|
1163
|
-
.sun-editor-editable table td:not(.se-selected-table-cell):hover::after {
|
|
1163
|
+
.sun-editor-editable[contenteditable='true'] table th:not(.se-selected-table-cell):hover::after,
|
|
1164
|
+
.sun-editor-editable[contenteditable='true'] table td:not(.se-selected-table-cell):hover::after {
|
|
1164
1165
|
content: '';
|
|
1165
1166
|
position: absolute;
|
|
1166
1167
|
top: 0;
|
|
@@ -2153,7 +2154,7 @@
|
|
|
2153
2154
|
outline: 2px solid #80bdff;
|
|
2154
2155
|
}
|
|
2155
2156
|
|
|
2156
|
-
.sun-editor-editable .se-component figure.se-figure-selected:not(.se-figure-over-selected)::after {
|
|
2157
|
+
.sun-editor-editable[contenteditable='true'] .se-component figure.se-figure-selected:not(.se-figure-over-selected)::after {
|
|
2157
2158
|
pointer-events: none;
|
|
2158
2159
|
}
|
|
2159
2160
|
|
|
@@ -2926,8 +2927,8 @@
|
|
|
2926
2927
|
|
|
2927
2928
|
/** --- selected class */
|
|
2928
2929
|
/* -- table */
|
|
2929
|
-
.sun-editor-editable table td.se-selected-table-cell::after,
|
|
2930
|
-
.sun-editor-editable table th.se-selected-table-cell::after {
|
|
2930
|
+
.sun-editor-editable[contenteditable='true'] table td.se-selected-table-cell::after,
|
|
2931
|
+
.sun-editor-editable[contenteditable='true'] table th.se-selected-table-cell::after {
|
|
2931
2932
|
position: absolute;
|
|
2932
2933
|
content: '';
|
|
2933
2934
|
background-color: #d0e3ff;
|
|
@@ -2939,8 +2940,8 @@
|
|
|
2939
2940
|
right: -1px;
|
|
2940
2941
|
top: -1px;
|
|
2941
2942
|
}
|
|
2942
|
-
.sun-editor-editable table td.se-selected-cell-focus,
|
|
2943
|
-
.sun-editor-editable table th.se-selected-cell-focus {
|
|
2943
|
+
.sun-editor-editable[contenteditable='true'] table td.se-selected-cell-focus,
|
|
2944
|
+
.sun-editor-editable[contenteditable='true'] table th.se-selected-cell-focus {
|
|
2944
2945
|
outline: 2px dashed #1275ff;
|
|
2945
2946
|
z-index: 1;
|
|
2946
2947
|
}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { domUtils } from '../../../helper';
|
|
2
2
|
import { _DragHandle } from '../../../modules';
|
|
3
3
|
|
|
4
|
-
export function OnDragOver_wysiwyg(dragCursor,
|
|
4
|
+
export function OnDragOver_wysiwyg(fc, dragCursor, _iframeTopArea, _innerToolbar, e) {
|
|
5
5
|
e.preventDefault();
|
|
6
6
|
|
|
7
7
|
const { sc, so, ec, eo } = this.selection.getEventLocationRange(e);
|
|
8
8
|
|
|
9
|
-
const cursorRange =
|
|
9
|
+
const cursorRange = fc.get('_wd').createRange();
|
|
10
10
|
cursorRange.setStart(sc, so);
|
|
11
11
|
cursorRange.setEnd(ec, eo);
|
|
12
12
|
|
|
13
13
|
const _offset = { y: 0, x: 0 };
|
|
14
|
-
if (
|
|
15
|
-
const iframeOffset = this.offset.getGlobal(
|
|
16
|
-
|
|
14
|
+
if (_iframeTopArea) {
|
|
15
|
+
const iframeOffset = this.offset.getGlobal(_iframeTopArea);
|
|
16
|
+
const toolbarH = _innerToolbar ? this.context.get('toolbar.main').offsetHeight : 0;
|
|
17
|
+
_offset.y = iframeOffset.top + toolbarH - this._w.scrollY;
|
|
17
18
|
_offset.x = iframeOffset.left - this._w.scrollX;
|
|
18
19
|
}
|
|
19
20
|
|
|
@@ -28,6 +29,10 @@ export function OnDragOver_wysiwyg(dragCursor, _iframe, e) {
|
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
|
|
32
|
+
export function OnDragEnd_wysiwyg(dragCursor) {
|
|
33
|
+
dragCursor.style.display = 'none';
|
|
34
|
+
}
|
|
35
|
+
|
|
31
36
|
export function OnDrop_wysiwyg(frameContext, dragCursor, e) {
|
|
32
37
|
try {
|
|
33
38
|
if (frameContext.get('isReadOnly')) {
|
|
@@ -317,6 +317,7 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
|
|
|
317
317
|
if (fileComponentInfo) {
|
|
318
318
|
e.preventDefault();
|
|
319
319
|
e.stopPropagation();
|
|
320
|
+
if (domUtils.isZeroWith(formatEl.textContent)) domUtils.removeItem(formatEl);
|
|
320
321
|
if (this.component.select(fileComponentInfo.target, fileComponentInfo.pluginName, false) === false) this.editor.blur();
|
|
321
322
|
break;
|
|
322
323
|
}
|
|
@@ -588,6 +589,9 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
|
|
|
588
589
|
} else {
|
|
589
590
|
this.selection.setRange(temp, 0, temp, 0);
|
|
590
591
|
}
|
|
592
|
+
|
|
593
|
+
// enter scroll
|
|
594
|
+
this.selection.scrollTo(range);
|
|
591
595
|
break;
|
|
592
596
|
} else if (rangeEl && formatEl && !domUtils.isTableCell(rangeEl) && !/^FIGCAPTION$/i.test(rangeEl.nodeName)) {
|
|
593
597
|
const rangeEnt = this.selection.getRange();
|
|
@@ -600,6 +604,9 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
|
|
|
600
604
|
newEl.appendChild(selectionNode.nextSibling);
|
|
601
605
|
|
|
602
606
|
this.selection.setRange(br, 1, br, 1);
|
|
607
|
+
|
|
608
|
+
// enter scroll
|
|
609
|
+
this.selection.scrollTo(range);
|
|
603
610
|
break;
|
|
604
611
|
}
|
|
605
612
|
|
|
@@ -675,6 +682,9 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
|
|
|
675
682
|
const newEl = this.format.addLine(brBlock, this.format.isLine(brBlock.nextElementSibling) && !this.format.isBlock(brBlock.nextElementSibling) ? brBlock.nextElementSibling : null);
|
|
676
683
|
domUtils.copyFormatAttributes(newEl, brBlock);
|
|
677
684
|
this.selection.setRange(newEl, 1, newEl, 1);
|
|
685
|
+
|
|
686
|
+
// enter scroll
|
|
687
|
+
this.selection.scrollTo(range);
|
|
678
688
|
break;
|
|
679
689
|
}
|
|
680
690
|
|
|
@@ -704,6 +714,9 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
|
|
|
704
714
|
}
|
|
705
715
|
|
|
706
716
|
this._onShortcutKey = true;
|
|
717
|
+
|
|
718
|
+
// enter scroll
|
|
719
|
+
this.selection.scrollTo(range);
|
|
707
720
|
break;
|
|
708
721
|
}
|
|
709
722
|
|
|
@@ -734,6 +747,8 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
|
|
|
734
747
|
this.selection.setRange(firstEl, 0, firstEl, 0);
|
|
735
748
|
}
|
|
736
749
|
|
|
750
|
+
// enter scroll
|
|
751
|
+
this.selection.scrollTo(range);
|
|
737
752
|
break;
|
|
738
753
|
}
|
|
739
754
|
|
|
@@ -756,6 +771,9 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
|
|
|
756
771
|
domUtils.copyTagAttributes(newEl, formatEl, this.options.get('lineAttrReset'));
|
|
757
772
|
this.selection.setRange(newEl, offset, newEl, offset);
|
|
758
773
|
}
|
|
774
|
+
|
|
775
|
+
// enter scroll
|
|
776
|
+
this.selection.scrollTo(range);
|
|
759
777
|
break;
|
|
760
778
|
}
|
|
761
779
|
|
|
@@ -797,16 +815,25 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
|
|
|
797
815
|
domUtils.copyTagAttributes(newEl, formatEl, this.options.get('lineAttrReset'));
|
|
798
816
|
this.selection.setRange(newEl, offset, newEl, offset);
|
|
799
817
|
|
|
818
|
+
// enter scroll
|
|
819
|
+
this.selection.scrollTo(range);
|
|
800
820
|
break;
|
|
801
821
|
}
|
|
802
822
|
}
|
|
803
823
|
|
|
804
|
-
if (selectRange)
|
|
824
|
+
if (selectRange) {
|
|
825
|
+
// enter scroll
|
|
826
|
+
this.selection.scrollTo(range);
|
|
827
|
+
break;
|
|
828
|
+
}
|
|
805
829
|
|
|
806
830
|
if (rangeEl && domUtils.getParentElement(rangeEl, 'FIGCAPTION') && domUtils.getParentElement(rangeEl, domUtils.isList)) {
|
|
807
831
|
this.__enterPrevent(e);
|
|
808
832
|
formatEl = this.format.addLine(formatEl, null);
|
|
809
833
|
this.selection.setRange(formatEl, 0, formatEl, 0);
|
|
834
|
+
|
|
835
|
+
// enter scroll
|
|
836
|
+
this.selection.scrollTo(range);
|
|
810
837
|
}
|
|
811
838
|
|
|
812
839
|
break;
|
|
@@ -829,9 +856,6 @@ export function OnKeyDown_wysiwyg(frameContext, e) {
|
|
|
829
856
|
this.selection.setRange(zeroWidth, 1, zeroWidth, 1);
|
|
830
857
|
}
|
|
831
858
|
|
|
832
|
-
// enter scroll
|
|
833
|
-
if (keyCode === 13) this.selection.scrollTo(range);
|
|
834
|
-
|
|
835
859
|
// next component
|
|
836
860
|
if (!DIR_KEYCODE.test(keyCode)) return;
|
|
837
861
|
|
|
@@ -11,7 +11,7 @@ import { ButtonsHandler, OnClick_menuTray, OnClick_toolbar } from './eventHandle
|
|
|
11
11
|
import { OnMouseDown_wysiwyg, OnMouseUp_wysiwyg, OnClick_wysiwyg, OnMouseMove_wysiwyg, OnMouseLeave_wysiwyg } from './eventHandlers/handler_ww_mouse';
|
|
12
12
|
import { OnInput_wysiwyg, OnKeyDown_wysiwyg, OnKeyUp_wysiwyg } from './eventHandlers/handler_ww_key_input';
|
|
13
13
|
import { OnPaste_wysiwyg, OnCopy_wysiwyg, OnCut_wysiwyg } from './eventHandlers/handler_ww_clipboard';
|
|
14
|
-
import { OnDragOver_wysiwyg, OnDrop_wysiwyg } from './eventHandlers/handler_ww_dragDrop';
|
|
14
|
+
import { OnDragOver_wysiwyg, OnDragEnd_wysiwyg, OnDrop_wysiwyg } from './eventHandlers/handler_ww_dragDrop';
|
|
15
15
|
|
|
16
16
|
const { _w, ON_OVER_COMPONENT, isMobile } = env;
|
|
17
17
|
|
|
@@ -656,7 +656,13 @@ EventManager.prototype = {
|
|
|
656
656
|
this.addEvent(eventWysiwyg, 'paste', OnPaste_wysiwyg.bind(this, fc), false);
|
|
657
657
|
this.addEvent(eventWysiwyg, 'copy', OnCopy_wysiwyg.bind(this, fc), false);
|
|
658
658
|
this.addEvent(eventWysiwyg, 'cut', OnCut_wysiwyg.bind(this, fc), false);
|
|
659
|
-
this.addEvent(
|
|
659
|
+
this.addEvent(
|
|
660
|
+
eventWysiwyg,
|
|
661
|
+
'dragover',
|
|
662
|
+
OnDragOver_wysiwyg.bind(this, fc, dragCursor, isIframe ? this.editor.frameContext.get('topArea') : null, !this.options.get('toolbar_container') && !this.editor.isBalloon && !this.editor.isInline),
|
|
663
|
+
false
|
|
664
|
+
);
|
|
665
|
+
this.addEvent(eventWysiwyg, 'dragend', OnDragEnd_wysiwyg.bind(this, dragCursor), false);
|
|
660
666
|
this.addEvent(eventWysiwyg, 'drop', OnDrop_wysiwyg.bind(this, fc, dragCursor), false);
|
|
661
667
|
this.addEvent(eventWysiwyg, 'scroll', OnScroll_wysiwyg.bind(this, fc, eventWysiwyg), { passive: true, useCapture: false });
|
|
662
668
|
this.addEvent(eventWysiwyg, 'focus', OnFocus_wysiwyg.bind(this, fc), false);
|
|
@@ -514,7 +514,7 @@ function OnKeyDown_component(e) {
|
|
|
514
514
|
return;
|
|
515
515
|
}
|
|
516
516
|
|
|
517
|
-
// backspace, delete
|
|
517
|
+
// backspace key, delete key
|
|
518
518
|
if (keyCode === 8 || keyCode === 46) {
|
|
519
519
|
e.preventDefault();
|
|
520
520
|
e.stopPropagation();
|
|
@@ -526,7 +526,7 @@ function OnKeyDown_component(e) {
|
|
|
526
526
|
}
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
-
// enter
|
|
529
|
+
// enter key
|
|
530
530
|
if (keyCode === 13) {
|
|
531
531
|
e.preventDefault();
|
|
532
532
|
const compContext = this.currentInfo || this.get(this.currentTarget);
|
package/src/core/class/offset.js
CHANGED
|
@@ -43,11 +43,27 @@ Offset.prototype = {
|
|
|
43
43
|
},
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* @description
|
|
46
|
+
* @description Gets the position just outside the argument's internal editor(wysiwygFrame). [getLocal() + iframe offset]
|
|
47
47
|
* @param {Node} node Target node
|
|
48
48
|
* @returns {{top:boolean, left:boolean}}
|
|
49
49
|
*/
|
|
50
50
|
get(node) {
|
|
51
|
+
const wFrame = this.editor.frameContext.get('wysiwygFrame');
|
|
52
|
+
const iframe = /iframe/i.test(wFrame?.nodeName);
|
|
53
|
+
const off = this.getLocal(node);
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
left: off.left + (iframe ? wFrame.parentElement.offsetLeft : 0),
|
|
57
|
+
top: off.top + (iframe ? wFrame.parentElement.offsetTop : 0)
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @description Gets the position in the internal editor of the argument.
|
|
63
|
+
* @param {Node} node Target node
|
|
64
|
+
* @returns {{top:boolean, left:boolean}}
|
|
65
|
+
*/
|
|
66
|
+
getLocal(node) {
|
|
51
67
|
let offsetLeft = 0;
|
|
52
68
|
let offsetTop = 0;
|
|
53
69
|
let offsetElement = node.nodeType === 3 ? node.parentElement : node;
|
|
@@ -60,12 +76,9 @@ Offset.prototype = {
|
|
|
60
76
|
offsetElement = offsetElement.offsetParent;
|
|
61
77
|
}
|
|
62
78
|
|
|
63
|
-
const wFrame = this.editor.frameContext.get('wysiwygFrame');
|
|
64
|
-
const iframe = /iframe/i.test(wFrame?.nodeName);
|
|
65
|
-
|
|
66
79
|
return {
|
|
67
|
-
left: offsetLeft
|
|
68
|
-
top: offsetTop - (wysiwyg ? wysiwyg.scrollTop : 0)
|
|
80
|
+
left: offsetLeft,
|
|
81
|
+
top: offsetTop - (wysiwyg ? wysiwyg.scrollTop : 0)
|
|
69
82
|
};
|
|
70
83
|
},
|
|
71
84
|
|
|
@@ -376,22 +389,26 @@ Offset.prototype = {
|
|
|
376
389
|
const tmbw = clientSize.h - targetRect.bottom;
|
|
377
390
|
let toolbarH = !this.editor.toolbar._sticky && (this.editor.isBalloon || this.editor.isInline) ? 0 : this.context.get('toolbar.main').offsetHeight;
|
|
378
391
|
let rmt, rmb;
|
|
392
|
+
let rt = 0;
|
|
379
393
|
if (this.editor.frameContext.get('isFullScreen')) {
|
|
380
394
|
rmt = tmtw - toolbarH;
|
|
381
395
|
rmb = tmbw;
|
|
382
396
|
} else {
|
|
383
397
|
const tMargin = targetRect.top;
|
|
384
398
|
const bMargin = clientSize.h - targetRect.bottom;
|
|
399
|
+
const editorOffset = this.getGlobal();
|
|
400
|
+
const editorScroll = this.getGlobalScroll();
|
|
401
|
+
const statusBarH = this.editor.frameContext.get('statusbar')?.offsetHeight || 0;
|
|
385
402
|
|
|
386
403
|
if (isIframe) {
|
|
387
|
-
const editorOffset = this.getGlobal();
|
|
388
|
-
const editorScroll = this.getGlobalScroll();
|
|
389
404
|
const emt = editorOffset.top - editorScroll.top - editorScroll.ts;
|
|
390
405
|
const editorH = this.editor.frameContext.get('topArea').offsetHeight;
|
|
391
406
|
rmt = targetRect.top - emt;
|
|
392
|
-
rmb = bMargin - (editorScroll.oh - (editorH + emt) +
|
|
407
|
+
rmb = bMargin - (editorScroll.oh - (editorH + emt) + statusBarH);
|
|
393
408
|
} else {
|
|
394
|
-
|
|
409
|
+
rt = !this.editor.toolbar._sticky && !this.options.get('toolbar_container') ? toolbarH : 0;
|
|
410
|
+
const wst = !isTargetAbs && /\d+/.test(this.editor.frameOptions.get('height')) ? editorOffset.top - _w.scrollY + rt : 0;
|
|
411
|
+
const wsb = !isTargetAbs && /\d+/.test(this.editor.frameOptions.get('height')) ? _w.innerHeight - (editorOffset.top + editorOffset.height - _w.scrollY) : 0;
|
|
395
412
|
let st = wst;
|
|
396
413
|
if (toolbarH > wst) {
|
|
397
414
|
if (this.editor.toolbar._sticky) {
|
|
@@ -402,10 +419,12 @@ Offset.prototype = {
|
|
|
402
419
|
}
|
|
403
420
|
} else if (this.options.get('toolbar_container')) {
|
|
404
421
|
toolbarH = 0;
|
|
422
|
+
} else {
|
|
423
|
+
st = wst + (this.editor.toolbar._sticky ? toolbarH : 0);
|
|
405
424
|
}
|
|
406
425
|
|
|
407
426
|
rmt = targetRect.top - st;
|
|
408
|
-
rmb = wwScroll.rects.bottom - targetRect.bottom;
|
|
427
|
+
rmb = wwScroll.rects.bottom - targetRect.bottom - wsb - statusBarH;
|
|
409
428
|
}
|
|
410
429
|
|
|
411
430
|
// display margin
|
|
@@ -413,7 +432,7 @@ Offset.prototype = {
|
|
|
413
432
|
rmb = rmb > 0 ? bMargin : rmb;
|
|
414
433
|
}
|
|
415
434
|
|
|
416
|
-
if (isWWTarget && (rmb + targetH <= 0 || rmt + targetH <= 0)) return;
|
|
435
|
+
if (isWWTarget && (rmb + targetH <= 0 || rmt + rt + targetH <= 0)) return;
|
|
417
436
|
|
|
418
437
|
let t = addOffset.top;
|
|
419
438
|
let y = 0;
|
|
@@ -425,7 +444,7 @@ Offset.prototype = {
|
|
|
425
444
|
if (y < 0) {
|
|
426
445
|
arrowDir = 'down';
|
|
427
446
|
t -= targetH + elH + ah * 2;
|
|
428
|
-
y = rmt - (elH + ah);
|
|
447
|
+
y = toolbarH + rmt - (elH + ah);
|
|
429
448
|
if (y < 0) {
|
|
430
449
|
arrowDir = '';
|
|
431
450
|
t -= y;
|
|
@@ -235,13 +235,13 @@ Selection.prototype = {
|
|
|
235
235
|
eo = e.rangeOffset;
|
|
236
236
|
} else if (this.editor.frameContext.get('_wd').caretRangeFromPoint) {
|
|
237
237
|
let r = this.editor.frameContext.get('_wd').caretRangeFromPoint(e.clientX, e.clientY);
|
|
238
|
-
if (!r) r = this.
|
|
238
|
+
if (!r) r = this.getRange();
|
|
239
239
|
sc = r.startContainer;
|
|
240
240
|
so = r.startOffset;
|
|
241
241
|
ec = r.endContainer;
|
|
242
242
|
eo = r.endOffset;
|
|
243
243
|
} else {
|
|
244
|
-
const r = this.
|
|
244
|
+
const r = this.getRange();
|
|
245
245
|
sc = r.startContainer;
|
|
246
246
|
so = r.startOffset;
|
|
247
247
|
ec = r.endContainer;
|
|
@@ -264,7 +264,7 @@ Selection.prototype = {
|
|
|
264
264
|
if (ref instanceof Selection) {
|
|
265
265
|
ref = ref.getRangeAt(0);
|
|
266
266
|
} else if (ref instanceof Node) {
|
|
267
|
-
ref = this.
|
|
267
|
+
ref = this.setRange(ref, 1, ref, 1);
|
|
268
268
|
} else if (typeof ref?.startContainer === 'undefined') {
|
|
269
269
|
console.warn('[SUNEDITOR.html.scrollTo.warn] "selectionRange" must be Selection or Range or Node object.', ref);
|
|
270
270
|
}
|
|
@@ -387,8 +387,10 @@ Selection.prototype = {
|
|
|
387
387
|
let rangeObj = this.getRange();
|
|
388
388
|
if (this._isNone(rangeObj)) {
|
|
389
389
|
if (!domUtils.isWysiwygFrame(rangeObj.startContainer) || !domUtils.isWysiwygFrame(rangeObj.endContainer)) return false;
|
|
390
|
-
const ww = rangeObj.
|
|
391
|
-
|
|
390
|
+
const ww = rangeObj.commonAncestorContainer;
|
|
391
|
+
const first = ww.children[rangeObj.startOffset];
|
|
392
|
+
const end = ww.children[rangeObj.endOffset];
|
|
393
|
+
rangeObj = this.setRange(first, 0, end, first === end ? 0 : 1);
|
|
392
394
|
}
|
|
393
395
|
|
|
394
396
|
const range = rangeObj;
|
package/src/core/class/viewer.js
CHANGED
|
@@ -324,7 +324,7 @@ Viewer.prototype = {
|
|
|
324
324
|
const iframe = domUtils.createElement('IFRAME', { style: 'display: none;' });
|
|
325
325
|
this._d.body.appendChild(iframe);
|
|
326
326
|
|
|
327
|
-
const contentHTML = this.options.get('printTemplate') ? this.options.get('printTemplate').replace(/\{\s*
|
|
327
|
+
const contentHTML = this.options.get('printTemplate') ? this.options.get('printTemplate').replace(/\{\{\s*contents\s*\}\}/i, this.html.get(true)) : this.html.get(true);
|
|
328
328
|
const printDocument = domUtils.getIframeDocument(iframe);
|
|
329
329
|
const wDoc = this.editor.frameContext.get('_wd');
|
|
330
330
|
|
|
@@ -392,7 +392,7 @@ Viewer.prototype = {
|
|
|
392
392
|
this.editor._offCurrentController();
|
|
393
393
|
this.editor._offCurrentModal();
|
|
394
394
|
|
|
395
|
-
const contentHTML = this.options.get('previewTemplate') ? this.options.get('previewTemplate').replace(/\{\s*
|
|
395
|
+
const contentHTML = this.options.get('previewTemplate') ? this.options.get('previewTemplate').replace(/\{\{\s*contents\s*\}\}/i, this.html.get(true)) : this.html.get(true);
|
|
396
396
|
const windowObject = this._w.open('', '_blank');
|
|
397
397
|
windowObject.mimeType = 'text/html';
|
|
398
398
|
const wDoc = this.editor.frameContext.get('_wd');
|
|
@@ -98,12 +98,9 @@ const Constructor = function (editorTargets, options) {
|
|
|
98
98
|
/** --- Plugins ------------------------------------------------------------------------------------------ */
|
|
99
99
|
const plugins = {};
|
|
100
100
|
if (options.plugins) {
|
|
101
|
+
const excludedPlugins = options.excludedPlugins || [];
|
|
101
102
|
const originPlugins = options.plugins;
|
|
102
|
-
const pluginsValues = Array.isArray(originPlugins.
|
|
103
|
-
? originPlugins
|
|
104
|
-
: Object.keys(originPlugins).map(function (name) {
|
|
105
|
-
return originPlugins[name];
|
|
106
|
-
});
|
|
103
|
+
const pluginsValues = (Array.isArray(originPlugins) ? originPlugins : Object.keys(originPlugins)).filter((name) => !excludedPlugins.includes(name)).map((name) => originPlugins[name]);
|
|
107
104
|
|
|
108
105
|
for (let i = 0, len = pluginsValues.length, p; i < len; i++) {
|
|
109
106
|
p = pluginsValues[i].default || pluginsValues[i];
|
package/src/langs/en.js
CHANGED
|
@@ -54,7 +54,11 @@
|
|
|
54
54
|
color: 'Color',
|
|
55
55
|
colorPicker: 'Color picker',
|
|
56
56
|
column: 'Column',
|
|
57
|
+
comment: 'Comments',
|
|
58
|
+
commentAdd: 'Add comment',
|
|
59
|
+
commentShow: 'Show comments',
|
|
57
60
|
copy: 'Copy',
|
|
61
|
+
copyFormatting: 'Copy formatting',
|
|
58
62
|
cut: 'Cut',
|
|
59
63
|
default: 'Default',
|
|
60
64
|
deleteColumn: 'Delete column',
|
|
@@ -65,6 +69,8 @@
|
|
|
65
69
|
drag: 'Drag',
|
|
66
70
|
edit: 'Edit',
|
|
67
71
|
exportPdf: 'Export to PDF',
|
|
72
|
+
exportWord: 'Export to Word',
|
|
73
|
+
find: 'Find',
|
|
68
74
|
decrease: 'Decrease',
|
|
69
75
|
increase: 'Increase',
|
|
70
76
|
fileUpload: 'File upload',
|
|
@@ -86,6 +92,7 @@
|
|
|
86
92
|
image_modal_file: 'Select from files',
|
|
87
93
|
image_modal_title: 'Insert image',
|
|
88
94
|
image_modal_url: 'Image URL',
|
|
95
|
+
importWord: 'Import from Word',
|
|
89
96
|
indent: 'Indent',
|
|
90
97
|
inlineStyle: 'Inline style',
|
|
91
98
|
insertColumnAfter: 'Insert column after',
|
|
@@ -126,6 +133,7 @@
|
|
|
126
133
|
newDocument: 'New document',
|
|
127
134
|
numberedList: 'Numbered list',
|
|
128
135
|
outdent: 'Outdent',
|
|
136
|
+
pageBreak: 'Page break',
|
|
129
137
|
paragraphStyle: 'Paragraph style',
|
|
130
138
|
preview: 'Preview',
|
|
131
139
|
print: 'print',
|
|
@@ -134,12 +142,15 @@
|
|
|
134
142
|
redo: 'Redo',
|
|
135
143
|
remove: 'Remove',
|
|
136
144
|
removeFormat: 'Remove Format',
|
|
145
|
+
replace: 'Replace',
|
|
146
|
+
replaceAll: 'Replace all',
|
|
137
147
|
resize100: 'Zoom 100%',
|
|
138
148
|
resize25: 'Zoom 25%',
|
|
139
149
|
resize50: 'Zoom 50%',
|
|
140
150
|
resize75: 'Zoom 75%',
|
|
141
151
|
resize: 'Resize',
|
|
142
152
|
revert: 'Revert',
|
|
153
|
+
revisionHistory: 'Revision History',
|
|
143
154
|
right: 'Right',
|
|
144
155
|
rotateLeft: 'Rotate left',
|
|
145
156
|
rotateRight: 'Rotate right',
|
package/src/langs/ko.js
CHANGED
|
@@ -15,10 +15,15 @@
|
|
|
15
15
|
const lang = {
|
|
16
16
|
code: 'ko',
|
|
17
17
|
align: '정렬',
|
|
18
|
+
alignBottom: '아래쪽 정렬',
|
|
18
19
|
alignCenter: '가운데 정렬',
|
|
19
20
|
alignJustify: '양쪽 정렬',
|
|
20
21
|
alignLeft: '왼쪽 정렬',
|
|
22
|
+
alignMiddle: '중간 정렬',
|
|
21
23
|
alignRight: '오른쪽 정렬',
|
|
24
|
+
alignTop: '위쪽 정렬',
|
|
25
|
+
asBlock: '블록으로 보기',
|
|
26
|
+
asLink: '링크로 보기',
|
|
22
27
|
audio: '오디오',
|
|
23
28
|
audio_modal_file: '파일 선택',
|
|
24
29
|
audio_modal_title: '오디오 삽입',
|
|
@@ -26,18 +31,49 @@
|
|
|
26
31
|
autoSize: '자동 크기',
|
|
27
32
|
backgroundColor: '배경색',
|
|
28
33
|
basic: '기본',
|
|
34
|
+
blockStyle: '블록 스타일',
|
|
29
35
|
bold: '굵게',
|
|
36
|
+
border: '테두리',
|
|
37
|
+
border_all: '모든 테두리',
|
|
38
|
+
border_inside: '안쪽 테두리',
|
|
39
|
+
border_horizontal: '안쪽 가로 테두리',
|
|
40
|
+
border_vertical: '안쪽 세로 테두리',
|
|
41
|
+
border_outside: '바깥쪽 테두리',
|
|
42
|
+
border_left: '왼쪽 테두리',
|
|
43
|
+
border_top: '위쪽 테두리',
|
|
44
|
+
border_right: '오른쪽 테두리',
|
|
45
|
+
border_bottom: '아래쪽 테두리',
|
|
46
|
+
border_none: '테두리 없음',
|
|
30
47
|
bulletedList: '원형 리스트',
|
|
48
|
+
cancel: '취소',
|
|
31
49
|
caption: '설명 넣기',
|
|
50
|
+
cellProperties: '셀 속성',
|
|
32
51
|
center: '가운데',
|
|
33
52
|
close: '닫기',
|
|
34
53
|
codeView: 'HTML 편집',
|
|
54
|
+
color: '색상',
|
|
55
|
+
colorPicker: '색상 선택기',
|
|
56
|
+
column: '열',
|
|
57
|
+
comment: '코멘트',
|
|
58
|
+
commentAdd: '코멘트 추가',
|
|
59
|
+
commentShow: '코멘트 보기',
|
|
60
|
+
copy: '복사',
|
|
61
|
+
copyFormatting: '서식 복사',
|
|
62
|
+
cut: '잘라내기',
|
|
35
63
|
default: '기본값',
|
|
36
64
|
deleteColumn: '열 삭제',
|
|
37
65
|
deleteRow: '행 삭제',
|
|
38
66
|
dir_ltr: '왼쪽에서 오른쪽',
|
|
39
67
|
dir_rtl: '오른쪽에서 왼쪽',
|
|
68
|
+
download: '다운로드',
|
|
69
|
+
drag: '드래그',
|
|
40
70
|
edit: '편집',
|
|
71
|
+
exportPdf: 'PDF로 내보내기',
|
|
72
|
+
exportWord: 'Word로 내보내기',
|
|
73
|
+
find: '찾기',
|
|
74
|
+
decrease: '내리기',
|
|
75
|
+
increase: '올리기',
|
|
76
|
+
fileUpload: '파일 업로드',
|
|
41
77
|
fixedColumnWidth: '고정 된 열 너비',
|
|
42
78
|
font: '글꼴',
|
|
43
79
|
fontColor: '글자색',
|
|
@@ -56,11 +92,14 @@
|
|
|
56
92
|
image_modal_file: '파일 선택',
|
|
57
93
|
image_modal_title: '이미지 삽입',
|
|
58
94
|
image_modal_url: '이미지 주소',
|
|
95
|
+
importWord: '워드에서 가져오기',
|
|
59
96
|
indent: '들여쓰기',
|
|
97
|
+
inlineStyle: '인라인 스타일',
|
|
60
98
|
insertColumnAfter: '오른쪽에 열 삽입',
|
|
61
99
|
insertColumnBefore: '왼쪽에 열 삽입',
|
|
62
100
|
insertRowAbove: '위에 행 삽입',
|
|
63
101
|
insertRowBelow: '아래에 행 삽입',
|
|
102
|
+
insertLine: '라인 삽입',
|
|
64
103
|
italic: '기울임',
|
|
65
104
|
layout: '레이아웃',
|
|
66
105
|
left: '왼쪽',
|
|
@@ -72,6 +111,7 @@
|
|
|
72
111
|
link_modal_text: '화면 텍스트',
|
|
73
112
|
link_modal_title: '링크 삽입',
|
|
74
113
|
link_modal_url: '인터넷 주소',
|
|
114
|
+
link_modal_relAttribute: 'Rel 속성',
|
|
75
115
|
list: '리스트',
|
|
76
116
|
math: '수식',
|
|
77
117
|
math_modal_fontSizeLabel: '글자 크기',
|
|
@@ -90,8 +130,10 @@
|
|
|
90
130
|
minSize: '최소화',
|
|
91
131
|
mirrorHorizontal: '좌우 반전',
|
|
92
132
|
mirrorVertical: '상하 반전',
|
|
133
|
+
newDocument: '새 문서',
|
|
93
134
|
numberedList: '숫자형 리스트',
|
|
94
135
|
outdent: '내어쓰기',
|
|
136
|
+
pageBreak: '페이지 나누기',
|
|
95
137
|
paragraphStyle: '문단 스타일',
|
|
96
138
|
preview: '미리보기',
|
|
97
139
|
print: '인쇄',
|
|
@@ -100,17 +142,22 @@
|
|
|
100
142
|
redo: '다시 실행',
|
|
101
143
|
remove: '삭제',
|
|
102
144
|
removeFormat: '형식 제거',
|
|
145
|
+
replace: '바꾸기',
|
|
146
|
+
replaceAll: '전체 바꾸기',
|
|
103
147
|
resize100: '100% 크기',
|
|
104
148
|
resize25: '25% 크기',
|
|
105
149
|
resize50: '50% 크기',
|
|
106
150
|
resize75: '75% 크기',
|
|
107
151
|
resize: '크기',
|
|
108
152
|
revert: '되돌리기',
|
|
153
|
+
revisionHistory: '수정 이력',
|
|
109
154
|
right: '오른쪽',
|
|
110
155
|
rotateLeft: '왼쪽으로 회전',
|
|
111
156
|
rotateRight: '오른쪽으로 회전',
|
|
157
|
+
row: '행',
|
|
112
158
|
save: '저장',
|
|
113
159
|
search: '검색',
|
|
160
|
+
selectAll: '전체 선택',
|
|
114
161
|
showBlocks: '블록 보기',
|
|
115
162
|
size: '크기',
|
|
116
163
|
splitCells: '셀 분할',
|
|
@@ -120,6 +167,7 @@
|
|
|
120
167
|
superscript: '위 첨자',
|
|
121
168
|
table: '테이블',
|
|
122
169
|
tableHeader: '테이블 제목',
|
|
170
|
+
tableProperties: '테이블 속성',
|
|
123
171
|
tags: '태그',
|
|
124
172
|
tag_blockquote: '인용문',
|
|
125
173
|
tag_div: '기본 (DIV)',
|
|
@@ -3,7 +3,7 @@ import { domUtils, env } from '../helper';
|
|
|
3
3
|
import { _DragHandle } from '../modules';
|
|
4
4
|
|
|
5
5
|
const { ON_OVER_COMPONENT } = env;
|
|
6
|
-
const NON_RESPONSE_KEYCODE = /^(
|
|
6
|
+
const NON_RESPONSE_KEYCODE = /^(1[7-9]|20|27|45|11[2-9]|12[0-3]|144|145)$/;
|
|
7
7
|
const INDEX_0 = 2147483647;
|
|
8
8
|
const INDEX_1 = 2147483646;
|
|
9
9
|
const INDEX_2 = 2147483645;
|
|
@@ -121,7 +121,7 @@ FileUpload.prototype = {
|
|
|
121
121
|
return;
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
this.
|
|
124
|
+
this.submitFile([file]);
|
|
125
125
|
this.editor.focus();
|
|
126
126
|
|
|
127
127
|
return false;
|
|
@@ -156,7 +156,7 @@ FileUpload.prototype = {
|
|
|
156
156
|
this.component.select(this._element, FileUpload.key, false);
|
|
157
157
|
},
|
|
158
158
|
|
|
159
|
-
async
|
|
159
|
+
async submitFile(fileList) {
|
|
160
160
|
if (fileList.length === 0) return;
|
|
161
161
|
|
|
162
162
|
let fileSize = 0;
|
|
@@ -362,7 +362,7 @@ FileUpload.prototype = {
|
|
|
362
362
|
};
|
|
363
363
|
|
|
364
364
|
async function OnChangeFile(e) {
|
|
365
|
-
await this.
|
|
365
|
+
await this.submitFile(e.target.files);
|
|
366
366
|
}
|
|
367
367
|
|
|
368
368
|
function CreateHTML_controller({ lang, icons }) {
|