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