suneditor 3.1.4 → 3.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/suneditor-contents.min.css +1 -1
- package/dist/suneditor.min.css +28 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +2 -1
- package/src/assets/design/color.css +12 -0
- package/src/assets/design/size.css +9 -2
- package/src/assets/icons/defaultIcons.js +96 -47
- package/src/assets/suneditor-contents.css +3 -2
- package/src/assets/suneditor.css +481 -31
- package/src/core/config/contextProvider.js +2 -1
- package/src/core/config/eventManager.js +41 -2
- package/src/core/config/optionProvider.js +23 -2
- package/src/core/editor.js +32 -14
- package/src/core/event/actions/index.js +76 -9
- package/src/core/event/effects/common.registry.js +2 -1
- package/src/core/event/effects/keydown.registry.js +169 -33
- package/src/core/event/effects/ruleHelpers.js +20 -6
- package/src/core/event/eventOrchestrator.js +162 -30
- package/src/core/event/handlers/handler_toolbar.js +4 -2
- package/src/core/event/handlers/handler_ww_dragDrop.js +10 -0
- package/src/core/event/handlers/handler_ww_input.js +84 -2
- package/src/core/event/handlers/handler_ww_key.js +82 -21
- package/src/core/event/handlers/handler_ww_mouse.js +45 -8
- package/src/core/event/ports.js +27 -13
- package/src/core/event/reducers/keydown.reducer.js +33 -5
- package/src/core/event/rules/keydown.rule.arrow.js +12 -2
- package/src/core/event/rules/keydown.rule.backspace.js +110 -15
- package/src/core/event/rules/keydown.rule.delete.js +62 -7
- package/src/core/event/rules/keydown.rule.enter.js +62 -31
- package/src/core/event/support/defaultLineManager.js +9 -2
- package/src/core/event/support/selectionState.js +13 -3
- package/src/core/kernel/coreKernel.js +1 -0
- package/src/core/logic/dom/char.js +13 -3
- package/src/core/logic/dom/format.js +171 -39
- package/src/core/logic/dom/html.js +350 -72
- package/src/core/logic/dom/inline.js +229 -34
- package/src/core/logic/dom/listFormat.js +111 -20
- package/src/core/logic/dom/nodeTransform.js +36 -11
- package/src/core/logic/dom/offset.js +116 -31
- package/src/core/logic/dom/selection.js +147 -29
- package/src/core/logic/panel/blockHandle.js +785 -0
- package/src/core/logic/panel/blockResolver.js +278 -0
- package/src/core/logic/panel/finder.js +16 -6
- package/src/core/logic/panel/menu.js +119 -18
- package/src/core/logic/panel/toolbar.js +75 -19
- package/src/core/logic/panel/viewer.js +76 -20
- package/src/core/logic/shell/_commandExecutor.js +44 -9
- package/src/core/logic/shell/commandDispatcher.js +46 -4
- package/src/core/logic/shell/component.js +102 -25
- package/src/core/logic/shell/focusManager.js +13 -3
- package/src/core/logic/shell/history.js +21 -6
- package/src/core/logic/shell/pluginManager.js +21 -13
- package/src/core/logic/shell/shortcuts.js +9 -1
- package/src/core/logic/shell/ui.js +139 -37
- package/src/core/schema/frameContext.js +34 -3
- package/src/core/schema/options.js +46 -4
- package/src/core/section/constructor.js +537 -106
- package/src/core/section/documentType.js +35 -6
- package/src/helper/converter.js +24 -7
- package/src/helper/dom/domCheck.js +25 -5
- package/src/helper/dom/domQuery.js +2 -1
- package/src/helper/dom/domUtils.js +17 -4
- package/src/helper/env.js +11 -2
- package/src/helper/keyCodeMap.js +6 -2
- package/src/helper/markdown.js +24 -5
- package/src/helper/msOffice.js +9 -2
- package/src/interfaces/plugins.js +1 -1
- package/src/langs/ckb.js +0 -1
- package/src/langs/cs.js +0 -1
- package/src/langs/da.js +0 -1
- package/src/langs/de.js +0 -1
- package/src/langs/en.js +0 -1
- package/src/langs/es.js +0 -1
- package/src/langs/fa.js +0 -1
- package/src/langs/fr.js +0 -1
- package/src/langs/he.js +0 -1
- package/src/langs/hu.js +0 -1
- package/src/langs/index.js +27 -1
- package/src/langs/it.js +0 -1
- package/src/langs/ja.js +0 -1
- package/src/langs/km.js +0 -1
- package/src/langs/ko.js +0 -1
- package/src/langs/lv.js +0 -1
- package/src/langs/nl.js +0 -1
- package/src/langs/pl.js +0 -1
- package/src/langs/pt_br.js +0 -1
- package/src/langs/ro.js +0 -1
- package/src/langs/ru.js +0 -1
- package/src/langs/se.js +0 -1
- package/src/langs/tr.js +0 -1
- package/src/langs/uk.js +0 -1
- package/src/langs/ur.js +0 -1
- package/src/langs/zh_cn.js +0 -1
- package/src/modules/contract/Browser.js +58 -14
- package/src/modules/contract/ColorPicker.js +12 -4
- package/src/modules/contract/Controller.js +37 -7
- package/src/modules/contract/Figure.js +156 -36
- package/src/modules/contract/HueSlider.js +27 -4
- package/src/modules/contract/Modal.js +50 -10
- package/src/modules/manager/FileManager.js +50 -8
- package/src/modules/ui/CommandMenu.js +597 -0
- package/src/modules/ui/ModalAnchorEditor.js +33 -6
- package/src/modules/ui/SelectMenu.js +481 -36
- package/src/modules/ui/index.js +1 -0
- package/src/plugins/browser/audioGallery.js +2 -1
- package/src/plugins/browser/fileBrowser.js +9 -2
- package/src/plugins/browser/fileGallery.js +2 -1
- package/src/plugins/browser/imageGallery.js +18 -3
- package/src/plugins/browser/videoGallery.js +13 -4
- package/src/plugins/command/blockquote.js +6 -1
- package/src/plugins/command/codeBlock.js +43 -5
- package/src/plugins/command/exportPDF.js +20 -4
- package/src/plugins/command/fileUpload.js +46 -11
- package/src/plugins/command/list_bulleted.js +6 -1
- package/src/plugins/command/list_numbered.js +6 -1
- package/src/plugins/dropdown/align.js +21 -33
- package/src/plugins/dropdown/backgroundColor.js +10 -2
- package/src/plugins/dropdown/blockStyle.js +17 -22
- package/src/plugins/dropdown/font.js +34 -34
- package/src/plugins/dropdown/hr.js +15 -43
- package/src/plugins/dropdown/layout.js +10 -27
- package/src/plugins/dropdown/lineHeight.js +10 -33
- package/src/plugins/dropdown/list.js +19 -25
- package/src/plugins/dropdown/paragraphStyle.js +16 -24
- package/src/plugins/dropdown/table/index.js +72 -17
- package/src/plugins/dropdown/table/render/table.html.js +3 -1
- package/src/plugins/dropdown/table/services/table.cell.js +33 -7
- package/src/plugins/dropdown/table/services/table.clipboard.js +5 -1
- package/src/plugins/dropdown/table/services/table.grid.js +40 -9
- package/src/plugins/dropdown/table/services/table.resize.js +55 -11
- package/src/plugins/dropdown/table/services/table.selection.js +27 -7
- package/src/plugins/dropdown/table/services/table.style.js +120 -20
- package/src/plugins/dropdown/template.js +13 -29
- package/src/plugins/dropdown/textStyle.js +22 -35
- package/src/plugins/field/autocomplete.js +8 -4
- package/src/plugins/field/slashCommand.js +297 -0
- package/src/plugins/index.js +3 -0
- package/src/plugins/input/fontSize.js +37 -8
- package/src/plugins/input/pageNavigator.js +7 -1
- package/src/plugins/modal/audio.js +71 -17
- package/src/plugins/modal/drawing.js +41 -11
- package/src/plugins/modal/embed.js +92 -22
- package/src/plugins/modal/image/index.js +114 -28
- package/src/plugins/modal/image/services/image.size.js +9 -2
- package/src/plugins/modal/image/services/image.upload.js +38 -4
- package/src/plugins/modal/link.js +9 -2
- package/src/plugins/modal/math.js +10 -2
- package/src/plugins/modal/video/index.js +112 -26
- package/src/plugins/modal/video/render/video.html.js +4 -1
- package/src/plugins/modal/video/services/video.size.js +15 -4
- package/src/plugins/modal/video/services/video.upload.js +10 -2
- package/src/plugins/popup/anchor.js +14 -2
- package/src/suneditor.js +8 -2
- package/src/themes/cobalt.css +12 -0
- package/src/themes/cream.css +12 -0
- package/src/themes/dark.css +12 -0
- package/src/themes/midnight.css +12 -0
- package/src/typedef.js +32 -21
- package/types/assets/icons/defaultIcons.d.ts +1 -0
- package/types/core/config/contextProvider.d.ts +7 -1
- package/types/core/config/eventManager.d.ts +37 -4
- package/types/core/config/optionProvider.d.ts +5 -1
- package/types/core/event/actions/index.d.ts +44 -6
- package/types/core/event/effects/keydown.registry.d.ts +37 -7
- package/types/core/event/effects/ruleHelpers.d.ts +6 -1
- package/types/core/event/eventOrchestrator.d.ts +13 -3
- package/types/core/event/handlers/handler_ww_clipboard.d.ts +15 -3
- package/types/core/event/handlers/handler_ww_dragDrop.d.ts +14 -2
- package/types/core/event/handlers/handler_ww_input.d.ts +10 -2
- package/types/core/event/handlers/handler_ww_key.d.ts +10 -2
- package/types/core/event/handlers/handler_ww_mouse.d.ts +25 -5
- package/types/core/event/ports.d.ts +11 -4
- package/types/core/event/reducers/keydown.reducer.d.ts +12 -3
- package/types/core/event/rules/keydown.rule.backspace.d.ts +6 -1
- package/types/core/kernel/store.d.ts +4 -1
- package/types/core/logic/dom/format.d.ts +32 -14
- package/types/core/logic/dom/html.d.ts +11 -3
- package/types/core/logic/dom/nodeTransform.d.ts +6 -6
- package/types/core/logic/panel/blockHandle.d.ts +64 -0
- package/types/core/logic/panel/blockResolver.d.ts +50 -0
- package/types/core/logic/panel/menu.d.ts +72 -3
- package/types/core/logic/shell/commandDispatcher.d.ts +8 -0
- package/types/core/logic/shell/component.d.ts +5 -3
- package/types/core/logic/shell/shortcuts.d.ts +10 -1
- package/types/core/logic/shell/ui.d.ts +7 -1
- package/types/core/schema/context.d.ts +7 -1
- package/types/core/schema/frameContext.d.ts +36 -4
- package/types/core/schema/options.d.ts +83 -2
- package/types/core/section/constructor.d.ts +38 -1
- package/types/events.d.ts +208 -32
- package/types/helper/converter.d.ts +4 -2
- package/types/helper/dom/domCheck.d.ts +12 -2
- package/types/helper/dom/domQuery.d.ts +35 -7
- package/types/helper/dom/domUtils.d.ts +4 -1
- package/types/interfaces/plugins.d.ts +2 -2
- package/types/langs/_Lang.d.ts +0 -1
- package/types/modules/contract/ColorPicker.d.ts +2 -2
- package/types/modules/contract/Controller.d.ts +7 -0
- package/types/modules/contract/Figure.d.ts +31 -4
- package/types/modules/ui/CommandMenu.d.ts +262 -0
- package/types/modules/ui/SelectMenu.d.ts +56 -3
- package/types/modules/ui/index.d.ts +1 -0
- package/types/plugins/browser/audioGallery.d.ts +1 -1
- package/types/plugins/browser/fileBrowser.d.ts +1 -1
- package/types/plugins/browser/fileGallery.d.ts +1 -1
- package/types/plugins/browser/imageGallery.d.ts +1 -1
- package/types/plugins/browser/videoGallery.d.ts +1 -1
- package/types/plugins/dropdown/align.d.ts +1 -1
- package/types/plugins/dropdown/blockStyle.d.ts +3 -1
- package/types/plugins/dropdown/table/index.d.ts +4 -1
- package/types/plugins/dropdown/table/services/table.clipboard.d.ts +5 -1
- package/types/plugins/dropdown/table/services/table.grid.d.ts +10 -2
- package/types/plugins/field/autocomplete.d.ts +0 -1
- package/types/plugins/field/slashCommand.d.ts +165 -0
- package/types/plugins/index.d.ts +3 -0
- package/types/plugins/modal/link.d.ts +4 -1
- package/types/typedef.d.ts +48 -23
|
@@ -49,7 +49,8 @@ class AudioGallery extends PluginBrowser {
|
|
|
49
49
|
this.onSelectfunction = null;
|
|
50
50
|
|
|
51
51
|
// modules
|
|
52
|
-
const thumbnail =
|
|
52
|
+
const thumbnail =
|
|
53
|
+
typeof pluginOptions.thumbnail === 'string' ? pluginOptions.thumbnail : this.$.icons.audio_thumbnail;
|
|
53
54
|
this.browser = new Browser(this, this.$, {
|
|
54
55
|
title: this.$.lang.audioGallery,
|
|
55
56
|
data: pluginOptions.data,
|
|
@@ -61,7 +61,11 @@ class FileBrowser extends PluginBrowser {
|
|
|
61
61
|
this.onSelectfunction = null;
|
|
62
62
|
|
|
63
63
|
// modules
|
|
64
|
-
const thumbnail = {
|
|
64
|
+
const thumbnail = {
|
|
65
|
+
video: this.$.icons.video_thumbnail,
|
|
66
|
+
audio: this.$.icons.audio_thumbnail,
|
|
67
|
+
file: this.$.icons.file_thumbnail,
|
|
68
|
+
};
|
|
65
69
|
const defaultThumbnail = this.$.icons.file_thumbnail;
|
|
66
70
|
this.browser = new Browser(this, this.$, {
|
|
67
71
|
title: this.$.lang.fileBrowser,
|
|
@@ -73,7 +77,10 @@ class FileBrowser extends PluginBrowser {
|
|
|
73
77
|
selectorHandler: this.#SetItem.bind(this),
|
|
74
78
|
columnSize: 4,
|
|
75
79
|
className: 'se-file-browser',
|
|
76
|
-
thumbnail:
|
|
80
|
+
thumbnail:
|
|
81
|
+
typeof pluginOptions.thumbnail === 'function'
|
|
82
|
+
? pluginOptions.thumbnail
|
|
83
|
+
: (item) => thumbnail[item.type] || defaultThumbnail,
|
|
77
84
|
props: [...new Set((pluginOptions.props ?? []).concat(['frame']))],
|
|
78
85
|
expand: pluginOptions.expand,
|
|
79
86
|
});
|
|
@@ -50,7 +50,8 @@ class FileGallery extends PluginBrowser {
|
|
|
50
50
|
this.onSelectfunction = null;
|
|
51
51
|
|
|
52
52
|
// modules
|
|
53
|
-
const thumbnail =
|
|
53
|
+
const thumbnail =
|
|
54
|
+
typeof pluginOptions.thumbnail === 'string' ? pluginOptions.thumbnail : this.$.icons.file_thumbnail;
|
|
54
55
|
this.browser = new Browser(this, this.$, {
|
|
55
56
|
title: this.$.lang.fileGallery,
|
|
56
57
|
data: pluginOptions.data,
|
|
@@ -62,8 +62,14 @@ class ImageGallery extends PluginBrowser {
|
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
// members
|
|
65
|
-
this.width =
|
|
66
|
-
|
|
65
|
+
this.width =
|
|
66
|
+
this.$.plugins.image.pluginOptions.defaultWidth === 'auto'
|
|
67
|
+
? ''
|
|
68
|
+
: this.$.plugins.image.pluginOptions.defaultWidth;
|
|
69
|
+
this.height =
|
|
70
|
+
this.$.plugins.image.pluginOptions.defaultHeight === 'auto'
|
|
71
|
+
? ''
|
|
72
|
+
: this.$.plugins.image.pluginOptions.defaultHeight;
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
/**
|
|
@@ -94,7 +100,16 @@ class ImageGallery extends PluginBrowser {
|
|
|
94
100
|
} else {
|
|
95
101
|
const file = { name: target.getAttribute('data-name'), size: 0 };
|
|
96
102
|
this.$.plugins.image.modalInit();
|
|
97
|
-
this.$.plugins.image.create(
|
|
103
|
+
this.$.plugins.image.create(
|
|
104
|
+
target.getAttribute('data-command'),
|
|
105
|
+
null,
|
|
106
|
+
this.width,
|
|
107
|
+
this.height,
|
|
108
|
+
'none',
|
|
109
|
+
file,
|
|
110
|
+
target.alt,
|
|
111
|
+
true,
|
|
112
|
+
);
|
|
98
113
|
}
|
|
99
114
|
}
|
|
100
115
|
}
|
|
@@ -50,7 +50,8 @@ class VideoGallery extends PluginBrowser {
|
|
|
50
50
|
this.onSelectfunction = null;
|
|
51
51
|
|
|
52
52
|
// modules
|
|
53
|
-
const thumbnail =
|
|
53
|
+
const thumbnail =
|
|
54
|
+
typeof pluginOptions.thumbnail === 'string' ? pluginOptions.thumbnail : this.$.icons.video_thumbnail;
|
|
54
55
|
this.browser = new Browser(this, this.$, {
|
|
55
56
|
title: this.$.lang.videoGallery,
|
|
56
57
|
data: pluginOptions.data,
|
|
@@ -66,8 +67,14 @@ class VideoGallery extends PluginBrowser {
|
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
// members
|
|
69
|
-
this.width =
|
|
70
|
-
|
|
70
|
+
this.width =
|
|
71
|
+
this.$.plugins.video.pluginOptions.defaultWidth === 'auto'
|
|
72
|
+
? ''
|
|
73
|
+
: this.$.plugins.video.pluginOptions.defaultWidth;
|
|
74
|
+
this.height =
|
|
75
|
+
this.$.plugins.video.pluginOptions.defaultHeight === 'auto'
|
|
76
|
+
? ''
|
|
77
|
+
: this.$.plugins.video.pluginOptions.defaultHeight;
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
/**
|
|
@@ -105,7 +112,9 @@ class VideoGallery extends PluginBrowser {
|
|
|
105
112
|
const file = { name: target.getAttribute('data-name'), size: 0 };
|
|
106
113
|
this.$.plugins.video.modalInit();
|
|
107
114
|
this.$.plugins.video.create(
|
|
108
|
-
this.$.plugins.video[
|
|
115
|
+
this.$.plugins.video[
|
|
116
|
+
target.getAttribute('data-frame') === 'iframe' ? 'createIframeTag' : 'createVideoTag'
|
|
117
|
+
]({ poster: target.getAttribute('data-thumbnail') }),
|
|
109
118
|
url,
|
|
110
119
|
null,
|
|
111
120
|
this.width,
|
|
@@ -45,7 +45,12 @@ class Blockquote extends PluginCommand {
|
|
|
45
45
|
const currentBlockquote = dom.query.getParentElement(this.$.selection.getNode(), 'blockquote');
|
|
46
46
|
|
|
47
47
|
if (currentBlockquote) {
|
|
48
|
-
this.$.format.removeBlock(currentBlockquote, {
|
|
48
|
+
this.$.format.removeBlock(currentBlockquote, {
|
|
49
|
+
selectedFormats: null,
|
|
50
|
+
newBlockElement: null,
|
|
51
|
+
shouldDelete: false,
|
|
52
|
+
skipHistory: false,
|
|
53
|
+
});
|
|
49
54
|
} else {
|
|
50
55
|
this.$.format.applyBlock(this.quoteTag.cloneNode(false));
|
|
51
56
|
}
|
|
@@ -5,7 +5,29 @@ import { SelectMenu } from '../../modules/ui';
|
|
|
5
5
|
|
|
6
6
|
void PluginDropdown;
|
|
7
7
|
|
|
8
|
-
const DEFAULT_LANGS = [
|
|
8
|
+
const DEFAULT_LANGS = [
|
|
9
|
+
'javascript',
|
|
10
|
+
'typescript',
|
|
11
|
+
'html',
|
|
12
|
+
'css',
|
|
13
|
+
'json',
|
|
14
|
+
'python',
|
|
15
|
+
'java',
|
|
16
|
+
'c',
|
|
17
|
+
'cpp',
|
|
18
|
+
'csharp',
|
|
19
|
+
'go',
|
|
20
|
+
'rust',
|
|
21
|
+
'ruby',
|
|
22
|
+
'php',
|
|
23
|
+
'swift',
|
|
24
|
+
'kotlin',
|
|
25
|
+
'sql',
|
|
26
|
+
'bash',
|
|
27
|
+
'markdown',
|
|
28
|
+
'xml',
|
|
29
|
+
'yaml',
|
|
30
|
+
];
|
|
9
31
|
|
|
10
32
|
/**
|
|
11
33
|
* @typedef {Object} CodeBlockPluginOptions
|
|
@@ -66,7 +88,12 @@ class CodeBlock extends PluginCommand {
|
|
|
66
88
|
// ───────────────── [[toolbar dropdown type]] ─────────────────
|
|
67
89
|
this.afterItem = dom.utils.createElement(
|
|
68
90
|
'button',
|
|
69
|
-
{
|
|
91
|
+
{
|
|
92
|
+
class: 'se-btn se-tooltip se-sub-arrow-btn',
|
|
93
|
+
type: 'button',
|
|
94
|
+
'data-command': CodeBlock.key,
|
|
95
|
+
'data-type': 'dropdown',
|
|
96
|
+
},
|
|
70
97
|
`${this.$.icons.arrow_down}<span class="se-tooltip-inner"><span class="se-tooltip-text">${this.$.lang.codeLanguage || 'Language'}</span></span>`,
|
|
71
98
|
);
|
|
72
99
|
|
|
@@ -242,11 +269,19 @@ class CodeBlock extends PluginCommand {
|
|
|
242
269
|
}
|
|
243
270
|
|
|
244
271
|
#addPreLeaveEvent() {
|
|
245
|
-
this.#mouseLeaveEvent ??= this.$.eventManager.addEvent(
|
|
272
|
+
this.#mouseLeaveEvent ??= this.$.eventManager.addEvent(
|
|
273
|
+
this.#hoverCurrentPre,
|
|
274
|
+
'mouseleave',
|
|
275
|
+
this.#removeEventFunc,
|
|
276
|
+
);
|
|
246
277
|
}
|
|
247
278
|
|
|
248
279
|
#addCtrlLeaveEvent() {
|
|
249
|
-
this.#mouseLeaveEvent ??= this.$.eventManager.addEvent(
|
|
280
|
+
this.#mouseLeaveEvent ??= this.$.eventManager.addEvent(
|
|
281
|
+
this.#hoverController.form,
|
|
282
|
+
'mouseleave',
|
|
283
|
+
this.#removeEventFunc,
|
|
284
|
+
);
|
|
250
285
|
}
|
|
251
286
|
|
|
252
287
|
#buildHoverMenu(currentLang) {
|
|
@@ -271,7 +306,10 @@ class CodeBlock extends PluginCommand {
|
|
|
271
306
|
* @returns {string}
|
|
272
307
|
*/
|
|
273
308
|
#getPreLang(preOrChild) {
|
|
274
|
-
const pre =
|
|
309
|
+
const pre =
|
|
310
|
+
preOrChild?.nodeName === 'PRE'
|
|
311
|
+
? preOrChild
|
|
312
|
+
: dom.query.getParentElement(preOrChild, (el) => /^PRE$/i.test(el.nodeName));
|
|
275
313
|
if (!pre) return '';
|
|
276
314
|
return /** @type {HTMLElement} */ (pre).className.match(/language-(\S+)/)?.[1] || '';
|
|
277
315
|
}
|
|
@@ -62,17 +62,29 @@ class ExportPDF extends PluginCommand {
|
|
|
62
62
|
let ww = null;
|
|
63
63
|
|
|
64
64
|
try {
|
|
65
|
-
const standardWW =
|
|
65
|
+
const standardWW =
|
|
66
|
+
this.$.frameContext.get('documentTypePageMirror') || this.$.frameContext.get('wysiwygFrame');
|
|
66
67
|
|
|
67
68
|
// Strip theme class so getComputedStyle resolves default (light) colors for borders, shadows, etc.
|
|
68
69
|
const themeClass = (this.$.options.get('_themeClass') || '').trim();
|
|
69
70
|
const wwClassName = themeClass ? standardWW.className.replace(themeClass, '').trim() : standardWW.className;
|
|
70
71
|
const editableDiv = dom.utils.createElement('div', { class: wwClassName }, standardWW.innerHTML);
|
|
71
|
-
ww = dom.utils.createElement(
|
|
72
|
+
ww = dom.utils.createElement(
|
|
73
|
+
'div',
|
|
74
|
+
{
|
|
75
|
+
style: `position: absolute; top: -10000px; left: -10000px; width: 21cm; columns: 21cm; height: auto;`,
|
|
76
|
+
},
|
|
77
|
+
editableDiv,
|
|
78
|
+
);
|
|
72
79
|
|
|
73
80
|
const innerPadding = _w.getComputedStyle(standardWW).padding;
|
|
74
81
|
const inlineWW = dom.utils.applyInlineStylesAll(editableDiv, true, this.$.options.get('allUsedStyles'));
|
|
75
|
-
inlineWW.style.padding =
|
|
82
|
+
inlineWW.style.padding =
|
|
83
|
+
inlineWW.style.paddingTop =
|
|
84
|
+
inlineWW.style.paddingBottom =
|
|
85
|
+
inlineWW.style.paddingLeft =
|
|
86
|
+
inlineWW.style.paddingRight =
|
|
87
|
+
'0';
|
|
76
88
|
|
|
77
89
|
ww.innerHTML = `
|
|
78
90
|
<style>
|
|
@@ -129,7 +141,11 @@ class ExportPDF extends PluginCommand {
|
|
|
129
141
|
const contentDisposition = xhr.getResponseHeader('Content-Disposition');
|
|
130
142
|
const downloadUrl = URL.createObjectURL(blob);
|
|
131
143
|
const filename = (contentDisposition.match(/filename="([^"]+)/) || [])[1] || this.fileName + '.pdf';
|
|
132
|
-
const a = dom.utils.createElement(
|
|
144
|
+
const a = dom.utils.createElement(
|
|
145
|
+
'A',
|
|
146
|
+
{ href: downloadUrl, download: filename, style: 'display: none;' },
|
|
147
|
+
null,
|
|
148
|
+
);
|
|
133
149
|
|
|
134
150
|
try {
|
|
135
151
|
_d.body.appendChild(a);
|
|
@@ -69,7 +69,8 @@ class FileUpload extends PluginCommand {
|
|
|
69
69
|
this.title = this.$.lang.fileUpload;
|
|
70
70
|
this.icon = 'file_upload';
|
|
71
71
|
|
|
72
|
-
if (!pluginOptions.uploadUrl)
|
|
72
|
+
if (!pluginOptions.uploadUrl)
|
|
73
|
+
console.warn('[SUNEDITOR.fileUpload.warn] "fileUpload" plugin must be have "uploadUrl" option.');
|
|
73
74
|
|
|
74
75
|
// members
|
|
75
76
|
this.uploadUrl = pluginOptions.uploadUrl;
|
|
@@ -77,7 +78,8 @@ class FileUpload extends PluginCommand {
|
|
|
77
78
|
this.uploadSizeLimit = numbers.get(pluginOptions.uploadSizeLimit, 0);
|
|
78
79
|
this.uploadSingleSizeLimit = numbers.get(pluginOptions.uploadSingleSizeLimit, 0);
|
|
79
80
|
this.allowMultiple = !!pluginOptions.allowMultiple;
|
|
80
|
-
this.acceptedFormats =
|
|
81
|
+
this.acceptedFormats =
|
|
82
|
+
typeof pluginOptions.acceptedFormats !== 'string' ? '*' : pluginOptions.acceptedFormats.trim() || '*';
|
|
81
83
|
this.as = pluginOptions.as || 'box';
|
|
82
84
|
this.insertBehavior = pluginOptions.insertBehavior;
|
|
83
85
|
this.input = dom.utils.createElement('input', { type: 'file', accept: this.acceptedFormats });
|
|
@@ -109,7 +111,9 @@ class FileUpload extends PluginCommand {
|
|
|
109
111
|
},
|
|
110
112
|
};
|
|
111
113
|
|
|
112
|
-
const figureControls = (
|
|
114
|
+
const figureControls = (
|
|
115
|
+
pluginOptions.controls || [['custom-as', 'align', 'edit', 'custom-download', 'copy', 'remove']]
|
|
116
|
+
).map((subArray) => subArray.map((item) => (item.startsWith('custom-') ? customItems[item] : item)));
|
|
113
117
|
this.figure = new Figure(this, this.$, figureControls, {});
|
|
114
118
|
|
|
115
119
|
// file manager
|
|
@@ -122,7 +126,13 @@ class FileUpload extends PluginCommand {
|
|
|
122
126
|
// controller
|
|
123
127
|
if (/\bedit\b/.test(JSON.stringify(figureControls))) {
|
|
124
128
|
const controllerEl = CreateHTML_controller(this.$);
|
|
125
|
-
this.controller = new Controller(
|
|
129
|
+
this.controller = new Controller(
|
|
130
|
+
this,
|
|
131
|
+
this.$,
|
|
132
|
+
controllerEl,
|
|
133
|
+
{ position: 'bottom', disabled: true },
|
|
134
|
+
FileUpload.key,
|
|
135
|
+
);
|
|
126
136
|
this.editInput = controllerEl.querySelector('input');
|
|
127
137
|
}
|
|
128
138
|
|
|
@@ -188,7 +198,13 @@ class FileUpload extends PluginCommand {
|
|
|
188
198
|
if (dom.check.isFigure(target.parentElement)) {
|
|
189
199
|
asBtn.innerHTML = this.$.icons.reduction + dom.utils.createTooltipInner(this.$.lang.asLink);
|
|
190
200
|
asBtn.setAttribute('data-value', 'link');
|
|
191
|
-
this.figure.open(target, {
|
|
201
|
+
this.figure.open(target, {
|
|
202
|
+
nonResizing: true,
|
|
203
|
+
nonSizeInfo: true,
|
|
204
|
+
nonBorder: true,
|
|
205
|
+
figureTarget: true,
|
|
206
|
+
infoOnly: false,
|
|
207
|
+
});
|
|
192
208
|
} else {
|
|
193
209
|
asBtn.innerHTML = this.$.icons.expansion + dom.utils.createTooltipInner(this.$.lang.asBlock);
|
|
194
210
|
asBtn.setAttribute('data-value', 'box');
|
|
@@ -204,7 +220,11 @@ class FileUpload extends PluginCommand {
|
|
|
204
220
|
componentEdit(target) {
|
|
205
221
|
this.editInput.value = target.textContent;
|
|
206
222
|
this.figure.controllerHide();
|
|
207
|
-
this.controller.open(target, null, {
|
|
223
|
+
this.controller.open(target, null, {
|
|
224
|
+
isWWTarget: !dom.check.isFigure(target.parentElement),
|
|
225
|
+
initMethod: null,
|
|
226
|
+
addOffset: null,
|
|
227
|
+
});
|
|
208
228
|
this.editInput.focus();
|
|
209
229
|
}
|
|
210
230
|
|
|
@@ -218,11 +238,17 @@ class FileUpload extends PluginCommand {
|
|
|
218
238
|
const figure = Figure.GetContainer(target);
|
|
219
239
|
const containerTarget = dom.query.getParentElement(target, '.se-component') || target;
|
|
220
240
|
|
|
221
|
-
const message = await this.$.eventManager.triggerEvent('onFileDeleteBefore', {
|
|
241
|
+
const message = await this.$.eventManager.triggerEvent('onFileDeleteBefore', {
|
|
242
|
+
element: figure.target,
|
|
243
|
+
container: figure,
|
|
244
|
+
url: figure.target.getAttribute('href'),
|
|
245
|
+
});
|
|
222
246
|
if (message === false) return;
|
|
223
247
|
|
|
224
248
|
const isInlineComp = this.$.component.isInline(containerTarget);
|
|
225
|
-
const focusEl = isInlineComp
|
|
249
|
+
const focusEl = isInlineComp
|
|
250
|
+
? containerTarget.previousSibling || containerTarget.nextSibling
|
|
251
|
+
: containerTarget.previousElementSibling || containerTarget.nextElementSibling;
|
|
226
252
|
dom.utils.removeItem(containerTarget);
|
|
227
253
|
this.$.ui.offCurrentController();
|
|
228
254
|
|
|
@@ -245,7 +271,8 @@ class FileUpload extends PluginCommand {
|
|
|
245
271
|
f = fileList[i];
|
|
246
272
|
s = f.size;
|
|
247
273
|
if (slngleSizeLimit > 0 && s > slngleSizeLimit) {
|
|
248
|
-
const err =
|
|
274
|
+
const err =
|
|
275
|
+
'[SUNEDITOR.fileUpload.fail] Size of uploadable single file: ' + slngleSizeLimit / 1000 + 'KB';
|
|
249
276
|
const message = await this.$.eventManager.triggerEvent('onFileUploadError', {
|
|
250
277
|
error: err,
|
|
251
278
|
limitSize: slngleSizeLimit,
|
|
@@ -369,14 +396,22 @@ class FileUpload extends PluginCommand {
|
|
|
369
396
|
|
|
370
397
|
if (this.as === 'link') {
|
|
371
398
|
a.className = 'se-component se-inline-component';
|
|
372
|
-
this.$.component.insert(a, {
|
|
399
|
+
this.$.component.insert(a, {
|
|
400
|
+
scrollTo: isLast ? true : false,
|
|
401
|
+
insertBehavior: isLast ? this.insertBehavior : null,
|
|
402
|
+
});
|
|
373
403
|
return;
|
|
374
404
|
}
|
|
375
405
|
|
|
376
406
|
const figure = Figure.CreateContainer(a);
|
|
377
407
|
dom.utils.addClass(figure.container, 'se-file-figure|se-flex-component');
|
|
378
408
|
|
|
379
|
-
if (
|
|
409
|
+
if (
|
|
410
|
+
!this.$.component.insert(figure.container, {
|
|
411
|
+
scrollTo: isLast ? true : false,
|
|
412
|
+
insertBehavior: isLast ? this.insertBehavior : null,
|
|
413
|
+
})
|
|
414
|
+
) {
|
|
380
415
|
this.$.focusManager.focus();
|
|
381
416
|
return;
|
|
382
417
|
}
|
|
@@ -27,7 +27,12 @@ class List_bulleted extends PluginCommand {
|
|
|
27
27
|
this.icon = 'list_bulleted';
|
|
28
28
|
this.afterItem = dom.utils.createElement(
|
|
29
29
|
'button',
|
|
30
|
-
{
|
|
30
|
+
{
|
|
31
|
+
class: 'se-btn se-tooltip se-sub-arrow-btn',
|
|
32
|
+
type: 'button',
|
|
33
|
+
'data-command': List_bulleted.key,
|
|
34
|
+
'data-type': 'dropdown',
|
|
35
|
+
},
|
|
31
36
|
`${this.$.icons.arrow_down}<span class="se-tooltip-inner"><span class="se-tooltip-text">${this.$.lang.bulletedList}</span></span>`,
|
|
32
37
|
);
|
|
33
38
|
|
|
@@ -27,7 +27,12 @@ class List_numbered extends PluginCommand {
|
|
|
27
27
|
this.icon = 'list_numbered';
|
|
28
28
|
this.afterItem = dom.utils.createElement(
|
|
29
29
|
'button',
|
|
30
|
-
{
|
|
30
|
+
{
|
|
31
|
+
class: 'se-btn se-tooltip se-sub-arrow-btn',
|
|
32
|
+
type: 'button',
|
|
33
|
+
'data-command': List_numbered.key,
|
|
34
|
+
'data-type': 'dropdown',
|
|
35
|
+
},
|
|
31
36
|
`${this.$.icons.arrow_down}<span class="se-tooltip-inner"><span class="se-tooltip-text">${this.$.lang.numberedList}</span></span>`,
|
|
32
37
|
);
|
|
33
38
|
|
|
@@ -23,10 +23,6 @@ class Align extends PluginDropdown {
|
|
|
23
23
|
this.title = this.$.lang.align;
|
|
24
24
|
this.icon = this.$.options.get('_rtl') ? 'align_right' : 'align_left';
|
|
25
25
|
|
|
26
|
-
// create HTML
|
|
27
|
-
const menu = CreateHTML(this.$, pluginOptions.items);
|
|
28
|
-
const commandArea = (this._itemMenu = menu.querySelector('ul'));
|
|
29
|
-
|
|
30
26
|
// members
|
|
31
27
|
this.defaultDir = '';
|
|
32
28
|
this.alignIcons = {
|
|
@@ -35,10 +31,13 @@ class Align extends PluginDropdown {
|
|
|
35
31
|
right: this.$.icons.align_right,
|
|
36
32
|
center: this.$.icons.align_center,
|
|
37
33
|
};
|
|
38
|
-
this.alignList = commandArea.querySelectorAll('li button');
|
|
39
34
|
|
|
40
|
-
//
|
|
41
|
-
this.$.menu.initDropdownTarget(Align,
|
|
35
|
+
// create menu from items
|
|
36
|
+
const menu = this.$.menu.initDropdownTarget(Align, CreateItems(this.$, pluginOptions.items), {
|
|
37
|
+
className: 'se-list-align',
|
|
38
|
+
});
|
|
39
|
+
this._itemMenu = menu.querySelector('ul');
|
|
40
|
+
this.alignList = menu.querySelectorAll('li button');
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
/**
|
|
@@ -139,33 +138,22 @@ class Align extends PluginDropdown {
|
|
|
139
138
|
/**
|
|
140
139
|
* @param {SunEditor.Deps} $ - Kernel dependencies
|
|
141
140
|
* @param {string[]} [items] - Align items list
|
|
142
|
-
* @returns {
|
|
141
|
+
* @returns {Array<import('../../core/logic/panel/menu').DropdownItem>}
|
|
143
142
|
*/
|
|
144
|
-
function
|
|
145
|
-
const alignItems = Array.isArray(items)
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
</
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return dom.utils.createElement(
|
|
160
|
-
'div',
|
|
161
|
-
{
|
|
162
|
-
class: 'se-dropdown se-list-layer se-list-align',
|
|
163
|
-
},
|
|
164
|
-
/*html*/ `
|
|
165
|
-
<div class="se-list-inner">
|
|
166
|
-
<ul class="se-list-basic">${html}</ul>
|
|
167
|
-
</div>`,
|
|
168
|
-
);
|
|
143
|
+
function CreateItems({ lang, icons, options }, items) {
|
|
144
|
+
const alignItems = Array.isArray(items)
|
|
145
|
+
? items
|
|
146
|
+
: options.get('_rtl')
|
|
147
|
+
? ['right', 'center', 'left', 'justify']
|
|
148
|
+
: ['left', 'center', 'right', 'justify'];
|
|
149
|
+
return alignItems.map((item) => {
|
|
150
|
+
const text = lang['align' + item.charAt(0).toUpperCase() + item.slice(1)];
|
|
151
|
+
return {
|
|
152
|
+
command: item,
|
|
153
|
+
title: text,
|
|
154
|
+
innerHTML: `<span class="se-list-icon">${icons['align_' + item]}</span>${text}`,
|
|
155
|
+
};
|
|
156
|
+
});
|
|
169
157
|
}
|
|
170
158
|
|
|
171
159
|
export default Align;
|
|
@@ -92,9 +92,17 @@ class BackgroundColor extends PluginDropdownFree {
|
|
|
92
92
|
colorPickerAction(color) {
|
|
93
93
|
if (color) {
|
|
94
94
|
const newNode = dom.utils.createElement('SPAN', { style: 'background-color: ' + color + ';' });
|
|
95
|
-
this.$.inline.apply(newNode, {
|
|
95
|
+
this.$.inline.apply(newNode, {
|
|
96
|
+
stylesToModify: ['background-color'],
|
|
97
|
+
nodesToRemove: null,
|
|
98
|
+
strictRemove: null,
|
|
99
|
+
});
|
|
96
100
|
} else {
|
|
97
|
-
this.$.inline.apply(null, {
|
|
101
|
+
this.$.inline.apply(null, {
|
|
102
|
+
stylesToModify: ['background-color'],
|
|
103
|
+
nodesToRemove: ['span'],
|
|
104
|
+
strictRemove: true,
|
|
105
|
+
});
|
|
98
106
|
}
|
|
99
107
|
|
|
100
108
|
this.$.menu.dropdownOff();
|
|
@@ -35,15 +35,14 @@ class BlockStyle extends PluginDropdown {
|
|
|
35
35
|
this.title = this.$.lang.formats;
|
|
36
36
|
this.inner = '<span class="se-txt">' + this.$.lang.formats + '</span>' + this.$.icons.arrow_down;
|
|
37
37
|
|
|
38
|
-
// create
|
|
39
|
-
const menu =
|
|
38
|
+
// create menu from items
|
|
39
|
+
const menu = this.$.menu.initDropdownTarget(BlockStyle, CreateItems(this.$, pluginOptions.items), {
|
|
40
|
+
className: 'se-list-format',
|
|
41
|
+
});
|
|
40
42
|
|
|
41
43
|
// members
|
|
42
44
|
this.formatList = menu.querySelectorAll('li button');
|
|
43
45
|
this.currentFormat = '';
|
|
44
|
-
|
|
45
|
-
// init
|
|
46
|
-
this.$.menu.initDropdownTarget(BlockStyle, menu);
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
/**
|
|
@@ -86,7 +85,8 @@ class BlockStyle extends PluginDropdown {
|
|
|
86
85
|
on(target) {
|
|
87
86
|
const formatList = this.formatList;
|
|
88
87
|
const targetText = target.querySelector('.se-txt');
|
|
89
|
-
const currentFormat =
|
|
88
|
+
const currentFormat =
|
|
89
|
+
(targetText.getAttribute('data-value') || '') + (targetText.getAttribute('data-class') || '');
|
|
90
90
|
|
|
91
91
|
if (currentFormat !== this.currentFormat) {
|
|
92
92
|
for (let i = 0, len = formatList.length, f; i < len; i++) {
|
|
@@ -136,15 +136,12 @@ class BlockStyle extends PluginDropdown {
|
|
|
136
136
|
/**
|
|
137
137
|
* @param {SunEditor.Deps} $ - Kernel dependencies
|
|
138
138
|
* @param {Array<string|BlockStyleItem>} [items] - Block style items
|
|
139
|
-
* @returns {
|
|
139
|
+
* @returns {Array<import('../../core/logic/panel/menu').DropdownItem>}
|
|
140
140
|
*/
|
|
141
|
-
function
|
|
141
|
+
function CreateItems({ lang }, items) {
|
|
142
142
|
const defaultFormats = ['p', 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
|
143
143
|
const formatList = !items || items.length === 0 ? defaultFormats : items;
|
|
144
|
-
|
|
145
|
-
let list = /*html*/ `
|
|
146
|
-
<div class="se-list-inner">
|
|
147
|
-
<ul class="se-list-basic">`;
|
|
144
|
+
const result = [];
|
|
148
145
|
|
|
149
146
|
for (let i = 0, len = formatList.length, format, tagName, command, name, h, attrs, className; i < len; i++) {
|
|
150
147
|
format = formatList[i];
|
|
@@ -165,18 +162,16 @@ function CreateHTML({ lang }, items) {
|
|
|
165
162
|
attrs = className ? ' class="' + className + '"' : '';
|
|
166
163
|
}
|
|
167
164
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
165
|
+
result.push({
|
|
166
|
+
command,
|
|
167
|
+
value: tagName,
|
|
168
|
+
title: name,
|
|
169
|
+
innerHTML: `<${tagName}${attrs}>${name}</${tagName}>`,
|
|
170
|
+
attrs: { 'data-class': className || '' },
|
|
171
|
+
});
|
|
174
172
|
}
|
|
175
|
-
list += /*html*/ `
|
|
176
|
-
</ul>
|
|
177
|
-
</div>`;
|
|
178
173
|
|
|
179
|
-
return
|
|
174
|
+
return result;
|
|
180
175
|
}
|
|
181
176
|
|
|
182
177
|
export default BlockStyle;
|