@abbox/inspector 0.4.8 → 0.4.10
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/dist/host/client-bridge.d.ts.map +1 -1
- package/dist/host/client-bridge.js +52 -6
- package/dist/host/validate.d.ts.map +1 -1
- package/dist/host/validate.js +21 -1
- package/dist/react/AbboxInspectorBoot.d.ts +11 -2
- package/dist/react/AbboxInspectorBoot.d.ts.map +1 -1
- package/dist/react/AbboxInspectorBoot.js +14 -4
- package/dist/runtime/bootstrap.d.ts +1 -0
- package/dist/runtime/bootstrap.d.ts.map +1 -1
- package/dist/runtime/bootstrap.js +10 -1
- package/dist/runtime/inspector.d.ts.map +1 -1
- package/dist/runtime/inspector.js +13 -2
- package/dist/runtime/overlay.d.ts +4 -0
- package/dist/runtime/overlay.d.ts.map +1 -1
- package/dist/runtime/overlay.js +73 -2
- package/package.json +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-bridge.d.ts","sourceRoot":"","sources":["../../src/host/client-bridge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client-bridge.d.ts","sourceRoot":"","sources":["../../src/host/client-bridge.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CAqHjB"}
|
|
@@ -2,15 +2,51 @@ import { ABBBOX_INSPECTOR_CHANNEL, PROTOCOL_VERSION, } from "../protocol.js";
|
|
|
2
2
|
import { createInspectorRuntime } from "../runtime/inspector.js";
|
|
3
3
|
import { withLocalhostAliases } from "./origin-aliases.js";
|
|
4
4
|
import { validateIncomingMessage } from "./validate.js";
|
|
5
|
+
// Only available in browser context
|
|
6
|
+
let addDebugLog = () => { };
|
|
7
|
+
if (typeof window !== "undefined") {
|
|
8
|
+
import("../runtime/overlay.js").then((m) => {
|
|
9
|
+
addDebugLog = m.addDebugLog;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
5
12
|
export function createInspectorClient(options) {
|
|
6
13
|
const win = options.window ?? globalThis.window;
|
|
7
14
|
const doc = options.document ?? win.document;
|
|
8
15
|
const allowedOrigins = withLocalhostAliases(options.allowedHostOrigins);
|
|
16
|
+
addDebugLog(`Client init: sessionId=${options.sessionId}`);
|
|
17
|
+
addDebugLog(`Allowed origins: ${allowedOrigins.join(", ")}`);
|
|
18
|
+
addDebugLog(`Window href: ${win.location.href}`);
|
|
19
|
+
addDebugLog(`Parent href: ${win.parent?.location?.href ?? "N/A"}`);
|
|
9
20
|
const send = (message) => {
|
|
10
|
-
if (!win.parent || win.parent === win)
|
|
21
|
+
if (!win.parent || win.parent === win) {
|
|
22
|
+
addDebugLog(`send() skipped: parent=${!!win.parent}`);
|
|
11
23
|
return;
|
|
24
|
+
}
|
|
25
|
+
let sent = false;
|
|
26
|
+
// Try each allowed origin
|
|
12
27
|
for (const targetOrigin of allowedOrigins) {
|
|
13
|
-
|
|
28
|
+
try {
|
|
29
|
+
addDebugLog(`→ ${message.type} on ${targetOrigin}`);
|
|
30
|
+
win.parent.postMessage(message, targetOrigin);
|
|
31
|
+
sent = true;
|
|
32
|
+
addDebugLog(`✓ ${message.type} sent`);
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
addDebugLog(`✗ ${targetOrigin}: ${String(err).slice(0, 40)}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// If all allowed origins failed, try wildcard
|
|
40
|
+
if (!sent) {
|
|
41
|
+
try {
|
|
42
|
+
addDebugLog(`→ ${message.type} on wildcard`);
|
|
43
|
+
win.parent.postMessage(message, "*");
|
|
44
|
+
sent = true;
|
|
45
|
+
addDebugLog(`✓ ${message.type} sent via *`);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
addDebugLog(`✗ Wildcard: ${String(err).slice(0, 40)}`);
|
|
49
|
+
}
|
|
14
50
|
}
|
|
15
51
|
};
|
|
16
52
|
const base = () => ({
|
|
@@ -47,15 +83,25 @@ export function createInspectorClient(options) {
|
|
|
47
83
|
sessionId: options.sessionId,
|
|
48
84
|
allowedOrigins,
|
|
49
85
|
});
|
|
50
|
-
if (!msg)
|
|
86
|
+
if (!msg) {
|
|
87
|
+
addDebugLog(`Message rejected from ${event.origin}`);
|
|
51
88
|
return;
|
|
52
|
-
|
|
89
|
+
}
|
|
90
|
+
addDebugLog(`← Received: ${msg.type}`);
|
|
91
|
+
if (msg.type === "INSPECTOR_HOST_HELLO") {
|
|
92
|
+
addDebugLog(` Sending INSPECTOR_READY`);
|
|
53
93
|
sendReady();
|
|
54
|
-
|
|
94
|
+
}
|
|
95
|
+
if (msg.type === "INSPECTOR_ENABLE") {
|
|
96
|
+
addDebugLog(` Enabling inspector runtime`);
|
|
55
97
|
runtime.enable();
|
|
56
|
-
|
|
98
|
+
}
|
|
99
|
+
if (msg.type === "INSPECTOR_DISABLE") {
|
|
100
|
+
addDebugLog(` Disabling inspector runtime`);
|
|
57
101
|
runtime.disable();
|
|
102
|
+
}
|
|
58
103
|
if (msg.type === "APPLY_CHANGE_MARKERS") {
|
|
104
|
+
addDebugLog(` Applying ${msg.markers.length} change markers`);
|
|
59
105
|
runtime.setChangeMarkers(msg.markers);
|
|
60
106
|
}
|
|
61
107
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/host/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAsB,MAAM,gBAAgB,CAAC;AAE3E,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,gBAAgB,GAAG,IAAI,CAKzB;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,MAAM,GACnB,IAAI,
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/host/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAsB,MAAM,gBAAgB,CAAC;AAE3E,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,gBAAgB,GAAG,IAAI,CAKzB;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,MAAM,GACnB,IAAI,CAoBN"}
|
package/dist/host/validate.js
CHANGED
|
@@ -9,5 +9,25 @@ export function validateIncomingMessage(data, origin, options) {
|
|
|
9
9
|
return data;
|
|
10
10
|
}
|
|
11
11
|
export function postToTarget(target, message, targetOrigin) {
|
|
12
|
-
|
|
12
|
+
try {
|
|
13
|
+
target.postMessage(message, targetOrigin);
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
// If postMessage fails (e.g., origin mismatch with localhost vs 127.0.0.1),
|
|
17
|
+
// try common alternative origins
|
|
18
|
+
const fallbackOrigins = [
|
|
19
|
+
targetOrigin.replace("://localhost", "://127.0.0.1"),
|
|
20
|
+
targetOrigin.replace("://127.0.0.1", "://localhost"),
|
|
21
|
+
"*",
|
|
22
|
+
];
|
|
23
|
+
for (const origin of fallbackOrigins) {
|
|
24
|
+
try {
|
|
25
|
+
target.postMessage(message, origin);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Continue to next fallback
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
13
33
|
}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export type AbboxInspectorBootProps = {
|
|
2
|
+
/** Search params from Next.js useSearchParams (for RSC environments).
|
|
3
|
+
* Required in Next.js 13+ RSC where window.location.search may be empty.
|
|
4
|
+
* Pass Object.fromEntries(useSearchParams()) from your layout.
|
|
5
|
+
*/
|
|
6
|
+
searchParams?: Record<string, string | string[]>;
|
|
7
|
+
};
|
|
8
|
+
/** Mount once in the root layout so the Viewer iframe can connect via `abboxSession`.
|
|
9
|
+
* In Next.js 13+ RSC, pass searchParams prop from useSearchParams() in your layout.
|
|
10
|
+
*/
|
|
11
|
+
export declare function AbboxInspectorBoot(props?: AbboxInspectorBootProps): null;
|
|
3
12
|
//# sourceMappingURL=AbboxInspectorBoot.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbboxInspectorBoot.d.ts","sourceRoot":"","sources":["../../src/react/AbboxInspectorBoot.tsx"],"names":[],"mappings":"AAKA,
|
|
1
|
+
{"version":3,"file":"AbboxInspectorBoot.d.ts","sourceRoot":"","sources":["../../src/react/AbboxInspectorBoot.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,uBAAuB,GAAG;IACpC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;CAClD,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,uBAAuB,QAiBjE"}
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useEffect } from "react";
|
|
3
3
|
import { bootstrapInspectorPreview } from "../runtime/bootstrap.js";
|
|
4
|
-
/** Mount once in the root layout so the Viewer iframe can connect via `abboxSession`.
|
|
5
|
-
|
|
4
|
+
/** Mount once in the root layout so the Viewer iframe can connect via `abboxSession`.
|
|
5
|
+
* In Next.js 13+ RSC, pass searchParams prop from useSearchParams() in your layout.
|
|
6
|
+
*/
|
|
7
|
+
export function AbboxInspectorBoot(props) {
|
|
6
8
|
useEffect(() => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
// Convert searchParams to URLSearchParams if provided
|
|
10
|
+
let searchParams;
|
|
11
|
+
if (props?.searchParams) {
|
|
12
|
+
searchParams = new URLSearchParams(Object.entries(props.searchParams).map(([k, v]) => [
|
|
13
|
+
k,
|
|
14
|
+
Array.isArray(v) ? v[0] : v,
|
|
15
|
+
]));
|
|
16
|
+
}
|
|
17
|
+
bootstrapInspectorPreview({ searchParams });
|
|
18
|
+
}, [props?.searchParams]);
|
|
9
19
|
return null;
|
|
10
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"AAuCA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"AAuCA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzD,CAAC;AA8CF;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,gBAAqB,GAC7B,IAAI,CAiDN;AAED,4CAA4C;AAC5C,wBAAgB,+BAA+B,IAAI,IAAI,CAMtD"}
|
|
@@ -72,7 +72,16 @@ export function bootstrapInspectorPreview(options = {}) {
|
|
|
72
72
|
if (!isAbboxInspectorRuntimeEnabled())
|
|
73
73
|
return;
|
|
74
74
|
const win = window;
|
|
75
|
-
|
|
75
|
+
// In Next.js 13+ RSC, window.location.search may be empty. Fallback to passed searchParams.
|
|
76
|
+
let params;
|
|
77
|
+
if (options.searchParams) {
|
|
78
|
+
params = options.searchParams instanceof URLSearchParams
|
|
79
|
+
? options.searchParams
|
|
80
|
+
: new URLSearchParams(options.searchParams);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
params = new URLSearchParams(win.location.search);
|
|
84
|
+
}
|
|
76
85
|
const sessionFromUrl = params.get("abboxSession");
|
|
77
86
|
const hostParam = params.get("abboxHostOrigin");
|
|
78
87
|
if (!sessionFromUrl) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspector.d.ts","sourceRoot":"","sources":["../../src/runtime/inspector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"inspector.d.ts","sourceRoot":"","sources":["../../src/runtime/inspector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAkBxE,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,gBAAgB,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IACpD,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAAC;IACrD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,gBAAgB,CA0OlB"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { runtimeElementRefFor } from "./element-ref.js";
|
|
2
2
|
import { extractMetadata, findSourceLocation, sourceKeyFor, sourceMappingStatus, } from "./metadata.js";
|
|
3
|
-
import { createOverlay, hideHighlight, positionHighlight, rectForElement, renderChangeMarkers, } from "./overlay.js";
|
|
3
|
+
import { createOverlay, hideHighlight, hideSelectedHighlight, positionHighlight, positionSelectedHighlight, rectForElement, renderChangeMarkers, } from "./overlay.js";
|
|
4
4
|
export function createInspectorRuntime(options) {
|
|
5
5
|
const { document: doc, window: win } = options;
|
|
6
6
|
const overlay = createOverlay(doc);
|
|
7
7
|
let enabled = false;
|
|
8
8
|
let hovered = null;
|
|
9
|
+
let selected = null;
|
|
9
10
|
const refIdToElement = new Map();
|
|
10
11
|
let markers = [];
|
|
11
12
|
let focusedMarkerId = null;
|
|
@@ -49,8 +50,12 @@ export function createInspectorRuntime(options) {
|
|
|
49
50
|
select(target);
|
|
50
51
|
};
|
|
51
52
|
const onScrollOrResize = () => {
|
|
52
|
-
if (
|
|
53
|
+
if (selected) {
|
|
54
|
+
positionSelectedHighlight(overlay.selectedHighlight, rectForElement(selected));
|
|
55
|
+
}
|
|
56
|
+
if (hovered) {
|
|
53
57
|
positionHighlight(overlay.highlight, rectForElement(hovered));
|
|
58
|
+
}
|
|
54
59
|
if (markers.length) {
|
|
55
60
|
renderChangeMarkers(overlay.markerLayer, markers, (id) => refIdToElement.get(id) ?? null, options.onChangeMarkerSelected);
|
|
56
61
|
}
|
|
@@ -76,7 +81,10 @@ export function createInspectorRuntime(options) {
|
|
|
76
81
|
options.onHover?.(payloadFor(el));
|
|
77
82
|
}
|
|
78
83
|
function select(el) {
|
|
84
|
+
console.log("[inspector] element selected", el.tagName);
|
|
85
|
+
selected = el;
|
|
79
86
|
hovered = el;
|
|
87
|
+
positionSelectedHighlight(overlay.selectedHighlight, rectForElement(el));
|
|
80
88
|
positionHighlight(overlay.highlight, rectForElement(el));
|
|
81
89
|
options.onSelect?.(payloadFor(el));
|
|
82
90
|
}
|
|
@@ -125,7 +133,9 @@ export function createInspectorRuntime(options) {
|
|
|
125
133
|
}
|
|
126
134
|
function clearSelection() {
|
|
127
135
|
hovered = null;
|
|
136
|
+
selected = null;
|
|
128
137
|
hideHighlight(overlay.highlight);
|
|
138
|
+
hideSelectedHighlight(overlay.selectedHighlight);
|
|
129
139
|
options.onClear?.();
|
|
130
140
|
}
|
|
131
141
|
win.addEventListener("scroll", onScrollOrResize, true);
|
|
@@ -145,6 +155,7 @@ export function createInspectorRuntime(options) {
|
|
|
145
155
|
teardownListeners();
|
|
146
156
|
hovered = null;
|
|
147
157
|
hideHighlight(overlay.highlight);
|
|
158
|
+
hideSelectedHighlight(overlay.selectedHighlight);
|
|
148
159
|
clearSelection();
|
|
149
160
|
},
|
|
150
161
|
isEnabled: () => enabled,
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type { ChangeMarker, ElementRect } from "../protocol.js";
|
|
2
|
+
export declare function addDebugLog(message: string): void;
|
|
2
3
|
export type OverlayHandles = {
|
|
3
4
|
highlight: HTMLDivElement;
|
|
5
|
+
selectedHighlight: HTMLDivElement;
|
|
4
6
|
markerLayer: HTMLDivElement;
|
|
5
7
|
destroy: () => void;
|
|
6
8
|
};
|
|
7
9
|
export declare function createOverlay(root: Document): OverlayHandles;
|
|
8
10
|
export declare function positionHighlight(highlight: HTMLDivElement, rect: ElementRect): void;
|
|
11
|
+
export declare function positionSelectedHighlight(selectedHighlight: HTMLDivElement, rect: ElementRect): void;
|
|
9
12
|
export declare function hideHighlight(highlight: HTMLDivElement): void;
|
|
13
|
+
export declare function hideSelectedHighlight(selectedHighlight: HTMLDivElement): void;
|
|
10
14
|
export declare function rectForElement(el: Element): ElementRect;
|
|
11
15
|
export declare function renderChangeMarkers(layer: HTMLDivElement, markers: ChangeMarker[], resolveElement: (refId: string) => Element | null, onSelect?: (changeId: string) => void): void;
|
|
12
16
|
//# sourceMappingURL=overlay.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/runtime/overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/runtime/overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAUhE,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,QAM1C;AAiCD,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,cAAc,CAAC;IAC1B,iBAAiB,EAAE,cAAc,CAAC;IAClC,WAAW,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,CAiD5D;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,cAAc,EACzB,IAAI,EAAE,WAAW,GAChB,IAAI,CAQN;AAED,wBAAgB,yBAAyB,CACvC,iBAAiB,EAAE,cAAc,EACjC,IAAI,EAAE,WAAW,GAChB,IAAI,CASN;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAE7D;AAED,wBAAgB,qBAAqB,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAE7E;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,WAAW,CAQvD;AAOD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,YAAY,EAAE,EACvB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,EACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACpC,IAAI,CA+DN"}
|
package/dist/runtime/overlay.js
CHANGED
|
@@ -1,12 +1,68 @@
|
|
|
1
1
|
const HIGHLIGHT_Z = 2147483646;
|
|
2
|
+
const SELECTED_HIGHLIGHT_Z = 2147483643;
|
|
2
3
|
const MARKER_Z = 2147483645;
|
|
4
|
+
// Debug panel for on-screen logging
|
|
5
|
+
let debugPanel = null;
|
|
6
|
+
let debugLogs = [];
|
|
7
|
+
export function addDebugLog(message) {
|
|
8
|
+
const timestamp = new Date().toLocaleTimeString();
|
|
9
|
+
const log = `[${timestamp}] ${message}`;
|
|
10
|
+
debugLogs.push(log);
|
|
11
|
+
if (debugLogs.length > 20)
|
|
12
|
+
debugLogs.shift(); // Keep last 20 logs
|
|
13
|
+
updateDebugPanel();
|
|
14
|
+
}
|
|
15
|
+
function updateDebugPanel() {
|
|
16
|
+
if (!debugPanel)
|
|
17
|
+
createDebugPanel();
|
|
18
|
+
if (debugPanel) {
|
|
19
|
+
debugPanel.textContent = debugLogs.join("\n");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function createDebugPanel() {
|
|
23
|
+
if (debugPanel)
|
|
24
|
+
return;
|
|
25
|
+
debugPanel = document.createElement("div");
|
|
26
|
+
debugPanel.setAttribute("data-abbox-debug-panel", "true");
|
|
27
|
+
Object.assign(debugPanel.style, {
|
|
28
|
+
position: "fixed",
|
|
29
|
+
bottom: "10px",
|
|
30
|
+
right: "10px",
|
|
31
|
+
background: "rgba(0, 0, 0, 0.9)",
|
|
32
|
+
color: "#0f0",
|
|
33
|
+
padding: "10px",
|
|
34
|
+
borderRadius: "4px",
|
|
35
|
+
fontFamily: "monospace",
|
|
36
|
+
fontSize: "11px",
|
|
37
|
+
maxWidth: "400px",
|
|
38
|
+
maxHeight: "300px",
|
|
39
|
+
overflowY: "auto",
|
|
40
|
+
zIndex: "2147483647",
|
|
41
|
+
whiteSpace: "pre-wrap",
|
|
42
|
+
wordBreak: "break-word",
|
|
43
|
+
});
|
|
44
|
+
document.body.appendChild(debugPanel);
|
|
45
|
+
}
|
|
3
46
|
export function createOverlay(root) {
|
|
47
|
+
addDebugLog("Creating overlay elements");
|
|
48
|
+
const selectedHighlight = root.createElement("div");
|
|
49
|
+
selectedHighlight.setAttribute("data-abbox-inspector", "selected-highlight");
|
|
50
|
+
Object.assign(selectedHighlight.style, {
|
|
51
|
+
position: "fixed",
|
|
52
|
+
pointerEvents: "none",
|
|
53
|
+
border: "40px dashed #2563eb",
|
|
54
|
+
background: "rgba(37, 99, 235, 0.06)",
|
|
55
|
+
borderRadius: "2px",
|
|
56
|
+
zIndex: String(SELECTED_HIGHLIGHT_Z),
|
|
57
|
+
display: "none",
|
|
58
|
+
boxSizing: "border-box",
|
|
59
|
+
});
|
|
4
60
|
const highlight = root.createElement("div");
|
|
5
61
|
highlight.setAttribute("data-abbox-inspector", "highlight");
|
|
6
62
|
Object.assign(highlight.style, {
|
|
7
63
|
position: "fixed",
|
|
8
64
|
pointerEvents: "none",
|
|
9
|
-
border: "
|
|
65
|
+
border: "20px solid #2563eb",
|
|
10
66
|
background: "rgba(37, 99, 235, 0.12)",
|
|
11
67
|
borderRadius: "2px",
|
|
12
68
|
zIndex: String(HIGHLIGHT_Z),
|
|
@@ -21,11 +77,13 @@ export function createOverlay(root) {
|
|
|
21
77
|
pointerEvents: "none",
|
|
22
78
|
zIndex: String(MARKER_Z),
|
|
23
79
|
});
|
|
24
|
-
root.body.append(highlight, markerLayer);
|
|
80
|
+
root.body.append(selectedHighlight, highlight, markerLayer);
|
|
25
81
|
return {
|
|
26
82
|
highlight,
|
|
83
|
+
selectedHighlight,
|
|
27
84
|
markerLayer,
|
|
28
85
|
destroy: () => {
|
|
86
|
+
selectedHighlight.remove();
|
|
29
87
|
highlight.remove();
|
|
30
88
|
markerLayer.remove();
|
|
31
89
|
},
|
|
@@ -40,9 +98,22 @@ export function positionHighlight(highlight, rect) {
|
|
|
40
98
|
height: `${rect.height}px`,
|
|
41
99
|
});
|
|
42
100
|
}
|
|
101
|
+
export function positionSelectedHighlight(selectedHighlight, rect) {
|
|
102
|
+
addDebugLog(`Selected: ${rect.width}×${rect.height} at ${Math.round(rect.x)},${Math.round(rect.y)}`);
|
|
103
|
+
Object.assign(selectedHighlight.style, {
|
|
104
|
+
display: "block",
|
|
105
|
+
left: `${rect.x}px`,
|
|
106
|
+
top: `${rect.y}px`,
|
|
107
|
+
width: `${rect.width}px`,
|
|
108
|
+
height: `${rect.height}px`,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
43
111
|
export function hideHighlight(highlight) {
|
|
44
112
|
highlight.style.display = "none";
|
|
45
113
|
}
|
|
114
|
+
export function hideSelectedHighlight(selectedHighlight) {
|
|
115
|
+
selectedHighlight.style.display = "none";
|
|
116
|
+
}
|
|
46
117
|
export function rectForElement(el) {
|
|
47
118
|
const r = el.getBoundingClientRect();
|
|
48
119
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abbox/inspector",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.10",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -82,12 +82,13 @@
|
|
|
82
82
|
}
|
|
83
83
|
},
|
|
84
84
|
"devDependencies": {
|
|
85
|
-
"@types/react": "^19.3.0",
|
|
86
|
-
"react": "^19.3.0",
|
|
87
85
|
"@biomejs/biome": "2.5.15",
|
|
88
86
|
"@types/babel__core": "^7.20.5",
|
|
89
87
|
"@types/node": "^22.20.5",
|
|
88
|
+
"@types/react": "^19.3.0",
|
|
90
89
|
"happy-dom": "^20.0.10",
|
|
90
|
+
"next": "^16.4.3",
|
|
91
|
+
"react": "^19.3.0",
|
|
91
92
|
"typescript": "^5.7.3",
|
|
92
93
|
"vitest": "^5.0.4"
|
|
93
94
|
}
|