WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
40919
beforeload event not sent to document for <img src> added to document using .innerHTML (affects images.google.com)
https://bugs.webkit.org/show_bug.cgi?id=40919
Summary
beforeload event not sent to document for <img src> added to document using ....
Adam Roben (:aroben)
Reported
2010-06-21 08:19:18 PDT
Created
attachment 59252
[details]
test case To reproduce: 1. Load attached test case The document's beforeload event listener never gets called for the image. This is indicated by the URL of the image not being printed into the page.
Attachments
test case
(581 bytes, text/html)
2010-06-21 08:19 PDT
,
Adam Roben (:aroben)
no flags
Details
Patch
(1.71 KB, patch)
2010-06-23 11:20 PDT
,
Dave Hyatt
no flags
Details
Formatted Diff
Diff
Patch
(4.90 KB, patch)
2010-06-30 16:17 PDT
,
Andy Estes
no flags
Details
Formatted Diff
Diff
Patch
(3.94 KB, patch)
2010-06-30 23:59 PDT
,
Andy Estes
darin
: review+
Details
Formatted Diff
Diff
Show Obsolete
(2)
View All
Add attachment
proposed patch, testcase, etc.
Adam Roben (:aroben)
Comment 1
2010-06-21 08:19:58 PDT
images.google.com uses this technique, meaning that beforeload doesn't work to block many images on images.google.com.
Adam Roben (:aroben)
Comment 2
2010-06-21 08:20:56 PDT
The problem is that the <img> element's inDocument() function returns false when the beforeload event is being dispatched. This causes Node::eventAncestors to return 0 ancestors, so the event never gets up to the document.
Adam Roben (:aroben)
Comment 3
2010-06-21 08:21:20 PDT
<
rdar://problem/8113003
>
Adam Roben (:aroben)
Comment 4
2010-06-21 08:28:47 PDT
The beforeload event is sent via a call to ImageLoader::dispatchPendingBeforeLoadEvents() at the end of HTMLDocumentParser::write(). Apparently this is before the <img> has actually been added to the document.
Dave Hyatt
Comment 5
2010-06-21 12:40:59 PDT
Technically this is correct behavior. We need to figure out what we're going to do with the loads that happen on DOM elements that aren't in the document yet. I suspect we may need to do something funky like allow bubbling/capturing from the root of the unattached tree up to the document. No other event behaves like this, but I can't think of a better way. All loads need to be easily observable from a single listener, even ones that occur on elements that aren't in the document yet.
Adam Roben (:aroben)
Comment 6
2010-06-21 12:59:06 PDT
(In reply to
comment #5
)
> Technically this is correct behavior. We need to figure out what we're going to do with the loads that happen on DOM elements that aren't in the document yet. I suspect we may need to do something funky like allow bubbling/capturing from the root of the unattached tree up to the document.
Another option is to delay the loading until the element is inserted into the document. But I assume that would cause compatibility problems.
Adam Roben (:aroben)
Comment 7
2010-06-22 12:06:30 PDT
The same bug does not affect the following code: var img = new Image(); img.src = foo; document.body.appendChild(img); Setting @src schedules the beforeload event to be sent after a timer fires (via ImageEventSender::dispatchEventSoon). By the time the timer fires, the image is already in the document.
Dave Hyatt
Comment 8
2010-06-23 11:20:07 PDT
Created
attachment 59536
[details]
Patch This patch does two things: (1) It makes beforeload flow up to the document even for nodes that aren't reachable from the document element. This lets the document observe orphaned image loads. (2) It doesn't bother doing the synchronous beforeload dispatch after parsing document fragments. This ensures that fragments that then get assigned into the document are in the document at the time beforeload fires.
Andy Estes
Comment 9
2010-06-30 16:17:29 PDT
Created
attachment 60166
[details]
Patch
Andy Estes
Comment 10
2010-06-30 16:18:49 PDT
(In reply to
comment #9
)
> Created an attachment (id=60166) [details] > Patch
This is hyatt's patch with a layout test.
Darin Adler
Comment 11
2010-06-30 17:06:21 PDT
Comment on
attachment 60166
[details]
Patch
> + // beforeload is always observable by the document, even for elements that are not contained in > + // the document. > + if (!inDocument() && event->type() == eventNames().beforeloadEvent) > + ancestors.append(document());
Is this really the design we want for beforeload? It's very strange! Why would the document need to get the event for a node that's not in it? What’s the reason for this event to be different from all others in this respect? (I would say "The beforeload event" so you can capitalize the comment sentence.)
Andy Estes
Comment 12
2010-06-30 23:20:29 PDT
(In reply to
comment #11
)
> (From update of
attachment 60166
[details]
) > > + // beforeload is always observable by the document, even for elements that are not contained in > > + // the document. > > + if (!inDocument() && event->type() == eventNames().beforeloadEvent) > > + ancestors.append(document()); > > Is this really the design we want for beforeload? It's very strange! Why would the document need to get the event for a node that's not in it? What’s the reason for this event to be different from all others in this respect?
I think the problem is that a clever page could bypass document-level beforeload handlers by doing something like this: var img = new Image(); img.src = ...; img.onload = function(event) { targetNode.appendChild(img); } For injected scripts to be able to cancel loads, it sounds like beforeload events from fragments will need to be propagated to somewhere in the DOM. Sam mentioned in person that perhaps parenting fragments to the window would make more sense. Since this change isn't strictly necessary to fix the .innerHTML bug, I think I should file a new bug to track this issue and resubmit the patch with the Node.cpp change removed.
Andy Estes
Comment 13
2010-06-30 23:59:37 PDT
Created
attachment 60206
[details]
Patch
Andy Estes
Comment 14
2010-07-01 15:17:20 PDT
Committed
r62302
: <
http://trac.webkit.org/changeset/62302
>
Andy Estes
Comment 15
2010-07-06 19:29:45 PDT
(In reply to
comment #12
)
> Since this change isn't strictly necessary to fix the .innerHTML bug, I think I should file a new bug to track this issue and resubmit the patch with the Node.cpp change removed.
I filed
https://bugs.webkit.org/show_bug.cgi?id=41730
to track this issue.
Tony Gentilcore
Comment 16
2010-08-05 13:48:49 PDT
FYI, this caused crashes: if (m_noMoreData && !m_inWrite && !state.loadingExtScript() && !m_executingScript && !m_timer.isActive()) end(); // this actually causes us to be deleted // After parsing, go ahead and dispatch image beforeload events, but only if we're doing // document parsing. For document fragments we wait, since they'll likely end up in the document by the time // the beforeload events fire. if (!m_fragment) ImageLoader::dispatchPendingBeforeLoadEvents(); Notice end() might cause this to be deleted and m_fragment is a member. This is a blocker on the Chrome release branch so I'm working on a test and fix.
Tony Gentilcore
Comment 17
2010-08-05 14:54:28 PDT
> This is a blocker on the Chrome release branch so I'm working on a test and fix.
Scratch that. I've just rolled this out on the branch.
Andy Estes
Comment 18
2010-08-05 15:04:51 PDT
(In reply to
comment #17
)
> > This is a blocker on the Chrome release branch so I'm working on a test and fix. > > Scratch that. I've just rolled this out on the branch.
Tony, can you attach a test case that reproduces the crash? This is obviously an issue we'd like to fix in ToT.
Tony Gentilcore
Comment 19
2010-08-05 15:35:09 PDT
(In reply to
comment #18
)
> (In reply to
comment #17
) > > > This is a blocker on the Chrome release branch so I'm working on a test and fix. > > > > Scratch that. I've just rolled this out on the branch. > > Tony, can you attach a test case that reproduces the crash? This is obviously an issue we'd like to fix in ToT.
I don't have a reduced case. The trick is to reach the branch that triggers end(). FWIW, this reproduces pretty reliably (but not 100%) for me with
http://www.mashable.com/
I wasn't planning on spending time reducing since this is in the legacy parser. We just switched back to the legacy parser for Chrome 6 because of what's left in
https://bugs.webkit.org/show_bug.cgi?id=41115
.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug