Commit aea81ada authored by stuartmorgan's avatar stuartmorgan Committed by Commit bot

Re-sync ios/web with downstream version

In-flight CLs that landed downstream during the upstreaming of these
files resulted in drift; this re-syncs the files to the latest
versions.

BUG=464810

Review URL: https://codereview.chromium.org/1106963003

Cr-Commit-Position: refs/heads/master@{#327059}
parent aeb8e893
......@@ -108,6 +108,7 @@
'public/web_state/web_state_observer_bridge.h',
'public/web_thread.h',
'public/web_view_type.h',
'public/web_view_util.h',
'string_util.cc',
'ui_web_view_util.h',
'ui_web_view_util.mm',
......@@ -150,7 +151,6 @@
'web_thread.cc',
'web_thread_impl.cc',
'web_thread_impl.h',
'web_view_util.h',
'web_view_util.mm',
],
'link_settings': {
......
......@@ -184,7 +184,7 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
for (size_t i = 0; i < items.size(); ++i) {
scoped_ptr<web::NavigationItem> item(items[i]);
base::scoped_nsobject<CRWSessionEntry> entry(
[[CRWSessionEntry alloc] initWithNavigationItem:item.Pass() index:i]);
[[CRWSessionEntry alloc] initWithNavigationItem:item.Pass()]);
[_entries addObject:entry];
}
_currentNavigationIndex = currentIndex;
......@@ -326,11 +326,9 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
// (a) new (non-history), browser-initiated navigations, and
// (b) pending unsafe navigations (while showing the interstitial)
// in order to prevent URL spoof attacks.
web::NavigationItemImpl* pendingItemImpl =
static_cast<web::NavigationItemImpl*>([_pendingEntry navigationItem]);
if (_pendingEntry &&
(!pendingItemImpl->is_renderer_initiated() ||
pendingItemImpl->IsUnsafe())) {
web::NavigationItemImpl* pendingItem = [_pendingEntry navigationItemImpl];
if (pendingItem &&
(!pendingItem->is_renderer_initiated() || pendingItem->IsUnsafe())) {
return _pendingEntry.get();
}
return [self lastCommittedEntry];
......@@ -397,8 +395,10 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
}
}
BOOL useDesktopUserAgent = _useDesktopUserAgentForNextPendingEntry ||
self.currentEntry.useDesktopUserAgent;
BOOL useDesktopUserAgent =
_useDesktopUserAgentForNextPendingEntry ||
(self.currentEntry.navigationItem &&
self.currentEntry.navigationItem->IsOverridingUserAgent());
_useDesktopUserAgentForNextPendingEntry = NO;
_pendingEntry.reset([[self sessionEntryWithURL:url
referrer:ref
......@@ -418,18 +418,17 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
// session history. Don't modify the entry list.
if (!_pendingEntry)
return;
web::NavigationItem* item = [_pendingEntry navigationItem];
web::NavigationItemImpl* item = [_pendingEntry navigationItemImpl];
if (url != item->GetURL()) {
item->SetURL(url);
item->SetVirtualURL(url);
// Since updates are caused by page redirects, they are renderer-initiated.
web::NavigationItemImpl* pendingItemImpl =
static_cast<web::NavigationItemImpl*>([_pendingEntry navigationItem]);
pendingItemImpl->set_is_renderer_initiated(true);
item->set_is_renderer_initiated(true);
// Redirects (3xx response code), or client side navigation must change
// POST requests to GETs.
[_pendingEntry setPOSTData:nil];
[_pendingEntry resetHTTPHeaders];
item->SetPostData(nil);
item->ResetHttpRequestHeaders();
}
// This should probably not be sent if the URLs matched, but that's what was
......@@ -472,9 +471,7 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
_currentNavigationIndex = [_entries count] - 1;
// Once an entry is committed it's not renderer-initiated any more. (Matches
// the implementation in NavigationController.)
web::NavigationItemImpl* pendingItemImpl =
static_cast<web::NavigationItemImpl*>([_pendingEntry navigationItem]);
pendingItemImpl->ResetForCommit();
[_pendingEntry navigationItemImpl]->ResetForCommit();
_pendingEntry.reset();
}
......@@ -526,14 +523,17 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
CHECK(
web::history_state_util::IsHistoryStateChangeValid(item->GetURL(), url));
web::Referrer referrer(item->GetURL(), web::ReferrerPolicyDefault);
bool overrideUserAgent =
self.currentEntry.navigationItem->IsOverridingUserAgent();
base::scoped_nsobject<CRWSessionEntry> pushedEntry(
[[self sessionEntryWithURL:url
referrer:referrer
transition:ui::PAGE_TRANSITION_LINK
useDesktopUserAgent:self.currentEntry.useDesktopUserAgent
useDesktopUserAgent:overrideUserAgent
rendererInitiated:NO] retain]);
pushedEntry.get().serializedStateObject = stateObject;
pushedEntry.get().createdFromPushState = YES;
web::NavigationItemImpl* pushedItem = [pushedEntry navigationItemImpl];
pushedItem->SetSerializedStateObject(stateObject);
pushedItem->SetIsCreatedFromPushState(true);
web::SSLStatus& sslStatus = [self currentEntry].navigationItem->GetSSL();
pushedEntry.get().navigationItem->GetSSL() = sslStatus;
......@@ -551,8 +551,10 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
stateObject:(NSString*)stateObject {
DCHECK(!_transientEntry);
CRWSessionEntry* currentEntry = self.currentEntry;
web::NavigationItemImpl* currentItem = self.currentEntry.navigationItemImpl;
currentItem->SetURL(url);
currentItem->SetSerializedStateObject(stateObject);
currentEntry.navigationItem->SetURL(url);
currentEntry.serializedStateObject = stateObject;
// If the change is to a committed entry, notify interested parties.
if (currentEntry != self.pendingEntry && _navigationManager)
_navigationManager->OnNavigationItemChanged();
......@@ -808,15 +810,14 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
NSUInteger endIndex = firstIndex < secondIndex ? secondIndex : firstIndex;
for (NSUInteger i = startIndex + 1; i <= endIndex; i++) {
CRWSessionEntry* entry = [_entries objectAtIndex:i];
web::NavigationItemImpl* item = [_entries[i] navigationItemImpl];
// Every entry in the sequence has to be created from a pushState() call.
if (!entry.createdFromPushState)
if (!item->IsCreatedFromPushState())
return NO;
// Every entry in the sequence has to have a URL that could have been
// created from a pushState() call.
if (!web::history_state_util::IsHistoryStateChangeValid(
firstEntry.navigationItem->GetURL(),
entry.navigationItem->GetURL()))
firstEntry.navigationItem->GetURL(), item->GetURL()))
return NO;
}
return YES;
......@@ -839,7 +840,7 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
- (void)useDesktopUserAgentForNextPendingEntry {
if (_pendingEntry)
[_pendingEntry setUseDesktopUserAgent:YES];
[_pendingEntry navigationItem]->SetIsOverridingUserAgent(true);
else
_useDesktopUserAgentForNextPendingEntry = YES;
}
......@@ -864,11 +865,13 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
GURL loaded_url(url);
web::BrowserURLRewriter::GetInstance()->RewriteURLIfNecessary(&loaded_url,
_browserState);
return [[[CRWSessionEntry alloc] initWithUrl:loaded_url
referrer:referrer
transition:transition
useDesktopUserAgent:useDesktopUserAgent
rendererInitiated:rendererInitiated] autorelease];
scoped_ptr<web::NavigationItemImpl> item(new web::NavigationItemImpl());
item->SetURL(loaded_url);
item->SetReferrer(referrer);
item->SetTransitionType(transition);
item->SetIsOverridingUserAgent(useDesktopUserAgent);
item->set_is_renderer_initiated(rendererInitiated);
return [[CRWSessionEntry alloc] initWithNavigationItem:item.Pass()];
}
@end
......@@ -837,11 +837,12 @@ TEST_F(CRWSessionControllerTest, PushNewEntry) {
NSString* stateObject1 = @"{'foo': 1}";
[controller pushNewEntryWithURL:pushPageGurl1 stateObject:stateObject1];
CRWSessionEntry* pushedEntry = [controller currentEntry];
web::NavigationItemImpl* pushedItem = pushedEntry.navigationItemImpl;
NSUInteger expectedCount = 2;
EXPECT_EQ(expectedCount, controller.get().entries.count);
EXPECT_EQ(pushPageGurl1, pushedEntry.navigationItem->GetURL());
EXPECT_TRUE(pushedEntry.createdFromPushState);
EXPECT_NSEQ(stateObject1, pushedEntry.serializedStateObject);
EXPECT_TRUE(pushedItem->IsCreatedFromPushState());
EXPECT_NSEQ(stateObject1, pushedItem->GetSerializedStateObject());
EXPECT_EQ(GURL("http://www.firstpage.com/"),
pushedEntry.navigationItem->GetReferrer().url);
......@@ -849,11 +850,12 @@ TEST_F(CRWSessionControllerTest, PushNewEntry) {
GURL pushPageGurl2("http://www.firstpage.com/push2");
[controller pushNewEntryWithURL:pushPageGurl2 stateObject:nil];
pushedEntry = [controller currentEntry];
pushedItem = pushedEntry.navigationItemImpl;
expectedCount = 3;
EXPECT_EQ(expectedCount, controller.get().entries.count);
EXPECT_EQ(pushPageGurl2, pushedEntry.navigationItem->GetURL());
EXPECT_TRUE(pushedEntry.createdFromPushState);
EXPECT_EQ(nil, pushedEntry.serializedStateObject);
EXPECT_TRUE(pushedItem->IsCreatedFromPushState());
EXPECT_EQ(nil, pushedItem->GetSerializedStateObject());
EXPECT_EQ(pushPageGurl1, pushedEntry.navigationItem->GetReferrer().url);
}
......@@ -884,9 +886,9 @@ TEST_F(CRWSessionControllerTest, IsPushStateNavigation) {
CRWSessionEntry* entry3 = [controller.get().entries objectAtIndex:3];
CRWSessionEntry* entry4 = [controller.get().entries objectAtIndex:4];
CRWSessionEntry* entry5 = [controller.get().entries objectAtIndex:5];
entry1.createdFromPushState = YES;
entry4.createdFromPushState = YES;
entry5.createdFromPushState = YES;
entry1.navigationItemImpl->SetIsCreatedFromPushState(true);
entry4.navigationItemImpl->SetIsCreatedFromPushState(true);
entry5.navigationItemImpl->SetIsCreatedFromPushState(true);
EXPECT_TRUE(
[controller isPushStateNavigationBetweenEntry:entry0 andEntry:entry1]);
......@@ -923,11 +925,12 @@ TEST_F(CRWSessionControllerTest, UpdateCurrentEntry) {
[controller updateCurrentEntryWithURL:replacePageGurl1
stateObject:stateObject1];
CRWSessionEntry* replacedEntry = [controller currentEntry];
web::NavigationItemImpl* replacedItem = replacedEntry.navigationItemImpl;
NSUInteger expectedCount = 3;
EXPECT_EQ(expectedCount, controller.get().entries.count);
EXPECT_EQ(replacePageGurl1, replacedEntry.navigationItem->GetURL());
EXPECT_FALSE(replacedEntry.createdFromPushState);
EXPECT_NSEQ(stateObject1, replacedEntry.serializedStateObject);
EXPECT_FALSE(replacedItem->IsCreatedFromPushState());
EXPECT_NSEQ(stateObject1, replacedItem->GetSerializedStateObject());
EXPECT_EQ(GURL("http://www.starturl.com/"),
replacedEntry.navigationItem->GetReferrer().url);
......@@ -935,10 +938,11 @@ TEST_F(CRWSessionControllerTest, UpdateCurrentEntry) {
GURL replacePageGurl2("http://www.firstpage.com/#replace2");
[controller.get() updateCurrentEntryWithURL:replacePageGurl2 stateObject:nil];
replacedEntry = [controller currentEntry];
replacedItem = replacedEntry.navigationItemImpl;
EXPECT_EQ(expectedCount, controller.get().entries.count);
EXPECT_EQ(replacePageGurl2, replacedEntry.navigationItem->GetURL());
EXPECT_FALSE(replacedEntry.createdFromPushState);
EXPECT_NSEQ(nil, replacedEntry.serializedStateObject);
EXPECT_FALSE(replacedItem->IsCreatedFromPushState());
EXPECT_NSEQ(nil, replacedItem->GetSerializedStateObject());
EXPECT_EQ(GURL("http://www.starturl.com/"),
replacedEntry.navigationItem->GetReferrer().url);
}
......
......@@ -15,6 +15,7 @@
namespace web {
class NavigationItem;
class NavigationItemImpl;
struct Referrer;
}
......@@ -25,40 +26,22 @@ struct Referrer;
// TODO(rohitrao): Fold CRWSessionEntry's logic into NavigationItem.
@interface CRWSessionEntry : NSObject<NSCoding, NSCopying>
@property(nonatomic, assign) NSInteger index;
@property(nonatomic, readonly) const GURL& originalUrl;
@property(nonatomic, assign) BOOL useDesktopUserAgent;
@property(nonatomic, assign) BOOL usedDataReductionProxy;
@property(nonatomic, retain) NSString* serializedStateObject;
@property(nonatomic, assign) BOOL createdFromPushState;
@property(nonatomic, retain) NSData* POSTData;
@property(nonatomic, readonly) NSDictionary* httpHeaders;
@property(nonatomic, assign) BOOL skipResubmitDataConfirmation;
// Initialize the session entry with the given url.
- (id)initWithUrl:(const GURL&)url
referrer:(const web::Referrer&)referrer
transition:(ui::PageTransition)transition
useDesktopUserAgent:(BOOL)useDesktopUserAgent
rendererInitiated:(BOOL)rendererInitiated;
// Initialize the session entry with the given NavigationItem.
- (id)initWithNavigationItem:(scoped_ptr<web::NavigationItem>)item
index:(int)index;
// Returns a pointer to the NavigationItem associated with this CRWSessionEntry.
// Pointer to the NavigationItem associated with this CRWSessionEntry.
// Eventually, this will replace CRWSessionEntry entirely.
- (web::NavigationItem*)navigationItem;
@property(nonatomic, readonly) web::NavigationItem* navigationItem;
// Adds headers from |moreHTTPHeaders| to |httpHeaders|; existing headers with
// the same key will be overridden.
- (void)addHTTPHeaders:(NSDictionary*)moreHTTPHeaders;
// Pointer to the NavigationItemImpl associated with this CRWSessionEntry.
// TODO(kkhorimoto): This is a convenience property to avoid requiring static
// casts every time the web layer needs access to members only available in
// NavigationItemImpl. Remove once more navigation management moves into
// NavigationManager and CRWSessionEntry=>web::NavigationItemImpl conversions
// become less prominent.
@property(nonatomic, readonly) web::NavigationItemImpl* navigationItemImpl;
// Removes the header for the given key from |httpHeaders|.
- (void)removeHTTPHeaderForKey:(NSString*)key;
// Resets |httpHeaders| to nil.
- (void)resetHTTPHeaders;
// Initialize the session entry with the given NavigationItem.
- (instancetype)initWithNavigationItem:(scoped_ptr<web::NavigationItem>)item;
@end
......
......@@ -24,46 +24,11 @@ NSString* const kZoomScaleKey = @"zoom";
}
@interface CRWSessionEntry () {
// The index in the CRWSessionController.
//
// This is used when determining the selected CRWSessionEntry and only useful
// to the SessionServiceIOS.
NSInteger _index;
// The original URL of the page. In cases where a redirect occurred, |url_|
// will contain the final post-redirect URL, and |originalUrl_| will contain
// the pre-redirect URL. This field is not persisted to disk.
GURL _originalUrl;
// Headers passed along with the request. For POST requests, these are
// persisted, to be able to resubmit them. Some specialized non-POST requests
// may also pass custom headers.
base::scoped_nsobject<NSMutableDictionary> _httpHeaders;
// Data submitted with a POST request, persisted for resubmits.
NSData* _POSTData;
// Serialized representation of the state object that was used in conjunction
// with a JavaScript window.history.pushState() or
// window.history.replaceState() call that created or modified this
// CRWSessionEntry. Intended to be used for JavaScript history operations and
// will be nil in most cases.
NSString* _serializedStateObject;
// Whether or not this entry was created by calling history.pushState().
BOOL _createdFromPushState;
// If |YES| use a desktop user agent in HTTP requests and UIWebView.
BOOL _useDesktopUserAgent;
// If |YES| the page was last fetched through the data reduction proxy.
BOOL _usedDataReductionProxy;
// Whether or not to bypass showing the resubmit data confirmation when
// loading a POST request. Set to YES for browser-generated POST requests such
// as search-by-image requests.
BOOL _skipResubmitDataConfirmation;
// The NavigationItemImpl corresponding to this CRWSessionEntry.
// TODO(stuartmorgan): Move ownership to NavigationManagerImpl.
scoped_ptr<web::NavigationItemImpl> _navigationItem;
......@@ -84,48 +49,15 @@ NSString* const kZoomScaleKey = @"zoom";
@implementation CRWSessionEntry
@synthesize POSTData = _POSTData;
@synthesize originalUrl = _originalUrl;
@synthesize useDesktopUserAgent = _useDesktopUserAgent;
@synthesize usedDataReductionProxy = _usedDataReductionProxy;
@synthesize index = _index;
@synthesize serializedStateObject = _serializedStateObject;
@synthesize createdFromPushState = _createdFromPushState;
@synthesize skipResubmitDataConfirmation = _skipResubmitDataConfirmation;
// Creates a new session entry. These may be nil.
- (instancetype)initWithUrl:(const GURL&)url
referrer:(const web::Referrer&)referrer
transition:(ui::PageTransition)transition
useDesktopUserAgent:(BOOL)useDesktopUserAgent
rendererInitiated:(BOOL)rendererInitiated {
self = [super init];
if (self) {
_propertyReleaser_CRWSessionEntry.Init(self, [CRWSessionEntry class]);
_navigationItem.reset(new web::NavigationItemImpl());
_navigationItem->SetURL(url);
_navigationItem->SetReferrer(referrer);
_navigationItem->SetTransitionType(transition);
_navigationItem->set_is_renderer_initiated(rendererInitiated);
self.originalUrl = url;
self.useDesktopUserAgent = useDesktopUserAgent;
}
return self;
}
- (instancetype)initWithNavigationItem:(scoped_ptr<web::NavigationItem>)item
index:(int)index {
- (instancetype)initWithNavigationItem:(scoped_ptr<web::NavigationItem>)item {
self = [super init];
if (self) {
_propertyReleaser_CRWSessionEntry.Init(self, [CRWSessionEntry class]);
_navigationItem.reset(
static_cast<web::NavigationItemImpl*>(item.release()));
self.index = index;
self.originalUrl = _navigationItem->GetURL();
self.useDesktopUserAgent = NO;
}
return self;
}
......@@ -177,15 +109,13 @@ NSString* const kZoomScaleKey = @"zoom";
_navigationItem->SetTransitionType(ui::PAGE_TRANSITION_RELOAD);
_navigationItem->SetPageScrollState([[self class]
scrollStateFromDictionary:[aDecoder decodeObjectForKey:@"state"]]);
self.index = [aDecoder decodeIntForKey:@"index"];
self.useDesktopUserAgent =
[aDecoder decodeBoolForKey:@"useDesktopUserAgent"];
self.usedDataReductionProxy =
[aDecoder decodeBoolForKey:@"usedDataReductionProxy"];
[self addHTTPHeaders:[aDecoder decodeObjectForKey:@"httpHeaders"]];
self.POSTData = [aDecoder decodeObjectForKey:@"POSTData"];
self.skipResubmitDataConfirmation =
[aDecoder decodeBoolForKey:@"skipResubmitDataConfirmation"];
_navigationItem->SetShouldSkipResubmitDataConfirmation(
[aDecoder decodeBoolForKey:@"skipResubmitDataConfirmation"]);
_navigationItem->SetIsOverridingUserAgent(
[aDecoder decodeBoolForKey:@"useDesktopUserAgent"]);
_navigationItem->SetPostData([aDecoder decodeObjectForKey:@"POSTData"]);
_navigationItem->AddHttpRequestHeaders(
[aDecoder decodeObjectForKey:@"httpHeaders"]);
}
return self;
}
......@@ -193,7 +123,6 @@ NSString* const kZoomScaleKey = @"zoom";
- (void)encodeWithCoder:(NSCoder*)aCoder {
// Desktop Chrome doesn't persist |url_| or |originalUrl_|, only
// |virtualUrl_|.
[aCoder encodeInt:self.index forKey:@"index"];
web::nscoder_util::EncodeString(aCoder, @"virtualUrlString",
_navigationItem->GetVirtualURL().spec());
web::nscoder_util::EncodeString(aCoder, @"referrerUrlString",
......@@ -208,13 +137,13 @@ NSString* const kZoomScaleKey = @"zoom";
[aCoder encodeObject:[[self class] dictionaryFromScrollState:
_navigationItem->GetPageScrollState()]
forKey:@"state"];
[aCoder encodeBool:self.useDesktopUserAgent forKey:@"useDesktopUserAgent"];
[aCoder encodeBool:self.usedDataReductionProxy
forKey:@"usedDataReductionProxy"];
[aCoder encodeObject:self.httpHeaders forKey:@"httpHeaders"];
[aCoder encodeObject:self.POSTData forKey:@"POSTData"];
[aCoder encodeBool:self.skipResubmitDataConfirmation
[aCoder encodeBool:_navigationItem->ShouldSkipResubmitDataConfirmation()
forKey:@"skipResubmitDataConfirmation"];
[aCoder encodeBool:_navigationItem->IsOverridingUserAgent()
forKey:@"useDesktopUserAgent"];
[aCoder encodeObject:_navigationItem->GetPostData() forKey:@"POSTData"];
[aCoder encodeObject:_navigationItem->GetHttpRequestHeaders()
forKey:@"httpHeaders"];
}
// TODO(ios): Shall we overwrite EqualTo:?
......@@ -224,13 +153,7 @@ NSString* const kZoomScaleKey = @"zoom";
copy->_propertyReleaser_CRWSessionEntry.Init(copy, [CRWSessionEntry class]);
copy->_navigationItem.reset(
new web::NavigationItemImpl(*_navigationItem.get()));
copy->_index = _index;
copy->_originalUrl = _originalUrl;
copy->_useDesktopUserAgent = _useDesktopUserAgent;
copy->_usedDataReductionProxy = _usedDataReductionProxy;
copy->_POSTData = [_POSTData copy];
copy->_httpHeaders.reset([_httpHeaders mutableCopy]);
copy->_skipResubmitDataConfirmation = _skipResubmitDataConfirmation;
return copy;
}
......@@ -238,40 +161,22 @@ NSString* const kZoomScaleKey = @"zoom";
return [NSString
stringWithFormat:
@"url:%@ originalurl:%@ title:%@ transition:%d scrollState:%@ "
@"desktopUA:%d " @"proxy:%d",
@"desktopUA:%d",
base::SysUTF8ToNSString(_navigationItem->GetURL().spec()),
base::SysUTF8ToNSString(self.originalUrl.spec()),
base::SysUTF16ToNSString(_navigationItem->GetTitle()),
_navigationItem->GetTransitionType(),
[[self class]
scrollStateDescription:_navigationItem->GetPageScrollState()],
_useDesktopUserAgent, _usedDataReductionProxy];
_navigationItem->IsOverridingUserAgent()];
}
- (web::NavigationItem*)navigationItem {
return _navigationItem.get();
}
- (NSDictionary*)httpHeaders {
return _httpHeaders ? [NSDictionary dictionaryWithDictionary:_httpHeaders]
: nil;
}
- (void)addHTTPHeaders:(NSDictionary*)moreHTTPHeaders {
if (_httpHeaders)
[_httpHeaders addEntriesFromDictionary:moreHTTPHeaders];
else
_httpHeaders.reset([moreHTTPHeaders mutableCopy]);
}
- (void)removeHTTPHeaderForKey:(NSString*)key {
[_httpHeaders removeObjectForKey:key];
if (![_httpHeaders count])
_httpHeaders.reset();
}
- (void)resetHTTPHeaders {
_httpHeaders.reset();
- (web::NavigationItemImpl*)navigationItemImpl {
return _navigationItem.get();
}
#pragma mark - Serialization helpers
......
......@@ -6,6 +6,7 @@
#define IOS_WEB_NAVIGATION_NAVIGATION_ITEM_IMPL_H_
#include "base/basictypes.h"
#include "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "ios/web/navigation/navigation_item_facade_delegate.h"
......@@ -15,7 +16,6 @@
#include "ios/web/public/ssl_status.h"
#include "url/gurl.h"
namespace web {
class NavigationItemFacadeDelegate;
......@@ -64,6 +64,38 @@ class NavigationItemImpl : public web::NavigationItem {
base::Time GetTimestamp() const override;
void SetUnsafe(bool is_unsafe) override;
bool IsUnsafe() const override;
void SetIsOverridingUserAgent(bool is_overriding_user_agent) override;
bool IsOverridingUserAgent() const override;
bool HasPostData() const override;
NSDictionary* GetHttpRequestHeaders() const override;
void AddHttpRequestHeaders(NSDictionary* additional_headers) override;
// Serialized representation of the state object that was used in conjunction
// with a JavaScript window.history.pushState() or
// window.history.replaceState() call that created or modified this
// CRWSessionEntry. Intended to be used for JavaScript history operations and
// will be nil in most cases.
void SetSerializedStateObject(NSString* serialized_state_object);
NSString* GetSerializedStateObject() const;
// Whether or not this item was created by calling history.pushState().
void SetIsCreatedFromPushState(bool push_state);
bool IsCreatedFromPushState() const;
// Whether or not to bypass showing the resubmit data confirmation when
// loading a POST request. Set to YES for browser-generated POST requests.
void SetShouldSkipResubmitDataConfirmation(bool skip);
bool ShouldSkipResubmitDataConfirmation() const;
// Data submitted with a POST request, persisted for resubmits.
void SetPostData(NSData* post_data);
NSData* GetPostData() const;
// Removes the header for |key| from |http_request_headers_|.
void RemoveHttpRequestHeaderForKey(NSString* key);
// Removes all http headers from |http_request_headers_|.
void ResetHttpRequestHeaders();
// Once a navigation item is committed, we should no longer track
// non-persisted state, as documented on the members below.
......@@ -88,6 +120,13 @@ class NavigationItemImpl : public web::NavigationItem {
FaviconStatus favicon_;
SSLStatus ssl_;
base::Time timestamp_;
bool is_overriding_user_agent_;
base::scoped_nsobject<NSMutableDictionary> http_request_headers_;
base::scoped_nsobject<NSString> serialized_state_object_;
bool is_created_from_push_state_;
bool should_skip_resubmit_data_confirmation_;
base::scoped_nsobject<NSData> post_data_;
// Whether the item, while loading, was created for a renderer-initiated
// navigation. This dictates whether the URL should be displayed before the
......
......@@ -32,6 +32,9 @@ NavigationItemImpl::NavigationItemImpl()
: unique_id_(GetUniqueIDInConstructor()),
page_id_(-1),
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) {
......@@ -52,6 +55,13 @@ NavigationItemImpl::NavigationItemImpl(const NavigationItemImpl& item)
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_),
......@@ -187,12 +197,6 @@ base::Time NavigationItemImpl::GetTimestamp() const {
return timestamp_;
}
void NavigationItemImpl::ResetForCommit() {
// Any state that only matters when a navigation item is pending should be
// cleared here.
set_is_renderer_initiated(false);
}
void NavigationItemImpl::SetUnsafe(bool is_unsafe) {
is_unsafe_ = is_unsafe;
}
......@@ -201,4 +205,82 @@ bool NavigationItemImpl::IsUnsafe() const {
return is_unsafe_;
}
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
......@@ -5,6 +5,7 @@
#include "base/logging.h"
#include "base/mac/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/sys_string_conversions.h"
#include "ios/web/navigation/navigation_item_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
......@@ -13,10 +14,23 @@
namespace web {
namespace {
static NSString* const kHTTPHeaderKey1 = @"key1";
static NSString* const kHTTPHeaderKey2 = @"key2";
static NSString* const kHTTPHeaderValue1 = @"value1";
static NSString* const kHTTPHeaderValue2 = @"value2";
class NavigationItemTest : public PlatformTest {
protected:
void SetUp() override { item_.reset(new NavigationItemImpl()); }
void SetUp() override {
item_.reset(new web::NavigationItemImpl());
item_->SetURL(GURL("http://init.test"));
item_->SetTransitionType(ui::PAGE_TRANSITION_AUTO_BOOKMARK);
item_->SetTimestamp(base::Time::Now());
item_->AddHttpRequestHeaders(@{kHTTPHeaderKey1 : kHTTPHeaderValue1});
item_->SetPostData([@"Test data" dataUsingEncoding:NSUTF8StringEncoding]);
}
// The NavigationItemImpl instance being tested.
scoped_ptr<NavigationItemImpl> item_;
};
......@@ -27,5 +41,71 @@ TEST_F(NavigationItemTest, Dummy) {
EXPECT_TRUE(item_->GetURL().is_valid());
}
// Tests that copied NavigationItemImpls create copies of data members that are
// objects.
TEST_F(NavigationItemTest, Copy) {
// Create objects to be copied.
NSString* postData0 = @"postData0";
NSMutableData* mutablePostData =
[[postData0 dataUsingEncoding:NSUTF8StringEncoding] mutableCopy];
item_->SetPostData(mutablePostData);
NSString* state0 = @"state0";
NSMutableString* mutableState = [state0 mutableCopy];
item_->SetSerializedStateObject(mutableState);
// Create copy.
web::NavigationItemImpl copy(*item_.get());
// Modify the objects.
NSString* postData1 = @"postData1";
[mutablePostData setData:[postData1 dataUsingEncoding:NSUTF8StringEncoding]];
NSString* state1 = @"state1";
[mutableState setString:state1];
// Check that changes occurred in |item_|, but not in |copy|.
EXPECT_NSEQ([postData1 dataUsingEncoding:NSUTF8StringEncoding],
item_->GetPostData());
EXPECT_NSEQ(state1, item_->GetSerializedStateObject());
EXPECT_NSEQ([postData0 dataUsingEncoding:NSUTF8StringEncoding],
copy.GetPostData());
EXPECT_NSEQ(state0, copy.GetSerializedStateObject());
}
// Tests whether |NavigationItem::AddHttpRequestHeaders()| adds the passed
// headers to the item's request http headers.
TEST_F(NavigationItemTest, AddHttpRequestHeaders) {
EXPECT_NSEQ(@{kHTTPHeaderKey1 : kHTTPHeaderValue1},
item_->GetHttpRequestHeaders());
item_->AddHttpRequestHeaders(@{kHTTPHeaderKey1 : kHTTPHeaderValue2});
EXPECT_NSEQ(@{kHTTPHeaderKey1 : kHTTPHeaderValue2},
item_->GetHttpRequestHeaders());
item_->AddHttpRequestHeaders(@{kHTTPHeaderKey2 : kHTTPHeaderValue1});
NSDictionary* expected = @{
kHTTPHeaderKey1 : kHTTPHeaderValue2,
kHTTPHeaderKey2 : kHTTPHeaderValue1
};
EXPECT_NSEQ(expected, item_->GetHttpRequestHeaders());
}
// Tests whether |NavigationItem::AddHttpRequestHeaders()| removes the header
// value associated with the passed key from the item's request http headers.
TEST_F(NavigationItemTest, RemoveHttpRequestHeaderForKey) {
NSDictionary* httpHeaders = @{
kHTTPHeaderKey1 : kHTTPHeaderValue1,
kHTTPHeaderKey2 : kHTTPHeaderValue2
};
item_->AddHttpRequestHeaders(httpHeaders);
EXPECT_NSEQ(httpHeaders, item_->GetHttpRequestHeaders());
item_->RemoveHttpRequestHeaderForKey(kHTTPHeaderKey1);
EXPECT_NSEQ(@{kHTTPHeaderKey2 : kHTTPHeaderValue2},
item_->GetHttpRequestHeaders());
item_->RemoveHttpRequestHeaderForKey(kHTTPHeaderKey2);
EXPECT_FALSE(item_->GetHttpRequestHeaders());
}
} // namespace
} // namespace web
......@@ -14,8 +14,4 @@ specific_include_rules = {
"^.*\.h$": [
"-content",
],
# TODO(eugenebut): make web_view_util.h public.
"web_test_util": [
"+ios/web/web_view_util.h",
],
}
......@@ -13,6 +13,12 @@
class GURL;
#if defined(__OBJC__)
@class NSDictionary;
#else
class NSDictionary;
#endif // __OBJC__
namespace web {
struct FaviconStatus;
struct Referrer;
......@@ -114,6 +120,21 @@ class NavigationItem {
// property doesn't get serialized.
virtual void SetUnsafe(bool is_unsafe) = 0;
virtual bool IsUnsafe() const = 0;
// |true| if this item uses a desktop user agent in HTTP requests and
// UIWebView.
virtual void SetIsOverridingUserAgent(bool is_overriding_user_agent) = 0;
virtual bool IsOverridingUserAgent() const = 0;
// |true| if this item is the result of a POST request with data.
virtual bool HasPostData() const = 0;
// Returns the item's current http request headers.
virtual NSDictionary* GetHttpRequestHeaders() const = 0;
// Adds headers from |additional_headers| to the item's http request headers.
// Existing headers with the same key will be overridden.
virtual void AddHttpRequestHeaders(NSDictionary* additional_headers) = 0;
};
} // namespace web
......
......@@ -5,7 +5,7 @@
#ifndef IOS_WEB_PUBLIC_TEST_WEB_TEST_UTIL_H_
#define IOS_WEB_PUBLIC_TEST_WEB_TEST_UTIL_H_
#include "ios/web/web_view_util.h"
#include "ios/web/public/web_view_util.h"
// A helper macro that allows skipping a unit test on iOS7 and earlier. Example:
//
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_WEB_WEB_VIEW_UTIL_H_
#define IOS_WEB_WEB_VIEW_UTIL_H_
#ifndef IOS_WEB_PUBLIC_WEB_VIEW_UTIL_H_
#define IOS_WEB_PUBLIC_WEB_VIEW_UTIL_H_
namespace web {
......@@ -12,4 +12,4 @@ bool IsWKWebViewSupported();
} // web
#endif // IOS_WEB_WEB_VIEW_UTIL_H_
#endif // IOS_WEB_PUBLIC_WEB_VIEW_UTIL_H_
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ios/web/web_view_util.h"
#include "ios/web/public/web_view_util.h"
#include <Foundation/Foundation.h>
#include <sys/sysctl.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment