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

Side by Side Diff: ios/web/web_state/ui/crw_wk_navigation_states.mm

Issue 2838593002: Allow storing null navigations in CRWWKNavigationStates. (Closed)
Patch Set: Created 3 years, 8 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/web_state/ui/crw_wk_navigation_states.h" 5 #import "ios/web/web_state/ui/crw_wk_navigation_states.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "ios/web/web_state/navigation_context_impl.h" 8 #include "ios/web/web_state/navigation_context_impl.h"
9 9
10 #if !defined(__has_feature) || !__has_feature(objc_arc) 10 #if !defined(__has_feature) || !__has_feature(objc_arc)
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 76
77 - (web::NavigationContextImpl*)context { 77 - (web::NavigationContextImpl*)context {
78 return _context.get(); 78 return _context.get();
79 } 79 }
80 80
81 @end 81 @end
82 82
83 @interface CRWWKNavigationStates () { 83 @interface CRWWKNavigationStates () {
84 NSMapTable* _records; 84 NSMapTable* _records;
85 NSUInteger _lastStateIndex; 85 NSUInteger _lastStateIndex;
86 WKNavigation* _nullNavigation;
86 } 87 }
88
89 // Returns key to use for storing navigation in records table.
90 - (id)keyForNavigation:(WKNavigation*)navigation;
91
92 // Returns last added navigation and record.
93 - (void)getLastAddedNavigation:(WKNavigation**)outNavigation
94 record:(CRWWKNavigationsStateRecord**)outRecord;
95
87 @end 96 @end
88 97
89 @implementation CRWWKNavigationStates 98 @implementation CRWWKNavigationStates
90 99
91 - (instancetype)init { 100 - (instancetype)init {
92 if ((self = [super init])) { 101 if ((self = [super init])) {
93 _records = [NSMapTable weakToStrongObjectsMapTable]; 102 _records = [NSMapTable weakToStrongObjectsMapTable];
103 _nullNavigation = static_cast<WKNavigation*>([NSNull null]);
kkhorimoto 2017/04/25 14:00:11 Is reinterpret_cast more appropriate here?
Eugene But (OOO till 7-30) 2017/04/26 05:51:33 This translates one Obc-C pointer type to another,
94 } 104 }
95 return self; 105 return self;
96 } 106 }
97 107
98 - (NSString*)description { 108 - (NSString*)description {
99 return [NSString stringWithFormat:@"records: %@, lastAddedNavigation: %@", 109 return [NSString stringWithFormat:@"records: %@, lastAddedNavigation: %@",
100 _records, self.lastAddedNavigation]; 110 _records, self.lastAddedNavigation];
101 } 111 }
102 112
103 - (void)setState:(web::WKNavigationState)state 113 - (void)setState:(web::WKNavigationState)state
104 forNavigation:(WKNavigation*)navigation { 114 forNavigation:(WKNavigation*)navigation {
105 if (!navigation) { 115 id key = [self keyForNavigation:navigation];
106 // WKWebView may call WKNavigationDelegate callbacks with nil. 116 CRWWKNavigationsStateRecord* record = [_records objectForKey:key];
107 return;
108 }
109
110 CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation];
111 if (!record) { 117 if (!record) {
112 DCHECK(state == web::WKNavigationState::REQUESTED || 118 DCHECK(state == web::WKNavigationState::REQUESTED ||
113 state == web::WKNavigationState::STARTED || 119 state == web::WKNavigationState::STARTED ||
114 state == web::WKNavigationState::COMMITTED); 120 state == web::WKNavigationState::COMMITTED);
115 record = 121 record =
116 [[CRWWKNavigationsStateRecord alloc] initWithState:state 122 [[CRWWKNavigationsStateRecord alloc] initWithState:state
117 index:++_lastStateIndex]; 123 index:++_lastStateIndex];
118 } else { 124 } else {
119 DCHECK( 125 DCHECK(
120 record.state < state || 126 record.state < state ||
121 (record.state == state && state == web::WKNavigationState::REDIRECTED)); 127 (record.state == state && state == web::WKNavigationState::REDIRECTED));
122 record.state = state; 128 record.state = state;
123 } 129 }
124 [_records setObject:record forKey:navigation]; 130 [_records setObject:record forKey:key];
125 } 131 }
126 132
127 - (void)removeNavigation:(WKNavigation*)navigation { 133 - (void)removeNavigation:(WKNavigation*)navigation {
128 if (!navigation) { 134 id key = [self keyForNavigation:navigation];
129 // WKWebView may call WKNavigationDelegate callbacks with nil. 135 DCHECK([_records objectForKey:key]);
130 return; 136 [_records removeObjectForKey:key];
131 }
132
133 DCHECK([_records objectForKey:navigation]);
134 [_records removeObjectForKey:navigation];
135 } 137 }
136 138
137 - (void)setContext:(std::unique_ptr<web::NavigationContextImpl>)context 139 - (void)setContext:(std::unique_ptr<web::NavigationContextImpl>)context
138 forNavigation:(WKNavigation*)navigation { 140 forNavigation:(WKNavigation*)navigation {
139 if (!navigation) { 141 id key = [self keyForNavigation:navigation];
140 // WKWebView may call WKNavigationDelegate callbacks with nil. 142 CRWWKNavigationsStateRecord* record = [_records objectForKey:key];
141 return;
142 }
143 CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation];
144 if (!record) { 143 if (!record) {
145 record = 144 record =
146 [[CRWWKNavigationsStateRecord alloc] initWithContext:std::move(context) 145 [[CRWWKNavigationsStateRecord alloc] initWithContext:std::move(context)
147 index:++_lastStateIndex]; 146 index:++_lastStateIndex];
148 } else { 147 } else {
149 [record setContext:std::move(context)]; 148 [record setContext:std::move(context)];
150 } 149 }
151 [_records setObject:record forKey:navigation]; 150 [_records setObject:record forKey:key];
152 } 151 }
153 152
154 - (web::NavigationContextImpl*)contextForNavigation:(WKNavigation*)navigation { 153 - (web::NavigationContextImpl*)contextForNavigation:(WKNavigation*)navigation {
155 if (!navigation) { 154 id key = [self keyForNavigation:navigation];
156 // WKWebView may call WKNavigationDelegate callbacks with nil. 155 CRWWKNavigationsStateRecord* record = [_records objectForKey:key];
157 return nullptr;
158 }
159 CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation];
160 return record.context; 156 return record.context;
161 } 157 }
162 158
163 - (WKNavigation*)lastAddedNavigation { 159 - (WKNavigation*)lastAddedNavigation {
164 WKNavigation* result = nil; 160 WKNavigation* result = nil;
161 CRWWKNavigationsStateRecord* unused = nil;
162 [self getLastAddedNavigation:&result record:&unused];
163 return result;
164 }
165
166 - (web::WKNavigationState)lastAddedNavigationState {
167 CRWWKNavigationsStateRecord* result = nil;
168 WKNavigation* unused = nil;
169 [self getLastAddedNavigation:&unused record:&result];
170 return result.state;
171 }
172
173 - (id)keyForNavigation:(WKNavigation*)navigation {
174 return navigation ? navigation : _nullNavigation;
175 }
176
177 - (void)getLastAddedNavigation:(WKNavigation**)outNavigation
178 record:(CRWWKNavigationsStateRecord**)outRecord {
165 NSUInteger lastAddedIndex = 0; // record indices start with 1. 179 NSUInteger lastAddedIndex = 0; // record indices start with 1.
166 for (WKNavigation* navigation in _records) { 180 for (WKNavigation* navigation in _records) {
167 CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation]; 181 CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation];
168 if (lastAddedIndex < record.index) { 182 if (lastAddedIndex < record.index) {
169 result = navigation; 183 *outNavigation = navigation;
184 *outRecord = record;
170 lastAddedIndex = record.index; 185 lastAddedIndex = record.index;
171 } 186 }
172 } 187 }
173 return result;
174 }
175 188
176 - (web::WKNavigationState)lastAddedNavigationState { 189 if (*outNavigation == _nullNavigation) {
177 CRWWKNavigationsStateRecord* lastAddedRecord = nil; 190 // |_nullNavigation| is a key for storing null navigations.
178 WKNavigation* lastAddedNavigation = [self lastAddedNavigation]; 191 *outNavigation = nil;
179 if (lastAddedNavigation) 192 }
180 lastAddedRecord = [_records objectForKey:lastAddedNavigation];
181
182 return lastAddedRecord.state;
183 } 193 }
184 194
185 @end 195 @end
OLDNEW
« no previous file with comments | « ios/web/web_state/ui/crw_wk_navigation_states.h ('k') | ios/web/web_state/ui/crw_wk_navigation_states_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698