Closed mustaqahmed closed 3 years ago
Here is the design doc for our proposal.
So we'd end up with both a timeout and forwarding a bit? Seems a bit unfortunate.
cc @smaug----
Let me clarify the difference between the proposed "transfer" vs the "gesture token forwarding" we (conceptually) have without UAv2. I mentioned "conceptually" here because no browser fully supported it because of the complications involved.
This would be a dedicated API for activation. Only the postMessage()
calls with a special option would perform the transfer. No other "chaining" (postMessage()
without the option, promises, setTimeout()
, whatever) would transfer the activation.
Token forwarding is assumed implicit with any kind of chaining. This makes the outcome of any call to an activation-gated API dependent on the implementation details of the chaining involved in this call. E.g. in Chrome, we never logically supported token forwarding through promises (it just happened to work in same-process cases because of a renderer-wide shared state).
Transfer vs propagation differences. The sender (frame) loses activation state through a transfer, so can't call any activation gated API after a transfer. And only the remaining (delta) expiry time available at the sender is transferred to the receiver, making an arbitrary chain of transfers safe from abuse.
This is not the case with token forwarding: it extends activation availability to the "chained task". This can be abused to multiply a user activation (possibly by a pair of rogue cross-origin subframes). Because of this, Chrome has been halting the forwarding after the first postMessage()
call or (in most browsers) beyond a 'setTimeout()` call depth of one. This is not consistent.
Btw, it doesn't have to be postMessage()
. Something like targetwindow.transferActivation()
could be an option too, might be even better if we want/have to define it to be synchronous.
Thanks. FWIW, I don't think we want another synchronous communication channel between two places that could be in different processes.
Sticking to postMessage()
seems logical then, because:
@mounirlamouri suggested window.transferUserActivation()
instead, which I think can be asynchronous too.
@annevk, wdyt?
@smaug----: we would love to know your thoughts too.
Something that was pointed out to me offline is that my proposal assumes that the user activation isn't linked to a scope which may be what Mozilla and Chrome are doing but not what Safari is. Do we see a path forward with some consistency here? Do we want to design an API based on a convergence towards a similar behaviour?
@mounirlamouri: The transfer idea here could be applied to scoped user activation model too, primarily because the model never really worked consistently with postMessages
, even for same-origin frames. If the convergence question here is about the underlying model for user activation, I would suggest #1903 for that discussion.
I agree with @mounirlamouri that window.transferUserActivation()
is a cleaner API, vs postMessage()
transfer.
So, since this transfer API (whether postMessage
or transferUserActivation
) requires developer to specificially make the transfer, won't they need an introspection API to know if the given window has activation state at the current moment? (Or are we expecting them to simply always attempt to transfer the activation whether or not they might have it?) Is there a place where the current activation state can be read? (e.g., window.hasActivation
or window.hasTransientActivation
/ hasEverBeenActivated
)?
Ah, makes sense. Thanks! https://github.com/dtapuska/useractivation
Motivated by the feedback from TAG about this proposal, plus a new use-case we want to support, we have switched our focus to an alternate Capability Delegation API (WICG repo, design doc).
To prove that a simple user activation model works for the web (#1903), Chrome just shipped User Activation v2 in M72 (stable release started 2 weeks ago). We encountered some minor regressions so far, all around the common theme that an activated frame wants to delegate activation-dependent tasks to another frame.
This requirement was not relevant before UAv2 in Chrome, because of render-process-wide visibility of activation state. UAv2 defines the default visibility of a user activation to be all container frames, which exposed those use-cases as regressions.
We need to address this problem now: define a way to change the default visibility of user activation.
Here is our proposal: allow transfer of user activation to a target frame through
postMessage()
calls.