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.
@@ -7282,15 +7282,13 @@ var Fullscreen = class {
7282
7282
  }
7283
7283
  };
7284
7284
  //#endregion
7285
- //#region src/js/module/LinkDialog.js
7285
+ //#region src/js/module/BaseDialog.js
7286
7286
  /**
7287
- * LinkDialog.js - Dialog for inserting / editing hyperlinks
7288
- * Inspired by Summernote's LinkDialog rewritten without jQuery
7287
+ * Shared lifecycle and shell-building logic for all modal dialogs.
7288
+ * Subclasses implement _buildDialog() for their specific form fields.
7289
7289
  */
7290
- var LinkDialog = class {
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 && this._dialog.parentNode) this._dialog.remove();
7311
+ if (this._dialog?.parentNode) this._dialog.remove();
7311
7312
  this._dialog = null;
7312
7313
  }
7313
- /**
7314
- * Opens the link dialog.
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
- _buildDialog() {
7325
- const L = this.context.locale.linkDialog;
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": L.ariaLabel
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 = `<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>`;
7336
- const title = createElement("h3", { class: "an-dialog-title" });
7337
- title.textContent = L.title;
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(title);
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 = createElement("div", { class: "an-dialog-actions" });
7372
- const insertBtn = createElement("button", {
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(d1, d2, d3, d4, d5);
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 ImageDialog = class {
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
- withSavedRange((range) => {
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 = createElement("div", {
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(header, urlLabel, urlInput, altLabel, altInput);
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 = createElement("div", { class: "an-dialog-actions" });
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(d1, d2, d3, d4, d5);
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 VideoDialog = class {
7710
- /** @param {import('../Context.js').Context} context */
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
- withSavedRange((range) => {
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 = createElement("div", {
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 = createElement("div", { class: "an-dialog-actions" });
7778
- const insertBtn = createElement("button", {
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, d1, d2, d3, d4);
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.5.0"
16821
+ version: "1.6.2"
16912
16822
  };
16913
16823
  /**
16914
16824
  * @param {string|Element|NodeList|Element[]} selector