@web-widget/inspector 1.68.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1545 @@
1
+ import { css, LitElement, html } from 'lit';
2
+ import { property, state } from 'lit/decorators.js';
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __decorateClass = (decorators, target, key, kind) => {
7
+ var result = kind > 1 ? undefined : kind ? __getOwnPropDesc(target, key) : target;
8
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
9
+ if (decorator = decorators[i])
10
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
11
+ if (kind && result) __defProp(target, key, result);
12
+ return result;
13
+ };
14
+
15
+ // src/utils/widget-finder.ts
16
+ function findWebWidgetContainer(element) {
17
+ if (!element) {
18
+ return null;
19
+ }
20
+ if (element.tagName === "WEB-WIDGET" && element.hasAttribute("import")) {
21
+ return element;
22
+ }
23
+ const container = element.closest("web-widget[import]");
24
+ return container;
25
+ }
26
+
27
+ // src/utils/storage.ts
28
+ function getStoredValue(key, defaultValue) {
29
+ const stored = localStorage.getItem(key);
30
+ if (stored === null) {
31
+ return defaultValue;
32
+ }
33
+ try {
34
+ return JSON.parse(stored);
35
+ } catch {
36
+ return defaultValue;
37
+ }
38
+ }
39
+ function setStoredValue(key, value) {
40
+ localStorage.setItem(key, JSON.stringify(value));
41
+ }
42
+
43
+ // src/utils/design-system.ts
44
+ var spacing = {
45
+ xs: "0.25rem",
46
+ sm: "0.5rem",
47
+ md: "0.75rem",
48
+ lg: "1rem",
49
+ xl: "1.25rem",
50
+ "2xl": "1.5rem",
51
+ "3xl": "2rem",
52
+ "4xl": "2.5rem",
53
+ "5xl": "3rem"
54
+ };
55
+ var typography = {
56
+ fontFamily: {
57
+ sans: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
58
+ mono: 'ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace'
59
+ },
60
+ fontSize: {
61
+ xs: "0.75rem",
62
+ sm: "0.875rem",
63
+ base: "1rem",
64
+ lg: "1.125rem",
65
+ xl: "1.25rem",
66
+ "2xl": "1.5rem",
67
+ "3xl": "1.875rem",
68
+ "4xl": "2.25rem"
69
+ },
70
+ fontWeight: {
71
+ normal: "400",
72
+ medium: "500",
73
+ semibold: "600",
74
+ bold: "700"
75
+ },
76
+ lineHeight: {
77
+ none: "1",
78
+ tight: "1.25",
79
+ normal: "1.5",
80
+ relaxed: "1.75"
81
+ },
82
+ letterSpacing: {
83
+ normal: "0",
84
+ wide: "0.025em",
85
+ wider: "0.05em",
86
+ widest: "0.1em"
87
+ }
88
+ };
89
+ var borderRadius = {
90
+ none: "0",
91
+ sm: "0.125rem",
92
+ base: "0.25rem",
93
+ md: "0.375rem",
94
+ lg: "0.5rem",
95
+ xl: "0.75rem",
96
+ "2xl": "1rem",
97
+ "3xl": "1.5rem",
98
+ full: "9999px"
99
+ };
100
+ var boxShadow = {
101
+ none: "none",
102
+ sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
103
+ base: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",
104
+ md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
105
+ lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
106
+ xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
107
+ "2xl": "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
108
+ inner: "inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)"
109
+ };
110
+ var opacity = {
111
+ 0: "0",
112
+ 5: "0.05",
113
+ 10: "0.1",
114
+ 20: "0.2",
115
+ 25: "0.25",
116
+ 30: "0.3",
117
+ 40: "0.4",
118
+ 50: "0.5",
119
+ 60: "0.6",
120
+ 70: "0.7",
121
+ 75: "0.75",
122
+ 80: "0.8",
123
+ 85: "0.85",
124
+ 90: "0.9",
125
+ 95: "0.95",
126
+ 98: "0.98",
127
+ 100: "1"
128
+ };
129
+ var backdropBlur = {
130
+ none: "0",
131
+ sm: "4px",
132
+ base: "8px",
133
+ md: "12px",
134
+ lg: "16px",
135
+ xl: "24px",
136
+ "2xl": "40px",
137
+ "3xl": "64px"
138
+ };
139
+ var transition = {
140
+ none: "none",
141
+ all: "all 150ms cubic-bezier(0.4, 0, 0.2, 1)",
142
+ colors: "color 150ms cubic-bezier(0.4, 0, 0.2, 1), background-color 150ms cubic-bezier(0.4, 0, 0.2, 1), border-color 150ms cubic-bezier(0.4, 0, 0.2, 1)",
143
+ opacity: "opacity 150ms cubic-bezier(0.4, 0, 0.2, 1)",
144
+ transform: "transform 150ms cubic-bezier(0.4, 0, 0.2, 1)"
145
+ };
146
+ var zIndex = {
147
+ auto: "auto",
148
+ 0: "0",
149
+ 10: "10",
150
+ 20: "20",
151
+ 30: "30",
152
+ 40: "40",
153
+ 50: "50",
154
+ dropdown: "1000",
155
+ sticky: "1020",
156
+ fixed: "1030",
157
+ modal: "1040",
158
+ popover: "1050",
159
+ tooltip: "1060",
160
+ toast: "1070"
161
+ };
162
+ var themes = {
163
+ light: {
164
+ bg: "rgba(255, 255, 255, 0.92)",
165
+ fg: "#222",
166
+ fgHover: "#111",
167
+ fgSelected: "#000",
168
+ border: "#e5e7eb",
169
+ accent: "#888",
170
+ accentHover: "#666",
171
+ accentSelected: "#444",
172
+ primary: "rgba(102, 126, 234, 1)",
173
+ primaryHover: "rgba(102, 126, 234, 0.9)",
174
+ primarySelected: "rgba(102, 126, 234, 1)"
175
+ },
176
+ dark: {
177
+ bg: "rgba(17, 17, 17, 0.92)",
178
+ fg: "#f3f4f6",
179
+ fgHover: "#ffffff",
180
+ fgSelected: "#ffffff",
181
+ border: "#374151",
182
+ accent: "#9ca3af",
183
+ accentHover: "#d1d5db",
184
+ accentSelected: "#f3f4f6",
185
+ primary: "rgba(102, 126, 234, 1)",
186
+ primaryHover: "rgba(102, 126, 234, 0.9)",
187
+ primarySelected: "rgba(102, 126, 234, 1)"
188
+ }
189
+ };
190
+ var DESIGN_SYSTEM = {
191
+ spacing,
192
+ typography,
193
+ borderRadius,
194
+ boxShadow,
195
+ opacity,
196
+ backdropBlur,
197
+ transition,
198
+ zIndex
199
+ };
200
+ function getThemeVariables(theme) {
201
+ return themes[theme];
202
+ }
203
+
204
+ // src/utils/theme.ts
205
+ function applyTheme(vars) {
206
+ const root = document.documentElement;
207
+ root.style.setProperty("--wwi-bg", vars.bg);
208
+ root.style.setProperty("--wwi-fg", vars.fg);
209
+ root.style.setProperty("--wwi-border", vars.border);
210
+ root.style.setProperty("--wwi-accent", vars.accent);
211
+ }
212
+ function detectAutoTheme() {
213
+ if (typeof document === "undefined" || !document.body || !document.documentElement) {
214
+ return undefined;
215
+ }
216
+ const bodyStyle = getComputedStyle(document.body);
217
+ let bg = bodyStyle?.backgroundColor;
218
+ if (!bg || bg === "rgba(0, 0, 0, 0)" || bg === "transparent") {
219
+ const docStyle = getComputedStyle(document.documentElement);
220
+ bg = docStyle?.backgroundColor;
221
+ }
222
+ let isTransparent = false;
223
+ if (!bg || bg === "rgba(0, 0, 0, 0)" || bg === "transparent") {
224
+ bg = "rgb(255,255,255)";
225
+ isTransparent = true;
226
+ }
227
+ let r = 255;
228
+ let g = 255;
229
+ let b = 255;
230
+ const match = bg.match(/rgba?\(([^)]+)\)/);
231
+ if (match) {
232
+ const parts = match[1]?.split(",").map((x) => parseFloat(x.trim())) ?? [];
233
+ r = parts[0] ?? 255;
234
+ g = parts[1] ?? 255;
235
+ b = parts[2] ?? 255;
236
+ }
237
+ const brightness = (r * 299 + g * 587 + b * 114) / 1e3;
238
+ if (isTransparent || Number.isNaN(brightness) || brightness >= 128) {
239
+ return "light";
240
+ } else {
241
+ return "dark";
242
+ }
243
+ }
244
+ function applyThemeMode(mode) {
245
+ if (mode !== "auto") {
246
+ const theme = getThemeVariables(mode);
247
+ if (theme) {
248
+ applyTheme(theme);
249
+ }
250
+ return;
251
+ }
252
+ const autoTheme = detectAutoTheme();
253
+ if (autoTheme) {
254
+ const theme = getThemeVariables(autoTheme);
255
+ if (theme) {
256
+ applyTheme(theme);
257
+ } else {
258
+ applyTheme(getThemeVariables("light"));
259
+ }
260
+ } else {
261
+ applyTheme(getThemeVariables("light"));
262
+ }
263
+ }
264
+
265
+ // src/utils/box.ts
266
+ function isValidRect(rect) {
267
+ return rect.width > 0 || rect.height > 0;
268
+ }
269
+ function mergeRects(rects) {
270
+ if (rects.length === 0) return null;
271
+ let top = Infinity, left = Infinity, right = -Infinity, bottom = -Infinity;
272
+ for (const rect of rects) {
273
+ top = Math.min(top, rect.top);
274
+ left = Math.min(left, rect.left);
275
+ right = Math.max(right, rect.right);
276
+ bottom = Math.max(bottom, rect.bottom);
277
+ }
278
+ return {
279
+ top,
280
+ left,
281
+ right,
282
+ bottom,
283
+ width: right - left,
284
+ height: bottom - top
285
+ };
286
+ }
287
+ function getNodeRectsDeep(node) {
288
+ const rects = [];
289
+ if (node.nodeType === Node.ELEMENT_NODE) {
290
+ const el = node;
291
+ const style = getComputedStyle(el);
292
+ if (style.display === "none") return [];
293
+ const rect = el.getBoundingClientRect();
294
+ if (isValidRect(rect)) rects.push(rect);
295
+ const children = el.shadowRoot ? Array.from(el.shadowRoot.children) : Array.from(el.children);
296
+ for (const child of children) {
297
+ rects.push(...getNodeRectsDeep(child));
298
+ }
299
+ if (el.tagName === "SLOT") {
300
+ const assigned = el.assignedNodes({ flatten: true });
301
+ for (const assignedNode of assigned) {
302
+ rects.push(...getNodeRectsDeep(assignedNode));
303
+ }
304
+ }
305
+ } else if (node.nodeType === Node.TEXT_NODE) {
306
+ const range = document.createRange();
307
+ range.selectNodeContents(node);
308
+ const rect = range.getBoundingClientRect();
309
+ if (isValidRect(rect)) rects.push(rect);
310
+ }
311
+ return rects;
312
+ }
313
+ function getElementBox(el) {
314
+ const allRects = getNodeRectsDeep(el);
315
+ return mergeRects(allRects);
316
+ }
317
+
318
+ // src/utils/debug-data.ts
319
+ var DebugDataCollector = class {
320
+ /**
321
+ * Collect debug data for an element
322
+ */
323
+ static collectElementData(element) {
324
+ const bounds = getElementBox(element) ?? {
325
+ left: 0,
326
+ top: 0,
327
+ right: 0,
328
+ bottom: 0,
329
+ width: 0,
330
+ height: 0
331
+ };
332
+ const isWebWidget = element.tagName === "WEB-WIDGET";
333
+ const data = {
334
+ tag: element.tagName.toLowerCase(),
335
+ bounds,
336
+ isWebWidget
337
+ };
338
+ if (element.id) {
339
+ data.id = element.id;
340
+ }
341
+ if (isWebWidget) {
342
+ data.webWidgetData = this.collectWebWidgetData(element);
343
+ }
344
+ return data;
345
+ }
346
+ /**
347
+ * Collect debug data for Web Widget
348
+ */
349
+ static collectWebWidgetData(element) {
350
+ const data = {};
351
+ const name = element.getAttribute("name");
352
+ if (name) {
353
+ data.name = name;
354
+ }
355
+ const importUrl = element.getAttribute("import");
356
+ if (importUrl) {
357
+ data.module = importUrl;
358
+ }
359
+ const loading = element.loading;
360
+ if (loading && loading !== "eager") {
361
+ data.loading = loading;
362
+ }
363
+ const renderTarget = element.renderTarget;
364
+ if (renderTarget && renderTarget !== "light") {
365
+ data.renderTarget = renderTarget;
366
+ }
367
+ const status = element.status;
368
+ if (status) {
369
+ data.status = status;
370
+ }
371
+ if (element.inactive) {
372
+ data.inactive = true;
373
+ }
374
+ const contextData = element.getAttribute("contextdata");
375
+ if (contextData) {
376
+ try {
377
+ data.contextData = JSON.parse(contextData);
378
+ } catch {
379
+ }
380
+ }
381
+ const performanceData = this.collectPerformanceData();
382
+ if (performanceData.loadTime) {
383
+ data.loadTime = performanceData.loadTime;
384
+ }
385
+ if (performanceData.mountTime) {
386
+ data.mountTime = performanceData.mountTime;
387
+ }
388
+ return data;
389
+ }
390
+ /**
391
+ * Collect performance data
392
+ */
393
+ static collectPerformanceData() {
394
+ const data = {};
395
+ const loadMeasure = performance.getEntriesByName("web-widget:load")[0];
396
+ const mountMeasure = performance.getEntriesByName("web-widget:mount")[0];
397
+ if (loadMeasure) {
398
+ data.loadTime = Math.round(loadMeasure.duration);
399
+ }
400
+ if (mountMeasure) {
401
+ data.mountTime = Math.round(mountMeasure.duration);
402
+ }
403
+ return data;
404
+ }
405
+ /**
406
+ * Convert debug data to display format with priority-based sorting
407
+ */
408
+ static formatDebugData(data) {
409
+ const items = [];
410
+ if (data.isWebWidget && data.webWidgetData) {
411
+ const widgetData = data.webWidgetData;
412
+ if (widgetData.name) {
413
+ items.push({ key: "Component", value: widgetData.name, priority: 1 });
414
+ }
415
+ if (widgetData.module) {
416
+ items.push({ key: "Module", value: widgetData.module, priority: 2 });
417
+ }
418
+ if (widgetData.status) {
419
+ items.push({ key: "Status", value: widgetData.status, priority: 3 });
420
+ }
421
+ if (widgetData.inactive) {
422
+ items.push({ key: "State", value: "inactive", priority: 4 });
423
+ }
424
+ if (widgetData.loading) {
425
+ items.push({ key: "Loading", value: widgetData.loading, priority: 5 });
426
+ }
427
+ if (widgetData.renderTarget) {
428
+ items.push({
429
+ key: "Render",
430
+ value: widgetData.renderTarget,
431
+ priority: 6
432
+ });
433
+ }
434
+ if (widgetData.loadTime) {
435
+ items.push({
436
+ key: "Load Time",
437
+ value: `${widgetData.loadTime}ms`,
438
+ priority: 7
439
+ });
440
+ }
441
+ if (widgetData.mountTime) {
442
+ items.push({
443
+ key: "Mount Time",
444
+ value: `${widgetData.mountTime}ms`,
445
+ priority: 8
446
+ });
447
+ }
448
+ if (widgetData.contextData) {
449
+ const dataKeys = Object.keys(widgetData.contextData);
450
+ if (dataKeys.length > 0) {
451
+ items.push({
452
+ key: "Parameters",
453
+ value: `${dataKeys.length} keys`,
454
+ priority: 9
455
+ });
456
+ }
457
+ }
458
+ } else {
459
+ items.push({ key: "Tag", value: data.tag, priority: 1 });
460
+ if (data.id) {
461
+ items.push({ key: "ID", value: data.id, priority: 2 });
462
+ }
463
+ }
464
+ items.push({
465
+ key: "Size",
466
+ value: `${Math.round(data.bounds.width)}\xD7${Math.round(data.bounds.height)}px`,
467
+ priority: 10
468
+ });
469
+ return items.sort((a, b) => a.priority - b.priority);
470
+ }
471
+ /**
472
+ * Generate tooltip content with priority-based styling
473
+ */
474
+ static generateTooltipContent(element) {
475
+ const debugData = this.collectElementData(element);
476
+ const formattedData = this.formatDebugData(debugData);
477
+ const tableRows = formattedData.map((item) => {
478
+ const priorityClass = this.getPriorityClass(item.priority);
479
+ return `<tr class="${priorityClass}"><td class="key">${item.key}</td><td class="value">${item.value}</td></tr>`;
480
+ }).join("");
481
+ const helpText = debugData.isWebWidget ? '<div class="tooltip-help">\u{1F4A1} Click to open source code</div>' : "";
482
+ return `<table class="tooltip-table">${tableRows}</table>${helpText}`;
483
+ }
484
+ /**
485
+ * Get CSS class based on priority level
486
+ */
487
+ static getPriorityClass(priority) {
488
+ if (priority <= 3) return "priority-high";
489
+ if (priority <= 6) return "priority-medium";
490
+ return "priority-low";
491
+ }
492
+ };
493
+
494
+ // src/constants.ts
495
+ var Z_INDEX = {
496
+ /** Tooltip/Bubble - Highest priority for information display */
497
+ TOOLTIP: 2147483647,
498
+ /** Toolbar - Inspector controls and UI */
499
+ TOOLBAR: 2147483646,
500
+ /** Overlay - Element highlighting during inspection mode */
501
+ OVERLAY: 2147483645,
502
+ /** Page elements - Default z-index for normal content */
503
+ PAGE_ELEMENTS: "auto"
504
+ };
505
+
506
+ // src/element.ts
507
+ var HTMLWebWidgetInspectorElement = class extends LitElement {
508
+ constructor() {
509
+ super(...arguments);
510
+ this.dir = "";
511
+ this.keys = [];
512
+ this.pageSource = "";
513
+ this._theme = "auto";
514
+ this.isToolbarVisible = true;
515
+ this.isInspectorMode = false;
516
+ this.isMinimized = false;
517
+ this.hoveredElement = null;
518
+ this.widgetCount = 0;
519
+ this.pressedKeys = /* @__PURE__ */ new Set();
520
+ this.tooltipElement = null;
521
+ this.tooltipTimeout = null;
522
+ }
523
+ get theme() {
524
+ return this._theme;
525
+ }
526
+ set theme(value) {
527
+ const oldValue = this._theme;
528
+ this._theme = value;
529
+ this.setAttribute("theme", value);
530
+ if (oldValue !== value) {
531
+ this.initializeTheme();
532
+ }
533
+ }
534
+ connectedCallback() {
535
+ super.connectedCallback();
536
+ this.initializeTheme();
537
+ this.initializeEventListeners();
538
+ this.updateWidgetCount();
539
+ this.loadStoredState();
540
+ this.loadRouteModuleSourceFromHeaders();
541
+ }
542
+ disconnectedCallback() {
543
+ super.disconnectedCallback();
544
+ this.cleanupTooltip();
545
+ this.cleanupInspectorElements();
546
+ }
547
+ initializeTheme() {
548
+ applyThemeMode(this.theme);
549
+ }
550
+ initializeEventListeners() {
551
+ document.addEventListener("keydown", (e) => this.handleKeyEvent(e, true), {
552
+ capture: true
553
+ });
554
+ document.addEventListener("keyup", (e) => this.handleKeyEvent(e, false), {
555
+ capture: true
556
+ });
557
+ window.addEventListener("blur", this.clearKeys.bind(this), {
558
+ capture: true
559
+ });
560
+ document.addEventListener("mousemove", this.handleHoverEvent.bind(this), {
561
+ capture: true
562
+ });
563
+ document.addEventListener("mouseover", this.handleHoverEvent.bind(this), {
564
+ capture: true
565
+ });
566
+ document.addEventListener("click", this.handleClickEvent.bind(this), {
567
+ capture: true
568
+ });
569
+ document.addEventListener("contextmenu", this.clearKeys.bind(this), {
570
+ capture: true
571
+ });
572
+ window.addEventListener("resize", this.updateState.bind(this));
573
+ document.addEventListener("scroll", this.updateState.bind(this));
574
+ }
575
+ loadStoredState() {
576
+ this.isToolbarVisible = getStoredValue(
577
+ "web-widget-inspector-visible",
578
+ true
579
+ );
580
+ this.isMinimized = getStoredValue("web-widget-inspector-minimized", false);
581
+ }
582
+ handleKeyEvent(event, add) {
583
+ if (event.code === "Escape" && this.isInspectorMode) {
584
+ this.isInspectorMode = false;
585
+ this.updateState();
586
+ event.preventDefault();
587
+ return;
588
+ }
589
+ if (add) {
590
+ this.pressedKeys.add(event.code);
591
+ } else {
592
+ this.pressedKeys.delete(event.code);
593
+ }
594
+ this.updateState();
595
+ }
596
+ clearKeys() {
597
+ this.pressedKeys.clear();
598
+ }
599
+ checkKeysMatch(targetKeys) {
600
+ if (!targetKeys.length) return false;
601
+ return targetKeys.every((key) => {
602
+ const normalizedKey = key === "Shift" ? "ShiftLeft" : key;
603
+ return this.pressedKeys.has(key) || this.pressedKeys.has(normalizedKey);
604
+ });
605
+ }
606
+ handleHoverEvent(event) {
607
+ if (!this.isInspectorMode) return;
608
+ const target = findWebWidgetContainer(event.target);
609
+ if (this.hoveredElement !== target) {
610
+ this.hoveredElement = target;
611
+ this.updateState();
612
+ }
613
+ }
614
+ handleClickEvent(event) {
615
+ if (this.isInspectorMode) {
616
+ const toolbar = this.renderRoot?.querySelector(".inspector-toolbar");
617
+ const isToolbarClick = toolbar?.contains(event.target);
618
+ if (isToolbarClick) {
619
+ return;
620
+ }
621
+ event.preventDefault();
622
+ event.stopPropagation();
623
+ event.stopImmediatePropagation();
624
+ const widgetTarget = findWebWidgetContainer(event.target);
625
+ const inspectUrl = widgetTarget?.getAttribute("import");
626
+ if (inspectUrl) {
627
+ document.body.style.cursor = "progress";
628
+ this.openInEditor(inspectUrl, this.dir);
629
+ this.updateState();
630
+ }
631
+ }
632
+ }
633
+ updateState() {
634
+ const shouldShowInspector = !!(this.hoveredElement && this.isInspectorMode);
635
+ const targetKeys = this.keys;
636
+ this.isToolbarVisible || this.checkKeysMatch(targetKeys);
637
+ if (!this.isToolbarVisible && this.checkKeysMatch(targetKeys)) {
638
+ this.showToolbar();
639
+ }
640
+ this.updateOverlay(shouldShowInspector);
641
+ this.setButtonSelected(this.isInspectorMode);
642
+ if (this.isInspectorMode) {
643
+ const shouldShowPointer = !!this.hoveredElement;
644
+ if (shouldShowPointer) {
645
+ document.body.style.setProperty("cursor", "pointer", "important");
646
+ } else {
647
+ document.body.style.removeProperty("cursor");
648
+ }
649
+ } else {
650
+ document.body.style.removeProperty("cursor");
651
+ }
652
+ this.requestUpdate();
653
+ }
654
+ updateOverlay(show) {
655
+ let highlightOverlay = document.querySelector(
656
+ ".web-widget-inspector-highlight-overlay"
657
+ );
658
+ if (this.isInspectorMode) {
659
+ if (show && this.hoveredElement) {
660
+ if (!highlightOverlay) {
661
+ highlightOverlay = document.createElement("div");
662
+ highlightOverlay.className = "web-widget-inspector-highlight-overlay";
663
+ highlightOverlay.setAttribute("aria-hidden", "true");
664
+ document.body.appendChild(highlightOverlay);
665
+ }
666
+ const rect = getElementBox(this.hoveredElement) ?? {
667
+ top: 0,
668
+ left: 0,
669
+ width: 0,
670
+ height: 0
671
+ };
672
+ highlightOverlay.style.cssText = `
673
+ position: fixed !important;
674
+ top: ${rect.top}px !important;
675
+ left: ${rect.left}px !important;
676
+ width: ${rect.width}px !important;
677
+ height: ${rect.height}px !important;
678
+ z-index: 999998 !important;
679
+ pointer-events: none !important;
680
+ visibility: visible !important;
681
+ opacity: 1 !important;
682
+ display: block !important;
683
+ cursor: pointer !important;
684
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
685
+ background: repeating-linear-gradient(
686
+ 45deg,
687
+ rgba(102, 126, 234, 0.5),
688
+ rgba(102, 126, 234, 0.5) 5px,
689
+ rgba(255, 255, 255, 0.5) 5px,
690
+ rgba(255, 255, 255, 0.5) 10px
691
+ ) !important;
692
+ border: 2px solid rgba(102, 126, 234, 0.9) !important;
693
+ border-radius: 0 !important;
694
+ box-sizing: border-box !important;
695
+ `;
696
+ this.showTooltip(this.hoveredElement);
697
+ } else {
698
+ if (highlightOverlay) {
699
+ highlightOverlay.remove();
700
+ }
701
+ this.hideTooltip();
702
+ }
703
+ } else {
704
+ if (highlightOverlay) {
705
+ highlightOverlay.remove();
706
+ }
707
+ this.hideTooltip();
708
+ }
709
+ }
710
+ setButtonSelected(selected) {
711
+ const btn = this.renderRoot?.querySelector(".inspect-btn");
712
+ if (btn) {
713
+ btn.setAttribute("data-selected", selected ? "true" : "false");
714
+ btn.setAttribute("aria-pressed", selected ? "true" : "false");
715
+ }
716
+ }
717
+ updateWidgetCount() {
718
+ this.widgetCount = document.querySelectorAll("web-widget[import]").length;
719
+ }
720
+ createTooltipElement() {
721
+ if (this.tooltipElement) {
722
+ return this.tooltipElement;
723
+ }
724
+ if (!this.isInspectorMode) {
725
+ const dummy = document.createElement("div");
726
+ dummy.style.display = "none";
727
+ return dummy;
728
+ }
729
+ this.ensureTooltipStyles();
730
+ const tooltip = document.createElement("div");
731
+ tooltip.className = "inspector-tooltip";
732
+ tooltip.setAttribute("aria-hidden", "true");
733
+ tooltip.setAttribute("data-visible", "false");
734
+ document.body.appendChild(tooltip);
735
+ this.tooltipElement = tooltip;
736
+ return tooltip;
737
+ }
738
+ ensureTooltipStyles() {
739
+ if (!this.isInspectorMode) {
740
+ return;
741
+ }
742
+ if (document.getElementById("inspector-tooltip-styles")) {
743
+ return;
744
+ }
745
+ const style = document.createElement("style");
746
+ style.id = "inspector-tooltip-styles";
747
+ style.textContent = `
748
+ .inspector-tooltip {
749
+ position: fixed;
750
+ z-index: ${Z_INDEX.TOOLTIP};
751
+ pointer-events: none;
752
+ background: var(--wwi-bg, rgba(255, 255, 255, 0.95));
753
+ color: var(--wwi-fg, #222);
754
+ border: 1px solid var(--wwi-border, #e5e7eb);
755
+ border-radius: 0.375rem;
756
+ padding: ${DESIGN_SYSTEM.spacing.lg} ${DESIGN_SYSTEM.spacing.xl};
757
+ font-size: ${DESIGN_SYSTEM.typography.fontSize.base};
758
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
759
+ line-height: ${DESIGN_SYSTEM.typography.lineHeight.normal};
760
+ font-weight: ${DESIGN_SYSTEM.typography.fontWeight.normal};
761
+ letter-spacing: ${DESIGN_SYSTEM.typography.letterSpacing.normal};
762
+ word-wrap: break-word;
763
+ white-space: pre-wrap;
764
+ box-shadow: ${DESIGN_SYSTEM.boxShadow.base};
765
+ backdrop-filter: blur(8px);
766
+ max-width: 640px;
767
+ min-width: 280px;
768
+ visibility: hidden;
769
+ }
770
+
771
+ .tooltip-table {
772
+ width: 100%;
773
+ border-collapse: collapse;
774
+ font-size: ${DESIGN_SYSTEM.typography.fontSize.xs};
775
+ line-height: ${DESIGN_SYSTEM.typography.lineHeight.normal};
776
+ }
777
+
778
+ .tooltip-table td {
779
+ padding: ${DESIGN_SYSTEM.spacing.xs} 0;
780
+ vertical-align: top;
781
+ }
782
+
783
+ .tooltip-table .key {
784
+ color: var(--wwi-accent, #888);
785
+ font-weight: ${DESIGN_SYSTEM.typography.fontWeight.medium};
786
+ padding-right: ${DESIGN_SYSTEM.spacing.lg};
787
+ white-space: nowrap;
788
+ text-align: left;
789
+ opacity: 0.8;
790
+ }
791
+
792
+ .tooltip-table .value {
793
+ color: var(--wwi-fg, #222);
794
+ font-weight: ${DESIGN_SYSTEM.typography.fontWeight.normal};
795
+ word-break: break-all;
796
+ text-align: right;
797
+ }
798
+
799
+ /* Priority-based styling */
800
+ .tooltip-table tr.priority-high .key {
801
+ color: var(--wwi-fg, #222);
802
+ font-weight: ${DESIGN_SYSTEM.typography.fontWeight.semibold};
803
+ opacity: 1;
804
+ }
805
+
806
+ .tooltip-table tr.priority-high .value {
807
+ color: var(--wwi-fg, #222);
808
+ font-weight: ${DESIGN_SYSTEM.typography.fontWeight.medium};
809
+ }
810
+
811
+ .tooltip-table tr.priority-medium .key {
812
+ color: var(--wwi-accent, #666);
813
+ font-weight: ${DESIGN_SYSTEM.typography.fontWeight.medium};
814
+ opacity: 0.9;
815
+ }
816
+
817
+ .tooltip-table tr.priority-medium .value {
818
+ color: var(--wwi-fg, #444);
819
+ font-weight: ${DESIGN_SYSTEM.typography.fontWeight.normal};
820
+ }
821
+
822
+ .tooltip-table tr.priority-low .key {
823
+ color: var(--wwi-accent, #888);
824
+ font-weight: ${DESIGN_SYSTEM.typography.fontWeight.normal};
825
+ opacity: 0.7;
826
+ }
827
+
828
+ .tooltip-table tr.priority-low .value {
829
+ color: var(--wwi-fg, #666);
830
+ font-weight: ${DESIGN_SYSTEM.typography.fontWeight.normal};
831
+ opacity: 0.8;
832
+ }
833
+
834
+ .tooltip-help {
835
+ margin-top: ${DESIGN_SYSTEM.spacing.md};
836
+ padding-top: ${DESIGN_SYSTEM.spacing.md};
837
+ border-top: 1px solid var(--wwi-border, #e5e7eb);
838
+ font-size: ${DESIGN_SYSTEM.typography.fontSize.xs};
839
+ color: var(--wwi-accent, #888);
840
+ text-align: center;
841
+ opacity: 0.8;
842
+ }
843
+
844
+ @media (max-width: 768px) {
845
+ .inspector-toolbar {
846
+ bottom: ${DESIGN_SYSTEM.spacing.md};
847
+ left: ${DESIGN_SYSTEM.spacing.md};
848
+ right: ${DESIGN_SYSTEM.spacing.md};
849
+ flex-wrap: wrap;
850
+ max-width: calc(100vw - ${DESIGN_SYSTEM.spacing.xl});
851
+ padding: ${DESIGN_SYSTEM.spacing.md} ${DESIGN_SYSTEM.spacing.lg};
852
+ gap: ${DESIGN_SYSTEM.spacing.md};
853
+ }
854
+
855
+ .inspector-btn {
856
+ padding: ${DESIGN_SYSTEM.spacing.md} ${DESIGN_SYSTEM.spacing.md};
857
+ font-size: ${DESIGN_SYSTEM.typography.fontSize.sm};
858
+ }
859
+
860
+ .inspector-info {
861
+ font-size: ${DESIGN_SYSTEM.typography.fontSize.sm};
862
+ }
863
+
864
+ .inspector-tooltip {
865
+ font-size: ${DESIGN_SYSTEM.typography.fontSize.sm};
866
+ padding: ${DESIGN_SYSTEM.spacing.md} ${DESIGN_SYSTEM.spacing.lg};
867
+ max-width: calc(100vw - ${DESIGN_SYSTEM.spacing.xl});
868
+ }
869
+
870
+ .tooltip-table {
871
+ font-size: ${DESIGN_SYSTEM.typography.fontSize.sm};
872
+ }
873
+ }
874
+ `;
875
+ document.head.appendChild(style);
876
+ }
877
+ calculateSimplePosition(elementRect, tooltipRect) {
878
+ const viewportWidth = window.innerWidth;
879
+ const viewportHeight = window.innerHeight;
880
+ const padding = 8;
881
+ const minMargin = 8;
882
+ let x = elementRect.left;
883
+ let y = elementRect.top - tooltipRect.height - padding;
884
+ if (y < minMargin) {
885
+ y = elementRect.top + elementRect.height + padding;
886
+ }
887
+ x = Math.max(
888
+ minMargin,
889
+ Math.min(viewportWidth - tooltipRect.width - minMargin, x)
890
+ );
891
+ y = Math.max(
892
+ minMargin,
893
+ Math.min(viewportHeight - tooltipRect.height - minMargin, y)
894
+ );
895
+ return { x, y };
896
+ }
897
+ generateTooltipContent(element) {
898
+ return DebugDataCollector.generateTooltipContent(element);
899
+ }
900
+ showTooltip(element) {
901
+ if (!this.isInspectorMode || !element) return;
902
+ if (this.tooltipTimeout) {
903
+ clearTimeout(this.tooltipTimeout);
904
+ this.tooltipTimeout = null;
905
+ }
906
+ const tooltip = this.createTooltipElement();
907
+ const content = this.generateTooltipContent(element);
908
+ tooltip.innerHTML = content;
909
+ tooltip.style.visibility = "hidden";
910
+ tooltip.style.display = "block";
911
+ tooltip.offsetHeight;
912
+ const elementRect = getElementBox(element);
913
+ const tooltipRect = tooltip.getBoundingClientRect();
914
+ const position = this.calculateSimplePosition(
915
+ elementRect ?? {
916
+ top: 0,
917
+ left: 0,
918
+ right: 0,
919
+ bottom: 0,
920
+ width: 0,
921
+ height: 0
922
+ },
923
+ tooltipRect
924
+ );
925
+ tooltip.style.left = `${position.x}px`;
926
+ tooltip.style.top = `${position.y}px`;
927
+ tooltip.setAttribute("data-visible", "true");
928
+ tooltip.style.visibility = "visible";
929
+ }
930
+ hideTooltip() {
931
+ if (this.tooltipTimeout) {
932
+ clearTimeout(this.tooltipTimeout);
933
+ this.tooltipTimeout = null;
934
+ }
935
+ if (this.tooltipElement) {
936
+ this.tooltipElement.setAttribute("data-visible", "false");
937
+ this.tooltipElement.style.visibility = "hidden";
938
+ }
939
+ }
940
+ cleanupTooltip() {
941
+ if (this.tooltipElement) {
942
+ this.tooltipElement.remove();
943
+ this.tooltipElement = null;
944
+ }
945
+ if (this.tooltipTimeout) {
946
+ clearTimeout(this.tooltipTimeout);
947
+ this.tooltipTimeout = null;
948
+ }
949
+ }
950
+ cleanupInspectorElements() {
951
+ const highlightOverlay = document.querySelector(
952
+ ".web-widget-inspector-highlight-overlay"
953
+ );
954
+ if (highlightOverlay) {
955
+ highlightOverlay.remove();
956
+ }
957
+ const tooltipStyles = document.getElementById("inspector-tooltip-styles");
958
+ if (tooltipStyles) {
959
+ tooltipStyles.remove();
960
+ }
961
+ if (this.tooltipElement) {
962
+ this.tooltipElement.remove();
963
+ this.tooltipElement = null;
964
+ }
965
+ document.body.style.removeProperty("cursor");
966
+ }
967
+ toggleInspector() {
968
+ this.isInspectorMode = !this.isInspectorMode;
969
+ if (!this.isInspectorMode) {
970
+ this.cleanupInspectorElements();
971
+ }
972
+ this.updateState();
973
+ }
974
+ showToolbar() {
975
+ this.isToolbarVisible = true;
976
+ this.updateState();
977
+ setStoredValue("web-widget-inspector-visible", true);
978
+ }
979
+ hideToolbar() {
980
+ this.isToolbarVisible = false;
981
+ this.updateState();
982
+ setStoredValue("web-widget-inspector-visible", false);
983
+ }
984
+ minimizeToolbar() {
985
+ this.isMinimized = !this.isMinimized;
986
+ this.updateState();
987
+ setStoredValue("web-widget-inspector-minimized", this.isMinimized);
988
+ }
989
+ openInEditor(path, srcDir) {
990
+ if (srcDir) {
991
+ const resolvedURL = new URL(path, document.baseURI);
992
+ if (resolvedURL.origin === location.origin) {
993
+ const filePath = srcDir + resolvedURL.pathname;
994
+ this.openFileInEditor(filePath);
995
+ } else {
996
+ location.href = resolvedURL.href;
997
+ }
998
+ } else {
999
+ this.openFileInEditor(path);
1000
+ }
1001
+ }
1002
+ openFileInEditor(filePath) {
1003
+ document.body.style.cursor = "progress";
1004
+ fetch(`/__open-in-editor?file=${encodeURIComponent(filePath)}`).finally(
1005
+ () => {
1006
+ document.body.style.removeProperty("cursor");
1007
+ }
1008
+ );
1009
+ }
1010
+ getCurrentFilePath() {
1011
+ if (!this.pageSource) return "";
1012
+ try {
1013
+ if (this.pageSource.startsWith("source://")) {
1014
+ return this.pageSource.replace("source://", "");
1015
+ }
1016
+ const url = new URL(this.pageSource);
1017
+ return url.pathname;
1018
+ } catch {
1019
+ return this.pageSource;
1020
+ }
1021
+ }
1022
+ loadRouteModuleSourceFromHeaders() {
1023
+ if (!this.pageSource) {
1024
+ fetch(window.location.href, { method: "HEAD" }).then((response) => {
1025
+ const moduleSource = response.headers.get("x-module-source");
1026
+ if (moduleSource) {
1027
+ this.pageSource = moduleSource;
1028
+ }
1029
+ }).catch((error) => {
1030
+ console.error(
1031
+ "Error loading route module source from headers:",
1032
+ error
1033
+ );
1034
+ });
1035
+ }
1036
+ }
1037
+ render() {
1038
+ if (!this.isToolbarVisible) {
1039
+ return html``;
1040
+ }
1041
+ return html`
1042
+ <div
1043
+ class="inspector-toolbar"
1044
+ data-minimized=${this.isMinimized ? "true" : "false"}
1045
+ data-inspector-active=${this.isInspectorMode ? "true" : "false"}>
1046
+ <div class="inspector-header">
1047
+ <div
1048
+ class="inspector-logo"
1049
+ tabindex="0"
1050
+ title="Web Widget Inspector"
1051
+ @click=${this.minimizeToolbar}>
1052
+ <svg
1053
+ width="16"
1054
+ height="16"
1055
+ viewBox="0 0 24 24"
1056
+ fill="currentColor"
1057
+ aria-hidden="true">
1058
+ <path
1059
+ d="M12,2A2,2 0 0,1 14,4C14,4.74 13.6,5.39 13,5.73V7H14A7,7 0 0,1 21,14H22A1,1 0 0,1 23,15V18A1,1 0 0,1 22,19H21V20A2,2 0 0,1 19,22H5A2,2 0 0,1 3,20V19H2A1,1 0 0,1 1,18V15A1,1 0 0,1 2,14H3A7,7 0 0,1 10,7H11V5.73C10.4,5.39 10,4.74 10,4A2,2 0 0,1 12,2Z" />
1060
+ </svg>
1061
+ <div class="logo-text">
1062
+ <span class="logo-title">WEB WIDGET</span>
1063
+ <span class="logo-subtitle">DEV INSPECTOR</span>
1064
+ </div>
1065
+ </div>
1066
+ </div>
1067
+
1068
+ <div class="inspector-info">
1069
+ <span class="widget-count">${this.widgetCount} widgets</span>
1070
+ </div>
1071
+
1072
+ <div class="inspector-actions">
1073
+ <button
1074
+ class="inspector-btn inspect-btn"
1075
+ @click=${this.toggleInspector}
1076
+ title="Click to activate widget inspector (ESC to exit)"
1077
+ aria-label="Activate widget inspector mode">
1078
+ <svg
1079
+ width="16"
1080
+ height="16"
1081
+ viewBox="0 0 24 24"
1082
+ fill="none"
1083
+ stroke="currentColor"
1084
+ stroke-width="2"
1085
+ stroke-linecap="round"
1086
+ stroke-linejoin="round">
1087
+ <circle cx="11" cy="11" r="8" />
1088
+ <line x1="21" y1="21" x2="16.65" y2="16.65" />
1089
+ </svg>
1090
+ <span>Inspect</span>
1091
+ </button>
1092
+
1093
+ <button
1094
+ class="inspector-btn page-btn"
1095
+ @click=${() => {
1096
+ const currentFilePath = this.getCurrentFilePath();
1097
+ if (currentFilePath) {
1098
+ this.openInEditor(currentFilePath);
1099
+ }
1100
+ }}
1101
+ title="Open current page source code"
1102
+ aria-label="Open current page source code">
1103
+ <svg
1104
+ width="16"
1105
+ height="16"
1106
+ viewBox="0 0 24 24"
1107
+ fill="none"
1108
+ stroke="currentColor"
1109
+ stroke-width="2"
1110
+ stroke-linecap="round"
1111
+ stroke-linejoin="round">
1112
+ <rect x="3" y="3" width="18" height="18" rx="2" />
1113
+ <path d="M9 9h6v6H9z" />
1114
+ </svg>
1115
+ <span>Open Source</span>
1116
+ </button>
1117
+ </div>
1118
+
1119
+ <div class="inspector-controls">
1120
+ <button
1121
+ class="inspector-btn hide-btn"
1122
+ @click=${this.hideToolbar}
1123
+ title="Hide Web Widget Inspector"
1124
+ aria-label="Hide inspector toolbar">
1125
+ <svg
1126
+ width="16"
1127
+ height="16"
1128
+ viewBox="0 0 24 24"
1129
+ fill="none"
1130
+ stroke="currentColor"
1131
+ stroke-width="2"
1132
+ stroke-linecap="round"
1133
+ stroke-linejoin="round">
1134
+ <line x1="18" y1="6" x2="6" y2="18" />
1135
+ <line x1="6" y1="6" x2="18" y2="18" />
1136
+ </svg>
1137
+ </button>
1138
+ <button
1139
+ class="inspector-btn toggle-btn"
1140
+ @click=${this.minimizeToolbar}
1141
+ title="Minimize Web Widget Inspector"
1142
+ aria-label="Minimize inspector toolbar">
1143
+ <svg
1144
+ width="16"
1145
+ height="16"
1146
+ viewBox="0 0 24 24"
1147
+ fill="none"
1148
+ stroke="currentColor"
1149
+ stroke-width="2"
1150
+ stroke-linecap="round"
1151
+ stroke-linejoin="round">
1152
+ <polyline points="6 9 12 15 18 9" />
1153
+ </svg>
1154
+ </button>
1155
+ </div>
1156
+ </div>
1157
+ `;
1158
+ }
1159
+ };
1160
+ HTMLWebWidgetInspectorElement.styles = css`
1161
+ :host {
1162
+ display: contents;
1163
+ }
1164
+
1165
+ .inspector-toolbar,
1166
+ .inspector-toolbar *,
1167
+ .inspector-tooltip,
1168
+ .inspector-tooltip * {
1169
+ font-family:
1170
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
1171
+ Arial, sans-serif !important;
1172
+ }
1173
+
1174
+ .inspector-toolbar {
1175
+ display: flex;
1176
+ align-items: center;
1177
+ gap: 0.75rem;
1178
+ position: fixed;
1179
+ bottom: 1rem;
1180
+ left: 1rem;
1181
+ z-index: ${Z_INDEX.TOOLBAR};
1182
+ background: var(--wwi-bg, rgba(255, 255, 255, 0.95));
1183
+ color: var(--wwi-fg, #222);
1184
+ padding: 0.75rem 1rem;
1185
+ border-radius: 0.375rem;
1186
+ border: 1px solid var(--wwi-border, #e5e7eb);
1187
+ box-shadow:
1188
+ 0 1px 3px 0 rgba(0, 0, 0, 0.1),
1189
+ 0 1px 2px 0 rgba(0, 0, 0, 0.06);
1190
+ font-family:
1191
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
1192
+ Arial, sans-serif;
1193
+ font-size: 0.875rem;
1194
+ min-width: max-content;
1195
+ transition: all 0.2s;
1196
+ backdrop-filter: blur(8px);
1197
+ }
1198
+
1199
+ .inspector-toolbar[data-minimized='true'] {
1200
+ padding: 0 !important;
1201
+ gap: 0 !important;
1202
+ min-width: 0 !important;
1203
+ width: 32px !important;
1204
+ height: 32px !important;
1205
+ background: var(--wwi-bg, rgba(255, 255, 255, 0.95)) !important;
1206
+ border: 1px solid var(--wwi-border, #e5e7eb) !important;
1207
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06) !important;
1208
+ border-radius: 50% !important;
1209
+ cursor: pointer !important;
1210
+ justify-content: center !important;
1211
+ align-items: center !important;
1212
+ display: flex !important;
1213
+ transition:
1214
+ background 0.2s,
1215
+ border 0.2s !important;
1216
+ }
1217
+
1218
+ .inspector-toolbar[data-minimized='true']:hover {
1219
+ background: var(--wwi-bg, rgba(255, 255, 255, 0.98)) !important;
1220
+ border: 1px solid var(--wwi-border, #e5e7eb) !important;
1221
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08) !important;
1222
+ }
1223
+
1224
+ .inspector-toolbar[data-minimized='true'] .inspector-header {
1225
+ display: flex !important;
1226
+ flex: 1 1 auto !important;
1227
+ align-items: center !important;
1228
+ justify-content: center !important;
1229
+ padding: 0 !important;
1230
+ margin: 0 !important;
1231
+ height: 100% !important;
1232
+ }
1233
+
1234
+ .inspector-toolbar[data-minimized='true'] .inspector-logo {
1235
+ display: flex !important;
1236
+ align-items: center !important;
1237
+ justify-content: center !important;
1238
+ width: 100% !important;
1239
+ height: 100% !important;
1240
+ margin: 0 !important;
1241
+ padding: 0 !important;
1242
+ }
1243
+
1244
+ .inspector-toolbar[data-minimized='true'] .inspector-logo svg {
1245
+ margin: 0 !important;
1246
+ width: 16px !important;
1247
+ height: 16px !important;
1248
+ display: block !important;
1249
+ opacity: 0.7 !important;
1250
+ filter: none !important;
1251
+ transition: opacity 0.2s !important;
1252
+ }
1253
+
1254
+ .inspector-toolbar[data-minimized='true']:hover .inspector-logo svg {
1255
+ opacity: 1 !important;
1256
+ filter: none !important;
1257
+ }
1258
+
1259
+ .inspector-toolbar[data-minimized='true']
1260
+ .inspector-header
1261
+ .inspector-logo
1262
+ span,
1263
+ .inspector-toolbar[data-minimized='true'] .inspector-logo .logo-text,
1264
+ .inspector-toolbar[data-minimized='true'] .inspector-info,
1265
+ .inspector-toolbar[data-minimized='true'] .inspector-actions,
1266
+ .inspector-toolbar[data-minimized='true'] .inspector-controls {
1267
+ display: none !important;
1268
+ }
1269
+
1270
+ .inspector-overlay {
1271
+ position: fixed;
1272
+ z-index: ${Z_INDEX.OVERLAY};
1273
+ pointer-events: none;
1274
+ background: repeating-linear-gradient(
1275
+ 45deg,
1276
+ rgba(102, 126, 234, 0.5),
1277
+ rgba(102, 126, 234, 0.5) 5px,
1278
+ rgba(255, 255, 255, 0.5) 5px,
1279
+ rgba(255, 255, 255, 0.5) 10px
1280
+ );
1281
+ border: 2px solid rgba(102, 126, 234, 0.9);
1282
+ border-radius: 0;
1283
+ box-sizing: border-box;
1284
+ }
1285
+
1286
+ .inspector-tooltip {
1287
+ /* Styles dynamically injected by ensureTooltipStyles */
1288
+ display: none;
1289
+ }
1290
+
1291
+ .inspector-header {
1292
+ display: flex;
1293
+ align-items: center;
1294
+ gap: 0.375rem;
1295
+ padding-right: 0.5rem;
1296
+ }
1297
+
1298
+ .inspector-logo {
1299
+ display: flex;
1300
+ align-items: center;
1301
+ gap: 0.375rem;
1302
+ font-weight: 600;
1303
+ color: var(--wwi-accent, #888);
1304
+ font-size: 0.75rem;
1305
+ user-select: none;
1306
+ }
1307
+
1308
+ .inspector-logo svg {
1309
+ cursor: pointer;
1310
+ color: var(--wwi-accent, #888);
1311
+ width: 16px;
1312
+ height: 16px;
1313
+ margin-right: 0.125rem;
1314
+ }
1315
+
1316
+ .logo-text {
1317
+ display: flex;
1318
+ flex-direction: column;
1319
+ line-height: 1;
1320
+ gap: 0.125rem;
1321
+ align-items: flex-start;
1322
+ }
1323
+
1324
+ .logo-title {
1325
+ font-weight: 700;
1326
+ font-size: 0.7rem;
1327
+ color: var(--wwi-accent, #888);
1328
+ letter-spacing: 0.05em;
1329
+ text-transform: uppercase;
1330
+ }
1331
+
1332
+ .logo-subtitle {
1333
+ font-weight: 500;
1334
+ font-size: 0.5rem;
1335
+ color: var(--wwi-accent, #888);
1336
+ opacity: 0.75;
1337
+ letter-spacing: 0.14em;
1338
+ text-transform: uppercase;
1339
+ }
1340
+
1341
+ .inspector-info {
1342
+ display: flex;
1343
+ align-items: center;
1344
+ gap: 0.5rem;
1345
+ font-size: 0.875rem;
1346
+ color: var(--wwi-fg, #222);
1347
+ opacity: 0.7;
1348
+ }
1349
+
1350
+ .widget-count {
1351
+ color: var(--wwi-accent, #888);
1352
+ font-weight: 500;
1353
+ }
1354
+
1355
+ .inspector-actions {
1356
+ display: flex;
1357
+ align-items: center;
1358
+ gap: 0.375rem;
1359
+ }
1360
+
1361
+ .inspector-controls {
1362
+ display: flex;
1363
+ align-items: center;
1364
+ gap: 0.125rem;
1365
+ }
1366
+
1367
+ .inspector-btn {
1368
+ display: flex;
1369
+ align-items: center;
1370
+ gap: 0.25rem;
1371
+ background: transparent;
1372
+ border: 1px solid transparent;
1373
+ color: var(--wwi-fg, #222);
1374
+ padding: 0.25rem 0.5rem;
1375
+ border-radius: 0.25rem;
1376
+ cursor: pointer;
1377
+ transition: all 0.15s ease;
1378
+ font-size: 0.875rem;
1379
+ font-weight: 500;
1380
+ white-space: nowrap;
1381
+ opacity: 0.8;
1382
+ }
1383
+
1384
+ .inspector-btn:hover {
1385
+ background: rgba(0, 0, 0, 0.12);
1386
+ border-color: rgba(0, 0, 0, 0.2);
1387
+ color: var(--wwi-fg, #111);
1388
+ opacity: 1;
1389
+ transform: translateY(-1px);
1390
+ box-shadow:
1391
+ 0 1px 3px 0 rgba(0, 0, 0, 0.1),
1392
+ 0 1px 2px 0 rgba(0, 0, 0, 0.06);
1393
+ }
1394
+
1395
+ .inspector-btn[data-selected='true'] {
1396
+ background: rgba(102, 126, 234, 0.15);
1397
+ border-color: rgba(102, 126, 234, 0.4);
1398
+ color: rgba(102, 126, 234, 1);
1399
+ box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
1400
+ opacity: 1;
1401
+ position: relative;
1402
+ }
1403
+
1404
+ .inspector-btn[data-selected='true']::before {
1405
+ content: '';
1406
+ position: absolute;
1407
+ top: -2px;
1408
+ left: -2px;
1409
+ right: -2px;
1410
+ bottom: -2px;
1411
+ background: linear-gradient(
1412
+ 45deg,
1413
+ rgba(102, 126, 234, 0.3),
1414
+ rgba(102, 126, 234, 0.1)
1415
+ );
1416
+ border-radius: 0.375rem;
1417
+ z-index: -1;
1418
+ animation: pulse 2s infinite;
1419
+ }
1420
+
1421
+ @keyframes pulse {
1422
+ 0%,
1423
+ 100% {
1424
+ opacity: 0.6;
1425
+ }
1426
+ 50% {
1427
+ opacity: 1;
1428
+ }
1429
+ }
1430
+
1431
+ .inspector-btn[data-selected='true'] svg {
1432
+ stroke: rgba(102, 126, 234, 1);
1433
+ filter: drop-shadow(0 0 2px rgba(102, 126, 234, 0.3));
1434
+ }
1435
+
1436
+ .inspector-btn svg {
1437
+ flex-shrink: 0;
1438
+ width: 14px;
1439
+ height: 14px;
1440
+ stroke: currentColor;
1441
+ opacity: 0.9;
1442
+ }
1443
+
1444
+ .inspector-toolbar[data-inspector-active='true'] {
1445
+ border-color: rgba(102, 126, 234, 0.4);
1446
+ box-shadow:
1447
+ 0 2px 8px rgba(0, 0, 0, 0.06),
1448
+ 0 0 0 1px rgba(102, 126, 234, 0.2);
1449
+ background: var(--wwi-bg, rgba(255, 255, 255, 0.98));
1450
+ }
1451
+
1452
+ .inspector-toolbar[data-inspector-active='true']::before {
1453
+ content: '';
1454
+ position: absolute;
1455
+ top: -1px;
1456
+ left: -1px;
1457
+ right: -1px;
1458
+ bottom: -1px;
1459
+ background: linear-gradient(
1460
+ 45deg,
1461
+ rgba(102, 126, 234, 0.1),
1462
+ rgba(102, 126, 234, 0.05)
1463
+ );
1464
+ border-radius: 0.5rem;
1465
+ z-index: -1;
1466
+ animation: toolbar-pulse 3s infinite;
1467
+ }
1468
+
1469
+ @keyframes toolbar-pulse {
1470
+ 0%,
1471
+ 100% {
1472
+ opacity: 0.3;
1473
+ }
1474
+ 50% {
1475
+ opacity: 0.6;
1476
+ }
1477
+ }
1478
+
1479
+ @media (max-width: 768px) {
1480
+ .inspector-toolbar {
1481
+ bottom: 0.75rem;
1482
+ left: 0.75rem;
1483
+ right: 0.75rem;
1484
+ flex-wrap: wrap;
1485
+ max-width: calc(100vw - 1.25rem);
1486
+ padding: 0.75rem 1rem;
1487
+ gap: 0.75rem;
1488
+ }
1489
+
1490
+ .inspector-btn {
1491
+ padding: 0.75rem 0.75rem;
1492
+ font-size: 0.875rem;
1493
+ }
1494
+
1495
+ .inspector-info {
1496
+ font-size: 0.875rem;
1497
+ }
1498
+
1499
+ .logo-text {
1500
+ gap: 0.1rem;
1501
+ }
1502
+
1503
+ .logo-title {
1504
+ font-size: 0.6rem;
1505
+ letter-spacing: 0.04em;
1506
+ }
1507
+
1508
+ .logo-subtitle {
1509
+ font-size: 0.45rem;
1510
+ letter-spacing: 0.12em;
1511
+ }
1512
+ }
1513
+ `;
1514
+ __decorateClass([
1515
+ property({ type: String })
1516
+ ], HTMLWebWidgetInspectorElement.prototype, "dir", 2);
1517
+ __decorateClass([
1518
+ property({ type: Array })
1519
+ ], HTMLWebWidgetInspectorElement.prototype, "keys", 2);
1520
+ __decorateClass([
1521
+ property({ type: String, attribute: "page-source" })
1522
+ ], HTMLWebWidgetInspectorElement.prototype, "pageSource", 2);
1523
+ __decorateClass([
1524
+ property({ type: String })
1525
+ ], HTMLWebWidgetInspectorElement.prototype, "theme", 1);
1526
+ __decorateClass([
1527
+ state()
1528
+ ], HTMLWebWidgetInspectorElement.prototype, "isToolbarVisible", 2);
1529
+ __decorateClass([
1530
+ state()
1531
+ ], HTMLWebWidgetInspectorElement.prototype, "isInspectorMode", 2);
1532
+ __decorateClass([
1533
+ state()
1534
+ ], HTMLWebWidgetInspectorElement.prototype, "isMinimized", 2);
1535
+ __decorateClass([
1536
+ state()
1537
+ ], HTMLWebWidgetInspectorElement.prototype, "hoveredElement", 2);
1538
+ __decorateClass([
1539
+ state()
1540
+ ], HTMLWebWidgetInspectorElement.prototype, "widgetCount", 2);
1541
+
1542
+ // src/index.ts
1543
+ customElements.define("web-widget-inspector", HTMLWebWidgetInspectorElement);
1544
+ //# sourceMappingURL=index.js.map
1545
+ //# sourceMappingURL=index.js.map