-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
load event handling for iframes with no src may not be web compatible #4965
Comments
Totally forgot to cc people: @annevk @foolip @domenic @TimothyGu |
I haven't verified in debug build, but I suspect https://cs.chromium.org/chromium/src/third_party/blink/renderer/core/frame/local_dom_window.cc?l=1383&rcl=ef5184e1d38e632e1b12588586c473fc0e02237b is the place in Chromium that fires that sync load event, and suspect that it's because of the initial "about:blank" page being loaded synchronously when inserting the iframe. The preceding comment is suspicious:
It's unsurprising that this code predates any spec on this, but now the spec is pretty clear in "When an iframe element element is inserted into a document whose browsing context is non-null, the user agent must run these steps" that the browsing context is created sync but the event is fired in a queued task. @bzbarsky it sounds like in addition to the synchronicity of the event dispatch you also think some spec change is needed around |
Getting further through my inbox, I suspect https://bugs.chromium.org/p/chromium/issues/detail?id=878491#c4 may be related to this, although that also involves |
I'm not sure I understand either. There's a problem with the initial |
The original snippet of code that triggered my investigation into this was https://bugzilla.mozilla.org/show_bug.cgi?id=1575799#c16 and does indeed involve load event bits for I suggested a modification to the page in question in https://bugzilla.mozilla.org/show_bug.cgi?id=1575799#c18 and then realized that that modification would stop working in Firefox once Firefox started following the spec for initial about:blank creation better. The actual in-the-wild code involved is more like https://bugzilla.mozilla.org/show_bug.cgi?id=1575799#c21 and they are planning to change it to use DOM operations instead of
No, I don't think so...
None of them fire a load event for downloads, and the specification does not either. The "spec-compliant way" works in every browser and would continue working if they all aligned with the spec in all the relevant ways; it's just complicated and non-intuitive. |
If part of the problem is that making the load event fire async will sometimes fire it where it's currently assumed to not fire, is there any set of conditions that the queued task could check and decide to not fire the event? Media elements do something like this to avoid firing events originating from one invocation of the media load algorithm after it has restarted for another resource. Doing this for browsing contexts is probably more complicated, but would it fix any of the problem? |
Firing If you're okay with experimenting with it in Firefox I wouldn't mind. |
Well, I don't quite understand the semantics Chrome and Safari (e.g. is this limited to no-src cases, or also including src = about:blank, or something else where the browser knows synchronously that it's done, e.g. a srcdoc with no subresources). That makes it a bit hard to experiment... |
I see, so testing |
@bzbarsky web-platform-tests/wpt#19693 has some tests, further suggestions welcome. They're currently aligned with Chrome/Safari in that no src and src=about:blank fire load during append (did not test relative to mutation events) and everything else fires load "asynchronously". |
How do things behave when there are multiple iframe elements being inserted, whether via a single append operation on an ancestor, via document fragment insertion, via innerHTML, etc? What does ordering for the load events look like and how does it order with the rest of the insertion process? |
Possibly, yes. In particular, whether a new navigation has started. We could also track the task that's queued and "cancel" it when a navigation starts. That said, if we can spec the "just fire it sync on insertion" behavior, great. |
I added a simple test for multiple Given that there's precedent with At this point I'd be happy to help someone make these changes, but I'm probably not gonna do it all myself until the priority rises. |
@foolip It looks like a bunch of WPTs were written assuming the non-spec Chrome behavior here, which made them completely break in Firefox. See https://bugzilla.mozilla.org/show_bug.cgi?id=1598674 |
Thanks for pointing that out, @bzbarsky! @stephenmcgruer can you dig into what happened here, how were the tests added to wpt and what tooling would we need in place to notice this sort of problem before it's merged? |
I realized that in Chrome it's possible for an web-platform-tests/wpt#19693 has more tests/assertions for those now. It's also a little weird that sometimes a nested browsing context is created with an event and sometimes without. |
@foolip Apologies for the delay. I'm not immediately clear on reading this thread why we would have expected these tests to be caught? Current tooling for Chromium-exported tests doesn't require a test to pass on any given browser, it just requires the results to be consistent. We do have the (slightly strangely named) Export Notifier project which will hopefully (re)launch Q1. This would let Chromium CL authors know that a test is newly failing in some browser (which should include new tests, I imagine), but we would still not want to automatically block those cases. (Many legitimate tests fail on some browser). Overall, having invalid tests sneak in is the price of a shared test suite, and I consider it worth the effort to find and fix such tests (since they often expose interop issues between browsers!). Hopefully that effort is spread reasonably evenly over browsers (I know animations team have had to squash some tests that were invalid and failing in Chrome), but if it's not then we should consider what else we could do to resolve that. |
Note that there is also a test at https://github.com/web-platform-tests/wpt/blob/master/html/semantics/embedded-content/the-iframe-element/iframe-nosrc.html that tests this behavior and has a currently-spec-unsupported assertion about |
@stephenmcgruer the title of https://bugzilla.mozilla.org/show_bug.cgi?id=1598674 says "Hundreds of timeouts" so maybe just summarizing the results (e.g. "Firefox: 103 new tests, 103 timeout") would bring attention to it where that's surprising. I'm struggling to find a single wpt PR that added the tests, web-platform-tests/wpt#4292 is the oldest but web-platform-tests/wpt#4292 (comment) actually looks good. Huge numbers of timeouts will make the tests run slower and can often be turned into a fast fail, but it's not a case that I think we can require any action for when the tests are new as here. Regressing to timeout is a different matter and probably worth flagging. |
Consider this testcase:
(where you can use any URL that has
Content-Disposition: attachment
for the src). Per spec what should happen here is this:appendChild
call https://html.spec.whatwg.org/multipage/iframe-embed-object.html#process-the-iframe-attributes runs and does the "Queue a task to run the iframe load event steps." bit.What happens in browsers instead is:
appendChild
call, as far as I can tell, so that the listener is added after the event has fired and hence the frame is never removed and "error" is never logged. The navigation does not fire a load event, because it hasContent-Disposition: attachment
and hence is not loaded in the iframe.about:blank
load which would fire a load event async when it completes. The start of a new navigation cancels that load, so there is no load event fired at all. The frame is never removed and "error" is never logged. The navigation to the PDF does not fire a load event, because it hasContent-Disposition: attachment
and hence is not loaded in the iframe.I don't have a good proposal for what the spec should say here... Currently the spec-compliant way for a page to do what the above script is trying to do is something like:
which is rather annoying from an authoring perspective and hard for authors to think of.
That said, I expect that parser-triggered insertions likely do need the async load event thing in some way, though this testcase:
shows "sync-loaded" in Chrome and Safari (and "async-loaded" in Firefox; per spec behavior could be either way depending on whether there's a packet boundary between the
<iframe>
and the<script>
, afaict).The text was updated successfully, but these errors were encountered: