Upstream version 8.37.180.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 "web/OpenedFrameTracker.h"
10 #include "web/WebLocalFrameImpl.h"
11 #include "web/WebRemoteFrameImpl.h"
12 #include <algorithm>
13
14
15 namespace blink {
16
17 WebCore::Frame* toWebCoreFrame(const WebFrame* frame)
18 {
19     if (!frame)
20         return 0;
21
22     return frame->isWebLocalFrame()
23         ? static_cast<WebCore::Frame*>(toWebLocalFrameImpl(frame)->frame())
24         : toWebRemoteFrameImpl(frame)->frame();
25 }
26
27 void WebFrame::swap(WebFrame* frame)
28 {
29     using std::swap;
30
31     if (m_parent) {
32         if (m_parent->m_firstChild == this)
33             m_parent->m_firstChild = frame;
34         if (m_parent->m_lastChild == this)
35             m_parent->m_lastChild = frame;
36         swap(m_parent, frame->m_parent);
37     }
38     if (m_previousSibling) {
39         m_previousSibling->m_nextSibling = frame;
40         swap(m_previousSibling, frame->m_previousSibling);
41     }
42     if (m_nextSibling) {
43         m_nextSibling->m_previousSibling = frame;
44         swap(m_nextSibling, frame->m_nextSibling);
45     }
46     if (m_opener) {
47         m_opener->m_openedFrameTracker->remove(this);
48         m_opener->m_openedFrameTracker->add(frame);
49         swap(m_opener, frame->m_opener);
50     }
51     if (!m_openedFrameTracker->isEmpty()) {
52         m_openedFrameTracker->updateOpener(frame);
53         frame->m_openedFrameTracker.reset(m_openedFrameTracker.release());
54     }
55 }
56
57 WebFrame* WebFrame::opener() const
58 {
59     return m_opener;
60 }
61
62 void WebFrame::setOpener(WebFrame* opener)
63 {
64     if (m_opener)
65         m_opener->m_openedFrameTracker->remove(this);
66     if (opener)
67         opener->m_openedFrameTracker->add(this);
68     m_opener = opener;
69 }
70
71 void WebFrame::appendChild(WebFrame* child)
72 {
73     // FIXME: Original code asserts that the frames have the same Page. We
74     // should add an equivalent check... figure out what.
75     child->m_parent = this;
76     WebFrame* oldLast = m_lastChild;
77     m_lastChild = child;
78
79     if (oldLast) {
80         child->m_previousSibling = oldLast;
81         oldLast->m_nextSibling = child;
82     } else {
83         m_firstChild = child;
84     }
85
86     toWebCoreFrame(this)->tree().invalidateScopedChildCount();
87 }
88
89 void WebFrame::removeChild(WebFrame* child)
90 {
91     child->m_parent = 0;
92
93     if (m_firstChild == child)
94         m_firstChild = child->m_nextSibling;
95     else
96         child->m_previousSibling->m_nextSibling = child->m_nextSibling;
97
98     if (m_lastChild == child)
99         m_lastChild = child->m_previousSibling;
100     else
101         child->m_nextSibling->m_previousSibling = child->m_previousSibling;
102
103     child->m_previousSibling = child->m_nextSibling = 0;
104
105     toWebCoreFrame(this)->tree().invalidateScopedChildCount();
106 }
107
108 WebFrame* WebFrame::parent() const
109 {
110     return m_parent;
111 }
112
113 WebFrame* WebFrame::top() const
114 {
115     WebFrame* frame = const_cast<WebFrame*>(this);
116     for (WebFrame* parent = frame; parent; parent = parent->m_parent)
117         frame = parent;
118     return frame;
119 }
120
121 WebFrame* WebFrame::firstChild() const
122 {
123     return m_firstChild;
124 }
125
126 WebFrame* WebFrame::lastChild() const
127 {
128     return m_lastChild;
129 }
130
131 WebFrame* WebFrame::previousSibling() const
132 {
133     return m_previousSibling;
134 }
135
136 WebFrame* WebFrame::nextSibling() const
137 {
138     return m_nextSibling;
139 }
140
141 WebFrame* WebFrame::traversePrevious(bool wrap) const
142 {
143     WebCore::Frame* frame = toWebCoreFrame(this);
144     if (!frame)
145         return 0;
146     return fromFrame(frame->tree().traversePreviousWithWrap(wrap));
147 }
148
149 WebFrame* WebFrame::traverseNext(bool wrap) const
150 {
151     WebCore::Frame* frame = toWebCoreFrame(this);
152     if (!frame)
153         return 0;
154     return fromFrame(frame->tree().traverseNextWithWrap(wrap));
155 }
156
157 WebFrame* WebFrame::findChildByName(const WebString& name) const
158 {
159     WebCore::Frame* frame = toWebCoreFrame(this);
160     if (!frame)
161         return 0;
162     // FIXME: It's not clear this should ever be called to find a remote frame.
163     // Perhaps just disallow that completely?
164     return fromFrame(frame->tree().child(name));
165 }
166
167 WebFrame* WebFrame::fromFrame(WebCore::Frame* frame)
168 {
169     if (!frame)
170         return 0;
171
172     if (frame->isLocalFrame())
173         return WebLocalFrameImpl::fromFrame(toLocalFrame(*frame));
174     return WebRemoteFrameImpl::fromFrame(toRemoteFrame(*frame));
175 }
176
177 WebFrame::WebFrame()
178     : m_parent(0)
179     , m_previousSibling(0)
180     , m_nextSibling(0)
181     , m_firstChild(0)
182     , m_lastChild(0)
183     , m_opener(0)
184     , m_openedFrameTracker(new OpenedFrameTracker)
185 {
186 }
187
188 WebFrame::~WebFrame()
189 {
190     m_openedFrameTracker.reset(0);
191 }
192
193 } // namespace blink