| 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..ab907dd5f1330a0928b2ecba80fb120328c7a1b7
|
| --- /dev/null
|
| +++ b/ios/web/web_state/ui/crw_wk_navigation_states.mm
|
| @@ -0,0 +1,110 @@
|
| +// 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, _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)addNavigation:(WKNavigation*)navigation
|
| + forState:(web::WKNavigationState)state {
|
| + 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::WK_NAVIGATION_STATE_REQUESTED ||
|
| + state == web::WK_NAVIGATION_STATE_STARTED ||
|
| + state == web::WK_NAVIGATION_STATE_COMMITTED);
|
| + record =
|
| + [[CRWWKNavigationsStateRecord alloc] initWithState:state
|
| + index:++_lastStateIndex];
|
| + } else {
|
| + DCHECK_GT(state, record.state);
|
| + record.state = state;
|
| + }
|
| + [_records setObject:record forKey:navigation];
|
| +}
|
| +
|
| +- (WKNavigation*)lastAddedNavigation {
|
| + WKNavigation* result = nil;
|
| + NSUInteger lastAddedIndex = 0; // record indices srart 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
|
|
|