| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/web/navigation/crw_session_entry.h" | 5 #import "ios/web/navigation/crw_session_entry.h" |
| 6 | 6 |
| 7 #include "base/mac/objc_property_releaser.h" | 7 #include "base/mac/objc_property_releaser.h" |
| 8 #include "base/mac/scoped_nsobject.h" | 8 #include "base/mac/scoped_nsobject.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
| 11 #include "ios/web/navigation/navigation_item_impl.h" | 11 #include "ios/web/navigation/navigation_item_impl.h" |
| 12 #include "ios/web/navigation/nscoder_util.h" | 12 #include "ios/web/navigation/nscoder_util.h" |
| 13 #include "ios/web/public/navigation_item.h" | 13 #include "ios/web/public/navigation_item.h" |
| 14 #include "ios/web/public/web_state/page_scroll_state.h" | 14 #include "ios/web/public/web_state/page_scroll_state.h" |
| 15 #import "net/base/mac/url_conversions.h" | 15 #import "net/base/mac/url_conversions.h" |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 // Keys used to serialize web::PageScrollState properties. | 18 // Keys used to serialize web::PageScrollState properties. |
| 19 NSString* const kScrollOffsetXKey = @"scrollX"; | 19 NSString* const kScrollOffsetXKey = @"scrollX"; |
| 20 NSString* const kScrollOffsetYKey = @"scrollY"; | 20 NSString* const kScrollOffsetYKey = @"scrollY"; |
| 21 NSString* const kMinimumZoomScaleKey = @"minZoom"; | 21 NSString* const kMinimumZoomScaleKey = @"minZoom"; |
| 22 NSString* const kMaximumZoomScaleKey = @"maxZoom"; | 22 NSString* const kMaximumZoomScaleKey = @"maxZoom"; |
| 23 NSString* const kZoomScaleKey = @"zoom"; | 23 NSString* const kZoomScaleKey = @"zoom"; |
| 24 } | 24 } |
| 25 | 25 |
| 26 @interface CRWSessionEntry () { | 26 @interface CRWSessionEntry () { |
| 27 // The index in the CRWSessionController. | |
| 28 // | |
| 29 // This is used when determining the selected CRWSessionEntry and only useful | |
| 30 // to the SessionServiceIOS. | |
| 31 NSInteger _index; | |
| 32 | |
| 33 // The original URL of the page. In cases where a redirect occurred, |url_| | 27 // The original URL of the page. In cases where a redirect occurred, |url_| |
| 34 // will contain the final post-redirect URL, and |originalUrl_| will contain | 28 // will contain the final post-redirect URL, and |originalUrl_| will contain |
| 35 // the pre-redirect URL. This field is not persisted to disk. | 29 // the pre-redirect URL. This field is not persisted to disk. |
| 36 GURL _originalUrl; | 30 GURL _originalUrl; |
| 37 | 31 |
| 38 // Headers passed along with the request. For POST requests, these are | |
| 39 // persisted, to be able to resubmit them. Some specialized non-POST requests | |
| 40 // may also pass custom headers. | |
| 41 base::scoped_nsobject<NSMutableDictionary> _httpHeaders; | |
| 42 | |
| 43 // Data submitted with a POST request, persisted for resubmits. | |
| 44 NSData* _POSTData; | |
| 45 | |
| 46 // Serialized representation of the state object that was used in conjunction | |
| 47 // with a JavaScript window.history.pushState() or | |
| 48 // window.history.replaceState() call that created or modified this | |
| 49 // CRWSessionEntry. Intended to be used for JavaScript history operations and | |
| 50 // will be nil in most cases. | |
| 51 NSString* _serializedStateObject; | |
| 52 | |
| 53 // Whether or not this entry was created by calling history.pushState(). | |
| 54 BOOL _createdFromPushState; | |
| 55 | |
| 56 // If |YES| use a desktop user agent in HTTP requests and UIWebView. | |
| 57 BOOL _useDesktopUserAgent; | |
| 58 | |
| 59 // If |YES| the page was last fetched through the data reduction proxy. | |
| 60 BOOL _usedDataReductionProxy; | |
| 61 | |
| 62 // Whether or not to bypass showing the resubmit data confirmation when | |
| 63 // loading a POST request. Set to YES for browser-generated POST requests such | |
| 64 // as search-by-image requests. | |
| 65 BOOL _skipResubmitDataConfirmation; | |
| 66 | |
| 67 // The NavigationItemImpl corresponding to this CRWSessionEntry. | 32 // The NavigationItemImpl corresponding to this CRWSessionEntry. |
| 68 // TODO(stuartmorgan): Move ownership to NavigationManagerImpl. | 33 // TODO(stuartmorgan): Move ownership to NavigationManagerImpl. |
| 69 scoped_ptr<web::NavigationItemImpl> _navigationItem; | 34 scoped_ptr<web::NavigationItemImpl> _navigationItem; |
| 70 | 35 |
| 71 base::mac::ObjCPropertyReleaser _propertyReleaser_CRWSessionEntry; | 36 base::mac::ObjCPropertyReleaser _propertyReleaser_CRWSessionEntry; |
| 72 } | 37 } |
| 73 // Redefine originalUrl to be read-write. | 38 // Redefine originalUrl to be read-write. |
| 74 @property(nonatomic, readwrite) const GURL& originalUrl; | 39 @property(nonatomic, readwrite) const GURL& originalUrl; |
| 75 | 40 |
| 76 // Converts a serialized NSDictionary to a web::PageScrollState. | 41 // Converts a serialized NSDictionary to a web::PageScrollState. |
| 77 + (web::PageScrollState)scrollStateFromDictionary:(NSDictionary*)dictionary; | 42 + (web::PageScrollState)scrollStateFromDictionary:(NSDictionary*)dictionary; |
| 78 // Serializes a web::PageScrollState to an NSDictionary. | 43 // Serializes a web::PageScrollState to an NSDictionary. |
| 79 + (NSDictionary*)dictionaryFromScrollState: | 44 + (NSDictionary*)dictionaryFromScrollState: |
| 80 (const web::PageScrollState&)scrollState; | 45 (const web::PageScrollState&)scrollState; |
| 81 // Returns a readable description of |scrollState|. | 46 // Returns a readable description of |scrollState|. |
| 82 + (NSString*)scrollStateDescription:(const web::PageScrollState&)scrollState; | 47 + (NSString*)scrollStateDescription:(const web::PageScrollState&)scrollState; |
| 83 @end | 48 @end |
| 84 | 49 |
| 85 @implementation CRWSessionEntry | 50 @implementation CRWSessionEntry |
| 86 | 51 |
| 87 @synthesize POSTData = _POSTData; | |
| 88 @synthesize originalUrl = _originalUrl; | 52 @synthesize originalUrl = _originalUrl; |
| 89 @synthesize useDesktopUserAgent = _useDesktopUserAgent; | |
| 90 @synthesize usedDataReductionProxy = _usedDataReductionProxy; | |
| 91 @synthesize index = _index; | |
| 92 @synthesize serializedStateObject = _serializedStateObject; | |
| 93 @synthesize createdFromPushState = _createdFromPushState; | |
| 94 @synthesize skipResubmitDataConfirmation = _skipResubmitDataConfirmation; | |
| 95 | 53 |
| 96 // Creates a new session entry. These may be nil. | 54 - (instancetype)initWithNavigationItem:(scoped_ptr<web::NavigationItem>)item { |
| 97 - (instancetype)initWithUrl:(const GURL&)url | |
| 98 referrer:(const web::Referrer&)referrer | |
| 99 transition:(ui::PageTransition)transition | |
| 100 useDesktopUserAgent:(BOOL)useDesktopUserAgent | |
| 101 rendererInitiated:(BOOL)rendererInitiated { | |
| 102 self = [super init]; | |
| 103 if (self) { | |
| 104 _propertyReleaser_CRWSessionEntry.Init(self, [CRWSessionEntry class]); | |
| 105 _navigationItem.reset(new web::NavigationItemImpl()); | |
| 106 | |
| 107 _navigationItem->SetURL(url); | |
| 108 _navigationItem->SetReferrer(referrer); | |
| 109 _navigationItem->SetTransitionType(transition); | |
| 110 _navigationItem->set_is_renderer_initiated(rendererInitiated); | |
| 111 | |
| 112 self.originalUrl = url; | |
| 113 self.useDesktopUserAgent = useDesktopUserAgent; | |
| 114 } | |
| 115 return self; | |
| 116 } | |
| 117 | |
| 118 - (instancetype)initWithNavigationItem:(scoped_ptr<web::NavigationItem>)item | |
| 119 index:(int)index { | |
| 120 self = [super init]; | 55 self = [super init]; |
| 121 if (self) { | 56 if (self) { |
| 122 _propertyReleaser_CRWSessionEntry.Init(self, [CRWSessionEntry class]); | 57 _propertyReleaser_CRWSessionEntry.Init(self, [CRWSessionEntry class]); |
| 123 _navigationItem.reset( | 58 _navigationItem.reset( |
| 124 static_cast<web::NavigationItemImpl*>(item.release())); | 59 static_cast<web::NavigationItemImpl*>(item.release())); |
| 125 | |
| 126 self.index = index; | |
| 127 self.originalUrl = _navigationItem->GetURL(); | 60 self.originalUrl = _navigationItem->GetURL(); |
| 128 self.useDesktopUserAgent = NO; | |
| 129 } | 61 } |
| 130 return self; | 62 return self; |
| 131 } | 63 } |
| 132 | 64 |
| 133 - (instancetype)initWithCoder:(NSCoder*)aDecoder { | 65 - (instancetype)initWithCoder:(NSCoder*)aDecoder { |
| 134 self = [super init]; | 66 self = [super init]; |
| 135 if (self) { | 67 if (self) { |
| 136 _propertyReleaser_CRWSessionEntry.Init(self, [CRWSessionEntry class]); | 68 _propertyReleaser_CRWSessionEntry.Init(self, [CRWSessionEntry class]); |
| 137 _navigationItem.reset(new web::NavigationItemImpl()); | 69 _navigationItem.reset(new web::NavigationItemImpl()); |
| 138 | 70 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 } | 102 } |
| 171 | 103 |
| 172 NSString* title = [aDecoder decodeObjectForKey:@"title"]; | 104 NSString* title = [aDecoder decodeObjectForKey:@"title"]; |
| 173 // Use a transition type of reload so that we don't incorrectly increase | 105 // Use a transition type of reload so that we don't incorrectly increase |
| 174 // the typed count. This is what desktop chrome does. | 106 // the typed count. This is what desktop chrome does. |
| 175 _navigationItem->SetPageID(-1); | 107 _navigationItem->SetPageID(-1); |
| 176 _navigationItem->SetTitle(base::SysNSStringToUTF16(title)); | 108 _navigationItem->SetTitle(base::SysNSStringToUTF16(title)); |
| 177 _navigationItem->SetTransitionType(ui::PAGE_TRANSITION_RELOAD); | 109 _navigationItem->SetTransitionType(ui::PAGE_TRANSITION_RELOAD); |
| 178 _navigationItem->SetPageScrollState([[self class] | 110 _navigationItem->SetPageScrollState([[self class] |
| 179 scrollStateFromDictionary:[aDecoder decodeObjectForKey:@"state"]]); | 111 scrollStateFromDictionary:[aDecoder decodeObjectForKey:@"state"]]); |
| 180 self.index = [aDecoder decodeIntForKey:@"index"]; | 112 _navigationItem->SetShouldSkipResubmitDataConfirmation( |
| 181 self.useDesktopUserAgent = | 113 [aDecoder decodeBoolForKey:@"skipResubmitDataConfirmation"]); |
| 182 [aDecoder decodeBoolForKey:@"useDesktopUserAgent"]; | 114 _navigationItem->SetIsOverridingUserAgent( |
| 183 self.usedDataReductionProxy = | 115 [aDecoder decodeBoolForKey:@"useDesktopUserAgent"]); |
| 184 [aDecoder decodeBoolForKey:@"usedDataReductionProxy"]; | 116 _navigationItem->SetPostData([aDecoder decodeObjectForKey:@"POSTData"]); |
| 185 [self addHTTPHeaders:[aDecoder decodeObjectForKey:@"httpHeaders"]]; | 117 _navigationItem->AddHttpRequestHeaders( |
| 186 self.POSTData = [aDecoder decodeObjectForKey:@"POSTData"]; | 118 [aDecoder decodeObjectForKey:@"httpHeaders"]); |
| 187 self.skipResubmitDataConfirmation = | |
| 188 [aDecoder decodeBoolForKey:@"skipResubmitDataConfirmation"]; | |
| 189 } | 119 } |
| 190 return self; | 120 return self; |
| 191 } | 121 } |
| 192 | 122 |
| 193 - (void)encodeWithCoder:(NSCoder*)aCoder { | 123 - (void)encodeWithCoder:(NSCoder*)aCoder { |
| 194 // Desktop Chrome doesn't persist |url_| or |originalUrl_|, only | 124 // Desktop Chrome doesn't persist |url_| or |originalUrl_|, only |
| 195 // |virtualUrl_|. | 125 // |virtualUrl_|. |
| 196 [aCoder encodeInt:self.index forKey:@"index"]; | |
| 197 web::nscoder_util::EncodeString(aCoder, @"virtualUrlString", | 126 web::nscoder_util::EncodeString(aCoder, @"virtualUrlString", |
| 198 _navigationItem->GetVirtualURL().spec()); | 127 _navigationItem->GetVirtualURL().spec()); |
| 199 web::nscoder_util::EncodeString(aCoder, @"referrerUrlString", | 128 web::nscoder_util::EncodeString(aCoder, @"referrerUrlString", |
| 200 _navigationItem->GetReferrer().url.spec()); | 129 _navigationItem->GetReferrer().url.spec()); |
| 201 [aCoder encodeInt:_navigationItem->GetReferrer().policy | 130 [aCoder encodeInt:_navigationItem->GetReferrer().policy |
| 202 forKey:@"referrerPolicy"]; | 131 forKey:@"referrerPolicy"]; |
| 203 [aCoder encodeInt64:_navigationItem->GetTimestamp().ToInternalValue() | 132 [aCoder encodeInt64:_navigationItem->GetTimestamp().ToInternalValue() |
| 204 forKey:@"timestamp"]; | 133 forKey:@"timestamp"]; |
| 205 | 134 |
| 206 [aCoder encodeObject:base::SysUTF16ToNSString(_navigationItem->GetTitle()) | 135 [aCoder encodeObject:base::SysUTF16ToNSString(_navigationItem->GetTitle()) |
| 207 forKey:@"title"]; | 136 forKey:@"title"]; |
| 208 [aCoder encodeObject:[[self class] dictionaryFromScrollState: | 137 [aCoder encodeObject:[[self class] dictionaryFromScrollState: |
| 209 _navigationItem->GetPageScrollState()] | 138 _navigationItem->GetPageScrollState()] |
| 210 forKey:@"state"]; | 139 forKey:@"state"]; |
| 211 [aCoder encodeBool:self.useDesktopUserAgent forKey:@"useDesktopUserAgent"]; | 140 [aCoder encodeBool:_navigationItem->ShouldSkipResubmitDataConfirmation() |
| 212 [aCoder encodeBool:self.usedDataReductionProxy | |
| 213 forKey:@"usedDataReductionProxy"]; | |
| 214 [aCoder encodeObject:self.httpHeaders forKey:@"httpHeaders"]; | |
| 215 [aCoder encodeObject:self.POSTData forKey:@"POSTData"]; | |
| 216 [aCoder encodeBool:self.skipResubmitDataConfirmation | |
| 217 forKey:@"skipResubmitDataConfirmation"]; | 141 forKey:@"skipResubmitDataConfirmation"]; |
| 142 [aCoder encodeBool:_navigationItem->IsOverridingUserAgent() |
| 143 forKey:@"useDesktopUserAgent"]; |
| 144 [aCoder encodeObject:_navigationItem->GetPostData() forKey:@"POSTData"]; |
| 145 [aCoder encodeObject:_navigationItem->GetHttpRequestHeaders() |
| 146 forKey:@"httpHeaders"]; |
| 218 } | 147 } |
| 219 | 148 |
| 220 // TODO(ios): Shall we overwrite EqualTo:? | 149 // TODO(ios): Shall we overwrite EqualTo:? |
| 221 | 150 |
| 222 - (instancetype)copyWithZone:(NSZone*)zone { | 151 - (instancetype)copyWithZone:(NSZone*)zone { |
| 223 CRWSessionEntry* copy = [[[self class] alloc] init]; | 152 CRWSessionEntry* copy = [[[self class] alloc] init]; |
| 224 copy->_propertyReleaser_CRWSessionEntry.Init(copy, [CRWSessionEntry class]); | 153 copy->_propertyReleaser_CRWSessionEntry.Init(copy, [CRWSessionEntry class]); |
| 225 copy->_navigationItem.reset( | 154 copy->_navigationItem.reset( |
| 226 new web::NavigationItemImpl(*_navigationItem.get())); | 155 new web::NavigationItemImpl(*_navigationItem.get())); |
| 227 copy->_index = _index; | |
| 228 copy->_originalUrl = _originalUrl; | 156 copy->_originalUrl = _originalUrl; |
| 229 copy->_useDesktopUserAgent = _useDesktopUserAgent; | |
| 230 copy->_usedDataReductionProxy = _usedDataReductionProxy; | |
| 231 copy->_POSTData = [_POSTData copy]; | |
| 232 copy->_httpHeaders.reset([_httpHeaders mutableCopy]); | |
| 233 copy->_skipResubmitDataConfirmation = _skipResubmitDataConfirmation; | |
| 234 return copy; | 157 return copy; |
| 235 } | 158 } |
| 236 | 159 |
| 237 - (NSString*)description { | 160 - (NSString*)description { |
| 238 return [NSString | 161 return [NSString |
| 239 stringWithFormat: | 162 stringWithFormat: |
| 240 @"url:%@ originalurl:%@ title:%@ transition:%d scrollState:%@ " | 163 @"url:%@ originalurl:%@ title:%@ transition:%d scrollState:%@ " |
| 241 @"desktopUA:%d " @"proxy:%d", | 164 @"desktopUA:%d", |
| 242 base::SysUTF8ToNSString(_navigationItem->GetURL().spec()), | 165 base::SysUTF8ToNSString(_navigationItem->GetURL().spec()), |
| 243 base::SysUTF8ToNSString(self.originalUrl.spec()), | 166 base::SysUTF8ToNSString(self.originalUrl.spec()), |
| 244 base::SysUTF16ToNSString(_navigationItem->GetTitle()), | 167 base::SysUTF16ToNSString(_navigationItem->GetTitle()), |
| 245 _navigationItem->GetTransitionType(), | 168 _navigationItem->GetTransitionType(), |
| 246 [[self class] | 169 [[self class] |
| 247 scrollStateDescription:_navigationItem->GetPageScrollState()], | 170 scrollStateDescription:_navigationItem->GetPageScrollState()], |
| 248 _useDesktopUserAgent, _usedDataReductionProxy]; | 171 _navigationItem->IsOverridingUserAgent()]; |
| 249 } | 172 } |
| 250 | 173 |
| 251 - (web::NavigationItem*)navigationItem { | 174 - (web::NavigationItem*)navigationItem { |
| 252 return _navigationItem.get(); | 175 return _navigationItem.get(); |
| 253 } | 176 } |
| 254 | 177 |
| 255 - (NSDictionary*)httpHeaders { | 178 - (web::NavigationItemImpl*)navigationItemImpl { |
| 256 return _httpHeaders ? [NSDictionary dictionaryWithDictionary:_httpHeaders] | 179 return _navigationItem.get(); |
| 257 : nil; | |
| 258 } | |
| 259 | |
| 260 - (void)addHTTPHeaders:(NSDictionary*)moreHTTPHeaders { | |
| 261 if (_httpHeaders) | |
| 262 [_httpHeaders addEntriesFromDictionary:moreHTTPHeaders]; | |
| 263 else | |
| 264 _httpHeaders.reset([moreHTTPHeaders mutableCopy]); | |
| 265 } | |
| 266 | |
| 267 - (void)removeHTTPHeaderForKey:(NSString*)key { | |
| 268 [_httpHeaders removeObjectForKey:key]; | |
| 269 if (![_httpHeaders count]) | |
| 270 _httpHeaders.reset(); | |
| 271 } | |
| 272 | |
| 273 - (void)resetHTTPHeaders { | |
| 274 _httpHeaders.reset(); | |
| 275 } | 180 } |
| 276 | 181 |
| 277 #pragma mark - Serialization helpers | 182 #pragma mark - Serialization helpers |
| 278 | 183 |
| 279 + (web::PageScrollState)scrollStateFromDictionary:(NSDictionary*)dictionary { | 184 + (web::PageScrollState)scrollStateFromDictionary:(NSDictionary*)dictionary { |
| 280 web::PageScrollState scrollState; | 185 web::PageScrollState scrollState; |
| 281 NSNumber* serializedValue = nil; | 186 NSNumber* serializedValue = nil; |
| 282 if ((serializedValue = dictionary[kScrollOffsetXKey])) | 187 if ((serializedValue = dictionary[kScrollOffsetXKey])) |
| 283 scrollState.set_scroll_offset_x([serializedValue doubleValue]); | 188 scrollState.set_scroll_offset_x([serializedValue doubleValue]); |
| 284 if ((serializedValue = dictionary[kScrollOffsetYKey])) | 189 if ((serializedValue = dictionary[kScrollOffsetYKey])) |
| (...skipping 24 matching lines...) Expand all Loading... |
| 309 @"zoomScale:%0.2f }"; | 214 @"zoomScale:%0.2f }"; |
| 310 return [NSString stringWithFormat:kPageScrollStateDescriptionFormat, | 215 return [NSString stringWithFormat:kPageScrollStateDescriptionFormat, |
| 311 scrollState.scroll_offset_x(), | 216 scrollState.scroll_offset_x(), |
| 312 scrollState.scroll_offset_y(), | 217 scrollState.scroll_offset_y(), |
| 313 scrollState.minimum_zoom_scale(), | 218 scrollState.minimum_zoom_scale(), |
| 314 scrollState.maximum_zoom_scale(), | 219 scrollState.maximum_zoom_scale(), |
| 315 scrollState.zoom_scale()]; | 220 scrollState.zoom_scale()]; |
| 316 } | 221 } |
| 317 | 222 |
| 318 @end | 223 @end |
| OLD | NEW |