Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Unified Diff: Source/WebCore/loader/FrameLoader.cpp

Issue 7727007: Merge 93521 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/835/
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « LayoutTests/fast/loader/resources/document-destruction-within-unload-iframe.html ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/WebCore/loader/FrameLoader.cpp
===================================================================
--- Source/WebCore/loader/FrameLoader.cpp (revision 93735)
+++ Source/WebCore/loader/FrameLoader.cpp (working copy)
@@ -367,7 +367,7 @@
Node* currentFocusedNode = m_frame->document()->focusedNode();
if (currentFocusedNode)
currentFocusedNode->aboutToUnload();
- if (m_frame->domWindow()) {
+ if (m_frame->domWindow() && m_pageDismissalEventBeingDispatched == NoDismissal) {
if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) {
m_pageDismissalEventBeingDispatched = PageHideDismissal;
m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document());
@@ -1678,6 +1678,20 @@
m_documentLoader->detachFromFrame();
m_documentLoader = loader;
+
+ // The following abomination is brought to you by the unload event.
+ // The detachChildren() call above may trigger a child frame's unload event,
+ // which could do something obnoxious like call document.write("") on
+ // the main frame, which results in detaching children while detaching children.
+ // This can cause the new m_documentLoader to be detached from its Frame*, but still
+ // be alive. To make matters worse, DocumentLoaders with a null Frame* aren't supposed
+ // to happen when they're still alive (and many places below us on the stack think the
+ // DocumentLoader is still usable). Ergo, we reattach loader to its Frame, and pretend
+ // like nothing ever happened.
+ if (m_documentLoader && !m_documentLoader->frame()) {
+ ASSERT(!m_documentLoader->isLoading());
+ m_documentLoader->setFrame(m_frame);
+ }
}
void FrameLoader::setPolicyDocumentLoader(DocumentLoader* loader)
@@ -2348,12 +2362,14 @@
void FrameLoader::detachChildren()
{
- // FIXME: Is it really necessary to do this in reverse order?
- Frame* previous;
- for (Frame* child = m_frame->tree()->lastChild(); child; child = previous) {
- previous = child->tree()->previousSibling();
- child->loader()->detachFromParent();
- }
+ typedef Vector<RefPtr<Frame> > FrameVector;
+ FrameVector childrenToDetach;
+ childrenToDetach.reserveCapacity(m_frame->tree()->childCount());
+ for (Frame* child = m_frame->tree()->lastChild(); child; child = child->tree()->previousSibling())
+ childrenToDetach.append(child);
+ FrameVector::iterator end = childrenToDetach.end();
+ for (FrameVector::iterator it = childrenToDetach.begin(); it != end; it++)
+ (*it)->loader()->detachFromParent();
}
void FrameLoader::closeAndRemoveChild(Frame* child)
« no previous file with comments | « LayoutTests/fast/loader/resources/document-destruction-within-unload-iframe.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698