autumnnote 1.8.3 → 1.9.1
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/dist/autumnnote.es.js +107 -26
- package/dist/autumnnote.es.js.map +1 -1
- package/dist/autumnnote.umd.js +115 -26
- package/dist/autumnnote.umd.js.map +1 -1
- package/package.json +1 -2
- package/src/js/core/markdown.js +85 -35
- package/src/js/index.js +1 -1
- package/src/js/module/Clipboard.js +25 -0
- package/types/index.d.ts +1 -1
package/dist/autumnnote.es.js
CHANGED
|
@@ -5596,7 +5596,7 @@ function _domToMd(node, depth = 0) {
|
|
|
5596
5596
|
* @returns {boolean} `true` if any Markdown-like pattern is present, `false` otherwise.
|
|
5597
5597
|
*/
|
|
5598
5598
|
function isMarkdown(text) {
|
|
5599
|
-
return /^#{1,6} [^\s]|^[ \t]*[-*+] [^\s]|^[ \t]*\d+\. [^\s]|^> [^\s]|^```|^\*{2}[^*\n]+\*{2}/m.test(text);
|
|
5599
|
+
return /^#{1,6} [^\s]|^[ \t]*[-*+] [^\s]|^[ \t]*\d+\. [^\s]|^> [^\s]|^```|^\*{2}[^*\n]+\*{2}/m.test(text) || /^.+\n=+\s*$/m.test(text) || /^.+\n-{2,}\s*$/m.test(text);
|
|
5600
5600
|
}
|
|
5601
5601
|
/**
|
|
5602
5602
|
* Converts a Markdown string to an HTML string.
|
|
@@ -5623,6 +5623,18 @@ function markdownToHTML(text) {
|
|
|
5623
5623
|
i++;
|
|
5624
5624
|
continue;
|
|
5625
5625
|
}
|
|
5626
|
+
if (line.trim() && !/^(-{3,}|\*{3,}|_{3,})\s*$/.test(line) && !/^#{1,6} /.test(line) && i + 1 < lines.length) {
|
|
5627
|
+
if (/^=+\s*$/.test(lines[i + 1])) {
|
|
5628
|
+
out.push(`<h1>${_inline(line.trim())}</h1>`);
|
|
5629
|
+
i += 2;
|
|
5630
|
+
continue;
|
|
5631
|
+
}
|
|
5632
|
+
if (/^-{2,}\s*$/.test(lines[i + 1])) {
|
|
5633
|
+
out.push(`<h2>${_inline(line.trim())}</h2>`);
|
|
5634
|
+
i += 2;
|
|
5635
|
+
continue;
|
|
5636
|
+
}
|
|
5637
|
+
}
|
|
5626
5638
|
if (/^(-{3,}|\*{3,}|_{3,})\s*$/.test(line)) {
|
|
5627
5639
|
out.push("<hr>");
|
|
5628
5640
|
i++;
|
|
@@ -5645,30 +5657,15 @@ function markdownToHTML(text) {
|
|
|
5645
5657
|
continue;
|
|
5646
5658
|
}
|
|
5647
5659
|
if (/^[-*+] /.test(line)) {
|
|
5648
|
-
const
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
while (i < lines.length && /^[-*+] /.test(lines[i])) {
|
|
5652
|
-
if (/^[-*+]\s+\[[ xX]\]\s+/.test(lines[i]) !== isChecklist) break;
|
|
5653
|
-
const content = lines[i].slice(2);
|
|
5654
|
-
if (isChecklist) {
|
|
5655
|
-
const cbMatch = /^\[([ xX])\][ \t]+/.exec(content);
|
|
5656
|
-
const cbHtml = `<input type="checkbox" contenteditable="false"${cbMatch?.[1]?.toLowerCase() === "x" ? " checked" : ""}>`;
|
|
5657
|
-
const textContent = cbMatch ? content.slice(cbMatch[0].length) : content;
|
|
5658
|
-
items.push(`<li>${cbHtml}${_inline(textContent)}</li>`);
|
|
5659
|
-
} else items.push(`<li>${_inline(content)}</li>`);
|
|
5660
|
-
i++;
|
|
5661
|
-
}
|
|
5662
|
-
out.push(`<${listTag}>${items.join("")}</${listTag.split(" ")[0]}>`);
|
|
5660
|
+
const { html: listHtml, endIdx } = _parseListBlock(lines, i);
|
|
5661
|
+
out.push(listHtml);
|
|
5662
|
+
i = endIdx;
|
|
5663
5663
|
continue;
|
|
5664
5664
|
}
|
|
5665
5665
|
if (/^\d+\. /.test(line)) {
|
|
5666
|
-
const
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
i++;
|
|
5670
|
-
}
|
|
5671
|
-
out.push(`<ol>${items.join("")}</ol>`);
|
|
5666
|
+
const { html: listHtml, endIdx } = _parseListBlock(lines, i);
|
|
5667
|
+
out.push(listHtml);
|
|
5668
|
+
i = endIdx;
|
|
5672
5669
|
continue;
|
|
5673
5670
|
}
|
|
5674
5671
|
if (line.trim() === "") {
|
|
@@ -5677,20 +5674,29 @@ function markdownToHTML(text) {
|
|
|
5677
5674
|
}
|
|
5678
5675
|
if (/^\|.+\|/.test(line) && i + 1 < lines.length && /^\|[\s|:-]+\|/.test(lines[i + 1])) {
|
|
5679
5676
|
const headerCells = _parseTableRow(line);
|
|
5677
|
+
const alignments = _parseTableRow(lines[i + 1]).map((c) => {
|
|
5678
|
+
if (c.startsWith(":") && c.endsWith(":")) return "center";
|
|
5679
|
+
if (c.endsWith(":")) return "right";
|
|
5680
|
+
if (c.startsWith(":")) return "left";
|
|
5681
|
+
return null;
|
|
5682
|
+
});
|
|
5680
5683
|
i += 2;
|
|
5681
5684
|
const bodyRows = [];
|
|
5682
5685
|
while (i < lines.length && /^\|.+\|/.test(lines[i])) {
|
|
5683
5686
|
bodyRows.push(_parseTableRow(lines[i]));
|
|
5684
5687
|
i++;
|
|
5685
5688
|
}
|
|
5686
|
-
const
|
|
5687
|
-
|
|
5689
|
+
const _cell = (tag, content, align) => {
|
|
5690
|
+
return `<${tag}${align ? ` style="text-align:${align}"` : ""}>${_inline(content)}</${tag}>`;
|
|
5691
|
+
};
|
|
5692
|
+
const thead = `<thead><tr>${headerCells.map((c, idx) => _cell("th", c, alignments[idx])).join("")}</tr></thead>`;
|
|
5693
|
+
const renderRow = (row) => `<tr>${row.map((c, idx) => _cell("td", c, alignments[idx])).join("")}</tr>`;
|
|
5688
5694
|
const tbody = bodyRows.length ? `<tbody>${bodyRows.map(renderRow).join("")}</tbody>` : "";
|
|
5689
5695
|
out.push(`<table>${thead}${tbody}</table>`);
|
|
5690
5696
|
continue;
|
|
5691
5697
|
}
|
|
5692
5698
|
const paraLines = [];
|
|
5693
|
-
while (i < lines.length && lines[i].trim() !== "" && !/^(#{1,6} |> |[-*+] |\d+\. |```|---\s*$|\*{3}\s*$|_{3}\s*$)/.test(lines[i]) && !/^\|.+\|/.test(lines[i])) {
|
|
5699
|
+
while (i < lines.length && lines[i].trim() !== "" && !/^(#{1,6} |> |[-*+] |\d+\. |```|---\s*$|\*{3}\s*$|_{3}\s*$)/.test(lines[i]) && !/^\|.+\|/.test(lines[i]) && !(i + 1 < lines.length && /^=+\s*$/.test(lines[i + 1])) && !(i + 1 < lines.length && /^-{2,}\s*$/.test(lines[i + 1]))) {
|
|
5694
5700
|
paraLines.push(lines[i]);
|
|
5695
5701
|
i++;
|
|
5696
5702
|
}
|
|
@@ -5707,6 +5713,57 @@ function markdownToHTML(text) {
|
|
|
5707
5713
|
function _parseTableRow(row) {
|
|
5708
5714
|
return row.replace(/^\|/, "").replace(/\|$/, "").split("|").map((c) => c.trim());
|
|
5709
5715
|
}
|
|
5716
|
+
function _parseListBlock(lines, startIdx) {
|
|
5717
|
+
const baseIndent = lines[startIdx].match(/^(\s*)/)[1].length;
|
|
5718
|
+
const isOL = /^\s*\d+\. /.test(lines[startIdx]);
|
|
5719
|
+
const items = [];
|
|
5720
|
+
let firstIsCB = null;
|
|
5721
|
+
let i = startIdx;
|
|
5722
|
+
while (i < lines.length) {
|
|
5723
|
+
const line = lines[i];
|
|
5724
|
+
if (line.trim() === "") break;
|
|
5725
|
+
const indent = line.match(/^(\s*)/)[1].length;
|
|
5726
|
+
if (indent < baseIndent) break;
|
|
5727
|
+
if (indent === baseIndent) {
|
|
5728
|
+
if (!/^\s*(?:[-*+]|\d+\.) /.test(line)) break;
|
|
5729
|
+
if (/^\s*\d+\. /.test(line) !== isOL) break;
|
|
5730
|
+
const raw = isOL ? line.replace(/^\s*\d+\. /, "") : line.replace(/^\s*[-*+] /, "");
|
|
5731
|
+
const isCB = !isOL && /^\[[ xX]\]\s+/.test(raw);
|
|
5732
|
+
if (firstIsCB === null) firstIsCB = isCB;
|
|
5733
|
+
if (isCB !== firstIsCB) break;
|
|
5734
|
+
const checked = isCB && raw[1].toLowerCase() === "x";
|
|
5735
|
+
const text = isCB ? raw.replace(/^\[[ xX]\]\s+/, "") : raw;
|
|
5736
|
+
items.push({
|
|
5737
|
+
text,
|
|
5738
|
+
isCB,
|
|
5739
|
+
checked,
|
|
5740
|
+
sub: ""
|
|
5741
|
+
});
|
|
5742
|
+
i++;
|
|
5743
|
+
} else {
|
|
5744
|
+
if (!items.length) {
|
|
5745
|
+
i++;
|
|
5746
|
+
continue;
|
|
5747
|
+
}
|
|
5748
|
+
if (/^\s*(?:[-*+]|\d+\.) /.test(line)) {
|
|
5749
|
+
const nested = _parseListBlock(lines, i);
|
|
5750
|
+
items[items.length - 1].sub += nested.html;
|
|
5751
|
+
i = nested.endIdx;
|
|
5752
|
+
} else {
|
|
5753
|
+
items[items.length - 1].text += " " + line.trim();
|
|
5754
|
+
i++;
|
|
5755
|
+
}
|
|
5756
|
+
}
|
|
5757
|
+
}
|
|
5758
|
+
const open = isOL ? "<ol>" : !isOL && firstIsCB === true ? "<ul class=\"an-checklist\">" : "<ul>";
|
|
5759
|
+
const close = isOL ? "</ol>" : "</ul>";
|
|
5760
|
+
return {
|
|
5761
|
+
html: `${open}${items.map(({ text, isCB, checked, sub }) => {
|
|
5762
|
+
return `<li>${isCB ? `<input type="checkbox" contenteditable="false"${checked ? " checked" : ""}>` : ""}${_inline(text)}${sub}</li>`;
|
|
5763
|
+
}).join("")}${close}`,
|
|
5764
|
+
endIdx: i
|
|
5765
|
+
};
|
|
5766
|
+
}
|
|
5710
5767
|
function _inline(text) {
|
|
5711
5768
|
text = text.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_, alt, src) => `<img src="${_escAttr(src)}" alt="${_escAttr(alt)}" class="an-image">`);
|
|
5712
5769
|
text = text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_, label, href) => `<a href="${_escAttr(href)}">${_esc(label)}</a>`);
|
|
@@ -7258,6 +7315,29 @@ var Clipboard = class {
|
|
|
7258
7315
|
return doc.body.innerHTML;
|
|
7259
7316
|
}
|
|
7260
7317
|
/**
|
|
7318
|
+
* Normalizes task lists from external sources (GitHub, GitLab, etc.) so they
|
|
7319
|
+
* pass the sanitiser's `ul.an-checklist` guard. Runs before sanitiseHTML().
|
|
7320
|
+
* @param {string} html
|
|
7321
|
+
* @returns {string}
|
|
7322
|
+
*/
|
|
7323
|
+
_normalizeExternalTaskLists(html) {
|
|
7324
|
+
const doc = new DOMParser().parseFromString(`<body>${html}</body>`, "text/html");
|
|
7325
|
+
for (const cb of doc.querySelectorAll("input[type=\"checkbox\"]")) {
|
|
7326
|
+
const li = cb.closest("li");
|
|
7327
|
+
const ul = li?.closest("ul");
|
|
7328
|
+
if (!li || !ul || ul.classList.contains("an-checklist")) continue;
|
|
7329
|
+
ul.classList.add("an-checklist");
|
|
7330
|
+
cb.removeAttribute("disabled");
|
|
7331
|
+
cb.setAttribute("contenteditable", "false");
|
|
7332
|
+
for (const attr of Array.from(cb.attributes)) if (![
|
|
7333
|
+
"type",
|
|
7334
|
+
"checked",
|
|
7335
|
+
"contenteditable"
|
|
7336
|
+
].includes(attr.name)) cb.removeAttribute(attr.name);
|
|
7337
|
+
}
|
|
7338
|
+
return doc.body.innerHTML;
|
|
7339
|
+
}
|
|
7340
|
+
/**
|
|
7261
7341
|
* Forces the next paste operation to strip all HTML formatting.
|
|
7262
7342
|
* Called by Editor when Ctrl+Shift+V is pressed.
|
|
7263
7343
|
* @param {boolean} val
|
|
@@ -7315,6 +7395,7 @@ var Clipboard = class {
|
|
|
7315
7395
|
let html = raw;
|
|
7316
7396
|
if (isWordContent) html = this._cleanWordHtml(html);
|
|
7317
7397
|
else if (isSocialContent) html = this._cleanSocialHtml(html);
|
|
7398
|
+
html = this._normalizeExternalTaskLists(html);
|
|
7318
7399
|
html = sanitiseHTML(html);
|
|
7319
7400
|
if (this.options.pasteStripAttributes) html = this._stripAttributes(html);
|
|
7320
7401
|
execCommand("insertHTML", html);
|
|
@@ -17500,7 +17581,7 @@ var AutumnNote = {
|
|
|
17500
17581
|
/** All pre-built button definitions — accessible in every module format including UMD/CJS. */
|
|
17501
17582
|
buttons,
|
|
17502
17583
|
/** Library version */
|
|
17503
|
-
version: "1.
|
|
17584
|
+
version: "1.9.1"
|
|
17504
17585
|
};
|
|
17505
17586
|
/**
|
|
17506
17587
|
* @param {string|Element|NodeList|Element[]} selector
|