| Index: ios/web/navigation/crw_session_entry.mm
|
| diff --git a/ios/web/navigation/crw_session_entry.mm b/ios/web/navigation/crw_session_entry.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..10799f1dc36b76faa96d79b17a8acc7bebaa7065
|
| --- /dev/null
|
| +++ b/ios/web/navigation/crw_session_entry.mm
|
| @@ -0,0 +1,264 @@
|
| +// Copyright 2012 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.
|
| +
|
| +#import "ios/web/navigation/crw_session_entry.h"
|
| +
|
| +#include "base/mac/objc_property_releaser.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 "ios/web/navigation/nscoder_util.h"
|
| +#include "ios/web/public/navigation_item.h"
|
| +#import "net/base/mac/url_conversions.h"
|
| +
|
| +@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;
|
| +
|
| + // Content state is an opaque dictionary created by WebKit that represents the
|
| + // state of the page. This includes form entries and scroll position for each
|
| + // frame. We store it so that we can supply it back to WebKit to restore form
|
| + // state properly when the user goes back and forward.
|
| + // TODO(pinkerton): Figure out exactly what this contains given that we
|
| + // don't have anywhere near the access to WebKit that the desktop does.
|
| + NSDictionary* _state;
|
| +
|
| + // 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;
|
| +
|
| + base::mac::ObjCPropertyReleaser _propertyReleaser_CRWSessionEntry;
|
| +}
|
| +// Redefine originalUrl to be read-write.
|
| +@property(nonatomic, readwrite) const GURL& originalUrl;
|
| +
|
| +@end
|
| +
|
| +@implementation CRWSessionEntry
|
| +
|
| +@synthesize POSTData = _POSTData;
|
| +@synthesize originalUrl = _originalUrl;
|
| +@synthesize useDesktopUserAgent = _useDesktopUserAgent;
|
| +@synthesize usedDataReductionProxy = _usedDataReductionProxy;
|
| +@synthesize state = _state;
|
| +@synthesize index = _index;
|
| +@synthesize serializedStateObject = _serializedStateObject;
|
| +@synthesize createdFromPushState = _createdFromPushState;
|
| +@synthesize skipResubmitDataConfirmation = _skipResubmitDataConfirmation;
|
| +
|
| +// Creates a new session entry. These may be nil.
|
| +- (id)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;
|
| +}
|
| +
|
| +- (id)initWithNavigationItem:(scoped_ptr<web::NavigationItem>)item
|
| + index:(int)index {
|
| + 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;
|
| +}
|
| +
|
| +- (id)initWithCoder:(NSCoder*)aDecoder {
|
| + self = [super init];
|
| + if (self) {
|
| + _propertyReleaser_CRWSessionEntry.Init(self, [CRWSessionEntry class]);
|
| + _navigationItem.reset(new web::NavigationItemImpl());
|
| +
|
| + // Desktop chrome only persists virtualUrl_ and uses it to feed the url
|
| + // when creating a NavigationEntry.
|
| + GURL url;
|
| + if ([aDecoder containsValueForKey:@"virtualUrlString"]) {
|
| + url = GURL(
|
| + web::nscoder_util::DecodeString(aDecoder, @"virtualUrlString"));
|
| + } else {
|
| + // Backward compatibility.
|
| + url = net::GURLWithNSURL([aDecoder decodeObjectForKey:@"virtualUrl"]);
|
| + }
|
| + _navigationItem->SetURL(url);
|
| + self.originalUrl = url;
|
| +
|
| + if ([aDecoder containsValueForKey:@"referrerUrlString"]) {
|
| + const std::string referrerString(web::nscoder_util::DecodeString(
|
| + aDecoder, @"referrerUrlString"));
|
| + web::ReferrerPolicy referrerPolicy =
|
| + static_cast<web::ReferrerPolicy>(
|
| + [aDecoder decodeIntForKey:@"referrerPolicy"]);
|
| + _navigationItem->SetReferrer(
|
| + web::Referrer(GURL(referrerString), referrerPolicy));
|
| + } else {
|
| + // Backward compatibility.
|
| + NSURL* referrer = [aDecoder decodeObjectForKey:@"referrer"];
|
| + _navigationItem->SetReferrer(web::Referrer(
|
| + net::GURLWithNSURL(referrer), web::ReferrerPolicyDefault));
|
| + }
|
| +
|
| + if ([aDecoder containsValueForKey:@"timestamp"]) {
|
| + int64 us = [aDecoder decodeInt64ForKey:@"timestamp"];
|
| + _navigationItem->SetTimestamp(base::Time::FromInternalValue(us));
|
| + }
|
| +
|
| + NSString* title = [aDecoder decodeObjectForKey:@"title"];
|
| + // Use a transition type of reload so that we don't incorrectly increase
|
| + // the typed count. This is what desktop chrome does.
|
| + _navigationItem->SetPageID(-1);
|
| + _navigationItem->SetTitle(base::SysNSStringToUTF16(title));
|
| + _navigationItem->SetTransitionType(ui::PAGE_TRANSITION_RELOAD);
|
| + self.index = [aDecoder decodeIntForKey:@"index"];
|
| + self.state = [aDecoder decodeObjectForKey:@"state"];
|
| + 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"];
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (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",
|
| + _navigationItem->GetReferrer().url.spec());
|
| + [aCoder encodeInt:_navigationItem->GetReferrer().policy
|
| + forKey:@"referrerPolicy"];
|
| + [aCoder encodeInt64:_navigationItem->GetTimestamp().ToInternalValue()
|
| + forKey:@"timestamp"];
|
| +
|
| + [aCoder encodeObject:base::SysUTF16ToNSString(_navigationItem->GetTitle())
|
| + forKey:@"title"];
|
| + [aCoder encodeObject:self.state 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
|
| + forKey:@"skipResubmitDataConfirmation"];
|
| +}
|
| +
|
| +// TODO(ios): Shall we overwrite EqualTo:?
|
| +
|
| +- (id)copyWithZone:(NSZone *)zone {
|
| + CRWSessionEntry* copy = [[[self class] alloc] init];
|
| + copy->_propertyReleaser_CRWSessionEntry.Init(copy, [CRWSessionEntry class]);
|
| + copy->_navigationItem.reset(
|
| + new web::NavigationItemImpl(*_navigationItem.get()));
|
| + copy->_index = _index;
|
| + copy->_originalUrl = _originalUrl;
|
| + copy->_state = [_state copy];
|
| + copy->_useDesktopUserAgent = _useDesktopUserAgent;
|
| + copy->_usedDataReductionProxy = _usedDataReductionProxy;
|
| + copy->_POSTData = [_POSTData copy];
|
| + copy->_httpHeaders.reset([_httpHeaders mutableCopy]);
|
| + copy->_skipResubmitDataConfirmation = _skipResubmitDataConfirmation;
|
| + return copy;
|
| +}
|
| +
|
| +- (NSString*)description {
|
| + return [NSString stringWithFormat:
|
| + @"url:%@ originalurl:%@ title:%@ transition:%d state:%@ desktopUA:%d "
|
| + @"proxy:%d",
|
| + base::SysUTF8ToNSString(_navigationItem->GetURL().spec()),
|
| + base::SysUTF8ToNSString(self.originalUrl.spec()),
|
| + base::SysUTF16ToNSString(_navigationItem->GetTitle()),
|
| + _navigationItem->GetTransitionType(),
|
| + _state, _useDesktopUserAgent, _usedDataReductionProxy];
|
| +}
|
| +
|
| +- (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();
|
| +}
|
| +
|
| +@end
|
|
|