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