autumnnote 1.7.0 → 1.8.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.
@@ -1458,6 +1458,48 @@ var defaultToolbar = [
1458
1458
  shortcutsBtn
1459
1459
  ]
1460
1460
  ];
1461
+ var buttons = {
1462
+ boldBtn,
1463
+ italicBtn,
1464
+ underlineBtn,
1465
+ strikeBtn,
1466
+ superscriptBtn,
1467
+ subscriptBtn,
1468
+ alignLeftBtn,
1469
+ alignCenterBtn,
1470
+ alignRightBtn,
1471
+ alignJustifyBtn,
1472
+ ulBtn,
1473
+ olBtn,
1474
+ indentBtn,
1475
+ outdentBtn,
1476
+ undoBtn,
1477
+ redoBtn,
1478
+ hrBtn,
1479
+ linkBtn,
1480
+ imageBtn,
1481
+ videoBtn,
1482
+ emojiBtn,
1483
+ iconBtn,
1484
+ tableBtn,
1485
+ fontSizeBtn,
1486
+ removeFormatBtn,
1487
+ directionBtn,
1488
+ fontFamilyBtn,
1489
+ paragraphStyleBtn,
1490
+ lineHeightBtn,
1491
+ codeviewBtn,
1492
+ fullscreenBtn,
1493
+ shortcutsBtn,
1494
+ findBtn,
1495
+ findReplaceBtn,
1496
+ inlineCodeBtn,
1497
+ checklistBtn,
1498
+ printBtn,
1499
+ foreColorBtn,
1500
+ backColorBtn,
1501
+ defaultToolbar
1502
+ };
1461
1503
  //#endregion
1462
1504
  //#region src/js/settings.js
1463
1505
  /**
@@ -1752,6 +1794,7 @@ var en = {
1752
1794
  findPlaceholder: "Find…",
1753
1795
  searchAriaLabel: "Search text",
1754
1796
  caseSensitive: "\xA0Case sensitive",
1797
+ wholeWord: "Whole Word",
1755
1798
  prevBtn: "← Prev",
1756
1799
  nextBtn: "Next →",
1757
1800
  replacePlaceholder: "Replace with…",
@@ -1762,6 +1805,12 @@ var en = {
1762
1805
  useRegex: "Use Regular Expression",
1763
1806
  close: "×"
1764
1807
  },
1808
+ autoSaveRestore: {
1809
+ found: "Draft found. Restore?",
1810
+ foundAt: "Draft from {date}. Restore?",
1811
+ restore: "Restore",
1812
+ discard: "Discard"
1813
+ },
1765
1814
  shortcutsDialog: {
1766
1815
  title: "Keyboard Shortcuts",
1767
1816
  ariaLabel: "Keyboard Shortcuts",
@@ -2324,6 +2373,12 @@ var locales = {
2324
2373
  errors: {
2325
2374
  imageFormat: (type) => `Định dạng "${type}" không được hỗ trợ hiển thị trên trình duyệt. Vui lòng chuyển đổi sang JPEG, PNG hoặc WebP.`,
2326
2375
  imageSize: (maxSize) => `Tệp hình ảnh quá lớn. Kích thước tối đa cho phép là ${maxSize} MB.`
2376
+ },
2377
+ autoSaveRestore: {
2378
+ found: "Tìm thấy bản nháp. Khôi phục?",
2379
+ foundAt: "Bản nháp từ {date}. Khôi phục?",
2380
+ restore: "Khôi phục",
2381
+ discard: "Bỏ qua"
2327
2382
  }
2328
2383
  },
2329
2384
  ja: {
@@ -2662,6 +2717,12 @@ var locales = {
2662
2717
  errors: {
2663
2718
  imageFormat: (type) => `形式 "${type}" はブラウザでの表示をサポートしていません。JPEG、PNG、または WebP に変換してください。`,
2664
2719
  imageSize: (maxSize) => `画像ファイルが大きすぎます。最大許容サイズは ${maxSize} MB です。`
2720
+ },
2721
+ autoSaveRestore: {
2722
+ found: "下書きが見つかりました。復元しますか?",
2723
+ foundAt: "{date} の下書きが見つかりました。復元しますか?",
2724
+ restore: "復元",
2725
+ discard: "破棄"
2665
2726
  }
2666
2727
  },
2667
2728
  zh: {
@@ -3000,6 +3061,12 @@ var locales = {
3000
3061
  errors: {
3001
3062
  imageFormat: (type) => `格式 "${type}" 不支持在浏览器中显示。请转换为 JPEG、PNG 或 WebP。`,
3002
3063
  imageSize: (maxSize) => `图片文件过大。最大允许大小为 ${maxSize} MB。`
3064
+ },
3065
+ autoSaveRestore: {
3066
+ found: "找到草稿。是否恢复?",
3067
+ foundAt: "发现 {date} 的草稿。是否恢复?",
3068
+ restore: "恢复",
3069
+ discard: "放弃"
3003
3070
  }
3004
3071
  },
3005
3072
  fr: {
@@ -3338,6 +3405,12 @@ var locales = {
3338
3405
  errors: {
3339
3406
  imageFormat: (type) => `Le format "${type}" n'est pas pris en charge par le navigateur. Veuillez le convertir en JPEG, PNG ou WebP.`,
3340
3407
  imageSize: (maxSize) => `Le fichier image est trop volumineux. La taille maximale autorisée est de ${maxSize}\u00a0Mo.`
3408
+ },
3409
+ autoSaveRestore: {
3410
+ found: "Brouillon trouvé. Restaurer ?",
3411
+ foundAt: "Brouillon du {date}. Restaurer ?",
3412
+ restore: "Restaurer",
3413
+ discard: "Ignorer"
3341
3414
  }
3342
3415
  },
3343
3416
  de: {
@@ -3676,6 +3749,12 @@ var locales = {
3676
3749
  errors: {
3677
3750
  imageFormat: (type) => `Das Format „${type}" wird in Webbrowsern nicht unterstützt. Bitte konvertieren Sie es zuerst in JPEG, PNG oder WebP.`,
3678
3751
  imageSize: (maxSize) => `Die Bilddatei ist zu groß. Die maximal zulässige Größe beträgt ${maxSize} MB.`
3752
+ },
3753
+ autoSaveRestore: {
3754
+ found: "Entwurf gefunden. Wiederherstellen?",
3755
+ foundAt: "Entwurf vom {date}. Wiederherstellen?",
3756
+ restore: "Wiederherstellen",
3757
+ discard: "Verwerfen"
3679
3758
  }
3680
3759
  },
3681
3760
  es: {
@@ -4014,6 +4093,12 @@ var locales = {
4014
4093
  errors: {
4015
4094
  imageFormat: (type) => `El formato "${type}" no es compatible con los navegadores web. Por favor, conviértalo primero a JPEG, PNG o WebP.`,
4016
4095
  imageSize: (maxSize) => `El archivo de imagen es demasiado grande. El tamaño máximo permitido es ${maxSize} MB.`
4096
+ },
4097
+ autoSaveRestore: {
4098
+ found: "Borrador encontrado. ¿Restaurar?",
4099
+ foundAt: "Borrador del {date}. ¿Restaurar?",
4100
+ restore: "Restaurar",
4101
+ discard: "Descartar"
4017
4102
  }
4018
4103
  },
4019
4104
  ko: {
@@ -4352,6 +4437,12 @@ var locales = {
4352
4437
  errors: {
4353
4438
  imageFormat: (type) => `"${type}" 형식은 웹 브라우저에서 지원되지 않습니다. JPEG, PNG 또는 WebP로 변환해 주세요.`,
4354
4439
  imageSize: (maxSize) => `이미지 파일이 너무 큽니다. 최대 허용 크기는 ${maxSize} MB입니다.`
4440
+ },
4441
+ autoSaveRestore: {
4442
+ found: "초안을 찾았습니다. 복원하시겠습니까?",
4443
+ foundAt: "{date}의 초안을 찾았습니다. 복원하시겠습니까?",
4444
+ restore: "복원",
4445
+ discard: "삭제"
4355
4446
  }
4356
4447
  }
4357
4448
  };
@@ -6977,6 +7068,15 @@ var Clipboard = class {
6977
7068
  if (!clipboardData) return;
6978
7069
  const forcePlain = this._forcePlain;
6979
7070
  this._forcePlain = false;
7071
+ const maxBytes = (this.options.maxPasteSize ?? 5) * 1024 * 1024;
7072
+ if (maxBytes > 0) {
7073
+ const text = clipboardData.getData("text/plain") || "";
7074
+ const html = clipboardData.getData("text/html") || "";
7075
+ if (Math.max(text.length, html.length) > maxBytes) {
7076
+ event.preventDefault();
7077
+ return;
7078
+ }
7079
+ }
6980
7080
  if (clipboardData.items) {
6981
7081
  const imageItems = Array.from(clipboardData.items).filter((item) => item.kind === "file" && item.type.startsWith("image/"));
6982
7082
  if (imageItems.length > 0) {
@@ -8099,6 +8199,7 @@ var ImageResizer = class {
8099
8199
  const aspectRatio = startW / (startH || 1);
8100
8200
  const isCorner = pos.length === 2;
8101
8201
  const editable = this.context.layoutInfo.editable;
8202
+ const minSz = this.context.options?.minImageSize ?? 20;
8102
8203
  let _raf = null;
8103
8204
  const onMove = (me) => {
8104
8205
  if (_raf !== null) return;
@@ -8111,15 +8212,15 @@ var ImageResizer = class {
8111
8212
  const maxW = editable.clientWidth || Infinity;
8112
8213
  let newW = startW;
8113
8214
  let newH = startH;
8114
- if (pos.includes("e")) newW = Math.max(20, startW + dx);
8115
- if (pos.includes("w")) newW = Math.max(20, startW - dx);
8116
- if (pos.includes("s")) newH = Math.max(20, startH + dy);
8117
- if (pos.includes("n")) newH = Math.max(20, startH - dy);
8215
+ if (pos.includes("e")) newW = Math.max(minSz, startW + dx);
8216
+ if (pos.includes("w")) newW = Math.max(minSz, startW - dx);
8217
+ if (pos.includes("s")) newH = Math.max(minSz, startH + dy);
8218
+ if (pos.includes("n")) newH = Math.max(minSz, startH - dy);
8118
8219
  newW = Math.min(newW, maxW);
8119
- if (isCorner) if (Math.abs(dx) >= Math.abs(dy)) newH = Math.max(20, Math.round(newW / aspectRatio));
8220
+ if (isCorner) if (Math.abs(dx) >= Math.abs(dy)) newH = Math.max(minSz, Math.round(newW / aspectRatio));
8120
8221
  else {
8121
- newW = Math.min(Math.max(20, Math.round(newH * aspectRatio)), maxW);
8122
- newH = Math.max(20, Math.round(newW / aspectRatio));
8222
+ newW = Math.min(Math.max(minSz, Math.round(newH * aspectRatio)), maxW);
8223
+ newH = Math.max(minSz, Math.round(newW / aspectRatio));
8123
8224
  }
8124
8225
  img.style.width = `${newW}px`;
8125
8226
  img.style.height = `${newH}px`;
@@ -14562,6 +14663,7 @@ var FindReplace = class extends BaseDialog {
14562
14663
  this._currentIndex = -1;
14563
14664
  this._caseSensitive = false;
14564
14665
  this._useRegex = false;
14666
+ this._wholeWord = false;
14565
14667
  /** @type {'find'|'replace'} */
14566
14668
  this._mode = "find";
14567
14669
  /** Cached compiled regex — reused when query and case-sensitivity are unchanged */
@@ -14569,6 +14671,7 @@ var FindReplace = class extends BaseDialog {
14569
14671
  this._lastQuery = null;
14570
14672
  this._lastCaseSensitive = null;
14571
14673
  this._lastUseRegex = null;
14674
+ this._lastWholeWord = null;
14572
14675
  this._focusTimer = null;
14573
14676
  }
14574
14677
  destroy() {
@@ -14679,6 +14782,13 @@ var FindReplace = class extends BaseDialog {
14679
14782
  "aria-label": L.useRegex
14680
14783
  });
14681
14784
  regexBtn.textContent = ".*";
14785
+ const wholeWordBtn = createElement("button", {
14786
+ type: "button",
14787
+ class: "an-fr-icon-btn",
14788
+ title: L.wholeWord,
14789
+ "aria-label": L.wholeWord
14790
+ });
14791
+ wholeWordBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="7" width="18" height="10" rx="2"/><line x1="7" y1="21" x2="7" y2="17"/><line x1="17" y1="21" x2="17" y2="17"/></svg>`;
14682
14792
  const prevBtn = createElement("button", {
14683
14793
  type: "button",
14684
14794
  class: "an-fr-icon-btn",
@@ -14695,7 +14805,7 @@ var FindReplace = class extends BaseDialog {
14695
14805
  nextBtn.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>`;
14696
14806
  const counter = createElement("span", { class: "an-fr-counter" });
14697
14807
  this._counterEl = counter;
14698
- searchBar.append(findInput, caseCheckbox, caseBtn, regexBtn, prevBtn, nextBtn, counter);
14808
+ searchBar.append(findInput, caseCheckbox, caseBtn, regexBtn, wholeWordBtn, prevBtn, nextBtn, counter);
14699
14809
  box.appendChild(searchBar);
14700
14810
  const replaceRow = createElement("div", { class: "an-fr-replace-row" });
14701
14811
  replaceRow.style.display = "none";
@@ -14763,7 +14873,14 @@ var FindReplace = class extends BaseDialog {
14763
14873
  this._lastQuery = null;
14764
14874
  this._onSearch();
14765
14875
  });
14766
- this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, dRegex);
14876
+ const dWholeWord = on(wholeWordBtn, "click", () => {
14877
+ this._wholeWord = !this._wholeWord;
14878
+ wholeWordBtn.classList.toggle("an-fr-icon-btn--active", this._wholeWord);
14879
+ this._queryRegex = null;
14880
+ this._lastQuery = null;
14881
+ this._onSearch();
14882
+ });
14883
+ this._disposers.push(d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, dRegex, dWholeWord);
14767
14884
  return overlay;
14768
14885
  }
14769
14886
  _onSearch() {
@@ -14821,10 +14938,11 @@ var FindReplace = class extends BaseDialog {
14821
14938
  */
14822
14939
  _findRawMatches(query, root) {
14823
14940
  const results = [];
14824
- if (this._lastQuery !== query || this._lastCaseSensitive !== this._caseSensitive || this._lastUseRegex !== this._useRegex) {
14941
+ if (this._lastQuery !== query || this._lastCaseSensitive !== this._caseSensitive || this._lastUseRegex !== this._useRegex || this._lastWholeWord !== this._wholeWord) {
14825
14942
  const flags = this._caseSensitive ? "g" : "gi";
14826
14943
  try {
14827
- const pattern = this._useRegex ? query : query.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
14944
+ let pattern = this._useRegex ? query : query.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
14945
+ if (this._wholeWord) pattern = `\\b${pattern}\\b`;
14828
14946
  this._queryRegex = new RegExp(pattern, flags);
14829
14947
  } catch (_) {
14830
14948
  this._queryRegex = null;
@@ -14832,6 +14950,7 @@ var FindReplace = class extends BaseDialog {
14832
14950
  this._lastQuery = query;
14833
14951
  this._lastCaseSensitive = this._caseSensitive;
14834
14952
  this._lastUseRegex = this._useRegex;
14953
+ this._lastWholeWord = this._wholeWord;
14835
14954
  }
14836
14955
  if (!this._queryRegex) return results;
14837
14956
  const re = this._queryRegex;
@@ -16378,7 +16497,10 @@ var Mention = class {
16378
16497
  this._showDropdown();
16379
16498
  };
16380
16499
  const result = this._cfg.onSearch(this._query, cb);
16381
- if (result && typeof result.then === "function") result.then(cb).catch(() => this._hideDropdown());
16500
+ if (result && typeof result.then === "function") result.then(cb).catch((err) => {
16501
+ this._hideDropdown();
16502
+ if (typeof this._cfg.onError === "function") this._cfg.onError(err);
16503
+ });
16382
16504
  }, this._cfg.debounce);
16383
16505
  }
16384
16506
  _onKeydown(e) {
@@ -16646,10 +16768,13 @@ var Context = class {
16646
16768
  }
16647
16769
  /**
16648
16770
  * Returns the current HTML content of the editor.
16771
+ * Zero-width spaces (U+200B) inserted by inline editing helpers are stripped
16772
+ * from the output so they don't leak into the consumer's HTML.
16649
16773
  * @returns {string}
16650
16774
  */
16651
16775
  getHTML() {
16652
- return this.invoke("editor.getHTML");
16776
+ const html = this.invoke("editor.getHTML");
16777
+ return typeof html === "string" ? html.replace(/​/g, "") : html;
16653
16778
  }
16654
16779
  /**
16655
16780
  * Sets the HTML content of the editor.
@@ -16820,6 +16945,25 @@ var Context = class {
16820
16945
  }));
16821
16946
  }
16822
16947
  /**
16948
+ * Moves focus into the editable area.
16949
+ */
16950
+ focus() {
16951
+ this.layoutInfo.editable.focus();
16952
+ }
16953
+ /**
16954
+ * Removes focus from the editable area.
16955
+ */
16956
+ blur() {
16957
+ this.layoutInfo.editable.blur();
16958
+ }
16959
+ /**
16960
+ * Returns true when the editor is currently in fullscreen mode.
16961
+ * @returns {boolean}
16962
+ */
16963
+ isFullscreen() {
16964
+ return this.invoke("fullscreen.isActive") === true;
16965
+ }
16966
+ /**
16823
16967
  * Sets whether the editor is disabled (readonly).
16824
16968
  * @param {boolean} disabled
16825
16969
  */
@@ -17115,8 +17259,10 @@ var AutumnNote = {
17115
17259
  registerButton(btnDef);
17116
17260
  return this;
17117
17261
  },
17262
+ /** All pre-built button definitions — accessible in every module format including UMD/CJS. */
17263
+ buttons,
17118
17264
  /** Library version */
17119
- version: "1.7.0"
17265
+ version: "1.8.0"
17120
17266
  };
17121
17267
  /**
17122
17268
  * @param {string|Element|NodeList|Element[]} selector
@@ -17129,6 +17275,6 @@ function resolveElements(selector) {
17129
17275
  return [];
17130
17276
  }
17131
17277
  //#endregion
17132
- export { Context, ELEMENT_NODE, TEXT_NODE, WrappedRange, _buttonRegistry, alignCenterBtn, alignJustifyBtn, alignLeftBtn, alignRightBtn, all, ancestors, any, backColorBtn, boldBtn, checklistBtn, children, chunk, clamp, closest, closestPara, codeviewBtn, collapsedRange, compose, createElement, currentRange, debounce, AutumnNote as default, defaultOptions, defaultToolbar, directionBtn, emojiBtn, env, findBtn, findReplaceBtn, first, flatten, fontFamilyBtn, fontSizeBtn, foreColorBtn, fromNativeRange, fullscreenBtn, getButton, groupBy, hrBtn, iconBtn, identity, imageBtn, indentBtn, initial, inlineCodeBtn, insertAfter, isAnchor, isEditable, isElement, isEmpty, isFunction, isImage, isInline, isInsideEditable, isKey, isLi, isList, isModifier, isNil, isPara, isPlainObject, isSelectionInside, isString, isTable, isText, isVoid, italicBtn, key, last, lineHeightBtn, linkBtn, locales, makeDraggable, mergeDeep, nextElement, nodeValue, olBtn, on, outdentBtn, outerHtml, paragraphStyleBtn, placeCaret, prevElement, printBtn, rangeFromElement, rect2bnd, redoBtn, registerButton, remove, removeFormatBtn, resolveLocale, sanitiseHTML, sanitiseUrl, shortcutsBtn, splitText, strikeBtn, subscriptBtn, superscriptBtn, tableBtn, tail, throttle, trapFocus, ulBtn, underlineBtn, undoBtn, unique, unwrap, videoBtn, withSavedRange, wrap };
17278
+ export { Context, ELEMENT_NODE, TEXT_NODE, WrappedRange, _buttonRegistry, alignCenterBtn, alignJustifyBtn, alignLeftBtn, alignRightBtn, all, ancestors, any, backColorBtn, boldBtn, buttons, checklistBtn, children, chunk, clamp, closest, closestPara, codeviewBtn, collapsedRange, compose, createElement, currentRange, debounce, AutumnNote as default, defaultOptions, defaultToolbar, directionBtn, emojiBtn, env, findBtn, findReplaceBtn, first, flatten, fontFamilyBtn, fontSizeBtn, foreColorBtn, fromNativeRange, fullscreenBtn, getButton, groupBy, hrBtn, iconBtn, identity, imageBtn, indentBtn, initial, inlineCodeBtn, insertAfter, isAnchor, isEditable, isElement, isEmpty, isFunction, isImage, isInline, isInsideEditable, isKey, isLi, isList, isModifier, isNil, isPara, isPlainObject, isSelectionInside, isString, isTable, isText, isVoid, italicBtn, key, last, lineHeightBtn, linkBtn, locales, makeDraggable, mergeDeep, nextElement, nodeValue, olBtn, on, outdentBtn, outerHtml, paragraphStyleBtn, placeCaret, prevElement, printBtn, rangeFromElement, rect2bnd, redoBtn, registerButton, remove, removeFormatBtn, resolveLocale, sanitiseHTML, sanitiseUrl, shortcutsBtn, splitText, strikeBtn, subscriptBtn, superscriptBtn, tableBtn, tail, throttle, trapFocus, ulBtn, underlineBtn, undoBtn, unique, unwrap, videoBtn, withSavedRange, wrap };
17133
17279
 
17134
17280
  //# sourceMappingURL=autumnnote.es.js.map