@devaccel-labs/comment-service 0.8.0 → 0.9.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.
|
@@ -208,12 +208,13 @@ function overlayFor(element) {
|
|
|
208
208
|
const role = node.getAttribute("role") || (node.tagName === "DIALOG" ? "dialog" : "dialog");
|
|
209
209
|
return { role, name: labelFor(node) || "dialog" };
|
|
210
210
|
}
|
|
211
|
-
function
|
|
211
|
+
function fiberOf(element) {
|
|
212
212
|
const key2 = Object.keys(element).find((name) => name.startsWith("__reactFiber$") || name.startsWith("__reactInternalInstance$"));
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
return key2 ? element[key2] : void 0;
|
|
214
|
+
}
|
|
215
|
+
function fiberNames(element) {
|
|
215
216
|
const names = [];
|
|
216
|
-
let fiber = element
|
|
217
|
+
let fiber = fiberOf(element);
|
|
217
218
|
for (let guard = 0; fiber && guard < 40; guard++) {
|
|
218
219
|
const type = fiber.type;
|
|
219
220
|
if (typeof type === "function") {
|
|
@@ -222,10 +223,30 @@ function fiberNames(element) {
|
|
|
222
223
|
if (name && !name.startsWith("_"))
|
|
223
224
|
names.push(name);
|
|
224
225
|
}
|
|
225
|
-
fiber = fiber.return;
|
|
226
|
+
fiber = fiber.return ?? void 0;
|
|
226
227
|
}
|
|
227
228
|
return names.reverse();
|
|
228
229
|
}
|
|
230
|
+
function fiberStamps(element) {
|
|
231
|
+
const stamps = [];
|
|
232
|
+
let fiber = fiberOf(element);
|
|
233
|
+
for (let guard = 0; fiber && guard < 2e3; guard++) {
|
|
234
|
+
const props = fiber.memoizedProps;
|
|
235
|
+
const name = props && typeof props === "object" ? props["data-cs-cmp"] : void 0;
|
|
236
|
+
if (typeof name === "string" && name) {
|
|
237
|
+
const file = props?.["data-cs-file"];
|
|
238
|
+
stamps.push({ name, file: typeof file === "string" ? file : null });
|
|
239
|
+
}
|
|
240
|
+
fiber = fiber.return ?? void 0;
|
|
241
|
+
}
|
|
242
|
+
return stamps;
|
|
243
|
+
}
|
|
244
|
+
function bodyChild(element) {
|
|
245
|
+
let current = element;
|
|
246
|
+
while (current?.parentElement && current.parentElement !== current.ownerDocument.body)
|
|
247
|
+
current = current.parentElement;
|
|
248
|
+
return current?.parentElement ? current : null;
|
|
249
|
+
}
|
|
229
250
|
function obviouslyHidden(element) {
|
|
230
251
|
const dialog = element.closest("dialog");
|
|
231
252
|
if (dialog instanceof HTMLDialogElement && !dialog.open)
|
|
@@ -253,6 +274,18 @@ function ownership(element) {
|
|
|
253
274
|
}
|
|
254
275
|
current = current.parentElement;
|
|
255
276
|
}
|
|
277
|
+
const top = bodyChild(element);
|
|
278
|
+
if (top && top !== element && (!owner || !top.contains(owner))) {
|
|
279
|
+
const stamps = fiberStamps(element);
|
|
280
|
+
if (stamps.length && (!owner || stamps[0].name !== owner.getAttribute("data-cs-cmp"))) {
|
|
281
|
+
return {
|
|
282
|
+
component: stamps[0],
|
|
283
|
+
stack: stamps.map((stamp) => stamp.name).reverse(),
|
|
284
|
+
componentRoot: false,
|
|
285
|
+
owner: top
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
256
289
|
if (owner) {
|
|
257
290
|
return {
|
|
258
291
|
component: { name: owner.getAttribute("data-cs-cmp") || "component", file: owner.getAttribute("data-cs-file") },
|
|
@@ -349,7 +382,7 @@ function elementAt(x, y) {
|
|
|
349
382
|
return null;
|
|
350
383
|
}
|
|
351
384
|
function describeElement(element) {
|
|
352
|
-
const name = element.
|
|
385
|
+
const name = ownership(element).component?.name;
|
|
353
386
|
const label = labelFor(element);
|
|
354
387
|
if (name && label)
|
|
355
388
|
return `${name} \u2014 ${label}`;
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
resolveInDocument,
|
|
10
10
|
runtimeVersion,
|
|
11
11
|
stripHandoffFromUrl
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-KKE43QYT.js";
|
|
13
13
|
|
|
14
14
|
// ../react/dist/runtime.js
|
|
15
15
|
import { jsx as _jsx7 } from "react/jsx-runtime";
|
|
@@ -491,10 +491,7 @@ function MentionTextarea({ value, onValueChange, members, selfEmail, onMention,
|
|
|
491
491
|
} }), open && rect && root ? createPortal(_jsx4("div", { className: "cs-people cs-hit", role: "listbox", "data-cs-ui": "mention-list", style: {
|
|
492
492
|
left: Math.min(rect.left, window.innerWidth - 272),
|
|
493
493
|
...below ? { top: rect.bottom + 6 } : { bottom: window.innerHeight - rect.top + 6 }
|
|
494
|
-
}, children: matches.map((member) => _jsxs4("div", { role: "option", "aria-selected": member === selected, "data-cs-ui": "mention-option", className: member === selected ? "cs-person is-on" : "cs-person",
|
|
495
|
-
event.preventDefault();
|
|
496
|
-
insert(member);
|
|
497
|
-
}, onMouseEnter: () => setIndex(matches.indexOf(member)), children: [_jsx4("span", { className: "cs-avatar", style: { width: 24, height: 24, fontSize: 10, background: colorFor(member.name) }, children: initials(member.name) }), _jsxs4("span", { className: "cs-person-text", children: [_jsx4("strong", { children: member.name }), _jsx4("small", { children: member.email })] })] }, member.id)) }), root) : null] });
|
|
494
|
+
}, children: matches.map((member) => _jsxs4("div", { role: "option", "aria-selected": member === selected, "data-cs-ui": "mention-option", className: member === selected ? "cs-person is-on" : "cs-person", onClick: () => insert(member), onMouseEnter: () => setIndex(matches.indexOf(member)), children: [_jsx4("span", { className: "cs-avatar", style: { width: 24, height: 24, fontSize: 10, background: colorFor(member.name) }, children: initials(member.name) }), _jsxs4("span", { className: "cs-person-text", children: [_jsx4("strong", { children: member.name }), _jsx4("small", { children: member.email })] })] }, member.id)) }), root) : null] });
|
|
498
495
|
}
|
|
499
496
|
|
|
500
497
|
// ../../node_modules/modern-screenshot/dist/index.mjs
|
|
@@ -2921,38 +2918,73 @@ function ToolbarApp({ sessionPath = "/api/comment-service/session", pollMs = 4e3
|
|
|
2921
2918
|
savePrefs({ ...prefs, pinsHidden: next });
|
|
2922
2919
|
say(next ? "Pins hidden \xB7 H to show" : "Pins shown");
|
|
2923
2920
|
}, [pinsHidden, prefs, savePrefs, say]);
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2921
|
+
const onKey = useRef3(() => {
|
|
2922
|
+
});
|
|
2923
|
+
onKey.current = (event) => {
|
|
2924
|
+
if (event.defaultPrevented)
|
|
2925
|
+
return;
|
|
2926
|
+
if (event.key === "Escape") {
|
|
2927
|
+
if (mode !== "browse" || draft || surface !== "none") {
|
|
2928
|
+
event.stopImmediatePropagation();
|
|
2929
|
+
setMode("browse");
|
|
2930
|
+
setDraft(null);
|
|
2931
|
+
setReattachId(null);
|
|
2932
|
+
setSurface("none");
|
|
2933
|
+
setConfirmReset(false);
|
|
2934
|
+
setRenaming(null);
|
|
2938
2935
|
}
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2936
|
+
return;
|
|
2937
|
+
}
|
|
2938
|
+
if (!member || event.metaKey || event.ctrlKey || event.altKey || isTyping(event.target))
|
|
2939
|
+
return;
|
|
2940
|
+
const key = event.key.toLowerCase();
|
|
2941
|
+
if (key === "c")
|
|
2942
|
+
startComment();
|
|
2943
|
+
else if (key === "i") {
|
|
2944
|
+
setView(prefs.view ?? "list");
|
|
2945
|
+
setSurface((current) => current === "inbox" ? "none" : "inbox");
|
|
2946
|
+
} else if (key === "h")
|
|
2947
|
+
togglePins();
|
|
2948
|
+
else
|
|
2949
|
+
return;
|
|
2950
|
+
event.preventDefault();
|
|
2951
|
+
event.stopImmediatePropagation();
|
|
2952
|
+
};
|
|
2953
|
+
useEffect2(() => {
|
|
2954
|
+
const inToolbar = (event) => event.target instanceof Element && Boolean(event.target.closest("#cs-root"));
|
|
2955
|
+
const fromPage = (event) => {
|
|
2956
|
+
if (!inToolbar(event))
|
|
2957
|
+
onKey.current(event);
|
|
2958
|
+
};
|
|
2959
|
+
const fromToolbar = (event) => {
|
|
2960
|
+
if (inToolbar(event))
|
|
2961
|
+
onKey.current(event);
|
|
2962
|
+
};
|
|
2963
|
+
window.addEventListener("keydown", fromPage, true);
|
|
2964
|
+
document.addEventListener("keydown", fromToolbar);
|
|
2965
|
+
return () => {
|
|
2966
|
+
window.removeEventListener("keydown", fromPage, true);
|
|
2967
|
+
document.removeEventListener("keydown", fromToolbar);
|
|
2968
|
+
};
|
|
2969
|
+
}, []);
|
|
2970
|
+
useEffect2(() => {
|
|
2971
|
+
const textControl = "input, textarea, select, [contenteditable]";
|
|
2972
|
+
const shield = (event) => {
|
|
2973
|
+
const target = event.target;
|
|
2974
|
+
if (!(target instanceof Element) || !target.closest("#cs-root"))
|
|
2950
2975
|
return;
|
|
2951
|
-
event.
|
|
2976
|
+
event.stopPropagation();
|
|
2977
|
+
if (event.type === "mousedown" && !target.closest(textControl))
|
|
2978
|
+
event.preventDefault();
|
|
2952
2979
|
};
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2980
|
+
const types = ["pointerdown", "mousedown", "touchstart"];
|
|
2981
|
+
for (const type of types)
|
|
2982
|
+
window.addEventListener(type, shield, true);
|
|
2983
|
+
return () => {
|
|
2984
|
+
for (const type of types)
|
|
2985
|
+
window.removeEventListener(type, shield, true);
|
|
2986
|
+
};
|
|
2987
|
+
}, []);
|
|
2956
2988
|
useEffect2(() => {
|
|
2957
2989
|
if (mode === "browse") {
|
|
2958
2990
|
setHighlight(null);
|
|
@@ -3009,12 +3041,24 @@ function ToolbarApp({ sessionPath = "/api/comment-service/session", pollMs = 4e3
|
|
|
3009
3041
|
setMode("browse");
|
|
3010
3042
|
setError("");
|
|
3011
3043
|
};
|
|
3044
|
+
const swallow = (event) => {
|
|
3045
|
+
if (event.target instanceof Element && event.target.closest("#cs-root"))
|
|
3046
|
+
return;
|
|
3047
|
+
if (!event.type.startsWith("touch"))
|
|
3048
|
+
event.preventDefault();
|
|
3049
|
+
event.stopPropagation();
|
|
3050
|
+
};
|
|
3051
|
+
const presses = ["pointerdown", "mousedown", "pointerup", "mouseup", "touchstart", "touchend"];
|
|
3012
3052
|
document.addEventListener("mousemove", onMove, true);
|
|
3013
|
-
|
|
3053
|
+
window.addEventListener("click", onClick, true);
|
|
3054
|
+
for (const type of presses)
|
|
3055
|
+
window.addEventListener(type, swallow, true);
|
|
3014
3056
|
return () => {
|
|
3015
3057
|
document.documentElement.style.cursor = "";
|
|
3016
3058
|
document.removeEventListener("mousemove", onMove, true);
|
|
3017
|
-
|
|
3059
|
+
window.removeEventListener("click", onClick, true);
|
|
3060
|
+
for (const type of presses)
|
|
3061
|
+
window.removeEventListener(type, swallow, true);
|
|
3018
3062
|
};
|
|
3019
3063
|
}, [member, mode, portal, reattachId, refresh, say, session]);
|
|
3020
3064
|
useEffect2(() => {
|
package/dist/react.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
captureHandoff,
|
|
3
3
|
runtimeVersion
|
|
4
|
-
} from "./chunks/chunk-
|
|
4
|
+
} from "./chunks/chunk-KKE43QYT.js";
|
|
5
5
|
|
|
6
6
|
// ../react/dist/loader.js
|
|
7
7
|
import { useEffect, useRef } from "react";
|
|
8
8
|
captureHandoff();
|
|
9
|
-
var bundled = () => import("./chunks/runtime-
|
|
9
|
+
var bundled = () => import("./chunks/runtime-2ZDPCFHS.js");
|
|
10
10
|
async function serviceUrl(sessionPath) {
|
|
11
11
|
try {
|
|
12
12
|
const response = await fetch(sessionPath, {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export declare function toProjectPath(filename: string, root: string): string;
|
|
2
2
|
/**
|
|
3
|
-
* Stamp the root
|
|
3
|
+
* Stamp the root node of each component of each component with a stable file + component name.
|
|
4
4
|
* Line numbers are intentionally not included: moving the component in the file
|
|
5
|
-
* or on the page must not change the stamp.
|
|
5
|
+
* or on the page must not change the stamp. A root that is itself a component
|
|
6
|
+
* (`<DropdownMenu>`, `<Menu.Root>`) gets the stamp as a prop: it reaches the DOM when
|
|
7
|
+
* the component spreads its props, and the toolbar reads it from React's tree when
|
|
8
|
+
* the component renders into a portal.
|
|
6
9
|
*/
|
|
7
10
|
export declare function annotateSource(code: string, filename: string, root: string): string;
|
package/dist/vite.js
CHANGED
|
@@ -58,6 +58,16 @@ function setAttr(path, name, value) {
|
|
|
58
58
|
return;
|
|
59
59
|
path.node.openingElement.attributes.push(t.jsxAttribute(t.jsxIdentifier(name), t.stringLiteral(value)));
|
|
60
60
|
}
|
|
61
|
+
var unstampable = /^(?:React\.)?(?:Fragment|Suspense|StrictMode|Profiler|Activity|ViewTransition)$|\.(?:Provider|Consumer)$/;
|
|
62
|
+
function jsxName(name) {
|
|
63
|
+
if (t.isJSXIdentifier(name))
|
|
64
|
+
return name.name;
|
|
65
|
+
if (t.isJSXMemberExpression(name)) {
|
|
66
|
+
const object = jsxName(name.object);
|
|
67
|
+
return object ? `${object}.${name.property.name}` : null;
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
61
71
|
function annotateSource(code, filename, root) {
|
|
62
72
|
if (!filename.match(/\.[jt]sx$/))
|
|
63
73
|
return code;
|
|
@@ -77,10 +87,8 @@ function annotateSource(code, filename, root) {
|
|
|
77
87
|
let changed = false;
|
|
78
88
|
traverse()(ast, {
|
|
79
89
|
JSXElement(path) {
|
|
80
|
-
const
|
|
81
|
-
if (!
|
|
82
|
-
return;
|
|
83
|
-
if (opening.name[0] !== opening.name[0].toLowerCase())
|
|
90
|
+
const tag = jsxName(path.node.openingElement.name);
|
|
91
|
+
if (!tag || unstampable.test(tag))
|
|
84
92
|
return;
|
|
85
93
|
if (!isRootJsx(path))
|
|
86
94
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devaccel-labs/comment-service",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "In-UI component comments for TanStack Start on Cloudflare. Anchors survive redeploys.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"esbuild": "^0.28.1",
|
|
46
|
-
"@devaccel/comment-core": "0.1.0",
|
|
47
46
|
"@devaccel/comment-compiler": "0.1.0",
|
|
47
|
+
"@devaccel/comment-core": "0.1.0",
|
|
48
48
|
"@devaccel/comment-react": "0.1.0",
|
|
49
49
|
"@devaccel/comment-server": "0.1.0",
|
|
50
50
|
"@devaccel/comment-start": "0.1.0"
|