New issue
Advanced search Search tips

Issue 916993 link

Starred by 4 users

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug

Blocking:
issue 912936



Sign in to add a comment

requestFullscreen for iframe's element is broken

Reported by bars....@gmail.com, Dec 20

Issue description

Chrome Version       : 73.0.3645.0 (Official Build) canary (64-bit)
URLs (if applicable) : https://output.jsbin.com/banozabubi
Other browsers tested:
  Add OK or FAIL, along with the version, after other browsers where you
have tested this issue:
     Safari: OK
    Firefox: OK
       Edge: OK
  Chrome 71: OK

What steps will reproduce the problem?
(1) to have an iframe with allowfullscreen attribute on the page
(2) user clicks on an element in the top frame with onclick event listener
(3) js code calls requestFulscreen for the element in the iframe

What is the expected result?
iframe's element becomes fullscreen

What happens instead?
the code failed to open
`Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture.`


Please provide any additional information below. Attach a screenshot if
possible.
this issue is also relevant for Chrome 72 Beta
 
Owner: mustaq@chromium.org
Status: Assigned (was: Unconfirmed)
Caused by user activation V2. Disable user activation V2 and it works correctly. Over to mustaq.
Blocking: 912936
Labels: UserActivation
UAv2 clarified that the expectation that any element that wants to go fullscreen must have some user interaction within its own frame or any subframe.  In the repro, the user interacted with the top frame, so the newly created child frame shouldn't be able to go fullscreen.

I works such way before in Chrome and in all other browsers.

I don't see any reason why js can't open an iframe's element (with allowfullscreen attribute) to open in fullscreen.
The "allowfullscreen" attribute only controls access to Fullscreen API, it doesn't bypass user activation requirements.  E.g. even before UAv2, a cross-origin iframe with "allowFullscreen" couldn't successfully call requestFullscreen() w/o user gesture.

Also this page does work... 
https://output.jsbin.com/cikiqiq

ie; if you request the iframe become fullscreen. Not a field inside the other document. For cross-origin you can never reach inside a document.

It seems the with UAv2 you are using the relevant realm for the context of the user gesture sequence and before it was the current realm.

https://html.spec.whatwg.org/multipage/webappapis.html#current
Cc: foolip@chromium.org
In plain terms, does the user activation need to be:
- in the frame where the script is running (needed for this bug), or
- in the frame whose DOM contains the element (as of Fullscreen+UAv2 today).

The question came up before.

The implementation change should be easy, just want to make sure we want to switch.


What's the spec perspective?
Per the definition of https://html.spec.whatwg.org/multipage/interaction.html#triggered-by-user-activation this sort of thing should work. However, per the same definition, postMessage to a cross-origin iframe should probably also carry along with it the power to go fullscreen. Given that you're in the process of revamping user activation, what the spec *does* say isn't as relevant as what it *should* say.

Web compat allowing, the current Fullscreen+UAv2 behavior seems sensible because it's simple, but this bugs shows that there was at least content depending on the old behavior. Do we have use counters to see how many fullscreen requests are affected by the changes?

What https://jsbin.com/banozabubi/2/edit?html,js,output does is pretty reasonable, and the iframes are script-created and could just as well have been web components or plain divs, which would work.
If the repro attached a regular (non-frame) div, or attached the same-origin iframe before user interaction, it would work.

In M72, UAv2 shipped with a same-origin relaxation (temporarily making it a bit closer to UAv1), and it doesn't seem to solve this particular case.  We can't expect the unattached frame to see user activation dynamically, right?

Do you have any concerns with execution-context's user activation (mentioned in #c6)?

(We have UserActivation.AvailabilityCheck.FrameResult which covers all APIs (not just fullscreen): M71 stable gives pre-UAv2 counts, M72 beta gives post UAv2 counts.  Not much useful here.)

Ah, is the problem in how we propagate user activation to same-origin iframes, that it happens when there a click happens and isn't recomputed if an iframe is inserted? If so, that order dependence seems unfortunate, couldn't that be fixed?

I don't have any concerns with using the execution context's user activation, that'd fix the problem, as long as it's also complexity we'd be happy to add to the spec if needed.
Dynamically attached frame shouldn't automatically inherit the activation, even when we will have an iframe attribute to allow subframe visibility (Issue 728334).  A rogue site can then pull other sites to inherit the top frame activation.  (And the same-site relaxation we have is a temporary measure until we fix that bug.)

It seems calls from v8 passes on the relevant realm:
https://cs.chromium.org/chromium/src/out/Debug/gen/third_party/blink/renderer/bindings/core/v8/v8_element.cc?rcl=dfee432409f33a542d8e88efac19971342f7a37d&l=3346
Not sure if it would "align" with the (currently missing) realms in follow-up calls like this:
https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/html/media/html_video_element.cc?rcl=dd756fa4655b4c42dc3de5fe4fff7e13b1c58868&l=460

This needs some time to add all the missing ScriptContexts, then there is no guarantee it would work.

---

bars.wrk@gmail.com: Does the tweaked repro in #c5 above solve your problem?
The ScriptState is requested for the unprefixed versions of request fullscreen. (see element_fullscreen.idl) so that we can bind the promise to the script state.

So it should work. You should be able to modify the fullscreen to do something like

LocalFrame::HasTransientUserActivation(LocalDOMWindow::From(script_state)->GetFrame())


Here is another follow-up call from browser w/o any script context:
https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/exported/web_remote_frame_impl.cc?rcl=d95391c523724ace257cb74c41e1f109c425a9ae&l=321

I have to guarantee that all the internal calls following a single request have a common script context.
mustaq@chromium.org
Does the tweaked repro in #c5 above solve your problem?

No, it doesn't. I need to open the iframe's child node, not the whole iframe.

Sign in to add a comment