1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "public/web/WebFrame.h"
8 #include "core/frame/RemoteFrame.h"
9 #include "core/html/HTMLFrameOwnerElement.h"
10 #include "web/OpenedFrameTracker.h"
11 #include "web/WebLocalFrameImpl.h"
12 #include "web/WebRemoteFrameImpl.h"
18 Frame* toCoreFrame(const WebFrame* frame)
23 return frame->isWebLocalFrame()
24 ? static_cast<Frame*>(toWebLocalFrameImpl(frame)->frame())
25 : toWebRemoteFrameImpl(frame)->frame();
28 void WebFrame::swap(WebFrame* frame)
32 // All child frames must have been detached first.
33 ASSERT(!m_firstChild && !m_lastChild);
34 // The frame being swapped in should not have a blink::Frame associated
36 ASSERT(!toCoreFrame(frame));
39 if (m_parent->m_firstChild == this)
40 m_parent->m_firstChild = frame;
41 if (m_parent->m_lastChild == this)
42 m_parent->m_lastChild = frame;
43 swap(m_parent, frame->m_parent);
46 if (m_previousSibling) {
47 m_previousSibling->m_nextSibling = frame;
48 swap(m_previousSibling, frame->m_previousSibling);
51 m_nextSibling->m_previousSibling = frame;
52 swap(m_nextSibling, frame->m_nextSibling);
56 m_opener->m_openedFrameTracker->remove(this);
57 m_opener->m_openedFrameTracker->add(frame);
58 swap(m_opener, frame->m_opener);
60 if (!m_openedFrameTracker->isEmpty()) {
61 m_openedFrameTracker->updateOpener(frame);
62 frame->m_openedFrameTracker.reset(m_openedFrameTracker.release());
65 // Finally, clone the state of the current blink::Frame into one matching
66 // the type of the passed in WebFrame.
67 // FIXME: This is a bit clunky; this results in pointless decrements and
68 // increments of connected subframes.
69 Frame* oldFrame = toCoreFrame(this);
70 FrameOwner* owner = oldFrame->owner();
71 oldFrame->disconnectOwnerElement();
72 if (frame->isWebLocalFrame()) {
73 toWebLocalFrameImpl(frame)->initializeCoreFrame(oldFrame->host(), owner, oldFrame->tree().name(), nullAtom);
75 toWebRemoteFrameImpl(frame)->initializeCoreFrame(oldFrame->host(), owner, oldFrame->tree().name());
79 WebFrame* WebFrame::opener() const
84 void WebFrame::setOpener(WebFrame* opener)
87 m_opener->m_openedFrameTracker->remove(this);
89 opener->m_openedFrameTracker->add(this);
93 void WebFrame::appendChild(WebFrame* child)
95 // FIXME: Original code asserts that the frames have the same Page. We
96 // should add an equivalent check... figure out what.
97 child->m_parent = this;
98 WebFrame* oldLast = m_lastChild;
102 child->m_previousSibling = oldLast;
103 oldLast->m_nextSibling = child;
105 m_firstChild = child;
108 toCoreFrame(this)->tree().invalidateScopedChildCount();
111 void WebFrame::removeChild(WebFrame* child)
115 if (m_firstChild == child)
116 m_firstChild = child->m_nextSibling;
118 child->m_previousSibling->m_nextSibling = child->m_nextSibling;
120 if (m_lastChild == child)
121 m_lastChild = child->m_previousSibling;
123 child->m_nextSibling->m_previousSibling = child->m_previousSibling;
125 child->m_previousSibling = child->m_nextSibling = 0;
127 toCoreFrame(this)->tree().invalidateScopedChildCount();
130 WebFrame* WebFrame::parent() const
135 WebFrame* WebFrame::top() const
137 WebFrame* frame = const_cast<WebFrame*>(this);
138 for (WebFrame* parent = frame; parent; parent = parent->m_parent)
143 WebFrame* WebFrame::firstChild() const
148 WebFrame* WebFrame::lastChild() const
153 WebFrame* WebFrame::previousSibling() const
155 return m_previousSibling;
158 WebFrame* WebFrame::nextSibling() const
160 return m_nextSibling;
163 WebFrame* WebFrame::traversePrevious(bool wrap) const
165 if (Frame* frame = toCoreFrame(this))
166 return fromFrame(frame->tree().traversePreviousWithWrap(wrap));
170 WebFrame* WebFrame::traverseNext(bool wrap) const
172 if (Frame* frame = toCoreFrame(this))
173 return fromFrame(frame->tree().traverseNextWithWrap(wrap));
177 WebFrame* WebFrame::findChildByName(const WebString& name) const
179 Frame* frame = toCoreFrame(this);
182 // FIXME: It's not clear this should ever be called to find a remote frame.
183 // Perhaps just disallow that completely?
184 return fromFrame(frame->tree().child(name));
187 WebFrame* WebFrame::fromFrame(blink::Frame* frame)
192 if (frame->isLocalFrame())
193 return WebLocalFrameImpl::fromFrame(toLocalFrame(*frame));
194 return WebRemoteFrameImpl::fromFrame(toRemoteFrame(*frame));
199 , m_previousSibling(0)
204 , m_openedFrameTracker(new OpenedFrameTracker)
208 WebFrame::~WebFrame()
210 m_openedFrameTracker.reset(0);