Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / web_navigation / frame_navigation_state.cc
1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h"
6
7 #include "base/logging.h"
8 #include "chrome/common/url_constants.h"
9 #include "extensions/common/constants.h"
10
11 namespace extensions {
12
13 namespace {
14
15 // URL schemes for which we'll send events.
16 const char* kValidSchemes[] = {
17   content::kChromeUIScheme,
18   content::kHttpScheme,
19   content::kHttpsScheme,
20   content::kFileScheme,
21   content::kFtpScheme,
22   content::kJavaScriptScheme,
23   content::kDataScheme,
24   content::kFileSystemScheme,
25 };
26
27 }  // namespace
28
29 FrameNavigationState::FrameID::FrameID()
30     : frame_num(-1),
31       render_view_host(NULL) {
32 }
33
34 FrameNavigationState::FrameID::FrameID(
35     int64 frame_num,
36     content::RenderViewHost* render_view_host)
37     : frame_num(frame_num),
38       render_view_host(render_view_host) {
39 }
40
41 bool FrameNavigationState::FrameID::operator<(
42     const FrameNavigationState::FrameID& other) const {
43   return frame_num < other.frame_num ||
44       (frame_num == other.frame_num &&
45        render_view_host < other.render_view_host);
46 }
47
48 bool FrameNavigationState::FrameID::operator==(
49     const FrameNavigationState::FrameID& other) const {
50   return frame_num == other.frame_num &&
51       render_view_host == other.render_view_host;
52 }
53
54 bool FrameNavigationState::FrameID::operator!=(
55     const FrameNavigationState::FrameID& other) const {
56   return !(*this == other);
57 }
58
59 FrameNavigationState::FrameState::FrameState() {}
60
61 // static
62 bool FrameNavigationState::allow_extension_scheme_ = false;
63
64 FrameNavigationState::FrameNavigationState() {}
65
66 FrameNavigationState::~FrameNavigationState() {}
67
68 bool FrameNavigationState::CanSendEvents(FrameID frame_id) const {
69   FrameIdToStateMap::const_iterator frame_state =
70       frame_state_map_.find(frame_id);
71   if (frame_state == frame_state_map_.end() ||
72       frame_state->second.error_occurred) {
73     return false;
74   }
75   return IsValidUrl(frame_state->second.url);
76 }
77
78 bool FrameNavigationState::IsValidUrl(const GURL& url) const {
79   for (unsigned i = 0; i < arraysize(kValidSchemes); ++i) {
80     if (url.scheme() == kValidSchemes[i])
81       return true;
82   }
83   // Allow about:blank and about:srcdoc.
84   if (url.spec() == content::kAboutBlankURL ||
85       url.spec() == content::kAboutSrcDocURL) {
86     return true;
87   }
88   if (allow_extension_scheme_ && url.scheme() == extensions::kExtensionScheme)
89     return true;
90   return false;
91 }
92
93 void FrameNavigationState::TrackFrame(FrameID frame_id,
94                                       FrameID parent_frame_id,
95                                       const GURL& url,
96                                       bool is_main_frame,
97                                       bool is_error_page,
98                                       bool is_iframe_srcdoc) {
99   FrameState& frame_state = frame_state_map_[frame_id];
100   frame_state.error_occurred = is_error_page;
101   frame_state.url = url;
102   frame_state.is_main_frame = is_main_frame;
103   frame_state.is_iframe_srcdoc = is_iframe_srcdoc;
104   DCHECK(!is_iframe_srcdoc || url == GURL(content::kAboutBlankURL));
105   frame_state.is_navigating = true;
106   frame_state.is_committed = false;
107   frame_state.is_server_redirected = false;
108   frame_state.is_parsing = true;
109   if (!is_main_frame) {
110     frame_state.parent_frame_num = parent_frame_id.frame_num;
111   } else {
112     DCHECK(parent_frame_id.frame_num == -1);
113     frame_state.parent_frame_num = -1;
114   }
115   frame_ids_.insert(frame_id);
116 }
117
118 void FrameNavigationState::FrameDetached(FrameID frame_id) {
119   FrameIdToStateMap::const_iterator frame_state =
120       frame_state_map_.find(frame_id);
121   if (frame_state == frame_state_map_.end())
122     return;
123   if (frame_id == main_frame_id_)
124     main_frame_id_ = FrameID();
125   frame_state_map_.erase(frame_id);
126   frame_ids_.erase(frame_id);
127 #ifndef NDEBUG
128   // Check that the deleted frame was not the parent of any other frame. WebKit
129   // should always detach frames starting with the children.
130   for (FrameIdToStateMap::const_iterator frame = frame_state_map_.begin();
131        frame != frame_state_map_.end(); ++frame) {
132     if (frame->first.render_view_host != frame_id.render_view_host)
133       continue;
134     if (frame->second.parent_frame_num != frame_id.frame_num)
135       continue;
136     NOTREACHED();
137   }
138 #endif
139 }
140
141 void FrameNavigationState::StopTrackingFramesInRVH(
142     content::RenderViewHost* render_view_host,
143     FrameID id_to_skip) {
144   for (std::set<FrameID>::iterator frame = frame_ids_.begin();
145        frame != frame_ids_.end();) {
146     if (frame->render_view_host != render_view_host || *frame == id_to_skip) {
147       ++frame;
148       continue;
149     }
150     FrameID frame_id = *frame;
151     ++frame;
152     if (frame_id == main_frame_id_)
153       main_frame_id_ = FrameID();
154     frame_state_map_.erase(frame_id);
155     frame_ids_.erase(frame_id);
156   }
157 }
158
159 void FrameNavigationState::UpdateFrame(FrameID frame_id, const GURL& url) {
160   FrameIdToStateMap::iterator frame_state = frame_state_map_.find(frame_id);
161   if (frame_state == frame_state_map_.end()) {
162     NOTREACHED();
163     return;
164   }
165   frame_state->second.url = url;
166 }
167
168 bool FrameNavigationState::IsValidFrame(FrameID frame_id) const {
169   FrameIdToStateMap::const_iterator frame_state =
170       frame_state_map_.find(frame_id);
171   return (frame_state != frame_state_map_.end());
172 }
173
174 GURL FrameNavigationState::GetUrl(FrameID frame_id) const {
175   FrameIdToStateMap::const_iterator frame_state =
176       frame_state_map_.find(frame_id);
177   if (frame_state == frame_state_map_.end()) {
178     NOTREACHED();
179     return GURL();
180   }
181   if (frame_state->second.is_iframe_srcdoc)
182     return GURL(content::kAboutSrcDocURL);
183   return frame_state->second.url;
184 }
185
186 bool FrameNavigationState::IsMainFrame(FrameID frame_id) const {
187   FrameIdToStateMap::const_iterator frame_state =
188       frame_state_map_.find(frame_id);
189   return (frame_state != frame_state_map_.end() &&
190           frame_state->second.is_main_frame);
191 }
192
193 FrameNavigationState::FrameID FrameNavigationState::GetMainFrameID() const {
194   return main_frame_id_;
195 }
196
197 FrameNavigationState::FrameID FrameNavigationState::GetParentFrameID(
198     FrameID frame_id) const {
199   FrameIdToStateMap::const_iterator frame_state =
200       frame_state_map_.find(frame_id);
201   if (frame_state == frame_state_map_.end()) {
202     NOTREACHED();
203     return FrameID();
204   }
205   return FrameID(frame_state->second.parent_frame_num,
206                  frame_id.render_view_host);
207 }
208
209 void FrameNavigationState::SetErrorOccurredInFrame(FrameID frame_id) {
210   DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end());
211   frame_state_map_[frame_id].error_occurred = true;
212 }
213
214 bool FrameNavigationState::GetErrorOccurredInFrame(FrameID frame_id) const {
215   FrameIdToStateMap::const_iterator frame_state =
216       frame_state_map_.find(frame_id);
217   return (frame_state == frame_state_map_.end() ||
218           frame_state->second.error_occurred);
219 }
220
221 void FrameNavigationState::SetNavigationCompleted(FrameID frame_id) {
222   DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end());
223   frame_state_map_[frame_id].is_navigating = false;
224 }
225
226 bool FrameNavigationState::GetNavigationCompleted(FrameID frame_id) const {
227   FrameIdToStateMap::const_iterator frame_state =
228       frame_state_map_.find(frame_id);
229   return (frame_state == frame_state_map_.end() ||
230           !frame_state->second.is_navigating);
231 }
232
233 void FrameNavigationState::SetParsingFinished(FrameID frame_id) {
234   DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end());
235   frame_state_map_[frame_id].is_parsing = false;
236 }
237
238 bool FrameNavigationState::GetParsingFinished(FrameID frame_id) const {
239   FrameIdToStateMap::const_iterator frame_state =
240       frame_state_map_.find(frame_id);
241   return (frame_state == frame_state_map_.end() ||
242           !frame_state->second.is_parsing);
243 }
244
245 void FrameNavigationState::SetNavigationCommitted(FrameID frame_id) {
246   DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end());
247   frame_state_map_[frame_id].is_committed = true;
248   if (frame_state_map_[frame_id].is_main_frame)
249     main_frame_id_ = frame_id;
250 }
251
252 bool FrameNavigationState::GetNavigationCommitted(FrameID frame_id) const {
253   FrameIdToStateMap::const_iterator frame_state =
254       frame_state_map_.find(frame_id);
255   return (frame_state != frame_state_map_.end() &&
256           frame_state->second.is_committed);
257 }
258
259 void FrameNavigationState::SetIsServerRedirected(FrameID frame_id) {
260   DCHECK(frame_state_map_.find(frame_id) != frame_state_map_.end());
261   frame_state_map_[frame_id].is_server_redirected = true;
262 }
263
264 bool FrameNavigationState::GetIsServerRedirected(FrameID frame_id) const {
265   FrameIdToStateMap::const_iterator frame_state =
266       frame_state_map_.find(frame_id);
267   return (frame_state != frame_state_map_.end() &&
268           frame_state->second.is_server_redirected);
269 }
270
271 }  // namespace extensions