@oddsquad/vite-plugin-lit 0.2.3 → 0.4.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.
Files changed (240) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/LICENSE +28 -0
  3. package/README.md +157 -0
  4. package/bin.mjs +154 -0
  5. package/client.d.ts +61 -0
  6. package/dist/client/assets/browser-agent-rpc-BXhoSh1z-CdtPhBL-.js +69 -0
  7. package/dist/client/assets/browser-agent-rpc-BXhoSh1z-CdtPhBL-.js.map +1 -0
  8. package/dist/client/assets/flow-DK8vmxvN.js +745 -0
  9. package/dist/client/assets/flow-DK8vmxvN.js.map +1 -0
  10. package/dist/client/assets/index-DVe6M4HV.js +10614 -0
  11. package/dist/client/assets/index-DVe6M4HV.js.map +1 -0
  12. package/{panel → dist/client}/index.html +1 -0
  13. package/index.d.ts.map +1 -1
  14. package/index.js +2 -2
  15. package/index.js.map +1 -1
  16. package/lib/color-scheme.d.ts.map +1 -1
  17. package/lib/color-scheme.js +17 -21
  18. package/lib/color-scheme.js.map +1 -1
  19. package/lib/devframe/definition.d.ts +45 -0
  20. package/lib/devframe/definition.d.ts.map +1 -0
  21. package/lib/devframe/definition.js +547 -0
  22. package/lib/devframe/definition.js.map +1 -0
  23. package/lib/devframe/icon.d.ts +8 -0
  24. package/lib/devframe/icon.d.ts.map +1 -0
  25. package/lib/devframe/icon.js +21 -0
  26. package/lib/devframe/icon.js.map +1 -0
  27. package/lib/devframe/paths.d.ts +12 -0
  28. package/lib/devframe/paths.d.ts.map +1 -0
  29. package/lib/devframe/paths.js +38 -0
  30. package/lib/devframe/paths.js.map +1 -0
  31. package/lib/devframe/protocol.d.ts +218 -0
  32. package/lib/devframe/protocol.d.ts.map +1 -0
  33. package/lib/devframe/protocol.js +77 -0
  34. package/lib/devframe/protocol.js.map +1 -0
  35. package/lib/devframe/source.d.ts +49 -0
  36. package/lib/devframe/source.d.ts.map +1 -0
  37. package/lib/devframe/source.js +23 -0
  38. package/lib/devframe/source.js.map +1 -0
  39. package/lib/devframe/vite.d.ts +116 -0
  40. package/lib/devframe/vite.d.ts.map +1 -0
  41. package/lib/devframe/vite.js +292 -0
  42. package/lib/devframe/vite.js.map +1 -0
  43. package/lib/http.d.ts +29 -0
  44. package/lib/http.d.ts.map +1 -0
  45. package/lib/http.js +35 -0
  46. package/lib/http.js.map +1 -0
  47. package/lib/icons.d.ts +2 -0
  48. package/lib/icons.d.ts.map +1 -1
  49. package/lib/icons.js +10 -4
  50. package/lib/icons.js.map +1 -1
  51. package/lib/options.d.ts +131 -0
  52. package/lib/options.d.ts.map +1 -0
  53. package/lib/options.js +128 -0
  54. package/lib/options.js.map +1 -0
  55. package/lib/plugin.d.ts +6 -137
  56. package/lib/plugin.d.ts.map +1 -1
  57. package/lib/plugin.js +280 -677
  58. package/lib/plugin.js.map +1 -1
  59. package/lib/plugins/css-literals.d.ts +15 -0
  60. package/lib/plugins/css-literals.d.ts.map +1 -0
  61. package/lib/plugins/css-literals.js +154 -0
  62. package/lib/plugins/css-literals.js.map +1 -0
  63. package/lib/plugins/css-queries.d.ts +20 -0
  64. package/lib/plugins/css-queries.d.ts.map +1 -0
  65. package/lib/plugins/css-queries.js +139 -0
  66. package/lib/plugins/css-queries.js.map +1 -0
  67. package/lib/plugins/open-in-editor.d.ts +16 -0
  68. package/lib/plugins/open-in-editor.d.ts.map +1 -0
  69. package/lib/plugins/open-in-editor.js +91 -0
  70. package/lib/plugins/open-in-editor.js.map +1 -0
  71. package/lib/plugins/shared.d.ts +13 -0
  72. package/lib/plugins/shared.d.ts.map +1 -0
  73. package/lib/plugins/shared.js +23 -0
  74. package/lib/plugins/shared.js.map +1 -0
  75. package/lib/plugins/timeline-virtual.d.ts +19 -0
  76. package/lib/plugins/timeline-virtual.d.ts.map +1 -0
  77. package/lib/plugins/timeline-virtual.js +53 -0
  78. package/lib/plugins/timeline-virtual.js.map +1 -0
  79. package/lib/runtime/css.d.ts +2 -2
  80. package/lib/runtime/css.d.ts.map +1 -1
  81. package/lib/runtime/css.js +41 -34
  82. package/lib/runtime/css.js.map +1 -1
  83. package/lib/runtime/edge-panel.d.ts.map +1 -1
  84. package/lib/runtime/edge-panel.js +82 -91
  85. package/lib/runtime/edge-panel.js.map +1 -1
  86. package/lib/runtime/fonts.d.ts.map +1 -1
  87. package/lib/runtime/fonts.js +1 -1
  88. package/lib/runtime/fonts.js.map +1 -1
  89. package/lib/runtime/indicator.d.ts.map +1 -1
  90. package/lib/runtime/indicator.js +71 -74
  91. package/lib/runtime/indicator.js.map +1 -1
  92. package/lib/runtime/inspector/collect.d.ts.map +1 -1
  93. package/lib/runtime/inspector/collect.js +83 -90
  94. package/lib/runtime/inspector/collect.js.map +1 -1
  95. package/lib/runtime/inspector/highlight.d.ts +16 -0
  96. package/lib/runtime/inspector/highlight.d.ts.map +1 -0
  97. package/lib/runtime/inspector/highlight.js +66 -0
  98. package/lib/runtime/inspector/highlight.js.map +1 -0
  99. package/lib/runtime/inspector/install.d.ts.map +1 -1
  100. package/lib/runtime/inspector/install.js +230 -205
  101. package/lib/runtime/inspector/install.js.map +1 -1
  102. package/lib/runtime/inspector/serialize.d.ts.map +1 -1
  103. package/lib/runtime/inspector/serialize.js +86 -107
  104. package/lib/runtime/inspector/serialize.js.map +1 -1
  105. package/lib/runtime/intern.d.ts.map +1 -1
  106. package/lib/runtime/intern.js +31 -29
  107. package/lib/runtime/intern.js.map +1 -1
  108. package/lib/runtime/overrides.d.ts.map +1 -1
  109. package/lib/runtime/overrides.js +14 -13
  110. package/lib/runtime/overrides.js.map +1 -1
  111. package/lib/runtime/patch.d.ts +8 -0
  112. package/lib/runtime/patch.d.ts.map +1 -1
  113. package/lib/runtime/patch.js +321 -282
  114. package/lib/runtime/patch.js.map +1 -1
  115. package/lib/runtime/source-meta.d.ts.map +1 -1
  116. package/lib/runtime/source-meta.js +1 -1
  117. package/lib/runtime/source-meta.js.map +1 -1
  118. package/lib/runtime/source-overlay/editors.d.ts.map +1 -1
  119. package/lib/runtime/source-overlay/editors.js +27 -27
  120. package/lib/runtime/source-overlay/editors.js.map +1 -1
  121. package/lib/runtime/source-overlay/mask-path.d.ts.map +1 -1
  122. package/lib/runtime/source-overlay/mask-path.js +15 -15
  123. package/lib/runtime/source-overlay/mask-path.js.map +1 -1
  124. package/lib/runtime/source-overlay/overlay-element.d.ts.map +1 -1
  125. package/lib/runtime/source-overlay/overlay-element.js +359 -355
  126. package/lib/runtime/source-overlay/overlay-element.js.map +1 -1
  127. package/lib/runtime/source-overlay/source-host.d.ts.map +1 -1
  128. package/lib/runtime/source-overlay/source-host.js +64 -71
  129. package/lib/runtime/source-overlay/source-host.js.map +1 -1
  130. package/lib/runtime/source-overlay/template.d.ts.map +1 -1
  131. package/lib/runtime/source-overlay/template.js +3 -3
  132. package/lib/runtime/source-overlay/template.js.map +1 -1
  133. package/lib/runtime/source-overlay.d.ts.map +1 -1
  134. package/lib/runtime/source-overlay.js +5 -2
  135. package/lib/runtime/source-overlay.js.map +1 -1
  136. package/lib/runtime/timeline/clock.d.ts.map +1 -1
  137. package/lib/runtime/timeline/clock.js +2 -2
  138. package/lib/runtime/timeline/clock.js.map +1 -1
  139. package/lib/runtime/timeline/flash.d.ts +39 -0
  140. package/lib/runtime/timeline/flash.d.ts.map +1 -0
  141. package/lib/runtime/timeline/flash.js +169 -0
  142. package/lib/runtime/timeline/flash.js.map +1 -0
  143. package/lib/runtime/timeline/identity.d.ts.map +1 -1
  144. package/lib/runtime/timeline/identity.js +27 -27
  145. package/lib/runtime/timeline/identity.js.map +1 -1
  146. package/lib/runtime/timeline/input.d.ts.map +1 -1
  147. package/lib/runtime/timeline/input.js +54 -67
  148. package/lib/runtime/timeline/input.js.map +1 -1
  149. package/lib/runtime/timeline/install.d.ts.map +1 -1
  150. package/lib/runtime/timeline/install.js +47 -33
  151. package/lib/runtime/timeline/install.js.map +1 -1
  152. package/lib/runtime/timeline/lifecycle.d.ts +8 -0
  153. package/lib/runtime/timeline/lifecycle.d.ts.map +1 -1
  154. package/lib/runtime/timeline/lifecycle.js +149 -133
  155. package/lib/runtime/timeline/lifecycle.js.map +1 -1
  156. package/lib/runtime/timeline/public-api.d.ts +2 -2
  157. package/lib/runtime/timeline/public-api.d.ts.map +1 -1
  158. package/lib/runtime/timeline/public-api.js +11 -11
  159. package/lib/runtime/timeline/public-api.js.map +1 -1
  160. package/lib/runtime/timeline/render.d.ts +15 -6
  161. package/lib/runtime/timeline/render.d.ts.map +1 -1
  162. package/lib/runtime/timeline/render.js +212 -78
  163. package/lib/runtime/timeline/render.js.map +1 -1
  164. package/lib/runtime/timeline/transport.d.ts.map +1 -1
  165. package/lib/runtime/timeline/transport.js +39 -43
  166. package/lib/runtime/timeline/transport.js.map +1 -1
  167. package/lib/segmented-tabs.d.ts +3 -1
  168. package/lib/segmented-tabs.d.ts.map +1 -1
  169. package/lib/segmented-tabs.js +136 -107
  170. package/lib/segmented-tabs.js.map +1 -1
  171. package/lib/snapshot.d.ts +28 -0
  172. package/lib/snapshot.d.ts.map +1 -0
  173. package/lib/snapshot.js +57 -0
  174. package/lib/snapshot.js.map +1 -0
  175. package/lib/source-meta.d.ts.map +1 -1
  176. package/lib/source-meta.js +176 -162
  177. package/lib/source-meta.js.map +1 -1
  178. package/lib/timeline/derive.d.ts +152 -0
  179. package/lib/timeline/derive.d.ts.map +1 -0
  180. package/lib/timeline/derive.js +242 -0
  181. package/lib/timeline/derive.js.map +1 -0
  182. package/lib/tokens.d.ts.map +1 -1
  183. package/lib/tokens.js +17 -18
  184. package/lib/tokens.js.map +1 -1
  185. package/lib/transform.d.ts.map +1 -1
  186. package/lib/transform.js +62 -57
  187. package/lib/transform.js.map +1 -1
  188. package/lib/types.d.ts.map +1 -1
  189. package/lib/types.js +1 -1
  190. package/lib/types.js.map +1 -1
  191. package/lib/wrap-table.d.ts.map +1 -1
  192. package/lib/wrap-table.js +19 -17
  193. package/lib/wrap-table.js.map +1 -1
  194. package/package.json +80 -13
  195. package/types/hmr-incompatibility.d.ts +59 -0
  196. package/types/hmr-incompatibility.d.ts.map +1 -0
  197. package/types/hmr-incompatibility.js +30 -0
  198. package/types/hmr-incompatibility.js.map +1 -0
  199. package/types/in-page.d.ts +49 -0
  200. package/types/in-page.d.ts.map +1 -0
  201. package/types/in-page.js +33 -0
  202. package/types/in-page.js.map +1 -0
  203. package/types/inspector.d.ts.map +1 -1
  204. package/types/inspector.js.map +1 -1
  205. package/types/snapshot.d.ts +44 -0
  206. package/types/snapshot.d.ts.map +1 -0
  207. package/types/snapshot.js +7 -0
  208. package/types/snapshot.js.map +1 -0
  209. package/types/timeline.d.ts +23 -1
  210. package/types/timeline.d.ts.map +1 -1
  211. package/types/timeline.js +2 -0
  212. package/types/timeline.js.map +1 -1
  213. package/lib/timeline-plugin.d.ts +0 -72
  214. package/lib/timeline-plugin.d.ts.map +0 -1
  215. package/lib/timeline-plugin.js +0 -376
  216. package/lib/timeline-plugin.js.map +0 -1
  217. package/panel/components-view.d.ts +0 -60
  218. package/panel/components-view.d.ts.map +0 -1
  219. package/panel/components-view.js +0 -587
  220. package/panel/components-view.js.map +0 -1
  221. package/panel/devtools-settings.d.ts +0 -41
  222. package/panel/devtools-settings.d.ts.map +0 -1
  223. package/panel/devtools-settings.js +0 -463
  224. package/panel/devtools-settings.js.map +0 -1
  225. package/panel/lit-devtools-panel.d.ts +0 -37
  226. package/panel/lit-devtools-panel.d.ts.map +0 -1
  227. package/panel/lit-devtools-panel.js +0 -185
  228. package/panel/lit-devtools-panel.js.map +0 -1
  229. package/panel/timeline-event-list.d.ts +0 -43
  230. package/panel/timeline-event-list.d.ts.map +0 -1
  231. package/panel/timeline-event-list.js +0 -416
  232. package/panel/timeline-event-list.js.map +0 -1
  233. package/panel/timeline-layers.d.ts +0 -25
  234. package/panel/timeline-layers.d.ts.map +0 -1
  235. package/panel/timeline-layers.js +0 -96
  236. package/panel/timeline-layers.js.map +0 -1
  237. package/panel/timeline-view.d.ts +0 -38
  238. package/panel/timeline-view.d.ts.map +0 -1
  239. package/panel/timeline-view.js +0 -234
  240. package/panel/timeline-view.js.map +0 -1
@@ -3,383 +3,387 @@
3
3
  * Copyright 2026 Google LLC
4
4
  * SPDX-License-Identifier: BSD-3-Clause
5
5
  */
6
- import { BUILTIN_EDITORS, resolveEditor } from './editors.js';
7
- import { defaultResolver, findSourceAtPoint, findSourceHost, } from './source-host.js';
8
- import { buildSpotlightClipPath } from './mask-path.js';
9
- import { OVERLAY_HTML } from './template.js';
10
- import { observeEdgeInsets } from '../edge-panel.js';
11
- import { subscribeOverride } from '../overrides.js';
12
- import { injectTokens } from '../../tokens.js';
13
- import { idOf } from '../timeline/identity.js';
14
- import { INSPECT_OVERLAY_TOGGLE_CHANNEL, INSPECT_DATA_CHANNEL, } from '../../../types/inspector.js';
6
+ import {BUILTIN_EDITORS, resolveEditor} from './editors.js';
7
+ import {
8
+ defaultResolver,
9
+ findSourceAtPoint,
10
+ findSourceHost,
11
+ } from './source-host.js';
12
+ import {buildSpotlightClipPath} from './mask-path.js';
13
+ import {OVERLAY_HTML} from './template.js';
14
+ import {observeEdgeInsets} from '../edge-panel.js';
15
+ import {subscribeOverride} from '../overrides.js';
16
+ import {injectTokens} from '../../tokens.js';
17
+ import {idOf} from '../timeline/identity.js';
18
+ import {
19
+ INSPECT_OVERLAY_TOGGLE_CHANNEL,
20
+ INSPECT_DATA_CHANNEL,
21
+ } from '../../../types/inspector.js';
15
22
  class LitSourceOverlay extends HTMLElement {
16
- #active = false;
17
- #hot;
18
- #options = {};
19
- #editor = BUILTIN_EDITORS.vscode;
20
- #resolver = defaultResolver;
21
- #dialog;
22
- #mask;
23
- #highlight;
24
- #tooltip;
25
- #tag;
26
- #path;
27
- #info = null;
28
- #targetEl = null;
29
- #throttleTimer;
30
- #scrollTimer;
31
- #resizeObserver;
32
- #cursorStyle = null;
33
- // Whether the Vite HMR WebSocket is currently connected. Used to suppress the
34
- // editor-URL-scheme fallback once the dev server is gone — otherwise a failed
35
- // open-in-editor fetch would navigate the tab to `vscode://…`.
36
- #connected = true;
37
- #lastMouseX = 0;
38
- #lastMouseY = 0;
39
- #edgeDispose;
40
- #overrideSubscribed = false;
41
- constructor() {
42
- super();
43
- const root = this.attachShadow({ mode: 'closed' });
44
- root.innerHTML = OVERLAY_HTML;
45
- this.#dialog = root.getElementById('overlay');
46
- this.#mask = root.getElementById('mask');
47
- this.#highlight = root.getElementById('highlight');
48
- this.#tooltip = root.getElementById('tooltip');
49
- this.#tag = root.getElementById('tag');
50
- this.#path = root.getElementById('path');
51
- root.getElementById('open').addEventListener('click', (e) => {
52
- e.stopPropagation();
53
- if (this.#info !== null)
54
- this.#select(this.#info, true);
55
- });
56
- root.getElementById('copy').addEventListener('click', (e) => {
57
- e.stopPropagation();
58
- if (this.#info === null)
59
- return;
60
- const text = `${this.#normalizePath(this.#info.source.filePath)}:${this.#info.source.lineNumber}`;
61
- navigator.clipboard?.writeText(text);
62
- });
63
- this.#dialog.addEventListener('cancel', (e) => e.preventDefault());
64
- }
65
- connectedCallback() {
66
- injectTokens();
67
- document.addEventListener('mousemove', this.#onTrackMouse, true);
68
- document.addEventListener('keydown', this.#onKeyDown, true);
69
- const hot = import.meta.hot;
70
- this.#hot = hot;
71
- hot?.on('vite:beforeFullReload', () => this.deactivate());
72
- hot?.on('vite:ws:disconnect', () => (this.#connected = false));
73
- hot?.on('vite:ws:connect', () => (this.#connected = true));
23
+ #active = false;
24
+ #hot;
25
+ #options = {};
26
+ #editor = BUILTIN_EDITORS.vscode;
27
+ #resolver = defaultResolver;
28
+ #dialog;
29
+ #mask;
30
+ #highlight;
31
+ #tooltip;
32
+ #tag;
33
+ #path;
34
+ #info = null;
35
+ #targetEl = null;
36
+ #throttleTimer;
37
+ #scrollTimer;
38
+ #resizeObserver;
39
+ #cursorStyle = null;
40
+ // Whether the Vite HMR WebSocket is currently connected. Used to suppress the
41
+ // editor-URL-scheme fallback once the dev server is gone — otherwise a failed
42
+ // open-in-editor fetch would navigate the tab to `vscode://…`.
43
+ #connected = true;
44
+ #lastMouseX = 0;
45
+ #lastMouseY = 0;
46
+ #edgeDispose;
47
+ #overrideSubscribed = false;
48
+ #hotOff;
49
+ constructor() {
50
+ super();
51
+ const root = this.attachShadow({mode: 'closed'});
52
+ root.innerHTML = OVERLAY_HTML;
53
+ this.#dialog = root.getElementById('overlay');
54
+ this.#mask = root.getElementById('mask');
55
+ this.#highlight = root.getElementById('highlight');
56
+ this.#tooltip = root.getElementById('tooltip');
57
+ this.#tag = root.getElementById('tag');
58
+ this.#path = root.getElementById('path');
59
+ root.getElementById('open').addEventListener('click', (e) => {
60
+ e.stopPropagation();
61
+ if (this.#info !== null) this.#select(this.#info, true);
62
+ });
63
+ root.getElementById('copy').addEventListener('click', (e) => {
64
+ e.stopPropagation();
65
+ if (this.#info === null) return;
66
+ const text = `${this.#normalizePath(this.#info.source.filePath)}:${this.#info.source.lineNumber}`;
67
+ void navigator.clipboard?.writeText(text);
68
+ });
69
+ this.#dialog.addEventListener('cancel', (e) => e.preventDefault());
70
+ }
71
+ connectedCallback() {
72
+ injectTokens();
73
+ document.addEventListener('mousemove', this.#onTrackMouse, true);
74
+ document.addEventListener('keydown', this.#onKeyDown, true);
75
+ const hot = import.meta.hot;
76
+ this.#hot = hot;
77
+ if (hot !== undefined && this.#hotOff === undefined) {
78
+ // Removed again in disconnectedCallback, so a re-attached overlay
79
+ // doesn't stack duplicates and a detached one stops reacting.
80
+ const handlers = [
81
+ ['vite:beforeFullReload', () => this.deactivate()],
82
+ ['vite:ws:disconnect', () => (this.#connected = false)],
83
+ ['vite:ws:connect', () => (this.#connected = true)],
74
84
  // Toggle from the Vite DevTools command/shortcut (handler runs server-side).
75
- hot?.on(INSPECT_OVERLAY_TOGGLE_CHANNEL, () => this.toggle());
76
- // Keep the (bottom-fixed) tooltip clear of the Vite DevTools edge panel.
77
- this.#edgeDispose = observeEdgeInsets((insets) => {
78
- this.style.setProperty('--edge-bottom', `${insets.bottom}px`);
79
- });
80
- // Apply the panel's editor override live (and on load). Merge so other
81
- // configured options (key, throttle, …) survive.
82
- if (!this.#overrideSubscribed) {
83
- this.#overrideSubscribed = true;
84
- subscribeOverride(hot, (o) => {
85
- if (o.sourceOverlayEditor !== undefined) {
86
- this.#options = { ...this.#options, editor: o.sourceOverlayEditor };
87
- this.#editor = resolveEditor(o.sourceOverlayEditor);
88
- }
89
- });
85
+ [INSPECT_OVERLAY_TOGGLE_CHANNEL, () => this.toggle()],
86
+ ];
87
+ for (const [event, cb] of handlers) hot.on(event, cb);
88
+ this.#hotOff = () => {
89
+ for (const [event, cb] of handlers) hot.off(event, cb);
90
+ };
91
+ }
92
+ // Keep the (bottom-fixed) tooltip clear of the Vite DevTools edge panel.
93
+ this.#edgeDispose = observeEdgeInsets((insets) => {
94
+ this.style.setProperty('--edge-bottom', `${insets.bottom}px`);
95
+ });
96
+ // Apply the panel's editor override live (and on load). Merge so other
97
+ // configured options (key, throttle, …) survive.
98
+ if (!this.#overrideSubscribed) {
99
+ this.#overrideSubscribed = true;
100
+ subscribeOverride(hot, (o) => {
101
+ if (o.sourceOverlayEditor !== undefined) {
102
+ this.#options = {...this.#options, editor: o.sourceOverlayEditor};
103
+ this.#editor = resolveEditor(o.sourceOverlayEditor);
90
104
  }
105
+ });
91
106
  }
92
- disconnectedCallback() {
93
- document.removeEventListener('mousemove', this.#onTrackMouse, true);
94
- document.removeEventListener('keydown', this.#onKeyDown, true);
95
- this.deactivate();
96
- this.#edgeDispose?.();
97
- this.#edgeDispose = undefined;
107
+ }
108
+ disconnectedCallback() {
109
+ document.removeEventListener('mousemove', this.#onTrackMouse, true);
110
+ document.removeEventListener('keydown', this.#onKeyDown, true);
111
+ this.deactivate();
112
+ this.#edgeDispose?.();
113
+ this.#edgeDispose = undefined;
114
+ this.#hotOff?.();
115
+ this.#hotOff = undefined;
116
+ }
117
+ configure(options) {
118
+ this.#options = options;
119
+ this.#editor = resolveEditor(options.editor);
120
+ }
121
+ activate() {
122
+ if (this.#active) return;
123
+ this.#active = true;
124
+ this.#dialog.showModal();
125
+ this.#mask.style.background = 'rgba(0,0,0,0.35)';
126
+ // The overlay is pointer-events:none, so the cursor reflects the hovered
127
+ // page element. Force a crosshair while inspecting. The closed shadow DOM
128
+ // tooltip is unaffected, so its buttons keep their own pointer cursor.
129
+ if (this.#cursorStyle === null) {
130
+ this.#cursorStyle = document.createElement('style');
131
+ this.#cursorStyle.textContent = '*{cursor:crosshair !important}';
98
132
  }
99
- configure(options) {
100
- this.#options = options;
101
- this.#editor = resolveEditor(options.editor);
133
+ document.head.append(this.#cursorStyle);
134
+ document.addEventListener('mousemove', this.#onMouseMove, true);
135
+ document.addEventListener('click', this.#onClick, true);
136
+ window.addEventListener('scroll', this.#onScrollOrResize, {passive: true});
137
+ window.addEventListener('resize', this.#onScrollOrResize, {passive: true});
138
+ void this.#resolveAt(this.#lastMouseX, this.#lastMouseY);
139
+ }
140
+ deactivate() {
141
+ if (!this.#active) return;
142
+ this.#active = false;
143
+ this.#dialog.close();
144
+ this.#mask.style.background = 'rgba(0,0,0,0)';
145
+ this.#cursorStyle?.remove();
146
+ document.removeEventListener('mousemove', this.#onMouseMove, true);
147
+ document.removeEventListener('click', this.#onClick, true);
148
+ window.removeEventListener('scroll', this.#onScrollOrResize);
149
+ window.removeEventListener('resize', this.#onScrollOrResize);
150
+ if (this.#throttleTimer !== undefined) {
151
+ clearTimeout(this.#throttleTimer);
152
+ this.#throttleTimer = undefined;
102
153
  }
103
- activate() {
104
- if (this.#active)
105
- return;
106
- this.#active = true;
107
- this.#dialog.showModal();
108
- this.#mask.style.background = 'rgba(0,0,0,0.35)';
109
- // The overlay is pointer-events:none, so the cursor reflects the hovered
110
- // page element. Force a crosshair while inspecting. The closed shadow DOM
111
- // tooltip is unaffected, so its buttons keep their own pointer cursor.
112
- if (this.#cursorStyle === null) {
113
- this.#cursorStyle = document.createElement('style');
114
- this.#cursorStyle.textContent = '*{cursor:crosshair !important}';
115
- }
116
- document.head.append(this.#cursorStyle);
117
- document.addEventListener('mousemove', this.#onMouseMove, true);
118
- document.addEventListener('click', this.#onClick, true);
119
- window.addEventListener('scroll', this.#onScrollOrResize, { passive: true });
120
- window.addEventListener('resize', this.#onScrollOrResize, { passive: true });
121
- this.#resolveAt(this.#lastMouseX, this.#lastMouseY);
154
+ if (this.#scrollTimer !== undefined) {
155
+ clearTimeout(this.#scrollTimer);
156
+ this.#scrollTimer = undefined;
122
157
  }
123
- deactivate() {
124
- if (!this.#active)
125
- return;
126
- this.#active = false;
127
- this.#dialog.close();
128
- this.#mask.style.background = 'rgba(0,0,0,0)';
129
- this.#cursorStyle?.remove();
130
- document.removeEventListener('mousemove', this.#onMouseMove, true);
131
- document.removeEventListener('click', this.#onClick, true);
132
- window.removeEventListener('scroll', this.#onScrollOrResize);
133
- window.removeEventListener('resize', this.#onScrollOrResize);
134
- if (this.#throttleTimer !== undefined) {
135
- clearTimeout(this.#throttleTimer);
136
- this.#throttleTimer = undefined;
137
- }
138
- if (this.#scrollTimer !== undefined) {
139
- clearTimeout(this.#scrollTimer);
140
- this.#scrollTimer = undefined;
141
- }
142
- this.#clearTarget();
158
+ this.#clearTarget();
159
+ }
160
+ toggle() {
161
+ if (this.#active) this.deactivate();
162
+ else this.activate();
163
+ }
164
+ #normalizePath(filePath) {
165
+ const root = this.#options.workspaceRoot;
166
+ if (root !== undefined && filePath.startsWith(root)) {
167
+ const rest = filePath.slice(root.length);
168
+ return rest.startsWith('/') ? rest.slice(1) : rest;
143
169
  }
144
- toggle() {
145
- if (this.#active)
146
- this.deactivate();
147
- else
148
- this.activate();
170
+ return filePath;
171
+ }
172
+ async #openInEditor(filePath, lineNumber) {
173
+ const path = this.#normalizePath(filePath);
174
+ const endpoint = this.#options.openInEditorPath ?? '/__lit-open-in-editor';
175
+ try {
176
+ const params = new URLSearchParams({
177
+ file: path,
178
+ line: String(lineNumber),
179
+ });
180
+ const res = await fetch(`${endpoint}?${params.toString()}`);
181
+ if (res.ok) return;
182
+ } catch {
183
+ // Fall back to editor URL schemes (e.g. StackBlitz previews).
149
184
  }
150
- #normalizePath(filePath) {
151
- const root = this.#options.workspaceRoot;
152
- if (root !== undefined && filePath.startsWith(root)) {
153
- const rest = filePath.slice(root.length);
154
- return rest.startsWith('/') ? rest.slice(1) : rest;
155
- }
156
- return filePath;
185
+ // Skip the URL-scheme fallback when the dev server is gone: a fetch failure
186
+ // there means "server quit", not "no endpoint", and navigating the tab to
187
+ // `vscode://…` on shutdown is jarring and unwanted.
188
+ if (!this.#connected) return;
189
+ window.open(this.#editor.url(path, lineNumber), '_self');
190
+ }
191
+ #updateHighlightRect() {
192
+ if (this.#targetEl === null) return;
193
+ const rect = this.#targetEl.getBoundingClientRect();
194
+ const raw = getComputedStyle(this)
195
+ .getPropertyValue('--lit-devtools-radius')
196
+ .trim();
197
+ const r = parseFloat(raw) || 6;
198
+ // The tinted box hugs the element's exact rect — that's the boundary being
199
+ // picked; only the spotlight cutout gets the breathing room of `r`.
200
+ this.#highlight.style.display = 'block';
201
+ this.#highlight.style.left = `${rect.left}px`;
202
+ this.#highlight.style.top = `${rect.top}px`;
203
+ this.#highlight.style.width = `${rect.width}px`;
204
+ this.#highlight.style.height = `${rect.height}px`;
205
+ this.#mask.style.clipPath = buildSpotlightClipPath(
206
+ rect.left - r,
207
+ rect.top - r,
208
+ rect.width + 2 * r,
209
+ rect.height + 2 * r,
210
+ r
211
+ );
212
+ }
213
+ #showTooltip() {
214
+ if (this.#info === null) return;
215
+ this.#tag.textContent = `<${this.#info.tagName}>`;
216
+ this.#path.textContent = `${this.#normalizePath(this.#info.source.filePath)}:${this.#info.source.lineNumber}`;
217
+ this.#tooltip.style.display = 'flex';
218
+ }
219
+ #clearTarget() {
220
+ this.#targetEl = null;
221
+ this.#info = null;
222
+ this.#highlight.style.display = 'none';
223
+ this.#highlight.style.left = '0';
224
+ this.#highlight.style.top = '0';
225
+ this.#highlight.style.width = '0';
226
+ this.#highlight.style.height = '0';
227
+ this.#mask.style.clipPath = 'none';
228
+ this.#tooltip.style.display = 'none';
229
+ if (this.#resizeObserver !== undefined) {
230
+ this.#resizeObserver.disconnect();
231
+ this.#resizeObserver = undefined;
157
232
  }
158
- async #openInEditor(filePath, lineNumber) {
159
- const path = this.#normalizePath(filePath);
160
- const endpoint = this.#options.openInEditorPath ?? '/__lit-open-in-editor';
161
- try {
162
- const params = new URLSearchParams({
163
- file: path,
164
- line: String(lineNumber),
165
- });
166
- const res = await fetch(`${endpoint}?${params.toString()}`);
167
- if (res.ok)
168
- return;
169
- }
170
- catch {
171
- // Fall back to editor URL schemes (e.g. StackBlitz previews).
172
- }
173
- // Skip the URL-scheme fallback when the dev server is gone: a fetch failure
174
- // there means "server quit", not "no endpoint", and navigating the tab to
175
- // `vscode://…` on shutdown is jarring and unwanted.
176
- if (!this.#connected)
177
- return;
178
- window.open(this.#editor.url(path, lineNumber), '_self');
233
+ }
234
+ #shouldSkip(el) {
235
+ if (el === this.#dialog || this.#dialog.contains(el)) return true;
236
+ if (el.tagName === 'IFRAME') return true;
237
+ // Never target devtools' own injected elements (indicator, overlay).
238
+ const tag = el.tagName.toLowerCase();
239
+ if (tag === 'lit-source-overlay' || tag.startsWith('lit-devtools-')) {
240
+ return true;
179
241
  }
180
- #updateHighlightRect() {
181
- if (this.#targetEl === null)
182
- return;
183
- const rect = this.#targetEl.getBoundingClientRect();
184
- const raw = getComputedStyle(this)
185
- .getPropertyValue('--lit-devtools-radius')
186
- .trim();
187
- const r = parseFloat(raw) || 6;
188
- // The tinted box hugs the element's exact rect — that's the boundary being
189
- // picked; only the spotlight cutout gets the breathing room of `r`.
190
- this.#highlight.style.display = 'block';
191
- this.#highlight.style.left = `${rect.left}px`;
192
- this.#highlight.style.top = `${rect.top}px`;
193
- this.#highlight.style.width = `${rect.width}px`;
194
- this.#highlight.style.height = `${rect.height}px`;
195
- this.#mask.style.clipPath = buildSpotlightClipPath(rect.left - r, rect.top - r, rect.width + 2 * r, rect.height + 2 * r, r);
242
+ const exclude = this.#options.exclude;
243
+ return exclude !== undefined && exclude(el);
244
+ }
245
+ async #resolveAt(x, y) {
246
+ this.#lastMouseX = x;
247
+ this.#lastMouseY = y;
248
+ const el = findSourceAtPoint(x, y, this.#dialog);
249
+ if (el === null || this.#shouldSkip(el)) {
250
+ this.#clearTarget();
251
+ return;
196
252
  }
197
- #showTooltip() {
198
- if (this.#info === null)
199
- return;
200
- this.#tag.textContent = `<${this.#info.tagName}>`;
201
- this.#path.textContent = `${this.#normalizePath(this.#info.source.filePath)}:${this.#info.source.lineNumber}`;
202
- this.#tooltip.style.display = 'flex';
253
+ const host = findSourceHost(el);
254
+ if (host === null) {
255
+ this.#clearTarget();
256
+ return;
203
257
  }
204
- #clearTarget() {
205
- this.#targetEl = null;
206
- this.#info = null;
207
- this.#highlight.style.display = 'none';
208
- this.#highlight.style.left = '0';
209
- this.#highlight.style.top = '0';
210
- this.#highlight.style.width = '0';
211
- this.#highlight.style.height = '0';
212
- this.#mask.style.clipPath = 'none';
213
- this.#tooltip.style.display = 'none';
214
- if (this.#resizeObserver !== undefined) {
215
- this.#resizeObserver.disconnect();
216
- this.#resizeObserver = undefined;
217
- }
258
+ if (host === this.#targetEl && this.#info !== null) {
259
+ this.#updateHighlightRect();
260
+ return;
218
261
  }
219
- #shouldSkip(el) {
220
- if (el === this.#dialog || this.#dialog.contains(el))
221
- return true;
222
- if (el.tagName === 'IFRAME')
223
- return true;
224
- // Never target devtools' own injected elements (indicator, overlay).
225
- const tag = el.tagName.toLowerCase();
226
- if (tag === 'lit-source-overlay' || tag.startsWith('lit-devtools-')) {
227
- return true;
228
- }
229
- const exclude = this.#options.exclude;
230
- return exclude !== undefined && exclude(el);
262
+ this.#targetEl = host;
263
+ if (this.#resizeObserver === undefined) {
264
+ this.#resizeObserver = new ResizeObserver(() =>
265
+ this.#updateHighlightRect()
266
+ );
267
+ } else {
268
+ this.#resizeObserver.disconnect();
231
269
  }
232
- async #resolveAt(x, y) {
233
- this.#lastMouseX = x;
234
- this.#lastMouseY = y;
235
- const el = findSourceAtPoint(x, y, this.#dialog);
236
- if (el === null || this.#shouldSkip(el)) {
237
- this.#clearTarget();
238
- return;
239
- }
240
- const host = findSourceHost(el);
241
- if (host === null) {
242
- this.#clearTarget();
243
- return;
244
- }
245
- if (host === this.#targetEl && this.#info !== null) {
246
- this.#updateHighlightRect();
247
- return;
248
- }
249
- this.#targetEl = host;
250
- if (this.#resizeObserver === undefined) {
251
- this.#resizeObserver = new ResizeObserver(() => this.#updateHighlightRect());
252
- }
253
- else {
254
- this.#resizeObserver.disconnect();
255
- }
256
- this.#resizeObserver.observe(host);
257
- const resolved = await this.#resolver.resolveElementInfo(el);
258
- if (resolved === null) {
259
- this.#clearTarget();
260
- return;
261
- }
262
- this.#info = resolved;
263
- this.#updateHighlightRect();
264
- this.#showTooltip();
270
+ this.#resizeObserver.observe(host);
271
+ const resolved = await this.#resolver.resolveElementInfo(el);
272
+ if (resolved === null) {
273
+ this.#clearTarget();
274
+ return;
265
275
  }
266
- #onTrackMouse = (event) => {
267
- this.#lastMouseX = event.clientX;
268
- this.#lastMouseY = event.clientY;
269
- };
270
- #onKeyDown = (event) => {
271
- if ((event.metaKey || event.ctrlKey) && event.shiftKey && !event.altKey) {
272
- const pressed = event.key.toLowerCase();
273
- const hotkey = (this.#options.key ?? 'e').toLowerCase();
274
- if (pressed === hotkey) {
275
- event.preventDefault();
276
- this.toggle();
277
- }
278
- }
279
- if (this.#active && event.key === 'Escape') {
280
- event.preventDefault();
281
- event.stopPropagation();
282
- }
283
- };
284
- #onMouseMove = (event) => {
285
- if (!this.#active)
286
- return;
287
- // Keep the current selection while hovering the tooltip so its buttons stay
288
- // clickable — the tooltip isn't a source element, so re-resolving here would
289
- // clear the target and hide the panel out from under the pointer.
290
- if (this.#pointInTooltip(event.clientX, event.clientY))
291
- return;
292
- const throttleMs = this.#options.throttleMs ?? 50;
293
- if (this.#throttleTimer !== undefined)
294
- return;
295
- this.#throttleTimer = setTimeout(() => {
296
- this.#throttleTimer = undefined;
297
- // Resolve against the latest pointer position (kept current by
298
- // #onTrackMouse), not the coords captured when this timer was scheduled
299
- // ~throttleMs ago — otherwise the highlight lags the cursor during
300
- // continuous movement.
301
- const x = this.#lastMouseX;
302
- const y = this.#lastMouseY;
303
- if (this.#pointInTooltip(x, y))
304
- return;
305
- this.#resolveAt(x, y);
306
- }, throttleMs);
307
- };
308
- #select(info, openInEditor = false) {
309
- const target = this.#targetEl;
310
- // Cancel the whole selection mode on any deliberate pick, before acting —
311
- // the editor may open via a URL scheme that doesn't navigate this tab away,
312
- // so we can't rely on the open outcome to dismiss the inspector.
313
- this.deactivate();
314
- this.#options.onSelect?.(info);
315
- if (openInEditor) {
316
- this.#openInEditor(info.source.filePath, info.source.lineNumber);
317
- return;
318
- }
319
- // Report the picked element to the DevTools panel, which selects it in the
320
- // Components tree. Identity matches the inspector runtime via idOf().
321
- if (target !== null) {
322
- this.#hot?.send(INSPECT_DATA_CHANNEL, { type: 'pick', id: idOf(target) });
323
- this.#openDevtoolsPanel();
324
- }
276
+ this.#info = resolved;
277
+ this.#updateHighlightRect();
278
+ this.#showTooltip();
279
+ }
280
+ #onTrackMouse = (event) => {
281
+ this.#lastMouseX = event.clientX;
282
+ this.#lastMouseY = event.clientY;
283
+ };
284
+ #onKeyDown = (event) => {
285
+ if ((event.metaKey || event.ctrlKey) && event.shiftKey && !event.altKey) {
286
+ const pressed = event.key.toLowerCase();
287
+ const hotkey = (this.#options.key ?? 's').toLowerCase();
288
+ if (pressed === hotkey) {
289
+ event.preventDefault();
290
+ this.toggle();
291
+ }
325
292
  }
326
- /**
327
- * Bring the Lit DevTools dock entry to the front so a pick is visible even
328
- * when the panel was closed. The panel mirrors this from its own
329
- * `inspector-activate` handler, but only once its iframe is mounted — and the
330
- * @vitejs/devtools shell does not mount that iframe until the entry has been
331
- * opened at least once. This overlay always runs on the page, so calling
332
- * `switchEntry` here covers the cold-start case where no panel exists yet to
333
- * receive the `pick` message.
334
- */
335
- #openDevtoolsPanel() {
336
- try {
337
- const ctx = window.__VITE_DEVTOOLS_CLIENT_CONTEXT__;
338
- ctx?.docks?.switchEntry?.('lit-devtools');
339
- }
340
- catch {
341
- // Not running inside the DevTools shell — ignore.
342
- }
293
+ if (this.#active && event.key === 'Escape') {
294
+ event.preventDefault();
295
+ event.stopPropagation();
343
296
  }
344
- #pointInTooltip(x, y) {
345
- if (this.#tooltip.style.display === 'none')
346
- return false;
347
- const r = this.#tooltip.getBoundingClientRect();
348
- return x >= r.left && x <= r.right && y >= r.top && y <= r.bottom;
297
+ };
298
+ #onMouseMove = (event) => {
299
+ if (!this.#active) return;
300
+ // Keep the current selection while hovering the tooltip so its buttons stay
301
+ // clickable — the tooltip isn't a source element, so re-resolving here would
302
+ // clear the target and hide the panel out from under the pointer.
303
+ if (this.#pointInTooltip(event.clientX, event.clientY)) return;
304
+ const throttleMs = this.#options.throttleMs ?? 50;
305
+ if (this.#throttleTimer !== undefined) return;
306
+ this.#throttleTimer = setTimeout(() => {
307
+ this.#throttleTimer = undefined;
308
+ // Resolve against the latest pointer position (kept current by
309
+ // #onTrackMouse), not the coords captured when this timer was scheduled
310
+ // ~throttleMs ago — otherwise the highlight lags the cursor during
311
+ // continuous movement.
312
+ const x = this.#lastMouseX;
313
+ const y = this.#lastMouseY;
314
+ if (this.#pointInTooltip(x, y)) return;
315
+ void this.#resolveAt(x, y);
316
+ }, throttleMs);
317
+ };
318
+ #select(info, openInEditor = false) {
319
+ const target = this.#targetEl;
320
+ // Cancel the whole selection mode on any deliberate pick, before acting —
321
+ // the editor may open via a URL scheme that doesn't navigate this tab away,
322
+ // so we can't rely on the open outcome to dismiss the inspector.
323
+ this.deactivate();
324
+ this.#options.onSelect?.(info);
325
+ if (openInEditor) {
326
+ void this.#openInEditor(info.source.filePath, info.source.lineNumber);
327
+ return;
349
328
  }
350
- #onClick = (event) => {
351
- if (!this.#active || this.#info === null)
352
- return;
353
- // Clicks on the tooltip panel are handled by its own buttons (open/copy).
354
- // The overlay's shadow root is closed, so we detect this by hit-rect rather
355
- // than inspecting the event path, and let the event reach those buttons.
356
- if (this.#pointInTooltip(event.clientX, event.clientY))
357
- return;
358
- event.preventDefault();
359
- event.stopPropagation();
360
- this.#select(this.#info, event.metaKey || event.ctrlKey);
361
- };
362
- #onScrollOrResize = () => {
363
- if (this.#scrollTimer !== undefined)
364
- clearTimeout(this.#scrollTimer);
365
- this.#scrollTimer = setTimeout(() => {
366
- this.#scrollTimer = undefined;
367
- if (this.#targetEl !== null) {
368
- this.#updateHighlightRect();
369
- }
370
- }, 50);
371
- };
329
+ // Report the picked element to the DevTools panel, which selects it in the
330
+ // Components tree. Identity matches the inspector runtime via idOf().
331
+ if (target !== null) {
332
+ this.#hot?.send(INSPECT_DATA_CHANNEL, {type: 'pick', id: idOf(target)});
333
+ this.#openDevtoolsPanel();
334
+ }
335
+ }
336
+ /**
337
+ * Bring the Lit DevTools dock entry to the front so a pick is visible even
338
+ * when the panel was closed. The panel mirrors this from its own
339
+ * `inspector-activate` handler, but only once its iframe is mounted — and the
340
+ * @vitejs/devtools shell does not mount that iframe until the entry has been
341
+ * opened at least once. This overlay always runs on the page, so calling
342
+ * `switchEntry` here covers the cold-start case where no panel exists yet to
343
+ * receive the `pick` message.
344
+ */
345
+ #openDevtoolsPanel() {
346
+ try {
347
+ const ctx = window.__VITE_DEVTOOLS_CLIENT_CONTEXT__;
348
+ void ctx?.docks?.switchEntry?.('lit-devtools');
349
+ } catch {
350
+ // Not running inside the DevTools shell — ignore.
351
+ }
352
+ }
353
+ #pointInTooltip(x, y) {
354
+ if (this.#tooltip.style.display === 'none') return false;
355
+ const r = this.#tooltip.getBoundingClientRect();
356
+ return x >= r.left && x <= r.right && y >= r.top && y <= r.bottom;
357
+ }
358
+ #onClick = (event) => {
359
+ if (!this.#active || this.#info === null) return;
360
+ // Clicks on the tooltip panel are handled by its own buttons (open/copy).
361
+ // The overlay's shadow root is closed, so we detect this by hit-rect rather
362
+ // than inspecting the event path, and let the event reach those buttons.
363
+ if (this.#pointInTooltip(event.clientX, event.clientY)) return;
364
+ event.preventDefault();
365
+ event.stopPropagation();
366
+ this.#select(this.#info, event.metaKey || event.ctrlKey);
367
+ };
368
+ #onScrollOrResize = () => {
369
+ if (this.#scrollTimer !== undefined) clearTimeout(this.#scrollTimer);
370
+ this.#scrollTimer = setTimeout(() => {
371
+ this.#scrollTimer = undefined;
372
+ if (this.#targetEl !== null) {
373
+ this.#updateHighlightRect();
374
+ }
375
+ }, 50);
376
+ };
372
377
  }
373
378
  customElements.define('lit-source-overlay', LitSourceOverlay);
374
379
  export const initSourceOverlay = (initOptions = {}) => {
375
- if (typeof window === 'undefined')
376
- return;
377
- const el = document.createElement('lit-source-overlay');
378
- el.configure(initOptions);
379
- document.body.append(el);
380
+ if (typeof window === 'undefined') return;
381
+ const el = document.createElement('lit-source-overlay');
382
+ el.configure(initOptions);
383
+ document.body.append(el);
380
384
  };
381
385
  export const toggleSourceOverlay = () => {
382
- const el = document.querySelector('lit-source-overlay');
383
- el?.toggle();
386
+ const el = document.querySelector('lit-source-overlay');
387
+ el?.toggle();
384
388
  };
385
- //# sourceMappingURL=overlay-element.js.map
389
+ //# sourceMappingURL=overlay-element.js.map