browsertrack 0.2.2 → 0.2.3
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/{chunk-TWEYRBDU.js → chunk-5NR5K3ER.js} +24 -5
- package/dist/chunk-5NR5K3ER.js.map +1 -0
- package/dist/{chunk-AYSVE6NG.js → chunk-G5CIZSQM.js} +2 -2
- package/dist/{chunk-QRZ57ME3.js → chunk-ONPW7AYL.js} +75 -11
- package/dist/chunk-ONPW7AYL.js.map +1 -0
- package/dist/{chunk-4HRLW6YF.js → chunk-PG4JJDCV.js} +196 -17
- package/dist/chunk-PG4JJDCV.js.map +1 -0
- package/dist/cli/index.js +22 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/client/index.cjs +267 -26
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +2 -2
- package/dist/client.iife.js +121 -15
- package/dist/core/index.d.ts +9 -2
- package/dist/core/index.js +3 -1
- package/dist/daemon/index.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -4
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +3 -3
- package/dist/{server-DjV7RWQM.d.ts → server-BRG-RQQP.d.ts} +1 -0
- package/package.json +1 -1
- package/packages/client/src/notes/inspector.ts +210 -19
- package/packages/core/src/selector.ts +110 -15
- package/packages/mcp/src/handlers.ts +7 -0
- package/packages/mcp/src/server.ts +21 -3
- package/test/core/selector.test.ts +133 -0
- package/dist/chunk-4HRLW6YF.js.map +0 -1
- package/dist/chunk-QRZ57ME3.js.map +0 -1
- package/dist/chunk-TWEYRBDU.js.map +0 -1
- /package/dist/{chunk-AYSVE6NG.js.map → chunk-G5CIZSQM.js.map} +0 -0
package/dist/client/index.cjs
CHANGED
|
@@ -133,7 +133,8 @@ function redactUrl(rawUrl) {
|
|
|
133
133
|
function getSemanticSelector(element, options = {}) {
|
|
134
134
|
if (!element || !element.tagName) return "unknown";
|
|
135
135
|
const maxClasses = options.maxClasses ?? 2;
|
|
136
|
-
const
|
|
136
|
+
const maxParentDepth = options.maxParentDepth ?? 3;
|
|
137
|
+
const testId = element.getAttribute("data-testid") || element.getAttribute("data-test") || element.getAttribute("data-cy") || element.getAttribute("data-qa") || element.getAttribute("data-component");
|
|
137
138
|
if (testId) {
|
|
138
139
|
return `[data-testid="${testId}"]`;
|
|
139
140
|
}
|
|
@@ -141,28 +142,90 @@ function getSemanticSelector(element, options = {}) {
|
|
|
141
142
|
if (id && !/^[0-9]+$/.test(id) && !/[0-9a-f]{8}-[0-9a-f]{4}/i.test(id)) {
|
|
142
143
|
return `#${id}`;
|
|
143
144
|
}
|
|
145
|
+
const tag = element.tagName.toLowerCase();
|
|
144
146
|
const ariaLabel = element.getAttribute("aria-label");
|
|
145
|
-
if (ariaLabel && ariaLabel.length <
|
|
146
|
-
return `${
|
|
147
|
+
if (ariaLabel && ariaLabel.length < 40) {
|
|
148
|
+
return `${tag}[aria-label="${ariaLabel}"]`;
|
|
149
|
+
}
|
|
150
|
+
const role = element.getAttribute("role");
|
|
151
|
+
if (role && !["presentation", "none"].includes(role)) {
|
|
152
|
+
const roleSelector = `${tag}[role="${role}"]`;
|
|
153
|
+
if (tag === "button" || tag === "a" || tag === "nav" || tag === "dialog") {
|
|
154
|
+
return roleSelector;
|
|
155
|
+
}
|
|
147
156
|
}
|
|
148
157
|
const nameAttr = element.getAttribute("name");
|
|
149
158
|
if (nameAttr) {
|
|
150
|
-
return `${
|
|
151
|
-
}
|
|
152
|
-
const
|
|
153
|
-
|
|
159
|
+
return `${tag}[name="${nameAttr}"]`;
|
|
160
|
+
}
|
|
161
|
+
const titleAttr = element.getAttribute("title");
|
|
162
|
+
if (titleAttr && titleAttr.length < 30) {
|
|
163
|
+
return `${tag}[title="${titleAttr}"]`;
|
|
164
|
+
}
|
|
165
|
+
const rawClassList = Array.from(element.classList || []);
|
|
166
|
+
const classList = rawClassList.filter(
|
|
167
|
+
(c) => !c.startsWith("css-") && !c.startsWith("_") && !/^[a-z0-9]{5,}$/i.test(c) && // filter dynamic hashed utility classes
|
|
168
|
+
!c.includes(":") && // Tailwind pseudo-class prefixes (hover:, md:, etc.)
|
|
169
|
+
!c.includes("[")
|
|
170
|
+
// Tailwind arbitrary value classes
|
|
171
|
+
).slice(0, maxClasses);
|
|
154
172
|
if (classList.length > 0) {
|
|
155
173
|
const classStr = classList.map((c) => `.${c}`).join("");
|
|
156
174
|
return `${tag}${classStr}`;
|
|
157
175
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
176
|
+
const hasParent = element.parentElement && (typeof document === "undefined" || element.parentElement !== document.body && element.parentElement !== document.documentElement);
|
|
177
|
+
if (hasParent) {
|
|
178
|
+
let suffix = "";
|
|
179
|
+
if (element.parentElement.children && element.parentElement.children.length > 1) {
|
|
180
|
+
const sameTagSiblings = Array.from(element.parentElement.children).filter(
|
|
181
|
+
(child) => child.tagName && child.tagName.toLowerCase() === tag
|
|
182
|
+
);
|
|
183
|
+
if (sameTagSiblings.length > 1) {
|
|
184
|
+
const index = sameTagSiblings.indexOf(element) + 1;
|
|
185
|
+
if (index > 0) {
|
|
186
|
+
suffix = `:nth-of-type(${index})`;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (maxParentDepth > 0) {
|
|
191
|
+
const parentSelector = getSemanticSelector(element.parentElement, {
|
|
192
|
+
maxClasses: 1,
|
|
193
|
+
maxParentDepth: maxParentDepth - 1
|
|
194
|
+
});
|
|
195
|
+
if (parentSelector && parentSelector !== "unknown" && parentSelector !== "body" && parentSelector !== "html") {
|
|
196
|
+
return `${parentSelector} > ${tag}${suffix}`;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (suffix) {
|
|
200
|
+
return `${tag}${suffix}`;
|
|
162
201
|
}
|
|
163
202
|
}
|
|
164
203
|
return tag;
|
|
165
204
|
}
|
|
205
|
+
function resolveMeaningfulTarget(element) {
|
|
206
|
+
if (!element || typeof element !== "object") {
|
|
207
|
+
return element;
|
|
208
|
+
}
|
|
209
|
+
const el = element;
|
|
210
|
+
const isSvg = el.tagName.toLowerCase() === "svg" || el.namespaceURI?.includes("svg");
|
|
211
|
+
if (isSvg || el.closest?.("svg")) {
|
|
212
|
+
const interactiveParent = el.closest?.(
|
|
213
|
+
'button, a, [role="button"], [role="link"], [role="tab"], summary, label, [data-testid], [data-component]'
|
|
214
|
+
);
|
|
215
|
+
if (interactiveParent) return interactiveParent;
|
|
216
|
+
const svgEl = isSvg ? el : el.closest?.("svg");
|
|
217
|
+
if (svgEl) return svgEl;
|
|
218
|
+
}
|
|
219
|
+
const leafTags = ["span", "i", "em", "b", "strong", "small", "mark", "code"];
|
|
220
|
+
const tag = el.tagName.toLowerCase();
|
|
221
|
+
if (leafTags.includes(tag) && !el.id && !el.getAttribute("data-testid") && !el.getAttribute("data-component") && !el.getAttribute("aria-label")) {
|
|
222
|
+
const interactiveParent = el.closest?.(
|
|
223
|
+
'button, a, [role="button"], [role="link"], [role="tab"], [role="menuitem"], summary, label, [data-testid], [data-component]'
|
|
224
|
+
);
|
|
225
|
+
if (interactiveParent) return interactiveParent;
|
|
226
|
+
}
|
|
227
|
+
return el;
|
|
228
|
+
}
|
|
166
229
|
function truncate(str, maxLength = 200) {
|
|
167
230
|
if (!str) return "";
|
|
168
231
|
if (str.length <= maxLength) return str;
|
|
@@ -1511,12 +1574,19 @@ var NoteInspector = class {
|
|
|
1511
1574
|
__publicField(this, "savedNotes", []);
|
|
1512
1575
|
__publicField(this, "showMarkers", true);
|
|
1513
1576
|
__publicField(this, "isHidden", false);
|
|
1577
|
+
__publicField(this, "isToolbarCollapsed", false);
|
|
1514
1578
|
__publicField(this, "cleanups", []);
|
|
1515
1579
|
this.transport = transport;
|
|
1516
1580
|
this.screenshotDriver = screenshotDriver;
|
|
1517
1581
|
const hiddenByQuery = shouldHideUIFromUrl(options.hideQueryParam);
|
|
1518
1582
|
this.isHidden = options.hidden === true || hiddenByQuery;
|
|
1519
1583
|
this.showMarkers = options.showBadges !== false && !this.isHidden;
|
|
1584
|
+
try {
|
|
1585
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
1586
|
+
this.isToolbarCollapsed = window.sessionStorage.getItem("bt_toolbar_collapsed") === "true";
|
|
1587
|
+
}
|
|
1588
|
+
} catch {
|
|
1589
|
+
}
|
|
1520
1590
|
this.options = {
|
|
1521
1591
|
shortcut: "Alt+Click",
|
|
1522
1592
|
maskSelectors: ['input[type="password"]', "[data-sensitive]"],
|
|
@@ -1644,11 +1714,28 @@ var NoteInspector = class {
|
|
|
1644
1714
|
this.shadowRoot = this.container.attachShadow({ mode: "open" });
|
|
1645
1715
|
const style = document.createElement("style");
|
|
1646
1716
|
style.textContent = `
|
|
1647
|
-
:
|
|
1648
|
-
|
|
1649
|
-
|
|
1717
|
+
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');
|
|
1718
|
+
|
|
1719
|
+
:host, :host *, :host *::before, :host *::after {
|
|
1720
|
+
box-sizing: border-box;
|
|
1650
1721
|
-webkit-font-smoothing: antialiased;
|
|
1651
1722
|
-moz-osx-font-smoothing: grayscale;
|
|
1723
|
+
text-rendering: optimizeLegibility;
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
:host {
|
|
1727
|
+
font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
1728
|
+
color-scheme: dark;
|
|
1729
|
+
letter-spacing: -0.012em;
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
button, input, textarea, select {
|
|
1733
|
+
font-family: inherit;
|
|
1734
|
+
letter-spacing: inherit;
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
code, pre, kbd, .bt-mono, .bt-badge, .bt-region-badge, .bt-target-pill, .bt-component-pill {
|
|
1738
|
+
font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
1652
1739
|
}
|
|
1653
1740
|
|
|
1654
1741
|
/* 1. Element Highlight Overlay */
|
|
@@ -1882,7 +1969,7 @@ var NoteInspector = class {
|
|
|
1882
1969
|
pointer-events: auto;
|
|
1883
1970
|
z-index: 2147483646;
|
|
1884
1971
|
user-select: none;
|
|
1885
|
-
transition: all 0.
|
|
1972
|
+
transition: all 0.22s cubic-bezier(0.16, 1, 0.3, 1);
|
|
1886
1973
|
}
|
|
1887
1974
|
|
|
1888
1975
|
.bt-toolbar-btn {
|
|
@@ -1943,6 +2030,86 @@ var NoteInspector = class {
|
|
|
1943
2030
|
margin: 0 2px;
|
|
1944
2031
|
}
|
|
1945
2032
|
|
|
2033
|
+
.bt-toolbar-collapse-btn {
|
|
2034
|
+
background: transparent;
|
|
2035
|
+
border: none;
|
|
2036
|
+
color: #64748b;
|
|
2037
|
+
font-size: 11px;
|
|
2038
|
+
font-weight: 700;
|
|
2039
|
+
padding: 6px 8px;
|
|
2040
|
+
border-radius: 20px;
|
|
2041
|
+
cursor: pointer;
|
|
2042
|
+
display: flex;
|
|
2043
|
+
align-items: center;
|
|
2044
|
+
justify-content: center;
|
|
2045
|
+
transition: all 0.15s ease;
|
|
2046
|
+
font-family: inherit;
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
.bt-toolbar-collapse-btn:hover {
|
|
2050
|
+
background: #1e293b;
|
|
2051
|
+
color: #f8fafc;
|
|
2052
|
+
}
|
|
2053
|
+
|
|
2054
|
+
/* Collapsed Toolbar State */
|
|
2055
|
+
.bt-toolbar.bt-toolbar-collapsed {
|
|
2056
|
+
padding: 0;
|
|
2057
|
+
background: transparent;
|
|
2058
|
+
border: none;
|
|
2059
|
+
box-shadow: none;
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
.bt-toolbar.bt-toolbar-collapsed .bt-toolbar-btn,
|
|
2063
|
+
.bt-toolbar.bt-toolbar-collapsed .bt-toolbar-divider,
|
|
2064
|
+
.bt-toolbar.bt-toolbar-collapsed .bt-toolbar-collapse-btn {
|
|
2065
|
+
display: none !important;
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
.bt-toolbar-trigger {
|
|
2069
|
+
display: none;
|
|
2070
|
+
background: #0f172a;
|
|
2071
|
+
border: 1px solid #334155;
|
|
2072
|
+
border-radius: 30px;
|
|
2073
|
+
padding: 6px 14px;
|
|
2074
|
+
color: #38bdf8;
|
|
2075
|
+
font-size: 12px;
|
|
2076
|
+
font-weight: 600;
|
|
2077
|
+
cursor: pointer;
|
|
2078
|
+
align-items: center;
|
|
2079
|
+
gap: 8px;
|
|
2080
|
+
box-shadow: 0 10px 25px -3px rgba(0,0,0,0.6), 0 4px 6px -4px rgba(0,0,0,0.4);
|
|
2081
|
+
transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
|
|
2082
|
+
font-family: inherit;
|
|
2083
|
+
user-select: none;
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
.bt-toolbar.bt-toolbar-collapsed .bt-toolbar-trigger {
|
|
2087
|
+
display: inline-flex;
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
.bt-toolbar-trigger:hover {
|
|
2091
|
+
background: #1e293b;
|
|
2092
|
+
color: #ffffff;
|
|
2093
|
+
transform: translateY(-2px);
|
|
2094
|
+
box-shadow: 0 12px 28px -3px rgba(0,0,0,0.7);
|
|
2095
|
+
border-color: #38bdf8;
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
.bt-pulse-dot {
|
|
2099
|
+
width: 7px;
|
|
2100
|
+
height: 7px;
|
|
2101
|
+
border-radius: 50%;
|
|
2102
|
+
background: #38bdf8;
|
|
2103
|
+
box-shadow: 0 0 8px #38bdf8;
|
|
2104
|
+
display: inline-block;
|
|
2105
|
+
animation: bt-dot-pulse 2s infinite;
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
@keyframes bt-dot-pulse {
|
|
2109
|
+
0%, 100% { opacity: 1; transform: scale(1); }
|
|
2110
|
+
50% { opacity: 0.4; transform: scale(0.85); }
|
|
2111
|
+
}
|
|
2112
|
+
|
|
1946
2113
|
/* 5. Modals & Popover Card */
|
|
1947
2114
|
.bt-modal-backdrop {
|
|
1948
2115
|
position: fixed;
|
|
@@ -2353,8 +2520,13 @@ var NoteInspector = class {
|
|
|
2353
2520
|
createToolbar() {
|
|
2354
2521
|
if (!this.shadowRoot || this.toolbarElement) return;
|
|
2355
2522
|
this.toolbarElement = document.createElement("div");
|
|
2356
|
-
this.toolbarElement.className = "bt-toolbar"
|
|
2523
|
+
this.toolbarElement.className = `bt-toolbar ${this.isToolbarCollapsed ? "bt-toolbar-collapsed" : ""}`;
|
|
2357
2524
|
this.toolbarElement.innerHTML = `
|
|
2525
|
+
<button class="bt-toolbar-trigger" id="bt-toolbar-expand" title="Expand BrowserTrack toolbar (Alt+T)">
|
|
2526
|
+
<span class="bt-pulse-dot"></span>
|
|
2527
|
+
<span>\u26A1 BrowserTrack</span>
|
|
2528
|
+
<span class="bt-count-pill" id="bt-notes-count-collapsed">0</span>
|
|
2529
|
+
</button>
|
|
2358
2530
|
<button class="bt-toolbar-btn" id="bt-mode-element" title="Inspect element (or hold Alt+Click)">
|
|
2359
2531
|
<span>\u{1F3AF}</span> Element
|
|
2360
2532
|
</button>
|
|
@@ -2372,12 +2544,26 @@ var NoteInspector = class {
|
|
|
2372
2544
|
<button class="bt-toolbar-btn active" id="bt-toggle-notes" title="Toggle visible note markers on screen">
|
|
2373
2545
|
<span>\u{1F4CC}</span> Notes <span class="bt-count-pill" id="bt-notes-count">0</span>
|
|
2374
2546
|
</button>
|
|
2547
|
+
<div class="bt-toolbar-divider"></div>
|
|
2548
|
+
<button class="bt-toolbar-collapse-btn" id="bt-toolbar-collapse" title="Collapse toolbar (Alt+T)">
|
|
2549
|
+
<span>\u276F</span>
|
|
2550
|
+
</button>
|
|
2375
2551
|
`;
|
|
2552
|
+
const btnExpand = this.toolbarElement.querySelector("#bt-toolbar-expand");
|
|
2553
|
+
const btnCollapse = this.toolbarElement.querySelector("#bt-toolbar-collapse");
|
|
2376
2554
|
const btnElement = this.toolbarElement.querySelector("#bt-mode-element");
|
|
2377
2555
|
const btnRegion = this.toolbarElement.querySelector("#bt-mode-region");
|
|
2378
2556
|
const btnPage = this.toolbarElement.querySelector("#bt-mode-page");
|
|
2379
2557
|
const btnFlow = this.toolbarElement.querySelector("#bt-mode-flow");
|
|
2380
2558
|
const btnToggleNotes = this.toolbarElement.querySelector("#bt-toggle-notes");
|
|
2559
|
+
btnExpand.onclick = (e) => {
|
|
2560
|
+
e.stopPropagation();
|
|
2561
|
+
this.toggleToolbarCollapse(false);
|
|
2562
|
+
};
|
|
2563
|
+
btnCollapse.onclick = (e) => {
|
|
2564
|
+
e.stopPropagation();
|
|
2565
|
+
this.toggleToolbarCollapse(true);
|
|
2566
|
+
};
|
|
2381
2567
|
btnElement.onclick = (e) => {
|
|
2382
2568
|
e.stopPropagation();
|
|
2383
2569
|
this.setMode(this.activeMode === "element" ? "idle" : "element");
|
|
@@ -2406,6 +2592,17 @@ var NoteInspector = class {
|
|
|
2406
2592
|
};
|
|
2407
2593
|
this.shadowRoot.appendChild(this.toolbarElement);
|
|
2408
2594
|
}
|
|
2595
|
+
toggleToolbarCollapse(force) {
|
|
2596
|
+
if (!this.toolbarElement) return;
|
|
2597
|
+
this.isToolbarCollapsed = typeof force === "boolean" ? force : !this.isToolbarCollapsed;
|
|
2598
|
+
this.toolbarElement.classList.toggle("bt-toolbar-collapsed", this.isToolbarCollapsed);
|
|
2599
|
+
try {
|
|
2600
|
+
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
2601
|
+
window.sessionStorage.setItem("bt_toolbar_collapsed", String(this.isToolbarCollapsed));
|
|
2602
|
+
}
|
|
2603
|
+
} catch {
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2409
2606
|
updateToolbarState() {
|
|
2410
2607
|
if (!this.toolbarElement) return;
|
|
2411
2608
|
const btnElement = this.toolbarElement.querySelector("#bt-mode-element");
|
|
@@ -2429,11 +2626,15 @@ var NoteInspector = class {
|
|
|
2429
2626
|
}
|
|
2430
2627
|
updateToolbarCount() {
|
|
2431
2628
|
if (!this.toolbarElement) return;
|
|
2629
|
+
const openCount = this.savedNotes.filter((n) => n.status === "OPEN").length;
|
|
2432
2630
|
const countEl = this.toolbarElement.querySelector("#bt-notes-count");
|
|
2433
2631
|
if (countEl) {
|
|
2434
|
-
const openCount = this.savedNotes.filter((n) => n.status === "OPEN").length;
|
|
2435
2632
|
countEl.textContent = String(openCount);
|
|
2436
2633
|
}
|
|
2634
|
+
const countCollapsedEl = this.toolbarElement.querySelector("#bt-notes-count-collapsed");
|
|
2635
|
+
if (countCollapsedEl) {
|
|
2636
|
+
countCollapsedEl.textContent = String(openCount);
|
|
2637
|
+
}
|
|
2437
2638
|
}
|
|
2438
2639
|
renderMarkers() {
|
|
2439
2640
|
const root = this.ensureContainer();
|
|
@@ -2489,6 +2690,10 @@ var NoteInspector = class {
|
|
|
2489
2690
|
}
|
|
2490
2691
|
const rect = targetEl ? targetEl.getBoundingClientRect() : note.target?.boundingRect;
|
|
2491
2692
|
if (rect) {
|
|
2693
|
+
const isOffscreen = targetEl && (rect.bottom < 0 || rect.top > window.innerHeight || rect.right < 0 || rect.left > window.innerWidth);
|
|
2694
|
+
if (isOffscreen) {
|
|
2695
|
+
return;
|
|
2696
|
+
}
|
|
2492
2697
|
const pin = document.createElement("div");
|
|
2493
2698
|
pin.className = markerClass;
|
|
2494
2699
|
pin.setAttribute("data-note-id", note.id);
|
|
@@ -2682,7 +2887,8 @@ var NoteInspector = class {
|
|
|
2682
2887
|
return;
|
|
2683
2888
|
}
|
|
2684
2889
|
if (e.altKey || this.activeMode === "element") {
|
|
2685
|
-
const
|
|
2890
|
+
const rawTarget = document.elementFromPoint(e.clientX, e.clientY);
|
|
2891
|
+
const target = rawTarget ? resolveMeaningfulTarget(rawTarget) : null;
|
|
2686
2892
|
if (target && target !== this.container && !this.container?.contains(target)) {
|
|
2687
2893
|
this.hoveredElement = target;
|
|
2688
2894
|
this.updateHighlight(target);
|
|
@@ -2706,7 +2912,8 @@ var NoteInspector = class {
|
|
|
2706
2912
|
if (e.altKey || this.activeMode === "element") {
|
|
2707
2913
|
e.preventDefault();
|
|
2708
2914
|
e.stopPropagation();
|
|
2709
|
-
const
|
|
2915
|
+
const rawTarget = this.hoveredElement || document.elementFromPoint(e.clientX, e.clientY);
|
|
2916
|
+
const target = rawTarget ? resolveMeaningfulTarget(rawTarget) : null;
|
|
2710
2917
|
if (target && target !== this.container && !this.container?.contains(target)) {
|
|
2711
2918
|
this.selectedElement = target;
|
|
2712
2919
|
this.openNoteEditor(target, "element");
|
|
@@ -2720,6 +2927,11 @@ var NoteInspector = class {
|
|
|
2720
2927
|
};
|
|
2721
2928
|
const onKeyDown = (e) => {
|
|
2722
2929
|
try {
|
|
2930
|
+
if (e.altKey && (e.key === "t" || e.key === "T")) {
|
|
2931
|
+
e.preventDefault();
|
|
2932
|
+
this.toggleToolbarCollapse();
|
|
2933
|
+
return;
|
|
2934
|
+
}
|
|
2723
2935
|
if (e.key === "Escape") {
|
|
2724
2936
|
if (this.cardOverlay && this.cardOverlay.parentElement && this.shadowRoot) {
|
|
2725
2937
|
this.shadowRoot.removeChild(this.cardOverlay);
|
|
@@ -2827,6 +3039,11 @@ var NoteInspector = class {
|
|
|
2827
3039
|
this.regionBox.appendChild(badge);
|
|
2828
3040
|
}
|
|
2829
3041
|
badge.textContent = `Region: ${Math.round(width)} \xD7 ${Math.round(height)} px`;
|
|
3042
|
+
if (top < 32) {
|
|
3043
|
+
badge.style.top = "4px";
|
|
3044
|
+
} else {
|
|
3045
|
+
badge.style.top = "-26px";
|
|
3046
|
+
}
|
|
2830
3047
|
};
|
|
2831
3048
|
this.regionOverlay.onmouseup = (e) => {
|
|
2832
3049
|
if (!this.isDraggingRegion) return;
|
|
@@ -2885,6 +3102,18 @@ var NoteInspector = class {
|
|
|
2885
3102
|
const selector = getSemanticSelector(el);
|
|
2886
3103
|
const label = this.activeScenario ? `\u{1F3AC} Step ${this.activeScenario.stepNumber} \xB7 ${selector}` : selector;
|
|
2887
3104
|
badge.textContent = `${label} (${Math.round(rect.width)} \xD7 ${Math.round(rect.height)} px)`;
|
|
3105
|
+
if (rect.top < 32) {
|
|
3106
|
+
badge.style.top = `${rect.height + 4}px`;
|
|
3107
|
+
} else {
|
|
3108
|
+
badge.style.top = "-26px";
|
|
3109
|
+
}
|
|
3110
|
+
if (rect.left + 260 > window.innerWidth) {
|
|
3111
|
+
badge.style.left = "auto";
|
|
3112
|
+
badge.style.right = "0";
|
|
3113
|
+
} else {
|
|
3114
|
+
badge.style.left = "0";
|
|
3115
|
+
badge.style.right = "auto";
|
|
3116
|
+
}
|
|
2888
3117
|
}
|
|
2889
3118
|
hideHighlight() {
|
|
2890
3119
|
if (this.highlightOverlay) {
|
|
@@ -3027,10 +3256,11 @@ var NoteInspector = class {
|
|
|
3027
3256
|
btnNextStep.disabled = true;
|
|
3028
3257
|
if (btnSave) btnSave.disabled = true;
|
|
3029
3258
|
if (btnFinishFlow) btnFinishFlow.disabled = true;
|
|
3259
|
+
closeModal();
|
|
3030
3260
|
try {
|
|
3031
3261
|
await options.onSave(message, action);
|
|
3032
|
-
}
|
|
3033
|
-
|
|
3262
|
+
} catch {
|
|
3263
|
+
this.showToast("Failed to save note", "\u26A0\uFE0F");
|
|
3034
3264
|
}
|
|
3035
3265
|
};
|
|
3036
3266
|
if (btnSave) {
|
|
@@ -3057,8 +3287,12 @@ var NoteInspector = class {
|
|
|
3057
3287
|
const selector = noteType === "page" ? "body" : getSemanticSelector(targetEl);
|
|
3058
3288
|
let screenshotDataUrl;
|
|
3059
3289
|
try {
|
|
3060
|
-
const
|
|
3061
|
-
|
|
3290
|
+
const snapPromise = this.screenshotDriver.captureElement(targetEl);
|
|
3291
|
+
const timeoutPromise = new Promise(
|
|
3292
|
+
(resolve) => setTimeout(() => resolve({ ok: false }), 800)
|
|
3293
|
+
);
|
|
3294
|
+
const snap = await Promise.race([snapPromise, timeoutPromise]);
|
|
3295
|
+
if (snap && snap.ok && snap.dataUrl) {
|
|
3062
3296
|
screenshotDataUrl = snap.dataUrl;
|
|
3063
3297
|
}
|
|
3064
3298
|
} catch {
|
|
@@ -3113,9 +3347,16 @@ var NoteInspector = class {
|
|
|
3113
3347
|
async saveRegionVisualNote(region, message, scenario) {
|
|
3114
3348
|
let screenshotDataUrl;
|
|
3115
3349
|
try {
|
|
3116
|
-
const
|
|
3117
|
-
|
|
3118
|
-
|
|
3350
|
+
const centerX = region.x + region.width / 2;
|
|
3351
|
+
const centerY = region.y + region.height / 2;
|
|
3352
|
+
const targetElement = document.elementFromPoint(centerX, centerY) || document.body;
|
|
3353
|
+
const snapPromise = this.screenshotDriver.captureElement(targetElement);
|
|
3354
|
+
const timeoutPromise = new Promise(
|
|
3355
|
+
(resolve) => setTimeout(() => resolve({ ok: false }), 800)
|
|
3356
|
+
);
|
|
3357
|
+
const snap = await Promise.race([snapPromise, timeoutPromise]);
|
|
3358
|
+
if (snap && snap.ok && snap.dataUrl) {
|
|
3359
|
+
screenshotDataUrl = snap.dataUrl;
|
|
3119
3360
|
}
|
|
3120
3361
|
} catch {
|
|
3121
3362
|
}
|
package/dist/client/index.d.ts
CHANGED
|
@@ -206,6 +206,7 @@ declare class NoteInspector {
|
|
|
206
206
|
private savedNotes;
|
|
207
207
|
private showMarkers;
|
|
208
208
|
private isHidden;
|
|
209
|
+
private isToolbarCollapsed;
|
|
209
210
|
private cleanups;
|
|
210
211
|
constructor(transport: WebSocketTransport, screenshotDriver: ScreenshotDriver, options?: InspectorOptions);
|
|
211
212
|
init(): void;
|
|
@@ -218,6 +219,7 @@ declare class NoteInspector {
|
|
|
218
219
|
setVisible(visible: boolean): void;
|
|
219
220
|
private ensureContainer;
|
|
220
221
|
private createToolbar;
|
|
222
|
+
toggleToolbarCollapse(force?: boolean): void;
|
|
221
223
|
private updateToolbarState;
|
|
222
224
|
private updateToolbarCount;
|
|
223
225
|
renderMarkers(): void;
|
package/dist/client/index.js
CHANGED
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
init,
|
|
9
9
|
resolveComponentSource,
|
|
10
10
|
shouldHideUIFromUrl
|
|
11
|
-
} from "../chunk-
|
|
12
|
-
import "../chunk-
|
|
11
|
+
} from "../chunk-PG4JJDCV.js";
|
|
12
|
+
import "../chunk-ONPW7AYL.js";
|
|
13
13
|
export {
|
|
14
14
|
BreadcrumbBuffer,
|
|
15
15
|
BrowserScriptScreenshotDriver,
|