Bug 281786
| Summary: | Auto-scrolling on popular Guitar Tab site doesn't work when page is zoomed | ||
|---|---|---|---|
| Product: | WebKit | Reporter: | Daniel Jalkut <jalkut> |
| Component: | New Bugs | Assignee: | Nobody <webkit-unassigned> |
| Status: | NEW | ||
| Severity: | Normal | CC: | karlcow, simon.fraser, webkit-bug-importer |
| Priority: | P2 | Keywords: | BrowserCompat, InRadar |
| Version: | Safari Technology Preview | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
Daniel Jalkut
The Ultimate Guitar tab site features an autoscroll button which is intended to scroll the content of the page automatically so you can play along.
The scroll works fine in Safari UNLESS you've zoomed the page to any non-100% zoom level.
To reproduce:
1. Navigate to any Ultimate Guitar song page, for example: https://tabs.ultimate-guitar.com/tab/the-beths/expert-in-a-dying-field-chords-4271140
2. Ensure the page is zoomed to actual size by pressing Cmd-0
3. Click the "Autoscroll" button at the bottom of the page
4. While the page content is scrolling, press Cmd-+ to increase the zoom factor for the page.
Expected: the scrolling should continue
Actual: the scrolling stops
Notice that if you switch back to 100% (Cmd-0) the scrolling immediately begins again. Then zooming to a non-100% factor immediately stops it.
I don't know if this is ultimately (hah!) a bug in their autoscrolling code, or something wrong in WebKit. I confirmed though that the same feature works at all zoom sizes in Chrome.
| Attachments | ||
|---|---|---|
| Add attachment proposed patch, testcase, etc. |
Sam Sneddon [:gsnedders]
Daniel also pointed at https://www.ultimate-guitar.com/forum/showthread.php?t=2215942 in Slack, where it suggests the developer is aware of this.
Radar WebKit Bug Importer
<rdar://problem/138214931>
Karl Dubost
The autoscroll is managed by
```
const G = () => {
const [t, e] = (0, y.useState)(document.body.getBoundingClientRect()),
[o, i] = (0, y.useState)(0),
[n, s] = (0, y.useState)(t.top),
[a, r] = (0, y.useState)(t.left),
[l, c] = (0, y.useState)(null),
d = () => {
e(document.body.getBoundingClientRect()),
c(o > -t.top ? "down" : "up")
};
return (0, y.useEffect)((() => {
s(t.top ? -t.top : 0),
r(t.left),
i(t.top ? -t.top : 0)
}), [t]), (0, y.useEffect)((() => (window.addEventListener("scroll", d), () => {
window.removeEventListener("scroll", d)
}))), {
scrollY: n,
scrollX: a,
scrollDirection: l
}
},
```
in https://tabs.ultimate-guitar.com/static/public/build/ug_react_es6/202411/7496.96e2ce90724815b836fc437c3c770313.js
To note that the zoom also stops the scrolling on Firefox. So only chrome keeps scrolling.
Also when coming back to "zoom: 100%", then the scroll restarts.
Karl Dubost
I wonder how document.body.getBoundingClientRect() changes when zooming on different browsers.
Karl Dubost
document.body.getBoundingClientRect() changes in similar ways in different browsers.
Karl Dubost
Another data point,
If I zoom BEFORE activating the autoscroll, and activate it, then the autoscroll is not working.
In that same sequence, if I set back to 100%, the autoscroll starts.
Simon Fraser (smfr)
The autoscroll code is actually this:
```
v = (0, n.useCallback)((t => {
const {current: e} = r;
if (!d.current || !a.current || !e)
return;
const i = 0 < window.innerHeight - l - a.current.getBoundingClientRect().bottom,
n = e instanceof Window ? e.scrollX : e.scrollLeft;
if (i) {
if (!t)
return void f();
e.scrollTo(n, 0)
}
if (!i) {
const t = e instanceof Window ? e.scrollY : e.scrollTop;
e.scrollTo(n, t + u.current)
}
const o = 1e3 / p.current * (g.nR / (40 - (40 / 15 - 1)));
c.current = window.setTimeout(v, o)
}), [e, l]);
```
Maybe this is related to bug 174362.
Simon Fraser (smfr)
Bug 174362 is about pinch zoom, not Command-+ zoom
Daniel Jalkut
Thanks for isolating the autoscroll code. I wonder if there's something about the different zoom levels that causes the math to be off such that the `e.scrollTo` line continuously scrolls to the same offset. I don't know enough about how the zoomed window might change the semantic meaning of a "scrollY" value, for example. But I can observe that while the bug is happening it constantly tries to scroll by "1" (u.current), but by the time the callback is reached again e.scrollY is still at the same location. So maybe scrolling by 1 isn't enough?
In fact, as a quick check, I broke at the line where the scrollTo occurs, and changed the value of `u.current` to 2 instead of 1. Making this changes causes the scroll animation to resume.
In fact, I can confirm that at the breakpoint, if e.scrollY for example is 1302, manually invoking `e.scrollTo(0, 1303)` has no impact on e.scrollY. But something like `e.scrollTo(0, 1305` does.
Daniel Jalkut
Perhaps the distinction between browsers here is if Chrome's implementation of `scrollTo` rounds "out" (rounding up for positive and down for negative changes), but Safari rounds "in." I think the bug somehow has to do with the developer's assumption that consistently asking for the scroll to be "1" greater will always result in a change, but that on Safari it is not guaranteed.