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.
@@ -6978,15 +6978,13 @@
6978
6978
  }
6979
6979
  };
6980
6980
  //#endregion
6981
- //#region src/js/module/LinkDialog.js
6981
+ //#region src/js/module/BaseDialog.js
6982
6982
  /**
6983
- * LinkDialog.js - Dialog for inserting / editing hyperlinks
6984
- * Inspired by Summernote's LinkDialog rewritten without jQuery
6983
+ * Shared lifecycle and shell-building logic for all modal dialogs.
6984
+ * Subclasses implement _buildDialog() for their specific form fields.
6985
6985
  */
6986
- var LinkDialog = class {
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 && this._dialog.parentNode) this._dialog.remove();
7007
+ if (this._dialog?.parentNode) this._dialog.remove();
7007
7008
  this._dialog = null;
7008
7009
  }
7009
- /**
7010
- * Opens the link dialog.
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
- _buildDialog() {
7021
- const L = this.context.locale.linkDialog;
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": L.ariaLabel
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 = `<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>`;
7032
- const title = createElement("h3", { class: "an-dialog-title" });
7033
- title.textContent = L.title;
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(title);
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 = createElement("div", { class: "an-dialog-actions" });
7068
- const insertBtn = createElement("button", {
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(d1, d2, d3, d4, d5);
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 ImageDialog = class {
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
- withSavedRange((range) => {
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 = createElement("div", {
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(header, urlLabel, urlInput, altLabel, altInput);
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 = createElement("div", { class: "an-dialog-actions" });
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(d1, d2, d3, d4, d5);
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 VideoDialog = class {
7406
- /** @param {import('../Context.js').Context} context */
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
- withSavedRange((range) => {
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 = createElement("div", {
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 = createElement("div", { class: "an-dialog-actions" });
7474
- const insertBtn = createElement("button", {
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, d1, d2, d3, d4);
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.5.0"
16391
+ version: "1.6.2"
16482
16392
  };
16483
16393
  /**
16484
16394
  * @param {string|Element|NodeList|Element[]} selector