Home | History | Annotate | Download | only in web_navigation
      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 "content/public/browser/render_frame_host.h"
     10 #include "extensions/common/constants.h"
     11 
     12 namespace extensions {
     13 
     14 namespace {
     15 
     16 // URL schemes for which we'll send events.
     17 const char* kValidSchemes[] = {
     18     content::kChromeUIScheme,
     19     url::kHttpScheme,
     20     url::kHttpsScheme,
     21     url::kFileScheme,
     22     url::kFtpScheme,
     23     url::kJavaScriptScheme,
     24     url::kDataScheme,
     25     url::kFileSystemScheme,
     26 };
     27 
     28 }  // namespace
     29 
     30 FrameNavigationState::FrameState::FrameState() {}
     31 
     32 // static
     33 bool FrameNavigationState::allow_extension_scheme_ = false;
     34 
     35 FrameNavigationState::FrameNavigationState() : main_frame_host_(NULL) {
     36 }
     37 
     38 FrameNavigationState::~FrameNavigationState() {}
     39 
     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) {
     45     return false;
     46   }
     47   return IsValidUrl(it->second.url);
     48 }
     49 
     50 bool FrameNavigationState::IsValidUrl(const GURL& url) const {
     51   for (unsigned i = 0; i < arraysize(kValidSchemes); ++i) {
     52     if (url.scheme() == kValidSchemes[i])
     53       return true;
     54   }
     55   // Allow about:blank and about:srcdoc.
     56   if (url.spec() == url::kAboutBlankURL ||
     57       url.spec() == content::kAboutSrcDocURL) {
     58     return true;
     59   }
     60   return allow_extension_scheme_ && url.scheme() == kExtensionScheme;
     61 }
     62 
     63 void FrameNavigationState::TrackFrame(content::RenderFrameHost* frame_host,
     64                                       const GURL& url,
     65                                       bool is_error_page,
     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);
     77 }
     78 
     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);
     84 }
     85 
     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) {
     93       ++it;
     94       continue;
     95     }
     96     if (*it == main_frame_host_)
     97       main_frame_host_ = NULL;
     98     frame_host_state_map_.erase(*it);
     99     frame_hosts_.erase(it++);
    100   }
    101 }
    102 
    103 void FrameNavigationState::UpdateFrame(content::RenderFrameHost* frame_host,
    104                                        const GURL& url) {
    105   FrameHostToStateMap::iterator it = frame_host_state_map_.find(frame_host);
    106   if (it == frame_host_state_map_.end()) {
    107     NOTREACHED();
    108     return;
    109   }
    110   it->second.url = url;
    111 }
    112 
    113 bool FrameNavigationState::IsValidFrame(
    114     content::RenderFrameHost* frame_host) const {
    115   return frame_host_state_map_.find(frame_host) != frame_host_state_map_.end();
    116 }
    117 
    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()) {
    122     NOTREACHED();
    123     return GURL();
    124   }
    125   if (it->second.is_iframe_srcdoc)
    126     return GURL(content::kAboutSrcDocURL);
    127   return it->second.url;
    128 }
    129 
    130 content::RenderFrameHost* FrameNavigationState::GetLastCommittedMainFrameHost()
    131     const {
    132   return main_frame_host_;
    133 }
    134 
    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()) {
    139     NOTREACHED();
    140     return;
    141   }
    142   it->second.error_occurred = true;
    143 }
    144 
    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;
    151 }
    152 
    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()) {
    157     NOTREACHED();
    158     return;
    159   }
    160   it->second.is_navigating = false;
    161 }
    162 
    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;
    169 }
    170 
    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()) {
    175     NOTREACHED();
    176     return;
    177   }
    178   it->second.is_parsing = false;
    179 }
    180 
    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;
    187 }
    188 
    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()) {
    193     NOTREACHED();
    194     return;
    195   }
    196   it->second.is_committed = true;
    197   if (!frame_host->GetParent())
    198     main_frame_host_ = frame_host;
    199 }
    200 
    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;
    207 }
    208 
    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()) {
    213     NOTREACHED();
    214     return;
    215   }
    216   it->second.is_server_redirected = true;
    217 }
    218 
    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;
    225 }
    226 
    227 }  // namespace extensions
    228