Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: ios/web/navigation/crw_session_entry.mm

Issue 1028603004: Upstream ios/web/navigation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ios-testing
Patch Set: Rebase and resync Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #import "ios/web/navigation/crw_session_entry.h"
6
7 #include "base/mac/objc_property_releaser.h"
8 #include "base/mac/scoped_nsobject.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "ios/web/navigation/navigation_item_impl.h"
12 #include "ios/web/navigation/nscoder_util.h"
13 #include "ios/web/public/navigation_item.h"
14 #include "ios/web/public/web_state/page_scroll_state.h"
15 #import "net/base/mac/url_conversions.h"
16
17 namespace {
18 // Keys used to serialize web::PageScrollState properties.
19 NSString* const kScrollOffsetXKey = @"scrollX";
20 NSString* const kScrollOffsetYKey = @"scrollY";
21 NSString* const kMinimumZoomScaleKey = @"minZoom";
22 NSString* const kMaximumZoomScaleKey = @"maxZoom";
23 NSString* const kZoomScaleKey = @"zoom";
24 }
25
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_|
34 // will contain the final post-redirect URL, and |originalUrl_| will contain
35 // the pre-redirect URL. This field is not persisted to disk.
36 GURL _originalUrl;
37
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.
68 // TODO(stuartmorgan): Move ownership to NavigationManagerImpl.
69 scoped_ptr<web::NavigationItemImpl> _navigationItem;
70
71 base::mac::ObjCPropertyReleaser _propertyReleaser_CRWSessionEntry;
72 }
73 // Redefine originalUrl to be read-write.
74 @property(nonatomic, readwrite) const GURL& originalUrl;
75
76 // Converts a serialized NSDictionary to a web::PageScrollState.
77 + (web::PageScrollState)scrollStateFromDictionary:(NSDictionary*)dictionary;
78 // Serializes a web::PageScrollState to an NSDictionary.
79 + (NSDictionary*)dictionaryFromScrollState:
80 (const web::PageScrollState&)scrollState;
81 // Returns a readable description of |scrollState|.
82 + (NSString*)scrollStateDescription:(const web::PageScrollState&)scrollState;
83 @end
84
85 @implementation CRWSessionEntry
86
87 @synthesize POSTData = _POSTData;
88 @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
96 // Creates a new session entry. These may be nil.
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];
121 if (self) {
122 _propertyReleaser_CRWSessionEntry.Init(self, [CRWSessionEntry class]);
123 _navigationItem.reset(
124 static_cast<web::NavigationItemImpl*>(item.release()));
125
126 self.index = index;
127 self.originalUrl = _navigationItem->GetURL();
128 self.useDesktopUserAgent = NO;
129 }
130 return self;
131 }
132
133 - (instancetype)initWithCoder:(NSCoder*)aDecoder {
134 self = [super init];
135 if (self) {
136 _propertyReleaser_CRWSessionEntry.Init(self, [CRWSessionEntry class]);
137 _navigationItem.reset(new web::NavigationItemImpl());
138
139 // Desktop chrome only persists virtualUrl_ and uses it to feed the url
140 // when creating a NavigationEntry.
141 GURL url;
142 if ([aDecoder containsValueForKey:@"virtualUrlString"]) {
143 url = GURL(
144 web::nscoder_util::DecodeString(aDecoder, @"virtualUrlString"));
145 } else {
146 // Backward compatibility.
147 url = net::GURLWithNSURL([aDecoder decodeObjectForKey:@"virtualUrl"]);
148 }
149 _navigationItem->SetURL(url);
150 self.originalUrl = url;
151
152 if ([aDecoder containsValueForKey:@"referrerUrlString"]) {
153 const std::string referrerString(web::nscoder_util::DecodeString(
154 aDecoder, @"referrerUrlString"));
155 web::ReferrerPolicy referrerPolicy =
156 static_cast<web::ReferrerPolicy>(
157 [aDecoder decodeIntForKey:@"referrerPolicy"]);
158 _navigationItem->SetReferrer(
159 web::Referrer(GURL(referrerString), referrerPolicy));
160 } else {
161 // Backward compatibility.
162 NSURL* referrer = [aDecoder decodeObjectForKey:@"referrer"];
163 _navigationItem->SetReferrer(web::Referrer(
164 net::GURLWithNSURL(referrer), web::ReferrerPolicyDefault));
165 }
166
167 if ([aDecoder containsValueForKey:@"timestamp"]) {
168 int64 us = [aDecoder decodeInt64ForKey:@"timestamp"];
169 _navigationItem->SetTimestamp(base::Time::FromInternalValue(us));
170 }
171
172 NSString* title = [aDecoder decodeObjectForKey:@"title"];
173 // Use a transition type of reload so that we don't incorrectly increase
174 // the typed count. This is what desktop chrome does.
175 _navigationItem->SetPageID(-1);
176 _navigationItem->SetTitle(base::SysNSStringToUTF16(title));
177 _navigationItem->SetTransitionType(ui::PAGE_TRANSITION_RELOAD);
178 _navigationItem->SetPageScrollState([[self class]
179 scrollStateFromDictionary:[aDecoder decodeObjectForKey:@"state"]]);
180 self.index = [aDecoder decodeIntForKey:@"index"];
181 self.useDesktopUserAgent =
182 [aDecoder decodeBoolForKey:@"useDesktopUserAgent"];
183 self.usedDataReductionProxy =
184 [aDecoder decodeBoolForKey:@"usedDataReductionProxy"];
185 [self addHTTPHeaders:[aDecoder decodeObjectForKey:@"httpHeaders"]];
186 self.POSTData = [aDecoder decodeObjectForKey:@"POSTData"];
187 self.skipResubmitDataConfirmation =
188 [aDecoder decodeBoolForKey:@"skipResubmitDataConfirmation"];
189 }
190 return self;
191 }
192
193 - (void)encodeWithCoder:(NSCoder*)aCoder {
194 // Desktop Chrome doesn't persist |url_| or |originalUrl_|, only
195 // |virtualUrl_|.
196 [aCoder encodeInt:self.index forKey:@"index"];
197 web::nscoder_util::EncodeString(aCoder, @"virtualUrlString",
198 _navigationItem->GetVirtualURL().spec());
199 web::nscoder_util::EncodeString(aCoder, @"referrerUrlString",
200 _navigationItem->GetReferrer().url.spec());
201 [aCoder encodeInt:_navigationItem->GetReferrer().policy
202 forKey:@"referrerPolicy"];
203 [aCoder encodeInt64:_navigationItem->GetTimestamp().ToInternalValue()
204 forKey:@"timestamp"];
205
206 [aCoder encodeObject:base::SysUTF16ToNSString(_navigationItem->GetTitle())
207 forKey:@"title"];
208 [aCoder encodeObject:[[self class] dictionaryFromScrollState:
209 _navigationItem->GetPageScrollState()]
210 forKey:@"state"];
211 [aCoder encodeBool:self.useDesktopUserAgent forKey:@"useDesktopUserAgent"];
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"];
218 }
219
220 // TODO(ios): Shall we overwrite EqualTo:?
221
222 - (instancetype)copyWithZone:(NSZone*)zone {
223 CRWSessionEntry* copy = [[[self class] alloc] init];
224 copy->_propertyReleaser_CRWSessionEntry.Init(copy, [CRWSessionEntry class]);
225 copy->_navigationItem.reset(
226 new web::NavigationItemImpl(*_navigationItem.get()));
227 copy->_index = _index;
228 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;
235 }
236
237 - (NSString*)description {
238 return [NSString
239 stringWithFormat:
240 @"url:%@ originalurl:%@ title:%@ transition:%d scrollState:%@ "
241 @"desktopUA:%d " @"proxy:%d",
242 base::SysUTF8ToNSString(_navigationItem->GetURL().spec()),
243 base::SysUTF8ToNSString(self.originalUrl.spec()),
244 base::SysUTF16ToNSString(_navigationItem->GetTitle()),
245 _navigationItem->GetTransitionType(),
246 [[self class]
247 scrollStateDescription:_navigationItem->GetPageScrollState()],
248 _useDesktopUserAgent, _usedDataReductionProxy];
249 }
250
251 - (web::NavigationItem*)navigationItem {
252 return _navigationItem.get();
253 }
254
255 - (NSDictionary*)httpHeaders {
256 return _httpHeaders ? [NSDictionary dictionaryWithDictionary:_httpHeaders]
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 }
276
277 #pragma mark - Serialization helpers
278
279 + (web::PageScrollState)scrollStateFromDictionary:(NSDictionary*)dictionary {
280 web::PageScrollState scrollState;
281 NSNumber* serializedValue = nil;
282 if ((serializedValue = dictionary[kScrollOffsetXKey]))
283 scrollState.set_scroll_offset_x([serializedValue doubleValue]);
284 if ((serializedValue = dictionary[kScrollOffsetYKey]))
285 scrollState.set_scroll_offset_y([serializedValue doubleValue]);
286 if ((serializedValue = dictionary[kMinimumZoomScaleKey]))
287 scrollState.set_minimum_zoom_scale([serializedValue doubleValue]);
288 if ((serializedValue = dictionary[kMaximumZoomScaleKey]))
289 scrollState.set_maximum_zoom_scale([serializedValue doubleValue]);
290 if ((serializedValue = dictionary[kZoomScaleKey]))
291 scrollState.set_zoom_scale([serializedValue doubleValue]);
292 return scrollState;
293 }
294
295 + (NSDictionary*)dictionaryFromScrollState:
296 (const web::PageScrollState&)scrollState {
297 return @{
298 kScrollOffsetXKey : @(scrollState.scroll_offset_x()),
299 kScrollOffsetYKey : @(scrollState.scroll_offset_y()),
300 kMinimumZoomScaleKey : @(scrollState.minimum_zoom_scale()),
301 kMaximumZoomScaleKey : @(scrollState.maximum_zoom_scale()),
302 kZoomScaleKey : @(scrollState.zoom_scale())
303 };
304 }
305
306 + (NSString*)scrollStateDescription:(const web::PageScrollState&)scrollState {
307 NSString* const kPageScrollStateDescriptionFormat =
308 @"{ scrollOffset:(%0.2f, %0.2f), zoomScaleRange:(%0.2f, %0.2f), "
309 @"zoomScale:%0.2f }";
310 return [NSString stringWithFormat:kPageScrollStateDescriptionFormat,
311 scrollState.scroll_offset_x(),
312 scrollState.scroll_offset_y(),
313 scrollState.minimum_zoom_scale(),
314 scrollState.maximum_zoom_scale(),
315 scrollState.zoom_scale()];
316 }
317
318 @end
OLDNEW
« no previous file with comments | « ios/web/navigation/crw_session_entry.h ('k') | ios/web/navigation/crw_session_entry_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698