@scenetest/vite-plugin 0.11.0 → 0.12.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.d.ts.map +1 -1
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/panels/observer/audio.d.ts +81 -0
- package/dist/panels/observer/audio.d.ts.map +1 -0
- package/dist/panels/observer/audio.js +296 -0
- package/dist/panels/observer/audio.js.map +1 -0
- package/dist/panels/observer/auto.d.ts +10 -0
- package/dist/panels/observer/auto.d.ts.map +1 -0
- package/dist/panels/observer/auto.js +11 -0
- package/dist/panels/observer/auto.js.map +1 -0
- package/dist/panels/observer/fs-viewer.d.ts +20 -0
- package/dist/panels/observer/fs-viewer.d.ts.map +1 -0
- package/dist/panels/observer/fs-viewer.js +536 -0
- package/dist/panels/observer/fs-viewer.js.map +1 -0
- package/dist/panels/observer/fullscreen.d.ts +24 -0
- package/dist/panels/observer/fullscreen.d.ts.map +1 -0
- package/dist/panels/observer/fullscreen.js +701 -0
- package/dist/panels/observer/fullscreen.js.map +1 -0
- package/dist/panels/observer/history.d.ts +41 -0
- package/dist/panels/observer/history.d.ts.map +1 -0
- package/dist/panels/observer/history.js +307 -0
- package/dist/panels/observer/history.js.map +1 -0
- package/dist/panels/observer/index.d.ts +33 -0
- package/dist/panels/observer/index.d.ts.map +1 -0
- package/dist/panels/observer/index.js +128 -0
- package/dist/panels/observer/index.js.map +1 -0
- package/dist/panels/observer/panel.d.ts +12 -0
- package/dist/panels/observer/panel.d.ts.map +1 -0
- package/dist/panels/observer/panel.js +461 -0
- package/dist/panels/observer/panel.js.map +1 -0
- package/dist/panels/observer/render.d.ts +109 -0
- package/dist/panels/observer/render.d.ts.map +1 -0
- package/dist/panels/observer/render.js +760 -0
- package/dist/panels/observer/render.js.map +1 -0
- package/dist/panels/observer/state.d.ts +57 -0
- package/dist/panels/observer/state.d.ts.map +1 -0
- package/dist/panels/observer/state.js +187 -0
- package/dist/panels/observer/state.js.map +1 -0
- package/dist/panels/observer/styles.d.ts +6 -0
- package/dist/panels/observer/styles.d.ts.map +1 -0
- package/dist/panels/observer/styles.js +1706 -0
- package/dist/panels/observer/styles.js.map +1 -0
- package/dist/panels/observer/types.d.ts +102 -0
- package/dist/panels/observer/types.d.ts.map +1 -0
- package/dist/panels/observer/types.js +5 -0
- package/dist/panels/observer/types.js.map +1 -0
- package/dist/panels/observer/utils.d.ts +45 -0
- package/dist/panels/observer/utils.d.ts.map +1 -0
- package/dist/panels/observer/utils.js +101 -0
- package/dist/panels/observer/utils.js.map +1 -0
- package/dist/panels/recorder/auto.d.ts +10 -0
- package/dist/panels/recorder/auto.d.ts.map +1 -0
- package/dist/panels/recorder/auto.js +11 -0
- package/dist/panels/recorder/auto.js.map +1 -0
- package/dist/panels/recorder/capture.d.ts +18 -0
- package/dist/panels/recorder/capture.d.ts.map +1 -0
- package/dist/panels/recorder/capture.js +218 -0
- package/dist/panels/recorder/capture.js.map +1 -0
- package/dist/panels/recorder/index.d.ts +41 -0
- package/dist/panels/recorder/index.d.ts.map +1 -0
- package/dist/panels/recorder/index.js +208 -0
- package/dist/panels/recorder/index.js.map +1 -0
- package/dist/panels/recorder/panel.d.ts +55 -0
- package/dist/panels/recorder/panel.d.ts.map +1 -0
- package/dist/panels/recorder/panel.js +284 -0
- package/dist/panels/recorder/panel.js.map +1 -0
- package/dist/panels/recorder/reverse-selector.d.ts +31 -0
- package/dist/panels/recorder/reverse-selector.d.ts.map +1 -0
- package/dist/panels/recorder/reverse-selector.js +116 -0
- package/dist/panels/recorder/reverse-selector.js.map +1 -0
- package/dist/panels/recorder/styles.d.ts +5 -0
- package/dist/panels/recorder/styles.d.ts.map +1 -0
- package/dist/panels/recorder/styles.js +300 -0
- package/dist/panels/recorder/styles.js.map +1 -0
- package/dist/panels/recorder/types.d.ts +51 -0
- package/dist/panels/recorder/types.d.ts.map +1 -0
- package/dist/panels/recorder/types.js +15 -0
- package/dist/panels/recorder/types.js.map +1 -0
- package/dist/strip.d.ts.map +1 -1
- package/dist/strip.js +6 -3
- package/dist/strip.js.map +1 -1
- package/dist/transform.d.ts.map +1 -1
- package/dist/transform.js +5 -2
- package/dist/transform.js.map +1 -1
- package/package.json +12 -6
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main panel UI management
|
|
3
|
+
*/
|
|
4
|
+
import { groups, passCount, failCount, panel, listEl, filter, setPanel, setListEl, setFilter, clearAll, toggleGroupCollapsed, panelCorner, setPanelCorner, } from './state.js';
|
|
5
|
+
import { filterItems } from './utils.js';
|
|
6
|
+
import { renderPanelGroup, attachEventListeners } from './render.js';
|
|
7
|
+
import { openInEditor } from './utils.js';
|
|
8
|
+
import { panelStyles } from './styles.js';
|
|
9
|
+
import { openFullscreen, updateFullscreenWindow } from './fullscreen.js';
|
|
10
|
+
import { clearSymphony, playSymphony, stopSymphony, toggleMute, isPlaying, getSymphonyInfo, initAudio, } from './audio.js';
|
|
11
|
+
/**
|
|
12
|
+
* Get the HTML template for the panel
|
|
13
|
+
*/
|
|
14
|
+
function getPanelHTML() {
|
|
15
|
+
return `
|
|
16
|
+
<style>${panelStyles}</style>
|
|
17
|
+
<div id="scenetest-header">
|
|
18
|
+
<span id="scenetest-title"><span class="scenetest-icon"><span>\uD83C\uDFAC</span></span>scenetest</span>
|
|
19
|
+
<span id="scenetest-counts">
|
|
20
|
+
<span class="scenetest-count pass" id="scenetest-pass" title="Click to filter passes">\u2713 0</span>
|
|
21
|
+
<span class="scenetest-count fail" id="scenetest-fail" title="Click to filter failures">\u2717 0</span>
|
|
22
|
+
</span>
|
|
23
|
+
</div>
|
|
24
|
+
<div id="scenetest-actions">
|
|
25
|
+
<div class="scenetest-btn-group">
|
|
26
|
+
<button class="scenetest-btn active" id="scenetest-filter-all">all</button>
|
|
27
|
+
<button class="scenetest-btn" id="scenetest-filter-fails">errors</button>
|
|
28
|
+
</div>
|
|
29
|
+
<span class="scenetest-separator"></span>
|
|
30
|
+
<div class="scenetest-btn-group scenetest-audio-controls">
|
|
31
|
+
<button class="scenetest-btn scenetest-audio-btn" id="scenetest-mute" title="Toggle sound">\uD83D\uDD0A</button>
|
|
32
|
+
<button class="scenetest-btn scenetest-audio-btn" id="scenetest-play" title="Play symphony">\u25B6</button>
|
|
33
|
+
</div>
|
|
34
|
+
<span class="scenetest-separator"></span>
|
|
35
|
+
<a class="scenetest-btn" id="scenetest-dashboard" href="/__scenetest/dashboard" target="_blank" title="Live dashboard">dashboard</a>
|
|
36
|
+
<button class="scenetest-btn" id="scenetest-fullscreen">fullscreen</button>
|
|
37
|
+
<button class="scenetest-btn" id="scenetest-clear">clear</button>
|
|
38
|
+
</div>
|
|
39
|
+
<div id="scenetest-list">
|
|
40
|
+
<div id="scenetest-empty">Click around to see inline assertions...</div>
|
|
41
|
+
</div>
|
|
42
|
+
`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Handle filter change
|
|
46
|
+
*/
|
|
47
|
+
function handleSetFilter(newFilter) {
|
|
48
|
+
setFilter(newFilter);
|
|
49
|
+
// Update button states
|
|
50
|
+
panel?.querySelector('#scenetest-filter-all')?.classList.toggle('active', filter === 'all');
|
|
51
|
+
panel?.querySelector('#scenetest-filter-fails')?.classList.toggle('active', filter === 'fails');
|
|
52
|
+
panel?.querySelector('#scenetest-pass')?.classList.toggle('active', filter === 'passes');
|
|
53
|
+
panel?.querySelector('#scenetest-fail')?.classList.toggle('active', filter === 'fails');
|
|
54
|
+
updatePanel();
|
|
55
|
+
updateFullscreenWindow();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Apply the correct corner CSS class to the panel
|
|
59
|
+
*/
|
|
60
|
+
function applyCornerClass(el, corner) {
|
|
61
|
+
el.classList.remove('corner-bottom-right', 'corner-bottom-left', 'corner-top-right', 'corner-top-left');
|
|
62
|
+
el.classList.add(`corner-${corner}`);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Calculate the pixel position (top, left) for a given corner
|
|
66
|
+
*/
|
|
67
|
+
function getCornerPosition(corner, panelWidth, panelHeight) {
|
|
68
|
+
const vpW = window.innerWidth;
|
|
69
|
+
const vpH = window.innerHeight;
|
|
70
|
+
const margin = 16;
|
|
71
|
+
switch (corner) {
|
|
72
|
+
case 'top-left': return { top: margin, left: margin };
|
|
73
|
+
case 'top-right': return { top: margin, left: vpW - panelWidth - margin };
|
|
74
|
+
case 'bottom-left': return { top: vpH - panelHeight - margin, left: margin };
|
|
75
|
+
case 'bottom-right': return { top: vpH - panelHeight - margin, left: vpW - panelWidth - margin };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const DRAG_THRESHOLD = 5; // px of movement before we consider it a drag
|
|
79
|
+
const UNSNAP_THRESHOLD = 50; // px of mouse movement before panel breaks free
|
|
80
|
+
const DAMPING = 0.3; // Rubber-band resistance (panel moves at 30% of mouse displacement)
|
|
81
|
+
const FLICK_VELOCITY = 250; // px/s — momentum can override position-based corner pick
|
|
82
|
+
const VELOCITY_WINDOW = 80; // ms of recent motion to sample for velocity
|
|
83
|
+
/**
|
|
84
|
+
* Pick a target corner that is NOT the original corner.
|
|
85
|
+
* Uses the panel's current viewport quadrant, with momentum as a tiebreaker
|
|
86
|
+
* when the panel is still in the original quadrant.
|
|
87
|
+
*/
|
|
88
|
+
function pickNonOriginalCorner(panelRect, vx, vy, original) {
|
|
89
|
+
const centerX = panelRect.left + panelRect.width / 2;
|
|
90
|
+
const centerY = panelRect.top + panelRect.height / 2;
|
|
91
|
+
const vpW = window.innerWidth;
|
|
92
|
+
const vpH = window.innerHeight;
|
|
93
|
+
// 1. Position-based: which quadrant is the panel center in?
|
|
94
|
+
const isRight = centerX > vpW / 2;
|
|
95
|
+
const isBottom = centerY > vpH / 2;
|
|
96
|
+
const posCorner = isBottom
|
|
97
|
+
? (isRight ? 'bottom-right' : 'bottom-left')
|
|
98
|
+
: (isRight ? 'top-right' : 'top-left');
|
|
99
|
+
if (posCorner !== original)
|
|
100
|
+
return posCorner;
|
|
101
|
+
// 2. Momentum override: if fast enough, use flick direction
|
|
102
|
+
const speed = Math.sqrt(vx * vx + vy * vy);
|
|
103
|
+
if (speed >= FLICK_VELOCITY) {
|
|
104
|
+
const flickCorner = vy < 0
|
|
105
|
+
? (vx < 0 ? 'top-left' : 'top-right')
|
|
106
|
+
: (vx < 0 ? 'bottom-left' : 'bottom-right');
|
|
107
|
+
if (flickCorner !== original)
|
|
108
|
+
return flickCorner;
|
|
109
|
+
}
|
|
110
|
+
// 3. Fallback: still in the original quadrant with no strong momentum.
|
|
111
|
+
// Flip the axis closer to the midline (the direction the user was pulling).
|
|
112
|
+
const xDist = Math.abs(centerX - vpW / 2);
|
|
113
|
+
const yDist = Math.abs(centerY - vpH / 2);
|
|
114
|
+
const [origV, origH] = original.split('-');
|
|
115
|
+
if (xDist < yDist) {
|
|
116
|
+
// Closer to vertical midline → flip horizontal axis
|
|
117
|
+
return `${origV}-${origH === 'right' ? 'left' : 'right'}`;
|
|
118
|
+
}
|
|
119
|
+
// Closer to horizontal midline → flip vertical axis
|
|
120
|
+
return `${origV === 'bottom' ? 'top' : 'bottom'}-${origH}`;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Set up drag-and-snap with rubber-band tension, unsnap, and
|
|
124
|
+
* position/momentum-based corner selection.
|
|
125
|
+
*
|
|
126
|
+
* Phase 1 (< 50px mouse movement): Rubber-band — panel resists as if tethered.
|
|
127
|
+
* Phase 2 (≥ 50px): Panel unsnaps and follows the mouse freely.
|
|
128
|
+
*
|
|
129
|
+
* On release:
|
|
130
|
+
* - Never unsnapped → snap back to original corner.
|
|
131
|
+
* - Unsnapped → pick the best non-original corner by position, with
|
|
132
|
+
* momentum as tiebreaker. The panel never returns to its starting corner.
|
|
133
|
+
*/
|
|
134
|
+
function setupDrag(panelEl) {
|
|
135
|
+
const header = panelEl.querySelector('#scenetest-header');
|
|
136
|
+
if (!header)
|
|
137
|
+
return;
|
|
138
|
+
let isDragging = false;
|
|
139
|
+
let hasUnsnapped = false;
|
|
140
|
+
let startX = 0;
|
|
141
|
+
let startY = 0;
|
|
142
|
+
let anchorX = 0; // Panel's resting left position before drag
|
|
143
|
+
let anchorY = 0; // Panel's resting top position before drag
|
|
144
|
+
let grabOffsetX = 0; // Offset from pointer to panel left edge (for free-follow)
|
|
145
|
+
let grabOffsetY = 0;
|
|
146
|
+
let isAnimating = false;
|
|
147
|
+
const samples = [];
|
|
148
|
+
function onPointerDown(clientX, clientY) {
|
|
149
|
+
if (isAnimating)
|
|
150
|
+
return;
|
|
151
|
+
const rect = panelEl.getBoundingClientRect();
|
|
152
|
+
startX = clientX;
|
|
153
|
+
startY = clientY;
|
|
154
|
+
anchorX = rect.left;
|
|
155
|
+
anchorY = rect.top;
|
|
156
|
+
isDragging = false;
|
|
157
|
+
hasUnsnapped = false;
|
|
158
|
+
samples.length = 0;
|
|
159
|
+
samples.push({ x: clientX, y: clientY, t: performance.now() });
|
|
160
|
+
}
|
|
161
|
+
function onPointerMove(clientX, clientY) {
|
|
162
|
+
if (isAnimating)
|
|
163
|
+
return;
|
|
164
|
+
const dx = clientX - startX;
|
|
165
|
+
const dy = clientY - startY;
|
|
166
|
+
if (!isDragging) {
|
|
167
|
+
if (Math.abs(dx) < DRAG_THRESHOLD && Math.abs(dy) < DRAG_THRESHOLD)
|
|
168
|
+
return;
|
|
169
|
+
isDragging = true;
|
|
170
|
+
panelEl.classList.add('dragging');
|
|
171
|
+
// Switch to explicit top/left at current anchor position
|
|
172
|
+
panelEl.style.top = anchorY + 'px';
|
|
173
|
+
panelEl.style.left = anchorX + 'px';
|
|
174
|
+
panelEl.style.bottom = 'auto';
|
|
175
|
+
panelEl.style.right = 'auto';
|
|
176
|
+
panelEl.classList.remove('corner-bottom-right', 'corner-bottom-left', 'corner-top-right', 'corner-top-left');
|
|
177
|
+
}
|
|
178
|
+
// Track velocity samples
|
|
179
|
+
samples.push({ x: clientX, y: clientY, t: performance.now() });
|
|
180
|
+
// Check for unsnap: once mouse moves far enough, panel breaks free
|
|
181
|
+
if (!hasUnsnapped && Math.sqrt(dx * dx + dy * dy) >= UNSNAP_THRESHOLD) {
|
|
182
|
+
hasUnsnapped = true;
|
|
183
|
+
// Use the original grab point so the panel jumps forward to reclaim
|
|
184
|
+
// the 70% gap that was suppressed by damping — this is the "pop"
|
|
185
|
+
grabOffsetX = startX - anchorX;
|
|
186
|
+
grabOffsetY = startY - anchorY;
|
|
187
|
+
// Animate the pop with a quick transition + shadow burst
|
|
188
|
+
panelEl.classList.add('unsnapping');
|
|
189
|
+
const onPop = (e) => {
|
|
190
|
+
if (e.target === panelEl && e.propertyName === 'top') {
|
|
191
|
+
panelEl.removeEventListener('transitionend', onPop);
|
|
192
|
+
panelEl.classList.remove('unsnapping');
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
panelEl.addEventListener('transitionend', onPop);
|
|
196
|
+
setTimeout(() => panelEl.classList.remove('unsnapping'), 150);
|
|
197
|
+
}
|
|
198
|
+
if (hasUnsnapped) {
|
|
199
|
+
// Free follow: panel tracks mouse 1:1
|
|
200
|
+
panelEl.style.left = (clientX - grabOffsetX) + 'px';
|
|
201
|
+
panelEl.style.top = (clientY - grabOffsetY) + 'px';
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
// Rubber-band: panel moves at DAMPING rate of mouse displacement
|
|
205
|
+
panelEl.style.left = (anchorX + dx * DAMPING) + 'px';
|
|
206
|
+
panelEl.style.top = (anchorY + dy * DAMPING) + 'px';
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function getVelocity() {
|
|
210
|
+
const now = performance.now();
|
|
211
|
+
const recent = samples.filter(s => now - s.t < VELOCITY_WINDOW);
|
|
212
|
+
if (recent.length < 2)
|
|
213
|
+
return { vx: 0, vy: 0 };
|
|
214
|
+
const first = recent[0];
|
|
215
|
+
const last = recent[recent.length - 1];
|
|
216
|
+
const dt = (last.t - first.t) / 1000;
|
|
217
|
+
if (dt < 0.001)
|
|
218
|
+
return { vx: 0, vy: 0 };
|
|
219
|
+
return {
|
|
220
|
+
vx: (last.x - first.x) / dt,
|
|
221
|
+
vy: (last.y - first.y) / dt,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function onPointerUp() {
|
|
225
|
+
if (!isDragging || isAnimating) {
|
|
226
|
+
isDragging = false;
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
panelEl.classList.remove('dragging');
|
|
230
|
+
const { vx, vy } = getVelocity();
|
|
231
|
+
let targetCorner;
|
|
232
|
+
let isFlick;
|
|
233
|
+
if (hasUnsnapped) {
|
|
234
|
+
// Panel broke free — must go to a non-original corner
|
|
235
|
+
const rect = panelEl.getBoundingClientRect();
|
|
236
|
+
targetCorner = pickNonOriginalCorner(rect, vx, vy, panelCorner);
|
|
237
|
+
isFlick = true;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
// Didn't unsnap — rubber-band back to original
|
|
241
|
+
targetCorner = panelCorner;
|
|
242
|
+
isFlick = false;
|
|
243
|
+
}
|
|
244
|
+
// Calculate target pixel position
|
|
245
|
+
const rect = panelEl.getBoundingClientRect();
|
|
246
|
+
const dest = getCornerPosition(targetCorner, rect.width, rect.height);
|
|
247
|
+
// Animate to target
|
|
248
|
+
isAnimating = true;
|
|
249
|
+
panelEl.classList.add(isFlick ? 'flicking' : 'snapping');
|
|
250
|
+
// Force reflow so the browser captures the current position before we set the target
|
|
251
|
+
void panelEl.offsetHeight;
|
|
252
|
+
panelEl.style.top = dest.top + 'px';
|
|
253
|
+
panelEl.style.left = dest.left + 'px';
|
|
254
|
+
// Clean up after animation completes
|
|
255
|
+
let cleaned = false;
|
|
256
|
+
const cleanup = () => {
|
|
257
|
+
if (cleaned)
|
|
258
|
+
return;
|
|
259
|
+
cleaned = true;
|
|
260
|
+
panelEl.classList.remove('snapping', 'flicking');
|
|
261
|
+
panelEl.style.top = '';
|
|
262
|
+
panelEl.style.left = '';
|
|
263
|
+
panelEl.style.bottom = '';
|
|
264
|
+
panelEl.style.right = '';
|
|
265
|
+
if (isFlick)
|
|
266
|
+
setPanelCorner(targetCorner);
|
|
267
|
+
applyCornerClass(panelEl, targetCorner);
|
|
268
|
+
isAnimating = false;
|
|
269
|
+
};
|
|
270
|
+
panelEl.addEventListener('transitionend', function onEnd(e) {
|
|
271
|
+
if (e.target === panelEl && (e.propertyName === 'top' || e.propertyName === 'left')) {
|
|
272
|
+
panelEl.removeEventListener('transitionend', onEnd);
|
|
273
|
+
cleanup();
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
// Fallback in case transitionend doesn't fire
|
|
277
|
+
setTimeout(cleanup, isFlick ? 450 : 350);
|
|
278
|
+
isDragging = false;
|
|
279
|
+
}
|
|
280
|
+
// Mouse events
|
|
281
|
+
header.addEventListener('mousedown', (e) => {
|
|
282
|
+
const target = e.target;
|
|
283
|
+
if (target.classList.contains('scenetest-count'))
|
|
284
|
+
return;
|
|
285
|
+
if (isAnimating)
|
|
286
|
+
return;
|
|
287
|
+
e.preventDefault();
|
|
288
|
+
onPointerDown(e.clientX, e.clientY);
|
|
289
|
+
const onMouseMove = (ev) => {
|
|
290
|
+
ev.preventDefault();
|
|
291
|
+
onPointerMove(ev.clientX, ev.clientY);
|
|
292
|
+
};
|
|
293
|
+
const onMouseUp = () => {
|
|
294
|
+
document.removeEventListener('mousemove', onMouseMove);
|
|
295
|
+
document.removeEventListener('mouseup', onMouseUp);
|
|
296
|
+
if (!isDragging) {
|
|
297
|
+
// It was a click, not a drag — toggle collapse
|
|
298
|
+
panelEl.classList.toggle('collapsed');
|
|
299
|
+
}
|
|
300
|
+
onPointerUp();
|
|
301
|
+
};
|
|
302
|
+
document.addEventListener('mousemove', onMouseMove);
|
|
303
|
+
document.addEventListener('mouseup', onMouseUp);
|
|
304
|
+
});
|
|
305
|
+
// Touch events
|
|
306
|
+
header.addEventListener('touchstart', (e) => {
|
|
307
|
+
const target = e.target;
|
|
308
|
+
if (target.classList.contains('scenetest-count'))
|
|
309
|
+
return;
|
|
310
|
+
if (isAnimating)
|
|
311
|
+
return;
|
|
312
|
+
const touch = e.touches[0];
|
|
313
|
+
onPointerDown(touch.clientX, touch.clientY);
|
|
314
|
+
const onTouchMove = (ev) => {
|
|
315
|
+
const t = ev.touches[0];
|
|
316
|
+
onPointerMove(t.clientX, t.clientY);
|
|
317
|
+
if (isDragging)
|
|
318
|
+
ev.preventDefault();
|
|
319
|
+
};
|
|
320
|
+
const onTouchEnd = () => {
|
|
321
|
+
document.removeEventListener('touchmove', onTouchMove);
|
|
322
|
+
document.removeEventListener('touchend', onTouchEnd);
|
|
323
|
+
if (!isDragging) {
|
|
324
|
+
panelEl.classList.toggle('collapsed');
|
|
325
|
+
}
|
|
326
|
+
onPointerUp();
|
|
327
|
+
};
|
|
328
|
+
document.addEventListener('touchmove', onTouchMove, { passive: false });
|
|
329
|
+
document.addEventListener('touchend', onTouchEnd);
|
|
330
|
+
}, { passive: true });
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Create and mount the floating panel
|
|
334
|
+
*/
|
|
335
|
+
export function createPanel() {
|
|
336
|
+
if (panel)
|
|
337
|
+
return;
|
|
338
|
+
const panelEl = document.createElement('div');
|
|
339
|
+
panelEl.id = 'scenetest-panel';
|
|
340
|
+
panelEl.innerHTML = getPanelHTML();
|
|
341
|
+
document.body.appendChild(panelEl);
|
|
342
|
+
setPanel(panelEl);
|
|
343
|
+
setListEl(panelEl.querySelector('#scenetest-list'));
|
|
344
|
+
// Attach event listeners ONCE for the list content (uses event delegation)
|
|
345
|
+
attachEventListeners(panelEl.querySelector('#scenetest-list'), {
|
|
346
|
+
openFullscreenToGroup: (groupId) => openFullscreen(groupId),
|
|
347
|
+
openInEditor: (location) => openInEditor(location),
|
|
348
|
+
toggleCollapsed: (groupId) => toggleGroupCollapsed(groupId),
|
|
349
|
+
});
|
|
350
|
+
// Apply initial corner position and set up drag-and-snap
|
|
351
|
+
applyCornerClass(panelEl, panelCorner);
|
|
352
|
+
setupDrag(panelEl);
|
|
353
|
+
// Filter by clicking counts
|
|
354
|
+
panelEl.querySelector('#scenetest-pass')?.addEventListener('click', (e) => {
|
|
355
|
+
e.stopPropagation();
|
|
356
|
+
handleSetFilter(filter === 'passes' ? 'all' : 'passes');
|
|
357
|
+
});
|
|
358
|
+
panelEl.querySelector('#scenetest-fail')?.addEventListener('click', (e) => {
|
|
359
|
+
e.stopPropagation();
|
|
360
|
+
handleSetFilter(filter === 'fails' ? 'all' : 'fails');
|
|
361
|
+
});
|
|
362
|
+
// Filter buttons
|
|
363
|
+
panelEl.querySelector('#scenetest-filter-all')?.addEventListener('click', (e) => {
|
|
364
|
+
e.stopPropagation();
|
|
365
|
+
handleSetFilter('all');
|
|
366
|
+
});
|
|
367
|
+
panelEl.querySelector('#scenetest-filter-fails')?.addEventListener('click', (e) => {
|
|
368
|
+
e.stopPropagation();
|
|
369
|
+
handleSetFilter('fails');
|
|
370
|
+
});
|
|
371
|
+
// Clear button
|
|
372
|
+
panelEl.querySelector('#scenetest-clear')?.addEventListener('click', (e) => {
|
|
373
|
+
e.stopPropagation();
|
|
374
|
+
clearAll();
|
|
375
|
+
clearSymphony();
|
|
376
|
+
updatePanel();
|
|
377
|
+
updateFullscreenWindow();
|
|
378
|
+
});
|
|
379
|
+
// Fullscreen button
|
|
380
|
+
panelEl.querySelector('#scenetest-fullscreen')?.addEventListener('click', (e) => {
|
|
381
|
+
e.stopPropagation();
|
|
382
|
+
openFullscreen();
|
|
383
|
+
});
|
|
384
|
+
// Audio: Mute toggle
|
|
385
|
+
panelEl.querySelector('#scenetest-mute')?.addEventListener('click', (e) => {
|
|
386
|
+
e.stopPropagation();
|
|
387
|
+
// Initialize audio on first user interaction
|
|
388
|
+
initAudio();
|
|
389
|
+
const nowMuted = toggleMute();
|
|
390
|
+
const muteBtn = panelEl.querySelector('#scenetest-mute');
|
|
391
|
+
if (muteBtn) {
|
|
392
|
+
muteBtn.textContent = nowMuted ? '\uD83D\uDD07' : '\uD83D\uDD0A';
|
|
393
|
+
muteBtn.classList.toggle('muted', nowMuted);
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
// Audio: Play symphony
|
|
397
|
+
panelEl.querySelector('#scenetest-play')?.addEventListener('click', (e) => {
|
|
398
|
+
e.stopPropagation();
|
|
399
|
+
// Initialize audio on first user interaction
|
|
400
|
+
initAudio();
|
|
401
|
+
const playBtn = panelEl.querySelector('#scenetest-play');
|
|
402
|
+
if (isPlaying()) {
|
|
403
|
+
stopSymphony();
|
|
404
|
+
if (playBtn) {
|
|
405
|
+
playBtn.textContent = '\u25B6';
|
|
406
|
+
playBtn.classList.remove('playing');
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
const info = getSymphonyInfo();
|
|
411
|
+
if (info.eventCount === 0) {
|
|
412
|
+
// Nothing to play
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
playSymphony();
|
|
416
|
+
if (playBtn) {
|
|
417
|
+
playBtn.textContent = '\u23F9';
|
|
418
|
+
playBtn.classList.add('playing');
|
|
419
|
+
}
|
|
420
|
+
// Set up callback for when symphony completes
|
|
421
|
+
;
|
|
422
|
+
window.__scenetest_symphonyComplete = () => {
|
|
423
|
+
const btn = panel?.querySelector('#scenetest-play');
|
|
424
|
+
if (btn) {
|
|
425
|
+
btn.textContent = '\u25B6';
|
|
426
|
+
btn.classList.remove('playing');
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Update the panel content
|
|
434
|
+
*/
|
|
435
|
+
export function updatePanel() {
|
|
436
|
+
if (!panel || !listEl)
|
|
437
|
+
return;
|
|
438
|
+
const passEl = panel.querySelector('#scenetest-pass');
|
|
439
|
+
const failEl = panel.querySelector('#scenetest-fail');
|
|
440
|
+
if (passEl)
|
|
441
|
+
passEl.textContent = `\u2713 ${passCount}`;
|
|
442
|
+
if (failEl)
|
|
443
|
+
failEl.textContent = `\u2717 ${failCount}`;
|
|
444
|
+
const filteredGroups = groups
|
|
445
|
+
.map(g => ({
|
|
446
|
+
...g,
|
|
447
|
+
items: filterItems(g.items),
|
|
448
|
+
}))
|
|
449
|
+
.filter(g => g.items.length > 0);
|
|
450
|
+
if (filteredGroups.length === 0) {
|
|
451
|
+
const message = filter === 'fails' ? 'No errors! All assertions passed.' : 'Click around to see inline assertions...';
|
|
452
|
+
listEl.innerHTML = `<div id="scenetest-empty">${message}</div>`;
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
// Always show grouped view
|
|
456
|
+
listEl.innerHTML = filteredGroups
|
|
457
|
+
.map(g => renderPanelGroup(g))
|
|
458
|
+
.reverse()
|
|
459
|
+
.join('');
|
|
460
|
+
}
|
|
461
|
+
//# sourceMappingURL=panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel.js","sourceRoot":"","sources":["../../../src/panels/observer/panel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rendering functions for the dev panel
|
|
3
|
+
*
|
|
4
|
+
* SECURITY NOTE: These functions use data attributes instead of inline onclick
|
|
5
|
+
* handlers to prevent XSS. Event listeners are attached via delegation in
|
|
6
|
+
* attachEventListeners() after rendering.
|
|
7
|
+
*/
|
|
8
|
+
import type { AssertionResult, AssertionGroup, LocationGroup, LocationEntry } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Render a single assertion item for the main panel
|
|
11
|
+
* Click opens fullscreen view, no history shown (history only in fullscreen)
|
|
12
|
+
*/
|
|
13
|
+
export declare function renderPanelItem(a: AssertionResult, groupId: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* Render a single assertion item for the main panel (ungrouped, with time)
|
|
16
|
+
*/
|
|
17
|
+
export declare function renderPanelItemWithTime(a: AssertionResult): string;
|
|
18
|
+
/**
|
|
19
|
+
* Render a group of assertions for the main panel
|
|
20
|
+
*/
|
|
21
|
+
export declare function renderPanelGroup(g: AssertionGroup): string;
|
|
22
|
+
/**
|
|
23
|
+
* Render a single assertion item for fullscreen view
|
|
24
|
+
*/
|
|
25
|
+
export declare function renderFullscreenItem(a: AssertionResult): string;
|
|
26
|
+
/**
|
|
27
|
+
* Render a group of assertions for fullscreen view
|
|
28
|
+
*/
|
|
29
|
+
export declare function renderFullscreenGroup(g: AssertionGroup): string;
|
|
30
|
+
/**
|
|
31
|
+
* Render a location row for the "by location" view
|
|
32
|
+
* Shows one row per unique code location with status dots
|
|
33
|
+
*/
|
|
34
|
+
export declare function renderLocationRow(group: LocationGroup): string;
|
|
35
|
+
/**
|
|
36
|
+
* Render a piano roll visualization showing notes over time (chronological grid)
|
|
37
|
+
* X axis = time (chords), Y axis = notes (pitch)
|
|
38
|
+
*/
|
|
39
|
+
export declare function renderPianoRoll(locations: LocationGroup[], allAssertions: AssertionResult[]): string;
|
|
40
|
+
/**
|
|
41
|
+
* Render a sequence entry for the "sequence" view
|
|
42
|
+
* Shows a single run of an assertion at a specific location
|
|
43
|
+
* isFirst/isLast are used to show timeline labels
|
|
44
|
+
*/
|
|
45
|
+
export declare function renderSequenceEntry(entry: LocationEntry, _location: AssertionResult['location'], isFirst?: boolean, isLast?: boolean): string;
|
|
46
|
+
/**
|
|
47
|
+
* Render a chord tooltip showing all assertions that fired together
|
|
48
|
+
*/
|
|
49
|
+
export declare function renderChordTooltip(assertions: AssertionResult[]): string;
|
|
50
|
+
/**
|
|
51
|
+
* Render the sequence view header showing the location being tracked
|
|
52
|
+
*/
|
|
53
|
+
export declare function renderSequenceHeader(group: LocationGroup): string;
|
|
54
|
+
/**
|
|
55
|
+
* Render the back button for sequence view
|
|
56
|
+
*/
|
|
57
|
+
export declare function renderBackButton(fromView?: 'grouped' | 'byLocation'): string;
|
|
58
|
+
/**
|
|
59
|
+
* A node in the file tree. Directories have children, files have assertions.
|
|
60
|
+
*/
|
|
61
|
+
export interface FileTreeNode {
|
|
62
|
+
/** Display name for this segment (e.g. "App.tsx" or "components") */
|
|
63
|
+
name: string;
|
|
64
|
+
/** Full relative path up to this node (used as collapse key) */
|
|
65
|
+
path: string;
|
|
66
|
+
/** True if this is a leaf file node */
|
|
67
|
+
isFile: boolean;
|
|
68
|
+
/** Child directory/file nodes */
|
|
69
|
+
children: FileTreeNode[];
|
|
70
|
+
/** Assertion groups that belong to this file (only for file nodes) */
|
|
71
|
+
assertions: LocationGroup[];
|
|
72
|
+
/** Aggregated status */
|
|
73
|
+
status: 'pass' | 'fail' | 'warn';
|
|
74
|
+
/** Most recent timestamp among all assertions in this subtree */
|
|
75
|
+
lastTimestamp: number;
|
|
76
|
+
/** Total assertion count in this subtree */
|
|
77
|
+
totalAssertions: number;
|
|
78
|
+
/** Total failures in this subtree */
|
|
79
|
+
totalFailures: number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Build a file tree from location groups.
|
|
83
|
+
*
|
|
84
|
+
* Groups assertions by their `location.file`, constructs a trie from the path
|
|
85
|
+
* segments, and compacts single-child directory chains (e.g. "src/components").
|
|
86
|
+
*/
|
|
87
|
+
export declare function buildFileTree(locations: LocationGroup[]): FileTreeNode[];
|
|
88
|
+
/**
|
|
89
|
+
* Render the full file tree view.
|
|
90
|
+
*/
|
|
91
|
+
export declare function renderFileTree(tree: FileTreeNode[]): string;
|
|
92
|
+
/**
|
|
93
|
+
* Attach event listeners to rendered elements using event delegation.
|
|
94
|
+
* Call this after rendering HTML to a container.
|
|
95
|
+
*
|
|
96
|
+
* @param container - The container element (or document)
|
|
97
|
+
* @param handlers - Object with handler functions
|
|
98
|
+
*/
|
|
99
|
+
export declare function attachEventListeners(container: Document | HTMLElement, handlers: {
|
|
100
|
+
openFullscreenToGroup?: (groupId: number) => void;
|
|
101
|
+
openInEditor?: (location: unknown) => void;
|
|
102
|
+
openInEditorFullscreen?: (location: unknown) => void;
|
|
103
|
+
showSequence?: (key: string) => void;
|
|
104
|
+
backToLocationView?: () => void;
|
|
105
|
+
setViewMode?: (mode: string) => void;
|
|
106
|
+
toggleCollapsed?: (groupId: number) => void;
|
|
107
|
+
toggleFileTree?: (path: string) => void;
|
|
108
|
+
}): void;
|
|
109
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/panels/observer/render.ts"],"names":[],"mappings":"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"}
|