browsertrack 0.2.0 → 0.2.2
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/AGENTS.md +11 -6
- package/README.md +2 -0
- package/dist/{chunk-WB7ZKWK7.js → chunk-4HRLW6YF.js} +509 -109
- package/dist/chunk-4HRLW6YF.js.map +1 -0
- package/dist/{chunk-3HOXPTM2.js → chunk-AYSVE6NG.js} +808 -53
- package/dist/chunk-AYSVE6NG.js.map +1 -0
- package/dist/{chunk-6VA7GBAO.js → chunk-QRZ57ME3.js} +70 -2
- package/dist/chunk-QRZ57ME3.js.map +1 -0
- package/dist/{chunk-UP5JKCFY.js → chunk-TWEYRBDU.js} +281 -44
- package/dist/chunk-TWEYRBDU.js.map +1 -0
- package/dist/cli/index.js +1040 -546
- package/dist/cli/index.js.map +1 -1
- package/dist/client/index.cjs +536 -109
- package/dist/client/index.d.ts +36 -4
- package/dist/client/index.js +8 -4
- package/dist/client.iife.js +42 -19
- package/dist/{notes-BMnonq46.d.ts → commands-fjuqKzkm.d.ts} +125 -114
- package/dist/core/index.d.ts +26 -3
- package/dist/core/index.js +9 -1
- package/dist/daemon/index.d.ts +4 -4
- package/dist/daemon/index.js +6 -8
- package/dist/{engine-B43IohQY.d.ts → engine-CmchnMDq.d.ts} +2 -2
- package/dist/index.d.ts +5 -5
- package/dist/index.js +14 -7
- package/dist/mcp/index.d.ts +4 -4
- package/dist/mcp/index.js +7 -4
- package/dist/{projects-D5J-egVN.d.ts → projects-DB7S312i.d.ts} +1 -1
- package/dist/{server-BztYp1Zc.d.ts → server-DjV7RWQM.d.ts} +10 -2
- package/docs/cli.md +4 -1
- package/docs/component-resolver.md +108 -0
- package/docs/getting-started.md +60 -6
- package/docs/index.md +1 -0
- package/docs/mcp-reference.md +44 -2
- package/docs/visual-notes.md +36 -0
- package/package.json +1 -1
- package/packages/cli/src/index.ts +247 -151
- package/packages/client/src/client.ts +18 -1
- package/packages/client/src/config.ts +84 -1
- package/packages/client/src/index.ts +4 -1
- package/packages/client/src/interceptors/interaction.ts +3 -0
- package/packages/client/src/interceptors/navigation.ts +38 -26
- package/packages/client/src/interceptors/network.ts +22 -17
- package/packages/client/src/notes/inspector.ts +186 -51
- package/packages/client/src/source/resolver.ts +278 -0
- package/packages/client/src/transport/websocket.ts +23 -18
- package/packages/core/src/index.ts +1 -0
- package/packages/core/src/safety.ts +86 -0
- package/packages/core/src/types/events.ts +3 -0
- package/packages/core/src/types/notes.ts +11 -0
- package/packages/daemon/src/server/daemon.ts +7 -1
- package/packages/daemon/src/server/http.ts +125 -5
- package/packages/daemon/src/server/ws.ts +33 -29
- package/packages/daemon/src/storage/db.ts +57 -35
- package/packages/mcp/src/handlers.ts +115 -45
- package/packages/mcp/src/server.ts +202 -2
- package/test/client/component-resolver.test.ts +141 -0
- package/test/client/interceptors.test.ts +56 -0
- package/test/core/safety.test.ts +106 -0
- package/test/daemon/storage.test.ts +36 -0
- package/test/e2e/daemon-mcp-e2e.test.ts +10 -0
- package/test/mcp/auto-start.test.ts +87 -0
- package/dist/chunk-3HOXPTM2.js.map +0 -1
- package/dist/chunk-6VA7GBAO.js.map +0 -1
- package/dist/chunk-7OCOQGDN.js +0 -635
- package/dist/chunk-7OCOQGDN.js.map +0 -1
- package/dist/chunk-UP5JKCFY.js.map +0 -1
- package/dist/chunk-WB7ZKWK7.js.map +0 -1
package/dist/client/index.cjs
CHANGED
|
@@ -28,7 +28,9 @@ __export(src_exports, {
|
|
|
28
28
|
DEFAULT_OPTIONS: () => DEFAULT_OPTIONS,
|
|
29
29
|
NoteInspector: () => NoteInspector,
|
|
30
30
|
getClient: () => getClient,
|
|
31
|
-
init: () => init
|
|
31
|
+
init: () => init,
|
|
32
|
+
resolveComponentSource: () => resolveComponentSource,
|
|
33
|
+
shouldHideUIFromUrl: () => shouldHideUIFromUrl
|
|
32
34
|
});
|
|
33
35
|
module.exports = __toCommonJS(src_exports);
|
|
34
36
|
|
|
@@ -167,12 +169,252 @@ function truncate(str, maxLength = 200) {
|
|
|
167
169
|
return str.slice(0, maxLength) + "...";
|
|
168
170
|
}
|
|
169
171
|
|
|
172
|
+
// packages/core/src/safety.ts
|
|
173
|
+
function safeJsonStringify(val, fallback = "{}") {
|
|
174
|
+
if (val === void 0) return fallback;
|
|
175
|
+
try {
|
|
176
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
177
|
+
return JSON.stringify(val, (key, value) => {
|
|
178
|
+
if (typeof value === "object" && value !== null) {
|
|
179
|
+
if (seen.has(value)) {
|
|
180
|
+
return "[Circular]";
|
|
181
|
+
}
|
|
182
|
+
seen.add(value);
|
|
183
|
+
}
|
|
184
|
+
if (typeof value === "bigint") {
|
|
185
|
+
return value.toString();
|
|
186
|
+
}
|
|
187
|
+
return value;
|
|
188
|
+
});
|
|
189
|
+
} catch {
|
|
190
|
+
try {
|
|
191
|
+
return JSON.stringify(String(val));
|
|
192
|
+
} catch {
|
|
193
|
+
return fallback;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// packages/client/src/source/resolver.ts
|
|
199
|
+
function resolveComponentSource(el) {
|
|
200
|
+
if (!el || typeof el !== "object") return void 0;
|
|
201
|
+
const reactInfo = resolveReactComponent(el);
|
|
202
|
+
if (reactInfo) return reactInfo;
|
|
203
|
+
const vueInfo = resolveVueComponent(el);
|
|
204
|
+
if (vueInfo) return vueInfo;
|
|
205
|
+
const svelteInfo = resolveSvelteComponent(el);
|
|
206
|
+
if (svelteInfo) return svelteInfo;
|
|
207
|
+
if (el.tagName && el.tagName.includes("-")) {
|
|
208
|
+
return {
|
|
209
|
+
framework: "web-component",
|
|
210
|
+
componentName: el.tagName.toLowerCase(),
|
|
211
|
+
hierarchy: [el.tagName.toLowerCase()]
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const attrInfo = resolveDataAttributeComponent(el);
|
|
215
|
+
if (attrInfo) return attrInfo;
|
|
216
|
+
return void 0;
|
|
217
|
+
}
|
|
218
|
+
function resolveReactComponent(el) {
|
|
219
|
+
try {
|
|
220
|
+
const fiberKey = Object.keys(el).find(
|
|
221
|
+
(key) => key.startsWith("__reactFiber$") || key.startsWith("__reactInternalInstance$")
|
|
222
|
+
);
|
|
223
|
+
if (!fiberKey) return void 0;
|
|
224
|
+
const hostFiber = el[fiberKey];
|
|
225
|
+
if (!hostFiber) return void 0;
|
|
226
|
+
let sourceFile;
|
|
227
|
+
let sourceLine;
|
|
228
|
+
let sourceColumn;
|
|
229
|
+
let componentName;
|
|
230
|
+
const hierarchy = [];
|
|
231
|
+
let props;
|
|
232
|
+
if (hostFiber._debugSource) {
|
|
233
|
+
sourceFile = hostFiber._debugSource.fileName;
|
|
234
|
+
sourceLine = hostFiber._debugSource.lineNumber;
|
|
235
|
+
sourceColumn = hostFiber._debugSource.columnNumber;
|
|
236
|
+
}
|
|
237
|
+
if (hostFiber._debugOwner) {
|
|
238
|
+
const ownerType = hostFiber._debugOwner.type;
|
|
239
|
+
componentName = getReactComponentName(ownerType);
|
|
240
|
+
if (!sourceFile && hostFiber._debugOwner._debugSource) {
|
|
241
|
+
sourceFile = hostFiber._debugOwner._debugSource.fileName;
|
|
242
|
+
sourceLine = hostFiber._debugOwner._debugSource.lineNumber;
|
|
243
|
+
sourceColumn = hostFiber._debugOwner._debugSource.columnNumber;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
let curr = hostFiber;
|
|
247
|
+
let depth = 0;
|
|
248
|
+
while (curr && depth < 50) {
|
|
249
|
+
depth++;
|
|
250
|
+
const type = curr.type;
|
|
251
|
+
const name = getReactComponentName(type);
|
|
252
|
+
if (name && !name.startsWith("html:") && name !== "Fragment") {
|
|
253
|
+
if (!componentName) {
|
|
254
|
+
componentName = name;
|
|
255
|
+
}
|
|
256
|
+
if (!hierarchy.includes(name)) {
|
|
257
|
+
hierarchy.unshift(name);
|
|
258
|
+
}
|
|
259
|
+
if (!sourceFile && curr._debugSource) {
|
|
260
|
+
sourceFile = curr._debugSource.fileName;
|
|
261
|
+
sourceLine = curr._debugSource.lineNumber;
|
|
262
|
+
sourceColumn = curr._debugSource.columnNumber;
|
|
263
|
+
}
|
|
264
|
+
if (!props && curr.memoizedProps && typeof curr.memoizedProps === "object") {
|
|
265
|
+
props = sanitizeProps(curr.memoizedProps);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
curr = curr.return;
|
|
269
|
+
}
|
|
270
|
+
if (!componentName && !sourceFile) {
|
|
271
|
+
return void 0;
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
framework: "react",
|
|
275
|
+
componentName,
|
|
276
|
+
sourceFile: normalizeFilePath(sourceFile),
|
|
277
|
+
sourceLine,
|
|
278
|
+
sourceColumn,
|
|
279
|
+
hierarchy: hierarchy.length > 0 ? hierarchy : componentName ? [componentName] : void 0,
|
|
280
|
+
props
|
|
281
|
+
};
|
|
282
|
+
} catch {
|
|
283
|
+
return void 0;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function getReactComponentName(type) {
|
|
287
|
+
if (!type) return void 0;
|
|
288
|
+
if (typeof type === "string") return void 0;
|
|
289
|
+
if (type.displayName) return type.displayName;
|
|
290
|
+
if (type.name) return type.name;
|
|
291
|
+
if (type.render?.displayName) return type.render.displayName;
|
|
292
|
+
if (type.render?.name) return type.render.name;
|
|
293
|
+
return void 0;
|
|
294
|
+
}
|
|
295
|
+
function resolveVueComponent(el) {
|
|
296
|
+
try {
|
|
297
|
+
const vueParent = el.__vueParentComponent || el.__vnode?.ctx;
|
|
298
|
+
if (vueParent) {
|
|
299
|
+
const type = vueParent.type || {};
|
|
300
|
+
const componentName = type.name || type.__name || type.displayName || "AnonymousComponent";
|
|
301
|
+
const sourceFile = type.__file;
|
|
302
|
+
const hierarchy = [];
|
|
303
|
+
let curr = vueParent;
|
|
304
|
+
let depth = 0;
|
|
305
|
+
while (curr && depth < 50) {
|
|
306
|
+
depth++;
|
|
307
|
+
const cType = curr.type || {};
|
|
308
|
+
const cName = cType.name || cType.__name || cType.displayName;
|
|
309
|
+
if (cName && !hierarchy.includes(cName)) {
|
|
310
|
+
hierarchy.unshift(cName);
|
|
311
|
+
}
|
|
312
|
+
curr = curr.parent;
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
framework: "vue",
|
|
316
|
+
componentName,
|
|
317
|
+
sourceFile: normalizeFilePath(sourceFile),
|
|
318
|
+
hierarchy: hierarchy.length > 0 ? hierarchy : [componentName],
|
|
319
|
+
props: vueParent.props ? sanitizeProps(vueParent.props) : void 0
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
const vue2Instance = el.__vue__;
|
|
323
|
+
if (vue2Instance) {
|
|
324
|
+
const options = vue2Instance.$options || {};
|
|
325
|
+
const componentName = options.name || options._componentTag || "VueComponent";
|
|
326
|
+
const sourceFile = options.__file;
|
|
327
|
+
return {
|
|
328
|
+
framework: "vue",
|
|
329
|
+
componentName,
|
|
330
|
+
sourceFile: normalizeFilePath(sourceFile),
|
|
331
|
+
hierarchy: [componentName],
|
|
332
|
+
props: vue2Instance.$props ? sanitizeProps(vue2Instance.$props) : void 0
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
return void 0;
|
|
336
|
+
} catch {
|
|
337
|
+
return void 0;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function resolveSvelteComponent(el) {
|
|
341
|
+
try {
|
|
342
|
+
let curr = el;
|
|
343
|
+
let depth = 0;
|
|
344
|
+
while (curr && depth < 50) {
|
|
345
|
+
depth++;
|
|
346
|
+
const meta = curr.__svelte_meta;
|
|
347
|
+
if (meta && meta.loc) {
|
|
348
|
+
return {
|
|
349
|
+
framework: "svelte",
|
|
350
|
+
sourceFile: normalizeFilePath(meta.loc.file),
|
|
351
|
+
sourceLine: meta.loc.line,
|
|
352
|
+
sourceColumn: meta.loc.column,
|
|
353
|
+
componentName: meta.loc.file ? getBaseNameWithoutExt(meta.loc.file) : void 0,
|
|
354
|
+
hierarchy: meta.loc.file ? [getBaseNameWithoutExt(meta.loc.file)] : void 0
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
curr = curr.parentElement;
|
|
358
|
+
}
|
|
359
|
+
return void 0;
|
|
360
|
+
} catch {
|
|
361
|
+
return void 0;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
function resolveDataAttributeComponent(el) {
|
|
365
|
+
try {
|
|
366
|
+
const compEl = el.closest("[data-component], [data-component-name], [data-source-file]");
|
|
367
|
+
if (!compEl) return void 0;
|
|
368
|
+
const componentName = compEl.getAttribute("data-component") || compEl.getAttribute("data-component-name") || void 0;
|
|
369
|
+
const sourceFile = compEl.getAttribute("data-source-file") || void 0;
|
|
370
|
+
const lineAttr = compEl.getAttribute("data-source-line");
|
|
371
|
+
const sourceLine = lineAttr ? parseInt(lineAttr, 10) : void 0;
|
|
372
|
+
if (!componentName && !sourceFile) return void 0;
|
|
373
|
+
return {
|
|
374
|
+
framework: "vanilla",
|
|
375
|
+
componentName,
|
|
376
|
+
sourceFile: normalizeFilePath(sourceFile),
|
|
377
|
+
sourceLine: isNaN(sourceLine) ? void 0 : sourceLine,
|
|
378
|
+
hierarchy: componentName ? [componentName] : void 0
|
|
379
|
+
};
|
|
380
|
+
} catch {
|
|
381
|
+
return void 0;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
function normalizeFilePath(filePath) {
|
|
385
|
+
if (!filePath) return void 0;
|
|
386
|
+
const cleaned = filePath.split("?")[0];
|
|
387
|
+
return cleaned;
|
|
388
|
+
}
|
|
389
|
+
function getBaseNameWithoutExt(filePath) {
|
|
390
|
+
const parts = filePath.split("/");
|
|
391
|
+
const last = parts[parts.length - 1] || filePath;
|
|
392
|
+
return last.split(".")[0] || last;
|
|
393
|
+
}
|
|
394
|
+
function sanitizeProps(props) {
|
|
395
|
+
const result = {};
|
|
396
|
+
for (const [key, value] of Object.entries(props)) {
|
|
397
|
+
if (key.startsWith("__") || typeof value === "function") continue;
|
|
398
|
+
if (value === null || value === void 0) {
|
|
399
|
+
result[key] = value;
|
|
400
|
+
} else if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
401
|
+
result[key] = value;
|
|
402
|
+
} else if (Array.isArray(value)) {
|
|
403
|
+
result[key] = `Array(${value.length})`;
|
|
404
|
+
} else if (typeof value === "object") {
|
|
405
|
+
result[key] = "[Object]";
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return result;
|
|
409
|
+
}
|
|
410
|
+
|
|
170
411
|
// packages/client/src/interceptors/interaction.ts
|
|
171
412
|
function extractElementSummary(el) {
|
|
172
413
|
const selector = getSemanticSelector(el);
|
|
173
414
|
const tag = el.tagName.toLowerCase();
|
|
174
415
|
const id = el.id || void 0;
|
|
175
416
|
const classes = Array.from(el.classList || []);
|
|
417
|
+
const componentSource = resolveComponentSource(el);
|
|
176
418
|
let boundingRect = void 0;
|
|
177
419
|
let visible = true;
|
|
178
420
|
try {
|
|
@@ -204,7 +446,8 @@ function extractElementSummary(el) {
|
|
|
204
446
|
boundingRect,
|
|
205
447
|
visible,
|
|
206
448
|
innerText,
|
|
207
|
-
outerHTML
|
|
449
|
+
outerHTML,
|
|
450
|
+
componentSource
|
|
208
451
|
};
|
|
209
452
|
}
|
|
210
453
|
function setupInteractionInterceptors(onInteraction) {
|
|
@@ -522,10 +765,62 @@ var DEFAULT_OPTIONS = {
|
|
|
522
765
|
enabled: true,
|
|
523
766
|
shortcut: "Alt+Click",
|
|
524
767
|
showBadges: true,
|
|
768
|
+
showToolbar: true,
|
|
525
769
|
maskSelectors: ['input[type="password"]', "[data-sensitive]"]
|
|
526
770
|
},
|
|
771
|
+
hidden: false,
|
|
772
|
+
hideQueryParam: void 0,
|
|
527
773
|
debug: false
|
|
528
774
|
};
|
|
775
|
+
var HIDE_VALUES = /* @__PURE__ */ new Set(["0", "false", "hidden", "hide", "off", "none", "disabled", "ui_off", "silent"]);
|
|
776
|
+
function shouldHideUIFromUrl(customParam, searchString) {
|
|
777
|
+
let search = searchString;
|
|
778
|
+
if (search === void 0) {
|
|
779
|
+
if (typeof window === "undefined" || !window.location) return false;
|
|
780
|
+
search = window.location.search;
|
|
781
|
+
}
|
|
782
|
+
if (!search) return false;
|
|
783
|
+
try {
|
|
784
|
+
const params = new URLSearchParams(search);
|
|
785
|
+
if (customParam) {
|
|
786
|
+
const customKeys = Array.isArray(customParam) ? customParam : [customParam];
|
|
787
|
+
for (const key of customKeys) {
|
|
788
|
+
if (params.has(key)) {
|
|
789
|
+
const val = (params.get(key) || "").toLowerCase().trim();
|
|
790
|
+
if (val === "" || val === "1" || val === "true" || HIDE_VALUES.has(val)) {
|
|
791
|
+
return true;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
for (const flag of ["no_bt", "no_browsertrack", "hide_bt", "hide_browsertrack"]) {
|
|
797
|
+
if (params.has(flag)) {
|
|
798
|
+
const val = (params.get(flag) || "").toLowerCase().trim();
|
|
799
|
+
if (val === "" || val === "1" || val === "true" || val === "yes") {
|
|
800
|
+
return true;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
if (params.has("bt")) {
|
|
805
|
+
const val = (params.get("bt") || "").toLowerCase().trim();
|
|
806
|
+
if (HIDE_VALUES.has(val)) return true;
|
|
807
|
+
}
|
|
808
|
+
if (params.has("browsertrack")) {
|
|
809
|
+
const val = (params.get("browsertrack") || "").toLowerCase().trim();
|
|
810
|
+
if (HIDE_VALUES.has(val)) return true;
|
|
811
|
+
}
|
|
812
|
+
if (params.has("bt_ui")) {
|
|
813
|
+
const val = (params.get("bt_ui") || "").toLowerCase().trim();
|
|
814
|
+
if (HIDE_VALUES.has(val) || val === "0" || val === "false") return true;
|
|
815
|
+
}
|
|
816
|
+
if (params.has("bt_hide")) {
|
|
817
|
+
const val = (params.get("bt_hide") || "").toLowerCase().trim();
|
|
818
|
+
if (val === "" || val === "1" || val === "true") return true;
|
|
819
|
+
}
|
|
820
|
+
} catch {
|
|
821
|
+
}
|
|
822
|
+
return false;
|
|
823
|
+
}
|
|
529
824
|
|
|
530
825
|
// packages/client/src/interceptors/console.ts
|
|
531
826
|
function setupConsoleInterceptors(onConsole) {
|
|
@@ -586,12 +881,16 @@ function setupConsoleInterceptors(onConsole) {
|
|
|
586
881
|
function setupNavigationInterceptors(onNavigation) {
|
|
587
882
|
if (typeof window === "undefined" || typeof history === "undefined") return () => {
|
|
588
883
|
};
|
|
589
|
-
let currentUrl =
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
884
|
+
let currentUrl = "";
|
|
885
|
+
try {
|
|
886
|
+
currentUrl = redactUrl(window.location.href);
|
|
887
|
+
onNavigation({
|
|
888
|
+
to: currentUrl,
|
|
889
|
+
type: "initial",
|
|
890
|
+
timestamp: Date.now()
|
|
891
|
+
});
|
|
892
|
+
} catch {
|
|
893
|
+
}
|
|
595
894
|
const originalPushState = history.pushState;
|
|
596
895
|
const originalReplaceState = history.replaceState;
|
|
597
896
|
history.pushState = function(data, unused, url) {
|
|
@@ -627,26 +926,32 @@ function setupNavigationInterceptors(onNavigation) {
|
|
|
627
926
|
return result;
|
|
628
927
|
};
|
|
629
928
|
const onPopState = () => {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
929
|
+
try {
|
|
930
|
+
const from = currentUrl;
|
|
931
|
+
const to = redactUrl(window.location.href);
|
|
932
|
+
currentUrl = to;
|
|
933
|
+
onNavigation({
|
|
934
|
+
from,
|
|
935
|
+
to,
|
|
936
|
+
type: "popstate",
|
|
937
|
+
timestamp: Date.now()
|
|
938
|
+
});
|
|
939
|
+
} catch {
|
|
940
|
+
}
|
|
639
941
|
};
|
|
640
942
|
const onHashChange = () => {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
943
|
+
try {
|
|
944
|
+
const from = currentUrl;
|
|
945
|
+
const to = redactUrl(window.location.href);
|
|
946
|
+
currentUrl = to;
|
|
947
|
+
onNavigation({
|
|
948
|
+
from,
|
|
949
|
+
to,
|
|
950
|
+
type: "hashchange",
|
|
951
|
+
timestamp: Date.now()
|
|
952
|
+
});
|
|
953
|
+
} catch {
|
|
954
|
+
}
|
|
650
955
|
};
|
|
651
956
|
window.addEventListener("popstate", onPopState);
|
|
652
957
|
window.addEventListener("hashchange", onHashChange);
|
|
@@ -683,31 +988,38 @@ function setupNetworkInterceptors(onNetwork) {
|
|
|
683
988
|
urlStr = "unknown_url";
|
|
684
989
|
}
|
|
685
990
|
const safeUrl = redactUrl(urlStr);
|
|
991
|
+
let response;
|
|
686
992
|
try {
|
|
687
|
-
|
|
688
|
-
const durationMs = Date.now() - startTime;
|
|
689
|
-
onNetwork({
|
|
690
|
-
url: safeUrl,
|
|
691
|
-
method,
|
|
692
|
-
status: response.status,
|
|
693
|
-
statusText: response.statusText,
|
|
694
|
-
durationMs,
|
|
695
|
-
timestamp: startTime
|
|
696
|
-
});
|
|
697
|
-
return response;
|
|
993
|
+
response = await originalFetch.apply(window, [input, init2]);
|
|
698
994
|
} catch (err) {
|
|
699
|
-
const
|
|
995
|
+
const durationMs2 = Date.now() - startTime;
|
|
700
996
|
const isAbort = err?.name === "AbortError";
|
|
997
|
+
try {
|
|
998
|
+
onNetwork({
|
|
999
|
+
url: safeUrl,
|
|
1000
|
+
method,
|
|
1001
|
+
durationMs: durationMs2,
|
|
1002
|
+
error: err?.message || "Network request failed",
|
|
1003
|
+
aborted: isAbort,
|
|
1004
|
+
timestamp: startTime
|
|
1005
|
+
});
|
|
1006
|
+
} catch {
|
|
1007
|
+
}
|
|
1008
|
+
throw err;
|
|
1009
|
+
}
|
|
1010
|
+
const durationMs = Date.now() - startTime;
|
|
1011
|
+
try {
|
|
701
1012
|
onNetwork({
|
|
702
1013
|
url: safeUrl,
|
|
703
1014
|
method,
|
|
1015
|
+
status: response.status,
|
|
1016
|
+
statusText: response.statusText,
|
|
704
1017
|
durationMs,
|
|
705
|
-
error: err?.message || "Network request failed",
|
|
706
|
-
aborted: isAbort,
|
|
707
1018
|
timestamp: startTime
|
|
708
1019
|
});
|
|
709
|
-
|
|
1020
|
+
} catch {
|
|
710
1021
|
}
|
|
1022
|
+
return response;
|
|
711
1023
|
};
|
|
712
1024
|
cleanups.push(() => {
|
|
713
1025
|
window.fetch = originalFetch;
|
|
@@ -1095,15 +1407,18 @@ var WebSocketTransport = class {
|
|
|
1095
1407
|
}
|
|
1096
1408
|
}
|
|
1097
1409
|
send(payload) {
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1410
|
+
try {
|
|
1411
|
+
const raw = safeJsonStringify(payload);
|
|
1412
|
+
if (this.isConnected()) {
|
|
1413
|
+
try {
|
|
1414
|
+
this.ws.send(raw);
|
|
1415
|
+
} catch {
|
|
1416
|
+
this.enqueue(raw);
|
|
1417
|
+
}
|
|
1418
|
+
} else {
|
|
1103
1419
|
this.enqueue(raw);
|
|
1104
1420
|
}
|
|
1105
|
-
}
|
|
1106
|
-
this.enqueue(raw);
|
|
1421
|
+
} catch {
|
|
1107
1422
|
}
|
|
1108
1423
|
}
|
|
1109
1424
|
enqueue(raw) {
|
|
@@ -1128,17 +1443,17 @@ var WebSocketTransport = class {
|
|
|
1128
1443
|
}
|
|
1129
1444
|
sendHello() {
|
|
1130
1445
|
if (typeof window === "undefined") return;
|
|
1131
|
-
const hello = {
|
|
1132
|
-
type: "hello",
|
|
1133
|
-
origin: window.location.origin,
|
|
1134
|
-
url: window.location.href,
|
|
1135
|
-
title: document.title,
|
|
1136
|
-
userAgent: navigator.userAgent,
|
|
1137
|
-
timestamp: Date.now(),
|
|
1138
|
-
projectId: this.projectId
|
|
1139
|
-
};
|
|
1140
1446
|
try {
|
|
1141
|
-
|
|
1447
|
+
const hello = {
|
|
1448
|
+
type: "hello",
|
|
1449
|
+
origin: window.location.origin,
|
|
1450
|
+
url: window.location.href,
|
|
1451
|
+
title: document.title,
|
|
1452
|
+
userAgent: navigator.userAgent,
|
|
1453
|
+
timestamp: Date.now(),
|
|
1454
|
+
projectId: this.projectId
|
|
1455
|
+
};
|
|
1456
|
+
this.ws.send(safeJsonStringify(hello));
|
|
1142
1457
|
} catch {
|
|
1143
1458
|
}
|
|
1144
1459
|
}
|
|
@@ -1195,13 +1510,18 @@ var NoteInspector = class {
|
|
|
1195
1510
|
__publicField(this, "dragStartY", 0);
|
|
1196
1511
|
__publicField(this, "savedNotes", []);
|
|
1197
1512
|
__publicField(this, "showMarkers", true);
|
|
1513
|
+
__publicField(this, "isHidden", false);
|
|
1198
1514
|
__publicField(this, "cleanups", []);
|
|
1199
1515
|
this.transport = transport;
|
|
1200
1516
|
this.screenshotDriver = screenshotDriver;
|
|
1517
|
+
const hiddenByQuery = shouldHideUIFromUrl(options.hideQueryParam);
|
|
1518
|
+
this.isHidden = options.hidden === true || hiddenByQuery;
|
|
1519
|
+
this.showMarkers = options.showBadges !== false && !this.isHidden;
|
|
1201
1520
|
this.options = {
|
|
1202
1521
|
shortcut: "Alt+Click",
|
|
1203
1522
|
maskSelectors: ['input[type="password"]', "[data-sensitive]"],
|
|
1204
1523
|
showToolbar: true,
|
|
1524
|
+
showBadges: true,
|
|
1205
1525
|
...options
|
|
1206
1526
|
};
|
|
1207
1527
|
}
|
|
@@ -1279,12 +1599,48 @@ var NoteInspector = class {
|
|
|
1279
1599
|
this.hideHighlight();
|
|
1280
1600
|
}
|
|
1281
1601
|
}
|
|
1602
|
+
isVisible() {
|
|
1603
|
+
return !this.isHidden;
|
|
1604
|
+
}
|
|
1605
|
+
setVisible(visible) {
|
|
1606
|
+
this.isHidden = !visible;
|
|
1607
|
+
this.showMarkers = this.options.showBadges !== false && !this.isHidden;
|
|
1608
|
+
if (this.container) {
|
|
1609
|
+
this.container.style.display = this.isHidden ? "none" : "block";
|
|
1610
|
+
}
|
|
1611
|
+
if (this.toolbarElement) {
|
|
1612
|
+
this.toolbarElement.style.display = this.isHidden ? "none" : "flex";
|
|
1613
|
+
} else if (!this.isHidden && this.options.showToolbar !== false) {
|
|
1614
|
+
this.createToolbar();
|
|
1615
|
+
}
|
|
1616
|
+
if (this.isHidden) {
|
|
1617
|
+
this.hideHighlight();
|
|
1618
|
+
this.hideRegionOverlay();
|
|
1619
|
+
if (this.modalOverlay && this.shadowRoot) {
|
|
1620
|
+
this.shadowRoot.removeChild(this.modalOverlay);
|
|
1621
|
+
this.modalOverlay = null;
|
|
1622
|
+
}
|
|
1623
|
+
if (this.cardOverlay && this.shadowRoot) {
|
|
1624
|
+
this.shadowRoot.removeChild(this.cardOverlay);
|
|
1625
|
+
this.cardOverlay = null;
|
|
1626
|
+
}
|
|
1627
|
+
if (this.markersContainer) {
|
|
1628
|
+
this.markersContainer.innerHTML = "";
|
|
1629
|
+
}
|
|
1630
|
+
} else {
|
|
1631
|
+
this.renderMarkers();
|
|
1632
|
+
this.updateToolbarCount();
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1282
1635
|
ensureContainer() {
|
|
1283
1636
|
if (typeof document === "undefined") return null;
|
|
1284
1637
|
if (!this.container) {
|
|
1285
1638
|
this.container = document.createElement("div");
|
|
1286
1639
|
this.container.id = "browsertrack-inspector-host";
|
|
1287
1640
|
this.container.style.cssText = "all: initial; position: fixed; top: 0; left: 0; width: 0; height: 0; z-index: 2147483647; pointer-events: none;";
|
|
1641
|
+
if (this.isHidden) {
|
|
1642
|
+
this.container.style.display = "none";
|
|
1643
|
+
}
|
|
1288
1644
|
this.shadowRoot = this.container.attachShadow({ mode: "open" });
|
|
1289
1645
|
const style = document.createElement("style");
|
|
1290
1646
|
style.textContent = `
|
|
@@ -1727,6 +2083,22 @@ var NoteInspector = class {
|
|
|
1727
2083
|
color: #cbd5e1;
|
|
1728
2084
|
}
|
|
1729
2085
|
|
|
2086
|
+
.bt-component-pill {
|
|
2087
|
+
display: flex;
|
|
2088
|
+
align-items: center;
|
|
2089
|
+
gap: 6px;
|
|
2090
|
+
background: rgba(15, 23, 42, 0.95);
|
|
2091
|
+
border: 1px solid rgba(99, 102, 241, 0.35);
|
|
2092
|
+
border-radius: 6px;
|
|
2093
|
+
padding: 6px 10px;
|
|
2094
|
+
font-size: 11.5px;
|
|
2095
|
+
color: #c7d2fe;
|
|
2096
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
2097
|
+
overflow: hidden;
|
|
2098
|
+
text-overflow: ellipsis;
|
|
2099
|
+
white-space: nowrap;
|
|
2100
|
+
}
|
|
2101
|
+
|
|
1730
2102
|
.bt-scenario-stepper {
|
|
1731
2103
|
display: flex;
|
|
1732
2104
|
align-items: center;
|
|
@@ -1966,7 +2338,7 @@ var NoteInspector = class {
|
|
|
1966
2338
|
this.toastContainer = document.createElement("div");
|
|
1967
2339
|
this.toastContainer.className = "bt-toast-container";
|
|
1968
2340
|
this.shadowRoot.appendChild(this.toastContainer);
|
|
1969
|
-
if (this.options.showToolbar) {
|
|
2341
|
+
if (this.options.showToolbar && !this.isHidden) {
|
|
1970
2342
|
this.createToolbar();
|
|
1971
2343
|
}
|
|
1972
2344
|
}
|
|
@@ -2067,11 +2439,17 @@ var NoteInspector = class {
|
|
|
2067
2439
|
const root = this.ensureContainer();
|
|
2068
2440
|
if (!root || !this.markersContainer) return;
|
|
2069
2441
|
this.markersContainer.innerHTML = "";
|
|
2070
|
-
if (!this.showMarkers) return;
|
|
2442
|
+
if (!this.showMarkers || this.isHidden) return;
|
|
2071
2443
|
const currentPath = window.location.pathname;
|
|
2072
|
-
const activeNotes = this.savedNotes.filter(
|
|
2073
|
-
(n
|
|
2074
|
-
|
|
2444
|
+
const activeNotes = this.savedNotes.filter((n) => {
|
|
2445
|
+
if (n.status !== "OPEN") return false;
|
|
2446
|
+
if (!n.route) return true;
|
|
2447
|
+
if (n.route === currentPath) return true;
|
|
2448
|
+
if (n.route.includes("#") || n.route.includes("?")) {
|
|
2449
|
+
return window.location.href.includes(n.route);
|
|
2450
|
+
}
|
|
2451
|
+
return false;
|
|
2452
|
+
});
|
|
2075
2453
|
const pageNotes = [];
|
|
2076
2454
|
activeNotes.forEach((note, index) => {
|
|
2077
2455
|
if (note.type === "page") {
|
|
@@ -2198,6 +2576,13 @@ var NoteInspector = class {
|
|
|
2198
2576
|
|
|
2199
2577
|
${scenarioStepsHtml}
|
|
2200
2578
|
|
|
2579
|
+
${note.elementContext?.componentSource?.componentName ? `<div class="bt-component-pill" title="${note.elementContext.componentSource.sourceFile ? note.elementContext.componentSource.sourceFile + (note.elementContext.componentSource.sourceLine ? ":" + note.elementContext.componentSource.sourceLine : "") : note.elementContext.componentSource.componentName}">
|
|
2580
|
+
<span>\u{1F9EC}</span>
|
|
2581
|
+
<span style="font-weight: 600; color: #a5b4fc;"><${note.elementContext.componentSource.componentName}></span>
|
|
2582
|
+
${note.elementContext.componentSource.sourceFile ? `<span style="color: #64748b; font-size: 11px; margin-left: 4px;">${note.elementContext.componentSource.sourceFile}${note.elementContext.componentSource.sourceLine ? ":" + note.elementContext.componentSource.sourceLine : ""}</span>` : ""}
|
|
2583
|
+
${note.elementContext.componentSource.framework ? `<span class="bt-mode-badge" style="background: rgba(99, 102, 241, 0.15); color: #818cf8; margin-left: auto; font-size: 10px;">${note.elementContext.componentSource.framework.toUpperCase()}</span>` : ""}
|
|
2584
|
+
</div>` : ""}
|
|
2585
|
+
|
|
2201
2586
|
<div class="bt-target-pill" title="${contextText}">
|
|
2202
2587
|
<span>\u{1F3F7}\uFE0F</span>
|
|
2203
2588
|
<span class="bt-pill-content">${contextText}</span>
|
|
@@ -2289,65 +2674,83 @@ var NoteInspector = class {
|
|
|
2289
2674
|
}
|
|
2290
2675
|
setupListeners() {
|
|
2291
2676
|
const onMouseMove = (e) => {
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
this.
|
|
2296
|
-
|
|
2297
|
-
}
|
|
2298
|
-
if (e.altKey || this.activeMode === "element") {
|
|
2299
|
-
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
2300
|
-
if (target && target !== this.container && !this.container?.contains(target)) {
|
|
2301
|
-
this.hoveredElement = target;
|
|
2302
|
-
this.updateHighlight(target);
|
|
2677
|
+
try {
|
|
2678
|
+
if (this.isHidden || this.modalOverlay || this.cardOverlay || this.isDraggingRegion || this.activeMode === "region") return;
|
|
2679
|
+
const path = e.composedPath ? e.composedPath() : [];
|
|
2680
|
+
if (this.container && path.includes(this.container)) {
|
|
2681
|
+
this.hideHighlight();
|
|
2303
2682
|
return;
|
|
2304
2683
|
}
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2684
|
+
if (e.altKey || this.activeMode === "element") {
|
|
2685
|
+
const target = document.elementFromPoint(e.clientX, e.clientY);
|
|
2686
|
+
if (target && target !== this.container && !this.container?.contains(target)) {
|
|
2687
|
+
this.hoveredElement = target;
|
|
2688
|
+
this.updateHighlight(target);
|
|
2689
|
+
return;
|
|
2690
|
+
}
|
|
2691
|
+
}
|
|
2692
|
+
if (!e.altKey && this.activeMode !== "element") {
|
|
2693
|
+
this.hideHighlight();
|
|
2694
|
+
}
|
|
2695
|
+
} catch {
|
|
2308
2696
|
}
|
|
2309
2697
|
};
|
|
2310
2698
|
const onClick = (e) => {
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
e.
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
this.
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
this.
|
|
2699
|
+
try {
|
|
2700
|
+
if (this.isHidden || this.modalOverlay || this.cardOverlay) return;
|
|
2701
|
+
const path = e.composedPath ? e.composedPath() : [];
|
|
2702
|
+
if (this.container && path.includes(this.container)) {
|
|
2703
|
+
return;
|
|
2704
|
+
}
|
|
2705
|
+
if (this.activeMode === "region") return;
|
|
2706
|
+
if (e.altKey || this.activeMode === "element") {
|
|
2707
|
+
e.preventDefault();
|
|
2708
|
+
e.stopPropagation();
|
|
2709
|
+
const target = this.hoveredElement || document.elementFromPoint(e.clientX, e.clientY);
|
|
2710
|
+
if (target && target !== this.container && !this.container?.contains(target)) {
|
|
2711
|
+
this.selectedElement = target;
|
|
2712
|
+
this.openNoteEditor(target, "element");
|
|
2713
|
+
if (this.activeMode === "element" && !this.activeScenario) {
|
|
2714
|
+
this.setMode("idle");
|
|
2715
|
+
}
|
|
2326
2716
|
}
|
|
2327
2717
|
}
|
|
2718
|
+
} catch {
|
|
2328
2719
|
}
|
|
2329
2720
|
};
|
|
2330
2721
|
const onKeyDown = (e) => {
|
|
2331
|
-
|
|
2332
|
-
if (
|
|
2333
|
-
this.
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
if (
|
|
2337
|
-
this.
|
|
2722
|
+
try {
|
|
2723
|
+
if (e.key === "Escape") {
|
|
2724
|
+
if (this.cardOverlay && this.cardOverlay.parentElement && this.shadowRoot) {
|
|
2725
|
+
this.shadowRoot.removeChild(this.cardOverlay);
|
|
2726
|
+
this.cardOverlay = null;
|
|
2727
|
+
} else if (this.activeMode === "region" || this.activeMode === "element") {
|
|
2728
|
+
if (!this.activeScenario) {
|
|
2729
|
+
this.setMode("idle");
|
|
2730
|
+
}
|
|
2338
2731
|
}
|
|
2339
2732
|
}
|
|
2733
|
+
} catch {
|
|
2340
2734
|
}
|
|
2341
2735
|
};
|
|
2342
2736
|
const onKeyUp = (e) => {
|
|
2343
|
-
|
|
2344
|
-
this.
|
|
2737
|
+
try {
|
|
2738
|
+
if (e.key === "Alt" && !this.modalOverlay && !this.cardOverlay && this.activeMode !== "element") {
|
|
2739
|
+
this.hideHighlight();
|
|
2740
|
+
}
|
|
2741
|
+
} catch {
|
|
2345
2742
|
}
|
|
2346
2743
|
};
|
|
2347
2744
|
const onScrollOrResize = () => {
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2745
|
+
try {
|
|
2746
|
+
requestAnimationFrame(() => {
|
|
2747
|
+
try {
|
|
2748
|
+
this.updateMarkerPositions();
|
|
2749
|
+
} catch {
|
|
2750
|
+
}
|
|
2751
|
+
});
|
|
2752
|
+
} catch {
|
|
2753
|
+
}
|
|
2351
2754
|
};
|
|
2352
2755
|
window.addEventListener("mousemove", onMouseMove, { capture: true, passive: true });
|
|
2353
2756
|
window.addEventListener("click", onClick, { capture: true });
|
|
@@ -2496,10 +2899,12 @@ var NoteInspector = class {
|
|
|
2496
2899
|
if (noteType === "element") {
|
|
2497
2900
|
this.updateHighlight(targetEl);
|
|
2498
2901
|
}
|
|
2902
|
+
const comp = noteType === "element" ? resolveComponentSource(targetEl) : void 0;
|
|
2903
|
+
const compPrefix = comp?.componentName ? `\u{1F9EC} <${comp.componentName}>${comp.sourceFile ? " (" + comp.sourceFile + (comp.sourceLine ? ":" + comp.sourceLine : "") + ")" : ""} \xB7 ` : "";
|
|
2499
2904
|
this.renderNoteModal({
|
|
2500
2905
|
title: this.activeScenario ? `Step ${this.activeScenario.stepNumber}: ${this.activeScenario.title}` : "Add Visual Note",
|
|
2501
2906
|
modeBadge: this.activeScenario ? `STEP ${this.activeScenario.stepNumber}` : noteType.toUpperCase(),
|
|
2502
|
-
pillText: noteType === "page" ? `Page Viewport: ${window.innerWidth} \xD7 ${window.innerHeight} px` : `${getSemanticSelector(targetEl)} (${Math.round(targetEl.getBoundingClientRect().width)}\xD7${Math.round(targetEl.getBoundingClientRect().height)}) \xB7 Viewport: ${window.innerWidth}\xD7${window.innerHeight}`,
|
|
2907
|
+
pillText: noteType === "page" ? `Page Viewport: ${window.innerWidth} \xD7 ${window.innerHeight} px` : `${compPrefix}${getSemanticSelector(targetEl)} (${Math.round(targetEl.getBoundingClientRect().width)}\xD7${Math.round(targetEl.getBoundingClientRect().height)}) \xB7 Viewport: ${window.innerWidth}\xD7${window.innerHeight}`,
|
|
2503
2908
|
onSave: async (message, action) => {
|
|
2504
2909
|
let scenarioParam;
|
|
2505
2910
|
if (action === "next_step" && !this.activeScenario) {
|
|
@@ -2769,12 +3174,14 @@ var NoteInspector = class {
|
|
|
2769
3174
|
if (innerText && innerText.length > 200) {
|
|
2770
3175
|
innerText = truncate(innerText, 200);
|
|
2771
3176
|
}
|
|
3177
|
+
const componentSource = resolveComponentSource(el);
|
|
2772
3178
|
return {
|
|
2773
3179
|
selector,
|
|
2774
3180
|
tag: el.tagName.toLowerCase(),
|
|
2775
3181
|
attributes,
|
|
2776
3182
|
outerHTML,
|
|
2777
3183
|
innerText,
|
|
3184
|
+
componentSource,
|
|
2778
3185
|
parent: el.parentElement ? {
|
|
2779
3186
|
selector: getSemanticSelector(el.parentElement),
|
|
2780
3187
|
tag: el.parentElement.tagName.toLowerCase()
|
|
@@ -2805,7 +3212,11 @@ var NoteInspector = class {
|
|
|
2805
3212
|
region.width,
|
|
2806
3213
|
region.height
|
|
2807
3214
|
);
|
|
2808
|
-
|
|
3215
|
+
try {
|
|
3216
|
+
resolve(canvas.toDataURL("image/png"));
|
|
3217
|
+
} catch {
|
|
3218
|
+
resolve(dataUrl);
|
|
3219
|
+
}
|
|
2809
3220
|
};
|
|
2810
3221
|
img.onerror = () => resolve(dataUrl);
|
|
2811
3222
|
img.src = dataUrl;
|
|
@@ -2857,7 +3268,11 @@ var BrowserTrackClient = class {
|
|
|
2857
3268
|
if (this.options.notes.enabled) {
|
|
2858
3269
|
this.inspector = new NoteInspector(this.transport, this.screenshotDriver, {
|
|
2859
3270
|
shortcut: this.options.notes.shortcut,
|
|
2860
|
-
maskSelectors: this.options.notes.maskSelectors
|
|
3271
|
+
maskSelectors: this.options.notes.maskSelectors,
|
|
3272
|
+
showToolbar: this.options.notes.showToolbar,
|
|
3273
|
+
showBadges: this.options.notes.showBadges,
|
|
3274
|
+
hidden: this.options.hidden,
|
|
3275
|
+
hideQueryParam: this.options.hideQueryParam
|
|
2861
3276
|
});
|
|
2862
3277
|
}
|
|
2863
3278
|
}
|
|
@@ -2923,6 +3338,14 @@ var BrowserTrackClient = class {
|
|
|
2923
3338
|
this.inspector.setMode("element");
|
|
2924
3339
|
}
|
|
2925
3340
|
}
|
|
3341
|
+
isUIVisible() {
|
|
3342
|
+
return this.inspector ? this.inspector.isVisible() : false;
|
|
3343
|
+
}
|
|
3344
|
+
setUIVisible(visible) {
|
|
3345
|
+
if (this.inspector) {
|
|
3346
|
+
this.inspector.setVisible(visible);
|
|
3347
|
+
}
|
|
3348
|
+
}
|
|
2926
3349
|
setInspectMode(mode) {
|
|
2927
3350
|
if (this.inspector) {
|
|
2928
3351
|
this.inspector.setMode(mode);
|
|
@@ -3063,8 +3486,10 @@ if (typeof window !== "undefined") {
|
|
|
3063
3486
|
const autoInit = currentScript?.getAttribute("data-auto-init") !== "false";
|
|
3064
3487
|
const daemonUrl = currentScript?.getAttribute("data-daemon-url") || void 0;
|
|
3065
3488
|
const projectId = currentScript?.getAttribute("data-project-id") || void 0;
|
|
3489
|
+
const hidden = currentScript?.getAttribute("data-hidden") === "true";
|
|
3490
|
+
const hideQueryParam = currentScript?.getAttribute("data-hide-query-param") || void 0;
|
|
3066
3491
|
if (autoInit) {
|
|
3067
|
-
init({ daemonUrl, projectId });
|
|
3492
|
+
init({ daemonUrl, projectId, hidden, hideQueryParam });
|
|
3068
3493
|
}
|
|
3069
3494
|
} catch {
|
|
3070
3495
|
}
|
|
@@ -3077,5 +3502,7 @@ if (typeof window !== "undefined") {
|
|
|
3077
3502
|
DEFAULT_OPTIONS,
|
|
3078
3503
|
NoteInspector,
|
|
3079
3504
|
getClient,
|
|
3080
|
-
init
|
|
3505
|
+
init,
|
|
3506
|
+
resolveComponentSource,
|
|
3507
|
+
shouldHideUIFromUrl
|
|
3081
3508
|
});
|