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.
- package/README.md +96 -17
- package/dist/autumnnote.es.js +76 -8
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +68 -16
- package/dist/autumnnote.umd.js.map +1 -1
- package/package.json +8 -1
- package/src/js/core/markdown.js +5 -5
- package/src/js/editing/Style.js +9 -7
- package/src/js/index.js +1 -1
package/dist/autumnnote.umd.js
CHANGED
|
@@ -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
|
-
|
|
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}(
|
|
4964
|
-
text = text.replace(/_{3}(
|
|
4965
|
-
text = text.replace(/\*{2}(
|
|
4966
|
-
text = text.replace(/_{2}(
|
|
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(/~~(
|
|
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
|
|
16064
|
+
/** Library version */
|
|
16065
|
+
version: "1.5.0"
|
|
16014
16066
|
};
|
|
16015
16067
|
/**
|
|
16016
16068
|
* @param {string|Element|NodeList|Element[]} selector
|