@pixerate/editor 0.23.0 → 0.24.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 -1
- package/THIRD_PARTY_NOTICES.md +51 -0
- package/dist/agent/index.cjs +9 -8
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +4 -3
- package/dist/agent/index.d.ts +4 -3
- package/dist/agent/index.js +3 -2
- package/dist/agent/index.js.map +1 -1
- package/dist/canvas/index.cjs +1210 -17
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.d.cts +318 -1
- package/dist/canvas/index.d.ts +318 -1
- package/dist/canvas/index.js +1199 -6
- package/dist/canvas/index.js.map +1 -1
- package/dist/{chunk-QBJ22YZR.js → chunk-3CN2WD3X.js} +1354 -206
- package/dist/chunk-3CN2WD3X.js.map +1 -0
- package/dist/{chunk-JJDLPEWL.js → chunk-3LV6RRPH.js} +2 -2
- package/dist/{chunk-MJZBNWG7.js → chunk-5S3Z4PPF.js} +78 -557
- package/dist/chunk-5S3Z4PPF.js.map +1 -0
- package/dist/chunk-664LQYFJ.js +115 -0
- package/dist/chunk-664LQYFJ.js.map +1 -0
- package/dist/{chunk-AA4ZEVCC.cjs → chunk-D27YFC46.cjs} +101 -580
- package/dist/chunk-D27YFC46.cjs.map +1 -0
- package/dist/chunk-D6FH2YAX.cjs +131 -0
- package/dist/chunk-D6FH2YAX.cjs.map +1 -0
- package/dist/{chunk-4SUNJZWB.cjs → chunk-FD4LPFAE.cjs} +48 -200
- package/dist/chunk-FD4LPFAE.cjs.map +1 -0
- package/dist/chunk-FODNLX5N.js +749 -0
- package/dist/chunk-FODNLX5N.js.map +1 -0
- package/dist/{chunk-OYXSKQFR.js → chunk-FPENXAEJ.js} +35 -187
- package/dist/chunk-FPENXAEJ.js.map +1 -0
- package/dist/chunk-HLIMTC6N.js +1 -0
- package/dist/chunk-HLIMTC6N.js.map +1 -0
- package/dist/{chunk-QGHGJ56O.js → chunk-ITBSKI26.js} +1483 -19
- package/dist/chunk-ITBSKI26.js.map +1 -0
- package/dist/{chunk-XDMXXC4Z.cjs → chunk-MA2F5KHF.cjs} +350 -227
- package/dist/chunk-MA2F5KHF.cjs.map +1 -0
- package/dist/{chunk-RIKBJLS2.cjs → chunk-MCSJFWAO.cjs} +1356 -208
- package/dist/chunk-MCSJFWAO.cjs.map +1 -0
- package/dist/chunk-MKA3AHLV.cjs +256 -0
- package/dist/chunk-MKA3AHLV.cjs.map +1 -0
- package/dist/chunk-OLZJXL4R.cjs +749 -0
- package/dist/chunk-OLZJXL4R.cjs.map +1 -0
- package/dist/chunk-OXSV64JX.js +689 -0
- package/dist/chunk-OXSV64JX.js.map +1 -0
- package/dist/chunk-P3RQ5UJE.cjs +689 -0
- package/dist/chunk-P3RQ5UJE.cjs.map +1 -0
- package/dist/chunk-P6ODPZ4W.js +256 -0
- package/dist/chunk-P6ODPZ4W.js.map +1 -0
- package/dist/chunk-PGNZKFQS.js +685 -0
- package/dist/chunk-PGNZKFQS.js.map +1 -0
- package/dist/chunk-PL4JB3BF.cjs +1 -0
- package/dist/chunk-PL4JB3BF.cjs.map +1 -0
- package/dist/{chunk-GVSMRPHB.cjs → chunk-SBCZ6RN5.cjs} +1568 -104
- package/dist/chunk-SBCZ6RN5.cjs.map +1 -0
- package/dist/{chunk-CL37JGFW.cjs → chunk-SML64VJG.cjs} +4 -4
- package/dist/{chunk-CL37JGFW.cjs.map → chunk-SML64VJG.cjs.map} +1 -1
- package/dist/chunk-TNNJXF46.cjs +115 -0
- package/dist/chunk-TNNJXF46.cjs.map +1 -0
- package/dist/chunk-U5HZSFCS.js +131 -0
- package/dist/chunk-U5HZSFCS.js.map +1 -0
- package/dist/{chunk-K3R5NG2D.js → chunk-U5KWZU4X.js} +251 -128
- package/dist/chunk-U5KWZU4X.js.map +1 -0
- package/dist/chunk-XNORY7M6.cjs +685 -0
- package/dist/chunk-XNORY7M6.cjs.map +1 -0
- package/dist/commands/index.d.cts +5 -353
- package/dist/commands/index.d.ts +5 -353
- package/dist/comment-store-BEMgVlAA.d.cts +135 -0
- package/dist/comment-store-BEMgVlAA.d.ts +135 -0
- package/dist/compare/index.cjs +15 -0
- package/dist/compare/index.cjs.map +1 -0
- package/dist/compare/index.d.cts +58 -0
- package/dist/compare/index.d.ts +58 -0
- package/dist/compare/index.js +15 -0
- package/dist/compare/index.js.map +1 -0
- package/dist/{controller-pePCJLT1.d.cts → controller-BhLLAoi8.d.cts} +45 -4
- package/dist/{controller-pePCJLT1.d.ts → controller-BhLLAoi8.d.ts} +45 -4
- package/dist/documents-BQjzJNe2.d.ts +76 -0
- package/dist/documents-KRTPhvst.d.cts +76 -0
- package/dist/extensions/index.cjs +53 -5
- package/dist/extensions/index.cjs.map +1 -1
- package/dist/extensions/index.d.cts +7 -3
- package/dist/extensions/index.d.ts +7 -3
- package/dist/extensions/index.js +52 -4
- package/dist/generation/index.cjs +1373 -0
- package/dist/generation/index.cjs.map +1 -0
- package/dist/generation/index.d.cts +554 -0
- package/dist/generation/index.d.ts +554 -0
- package/dist/generation/index.js +1373 -0
- package/dist/generation/index.js.map +1 -0
- package/dist/grammar/index.cjs +48 -3
- package/dist/grammar/index.cjs.map +1 -1
- package/dist/grammar/index.d.cts +322 -100
- package/dist/grammar/index.d.ts +322 -100
- package/dist/grammar/index.js +54 -9
- package/dist/image-editor/index.cjs +1831 -30
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +590 -3
- package/dist/image-editor/index.d.ts +590 -3
- package/dist/image-editor/index.js +1807 -6
- package/dist/image-editor/index.js.map +1 -1
- package/dist/{index-CCr_z9kF.d.cts → index-BhJBSm2d.d.cts} +370 -4
- package/dist/{index-Ck6ajwXh.d.ts → index-fJrlkJCd.d.ts} +370 -4
- package/dist/index.cjs +162 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -8
- package/dist/index.d.ts +14 -8
- package/dist/index.js +174 -37
- package/dist/index.js.map +1 -1
- package/dist/migrate-iTlm3a8h.d.cts +112 -0
- package/dist/migrate-iTlm3a8h.d.ts +112 -0
- package/dist/persistence/index.cjs +676 -0
- package/dist/persistence/index.cjs.map +1 -0
- package/dist/persistence/index.d.cts +347 -0
- package/dist/persistence/index.d.ts +347 -0
- package/dist/persistence/index.js +676 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/{registry-D5-R90p0.d.cts → registry-BDe-vlv3.d.ts} +2 -40
- package/dist/registry-D32LpIc4.d.cts +354 -0
- package/dist/{registry-D5-R90p0.d.ts → registry-DnzpgY27.d.cts} +2 -40
- package/dist/registry-evKTP4ls.d.ts +354 -0
- package/dist/schema-DYDGdYL9.d.cts +41 -0
- package/dist/schema-DYDGdYL9.d.ts +41 -0
- package/dist/serializers/index.cjs +4 -3
- package/dist/serializers/index.cjs.map +1 -1
- package/dist/serializers/index.d.cts +2 -1
- package/dist/serializers/index.d.ts +2 -1
- package/dist/serializers/index.js +3 -2
- package/dist/sourcemap-C8AH3MBQ.d.cts +91 -0
- package/dist/sourcemap-DA1Evhrv.d.ts +91 -0
- package/dist/spreadsheet/index.cjs +37 -3
- package/dist/spreadsheet/index.cjs.map +1 -1
- package/dist/spreadsheet/index.d.cts +188 -17
- package/dist/spreadsheet/index.d.ts +188 -17
- package/dist/spreadsheet/index.js +43 -9
- package/dist/{tokens-CyLZmIei.d.cts → tokens-D7yXvUU6.d.cts} +15 -2
- package/dist/{tokens-CyLZmIei.d.ts → tokens-D7yXvUU6.d.ts} +15 -2
- package/dist/{track-changes-BSF58RK0.d.ts → track-changes-BK5sVf4_.d.cts} +18 -136
- package/dist/{track-changes-BSF58RK0.d.cts → track-changes-CDjCrwKe.d.ts} +18 -136
- package/package.json +16 -1
- package/dist/chunk-4SUNJZWB.cjs.map +0 -1
- package/dist/chunk-AA4ZEVCC.cjs.map +0 -1
- package/dist/chunk-AXV2ZW34.cjs +0 -118
- package/dist/chunk-AXV2ZW34.cjs.map +0 -1
- package/dist/chunk-B2ZRLN4S.js +0 -118
- package/dist/chunk-B2ZRLN4S.js.map +0 -1
- package/dist/chunk-GVSMRPHB.cjs.map +0 -1
- package/dist/chunk-K3R5NG2D.js.map +0 -1
- package/dist/chunk-MJZBNWG7.js.map +0 -1
- package/dist/chunk-OYXSKQFR.js.map +0 -1
- package/dist/chunk-QBJ22YZR.js.map +0 -1
- package/dist/chunk-QGHGJ56O.js.map +0 -1
- package/dist/chunk-RIKBJLS2.cjs.map +0 -1
- package/dist/chunk-XDMXXC4Z.cjs.map +0 -1
- /package/dist/{chunk-JJDLPEWL.js.map → chunk-3LV6RRPH.js.map} +0 -0
|
@@ -630,9 +630,11 @@ function getTrackedChanges(source) {
|
|
|
630
630
|
change.text += text;
|
|
631
631
|
return change;
|
|
632
632
|
};
|
|
633
|
+
const blockCounts = /* @__PURE__ */ new Map();
|
|
633
634
|
doc.descendants((node, pos) => {
|
|
634
635
|
const block = node.attrs?.[BLOCK_CHANGE_ATTRIBUTE];
|
|
635
636
|
if (block?.changeId && node.isTextblock) {
|
|
637
|
+
blockCounts.set(block.changeId, (blockCounts.get(block.changeId) ?? 0) + 1);
|
|
636
638
|
const change = add(
|
|
637
639
|
`block:${block.changeId}`,
|
|
638
640
|
"block",
|
|
@@ -642,7 +644,11 @@ function getTrackedChanges(source) {
|
|
|
642
644
|
node.textContent
|
|
643
645
|
);
|
|
644
646
|
if (!change.block) {
|
|
645
|
-
change.block = {
|
|
647
|
+
change.block = {
|
|
648
|
+
previous: block.previous,
|
|
649
|
+
current: blockSnapshot(doc, pos),
|
|
650
|
+
...block.operation ? { operation: block.operation } : {}
|
|
651
|
+
};
|
|
646
652
|
}
|
|
647
653
|
}
|
|
648
654
|
if (!node.isInline) return;
|
|
@@ -679,9 +685,17 @@ function getTrackedChanges(source) {
|
|
|
679
685
|
case "format":
|
|
680
686
|
change.description = describeFormatChange(change.format);
|
|
681
687
|
break;
|
|
682
|
-
case "block":
|
|
683
|
-
|
|
688
|
+
case "block": {
|
|
689
|
+
const { previous, current, operation } = change.block;
|
|
690
|
+
if (operation) {
|
|
691
|
+
const count = blockCounts.get(change.id) ?? 1;
|
|
692
|
+
const verb = operation === "insert" ? "Inserted" : "Deleted";
|
|
693
|
+
change.description = count > 1 ? `${verb} ${count} blocks` : `${verb} ${blockLabel(current.type, current.attrs)}`;
|
|
694
|
+
} else {
|
|
695
|
+
change.description = describeBlockChange(previous, current);
|
|
696
|
+
}
|
|
684
697
|
break;
|
|
698
|
+
}
|
|
685
699
|
}
|
|
686
700
|
});
|
|
687
701
|
return changes.sort((a, b) => a.from - b.from || a.to - b.to);
|
|
@@ -877,8 +891,56 @@ function restoreWrappers(tr, contentPos, wrappers) {
|
|
|
877
891
|
return;
|
|
878
892
|
}
|
|
879
893
|
}
|
|
894
|
+
function removeBlocks(tr, ids, decision) {
|
|
895
|
+
const removed = decision === "accept" ? "delete" : "insert";
|
|
896
|
+
const memo = /* @__PURE__ */ new Map();
|
|
897
|
+
const removable = (node) => {
|
|
898
|
+
const cached = memo.get(node);
|
|
899
|
+
if (cached !== void 0) return cached;
|
|
900
|
+
let result;
|
|
901
|
+
if (node.isTextblock) {
|
|
902
|
+
const record = node.attrs?.[BLOCK_CHANGE_ATTRIBUTE];
|
|
903
|
+
result = !!record?.changeId && record.operation === removed && ids.has(record.changeId);
|
|
904
|
+
} else if (node.isLeaf || node.childCount === 0) {
|
|
905
|
+
result = false;
|
|
906
|
+
} else {
|
|
907
|
+
result = true;
|
|
908
|
+
for (let i = 0; i < node.childCount && result; i++) result = removable(node.child(i));
|
|
909
|
+
}
|
|
910
|
+
memo.set(node, result);
|
|
911
|
+
return result;
|
|
912
|
+
};
|
|
913
|
+
const doc = tr.doc;
|
|
914
|
+
if (removable(doc)) {
|
|
915
|
+
const filler = doc.type.contentMatch.defaultType?.createAndFill();
|
|
916
|
+
if (filler) tr.replaceWith(0, doc.content.size, filler);
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
const ranges = [];
|
|
920
|
+
const visit = (node, contentStart) => {
|
|
921
|
+
node.forEach((child, offset) => {
|
|
922
|
+
const from = contentStart + offset;
|
|
923
|
+
if (removable(child)) {
|
|
924
|
+
ranges.push({ from, to: from + child.nodeSize });
|
|
925
|
+
} else if (!child.isTextblock && !child.isLeaf) {
|
|
926
|
+
visit(child, from + 1);
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
};
|
|
930
|
+
visit(doc, 0);
|
|
931
|
+
if (ranges.length === 0) return;
|
|
932
|
+
const startIndex = tr.steps.length;
|
|
933
|
+
ranges.reverse().forEach(({ from, to }) => {
|
|
934
|
+
const mapping = tr.mapping.slice(startIndex);
|
|
935
|
+
try {
|
|
936
|
+
tr.delete(mapping.map(from, 1), mapping.map(to, -1));
|
|
937
|
+
} catch {
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
}
|
|
880
941
|
function decideBlocks(tr, changes, decision) {
|
|
881
942
|
const ids = new Set(changes.map((c) => c.id));
|
|
943
|
+
removeBlocks(tr, ids, decision);
|
|
882
944
|
const items = [];
|
|
883
945
|
tr.doc.descendants((node, pos) => {
|
|
884
946
|
const record = node.attrs?.[BLOCK_CHANGE_ATTRIBUTE];
|
|
@@ -894,7 +956,7 @@ function decideBlocks(tr, changes, decision) {
|
|
|
894
956
|
const $pos = tr.doc.resolve(contentPos);
|
|
895
957
|
if (!$pos.parent.isTextblock || $pos.parentOffset !== 0) return;
|
|
896
958
|
const pos = $pos.before();
|
|
897
|
-
if (decision === "accept") {
|
|
959
|
+
if (decision === "accept" || record.operation) {
|
|
898
960
|
tr.setNodeAttribute(pos, BLOCK_CHANGE_ATTRIBUTE, null);
|
|
899
961
|
return;
|
|
900
962
|
}
|
|
@@ -1148,6 +1210,7 @@ function trackBlocks(tr, pending, ctx) {
|
|
|
1148
1210
|
if (!node.isTextblock || $pos.parentOffset !== 0 || $pos.depth === 0) return;
|
|
1149
1211
|
if (!node.type.spec.attrs || !(BLOCK_CHANGE_ATTRIBUTE in node.type.spec.attrs)) return;
|
|
1150
1212
|
const pos = $pos.before();
|
|
1213
|
+
if (existing?.operation || node.attrs[BLOCK_CHANGE_ATTRIBUTE]?.operation) return;
|
|
1151
1214
|
const original = existing?.previous ?? previous;
|
|
1152
1215
|
const current = blockSnapshot(tr.doc, pos);
|
|
1153
1216
|
if (sameBlock(original, current, ctx.ignoredAttributes)) {
|
|
@@ -1345,6 +1408,8 @@ var TrackChanges = Extension.create({
|
|
|
1345
1408
|
deletionHTMLAttributes: {},
|
|
1346
1409
|
formatChangeHTMLAttributes: {},
|
|
1347
1410
|
blockChangeClass: "pixerate-block-change border-l-2 border-amber-400 pl-2 dark:border-amber-500",
|
|
1411
|
+
blockInsertedClass: "pixerate-block-inserted underline decoration-emerald-500 text-emerald-700 dark:text-emerald-400",
|
|
1412
|
+
blockDeletedClass: "pixerate-block-deleted line-through decoration-red-500 text-red-600 dark:text-red-400",
|
|
1348
1413
|
trackFormatting: true,
|
|
1349
1414
|
trackBlocks: true,
|
|
1350
1415
|
trackCodeBlocks: true,
|
|
@@ -1366,6 +1431,8 @@ var TrackChanges = Extension.create({
|
|
|
1366
1431
|
addGlobalAttributes() {
|
|
1367
1432
|
if (this.options?.trackBlocks === false) return [];
|
|
1368
1433
|
const blockClass = this.options?.blockChangeClass ?? "";
|
|
1434
|
+
const insertedClass = this.options?.blockInsertedClass ?? "";
|
|
1435
|
+
const deletedClass = this.options?.blockDeletedClass ?? "";
|
|
1369
1436
|
return [
|
|
1370
1437
|
{
|
|
1371
1438
|
types: this.options?.blockTypes ?? ["paragraph", "heading", "codeBlock"],
|
|
@@ -1377,9 +1444,13 @@ var TrackChanges = Extension.create({
|
|
|
1377
1444
|
renderHTML: (attrs) => {
|
|
1378
1445
|
const value = attrs[BLOCK_CHANGE_ATTRIBUTE];
|
|
1379
1446
|
if (!value) return {};
|
|
1447
|
+
const operation = value.operation;
|
|
1448
|
+
const extra = operation === "insert" ? insertedClass : operation === "delete" ? deletedClass : "";
|
|
1449
|
+
const className = [blockClass, extra].filter(Boolean).join(" ");
|
|
1380
1450
|
return {
|
|
1381
1451
|
"data-block-change": JSON.stringify(value),
|
|
1382
|
-
...
|
|
1452
|
+
...operation ? { "data-block-operation": operation } : {},
|
|
1453
|
+
...className ? { class: className } : {}
|
|
1383
1454
|
};
|
|
1384
1455
|
}
|
|
1385
1456
|
}
|
|
@@ -1545,540 +1616,6 @@ var TrackChanges = Extension.create({
|
|
|
1545
1616
|
}
|
|
1546
1617
|
});
|
|
1547
1618
|
|
|
1548
|
-
// src/serializers/plain-text.ts
|
|
1549
|
-
import { Slice as Slice2, Fragment as Fragment2, Node as ProsemirrorNode } from "@tiptap/pm/model";
|
|
1550
|
-
var TRACKED_DELETION_REGEX = /<del\b(?=[^>]*\bdata-change-type=["']deletion["'])[^>]*>[\s\S]*?<\/del>/gi;
|
|
1551
|
-
var TRACKED_INSERTION_REGEX = /<ins\b(?=[^>]*\bdata-change-type=["']insertion["'])[^>]*>[\s\S]*?<\/ins>/gi;
|
|
1552
|
-
function stripTrackedChanges(html, view) {
|
|
1553
|
-
if (view === "all" || !html.includes("data-change-type")) return html;
|
|
1554
|
-
return html.replace(
|
|
1555
|
-
view === "accepted" ? TRACKED_DELETION_REGEX : TRACKED_INSERTION_REGEX,
|
|
1556
|
-
""
|
|
1557
|
-
);
|
|
1558
|
-
}
|
|
1559
|
-
function escapeHtml(text) {
|
|
1560
|
-
if (!text) return "";
|
|
1561
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1562
|
-
}
|
|
1563
|
-
var PARAGRAPH_HTML_REGEX = /^\s*<p[\s>][\s\S]*<\/p>\s*$/i;
|
|
1564
|
-
function plainTextToTipTapHtml(text) {
|
|
1565
|
-
if (!text) return "<p></p>";
|
|
1566
|
-
if (PARAGRAPH_HTML_REGEX.test(text)) {
|
|
1567
|
-
return text;
|
|
1568
|
-
}
|
|
1569
|
-
return text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").split("\n").map((line) => `<p>${escapeHtml(line)}</p>`).join("");
|
|
1570
|
-
}
|
|
1571
|
-
function plainTextToSlice(text, schema) {
|
|
1572
|
-
const nodes = [];
|
|
1573
|
-
text.replace(/\r\n?/g, "\n").split("\n").forEach((line) => {
|
|
1574
|
-
const nodeJson = { type: "paragraph" };
|
|
1575
|
-
if (line.length > 0) {
|
|
1576
|
-
nodeJson.content = [{ type: "text", text: line }];
|
|
1577
|
-
}
|
|
1578
|
-
try {
|
|
1579
|
-
nodes.push(ProsemirrorNode.fromJSON(schema, nodeJson));
|
|
1580
|
-
} catch {
|
|
1581
|
-
}
|
|
1582
|
-
});
|
|
1583
|
-
return Slice2.maxOpen(Fragment2.fromArray(nodes));
|
|
1584
|
-
}
|
|
1585
|
-
var BLOCK_TAGS = /* @__PURE__ */ new Set([
|
|
1586
|
-
"P",
|
|
1587
|
-
"DIV",
|
|
1588
|
-
"LI",
|
|
1589
|
-
"UL",
|
|
1590
|
-
"OL",
|
|
1591
|
-
"PRE",
|
|
1592
|
-
"BLOCKQUOTE",
|
|
1593
|
-
"TABLE",
|
|
1594
|
-
"TR",
|
|
1595
|
-
"H1",
|
|
1596
|
-
"H2",
|
|
1597
|
-
"H3",
|
|
1598
|
-
"H4",
|
|
1599
|
-
"H5",
|
|
1600
|
-
"H6",
|
|
1601
|
-
"HR"
|
|
1602
|
-
]);
|
|
1603
|
-
var MENTION_SPAN_REGEX = /<span\b(?=[^>]*\bdata-type=["']mention["'])([^>]*)>[\s\S]*?<\/span>/gi;
|
|
1604
|
-
function getHtmlAttribute(attrs, name) {
|
|
1605
|
-
const match = new RegExp(`\\b${name}=(?:"([^"]*)"|'([^']*)')`, "i").exec(
|
|
1606
|
-
attrs
|
|
1607
|
-
);
|
|
1608
|
-
return match ? match[1] ?? match[2] : void 0;
|
|
1609
|
-
}
|
|
1610
|
-
function parseHtmlFragment(html) {
|
|
1611
|
-
const template = document.createElement("template");
|
|
1612
|
-
template.innerHTML = html;
|
|
1613
|
-
return template.content;
|
|
1614
|
-
}
|
|
1615
|
-
function decodeHtmlEntities(text) {
|
|
1616
|
-
return text.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/�*39;/g, "'").replace(/ /g, "\xA0").replace(/&/g, "&");
|
|
1617
|
-
}
|
|
1618
|
-
function htmlToPlainText(html, options = {}) {
|
|
1619
|
-
if (!html) return "";
|
|
1620
|
-
const mentionNormalized = stripTrackedChanges(
|
|
1621
|
-
html,
|
|
1622
|
-
options.trackedChanges ?? "accepted"
|
|
1623
|
-
).replace(MENTION_SPAN_REGEX, (match, attrs) => {
|
|
1624
|
-
const label = getHtmlAttribute(attrs, "data-label") || getHtmlAttribute(attrs, "data-id");
|
|
1625
|
-
return label ? `@${label}` : match;
|
|
1626
|
-
});
|
|
1627
|
-
if (typeof document !== "undefined") {
|
|
1628
|
-
const fragment = parseHtmlFragment(mentionNormalized);
|
|
1629
|
-
fragment.querySelectorAll("br.ProseMirror-trailingBreak").forEach((br) => br.remove());
|
|
1630
|
-
const lines = [];
|
|
1631
|
-
let current = null;
|
|
1632
|
-
const flush = () => {
|
|
1633
|
-
if (current !== null) {
|
|
1634
|
-
lines.push(current);
|
|
1635
|
-
current = null;
|
|
1636
|
-
}
|
|
1637
|
-
};
|
|
1638
|
-
const visit = (node) => {
|
|
1639
|
-
if (node.nodeType === 3) {
|
|
1640
|
-
const value = node.nodeValue ?? "";
|
|
1641
|
-
if (current === null && value.trim() === "") return;
|
|
1642
|
-
current = (current ?? "") + value;
|
|
1643
|
-
return;
|
|
1644
|
-
}
|
|
1645
|
-
if (node.nodeType !== 1) return;
|
|
1646
|
-
const tag = node.tagName.toUpperCase();
|
|
1647
|
-
if (tag === "BR") {
|
|
1648
|
-
current = (current ?? "") + "\n";
|
|
1649
|
-
return;
|
|
1650
|
-
}
|
|
1651
|
-
if (!BLOCK_TAGS.has(tag)) {
|
|
1652
|
-
node.childNodes.forEach(visit);
|
|
1653
|
-
return;
|
|
1654
|
-
}
|
|
1655
|
-
flush();
|
|
1656
|
-
const linesBefore = lines.length;
|
|
1657
|
-
node.childNodes.forEach(visit);
|
|
1658
|
-
flush();
|
|
1659
|
-
if (lines.length === linesBefore && tag !== "HR") {
|
|
1660
|
-
lines.push("");
|
|
1661
|
-
}
|
|
1662
|
-
};
|
|
1663
|
-
fragment.childNodes.forEach(visit);
|
|
1664
|
-
flush();
|
|
1665
|
-
return lines.join("\n");
|
|
1666
|
-
}
|
|
1667
|
-
const text = mentionNormalized.replace(/<br\s*\/?>/gi, "\n").replace(
|
|
1668
|
-
/<\/(?:p|div|li|pre|blockquote|h[1-6])>(?:\s*<\/(?:li|ul|ol|blockquote|div)>)*/gi,
|
|
1669
|
-
"\n"
|
|
1670
|
-
).replace(/<[^>]+>/g, "");
|
|
1671
|
-
return decodeHtmlEntities(text).replace(/\n$/, "");
|
|
1672
|
-
}
|
|
1673
|
-
function getEditorText(editor, options = {}) {
|
|
1674
|
-
if (!editor) return "";
|
|
1675
|
-
const html = typeof editor.getHTML === "function" ? editor.getHTML() : "";
|
|
1676
|
-
if (html) {
|
|
1677
|
-
return htmlToPlainText(html, options);
|
|
1678
|
-
}
|
|
1679
|
-
if (typeof editor.getText === "function") {
|
|
1680
|
-
try {
|
|
1681
|
-
return editor.getText({ blockSeparator: "\n" });
|
|
1682
|
-
} catch {
|
|
1683
|
-
return editor.getText();
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
return "";
|
|
1687
|
-
}
|
|
1688
|
-
function extractMentionsFromDoc(docOrEditor) {
|
|
1689
|
-
if (!docOrEditor) return [];
|
|
1690
|
-
const mentions = [];
|
|
1691
|
-
const doc = docOrEditor?.state?.doc || (typeof docOrEditor?.descendants === "function" ? docOrEditor : null);
|
|
1692
|
-
if (doc && typeof doc.descendants === "function") {
|
|
1693
|
-
doc.descendants((node) => {
|
|
1694
|
-
if (node.type?.name === "mention" && node.attrs) {
|
|
1695
|
-
mentions.push({
|
|
1696
|
-
id: node.attrs.id || "",
|
|
1697
|
-
label: node.attrs.label || "",
|
|
1698
|
-
type: node.attrs.type,
|
|
1699
|
-
avatarUrl: node.attrs.avatarUrl,
|
|
1700
|
-
color: node.attrs.color,
|
|
1701
|
-
...node.attrs
|
|
1702
|
-
});
|
|
1703
|
-
}
|
|
1704
|
-
});
|
|
1705
|
-
return mentions;
|
|
1706
|
-
}
|
|
1707
|
-
if (typeof docOrEditor === "object" && docOrEditor.content) {
|
|
1708
|
-
const walk = (nodes) => {
|
|
1709
|
-
for (const node of nodes) {
|
|
1710
|
-
if (node.type === "mention" && node.attrs) {
|
|
1711
|
-
mentions.push({
|
|
1712
|
-
id: node.attrs.id || "",
|
|
1713
|
-
label: node.attrs.label || "",
|
|
1714
|
-
type: node.attrs.type,
|
|
1715
|
-
avatarUrl: node.attrs.avatarUrl,
|
|
1716
|
-
color: node.attrs.color,
|
|
1717
|
-
...node.attrs
|
|
1718
|
-
});
|
|
1719
|
-
}
|
|
1720
|
-
if (Array.isArray(node.content)) {
|
|
1721
|
-
walk(node.content);
|
|
1722
|
-
}
|
|
1723
|
-
}
|
|
1724
|
-
};
|
|
1725
|
-
walk(docOrEditor.content);
|
|
1726
|
-
return mentions;
|
|
1727
|
-
}
|
|
1728
|
-
if (typeof docOrEditor === "string") {
|
|
1729
|
-
if (typeof document !== "undefined") {
|
|
1730
|
-
parseHtmlFragment(docOrEditor).querySelectorAll('span[data-type="mention"]').forEach((el) => {
|
|
1731
|
-
mentions.push({
|
|
1732
|
-
id: el.getAttribute("data-id") || "",
|
|
1733
|
-
label: el.getAttribute("data-label") || "",
|
|
1734
|
-
type: el.getAttribute("data-type-name") || void 0,
|
|
1735
|
-
avatarUrl: el.getAttribute("data-avatar-url") || void 0,
|
|
1736
|
-
color: el.getAttribute("data-color") || void 0
|
|
1737
|
-
});
|
|
1738
|
-
});
|
|
1739
|
-
} else {
|
|
1740
|
-
const spanRegex = /<span([^>]*data-type=["']mention["'][^>]*)>/gi;
|
|
1741
|
-
let match;
|
|
1742
|
-
while ((match = spanRegex.exec(docOrEditor)) !== null) {
|
|
1743
|
-
const attrStr = match[1];
|
|
1744
|
-
const getAttr = (name) => {
|
|
1745
|
-
const m = new RegExp(`${name}=["']([^"']*)["']`, "i").exec(attrStr);
|
|
1746
|
-
return m ? m[1] : void 0;
|
|
1747
|
-
};
|
|
1748
|
-
mentions.push({
|
|
1749
|
-
id: getAttr("data-id") || "",
|
|
1750
|
-
label: getAttr("data-label") || "",
|
|
1751
|
-
type: getAttr("data-type-name") || getAttr("data-entity-type"),
|
|
1752
|
-
avatarUrl: getAttr("data-avatar-url"),
|
|
1753
|
-
color: getAttr("data-color")
|
|
1754
|
-
});
|
|
1755
|
-
}
|
|
1756
|
-
}
|
|
1757
|
-
if (mentions.length === 0) {
|
|
1758
|
-
const rawHandles = extractMentions(docOrEditor);
|
|
1759
|
-
for (const handle of rawHandles) {
|
|
1760
|
-
mentions.push({
|
|
1761
|
-
id: handle,
|
|
1762
|
-
label: handle,
|
|
1763
|
-
type: "user"
|
|
1764
|
-
});
|
|
1765
|
-
}
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
return mentions;
|
|
1769
|
-
}
|
|
1770
|
-
|
|
1771
|
-
// src/serializers/mentions.ts
|
|
1772
|
-
var MENTION_REGEX = /(?:^|[\s>(*_"';\\/[\]{}~`:]|"|>|<|&)@(?:"([^"]+)"|"([^&]+)"|([a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*))/g;
|
|
1773
|
-
var MARKDOWN_MENTION_SPLIT_REGEX = /(```[\s\S]*?```|~~~[\s\S]*?~~~|<pre[\s\S]*?<\/pre>|<code[\s\S]*?<\/code>|`[^`\n]+`|<span\b[^>]*\b(?:data-type=["']mention["']|class=["'][^"']*pixerate-mention-node[^"']*["']|data-mention=["'][^"']*["'])[^>]*>[\s\S]*?<\/span>|<[^>]+>|\]\([^)]+\)|(?:https?|file|vscode|cursor|mailto):\/\/[^\s<)]+)/gi;
|
|
1774
|
-
function stripMarkdownCode(content) {
|
|
1775
|
-
if (!content || typeof content !== "string") return "";
|
|
1776
|
-
return content.replace(/```[\s\S]*?```/g, "").replace(/~~~[\s\S]*?~~~/g, "").replace(/<pre[\s\S]*?<\/pre>/gi, "").replace(/<code[\s\S]*?<\/code>/gi, "").replace(/`[^`\n]*`/g, "");
|
|
1777
|
-
}
|
|
1778
|
-
function extractMentions(content) {
|
|
1779
|
-
if (!content || typeof content !== "string") return [];
|
|
1780
|
-
const normalizedMentionNodes = content.replace(
|
|
1781
|
-
/<span\b[^>]*\b(?:data-type=["']mention["']|class=["'][^"']*pixerate-mention-node[^"']*["'])[^>]*>([\s\S]*?)<\/span>/gi,
|
|
1782
|
-
(match2, inner) => {
|
|
1783
|
-
const labelMatch = match2.match(/\bdata-label=["']([^"']+)["']/i);
|
|
1784
|
-
if (labelMatch) return ` @${labelMatch[1]} `;
|
|
1785
|
-
const idMatch = match2.match(/\bdata-id=["']([^"']+)["']/i);
|
|
1786
|
-
if (idMatch) return ` @${idMatch[1]} `;
|
|
1787
|
-
return ` ${inner} `;
|
|
1788
|
-
}
|
|
1789
|
-
);
|
|
1790
|
-
const cleanContent = stripMarkdownCode(normalizedMentionNodes);
|
|
1791
|
-
const withoutUrls = cleanContent.replace(/(?:https?|ftp|file|vscode|cursor|mailto):\/\/[^\s<>()]+/gi, "").replace(/\]\([^)]*\)/g, "]");
|
|
1792
|
-
const textOnly = withoutUrls.replace(/<[^>]+>/g, " ");
|
|
1793
|
-
const mentions = [];
|
|
1794
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1795
|
-
const regex = new RegExp(MENTION_REGEX.source, "g");
|
|
1796
|
-
let match;
|
|
1797
|
-
while ((match = regex.exec(textOnly)) !== null) {
|
|
1798
|
-
const handle = (match[1] ?? match[2] ?? match[3] ?? "").trim();
|
|
1799
|
-
if (handle && !seen.has(handle)) {
|
|
1800
|
-
seen.add(handle);
|
|
1801
|
-
mentions.push(handle);
|
|
1802
|
-
}
|
|
1803
|
-
}
|
|
1804
|
-
return mentions;
|
|
1805
|
-
}
|
|
1806
|
-
function parseMentionSegments(content) {
|
|
1807
|
-
if (!content) return [];
|
|
1808
|
-
const segments = [];
|
|
1809
|
-
const regex = new RegExp(MENTION_REGEX.source, "g");
|
|
1810
|
-
let lastIndex = 0;
|
|
1811
|
-
let match;
|
|
1812
|
-
while ((match = regex.exec(content)) !== null) {
|
|
1813
|
-
const fullMatch = match[0];
|
|
1814
|
-
const atIndex = fullMatch.indexOf("@");
|
|
1815
|
-
const prefix = atIndex > 0 ? fullMatch.slice(0, atIndex) : "";
|
|
1816
|
-
const mentionToken = fullMatch.slice(atIndex);
|
|
1817
|
-
const handle = match[1] ?? match[2] ?? match[3];
|
|
1818
|
-
const matchStart = match.index + prefix.length;
|
|
1819
|
-
if (matchStart > lastIndex) {
|
|
1820
|
-
segments.push({
|
|
1821
|
-
type: "text",
|
|
1822
|
-
value: content.slice(lastIndex, matchStart)
|
|
1823
|
-
});
|
|
1824
|
-
}
|
|
1825
|
-
segments.push({
|
|
1826
|
-
type: "mention",
|
|
1827
|
-
value: mentionToken,
|
|
1828
|
-
handle
|
|
1829
|
-
});
|
|
1830
|
-
lastIndex = matchStart + mentionToken.length;
|
|
1831
|
-
}
|
|
1832
|
-
if (lastIndex < content.length) {
|
|
1833
|
-
segments.push({
|
|
1834
|
-
type: "text",
|
|
1835
|
-
value: content.slice(lastIndex)
|
|
1836
|
-
});
|
|
1837
|
-
}
|
|
1838
|
-
return segments;
|
|
1839
|
-
}
|
|
1840
|
-
function preprocessMarkdownMentions(content, optionsOrMentionables = []) {
|
|
1841
|
-
if (!content || typeof content !== "string") return "";
|
|
1842
|
-
const options = Array.isArray(optionsOrMentionables) ? { mentionables: optionsOrMentionables } : optionsOrMentionables;
|
|
1843
|
-
const allMentionables = options.mentionables || [];
|
|
1844
|
-
const defaultType = options.defaultType || "user";
|
|
1845
|
-
const resolveMention = options.resolveMention;
|
|
1846
|
-
const parts = content.split(MARKDOWN_MENTION_SPLIT_REGEX);
|
|
1847
|
-
return parts.map((part) => {
|
|
1848
|
-
if (!part) return "";
|
|
1849
|
-
if (part.startsWith("```") || part.startsWith("~~~") || part.startsWith("`") || part.startsWith("](") || /^(?:https?|file|vscode|cursor|mailto):\/\//i.test(part) || /^<pre[\s>]/i.test(part) || /^<code[\s>]/i.test(part) || /^<[^>]+>$/i.test(part) || /^<span\b[^>]*\b(?:data-type=["']mention["']|class=["'][^"']*pixerate-mention-node[^"']*["']|data-mention=["'][^"']*["'])/i.test(
|
|
1850
|
-
part
|
|
1851
|
-
)) {
|
|
1852
|
-
return part;
|
|
1853
|
-
}
|
|
1854
|
-
const regex = new RegExp(MENTION_REGEX.source, "g");
|
|
1855
|
-
return part.replace(regex, (match, quotedHandle, escapedQuotedHandle, standardHandle) => {
|
|
1856
|
-
const atIndex = match.indexOf("@");
|
|
1857
|
-
const prefix = atIndex > 0 ? match.slice(0, atIndex) : "";
|
|
1858
|
-
const rawHandle = (quotedHandle || escapedQuotedHandle || standardHandle || "").trim();
|
|
1859
|
-
if (!rawHandle) return match;
|
|
1860
|
-
const lowerHandle = rawHandle.toLowerCase();
|
|
1861
|
-
const entity = allMentionables.find((e) => {
|
|
1862
|
-
if (e.label?.toLowerCase() === lowerHandle) return true;
|
|
1863
|
-
if (e.handle?.toLowerCase() === lowerHandle) return true;
|
|
1864
|
-
if (e.name?.toLowerCase() === lowerHandle) return true;
|
|
1865
|
-
if (e.id?.toLowerCase() === lowerHandle) return true;
|
|
1866
|
-
if (e.type === "agent" && `agent${(e.handle || e.label || "").toLowerCase()}` === lowerHandle) return true;
|
|
1867
|
-
if (e.aliases?.some(
|
|
1868
|
-
(a) => a.toLowerCase() === lowerHandle || e.type === "agent" && `agent${a.toLowerCase()}` === lowerHandle
|
|
1869
|
-
)) {
|
|
1870
|
-
return true;
|
|
1871
|
-
}
|
|
1872
|
-
return false;
|
|
1873
|
-
});
|
|
1874
|
-
let id = entity?.id;
|
|
1875
|
-
let label = entity?.label || entity?.handle || rawHandle;
|
|
1876
|
-
let type = entity?.type;
|
|
1877
|
-
let avatarUrl = entity?.avatarUrl;
|
|
1878
|
-
let color = entity?.color || entity?.hexColor;
|
|
1879
|
-
if (!entity) {
|
|
1880
|
-
const customResolved = resolveMention?.(rawHandle);
|
|
1881
|
-
if (customResolved) {
|
|
1882
|
-
id = customResolved.id ?? id;
|
|
1883
|
-
label = customResolved.label ?? customResolved.handle ?? label;
|
|
1884
|
-
type = customResolved.type ?? type;
|
|
1885
|
-
avatarUrl = customResolved.avatarUrl ?? avatarUrl;
|
|
1886
|
-
color = customResolved.color ?? customResolved.hexColor ?? color;
|
|
1887
|
-
} else {
|
|
1888
|
-
const stripped = lowerHandle.replace(/^agent[\s\-_]*/i, "");
|
|
1889
|
-
if (["supervisor", "coordinator", "planner", "validator", "executor"].includes(stripped)) {
|
|
1890
|
-
type = "agent";
|
|
1891
|
-
id = stripped;
|
|
1892
|
-
label = stripped;
|
|
1893
|
-
} else if (lowerHandle === "agents") {
|
|
1894
|
-
type = "team";
|
|
1895
|
-
id = "agents";
|
|
1896
|
-
label = "agents";
|
|
1897
|
-
} else {
|
|
1898
|
-
type = defaultType;
|
|
1899
|
-
id = rawHandle;
|
|
1900
|
-
label = rawHandle;
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
const avatarAttr = avatarUrl ? ` data-avatar-url="${escapeHtml(avatarUrl)}"` : "";
|
|
1905
|
-
const colorAttr = color ? ` data-color="${escapeHtml(color)}"` : "";
|
|
1906
|
-
return `${prefix}<span class="pixerate-mention-node" data-type="mention" data-id="${escapeHtml(
|
|
1907
|
-
id || label
|
|
1908
|
-
)}" data-label="${escapeHtml(label)}" data-mention-suggestion-char="@" data-type-name="${escapeHtml(
|
|
1909
|
-
type || defaultType
|
|
1910
|
-
)}"${avatarAttr}${colorAttr}>@${escapeHtml(label)}</span>`;
|
|
1911
|
-
});
|
|
1912
|
-
}).join("");
|
|
1913
|
-
}
|
|
1914
|
-
|
|
1915
|
-
// src/serializers/markdown.ts
|
|
1916
|
-
import MarkdownIt from "markdown-it";
|
|
1917
|
-
import taskLists from "markdown-it-task-lists";
|
|
1918
|
-
var md = new MarkdownIt({
|
|
1919
|
-
html: true,
|
|
1920
|
-
linkify: true,
|
|
1921
|
-
breaks: true
|
|
1922
|
-
}).use(taskLists);
|
|
1923
|
-
var defaultValidateLink = md.validateLink;
|
|
1924
|
-
md.validateLink = (url) => {
|
|
1925
|
-
if (url.startsWith("file://") || url.startsWith("vscode://") || url.startsWith("cursor://")) {
|
|
1926
|
-
return true;
|
|
1927
|
-
}
|
|
1928
|
-
return defaultValidateLink.call(md, url);
|
|
1929
|
-
};
|
|
1930
|
-
var ALLOWED_HTML_TAGS = /* @__PURE__ */ new Set([
|
|
1931
|
-
"a",
|
|
1932
|
-
"abbr",
|
|
1933
|
-
"b",
|
|
1934
|
-
"blockquote",
|
|
1935
|
-
"br",
|
|
1936
|
-
"code",
|
|
1937
|
-
"del",
|
|
1938
|
-
"details",
|
|
1939
|
-
"div",
|
|
1940
|
-
"em",
|
|
1941
|
-
"h1",
|
|
1942
|
-
"h2",
|
|
1943
|
-
"h3",
|
|
1944
|
-
"h4",
|
|
1945
|
-
"h5",
|
|
1946
|
-
"h6",
|
|
1947
|
-
"hr",
|
|
1948
|
-
"i",
|
|
1949
|
-
"img",
|
|
1950
|
-
"input",
|
|
1951
|
-
"kbd",
|
|
1952
|
-
"li",
|
|
1953
|
-
"mark",
|
|
1954
|
-
"ol",
|
|
1955
|
-
"p",
|
|
1956
|
-
"pre",
|
|
1957
|
-
"s",
|
|
1958
|
-
"span",
|
|
1959
|
-
"strong",
|
|
1960
|
-
"sub",
|
|
1961
|
-
"summary",
|
|
1962
|
-
"sup",
|
|
1963
|
-
"table",
|
|
1964
|
-
"tbody",
|
|
1965
|
-
"td",
|
|
1966
|
-
"tfoot",
|
|
1967
|
-
"th",
|
|
1968
|
-
"thead",
|
|
1969
|
-
"tr",
|
|
1970
|
-
"u",
|
|
1971
|
-
"ul"
|
|
1972
|
-
]);
|
|
1973
|
-
var ALLOWED_HTML_ATTRS = /* @__PURE__ */ new Set([
|
|
1974
|
-
"alt",
|
|
1975
|
-
"align",
|
|
1976
|
-
"checked",
|
|
1977
|
-
"class",
|
|
1978
|
-
"colspan",
|
|
1979
|
-
"disabled",
|
|
1980
|
-
"height",
|
|
1981
|
-
"href",
|
|
1982
|
-
"rel",
|
|
1983
|
-
"rowspan",
|
|
1984
|
-
"src",
|
|
1985
|
-
"start",
|
|
1986
|
-
"target",
|
|
1987
|
-
"title",
|
|
1988
|
-
"type",
|
|
1989
|
-
"width"
|
|
1990
|
-
]);
|
|
1991
|
-
var HTML_TAG_REGEX = /<(\/?)([a-zA-Z][a-zA-Z0-9-]*)((?:\s+[^\s"'>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s"'=<>`]+))?)*)\s*\/?>/g;
|
|
1992
|
-
var HTML_ATTR_REGEX = /([^\s"'>\/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'=<>`]+)))?/g;
|
|
1993
|
-
function sanitizeTag(tagText, isClosing, rawTagName, rawAttrs, stripDisallowed) {
|
|
1994
|
-
const tagName = rawTagName.toLowerCase();
|
|
1995
|
-
const reject = () => stripDisallowed ? "" : escapeHtml(tagText);
|
|
1996
|
-
if (!ALLOWED_HTML_TAGS.has(tagName)) return reject();
|
|
1997
|
-
if (isClosing) return `</${tagName}>`;
|
|
1998
|
-
if (tagName === "input" && !/\stype\s*=\s*["']?checkbox["']?[\s>/]/i.test(tagText)) {
|
|
1999
|
-
return reject();
|
|
2000
|
-
}
|
|
2001
|
-
let attrs = "";
|
|
2002
|
-
let attrMatch;
|
|
2003
|
-
HTML_ATTR_REGEX.lastIndex = 0;
|
|
2004
|
-
while ((attrMatch = HTML_ATTR_REGEX.exec(rawAttrs)) !== null) {
|
|
2005
|
-
const name = attrMatch[1].toLowerCase();
|
|
2006
|
-
if (!ALLOWED_HTML_ATTRS.has(name) && !/^data-[a-z0-9_.-]+$/.test(name)) {
|
|
2007
|
-
continue;
|
|
2008
|
-
}
|
|
2009
|
-
const rawValue = attrMatch[2] ?? attrMatch[3] ?? attrMatch[4];
|
|
2010
|
-
if (rawValue === void 0) {
|
|
2011
|
-
attrs += ` ${name}`;
|
|
2012
|
-
continue;
|
|
2013
|
-
}
|
|
2014
|
-
const value = md.utils.unescapeAll(rawValue);
|
|
2015
|
-
if ((name === "href" || name === "src") && // Browsers ignore control characters and whitespace inside schemes.
|
|
2016
|
-
!md.validateLink(value.replace(/[\u0000-\u0020\u007f]/g, ""))) {
|
|
2017
|
-
continue;
|
|
2018
|
-
}
|
|
2019
|
-
attrs += ` ${name}="${escapeHtml(value)}"`;
|
|
2020
|
-
}
|
|
2021
|
-
return `<${tagName}${attrs}>`;
|
|
2022
|
-
}
|
|
2023
|
-
function sanitizeHtml(html, options = {}) {
|
|
2024
|
-
return sanitizeEmbeddedHtml(html, options.disallowedTags === "strip");
|
|
2025
|
-
}
|
|
2026
|
-
function sanitizeEmbeddedHtml(html, stripDisallowed = false) {
|
|
2027
|
-
let result = "";
|
|
2028
|
-
let lastIndex = 0;
|
|
2029
|
-
let match;
|
|
2030
|
-
HTML_TAG_REGEX.lastIndex = 0;
|
|
2031
|
-
while ((match = HTML_TAG_REGEX.exec(html)) !== null) {
|
|
2032
|
-
result += html.slice(lastIndex, match.index).replace(/</g, "<");
|
|
2033
|
-
result += sanitizeTag(match[0], match[1], match[2], match[3], stripDisallowed);
|
|
2034
|
-
lastIndex = match.index + match[0].length;
|
|
2035
|
-
}
|
|
2036
|
-
return result + html.slice(lastIndex).replace(/</g, "<");
|
|
2037
|
-
}
|
|
2038
|
-
var defaultHtmlInline = md.renderer.rules.html_inline;
|
|
2039
|
-
var defaultHtmlBlock = md.renderer.rules.html_block;
|
|
2040
|
-
md.renderer.rules.html_inline = (tokens, idx, options, env, self) => env?.allowUnsafeHtml ? defaultHtmlInline(tokens, idx, options, env, self) : sanitizeEmbeddedHtml(tokens[idx].content);
|
|
2041
|
-
md.renderer.rules.html_block = (tokens, idx, options, env, self) => env?.allowUnsafeHtml ? defaultHtmlBlock(tokens, idx, options, env, self) : sanitizeEmbeddedHtml(tokens[idx].content);
|
|
2042
|
-
function preprocessMarkdownFileLinks(content) {
|
|
2043
|
-
if (!content) return "";
|
|
2044
|
-
return content.replace(
|
|
2045
|
-
/\[([^\]]+)\]\(((?:file|vscode|cursor):\/\/[^)]+)\)/g,
|
|
2046
|
-
(_match, rawLabel, href) => {
|
|
2047
|
-
const trimmed = rawLabel.trim();
|
|
2048
|
-
const codeMatch = trimmed.match(/^`([^`]+)`$/);
|
|
2049
|
-
const labelContent = codeMatch ? `<code>${escapeHtml(codeMatch[1])}</code>` : escapeHtml(trimmed);
|
|
2050
|
-
return `<a href="${escapeHtml(href)}" data-file-link="true" title="Click to copy file path">${labelContent}</a>`;
|
|
2051
|
-
}
|
|
2052
|
-
);
|
|
2053
|
-
}
|
|
2054
|
-
function markdownToTipTapHtml(markdown, options) {
|
|
2055
|
-
if (!markdown) return "<p></p>";
|
|
2056
|
-
let content = markdown;
|
|
2057
|
-
if (options?.preprocessFileLinks) {
|
|
2058
|
-
content = preprocessMarkdownFileLinks(content);
|
|
2059
|
-
}
|
|
2060
|
-
if (options?.preprocessMentions || options?.mentionables || options?.preprocessOptions) {
|
|
2061
|
-
const mentionOpts = options.preprocessOptions || {
|
|
2062
|
-
mentionables: options.mentionables
|
|
2063
|
-
};
|
|
2064
|
-
content = preprocessMarkdownMentions(content, mentionOpts);
|
|
2065
|
-
}
|
|
2066
|
-
return md.render(content, { allowUnsafeHtml: options?.allowUnsafeHtml });
|
|
2067
|
-
}
|
|
2068
|
-
function getEditorMarkdown(editor, options = {}) {
|
|
2069
|
-
if (!editor) return "";
|
|
2070
|
-
const markdown = editor.storage?.markdown;
|
|
2071
|
-
if (typeof markdown?.getMarkdown === "function") {
|
|
2072
|
-
const doc = editor.state?.doc;
|
|
2073
|
-
if (doc && typeof markdown.serializer?.serialize === "function") {
|
|
2074
|
-
const resolved = resolveTrackedChanges(doc, options.trackedChanges ?? "accepted");
|
|
2075
|
-
if (resolved !== doc) return markdown.serializer.serialize(resolved);
|
|
2076
|
-
}
|
|
2077
|
-
return markdown.getMarkdown();
|
|
2078
|
-
}
|
|
2079
|
-
return getEditorText(editor, options);
|
|
2080
|
-
}
|
|
2081
|
-
|
|
2082
1619
|
export {
|
|
2083
1620
|
createReviewId,
|
|
2084
1621
|
CommentStore,
|
|
@@ -2101,22 +1638,6 @@ export {
|
|
|
2101
1638
|
isTrackChangesEnabled,
|
|
2102
1639
|
getTrackChangesStore,
|
|
2103
1640
|
resolveTrackedChanges,
|
|
2104
|
-
TrackChanges
|
|
2105
|
-
MENTION_REGEX,
|
|
2106
|
-
MARKDOWN_MENTION_SPLIT_REGEX,
|
|
2107
|
-
stripMarkdownCode,
|
|
2108
|
-
extractMentions,
|
|
2109
|
-
parseMentionSegments,
|
|
2110
|
-
preprocessMarkdownMentions,
|
|
2111
|
-
escapeHtml,
|
|
2112
|
-
plainTextToTipTapHtml,
|
|
2113
|
-
plainTextToSlice,
|
|
2114
|
-
htmlToPlainText,
|
|
2115
|
-
getEditorText,
|
|
2116
|
-
extractMentionsFromDoc,
|
|
2117
|
-
sanitizeHtml,
|
|
2118
|
-
preprocessMarkdownFileLinks,
|
|
2119
|
-
markdownToTipTapHtml,
|
|
2120
|
-
getEditorMarkdown
|
|
1641
|
+
TrackChanges
|
|
2121
1642
|
};
|
|
2122
|
-
//# sourceMappingURL=chunk-
|
|
1643
|
+
//# sourceMappingURL=chunk-5S3Z4PPF.js.map
|