blob: ae950fe93733f0008f5938486eadf643915da1fd [file] [log] [blame]
// Copyright 2018 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.
#ifndef IOS_WEB_NAVIGATION_ERROR_RETRY_STATE_MACHINE_H_
#define IOS_WEB_NAVIGATION_ERROR_RETRY_STATE_MACHINE_H_
#include "url/gurl.h"
namespace web {
// Defines the states of a NavigationItem that failed to load. This is used to
// coordinate the display of error page such that back/forward/reload navigation
// to a loaded error page will load the original URL. This is achieved in four
// steps:
// 1) A NavigationItem is set to gkDisplayingError when it first failed to load
// and a web error is displayed. If the failure occurred during provisional
// navigation, a placeholder entry is inserted into WKBackForwardList for
// this item.
// 2) Upon navigation to this item, use |loadHTMLString:| to modify the URL of
// the placeholder entry to the original URL and change the item state to
// kNavigatingToFailedNavigationItem.
// 3) Upon completion of the previous navigation, force a reload in WKWebView to
// reload the original URL and change the item state to
// kRetryFailedNavigationItem.
// 4) Upon completion of the reload, if successful, the item state is changed to
// kNoNavigationError.
// Full state transition diagram:
// https://docs.google.com/spreadsheets/d/1AdwRIuCShbRy4gEFB-SxaupmPmmO2MO7oLZ4F87XjRE/edit?usp=sharing
enum class ErrorRetryState {
// This is a new navigation request.
kNewRequest,
// This navigation item loaded without error.
kNoNavigationError,
// This navigation item failed to load and is in the process of loading a
// placeholder.
kLoadingPlaceholder,
// This navigation item failed to load and was stored in the WKBackForwardList
// and is now being reloaded.
kRetryPlaceholderNavigation,
// This navigation item has an entry in WKBackForwardList. Ready to present
// error in native view.
kReadyToDisplayError,
// This navigation item failed to load and a web error is displayed.
kDisplayingError,
// This navigation item is reactivated due to back/forward navigation and
// needs to try reloading.
kNavigatingToFailedNavigationItem,
// This navigation item is ready to be reloaded in web view.
kRetryFailedNavigationItem,
};
// Commands for CRWWebController to execute the state transition.
enum class ErrorRetryCommand {
// WebView should load placeholder request.
kLoadPlaceholder,
// WebView should load error view.
kLoadError,
// WebView should reload.
kReload,
// WebView should rewrite its URL (assumed to be a placeholder URL) to the
// navigation item's URL to prepare for reload.
kRewriteToWebViewURL,
// WebView should rewrite its URL to a placeholder URL to prepare for loading
// the error view.
kRewriteToPlaceholderURL,
// WebView doesn't need to do anything.
kDoNothing,
};
// A state machine that manages error and retry state of a navigation item. This
// is used to adapt WKWebView, which does not add provisional navigation failure
// to the back-forward list, to the Chrome convention, where such navigations
// are added to the back-forward list.
class ErrorRetryStateMachine {
public:
ErrorRetryStateMachine();
explicit ErrorRetryStateMachine(const ErrorRetryStateMachine& machine);
// Sets the original request URL to be tracked by this state machine. It is
// used for invariant detection.
void SetURL(const GURL& url);
// Returns the current error retry state.
ErrorRetryState state() const;
// Transitions the state machine to kNoNavigationError.
void SetNoNavigationError();
// Transitions the state machine to kDisplayingError.
void SetDisplayingWebError();
// Transitions the state machine to kRetryPlaceholderNavigation.
void SetRetryPlaceholderNavigation();
// Runs state transitions upon a failed provisional navigation.
ErrorRetryCommand DidFailProvisionalNavigation(const GURL& web_view_url,
const GURL& error_url);
// Runs state transitions upon a failure after the navigation is committed.
ErrorRetryCommand DidFailNavigation(const GURL& web_view_url);
// Runs state transitions upon a successful navigation.
ErrorRetryCommand DidFinishNavigation(const GURL& web_view_url);
private:
ErrorRetryCommand BackForwardOrReloadFailed();
ErrorRetryState state_;
GURL url_;
};
} // namespace web
#endif // IOS_WEB_NAVIGATION_ERROR_RETRY_STATE_MACHINE_H_