Chromium Code Reviews| Index: Source/web/WebFrameImpl.cpp |
| diff --git a/Source/web/WebFrameImpl.cpp b/Source/web/WebFrameImpl.cpp |
| index 487675737c5866caeae933894a3d329cbf423a31..e29a9dd5a4e287b47d43fcffed4624310cccbf63 100644 |
| --- a/Source/web/WebFrameImpl.cpp |
| +++ b/Source/web/WebFrameImpl.cpp |
| @@ -647,68 +647,91 @@ void WebFrameImpl::setOpener(const WebFrame* webFrame) |
| void WebFrameImpl::appendChild(WebFrame* child) |
| { |
| - // FIXME: Implement after this revision rolls into Chrome. |
| + // FIXME: Original code asserts that the frames have the same Page. We |
| + // should add an equivalent check... figure out what. |
| + WebFrameImpl* childImpl = toWebFrameImpl(child); |
| + childImpl->m_parent = this; |
| + WebFrameImpl* oldLast = m_lastChild; |
| + m_lastChild = childImpl; |
| + |
| + if (oldLast) { |
| + childImpl->m_previousSibling = oldLast; |
| + oldLast->m_nextSibling = childImpl; |
| + } else { |
| + m_firstChild = childImpl; |
| + } |
| + // FIXME: Not sure if this is a legitimate assert. |
| + ASSERT(frame()); |
| + frame()->tree().invalidateScopedChildCount(); |
| } |
| void WebFrameImpl::removeChild(WebFrame* child) |
| { |
| - // FIXME: Implement after this revision rolls into Chrome. |
| + WebFrameImpl* childImpl = toWebFrameImpl(child); |
| + childImpl->m_parent = 0; |
| + |
| + if (m_firstChild == childImpl) |
| + m_firstChild = childImpl->m_nextSibling; |
| + else |
| + childImpl->m_previousSibling->m_nextSibling = childImpl->m_nextSibling; |
| + |
| + if (m_lastChild == childImpl) |
| + m_lastChild = childImpl->m_previousSibling; |
| + else |
| + childImpl->m_nextSibling->m_previousSibling = childImpl->m_previousSibling; |
| + |
| + childImpl->m_previousSibling = childImpl->m_nextSibling = 0; |
| + // FIXME: Not sure if this is a legitimate assert. |
| + ASSERT(frame()); |
| + frame()->tree().invalidateScopedChildCount(); |
| } |
| WebFrame* WebFrameImpl::parent() const |
| { |
| - if (!frame()) |
| - return 0; |
| - return fromFrame(frame()->tree().parent()); |
| + return m_parent; |
| } |
| WebFrame* WebFrameImpl::top() const |
| { |
| - if (!frame()) |
| - return 0; |
| - return fromFrame(frame()->tree().top()); |
| + // FIXME: I am a bad person. |
|
eseidel
2014/02/13 23:49:40
This is not particularly helpful. :) It's not cle
dcheng
2014/02/14 20:29:28
The original versions were const. Making these non
|
| + WebFrameImpl* frame = const_cast<WebFrameImpl*>(this); |
| + for (WebFrameImpl* parent = frame; parent; parent = parent->m_parent) |
| + frame = parent; |
| + return frame; |
| } |
| -WebFrame* WebFrameImpl::firstChild() const |
| +WebFrame* WebFrameImpl::previousSibling() const |
| { |
| - if (!frame()) |
| - return 0; |
| - return fromFrame(frame()->tree().firstChild()); |
| + return m_previousSibling; |
| } |
| -WebFrame* WebFrameImpl::lastChild() const |
| +WebFrame* WebFrameImpl::nextSibling() const |
| { |
| - if (!frame()) |
| - return 0; |
| - return fromFrame(frame()->tree().lastChild()); |
| + return m_nextSibling; |
| } |
| -WebFrame* WebFrameImpl::nextSibling() const |
| +WebFrame* WebFrameImpl::firstChild() const |
| { |
| - if (!frame()) |
| - return 0; |
| - return fromFrame(frame()->tree().nextSibling()); |
| + return m_firstChild; |
| } |
| -WebFrame* WebFrameImpl::previousSibling() const |
| +WebFrame* WebFrameImpl::lastChild() const |
| { |
| - if (!frame()) |
| - return 0; |
| - return fromFrame(frame()->tree().previousSibling()); |
| + return m_lastChild; |
| } |
| -WebFrame* WebFrameImpl::traverseNext(bool wrap) const |
| +WebFrame* WebFrameImpl::traversePrevious(bool wrap) const |
| { |
| if (!frame()) |
| return 0; |
| - return fromFrame(frame()->tree().traverseNextWithWrap(wrap)); |
| + return fromFrame(frame()->tree().traversePreviousWithWrap(wrap)); |
| } |
| -WebFrame* WebFrameImpl::traversePrevious(bool wrap) const |
| +WebFrame* WebFrameImpl::traverseNext(bool wrap) const |
| { |
| if (!frame()) |
| return 0; |
| - return fromFrame(frame()->tree().traversePreviousWithWrap(wrap)); |
| + return fromFrame(frame()->tree().traverseNextWithWrap(wrap)); |
| } |
| WebFrame* WebFrameImpl::findChildByName(const WebString& name) const |
| @@ -2093,6 +2116,11 @@ WebFrameImpl* WebFrameImpl::create(WebFrameClient* client, long long embedderIde |
| WebFrameImpl::WebFrameImpl(WebFrameClient* client, long long embedderIdentifier) |
| : m_frameInit(WebFrameInit::create(this, embedderIdentifier)) |
| + , m_parent(0) |
| + , m_previousSibling(0) |
| + , m_nextSibling(0) |
| + , m_firstChild(0) |
| + , m_lastChild(0) |
| , m_client(client) |
| , m_permissionClient(0) |
| , m_currentActiveMatchFrame(0) |
| @@ -2151,8 +2179,7 @@ PassRefPtr<Frame> WebFrameImpl::createChildFrame(const FrameLoadRequest& request |
| childFrame->tree().setName(request.frameName()); |
| - frame()->tree().appendChild(childFrame); |
| - |
| + // FIXME: This comment is not quite accurate anymore. |
| // Frame::init() can trigger onload event in the parent frame, |
| // which may detach this frame and trigger a null-pointer access |
| // in FrameTree::removeChild. Move init() after appendChild call |