Chromium Code Reviews| 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()) |
|
eseidel
2014/02/13 23:49:40
I would have added a private loaderClient() or cli
|
| + 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); |
|
eseidel
2014/02/13 23:49:40
Why?
dcheng
2014/02/14 20:29:28
This was to minimize the amount of text rebaseline
|
| 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 |