@threadlabs/looma 0.28.15 → 0.28.17
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/editor/chunks/extensions.js +897 -112
- package/editor/extensions/callout.d.ts +2 -9
- package/editor/extensions/chip.d.ts +3 -2
- package/editor/extensions/figure.d.ts +12 -0
- package/editor/extensions/index.d.ts +2 -0
- package/editor/extensions/index.js +2 -2
- package/editor/extensions/markdown.d.ts +8 -10
- package/editor/extensions/table-of-contents.d.ts +1 -1
- package/editor/extensions/tabs.d.ts +13 -0
- package/editor/index.js +2 -2
- package/markdown/fixtures.d.ts +27 -0
- package/markdown/fixtures.js +224 -0
- package/markdown/index.d.ts +109 -0
- package/markdown/index.js +232 -0
- package/markdown/markdown-it.d.ts +13 -0
- package/markdown/markdown-it.js +397 -0
- package/package.json +17 -1
- package/vue/editor/index.js +61 -19
package/vue/editor/index.js
CHANGED
|
@@ -1840,6 +1840,34 @@ function formatEditorShortcut(keys, apple) {
|
|
|
1840
1840
|
].filter(Boolean).join("+");
|
|
1841
1841
|
}
|
|
1842
1842
|
var isApplePlatform = () => typeof navigator !== "undefined" && /mac|iphone|ipad|ipod/i.test(navigator.userAgentData?.platform || navigator.platform || navigator.userAgent);
|
|
1843
|
+
/**
|
|
1844
|
+
* The anchor a heading's text derives: NFC, lowercase, keeping letters, numbers and combining
|
|
1845
|
+
* marks, with every other run of characters one hyphen.
|
|
1846
|
+
* @failure Text with no letters or numbers, such as only emoji, derives `heading`.
|
|
1847
|
+
*/
|
|
1848
|
+
function loomaHeadingSlug(text) {
|
|
1849
|
+
return text.normalize("NFC").toLowerCase().replace(/[^\p{L}\p{N}\p{M}]+/gu, "-").replace(/^-+|-+$/g, "") || "heading";
|
|
1850
|
+
}
|
|
1851
|
+
/**
|
|
1852
|
+
* Gives every heading of a document its anchor, in document order.
|
|
1853
|
+
* @contract A custom ID is kept unless an earlier heading already has it. Any other heading takes
|
|
1854
|
+
* its slug, or the slug's first free suffix (`-1`, `-2`…), never one a later custom ID reserves.
|
|
1855
|
+
*/
|
|
1856
|
+
function assignLoomaHeadingIds(headings) {
|
|
1857
|
+
const reserved = new Set(headings.map(({ id }) => id).filter((id) => Boolean(id)));
|
|
1858
|
+
const used = /* @__PURE__ */ new Set();
|
|
1859
|
+
return headings.map(({ text, id: custom }) => {
|
|
1860
|
+
let id = custom || loomaHeadingSlug(text);
|
|
1861
|
+
if (custom ? used.has(id) : used.has(id) || reserved.has(id)) {
|
|
1862
|
+
const stem = id;
|
|
1863
|
+
let suffix = 1;
|
|
1864
|
+
while (used.has(`${stem}-${suffix}`) || reserved.has(`${stem}-${suffix}`)) suffix++;
|
|
1865
|
+
id = `${stem}-${suffix}`;
|
|
1866
|
+
}
|
|
1867
|
+
used.add(id);
|
|
1868
|
+
return id;
|
|
1869
|
+
});
|
|
1870
|
+
}
|
|
1843
1871
|
//#endregion
|
|
1844
1872
|
//#region src/editor/extensions/expand.ts
|
|
1845
1873
|
/**
|
|
@@ -2049,7 +2077,17 @@ function tableOfContentsTree(entries) {
|
|
|
2049
2077
|
}
|
|
2050
2078
|
return roots;
|
|
2051
2079
|
}
|
|
2052
|
-
|
|
2080
|
+
var derivedFrom = (id, text) => {
|
|
2081
|
+
const slug = loomaHeadingSlug(text);
|
|
2082
|
+
return id === slug || id.startsWith(`${slug}-`) && /^\d+$/.test(id.slice(slug.length + 1));
|
|
2083
|
+
};
|
|
2084
|
+
/**
|
|
2085
|
+
* Keeps heading anchors on Looma Markdown's rule. An anchor derived from its heading's text
|
|
2086
|
+
* (as it read before this change) follows the text; any other, including `looma-heading-N` anchors
|
|
2087
|
+
* saved before this rule, is a custom anchor and stays, so links to it keep working. With
|
|
2088
|
+
* a table of contents every heading gets an anchor; without one, only headings that have one.
|
|
2089
|
+
*/
|
|
2090
|
+
function anchorTransaction(state, previous) {
|
|
2053
2091
|
let hasToc = false;
|
|
2054
2092
|
const headings = [];
|
|
2055
2093
|
state.doc.descendants((node, position) => {
|
|
@@ -2059,24 +2097,28 @@ function anchorTransaction(state) {
|
|
|
2059
2097
|
position
|
|
2060
2098
|
});
|
|
2061
2099
|
});
|
|
2062
|
-
if (!
|
|
2063
|
-
const
|
|
2064
|
-
|
|
2100
|
+
if (!headings.length) return null;
|
|
2101
|
+
const before = /* @__PURE__ */ new Map();
|
|
2102
|
+
previous?.descendants((node) => {
|
|
2103
|
+
if (node.type.name === "heading" && typeof node.attrs.id === "string") before.set(node.attrs.id, node.textContent.trim());
|
|
2104
|
+
});
|
|
2105
|
+
const custom = (node) => {
|
|
2106
|
+
const id = node.attrs.id;
|
|
2107
|
+
if (typeof id !== "string" || !id || /\s/.test(id)) return void 0;
|
|
2108
|
+
return derivedFrom(id, before.get(id) ?? node.textContent.trim()) ? void 0 : id;
|
|
2109
|
+
};
|
|
2110
|
+
const ids = assignLoomaHeadingIds(headings.map(({ node }) => ({
|
|
2111
|
+
text: node.textContent.trim(),
|
|
2112
|
+
id: custom(node)
|
|
2113
|
+
})));
|
|
2065
2114
|
const transaction = state.tr;
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
transaction.setNodeMarkup(position, void 0, {
|
|
2074
|
-
...node.attrs,
|
|
2075
|
-
id
|
|
2076
|
-
});
|
|
2077
|
-
}
|
|
2078
|
-
used.add(id);
|
|
2079
|
-
}
|
|
2115
|
+
headings.forEach(({ node, position }, index) => {
|
|
2116
|
+
if (node.attrs.id === ids[index] || !hasToc && !node.attrs.id) return;
|
|
2117
|
+
transaction.setNodeMarkup(position, void 0, {
|
|
2118
|
+
...node.attrs,
|
|
2119
|
+
id: ids[index]
|
|
2120
|
+
});
|
|
2121
|
+
});
|
|
2080
2122
|
return transaction.docChanged ? transaction : null;
|
|
2081
2123
|
}
|
|
2082
2124
|
var LoomaHeadingAnchors = Extension.create({
|
|
@@ -2092,7 +2134,7 @@ var LoomaHeadingAnchors = Extension.create({
|
|
|
2092
2134
|
if (transaction) this.editor.view.dispatch(transaction.setMeta("addToHistory", false));
|
|
2093
2135
|
},
|
|
2094
2136
|
addProseMirrorPlugins() {
|
|
2095
|
-
return [new Plugin({ appendTransaction: (transactions,
|
|
2137
|
+
return [new Plugin({ appendTransaction: (transactions, oldState, state) => transactions.some((transaction) => transaction.docChanged) ? anchorTransaction(state, oldState.doc) : null })];
|
|
2096
2138
|
}
|
|
2097
2139
|
});
|
|
2098
2140
|
function contentsHtml(doc, config) {
|