Index: webkit-1.2.7/WebCore/dom/ContainerNode.cpp
===================================================================
--- webkit-1.2.7.orig/WebCore/dom/ContainerNode.cpp
+++ webkit-1.2.7/WebCore/dom/ContainerNode.cpp
@@ -301,7 +301,6 @@ static void willRemoveChild(Node* child)
     // fire removed from document mutation events.
     dispatchChildRemovalEvents(child);
 
-    if (child->attached())
         child->willRemove();
 }
 
@@ -315,7 +314,6 @@ static void willRemoveChildren(Container
         // fire removed from document mutation events.
         dispatchChildRemovalEvents(child.get());
 
-        if (child->attached())
             child->willRemove();
     }
 }
Index: webkit-1.2.7/WebCore/dom/Node.cpp
===================================================================
--- webkit-1.2.7.orig/WebCore/dom/Node.cpp
+++ webkit-1.2.7/WebCore/dom/Node.cpp
@@ -762,62 +762,39 @@ IntRect Node::getRect() const
     return IntRect();
 }
 
+inline void Node::markAncestorsWithChildNeedsStyleRecalc()
+{
+    for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
+        p->setChildNeedsStyleRecalc();
+    if (document()->childNeedsStyleRecalc())
+        document()->scheduleStyleRecalc();
+}
+
+
 void Node::setNeedsStyleRecalc(StyleChangeType changeType)
 {
     if ((changeType != NoStyleChange) && !attached()) // changed compared to what?
         return;
-
     if (!(changeType == InlineStyleChange && (m_styleChange == FullStyleChange || m_styleChange == SyntheticStyleChange)))
         m_styleChange = changeType;
 
-    if (m_styleChange != NoStyleChange) {
-        for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
-            p->setChildNeedsStyleRecalc(true);
-        if (document()->childNeedsStyleRecalc())
-            document()->scheduleStyleRecalc();
-    }
-}
+    if (changeType == NoStyleChange)
+	    markAncestorsWithChildNeedsStyleRecalc();
+} 
 
-static Node* outermostLazyAttachedAncestor(Node* start)
-{
-    Node* p = start;
-    for (Node* next = p->parentNode(); !next->renderer(); p = next, next = next->parentNode()) {}
-    return p;
-}
-
-void Node::lazyAttach()
-{
-    bool mustDoFullAttach = false;
+void Node::lazyAttach(ShouldSetAttached shouldSetAttached) 
+{ 
+	for (Node* n = this; n; n = n->traverseNextNode(this)) {
 
-    for (Node* n = this; n; n = n->traverseNextNode(this)) {
-        if (!n->canLazyAttach()) {
-            mustDoFullAttach = true;
-            break;
-        }
-
-        if (n->firstChild())
-            n->setChildNeedsStyleRecalc(true);
-        n->m_styleChange = FullStyleChange;
-        n->m_attached = true;
-    }
-
-    if (mustDoFullAttach) {
-        Node* lazyAttachedAncestor = outermostLazyAttachedAncestor(this);
-        if (lazyAttachedAncestor->attached())
-            lazyAttachedAncestor->detach();
-        lazyAttachedAncestor->attach();
-    } else {
-        for (Node* p = parentNode(); p && !p->childNeedsStyleRecalc(); p = p->parentNode())
-            p->setChildNeedsStyleRecalc(true);
-        if (document()->childNeedsStyleRecalc())
-            document()->scheduleStyleRecalc();
-    }
+		if (n->firstChild())
+			n->setChildNeedsStyleRecalc(true);
+		n->m_styleChange = FullStyleChange;
+		if (shouldSetAttached == SetAttached) 
+			n->setAttached(); 
+	} 
+	markAncestorsWithChildNeedsStyleRecalc(); 
 }
 
-bool Node::canLazyAttach()
-{
-    return shadowAncestorNode() == this;
-}
     
 void Node::setFocus(bool b)
 { 
Index: webkit-1.2.7/WebCore/dom/Node.h
===================================================================
--- webkit-1.2.7.orig/WebCore/dom/Node.h
+++ webkit-1.2.7/WebCore/dom/Node.h
@@ -288,8 +288,11 @@ public:
     void setNeedsStyleRecalc(StyleChangeType changeType = FullStyleChange);
     void setIsLink(bool b = true) { m_isLink = b; }
 
-    void lazyAttach();
-    virtual bool canLazyAttach();
+    enum ShouldSetAttached {
+        SetAttached,
+        DoNotSetAttached
+    };
+    void lazyAttach(ShouldSetAttached = SetAttached);
 
     virtual void setFocus(bool b = true);
     virtual void setActive(bool b = true, bool /*pause*/ = false) { m_active = b; }
@@ -583,6 +586,7 @@ private:
     static bool isContainer(ConstructionType);
     static bool isElement(ConstructionType);
     static bool isText(ConstructionType);
+    void markAncestorsWithChildNeedsStyleRecalc();
 
     virtual void refEventTarget() { ref(); }
     virtual void derefEventTarget() { deref(); }
Index: webkit-1.2.7/WebCore/html/HTMLFrameElementBase.cpp
===================================================================
--- webkit-1.2.7.orig/WebCore/html/HTMLFrameElementBase.cpp
+++ webkit-1.2.7/WebCore/html/HTMLFrameElementBase.cpp
@@ -50,9 +50,8 @@ HTMLFrameElementBase::HTMLFrameElementBa
     , m_scrolling(ScrollbarAuto)
     , m_marginWidth(-1)
     , m_marginHeight(-1)
-    , m_checkAttachedTimer(this, &HTMLFrameElementBase::checkAttachedTimerFired)
+    , m_checkInDocumentTimer(this, &HTMLFrameElementBase::checkInDocumentTimerFired)
     , m_viewSource(false)
-    , m_shouldOpenURLAfterAttach(false)
     , m_remainsAliveOnRemovalFromTree(false)
 {
 }
@@ -86,7 +85,6 @@ bool HTMLFrameElementBase::isURLAllowed(
             foundSelfReference = true;
         }
     }
-    
     return true;
 }
 
@@ -155,7 +153,6 @@ void HTMLFrameElementBase::setName()
     m_frameName = getAttribute(nameAttr);
     if (m_frameName.isNull())
         m_frameName = getAttribute(idAttributeName());
-    
     if (Frame* parentFrame = document()->frame())
         m_frameName = parentFrame->tree()->uniqueChildName(m_frameName);
 }
@@ -182,35 +179,32 @@ void HTMLFrameElementBase::updateOnRepar
 void HTMLFrameElementBase::insertedIntoDocument()
 {
     HTMLFrameOwnerElement::insertedIntoDocument();
-    
-    // We delay frame loading until after the render tree is fully constructed.
-    // Othewise, a synchronous load that executed JavaScript would see incorrect 
-    // (0) values for the frame's renderer-dependent properties, like width.
-    m_shouldOpenURLAfterAttach = true;
-
-    if (m_remainsAliveOnRemovalFromTree)
+    if (m_remainsAliveOnRemovalFromTree) {
         updateOnReparenting();
+        setRemainsAliveOnRemovalFromTree(false);
+        return;
+    }
+    // DocumentFragments don't kick of any loads.
+    if (!document()->frame())
+      return;
+
+    // Loads may cause synchronous javascript execution (e.g. beforeload or
+    // src=javascript), which could try to access the renderer before the normal
+    // parser machinery would call lazyAttach() and set us as needing style
+    // resolve.  Any code which expects this to be attached will resolve style
+    // before using renderer(), so this will make sure we attach in time.
+    // FIXME: Normally lazyAttach marks the renderer as attached(), but we don't
+    // want to do that here, as as callers expect to call attach() right after
+    // this and attach() will ASSERT(!attached())
+    ASSERT(!renderer()); // This recalc is unecessary if we already have a renderer.
+    lazyAttach(DoNotSetAttached);
+    setNameAndOpenURL();
 }
-
-void HTMLFrameElementBase::removedFromDocument()
-{
-    m_shouldOpenURLAfterAttach = false;
-
-    HTMLFrameOwnerElement::removedFromDocument();
-}
-
 void HTMLFrameElementBase::attach()
 {
-    if (m_shouldOpenURLAfterAttach) {
-        m_shouldOpenURLAfterAttach = false;
-        if (!m_remainsAliveOnRemovalFromTree)
-            queuePostAttachCallback(&HTMLFrameElementBase::setNameAndOpenURLCallback, this);
-    }
-
-    setRemainsAliveOnRemovalFromTree(false);
 
     HTMLFrameOwnerElement::attach();
-    
+   
     if (RenderPart* renderPart = toRenderPart(renderer())) {
         if (Frame* frame = contentFrame())
             renderPart->setWidget(frame->view());
@@ -253,19 +247,19 @@ bool HTMLFrameElementBase::isURLAttribut
 
 int HTMLFrameElementBase::width() const
 {
+    document()->updateLayoutIgnorePendingStylesheets();
     if (!renderer())
         return 0;
-    
-    document()->updateLayoutIgnorePendingStylesheets();
     return toRenderBox(renderer())->width();
 }
 
 int HTMLFrameElementBase::height() const
 {
+   
+    document()->updateLayoutIgnorePendingStylesheets();
     if (!renderer())
         return 0;
-    
-    document()->updateLayoutIgnorePendingStylesheets();
+   
     return toRenderBox(renderer())->height();
 }
 
@@ -276,12 +270,12 @@ void HTMLFrameElementBase::setRemainsAli
     // There is a possibility that JS will do document.adoptNode() on this element but will not insert it into the tree.
     // Start the async timer that is normally stopped by attach(). If it's not stopped and fires, it'll unload the frame.
     if (value)
-        m_checkAttachedTimer.startOneShot(0);
+      m_checkInDocumentTimer.startOneShot(0);
     else
-        m_checkAttachedTimer.stop();
+      m_checkInDocumentTimer.stop();
 }
 
-void HTMLFrameElementBase::checkAttachedTimerFired(Timer<HTMLFrameElementBase>*)
+void HTMLFrameElementBase::checkInDocumentTimerFired(Timer<HTMLFrameElementBase>*)
 {
     ASSERT(!attached());
     ASSERT(m_remainsAliveOnRemovalFromTree);
Index: webkit-1.2.7/WebCore/html/HTMLFrameElementBase.h
===================================================================
--- webkit-1.2.7.orig/WebCore/html/HTMLFrameElementBase.h
+++ webkit-1.2.7/WebCore/html/HTMLFrameElementBase.h
@@ -52,12 +52,10 @@ protected:
     virtual void parseMappedAttribute(MappedAttribute*);
 
     virtual void insertedIntoDocument();
-    virtual void removedFromDocument();
 
     virtual void attach();
 
 private:
-    virtual bool canLazyAttach() { return false; }
 
     virtual bool supportsFocus() const;
     virtual void setFocus(bool);
@@ -67,7 +65,7 @@ private:
     virtual void setName();
 
     virtual void willRemove();
-    void checkAttachedTimerFired(Timer<HTMLFrameElementBase>*);
+    void checkInDocumentTimerFired(Timer<HTMLFrameElementBase>*);
     void updateOnReparenting();
 
     bool viewSourceMode() const { return m_viewSource; }
@@ -85,12 +83,20 @@ private:
     int m_marginWidth;
     int m_marginHeight;
 
-    Timer<HTMLFrameElementBase> m_checkAttachedTimer;
+    // This is a performance optimization some call "magic iframe" which avoids
+     // tearing down the frame hierarchy when a web page calls adoptNode on a
+     // frame owning element but does not immediately insert it into the new
+     // document before JavaScript yields to WebCore.  If the element is not yet
+     // in a document by the time this timer fires, the frame hierarchy teardown
+     // will continue.  This can also be seen as implementation of:
+     // "Removing an iframe from a Document does not cause its browsing context
+     // to be discarded. Indeed, an iframe's browsing context can survive its
+     // original parent Document if its iframe is moved to another Document."
+     // From HTML5: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#the-iframe-element
+    Timer<HTMLFrameElementBase> m_checkInDocumentTimer;
 
     bool m_viewSource;
 
-    bool m_shouldOpenURLAfterAttach;
-
     bool m_remainsAliveOnRemovalFromTree;
 };
 
Index: webkit-1.2.7/WebCore/html/HTMLFrameOwnerElement.cpp
===================================================================
--- webkit-1.2.7.orig/WebCore/html/HTMLFrameOwnerElement.cpp
+++ webkit-1.2.7/WebCore/html/HTMLFrameOwnerElement.cpp
@@ -41,9 +41,11 @@ HTMLFrameOwnerElement::HTMLFrameOwnerEle
 
 void HTMLFrameOwnerElement::willRemove()
 {
+    // FIXME: It is unclear why this can't be moved to removedFromDocument()
+    // this is the only implementation of willRemove in WebCore!
     if (Frame* frame = contentFrame()) {
-        frame->disconnectOwnerElement();
-        frame->loader()->frameDetached();
+      frame->loader()->frameDetached();
+      frame->disconnectOwnerElement();
     }
 
     HTMLElement::willRemove();
