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 #ifndef IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_H_
6 #define IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_H_
7 
8 #import <UIKit/UIKit.h>
9 
10 #include "ios/web/public/deprecated/url_verification_constants.h"
11 #import "ios/web/web_state/ui/crw_touch_tracking_recognizer.h"
12 #import "ios/web/web_state/ui/crw_web_view_navigation_proxy.h"
13 
14 namespace web {
15 
16 enum class NavigationInitiationType;
17 enum class WKNavigationState;
18 
19 }  // namespace web
20 
21 @class CRWJSInjector;
22 @protocol CRWScrollableContent;
23 @protocol CRWSwipeRecognizerProvider;
24 @class CRWWebViewContentView;
25 @protocol CRWWebViewProxy;
26 class GURL;
27 @class WKWebView;
28 
29 namespace web {
30 class NavigationItem;
31 class NavigationItemImpl;
32 class WebState;
33 class WebStateImpl;
34 }
35 
36 // Manages a view that can be used either for rendering web content in a web
37 // view. CRWWebController also transparently evicts and restores the internal
38 // web view based on memory pressure, and manages access to interact with the
39 // web view.
40 // This is an abstract class which must not be instantiated directly.
41 // TODO(stuartmorgan): Move all of the navigation APIs out of this class.
42 @interface CRWWebController : NSObject <CRWTouchTrackingDelegate>
43 
44 // Whether or not a UIWebView is allowed to exist in this CRWWebController.
45 // Defaults to NO; this should be enabled before attempting to access the view.
46 @property(nonatomic, assign) BOOL webUsageEnabled;
47 
48 @property(nonatomic, weak) id<CRWSwipeRecognizerProvider>
49     swipeRecognizerProvider;
50 
51 // The container view used to display content.  If the view has been purged due
52 // to low memory, this will recreate it.
53 @property(weak, nonatomic, readonly) UIView* view;
54 
55 // The web view proxy associated with this controller.
56 @property(strong, nonatomic, readonly) id<CRWWebViewProxy> webViewProxy;
57 
58 // The web view navigation proxy associated with this controller.
59 @property(weak, nonatomic, readonly) id<CRWWebViewNavigationProxy>
60     webViewNavigationProxy;
61 
62 // The fraction of the page load that has completed as a number between 0.0
63 // (nothing loaded) and 1.0 (fully loaded).
64 @property(nonatomic, readonly) double loadingProgress;
65 
66 // YES if the web process backing WebView is believed to currently be crashed.
67 @property(nonatomic, readonly, assign, getter=isWebProcessCrashed)
68     BOOL webProcessCrashed;
69 
70 // Whether the WebController is visible. Returns YES after wasShown call and
71 // NO after wasHidden() call.
72 @property(nonatomic, assign, getter=isVisible) BOOL visible;
73 
74 // A Boolean value indicating whether horizontal swipe gestures will trigger
75 // back-forward list navigations.
76 @property(nonatomic) BOOL allowsBackForwardNavigationGestures;
77 
78 // JavaScript injector.
79 @property(nonatomic, strong, readonly) CRWJSInjector* jsInjector;
80 
81 // Whether the WebController should attempt to keep the render process alive.
82 @property(nonatomic, assign, getter=shouldKeepRenderProcessAlive)
83     BOOL keepsRenderProcessAlive;
84 
85 // Designated initializer. Initializes web controller with |webState|. The
86 // calling code must retain the ownership of |webState|.
87 - (instancetype)initWithWebState:(web::WebStateImpl*)webState;
88 
89 // Returns the latest navigation item created for new navigation, which is
90 // stored in navigation context.
91 - (web::NavigationItemImpl*)lastPendingItemForNewNavigation;
92 
93 // Replaces the currently displayed content with |contentView|.  The content
94 // view will be dismissed for the next navigation.
95 - (void)showTransientContentView:(UIView<CRWScrollableContent>*)contentView;
96 
97 // Clear the transient content view, if one is shown. This is a delegate
98 // method for WebStateImpl::ClearTransientContent(). Callers should use the
99 // WebStateImpl API instead of calling this method directly.
100 - (void)clearTransientContentView;
101 
102 // Removes the back WebView. DANGER: this method is exposed for the sole purpose
103 // of allowing WKBasedNavigationManagerImpl to reset the back-forward history.
104 // Please reconsider before using this method.
105 - (void)removeWebView;
106 
107 // Call when the CRWWebController needs go away. Caller must reset the delegate
108 // before calling.
109 - (void)close;
110 
111 // Returns YES if there is currently a live view in the tab (e.g., the view
112 // hasn't been discarded due to low memory).
113 // NOTE: This should be used for metrics-gathering only; for any other purpose
114 // callers should not know or care whether the view is live.
115 - (BOOL)isViewAlive;
116 
117 // Returns YES if the current live view is a web view with HTML.
118 // TODO(crbug.com/949651): Remove once JSFindInPageManager is removed.
119 - (BOOL)contentIsHTML;
120 
121 // Returns the CRWWebController's view of the current URL. Moreover, this method
122 // will set the trustLevel enum to the appropriate level from a security point
123 // of view. The caller has to handle the case where |trustLevel| is not
124 // appropriate, as this method won't display any error to the user.
125 - (GURL)currentURLWithTrustLevel:(web::URLVerificationTrustLevel*)trustLevel;
126 
127 // Reloads web view. |isRendererInitiated| is YES for renderer-initiated
128 // navigation. |isRendererInitiated| is NO for browser-initiated navigation.
129 - (void)reloadWithRendererInitiatedNavigation:(BOOL)isRendererInitiated;
130 
131 // Loads the URL indicated by current session state.
132 - (void)loadCurrentURLWithRendererInitiatedNavigation:(BOOL)rendererInitiated;
133 
134 // Loads the URL indicated by current session state if the current page has not
135 // loaded yet. This method should never be called directly. Use
136 // NavigationManager::LoadIfNecessary() instead.
137 - (void)loadCurrentURLIfNecessary;
138 
139 // Loads |data| of type |MIMEType| and replaces last committed URL with the
140 // given |URL|.
141 // If a load is in progress, it will be stopped before the data is loaded.
142 - (void)loadData:(NSData*)data
143         MIMEType:(NSString*)MIMEType
144           forURL:(const GURL&)URL;
145 
146 // Stops loading the page.
147 - (void)stopLoading;
148 
149 // Records the state (scroll position, form values, whatever can be harvested)
150 // from the current page into the current session entry.
151 - (void)recordStateInHistory;
152 
153 // Notifies the CRWWebController that it has been shown.
154 - (void)wasShown;
155 
156 // Notifies the CRWWebController that it has been hidden.
157 - (void)wasHidden;
158 
159 // Called when NavigationManager has completed go to index same-document
160 // navigation. Updates HTML5 history state, current document URL and sends
161 // approprivate navigation and loading WebStateObserver callbacks.
162 - (void)didFinishGoToIndexSameDocumentNavigationWithType:
163             (web::NavigationInitiationType)type
164                                           hasUserGesture:(BOOL)hasUserGesture;
165 
166 // Instructs WKWebView to navigate to the given navigation item. |wk_item| and
167 // |item| must point to the same navigation item. Calling this method may
168 // result in an iframe navigation.
169 - (void)goToBackForwardListItem:(WKBackForwardListItem*)item
170                  navigationItem:(web::NavigationItem*)item
171        navigationInitiationType:(web::NavigationInitiationType)type
172                  hasUserGesture:(BOOL)hasUserGesture;
173 
174 // Takes snapshot of web view with |rect|. |rect| should be in self.view's
175 // coordinate system.  |completion| is always called, but |snapshot| may be nil.
176 // Prior to iOS 11, |completion| is called with a nil
177 // snapshot. |completion| may be called more than once.
178 - (void)takeSnapshotWithRect:(CGRect)rect
179                   completion:(void (^)(UIImage* snapshot))completion;
180 
181 // Creates PDF representation of the web page and invokes the |completion| with
182 // the NSData of the PDF or nil if a PDF couldn't be generated.
183 - (void)createFullPagePDFWithCompletion:
184     (void (^)(NSData* PDFDocumentData))completion;
185 
186 // Creates a web view if it's not yet created. Returns the web view.
187 - (WKWebView*)ensureWebViewCreated;
188 
189 // Removes the webView from the view hierarchy.
190 - (void)removeWebViewFromViewHierarchy;
191 // Adds the webView back in the view hierarchy.
192 - (void)addWebViewToViewHierarchy;
193 
194 @end
195 
196 #pragma mark Testing
197 
198 @interface CRWWebController (UsedOnlyForTesting)  // Testing or internal API.
199 
200 @property(nonatomic, readonly) web::WebState* webState;
201 @property(nonatomic, readonly) web::WebStateImpl* webStateImpl;
202 // Returns the current page loading phase.
203 // TODO(crbug.com/956511): Remove this once refactor is done.
204 @property(nonatomic, readonly, assign) web::WKNavigationState navigationState;
205 
206 // Injects a CRWWebViewContentView for testing.  Takes ownership of
207 // |webViewContentView|.
208 - (void)injectWebViewContentView:(CRWWebViewContentView*)webViewContentView;
209 - (void)resetInjectedWebViewContentView;
210 
211 // Returns whether any observers are registered with the CRWWebController.
212 - (BOOL)hasObservers;
213 
214 // Loads the HTML into the page at the given URL.
215 - (void)loadHTML:(NSString*)HTML forURL:(const GURL&)URL;
216 
217 @end
218 
219 #endif  // IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_H_
220