@mrsf/markdown-it-mrsf 0.4.12 → 0.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 +4 -0
- package/dist/browser.cjs +194 -0
- package/dist/browser.cjs.map +7 -0
- package/dist/controller.cjs +1202 -0
- package/dist/controller.cjs.map +7 -0
- package/dist/index.cjs +240 -0
- package/dist/index.cjs.map +7 -0
- package/package.json +19 -7
package/README.md
CHANGED
|
@@ -206,6 +206,10 @@ All rendered elements follow a strict data-attribute contract:
|
|
|
206
206
|
- `data-mrsf-action` — action type (`add`, `resolve`, `unresolve`, `reply`, `edit`, `delete`, `navigate`)
|
|
207
207
|
- `data-mrsf-start-line`, `data-mrsf-end-line`, `data-mrsf-start-column`, `data-mrsf-end-column` — optional selection anchors when present
|
|
208
208
|
|
|
209
|
+
## Security / XSS
|
|
210
|
+
|
|
211
|
+
Per the MRSF specification, comment `text` is plain text, not HTML or Markdown. The renderer HTML-escapes comment `text`, `author`, `selected_text`, and `id` before emitting HTML, so untrusted comment content cannot inject markup through MRSF. Hosts should keep their Markdown pipeline's sanitization enabled for non-MRSF content.
|
|
212
|
+
|
|
209
213
|
## License
|
|
210
214
|
|
|
211
215
|
[MIT](../LICENSE)
|
package/dist/browser.cjs
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/browser.ts
|
|
21
|
+
var browser_exports = {};
|
|
22
|
+
__export(browser_exports, {
|
|
23
|
+
default: () => browser_default,
|
|
24
|
+
mrsfPlugin: () => mrsfPlugin
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(browser_exports);
|
|
27
|
+
|
|
28
|
+
// src/comments.ts
|
|
29
|
+
function getExtensionFields(comment) {
|
|
30
|
+
const extensions = {};
|
|
31
|
+
for (const [key, value] of Object.entries(comment)) {
|
|
32
|
+
if (key.startsWith("x_")) {
|
|
33
|
+
extensions[key] = value;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return extensions;
|
|
37
|
+
}
|
|
38
|
+
function toSlimComments(doc) {
|
|
39
|
+
return doc.comments.map((c) => ({
|
|
40
|
+
id: c.id,
|
|
41
|
+
author: c.author || "Unknown",
|
|
42
|
+
text: c.text || "",
|
|
43
|
+
line: c.line ?? null,
|
|
44
|
+
end_line: c.end_line ?? null,
|
|
45
|
+
start_column: c.start_column ?? null,
|
|
46
|
+
end_column: c.end_column ?? null,
|
|
47
|
+
selected_text: c.selected_text || null,
|
|
48
|
+
resolved: !!c.resolved,
|
|
49
|
+
reply_to: c.reply_to || null,
|
|
50
|
+
severity: c.severity || null,
|
|
51
|
+
type: c.type || null,
|
|
52
|
+
timestamp: c.timestamp || null,
|
|
53
|
+
...getExtensionFields(c)
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
function groupByLine(comments) {
|
|
57
|
+
const rootComments = comments.filter((c) => !c.reply_to && c.line != null);
|
|
58
|
+
const replies = comments.filter((c) => c.reply_to);
|
|
59
|
+
const replyMap = /* @__PURE__ */ new Map();
|
|
60
|
+
for (const r of replies) {
|
|
61
|
+
const list = replyMap.get(r.reply_to) || [];
|
|
62
|
+
list.push(r);
|
|
63
|
+
replyMap.set(r.reply_to, list);
|
|
64
|
+
}
|
|
65
|
+
const lineMap = /* @__PURE__ */ new Map();
|
|
66
|
+
for (const c of rootComments) {
|
|
67
|
+
const line = c.line;
|
|
68
|
+
const threads = lineMap.get(line) || [];
|
|
69
|
+
threads.push({
|
|
70
|
+
comment: c,
|
|
71
|
+
replies: replyMap.get(c.id) || []
|
|
72
|
+
});
|
|
73
|
+
lineMap.set(line, threads);
|
|
74
|
+
}
|
|
75
|
+
return lineMap;
|
|
76
|
+
}
|
|
77
|
+
function resolveComments(loader, options, env) {
|
|
78
|
+
const showResolved = options.showResolved ?? true;
|
|
79
|
+
const doc = loader(options, env);
|
|
80
|
+
if (!doc || !doc.comments || doc.comments.length === 0) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
let comments = toSlimComments(doc);
|
|
84
|
+
if (!showResolved) {
|
|
85
|
+
comments = comments.filter((c) => !c.resolved);
|
|
86
|
+
}
|
|
87
|
+
if (comments.length === 0) return null;
|
|
88
|
+
const lineMap = groupByLine(comments);
|
|
89
|
+
return { lineMap, comments };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// src/rules/core.ts
|
|
93
|
+
function installCoreRule(md, resolveComments2, options = {}) {
|
|
94
|
+
md.core.ruler.push("mrsf_inject", (state) => {
|
|
95
|
+
const result = resolveComments2(state);
|
|
96
|
+
if (!result) return;
|
|
97
|
+
const { lineMap } = result;
|
|
98
|
+
const tokens = state.tokens;
|
|
99
|
+
const TokenCtor = state.Token;
|
|
100
|
+
const processed = /* @__PURE__ */ new Set();
|
|
101
|
+
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
102
|
+
const token = tokens[i];
|
|
103
|
+
const map = token.map;
|
|
104
|
+
if (!map) continue;
|
|
105
|
+
if (token.type === "inline") continue;
|
|
106
|
+
const startLine1 = map[0] + 1;
|
|
107
|
+
const endLine1 = map[1];
|
|
108
|
+
token.attrSet("data-mrsf-line", String(startLine1));
|
|
109
|
+
token.attrSet("data-mrsf-start-line", String(startLine1));
|
|
110
|
+
token.attrSet("data-mrsf-end-line", String(endLine1));
|
|
111
|
+
for (let line0 = map[0]; line0 < map[1]; line0++) {
|
|
112
|
+
const line = line0 + 1;
|
|
113
|
+
if (processed.has(line)) continue;
|
|
114
|
+
processed.add(line);
|
|
115
|
+
const threads = lineMap.get(line);
|
|
116
|
+
if (threads && threads.length > 0) {
|
|
117
|
+
if (options.lineHighlight) {
|
|
118
|
+
const existingClass = token.attrGet("class") || "";
|
|
119
|
+
if (!existingClass.includes("mrsf-line-highlight")) {
|
|
120
|
+
token.attrSet(
|
|
121
|
+
"class",
|
|
122
|
+
existingClass ? `${existingClass} mrsf-line-highlight` : "mrsf-line-highlight"
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
token.attrSet("data-mrsf-line", String(line));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const allThreads = [];
|
|
131
|
+
for (const threads of lineMap.values()) {
|
|
132
|
+
allThreads.push(...threads);
|
|
133
|
+
}
|
|
134
|
+
if (allThreads.length > 0) {
|
|
135
|
+
const scriptToken = new TokenCtor("mrsf_data_script", "", 0);
|
|
136
|
+
scriptToken.meta = { threads: allThreads };
|
|
137
|
+
tokens.push(scriptToken);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/rules/renderer.ts
|
|
143
|
+
function escapeAttribute(value) {
|
|
144
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
145
|
+
}
|
|
146
|
+
function installRendererRules(md, options = {}) {
|
|
147
|
+
md.renderer.rules["mrsf_data_script"] = (tokens, idx) => {
|
|
148
|
+
const { threads } = tokens[idx].meta;
|
|
149
|
+
const payload = JSON.stringify({ threads });
|
|
150
|
+
if (options.dataContainer === "element") {
|
|
151
|
+
const elementId = options.dataElementId || "mrsf-comment-data";
|
|
152
|
+
return `<div id="${escapeAttribute(elementId)}" data-mrsf-json="${escapeAttribute(payload)}" aria-hidden="true"></div>`;
|
|
153
|
+
}
|
|
154
|
+
const data = payload.replace(/</g, "\\u003c");
|
|
155
|
+
return `<script type="application/mrsf+json">${data}</script>`;
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// src/shared.ts
|
|
160
|
+
function createMrsfPlugin(loader) {
|
|
161
|
+
return function mrsfPlugin2(md, options = {}) {
|
|
162
|
+
installCoreRule(
|
|
163
|
+
md,
|
|
164
|
+
(state) => resolveComments(loader, options, state.env),
|
|
165
|
+
{ lineHighlight: options.lineHighlight ?? false }
|
|
166
|
+
);
|
|
167
|
+
installRendererRules(md, {
|
|
168
|
+
dataContainer: options.dataContainer,
|
|
169
|
+
dataElementId: options.dataElementId
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// src/browser.ts
|
|
175
|
+
var mrsfPlugin = createMrsfPlugin((options, env) => {
|
|
176
|
+
if (options.comments) {
|
|
177
|
+
return options.comments;
|
|
178
|
+
}
|
|
179
|
+
if (options.loader) {
|
|
180
|
+
try {
|
|
181
|
+
return options.loader(options, env);
|
|
182
|
+
} catch {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (options.sidecarPath || options.documentPath) {
|
|
187
|
+
console.warn(
|
|
188
|
+
"[@mrsf/markdown-it-mrsf] sidecarPath and documentPath require Node.js. Use `comments` or `loader` options in browser environments."
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
return null;
|
|
192
|
+
});
|
|
193
|
+
var browser_default = mrsfPlugin;
|
|
194
|
+
//# sourceMappingURL=browser.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/browser.ts", "../src/comments.ts", "../src/rules/core.ts", "../src/rules/renderer.ts", "../src/shared.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Browser-safe entry point for @mrsf/markdown-it-mrsf.\n *\n * This entry is automatically selected by bundlers (Vite, webpack, esbuild)\n * via the `\"browser\"` export condition in package.json. It supports the\n * `comments` and `loader` provisioning modes \u2014 no Node.js file-system APIs.\n *\n * You do NOT need to import this directly. Just use:\n * import { mrsfPlugin } from \"@mrsf/markdown-it-mrsf\";\n *\n * Your bundler will resolve to this file automatically when targeting\n * a browser environment.\n */\n\nimport type { MrsfPluginOptions } from \"./types.js\";\nimport { createMrsfPlugin } from \"./shared.js\";\n\nexport type { MrsfPluginOptions, SlimComment, CommentThread, LineMap, CommentLoader } from \"./types.js\";\n\n/**\n * The markdown-it plugin function (browser-safe).\n *\n * Supports `comments` (inline data) and `loader` (custom function) options.\n */\nexport const mrsfPlugin = createMrsfPlugin((options: MrsfPluginOptions, env?: unknown) => {\n if (options.comments) {\n return options.comments;\n }\n\n if (options.loader) {\n try {\n return options.loader(options, env);\n } catch {\n return null;\n }\n }\n\n if (options.sidecarPath || options.documentPath) {\n console.warn(\n \"[@mrsf/markdown-it-mrsf] sidecarPath and documentPath require Node.js. \" +\n \"Use `comments` or `loader` options in browser environments.\"\n );\n }\n\n return null;\n});\n\nexport default mrsfPlugin;\n", "/* ---------------------------------------------------------------\n * AUTO-GENERATED \u2014 DO NOT EDIT\n *\n * Source: plugins/shared/src/comments.ts\n * Run `node plugins/sync-types.mjs` to regenerate.\n * --------------------------------------------------------------- */\n\n/**\n * Shared comment loading and grouping logic for MRSF rendering plugins.\n */\n\nimport type { MrsfDocument } from \"@mrsf/cli\";\nimport type { MrsfPluginOptions, SlimComment, CommentThread, LineMap, CommentLoader } from \"./types.js\";\n\nexport type { CommentLoader };\n\nfunction getExtensionFields(comment: Record<string, unknown>): Record<`x_${string}`, unknown> {\n const extensions: Record<`x_${string}`, unknown> = {};\n\n for (const [key, value] of Object.entries(comment)) {\n if (key.startsWith(\"x_\")) {\n extensions[key as `x_${string}`] = value;\n }\n }\n\n return extensions;\n}\n\n/**\n * Convert an MrsfDocument into a slim comment array.\n */\nexport function toSlimComments(doc: MrsfDocument): SlimComment[] {\n return doc.comments.map((c) => ({\n id: c.id,\n author: c.author || \"Unknown\",\n text: c.text || \"\",\n line: c.line ?? null,\n end_line: c.end_line ?? null,\n start_column: c.start_column ?? null,\n end_column: c.end_column ?? null,\n selected_text: c.selected_text || null,\n resolved: !!c.resolved,\n reply_to: c.reply_to || null,\n severity: c.severity || null,\n type: c.type || null,\n timestamp: c.timestamp || null,\n ...getExtensionFields(c as Record<string, unknown>),\n }));\n}\n\n/**\n * Group comments by line number, threading replies under parents.\n */\nexport function groupByLine(comments: SlimComment[]): LineMap {\n const rootComments = comments.filter((c) => !c.reply_to && c.line != null);\n const replies = comments.filter((c) => c.reply_to);\n\n const replyMap = new Map<string, SlimComment[]>();\n for (const r of replies) {\n const list = replyMap.get(r.reply_to!) || [];\n list.push(r);\n replyMap.set(r.reply_to!, list);\n }\n\n const lineMap: LineMap = new Map();\n for (const c of rootComments) {\n const line = c.line!;\n const threads = lineMap.get(line) || [];\n threads.push({\n comment: c,\n replies: replyMap.get(c.id) || [],\n });\n lineMap.set(line, threads);\n }\n\n return lineMap;\n}\n\n/**\n * Resolve options into a filtered LineMap ready for rendering.\n * Returns null if there are no comments to render.\n */\nexport function resolveComments(\n loader: CommentLoader,\n options: MrsfPluginOptions,\n env?: unknown,\n): { lineMap: LineMap; comments: SlimComment[] } | null {\n const showResolved = options.showResolved ?? true;\n\n const doc = loader(options, env);\n if (!doc || !doc.comments || doc.comments.length === 0) {\n return null;\n }\n\n let comments = toSlimComments(doc);\n if (!showResolved) {\n comments = comments.filter((c) => !c.resolved);\n }\n\n if (comments.length === 0) return null;\n\n const lineMap = groupByLine(comments);\n return { lineMap, comments };\n}\n", "/**\n * MRSF markdown-it plugin \u2014 core rule (overlay gutter architecture).\n *\n * Walks the parsed token stream and annotates block tokens with\n * `data-mrsf-line` attributes. Adds `mrsf-line-highlight` class on\n * commented lines. Appends an `mrsf_data_script` token with serialized\n * comment data for the client-side MrsfController.\n *\n * NO visual tokens are injected \u2014 all badges, tooltips, and gutter\n * elements are created at runtime by the controller.\n */\n\nimport type Token from \"markdown-it/lib/token.mjs\";\nimport type { Nesting } from \"markdown-it/lib/token.mjs\";\nimport type StateCore from \"markdown-it/lib/rules_core/state_core.mjs\";\nimport type { LineMap, CommentThread, SlimComment } from \"../types.js\";\n\nexport interface CoreRuleOptions {\n /** Whether to add mrsf-line-highlight class on commented tokens. Default: false. */\n lineHighlight?: boolean;\n}\n\nexport interface ResolvedCommentData {\n lineMap: LineMap;\n comments: SlimComment[];\n}\n\n/**\n * Install the MRSF core rule on a markdown-it instance.\n */\nexport function installCoreRule(\n md: { core: { ruler: { push: (name: string, fn: (state: StateCore) => void) => void } } },\n resolveComments: (state: StateCore) => ResolvedCommentData | null,\n options: CoreRuleOptions = {},\n): void {\n md.core.ruler.push(\"mrsf_inject\", (state: StateCore) => {\n const result = resolveComments(state);\n if (!result) return;\n\n const { lineMap } = result;\n const tokens = state.tokens;\n const TokenCtor = state.Token;\n const processed = new Set<number>();\n\n for (let i = tokens.length - 1; i >= 0; i--) {\n const token = tokens[i];\n const map = token.map;\n if (!map) continue;\n\n // Skip inline tokens \u2014 process their parent block tokens only.\n if (token.type === \"inline\") continue;\n\n // Annotate the element with line range\n const startLine1 = map[0] + 1;\n const endLine1 = map[1];\n token.attrSet(\"data-mrsf-line\", String(startLine1));\n token.attrSet(\"data-mrsf-start-line\", String(startLine1));\n token.attrSet(\"data-mrsf-end-line\", String(endLine1));\n\n // Check each line in this token's range for comments\n for (let line0 = map[0]; line0 < map[1]; line0++) {\n const line = line0 + 1; // 1-based\n if (processed.has(line)) continue;\n processed.add(line);\n\n const threads = lineMap.get(line);\n if (threads && threads.length > 0) {\n if (options.lineHighlight) {\n const existingClass = token.attrGet(\"class\") || \"\";\n if (!existingClass.includes(\"mrsf-line-highlight\")) {\n token.attrSet(\n \"class\",\n existingClass\n ? `${existingClass} mrsf-line-highlight`\n : \"mrsf-line-highlight\",\n );\n }\n }\n token.attrSet(\"data-mrsf-line\", String(line));\n }\n }\n }\n\n // Append a data script token with all comment data\n const allThreads: CommentThread[] = [];\n for (const threads of lineMap.values()) {\n allThreads.push(...threads);\n }\n if (allThreads.length > 0) {\n const scriptToken = new TokenCtor(\"mrsf_data_script\", \"\", 0);\n scriptToken.meta = { threads: allThreads };\n tokens.push(scriptToken);\n }\n });\n}\n", "/**\n * MRSF markdown-it plugin \u2014 renderer rules (overlay gutter architecture).\n *\n * Adds a single custom renderer rule:\n * - mrsf_data_script: renders a <script type=\"application/mrsf+json\">\n * containing serialized comment data for the MrsfController.\n */\n\nimport type { CommentThread } from \"../types.js\";\n\nexport interface RendererRuleOptions {\n dataContainer?: \"script\" | \"element\";\n dataElementId?: string;\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n\n/**\n * Install MRSF renderer rules on a markdown-it instance.\n */\nexport function installRendererRules(\n md: { renderer: { rules: Record<string, ((...args: any[]) => string) | undefined> } },\n options: RendererRuleOptions = {},\n): void {\n md.renderer.rules[\"mrsf_data_script\"] = (\n tokens: { meta: { threads: CommentThread[] } }[],\n idx: number,\n ): string => {\n const { threads } = tokens[idx].meta;\n const payload = JSON.stringify({ threads });\n if (options.dataContainer === \"element\") {\n const elementId = options.dataElementId || \"mrsf-comment-data\";\n return `<div id=\"${escapeAttribute(elementId)}\" data-mrsf-json=\"${escapeAttribute(payload)}\" aria-hidden=\"true\"></div>`;\n }\n\n // Escape < to prevent script tag injection (XSS safety)\n const data = payload.replace(/</g, \"\\\\u003c\");\n return `<script type=\"application/mrsf+json\">${data}</script>`;\n };\n}\n", "/**\n * Shared logic for @mrsf/markdown-it-mrsf.\n *\n * Contains the plugin factory using shared comment loading/grouping logic.\n */\n\nimport type MarkdownIt from \"markdown-it\";\nimport type { MrsfPluginOptions, CommentLoader } from \"./types.js\";\nimport { resolveComments } from \"./comments.js\";\nimport { installCoreRule } from \"./rules/core.js\";\nimport { installRendererRules } from \"./rules/renderer.js\";\n\n/**\n * Create a markdown-it plugin function with the given comment loader.\n *\n * @param loader - Function that resolves sidecar data from plugin options\n * @returns A markdown-it plugin function\n */\nexport function createMrsfPlugin(loader: CommentLoader) {\n return function mrsfPlugin(md: MarkdownIt, options: MrsfPluginOptions = {}): void {\n installCoreRule(\n md,\n (state) => resolveComments(loader, options, state.env),\n { lineHighlight: options.lineHighlight ?? false },\n );\n installRendererRules(md, {\n dataContainer: options.dataContainer,\n dataElementId: options.dataElementId,\n });\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["resolveComments", "mrsfPlugin"]
|
|
7
|
+
}
|