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,82 +1,128 @@
|
|
|
1
1
|
import EditorInjector from '../../editorInjector';
|
|
2
2
|
import { Modal, Controller, FileManager, Figure, _DragHandle } from '../../modules';
|
|
3
|
-
import {
|
|
3
|
+
import { dom, numbers, env } from '../../helper';
|
|
4
4
|
const { NO_EVENT, ON_OVER_COMPONENT } = env;
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import('../../events').AudioInfo} AudioInfo_audio
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {Object} AudioPluginOptions
|
|
12
|
+
* @property {string} [defaultWidth="300px"] - The default width of the audio tag (e.g., "300px").
|
|
13
|
+
* @property {string} [defaultHeight="150px"] - The default height of the audio tag (e.g., "150px").
|
|
14
|
+
* @property {boolean} [createFileInput] - Whether to create a file input element.
|
|
15
|
+
* @property {boolean} [createUrlInput] - Whether to create a URL input element (default is true if file input is not created).
|
|
16
|
+
* @property {string} [uploadUrl] - The URL to which files will be uploaded.
|
|
17
|
+
* @property {Object<string, string>} [uploadHeaders] - Headers to include in the file upload request.
|
|
18
|
+
* @property {number} [uploadSizeLimit] - The total upload size limit in bytes.
|
|
19
|
+
* @property {number} [uploadSingleSizeLimit] - The single file size limit in bytes.
|
|
20
|
+
* @property {boolean} [allowMultiple] - Whether to allow multiple file uploads.
|
|
21
|
+
* @property {string} [acceptedFormats="audio/*"] - Accepted file formats (default is "audio/*").
|
|
22
|
+
* @property {Object<string, string>} [audioTagAttributes] - Additional attributes to set on the audio tag.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @class
|
|
27
|
+
* @description Audio modal plugin.
|
|
28
|
+
*/
|
|
29
|
+
class Audio_ extends EditorInjector {
|
|
30
|
+
static key = 'audio';
|
|
31
|
+
static type = 'modal';
|
|
32
|
+
static className = '';
|
|
33
|
+
/**
|
|
34
|
+
* @this {Audio_}
|
|
35
|
+
* @param {HTMLElement} node - The node to check.
|
|
36
|
+
* @returns {HTMLElement|null} Returns a node if the node is a valid component.
|
|
37
|
+
*/
|
|
38
|
+
static component(node) {
|
|
39
|
+
return /^AUDIO$/i.test(node?.nodeName) ? node : null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @constructor
|
|
44
|
+
* @param {__se__EditorCore} editor - The root editor instance
|
|
45
|
+
* @param {AudioPluginOptions} pluginOptions
|
|
46
|
+
*/
|
|
47
|
+
constructor(editor, pluginOptions) {
|
|
48
|
+
// plugin bisic properties
|
|
49
|
+
super(editor);
|
|
50
|
+
this.title = this.lang.audio;
|
|
51
|
+
this.icon = 'audio';
|
|
52
|
+
|
|
53
|
+
// define plugin options
|
|
54
|
+
this.pluginOptions = {
|
|
55
|
+
defaultWidth: !pluginOptions.defaultWidth ? '' : numbers.is(pluginOptions.defaultWidth) ? pluginOptions.defaultWidth + 'px' : pluginOptions.defaultWidth,
|
|
56
|
+
defaultHeight: !pluginOptions.defaultHeight ? '' : numbers.is(pluginOptions.defaultHeight) ? pluginOptions.defaultHeight + 'px' : pluginOptions.defaultHeight,
|
|
57
|
+
createFileInput: !!pluginOptions.createFileInput,
|
|
58
|
+
createUrlInput: pluginOptions.createUrlInput === undefined || !pluginOptions.createFileInput ? true : pluginOptions.createUrlInput,
|
|
59
|
+
uploadUrl: typeof pluginOptions.uploadUrl === 'string' ? pluginOptions.uploadUrl : null,
|
|
60
|
+
uploadHeaders: pluginOptions.uploadHeaders || null,
|
|
61
|
+
uploadSizeLimit: numbers.get(pluginOptions.uploadSizeLimit, 0),
|
|
62
|
+
uploadSingleSizeLimit: numbers.get(pluginOptions.uploadSingleSizeLimit, 0),
|
|
63
|
+
allowMultiple: !!pluginOptions.allowMultiple,
|
|
64
|
+
acceptedFormats: typeof pluginOptions.acceptedFormats !== 'string' || pluginOptions.acceptedFormats.trim() === '*' ? 'audio/*' : pluginOptions.acceptedFormats.trim() || 'audio/*',
|
|
65
|
+
audioTagAttributes: pluginOptions.audioTagAttributes || null
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// create HTML
|
|
69
|
+
const modalEl = CreateHTML_modal(editor, this.pluginOptions);
|
|
70
|
+
const controllerEl = CreateHTML_controller(editor);
|
|
71
|
+
|
|
72
|
+
// modules
|
|
73
|
+
this.modal = new Modal(this, modalEl);
|
|
74
|
+
this.controller = new Controller(this, controllerEl, { position: 'bottom', disabled: true });
|
|
75
|
+
this.fileManager = new FileManager(this, {
|
|
76
|
+
query: 'audio',
|
|
77
|
+
loadHandler: this.events.onAudioLoad,
|
|
78
|
+
eventHandler: this.events.onAudioAction
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// members
|
|
82
|
+
this.figure = new Figure(this, null, {});
|
|
83
|
+
|
|
84
|
+
/** @type {HTMLElement} */
|
|
85
|
+
this.fileModalWrapper = modalEl.querySelector('.se-flex-input-wrapper');
|
|
86
|
+
/** @type {HTMLInputElement} */
|
|
87
|
+
this.audioInputFile = modalEl.querySelector('.__se__file_input');
|
|
88
|
+
/** @type {HTMLInputElement} */
|
|
89
|
+
this.audioUrlFile = modalEl.querySelector('.se-input-url');
|
|
90
|
+
/** @type {HTMLElement} */
|
|
91
|
+
this.preview = modalEl.querySelector('.se-link-preview');
|
|
92
|
+
/** @type {HTMLAudioElement} */
|
|
93
|
+
this._element = null;
|
|
94
|
+
|
|
95
|
+
this.defaultWidth = this.pluginOptions.defaultWidth;
|
|
96
|
+
this.defaultHeight = this.pluginOptions.defaultHeight;
|
|
97
|
+
this.urlValue = '';
|
|
98
|
+
|
|
99
|
+
const galleryButton = modalEl.querySelector('.__se__gallery');
|
|
100
|
+
if (galleryButton) this.eventManager.addEvent(galleryButton, 'click', this.#OpenGallery.bind(this));
|
|
101
|
+
|
|
102
|
+
// init
|
|
103
|
+
if (this.audioInputFile) {
|
|
104
|
+
this.eventManager.addEvent(modalEl.querySelector('.se-modal-files-edge-button'), 'click', this.#RemoveSelectedFiles.bind(this, this.audioUrlFile, this.preview));
|
|
105
|
+
if (this.audioUrlFile) {
|
|
106
|
+
this.eventManager.addEvent(this.audioInputFile, 'change', this.#FileInputChange.bind(this));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
54
109
|
if (this.audioUrlFile) {
|
|
55
|
-
this.eventManager.addEvent(this.
|
|
110
|
+
this.eventManager.addEvent(this.audioUrlFile, 'input', this.#OnLinkPreview.bind(this));
|
|
56
111
|
}
|
|
57
112
|
}
|
|
58
|
-
|
|
59
|
-
this.eventManager.addEvent(this.audioUrlFile, 'input', OnLinkPreview.bind(this));
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
Audio_.key = 'audio';
|
|
64
|
-
Audio_.type = 'modal';
|
|
65
|
-
Audio_.className = '';
|
|
66
|
-
Audio_.component = function (node) {
|
|
67
|
-
return /^AUDIO$/i.test(node?.nodeName) ? node : null;
|
|
68
|
-
};
|
|
69
|
-
Audio_.prototype = {
|
|
113
|
+
|
|
70
114
|
/**
|
|
71
|
-
* @
|
|
115
|
+
* @editorMethod Modules.Modal
|
|
116
|
+
* @description Executes the method that is called when a "Modal" module's is opened.
|
|
72
117
|
*/
|
|
73
118
|
open() {
|
|
74
119
|
this.modal.open();
|
|
75
|
-
}
|
|
120
|
+
}
|
|
76
121
|
|
|
77
122
|
/**
|
|
78
|
-
* @
|
|
79
|
-
* @
|
|
123
|
+
* @editorMethod Modules.Modal
|
|
124
|
+
* @description Executes the method that is called when a plugin's modal is opened.
|
|
125
|
+
* @param {boolean} isUpdate "Indicates whether the modal is for editing an existing component (true) or registering a new one (false)."
|
|
80
126
|
*/
|
|
81
127
|
on(isUpdate) {
|
|
82
128
|
if (!isUpdate) {
|
|
@@ -87,63 +133,86 @@ Audio_.prototype = {
|
|
|
87
133
|
} else {
|
|
88
134
|
if (this.audioInputFile && this.pluginOptions.allowMultiple) this.audioInputFile.removeAttribute('multiple');
|
|
89
135
|
}
|
|
90
|
-
}
|
|
136
|
+
}
|
|
91
137
|
|
|
92
138
|
/**
|
|
93
|
-
* @
|
|
94
|
-
* @
|
|
139
|
+
* @editorMethod Editor.EventManager
|
|
140
|
+
* @description Executes the event function of "paste" or "drop".
|
|
141
|
+
* @param {Object} params { frameContext, event, file }
|
|
142
|
+
* @param {__se__FrameContext} params.frameContext Frame context
|
|
143
|
+
* @param {ClipboardEvent} params.event Event object
|
|
144
|
+
* @param {File} params.file File object
|
|
145
|
+
* @returns {boolean} - If return false, the file upload will be canceled
|
|
95
146
|
*/
|
|
96
|
-
|
|
147
|
+
onFilePasteAndDrop({ file }) {
|
|
97
148
|
if (!/^audio/.test(file.type)) return;
|
|
98
149
|
|
|
99
150
|
this.submitFile([file]);
|
|
100
151
|
this.editor.focus();
|
|
101
152
|
|
|
102
153
|
return false;
|
|
103
|
-
}
|
|
154
|
+
}
|
|
104
155
|
|
|
105
156
|
/**
|
|
106
|
-
* @
|
|
107
|
-
* @
|
|
157
|
+
* @editorMethod Modules.Modal
|
|
158
|
+
* @description This function is called when a form within a modal window is "submit".
|
|
159
|
+
* @returns {Promise<boolean>} Success or failure
|
|
108
160
|
*/
|
|
109
|
-
modalAction() {
|
|
161
|
+
async modalAction() {
|
|
110
162
|
if (this.audioInputFile && this.audioInputFile?.files.length > 0) {
|
|
111
|
-
return this.submitFile(this.audioInputFile.files);
|
|
163
|
+
return await this.submitFile(this.audioInputFile.files);
|
|
112
164
|
} else if (this.audioUrlFile && this.urlValue.length > 0) {
|
|
113
|
-
return this.submitURL(this.urlValue);
|
|
165
|
+
return await this.submitURL(this.urlValue);
|
|
114
166
|
}
|
|
115
167
|
return false;
|
|
116
|
-
}
|
|
168
|
+
}
|
|
117
169
|
|
|
118
170
|
/**
|
|
119
|
-
* @
|
|
171
|
+
* @editorMethod Modules.Modal
|
|
172
|
+
* @description This function is called before the modal window is opened, but before it is closed.
|
|
120
173
|
*/
|
|
121
174
|
init() {
|
|
122
175
|
Modal.OnChangeFile(this.fileModalWrapper, []);
|
|
123
176
|
if (this.audioInputFile) this.audioInputFile.value = '';
|
|
124
177
|
if (this.audioUrlFile) this.urlValue = this.preview.textContent = this.audioUrlFile.value = '';
|
|
125
178
|
if (this.audioInputFile && this.audioUrlFile) {
|
|
126
|
-
this.audioUrlFile.
|
|
179
|
+
this.audioUrlFile.disabled = false;
|
|
127
180
|
this.preview.style.textDecoration = '';
|
|
128
181
|
}
|
|
129
|
-
}
|
|
182
|
+
}
|
|
130
183
|
|
|
131
184
|
/**
|
|
132
|
-
* @
|
|
133
|
-
* @
|
|
134
|
-
* @
|
|
185
|
+
* @editorMethod Modules.Controller
|
|
186
|
+
* @description Executes the method that is called when a button is clicked in the "controller".
|
|
187
|
+
* @param {HTMLButtonElement} target Target button element
|
|
135
188
|
*/
|
|
136
189
|
controllerAction(target) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
190
|
+
switch (target.getAttribute('data-command')) {
|
|
191
|
+
case 'update':
|
|
192
|
+
if (this.audioUrlFile) this.urlValue = this.preview.textContent = this.audioUrlFile.value = this._element.src;
|
|
193
|
+
this.open();
|
|
194
|
+
break;
|
|
195
|
+
case 'copy': {
|
|
196
|
+
const figure = Figure.GetContainer(this._element);
|
|
197
|
+
this.component.copy(figure.container);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
case 'delete':
|
|
201
|
+
this.destroy();
|
|
202
|
+
break;
|
|
142
203
|
}
|
|
143
|
-
}
|
|
204
|
+
}
|
|
144
205
|
|
|
145
206
|
/**
|
|
146
|
-
* @
|
|
207
|
+
* @editorMethod Editor.core
|
|
208
|
+
* @description This method is used to validate and preserve the format of the component within the editor.
|
|
209
|
+
* - It ensures that the structure and attributes of the element are maintained and secure.
|
|
210
|
+
* - The method checks if the element is already wrapped in a valid container and updates its attributes if necessary.
|
|
211
|
+
* - If the element isn't properly contained, a new container is created to retain the format.
|
|
212
|
+
* @returns {{query: string, method: (element: HTMLAudioElement) => void}} The format retention object containing the query and method to process the element.
|
|
213
|
+
* - query: The selector query to identify the relevant elements (in this case, 'audio').
|
|
214
|
+
* - method:The function to execute on the element to validate and preserve its format.
|
|
215
|
+
* - The function takes the element as an argument, checks if it is contained correctly, and applies necessary adjustments.
|
|
147
216
|
*/
|
|
148
217
|
retainFormat() {
|
|
149
218
|
return {
|
|
@@ -154,44 +223,51 @@ Audio_.prototype = {
|
|
|
154
223
|
|
|
155
224
|
this._setTagAttrs(element);
|
|
156
225
|
const figure = Figure.CreateContainer(element.cloneNode(true), 'se-flex-component');
|
|
157
|
-
this.figure.
|
|
226
|
+
this.figure.retainFigureFormat(figure.container, element, null, this.fileManager);
|
|
158
227
|
}
|
|
159
228
|
};
|
|
160
|
-
}
|
|
229
|
+
}
|
|
161
230
|
|
|
162
231
|
/**
|
|
163
|
-
* @
|
|
164
|
-
* @description
|
|
165
|
-
* @param {
|
|
232
|
+
* @editorMethod Editor.Component
|
|
233
|
+
* @description Executes the method that is called when a component of a plugin is selected.
|
|
234
|
+
* @param {HTMLElement} target Target component element
|
|
166
235
|
*/
|
|
167
|
-
select(
|
|
168
|
-
this.figure.open(
|
|
169
|
-
this.
|
|
170
|
-
}
|
|
236
|
+
select(target) {
|
|
237
|
+
this.figure.open(target, { nonResizing: true, nonSizeInfo: true, nonBorder: true, figureTarget: true, __fileManagerInfo: false });
|
|
238
|
+
this._ready(target);
|
|
239
|
+
}
|
|
171
240
|
|
|
172
241
|
/**
|
|
173
|
-
* @
|
|
242
|
+
* @private
|
|
243
|
+
* @description Prepares the component for selection.
|
|
244
|
+
* - Ensures that the controller is properly positioned and initialized.
|
|
245
|
+
* - Prevents duplicate event handling if the component is already selected.
|
|
246
|
+
* @param {HTMLElement} target - The selected element.
|
|
174
247
|
*/
|
|
175
|
-
|
|
248
|
+
_ready(target) {
|
|
176
249
|
if (_DragHandle.get('__overInfo') === ON_OVER_COMPONENT) return;
|
|
177
|
-
this._element = target;
|
|
250
|
+
this._element = /** @type {HTMLAudioElement} */ (target);
|
|
178
251
|
this.controller.open(target, null, { isWWTarget: false, addOffset: null });
|
|
179
|
-
}
|
|
252
|
+
}
|
|
180
253
|
|
|
181
254
|
/**
|
|
182
|
-
* @
|
|
255
|
+
* @editorMethod Editor.Component
|
|
256
|
+
* @description Method to delete a component of a plugin, called by the "FileManager", "Controller" module.
|
|
257
|
+
* @param {HTMLElement=} target Target element, if null current selected element
|
|
258
|
+
* @returns {Promise<void>}
|
|
183
259
|
*/
|
|
184
|
-
async destroy(
|
|
185
|
-
element =
|
|
260
|
+
async destroy(target) {
|
|
261
|
+
const element = target || this._element;
|
|
186
262
|
const figure = Figure.GetContainer(element);
|
|
187
263
|
const container = figure.container || element;
|
|
188
264
|
const focusEl = container.previousElementSibling || container.nextElementSibling;
|
|
189
265
|
|
|
190
|
-
const message = await this.triggerEvent('onAudioDeleteBefore', {
|
|
266
|
+
const message = await this.triggerEvent('onAudioDeleteBefore', { element: element, container: figure, url: element.getAttribute('src') });
|
|
191
267
|
if (message === false) return;
|
|
192
268
|
|
|
193
269
|
const emptyDiv = container.parentNode;
|
|
194
|
-
|
|
270
|
+
dom.utils.removeItem(container);
|
|
195
271
|
this.init();
|
|
196
272
|
this.controller.close();
|
|
197
273
|
|
|
@@ -208,8 +284,15 @@ Audio_.prototype = {
|
|
|
208
284
|
// focus
|
|
209
285
|
this.editor.focusEdge(focusEl);
|
|
210
286
|
this.history.push(false);
|
|
211
|
-
}
|
|
287
|
+
}
|
|
212
288
|
|
|
289
|
+
/**
|
|
290
|
+
* @private
|
|
291
|
+
* @description Registers uploaded audio files and creates the corresponding audio elements.
|
|
292
|
+
* - Iterates through the uploaded files and inserts them into the editor.
|
|
293
|
+
* @param {AudioInfo_audio} info - Upload metadata, including `isUpdate` flag and `element`.
|
|
294
|
+
* @param {Object<string, *>} response - Server response containing uploaded file details.
|
|
295
|
+
*/
|
|
213
296
|
_register(info, response) {
|
|
214
297
|
const fileList = response.result;
|
|
215
298
|
|
|
@@ -220,14 +303,19 @@ Audio_.prototype = {
|
|
|
220
303
|
file = { name: fileList[i].name, size: fileList[i].size };
|
|
221
304
|
this._createComp(oAudio, fileList[i].url, file, info.isUpdate);
|
|
222
305
|
}
|
|
223
|
-
}
|
|
306
|
+
}
|
|
224
307
|
|
|
308
|
+
/**
|
|
309
|
+
* @description Create an "audio" component using the provided files.
|
|
310
|
+
* @param {FileList|File[]} fileList File object list
|
|
311
|
+
* @returns {Promise<boolean>} If return false, the file upload will be canceled
|
|
312
|
+
*/
|
|
225
313
|
async submitFile(fileList) {
|
|
226
314
|
if (fileList.length === 0) return false;
|
|
227
315
|
|
|
228
316
|
let fileSize = 0;
|
|
229
317
|
const files = [];
|
|
230
|
-
const slngleSizeLimit = this.uploadSingleSizeLimit;
|
|
318
|
+
const slngleSizeLimit = this.pluginOptions.uploadSingleSizeLimit;
|
|
231
319
|
for (let i = 0, len = fileList.length, f, s; i < len; i++) {
|
|
232
320
|
f = fileList[i];
|
|
233
321
|
if (!/audio/i.test(f.type)) continue;
|
|
@@ -242,7 +330,7 @@ Audio_.prototype = {
|
|
|
242
330
|
file: f
|
|
243
331
|
});
|
|
244
332
|
|
|
245
|
-
this.
|
|
333
|
+
this.ui.alertOpen(message === NO_EVENT ? err : message || err, 'error');
|
|
246
334
|
|
|
247
335
|
return false;
|
|
248
336
|
}
|
|
@@ -256,7 +344,7 @@ Audio_.prototype = {
|
|
|
256
344
|
const err = '[SUNEDITOR.audioUpload.fail] Size of uploadable total audios: ' + limitSize / 1000 + 'KB';
|
|
257
345
|
const message = await this.triggerEvent('onAudioUploadError', { error: err, limitSize, currentSize: this.fileManager.getSize(), uploadSize: fileSize });
|
|
258
346
|
|
|
259
|
-
this.
|
|
347
|
+
this.ui.alertOpen(message === NO_EVENT ? err : message || err, 'error');
|
|
260
348
|
|
|
261
349
|
return false;
|
|
262
350
|
}
|
|
@@ -273,7 +361,7 @@ Audio_.prototype = {
|
|
|
273
361
|
}.bind(this, audioInfo);
|
|
274
362
|
|
|
275
363
|
const result = await this.triggerEvent('onAudioUploadBefore', {
|
|
276
|
-
|
|
364
|
+
info: audioInfo,
|
|
277
365
|
handler
|
|
278
366
|
});
|
|
279
367
|
|
|
@@ -284,8 +372,13 @@ Audio_.prototype = {
|
|
|
284
372
|
if (result === true || result === NO_EVENT) handler(null);
|
|
285
373
|
|
|
286
374
|
return true;
|
|
287
|
-
}
|
|
375
|
+
}
|
|
288
376
|
|
|
377
|
+
/**
|
|
378
|
+
* @description Create an "audio" component using the provided url.
|
|
379
|
+
* @param {string} url File url
|
|
380
|
+
* @returns {Promise<boolean>}
|
|
381
|
+
*/
|
|
289
382
|
async submitURL(url) {
|
|
290
383
|
if (url.length === 0) return false;
|
|
291
384
|
|
|
@@ -303,7 +396,7 @@ Audio_.prototype = {
|
|
|
303
396
|
}.bind(this, audioInfo);
|
|
304
397
|
|
|
305
398
|
const result = await this.triggerEvent('onAudioUploadBefore', {
|
|
306
|
-
|
|
399
|
+
info: audioInfo,
|
|
307
400
|
handler
|
|
308
401
|
});
|
|
309
402
|
|
|
@@ -314,15 +407,25 @@ Audio_.prototype = {
|
|
|
314
407
|
if (result === true || result === NO_EVENT) handler(null);
|
|
315
408
|
|
|
316
409
|
return true;
|
|
317
|
-
}
|
|
410
|
+
}
|
|
318
411
|
|
|
412
|
+
/**
|
|
413
|
+
* @private
|
|
414
|
+
* @description Creates or updates an audio component within the editor.
|
|
415
|
+
* - If `isUpdate` is `true`, updates the existing element's `src`.
|
|
416
|
+
* - Otherwise, inserts a new audio component with the given file.
|
|
417
|
+
* @param {HTMLAudioElement} element - The target audio element.
|
|
418
|
+
* @param {string} src - The source URL of the audio file.
|
|
419
|
+
* @param {{name: string, size: number}} file - The file metadata (name, size).
|
|
420
|
+
* @param {boolean} isUpdate - Whether to update an existing element.
|
|
421
|
+
*/
|
|
319
422
|
_createComp(element, src, file, isUpdate) {
|
|
320
423
|
// create new tag
|
|
321
424
|
if (!isUpdate) {
|
|
322
425
|
this.fileManager.setFileData(element, file);
|
|
323
426
|
element.src = src;
|
|
324
427
|
const figure = Figure.CreateContainer(element, 'se-flex-component');
|
|
325
|
-
if (!this.component.insert(figure.container, false, !this.options.get('componentAutoSelect'))) {
|
|
428
|
+
if (!this.component.insert(figure.container, { skipCharCount: false, skipSelection: !this.options.get('componentAutoSelect'), skipHistory: false })) {
|
|
326
429
|
this.editor.focus();
|
|
327
430
|
return;
|
|
328
431
|
}
|
|
@@ -335,26 +438,39 @@ Audio_.prototype = {
|
|
|
335
438
|
this.fileManager.setFileData(element, file);
|
|
336
439
|
if (element && element.src !== src) {
|
|
337
440
|
element.src = src;
|
|
338
|
-
this.component.select(element, Audio_.key
|
|
441
|
+
this.component.select(element, Audio_.key);
|
|
339
442
|
} else {
|
|
340
|
-
this.component.select(element, Audio_.key
|
|
443
|
+
this.component.select(element, Audio_.key);
|
|
341
444
|
return;
|
|
342
445
|
}
|
|
343
446
|
}
|
|
344
447
|
|
|
345
448
|
if (isUpdate) this.history.push(false);
|
|
346
|
-
}
|
|
449
|
+
}
|
|
347
450
|
|
|
451
|
+
/**
|
|
452
|
+
* @private
|
|
453
|
+
* @description Creates a new `<audio>` element with default attributes.
|
|
454
|
+
* - Applies width, height, and additional attributes from plugin options.
|
|
455
|
+
* @returns {HTMLAudioElement} - The newly created `<audio>` element.
|
|
456
|
+
*/
|
|
348
457
|
_createAudioTag() {
|
|
349
458
|
const w = this.defaultWidth;
|
|
350
459
|
const h = this.defaultHeight;
|
|
351
|
-
|
|
460
|
+
/** @type {HTMLAudioElement} */
|
|
461
|
+
const oAudio = dom.utils.createElement('AUDIO', { style: (w ? 'width:' + w + '; ' : '') + (h ? 'height:' + h + ';' : '') });
|
|
352
462
|
this._setTagAttrs(oAudio);
|
|
353
463
|
return oAudio;
|
|
354
|
-
}
|
|
464
|
+
}
|
|
355
465
|
|
|
466
|
+
/**
|
|
467
|
+
* @private
|
|
468
|
+
* @description Sets attributes on an audio element based on plugin options.
|
|
469
|
+
* - Adds the `controls` attribute and applies any custom attributes.
|
|
470
|
+
* @param {HTMLElement} element - The `<audio>` element to modify.
|
|
471
|
+
*/
|
|
356
472
|
_setTagAttrs(element) {
|
|
357
|
-
element.setAttribute('controls', true);
|
|
473
|
+
element.setAttribute('controls', 'true');
|
|
358
474
|
|
|
359
475
|
const attrs = this.pluginOptions.audioTagAttributes;
|
|
360
476
|
if (!attrs) return;
|
|
@@ -362,74 +478,127 @@ Audio_.prototype = {
|
|
|
362
478
|
for (const key in attrs) {
|
|
363
479
|
element.setAttribute(key, attrs[key]);
|
|
364
480
|
}
|
|
365
|
-
}
|
|
481
|
+
}
|
|
366
482
|
|
|
483
|
+
/**
|
|
484
|
+
* @private
|
|
485
|
+
* @description Uploads audio files to the server.
|
|
486
|
+
* - Sends a request to the configured upload URL and processes the response.
|
|
487
|
+
* @param {AudioInfo_audio} info - Upload metadata, including `files` and `isUpdate`.
|
|
488
|
+
* @param {FileList|File[]} files - The files to be uploaded.
|
|
489
|
+
*/
|
|
367
490
|
_serverUpload(info, files) {
|
|
368
491
|
if (!files) return;
|
|
369
492
|
|
|
370
493
|
const uploadFiles = this.modal.isUpdate ? [files[0]] : files;
|
|
371
|
-
this.fileManager.upload(this.pluginOptions.uploadUrl, this.pluginOptions.uploadHeaders, uploadFiles, UploadCallBack.bind(this, info), this._error.bind(this));
|
|
372
|
-
}
|
|
494
|
+
this.fileManager.upload(this.pluginOptions.uploadUrl, this.pluginOptions.uploadHeaders, uploadFiles, this.#UploadCallBack.bind(this, info), this._error.bind(this));
|
|
495
|
+
}
|
|
373
496
|
|
|
497
|
+
/**
|
|
498
|
+
* @private
|
|
499
|
+
* @description Handles errors that occur during the audio upload process.
|
|
500
|
+
* - Triggers the `onAudioUploadError` event to allow custom handling of errors.
|
|
501
|
+
* - Displays an error message in the editor's UI.
|
|
502
|
+
* - Logs the error to the console for debugging.
|
|
503
|
+
* @param {Object<string, *>} response - The error response object from the server or upload process.
|
|
504
|
+
* @returns {Promise<void>}
|
|
505
|
+
*/
|
|
374
506
|
async _error(response) {
|
|
375
507
|
const message = await this.triggerEvent('onAudioUploadError', { error: response });
|
|
376
508
|
const err = message === NO_EVENT ? response.errorMessage : message || response.errorMessage;
|
|
377
|
-
this.
|
|
509
|
+
this.ui.alertOpen(err, 'error');
|
|
378
510
|
console.error('[SUNEDITOR.plugin.audio.error]', err);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
constructor: Audio_
|
|
382
|
-
};
|
|
511
|
+
}
|
|
383
512
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
513
|
+
/**
|
|
514
|
+
* @description Handles the server response after a file upload.
|
|
515
|
+
* - If the upload is successful, registers the uploaded audio.
|
|
516
|
+
* - If an error occurs, triggers an error event.
|
|
517
|
+
* @param {AudioInfo_audio} info - Upload metadata.
|
|
518
|
+
* @param {XMLHttpRequest} xmlHttp - The completed XHR request.
|
|
519
|
+
*/
|
|
520
|
+
async #UploadCallBack(info, xmlHttp) {
|
|
521
|
+
if ((await this.triggerEvent('audioUploadHandler', { xmlHttp, info })) === NO_EVENT) {
|
|
522
|
+
const response = JSON.parse(xmlHttp.responseText);
|
|
523
|
+
if (response.errorMessage) {
|
|
524
|
+
this._error(response);
|
|
525
|
+
} else {
|
|
526
|
+
this._register(info, response);
|
|
527
|
+
}
|
|
391
528
|
}
|
|
392
529
|
}
|
|
393
|
-
}
|
|
394
530
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
531
|
+
/**
|
|
532
|
+
* @description Updates the preview text for the entered audio URL.
|
|
533
|
+
* - Formats the URL correctly based on the editor’s settings.
|
|
534
|
+
* @param {InputEvent} e - The input event triggered when the user types a URL.
|
|
535
|
+
*/
|
|
536
|
+
#OnLinkPreview(e) {
|
|
537
|
+
/** @type {HTMLInputElement} */
|
|
538
|
+
const target = dom.query.getEventTarget(e);
|
|
539
|
+
const value = target.value.trim();
|
|
540
|
+
this.urlValue = this.preview.textContent = !value
|
|
541
|
+
? ''
|
|
542
|
+
: this.options.get('defaultUrlProtocol') && !value.includes('://') && value.indexOf('#') !== 0
|
|
543
|
+
? this.options.get('defaultUrlProtocol') + value
|
|
544
|
+
: !value.includes('://')
|
|
545
|
+
? '/' + value
|
|
546
|
+
: value;
|
|
547
|
+
}
|
|
405
548
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
549
|
+
/**
|
|
550
|
+
* @description Opens the audio gallery plugin, if available.
|
|
551
|
+
* - Calls a function to populate the URL input with the selected audio file.
|
|
552
|
+
*/
|
|
553
|
+
#OpenGallery() {
|
|
554
|
+
this.plugins.audioGallery.open(this.#SetUrlInput.bind(this));
|
|
412
555
|
}
|
|
413
556
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
557
|
+
/**
|
|
558
|
+
* @param {HTMLInputElement} target - The target element.
|
|
559
|
+
*/
|
|
560
|
+
#SetUrlInput(target) {
|
|
561
|
+
this.urlValue = this.preview.textContent = this.audioUrlFile.value = target.getAttribute('data-command') || target.src;
|
|
562
|
+
this.audioUrlFile.focus();
|
|
563
|
+
}
|
|
417
564
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
this.
|
|
565
|
+
/**
|
|
566
|
+
* @description Clears the selected file input and re-enables the URL input.
|
|
567
|
+
* - Ensures that only one input method (file or URL) is used at a time.
|
|
568
|
+
* @param {HTMLInputElement} urlInput - The URL input field.
|
|
569
|
+
* @param {HTMLElement} preview - The preview text element.
|
|
570
|
+
*/
|
|
571
|
+
#RemoveSelectedFiles(urlInput, preview) {
|
|
572
|
+
this.audioInputFile.value = '';
|
|
573
|
+
if (urlInput) {
|
|
574
|
+
urlInput.disabled = false;
|
|
575
|
+
preview.style.textDecoration = '';
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// inputFile check
|
|
579
|
+
Modal.OnChangeFile(this.fileModalWrapper, []);
|
|
426
580
|
}
|
|
427
581
|
|
|
428
|
-
|
|
429
|
-
|
|
582
|
+
/**
|
|
583
|
+
* @param {InputEvent} e - Event object
|
|
584
|
+
*/
|
|
585
|
+
#FileInputChange(e) {
|
|
586
|
+
/** @type {HTMLInputElement} */
|
|
587
|
+
const target = dom.query.getEventTarget(e);
|
|
588
|
+
if (!this.audioInputFile.value) {
|
|
589
|
+
this.audioUrlFile.disabled = false;
|
|
590
|
+
this.preview.style.textDecoration = '';
|
|
591
|
+
} else {
|
|
592
|
+
this.audioUrlFile.disabled = true;
|
|
593
|
+
this.preview.style.textDecoration = 'line-through';
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
// inputFile check
|
|
597
|
+
Modal.OnChangeFile(this.fileModalWrapper, target.files);
|
|
598
|
+
}
|
|
430
599
|
}
|
|
431
600
|
|
|
432
|
-
function CreateHTML_modal({ lang, icons }, pluginOptions) {
|
|
601
|
+
function CreateHTML_modal({ lang, icons, plugins }, pluginOptions) {
|
|
433
602
|
let html = /*html*/ `
|
|
434
603
|
<form method="post" enctype="multipart/form-data">
|
|
435
604
|
<div class="se-modal-header">
|
|
@@ -450,7 +619,17 @@ function CreateHTML_modal({ lang, icons }, pluginOptions) {
|
|
|
450
619
|
html += /*html*/ `
|
|
451
620
|
<div class="se-modal-form">
|
|
452
621
|
<label>${lang.audio_modal_url}</label>
|
|
453
|
-
|
|
622
|
+
<div class="se-modal-form-files">
|
|
623
|
+
<input class="se-input-form se-input-url" data-focus type="text" />
|
|
624
|
+
${
|
|
625
|
+
plugins.audioGallery
|
|
626
|
+
? `<button type="button" class="se-btn se-tooltip se-modal-files-edge-button __se__gallery" aria-label="${lang.audioGallery}">
|
|
627
|
+
${icons.audio_gallery}
|
|
628
|
+
${dom.utils.createTooltipInner(lang.audioGallery)}
|
|
629
|
+
</button>`
|
|
630
|
+
: ''
|
|
631
|
+
}
|
|
632
|
+
</div>
|
|
454
633
|
<pre class="se-link-preview"></pre>
|
|
455
634
|
</div>`;
|
|
456
635
|
}
|
|
@@ -463,7 +642,7 @@ function CreateHTML_modal({ lang, icons }, pluginOptions) {
|
|
|
463
642
|
</div>
|
|
464
643
|
</form>`;
|
|
465
644
|
|
|
466
|
-
return
|
|
645
|
+
return dom.utils.createElement('DIV', { class: 'se-modal-content' }, html);
|
|
467
646
|
}
|
|
468
647
|
|
|
469
648
|
function CreateHTML_controller({ lang, icons }) {
|
|
@@ -477,6 +656,12 @@ function CreateHTML_controller({ lang, icons }) {
|
|
|
477
656
|
<span class="se-tooltip-text">${lang.edit}</span>
|
|
478
657
|
</span>
|
|
479
658
|
</button>
|
|
659
|
+
<button type="button" data-command="copy" tabindex="-1" class="se-btn se-tooltip">
|
|
660
|
+
${icons.copy}
|
|
661
|
+
<span class="se-tooltip-inner">
|
|
662
|
+
<span class="se-tooltip-text">${lang.copy}</span>
|
|
663
|
+
</span>
|
|
664
|
+
</button>
|
|
480
665
|
<button type="button" data-command="delete" tabindex="-1" class="se-btn se-tooltip">
|
|
481
666
|
${icons.delete}
|
|
482
667
|
<span class="se-tooltip-inner">
|
|
@@ -486,7 +671,7 @@ function CreateHTML_controller({ lang, icons }) {
|
|
|
486
671
|
</div>
|
|
487
672
|
</div>`;
|
|
488
673
|
|
|
489
|
-
return
|
|
674
|
+
return dom.utils.createElement('DIV', { class: 'se-controller' }, html);
|
|
490
675
|
}
|
|
491
676
|
|
|
492
677
|
export default Audio_;
|