summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/loader
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-09-08 11:31:09 +0100
committerSteve Block <steveblock@google.com>2011-09-09 11:34:50 +0100
commit131c31a2d968d23bd0a02c4f7a06a69900fa419d (patch)
treeff32acd610e6d7a2e3b6934cc3714f367458aab9 /Source/WebCore/loader
parentefe456e3824deb639f69f5900990c1de81fa33ab (diff)
downloadexternal_webkit-131c31a2d968d23bd0a02c4f7a06a69900fa419d.zip
external_webkit-131c31a2d968d23bd0a02c4f7a06a69900fa419d.tar.gz
external_webkit-131c31a2d968d23bd0a02c4f7a06a69900fa419d.tar.bz2
Cherry-pick WebKit change 93521 to fix FrameLoader
See http://trac.webkit.org/changeset/93521 Note that the change did not apply cleanly to FrameLoader::stopLoading() because we don't have http://trac.webkit.org/changeset/90164. See bug for details. Bug: 5264509 Change-Id: I824284b9daaa8bc033aebca558d5362ebfb617d8
Diffstat (limited to 'Source/WebCore/loader')
-rw-r--r--Source/WebCore/loader/FrameLoader.cpp35
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)