blob: 0e979bc48f3a78ca095712b151f475c767d6c7e2 [file] [log] [blame]
// Copyright 2014 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 "ios/web/navigation/navigation_item_impl.h"
#include <stddef.h>
#include <memory>
#include <utility>
#include "base/logging.h"
#include "components/url_formatter/url_formatter.h"
#include "ui/base/page_transition_types.h"
#include "ui/gfx/text_elider.h"
namespace {
// Returns a new unique ID for use in NavigationItem during construction. The
// returned ID is guaranteed to be nonzero (which is the "no ID" indicator).
static int GetUniqueIDInConstructor() {
static int unique_id_counter = 0;
return ++unique_id_counter;
}
} // namespace
namespace web {
// static
std::unique_ptr<NavigationItem> NavigationItem::Create() {
return std::unique_ptr<NavigationItem>(new NavigationItemImpl());
}
NavigationItemImpl::NavigationItemImpl()
: unique_id_(GetUniqueIDInConstructor()),
transition_type_(ui::PAGE_TRANSITION_LINK),
is_overriding_user_agent_(false),
is_created_from_push_state_(false),
should_skip_resubmit_data_confirmation_(false),
is_renderer_initiated_(false),
is_unsafe_(false),
facade_delegate_(nullptr) {
}
NavigationItemImpl::~NavigationItemImpl() {
}
NavigationItemImpl::NavigationItemImpl(const NavigationItemImpl& item)
: unique_id_(item.unique_id_),
url_(item.url_),
referrer_(item.referrer_),
virtual_url_(item.virtual_url_),
title_(item.title_),
page_display_state_(item.page_display_state_),
transition_type_(item.transition_type_),
favicon_(item.favicon_),
ssl_(item.ssl_),
timestamp_(item.timestamp_),
is_overriding_user_agent_(item.is_overriding_user_agent_),
http_request_headers_([item.http_request_headers_ copy]),
serialized_state_object_([item.serialized_state_object_ copy]),
is_created_from_push_state_(item.is_created_from_push_state_),
should_skip_resubmit_data_confirmation_(
item.should_skip_resubmit_data_confirmation_),
post_data_([item.post_data_ copy]),
is_renderer_initiated_(item.is_renderer_initiated_),
is_unsafe_(item.is_unsafe_),
cached_display_title_(item.cached_display_title_),
facade_delegate_(nullptr) {
}
void NavigationItemImpl::SetFacadeDelegate(
std::unique_ptr<NavigationItemFacadeDelegate> facade_delegate) {
facade_delegate_ = std::move(facade_delegate);
}
NavigationItemFacadeDelegate* NavigationItemImpl::GetFacadeDelegate() const {
return facade_delegate_.get();
}
int NavigationItemImpl::GetUniqueID() const {
return unique_id_;
}
void NavigationItemImpl::SetURL(const GURL& url) {
url_ = url;
cached_display_title_.clear();
}
const GURL& NavigationItemImpl::GetURL() const {
return url_;
}
void NavigationItemImpl::SetReferrer(const web::Referrer& referrer) {
referrer_ = referrer;
}
const web::Referrer& NavigationItemImpl::GetReferrer() const {
return referrer_;
}
void NavigationItemImpl::SetVirtualURL(const GURL& url) {
virtual_url_ = (url == url_) ? GURL() : url;
cached_display_title_.clear();
}
const GURL& NavigationItemImpl::GetVirtualURL() const {
return virtual_url_.is_empty() ? url_ : virtual_url_;
}
void NavigationItemImpl::SetTitle(const base::string16& title) {
title_ = title;
cached_display_title_.clear();
}
const base::string16& NavigationItemImpl::GetTitle() const {
return title_;
}
void NavigationItemImpl::SetPageDisplayState(
const web::PageDisplayState& display_state) {
page_display_state_ = display_state;
}
const PageDisplayState& NavigationItemImpl::GetPageDisplayState() const {
return page_display_state_;
}
const base::string16& NavigationItemImpl::GetTitleForDisplay() const {
// Most pages have real titles. Don't even bother caching anything if this is
// the case.
if (!title_.empty())
return title_;
// More complicated cases will use the URLs as the title. This result we will
// cache since it's more complicated to compute.
if (!cached_display_title_.empty())
return cached_display_title_;
// Use the virtual URL first if any, and fall back on using the real URL.
base::string16 title;
if (!virtual_url_.is_empty()) {
title = url_formatter::FormatUrl(virtual_url_);
} else if (!url_.is_empty()) {
title = url_formatter::FormatUrl(url_);
}
// For file:// URLs use the filename as the title, not the full path.
if (url_.SchemeIsFile()) {
base::string16::size_type slashpos = title.rfind('/');
if (slashpos != base::string16::npos)
title = title.substr(slashpos + 1);
}
const size_t kMaxTitleChars = 4 * 1024;
gfx::ElideString(title, kMaxTitleChars, &cached_display_title_);
return cached_display_title_;
}
void NavigationItemImpl::SetTransitionType(ui::PageTransition transition_type) {
transition_type_ = transition_type;
}
ui::PageTransition NavigationItemImpl::GetTransitionType() const {
return transition_type_;
}
const FaviconStatus& NavigationItemImpl::GetFavicon() const {
return favicon_;
}
FaviconStatus& NavigationItemImpl::GetFavicon() {
return favicon_;
}
const SSLStatus& NavigationItemImpl::GetSSL() const {
return ssl_;
}
SSLStatus& NavigationItemImpl::GetSSL() {
return ssl_;
}
void NavigationItemImpl::SetTimestamp(base::Time timestamp) {
timestamp_ = timestamp;
}
base::Time NavigationItemImpl::GetTimestamp() const {
return timestamp_;
}
void NavigationItemImpl::SetIsOverridingUserAgent(
bool is_overriding_user_agent) {
is_overriding_user_agent_ = is_overriding_user_agent;
}
bool NavigationItemImpl::IsOverridingUserAgent() const {
return is_overriding_user_agent_;
}
bool NavigationItemImpl::HasPostData() const {
return post_data_.get() != nil;
}
NSDictionary* NavigationItemImpl::GetHttpRequestHeaders() const {
return [[http_request_headers_ copy] autorelease];
}
void NavigationItemImpl::AddHttpRequestHeaders(
NSDictionary* additional_headers) {
if (!additional_headers)
return;
if (http_request_headers_)
[http_request_headers_ addEntriesFromDictionary:additional_headers];
else
http_request_headers_.reset([additional_headers mutableCopy]);
}
void NavigationItemImpl::SetSerializedStateObject(
NSString* serialized_state_object) {
serialized_state_object_.reset([serialized_state_object retain]);
}
NSString* NavigationItemImpl::GetSerializedStateObject() const {
return serialized_state_object_.get();
}
void NavigationItemImpl::SetIsCreatedFromPushState(bool push_state) {
is_created_from_push_state_ = push_state;
}
bool NavigationItemImpl::IsCreatedFromPushState() const {
return is_created_from_push_state_;
}
void NavigationItemImpl::SetShouldSkipResubmitDataConfirmation(bool skip) {
should_skip_resubmit_data_confirmation_ = skip;
}
bool NavigationItemImpl::ShouldSkipResubmitDataConfirmation() const {
return should_skip_resubmit_data_confirmation_;
}
void NavigationItemImpl::SetPostData(NSData* post_data) {
post_data_.reset([post_data retain]);
}
NSData* NavigationItemImpl::GetPostData() const {
return post_data_.get();
}
void NavigationItemImpl::RemoveHttpRequestHeaderForKey(NSString* key) {
DCHECK(key);
[http_request_headers_ removeObjectForKey:key];
if (![http_request_headers_ count])
http_request_headers_.reset();
}
void NavigationItemImpl::ResetHttpRequestHeaders() {
http_request_headers_.reset();
}
void NavigationItemImpl::ResetForCommit() {
// Any state that only matters when a navigation item is pending should be
// cleared here.
set_is_renderer_initiated(false);
}
} // namespace web