| Index: Source/core/page/FrameTree.cpp
|
| diff --git a/Source/core/page/FrameTree.cpp b/Source/core/page/FrameTree.cpp
|
| index a2d74cfbcb774e4b0c0c432a53af28491a105170..cc01cfb16c3673b966c9c19d021aa74db422c765 100644
|
| --- a/Source/core/page/FrameTree.cpp
|
| +++ b/Source/core/page/FrameTree.cpp
|
| @@ -24,6 +24,7 @@
|
| #include "core/dom/Document.h"
|
| #include "core/frame/Frame.h"
|
| #include "core/frame/FrameView.h"
|
| +#include "core/loader/FrameLoaderClient.h"
|
| #include "core/page/Page.h"
|
| #include "core/page/PageGroup.h"
|
| #include "wtf/Vector.h"
|
| @@ -34,8 +35,21 @@ using std::swap;
|
|
|
| namespace WebCore {
|
|
|
| +namespace {
|
| +
|
| +const unsigned invalidChildCount = ~0;
|
| +
|
| +} // namespace
|
| +
|
| +FrameTree::FrameTree(Frame* thisFrame)
|
| + : m_thisFrame(thisFrame)
|
| + , m_scopedChildCount(invalidChildCount)
|
| +{
|
| +}
|
| +
|
| FrameTree::~FrameTree()
|
| {
|
| + // FIXME: Why is this here? Doesn't this parallel what we already do in ~Frame?
|
| for (Frame* child = firstChild(); child; child = child->tree().nextSibling())
|
| child->setView(0);
|
| }
|
| @@ -53,45 +67,48 @@ void FrameTree::setName(const AtomicString& name)
|
|
|
| Frame* FrameTree::parent() const
|
| {
|
| - return m_parent;
|
| + if (!m_thisFrame->loader().client())
|
| + return 0;
|
| + return m_thisFrame->loader().client()->parent();
|
| }
|
|
|
| -void FrameTree::appendChild(PassRefPtr<Frame> child)
|
| +Frame* FrameTree::top() const
|
| {
|
| - ASSERT(child->page() == m_thisFrame->page());
|
| - child->tree().m_parent = m_thisFrame;
|
| - Frame* oldLast = m_lastChild;
|
| - m_lastChild = child.get();
|
| -
|
| - if (oldLast) {
|
| - child->tree().m_previousSibling = oldLast;
|
| - oldLast->tree().m_nextSibling = child;
|
| - } else
|
| - m_firstChild = child;
|
| -
|
| - m_scopedChildCount = invalidCount;
|
| -
|
| - ASSERT(!m_lastChild->tree().m_nextSibling);
|
| + // FIXME: top() should never return null, so here are some hacks to deal
|
| + // with EmptyFrameLoaderClient and cases where the frame is detached
|
| + // already...
|
| + if (!m_thisFrame->loader().client())
|
| + return m_thisFrame;
|
| + Frame* candidate = m_thisFrame->loader().client()->top();
|
| + return candidate ? candidate : m_thisFrame;
|
| }
|
|
|
| -void FrameTree::removeChild(Frame* child)
|
| +Frame* FrameTree::previousSibling() const
|
| {
|
| - child->tree().m_parent = 0;
|
| -
|
| - // Slightly tricky way to prevent deleting the child until we are done with it, w/o
|
| - // extra refs. These swaps leave the child in a circular list by itself. Clearing its
|
| - // previous and next will then finally deref it.
|
| + if (!m_thisFrame->loader().client())
|
| + return 0;
|
| + return m_thisFrame->loader().client()->previousSibling();
|
| +}
|
|
|
| - RefPtr<Frame>& newLocationForNext = m_firstChild == child ? m_firstChild : child->tree().m_previousSibling->tree().m_nextSibling;
|
| - Frame*& newLocationForPrevious = m_lastChild == child ? m_lastChild : child->tree().m_nextSibling->tree().m_previousSibling;
|
| - swap(newLocationForNext, child->tree().m_nextSibling);
|
| - // For some inexplicable reason, the following line does not compile without the explicit std:: namespace
|
| - std::swap(newLocationForPrevious, child->tree().m_previousSibling);
|
| +Frame* FrameTree::nextSibling() const
|
| +{
|
| + if (!m_thisFrame->loader().client())
|
| + return 0;
|
| + return m_thisFrame->loader().client()->nextSibling();
|
| +}
|
|
|
| - child->tree().m_previousSibling = 0;
|
| - child->tree().m_nextSibling = 0;
|
| +Frame* FrameTree::firstChild() const
|
| +{
|
| + if (!m_thisFrame->loader().client())
|
| + return 0;
|
| + return m_thisFrame->loader().client()->firstChild();
|
| +}
|
|
|
| - m_scopedChildCount = invalidCount;
|
| +Frame* FrameTree::lastChild() const
|
| +{
|
| + if (!m_thisFrame->loader().client())
|
| + return 0;
|
| + return m_thisFrame->loader().client()->lastChild();
|
| }
|
|
|
| AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
|
| @@ -131,7 +148,7 @@ AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
|
| }
|
|
|
| name.appendLiteral("/<!--frame");
|
| - name.appendNumber(childCount());
|
| + name.appendNumber(childCount() - 1);
|
| name.appendLiteral("-->-->");
|
|
|
| return name.toAtomicString();
|
| @@ -183,11 +200,16 @@ inline unsigned FrameTree::scopedChildCount(TreeScope* scope) const
|
|
|
| unsigned FrameTree::scopedChildCount() const
|
| {
|
| - if (m_scopedChildCount == invalidCount)
|
| + if (m_scopedChildCount == invalidChildCount)
|
| m_scopedChildCount = scopedChildCount(m_thisFrame->document());
|
| return m_scopedChildCount;
|
| }
|
|
|
| +void FrameTree::invalidateScopedChildCount()
|
| +{
|
| + m_scopedChildCount = invalidChildCount;
|
| +}
|
| +
|
| unsigned FrameTree::childCount() const
|
| {
|
| unsigned count = 0;
|
| @@ -336,14 +358,6 @@ Frame* FrameTree::deepLastChild() const
|
| return result;
|
| }
|
|
|
| -Frame* FrameTree::top() const
|
| -{
|
| - Frame* frame = m_thisFrame;
|
| - for (Frame* parent = m_thisFrame; parent; parent = parent->tree().parent())
|
| - frame = parent;
|
| - return frame;
|
| -}
|
| -
|
| } // namespace WebCore
|
|
|
| #ifndef NDEBUG
|
|
|