Remove from top layer synchronously for not connected elements#128
Conversation
foolip
left a comment
There was a problem hiding this comment.
I like this structure of a solution, having something funny happen when the fullscreen element is removed but not mucking with event timing or order in any other cases. Just some questions about the implications about the specifics.
| <a>simple fullscreen document</a>, then set <var>doc</var> to <var>topLevelDoc</var> and | ||
| <var>resize</var> to true. | ||
|
|
||
| <li><p>If <var>doc</var>'s <a>fullscreen element</a> is not connected: |
There was a problem hiding this comment.
Can you link to https://dom.spec.whatwg.org/#connected?
|
|
||
| <li><p>If <var>doc</var>'s <a>fullscreen element</a> is not connected: | ||
| <ol> | ||
| <li><p><a for=set>Append</a> (<code>fullscreenchange</code>, <var>doc</var>'s |
There was a problem hiding this comment.
Exactly when this event will end up being fired won't be entirely reliable, it could be before or after the resize even depending on how fast the fullscreen transition is, but that's acceptable I think for this weird case. Did you look into firing the event in a task or microtask and which ways that is bad?
There was a problem hiding this comment.
I tried firing it in a microtask and it seemed to work fine. However I kept it the same as all the other events. Because in the special cases (like firing fullscreenerror in Step 10.1 requesting fullscreen it still queues the event for at rAF time).
| <a>fullscreen element</a>) to <var>doc</var>'s | ||
| <a>list of pending fullscreen events</a>. | ||
|
|
||
| <li><p><a lt="unfullscreen a document">Unfullscreen <var>doc</var></a>. |
There was a problem hiding this comment.
Do funny things happen if we don't do this step?
There was a problem hiding this comment.
Yes the fullscreenelement won't change synchronously (and that is the point of this change).
There was a problem hiding this comment.
document.fullscreenElement would change synchronously, because the element would be removed from top layer right after this code runs and before the element.remove() call returns.
|
There are still some funny edge cases with this approach especially regarding nested fullscreen. For example, if the removed fullscreen element is an Also, if the document is a sub-document, and the |
Removing an iframe triggers https://html.spec.whatwg.org/multipage/window-object.html#a-browsing-context-is-discarded. If you have a handle to the document within you can still look at
Yes. I think removing the "Unfullscreen doc" step and just continuing to run is the fix for this. Because
I'd be OK with either just leaving it a bit odd or setting resize to true. Keeping track of more state doesn't sound great. |
|
Ok I've removed the Unfullscreen doc step and added back the remove top layer code from #102 to make this complete. |
|
|
||
| <li><p>If <var>doc</var>'s <a>fullscreen element</a> is not <a>connected</a>: | ||
| <ol> | ||
| <li><p><a for=set>Append</a> (<code>fullscreenchange</code>, <var>doc</var>'s |
There was a problem hiding this comment.
Hmm, I realized one little wrinkle. We should probably call "unfullscreen an element" on the fullscreen element, so that the fullscreen flags are unset. Otherwise we'll be in a weird state where https://fullscreen.spec.whatwg.org/#css-pc-fullscreen continues to match.
That will mean that the other added "remove node from document’s top layer" will only clean up things other than fullscreen. That'll just have to be OK I think.
|
I don't think this is going to work... When you have two fullscreen elements in the top layer, and you remove one of them, you would end up making the browser window still in fullscreen, but the document has exited the fullscreen state. |
|
So I still think it is easier to just fully exit fullscreen in this case. That would natively solve all the edge cases and leave a sane state just like when the user presses escape. |
|
Note that, setting resize wouldn't work either. That way, you may end up having the document still in fullscreen state, but the window has been restored to normal state. |
This is a variation on the problem of calling
For some redefinition of "fully exit fullscreen" I think that would be fine, although if we fix the above problem that seems slightly nicer to me. The main problem with #126 is poking at the state of other frames synchronously, and it can't be implemented exactly like that in Chromium. Doing #65 would resolve the problem, making "fully exit fullscreen" more async. As part of that we'd have to make sure that setting |
|
I would definitely be nice if we can fix the issue of double-calling to With the double-calling
It's not completely clear to me how #65 would make things better... Do you mean moving more stuff into the async part would make it easier to implement in Chrome? I guess I'm fine with something like, invoke fully exit fullscreen asynchronously when the element gets removed... Would that resolve your problem? |
|
@foolip ping |
@upsuper, yes, if we use "fully exit fullscreen" to handle removing the current fullscreen element, and if we want to guarantee that it really does leave the document in question with an empty top layer stack, or alternatively that we resize and empty the top layers of all documents, then "fully exist fullscreen" needs to have some flag to really guarantee that, much like what @dtapuska has pushed now, in the same vein as #65. However, reading this thread again, and looking at the "double-calling I would suggest, rather, that if we are really troubled by these interactions, that we make it explicit that only one request to enter or exit fullscreen can be in-flight at once, then we can stop worrying about these cases or multiple requests racing. Effectively, then, the fullscreen state is a global thing and the first request always wins. (Details to be worked out.) @upsuper, do you think leaving this wart for now would be acceptable? It would amount to going back to the state of this PR at f59df4d. |
|
The problem of f59df4d isn't really identical to double-calling exitFullscreen. It's something happening internally which has the same effect as double-calling at this moment. That means, adding some mechanism to make only one in-flight enter / exit change isn't going to help for that case. But I think the discussion probably does go too far and I think it's fine that we resolve on doing f59df4d for now and try to figure out how to resolve its consequences. |
|
I mean, try to figure out how to resolve its consequences later in separate issues. |
|
@upsuper, yeah, you're right, while double We're in nested fullscreen, two elements in the top layer stack. Removing the fullscreen element will not cause us to exit fullscreen, but still we'll end up in the asynchronous part of "exit fullscreen" removing the second element from the top layer. @dtapuska, new idea for a fix. In the "If doc’s fullscreen element is not connected" condition, set a fullscreenElementWasConnected variable to false. In the async part (whether resize happened or not) just do nothing if that variable is false. |
|
@dtapuska or, file an issue and let's merge this as is. Tests that could be adapted for this PR are in web-platform-tests/wpt#6302. |
event and unfullscreen the element right away. When an node is being remove synchronously remove it from the top layer.
|
@foolip wpt tests already have landed for this. I've merged the pull requests into a single change and opened an issue for the two fullscreen elements in the top layer scenario. Please merge. |
|
Thanks @dtapuska! |
If the fullscreen element is not connected anymore dispatch
event and unfullscreen the element right away.
This allows an element that is being removed to see that it isn't the
fullscreen element synchronously.
Preview | Diff