suneditor 3.0.0-alpha.9 → 3.0.0-beta.2
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/CONTRIBUTING.md +170 -22
- package/{LICENSE.txt → LICENSE} +9 -9
- package/README.md +168 -30
- package/dist/suneditor.min.css +1 -1
- package/dist/suneditor.min.js +1 -1
- package/package.json +47 -21
- package/src/assets/design/color.css +121 -0
- package/src/assets/design/index.css +3 -0
- package/src/assets/design/size.css +35 -0
- package/src/assets/design/typography.css +37 -0
- package/src/assets/icons/defaultIcons.js +232 -0
- package/src/assets/suneditor-contents.css +181 -46
- package/src/assets/suneditor.css +1403 -650
- package/src/core/base/eventHandlers/handler_toolbar.js +35 -14
- package/src/core/base/eventHandlers/handler_ww_clipboard.js +23 -4
- package/src/core/base/eventHandlers/handler_ww_dragDrop.js +49 -10
- package/src/core/base/eventHandlers/handler_ww_key_input.js +422 -224
- package/src/core/base/eventHandlers/handler_ww_mouse.js +83 -36
- package/src/core/base/eventManager.js +520 -179
- package/src/core/base/history.js +95 -41
- package/src/core/class/char.js +26 -11
- package/src/core/class/component.js +345 -137
- package/src/core/class/format.js +683 -519
- package/src/core/class/html.js +485 -305
- package/src/core/class/menu.js +133 -47
- package/src/core/class/nodeTransform.js +90 -71
- package/src/core/class/offset.js +408 -92
- package/src/core/class/selection.js +216 -106
- package/src/core/class/shortcuts.js +68 -8
- package/src/core/class/toolbar.js +106 -116
- package/src/core/class/ui.js +422 -0
- package/src/core/class/viewer.js +178 -74
- package/src/core/editor.js +496 -389
- package/src/core/section/actives.js +123 -27
- package/src/core/section/constructor.js +615 -206
- package/src/core/section/context.js +28 -23
- package/src/core/section/documentType.js +561 -0
- package/src/editorInjector/_classes.js +19 -5
- package/src/editorInjector/_core.js +71 -7
- package/src/editorInjector/index.js +63 -1
- package/src/events.js +622 -0
- package/src/helper/clipboard.js +59 -0
- package/src/helper/converter.js +202 -26
- package/src/helper/dom/domCheck.js +304 -0
- package/src/helper/dom/domQuery.js +669 -0
- package/src/helper/dom/domUtils.js +557 -0
- package/src/helper/dom/index.js +12 -0
- package/src/helper/env.js +46 -56
- package/src/helper/index.js +10 -4
- package/src/helper/keyCodeMap.js +183 -0
- package/src/helper/numbers.js +12 -8
- package/src/helper/unicode.js +9 -5
- package/src/langs/ckb.js +74 -4
- package/src/langs/cs.js +72 -2
- package/src/langs/da.js +73 -3
- package/src/langs/de.js +73 -4
- package/src/langs/en.js +23 -3
- package/src/langs/es.js +73 -4
- package/src/langs/fa.js +75 -3
- package/src/langs/fr.js +73 -3
- package/src/langs/he.js +73 -4
- package/src/langs/hu.js +230 -0
- package/src/langs/index.js +7 -3
- package/src/langs/it.js +70 -1
- package/src/langs/ja.js +72 -4
- package/src/langs/km.js +230 -0
- package/src/langs/ko.js +22 -2
- package/src/langs/lv.js +74 -5
- package/src/langs/nl.js +73 -4
- package/src/langs/pl.js +73 -4
- package/src/langs/pt_br.js +70 -1
- package/src/langs/ro.js +74 -5
- package/src/langs/ru.js +73 -4
- package/src/langs/se.js +73 -4
- package/src/langs/tr.js +73 -1
- package/src/langs/{ua.js → uk.js} +75 -6
- package/src/langs/ur.js +77 -8
- package/src/langs/zh_cn.js +74 -5
- package/src/modules/ApiManager.js +77 -54
- package/src/modules/Browser.js +667 -0
- package/src/modules/ColorPicker.js +162 -102
- package/src/modules/Controller.js +273 -142
- package/src/modules/Figure.js +925 -484
- package/src/modules/FileManager.js +121 -69
- package/src/modules/HueSlider.js +113 -61
- package/src/modules/Modal.js +291 -122
- package/src/modules/ModalAnchorEditor.js +383 -234
- package/src/modules/SelectMenu.js +270 -168
- package/src/modules/_DragHandle.js +2 -1
- package/src/modules/index.js +3 -3
- package/src/plugins/browser/audioGallery.js +83 -0
- package/src/plugins/browser/fileBrowser.js +103 -0
- package/src/plugins/browser/fileGallery.js +83 -0
- package/src/plugins/browser/imageGallery.js +81 -0
- package/src/plugins/browser/videoGallery.js +103 -0
- package/src/plugins/command/blockquote.js +40 -27
- package/src/plugins/command/exportPDF.js +134 -0
- package/src/plugins/command/fileUpload.js +229 -162
- package/src/plugins/command/list_bulleted.js +83 -47
- package/src/plugins/command/list_numbered.js +83 -47
- package/src/plugins/dropdown/align.js +66 -54
- package/src/plugins/dropdown/backgroundColor.js +63 -49
- package/src/plugins/dropdown/font.js +71 -47
- package/src/plugins/dropdown/fontColor.js +63 -48
- package/src/plugins/dropdown/formatBlock.js +70 -33
- package/src/plugins/dropdown/hr.js +92 -51
- package/src/plugins/dropdown/layout.js +37 -26
- package/src/plugins/dropdown/lineHeight.js +54 -38
- package/src/plugins/dropdown/list.js +60 -45
- package/src/plugins/dropdown/paragraphStyle.js +51 -30
- package/src/plugins/dropdown/table.js +2003 -813
- package/src/plugins/dropdown/template.js +38 -26
- package/src/plugins/dropdown/textStyle.js +43 -31
- package/src/plugins/field/mention.js +147 -86
- package/src/plugins/index.js +32 -6
- package/src/plugins/input/fontSize.js +161 -108
- package/src/plugins/input/pageNavigator.js +70 -0
- package/src/plugins/modal/audio.js +358 -173
- package/src/plugins/modal/drawing.js +531 -0
- package/src/plugins/modal/embed.js +886 -0
- package/src/plugins/modal/image.js +674 -362
- package/src/plugins/modal/link.js +100 -71
- package/src/plugins/modal/math.js +367 -167
- package/src/plugins/modal/video.js +691 -335
- package/src/plugins/popup/anchor.js +222 -0
- package/src/suneditor.js +50 -13
- package/src/themes/dark.css +122 -0
- package/src/typedef.js +130 -0
- package/types/assets/icons/defaultIcons.d.ts +153 -0
- package/types/core/base/eventHandlers/handler_toolbar.d.ts +41 -0
- package/types/core/base/eventHandlers/handler_ww_clipboard.d.ts +40 -0
- package/types/core/base/eventHandlers/handler_ww_dragDrop.d.ts +35 -0
- package/types/core/base/eventHandlers/handler_ww_key_input.d.ts +45 -0
- package/types/core/base/eventHandlers/handler_ww_mouse.d.ts +39 -0
- package/types/core/base/eventManager.d.ts +385 -0
- package/types/core/base/history.d.ts +81 -0
- package/types/core/class/char.d.ts +60 -0
- package/types/core/class/component.d.ts +212 -0
- package/types/core/class/format.d.ts +616 -0
- package/types/core/class/html.d.ts +422 -0
- package/types/core/class/menu.d.ts +126 -0
- package/types/core/class/nodeTransform.d.ts +93 -0
- package/types/core/class/offset.d.ts +522 -0
- package/types/core/class/selection.d.ts +188 -0
- package/types/core/class/shortcuts.d.ts +142 -0
- package/types/core/class/toolbar.d.ts +189 -0
- package/types/core/class/ui.d.ts +164 -0
- package/types/core/class/viewer.d.ts +140 -0
- package/types/core/editor.d.ts +610 -0
- package/types/core/section/actives.d.ts +46 -0
- package/types/core/section/constructor.d.ts +777 -0
- package/types/core/section/context.d.ts +45 -0
- package/types/core/section/documentType.d.ts +178 -0
- package/types/editorInjector/_classes.d.ts +41 -0
- package/types/editorInjector/_core.d.ts +92 -0
- package/types/editorInjector/index.d.ts +71 -0
- package/types/events.d.ts +273 -0
- package/types/helper/clipboard.d.ts +12 -0
- package/types/helper/converter.d.ts +197 -0
- package/types/helper/dom/domCheck.d.ts +189 -0
- package/types/helper/dom/domQuery.d.ts +223 -0
- package/types/helper/dom/domUtils.d.ts +226 -0
- package/types/helper/dom/index.d.ts +9 -0
- package/types/helper/env.d.ts +132 -0
- package/types/helper/index.d.ts +174 -0
- package/types/helper/keyCodeMap.d.ts +110 -0
- package/types/helper/numbers.d.ts +46 -0
- package/types/helper/unicode.d.ts +28 -0
- package/types/index.d.ts +120 -0
- package/{typings/Lang.d.ts → types/langs/_Lang.d.ts} +173 -103
- package/types/langs/ckb.d.ts +3 -0
- package/types/langs/cs.d.ts +3 -0
- package/types/langs/da.d.ts +3 -0
- package/types/langs/de.d.ts +3 -0
- package/types/langs/en.d.ts +3 -0
- package/types/langs/es.d.ts +3 -0
- package/types/langs/fa.d.ts +3 -0
- package/types/langs/fr.d.ts +3 -0
- package/types/langs/he.d.ts +3 -0
- package/types/langs/hu.d.ts +3 -0
- package/types/langs/index.d.ts +54 -0
- package/types/langs/it.d.ts +3 -0
- package/types/langs/ja.d.ts +3 -0
- package/types/langs/km.d.ts +3 -0
- package/types/langs/ko.d.ts +3 -0
- package/types/langs/lv.d.ts +3 -0
- package/types/langs/nl.d.ts +3 -0
- package/types/langs/pl.d.ts +3 -0
- package/types/langs/pt_br.d.ts +3 -0
- package/types/langs/ro.d.ts +3 -0
- package/types/langs/ru.d.ts +3 -0
- package/types/langs/se.d.ts +3 -0
- package/types/langs/tr.d.ts +3 -0
- package/types/langs/uk.d.ts +3 -0
- package/types/langs/ur.d.ts +3 -0
- package/types/langs/zh_cn.d.ts +3 -0
- package/types/modules/ApiManager.d.ts +125 -0
- package/types/modules/Browser.d.ts +326 -0
- package/types/modules/ColorPicker.d.ts +131 -0
- package/types/modules/Controller.d.ts +251 -0
- package/types/modules/Figure.d.ts +517 -0
- package/types/modules/FileManager.d.ts +202 -0
- package/types/modules/HueSlider.d.ts +136 -0
- package/types/modules/Modal.d.ts +111 -0
- package/types/modules/ModalAnchorEditor.d.ts +236 -0
- package/types/modules/SelectMenu.d.ts +194 -0
- package/types/modules/_DragHandle.d.ts +7 -0
- package/types/modules/index.d.ts +26 -0
- package/types/plugins/browser/audioGallery.d.ts +55 -0
- package/types/plugins/browser/fileBrowser.d.ts +64 -0
- package/types/plugins/browser/fileGallery.d.ts +55 -0
- package/types/plugins/browser/imageGallery.d.ts +51 -0
- package/types/plugins/browser/videoGallery.d.ts +57 -0
- package/types/plugins/command/blockquote.d.ts +28 -0
- package/types/plugins/command/exportPDF.d.ts +46 -0
- package/types/plugins/command/fileUpload.d.ts +156 -0
- package/types/plugins/command/list_bulleted.d.ts +46 -0
- package/types/plugins/command/list_numbered.d.ts +46 -0
- package/types/plugins/dropdown/align.d.ts +60 -0
- package/types/plugins/dropdown/backgroundColor.d.ts +63 -0
- package/types/plugins/dropdown/font.d.ts +54 -0
- package/types/plugins/dropdown/fontColor.d.ts +63 -0
- package/types/plugins/dropdown/formatBlock.d.ts +54 -0
- package/types/plugins/dropdown/hr.d.ts +71 -0
- package/types/plugins/dropdown/layout.d.ts +40 -0
- package/types/plugins/dropdown/lineHeight.d.ts +50 -0
- package/types/plugins/dropdown/list.d.ts +39 -0
- package/types/plugins/dropdown/paragraphStyle.d.ts +54 -0
- package/types/plugins/dropdown/table.d.ts +627 -0
- package/types/plugins/dropdown/template.d.ts +40 -0
- package/types/plugins/dropdown/textStyle.d.ts +41 -0
- package/types/plugins/field/mention.d.ts +102 -0
- package/types/plugins/index.d.ts +107 -0
- package/types/plugins/input/fontSize.d.ts +170 -0
- package/types/plugins/input/pageNavigator.d.ts +28 -0
- package/types/plugins/modal/audio.d.ts +269 -0
- package/types/plugins/modal/drawing.d.ts +246 -0
- package/types/plugins/modal/embed.d.ts +387 -0
- package/types/plugins/modal/image.d.ts +451 -0
- package/types/plugins/modal/link.d.ts +128 -0
- package/types/plugins/modal/math.d.ts +193 -0
- package/types/plugins/modal/video.d.ts +485 -0
- package/types/plugins/popup/anchor.d.ts +56 -0
- package/types/suneditor.d.ts +51 -0
- package/types/typedef.d.ts +233 -0
- package/.eslintignore +0 -7
- package/.eslintrc.json +0 -64
- package/src/assets/icons/_default.js +0 -194
- package/src/core/base/events.js +0 -320
- package/src/core/class/notice.js +0 -42
- package/src/helper/domUtils.js +0 -1177
- package/src/modules/FileBrowser.js +0 -271
- package/src/plugins/command/exportPdf.js +0 -168
- package/src/plugins/fileBrowser/imageGallery.js +0 -81
- package/src/themes/test.css +0 -61
- package/typings/CommandPlugin.d.ts +0 -8
- package/typings/DialogPlugin.d.ts +0 -20
- package/typings/FileBrowserPlugin.d.ts +0 -30
- package/typings/Module.d.ts +0 -15
- package/typings/Plugin.d.ts +0 -42
- package/typings/SubmenuPlugin.d.ts +0 -8
- package/typings/_classes.d.ts +0 -17
- package/typings/_colorPicker.d.ts +0 -60
- package/typings/_core.d.ts +0 -55
- package/typings/align.d.ts +0 -5
- package/typings/audio.d.ts +0 -5
- package/typings/backgroundColor.d.ts +0 -5
- package/typings/blockquote.d.ts +0 -5
- package/typings/char.d.ts +0 -39
- package/typings/component.d.ts +0 -38
- package/typings/context.d.ts +0 -39
- package/typings/converter.d.ts +0 -33
- package/typings/dialog.d.ts +0 -28
- package/typings/domUtils.d.ts +0 -361
- package/typings/editor.d.ts +0 -7
- package/typings/editor.ts +0 -542
- package/typings/env.d.ts +0 -70
- package/typings/eventManager.d.ts +0 -37
- package/typings/events.d.ts +0 -262
- package/typings/fileBrowser.d.ts +0 -42
- package/typings/fileManager.d.ts +0 -67
- package/typings/font.d.ts +0 -5
- package/typings/fontColor.d.ts +0 -5
- package/typings/fontSize.d.ts +0 -5
- package/typings/format.d.ts +0 -191
- package/typings/formatBlock.d.ts +0 -5
- package/typings/history.d.ts +0 -48
- package/typings/horizontalRule.d.ts +0 -5
- package/typings/image.d.ts +0 -5
- package/typings/imageGallery.d.ts +0 -5
- package/typings/index.d.ts +0 -21
- package/typings/index.modules.d.ts +0 -11
- package/typings/index.plugins.d.ts +0 -58
- package/typings/lineHeight.d.ts +0 -5
- package/typings/link.d.ts +0 -5
- package/typings/list.d.ts +0 -5
- package/typings/math.d.ts +0 -5
- package/typings/mediaContainer.d.ts +0 -25
- package/typings/mention.d.ts +0 -5
- package/typings/node.d.ts +0 -57
- package/typings/notice.d.ts +0 -16
- package/typings/numbers.d.ts +0 -29
- package/typings/offset.d.ts +0 -24
- package/typings/options.d.ts +0 -589
- package/typings/paragraphStyle.d.ts +0 -5
- package/typings/resizing.d.ts +0 -141
- package/typings/selection.d.ts +0 -94
- package/typings/shortcuts.d.ts +0 -13
- package/typings/suneditor.d.ts +0 -9
- package/typings/table.d.ts +0 -5
- package/typings/template.d.ts +0 -5
- package/typings/textStyle.d.ts +0 -5
- package/typings/toolbar.d.ts +0 -32
- package/typings/unicode.d.ts +0 -25
- package/typings/video.d.ts +0 -5
|
@@ -1,122 +1,163 @@
|
|
|
1
1
|
import EditorInjector from '../editorInjector';
|
|
2
2
|
import SelectMenu from './SelectMenu';
|
|
3
3
|
import FileManager from './FileManager';
|
|
4
|
-
import {
|
|
5
|
-
import { CreateTooltipInner } from '../core/section/constructor';
|
|
4
|
+
import { dom, numbers, env, unicode } from '../helper';
|
|
6
5
|
const { NO_EVENT } = env;
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
|
-
* @
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* @
|
|
14
|
-
* @
|
|
15
|
-
* @
|
|
16
|
-
* @
|
|
17
|
-
* @
|
|
18
|
-
|
|
8
|
+
* @typedef {{default?: string, check_new_window?: string, check_bookmark?: string}} RELAttr
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} ModalAnchorEditorParams
|
|
13
|
+
* @property {boolean} [title=false] - Modal title display.
|
|
14
|
+
* @property {boolean} [textToDisplay=''] - Create Text to display input.
|
|
15
|
+
* @property {boolean} [openNewWindow=false] - Default checked value of the "Open in new window" checkbox.
|
|
16
|
+
* @property {boolean} [noAutoPrefix=false] - If true, disables the automatic prefixing of the host URL to the value of the link.
|
|
17
|
+
* @property {Array<string>} [relList=[]] - The "rel" attribute list of anchor tag.
|
|
18
|
+
* @property {RELAttr} [defaultRel={}] - Default "rel" attributes of anchor tag.
|
|
19
|
+
* @property {string=} uploadUrl - File upload URL.
|
|
20
|
+
* @property {Object<string, string>=} uploadHeaders - File upload headers.
|
|
21
|
+
* @property {number=} uploadSizeLimit - File upload size limit.
|
|
22
|
+
* @property {number=} uploadSingleSizeLimit - File upload single size limit.
|
|
23
|
+
* @property {string=} acceptedFormats - File upload accepted formats.
|
|
24
|
+
* @property {boolean=} enableFileUpload - If true, enables file upload.
|
|
25
|
+
* @example "REL" structure
|
|
19
26
|
{
|
|
20
27
|
default: 'nofollow', // Default rel
|
|
21
28
|
check_new_window: 'noreferrer noopener', // When "open new window" is checked
|
|
22
29
|
check_bookmark: 'bookmark' // When "bookmark" is checked
|
|
23
30
|
}
|
|
24
|
-
|
|
31
|
+
If true, disables the automatic prefixing of the host URL to the value of the link.
|
|
25
32
|
*/
|
|
26
|
-
const ModalAnchorEditor = function (inst, modalForm, params) {
|
|
27
|
-
// plugin bisic properties
|
|
28
|
-
EditorInjector.call(this, inst.editor);
|
|
29
|
-
|
|
30
|
-
// params
|
|
31
|
-
this.openNewWindow = !!params.openNewWindow;
|
|
32
|
-
this.relList = Array.isArray(params.relList) ? params.relList : [];
|
|
33
|
-
this.defaultRel = params.defaultRel || {};
|
|
34
|
-
this.noAutoPrefix = !!params.noAutoPrefix;
|
|
35
|
-
// file upload
|
|
36
|
-
if (params.enableFileUpload) {
|
|
37
|
-
this.uploadUrl = typeof params.uploadUrl === 'string' ? params.uploadUrl : null;
|
|
38
|
-
this.uploadHeaders = params.uploadHeaders || null;
|
|
39
|
-
this.uploadSizeLimit = /\d+/.test(params.uploadSizeLimit) ? numbers.get(params.uploadSizeLimit, 0) : null;
|
|
40
|
-
this.uploadSingleSizeLimit = /\d+/.test(params.uploadSingleSizeLimit) ? numbers.get(params.uploadSingleSizeLimit, 0) : null;
|
|
41
|
-
this.input = domUtils.createElement('input', { type: 'file', accept: params.acceptedFormats || '*' });
|
|
42
|
-
this.eventManager.addEvent(this.input, 'change', OnChangeFile.bind(this));
|
|
43
|
-
// file manager
|
|
44
|
-
this.fileManager = new FileManager(this, {
|
|
45
|
-
query: 'a[download]:not([data-se-file-download])',
|
|
46
|
-
loadHandler: this.events.onFileLoad,
|
|
47
|
-
eventHandler: this.events.onFileAction
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
33
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
type: 'button',
|
|
87
|
-
class: 'se-btn-list' + (defaultRel.includes(rel) ? ' se-checked' : ''),
|
|
88
|
-
'data-command': rel,
|
|
89
|
-
title: rel,
|
|
90
|
-
'aria-label': rel
|
|
91
|
-
},
|
|
92
|
-
rel + '<span class="se-svg">' + this.icons.checked + '</span>'
|
|
93
|
-
)
|
|
94
|
-
);
|
|
34
|
+
/**
|
|
35
|
+
* @class
|
|
36
|
+
* @description Modal form Anchor tag editor
|
|
37
|
+
* - Use it by inserting it into Modal in a plugin that uses Modal.
|
|
38
|
+
*/
|
|
39
|
+
class ModalAnchorEditor extends EditorInjector {
|
|
40
|
+
/**
|
|
41
|
+
* @constructor
|
|
42
|
+
* @param {*} inst The instance object that called the constructor.
|
|
43
|
+
* @param {Node} modalForm The modal form element
|
|
44
|
+
* @param {ModalAnchorEditorParams} params ModalAnchorEditor options
|
|
45
|
+
*/
|
|
46
|
+
constructor(inst, modalForm, params) {
|
|
47
|
+
// plugin bisic properties
|
|
48
|
+
super(inst.editor);
|
|
49
|
+
|
|
50
|
+
// params
|
|
51
|
+
this.openNewWindow = !!params.openNewWindow;
|
|
52
|
+
this.relList = Array.isArray(params.relList) ? params.relList : [];
|
|
53
|
+
this.defaultRel = params.defaultRel || {};
|
|
54
|
+
this.noAutoPrefix = !!params.noAutoPrefix;
|
|
55
|
+
// file upload
|
|
56
|
+
if (params.enableFileUpload) {
|
|
57
|
+
this.uploadUrl = typeof params.uploadUrl === 'string' ? params.uploadUrl : null;
|
|
58
|
+
this.uploadHeaders = params.uploadHeaders || null;
|
|
59
|
+
this.uploadSizeLimit = numbers.get(params.uploadSizeLimit, 0) || null;
|
|
60
|
+
this.uploadSingleSizeLimit = numbers.get(params.uploadSingleSizeLimit, 0) || null;
|
|
61
|
+
this.input = dom.utils.createElement('input', { type: 'file', accept: params.acceptedFormats || '*' });
|
|
62
|
+
this.eventManager.addEvent(this.input, 'change', this.#OnChangeFile.bind(this));
|
|
63
|
+
// file manager
|
|
64
|
+
this.fileManager = new FileManager(this, {
|
|
65
|
+
query: 'a[download]:not([data-se-file-download])',
|
|
66
|
+
loadHandler: this.events.onFileLoad,
|
|
67
|
+
eventHandler: this.events.onFileAction
|
|
68
|
+
});
|
|
95
69
|
}
|
|
96
|
-
this.selectMenu_rel = new SelectMenu(this, { checkList: true, position: 'right-middle', dir: 'ltr' });
|
|
97
|
-
this.selectMenu_rel.on(this.relButton, SetRelItem.bind(this));
|
|
98
|
-
this.selectMenu_rel.create(list);
|
|
99
|
-
this.eventManager.addEvent(this.relButton, 'click', OnClick_relbutton.bind(this));
|
|
100
|
-
}
|
|
101
70
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
71
|
+
// create HTML
|
|
72
|
+
const forms = CreatetModalForm(inst.editor, params, this.relList);
|
|
73
|
+
|
|
74
|
+
// members
|
|
75
|
+
this.kink = inst.constructor.key || inst.constructor.name;
|
|
76
|
+
this.inst = inst;
|
|
77
|
+
this.modalForm = /** @type {HTMLElement} */ (modalForm);
|
|
78
|
+
this.host = (this._w.location.origin + this._w.location.pathname).replace(/\/$/, '');
|
|
79
|
+
|
|
80
|
+
/** @type {HTMLInputElement} */
|
|
81
|
+
this.urlInput = forms.querySelector('.se-input-url');
|
|
82
|
+
/** @type {HTMLInputElement} */
|
|
83
|
+
this.displayInput = forms.querySelector('._se_display_text');
|
|
84
|
+
/** @type {HTMLInputElement} */
|
|
85
|
+
this.titleInput = forms.querySelector('._se_title');
|
|
86
|
+
/** @type {HTMLInputElement} */
|
|
87
|
+
this.newWindowCheck = forms.querySelector('._se_anchor_check');
|
|
88
|
+
/** @type {HTMLInputElement} */
|
|
89
|
+
this.downloadCheck = forms.querySelector('._se_anchor_download');
|
|
90
|
+
/** @type {HTMLElement} */
|
|
91
|
+
this.download = forms.querySelector('._se_anchor_download_icon');
|
|
92
|
+
/** @type {HTMLElement} */
|
|
93
|
+
this.preview = forms.querySelector('.se-link-preview');
|
|
94
|
+
/** @type {HTMLElement} */
|
|
95
|
+
this.bookmark = forms.querySelector('._se_anchor_bookmark_icon');
|
|
96
|
+
/** @type {HTMLButtonElement} */
|
|
97
|
+
this.bookmarkButton = forms.querySelector('._se_bookmark_button');
|
|
98
|
+
|
|
99
|
+
this.currentRel = [];
|
|
100
|
+
this.currentTarget = null;
|
|
101
|
+
this.linkValue = '';
|
|
102
|
+
this._change = false;
|
|
103
|
+
this._isRel = this.relList.length > 0;
|
|
104
|
+
// members - rel
|
|
105
|
+
if (this._isRel) {
|
|
106
|
+
/** @type {HTMLButtonElement} */
|
|
107
|
+
this.relButton = forms.querySelector('.se-anchor-rel-btn');
|
|
108
|
+
/** @type {HTMLElement} */
|
|
109
|
+
this.relPreview = forms.querySelector('.se-anchor-rel-preview');
|
|
110
|
+
|
|
111
|
+
const relList = this.relList;
|
|
112
|
+
const defaultRel = (this.defaultRel.default || '').split(' ');
|
|
113
|
+
const list = [];
|
|
114
|
+
for (let i = 0, len = relList.length, rel; i < len; i++) {
|
|
115
|
+
rel = relList[i];
|
|
116
|
+
list.push(
|
|
117
|
+
dom.utils.createElement(
|
|
118
|
+
'BUTTON',
|
|
119
|
+
{
|
|
120
|
+
type: 'button',
|
|
121
|
+
class: 'se-btn-list' + (defaultRel.includes(rel) ? ' se-checked' : ''),
|
|
122
|
+
'data-command': rel,
|
|
123
|
+
title: rel,
|
|
124
|
+
'aria-label': rel
|
|
125
|
+
},
|
|
126
|
+
rel + '<span class="se-svg">' + this.icons.checked + '</span>'
|
|
127
|
+
)
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
this.selectMenu_rel = new SelectMenu(this, { checkList: true, position: 'right-middle', dir: 'ltr' });
|
|
131
|
+
this.selectMenu_rel.on(this.relButton, this.#SetRelItem.bind(this));
|
|
132
|
+
this.selectMenu_rel.create(list);
|
|
133
|
+
this.eventManager.addEvent(this.relButton, 'click', this.#OnClick_relbutton.bind(this));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// init
|
|
137
|
+
this.modalForm.querySelector('.se-anchor-editor').appendChild(forms);
|
|
138
|
+
this.selectMenu_bookmark = new SelectMenu(this, { checkList: false, position: 'bottom-left', dir: 'ltr' });
|
|
139
|
+
this.selectMenu_bookmark.on(this.urlInput, this.#SetHeaderBookmark.bind(this));
|
|
140
|
+
this.eventManager.addEvent(this.newWindowCheck, 'change', this.#OnChange_newWindowCheck.bind(this));
|
|
141
|
+
this.eventManager.addEvent(this.downloadCheck, 'change', this.#OnChange_downloadCheck.bind(this));
|
|
142
|
+
this.eventManager.addEvent(this.displayInput, 'input', this.#OnChange_displayInput.bind(this));
|
|
143
|
+
this.eventManager.addEvent(this.urlInput, 'input', this.#OnChange_urlInput.bind(this));
|
|
144
|
+
this.eventManager.addEvent(this.urlInput, 'focus', this.#OnFocus_urlInput.bind(this));
|
|
145
|
+
this.eventManager.addEvent(this.bookmarkButton, 'click', this.#OnClick_bookmarkButton.bind(this));
|
|
146
|
+
this.eventManager.addEvent(forms.querySelector('._se_upload_button'), 'click', () => this.input.click());
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @description Initialize.
|
|
150
|
+
* - Sets the current anchor element to be edited.
|
|
151
|
+
* @param {Node} element Modal target element
|
|
152
|
+
*/
|
|
116
153
|
set(element) {
|
|
117
|
-
this.currentTarget = element;
|
|
118
|
-
}
|
|
154
|
+
this.currentTarget = /** @type {HTMLAnchorElement} */ (element);
|
|
155
|
+
}
|
|
119
156
|
|
|
157
|
+
/**
|
|
158
|
+
* @description Opens the anchor editor modal and populates it with data.
|
|
159
|
+
* @param {boolean} isUpdate - Indicates whether an existing anchor is being updated (`true`) or a new one is being created (`false`).
|
|
160
|
+
*/
|
|
120
161
|
on(isUpdate) {
|
|
121
162
|
if (!isUpdate) {
|
|
122
163
|
this.init();
|
|
@@ -124,31 +165,39 @@ ModalAnchorEditor.prototype = {
|
|
|
124
165
|
this.newWindowCheck.checked = this.openNewWindow;
|
|
125
166
|
this.titleInput.value = '';
|
|
126
167
|
} else if (this.currentTarget) {
|
|
127
|
-
const href = this.currentTarget.
|
|
128
|
-
this.linkValue = this.preview.textContent = this.urlInput.value = this._selfPathBookmark(href) ? href.
|
|
168
|
+
const href = this.currentTarget.href;
|
|
169
|
+
this.linkValue = this.preview.textContent = this.urlInput.value = this._selfPathBookmark(href) ? href.substring(href.lastIndexOf('#')) : href;
|
|
129
170
|
this.displayInput.value = this.currentTarget.textContent;
|
|
130
171
|
this.titleInput.value = this.currentTarget.title;
|
|
131
172
|
this.newWindowCheck.checked = /_blank/i.test(this.currentTarget.target) ? true : false;
|
|
132
|
-
this.downloadCheck.checked = this.currentTarget.download;
|
|
173
|
+
this.downloadCheck.checked = !!this.currentTarget.download;
|
|
133
174
|
}
|
|
134
175
|
|
|
135
176
|
this._setRel(isUpdate && this.currentTarget ? this.currentTarget.rel : this.defaultRel.default || '');
|
|
136
177
|
this._setLinkPreview(this.linkValue);
|
|
137
|
-
}
|
|
178
|
+
}
|
|
138
179
|
|
|
180
|
+
/**
|
|
181
|
+
* @description Creates an anchor (`<a>`) element with the specified attributes.
|
|
182
|
+
* @param {boolean} notText - If `true`, the anchor will not contain text content.
|
|
183
|
+
* @returns {HTMLElement|null} - The newly created anchor element, or `null` if the URL is empty.
|
|
184
|
+
*/
|
|
139
185
|
create(notText) {
|
|
140
186
|
if (this.linkValue.length === 0) return null;
|
|
141
187
|
|
|
142
188
|
const url = this.linkValue;
|
|
143
189
|
const displayText = this.displayInput.value.length === 0 ? url : this.displayInput.value;
|
|
144
190
|
|
|
145
|
-
const oA = this.currentTarget ||
|
|
191
|
+
const oA = /** @type {HTMLAnchorElement} */ (this.currentTarget || dom.utils.createElement('A'));
|
|
146
192
|
this._updateAnchor(oA, url, displayText, this.titleInput.value, notText);
|
|
147
193
|
this.linkValue = this.preview.textContent = this.urlInput.value = this.displayInput.value = '';
|
|
148
194
|
|
|
149
195
|
return oA;
|
|
150
|
-
}
|
|
196
|
+
}
|
|
151
197
|
|
|
198
|
+
/**
|
|
199
|
+
* @description Resets the ModalAnchorEditor to its initial state.
|
|
200
|
+
*/
|
|
152
201
|
init() {
|
|
153
202
|
this.currentTarget = null;
|
|
154
203
|
this.linkValue = this.preview.textContent = this.urlInput.value = '';
|
|
@@ -157,8 +206,17 @@ ModalAnchorEditor.prototype = {
|
|
|
157
206
|
this.downloadCheck.checked = false;
|
|
158
207
|
this._change = false;
|
|
159
208
|
this._setRel(this.defaultRel.default || '');
|
|
160
|
-
}
|
|
209
|
+
}
|
|
161
210
|
|
|
211
|
+
/**
|
|
212
|
+
* @private
|
|
213
|
+
* @description Updates the anchor element with new attributes.
|
|
214
|
+
* @param {HTMLAnchorElement} anchor - The anchor (`<a>`) element to update.
|
|
215
|
+
* @param {string} url - The URL for the anchor's `href` attribute.
|
|
216
|
+
* @param {string} displayText - The text to be displayed inside the anchor.
|
|
217
|
+
* @param {string} title - The tooltip text (title attribute).
|
|
218
|
+
* @param {boolean} notText - If `true`, the anchor will not contain text content.
|
|
219
|
+
*/
|
|
162
220
|
_updateAnchor(anchor, url, displayText, title, notText) {
|
|
163
221
|
// download
|
|
164
222
|
if (!this._selfPathBookmark(url) && this.downloadCheck.checked) {
|
|
@@ -186,13 +244,24 @@ ModalAnchorEditor.prototype = {
|
|
|
186
244
|
} else {
|
|
187
245
|
anchor.textContent = displayText;
|
|
188
246
|
}
|
|
189
|
-
}
|
|
247
|
+
}
|
|
190
248
|
|
|
249
|
+
/**
|
|
250
|
+
* @private
|
|
251
|
+
* @description Checks if the given path is an internal bookmark.
|
|
252
|
+
* @param {string} path - The URL or anchor link.
|
|
253
|
+
* @returns {boolean} - `true` if the path is an internal bookmark, otherwise `false`.
|
|
254
|
+
*/
|
|
191
255
|
_selfPathBookmark(path) {
|
|
192
256
|
const href = this._w.location.href.replace(/\/$/, '');
|
|
193
|
-
return path.indexOf('#') === 0 || (path.indexOf(href) === 0 && path.indexOf('#') === (!href.includes('#') ? href.length : href.
|
|
194
|
-
}
|
|
257
|
+
return path.indexOf('#') === 0 || (path.indexOf(href) === 0 && path.indexOf('#') === (!href.includes('#') ? href.length : href.substring(0, href.indexOf('#')).length));
|
|
258
|
+
}
|
|
195
259
|
|
|
260
|
+
/**
|
|
261
|
+
* @private
|
|
262
|
+
* @description Updates the `rel` attribute list in the modal and preview.
|
|
263
|
+
* @param {string} relAttr - The `rel` attribute string to set.
|
|
264
|
+
*/
|
|
196
265
|
_setRel(relAttr) {
|
|
197
266
|
if (!this._isRel) return;
|
|
198
267
|
|
|
@@ -201,22 +270,27 @@ ModalAnchorEditor.prototype = {
|
|
|
201
270
|
for (let i = 0, len = checkedRel.length, cmd; i < len; i++) {
|
|
202
271
|
cmd = checkedRel[i].getAttribute('data-command');
|
|
203
272
|
if (rels.includes(cmd)) {
|
|
204
|
-
|
|
273
|
+
dom.utils.addClass(checkedRel[i], 'se-checked');
|
|
205
274
|
} else {
|
|
206
|
-
|
|
275
|
+
dom.utils.removeClass(checkedRel[i], 'se-checked');
|
|
207
276
|
}
|
|
208
277
|
}
|
|
209
278
|
|
|
210
279
|
this.relPreview.title = this.relPreview.textContent = rels.join(' ');
|
|
211
280
|
if (rels.length > 0) {
|
|
212
|
-
|
|
281
|
+
dom.utils.addClass(this.relButton, 'on');
|
|
213
282
|
} else {
|
|
214
|
-
|
|
283
|
+
dom.utils.removeClass(this.relButton, 'on');
|
|
215
284
|
}
|
|
216
|
-
}
|
|
285
|
+
}
|
|
217
286
|
|
|
218
|
-
|
|
219
|
-
|
|
287
|
+
/**
|
|
288
|
+
* @private
|
|
289
|
+
* @description Generates a list of bookmark headers within the editor.
|
|
290
|
+
* @param {string} urlValue - The current URL input value.
|
|
291
|
+
*/
|
|
292
|
+
_createBookmarkList(urlValue) {
|
|
293
|
+
const headers = dom.query.getListChildren(this.editor.frameContext.get('wysiwyg'), (current) => /h[1-6]/i.test(current.nodeName) || (dom.check.isAnchor(current) && !!current.id));
|
|
220
294
|
if (headers.length === 0) return;
|
|
221
295
|
|
|
222
296
|
const valueRegExp = new RegExp(`^${urlValue.replace(/^#/, '')}`, 'i');
|
|
@@ -226,7 +300,7 @@ ModalAnchorEditor.prototype = {
|
|
|
226
300
|
v = headers[i];
|
|
227
301
|
if (!valueRegExp.test(v.textContent)) continue;
|
|
228
302
|
list.push(v);
|
|
229
|
-
menus.push(
|
|
303
|
+
menus.push(dom.check.isAnchor(v) ? `<div><span class="se-text-prefix-icon">${this.icons.bookmark_anchor}</span>${v.id}</div>` : `<div style="${v.style.cssText}">${v.textContent}</div>`);
|
|
230
304
|
}
|
|
231
305
|
|
|
232
306
|
if (list.length === 0) {
|
|
@@ -235,14 +309,19 @@ ModalAnchorEditor.prototype = {
|
|
|
235
309
|
this.selectMenu_bookmark.create(list, menus);
|
|
236
310
|
this.selectMenu_bookmark.open(this.options.get('_rtl') ? 'bottom-right' : '');
|
|
237
311
|
}
|
|
238
|
-
}
|
|
312
|
+
}
|
|
239
313
|
|
|
314
|
+
/**
|
|
315
|
+
* @private
|
|
316
|
+
* @description Updates the preview of the anchor link.
|
|
317
|
+
* @param {string} value - The current URL value.
|
|
318
|
+
*/
|
|
240
319
|
_setLinkPreview(value) {
|
|
241
320
|
const preview = this.preview;
|
|
242
321
|
const protocol = this.options.get('defaultUrlProtocol');
|
|
243
322
|
const noPrefix = this.noAutoPrefix;
|
|
244
323
|
const reservedProtocol = /^(mailto:|tel:|sms:|https*:\/\/|#)/.test(value) || value.indexOf(protocol) === 0;
|
|
245
|
-
const sameProtocol = !protocol ? false : RegExp('^' + unicode.escapeStringRegexp(value.
|
|
324
|
+
const sameProtocol = !protocol ? false : RegExp('^' + unicode.escapeStringRegexp(value.substring(0, protocol.length))).test(protocol);
|
|
246
325
|
|
|
247
326
|
value =
|
|
248
327
|
this.linkValue =
|
|
@@ -251,10 +330,10 @@ ModalAnchorEditor.prototype = {
|
|
|
251
330
|
|
|
252
331
|
if (this._selfPathBookmark(value)) {
|
|
253
332
|
this.bookmark.style.display = 'block';
|
|
254
|
-
|
|
333
|
+
dom.utils.addClass(this.bookmarkButton, 'active');
|
|
255
334
|
} else {
|
|
256
335
|
this.bookmark.style.display = 'none';
|
|
257
|
-
|
|
336
|
+
dom.utils.removeClass(this.bookmarkButton, 'active');
|
|
258
337
|
}
|
|
259
338
|
|
|
260
339
|
if (!this._selfPathBookmark(value) && this.downloadCheck.checked) {
|
|
@@ -262,8 +341,14 @@ ModalAnchorEditor.prototype = {
|
|
|
262
341
|
} else {
|
|
263
342
|
this.download.style.display = 'none';
|
|
264
343
|
}
|
|
265
|
-
}
|
|
344
|
+
}
|
|
266
345
|
|
|
346
|
+
/**
|
|
347
|
+
* @private
|
|
348
|
+
* @description Merges the given `rel` attribute value with the current list.
|
|
349
|
+
* @param {string} relAttr - The `rel` attribute to merge.
|
|
350
|
+
* @returns {string} - The updated `rel` attribute string.
|
|
351
|
+
*/
|
|
267
352
|
_relMerge(relAttr) {
|
|
268
353
|
const current = this.currentRel;
|
|
269
354
|
if (!relAttr) return current.join(' ');
|
|
@@ -280,8 +365,14 @@ ModalAnchorEditor.prototype = {
|
|
|
280
365
|
}
|
|
281
366
|
|
|
282
367
|
return current.join(' ');
|
|
283
|
-
}
|
|
368
|
+
}
|
|
284
369
|
|
|
370
|
+
/**
|
|
371
|
+
* @private
|
|
372
|
+
* @description Removes the specified `rel` attribute from the current list.
|
|
373
|
+
* @param {string} relAttr - The `rel` attribute to remove.
|
|
374
|
+
* @returns {string} - The updated `rel` attribute string.
|
|
375
|
+
*/
|
|
285
376
|
_relDelete(relAttr) {
|
|
286
377
|
if (!relAttr) return this.currentRel.join(' ');
|
|
287
378
|
if (/^only:/.test(relAttr)) relAttr = relAttr.replace(/^only:/, '').trim();
|
|
@@ -289,24 +380,39 @@ ModalAnchorEditor.prototype = {
|
|
|
289
380
|
const rels = this.currentRel.join(' ').replace(RegExp(relAttr + '\\s*'), '');
|
|
290
381
|
this.currentRel = rels.split(' ');
|
|
291
382
|
return rels;
|
|
292
|
-
}
|
|
383
|
+
}
|
|
293
384
|
|
|
385
|
+
/**
|
|
386
|
+
* @private
|
|
387
|
+
* @description Registers a newly uploaded file and sets its URL in the modal form.
|
|
388
|
+
* @param {Object<string, *>} response - The response object from the file upload request.
|
|
389
|
+
*/
|
|
294
390
|
_register(response) {
|
|
295
391
|
const file = response.result[0];
|
|
296
392
|
this.linkValue = this.preview.textContent = this.urlInput.value = file.url;
|
|
297
393
|
this.displayInput.value = file.name;
|
|
298
394
|
this.downloadCheck.checked = true;
|
|
299
395
|
this.download.style.display = 'block';
|
|
300
|
-
}
|
|
396
|
+
}
|
|
301
397
|
|
|
398
|
+
/**
|
|
399
|
+
* @private
|
|
400
|
+
* @description Handles file upload errors.
|
|
401
|
+
* @param {Object<string, *>} response - The error response object.
|
|
402
|
+
* @returns {Promise<void>}
|
|
403
|
+
*/
|
|
302
404
|
async _error(response) {
|
|
303
405
|
const message = await this.triggerEvent('onFileUploadError', { error: response });
|
|
304
406
|
if (message === false) return;
|
|
305
407
|
const err = message === NO_EVENT ? response.errorMessage : message || response.errorMessage;
|
|
306
|
-
this.
|
|
408
|
+
this.ui.alertOpen(err, 'error');
|
|
307
409
|
console.error('[SUNEDITOR.plugin.fileUpload.error]', err);
|
|
308
|
-
}
|
|
410
|
+
}
|
|
309
411
|
|
|
412
|
+
/**
|
|
413
|
+
* @description Handles the callback after a file upload completes.
|
|
414
|
+
* @param {XMLHttpRequest} xmlHttp - The XMLHttpRequest object containing the response.
|
|
415
|
+
*/
|
|
310
416
|
_uploadCallBack(xmlHttp) {
|
|
311
417
|
const response = JSON.parse(xmlHttp.responseText);
|
|
312
418
|
if (response.errorMessage) {
|
|
@@ -314,127 +420,170 @@ ModalAnchorEditor.prototype = {
|
|
|
314
420
|
} else {
|
|
315
421
|
this._register(response);
|
|
316
422
|
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
constructor: ModalAnchorEditor
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
async function OnChangeFile(e) {
|
|
323
|
-
const files = e.target.files;
|
|
324
|
-
if (!files[0]) return;
|
|
325
|
-
|
|
326
|
-
const fileInfo = {
|
|
327
|
-
url: this.uploadUrl,
|
|
328
|
-
uploadHeaders: this.uploadHeaders,
|
|
329
|
-
files
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
const handler = async function (infos, newInfos) {
|
|
333
|
-
infos = newInfos || infos;
|
|
334
|
-
const xmlHttp = await this.fileManager.asyncUpload(infos.url, infos.uploadHeaders, infos.files);
|
|
335
|
-
this._uploadCallBack(xmlHttp);
|
|
336
|
-
}.bind(this, fileInfo);
|
|
337
|
-
|
|
338
|
-
const result = await this.triggerEvent('onFileUploadBefore', {
|
|
339
|
-
...fileInfo,
|
|
340
|
-
handler
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
if (result === undefined) return true;
|
|
344
|
-
if (result === false) return false;
|
|
345
|
-
if (result !== null && typeof result === 'object') handler(result);
|
|
423
|
+
}
|
|
346
424
|
|
|
347
|
-
|
|
348
|
-
|
|
425
|
+
/**
|
|
426
|
+
* @description Handles file input change events.
|
|
427
|
+
* @param {InputEvent} e - The change event object.
|
|
428
|
+
*/
|
|
429
|
+
async #OnChangeFile(e) {
|
|
430
|
+
/** @type {HTMLInputElement} */
|
|
431
|
+
const eventTarget = dom.query.getEventTarget(e);
|
|
432
|
+
const files = eventTarget.files;
|
|
433
|
+
if (!files[0]) return;
|
|
434
|
+
|
|
435
|
+
const fileInfo = {
|
|
436
|
+
url: this.uploadUrl,
|
|
437
|
+
uploadHeaders: this.uploadHeaders,
|
|
438
|
+
files
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
const handler = async function (infos, newInfos) {
|
|
442
|
+
infos = newInfos || infos;
|
|
443
|
+
const xmlHttp = await this.fileManager.asyncUpload(infos.url, infos.uploadHeaders, infos.files);
|
|
444
|
+
this._uploadCallBack(xmlHttp);
|
|
445
|
+
}.bind(this, fileInfo);
|
|
446
|
+
// se-ts-ignore
|
|
447
|
+
void this._uploadCallBack;
|
|
448
|
+
|
|
449
|
+
const result = await this.triggerEvent('onFileUploadBefore', {
|
|
450
|
+
info: fileInfo,
|
|
451
|
+
handler
|
|
452
|
+
});
|
|
349
453
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
454
|
+
if (result === undefined) return true;
|
|
455
|
+
if (result === false) return false;
|
|
456
|
+
if (result !== null && typeof result === 'object') handler(result);
|
|
353
457
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
item.id = id;
|
|
357
|
-
this.urlInput.value = '#' + id;
|
|
458
|
+
if (result === true || result === NO_EVENT) handler(null);
|
|
459
|
+
}
|
|
358
460
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
461
|
+
/**
|
|
462
|
+
* @description Opens the `rel` attribute selection menu.
|
|
463
|
+
*/
|
|
464
|
+
#OnClick_relbutton() {
|
|
465
|
+
this.selectMenu_rel.open(this.options.get('_rtl') ? 'left-middle' : '');
|
|
466
|
+
}
|
|
363
467
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
468
|
+
/**
|
|
469
|
+
* @description Sets the selected bookmark as the URL.
|
|
470
|
+
* @param {HTMLElement} item - The selected bookmark element.
|
|
471
|
+
*/
|
|
472
|
+
#SetHeaderBookmark(item) {
|
|
473
|
+
const id = item.id || 'h_' + Math.random().toString().replace(/.+\./, '');
|
|
474
|
+
item.id = id;
|
|
475
|
+
this.urlInput.value = '#' + id;
|
|
476
|
+
|
|
477
|
+
this._setLinkPreview(this.urlInput.value);
|
|
478
|
+
this.selectMenu_bookmark.close();
|
|
479
|
+
this.urlInput.focus();
|
|
480
|
+
}
|
|
367
481
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
482
|
+
/**
|
|
483
|
+
* @param {HTMLElement} item - The selected `rel` attribute element.
|
|
484
|
+
*/
|
|
485
|
+
#SetRelItem(item) {
|
|
486
|
+
const cmd = item.getAttribute('data-command');
|
|
487
|
+
if (!cmd) return;
|
|
372
488
|
|
|
373
|
-
|
|
374
|
-
|
|
489
|
+
const current = this.currentRel;
|
|
490
|
+
const index = current.indexOf(cmd);
|
|
491
|
+
if (index === -1) current.push(cmd);
|
|
492
|
+
else current.splice(index, 1);
|
|
375
493
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}
|
|
494
|
+
this.relPreview.title = this.relPreview.textContent = current.join(', ');
|
|
495
|
+
}
|
|
379
496
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
497
|
+
/**
|
|
498
|
+
* @param {InputEvent} e - Event object
|
|
499
|
+
*/
|
|
500
|
+
#OnChange_displayInput(e) {
|
|
501
|
+
/** @type {HTMLInputElement} */
|
|
502
|
+
const eventTarget = dom.query.getEventTarget(e);
|
|
503
|
+
this._change = !!eventTarget.value.trim();
|
|
504
|
+
}
|
|
386
505
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
506
|
+
/**
|
|
507
|
+
* @param {InputEvent} e - Event object
|
|
508
|
+
*/
|
|
509
|
+
#OnChange_urlInput(e) {
|
|
510
|
+
/** @type {HTMLInputElement} */
|
|
511
|
+
const eventTarget = dom.query.getEventTarget(e);
|
|
512
|
+
const value = eventTarget.value.trim();
|
|
513
|
+
this._setLinkPreview(value);
|
|
514
|
+
if (this._selfPathBookmark(value)) this._createBookmarkList(value);
|
|
515
|
+
else this.selectMenu_bookmark.close();
|
|
516
|
+
}
|
|
391
517
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
url = url.substr(1);
|
|
396
|
-
this.bookmark.style.display = 'none';
|
|
397
|
-
domUtils.removeClass(this.bookmarkButton, 'active');
|
|
398
|
-
} else {
|
|
399
|
-
url = '#' + url;
|
|
400
|
-
this.bookmark.style.display = 'block';
|
|
401
|
-
domUtils.addClass(this.bookmarkButton, 'active');
|
|
402
|
-
this.downloadCheck.checked = false;
|
|
403
|
-
this.download.style.display = 'none';
|
|
404
|
-
this._createHeaderList(url);
|
|
518
|
+
#OnFocus_urlInput() {
|
|
519
|
+
const value = this.urlInput.value;
|
|
520
|
+
if (this._selfPathBookmark(value)) this._createBookmarkList(value);
|
|
405
521
|
}
|
|
406
522
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
523
|
+
#OnClick_bookmarkButton() {
|
|
524
|
+
let url = this.urlInput.value;
|
|
525
|
+
if (this._selfPathBookmark(url)) {
|
|
526
|
+
url = url.substring(1);
|
|
527
|
+
this.bookmark.style.display = 'none';
|
|
528
|
+
dom.utils.removeClass(this.bookmarkButton, 'active');
|
|
529
|
+
} else {
|
|
530
|
+
url = '#' + url;
|
|
531
|
+
this.bookmark.style.display = 'block';
|
|
532
|
+
dom.utils.addClass(this.bookmarkButton, 'active');
|
|
533
|
+
this.downloadCheck.checked = false;
|
|
534
|
+
this.download.style.display = 'none';
|
|
535
|
+
this._createBookmarkList(url);
|
|
536
|
+
}
|
|
411
537
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
this._setRel(this._relMerge(this.defaultRel.check_new_window));
|
|
416
|
-
} else {
|
|
417
|
-
this._setRel(this._relDelete(this.defaultRel.check_new_window));
|
|
538
|
+
this.urlInput.value = url;
|
|
539
|
+
this._setLinkPreview(url);
|
|
540
|
+
this.urlInput.focus();
|
|
418
541
|
}
|
|
419
|
-
}
|
|
420
542
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
543
|
+
/**
|
|
544
|
+
* @param {InputEvent} e - Event object
|
|
545
|
+
*/
|
|
546
|
+
#OnChange_newWindowCheck(e) {
|
|
547
|
+
if (typeof this.defaultRel.check_new_window !== 'string') return;
|
|
548
|
+
/** @type {HTMLInputElement} */
|
|
549
|
+
const eventTarget = dom.query.getEventTarget(e);
|
|
550
|
+
if (eventTarget.checked) {
|
|
551
|
+
this._setRel(this._relMerge(this.defaultRel.check_new_window));
|
|
552
|
+
} else {
|
|
553
|
+
this._setRel(this._relDelete(this.defaultRel.check_new_window));
|
|
429
554
|
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* @param {InputEvent} e - Event object
|
|
559
|
+
*/
|
|
560
|
+
#OnChange_downloadCheck(e) {
|
|
561
|
+
/** @type {HTMLInputElement} */
|
|
562
|
+
const eventTarget = dom.query.getEventTarget(e);
|
|
563
|
+
if (eventTarget.checked) {
|
|
564
|
+
this.download.style.display = 'block';
|
|
565
|
+
this.bookmark.style.display = 'none';
|
|
566
|
+
dom.utils.removeClass(this.bookmarkButton, 'active');
|
|
567
|
+
this.linkValue = this.preview.textContent = this.urlInput.value = this.urlInput.value.replace(/^#+/, '');
|
|
568
|
+
if (typeof this.defaultRel.check_bookmark === 'string') {
|
|
569
|
+
this._setRel(this._relMerge(this.defaultRel.check_bookmark));
|
|
570
|
+
}
|
|
571
|
+
} else {
|
|
572
|
+
this.download.style.display = 'none';
|
|
573
|
+
if (typeof this.defaultRel.check_bookmark === 'string') {
|
|
574
|
+
this._setRel(this._relDelete(this.defaultRel.check_bookmark));
|
|
575
|
+
}
|
|
434
576
|
}
|
|
435
577
|
}
|
|
436
578
|
}
|
|
437
579
|
|
|
580
|
+
/**
|
|
581
|
+
* @private
|
|
582
|
+
* @param {__se__EditorCore} editor - Editor instance
|
|
583
|
+
* @param {ModalAnchorEditorParams} params - ModalAnchorEditor options
|
|
584
|
+
* @param {Array<string>} relList - REL attribute list
|
|
585
|
+
* @returns {HTMLElement} - Modal form element
|
|
586
|
+
*/
|
|
438
587
|
function CreatetModalForm(editor, params, relList) {
|
|
439
588
|
const lang = editor.lang;
|
|
440
589
|
const icons = editor.icons;
|
|
@@ -451,13 +600,13 @@ function CreatetModalForm(editor, params, relList) {
|
|
|
451
600
|
params.enableFileUpload
|
|
452
601
|
? `<button type="button" class="se-btn se-tooltip se-modal-files-edge-button _se_upload_button" aria-label="${lang.fileUpload}">
|
|
453
602
|
${icons.file_upload}
|
|
454
|
-
${
|
|
603
|
+
${dom.utils.createTooltipInner(lang.fileUpload)}
|
|
455
604
|
</button>`
|
|
456
605
|
: ''
|
|
457
606
|
}
|
|
458
607
|
<button type="button" class="se-btn se-tooltip se-modal-files-edge-button _se_bookmark_button" aria-label="${lang.link_modal_bookmark}">
|
|
459
608
|
${icons.bookmark}
|
|
460
|
-
${
|
|
609
|
+
${dom.utils.createTooltipInner(lang.link_modal_bookmark)}
|
|
461
610
|
</button>
|
|
462
611
|
</div>
|
|
463
612
|
<div class="se-anchor-preview-form">
|
|
@@ -479,7 +628,7 @@ function CreatetModalForm(editor, params, relList) {
|
|
|
479
628
|
<div class="se-anchor-rel">
|
|
480
629
|
<button type="button" class="se-btn se-tooltip se-anchor-rel-btn" title="${lang.link_modal_relAttribute}" aria-label="${lang.link_modal_relAttribute}">
|
|
481
630
|
${icons.link_rel}
|
|
482
|
-
${
|
|
631
|
+
${dom.utils.createTooltipInner(lang.link_modal_relAttribute)}
|
|
483
632
|
</button>
|
|
484
633
|
<div class="se-anchor-rel-wrapper"><pre class="se-link-preview se-anchor-rel-preview"></pre></div>
|
|
485
634
|
</div>
|
|
@@ -488,7 +637,7 @@ function CreatetModalForm(editor, params, relList) {
|
|
|
488
637
|
|
|
489
638
|
html += '</div></div>';
|
|
490
639
|
|
|
491
|
-
return
|
|
640
|
+
return dom.utils.createElement('DIV', null, html);
|
|
492
641
|
}
|
|
493
642
|
|
|
494
643
|
export default ModalAnchorEditor;
|