navigation_entry_impl.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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_(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                                         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    PageTransition transition_type) {
206  transition_type_ = transition_type;
207}
208
209PageTransition 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::SetCanLoadLocalResources(bool allow) {
293  can_load_local_resources_ = allow;
294}
295
296bool NavigationEntryImpl::GetCanLoadLocalResources() const {
297  return can_load_local_resources_;
298}
299
300void NavigationEntryImpl::SetFrameToNavigate(const std::string& frame_name) {
301  frame_to_navigate_ = frame_name;
302}
303
304const std::string& NavigationEntryImpl::GetFrameToNavigate() const {
305  return frame_to_navigate_;
306}
307
308void NavigationEntryImpl::SetExtraData(const std::string& key,
309                                       const base::string16& data) {
310  extra_data_[key] = data;
311}
312
313bool NavigationEntryImpl::GetExtraData(const std::string& key,
314                                       base::string16* data) const {
315  std::map<std::string, base::string16>::const_iterator iter =
316      extra_data_.find(key);
317  if (iter == extra_data_.end())
318    return false;
319  *data = iter->second;
320  return true;
321}
322
323void NavigationEntryImpl::ClearExtraData(const std::string& key) {
324  extra_data_.erase(key);
325}
326
327void NavigationEntryImpl::ResetForCommit() {
328  // Any state that only matters when a navigation entry is pending should be
329  // cleared here.
330  SetBrowserInitiatedPostData(NULL);
331  set_is_renderer_initiated(false);
332  set_transferred_global_request_id(GlobalRequestID());
333  set_should_replace_entry(false);
334  redirect_chain_.clear();
335  set_should_clear_history_list(false);
336  set_frame_tree_node_id(-1);
337}
338
339void NavigationEntryImpl::SetScreenshotPNGData(
340    scoped_refptr<base::RefCountedBytes> png_data) {
341  screenshot_ = png_data;
342  if (screenshot_.get())
343    UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size());
344}
345
346}  // namespace content
347