autumnnote 1.15.0 → 1.16.0

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.
@@ -854,6 +854,7 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
854
854
  codeHighlightCDN: "https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0",
855
855
  markdownPaste: !0,
856
856
  historyLimit: 100,
857
+ historyMaxBytes: 10 * 1024 * 1024,
857
858
  defaultFontFamily: "Arial",
858
859
  defaultFontSize: "14px",
859
860
  fontFamilies: [
@@ -874,6 +875,8 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
874
875
  toolbarOverflow: "wrap",
875
876
  autoSave: !1,
876
877
  autoSaveKey: "autumnnote-autosave",
878
+ autoSaveDelay: 400,
879
+ autoSaveAdapter: null,
877
880
  maxChars: 0,
878
881
  maxWords: 0,
879
882
  tableHeaderRow: !1,
@@ -890,6 +893,12 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
890
893
  autoSaveRestoreTimeout: 7,
891
894
  onAutoSaveRestore: null,
892
895
  markdownShortcuts: !0,
896
+ slashMenu: !0,
897
+ slashCommands: [],
898
+ documentAdapters: {},
899
+ collaborationAdapter: null,
900
+ imageProcessor: null,
901
+ blockIds: !1,
893
902
  maxPasteSize: 5 * 1024 * 1024,
894
903
  minImageSize: 20,
895
904
  bubbleToolbar: !1,
@@ -1255,6 +1264,20 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
1255
1264
  errors: {
1256
1265
  imageFormat: (e) => `Format "${e}" is not supported for display in web browsers. Please convert to JPEG, PNG, or WebP first.`,
1257
1266
  imageSize: (e) => `Image file is too large. Maximum allowed size is ${e} MB.`
1267
+ },
1268
+ slashMenu: {
1269
+ noResults: "No matching commands",
1270
+ heading1: "Heading 1",
1271
+ heading2: "Heading 2",
1272
+ heading3: "Heading 3",
1273
+ bulletList: "Bullet List",
1274
+ numberedList: "Numbered List",
1275
+ checklist: "Checklist",
1276
+ blockquote: "Blockquote",
1277
+ codeBlock: "Code Block",
1278
+ horizontalRule: "Horizontal Rule",
1279
+ table: "Table",
1280
+ image: "Image"
1258
1281
  }
1259
1282
  }, Vt = {
1260
1283
  en: M,
@@ -1610,6 +1633,20 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
1610
1633
  foundAt: "Bản nháp từ {date}. Khôi phục?",
1611
1634
  restore: "Khôi phục",
1612
1635
  discard: "Bỏ qua"
1636
+ },
1637
+ slashMenu: {
1638
+ noResults: "Không có lệnh phù hợp",
1639
+ heading1: "Tiêu đề 1",
1640
+ heading2: "Tiêu đề 2",
1641
+ heading3: "Tiêu đề 3",
1642
+ bulletList: "Danh sách không thứ tự",
1643
+ numberedList: "Danh sách có thứ tự",
1644
+ checklist: "Danh sách công việc",
1645
+ blockquote: "Trích dẫn",
1646
+ codeBlock: "Khối mã",
1647
+ horizontalRule: "Đường kẻ ngang",
1648
+ table: "Bảng",
1649
+ image: "Hình ảnh"
1613
1650
  }
1614
1651
  },
1615
1652
  ja: {
@@ -1964,6 +2001,20 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
1964
2001
  foundAt: "{date} の下書きが見つかりました。復元しますか?",
1965
2002
  restore: "復元",
1966
2003
  discard: "破棄"
2004
+ },
2005
+ slashMenu: {
2006
+ noResults: "一致するコマンドがありません",
2007
+ heading1: "見出し1",
2008
+ heading2: "見出し2",
2009
+ heading3: "見出し3",
2010
+ bulletList: "箇条書きリスト",
2011
+ numberedList: "番号付きリスト",
2012
+ checklist: "チェックリスト",
2013
+ blockquote: "引用",
2014
+ codeBlock: "コードブロック",
2015
+ horizontalRule: "水平線",
2016
+ table: "表",
2017
+ image: "画像"
1967
2018
  }
1968
2019
  },
1969
2020
  zh: {
@@ -2318,6 +2369,20 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
2318
2369
  foundAt: "发现 {date} 的草稿。是否恢复?",
2319
2370
  restore: "恢复",
2320
2371
  discard: "放弃"
2372
+ },
2373
+ slashMenu: {
2374
+ noResults: "没有匹配的命令",
2375
+ heading1: "标题 1",
2376
+ heading2: "标题 2",
2377
+ heading3: "标题 3",
2378
+ bulletList: "项目符号列表",
2379
+ numberedList: "编号列表",
2380
+ checklist: "检查清单",
2381
+ blockquote: "引用",
2382
+ codeBlock: "代码块",
2383
+ horizontalRule: "水平线",
2384
+ table: "表格",
2385
+ image: "图片"
2321
2386
  }
2322
2387
  },
2323
2388
  fr: {
@@ -2672,6 +2737,20 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
2672
2737
  foundAt: "Brouillon du {date}. Restaurer ?",
2673
2738
  restore: "Restaurer",
2674
2739
  discard: "Ignorer"
2740
+ },
2741
+ slashMenu: {
2742
+ noResults: "Aucune commande correspondante",
2743
+ heading1: "Titre 1",
2744
+ heading2: "Titre 2",
2745
+ heading3: "Titre 3",
2746
+ bulletList: "Liste à puces",
2747
+ numberedList: "Liste numérotée",
2748
+ checklist: "Liste de contrôle",
2749
+ blockquote: "Citation",
2750
+ codeBlock: "Bloc de code",
2751
+ horizontalRule: "Ligne horizontale",
2752
+ table: "Tableau",
2753
+ image: "Image"
2675
2754
  }
2676
2755
  },
2677
2756
  de: {
@@ -3026,6 +3105,20 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
3026
3105
  foundAt: "Entwurf vom {date}. Wiederherstellen?",
3027
3106
  restore: "Wiederherstellen",
3028
3107
  discard: "Verwerfen"
3108
+ },
3109
+ slashMenu: {
3110
+ noResults: "Keine passenden Befehle",
3111
+ heading1: "Überschrift 1",
3112
+ heading2: "Überschrift 2",
3113
+ heading3: "Überschrift 3",
3114
+ bulletList: "Aufzählungsliste",
3115
+ numberedList: "Nummerierte Liste",
3116
+ checklist: "Checkliste",
3117
+ blockquote: "Zitat",
3118
+ codeBlock: "Codeblock",
3119
+ horizontalRule: "Horizontale Linie",
3120
+ table: "Tabelle",
3121
+ image: "Bild"
3029
3122
  }
3030
3123
  },
3031
3124
  es: {
@@ -3380,6 +3473,20 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
3380
3473
  foundAt: "Borrador del {date}. ¿Restaurar?",
3381
3474
  restore: "Restaurar",
3382
3475
  discard: "Descartar"
3476
+ },
3477
+ slashMenu: {
3478
+ noResults: "No hay comandos coincidentes",
3479
+ heading1: "Encabezado 1",
3480
+ heading2: "Encabezado 2",
3481
+ heading3: "Encabezado 3",
3482
+ bulletList: "Lista con viñetas",
3483
+ numberedList: "Lista numerada",
3484
+ checklist: "Lista de verificación",
3485
+ blockquote: "Cita",
3486
+ codeBlock: "Bloque de código",
3487
+ horizontalRule: "Línea horizontal",
3488
+ table: "Tabla",
3489
+ image: "Imagen"
3383
3490
  }
3384
3491
  },
3385
3492
  ko: {
@@ -3734,6 +3841,20 @@ var et = A("bold", "bold", "Bold (Ctrl+B)", () => Ce(), () => document.queryComm
3734
3841
  foundAt: "{date}의 초안을 찾았습니다. 복원하시겠습니까?",
3735
3842
  restore: "복원",
3736
3843
  discard: "삭제"
3844
+ },
3845
+ slashMenu: {
3846
+ noResults: "일치하는 명령이 없습니다",
3847
+ heading1: "제목 1",
3848
+ heading2: "제목 2",
3849
+ heading3: "제목 3",
3850
+ bulletList: "글머리 기호 목록",
3851
+ numberedList: "번호 매기기 목록",
3852
+ checklist: "체크리스트",
3853
+ blockquote: "인용문",
3854
+ codeBlock: "코드 블록",
3855
+ horizontalRule: "가로선",
3856
+ table: "표",
3857
+ image: "이미지"
3737
3858
  }
3738
3859
  }
3739
3860
  };
@@ -3922,8 +4043,13 @@ function nn(e, t) {
3922
4043
  //#endregion
3923
4044
  //#region src/js/editing/History.js
3924
4045
  var rn = class {
3925
- constructor(e, t = 100) {
3926
- this.editable = e, this._limit = t, this.stack = [], this.stackOffset = -1, this._savePoint();
4046
+ constructor(e, t = 100, n = 10 * 1024 * 1024) {
4047
+ this.editable = e, this._limit = t, this._maxBytes = n, this._bytes = 0, this.stack = [], this.stackOffset = -1, this._savePoint();
4048
+ }
4049
+ _entrySize(e) {
4050
+ let t = e.html.length;
4051
+ if (e.images) for (let n in e.images) t += e.images[n].length;
4052
+ return t;
3927
4053
  }
3928
4054
  _serialize() {
3929
4055
  return this.editable.innerHTML;
@@ -3977,13 +4103,17 @@ var rn = class {
3977
4103
  }
3978
4104
  }
3979
4105
  _savePoint() {
3980
- this.stackOffset < this.stack.length - 1 && (this.stack = this.stack.slice(0, this.stackOffset + 1));
3981
- let e = this._serialize(), { html: t, images: n } = this._tokenizeImages(e);
3982
- this.stack.push({
4106
+ if (this.stackOffset < this.stack.length - 1) {
4107
+ for (let e of this.stack.slice(this.stackOffset + 1)) this._bytes -= this._entrySize(e);
4108
+ this.stack = this.stack.slice(0, this.stackOffset + 1);
4109
+ }
4110
+ let e = this._serialize(), { html: t, images: n } = this._tokenizeImages(e), r = {
3983
4111
  html: t,
3984
4112
  images: n,
3985
4113
  sel: this._serializeSelection()
3986
- }), this.stack.length > this._limit ? this.stack.shift() : this.stackOffset++;
4114
+ };
4115
+ for (this.stack.push(r), this._bytes += this._entrySize(r); this.stack.length > 1 && (this.stack.length > this._limit || this._bytes > this._maxBytes);) this._bytes -= this._entrySize(this.stack.shift());
4116
+ this.stackOffset = this.stack.length - 1;
3987
4117
  }
3988
4118
  _restore(e) {
3989
4119
  e && (this.editable.innerHTML = this._detokenizeImages(e), this._restoreSelection(e.sel));
@@ -4016,7 +4146,7 @@ var rn = class {
4016
4146
  this.stackOffset >= this.stack.length - 1 || (this.stackOffset++, this._restore(this.stack[this.stackOffset]));
4017
4147
  }
4018
4148
  reset() {
4019
- this.stack = [], this.stackOffset = -1, this._savePoint();
4149
+ this.stack = [], this.stackOffset = -1, this._bytes = 0, this._savePoint();
4020
4150
  }
4021
4151
  canUndo() {
4022
4152
  return this.stackOffset > 0;
@@ -4643,7 +4773,7 @@ var Rn = class {
4643
4773
  }
4644
4774
  initialize() {
4645
4775
  let e = this.context.layoutInfo.editable;
4646
- return this._history = new rn(e, this.options.historyLimit || 100), this._bindEvents(e), this;
4776
+ return this._history = new rn(e, this.options.historyLimit || 100, this.options.historyMaxBytes || 10 * 1024 * 1024), this._bindEvents(e), this;
4647
4777
  }
4648
4778
  destroy() {
4649
4779
  this._disposers.forEach((e) => e()), this._disposers = [], this._history = null, clearTimeout(this._snapshotTimer), this._snapshotTimer = null;
@@ -4861,6 +4991,12 @@ var Rn = class {
4861
4991
  getRedoCount() {
4862
4992
  return this._history ? this._history.getRedoCount() : 0;
4863
4993
  }
4994
+ getSelectionBookmark() {
4995
+ return this._history?._serializeSelection() ?? null;
4996
+ }
4997
+ restoreSelectionBookmark(e) {
4998
+ return !e || !this._history ? !1 : (this._history._restoreSelection(e), !0);
4999
+ }
4864
5000
  bold() {
4865
5001
  Ce(), this.afterCommand();
4866
5002
  }
@@ -5385,7 +5521,7 @@ var qn = class {
5385
5521
  class: "an-status-info",
5386
5522
  "aria-label": "Editor statistics"
5387
5523
  });
5388
- return e.appendChild(this._wordCountEl), e.appendChild(this._charCountEl), this.el.appendChild(e), this._bindContentEvents(), this.update(), this;
5524
+ return e.appendChild(this._wordCountEl), e.appendChild(this._charCountEl), this.el.appendChild(e), this.update(), this;
5389
5525
  }
5390
5526
  destroy() {
5391
5527
  this._disposers.forEach((e) => e()), this._disposers = [], this._dragDisposers &&= (this._dragDisposers.forEach((e) => e()), null), this.el?.remove(), this.el = null;
@@ -5409,10 +5545,6 @@ var qn = class {
5409
5545
  }, d = D(e, "mousedown", s), f = D(e, "touchstart", u);
5410
5546
  this._disposers.push(d, f);
5411
5547
  }
5412
- _bindContentEvents() {
5413
- let e = this.context.layoutInfo.editable, n = D(e, "input", t(() => this.update(), 200));
5414
- this._disposers.push(n);
5415
- }
5416
5548
  update() {
5417
5549
  if (!this._wordCountEl || !this._charCountEl) return;
5418
5550
  let e = this.context.layoutInfo.editable.textContent || "", t = Gn(e), n = e.replaceAll("\n", "").length, r = this.options.maxWords || 0, i = this.options.maxChars || 0, a = this.context.locale.statusbar;
@@ -5620,9 +5752,8 @@ var qn = class {
5620
5752
  return;
5621
5753
  }
5622
5754
  let r = e.name.replace(/\.[^.]+$/, "");
5623
- this._compressImage(e).then((e) => {
5624
- let t = this._dataUrlToBlob(e), n = URL.createObjectURL(t);
5625
- this._blobRegistry.set(n, e), this.context.invoke("editor.insertImage", n, r);
5755
+ this.compressAndRegister(e).then((e) => {
5756
+ this.context.invoke("editor.insertImage", e, r);
5626
5757
  }).catch((t) => {
5627
5758
  let n = `Image "${e.name}" could not be processed.`;
5628
5759
  this.context.triggerEvent("imageError", {
@@ -5633,6 +5764,10 @@ var qn = class {
5633
5764
  });
5634
5765
  });
5635
5766
  }
5767
+ async compressAndRegister(e) {
5768
+ let t = this.options.imageProcessor, n = typeof t == "function" ? await t(e, { context: this.context }) : await this._compressImage(e), r = this._dataUrlToBlob(n), i = URL.createObjectURL(r);
5769
+ return this._blobRegistry.set(i, n), i;
5770
+ }
5636
5771
  resolveImages(e) {
5637
5772
  return this._blobRegistry?.size ? e.replace(/blob:[^"'> \t\n\r]*/g, (e) => this._blobRegistry.get(e) || e) : e;
5638
5773
  }
@@ -5904,8 +6039,8 @@ var qn = class {
5904
6039
  this._savedRange && this._savedRange.select(), this.context.invoke("editor.insertLink", e, t, n), this._close();
5905
6040
  }
5906
6041
  }, er = "<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>", tr = class extends U {
5907
- show() {
5908
- this._saveRange(), this._urlInput.value = "", this._altInput.value = "", this._fileInput && (this._fileInput.value = ""), this._open();
6042
+ show({ beforeInsert: e } = {}) {
6043
+ this._beforeInsert = typeof e == "function" ? e : null, this._saveRange(), this._urlInput.value = "", this._altInput.value = "", this._fileInput && (this._fileInput.value = ""), this._open();
5909
6044
  }
5910
6045
  _buildDialog() {
5911
6046
  let e = this.context.locale.imageDialog, { overlay: t, box: n } = this._buildDialogShell(e.ariaLabel, er, e.title), r = T("label", { class: "an-label" });
@@ -6011,10 +6146,16 @@ var qn = class {
6011
6146
  }), this._fileInput.value = "";
6012
6147
  return;
6013
6148
  }
6014
- let n = new FileReader();
6015
- n.onload = (e) => {
6016
- this._urlInput.value = e.target.result;
6017
- }, n.readAsDataURL(e);
6149
+ this.context.invoke("clipboard.compressAndRegister", e).then((e) => {
6150
+ this.context._alive !== !1 && (this._urlInput.value = e);
6151
+ }).catch((t) => {
6152
+ if (this.context._alive === !1) return;
6153
+ console.warn("[AutumnNote] ImageDialog: image compression failed, using original file.", t);
6154
+ let n = new FileReader();
6155
+ n.onload = (e) => {
6156
+ this._urlInput.value = e.target.result;
6157
+ }, n.readAsDataURL(e);
6158
+ });
6018
6159
  }
6019
6160
  _onInsert() {
6020
6161
  let e = this._urlInput.value.trim(), t = this._altInput.value.trim(), n = this._alignRow?.querySelector("input[name=\"an-img-align\"]:checked"), r = n ? n.value : "";
@@ -6022,7 +6163,12 @@ var qn = class {
6022
6163
  this._urlInput.focus();
6023
6164
  return;
6024
6165
  }
6025
- this._savedRange && this._savedRange.select(), this.context.invoke("editor.insertImage", e, t, r), this._close();
6166
+ this._savedRange && this._savedRange.select();
6167
+ let i = this._beforeInsert;
6168
+ this._beforeInsert = null, i?.(), this.context.invoke("editor.insertImage", e, t, r), this._close();
6169
+ }
6170
+ _close() {
6171
+ this._beforeInsert = null, super._close();
6026
6172
  }
6027
6173
  }, nr = "<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>", rr = class extends U {
6028
6174
  show() {
@@ -11720,10 +11866,10 @@ var Kr = class {
11720
11866
  this._selectLineAndDelete(), document.execCommand(e === "ul" ? "insertUnorderedList" : "insertOrderedList"), this.context.triggerEvent("change", this.context.getHTML());
11721
11867
  }
11722
11868
  _convertToChecklist() {
11723
- this._selectLineAndDelete(), this.context.invoke("editor.checklist"), this.context.triggerEvent("change", this.context.getHTML());
11869
+ this._selectLineAndDelete(), this.context.invoke("editor.toggleChecklist"), this.context.triggerEvent("change", this.context.getHTML());
11724
11870
  }
11725
11871
  _convertToHr() {
11726
- this._selectLineAndDelete(), this.context.invoke("editor.insertHR"), this.context.triggerEvent("change", this.context.getHTML());
11872
+ this._selectLineAndDelete(), this.context.invoke("editor.insertHr"), this.context.triggerEvent("change", this.context.getHTML());
11727
11873
  }
11728
11874
  _convertToCodeBlock() {
11729
11875
  this._selectLineAndDelete(), document.execCommand("formatBlock", !1, "pre"), this.context.triggerEvent("change", this.context.getHTML());
@@ -12148,9 +12294,236 @@ var Kr = class {
12148
12294
  let n;
12149
12295
  typeof this._cfg.onInsert == "function" && (n = this._cfg.onInsert(t)), n ||= `<span class="${this._cfg.mentionClass}" data-mention-id="${t.id}" contenteditable="false">@${t.label}</span>`, this.context.invoke("editor.insertHTML", n + "&#8203;"), this._hideDropdown(), this.context.triggerEvent("change", this.context.getHTML());
12150
12296
  }
12151
- }, ri = /* @__PURE__ */ new Map(), ii = /* @__PURE__ */ new Map(), ai = class {
12297
+ }, ri = class {
12298
+ constructor(e) {
12299
+ this.context = e, this.options = e.options, this._disposers = [], this._menu = null, this._filtered = [], this._activeIndex = -1, this._open = !1, this._query = "", this._textNode = null, this._triggerOffset = 0, this._caretRect = null;
12300
+ }
12301
+ initialize() {
12302
+ if (this.options.slashMenu === !1) return this;
12303
+ let e = this.context.layoutInfo.editable, t = D(e, "input", () => this._onInput()), n = D(e, "keydown", (e) => this._onKeydown(e)), r = D(document, "click", (e) => this._onDocClick(e));
12304
+ return this._disposers.push(t, n, r), this;
12305
+ }
12306
+ destroy() {
12307
+ this._menu?.remove(), this._menu = null, this._disposers.forEach((e) => e()), this._disposers = [];
12308
+ }
12309
+ _commands() {
12310
+ let e = this.context.locale.slashMenu, t = this.context, n = [
12311
+ {
12312
+ id: "h1",
12313
+ label: e.heading1,
12314
+ keywords: "h1 heading title",
12315
+ run: () => t.invoke("editor.formatBlock", "h1")
12316
+ },
12317
+ {
12318
+ id: "h2",
12319
+ label: e.heading2,
12320
+ keywords: "h2 heading subtitle",
12321
+ run: () => t.invoke("editor.formatBlock", "h2")
12322
+ },
12323
+ {
12324
+ id: "h3",
12325
+ label: e.heading3,
12326
+ keywords: "h3 heading",
12327
+ run: () => t.invoke("editor.formatBlock", "h3")
12328
+ },
12329
+ {
12330
+ id: "ul",
12331
+ label: e.bulletList,
12332
+ keywords: "ul bullet list unordered",
12333
+ run: () => t.invoke("editor.insertUL")
12334
+ },
12335
+ {
12336
+ id: "ol",
12337
+ label: e.numberedList,
12338
+ keywords: "ol numbered list ordered",
12339
+ run: () => t.invoke("editor.insertOL")
12340
+ },
12341
+ {
12342
+ id: "checklist",
12343
+ label: e.checklist,
12344
+ keywords: "checklist todo checkbox task",
12345
+ run: () => t.invoke("editor.toggleChecklist")
12346
+ },
12347
+ {
12348
+ id: "quote",
12349
+ label: e.blockquote,
12350
+ keywords: "quote blockquote",
12351
+ run: () => t.invoke("editor.formatBlock", "blockquote")
12352
+ },
12353
+ {
12354
+ id: "code",
12355
+ label: e.codeBlock,
12356
+ keywords: "code pre block",
12357
+ run: () => t.invoke("editor.formatBlock", "pre")
12358
+ },
12359
+ {
12360
+ id: "hr",
12361
+ label: e.horizontalRule,
12362
+ keywords: "hr divider rule line",
12363
+ run: () => t.invoke("editor.insertHr")
12364
+ },
12365
+ {
12366
+ id: "table",
12367
+ label: e.table,
12368
+ keywords: "table grid",
12369
+ run: () => t.invoke("editor.insertTable", 3, 3)
12370
+ },
12371
+ {
12372
+ id: "image",
12373
+ label: e.image,
12374
+ keywords: "image picture photo upload",
12375
+ run: () => t.invoke("imageDialog.show")
12376
+ }
12377
+ ], r = (this.options.slashCommands || []).map((e) => ({
12378
+ id: e.id,
12379
+ label: e.label || e.id,
12380
+ keywords: e.keywords || "",
12381
+ run: () => e.run(t)
12382
+ }));
12383
+ return [...n, ...r];
12384
+ }
12385
+ refresh() {
12386
+ this._open && this._filterAndRender();
12387
+ }
12388
+ _buildMenu() {
12389
+ let e = document.createElement("div");
12390
+ return e.className = "an-slash-menu", e.setAttribute("role", "listbox"), e.style.display = "none", e.addEventListener("mousedown", (e) => e.preventDefault()), e.addEventListener("click", (e) => {
12391
+ let t = e.target?.closest(".an-slash-menu-item");
12392
+ t && this._select(+t.dataset.index);
12393
+ }), e.addEventListener("mousemove", (e) => {
12394
+ let t = e.target?.closest(".an-slash-menu-item");
12395
+ t && this._highlight(+t.dataset.index);
12396
+ }), document.body.appendChild(e), this._menu = e, e;
12397
+ }
12398
+ _renderItems() {
12399
+ this._menu || this._buildMenu();
12400
+ let e = this._menu, t = this.context.locale.slashMenu;
12401
+ if (this._filtered.length === 0) {
12402
+ e.innerHTML = "";
12403
+ let n = document.createElement("div");
12404
+ n.className = "an-slash-menu-empty", n.textContent = t.noResults, e.appendChild(n), this._activeIndex = -1;
12405
+ return;
12406
+ }
12407
+ let n = document.createDocumentFragment();
12408
+ this._filtered.forEach((e, t) => {
12409
+ let r = document.createElement("div");
12410
+ r.className = "an-slash-menu-item", r.setAttribute("role", "option"), r.id = `an-slash-option-${e.id}`, r.dataset.index = String(t), r.textContent = e.label, n.appendChild(r);
12411
+ }), e.innerHTML = "", e.appendChild(n), this._highlight(0);
12412
+ }
12413
+ _highlight(e) {
12414
+ this._menu && (this._menu.querySelectorAll(".an-slash-menu-item").forEach((t, n) => {
12415
+ let r = n === e;
12416
+ t.classList.toggle("an-slash-menu-active", r), t.setAttribute("aria-selected", String(r)), r && this._menu.setAttribute("aria-activedescendant", t.id);
12417
+ }), this._activeIndex = e);
12418
+ }
12419
+ _position() {
12420
+ let e = this._menu, t = this._caretRect;
12421
+ if (!e || !t || t.height === 0) return;
12422
+ e.style.visibility = "hidden", e.style.display = "block";
12423
+ let n = e.offsetHeight, r = e.offsetWidth, i = t.bottom + 4, a = t.left;
12424
+ t.bottom + n + 8 > globalThis.innerHeight && (i = t.top - n - 4), a = Math.max(8, Math.min(a, globalThis.innerWidth - r - 8)), e.style.top = `${i}px`, e.style.left = `${a}px`, e.style.visibility = "";
12425
+ }
12426
+ _open_() {
12427
+ this._open = !0, this._filterAndRender(), this._position();
12428
+ }
12429
+ _close() {
12430
+ this._menu && (this._menu.style.display = "none"), this._open = !1, this._filtered = [], this._activeIndex = -1, this._menu?.removeAttribute("aria-activedescendant"), this._textNode = null, this._caretRect = null, this._query = "";
12431
+ }
12432
+ _isBlock(e) {
12433
+ if (e.nodeType !== Node.ELEMENT_NODE) return !1;
12434
+ let t = globalThis.getComputedStyle(e).display;
12435
+ return t === "block" || t === "list-item" || t === "table-cell";
12436
+ }
12437
+ _getTriggerContext() {
12438
+ let e = globalThis.getSelection();
12439
+ if (!e?.rangeCount) return null;
12440
+ let t = e.getRangeAt(0);
12441
+ if (!t.collapsed) return null;
12442
+ let n = this.context.layoutInfo.editable;
12443
+ if (!n.contains(t.startContainer) || t.startContainer.nodeType !== Node.TEXT_NODE) return null;
12444
+ let r = t.startContainer.parentNode;
12445
+ for (; r && r !== n && !this._isBlock(r);) r = r.parentNode;
12446
+ if (!r || r === n) return null;
12447
+ let i = r.textContent || "", a = document.createRange();
12448
+ a.setStart(r, 0), a.setEnd(t.startContainer, t.startOffset);
12449
+ let o = a.toString(), s = /^\/(\S*)$/.exec(o);
12450
+ return !s || i.length > o.length ? null : {
12451
+ query: s[1],
12452
+ textNode: t.startContainer,
12453
+ triggerOffset: t.startOffset - s[0].length
12454
+ };
12455
+ }
12456
+ _captureCaretRect(e, t) {
12457
+ try {
12458
+ let n = document.createRange(), r = Math.min(t + 1, e.textContent.length);
12459
+ n.setStart(e, t), n.setEnd(e, r);
12460
+ let i = n.getBoundingClientRect();
12461
+ if (i.height > 0) return i;
12462
+ } catch {}
12463
+ let n = globalThis.getSelection();
12464
+ if (!n?.rangeCount) return null;
12465
+ let r = n.getRangeAt(0).getClientRects();
12466
+ return r.length > 0 ? r[r.length - 1] : null;
12467
+ }
12468
+ _filterAndRender() {
12469
+ let e = this._query.toLowerCase();
12470
+ this._filtered = e ? this._commands().filter((t) => t.keywords.includes(e) || t.label.toLowerCase().includes(e)) : this._commands(), this._renderItems();
12471
+ }
12472
+ _onInput() {
12473
+ let e = this._getTriggerContext();
12474
+ if (!e) {
12475
+ this._open && this._close();
12476
+ return;
12477
+ }
12478
+ this._textNode = e.textNode, this._triggerOffset = e.triggerOffset, this._query = e.query, this._caretRect = this._captureCaretRect(e.textNode, e.triggerOffset), this._open ? (this._filterAndRender(), this._position()) : this._open_();
12479
+ }
12480
+ _onKeydown(e) {
12481
+ if (this._open) if (e.key === "ArrowDown") {
12482
+ if (e.preventDefault(), this._filtered.length === 0) return;
12483
+ this._highlight((this._activeIndex + 1) % this._filtered.length);
12484
+ } else if (e.key === "ArrowUp") {
12485
+ if (e.preventDefault(), this._filtered.length === 0) return;
12486
+ this._highlight((this._activeIndex - 1 + this._filtered.length) % this._filtered.length);
12487
+ } else e.key === "Enter" || e.key === "Tab" ? this._activeIndex >= 0 && (e.preventDefault(), this._select(this._activeIndex)) : e.key === "Escape" && (e.preventDefault(), this._close());
12488
+ }
12489
+ _onDocClick(e) {
12490
+ this._open && (this._menu?.contains(e.target) || this._close());
12491
+ }
12492
+ _deleteTriggerText() {
12493
+ let e = this._textNode;
12494
+ if (!e?.isConnected) return;
12495
+ e.textContent = e.textContent.slice(0, this._triggerOffset) + e.textContent.slice(this._triggerOffset + 1 + this._query.length);
12496
+ let t = globalThis.getSelection();
12497
+ if (!t) return;
12498
+ let n = document.createRange();
12499
+ n.setStart(e, this._triggerOffset), n.collapse(!0), t.removeAllRanges(), t.addRange(n);
12500
+ }
12501
+ _makeTriggerRemover() {
12502
+ let e = this._textNode, t = this._triggerOffset, n = this._query;
12503
+ return () => {
12504
+ if (!e?.isConnected) return;
12505
+ let r = e.textContent.slice(0, t), i = e.textContent.slice(t + 1 + n.length);
12506
+ e.textContent = r + i;
12507
+ let a = globalThis.getSelection();
12508
+ if (!a) return;
12509
+ let o = document.createRange();
12510
+ o.setStart(e, t), o.collapse(!0), a.removeAllRanges(), a.addRange(o);
12511
+ };
12512
+ }
12513
+ _select(e) {
12514
+ let t = this._filtered[e];
12515
+ if (t) {
12516
+ if (t.id === "image") {
12517
+ let e = this._makeTriggerRemover();
12518
+ this._close(), this.context.invoke("imageDialog.show", { beforeInsert: e });
12519
+ return;
12520
+ }
12521
+ this._deleteTriggerText(), this._close(), t.run();
12522
+ }
12523
+ }
12524
+ }, ii = /* @__PURE__ */ new Map(), ai = /* @__PURE__ */ new Map(), oi = class {
12152
12525
  constructor(e, t = {}) {
12153
- this.targetEl = e, this.options = c(j, t), this.locale = Ht(this.options.lang), this.layoutInfo = {}, this._listeners = /* @__PURE__ */ new Map(), this._modules = /* @__PURE__ */ new Map(), this._plugins = /* @__PURE__ */ new Map(), this._disposers = [], this._alive = !1;
12526
+ this.targetEl = e, this.options = c(j, t), this.locale = Ht(this.options.lang), this.layoutInfo = {}, this._listeners = /* @__PURE__ */ new Map(), this._modules = /* @__PURE__ */ new Map(), this._plugins = /* @__PURE__ */ new Map(), this._disposers = [], this._alive = !1, this._autoSaveTimer = null, this._pendingAutoSave = null, this._suppressedRemoteHTML = null;
12154
12527
  }
12155
12528
  initialize() {
12156
12529
  let { container: e, editable: t } = nn(this.targetEl, this.options);
@@ -12165,13 +12538,18 @@ var Kr = class {
12165
12538
  let n = new t(this);
12166
12539
  this._modules.set(e, n), n.initialize();
12167
12540
  };
12168
- if (e("editor", Rn), e("toolbar", Un), e("statusbar", qn), e("clipboard", Jn), e("contextMenu", zr), e("placeholder", Yn), e("codeview", Xn), e("fullscreen", Zn), e("linkDialog", $n), e("imageDialog", tr), e("videoDialog", rr), e("imageResizer", ar), e("videoResizer", sr), e("linkTooltip", dr), e("imageTooltip", mr), e("videoTooltip", _r), e("tableTooltip", wr), e("codeTooltip", kr), e("emojiDialog", Mr), e("iconDialog", Fr), e("shortcutsDialog", Hr), e("findReplace", Ur), e("imageCropOverlay", Kr), e("autoSaveRestore", qr), e("markdownShortcuts", Jr), e("bubbleToolbar", ti), e("mention", ni), ri.size > 0) for (let [t, n] of ri) e(t, n);
12541
+ if (e("editor", Rn), e("toolbar", Un), e("statusbar", qn), e("clipboard", Jn), e("contextMenu", zr), e("placeholder", Yn), e("codeview", Xn), e("fullscreen", Zn), e("linkDialog", $n), e("imageDialog", tr), e("videoDialog", rr), e("imageResizer", ar), e("videoResizer", sr), e("linkTooltip", dr), e("imageTooltip", mr), e("videoTooltip", _r), e("tableTooltip", wr), e("codeTooltip", kr), e("emojiDialog", Mr), e("iconDialog", Fr), e("shortcutsDialog", Hr), e("findReplace", Ur), e("imageCropOverlay", Kr), this.options.autoSaveRestore && e("autoSaveRestore", qr), this.options.markdownShortcuts !== !1 && e("markdownShortcuts", Jr), this.options.bubbleToolbar && e("bubbleToolbar", ti), this.options.mention && e("mention", ni), this.options.slashMenu !== !1 && e("slashMenu", ri), ii.size > 0) for (let [t, n] of ii) e(t, n);
12169
12542
  }
12170
12543
  registerModule(e, t) {
12171
12544
  if (this._modules.has(e)) return this;
12172
12545
  let n = new t(this);
12173
12546
  return n.initialize(), this._modules.set(e, n), this;
12174
12547
  }
12548
+ registerSlashCommand(e) {
12549
+ if (!e?.id || typeof e.run != "function") throw TypeError("[AutumnNote] Slash command requires an id and run(context) function.");
12550
+ let t = this.options.slashCommands || (this.options.slashCommands = []), n = t.findIndex((t) => t.id === e.id);
12551
+ return n >= 0 ? t[n] = e : t.push(e), this.invoke("slashMenu.refresh"), this;
12552
+ }
12175
12553
  use(e, t = {}) {
12176
12554
  return Array.isArray(e.buttons) && e.buttons.forEach((e) => Qe(e)), this._installPlugin(e, t), this;
12177
12555
  }
@@ -12195,24 +12573,64 @@ var Kr = class {
12195
12573
  });
12196
12574
  }
12197
12575
  _applyGlobalPlugins() {
12198
- if (ii.size !== 0) for (let { plugin: e, options: t } of ii.values()) this._installPlugin(e, t);
12576
+ if (ai.size !== 0) for (let { plugin: e, options: t } of ai.values()) this._installPlugin(e, t);
12199
12577
  }
12200
12578
  _bindEditorEvents(e) {
12201
12579
  let t = D(e, "input", () => this._syncToTarget()), n = D(e, "focus", () => {
12202
12580
  this.layoutInfo.container.classList.add("an-focused"), typeof this.options.onFocus == "function" && this.options.onFocus(this);
12203
12581
  }), r = D(e, "blur", () => {
12204
12582
  this.layoutInfo.container.classList.remove("an-focused"), this._syncToTarget(), typeof this.options.onBlur == "function" && this.options.onBlur(this);
12205
- }), i = this.on("change", () => this._syncToTarget());
12206
- if (this._disposers.push(t, n, r, i), this.options.autoSave && this.options.autoSaveKey) {
12207
- let e = this.on("change", () => {
12208
- try {
12209
- let e = this.options.autoSaveKey;
12210
- localStorage.setItem(e, this.getHTML()), localStorage.setItem(e + ":asrmeta", JSON.stringify({ savedAt: Date.now() }));
12211
- } catch {}
12212
- });
12583
+ }), i = this.on("change", (e) => this._syncToTarget(e)), a = this.on("change", (e) => {
12584
+ if (this.options.blockIds && (this.ensureBlockIds(), e = this.getHTML()), e === this._suppressedRemoteHTML) {
12585
+ this._suppressedRemoteHTML = null;
12586
+ return;
12587
+ }
12588
+ this.options.collaborationAdapter?.onLocalChange?.(e, this);
12589
+ });
12590
+ if (this._disposers.push(t, n, r, i, a), this.options.autoSave && this.options.autoSaveKey) {
12591
+ let e = this.on("change", (e) => this._scheduleAutoSave(e));
12213
12592
  this._disposers.push(e);
12214
12593
  }
12215
12594
  }
12595
+ _scheduleAutoSave(e) {
12596
+ this._pendingAutoSave = e, clearTimeout(this._autoSaveTimer), this._autoSaveTimer = setTimeout(() => this.flushAutoSave(), this.options.autoSaveDelay ?? 400);
12597
+ }
12598
+ async flushAutoSave() {
12599
+ if (clearTimeout(this._autoSaveTimer), this._autoSaveTimer = null, this._pendingAutoSave == null) return;
12600
+ let e = this._pendingAutoSave;
12601
+ this._pendingAutoSave = null;
12602
+ let t = this.options.autoSaveKey, n = Date.now();
12603
+ try {
12604
+ let r = this.options.autoSaveAdapter;
12605
+ typeof r?.save == "function" ? await r.save({
12606
+ key: t,
12607
+ html: e,
12608
+ savedAt: n,
12609
+ context: this
12610
+ }) : (localStorage.setItem(t, e), localStorage.setItem(t + ":asrmeta", JSON.stringify({ savedAt: n }))), this.triggerEvent("autoSave", {
12611
+ key: t,
12612
+ html: e,
12613
+ savedAt: n
12614
+ });
12615
+ } catch (e) {
12616
+ this.triggerEvent("autoSaveError", {
12617
+ key: t,
12618
+ error: e
12619
+ });
12620
+ }
12621
+ }
12622
+ async loadAutoSave() {
12623
+ let e = this.options.autoSaveAdapter;
12624
+ if (typeof e?.load == "function") return e.load({
12625
+ key: this.options.autoSaveKey,
12626
+ context: this
12627
+ });
12628
+ try {
12629
+ return localStorage.getItem(this.options.autoSaveKey);
12630
+ } catch {
12631
+ return null;
12632
+ }
12633
+ }
12216
12634
  invoke(e, ...t) {
12217
12635
  let [n, r] = e.split("."), i = this._modules.get(n);
12218
12636
  if (!i) {
@@ -12239,6 +12657,20 @@ var Kr = class {
12239
12657
  let n = "on" + e.charAt(0).toUpperCase() + e.slice(1);
12240
12658
  typeof this.options[n] == "function" && this.options[n](...t);
12241
12659
  }
12660
+ updateOptions(e = {}) {
12661
+ let t = c(this.options, e);
12662
+ Object.keys(this.options).forEach((e) => delete this.options[e]), Object.assign(this.options, t);
12663
+ let { container: n, editable: r } = this.layoutInfo;
12664
+ if (Object.hasOwn(e, "readOnly") && this.setDisabled(!!this.options.readOnly), Object.hasOwn(e, "spellcheck") && (r.spellcheck = this.options.spellcheck !== !1), Object.hasOwn(e, "placeholder") && (r.dataset.placeholder = this.options.placeholder || ""), Object.hasOwn(e, "direction")) {
12665
+ let e = this.options.direction === "rtl";
12666
+ r.setAttribute("dir", e ? "rtl" : "ltr"), n.classList.toggle("an-dir-rtl", e);
12667
+ }
12668
+ if (Object.hasOwn(e, "height") || Object.hasOwn(e, "minHeight")) {
12669
+ let e = this.options.height || this.options.minHeight || 0;
12670
+ r.style.minHeight = e ? `${e}px` : "";
12671
+ }
12672
+ return Object.hasOwn(e, "maxHeight") && (r.style.maxHeight = this.options.maxHeight ? `${this.options.maxHeight}px` : ""), Object.hasOwn(e, "toolbar") && this.invoke("toolbar.rebuild"), this.invoke("statusbar.update"), this.triggerEvent("optionsChange", { ...e }), this;
12673
+ }
12242
12674
  getHTML() {
12243
12675
  let e = this.invoke("editor.getHTML");
12244
12676
  return typeof e == "string" ? e.replace(/​/g, "") : e;
@@ -12279,6 +12711,50 @@ var Kr = class {
12279
12711
  getMarkdown() {
12280
12712
  return this.invoke("editor.getMarkdown");
12281
12713
  }
12714
+ getSelectionBookmark() {
12715
+ return this.invoke("editor.getSelectionBookmark") ?? null;
12716
+ }
12717
+ restoreSelectionBookmark(e) {
12718
+ return this.invoke("editor.restoreSelectionBookmark", e);
12719
+ }
12720
+ async importDocument(e, t) {
12721
+ let n = this.options.documentAdapters?.[e], r;
12722
+ if (typeof n?.import == "function") r = await n.import(t, this);
12723
+ else if (e === "html") r = String(t ?? "");
12724
+ else if (e === "markdown") return this.setMarkdown(String(t ?? "")), this;
12725
+ else if (e === "text") return this.setText(String(t ?? "")), this;
12726
+ else throw Error(`[AutumnNote] No importer registered for "${e}".`);
12727
+ return this.setHTML(r), this;
12728
+ }
12729
+ async exportDocument(e) {
12730
+ let t = this.options.documentAdapters?.[e];
12731
+ if (typeof t?.export == "function") return t.export(this, this.getHTML());
12732
+ if (e === "html") return this.getHTML();
12733
+ if (e === "markdown") return this.getMarkdown();
12734
+ if (e === "text") return this.getText();
12735
+ throw Error(`[AutumnNote] No exporter registered for "${e}".`);
12736
+ }
12737
+ ensureBlockIds() {
12738
+ let e = this.layoutInfo.editable.children;
12739
+ for (let t of e) if (!t.hasAttribute("data-an-block-id")) {
12740
+ let e = globalThis.crypto?.randomUUID?.() || `an-${Date.now()}-${Math.random().toString(36).slice(2)}`;
12741
+ t.setAttribute("data-an-block-id", e);
12742
+ }
12743
+ return this;
12744
+ }
12745
+ getDocument() {
12746
+ return this.options.blockIds && this.ensureBlockIds(), {
12747
+ version: 1,
12748
+ html: this.getHTML(),
12749
+ markdown: this.getMarkdown()
12750
+ };
12751
+ }
12752
+ loadDocument(e) {
12753
+ return this.setHTML(e?.html || ""), this.clearHistory(), this;
12754
+ }
12755
+ applyRemoteHTML(e) {
12756
+ return this.setHTML(e), this._suppressedRemoteHTML = this.getHTML(), this.clearHistory(), this;
12757
+ }
12282
12758
  getWordCount() {
12283
12759
  return this.invoke("statusbar.getWordCount") ?? 0;
12284
12760
  }
@@ -12334,7 +12810,7 @@ var Kr = class {
12334
12810
  }
12335
12811
  destroy() {
12336
12812
  if (!this._alive) return;
12337
- this._modules.forEach((e) => {
12813
+ this._pendingAutoSave != null && this.flushAutoSave(), this._modules.forEach((e) => {
12338
12814
  typeof e.destroy == "function" && e.destroy();
12339
12815
  }), this._modules.clear();
12340
12816
  for (let { plugin: e } of this._plugins.values()) if (typeof e.uninstall == "function") try {
@@ -12344,50 +12820,50 @@ var Kr = class {
12344
12820
  let e = this.layoutInfo.container, t = e?.classList.contains("an-theme-dark"), n = e?.classList.contains("an-theme-auto");
12345
12821
  e?.parentNode && (this.targetEl.style.display = "", e.remove()), t && !document.querySelector(".an-container.an-theme-dark") && document.body.classList.remove("an-theme-dark"), n && !document.querySelector(".an-container.an-theme-auto") && document.body.classList.remove("an-theme-auto"), typeof this.options.onDestroy == "function" && this.options.onDestroy(this), this._alive = !1, this._listeners.clear();
12346
12822
  }
12347
- _syncToTarget() {
12348
- (this.targetEl.tagName === "TEXTAREA" || this.targetEl.tagName === "INPUT") && (this.targetEl.value = this.getHTML());
12823
+ _syncToTarget(e) {
12824
+ (this.targetEl.tagName === "TEXTAREA" || this.targetEl.tagName === "INPUT") && (this.targetEl.value = typeof e == "string" ? e : this.getHTML());
12349
12825
  }
12350
12826
  };
12351
12827
  //#endregion
12352
12828
  //#region src/js/core/lists.js
12353
- function oi(e) {
12829
+ function si(e) {
12354
12830
  return e[e.length - 1];
12355
12831
  }
12356
- function si(e) {
12832
+ function ci(e) {
12357
12833
  return e[0];
12358
12834
  }
12359
- function ci(e, t = 1) {
12835
+ function li(e, t = 1) {
12360
12836
  return e.slice(0, e.length - t);
12361
12837
  }
12362
- function li(e, t = 1) {
12838
+ function ui(e, t = 1) {
12363
12839
  return e.slice(t);
12364
12840
  }
12365
- function ui(e) {
12841
+ function di(e) {
12366
12842
  return e.flat();
12367
12843
  }
12368
- function di(e) {
12844
+ function fi(e) {
12369
12845
  return [...new Set(e)];
12370
12846
  }
12371
- function fi(e, t) {
12847
+ function pi(e, t) {
12372
12848
  let n = [];
12373
12849
  for (let r = 0; r < e.length; r += t) n.push(e.slice(r, r + t));
12374
12850
  return n;
12375
12851
  }
12376
- function pi(e, t) {
12852
+ function mi(e, t) {
12377
12853
  return e.reduce((e, n) => {
12378
12854
  let r = t(n);
12379
12855
  return e[r] || (e[r] = []), e[r].push(n), e;
12380
12856
  }, {});
12381
12857
  }
12382
- function mi(e, t) {
12858
+ function hi(e, t) {
12383
12859
  return e.every(t);
12384
12860
  }
12385
- function hi(e, t) {
12861
+ function gi(e, t) {
12386
12862
  return e.some(t);
12387
12863
  }
12388
12864
  //#endregion
12389
12865
  //#region src/js/core/env.js
12390
- var Q = navigator.userAgent, gi = {
12866
+ var Q = navigator.userAgent, _i = {
12391
12867
  isChrome: /Chrome\//.test(Q),
12392
12868
  isFF: /Firefox\//.test(Q),
12393
12869
  isSafari: /^((?!chrome|android).)*safari/i.test(Q),
@@ -12396,17 +12872,17 @@ var Q = navigator.userAgent, gi = {
12396
12872
  isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(Q),
12397
12873
  isTouch: "ontouchstart" in globalThis || navigator.maxTouchPoints > 0,
12398
12874
  modifierKey: /Macintosh/.test(Q) ? "metaKey" : "ctrlKey"
12399
- }, _i = { ...j }, $ = /* @__PURE__ */ new WeakMap(), vi = {
12875
+ }, vi = { ...j }, $ = /* @__PURE__ */ new WeakMap(), yi = {
12400
12876
  create(e, t = {}) {
12401
- let n = yi(e).map((e) => {
12877
+ let n = bi(e).map((e) => {
12402
12878
  if ($.has(e)) return $.get(e);
12403
- let n = new ai(e, t);
12879
+ let n = new oi(e, t);
12404
12880
  return n.initialize(), $.set(e, n), n;
12405
12881
  });
12406
12882
  return n.length === 1 ? n[0] : n;
12407
12883
  },
12408
12884
  destroy(e) {
12409
- yi(e).forEach((e) => {
12885
+ bi(e).forEach((e) => {
12410
12886
  let t = $.get(e);
12411
12887
  t && (t.destroy(), $.delete(e));
12412
12888
  });
@@ -12422,31 +12898,36 @@ var Q = navigator.userAgent, gi = {
12422
12898
  Object.assign(j, e);
12423
12899
  },
12424
12900
  resetDefaults() {
12425
- Object.keys(j).forEach((e) => delete j[e]), Object.assign(j, _i);
12901
+ Object.keys(j).forEach((e) => delete j[e]), Object.assign(j, vi);
12426
12902
  },
12427
12903
  registerModule(e, t) {
12428
- ri.set(e, t);
12904
+ ii.set(e, t);
12429
12905
  },
12430
12906
  use(e, t = {}) {
12431
12907
  if (!e || typeof e.name != "string") throw TypeError("[AutumnNote] AutumnNote.use: plugin must have a string `name` property.");
12432
- return ii.has(e.name) ? (console.warn(`[AutumnNote] Plugin "${e.name}" already registered globally. Skipping.`), this) : (Array.isArray(e.buttons) && e.buttons.forEach((e) => Qe(e)), ii.set(e.name, {
12908
+ return ai.has(e.name) ? (console.warn(`[AutumnNote] Plugin "${e.name}" already registered globally. Skipping.`), this) : (Array.isArray(e.buttons) && e.buttons.forEach((e) => Qe(e)), ai.set(e.name, {
12433
12909
  plugin: e,
12434
12910
  options: t
12435
12911
  }), this);
12436
12912
  },
12437
12913
  hasPlugin(e) {
12438
- return ii.has(e);
12914
+ return ai.has(e);
12439
12915
  },
12440
12916
  registerButton(e) {
12441
12917
  return Qe(e), this;
12442
12918
  },
12919
+ registerSlashCommand(e) {
12920
+ if (!e?.id || typeof e.run != "function") throw TypeError("[AutumnNote] Slash command requires an id and run(context) function.");
12921
+ let t = j.slashCommands, n = t.findIndex((t) => t.id === e.id);
12922
+ return n >= 0 ? t[n] = e : t.push(e), this;
12923
+ },
12443
12924
  buttons: Bt,
12444
- version: "1.15.0"
12925
+ version: "1.16.0"
12445
12926
  };
12446
- function yi(e) {
12927
+ function bi(e) {
12447
12928
  return typeof e == "string" ? Array.from(document.querySelectorAll(e)) : e instanceof Element ? [e] : e instanceof NodeList || Array.isArray(e) ? Array.from(e) : [];
12448
12929
  }
12449
12930
  //#endregion
12450
- export { ai as Context, d as ELEMENT_NODE, f as TEXT_NODE, he as WrappedRange, Ze as _buttonRegistry, st as alignCenterBtn, lt as alignJustifyBtn, ot as alignLeftBtn, ct as alignRightBtn, mi as all, te as ancestors, hi as any, Rt as backColorBtn, et as boldBtn, Bt as buttons, Ft as checklistBtn, ne as children, fi as chunk, e as clamp, C as closest, w as closestPara, kt as codeviewBtn, ye as collapsedRange, r as compose, T as createElement, _e as currentRange, t as debounce, vi as default, j as defaultOptions, zt as defaultToolbar, Tt as directionBtn, bt as emojiBtn, gi as env, Mt as findBtn, Nt as findReplaceBtn, si as first, ui as flatten, Et as fontFamilyBtn, Ct as fontSizeBtn, Lt as foreColorBtn, ge as fromNativeRange, At as fullscreenBtn, $e as getButton, pi as groupBy, gt as hrBtn, xt as iconBtn, i as identity, vt as imageBtn, ft as indentBtn, ci as initial, Pt as inlineCodeBtn, se as insertAfter, S as isAnchor, x as isEditable, p as isElement, le as isEmpty, s as isFunction, ee as isImage, b as isInline, fe as isInsideEditable, I as isKey, _ as isLi, v as isList, L as isModifier, a as isNil, g as isPara, l as isPlainObject, be as isSelectionInside, o as isString, y as isTable, m as isText, h as isVoid, tt as italicBtn, F as key, oi as last, Ot as lineHeightBtn, _t as linkBtn, Vt as locales, me as makeDraggable, c as mergeDeep, ie as nextElement, ce as nodeValue, dt as olBtn, D as on, pt as outdentBtn, ue as outerHtml, Dt as paragraphStyleBtn, de as placeCaret, re as prevElement, It as printBtn, ve as rangeFromElement, u as rect2bnd, ht as redoBtn, Qe as registerButton, E as remove, wt as removeFormatBtn, Ht as resolveLocale, N as sanitiseHTML, P as sanitiseUrl, jt as shortcutsBtn, Se as splitText, rt as strikeBtn, at as subscriptBtn, it as superscriptBtn, St as tableBtn, li as tail, n as throttle, pe as trapFocus, ut as ulBtn, nt as underlineBtn, mt as undoBtn, di as unique, ae as unwrap, yt as videoBtn, xe as withSavedRange, oe as wrap };
12931
+ export { oi as Context, d as ELEMENT_NODE, f as TEXT_NODE, he as WrappedRange, Ze as _buttonRegistry, st as alignCenterBtn, lt as alignJustifyBtn, ot as alignLeftBtn, ct as alignRightBtn, hi as all, te as ancestors, gi as any, Rt as backColorBtn, et as boldBtn, Bt as buttons, Ft as checklistBtn, ne as children, pi as chunk, e as clamp, C as closest, w as closestPara, kt as codeviewBtn, ye as collapsedRange, r as compose, T as createElement, _e as currentRange, t as debounce, yi as default, j as defaultOptions, zt as defaultToolbar, Tt as directionBtn, bt as emojiBtn, _i as env, Mt as findBtn, Nt as findReplaceBtn, ci as first, di as flatten, Et as fontFamilyBtn, Ct as fontSizeBtn, Lt as foreColorBtn, ge as fromNativeRange, At as fullscreenBtn, $e as getButton, mi as groupBy, gt as hrBtn, xt as iconBtn, i as identity, vt as imageBtn, ft as indentBtn, li as initial, Pt as inlineCodeBtn, se as insertAfter, S as isAnchor, x as isEditable, p as isElement, le as isEmpty, s as isFunction, ee as isImage, b as isInline, fe as isInsideEditable, I as isKey, _ as isLi, v as isList, L as isModifier, a as isNil, g as isPara, l as isPlainObject, be as isSelectionInside, o as isString, y as isTable, m as isText, h as isVoid, tt as italicBtn, F as key, si as last, Ot as lineHeightBtn, _t as linkBtn, Vt as locales, me as makeDraggable, c as mergeDeep, ie as nextElement, ce as nodeValue, dt as olBtn, D as on, pt as outdentBtn, ue as outerHtml, Dt as paragraphStyleBtn, de as placeCaret, re as prevElement, It as printBtn, ve as rangeFromElement, u as rect2bnd, ht as redoBtn, Qe as registerButton, E as remove, wt as removeFormatBtn, Ht as resolveLocale, N as sanitiseHTML, P as sanitiseUrl, jt as shortcutsBtn, Se as splitText, rt as strikeBtn, at as subscriptBtn, it as superscriptBtn, St as tableBtn, ui as tail, n as throttle, pe as trapFocus, ut as ulBtn, nt as underlineBtn, mt as undoBtn, fi as unique, ae as unwrap, yt as videoBtn, xe as withSavedRange, oe as wrap };
12451
12932
 
12452
12933
  //# sourceMappingURL=autumnnote.es.js.map