routing: the requests sit right under the stage, sized to stay in sight with it (Image #23: 这一块离那个路由动画距离太远了,用户点击了这里都不知道发生了什么) — the groups and the providers with several accounts or keys came between them, so a request picked in the list played on a stage scrolled out of sight above. They now come after the requests, and the list is as tall as leaves the stage in view above it (216–420px), scrolling on its own rather than the page. Picking a request no longer sends the list back to its top in WebKit (it was emptied and refilled, which reset its scroll). click-scroll.test.cjs brings a row into the list before picking it, as a reader would; Chromium and WebKit pass
This commit is contained in:
3 files changed
+32
-2
No files matched your search
@@ -201,7 +201,7 @@
|
||||
.rt-livedot { width: 6px; height: 6px; margin-left: 7px; border-radius: 50%; background: var(--green); animation: rtlive 1.8s infinite; --fg: var(--green); }
|
||||
@media (prefers-reduced-motion: reduce) { .rt-livedot { animation: none; } }
|
||||
/* routing groups, and the providers routing over several of their own */
|
||||
.rt-gsec { display: grid; gap: 6px; margin-bottom: 16px; }
|
||||
.rt-gsec { display: grid; gap: 6px; margin-top: 16px; }
|
||||
.rt-gsec .row-head .note { margin-right: 6px; }
|
||||
.rt-gsec .rt-pools { margin-bottom: 0; }
|
||||
.rt-gsec .row-head + .list + .row-head { margin-top: 8px; }
|
||||
|
||||
@@ -1023,6 +1023,7 @@
|
||||
reqNote.textContent = day ? t(pastCut ? "the last {n} of {day}" : "{n} on {day}", { n: rs.length, day: dayName(day) })
|
||||
: t("the last {n} the gateway keeps", { n: rs.length });
|
||||
renderDays();
|
||||
if (!reqs.style.maxHeight) requestAnimationFrame(fitReqs); // first shown
|
||||
// none yet: what the list is for in its place, and no accounts column
|
||||
// to tally nothing
|
||||
const none = !rs.length;
|
||||
@@ -1039,6 +1040,9 @@
|
||||
renderActs(rs);
|
||||
return;
|
||||
}
|
||||
// the list scrolls on its own; WebKit, emptied for a moment, would
|
||||
// send it back to its top from under the row just picked
|
||||
const listTop = reqs.scrollTop;
|
||||
reqs.replaceChildren(...rs.map((r) => {
|
||||
const [said, how, tr] = outcome(r);
|
||||
const b = el("button", "rt-req " + how);
|
||||
@@ -1071,6 +1075,7 @@
|
||||
b.onclick = () => pick(r);
|
||||
return b;
|
||||
}));
|
||||
if (reqs.scrollTop !== listTop) reqs.scrollTop = listTop;
|
||||
renderActs(rs);
|
||||
}
|
||||
|
||||
@@ -1631,7 +1636,9 @@
|
||||
const gHead = el("div", "row-head"), gList = el("div", "list rt-groups");
|
||||
const pHead = el("div", "row-head"), pList = el("div", "list rt-pools");
|
||||
gsec.append(gHead, gList, pHead, pList);
|
||||
more.prepend(gsec);
|
||||
// after the requests: a request picked in the list plays on the stage,
|
||||
// so the list sits right under it
|
||||
more.append(gsec);
|
||||
const ROUTE_OPTS = [["", "Smart"], ["order", "In order"], ["rotate", "In turn"], ["usage", "Least used"]];
|
||||
const AFF_OPTS = [["", "Auto"], ["session", "Session"], ["turn", "Within a turn"], ["off", "Off"]];
|
||||
const AFF_HINT = {
|
||||
@@ -2066,6 +2073,18 @@
|
||||
loadGroups();
|
||||
|
||||
new ResizeObserver(() => layout()).observe(stage);
|
||||
// the list is as tall as leaves the stage in sight above it: the reader
|
||||
// scrolls the list, not the page, and a request picked plays in view.
|
||||
// Its top stays where it is as it is sized, so a row just clicked does too
|
||||
function fitReqs() {
|
||||
const v = $("#view-routing");
|
||||
if (v.hidden || !reqs.offsetParent) return;
|
||||
const above = reqs.getBoundingClientRect().top - box.getBoundingClientRect().top;
|
||||
const room = v.clientHeight - above - 28;
|
||||
reqs.style.maxHeight = Math.round(Math.max(216, Math.min(420, room))) + "px";
|
||||
}
|
||||
new ResizeObserver(fitReqs).observe($("#view-routing"));
|
||||
new ResizeObserver(fitReqs).observe(box);
|
||||
words();
|
||||
requestAnimationFrame(frame);
|
||||
poll();
|
||||
|
||||
@@ -107,6 +107,17 @@ for (const engine of (process.env.BROWSER ? [process.env.BROWSER] : ["chromium",
|
||||
for (const i of [3, 7, 5]) {
|
||||
const row = () => page.locator(".rt-req").nth(i);
|
||||
await scrollTo(`.rt-req >> nth=${i}`);
|
||||
// the list scrolls on its own: the reader brings the row into it
|
||||
// (the click would, before it is measured)
|
||||
const list = await page.locator(".rt-reqs").boundingBox();
|
||||
await page.mouse.move(list.x + list.width / 2, list.y + 20);
|
||||
for (let k = 0; k < 40; k++) {
|
||||
const b = await row().boundingBox();
|
||||
if (b.y + b.height <= list.y + list.height && b.y >= list.y) break;
|
||||
await page.mouse.wheel(0, b.y < list.y ? -20 : 20);
|
||||
await page.waitForTimeout(20);
|
||||
}
|
||||
await page.waitForTimeout(300);
|
||||
const was = await row().evaluate((e) => e.getBoundingClientRect().top);
|
||||
await row().click();
|
||||
await settle(page);
|
||||
|
||||
Reference in new issue
Block a user