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.es.js
CHANGED
|
@@ -7282,15 +7282,13 @@ var Fullscreen = class {
|
|
|
7282
7282
|
}
|
|
7283
7283
|
};
|
|
7284
7284
|
//#endregion
|
|
7285
|
-
//#region src/js/module/
|
|
7285
|
+
//#region src/js/module/BaseDialog.js
|
|
7286
7286
|
/**
|
|
7287
|
-
*
|
|
7288
|
-
*
|
|
7287
|
+
* Shared lifecycle and shell-building logic for all modal dialogs.
|
|
7288
|
+
* Subclasses implement _buildDialog() for their specific form fields.
|
|
7289
7289
|
*/
|
|
7290
|
-
var
|
|
7291
|
-
/**
|
|
7292
|
-
* @param {import('../Context.js').Context} context
|
|
7293
|
-
*/
|
|
7290
|
+
var BaseDialog = class {
|
|
7291
|
+
/** @param {import('../Context.js').Context} context */
|
|
7294
7292
|
constructor(context) {
|
|
7295
7293
|
this.context = context;
|
|
7296
7294
|
this.options = context.options;
|
|
@@ -7298,6 +7296,9 @@ var LinkDialog = class {
|
|
|
7298
7296
|
this._dialog = null;
|
|
7299
7297
|
this._disposers = [];
|
|
7300
7298
|
this._savedRange = null;
|
|
7299
|
+
/** @type {HTMLElement|null} First focusable input; set by subclass in _buildDialog(). */
|
|
7300
|
+
this._firstInput = null;
|
|
7301
|
+
this._removeTrap = null;
|
|
7301
7302
|
}
|
|
7302
7303
|
initialize() {
|
|
7303
7304
|
this._dialog = this._buildDialog();
|
|
@@ -7307,36 +7308,113 @@ var LinkDialog = class {
|
|
|
7307
7308
|
destroy() {
|
|
7308
7309
|
this._disposers.forEach((d) => d());
|
|
7309
7310
|
this._disposers = [];
|
|
7310
|
-
if (this._dialog
|
|
7311
|
+
if (this._dialog?.parentNode) this._dialog.remove();
|
|
7311
7312
|
this._dialog = null;
|
|
7312
7313
|
}
|
|
7313
|
-
/**
|
|
7314
|
-
|
|
7315
|
-
* Pre-fills with the currently selected link if present.
|
|
7316
|
-
*/
|
|
7317
|
-
show() {
|
|
7314
|
+
/** Saves the current selection range before opening the dialog. */
|
|
7315
|
+
_saveRange() {
|
|
7318
7316
|
withSavedRange((range) => {
|
|
7319
7317
|
this._savedRange = range;
|
|
7320
7318
|
});
|
|
7321
|
-
this._prefill();
|
|
7322
|
-
this._open();
|
|
7323
7319
|
}
|
|
7324
|
-
|
|
7325
|
-
|
|
7320
|
+
_open() {
|
|
7321
|
+
if (this._dialog) {
|
|
7322
|
+
this._dialog.style.display = "flex";
|
|
7323
|
+
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7324
|
+
setTimeout(() => this._firstInput && this._firstInput.focus(), 50);
|
|
7325
|
+
}
|
|
7326
|
+
}
|
|
7327
|
+
_close() {
|
|
7328
|
+
if (this._dialog) this._dialog.style.display = "none";
|
|
7329
|
+
if (this._removeTrap) {
|
|
7330
|
+
this._removeTrap();
|
|
7331
|
+
this._removeTrap = null;
|
|
7332
|
+
}
|
|
7333
|
+
this._savedRange = null;
|
|
7334
|
+
}
|
|
7335
|
+
/**
|
|
7336
|
+
* Builds the overlay + box + header shell common to all dialogs.
|
|
7337
|
+
* Also wires up draggable and overlay-click-to-close.
|
|
7338
|
+
* @param {string} ariaLabel
|
|
7339
|
+
* @param {string} iconHtml Raw SVG string for the dialog icon
|
|
7340
|
+
* @param {string} titleText
|
|
7341
|
+
* @returns {{ overlay: HTMLElement, box: HTMLElement }}
|
|
7342
|
+
*/
|
|
7343
|
+
_buildDialogShell(ariaLabel, iconHtml, titleText) {
|
|
7326
7344
|
const overlay = createElement("div", {
|
|
7327
7345
|
class: "an-dialog-overlay",
|
|
7328
7346
|
role: "dialog",
|
|
7329
7347
|
"aria-modal": "true",
|
|
7330
|
-
"aria-label":
|
|
7348
|
+
"aria-label": ariaLabel
|
|
7331
7349
|
});
|
|
7332
7350
|
const box = createElement("div", { class: "an-dialog-box" });
|
|
7333
7351
|
const header = createElement("div", { class: "an-dialog-header" });
|
|
7334
7352
|
const iconEl = createElement("span", { class: "an-dialog-icon" });
|
|
7335
|
-
iconEl.innerHTML =
|
|
7336
|
-
const
|
|
7337
|
-
|
|
7353
|
+
iconEl.innerHTML = iconHtml;
|
|
7354
|
+
const titleEl = createElement("h3", { class: "an-dialog-title" });
|
|
7355
|
+
titleEl.textContent = titleText;
|
|
7338
7356
|
header.appendChild(iconEl);
|
|
7339
|
-
header.appendChild(
|
|
7357
|
+
header.appendChild(titleEl);
|
|
7358
|
+
box.appendChild(header);
|
|
7359
|
+
overlay.appendChild(box);
|
|
7360
|
+
makeDraggable(header, box);
|
|
7361
|
+
const d = on(overlay, "click", (e) => {
|
|
7362
|
+
if (e.target === overlay) this._close();
|
|
7363
|
+
});
|
|
7364
|
+
this._disposers.push(d);
|
|
7365
|
+
return {
|
|
7366
|
+
overlay,
|
|
7367
|
+
box
|
|
7368
|
+
};
|
|
7369
|
+
}
|
|
7370
|
+
/**
|
|
7371
|
+
* Builds an action button row with a primary insert button and a cancel button.
|
|
7372
|
+
* Disposers are registered automatically.
|
|
7373
|
+
* @param {string} insertLabel
|
|
7374
|
+
* @param {string} cancelLabel
|
|
7375
|
+
* @param {() => void} onInsert
|
|
7376
|
+
* @returns {HTMLElement}
|
|
7377
|
+
*/
|
|
7378
|
+
_buildButtonRow(insertLabel, cancelLabel, onInsert) {
|
|
7379
|
+
const btnRow = createElement("div", { class: "an-dialog-actions" });
|
|
7380
|
+
const insertBtn = createElement("button", {
|
|
7381
|
+
type: "button",
|
|
7382
|
+
class: "an-btn an-btn-primary"
|
|
7383
|
+
});
|
|
7384
|
+
insertBtn.textContent = insertLabel;
|
|
7385
|
+
const cancelBtn = createElement("button", {
|
|
7386
|
+
type: "button",
|
|
7387
|
+
class: "an-btn"
|
|
7388
|
+
});
|
|
7389
|
+
cancelBtn.textContent = cancelLabel;
|
|
7390
|
+
btnRow.appendChild(insertBtn);
|
|
7391
|
+
btnRow.appendChild(cancelBtn);
|
|
7392
|
+
const d1 = on(insertBtn, "click", onInsert);
|
|
7393
|
+
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7394
|
+
this._disposers.push(d1, d2);
|
|
7395
|
+
return btnRow;
|
|
7396
|
+
}
|
|
7397
|
+
};
|
|
7398
|
+
//#endregion
|
|
7399
|
+
//#region src/js/module/LinkDialog.js
|
|
7400
|
+
/**
|
|
7401
|
+
* LinkDialog.js - Dialog for inserting / editing hyperlinks
|
|
7402
|
+
* Inspired by Summernote's LinkDialog — rewritten without jQuery
|
|
7403
|
+
*/
|
|
7404
|
+
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>`;
|
|
7405
|
+
var LinkDialog = class extends BaseDialog {
|
|
7406
|
+
/**
|
|
7407
|
+
* Opens the link dialog.
|
|
7408
|
+
* Pre-fills with the currently selected link if present.
|
|
7409
|
+
*/
|
|
7410
|
+
show() {
|
|
7411
|
+
this._saveRange();
|
|
7412
|
+
this._prefill();
|
|
7413
|
+
this._open();
|
|
7414
|
+
}
|
|
7415
|
+
_buildDialog() {
|
|
7416
|
+
const L = this.context.locale.linkDialog;
|
|
7417
|
+
const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG$2, L.title);
|
|
7340
7418
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7341
7419
|
urlLabel.textContent = L.url;
|
|
7342
7420
|
const urlInput = createElement("input", {
|
|
@@ -7348,6 +7426,7 @@ var LinkDialog = class {
|
|
|
7348
7426
|
autocomplete: "off"
|
|
7349
7427
|
});
|
|
7350
7428
|
this._urlInput = urlInput;
|
|
7429
|
+
this._firstInput = urlInput;
|
|
7351
7430
|
const textLabel = createElement("label", { class: "an-label" });
|
|
7352
7431
|
textLabel.textContent = L.displayText;
|
|
7353
7432
|
const textInput = createElement("input", {
|
|
@@ -7368,27 +7447,8 @@ var LinkDialog = class {
|
|
|
7368
7447
|
this._tabCheckbox = tabCheckbox;
|
|
7369
7448
|
tabLabel.appendChild(tabCheckbox);
|
|
7370
7449
|
tabLabel.appendChild(document.createTextNode(" " + L.openInNewTab));
|
|
7371
|
-
const btnRow =
|
|
7372
|
-
|
|
7373
|
-
type: "button",
|
|
7374
|
-
class: "an-btn an-btn-primary"
|
|
7375
|
-
});
|
|
7376
|
-
insertBtn.textContent = L.insertBtn;
|
|
7377
|
-
const cancelBtn = createElement("button", {
|
|
7378
|
-
type: "button",
|
|
7379
|
-
class: "an-btn"
|
|
7380
|
-
});
|
|
7381
|
-
cancelBtn.textContent = L.cancelBtn;
|
|
7382
|
-
btnRow.appendChild(insertBtn);
|
|
7383
|
-
btnRow.appendChild(cancelBtn);
|
|
7384
|
-
box.append(header, urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);
|
|
7385
|
-
overlay.appendChild(box);
|
|
7386
|
-
makeDraggable(header, box);
|
|
7387
|
-
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7388
|
-
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7389
|
-
const d3 = on(overlay, "click", (e) => {
|
|
7390
|
-
if (e.target === overlay) this._close();
|
|
7391
|
-
});
|
|
7450
|
+
const btnRow = this._buildButtonRow(L.insertBtn, L.cancelBtn, () => this._onInsert());
|
|
7451
|
+
box.append(urlLabel, urlInput, textLabel, textInput, tabLabel, btnRow);
|
|
7392
7452
|
const d4 = on(urlInput, "keydown", (e) => {
|
|
7393
7453
|
if (e.key === "Enter") {
|
|
7394
7454
|
e.preventDefault();
|
|
@@ -7401,7 +7461,7 @@ var LinkDialog = class {
|
|
|
7401
7461
|
this._onInsert();
|
|
7402
7462
|
}
|
|
7403
7463
|
});
|
|
7404
|
-
this._disposers.push(
|
|
7464
|
+
this._disposers.push(d4, d5);
|
|
7405
7465
|
return overlay;
|
|
7406
7466
|
}
|
|
7407
7467
|
_prefill() {
|
|
@@ -7450,21 +7510,6 @@ var LinkDialog = class {
|
|
|
7450
7510
|
this.context.invoke("editor.insertLink", url, text, newTab);
|
|
7451
7511
|
this._close();
|
|
7452
7512
|
}
|
|
7453
|
-
_open() {
|
|
7454
|
-
if (this._dialog) {
|
|
7455
|
-
this._dialog.style.display = "flex";
|
|
7456
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7457
|
-
setTimeout(() => this._urlInput && this._urlInput.focus(), 50);
|
|
7458
|
-
}
|
|
7459
|
-
}
|
|
7460
|
-
_close() {
|
|
7461
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
7462
|
-
if (this._removeTrap) {
|
|
7463
|
-
this._removeTrap();
|
|
7464
|
-
this._removeTrap = null;
|
|
7465
|
-
}
|
|
7466
|
-
this._savedRange = null;
|
|
7467
|
-
}
|
|
7468
7513
|
};
|
|
7469
7514
|
//#endregion
|
|
7470
7515
|
//#region src/js/module/ImageDialog.js
|
|
@@ -7472,33 +7517,10 @@ var LinkDialog = class {
|
|
|
7472
7517
|
* ImageDialog.js - Dialog for inserting images (by URL or file upload)
|
|
7473
7518
|
* Inspired by Summernote's ImageDialog — rewritten without jQuery
|
|
7474
7519
|
*/
|
|
7475
|
-
var
|
|
7476
|
-
|
|
7477
|
-
* @param {import('../Context.js').Context} context
|
|
7478
|
-
*/
|
|
7479
|
-
constructor(context) {
|
|
7480
|
-
this.context = context;
|
|
7481
|
-
this.options = context.options;
|
|
7482
|
-
/** @type {HTMLElement|null} */
|
|
7483
|
-
this._dialog = null;
|
|
7484
|
-
this._disposers = [];
|
|
7485
|
-
this._savedRange = null;
|
|
7486
|
-
}
|
|
7487
|
-
initialize() {
|
|
7488
|
-
this._dialog = this._buildDialog();
|
|
7489
|
-
document.body.appendChild(this._dialog);
|
|
7490
|
-
return this;
|
|
7491
|
-
}
|
|
7492
|
-
destroy() {
|
|
7493
|
-
this._disposers.forEach((d) => d());
|
|
7494
|
-
this._disposers = [];
|
|
7495
|
-
if (this._dialog && this._dialog.parentNode) this._dialog.remove();
|
|
7496
|
-
this._dialog = null;
|
|
7497
|
-
}
|
|
7520
|
+
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>`;
|
|
7521
|
+
var ImageDialog = class extends BaseDialog {
|
|
7498
7522
|
show() {
|
|
7499
|
-
|
|
7500
|
-
this._savedRange = range;
|
|
7501
|
-
});
|
|
7523
|
+
this._saveRange();
|
|
7502
7524
|
this._urlInput.value = "";
|
|
7503
7525
|
this._altInput.value = "";
|
|
7504
7526
|
if (this._fileInput) this._fileInput.value = "";
|
|
@@ -7506,20 +7528,7 @@ var ImageDialog = class {
|
|
|
7506
7528
|
}
|
|
7507
7529
|
_buildDialog() {
|
|
7508
7530
|
const L = this.context.locale.imageDialog;
|
|
7509
|
-
const overlay =
|
|
7510
|
-
class: "an-dialog-overlay",
|
|
7511
|
-
role: "dialog",
|
|
7512
|
-
"aria-modal": "true",
|
|
7513
|
-
"aria-label": L.ariaLabel
|
|
7514
|
-
});
|
|
7515
|
-
const box = createElement("div", { class: "an-dialog-box" });
|
|
7516
|
-
const header = createElement("div", { class: "an-dialog-header" });
|
|
7517
|
-
const iconEl = createElement("span", { class: "an-dialog-icon" });
|
|
7518
|
-
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>`;
|
|
7519
|
-
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7520
|
-
title.textContent = L.title;
|
|
7521
|
-
header.appendChild(iconEl);
|
|
7522
|
-
header.appendChild(title);
|
|
7531
|
+
const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG$1, L.title);
|
|
7523
7532
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7524
7533
|
urlLabel.textContent = L.imageUrl;
|
|
7525
7534
|
const urlInput = createElement("input", {
|
|
@@ -7529,6 +7538,7 @@ var ImageDialog = class {
|
|
|
7529
7538
|
autocomplete: "off"
|
|
7530
7539
|
});
|
|
7531
7540
|
this._urlInput = urlInput;
|
|
7541
|
+
this._firstInput = urlInput;
|
|
7532
7542
|
const altLabel = createElement("label", { class: "an-label" });
|
|
7533
7543
|
altLabel.textContent = L.altText;
|
|
7534
7544
|
const altInput = createElement("input", {
|
|
@@ -7538,7 +7548,7 @@ var ImageDialog = class {
|
|
|
7538
7548
|
autocomplete: "off"
|
|
7539
7549
|
});
|
|
7540
7550
|
this._altInput = altInput;
|
|
7541
|
-
box.append(
|
|
7551
|
+
box.append(urlLabel, urlInput, altLabel, altInput);
|
|
7542
7552
|
const alignLabel = createElement("label", { class: "an-label" });
|
|
7543
7553
|
alignLabel.textContent = L.alignment;
|
|
7544
7554
|
const alignRow = createElement("div", { class: "an-align-row" });
|
|
@@ -7592,27 +7602,8 @@ var ImageDialog = class {
|
|
|
7592
7602
|
this._disposers.push(d);
|
|
7593
7603
|
box.append(fileLabel, fileInput, fileHint);
|
|
7594
7604
|
}
|
|
7595
|
-
const btnRow =
|
|
7596
|
-
const insertBtn = createElement("button", {
|
|
7597
|
-
type: "button",
|
|
7598
|
-
class: "an-btn an-btn-primary"
|
|
7599
|
-
});
|
|
7600
|
-
insertBtn.textContent = L.insertBtn;
|
|
7601
|
-
const cancelBtn = createElement("button", {
|
|
7602
|
-
type: "button",
|
|
7603
|
-
class: "an-btn"
|
|
7604
|
-
});
|
|
7605
|
-
cancelBtn.textContent = L.cancelBtn;
|
|
7606
|
-
btnRow.appendChild(insertBtn);
|
|
7607
|
-
btnRow.appendChild(cancelBtn);
|
|
7605
|
+
const btnRow = this._buildButtonRow(L.insertBtn, L.cancelBtn, () => this._onInsert());
|
|
7608
7606
|
box.append(btnRow);
|
|
7609
|
-
overlay.appendChild(box);
|
|
7610
|
-
makeDraggable(header, box);
|
|
7611
|
-
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7612
|
-
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7613
|
-
const d3 = on(overlay, "click", (e) => {
|
|
7614
|
-
if (e.target === overlay) this._close();
|
|
7615
|
-
});
|
|
7616
7607
|
const d4 = on(urlInput, "keydown", (e) => {
|
|
7617
7608
|
if (e.key === "Enter") {
|
|
7618
7609
|
e.preventDefault();
|
|
@@ -7625,7 +7616,7 @@ var ImageDialog = class {
|
|
|
7625
7616
|
this._onInsert();
|
|
7626
7617
|
}
|
|
7627
7618
|
});
|
|
7628
|
-
this._disposers.push(
|
|
7619
|
+
this._disposers.push(d4, d5);
|
|
7629
7620
|
return overlay;
|
|
7630
7621
|
}
|
|
7631
7622
|
_onFileChange() {
|
|
@@ -7680,21 +7671,6 @@ var ImageDialog = class {
|
|
|
7680
7671
|
this.context.invoke("editor.insertImage", src, alt, align);
|
|
7681
7672
|
this._close();
|
|
7682
7673
|
}
|
|
7683
|
-
_open() {
|
|
7684
|
-
if (this._dialog) {
|
|
7685
|
-
this._dialog.style.display = "flex";
|
|
7686
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7687
|
-
setTimeout(() => this._urlInput && this._urlInput.focus(), 50);
|
|
7688
|
-
}
|
|
7689
|
-
}
|
|
7690
|
-
_close() {
|
|
7691
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
7692
|
-
if (this._removeTrap) {
|
|
7693
|
-
this._removeTrap();
|
|
7694
|
-
this._removeTrap = null;
|
|
7695
|
-
}
|
|
7696
|
-
this._savedRange = null;
|
|
7697
|
-
}
|
|
7698
7674
|
};
|
|
7699
7675
|
//#endregion
|
|
7700
7676
|
//#region src/js/module/VideoDialog.js
|
|
@@ -7706,31 +7682,10 @@ var ImageDialog = class {
|
|
|
7706
7682
|
* • Vimeo URLs → <iframe> embed
|
|
7707
7683
|
* • Direct video URLs → <video> element (.mp4 / .webm / .ogg)
|
|
7708
7684
|
*/
|
|
7709
|
-
var
|
|
7710
|
-
|
|
7711
|
-
constructor(context) {
|
|
7712
|
-
this.context = context;
|
|
7713
|
-
this.options = context.options;
|
|
7714
|
-
/** @type {HTMLElement|null} */
|
|
7715
|
-
this._dialog = null;
|
|
7716
|
-
this._disposers = [];
|
|
7717
|
-
this._savedRange = null;
|
|
7718
|
-
}
|
|
7719
|
-
initialize() {
|
|
7720
|
-
this._dialog = this._buildDialog();
|
|
7721
|
-
document.body.appendChild(this._dialog);
|
|
7722
|
-
return this;
|
|
7723
|
-
}
|
|
7724
|
-
destroy() {
|
|
7725
|
-
this._disposers.forEach((d) => d());
|
|
7726
|
-
this._disposers = [];
|
|
7727
|
-
if (this._dialog && this._dialog.parentNode) this._dialog.remove();
|
|
7728
|
-
this._dialog = null;
|
|
7729
|
-
}
|
|
7685
|
+
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>`;
|
|
7686
|
+
var VideoDialog = class extends BaseDialog {
|
|
7730
7687
|
show() {
|
|
7731
|
-
|
|
7732
|
-
this._savedRange = range;
|
|
7733
|
-
});
|
|
7688
|
+
this._saveRange();
|
|
7734
7689
|
this._urlInput.value = "";
|
|
7735
7690
|
this._widthInput.value = "560";
|
|
7736
7691
|
this._hintEl.textContent = "";
|
|
@@ -7738,20 +7693,7 @@ var VideoDialog = class {
|
|
|
7738
7693
|
}
|
|
7739
7694
|
_buildDialog() {
|
|
7740
7695
|
const L = this.context.locale.videoDialog;
|
|
7741
|
-
const overlay =
|
|
7742
|
-
class: "an-dialog-overlay",
|
|
7743
|
-
role: "dialog",
|
|
7744
|
-
"aria-modal": "true",
|
|
7745
|
-
"aria-label": L.ariaLabel
|
|
7746
|
-
});
|
|
7747
|
-
const box = createElement("div", { class: "an-dialog-box" });
|
|
7748
|
-
const header = createElement("div", { class: "an-dialog-header" });
|
|
7749
|
-
const iconEl = createElement("span", { class: "an-dialog-icon" });
|
|
7750
|
-
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>`;
|
|
7751
|
-
const title = createElement("h3", { class: "an-dialog-title" });
|
|
7752
|
-
title.textContent = L.title;
|
|
7753
|
-
header.appendChild(iconEl);
|
|
7754
|
-
header.appendChild(title);
|
|
7696
|
+
const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG, L.title);
|
|
7755
7697
|
const urlLabel = createElement("label", { class: "an-label" });
|
|
7756
7698
|
urlLabel.textContent = L.videoUrl;
|
|
7757
7699
|
const urlInput = createElement("input", {
|
|
@@ -7761,6 +7703,7 @@ var VideoDialog = class {
|
|
|
7761
7703
|
autocomplete: "off"
|
|
7762
7704
|
});
|
|
7763
7705
|
this._urlInput = urlInput;
|
|
7706
|
+
this._firstInput = urlInput;
|
|
7764
7707
|
const hintEl = createElement("p", { class: "an-dialog-hint" });
|
|
7765
7708
|
this._hintEl = hintEl;
|
|
7766
7709
|
const widthLabel = createElement("label", { class: "an-label" });
|
|
@@ -7774,38 +7717,19 @@ var VideoDialog = class {
|
|
|
7774
7717
|
value: "560"
|
|
7775
7718
|
});
|
|
7776
7719
|
this._widthInput = widthInput;
|
|
7777
|
-
const btnRow =
|
|
7778
|
-
|
|
7779
|
-
type: "button",
|
|
7780
|
-
class: "an-btn an-btn-primary"
|
|
7781
|
-
});
|
|
7782
|
-
insertBtn.textContent = L.insertBtn;
|
|
7783
|
-
const cancelBtn = createElement("button", {
|
|
7784
|
-
type: "button",
|
|
7785
|
-
class: "an-btn"
|
|
7786
|
-
});
|
|
7787
|
-
cancelBtn.textContent = L.cancelBtn;
|
|
7788
|
-
btnRow.appendChild(insertBtn);
|
|
7789
|
-
btnRow.appendChild(cancelBtn);
|
|
7790
|
-
box.append(header, urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);
|
|
7791
|
-
overlay.appendChild(box);
|
|
7792
|
-
makeDraggable(header, box);
|
|
7720
|
+
const btnRow = this._buildButtonRow(L.insertBtn, L.cancelBtn, () => this._onInsert());
|
|
7721
|
+
box.append(urlLabel, urlInput, hintEl, widthLabel, widthInput, btnRow);
|
|
7793
7722
|
const d0 = on(urlInput, "input", () => {
|
|
7794
7723
|
const info = this._parseVideoUrl(urlInput.value.trim());
|
|
7795
7724
|
hintEl.textContent = info ? this.context.locale.videoDialog.detected(info.type) : urlInput.value ? this.context.locale.videoDialog.unknownFormat : "";
|
|
7796
7725
|
});
|
|
7797
|
-
const d1 = on(insertBtn, "click", () => this._onInsert());
|
|
7798
|
-
const d2 = on(cancelBtn, "click", () => this._close());
|
|
7799
|
-
const d3 = on(overlay, "click", (e) => {
|
|
7800
|
-
if (e.target === overlay) this._close();
|
|
7801
|
-
});
|
|
7802
7726
|
const d4 = on(urlInput, "keydown", (e) => {
|
|
7803
7727
|
if (e.key === "Enter") {
|
|
7804
7728
|
e.preventDefault();
|
|
7805
7729
|
this._onInsert();
|
|
7806
7730
|
}
|
|
7807
7731
|
});
|
|
7808
|
-
this._disposers.push(d0,
|
|
7732
|
+
this._disposers.push(d0, d4);
|
|
7809
7733
|
return overlay;
|
|
7810
7734
|
}
|
|
7811
7735
|
_onInsert() {
|
|
@@ -7825,21 +7749,6 @@ var VideoDialog = class {
|
|
|
7825
7749
|
this.context.invoke("editor.insertVideo", html);
|
|
7826
7750
|
this._close();
|
|
7827
7751
|
}
|
|
7828
|
-
_open() {
|
|
7829
|
-
if (this._dialog) {
|
|
7830
|
-
this._dialog.style.display = "flex";
|
|
7831
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
7832
|
-
setTimeout(() => this._urlInput && this._urlInput.focus(), 50);
|
|
7833
|
-
}
|
|
7834
|
-
}
|
|
7835
|
-
_close() {
|
|
7836
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
7837
|
-
if (this._removeTrap) {
|
|
7838
|
-
this._removeTrap();
|
|
7839
|
-
this._removeTrap = null;
|
|
7840
|
-
}
|
|
7841
|
-
this._savedRange = null;
|
|
7842
|
-
}
|
|
7843
7752
|
/**
|
|
7844
7753
|
* Parses a video URL and returns { type, embedUrl } or null.
|
|
7845
7754
|
* @param {string} url
|
|
@@ -16333,7 +16242,7 @@ var Context = class {
|
|
|
16333
16242
|
register("markdownShortcuts", MarkdownShortcuts);
|
|
16334
16243
|
register("bubbleToolbar", BubbleToolbar);
|
|
16335
16244
|
register("mention", Mention);
|
|
16336
|
-
for (const [name, ModuleClass] of _customModules) register(name, ModuleClass);
|
|
16245
|
+
if (_customModules.size > 0) for (const [name, ModuleClass] of _customModules) register(name, ModuleClass);
|
|
16337
16246
|
}
|
|
16338
16247
|
/**
|
|
16339
16248
|
* Registers and initialises a custom module on this instance.
|
|
@@ -16386,6 +16295,7 @@ var Context = class {
|
|
|
16386
16295
|
});
|
|
16387
16296
|
}
|
|
16388
16297
|
_applyGlobalPlugins() {
|
|
16298
|
+
if (_globalPlugins.size === 0) return;
|
|
16389
16299
|
for (const { plugin, options } of _globalPlugins.values()) this._installPlugin(plugin, options);
|
|
16390
16300
|
}
|
|
16391
16301
|
_bindEditorEvents(editable) {
|
|
@@ -16908,7 +16818,7 @@ var AutumnNote = {
|
|
|
16908
16818
|
return this;
|
|
16909
16819
|
},
|
|
16910
16820
|
/** Library version */
|
|
16911
|
-
version: "1.
|
|
16821
|
+
version: "1.6.2"
|
|
16912
16822
|
};
|
|
16913
16823
|
/**
|
|
16914
16824
|
* @param {string|Element|NodeList|Element[]} selector
|