blob: 75b900cf14e1a143644ba51ae6c96873cb73b662 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/web_navigation/frame_navigation_state.h"
#include "base/logging.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/render_frame_host.h"
#include "extensions/common/constants.h"
namespace extensions {
namespace {
// URL schemes for which we'll send events.
const char* kValidSchemes[] = {
content::kChromeUIScheme,
url::kHttpScheme,
url::kHttpsScheme,
url::kFileScheme,
url::kFtpScheme,
url::kJavaScriptScheme,
url::kDataScheme,
url::kFileSystemScheme,
};
} // namespace
FrameNavigationState::FrameState::FrameState() {}
// static
bool FrameNavigationState::allow_extension_scheme_ = false;
FrameNavigationState::FrameNavigationState() : main_frame_host_(NULL) {
}
FrameNavigationState::~FrameNavigationState() {}
bool FrameNavigationState::CanSendEvents(
content::RenderFrameHost* frame_host) const {
FrameHostToStateMap::const_iterator it =
frame_host_state_map_.find(frame_host);
if (it == frame_host_state_map_.end() || it->second.error_occurred) {
return false;
}
return IsValidUrl(it->second.url);
}
bool FrameNavigationState::IsValidUrl(const GURL& url) const {
for (unsigned i = 0; i < arraysize(kValidSchemes); ++i) {
if (url.scheme() == kValidSchemes[i])
return true;
}
// Allow about:blank and about:srcdoc.
if (url.spec() == url::kAboutBlankURL ||
url.spec() == content::kAboutSrcDocURL) {
return true;
}
return allow_extension_scheme_ && url.scheme() == kExtensionScheme;
}
void FrameNavigationState::TrackFrame(content::RenderFrameHost* frame_host,
const GURL& url,
bool is_error_page,
bool is_iframe_srcdoc) {
FrameState& frame_state = frame_host_state_map_[frame_host];
frame_state.error_occurred = is_error_page;
frame_state.url = url;
frame_state.is_iframe_srcdoc = is_iframe_srcdoc;
DCHECK(!is_iframe_srcdoc || url == GURL(url::kAboutBlankURL));
frame_state.is_navigating = true;
frame_state.is_committed = false;
frame_state.is_server_redirected = false;
frame_state.is_parsing = true;
frame_hosts_.insert(frame_host);
}
void FrameNavigationState::FrameDetached(content::RenderFrameHost* frame_host) {
if (frame_host == main_frame_host_)
main_frame_host_ = NULL;
frame_host_state_map_.erase(frame_host);
frame_hosts_.erase(frame_host);
}
void FrameNavigationState::StopTrackingFramesInRVH(
content::RenderViewHost* render_view_host,
content::RenderFrameHost* frame_host_to_skip) {
for (std::set<content::RenderFrameHost*>::iterator it = frame_hosts_.begin();
it != frame_hosts_.end();) {
if ((*it)->GetRenderViewHost() != render_view_host ||
*it == frame_host_to_skip) {
++it;
continue;
}
if (*it == main_frame_host_)
main_frame_host_ = NULL;
frame_host_state_map_.erase(*it);
frame_hosts_.erase(it++);
}
}
void FrameNavigationState::UpdateFrame(content::RenderFrameHost* frame_host,
const GURL& url) {
FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
if (it == frame_host_state_map_.end()) {
NOTREACHED();
return;
}
it->second.url = url;
}
bool FrameNavigationState::IsValidFrame(
content::RenderFrameHost* frame_host) const {
return frame_host_state_map_.find(frame_host) != frame_host_state_map_.end();
}
GURL FrameNavigationState::GetUrl(content::RenderFrameHost* frame_host) const {
FrameHostToStateMap::const_iterator it =
frame_host_state_map_.find(frame_host);
if (it == frame_host_state_map_.end()) {
NOTREACHED();
return GURL();
}
if (it->second.is_iframe_srcdoc)
return GURL(content::kAboutSrcDocURL);
return it->second.url;
}
content::RenderFrameHost* FrameNavigationState::GetLastCommittedMainFrameHost()
const {
return main_frame_host_;
}
void FrameNavigationState::SetErrorOccurredInFrame(
content::RenderFrameHost* frame_host) {
FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
if (it == frame_host_state_map_.end()) {
NOTREACHED();
return;
}
it->second.error_occurred = true;
}
bool FrameNavigationState::GetErrorOccurredInFrame(
content::RenderFrameHost* frame_host) const {
FrameHostToStateMap::const_iterator it =
frame_host_state_map_.find(frame_host);
DCHECK(it != frame_host_state_map_.end());
return it == frame_host_state_map_.end() || it->second.error_occurred;
}
void FrameNavigationState::SetNavigationCompleted(
content::RenderFrameHost* frame_host) {
FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
if (it == frame_host_state_map_.end()) {
NOTREACHED();
return;
}
it->second.is_navigating = false;
}
bool FrameNavigationState::GetNavigationCompleted(
content::RenderFrameHost* frame_host) const {
FrameHostToStateMap::const_iterator it =
frame_host_state_map_.find(frame_host);
DCHECK(it != frame_host_state_map_.end());
return it == frame_host_state_map_.end() || !it->second.is_navigating;
}
void FrameNavigationState::SetParsingFinished(
content::RenderFrameHost* frame_host) {
FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
if (it == frame_host_state_map_.end()) {
NOTREACHED();
return;
}
it->second.is_parsing = false;
}
bool FrameNavigationState::GetParsingFinished(
content::RenderFrameHost* frame_host) const {
FrameHostToStateMap::const_iterator it =
frame_host_state_map_.find(frame_host);
DCHECK(it != frame_host_state_map_.end());
return it == frame_host_state_map_.end() || !it->second.is_parsing;
}
void FrameNavigationState::SetNavigationCommitted(
content::RenderFrameHost* frame_host) {
FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
if (it == frame_host_state_map_.end()) {
NOTREACHED();
return;
}
it->second.is_committed = true;
if (!frame_host->GetParent())
main_frame_host_ = frame_host;
}
bool FrameNavigationState::GetNavigationCommitted(
content::RenderFrameHost* frame_host) const {
FrameHostToStateMap::const_iterator it =
frame_host_state_map_.find(frame_host);
DCHECK(it != frame_host_state_map_.end());
return it != frame_host_state_map_.end() && it->second.is_committed;
}
void FrameNavigationState::SetIsServerRedirected(
content::RenderFrameHost* frame_host) {
FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
if (it == frame_host_state_map_.end()) {
NOTREACHED();
return;
}
it->second.is_server_redirected = true;
}
bool FrameNavigationState::GetIsServerRedirected(
content::RenderFrameHost* frame_host) const {
FrameHostToStateMap::const_iterator it =
frame_host_state_map_.find(frame_host);
DCHECK(it != frame_host_state_map_.end());
return it != frame_host_state_map_.end() && it->second.is_server_redirected;
}
} // namespace extensions