autumnnote 1.6.1 → 1.6.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/dist/autumnnote.es.js +123 -213
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +123 -213
- package/dist/autumnnote.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/js/Context.js +5 -2
- package/src/js/index.js +1 -1
- package/src/js/module/BaseDialog.js +126 -0
- package/src/js/module/ImageDialog.js +12 -82
- package/src/js/module/LinkDialog.js +12 -78
- package/src/js/module/VideoDialog.js +10 -80
package/dist/autumnnote.umd.js
CHANGED
|
@@ -6978,15 +6978,13 @@
|
|
|
6978
6978
|
}
|
|
6979
6979
|
};
|
|
6980
6980
|
//#endregion
|
|
6981
|
-
//#region src/js/module/
|
|
6981
|
+
//#region src/js/module/BaseDialog.js
|
|
6982
6982
|
/**
|
|
6983
|
-
*
|
|
6984
|
-
*
|
|
6983
|
+
* Shared lifecycle and shell-building logic for all modal dialogs.
|
|
6984
|
+
* Subclasses implement _buildDialog() for their specific form fields.
|
|
6985
6985
|
*/
|
|
6986
|
-
var
|
|
6987
|
-
/**
|
|
6988
|
-
* @param {import('../Context.js').Context} context
|
|
6989
|
-
*/
|
|
6986
|
+
var BaseDialog = class {
|
|
6987
|
+
/** @param {import('../Context.js').Context} context */
|
|
6990
6988
|
constructor(context) {
|
|
6991
6989
|
this.context = context;
|
|
6992
6990
|
this.options = context.options;
|
|
@@ -6994,6 +6992,9 @@
|
|
|
6994
6992
|
this._dialog = null;
|
|
6995
6993
|
this._disposers = [];
|
|
6996
6994
|
this._savedRange = null;
|
|
6995
|
+
/** @type {HTMLElement|null} First focusable input; set by subclass in _buildDialog(). */
|
|
6996
|
+
this._firstInput = null;
|
|
6997
|
+
this._removeTrap = null;
|
|
6997
6998
|
}
|
|
6998
6999
|
initialize() {
|
|
6999
7000
|
this._dialog = this._buildDialog();
|
|
@@ -7003,36 +7004,113 @@
|
|
|
7003
7004
|
destroy() {
|
|
7004
7005
|
this._disposers.forEach((d) => d());
|
|
7005
7006
|
this._disposers = [];
|
|
7006
|
-
if (this._dialog
|
|
7007
|
+
if (this._dialog?.parentNode) this._dialog.remove();
|
|
7007
7008
|
this._dialog = null;
|
|
7008
7009
|
}
|
|
7009
|
-
/**
|
|
7010
|
-
|
|
7011
|
-
* Pre-fills with the currently selected link if present.
|
|
7012
|
-
*/
|
|
7013
|
-
show() {
|
|
7010
|
+
/** Saves the current selection range before opening the dialog. */
|
|
7011
|
+
_saveRange() {
|
|
7014
7012
|
withSavedRange((range) => {
|
|
7015
7013
|
this._savedRange = range;
|
|
7016
7014
|
});
|
|
7017
|
-
this._prefill();
|
|
7018
|
-
this._open();
|
|
7019
7015
|
}
|
|
7020
|
-
|
|
7021
|
-
|
|
7016
|
+
_open() {
|
|
7017
|
+
if (this._dialog) {
|
|
7018
|
+
this._dialog.style.display = "flex";
|
|
7019
|
+
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7020
|
+
setTimeout(() => this._firstInput && this._firstInput.focus(), 50);
|
|
7021
|
+
}
|
|
7022
|
+
}
|
|
7023
|
+
_close() {
|
|
7024
|
+
if (this._dialog) this._dialog.style.display = "none";
|
|
7025
|
+
if (this._removeTrap) {
|
|
7026
|
+
this._removeTrap();
|
|
7027
|
+
this._removeTrap = null;
|
|
7028
|
+
}
|
|
7029
|
+
this._savedRange = null;
|
|
7030
|
+
}
|
|
7031
|
+
/**
|
|
7032
|
+
* Builds the overlay + box + header shell common to all dialogs.
|
|
7033
|
+
* Also wires up draggable and overlay-click-to-close.
|
|
7034
|
+
* @param {string} ariaLabel
|
|
7035
|
+
* @param {string} iconHtml Raw SVG string for the dialog icon
|
|
7036
|
+
* @param {string} titleText
|
|
7037
|
+
* @returns {{ overlay: HTMLElement, box: HTMLElement }}
|
|
7038
|
+
*/
|
|
7039
|
+
_buildDialogShell(ariaLabel, iconHtml, titleText) {
|
|
7022
7040
|
const overlay = createElement("div", {
|
|
7023
7041
|
class: "an-dialog-overlay",
|
|
7024
7042
|
role: "dialog",
|
|
7025
7043
|
"aria-modal": "true",
|
|
7026
|
-
"aria-label":
|
|
7044
|
+
"aria-label": ariaLabel
|
|
7027
7045
|
});
|
|
7028
7046
|
const box = createElement("div", { class: "an-dialog-box" });
|
|
7029
7047
|
const header = createElement("div", { class: "an-dialog-header" });
|
|
7030
7048
|
const iconEl = createElement("span", { class: "an-dialog-icon" });
|
|
7031
|
-
iconEl.innerHTML =
|
|
7032
|
-
const
|
|
7033
|
-
|
|
7049
|
+
iconEl.innerHTML = iconHtml;
|
|
7050
|
+
const titleEl = createElement("h3", { class: "an-dialog-title" });
|
|
7051
|
+
titleEl.textContent = titleText;
|
|
7034
7052
|
header.appendChild(iconEl);
|
|
7035
|
-
header.appendChild(
|
|
7053
|
+
header.appendChild(titleEl);
|
|
7054
|
+
box.appendChild(header);
|
|
7055
|
+
overlay.appendChild(box);
|
|
7056
|
+
makeDraggable(header, box);
|
|
7057
|
+
const d = on(overlay, "click", (e) => {
|
|
7058
|
+
if (e.target === overlay) this._close();
|
|
7059
|
+
});
|
|
7060
|
+
this._disposers.push(d);
|
|
7061
|
+
return {
|
|
7062
|
+
overlay,
|
|
7063
|
+
box
|
|
7064
|
+
};
|
|
7065
|
+
}
|
|
7066
|
+
/**
|
|
7067
|
+
* Builds an action button row with a primary insert button and a cancel button.
|
|
7068
|
+
* Disposers are registered automatically.
|
|
7069
|
+
* @param {string} insertLabel
|
|
7070
|
+
* @param {string} cancelLabel
|
|
7071
|
+
* @param {() => void} onInsert
|
|
7072
|
+
* @returns {HTMLElement}
|
|
7073
|
+
*/
|
|
7074
|
+
_buildButtonRow(insertLabel, cancelLabel, onInsert) {
|
|
7075
|
+
const btnRow = createElement("div", { class: "an-dialog-actions" });
|
|
7076
|
+
const insertBtn = createElement("button", {
|
|
7077
|
+
type: "button",
|
|
7078
|
+
class: "an-btn an-btn-primary"
|
|
7079
|
+
});
|
|
7080
|
+
insertBtn.textContent = insertLabel;
|
|
7081
|
+
const cancelBtn = createElement("button", {
|
|
7082
|
+
type: "button",
|
|
7083
|
+
class: "an-btn"
|
|
7084
|
+
});
|
|
7085
|
+
cancelBtn.textContent = cancelLabel;
|
|
7086
|
+
btnRow.appendChild(insertBtn);
|
|
7087
|
+
btnRow.appendChild(cancelBtn);
|
|
7088
|
+
const d1 = on(insertBtn, "click", onInsert);
|
|
7089
|
+
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7090
|
+
this._disposers.push(d1, d2);
|
|
7091
|
+
return btnRow;
|
|
7092
|
+
}
|
|
7093
|
+
};
|
|
7094
|
+
//#endregion
|
|
7095
|
+
//#region src/js/module/LinkDialog.js
|
|
7096
|
+
/**
|
|
7097
|
+
* LinkDialog.js - Dialog for inserting / editing hyperlinks
|
|
7098
|
+
* Inspired by Summernote's LinkDialog — rewritten without jQuery
|
|
7099
|
+
*/
|
|
7100
|
+
var ICON_SVG$2 = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>`;
|
|
7101
|
+
var LinkDialog = class extends BaseDialog {
|
|
7102
|
+
/**
|
|
7103
|
+
* Opens the link dialog.
|
|
7104
|
+
* Pre-fills with the currently selected link if present.
|
|
7105
|
+
*/
|
|
7106
|
+
show() {
|
|
7107
|
+
this._saveRange();
|
|
7108
|
+
this._prefill();
|
|
7109
|
+
this._open();
|
|
7110
|
+
}
|
|
7111
|
+
_buildDialog() {
|
|
7112
|
+
const L = this.context.locale.linkDialog;
|
|
7113
|
+
const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG$2, L.title);
|
|
7036
7114
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7037
7115
|
urlLabel.textContent = L.url;
|
|
7038
7116
|
const urlInput = createElement("input", {
|
|
@@ -7044,6 +7122,7 @@
|
|
|
7044
7122
|
autocomplete: "off"
|
|
7045
7123
|
});
|
|
7046
7124
|
this._urlInput = urlInput;
|
|
7125
|
+
this._firstInput = urlInput;
|
|
7047
7126
|
const textLabel = createElement("label", { class: "an-label" });
|
|
7048
7127
|
textLabel.textContent = L.displayText;
|
|
7049
7128
|
const textInput = createElement("input", {
|
|
@@ -7064,27 +7143,8 @@
|
|
|
7064
7143
|
this._tabCheckbox = tabCheckbox;
|
|
7065
7144
|
tabLabel.appendChild(tabCheckbox);
|
|
7066
7145
|
tabLabel.appendChild(document.createTextNode(" " + L.openInNewTab));
|
|
7067
|
-
const btnRow =
|
|
7068
|
-
|
|
7069
|
-
type: "button",
|
|
7070
|
-
class: "an-btn an-btn-primary"
|
|
7071
|
-
});
|
|
7072
|
-
insertBtn.textContent = L.insertBtn;
|
|
7073
|
-
const cancelBtn = createElement("button", {
|
|
7074
|
-
type: "button",
|
|
7075
|
-
class: "an-btn"
|
|
7076
|
-
});
|
|
7077
|
-
cancelBtn.textContent = L.cancelBtn;
|
|
7078
|
-
btnRow.appendChild(insertBtn);
|
|
7079
|
-
btnRow.appendChild(cancelBtn);
|
|
7080
|
-
box.append(header, urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);
|
|
7081
|
-
overlay.appendChild(box);
|
|
7082
|
-
makeDraggable(header, box);
|
|
7083
|
-
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7084
|
-
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7085
|
-
const d3 = on(overlay, "click", (e) => {
|
|
7086
|
-
if (e.target === overlay) this._close();
|
|
7087
|
-
});
|
|
7146
|
+
const btnRow = this._buildButtonRow(L.insertBtn, L.cancelBtn, () => this._onInsert());
|
|
7147
|
+
box.append(urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);
|
|
7088
7148
|
const d4 = on(urlInput, "keydown", (e) => {
|
|
7089
7149
|
if (e.key === "Enter") {
|
|
7090
7150
|
e.preventDefault();
|
|
@@ -7097,7 +7157,7 @@
|
|
|
7097
7157
|
this._onInsert();
|
|
7098
7158
|
}
|
|
7099
7159
|
});
|
|
7100
|
-
this._disposers.push(
|
|
7160
|
+
this._disposers.push(d4, d5);
|
|
7101
7161
|
return overlay;
|
|
7102
7162
|
}
|
|
7103
7163
|
_prefill() {
|
|
@@ -7146,21 +7206,6 @@
|
|
|
7146
7206
|
this.context.invoke("editor.insertLink", url, text, newTab);
|
|
7147
7207
|
this._close();
|
|
7148
7208
|
}
|
|
7149
|
-
_open() {
|
|
7150
|
-
if (this._dialog) {
|
|
7151
|
-
this._dialog.style.display = "flex";
|
|
7152
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7153
|
-
setTimeout(() => this._urlInput && this._urlInput.focus(), 50);
|
|
7154
|
-
}
|
|
7155
|
-
}
|
|
7156
|
-
_close() {
|
|
7157
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
7158
|
-
if (this._removeTrap) {
|
|
7159
|
-
this._removeTrap();
|
|
7160
|
-
this._removeTrap = null;
|
|
7161
|
-
}
|
|
7162
|
-
this._savedRange = null;
|
|
7163
|
-
}
|
|
7164
7209
|
};
|
|
7165
7210
|
//#endregion
|
|
7166
7211
|
//#region src/js/module/ImageDialog.js
|
|
@@ -7168,33 +7213,10 @@
|
|
|
7168
7213
|
* ImageDialog.js - Dialog for inserting images (by URL or file upload)
|
|
7169
7214
|
* Inspired by Summernote's ImageDialog — rewritten without jQuery
|
|
7170
7215
|
*/
|
|
7171
|
-
var
|
|
7172
|
-
|
|
7173
|
-
* @param {import('../Context.js').Context} context
|
|
7174
|
-
*/
|
|
7175
|
-
constructor(context) {
|
|
7176
|
-
this.context = context;
|
|
7177
|
-
this.options = context.options;
|
|
7178
|
-
/** @type {HTMLElement|null} */
|
|
7179
|
-
this._dialog = null;
|
|
7180
|
-
this._disposers = [];
|
|
7181
|
-
this._savedRange = null;
|
|
7182
|
-
}
|
|
7183
|
-
initialize() {
|
|
7184
|
-
this._dialog = this._buildDialog();
|
|
7185
|
-
document.body.appendChild(this._dialog);
|
|
7186
|
-
return this;
|
|
7187
|
-
}
|
|
7188
|
-
destroy() {
|
|
7189
|
-
this._disposers.forEach((d) => d());
|
|
7190
|
-
this._disposers = [];
|
|
7191
|
-
if (this._dialog && this._dialog.parentNode) this._dialog.remove();
|
|
7192
|
-
this._dialog = null;
|
|
7193
|
-
}
|
|
7216
|
+
var ICON_SVG$1 = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>`;
|
|
7217
|
+
var ImageDialog = class extends BaseDialog {
|
|
7194
7218
|
show() {
|
|
7195
|
-
|
|
7196
|
-
this._savedRange = range;
|
|
7197
|
-
});
|
|
7219
|
+
this._saveRange();
|
|
7198
7220
|
this._urlInput.value = "";
|
|
7199
7221
|
this._altInput.value = "";
|
|
7200
7222
|
if (this._fileInput) this._fileInput.value = "";
|
|
@@ -7202,20 +7224,7 @@
|
|
|
7202
7224
|
}
|
|
7203
7225
|
_buildDialog() {
|
|
7204
7226
|
const L = this.context.locale.imageDialog;
|
|
7205
|
-
const overlay =
|
|
7206
|
-
class: "an-dialog-overlay",
|
|
7207
|
-
role: "dialog",
|
|
7208
|
-
"aria-modal": "true",
|
|
7209
|
-
"aria-label": L.ariaLabel
|
|
7210
|
-
});
|
|
7211
|
-
const box = createElement("div", { class: "an-dialog-box" });
|
|
7212
|
-
const header = createElement("div", { class: "an-dialog-header" });
|
|
7213
|
-
const iconEl = createElement("span", { class: "an-dialog-icon" });
|
|
7214
|
-
iconEl.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>`;
|
|
7215
|
-
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7216
|
-
title.textContent = L.title;
|
|
7217
|
-
header.appendChild(iconEl);
|
|
7218
|
-
header.appendChild(title);
|
|
7227
|
+
const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG$1, L.title);
|
|
7219
7228
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7220
7229
|
urlLabel.textContent = L.imageUrl;
|
|
7221
7230
|
const urlInput = createElement("input", {
|
|
@@ -7225,6 +7234,7 @@
|
|
|
7225
7234
|
autocomplete: "off"
|
|
7226
7235
|
});
|
|
7227
7236
|
this._urlInput = urlInput;
|
|
7237
|
+
this._firstInput = urlInput;
|
|
7228
7238
|
const altLabel = createElement("label", { class: "an-label" });
|
|
7229
7239
|
altLabel.textContent = L.altText;
|
|
7230
7240
|
const altInput = createElement("input", {
|
|
@@ -7234,7 +7244,7 @@
|
|
|
7234
7244
|
autocomplete: "off"
|
|
7235
7245
|
});
|
|
7236
7246
|
this._altInput = altInput;
|
|
7237
|
-
box.append(
|
|
7247
|
+
box.append(urlLabel, urlInput, altLabel, altInput);
|
|
7238
7248
|
const alignLabel = createElement("label", { class: "an-label" });
|
|
7239
7249
|
alignLabel.textContent = L.alignment;
|
|
7240
7250
|
const alignRow = createElement("div", { class: "an-align-row" });
|
|
@@ -7288,27 +7298,8 @@
|
|
|
7288
7298
|
this._disposers.push(d);
|
|
7289
7299
|
box.append(fileLabel, fileInput, fileHint);
|
|
7290
7300
|
}
|
|
7291
|
-
const btnRow =
|
|
7292
|
-
const insertBtn = createElement("button", {
|
|
7293
|
-
type: "button",
|
|
7294
|
-
class: "an-btn an-btn-primary"
|
|
7295
|
-
});
|
|
7296
|
-
insertBtn.textContent = L.insertBtn;
|
|
7297
|
-
const cancelBtn = createElement("button", {
|
|
7298
|
-
type: "button",
|
|
7299
|
-
class: "an-btn"
|
|
7300
|
-
});
|
|
7301
|
-
cancelBtn.textContent = L.cancelBtn;
|
|
7302
|
-
btnRow.appendChild(insertBtn);
|
|
7303
|
-
btnRow.appendChild(cancelBtn);
|
|
7301
|
+
const btnRow = this._buildButtonRow(L.insertBtn, L.cancelBtn, () => this._onInsert());
|
|
7304
7302
|
box.append(btnRow);
|
|
7305
|
-
overlay.appendChild(box);
|
|
7306
|
-
makeDraggable(header, box);
|
|
7307
|
-
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7308
|
-
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7309
|
-
const d3 = on(overlay, "click", (e) => {
|
|
7310
|
-
if (e.target === overlay) this._close();
|
|
7311
|
-
});
|
|
7312
7303
|
const d4 = on(urlInput, "keydown", (e) => {
|
|
7313
7304
|
if (e.key === "Enter") {
|
|
7314
7305
|
e.preventDefault();
|
|
@@ -7321,7 +7312,7 @@
|
|
|
7321
7312
|
this._onInsert();
|
|
7322
7313
|
}
|
|
7323
7314
|
});
|
|
7324
|
-
this._disposers.push(
|
|
7315
|
+
this._disposers.push(d4, d5);
|
|
7325
7316
|
return overlay;
|
|
7326
7317
|
}
|
|
7327
7318
|
_onFileChange() {
|
|
@@ -7376,21 +7367,6 @@
|
|
|
7376
7367
|
this.context.invoke("editor.insertImage", src, alt, align);
|
|
7377
7368
|
this._close();
|
|
7378
7369
|
}
|
|
7379
|
-
_open() {
|
|
7380
|
-
if (this._dialog) {
|
|
7381
|
-
this._dialog.style.display = "flex";
|
|
7382
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7383
|
-
setTimeout(() => this._urlInput && this._urlInput.focus(), 50);
|
|
7384
|
-
}
|
|
7385
|
-
}
|
|
7386
|
-
_close() {
|
|
7387
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
7388
|
-
if (this._removeTrap) {
|
|
7389
|
-
this._removeTrap();
|
|
7390
|
-
this._removeTrap = null;
|
|
7391
|
-
}
|
|
7392
|
-
this._savedRange = null;
|
|
7393
|
-
}
|
|
7394
7370
|
};
|
|
7395
7371
|
//#endregion
|
|
7396
7372
|
//#region src/js/module/VideoDialog.js
|
|
@@ -7402,31 +7378,10 @@
|
|
|
7402
7378
|
* • Vimeo URLs → <iframe> embed
|
|
7403
7379
|
* • Direct video URLs → <video> element (.mp4 / .webm / .ogg)
|
|
7404
7380
|
*/
|
|
7405
|
-
var
|
|
7406
|
-
|
|
7407
|
-
constructor(context) {
|
|
7408
|
-
this.context = context;
|
|
7409
|
-
this.options = context.options;
|
|
7410
|
-
/** @type {HTMLElement|null} */
|
|
7411
|
-
this._dialog = null;
|
|
7412
|
-
this._disposers = [];
|
|
7413
|
-
this._savedRange = null;
|
|
7414
|
-
}
|
|
7415
|
-
initialize() {
|
|
7416
|
-
this._dialog = this._buildDialog();
|
|
7417
|
-
document.body.appendChild(this._dialog);
|
|
7418
|
-
return this;
|
|
7419
|
-
}
|
|
7420
|
-
destroy() {
|
|
7421
|
-
this._disposers.forEach((d) => d());
|
|
7422
|
-
this._disposers = [];
|
|
7423
|
-
if (this._dialog && this._dialog.parentNode) this._dialog.remove();
|
|
7424
|
-
this._dialog = null;
|
|
7425
|
-
}
|
|
7381
|
+
var ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg>`;
|
|
7382
|
+
var VideoDialog = class extends BaseDialog {
|
|
7426
7383
|
show() {
|
|
7427
|
-
|
|
7428
|
-
this._savedRange = range;
|
|
7429
|
-
});
|
|
7384
|
+
this._saveRange();
|
|
7430
7385
|
this._urlInput.value = "";
|
|
7431
7386
|
this._widthInput.value = "560";
|
|
7432
7387
|
this._hintEl.textContent = "";
|
|
@@ -7434,20 +7389,7 @@
|
|
|
7434
7389
|
}
|
|
7435
7390
|
_buildDialog() {
|
|
7436
7391
|
const L = this.context.locale.videoDialog;
|
|
7437
|
-
const overlay =
|
|
7438
|
-
class: "an-dialog-overlay",
|
|
7439
|
-
role: "dialog",
|
|
7440
|
-
"aria-modal": "true",
|
|
7441
|
-
"aria-label": L.ariaLabel
|
|
7442
|
-
});
|
|
7443
|
-
const box = createElement("div", { class: "an-dialog-box" });
|
|
7444
|
-
const header = createElement("div", { class: "an-dialog-header" });
|
|
7445
|
-
const iconEl = createElement("span", { class: "an-dialog-icon" });
|
|
7446
|
-
iconEl.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2"/></svg>`;
|
|
7447
|
-
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7448
|
-
title.textContent = L.title;
|
|
7449
|
-
header.appendChild(iconEl);
|
|
7450
|
-
header.appendChild(title);
|
|
7392
|
+
const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG, L.title);
|
|
7451
7393
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7452
7394
|
urlLabel.textContent = L.videoUrl;
|
|
7453
7395
|
const urlInput = createElement("input", {
|
|
@@ -7457,6 +7399,7 @@
|
|
|
7457
7399
|
autocomplete: "off"
|
|
7458
7400
|
});
|
|
7459
7401
|
this._urlInput = urlInput;
|
|
7402
|
+
this._firstInput = urlInput;
|
|
7460
7403
|
const hintEl = createElement("p", { class: "an-dialog-hint" });
|
|
7461
7404
|
this._hintEl = hintEl;
|
|
7462
7405
|
const widthLabel = createElement("label", { class: "an-label" });
|
|
@@ -7470,38 +7413,19 @@
|
|
|
7470
7413
|
value: "560"
|
|
7471
7414
|
});
|
|
7472
7415
|
this._widthInput = widthInput;
|
|
7473
|
-
const btnRow =
|
|
7474
|
-
|
|
7475
|
-
type: "button",
|
|
7476
|
-
class: "an-btn an-btn-primary"
|
|
7477
|
-
});
|
|
7478
|
-
insertBtn.textContent = L.insertBtn;
|
|
7479
|
-
const cancelBtn = createElement("button", {
|
|
7480
|
-
type: "button",
|
|
7481
|
-
class: "an-btn"
|
|
7482
|
-
});
|
|
7483
|
-
cancelBtn.textContent = L.cancelBtn;
|
|
7484
|
-
btnRow.appendChild(insertBtn);
|
|
7485
|
-
btnRow.appendChild(cancelBtn);
|
|
7486
|
-
box.append(header, urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);
|
|
7487
|
-
overlay.appendChild(box);
|
|
7488
|
-
makeDraggable(header, box);
|
|
7416
|
+
const btnRow = this._buildButtonRow(L.insertBtn, L.cancelBtn, () => this._onInsert());
|
|
7417
|
+
box.append(urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);
|
|
7489
7418
|
const d0 = on(urlInput, "input", () => {
|
|
7490
7419
|
const info = this._parseVideoUrl(urlInput.value.trim());
|
|
7491
7420
|
hintEl.textContent = info ? this.context.locale.videoDialog.detected(info.type) : urlInput.value ? this.context.locale.videoDialog.unknownFormat : "";
|
|
7492
7421
|
});
|
|
7493
|
-
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7494
|
-
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7495
|
-
const d3 = on(overlay, "click", (e) => {
|
|
7496
|
-
if (e.target === overlay) this._close();
|
|
7497
|
-
});
|
|
7498
7422
|
const d4 = on(urlInput, "keydown", (e) => {
|
|
7499
7423
|
if (e.key === "Enter") {
|
|
7500
7424
|
e.preventDefault();
|
|
7501
7425
|
this._onInsert();
|
|
7502
7426
|
}
|
|
7503
7427
|
});
|
|
7504
|
-
this._disposers.push(d0,
|
|
7428
|
+
this._disposers.push(d0, d4);
|
|
7505
7429
|
return overlay;
|
|
7506
7430
|
}
|
|
7507
7431
|
_onInsert() {
|
|
@@ -7521,21 +7445,6 @@
|
|
|
7521
7445
|
this.context.invoke("editor.insertVideo", html);
|
|
7522
7446
|
this._close();
|
|
7523
7447
|
}
|
|
7524
|
-
_open() {
|
|
7525
|
-
if (this._dialog) {
|
|
7526
|
-
this._dialog.style.display = "flex";
|
|
7527
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7528
|
-
setTimeout(() => this._urlInput && this._urlInput.focus(), 50);
|
|
7529
|
-
}
|
|
7530
|
-
}
|
|
7531
|
-
_close() {
|
|
7532
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
7533
|
-
if (this._removeTrap) {
|
|
7534
|
-
this._removeTrap();
|
|
7535
|
-
this._removeTrap = null;
|
|
7536
|
-
}
|
|
7537
|
-
this._savedRange = null;
|
|
7538
|
-
}
|
|
7539
7448
|
/**
|
|
7540
7449
|
* Parses a video URL and returns { type, embedUrl } or null.
|
|
7541
7450
|
* @param {string} url
|
|
@@ -16029,7 +15938,7 @@
|
|
|
16029
15938
|
register("markdownShortcuts", MarkdownShortcuts);
|
|
16030
15939
|
register("bubbleToolbar", BubbleToolbar);
|
|
16031
15940
|
register("mention", Mention);
|
|
16032
|
-
for (const [name, ModuleClass] of _customModules) register(name, ModuleClass);
|
|
15941
|
+
if (_customModules.size > 0) for (const [name, ModuleClass] of _customModules) register(name, ModuleClass);
|
|
16033
15942
|
}
|
|
16034
15943
|
/**
|
|
16035
15944
|
* Registers and initialises a custom module on this instance.
|
|
@@ -16082,6 +15991,7 @@
|
|
|
16082
15991
|
});
|
|
16083
15992
|
}
|
|
16084
15993
|
_applyGlobalPlugins() {
|
|
15994
|
+
if (_globalPlugins.size === 0) return;
|
|
16085
15995
|
for (const { plugin, options } of _globalPlugins.values()) this._installPlugin(plugin, options);
|
|
16086
15996
|
}
|
|
16087
15997
|
_bindEditorEvents(editable) {
|
|
@@ -16478,7 +16388,7 @@
|
|
|
16478
16388
|
return this;
|
|
16479
16389
|
},
|
|
16480
16390
|
/** Library version */
|
|
16481
|
-
version: "1.
|
|
16391
|
+
version: "1.6.2"
|
|
16482
16392
|
};
|
|
16483
16393
|
/**
|
|
16484
16394
|
* @param {string|Element|NodeList|Element[]} selector
|