-
Notifications
You must be signed in to change notification settings - Fork 757
[cssom-view-1] Scroll methods in Element and Window return Promises #12355
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Switch the return type for the scroll methods from `undefined` to `Promise<undefined>` as per the discussion and resolution in w3c#1562 (comment). Fixed: w3c#1562.
|
In the discussion we talked about the argument to the promise being an object which would tell the developer the result of the scroll, e.g. to know if it was cancelled / interrupted as was brought up a few times as a common thing to need to know. |
That's correct. The problem is that it not yet defined how the promise would be resolved to mark scroll completion vs interruption. I can update this PR to resolve with a
I am proposing to land this PR as "closing" #1562, staring a new spec issue to discuss 1+2 above, and then hash out 3 in the PR for that new issue. |
I would suggest that it not resolve with a boolean but rather with an object, e.g. define a ScrollResult, that we can add to if we later discover that we want to pass additional information. That said, having a boolean there and opening an issue for whether we should change it is a good thing.
This is normal, the resolution we have is effectively to pursue specifying and prototyping the feature. It's fully expected that in the process of doing this the implementor may make some opinionated decisions in writing the spec and bring those decisions back to the working group. Having something implemented will make it easier to have examples where we can show how the value would be used.
It would be valuable to define this to mean what we think makes the most sense. IMO this is anything that prevents completing the original scroll request. A programmatic scroll request on an unrelated scroller probably should not interrupt it. A scroll on the same scroller would mean that we are no longer actively scrolling to the originally requested location.
It is better to have the boolean there and to add an inline issue in the spec that says we need to agree on the type and when it is successful / unsuccessful. This shows spec readers that the API is likely to change, demonstrates the use case and can even point to the issue for people to add their feedback. Here's an example from css-images-5: csswg-drafts/css-images-5/Overview.bs Line 55 in b5312ce
|
|
Updated the PR with promise resolution with true/false, and filed #12495 for next steps. Please take a look. |
|
Here is a pdf showing the dependency of the scroll algorithms in this spec. Hopefully this will help the review here. |
|
The boolean stuff is rather confusing. Do we want / is it worth resolving differently for completion vs interruption? Can't stuff technically scroll after the UA resolves the promise, kinda defeating the point of it? |
|
What is the relation of this new scroll promise to the FWIW let element = document.getElementById('scroll-container');
element.scroll(0, 400).then(() => {
// ...scroll has finished
});After interop 2025 completes, the following or something like it should be relatively reliable. let element = document.getElementById('scroll-container');
let scrollPromise = new Promise(resolve => element.addEventListener("scrollend", resolve, {once: true}));
element.scroll(0, 400);
scrollPromise.then(() => {
// ...scroll has finished
}); |
|
Below are my responses, sorry for the delay (I was on vacation for several weeks).
@emilio I agree the original resolution does not include such details, and in our first patch we had the IDL type I think we correctly prevented the possibility of scrolling after promise resolution through the last few steps in our #perform-a-scroll algorithm. Note that all other scroll algorithms ultimately rely on this one, and they never resolve any promise with true unless the innermost call does the same. Please correct me if I missed any call dependency in the spec!
@dlrobertson: When multiple scrollers are involved, writing a |
|
Sure, but promise resolution is async and, in your example |
During the discussion in which we took the resolution, this was raised as an important point, from #1562 (comment):
If a user scrolls before we reach the target then it immediately resolves with false. This is because while we have completed the scrolling that is going to happen for that requested scroll, it was interrupted. In the use cases in the OP it was suggested that developers would use this for things like:
Having this completion state allows the developer to do something different for interrupted scrolls without needing to read back the scroll offset and try to figure out whether it was interrupted which can be hard when using scrollIntoView to determine exactly what offset you should expect to scroll to. Personally, I don't think it should be a boolean but rather a dictionary with an enum so that we could add additional arguments if we think of other things you might want to know about the completed scroll. |
You are correct, Our discussion seems to deserve a separate resolution in the WG. If you agree, I would suggest moving this discussion over to #12495 for a wider audience and settle this PR in one of the following ways:
@emilio What do you think? |
|
I'd probably resolve with undefined for now. Looks good with that. Thanks! |
|
I have switched the PR to Note that #perform-a-scroll still needs a promise that resolves with a Boolean because both #viewport-perform-a-scroll and #scroll-a-target-into-view need to know when all affected scrolls have completed. Again, the dependency of the scroll algorithms would be helpful I believe. |
In this model, we shouldn't need the boolean at all. ScrollIntoView just needs to wait until the promises for each of the scrolled scrollers resolve. If another scroll interrupts one or more of those scrolls then those interrupted scroll promises will be resolved immediately. |
My question is: do the uninterrupted scrollers still continue their scrolling even after one got interrupted? This is about the observed behavior and not about the returned promise. To explain in a different way, suppose a ScrollIntoView call starts smooth scrolling in scrollers |
This is getting beyond the issue of when the promises should be resolved. Whether or not any of the ongoing scrolls is interrupted, the scrollIntoView call should resolve when all of the dependent scrolls' promises have resolved. If they are interrupted, then the overall promise may resolve sooner. We can separately debate how interrupting a scroll should affect ongoing scrolls but I don't see what that has to do with the promise resolution. That said, this is a simple thing to test, I put together a test case https://codepen.io/flackr/pen/pvgJQxP . Chrome and Safari only interrupt the scroll of B, Firefox stops the scroll of B and C. I think that it doesn't make sense to stop scrolling A since you would still be able to scroll to the position that brings the B scroller into view. Stopping scrolling C (as firefox does) might make sense since it's no longer necessarily going to come into view. Though I could also see an argument for continuing it. Either way, this seems like a completely separate issue. |
|
Yeah, my comment about the observed behavior should have been in #12495. Done using the simplest possible promise resolution logic, see my latest commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple minor changes but otherwise looks good.
|
@emilio Please let me know if you would like to see any other changes. |
For a long time, the WPT had an `-expected.txt` with 58 IDL '[Fail]` messages for the mismatches Chrome had with the spec. In the last few months we landed IDL changes for scroll promises [1,2] which increased the number of mismatches to 71. Last week we landed the corresponding spec update [3] which brings the number of mismatches back to 58. [1] https://chromium-review.googlesource.com/c/chromium/src/+/6318459 [2] https://chromium-review.googlesource.com/c/chromium/src/+/6657206 [3] w3c/csswg-drafts#12355 The main `-expected.txt` was removed between [2] and [3] for whatever reason but that caused addition of platform-specific expectations in the platforms where the mismatch was noticed. This CL cleans them up too. Fixed: 431170125 Change-Id: Ic7dc61146fee579f7a421b14966990d9599c85dd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7049903 Reviewed-by: Vladimir Levin <vmpstr@chromium.org> Commit-Queue: Vladimir Levin <vmpstr@chromium.org> Auto-Submit: Mustaq Ahmed <mustaq@chromium.org> Cr-Commit-Position: refs/heads/main@{#1531672}
Switch the return type for the scroll methods from
undefinedtoPromise<undefined>as per the discussion and resolution in #1562 (comment).Fixed: #1562.