waygraph 0.12.37 → 0.12.38
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/cli.js +83 -22
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -712,6 +712,7 @@ async function installOverlay(page, title) {
|
|
|
712
712
|
if (!cursor) return;
|
|
713
713
|
const travel = ms || 600;
|
|
714
714
|
window.__wgCursorPos = { x: Number(x) || 0, y: Number(y) || 0 };
|
|
715
|
+
window.__wgCursorTravelUntil = Date.now() + (instant ? 0 : travel) + 40;
|
|
715
716
|
cursor.style.setProperty("--wg-cursor-ms", travel + "ms");
|
|
716
717
|
if (instant) {
|
|
717
718
|
const prev = cursor.style.transition;
|
|
@@ -812,10 +813,8 @@ async function installOverlay(page, title) {
|
|
|
812
813
|
let settled = zoom <= 1;
|
|
813
814
|
const settleAt = Date.now() + camMs;
|
|
814
815
|
const style = { size, weight, focus, color };
|
|
815
|
-
// Screen Studio / Screenify: dead zone
|
|
816
|
-
|
|
817
|
-
// on every mousemove (that fights like same-pole magnets).
|
|
818
|
-
const deadFrac = 0.4;
|
|
816
|
+
// Screen Studio / Screenify: dead zone follow (see followTick).
|
|
817
|
+
const deadFrac = 0.5;
|
|
819
818
|
let lastPanAt = 0;
|
|
820
819
|
const readCursorViewport = () => {
|
|
821
820
|
const cursor = document.getElementById("wg-cursor");
|
|
@@ -833,6 +832,11 @@ async function installOverlay(page, title) {
|
|
|
833
832
|
if (!window.__wgSetCamera || !window.__wgViewportToDoc) return;
|
|
834
833
|
const cam = window.__wgCamera;
|
|
835
834
|
if (!cam || !(cam.scale > 1.001)) return;
|
|
835
|
+
// Skip while the demo cursor is mid CSS travel - reading a
|
|
836
|
+
// mid-lerp rect makes the camera chase noise and teleport.
|
|
837
|
+
if (window.__wgCursorTravelUntil && Date.now() < window.__wgCursorTravelUntil) {
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
836
840
|
const pos = readCursorViewport();
|
|
837
841
|
if (!pos) return;
|
|
838
842
|
const vw = window.innerWidth;
|
|
@@ -849,12 +853,13 @@ async function installOverlay(page, title) {
|
|
|
849
853
|
else if (dy < -deadY) oy = dy + deadY;
|
|
850
854
|
if (ox === 0 && oy === 0) return;
|
|
851
855
|
const now = Date.now();
|
|
852
|
-
if (now - lastPanAt <
|
|
856
|
+
if (now - lastPanAt < 120) return;
|
|
853
857
|
lastPanAt = now;
|
|
854
|
-
//
|
|
855
|
-
const
|
|
856
|
-
const
|
|
857
|
-
|
|
858
|
+
// Partial gain - never yank the full overflow in one pan.
|
|
859
|
+
const gain = 0.35;
|
|
860
|
+
const nx = cam.cx + (ox / cam.scale) * gain;
|
|
861
|
+
const ny = cam.cy + (oy / cam.scale) * gain;
|
|
862
|
+
window.__wgSetCamera(nx, ny, cam.scale, 280);
|
|
858
863
|
};
|
|
859
864
|
const tick = () => {
|
|
860
865
|
const el = document.querySelector(sel);
|
|
@@ -1708,6 +1713,14 @@ async function cycleHighlightRings(page, highlights, gatesFast, opts) {
|
|
|
1708
1713
|
const last = list.length > 0 ? list[list.length - 1] : null;
|
|
1709
1714
|
if (!last || last.zoomOut !== false) {
|
|
1710
1715
|
await resetCameraZoom(page);
|
|
1716
|
+
} else {
|
|
1717
|
+
// Hold lock into the upcoming act click so follow/scroll cannot yank
|
|
1718
|
+
// the camera off the already-centered target (cart teleport bug).
|
|
1719
|
+
await page
|
|
1720
|
+
.evaluate(() => {
|
|
1721
|
+
window.__wgCameraLock = true;
|
|
1722
|
+
})
|
|
1723
|
+
.catch(() => {});
|
|
1711
1724
|
}
|
|
1712
1725
|
if (list.length === 0) {
|
|
1713
1726
|
await hideRing(page);
|
|
@@ -2444,10 +2457,11 @@ async function teardownOverlay(page) {
|
|
|
2444
2457
|
.catch(() => {});
|
|
2445
2458
|
}
|
|
2446
2459
|
|
|
2447
|
-
async function moveCursorTo(page, box, ms) {
|
|
2460
|
+
async function moveCursorTo(page, box, ms, opts) {
|
|
2448
2461
|
const x = box.x + box.width / 2;
|
|
2449
2462
|
const y = box.y + box.height / 2;
|
|
2450
2463
|
const travel = Math.max(0, Number(ms) || 0);
|
|
2464
|
+
const keepLock = !!(opts && opts.keepLock);
|
|
2451
2465
|
// Freeze camera follow while the demo cursor travels - otherwise dead-zone
|
|
2452
2466
|
// pans fight the click target (esp. right-edge cart chrome).
|
|
2453
2467
|
await page
|
|
@@ -2462,11 +2476,13 @@ async function moveCursorTo(page, box, ms) {
|
|
|
2462
2476
|
if (travel > 0) {
|
|
2463
2477
|
await new Promise((res) => setTimeout(res, travel));
|
|
2464
2478
|
}
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2479
|
+
if (!keepLock) {
|
|
2480
|
+
await page
|
|
2481
|
+
.evaluate(() => {
|
|
2482
|
+
window.__wgCameraLock = false;
|
|
2483
|
+
})
|
|
2484
|
+
.catch(() => {});
|
|
2485
|
+
}
|
|
2470
2486
|
return { x, y };
|
|
2471
2487
|
}
|
|
2472
2488
|
|
|
@@ -2594,6 +2610,7 @@ function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stubBefore
|
|
|
2594
2610
|
proto.click = async function (options) {
|
|
2595
2611
|
let clickPoint = null;
|
|
2596
2612
|
let clickTone = "auto";
|
|
2613
|
+
let keptCameraLock = false;
|
|
2597
2614
|
try {
|
|
2598
2615
|
await installOverlay(page);
|
|
2599
2616
|
// Wait until the target is visible BEFORE measuring - otherwise
|
|
@@ -2604,6 +2621,20 @@ function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stubBefore
|
|
|
2604
2621
|
state: "visible",
|
|
2605
2622
|
timeout: (options && options.timeout) || 30000,
|
|
2606
2623
|
}).catch(() => {});
|
|
2624
|
+
// Body-scale camera + Playwright scrollIntoView = teleport storm.
|
|
2625
|
+
// Lock the camera for the whole click when zoomed; force-click so
|
|
2626
|
+
// Playwright does not try to scroll the transformed page.
|
|
2627
|
+
const zoomed = await page
|
|
2628
|
+
.evaluate(() => !!(window.__wgCamera && window.__wgCamera.scale > 1.001))
|
|
2629
|
+
.catch(() => false);
|
|
2630
|
+
if (zoomed) {
|
|
2631
|
+
await page
|
|
2632
|
+
.evaluate(() => {
|
|
2633
|
+
window.__wgCameraLock = true;
|
|
2634
|
+
})
|
|
2635
|
+
.catch(() => {});
|
|
2636
|
+
keptCameraLock = true;
|
|
2637
|
+
}
|
|
2607
2638
|
const box = await this.boundingBox();
|
|
2608
2639
|
const narrated = box ? await wasJustNarrated(page) : false;
|
|
2609
2640
|
if (box && !narrated) {
|
|
@@ -2625,8 +2656,18 @@ function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stubBefore
|
|
|
2625
2656
|
const stubs = (stubBeforeRef && stubBeforeRef.current) || [];
|
|
2626
2657
|
const cap = await captionForLocator(page, this, stubs, fallback);
|
|
2627
2658
|
clickTone = cap.tone;
|
|
2628
|
-
|
|
2629
|
-
|
|
2659
|
+
// Already centered from stubBefore zoom: short cursor, keep lock.
|
|
2660
|
+
const travel = zoomed ? cursorMs(160) : cursorMs(600);
|
|
2661
|
+
clickPoint = await moveCursorTo(page, box, travel, {
|
|
2662
|
+
keepLock: zoomed,
|
|
2663
|
+
});
|
|
2664
|
+
// Re-measure after cursor settle - stale pre-travel box teleports the ring.
|
|
2665
|
+
const liveBox = (await this.boundingBox()) || box;
|
|
2666
|
+
clickPoint = {
|
|
2667
|
+
x: liveBox.x + liveBox.width / 2,
|
|
2668
|
+
y: liveBox.y + liveBox.height / 2,
|
|
2669
|
+
};
|
|
2670
|
+
await showRing(page, liveBox, cap.label, cap.tone, {
|
|
2630
2671
|
size: cap.size,
|
|
2631
2672
|
weight: cap.weight,
|
|
2632
2673
|
});
|
|
@@ -2638,7 +2679,10 @@ function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stubBefore
|
|
|
2638
2679
|
} else if (box) {
|
|
2639
2680
|
// Ring/caption already handled by narrate() - still move the
|
|
2640
2681
|
// cursor + pulse the click point, just skip re-showing the ring.
|
|
2641
|
-
|
|
2682
|
+
const travel = zoomed ? cursorMs(120) : cursorMs(200);
|
|
2683
|
+
clickPoint = await moveCursorTo(page, box, travel, {
|
|
2684
|
+
keepLock: zoomed,
|
|
2685
|
+
});
|
|
2642
2686
|
clickTone = "planned";
|
|
2643
2687
|
}
|
|
2644
2688
|
} catch {
|
|
@@ -2654,10 +2698,27 @@ function instrumentInteractionHighlighting(page, mem, slowMo, pacing, stubBefore
|
|
|
2654
2698
|
// mock click visually completes before the real one fires.
|
|
2655
2699
|
await new Promise((res) => setTimeout(res, skipTheater() ? 0 : 500));
|
|
2656
2700
|
}
|
|
2657
|
-
const
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2701
|
+
const zoomedClick = await page
|
|
2702
|
+
.evaluate(() => !!(window.__wgCamera && window.__wgCamera.scale > 1.001))
|
|
2703
|
+
.catch(() => false);
|
|
2704
|
+
const clickOpts =
|
|
2705
|
+
zoomedClick || keptCameraLock
|
|
2706
|
+
? { ...(options || {}), force: true }
|
|
2707
|
+
: options;
|
|
2708
|
+
try {
|
|
2709
|
+
const result = await originalClick.call(this, clickOpts);
|
|
2710
|
+
await new Promise((res) => setTimeout(res, clickPostPop()));
|
|
2711
|
+
await hideRing(page);
|
|
2712
|
+
return result;
|
|
2713
|
+
} finally {
|
|
2714
|
+
if (keptCameraLock) {
|
|
2715
|
+
await page
|
|
2716
|
+
.evaluate(() => {
|
|
2717
|
+
window.__wgCameraLock = false;
|
|
2718
|
+
})
|
|
2719
|
+
.catch(() => {});
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2661
2722
|
};
|
|
2662
2723
|
}
|
|
2663
2724
|
|