1// Copyright 2013 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 "content/browser/frame_host/navigation_entry_impl.h" 6 7#include "base/metrics/histogram.h" 8#include "base/strings/string_util.h" 9#include "base/strings/utf_string_conversions.h" 10#include "content/public/common/content_constants.h" 11#include "content/public/common/url_constants.h" 12#include "net/base/net_util.h" 13#include "ui/gfx/text_elider.h" 14 15// Use this to get a new unique ID for a NavigationEntry during construction. 16// The returned ID is guaranteed to be nonzero (which is the "no ID" indicator). 17static int GetUniqueIDInConstructor() { 18 static int unique_id_counter = 0; 19 return ++unique_id_counter; 20} 21 22namespace content { 23 24int NavigationEntryImpl::kInvalidBindings = -1; 25 26NavigationEntry* NavigationEntry::Create() { 27 return new NavigationEntryImpl(); 28} 29 30NavigationEntry* NavigationEntry::Create(const NavigationEntry& copy) { 31 return new NavigationEntryImpl(static_cast<const NavigationEntryImpl&>(copy)); 32} 33 34NavigationEntryImpl* NavigationEntryImpl::FromNavigationEntry( 35 NavigationEntry* entry) { 36 return static_cast<NavigationEntryImpl*>(entry); 37} 38 39NavigationEntryImpl::NavigationEntryImpl() 40 : unique_id_(GetUniqueIDInConstructor()), 41 site_instance_(NULL), 42 bindings_(kInvalidBindings), 43 page_type_(PAGE_TYPE_NORMAL), 44 update_virtual_url_with_url_(false), 45 page_id_(-1), 46 transition_type_(ui::PAGE_TRANSITION_LINK), 47 has_post_data_(false), 48 post_id_(-1), 49 restore_type_(RESTORE_NONE), 50 is_overriding_user_agent_(false), 51 http_status_code_(0), 52 is_renderer_initiated_(false), 53 should_replace_entry_(false), 54 should_clear_history_list_(false), 55 can_load_local_resources_(false), 56 frame_tree_node_id_(-1) { 57} 58 59NavigationEntryImpl::NavigationEntryImpl(SiteInstanceImpl* instance, 60 int page_id, 61 const GURL& url, 62 const Referrer& referrer, 63 const base::string16& title, 64 ui::PageTransition transition_type, 65 bool is_renderer_initiated) 66 : unique_id_(GetUniqueIDInConstructor()), 67 site_instance_(instance), 68 bindings_(kInvalidBindings), 69 page_type_(PAGE_TYPE_NORMAL), 70 url_(url), 71 referrer_(referrer), 72 update_virtual_url_with_url_(false), 73 title_(title), 74 page_id_(page_id), 75 transition_type_(transition_type), 76 has_post_data_(false), 77 post_id_(-1), 78 restore_type_(RESTORE_NONE), 79 is_overriding_user_agent_(false), 80 http_status_code_(0), 81 is_renderer_initiated_(is_renderer_initiated), 82 should_replace_entry_(false), 83 should_clear_history_list_(false), 84 can_load_local_resources_(false), 85 frame_tree_node_id_(-1) { 86} 87 88NavigationEntryImpl::~NavigationEntryImpl() { 89} 90 91int NavigationEntryImpl::GetUniqueID() const { 92 return unique_id_; 93} 94 95PageType NavigationEntryImpl::GetPageType() const { 96 return page_type_; 97} 98 99void NavigationEntryImpl::SetURL(const GURL& url) { 100 url_ = url; 101 cached_display_title_.clear(); 102} 103 104const GURL& NavigationEntryImpl::GetURL() const { 105 return url_; 106} 107 108void NavigationEntryImpl::SetBaseURLForDataURL(const GURL& url) { 109 base_url_for_data_url_ = url; 110} 111 112const GURL& NavigationEntryImpl::GetBaseURLForDataURL() const { 113 return base_url_for_data_url_; 114} 115 116void NavigationEntryImpl::SetReferrer(const Referrer& referrer) { 117 referrer_ = referrer; 118} 119 120const Referrer& NavigationEntryImpl::GetReferrer() const { 121 return referrer_; 122} 123 124void NavigationEntryImpl::SetVirtualURL(const GURL& url) { 125 virtual_url_ = (url == url_) ? GURL() : url; 126 cached_display_title_.clear(); 127} 128 129const GURL& NavigationEntryImpl::GetVirtualURL() const { 130 return virtual_url_.is_empty() ? url_ : virtual_url_; 131} 132 133void NavigationEntryImpl::SetTitle(const base::string16& title) { 134 title_ = title; 135 cached_display_title_.clear(); 136} 137 138const base::string16& NavigationEntryImpl::GetTitle() const { 139 return title_; 140} 141 142void NavigationEntryImpl::SetPageState(const PageState& state) { 143 page_state_ = state; 144} 145 146const PageState& NavigationEntryImpl::GetPageState() const { 147 return page_state_; 148} 149 150void NavigationEntryImpl::SetPageID(int page_id) { 151 page_id_ = page_id; 152} 153 154int32 NavigationEntryImpl::GetPageID() const { 155 return page_id_; 156} 157 158void NavigationEntryImpl::set_site_instance(SiteInstanceImpl* site_instance) { 159 site_instance_ = site_instance; 160} 161 162void NavigationEntryImpl::SetBindings(int bindings) { 163 // Ensure this is set to a valid value, and that it stays the same once set. 164 CHECK_NE(bindings, kInvalidBindings); 165 CHECK(bindings_ == kInvalidBindings || bindings_ == bindings); 166 bindings_ = bindings; 167} 168 169const base::string16& NavigationEntryImpl::GetTitleForDisplay( 170 const std::string& languages) const { 171 // Most pages have real titles. Don't even bother caching anything if this is 172 // the case. 173 if (!title_.empty()) 174 return title_; 175 176 // More complicated cases will use the URLs as the title. This result we will 177 // cache since it's more complicated to compute. 178 if (!cached_display_title_.empty()) 179 return cached_display_title_; 180 181 // Use the virtual URL first if any, and fall back on using the real URL. 182 base::string16 title; 183 if (!virtual_url_.is_empty()) { 184 title = net::FormatUrl(virtual_url_, languages); 185 } else if (!url_.is_empty()) { 186 title = net::FormatUrl(url_, languages); 187 } 188 189 // For file:// URLs use the filename as the title, not the full path. 190 if (url_.SchemeIsFile()) { 191 base::string16::size_type slashpos = title.rfind('/'); 192 if (slashpos != base::string16::npos) 193 title = title.substr(slashpos + 1); 194 } 195 196 gfx::ElideString(title, kMaxTitleChars, &cached_display_title_); 197 return cached_display_title_; 198} 199 200bool NavigationEntryImpl::IsViewSourceMode() const { 201 return virtual_url_.SchemeIs(kViewSourceScheme); 202} 203 204void NavigationEntryImpl::SetTransitionType( 205 ui::PageTransition transition_type) { 206 transition_type_ = transition_type; 207} 208 209ui::PageTransition NavigationEntryImpl::GetTransitionType() const { 210 return transition_type_; 211} 212 213const GURL& NavigationEntryImpl::GetUserTypedURL() const { 214 return user_typed_url_; 215} 216 217void NavigationEntryImpl::SetHasPostData(bool has_post_data) { 218 has_post_data_ = has_post_data; 219} 220 221bool NavigationEntryImpl::GetHasPostData() const { 222 return has_post_data_; 223} 224 225void NavigationEntryImpl::SetPostID(int64 post_id) { 226 post_id_ = post_id; 227} 228 229int64 NavigationEntryImpl::GetPostID() const { 230 return post_id_; 231} 232 233void NavigationEntryImpl::SetBrowserInitiatedPostData( 234 const base::RefCountedMemory* data) { 235 browser_initiated_post_data_ = data; 236} 237 238const base::RefCountedMemory* 239NavigationEntryImpl::GetBrowserInitiatedPostData() const { 240 return browser_initiated_post_data_.get(); 241} 242 243 244const FaviconStatus& NavigationEntryImpl::GetFavicon() const { 245 return favicon_; 246} 247 248FaviconStatus& NavigationEntryImpl::GetFavicon() { 249 return favicon_; 250} 251 252const SSLStatus& NavigationEntryImpl::GetSSL() const { 253 return ssl_; 254} 255 256SSLStatus& NavigationEntryImpl::GetSSL() { 257 return ssl_; 258} 259 260void NavigationEntryImpl::SetOriginalRequestURL(const GURL& original_url) { 261 original_request_url_ = original_url; 262} 263 264const GURL& NavigationEntryImpl::GetOriginalRequestURL() const { 265 return original_request_url_; 266} 267 268void NavigationEntryImpl::SetIsOverridingUserAgent(bool override) { 269 is_overriding_user_agent_ = override; 270} 271 272bool NavigationEntryImpl::GetIsOverridingUserAgent() const { 273 return is_overriding_user_agent_; 274} 275 276void NavigationEntryImpl::SetTimestamp(base::Time timestamp) { 277 timestamp_ = timestamp; 278} 279 280base::Time NavigationEntryImpl::GetTimestamp() const { 281 return timestamp_; 282} 283 284void NavigationEntryImpl::SetHttpStatusCode(int http_status_code) { 285 http_status_code_ = http_status_code; 286} 287 288int NavigationEntryImpl::GetHttpStatusCode() const { 289 return http_status_code_; 290} 291 292void NavigationEntryImpl::SetRedirectChain( 293 const std::vector<GURL>& redirect_chain) { 294 redirect_chain_ = redirect_chain; 295} 296 297const std::vector<GURL>& NavigationEntryImpl::GetRedirectChain() const { 298 return redirect_chain_; 299} 300 301bool NavigationEntryImpl::IsRestored() const { 302 return restore_type_ != RESTORE_NONE; 303} 304 305void NavigationEntryImpl::SetCanLoadLocalResources(bool allow) { 306 can_load_local_resources_ = allow; 307} 308 309bool NavigationEntryImpl::GetCanLoadLocalResources() const { 310 return can_load_local_resources_; 311} 312 313void NavigationEntryImpl::SetFrameToNavigate(const std::string& frame_name) { 314 frame_to_navigate_ = frame_name; 315} 316 317const std::string& NavigationEntryImpl::GetFrameToNavigate() const { 318 return frame_to_navigate_; 319} 320 321void NavigationEntryImpl::SetExtraData(const std::string& key, 322 const base::string16& data) { 323 extra_data_[key] = data; 324} 325 326bool NavigationEntryImpl::GetExtraData(const std::string& key, 327 base::string16* data) const { 328 std::map<std::string, base::string16>::const_iterator iter = 329 extra_data_.find(key); 330 if (iter == extra_data_.end()) 331 return false; 332 *data = iter->second; 333 return true; 334} 335 336void NavigationEntryImpl::ClearExtraData(const std::string& key) { 337 extra_data_.erase(key); 338} 339 340void NavigationEntryImpl::ResetForCommit() { 341 // Any state that only matters when a navigation entry is pending should be 342 // cleared here. 343 SetBrowserInitiatedPostData(NULL); 344 set_is_renderer_initiated(false); 345 set_transferred_global_request_id(GlobalRequestID()); 346 set_should_replace_entry(false); 347 348 set_should_clear_history_list(false); 349 set_frame_tree_node_id(-1); 350} 351 352void NavigationEntryImpl::SetScreenshotPNGData( 353 scoped_refptr<base::RefCountedBytes> png_data) { 354 screenshot_ = png_data; 355 if (screenshot_.get()) 356 UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); 357} 358 359} // namespace content 360