WICG / gesture-delegation

Gesture Delegation API proposal
Other
7 stars 5 forks source link

Delegate features instead of gestures #4

Closed jyasskin closed 6 years ago

jyasskin commented 7 years ago

I'm uncomfortable having a main frame delegate gestures to subframes. I'm not exactly sure why, but it could be

  1. It's not clear whether this delegates all gestures, (so, for example, the subframe could open a popup because the main frame received a gesture) or just the fact that there's ever been a gesture.
  2. This is a whole extra attribute to cover an intervention we're not even sure will stick.

I think I'd rather see you use Feature Policy to delegate the ability to vibrate, autoplay, etc from a parent to child frame. Then if the parent has the gesture so that it has the ability, that naturally propagates to the child, without mentioning the gesture itself.

@clelland, thoughts?

clelland commented 7 years ago

Parts of this proposal came out of my concern that there was a tension between the binary nature of feature policy (a feature is allowed, or it isn't) and the requirement for user activation for certain APIs. The question at the time was whether to use FP to allow sites to opt-out of explicitly activating subframes, or to use FP to block the feature entirely (even with activation)

If only feature policy were used, then you would have to define a policy controlled feature as either:

or

The simplest solution that allowed all three possibilities involved separating the feature policy (allowed or not) from the activation requiment (does activating the parent also activate the child?) Hence, this proposal.

I have a doc that I'll try to find to link to that explored some of this early on.

annevk commented 7 years ago

It does seem like there's a clash of sorts. E.g., Fullscreen requires user activation, but allowfullscreen should really be enough to allow it in an <iframe>. It should not also require a new attribute for user activation.

jyasskin commented 7 years ago

@clelland My memory of that discussion is that, given a parent frame with the ability to use capability A, it might want a subframe to be able to use that capability:

  1. At any time.
  2. In association with an activation/gesture on that subframe: a. Capability A could be used during that activation's handling, b. Or any time after an activation on the subframe.
  3. Never.

My understanding of the proposal here is that it adds a fourth case:

  1. In association with an activation on the parent frame.

For both vibration and audio-autoplay, that seems superfluous to me: the parent likely only has the ability in association with its own activation, so simply delegating "at any time" is sufficient, which is exactly what feature-policy provides.

clelland commented 7 years ago

@jyasskin This is the doc with my initial thoughts on this problem, which turned into this proposal, which eventually resulted in the proposal behind this WICG repo.

For both vibration and audio-autoplay, that seems superfluous to me: the parent likely only has the ability in association with its own activation, so simply delegating "at any time" is sufficient, which is exactly what feature-policy provides.

I don't know if there's a real distinction between (1) and (4) -- there shouldn't be a way for any site-declared policy to promote a feature from "requiring an activation" to "use at any time" -- I would combine both of those, and word it as "whenever allowed in the parent frame"

Depending on how you define a feature, feature-policy by itself would let you select between either (1) and (2), or between (2) and (3).

Right now, mechanisms like allowfullscreen, or the feature-policy equivalent allow="fullscreen", let you choose between (2) and (3). Even if you grant access to the fullscreen API to a cross-origin subframe, you can't declare that it is sufficiently trusted to be able to use the API without being specifically activated. That, I think, is the point of this proposal: to allow the embedder to declare that some third-party content is sufficiently "part of the main page" that activating the parent page should activate the 3rd-party child as well.

mustaqahmed commented 7 years ago

I view "feature policy" and "user gesture" as two disjoint concept: the first one controls the availability of a feature in a subframe while the second controls user interaction flow into subframes. At the very least,

Consider the parent frame of a video news website that allows the autoplay feature in a subframe containing ads. The news site most likely won't want an ad audio to start playing at the moment the user plays a news media, so it won't delegate user activation to the subframe. But it is acceptable that ad frame can play audio when the user interacts with the ad frame itself, so the autoplay feature gets exposed to the subframe.

On the other hand, it may be okay for the parent frame of a text-only page to delegate user activation to ad subframes (in addition to exposing the feature) because the ad audio content can't "interfere" with the main page's content.

mustaqahmed commented 7 years ago

@jyasskin: Am I correct that your original concern is caused by the use of "features" in both Feature Policy and the proposed allowedActivationDelegation list here? I agree that this "overlap" could cause developers' confusion.

Therefore, continuing my argument in my last post above on the orthogonality of "features" vs "activation state", should we possibly make the activation delegation API independent from "features"? In #5, I proposed one alternative that seems to fit this orthogonality argument. Essentially, instead of listing the features affected by the activation delegation, we can list of "types" of activations to delegate.

@jyasskin: would this address your concern?

@mounirlamouri: would it fit the granularity you wanted in the delegation?

jyasskin commented 7 years ago

'k, thinking through this again ... we can ask several questions about when an iframe can use a capability.

  1. Can the iframe use the capability at all?
  2. For capabilities that need a user activation when used anywhere, is an activation on the parent enough to activate the iframe?
  3. For capabilities that don't need user activation on the top-level frame, do they additionally need user activation to be used within the iframe?
  4. Can the iframe use the capability whenever the parent can? (This was @raymeskhoury's permission delegation, right?)

(2) and (4) kinda represent the question for the user, "Is the iframe 'part of' its parent?"

(3) doesn't seem to be proposed here.

(2) probably also only makes sense for the historical activation version, since to know when a transient activation is active, the iframe would need to get a message from the main frame, and it'd be nice if that message carried the gesture too. (I just made this comment on #5.)

I can't think of cases where (2) and (4) would give different outcomes when used for activation-y things, but (4) also generalizes to permission-y things, which makes me think it's the way to go.

What have I missed this time?

clelland commented 7 years ago

That's a pretty good summary, I think, @jyasskin -- (3) is definitely not being proposed; I don't think there's any combination of feature policy and this proposal that can add an activation requirement to an API that doesn't normally carry one.

Agreed that there is a definite resemblance between (2) and (4) here. Permission delegation also tries to answer the question "is the frame part of its parent," since it prompts the user for all permission requests as if they came from the top-level page.

Permission delegation is now being implemented entirely through feature policy, I believe. I'm trying to figure out why that seems sufficient for permission-gated features, but not for gesture-gated ones.

(The answer may have to do with the fact that a permission prompt will be raised, and the user will get the chance to consider the specific capability that is requested -- and even to consider why the top-level page is asking for it in the first place.)

One possibly important distinction between this proposal and permission delegation is that for permission delegation to work, the delegation must extend from the top-level frame all the way down the frame tree to the frame which actually initiates the permission request. This is how allowfullscreen, for instance, works, and how feature policy works in general.

With gesture delegation, the delegation doesn't have to start at the top-level. If the top-level frame doesn't delegate any gestures, but embeds a frame which delegates them to its children, then gesture delegation still works:

(Assume A embeds B, which embeds C)

Activating the top-level frame (A) doesn't activate the child frames (B) or (C), but activating (B) will activate (C).

jyasskin commented 7 years ago

In the A->B->C example, say both (A) and (B) grant the 'vibrate' feature policy, but only (B) delegates 'vibrate'. Then:

That seems like the same outcome as if we only delegate gestures.

mounirlamouri commented 6 years ago

Feature Policy is about allowing/blocking a feature while this feature is only about allowing an iframe to use the activation that a parent frame received. It doesn't mean the feature would be allowed or blocked as in the comment above, B will always be able to use 'vibrate' but will require a gesture on the frame if it didn't receive delegation.

The spirit of this proposal is to only use it for "document activation" which is whether a document received a user activation. Would it help if the attribute was renamed to make this clearer? I think it would make the name pretty heavy for no clear benefit but I'm happy to do this if it helps.

annevk commented 6 years ago

If the parent received activation of some sorts, how would that then end up in the child? From the example in the explainer it's not clear why you can't just invoke play() on the media element in the child.

mounirlamouri commented 6 years ago

Each frame would have its own flag which would be enabled when a user activation on the frame would have happened. Without the delegation, the child wouldn't be able to play as the click event happened on the parent but then a frame with a video is created. With the delegation, because the button was clicked, there was an activation on the parent and the parent allows the frame to use it. Does that make sense?

annevk commented 6 years ago

Currently none of the things that require user activation actually check what document/window the event happened in. Is part of this proposal to add that kind of infrastructure all over?

mounirlamouri commented 6 years ago

Part of the proposal is to add a flag to the browsing context that will record if it ever had a user activation and that will be used for vibration and media playback, yes.

annevk commented 6 years ago

Okay, that's not really clear from the explainer. It's also not clear to me at this point what changes that would entail to the HTML Standard and whether that requires a new primitive or some kind of overloading of the existing primitive. Figuring that out would help with naming.

mounirlamouri commented 6 years ago

I've changed the explainer slightly to be clearer about the new primitive. WDYT?

jyasskin commented 6 years ago

@annevk, when you have a question that's not the same as the main question in an issue, could you file a new issue?

@mounirlamouri:

B will always be able to use 'vibrate' but will require a gesture on the frame if it didn't receive delegation.

This doesn't make sense to me: I read your comment as saying that B will always be able to use 'vibrate' but sometimes will not be able to use 'vibrate'.

annevk commented 6 years ago

That's a lot better, though it probably needs to bound to a document. That also suggests the attribute should be named something like "delegateuseractivateddocument" (not entirely sure about tense, but "user activation" seems wrong as that's a different primitive).

annevk commented 6 years ago

@jyasskin sorry, filed #7.

mounirlamouri commented 6 years ago

@jyasskin 'vibrate' requires a user activation. Feature Policy allows an embedder to block 'vibrate' entirely. If vibrate isn't block with Feature Policy, it still requires a user activation. The proposal allows an embedder to delegate the user activation it receives on its document to an iframe in order to make it simpler to vibrate in iframes. Is this clearer?

mounirlamouri commented 6 years ago

To use vibrate() as an example, the options are:

I'm going to close this issue assuming this is answering the question. Please reopen if you still have concerns.

jyasskin commented 6 years ago

Yep, that's clear. This issue was saying that instead of asking pages to delegate the historical user activation bit, we should let the page delegate the whole ability to use the feature.