autumnnote 1.4.1 → 1.5.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.
@@ -633,9 +633,16 @@
633
633
  if (selectedLis.length > 0) {
634
634
  let firstP = null;
635
635
  selectedLis.forEach((li) => {
636
- const text = Array.from(li.childNodes).filter((n) => !(n.nodeType === 1 && n.tagName === "INPUT")).map((n) => n.textContent).join("").replace(/\u00a0/g, " ").trim();
637
636
  const p = document.createElement("p");
638
- p.textContent = text || "\xA0";
637
+ for (const child of li.childNodes) {
638
+ if (child.nodeType === 1 && child.tagName === "INPUT") continue;
639
+ p.appendChild(child.cloneNode(true));
640
+ }
641
+ p.innerHTML = p.innerHTML.replace(/\u200b/g, "");
642
+ if (!p.hasChildNodes() || !p.textContent.trim()) {
643
+ p.innerHTML = "";
644
+ p.appendChild(document.createTextNode("\xA0"));
645
+ }
639
646
  ul.parentNode.insertBefore(p, ul);
640
647
  if (!firstP) firstP = p;
641
648
  ul.removeChild(li);
@@ -915,13 +922,6 @@
915
922
  }
916
923
  };
917
924
  var removeFormatBtn = btn("removeFormat", "remove-format", "Remove Format", () => execCommand("removeFormat"));
918
- btn("direction", "direction", "Toggle Text Direction (LTR / RTL)", (ctx) => {
919
- const editable = ctx.layoutInfo.editable;
920
- const next = (editable.getAttribute("dir") || "ltr") === "ltr" ? "rtl" : "ltr";
921
- editable.setAttribute("dir", next);
922
- editable.style.textAlign = next === "rtl" ? "right" : "left";
923
- ctx.invoke("editor.afterCommand");
924
- });
925
925
  /** @type {DropdownDef} */
926
926
  var fontFamilyBtn = {
927
927
  name: "fontFamily",
@@ -1041,7 +1041,6 @@
1041
1041
  var fullscreenBtn = btn("fullscreen", "expand", "Fullscreen", (ctx) => ctx.invoke("fullscreen.toggle"), (ctx) => ctx.invoke("fullscreen.isActive"));
1042
1042
  var shortcutsBtn = btn("shortcuts", "keyboard", "Keyboard Shortcuts (Ctrl+Shift+/)", (ctx) => ctx.invoke("shortcutsDialog.show"));
1043
1043
  var findBtn = btn("find", "search", "Find (Ctrl+F)", (ctx) => ctx.invoke("findReplace.show", "find"));
1044
- btn("findReplace", "find-replace", "Find & Replace (Ctrl+H)", (ctx) => ctx.invoke("findReplace.show", "replace"));
1045
1044
  var inlineCodeBtn = btn("inlineCode", "inline-code", "Inline Code (Ctrl+`)", (ctx) => ctx.invoke("editor.inlineCode"), () => isInlineCode());
1046
1045
  var checklistBtn = btn("checklist", "checklist", "Checklist", (ctx) => ctx.invoke("editor.toggleChecklist"), () => isInChecklist());
1047
1046
  var printBtn = btn("print", "print", "Print", (ctx) => ctx.invoke("editor.print"));
@@ -1288,6 +1287,7 @@
1288
1287
  chooseHighlightColor: "Choose highlight color",
1289
1288
  customColor: "Custom color",
1290
1289
  insertTableLabel: "Insert Table",
1290
+ /** Map of paragraph-style value → label (only values needing translation) */
1291
1291
  paragraphItems: {
1292
1292
  p: "Normal",
1293
1293
  blockquote: "Quote",
@@ -1330,6 +1330,7 @@
1330
1330
  widthPlaceholder: "560",
1331
1331
  insertBtn: "Insert",
1332
1332
  cancelBtn: "Cancel",
1333
+ /** @param {string} type */
1333
1334
  detected: (type) => `Detected: ${type}`,
1334
1335
  unknownFormat: "Unknown format — will try direct video embed",
1335
1336
  invalidUrl: "Invalid URL — please enter a valid video link."
@@ -1492,9 +1493,13 @@
1492
1493
  },
1493
1494
  statusbar: {
1494
1495
  resizeHandle: "Resize editor",
1496
+ /** @param {number} n */
1495
1497
  words: (n) => `Words: ${n}`,
1498
+ /** @param {number} n @param {number} max */
1496
1499
  wordsLimit: (n, max) => `Words: ${n}/${max}`,
1500
+ /** @param {number} n */
1497
1501
  chars: (n) => `Chars: ${n}`,
1502
+ /** @param {number} n @param {number} max */
1498
1503
  charsLimit: (n, max) => `Chars: ${n}/${max}`
1499
1504
  },
1500
1505
  tooltips: {
@@ -1567,7 +1572,9 @@
1567
1572
  }
1568
1573
  },
1569
1574
  errors: {
1575
+ /** @param {string} type */
1570
1576
  imageFormat: (type) => `Format "${type}" is not supported for display in web browsers. Please convert to JPEG, PNG, or WebP first.`,
1577
+ /** @param {number} maxSize */
1571
1578
  imageSize: (maxSize) => `Image file is too large. Maximum allowed size is ${maxSize} MB.`
1572
1579
  }
1573
1580
  };
@@ -4960,13 +4967,13 @@
4960
4967
  function _inline(text) {
4961
4968
  text = text.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_, alt, src) => `<img src="${_escAttr(src)}" alt="${_escAttr(alt)}" class="an-image">`);
4962
4969
  text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, href) => `<a href="${_escAttr(href)}">${_esc(label)}</a>`);
4963
- text = text.replace(/\*{3}(.+?)\*{3}/g, (_, c) => `<strong><em>${_esc(c)}</em></strong>`);
4964
- text = text.replace(/_{3}(.+?)_{3}/g, (_, c) => `<strong><em>${_esc(c)}</em></strong>`);
4965
- text = text.replace(/\*{2}(.+?)\*{2}/g, (_, c) => `<strong>${_esc(c)}</strong>`);
4966
- text = text.replace(/_{2}(.+?)_{2}/g, (_, c) => `<strong>${_esc(c)}</strong>`);
4970
+ text = text.replace(/\*{3}([^*\n]+?)\*{3}/g, (_, c) => `<strong><em>${_esc(c)}</em></strong>`);
4971
+ text = text.replace(/_{3}([^_\n]+?)_{3}/g, (_, c) => `<strong><em>${_esc(c)}</em></strong>`);
4972
+ text = text.replace(/\*{2}([^*\n]+?)\*{2}/g, (_, c) => `<strong>${_esc(c)}</strong>`);
4973
+ text = text.replace(/_{2}([^_\n]+?)_{2}/g, (_, c) => `<strong>${_esc(c)}</strong>`);
4967
4974
  text = text.replace(/\*([^*\n]+?)\*/g, (_, c) => `<em>${_esc(c)}</em>`);
4968
4975
  text = text.replace(/_([^_\n]+?)_/g, (_, c) => `<em>${_esc(c)}</em>`);
4969
- text = text.replace(/~~(.+?)~~/g, (_, c) => `<del>${_esc(c)}</del>`);
4976
+ text = text.replace(/~~([^\n]+?)~~/g, (_, c) => `<del>${_esc(c)}</del>`);
4970
4977
  text = text.replace(/`([^`]+)`/g, (_, c) => `<code>${_esc(c)}</code>`);
4971
4978
  return text;
4972
4979
  }
@@ -15954,6 +15961,13 @@
15954
15961
  /** @type {WeakMap<Element, Context>} */
15955
15962
  var instances = /* @__PURE__ */ new WeakMap();
15956
15963
  var AutumnNote = {
15964
+ /**
15965
+ * Creates (or returns existing) editor instance on one or more elements.
15966
+ *
15967
+ * @param {string|Element|NodeList|Element[]} selector
15968
+ * @param {import('./settings.js').AsnOptions} [options]
15969
+ * @returns {Context|Context[]} single Context or array of Contexts
15970
+ */
15957
15971
  create(selector, options = {}) {
15958
15972
  const ctxs = resolveElements(selector).map((el) => {
15959
15973
  if (instances.has(el)) return instances.get(el);
@@ -15964,6 +15978,10 @@
15964
15978
  });
15965
15979
  return ctxs.length === 1 ? ctxs[0] : ctxs;
15966
15980
  },
15981
+ /**
15982
+ * Destroys the editor(s) on the given selector.
15983
+ * @param {string|Element|NodeList|Element[]} selector
15984
+ */
15967
15985
  destroy(selector) {
15968
15986
  resolveElements(selector).forEach((el) => {
15969
15987
  const ctx = instances.get(el);
@@ -15973,23 +15991,45 @@
15973
15991
  }
15974
15992
  });
15975
15993
  },
15994
+ /**
15995
+ * Returns the Context instance for a given element (or null).
15996
+ * @param {string|Element} selector
15997
+ * @returns {Context|null}
15998
+ */
15976
15999
  getInstance(selector) {
15977
16000
  const el = typeof selector === "string" ? document.querySelector(selector) : selector;
15978
16001
  return el ? instances.get(el) || null : null;
15979
16002
  },
16003
+ /** Returns a shallow copy of the default options (read-only snapshot). */
15980
16004
  get defaults() {
15981
16005
  return { ...defaultOptions };
15982
16006
  },
16007
+ /** Merges properties into the global defaults, applied to all future instances. */
15983
16008
  setDefaults(overrides) {
15984
16009
  Object.assign(defaultOptions, overrides);
15985
16010
  },
16011
+ /** Restores global defaults to their original factory values. */
15986
16012
  resetDefaults() {
15987
16013
  Object.keys(defaultOptions).forEach((k) => delete defaultOptions[k]);
15988
16014
  Object.assign(defaultOptions, _originalDefaults);
15989
16015
  },
16016
+ /**
16017
+ * Registers a custom module to be included in every new editor instance.
16018
+ * @param {string} name - unique module key used for ctx.invoke() calls
16019
+ * @param {Function} ModuleClass - class with initialize() and optional destroy()
16020
+ */
15990
16021
  registerModule(name, ModuleClass) {
15991
16022
  _customModules.set(name, ModuleClass);
15992
16023
  },
16024
+ /**
16025
+ * Installs a plugin globally — applied to every future editor instance.
16026
+ * Plugin `buttons` are registered to the global button registry immediately
16027
+ * so they are available when Toolbar initialises inside create().
16028
+ * Plugin `install()` is called after all built-in modules have initialised.
16029
+ * @param {object} plugin - { name, version?, buttons?, install?, uninstall? }
16030
+ * @param {object} [options] - Forwarded to plugin.install(context, options)
16031
+ * @returns {typeof AutumnNote}
16032
+ */
15993
16033
  use(plugin, options = {}) {
15994
16034
  if (!plugin || typeof plugin.name !== "string") throw new TypeError("[AutumnNote] AutumnNote.use: plugin must have a string `name` property.");
15995
16035
  if (_globalPlugins.has(plugin.name)) {
@@ -16003,14 +16043,26 @@
16003
16043
  });
16004
16044
  return this;
16005
16045
  },
16046
+ /**
16047
+ * Returns true if a plugin with the given name has been registered globally.
16048
+ * @param {string} name
16049
+ * @returns {boolean}
16050
+ */
16006
16051
  hasPlugin(name) {
16007
16052
  return _globalPlugins.has(name);
16008
16053
  },
16054
+ /**
16055
+ * Registers a single button definition in the global button registry.
16056
+ * After create(), call ctx.invoke('toolbar.rebuild') to render new buttons.
16057
+ * @param {object} btnDef - ButtonDef-compatible object with a `name` string
16058
+ * @returns {typeof AutumnNote}
16059
+ */
16009
16060
  registerButton(btnDef) {
16010
16061
  registerButton(btnDef);
16011
16062
  return this;
16012
16063
  },
16013
- version: "1.4.1"
16064
+ /** Library version */
16065
+ version: "1.5.0"
16014
16066
  };
16015
16067
  /**
16016
16068
  * @param {string|Element|NodeList|Element[]} selector