diff options
Diffstat (limited to 'Source/WebCore/loader/FrameLoader.cpp')
-rw-r--r-- | Source/WebCore/loader/FrameLoader.cpp | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/Source/WebCore/loader/FrameLoader.cpp b/Source/WebCore/loader/FrameLoader.cpp index dcaf03a..2def2a6 100644 --- a/Source/WebCore/loader/FrameLoader.cpp +++ b/Source/WebCore/loader/FrameLoader.cpp @@ -381,8 +381,11 @@ void FrameLoader::stopLoading(UnloadEventPolicy unloadEventPolicy) Node* currentFocusedNode = m_frame->document()->focusedNode(); if (currentFocusedNode) currentFocusedNode->aboutToUnload(); - m_pageDismissalEventBeingDispatched = true; - if (m_frame->domWindow()) { +// ANDROID + // See http://b/issue?id=5264509 + if (m_frame->domWindow() && !m_pageDismissalEventBeingDispatched) { + m_pageDismissalEventBeingDispatched = true; +// END ANDROID if (unloadEventPolicy == UnloadEventPolicyUnloadAndPageHide) m_frame->domWindow()->dispatchEvent(PageTransitionEvent::create(eventNames().pagehideEvent, m_frame->document()->inPageCache()), m_frame->document()); if (!m_frame->document()->inPageCache()) { @@ -1837,6 +1840,20 @@ void FrameLoader::setDocumentLoader(DocumentLoader* loader) 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) @@ -2563,12 +2580,14 @@ void FrameLoader::frameLoadCompleted() 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) |