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.
5 #include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h"
7 #include "base/logging.h"
8 #include "chrome/common/url_constants.h"
9 #include "content/public/browser/render_frame_host.h"
10 #include "extensions/common/constants.h"
12 namespace extensions {
16 // URL schemes for which we'll send events.
17 const char* const kValidSchemes[] = {
18 content::kChromeUIScheme,
23 url::kJavaScriptScheme,
25 url::kFileSystemScheme,
30 FrameNavigationState::FrameState::FrameState() {}
33 bool FrameNavigationState::allow_extension_scheme_ = false;
35 FrameNavigationState::FrameNavigationState() : main_frame_host_(NULL) {
38 FrameNavigationState::~FrameNavigationState() {}
40 bool FrameNavigationState::CanSendEvents(
41 content::RenderFrameHost* frame_host) const {
42 FrameHostToStateMap::const_iterator it =
43 frame_host_state_map_.find(frame_host);
44 if (it == frame_host_state_map_.end() || it->second.error_occurred) {
47 return IsValidUrl(it->second.url);
50 bool FrameNavigationState::IsValidUrl(const GURL& url) const {
51 for (unsigned i = 0; i < arraysize(kValidSchemes); ++i) {
52 if (url.scheme() == kValidSchemes[i])
55 // Allow about:blank and about:srcdoc.
56 if (url.spec() == url::kAboutBlankURL ||
57 url.spec() == content::kAboutSrcDocURL) {
60 return allow_extension_scheme_ && url.scheme() == kExtensionScheme;
63 void FrameNavigationState::TrackFrame(content::RenderFrameHost* frame_host,
66 bool is_iframe_srcdoc) {
67 FrameState& frame_state = frame_host_state_map_[frame_host];
68 frame_state.error_occurred = is_error_page;
69 frame_state.url = url;
70 frame_state.is_iframe_srcdoc = is_iframe_srcdoc;
71 DCHECK(!is_iframe_srcdoc || url == GURL(url::kAboutBlankURL));
72 frame_state.is_navigating = true;
73 frame_state.is_committed = false;
74 frame_state.is_server_redirected = false;
75 frame_state.is_parsing = true;
76 frame_hosts_.insert(frame_host);
79 void FrameNavigationState::FrameDetached(content::RenderFrameHost* frame_host) {
80 if (frame_host == main_frame_host_)
81 main_frame_host_ = NULL;
82 frame_host_state_map_.erase(frame_host);
83 frame_hosts_.erase(frame_host);
86 void FrameNavigationState::StopTrackingFramesInRVH(
87 content::RenderViewHost* render_view_host,
88 content::RenderFrameHost* frame_host_to_skip) {
89 for (std::set<content::RenderFrameHost*>::iterator it = frame_hosts_.begin();
90 it != frame_hosts_.end();) {
91 if ((*it)->GetRenderViewHost() != render_view_host ||
92 *it == frame_host_to_skip) {
96 if (*it == main_frame_host_)
97 main_frame_host_ = NULL;
98 frame_host_state_map_.erase(*it);
99 frame_hosts_.erase(it++);
103 void FrameNavigationState::UpdateFrame(content::RenderFrameHost* frame_host,
105 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
106 if (it == frame_host_state_map_.end()) {
110 it->second.url = url;
113 bool FrameNavigationState::IsValidFrame(
114 content::RenderFrameHost* frame_host) const {
115 return frame_host_state_map_.find(frame_host) != frame_host_state_map_.end();
118 GURL FrameNavigationState::GetUrl(content::RenderFrameHost* frame_host) const {
119 FrameHostToStateMap::const_iterator it =
120 frame_host_state_map_.find(frame_host);
121 if (it == frame_host_state_map_.end()) {
125 if (it->second.is_iframe_srcdoc)
126 return GURL(content::kAboutSrcDocURL);
127 return it->second.url;
130 content::RenderFrameHost* FrameNavigationState::GetLastCommittedMainFrameHost()
132 return main_frame_host_;
135 void FrameNavigationState::SetErrorOccurredInFrame(
136 content::RenderFrameHost* frame_host) {
137 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
138 if (it == frame_host_state_map_.end()) {
142 it->second.error_occurred = true;
145 bool FrameNavigationState::GetErrorOccurredInFrame(
146 content::RenderFrameHost* frame_host) const {
147 FrameHostToStateMap::const_iterator it =
148 frame_host_state_map_.find(frame_host);
149 DCHECK(it != frame_host_state_map_.end());
150 return it == frame_host_state_map_.end() || it->second.error_occurred;
153 void FrameNavigationState::SetNavigationCompleted(
154 content::RenderFrameHost* frame_host) {
155 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
156 if (it == frame_host_state_map_.end()) {
160 it->second.is_navigating = false;
163 bool FrameNavigationState::GetNavigationCompleted(
164 content::RenderFrameHost* frame_host) const {
165 FrameHostToStateMap::const_iterator it =
166 frame_host_state_map_.find(frame_host);
167 DCHECK(it != frame_host_state_map_.end());
168 return it == frame_host_state_map_.end() || !it->second.is_navigating;
171 void FrameNavigationState::SetParsingFinished(
172 content::RenderFrameHost* frame_host) {
173 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
174 if (it == frame_host_state_map_.end()) {
178 it->second.is_parsing = false;
181 bool FrameNavigationState::GetParsingFinished(
182 content::RenderFrameHost* frame_host) const {
183 FrameHostToStateMap::const_iterator it =
184 frame_host_state_map_.find(frame_host);
185 DCHECK(it != frame_host_state_map_.end());
186 return it == frame_host_state_map_.end() || !it->second.is_parsing;
189 void FrameNavigationState::SetNavigationCommitted(
190 content::RenderFrameHost* frame_host) {
191 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
192 if (it == frame_host_state_map_.end()) {
196 it->second.is_committed = true;
197 if (!frame_host->GetParent())
198 main_frame_host_ = frame_host;
201 bool FrameNavigationState::GetNavigationCommitted(
202 content::RenderFrameHost* frame_host) const {
203 FrameHostToStateMap::const_iterator it =
204 frame_host_state_map_.find(frame_host);
205 DCHECK(it != frame_host_state_map_.end());
206 return it != frame_host_state_map_.end() && it->second.is_committed;
209 void FrameNavigationState::SetIsServerRedirected(
210 content::RenderFrameHost* frame_host) {
211 FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
212 if (it == frame_host_state_map_.end()) {
216 it->second.is_server_redirected = true;
219 bool FrameNavigationState::GetIsServerRedirected(
220 content::RenderFrameHost* frame_host) const {
221 FrameHostToStateMap::const_iterator it =
222 frame_host_state_map_.find(frame_host);
223 DCHECK(it != frame_host_state_map_.end());
224 return it != frame_host_state_map_.end() && it->second.is_server_redirected;
227 } // namespace extensions