autumnnote 1.6.1 → 1.6.3
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 +147 -348
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +147 -348
- 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/EmojiDialog.js +7 -44
- package/src/js/module/FindReplace.js +4 -18
- package/src/js/module/IconDialog.js +9 -41
- package/src/js/module/ImageDialog.js +12 -82
- package/src/js/module/LinkDialog.js +12 -78
- package/src/js/module/ShortcutsDialog.js +20 -49
- 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$3 = `<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$3, 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$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"><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$2, 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$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"><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$1, 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
|
|
@@ -12747,35 +12656,17 @@ var EMOJI_LIST = [
|
|
|
12747
12656
|
"symbols"
|
|
12748
12657
|
]
|
|
12749
12658
|
];
|
|
12750
|
-
var EmojiDialog = class {
|
|
12751
|
-
|
|
12752
|
-
* @param {import('../Context.js').Context} context
|
|
12753
|
-
*/
|
|
12754
|
-
constructor(context) {
|
|
12755
|
-
this.context = context;
|
|
12756
|
-
/** @type {HTMLElement|null} */
|
|
12757
|
-
this._dialog = null;
|
|
12758
|
-
this._disposers = [];
|
|
12759
|
-
this._savedRange = null;
|
|
12760
|
-
this._activeCat = "all";
|
|
12761
|
-
}
|
|
12659
|
+
var EmojiDialog = class extends BaseDialog {
|
|
12660
|
+
_activeCat = "all";
|
|
12762
12661
|
initialize() {
|
|
12763
12662
|
return this;
|
|
12764
12663
|
}
|
|
12765
|
-
destroy() {
|
|
12766
|
-
this._disposers.forEach((d) => d());
|
|
12767
|
-
this._disposers = [];
|
|
12768
|
-
if (this._dialog && this._dialog.parentNode) this._dialog.remove();
|
|
12769
|
-
this._dialog = null;
|
|
12770
|
-
}
|
|
12771
12664
|
show() {
|
|
12772
12665
|
if (!this._dialog) {
|
|
12773
12666
|
this._dialog = this._buildDialog();
|
|
12774
12667
|
document.body.appendChild(this._dialog);
|
|
12775
12668
|
}
|
|
12776
|
-
|
|
12777
|
-
this._savedRange = range;
|
|
12778
|
-
});
|
|
12669
|
+
this._saveRange();
|
|
12779
12670
|
this._activeCat = "all";
|
|
12780
12671
|
this._searchInput.value = "";
|
|
12781
12672
|
this._updateCatTabs();
|
|
@@ -12844,6 +12735,7 @@ var EmojiDialog = class {
|
|
|
12844
12735
|
grid.appendChild(cell);
|
|
12845
12736
|
});
|
|
12846
12737
|
this._grid = grid;
|
|
12738
|
+
this._firstInput = searchInput;
|
|
12847
12739
|
const btnRow = createElement("div", { class: "an-dialog-actions" });
|
|
12848
12740
|
const cancelBtn = createElement("button", {
|
|
12849
12741
|
type: "button",
|
|
@@ -12933,21 +12825,6 @@ var EmojiDialog = class {
|
|
|
12933
12825
|
editable.focus();
|
|
12934
12826
|
this.context.invoke("editor.afterCommand");
|
|
12935
12827
|
}
|
|
12936
|
-
_open() {
|
|
12937
|
-
if (this._dialog) {
|
|
12938
|
-
this._dialog.style.display = "flex";
|
|
12939
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
12940
|
-
setTimeout(() => this._searchInput?.focus(), 50);
|
|
12941
|
-
}
|
|
12942
|
-
}
|
|
12943
|
-
_close() {
|
|
12944
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
12945
|
-
if (this._removeTrap) {
|
|
12946
|
-
this._removeTrap();
|
|
12947
|
-
this._removeTrap = null;
|
|
12948
|
-
}
|
|
12949
|
-
this._savedRange = null;
|
|
12950
|
-
}
|
|
12951
12828
|
};
|
|
12952
12829
|
//#endregion
|
|
12953
12830
|
//#region src/js/module/IconDialog.js
|
|
@@ -13205,19 +13082,9 @@ var ICON_LIST = [
|
|
|
13205
13082
|
["gift", "objects"],
|
|
13206
13083
|
["puzzle-piece", "objects"]
|
|
13207
13084
|
];
|
|
13208
|
-
var IconDialog = class {
|
|
13209
|
-
|
|
13210
|
-
|
|
13211
|
-
*/
|
|
13212
|
-
constructor(context) {
|
|
13213
|
-
this.context = context;
|
|
13214
|
-
/** @type {HTMLElement|null} */
|
|
13215
|
-
this._dialog = null;
|
|
13216
|
-
this._disposers = [];
|
|
13217
|
-
this._savedRange = null;
|
|
13218
|
-
this._selectedIcon = null;
|
|
13219
|
-
this._activeCat = "all";
|
|
13220
|
-
}
|
|
13085
|
+
var IconDialog = class extends BaseDialog {
|
|
13086
|
+
_selectedIcon = null;
|
|
13087
|
+
_activeCat = "all";
|
|
13221
13088
|
initialize() {
|
|
13222
13089
|
this._ensureFontAwesome();
|
|
13223
13090
|
return this;
|
|
@@ -13241,20 +13108,12 @@ var IconDialog = class {
|
|
|
13241
13108
|
link.referrerPolicy = "no-referrer";
|
|
13242
13109
|
document.head.appendChild(link);
|
|
13243
13110
|
}
|
|
13244
|
-
destroy() {
|
|
13245
|
-
this._disposers.forEach((d) => d());
|
|
13246
|
-
this._disposers = [];
|
|
13247
|
-
this._dialog?.remove();
|
|
13248
|
-
this._dialog = null;
|
|
13249
|
-
}
|
|
13250
13111
|
show() {
|
|
13251
13112
|
if (!this._dialog) {
|
|
13252
13113
|
this._dialog = this._buildDialog();
|
|
13253
13114
|
document.body.appendChild(this._dialog);
|
|
13254
13115
|
}
|
|
13255
|
-
|
|
13256
|
-
this._savedRange = range;
|
|
13257
|
-
});
|
|
13116
|
+
this._saveRange();
|
|
13258
13117
|
this._selectedIcon = null;
|
|
13259
13118
|
this._activeCat = "all";
|
|
13260
13119
|
this._searchInput.value = "";
|
|
@@ -13295,6 +13154,7 @@ var IconDialog = class {
|
|
|
13295
13154
|
autocomplete: "off"
|
|
13296
13155
|
});
|
|
13297
13156
|
this._searchInput = searchInput;
|
|
13157
|
+
this._firstInput = searchInput;
|
|
13298
13158
|
const catBar = createElement("div", { class: "an-icon-cats" });
|
|
13299
13159
|
const allTab = createElement("button", {
|
|
13300
13160
|
type: "button",
|
|
@@ -13533,21 +13393,9 @@ var IconDialog = class {
|
|
|
13533
13393
|
}
|
|
13534
13394
|
this.context.invoke("editor.afterCommand");
|
|
13535
13395
|
}
|
|
13536
|
-
_open() {
|
|
13537
|
-
if (this._dialog) {
|
|
13538
|
-
this._dialog.style.display = "flex";
|
|
13539
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
13540
|
-
setTimeout(() => this._searchInput?.focus(), 50);
|
|
13541
|
-
}
|
|
13542
|
-
}
|
|
13543
13396
|
_close() {
|
|
13544
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
13545
|
-
if (this._removeTrap) {
|
|
13546
|
-
this._removeTrap();
|
|
13547
|
-
this._removeTrap = null;
|
|
13548
|
-
}
|
|
13549
|
-
this._savedRange = null;
|
|
13550
13397
|
this._selectedIcon = null;
|
|
13398
|
+
super._close();
|
|
13551
13399
|
}
|
|
13552
13400
|
};
|
|
13553
13401
|
//#endregion
|
|
@@ -14288,59 +14136,25 @@ var SHORTCUTS = [
|
|
|
14288
14136
|
}]
|
|
14289
14137
|
}
|
|
14290
14138
|
];
|
|
14291
|
-
var
|
|
14292
|
-
|
|
14293
|
-
constructor(context) {
|
|
14294
|
-
this.context = context;
|
|
14295
|
-
this._dialog = null;
|
|
14296
|
-
this._closeBtn = null;
|
|
14297
|
-
this._disposers = [];
|
|
14298
|
-
}
|
|
14299
|
-
initialize() {
|
|
14300
|
-
this._dialog = this._buildDialog();
|
|
14301
|
-
document.body.appendChild(this._dialog);
|
|
14302
|
-
return this;
|
|
14303
|
-
}
|
|
14304
|
-
destroy() {
|
|
14305
|
-
this._disposers.forEach((d) => d());
|
|
14306
|
-
this._disposers = [];
|
|
14307
|
-
this._dialog?.remove();
|
|
14308
|
-
this._dialog = null;
|
|
14309
|
-
}
|
|
14139
|
+
var ICON_SVG = `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M6 11h.01M10 11h.01M14 11h.01M18 11h.01M6 15h.01M18 15h.01M10 15h4"/><path d="M7 3l5 4 5-4"/></svg>`;
|
|
14140
|
+
var ShortcutsDialog = class extends BaseDialog {
|
|
14310
14141
|
show() {
|
|
14311
|
-
|
|
14312
|
-
this._dialog.style.display = "flex";
|
|
14313
|
-
this._removeTrap = trapFocus(this._dialog, () => this._close());
|
|
14314
|
-
setTimeout(() => this._closeBtn?.focus(), 50);
|
|
14315
|
-
}
|
|
14316
|
-
}
|
|
14317
|
-
_close() {
|
|
14318
|
-
if (this._dialog) this._dialog.style.display = "none";
|
|
14319
|
-
if (this._removeTrap) {
|
|
14320
|
-
this._removeTrap();
|
|
14321
|
-
this._removeTrap = null;
|
|
14322
|
-
}
|
|
14142
|
+
this._open();
|
|
14323
14143
|
}
|
|
14324
14144
|
_buildDialog() {
|
|
14325
|
-
const
|
|
14326
|
-
|
|
14327
|
-
|
|
14328
|
-
"aria-modal": "true",
|
|
14329
|
-
"aria-label": this.context.locale.shortcutsDialog.ariaLabel
|
|
14330
|
-
});
|
|
14331
|
-
const box = createElement("div", { class: "an-dialog-box an-shortcuts-box" });
|
|
14332
|
-
const titleRow = createElement("div", { class: "an-icon-title-row" });
|
|
14333
|
-
const title = createElement("h3", { class: "an-dialog-title" });
|
|
14334
|
-
title.textContent = this.context.locale.shortcutsDialog.title;
|
|
14145
|
+
const L = this.context.locale.shortcutsDialog;
|
|
14146
|
+
const { overlay, box } = this._buildDialogShell(L.ariaLabel, ICON_SVG, L.title);
|
|
14147
|
+
box.classList.add("an-shortcuts-box");
|
|
14335
14148
|
const closeBtn = createElement("button", {
|
|
14336
14149
|
type: "button",
|
|
14337
14150
|
class: "an-icon-close",
|
|
14338
|
-
"aria-label":
|
|
14151
|
+
"aria-label": L.close,
|
|
14152
|
+
style: "margin-left:auto"
|
|
14339
14153
|
});
|
|
14340
14154
|
closeBtn.textContent = "×";
|
|
14341
14155
|
this._closeBtn = closeBtn;
|
|
14342
|
-
|
|
14343
|
-
box.appendChild(
|
|
14156
|
+
this._firstInput = closeBtn;
|
|
14157
|
+
box.querySelector(".an-dialog-header").appendChild(closeBtn);
|
|
14344
14158
|
(this.context.locale.shortcutsDialog.shortcuts || SHORTCUTS).forEach(({ category, items }) => {
|
|
14345
14159
|
const catEl = createElement("div", { class: "an-shortcuts-cat" });
|
|
14346
14160
|
catEl.textContent = category;
|
|
@@ -14357,12 +14171,8 @@ var ShortcutsDialog = class {
|
|
|
14357
14171
|
});
|
|
14358
14172
|
box.appendChild(table);
|
|
14359
14173
|
});
|
|
14360
|
-
overlay.appendChild(box);
|
|
14361
14174
|
const d1 = on(closeBtn, "click", () => this._close());
|
|
14362
|
-
|
|
14363
|
-
if (e.target === overlay) this._close();
|
|
14364
|
-
});
|
|
14365
|
-
this._disposers.push(d1, d2);
|
|
14175
|
+
this._disposers.push(d1);
|
|
14366
14176
|
return overlay;
|
|
14367
14177
|
}
|
|
14368
14178
|
};
|
|
@@ -14376,12 +14186,10 @@ var ShortcutsDialog = class {
|
|
|
14376
14186
|
* for highlighting. Supports case-sensitive search, Prev/Next navigation and
|
|
14377
14187
|
* single / replace-all replacement.
|
|
14378
14188
|
*/
|
|
14379
|
-
var FindReplace = class {
|
|
14189
|
+
var FindReplace = class extends BaseDialog {
|
|
14380
14190
|
/** @param {import('../Context.js').Context} context */
|
|
14381
14191
|
constructor(context) {
|
|
14382
|
-
|
|
14383
|
-
/** @type {HTMLElement|null} */
|
|
14384
|
-
this._dialog = null;
|
|
14192
|
+
super(context);
|
|
14385
14193
|
/** @type {HTMLInputElement|null} */
|
|
14386
14194
|
this._findInput = null;
|
|
14387
14195
|
/** @type {HTMLInputElement|null} */
|
|
@@ -14402,23 +14210,13 @@ var FindReplace = class {
|
|
|
14402
14210
|
this._queryRegex = null;
|
|
14403
14211
|
this._lastQuery = null;
|
|
14404
14212
|
this._lastCaseSensitive = null;
|
|
14405
|
-
this._disposers = [];
|
|
14406
|
-
this._removeTrap = null;
|
|
14407
14213
|
this._focusTimer = null;
|
|
14408
14214
|
}
|
|
14409
|
-
initialize() {
|
|
14410
|
-
this._dialog = this._buildDialog();
|
|
14411
|
-
document.body.appendChild(this._dialog);
|
|
14412
|
-
return this;
|
|
14413
|
-
}
|
|
14414
14215
|
destroy() {
|
|
14415
14216
|
clearTimeout(this._focusTimer);
|
|
14416
14217
|
this._focusTimer = null;
|
|
14417
14218
|
this._clearHighlights();
|
|
14418
|
-
|
|
14419
|
-
this._disposers = [];
|
|
14420
|
-
if (this._dialog && this._dialog.parentNode) this._dialog.remove();
|
|
14421
|
-
this._dialog = null;
|
|
14219
|
+
super.destroy();
|
|
14422
14220
|
}
|
|
14423
14221
|
/**
|
|
14424
14222
|
* Opens the dialog in 'find' or 'replace' mode.
|
|
@@ -16333,7 +16131,7 @@ var Context = class {
|
|
|
16333
16131
|
register("markdownShortcuts", MarkdownShortcuts);
|
|
16334
16132
|
register("bubbleToolbar", BubbleToolbar);
|
|
16335
16133
|
register("mention", Mention);
|
|
16336
|
-
for (const [name, ModuleClass] of _customModules) register(name, ModuleClass);
|
|
16134
|
+
if (_customModules.size > 0) for (const [name, ModuleClass] of _customModules) register(name, ModuleClass);
|
|
16337
16135
|
}
|
|
16338
16136
|
/**
|
|
16339
16137
|
* Registers and initialises a custom module on this instance.
|
|
@@ -16386,6 +16184,7 @@ var Context = class {
|
|
|
16386
16184
|
});
|
|
16387
16185
|
}
|
|
16388
16186
|
_applyGlobalPlugins() {
|
|
16187
|
+
if (_globalPlugins.size === 0) return;
|
|
16389
16188
|
for (const { plugin, options } of _globalPlugins.values()) this._installPlugin(plugin, options);
|
|
16390
16189
|
}
|
|
16391
16190
|
_bindEditorEvents(editable) {
|
|
@@ -16908,7 +16707,7 @@ var AutumnNote = {
|
|
|
16908
16707
|
return this;
|
|
16909
16708
|
},
|
|
16910
16709
|
/** Library version */
|
|
16911
|
-
version: "1.
|
|
16710
|
+
version: "1.6.3"
|
|
16912
16711
|
};
|
|
16913
16712
|
/**
|
|
16914
16713
|
* @param {string|Element|NodeList|Element[]} selector
|