Skip to content
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

Unclear "iframe load event steps" for initial load of about:blank in an iframe #490

Closed
jdm opened this issue Jan 9, 2016 · 15 comments
Closed
Labels
compat Standard is not web compatible or proprietary feature needs standardizing topic: navigation

Comments

@jdm
Copy link
Member

jdm commented Jan 9, 2016

The spec says that an iframe with no src attribute on first time through process the iframe attributes will queue a task to run iframe load event steps, which dispatches the load event at the iframe element.

For the following test hosted on joshmatthews.net:

<script>var sync_event1 = true;</script>
<iframe id="first" onload="console.log('first - onload from inline: ' + document.querySelector('#first').contentWindow.location + ' ' + sync_event1)"></iframe>
<script>
var iframe1 = document.querySelector('#first');
iframe1.addEventListener('load', function() {
  console.log('first - onload during script execution: ' + iframe1.contentWindow.location + ' ' + sync_event1);
});
sync_event1 = false;
</script>

<script>var sync_event2 = true;</script>
<iframe id="second" onload="console.log('second - onload from inline: ' + document.querySelector('#second').contentWindow.location + ' ' + sync_event2)"></iframe>
<script>
var iframe2 = document.querySelector('#second');
iframe2.addEventListener('load', function() {
  console.log('second - onload during script execution: ' + iframe2.contentWindow.location + ' ' + sync_event2);
});
iframe2.src = "http://joshmatthews.net";
sync_event2 = false;
</script>

I get this output from browsers -
Firefox, Edge:

first - onload from inline: about:blank false
first - onload during script execution: about:blank false
second - onload from inline: http://www.joshmatthews.net/ false
second - onload during script execution: http://www.joshmatthews.net/ false

Chrome, Safari:

first - onload from inline: about:blank true
second - onload from inline: about:blank true
second - onload from inline: http://www.joshmatthews.net/ false
second - onload during script execution: http://www.joshmatthews.net/ false

Specifically, Firefox appears to skip the initial load event for about:blank if the iframe's src is changed before the queued task executes, while Chrome's load event for the initial about:blank load is dispatched synchronously.

What is the intended behaviour here?

@zcorpan
Copy link
Member

zcorpan commented Jan 11, 2016

cc @hsivonen

@jdm
Copy link
Member Author

jdm commented Jan 11, 2016

I'd be curious to find out what Edge does, if someone has access.

@domenic
Copy link
Member

domenic commented Jan 11, 2016

If there's a URL for this test I can run it in Edge. I don't see one in the OP.

@jdm
Copy link
Member Author

jdm commented Jan 11, 2016

@domenic
Copy link
Member

domenic commented Jan 11, 2016

first - onload from inline: about:blank false
first - onload during script execution: about:blank false
second - onload from inline: http://www.joshmatthews.net/ false
second - onload during script execution: http://www.joshmatthews.net/ false

@jdm
Copy link
Member Author

jdm commented Jan 11, 2016

Nice, 50/50 behaviour split between browsers.

@zcorpan
Copy link
Member

zcorpan commented Jan 21, 2016

Previous research on about:blank that might be worth re-testing again:
https://hsivonen.fi/about-blank/

@zcorpan zcorpan added the compat Standard is not web compatible or proprietary feature needs standardizing label Jan 21, 2016
@hsivonen
Copy link
Member

hsivonen commented Feb 6, 2016

My take on what I think is worthwhile pursuing hasn't changed since my previous research.

I think the following are trouble and should be avoided:

  • Making a generally async event (load) fire synchronously in some case. This would force all events that have to fire before load to fire synchronously, too, and makes it substantially harder to reason about all these. That is, I think the WebKit/Blink behavior is bad.
  • Replacing one about:blank with another. This is bad, because if the page tries to do stuff with the first about:blank, that work gets blown away when the second about:blank arrives. That is, I think Gecko's behavior is bad.
  • Making things depend on the cache or otherwise on race conditions. That is, I think the old IE behavior is bad.

If I had the time, I'd pursue generating the initial about:blank synchronously and queuing a task to fire events on it. When the task is ready to run, I'd check if the browsing context has started navigating away from the about:blank document and refrain from firing the events if so. (This is remarkably hard to do in Gecko, which is why I didn't get this done years ago.)

I don't know if this is Web-compatible, but it seems like the least horrible synthesis of the good parts of the behaviors out there.

@jdm
Copy link
Member Author

jdm commented Jan 5, 2017

Servo is intending to implement the "least horrible synthesis" behaviour described by @hsivonen in a basic attempt to determine its compatibility with the web.

@annevk
Copy link
Member

annevk commented Apr 25, 2017

What are all the events that have to fire before load in the first bullet point?

@cdumez
Copy link

cdumez commented Aug 10, 2017

FYI, this behavior difference between Firefox/Gecko and Safari/Chrome has been causing unrelated Web-Platform-Tests to fail in some browsers in at least 2 instances I investigated (the most recent one being the Beacon tests contributed by Microsoft).

The test's utility script was:

  1. Creating an iframe
  2. Setting an onload event hander on this iframe to do some testing
  3. Appending the iframe to the document
  4. setting the iframe's src to the test URL

In Safari/Chrome, the onload event handler was called synchronously for the about:blank load, causing onload event handler to get called and checks to be done for the "wrong" document. Then the load event handler was called a second time (unexpectedly for the developer of the script) for the actual test load.

It'd be really good to align browsers here one way or another.

@wanderview
Copy link
Member

AFAIK current browser initial about:blank handling is only compatible for this case:

<iframe src="foo.html" id="frame">
<script>
document.getElementById('frame').contentWindow.foo = "foo";
</script>

Declarative iframe that is synchronously mutated.

@asajeffrey
Copy link

Just to add some more confusion, the current wording for "process the iframe attributes" (https://html.spec.whatwg.org/multipage/iframe-embed-object.html#process-the-iframe-attributes) says:

Otherwise, if the element has no src attribute specified, and the user agent is processing the iframe's attributes for the "first time"

  • Queue a task to run the iframe load event steps.
  • The task source for this task is the DOM manipulation task source.

In particular, this logic doesn't apply when src="about:blank", which results in two documents being created. It also doesn't apply when src="about:blank#foo", which means step 5 of "navigate" (https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate) applies:

If this is not a reload-triggered navigation, resource is a request, resource's url equals browsingContext's active document's URL with exclude fragments flag set, and resource's url's fragment is non-null, then navigate to that fragment, with replacement enabled if this was invoked with replacement enabled, and abort these steps.

AFAICT this causes the browsing context to traverse to the existing about:blank document, with the result that the load event is never fired. I don't think this is the intended semantics!

@asajeffrey
Copy link

One thing that's odd about the current spec is that the semantics for an unset src are different from src="" or src="about:blank". We could replace the text with:

If the srcdoc attribute is specified [no change]

Otherwise

  1. If the element has no src attribute specified, or its value is the empty string, let url be the URL "about:blank".

    Otherwise, parse the value of the src attribute, relative to the element's node document.

    If that is not successful, then let url be the URL "about:blank". Otherwise, let url be the resulting URL record.

  2. If url is "about:blank" then:

    Queue a task to run the iframe load event steps.
    The task source for this task is the DOM manipulation task source.

    Abort these steps.

  3. If there exists an ancestor browsing context [no change]

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 10, 2020
The handling of iframe load events is finicky as indicated in the open
WHATWG issue:

whatwg/html#490

This patch switches the wait mechanism to one that is well behaved
across browsers.  The new process arms the listener before inserting the
iframe into the document.

Bug: 1059963
Change-Id: I372d4fdae3b270699aedf2c5a4de4429e62f42a5
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Mar 10, 2020
The handling of iframe load events is finicky as indicated in the open
WHATWG issue:

whatwg/html#490

This patch switches the wait mechanism to one that is well behaved
across browsers.  The new process arms the listener before inserting the
iframe into the document.

Bug: 1059963
Change-Id: I372d4fdae3b270699aedf2c5a4de4429e62f42a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096782
Reviewed-by: Yi Gu <yigu@chromium.org>
Commit-Queue: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748853}
blueboxd pushed a commit to blueboxd/chromium-legacy that referenced this issue Mar 10, 2020
The handling of iframe load events is finicky as indicated in the open
WHATWG issue:

whatwg/html#490

This patch switches the wait mechanism to one that is well behaved
across browsers.  The new process arms the listener before inserting the
iframe into the document.

Bug: 1059963
Change-Id: I372d4fdae3b270699aedf2c5a4de4429e62f42a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096782
Reviewed-by: Yi Gu <yigu@chromium.org>
Commit-Queue: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748853}
Hexcles pushed a commit to web-platform-tests/wpt that referenced this issue Mar 11, 2020
The handling of iframe load events is finicky as indicated in the open
WHATWG issue:

whatwg/html#490

This patch switches the wait mechanism to one that is well behaved
across browsers.  The new process arms the listener before inserting the
iframe into the document.

Bug: 1059963
Change-Id: I372d4fdae3b270699aedf2c5a4de4429e62f42a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096782
Reviewed-by: Yi Gu <yigu@chromium.org>
Commit-Queue: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748853}
xeonchen pushed a commit to xeonchen/gecko that referenced this issue Mar 13, 2020
…placment.html, a=testonly

Automatic update from web-platform-tests
Fix timeout in update-and-send-events-replacment.html

The handling of iframe load events is finicky as indicated in the open
WHATWG issue:

whatwg/html#490

This patch switches the wait mechanism to one that is well behaved
across browsers.  The new process arms the listener before inserting the
iframe into the document.

Bug: 1059963
Change-Id: I372d4fdae3b270699aedf2c5a4de4429e62f42a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096782
Reviewed-by: Yi Gu <yigu@chromium.org>
Commit-Queue: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748853}

--

wpt-commits: ee5cfa46292bdcdd576e698503f4a4a9ffa977c0
wpt-pr: 22160
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Mar 13, 2020
…placment.html, a=testonly

Automatic update from web-platform-tests
Fix timeout in update-and-send-events-replacment.html

The handling of iframe load events is finicky as indicated in the open
WHATWG issue:

whatwg/html#490

This patch switches the wait mechanism to one that is well behaved
across browsers.  The new process arms the listener before inserting the
iframe into the document.

Bug: 1059963
Change-Id: I372d4fdae3b270699aedf2c5a4de4429e62f42a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096782
Reviewed-by: Yi Gu <yigu@chromium.org>
Commit-Queue: Kevin Ellis <kevers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748853}

--

wpt-commits: ee5cfa46292bdcdd576e698503f4a4a9ffa977c0
wpt-pr: 22160
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this issue Mar 16, 2020
…placment.html, a=testonly

Automatic update from web-platform-tests
Fix timeout in update-and-send-events-replacment.html

The handling of iframe load events is finicky as indicated in the open
WHATWG issue:

whatwg/html#490

This patch switches the wait mechanism to one that is well behaved
across browsers.  The new process arms the listener before inserting the
iframe into the document.

Bug: 1059963
Change-Id: I372d4fdae3b270699aedf2c5a4de4429e62f42a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096782
Reviewed-by: Yi Gu <yiguchromium.org>
Commit-Queue: Kevin Ellis <keverschromium.org>
Cr-Commit-Position: refs/heads/master{#748853}

--

wpt-commits: ee5cfa46292bdcdd576e698503f4a4a9ffa977c0
wpt-pr: 22160

UltraBlame original commit: 1f66d281b8ce3b572f364f86102f3c132ec64c8d
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this issue Mar 16, 2020
…placment.html, a=testonly

Automatic update from web-platform-tests
Fix timeout in update-and-send-events-replacment.html

The handling of iframe load events is finicky as indicated in the open
WHATWG issue:

whatwg/html#490

This patch switches the wait mechanism to one that is well behaved
across browsers.  The new process arms the listener before inserting the
iframe into the document.

Bug: 1059963
Change-Id: I372d4fdae3b270699aedf2c5a4de4429e62f42a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096782
Reviewed-by: Yi Gu <yiguchromium.org>
Commit-Queue: Kevin Ellis <keverschromium.org>
Cr-Commit-Position: refs/heads/master{#748853}

--

wpt-commits: ee5cfa46292bdcdd576e698503f4a4a9ffa977c0
wpt-pr: 22160

UltraBlame original commit: 1f66d281b8ce3b572f364f86102f3c132ec64c8d
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this issue Mar 16, 2020
…placment.html, a=testonly

Automatic update from web-platform-tests
Fix timeout in update-and-send-events-replacment.html

The handling of iframe load events is finicky as indicated in the open
WHATWG issue:

whatwg/html#490

This patch switches the wait mechanism to one that is well behaved
across browsers.  The new process arms the listener before inserting the
iframe into the document.

Bug: 1059963
Change-Id: I372d4fdae3b270699aedf2c5a4de4429e62f42a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2096782
Reviewed-by: Yi Gu <yiguchromium.org>
Commit-Queue: Kevin Ellis <keverschromium.org>
Cr-Commit-Position: refs/heads/master{#748853}

--

wpt-commits: ee5cfa46292bdcdd576e698503f4a4a9ffa977c0
wpt-pr: 22160

UltraBlame original commit: 1f66d281b8ce3b572f364f86102f3c132ec64c8d
@domenic
Copy link
Member

domenic commented Feb 6, 2022

I believe we fixed this in #6869.

@domenic domenic closed this as completed Feb 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compat Standard is not web compatible or proprietary feature needs standardizing topic: navigation
Development

No branches or pull requests

8 participants