| Index: ios/web/web_state/ui/crw_wk_navigation_states.mm
|
| diff --git a/ios/web/web_state/ui/crw_wk_navigation_states.mm b/ios/web/web_state/ui/crw_wk_navigation_states.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2f0a517513758b5fe5a9e4cd5ece5a6b10866722
|
| --- /dev/null
|
| +++ b/ios/web/web_state/ui/crw_wk_navigation_states.mm
|
| @@ -0,0 +1,113 @@
|
| +// Copyright 2016 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/web_state/ui/crw_wk_navigation_states.h"
|
| +
|
| +#include "base/logging.h"
|
| +
|
| +#if !defined(__has_feature) || !__has_feature(objc_arc)
|
| +#error "This file requires ARC support."
|
| +#endif
|
| +
|
| +// Holds a pair of state and creation order index.
|
| +@interface CRWWKNavigationsStateRecord : NSObject
|
| +// Navigation state.
|
| +@property(nonatomic, assign) web::WKNavigationState state;
|
| +// Numerical index representing creation order (smaller index denotes earlier
|
| +// navigations).
|
| +@property(nonatomic, assign, readonly) NSUInteger index;
|
| +
|
| +- (instancetype)init NS_UNAVAILABLE;
|
| +
|
| +// Initializes record with state and index values.
|
| +- (instancetype)initWithState:(web::WKNavigationState)state
|
| + index:(NSUInteger)index NS_DESIGNATED_INITIALIZER;
|
| +
|
| +@end
|
| +
|
| +@implementation CRWWKNavigationsStateRecord
|
| +@synthesize state = _state;
|
| +@synthesize index = _index;
|
| +
|
| +- (NSString*)description {
|
| + return [NSString stringWithFormat:@"state: %d, index: %ld", _state,
|
| + static_cast<long>(_index)];
|
| +}
|
| +
|
| +- (instancetype)initWithState:(web::WKNavigationState)state
|
| + index:(NSUInteger)index {
|
| + if ((self = [super init])) {
|
| + _state = state;
|
| + _index = index;
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +@end
|
| +
|
| +@interface CRWWKNavigationStates () {
|
| + NSMapTable* _records;
|
| + NSUInteger _lastStateIndex;
|
| +}
|
| +@end
|
| +
|
| +@implementation CRWWKNavigationStates
|
| +
|
| +- (instancetype)init {
|
| + if ((self = [super init])) {
|
| + _records = [NSMapTable weakToStrongObjectsMapTable];
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (NSString*)description {
|
| + return [NSString stringWithFormat:@"records: %@, lastAddedNavigation: %@",
|
| + _records, self.lastAddedNavigation];
|
| +}
|
| +
|
| +- (void)setState:(web::WKNavigationState)state
|
| + forNavigation:(WKNavigation*)navigation {
|
| + if (!navigation) {
|
| + // WKWebView may call WKNavigationDelegate callbacks with nil
|
| + // |WKNavigation|. TODO(crbug.com/677354): Remove this once WKWebView bug
|
| + // is fixed.
|
| + return;
|
| + }
|
| +
|
| + CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation];
|
| + if (!record) {
|
| + DCHECK(state == web::WKNavigationState::REQUESTED ||
|
| + state == web::WKNavigationState::STARTED ||
|
| + state == web::WKNavigationState::COMMITTED);
|
| + record =
|
| + [[CRWWKNavigationsStateRecord alloc] initWithState:state
|
| + index:++_lastStateIndex];
|
| + } else {
|
| + DCHECK(
|
| + record.state < state ||
|
| + (record.state == state && state == web::WKNavigationState::REDIRECTED));
|
| + record.state = state;
|
| + }
|
| + [_records setObject:record forKey:navigation];
|
| +}
|
| +
|
| +- (WKNavigation*)lastAddedNavigation {
|
| + WKNavigation* result = nil;
|
| + NSUInteger lastAddedIndex = 0; // record indices start with 1.
|
| + for (WKNavigation* navigation in _records) {
|
| + CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation];
|
| + if (lastAddedIndex < record.index) {
|
| + result = navigation;
|
| + lastAddedIndex = record.index;
|
| + }
|
| + }
|
| + return result;
|
| +}
|
| +
|
| +- (web::WKNavigationState)stateForNavigation:(WKNavigation*)navigation {
|
| + CRWWKNavigationsStateRecord* record = [_records objectForKey:navigation];
|
| + return record.state;
|
| +}
|
| +
|
| +@end
|
|
|