Bug 188499 - Setting a frame src after appending it to the DOM makes the frame's load event be fired twice
Summary: Setting a frame src after appending it to the DOM makes the frame's load even...
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: Frames (show other bugs)
Version: Safari 11
Hardware: Macintosh Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2018-08-12 23:53 PDT by Timothée Pillard
Modified: 2019-09-18 02:15 PDT (History)
7 users (show)

See Also:


Attachments
Test case (277 bytes, text/html)
2018-08-20 12:24 PDT, Ryosuke Niwa
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Timothée Pillard 2018-08-12 23:53:24 PDT
Hello,

I am creating this bug in follow-up to https://twitter.com/tpillard/status/1028663435524009984

The following JavaScript code will log the "Loaded" message twice.


```
const root = document.body;
const frame = document.createElement('iframe');
const href = 'https://bugs.webkit.org';

frame.onload = (evt) => console.log('Loaded', evt);
root.appendChild(frame);
frame.src = href;
```

Inverting the last two lines (setting the frame's src before appending it to the DOM) fixes the problem.

Tested and fixed with the following UA string:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1.1 Safari/605.1.15

I've originally had some customer complaints on this behavior, one includes the following UA string:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/11.1 Safari/605.1.15

While debugging, I noticed similar issues have been reported by users on StackOverflow over the years:
https://stackoverflow.com/questions/10781880/dynamically-created-iframe-triggers-onload-event-twice
https://stackoverflow.com/questions/22722046/onload-bug-in-google-chrome-safari
https://stackoverflow.com/questions/25066052/window-onload-called-twice-inside-an-iframe

I could not reproduce this behavior on other browsers I had at my disposal.

Thank you for any response,

--
Tim
Comment 1 Timothée Pillard 2018-08-13 00:05:52 PDT
Quick note:

Setting the `load` event handler on the iframe after appending it to the DOM fixes the problem as well.
Comment 2 Ryosuke Niwa 2018-08-20 12:24:29 PDT
Created attachment 347527 [details]
Test case
Comment 3 Ryosuke Niwa 2018-08-20 12:28:02 PDT
On interesting, When an iframe is inserted into a document, it loads about:blank which in turn fires a load event. What makes WebKit and Blink's behavior different from the spec is that we synchronously fire a load event in this case.

See https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element

When an iframe element is inserted into a document that has a browsing context, the user agent must create a new browsing context, set the element's nested browsing context to the newly-created browsing context, and then process the iframe attributes for the "first time".

https://html.spec.whatwg.org/multipage/iframe-embed-object.html#process-the-iframe-attributes

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.
Comment 4 Ryosuke Niwa 2018-08-20 12:28:51 PDT
My guess is that making the event load fire async won't be a Web compatible change at this point but we can try.
Comment 5 Radar WebKit Bug Importer 2018-11-12 16:27:33 PST
<rdar://problem/46008888>