-
Notifications
You must be signed in to change notification settings - Fork 135
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
Reject promise if document becomes not fully active #872
Comments
We have a notification system that monitors the document state associated with the payment request: If the document becomes We also have checks throughout the implementation that call |
@marcoscaceres : Do you mind if we just copy-paste your code? k, thx, bye! 🥇 |
Heh, open source for a reason:) |
Thanks @marcoscaceres for the pointers! I'm getting some push back from Blink architecture owners for adding a new hook without a real world use case. After thinking about this a bit more, it seems that the only scenario where the spec'ed behavior is critical is if a reference to the promise is retained in a different context after the document associated with the promise becomes inactive. Concretely, I can only think of one scenario where this would be the case:
If the iframe was not same-origin as the top-level frame, it wouldn't have been able to pass I suspect almost all of the PaymentRequests made from iframes are from cross-origin iframes. I'm going to add some telemetry to verify this. If the same-origin use case turns out to be non-existent, then it seems to me that we don't have a real world use case that would depend on the current spec behavior. Then can we remove the spec that the promise must be rejected if the document becomes inactive after the promise is created? |
In Firefox at least, this causes the payment sheet closes if the iframe or top-level browsing context that created the request navigates. That’s obviously quite important for us, otherwise the sheet would continue to show if the underlying document is navigated to a new origin. Chromium clearly uses a different mechanism for detecting and dealing with this, which is ok I would say. You are correct that from third-party iframes this won’t be observable via script. Without changing the tests, we could make the argument to the W3C Director that this is interoperable, because at least the payment sheet closes when the creator context navigates (even if promises are left in a pending state, which is not very clean but 🤷♂️ ). If it’s not too painful to get some telemetry data, then great. But I agree with you: I very much doubt there will be many same-origin iframes using the API this way, and then randomly navigating away... so no stress if you don’t want actually gather usage stats. @domenic, do you have any concerns wrt this? |
My concern is that basically I messed up pushing for us to reject the promise when the document became inactive. I am sorry 😢. See https://groups.google.com/a/chromium.org/d/msg/platform-architecture-dev/BszBZqcPcuk/42KLPiHCDAAJ for a bit more background. |
I'm thinking we can just remove step 3 from the "If document stops being fully active..." section, leaving the following:
This way Firefox can still close the payment sheet. In fact, Chromium needs this as well, the only thing we can't do is reject the promise because the event loop is already stopped.
What about changing the test such that instead of waiting for the promise to reject, the test will create another payment request in the main frame? We can use whether the main frame request succeeds in calling show() to check if the payment sheet triggered from the iframe is dismissed as expected.
Copying over what @domenic said on the chromium-dev thread:
I think this is consistent with my suggestion above. |
There are multiple places in the spec today that requires any outstanding promises to be rejected if the document becomes not fully active, e.g. show(), retry(), complete().
In Blink, this turns out to be difficult to implement because there is no hook to inform the
blink::PaymentRequest
object that its associated context is about to be destroy. The only hook is after the context is destroyed. This is too late, as any rejection queue then will not actually be executed. So from web developer's perspective, the promise gets into a limbo state, and never rejects nor resolves (http://crbug.com/941271).Where this causes a real problem for web developers is when a
show()
promise is created from aPaymentRequest
in one context (e.g. an iframe) and passed to a second context (e.g. a parent frame), and the first context navigates away. If the parent frame relies on the promise to resolve or reject to control its UI, it will hang.@domenic you suggested the following on the platform-architecture-dev thread regarding this issue:
I'm not sure I fully follow what you mean. Can you clarify how this solves the problem?
In the end, I think there are two options out of this problem:
Any thoughts? @marcoscaceres @domenic @aestes @rsolomakhin @ianbjacobs
The text was updated successfully, but these errors were encountered: