-
Notifications
You must be signed in to change notification settings - Fork 42
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
Remove nodes from top layer as part of the removing steps #102
Conversation
@upsuper, can you review? This matches the order in which things happen in Chromium. |
So the last step currently only covers modal Also it seems to me that the HTML spec already says
Would one of them be a duplicate? BTW, the sentence in the HTML spec would raise interesting interaction between |
Good catch, we should remove that bit from HTML. Since it currently doesn't mutate the DOM or fire any events, I think we should stick with that, but I can write tests asserting that it is so as part of web-platform-tests/wpt#6302. Can you elaborate on how the (lack of) hierarchy restrictions pose a problem here? |
(It took me quite a while to recall what I was thinking when I made that comment. Although I'm not completely sure, but I think it is what I was considering:) The problem is unrelated to hierarchy restrictions. It is more about that whether a I'm not sure why you don't want to merge #91 (probably because of lack of test at the moment?), but if that's troublesome to merge, probably we can move the single restriction on |
Right, not having to worry about such interaction would be good. In #91 (comment) I added use counters to answer this question, and we have numbers from the stable channel now: In other words, it essentially never happens, and I would happily add that restriction to Blink. If we do that, I think that simplified this issue somewhat. |
This way, interactions between the algorithms for fullscreen and dialog are simplified. Example concern: #102 (comment) This also makes it easier to reinstate hierarchy restrictions: #91 Tests: https://chromium-review.googlesource.com/c/chromium/src/+/684435
This way, interactions between the algorithms for fullscreen and dialog are simplified. Example concern: #102 (comment) This also makes it easier to reinstate hierarchy restrictions: #91 Tests: https://chromium-review.googlesource.com/c/chromium/src/+/684435
This way, interactions between the algorithms for fullscreen and dialog are simplified. Example concern: #102 (comment) This also makes it easier to reinstate hierarchy restrictions: #91 Tests: https://chromium-review.googlesource.com/c/chromium/src/+/684435
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is fine as far as we remove the duplicate sentence from HTML spec.
Thanks @upsuper! |
Also test that dialog.remove() doesn't do any of the things one might reasonably expect, to match the current spec and what's implemented. Tests for: whatwg/fullscreen#102 whatwg/html#3064
Also test that dialog.remove() doesn't do any of the things one might reasonably expect, to match the current spec and what's implemented. Tests for: whatwg/fullscreen#102 whatwg/html#3064 Drive-by: t.add_cleanup(() => document.exitFullscreen())
9ce7eb0
to
760bd7e
Compare
760bd7e
to
d59cbb4
Compare
<li><p>If <var>doc</var>'s <a>fullscreen element</a> is null, then resolve <var>promise</var> with | ||
undefined and terminate these steps. | ||
<li> | ||
<p>If <var>pendingDoc</var>'s <a>fullscreen element</a> is not <var>pending</var>: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@annevk @upsuper, I made another change today in order to unblock this and the tests. Here, if the fullscreen element has changed, just append a pending event for what the fullscreen element was. This will fix the missing event case, but will also mean duplicate events if document.exitFullscreen()
is called twice or more. It would be possible to avoid this by also having a "fullscreen element removed flag" for "exit fullscreen" that's only set in the removal case, but I'm not sure that's necessary complexity. Things are already pretty weird with multiple enter and exits, and I think that maybe just doing nothing for those cases might be a better fix. Not in this PR, I'm hoping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have implemented these changes and checked what it does to the tests. /fullscreen/api/document-exit-fullscreen-twice-manual.html and /fullscreen/model/remove-last-manual.html will need some tweaking, but it looks like the idea works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another way around is to change list of pending fullscreen events
to just pending fullscreen event
, which is either null or (string, element)
pair, and update, rather than append when new event comes.
I may be missing something, but I don't recall why we introduce the list rather than a single slot. Maybe we want to handle fullscreenerror
? I guess fullscreenerror
can just be dispatched asynchronously. I see no reason it is necessary to be dispatched in run fullscreen steps
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's from #92. The list is needed in case multiple things happen between two animation frames, in situation like #63 or if we're in nested fullscreen and call document.exitFullscreen()
twice. We could collapse those into a single fullscreenchange
event, but that seems a bit odd. We could handle fullscreenerror
differently, you're right, but that's not really part of the problem as long as the rest remain.
So I think that to do this differently, #63 and #119 would have to be resolved in the direction of significant simplification.
Also test that dialog.remove() doesn't do any of the things one might reasonably expect, to match the current spec and what's implemented. Tests for: whatwg/fullscreen#102 whatwg/html#3064 Drive-by: t.add_cleanup(() => document.exitFullscreen())
|
||
<li><p>Let <var>exitDocs</var> be the result of | ||
<a lt="collect documents to unfullscreen">collecting documents to unfullscreen</a> given | ||
<var>doc</var>. | ||
<var>pendingDoc</var>. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC, this will assert inside collect documents to unfullscreen
because it expects pendingDoc
's fullscreen element to be not null, but it may be null when you are removing the fullscreen element from a simple fullscreen document. You probably want to also change that function to not assert in that case...
This also raises a problem that you may be going to add a (pendingDoc, null)
into the list of pending fullscreen events
in the following loop. And if the original document is not a simple fullscreen document, you are going to unfullscreen one further level.
One way to solve all these might be to change collect documents to unfullscreen
to collect documents and elements to unfullscreen
and build an array of (document, element)
, and then you can pass (pendingDoc, pending)
into the function, and remove the assertion. With that change, you don't need the separate insertion above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because pending
is never null, any case where the fullscreen element is now null (or indeed different at all) is taken care of, and we "terminate these steps" above. The assert in "collect documents to unfullscreen" is in place in my changes to match these changes and isn't hit for this reason.
But why does it make sense to only fire an event for this document and not the ancestors in this case, one wonders? Because if resize
is true, then pendingDoc
is the top-level document. And if we hit the above condition for that case, then it was an iframe that was removed and all the descendant documents have already been disposed of. At least I've been unable to come up with a case that's going to be broken, although that doesn't mean there isn't one. #63 is a potential concern, but there I really think the fix should be that we make those kinds of combinations/races impossible, since I don't think there will always be a "reasonable" thing to do when we end up in those situations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm... It seems I somehow overlooked "terminate these steps" there...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we "terminate these steps" when pending
is different than pendingDoc
's fullscreen element, there would be a weird case:
If we have top-level document A being: <div id="outer"><iframe></iframe></div>
, then the iframe
contains document B. Now we fullscreen #outer
in A, then fullscreen document.body
in B. When we remove document.body
from B, it seems that the iframe
in A would keep being in fullscreen.
However, if we don't fullscreen #outer
at the beginning, removing document.body
from B would trigger a full unfullscreen, and the event would be solely dispatched to A rather than B.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so this is a case where A will have #outer
and iframe
in top layer with the "fullscreen flag" set, but iframe
doesn't have the the "iframe fullscreen flag" set. And B has just its document.body
in top layer as the fullscreen element. Calling document.exitFullscreen()
in B would normally leave us with A having just #outer
as the fullscreen element, i.e. we popped the iframe
from top layer. But, with what I've proposed, we'd "terminate these steps" and document A would be left with two elements in top layer.
One possible stance is "oh well, removing the fullscreen element does weird things, just like exiting fullscreen twice can". But I'll take a look at your suggestions to tweak "collect documents to unfullscreen", to see if I can make that behave exactly as if the fullscreen element hadn't changed yet, kind of like how it was when the fullscreen element stack was separate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put the proposal here: #126
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, okay, that makes sense. So we should probably move the appending after step 5 or 6 in my proposal, so that fullscreen events would come after resize event.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to add a step in the exit fullscreen that indicated if the fullscreen element is not connected then Unfullscreen it immediately (say after step 4)?
@dtapuska, was that assuming some of the changes in this PR, i.e., that within the "removing steps", we first call "exit fullscreen" (or "fully exit fullscreen") and then remove the element from top layer before any of the async bits, including resizing, happen? I'm not sure which step 4 you mean, but everything needs to be done or decided in the synchronous bits, as document.fullscreenElement
will change by the end of the "removing steps".
(Probably this was clear, just restating to make sure.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do see some difference in how the document cleanup steps run between Firefox and Chrome. When an iframe navigates to a new location Firefox exits fullscreen (matching what would the new fully exit fullscreen text) but Chrome doesn't.
@dtapuska I wonder if this comes down to the difference between "fully exit fullscreen" exiting fully for just the document it was invoked with, or the top-level document? The spec now has the first model, and #126 changes it to the second.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edge seems to match this as well
@dtapuska in other words, when navigating any document which is in fullscreen, Edge fully exits fullscreen?
the unfullscreen doc call as it isn't needed.
the unfullscreen doc call as it isn't needed.
Superseded by #128 |
Tests: web-platform-tests/wpt#6302
Preview | Diff