Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / web / WebFrame.cpp
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.
4
5 #include "config.h"
6 #include "public/web/WebFrame.h"
7
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"
13 #include <algorithm>
14
15
16 namespace blink {
17
18 Frame* toCoreFrame(const WebFrame* frame)
19 {
20     if (!frame)
21         return 0;
22
23     return frame->isWebLocalFrame()
24         ? static_cast<Frame*>(toWebLocalFrameImpl(frame)->frame())
25         : toWebRemoteFrameImpl(frame)->frame();
26 }
27
28 void WebFrame::swap(WebFrame* frame)
29 {
30     using std::swap;
31
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
35     // with it yet.
36     ASSERT(!toCoreFrame(frame));
37
38     if (m_parent) {
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);
44     }
45
46     if (m_previousSibling) {
47         m_previousSibling->m_nextSibling = frame;
48         swap(m_previousSibling, frame->m_previousSibling);
49     }
50     if (m_nextSibling) {
51         m_nextSibling->m_previousSibling = frame;
52         swap(m_nextSibling, frame->m_nextSibling);
53     }
54
55     if (m_opener) {
56         m_opener->m_openedFrameTracker->remove(this);
57         m_opener->m_openedFrameTracker->add(frame);
58         swap(m_opener, frame->m_opener);
59     }
60     if (!m_openedFrameTracker->isEmpty()) {
61         m_openedFrameTracker->updateOpener(frame);
62         frame->m_openedFrameTracker.reset(m_openedFrameTracker.release());
63     }
64
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);
74     } else {
75         toWebRemoteFrameImpl(frame)->initializeCoreFrame(oldFrame->host(), owner, oldFrame->tree().name());
76     }
77 }
78
79 WebFrame* WebFrame::opener() const
80 {
81     return m_opener;
82 }
83
84 void WebFrame::setOpener(WebFrame* opener)
85 {
86     if (m_opener)
87         m_opener->m_openedFrameTracker->remove(this);
88     if (opener)
89         opener->m_openedFrameTracker->add(this);
90     m_opener = opener;
91 }
92
93 void WebFrame::appendChild(WebFrame* child)
94 {
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;
99     m_lastChild = child;
100
101     if (oldLast) {
102         child->m_previousSibling = oldLast;
103         oldLast->m_nextSibling = child;
104     } else {
105         m_firstChild = child;
106     }
107
108     toCoreFrame(this)->tree().invalidateScopedChildCount();
109 }
110
111 void WebFrame::removeChild(WebFrame* child)
112 {
113     child->m_parent = 0;
114
115     if (m_firstChild == child)
116         m_firstChild = child->m_nextSibling;
117     else
118         child->m_previousSibling->m_nextSibling = child->m_nextSibling;
119
120     if (m_lastChild == child)
121         m_lastChild = child->m_previousSibling;
122     else
123         child->m_nextSibling->m_previousSibling = child->m_previousSibling;
124
125     child->m_previousSibling = child->m_nextSibling = 0;
126
127     toCoreFrame(this)->tree().invalidateScopedChildCount();
128 }
129
130 WebFrame* WebFrame::parent() const
131 {
132     return m_parent;
133 }
134
135 WebFrame* WebFrame::top() const
136 {
137     WebFrame* frame = const_cast<WebFrame*>(this);
138     for (WebFrame* parent = frame; parent; parent = parent->m_parent)
139         frame = parent;
140     return frame;
141 }
142
143 WebFrame* WebFrame::firstChild() const
144 {
145     return m_firstChild;
146 }
147
148 WebFrame* WebFrame::lastChild() const
149 {
150     return m_lastChild;
151 }
152
153 WebFrame* WebFrame::previousSibling() const
154 {
155     return m_previousSibling;
156 }
157
158 WebFrame* WebFrame::nextSibling() const
159 {
160     return m_nextSibling;
161 }
162
163 WebFrame* WebFrame::traversePrevious(bool wrap) const
164 {
165     if (Frame* frame = toCoreFrame(this))
166         return fromFrame(frame->tree().traversePreviousWithWrap(wrap));
167     return 0;
168 }
169
170 WebFrame* WebFrame::traverseNext(bool wrap) const
171 {
172     if (Frame* frame = toCoreFrame(this))
173         return fromFrame(frame->tree().traverseNextWithWrap(wrap));
174     return 0;
175 }
176
177 WebFrame* WebFrame::findChildByName(const WebString& name) const
178 {
179     Frame* frame = toCoreFrame(this);
180     if (!frame)
181         return 0;
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));
185 }
186
187 WebFrame* WebFrame::fromFrame(blink::Frame* frame)
188 {
189     if (!frame)
190         return 0;
191
192     if (frame->isLocalFrame())
193         return WebLocalFrameImpl::fromFrame(toLocalFrame(*frame));
194     return WebRemoteFrameImpl::fromFrame(toRemoteFrame(*frame));
195 }
196
197 WebFrame::WebFrame()
198     : m_parent(0)
199     , m_previousSibling(0)
200     , m_nextSibling(0)
201     , m_firstChild(0)
202     , m_lastChild(0)
203     , m_opener(0)
204     , m_openedFrameTracker(new OpenedFrameTracker)
205 {
206 }
207
208 WebFrame::~WebFrame()
209 {
210     m_openedFrameTracker.reset(0);
211 }
212
213 } // namespace blink