1 // Copyright 2014 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.
5 #ifndef IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_PROTECTED_H_
6 #define IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_PROTECTED_H_
8 #import "ios/web/web_state/ui/crw_web_controller.h"
10 #include "base/mac/scoped_nsobject.h"
11 #include "ios/web/public/referrer.h"
12 #include "ios/web/public/web_state/page_display_state.h"
14 @
class CRWSessionController
;
21 // Separator between window href and name.
22 extern const char* kWindowNameSeparator
;
23 // Key for user interaction data in JavaScript message context.
24 extern NSString
* const kUserIsInteractingKey
;
25 // Key for origin URL data in JavaScript message context.
26 extern NSString
* const kOriginURLKey
;
28 // Values of the UMA |Web.URLVerificationFailure| histogram.
29 enum WebViewDocumentType
{
30 // Generic contents (e.g. PDF documents).
31 WEB_VIEW_DOCUMENT_TYPE_GENERIC
= 0,
33 WEB_VIEW_DOCUMENT_TYPE_HTML
,
35 WEB_VIEW_DOCUMENT_TYPE_UNKNOWN
,
36 WEB_VIEW_DOCUMENT_TYPE_COUNT
,
39 // A guess for how likely a page change is to happen very soon.
40 // TODO(stuartmorgan): Eliminate this, or at least move to the UIWebView
42 enum PageChangeProbability
{
43 // No expectation that the page will be changing.
44 PAGE_CHANGE_PROBABILITY_LOW
,
45 // Reasonably high expectation that the page will be changing (e.g., the
46 // user just tapped a link).
47 PAGE_CHANGE_PROBABILITY_HIGH
,
48 // Very high expectation that the page will be changing (e.g., window.unload
50 PAGE_CHANGE_PROBABILITY_VERY_HIGH
,
53 struct NewWindowInfo
{
55 base::scoped_nsobject
<NSString
> window_name
;
56 web::ReferrerPolicy referrer_policy
;
57 bool user_is_interacting
;
58 NewWindowInfo(GURL url
,
59 NSString
* window_name
,
60 web::ReferrerPolicy referrer_policy
,
61 bool user_is_interacting
);
66 // Category for methods used or implemented by implementation subclasses of
68 @interface
CRWWebController (ProtectedMethods
)
70 #pragma mark Methods implemented by subclasses
71 // Everything in this section must be implemented by subclasses.
73 // If |contentView_| contains a web view, this is the web view it contains.
75 @
property(nonatomic
, readonly
) UIView
* webView
;
77 // The scroll view of |webView|.
78 @
property(nonatomic
, readonly
) UIScrollView
* webScrollView
;
80 // Whether or not to ignore URL verification failures. This may return YES in
81 // very limited situations where the URL can't be verified but there is no
82 // security impact to ignoring the failure (i.e., it's safe not to show the
84 @
property(nonatomic
, readonly
) BOOL ignoreURLVerificationFailures
;
86 // The title of the page.
87 @
property(nonatomic
, readonly
) NSString
* title
;
89 // Referrer for the current page; does not include the fragment.
90 @
property(nonatomic
, readonly
) NSString
* currentReferrerString
;
92 // This public property should be implemented by subclasses.
93 // TODO(stuartmorgan): See if we can get rid of this (it looks like it may only
94 // be fallback code for autocomplete that's necessarily used). If not, file a
95 // Radar since WKWebView doesn't appear to have this property.
96 // @property(nonatomic, assign) BOOL keyboardDisplayRequiresUserAction;
98 // Designated initializer.
99 - (instancetype
)initWithWebState
:(scoped_ptr
<web::WebStateImpl
>)webState
;
101 // Creates a web view if it's not yet created.
102 - (void)ensureWebViewCreated
;
104 // Destroys the web view by setting webView property to nil.
105 - (void)resetWebView
;
107 // Returns the current URL of the web view, and sets |trustLevel| accordingly
108 // based on the confidence in the verification.
109 - (GURL
)webURLWithTrustLevel
:(web::URLVerificationTrustLevel
*)trustLevel
;
111 // Registers the current user agent with the web view.
112 - (void)registerUserAgent
;
114 // Returns YES if the current navigation item corresponds to a web page
115 // loaded by a POST request.
116 - (BOOL
)isCurrentNavigationItemPOST
;
118 // Returns the type of document object loaded in the web view.
119 - (web::WebViewDocumentType
)webViewDocumentType
;
121 // Loads the given HTML in the web view.
122 - (void)loadWebHTMLString
:(NSString
*)html forURL
:(const GURL
&)URL
;
124 // These public methods should be implemented by subclasses.
125 //- (void)evaluateJavaScript:(NSString*)script
126 // stringResultHandler:(web::JavaScriptCompletion)handler;
127 //- (BOOL)scriptHasBeenInjectedForClass:(Class)jsInjectionManagerClass
128 // presenceBeacon:(NSString*)beacon;
129 //- (void)loadRequest:(NSMutableURLRequest*)request;
130 // Subclasses must call super's implementation.
131 //- (void)injectScript:(NSString*)script
132 // forClass:(Class)jsInjectionManagerClass;
133 //- (web::WebViewType)webViewType;
134 //- (void)evaluateUserJavaScript:(NSString*)script;
136 // Called before loading current URL in WebView.
137 - (void)willLoadCurrentURLInWebView
;
139 // Loads request for the URL of the current navigation item. Subclasses may
140 // choose to build a new NSURLRequest and call |loadRequest| on the underlying
141 // web view, or use native web view navigation where possible (for example,
142 // going back and forward through the history stack).
143 - (void)loadRequestForCurrentNavigationItem
;
145 // Indicates whether or not there's an indication that the page is probably
146 // about to change. This is called as a hint to the UIWebView-based subclass to
147 // change polling behavior.
148 // TODO(stuartmorgan): Remove once the hook points are driven from the subclass.
149 - (void)setPageChangeProbability
:(web::PageChangeProbability
)probability
;
151 // Cancels any load in progress in the web view.
152 - (void)abortWebLoad
;
154 // Called whenever any in-progress-load state should be reset.
155 // TODO(stuartmorgan): Remove this; it should be tracked internally to each
156 // subclass, since the existing logic is somewhat UIWebView-guesswork-based.
157 - (void)resetLoadState
;
159 // Evaluates given JavaScript to suppress the dialogs. Subclasses should prefer
160 // synchronous execution.
161 - (void)setSuppressDialogsWithHelperScript
:(NSString
*)script
;
163 // Called when CRWWebController believes that web page title has been changed.
164 - (void)titleDidChange
;
166 // Returns selector to handle JavaScript message with command property
167 // |command|. Subclasses may override to handle class-specific messages.
168 - (SEL
)selectorToHandleJavaScriptCommand
:(const std::string
&)command
;
170 // Sets zoom scale value for webview scroll view from |zoomState|.
171 - (void)applyWebViewScrollZoomScaleFromZoomState
:
172 (const web::PageZoomState
&)zoomState
;
174 // Handles cancelled load in WKWebView (error with NSURLErrorCancelled code).
175 - (void)handleCancelledError
:(NSError
*)error
;
177 #pragma mark - Optional methods for subclasses
178 // Subclasses may overwrite methods in this section.
180 // Checks if the URL has changed unexpectedly, and handles such changes.
181 // Returns true if the URL has changed.
182 // TODO(stuartmorgan): Remove once the hook points are driven from the subclass.
183 - (BOOL
)checkForUnexpectedURLChange
;
185 // Handles 'window.history.willChangeState' message.
186 - (BOOL
)handleWindowHistoryWillChangeStateMessage
:
187 (base::DictionaryValue
*)message
188 context
:(NSDictionary
*)context
;
189 // Handles 'window.history.didPushState' message.
190 - (BOOL
)handleWindowHistoryDidPushStateMessage
:(base::DictionaryValue
*)message
191 context
:(NSDictionary
*)context
;
193 // Handles 'window.history.didReplaceState' message.
194 - (BOOL
)handleWindowHistoryDidReplaceStateMessage
:
195 (base::DictionaryValue
*)message
196 context
:(NSDictionary
*)context
;
198 // Sets up WebUI for URL.
199 - (void)createWebUIForURL
:(const GURL
&)URL
;
201 // Clears WebUI, if one exists.
204 // Returns a NSMutableURLRequest that represents the current NavigationItem.
205 - (NSMutableURLRequest
*)requestForCurrentNavigationItem
;
207 // Compares the two URLs being navigated between during a history navigation to
208 // determine if a # needs to be appended to the URL of |toItem| to trigger a
209 // hashchange event. If so, also saves the modified URL into |toItem|.
210 - (GURL
)URLForHistoryNavigationFromItem
:(web::NavigationItem
*)fromItem
211 toItem
:(web::NavigationItem
*)toItem
;
213 #pragma mark - Internal methods for use by subclasses
215 // The web view's view of the current URL. During page transitions
216 // this may not be the same as the session history's view of the current URL.
217 // This method can change the state of the CRWWebController, as it will display
218 // an error if the returned URL is not reliable from a security point of view.
219 // Note that this method is expensive, so it should always be cached locally if
220 // it's needed multiple times in a method.
221 @
property(nonatomic
, readonly
) GURL currentURL
;
223 // The default URL for a newly created web view.
224 @
property(nonatomic
, readonly
) const GURL
& defaultURL
;
226 // Last URL change reported to webDidStartLoadingURL. Used to detect page
227 // location changes in practice.
228 @
property(nonatomic
, readonly
) GURL URLOnStartLoading
;
230 // Last URL change registered for load request.
231 @
property(nonatomic
, readonly
) GURL lastRegisteredRequestURL
;
233 // Returns YES if the object is being deallocated.
234 @
property(nonatomic
, readonly
) BOOL isBeingDestroyed
;
236 // Return YES if network activity is being halted. Halting happens prior to
238 @
property(nonatomic
, readonly
) BOOL isHalted
;
240 // Returns whether the user is interacting with the page.
241 @
property(nonatomic
, readonly
) BOOL userIsInteracting
;
243 // YES if a user interaction has been registered at any time once the page has
245 @
property(nonatomic
, readonly
) BOOL userInteractionRegistered
;
247 // Returns the current window id.
248 @
property(nonatomic
, readonly
) NSString
* windowId
;
250 // Returns windowID that is saved when a page changes. Used to detect refreshes.
251 @
property(nonatomic
, readonly
) NSString
* lastSeenWindowID
;
253 // Returns NavigationManager's session controller.
254 @
property(nonatomic
, readonly
) CRWSessionController
* sessionController
;
256 // Returns a new script which wraps |script| with windowID check so |script| is
257 // not evaluated on windowID mismatch.
258 - (NSString
*)scriptByAddingWindowIDCheckForScript
:(NSString
*)script
;
260 // Removes webView, optionally tracking the URL of the evicted
261 // page for later cache-based reconstruction.
262 - (void)removeWebViewAllowingCachedReconstruction
:(BOOL
)allowCache
;
264 // Subclasses must call this method every time when web view has been created
265 // or recreated. This method should not be called if a web view property has
266 // changed (e.g. view's background color). Web controller adds |webView| to its
268 - (void)webViewDidChange
;
270 // Updates the internal state and informs the delegate that any outstanding load
271 // operations are cancelled.
272 - (void)loadCancelled
;
274 // Aborts any load for both the web view and web controller.
277 // Returns the URL that the navigation system believes should be currently
279 // TODO(stuartmorgan):Remove this in favor of more specific getters.
280 - (const GURL
&)currentNavigationURL
;
282 // Called when the web page has changed document and/or URL, and so the page
283 // navigation should be reported to the delegate, and internal state updated to
284 // reflect the fact that the navigation has occurred.
285 // TODO(stuartmorgan): The code conflates URL changes and document object
286 // changes; the two need to be separated and handled differently.
287 - (void)webPageChanged
;
289 // Injects all scripts registered for early injection, as well as the window ID,
290 // if necssary. If they are already injected, this is a no-op.
291 - (void)injectEarlyInjectionScripts
;
293 // Inject windowID if not yet injected.
294 - (void)injectWindowID
;
296 // Called when a page (native or web) has actually started loading (i.e., for
297 // a web page the document has actually changed), or after the load request has
298 // been registered for a non-document-changing URL change. Updates internal
299 // state not specific to web pages, and informs the delegate.
300 - (void)didStartLoadingURL
:(const GURL
&)URL updateHistory
:(BOOL
)updateHistory
;
302 // Should be called with YES if a user interaction has been registered at any
303 // time once the page has loaded.
304 - (void)setUserInteractionRegistered
:(BOOL
)flag
;
306 // Returns YES if the user interacted with the page recently.
307 - (BOOL
)userClickedRecently
;
309 // Returns whether the desktop user agent should be used when setting the user
311 - (BOOL
)useDesktopUserAgent
;
313 // Called when SSL status has been updated for the current navigation item.
314 - (void)didUpdateSSLStatusForCurrentNavigationItem
;
316 // Processes the given web invocation; urlSchemeIsWebInvoke: must return YES
317 // for the given URL. |request| should be the request associated with that load.
318 - (void)handleWebInvokeURL
:(const GURL
&)url request
:(NSURLRequest
*)request
;
320 // Returns YES if the given load request should be allowed to continue. If this
321 // returns NO, the load should be cancelled. |targetFrame| contains information
322 // about the frame to which navigation is targeted, can be null.
323 // |isLinkClick| should indicate whether the navigation is the
324 // result of a link click (either directly, or via JS triggered by a link).
325 - (BOOL
)shouldAllowLoadWithRequest
:(NSURLRequest
*)request
326 targetFrame
:(const web::FrameInfo
*)targetFrame
327 isLinkClick
:(BOOL
)isLinkClick
;
329 // Prepares web controller and delegates for anticipated page change.
330 // Allows several methods to invoke webWill/DidAddPendingURL on anticipated page
331 // change, using the same cached request and calculated transition types.
332 - (void)registerLoadRequest
:(const GURL
&)URL
333 referrer
:(const web::Referrer
&)referrer
334 transition
:(ui::PageTransition
)transition
;
336 // Called when a load ends in an error.
337 // TODO(stuartmorgan): Figure out if there's actually enough shared logic that
338 // this makes sense. At the very least remove inMainFrame since that only makes
339 // sense for UIWebView.
340 - (void)handleLoadError
:(NSError
*)error inMainFrame
:(BOOL
)inMainFrame
;
342 // Update the appropriate parts of the model and broadcast to the embedder. This
343 // may be called multiple times and thus must be idempotent.
344 - (void)loadCompleteWithSuccess
:(BOOL
)loadSuccess
;
346 // Creates a new opened by DOM window and returns its autoreleased web
348 - (CRWWebController
*)createChildWebControllerWithReferrerURL
:
349 (const GURL
&)referrerURL
;
351 // Called following navigation completion to generate final navigation lifecycle
352 // events. Navigation is considered complete when the document has finished
353 // loading, or when other page load mechanics are completed on a
354 // non-document-changing URL change.
355 - (void)didFinishNavigation
;
357 // Returns the referrer policy for the given referrer policy string (as reported
359 - (web::ReferrerPolicy
)referrerPolicyFromString
:(const std::string
&)policy
;
361 // Returns YES if the popup should be blocked, NO otherwise.
362 - (BOOL
)shouldBlockPopupWithURL
:(const GURL
&)popupURL
363 sourceURL
:(const GURL
&)sourceURL
;
365 // Call to stop web controller activity, in particular to stop all network
366 // requests. Called as part of the close sequence if it hasn't already been
367 // halted; should also be called from the web delegate as part of any shutdown
368 // sequence which doesn't call -close.
369 - (void)terminateNetworkActivity
;
371 // Acts on a single message from the JS object, parsed from JSON into a
372 // DictionaryValue. Returns NO if the format for the message was invalid.
373 - (BOOL
)respondToMessage
:(base::DictionaryValue
*)crwMessage
374 userIsInteracting
:(BOOL
)userIsInteracting
375 originURL
:(const GURL
&)originURL
;
377 // Asynchronously determines window size of the web page. |handler| cannot
379 - (void)fetchWebPageSizeWithCompletionHandler
:(void (^)(CGSize
))handler
;
381 // Tries to open a popup with the given new window information.
382 - (void)openPopupWithInfo
:(const web::NewWindowInfo
&)windowInfo
;
384 // Returns the current entry from the underlying session controller.
385 // TODO(stuartmorgan): Audit all calls to these methods; these are just wrappers
386 // around the same logic as GetActiveEntry, so should probably not be used for
387 // the same reason that GetActiveEntry is deprecated. (E.g., page operations
388 // should generally be dealing with the last commited entry, not a pending
390 - (CRWSessionEntry
*)currentSessionEntry
;
391 // Returns the navigation item for the current page.
392 - (web::NavigationItem
*)currentNavItem
;
394 // The HTTP headers associated with the current navigation item. These are nil
395 // unless the request was a POST.
396 - (NSDictionary
*)currentHTTPHeaders
;
398 // Returns the referrer for the current page.
399 - (web::Referrer
)currentReferrer
;
401 // Returns the referrer for current navigation item. May be empty.
402 - (web::Referrer
)currentSessionEntryReferrer
;
404 // Returns the current transition type.
405 - (ui::PageTransition
)currentTransition
;
407 // Returns the current entry from the underlying session controller.
408 - (CRWSessionEntry
*)currentSessionEntry
;
410 // Resets pending external request information.
411 - (void)resetExternalRequest
;
415 #endif // IOS_WEB_WEB_STATE_UI_CRW_WEB_CONTROLLER_PROTECTED_H_