@threadlabs/looma 0.16.3 → 0.16.5
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 +20 -1
- package/package.json +1 -1
- package/vue/components.css +1 -1
- package/vue/editor/index.js +14 -3
|
@@ -8631,6 +8631,13 @@ function parseHtmlSlice(schema, value) {
|
|
|
8631
8631
|
const parsed = new globalThis.DOMParser().parseFromString(value, "text/html");
|
|
8632
8632
|
if (parsed.body.style.display === "none") return Slice.empty;
|
|
8633
8633
|
for (const element of parsed.body.querySelectorAll("[style]")) if (element.style.display === "none") element.remove();
|
|
8634
|
+
for (const wrapper of parsed.body.querySelectorAll("div")) for (const child of wrapper.children) {
|
|
8635
|
+
const next = child.nextSibling;
|
|
8636
|
+
if (child.localName !== "span" || next?.nodeType !== 1 || next.localName !== "span") continue;
|
|
8637
|
+
if (!child.textContent?.trim() || !next.textContent?.trim()) continue;
|
|
8638
|
+
if (/\s$/.test(child.textContent) || /^\s/.test(next.textContent)) continue;
|
|
8639
|
+
wrapper.insertBefore(parsed.createTextNode(" "), next);
|
|
8640
|
+
}
|
|
8634
8641
|
const container = document.createElement("div");
|
|
8635
8642
|
container.append(purify.sanitize(parsed.body.innerHTML, {
|
|
8636
8643
|
USE_PROFILES: { html: true },
|
|
@@ -8648,8 +8655,20 @@ function parseHtmlSlice(schema, value) {
|
|
|
8648
8655
|
if (!container.textContent?.trim() && !container.querySelector("img, hr")) return Slice.empty;
|
|
8649
8656
|
return DOMParser.fromSchema(schema).parseSlice(container, { preserveWhitespace: false });
|
|
8650
8657
|
}
|
|
8658
|
+
function markdownFrontmatter(value) {
|
|
8659
|
+
const match = /^---[ \t]*\r?\n([\s\S]*?)\r?\n(?:---|\.\.\.)[ \t]*(?:\r?\n|$)/.exec(value.slice(0, 8192));
|
|
8660
|
+
if (!match || !/^[A-Za-z][\w-]*:[ \t]*\S/m.test(match[1])) return null;
|
|
8661
|
+
return {
|
|
8662
|
+
source: match[0].trimEnd(),
|
|
8663
|
+
body: value.slice(match[0].length)
|
|
8664
|
+
};
|
|
8665
|
+
}
|
|
8666
|
+
function escapeHtmlText(value) {
|
|
8667
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
8668
|
+
}
|
|
8651
8669
|
function documentSlice(schema, plainText) {
|
|
8652
|
-
|
|
8670
|
+
const frontmatter = markdownFrontmatter(plainText);
|
|
8671
|
+
if (frontmatter || looksLikeMarkdown(plainText)) return parseHtmlSlice(schema, frontmatter ? `<pre><code class="language-yaml">${escapeHtmlText(frontmatter.source)}</code></pre>${markdown.render(frontmatter.body)}` : markdown.render(plainText));
|
|
8653
8672
|
if (looksLikeDocumentHtml(plainText)) return parseHtmlSlice(schema, plainText);
|
|
8654
8673
|
return null;
|
|
8655
8674
|
}
|
package/package.json
CHANGED
package/vue/components.css
CHANGED
|
@@ -8929,7 +8929,7 @@ html[data-ui-input-modality="touch"]
|
|
|
8929
8929
|
.ProseMirror table {
|
|
8930
8930
|
border-collapse: collapse;
|
|
8931
8931
|
margin: 0;
|
|
8932
|
-
width:
|
|
8932
|
+
width: 100% !important;
|
|
8933
8933
|
min-width: 100%;
|
|
8934
8934
|
max-width: none !important;
|
|
8935
8935
|
table-layout: fixed;
|
package/vue/editor/index.js
CHANGED
|
@@ -495,6 +495,7 @@ var LoomaEditor = defineComponent({
|
|
|
495
495
|
});
|
|
496
496
|
const imageDelivery = createLoomaImageDeliveryController({ resolveAttributes: () => props.resolveImageAttributes });
|
|
497
497
|
let lastFocusedSelection = null;
|
|
498
|
+
let linkPressedSelection = null;
|
|
498
499
|
const rememberSelection = (instance) => {
|
|
499
500
|
if (!instance.isFocused) return;
|
|
500
501
|
const selection = instance.view.state.selection;
|
|
@@ -541,8 +542,10 @@ var LoomaEditor = defineComponent({
|
|
|
541
542
|
if (!instance || !props.editable) return;
|
|
542
543
|
const current = instance.state.selection;
|
|
543
544
|
const preserved = lastFocusedSelection?.text && lastFocusedSelection.from !== lastFocusedSelection.to ? lastFocusedSelection : null;
|
|
544
|
-
const
|
|
545
|
-
|
|
545
|
+
const selection = linkPressedSelection ?? (current.empty ? preserved : null);
|
|
546
|
+
linkPressedSelection = null;
|
|
547
|
+
const from = selection?.from ?? current.from;
|
|
548
|
+
const to = selection?.to ?? current.to;
|
|
546
549
|
const empty = from === to;
|
|
547
550
|
const existing = instance.isActive("link");
|
|
548
551
|
linkSelection = {
|
|
@@ -1084,6 +1087,13 @@ var LoomaEditor = defineComponent({
|
|
|
1084
1087
|
"data-active": instance.isActive("link") ? "true" : "false",
|
|
1085
1088
|
onPointerenter: () => showTool(linkAnchorId, "Link", false),
|
|
1086
1089
|
onPointerleave: hideTool,
|
|
1090
|
+
onPointerdown: () => {
|
|
1091
|
+
const selection = instance.state.selection;
|
|
1092
|
+
linkPressedSelection = selection.empty ? null : {
|
|
1093
|
+
from: selection.from,
|
|
1094
|
+
to: selection.to
|
|
1095
|
+
};
|
|
1096
|
+
},
|
|
1087
1097
|
onFocusin: () => showTool(linkAnchorId, "Link", true),
|
|
1088
1098
|
onFocusout: hideTool
|
|
1089
1099
|
}, () => loomaIcon("link")),
|
|
@@ -1282,7 +1292,7 @@ var LoomaEditor = defineComponent({
|
|
|
1282
1292
|
class: "looma-editor__chip-popover",
|
|
1283
1293
|
open: chipOpen.value,
|
|
1284
1294
|
for: chipAnchorId,
|
|
1285
|
-
placement:
|
|
1295
|
+
placement: "bottom-start",
|
|
1286
1296
|
onClose: () => {
|
|
1287
1297
|
chipOpen.value = false;
|
|
1288
1298
|
}
|
|
@@ -1334,6 +1344,7 @@ var LoomaEditor = defineComponent({
|
|
|
1334
1344
|
onOpen: openLinkEditor,
|
|
1335
1345
|
onClose: () => {
|
|
1336
1346
|
linkOpen.value = false;
|
|
1347
|
+
linkPressedSelection = null;
|
|
1337
1348
|
}
|
|
1338
1349
|
}, () => h("form", {
|
|
1339
1350
|
class: "looma-editor__link-form",
|