summaryrefslogtreecommitdiffstats
path: root/ios/web
diff options
context:
space:
mode:
authorstuartmorgan <stuartmorgan@chromium.org>2015-11-06 07:39:25 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-06 15:40:53 +0000
commit2d9691f83347aafb095c622212b44cc274a34508 (patch)
tree44dbdc3496e7b6e5947764a2852a3f224e40321d /ios/web
parenta505cbb45ec92d2617fe80490acf7d01ef4d3225 (diff)
downloadchromium_src-2d9691f83347aafb095c622212b44cc274a34508.zip
chromium_src-2d9691f83347aafb095c622212b44cc274a34508.tar.gz
chromium_src-2d9691f83347aafb095c622212b44cc274a34508.tar.bz2
Improve MIME type handling with WKWebView
Eliminates the MIME type variable within WebController, since WebState should already have that information. Also adds a new navigation state hook to WebStateImpl (which will eventually be drived by NavigationManager) that commits pending headers as soon as the load commits, rather than waiting for the page to finish loading. To avoid UIWebView regressions, that callback is called from load completion rather than on URL change. In the future if the UIWebView web controller is restructured to distinguish fully between URL and document changes, this could be revisited, but for now this preserves behavior for UIWebView, while creating a better flow for WKWebView. BUG=533454, 551686 TEST=Features that rely on MIME type (e.g., Find in Page) should work even after non-document-changing navigations. Review URL: https://codereview.chromium.org/1422553007 Cr-Commit-Position: refs/heads/master@{#358328}
Diffstat (limited to 'ios/web')
-rw-r--r--ios/web/web_state/ui/crw_ui_web_view_web_controller.mm10
-rw-r--r--ios/web/web_state/ui/crw_web_controller+protected.h4
-rw-r--r--ios/web/web_state/ui/crw_web_controller.mm1
-rw-r--r--ios/web/web_state/ui/crw_wk_web_view_web_controller.mm30
-rw-r--r--ios/web/web_state/web_state_impl.h3
-rw-r--r--ios/web/web_state/web_state_impl.mm7
-rw-r--r--ios/web/web_state/web_state_impl_unittest.mm7
7 files changed, 36 insertions, 26 deletions
diff --git a/ios/web/web_state/ui/crw_ui_web_view_web_controller.mm b/ios/web/web_state/ui/crw_ui_web_view_web_controller.mm
index a001266..072b026 100644
--- a/ios/web/web_state/ui/crw_ui_web_view_web_controller.mm
+++ b/ios/web/web_state/ui/crw_ui_web_view_web_controller.mm
@@ -881,6 +881,16 @@ const size_t kMaxMessageQueueSize = 262144;
}
}
+- (void)loadCompletedForURL:(const GURL&)loadedURL {
+ // This is not actually the right place to call this, and is here to preserve
+ // the existing UIWebView behavior during the WKWebView transition. This
+ // should actually be called at the point where the web view URL is known to
+ // have actually changed, but currently there's not a clear way of knowing
+ // when that happens as a result of a load (vs. an in-page navigation), and
+ // over-calling this would regress other behavior.
+ self.webStateImpl->OnNavigationCommitted(loadedURL);
+}
+
#pragma mark - JS to ObjC messaging
- (void)respondToJSInvoke {
diff --git a/ios/web/web_state/ui/crw_web_controller+protected.h b/ios/web/web_state/ui/crw_web_controller+protected.h
index bfabca4..2a034cd 100644
--- a/ios/web/web_state/ui/crw_web_controller+protected.h
+++ b/ios/web/web_state/ui/crw_web_controller+protected.h
@@ -174,6 +174,10 @@ struct NewWindowInfo {
// Handles cancelled load in WKWebView (error with NSURLErrorCancelled code).
- (void)handleCancelledError:(NSError*)error;
+// Called when a load completes, to perform any final actions before informing
+// delegates.
+- (void)loadCompletedForURL:(const GURL&)loadedURL;
+
#pragma mark - Optional methods for subclasses
// Subclasses may overwrite methods in this section.
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index 630a84b..14f76f5 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -1784,6 +1784,7 @@ const NSTimeInterval kSnapshotOverlayTransition = 0.5;
_webStateImpl->GetCacheMode());
[self restoreStateFromHistory];
+ [self loadCompletedForURL:currentURL];
_webStateImpl->OnPageLoaded(currentURL, loadSuccess);
_webStateImpl->SetIsLoading(false);
// Inform the embedder the load completed.
diff --git a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
index d85fdb7..65a8f84 100644
--- a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
+++ b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
@@ -139,9 +139,6 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
// Referrer for the current page.
base::scoped_nsobject<NSString> _currentReferrerString;
- // Backs the property of the same name.
- base::scoped_nsobject<NSString> _documentMIMEType;
-
// Navigation type of the pending navigation action of the main frame. This
// value is assigned at |decidePolicyForNavigationAction| where the navigation
// type is extracted from the request and associated with a committed
@@ -181,9 +178,6 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
BOOL _interactionRegisteredSinceLastURLChange;
}
-// Response's MIME type of the last known navigation.
-@property(nonatomic, copy) NSString* documentMIMEType;
-
// Dictionary where keys are the names of WKWebView properties and values are
// selector names which should be called when a corresponding property has
// changed. e.g. @{ @"URL" : @"webViewURLDidChange" } means that
@@ -510,13 +504,13 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
return web::WEB_VIEW_DOCUMENT_TYPE_GENERIC;
}
- if (!self.documentMIMEType) {
+ std::string mimeType = self.webState->GetContentsMimeType();
+ if (mimeType.empty()) {
return web::WEB_VIEW_DOCUMENT_TYPE_UNKNOWN;
}
- if ([self.documentMIMEType isEqualToString:@"text/html"] ||
- [self.documentMIMEType isEqualToString:@"application/xhtml+xml"] ||
- [self.documentMIMEType isEqualToString:@"application/xml"]) {
+ if (mimeType == "text/html" || mimeType == "application/xhtml+xml" ||
+ mimeType == "application/xml") {
return web::WEB_VIEW_DOCUMENT_TYPE_HTML;
}
@@ -670,15 +664,11 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
}
}
-#pragma mark Private methods
-
-- (NSString*)documentMIMEType {
- return _documentMIMEType.get();
+- (void)loadCompletedForURL:(const GURL&)loadedURL {
+ // Nothing to do.
}
-- (void)setDocumentMIMEType:(NSString*)type {
- _documentMIMEType.reset([type copy]);
-}
+#pragma mark Private methods
- (NSDictionary*)wkWebViewObservers {
return @{
@@ -1517,9 +1507,6 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
[self updatePendingNavigationTypeForMainFrameFromNavigationAction:
navigationAction];
- if (navigationAction.sourceFrame.mainFrame)
- self.documentMIMEType = nil;
-
web::FrameInfo targetFrame(navigationAction.targetFrame.mainFrame);
BOOL isLinkClick = [self isLinkNavigation:navigationAction.navigationType];
BOOL allowLoad = [self shouldAllowLoadWithRequest:request
@@ -1552,8 +1539,6 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
self.webStateImpl->OnHttpResponseHeadersReceived(
HTTPHeaders.get(), net::GURLWithNSURL(navigationResponse.response.URL));
}
- if (navigationResponse.isForMainFrame)
- self.documentMIMEType = navigationResponse.response.MIMEType;
BOOL allowNavigation = navigationResponse.canShowMIMEType;
if (allowNavigation) {
@@ -1663,6 +1648,7 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
// This is the point where the document's URL has actually changed.
[self setDocumentURL:net::GURLWithNSURL([_wkWebView URL])];
DCHECK(_documentURL == self.lastRegisteredRequestURL);
+ self.webStateImpl->OnNavigationCommitted(_documentURL);
[self webPageChanged];
[self updateCurrentBackForwardListItemHolder];
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h
index 55eea50..b5d346a 100644
--- a/ios/web/web_state/web_state_impl.h
+++ b/ios/web/web_state/web_state_impl.h
@@ -77,6 +77,9 @@ class WebStateImpl : public WebState, public NavigationManagerDelegate {
// Notifies the observers that a provisional navigation has started.
void OnProvisionalNavigationStarted(const GURL& url);
+ // Called when a navigation is committed.
+ void OnNavigationCommitted(const GURL& url);
+
// Notifies the observers that the URL hash of the current page changed.
void OnUrlHashChanged();
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm
index 5129789..7a8aaf8 100644
--- a/ios/web/web_state/web_state_impl.mm
+++ b/ios/web/web_state/web_state_impl.mm
@@ -109,6 +109,10 @@ WebStateImpl* WebStateImpl::CopyForSessionWindow() {
return copy;
}
+void WebStateImpl::OnNavigationCommitted(const GURL& url) {
+ UpdateHttpResponseHeaders(url);
+}
+
void WebStateImpl::OnUrlHashChanged() {
FOR_EACH_OBSERVER(WebStateObserver, observers_, UrlHashChanged());
}
@@ -157,7 +161,6 @@ bool WebStateImpl::IsBeingDestroyed() const {
}
void WebStateImpl::OnPageLoaded(const GURL& url, bool load_success) {
- UpdateHttpResponseHeaders(url);
if (facade_delegate_)
facade_delegate_->OnPageLoaded();
@@ -315,6 +318,8 @@ void WebStateImpl::OnHttpResponseHeadersReceived(
// Store the headers in a map until the page finishes loading, as we do not
// know which URL corresponds to the main page yet.
// Remove the hash (if any) as it is sometimes altered by in-page navigations.
+ // TODO(crbug/551677): Simplify all this logic once UIWebView is no longer
+ // supported.
const GURL& url = GURLByRemovingRefFromGURL(resource_url);
response_headers_map_[url] = response_headers;
}
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm
index a3d5e91..1c13c78 100644
--- a/ios/web/web_state/web_state_impl_unittest.mm
+++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -250,7 +250,8 @@ TEST_F(WebStateTest, ResponseHeaders) {
web_state_->OnHttpResponseHeadersReceived(real_headers.get(), real_url);
web_state_->OnHttpResponseHeadersReceived(frame_headers.get(), frame_url);
// Include a hash to be sure it's handled correctly.
- web_state_->OnPageLoaded(GURL(real_url.spec() + std::string("#baz")), true);
+ web_state_->OnNavigationCommitted(
+ GURL(real_url.spec() + std::string("#baz")));
// Verify that the right header set was kept.
EXPECT_TRUE(
@@ -276,14 +277,14 @@ TEST_F(WebStateTest, ResponseHeaderClearing) {
EXPECT_EQ(NULL, web_state_->GetHttpResponseHeaders());
// There should be headers and parsed values after loading.
- web_state_->OnPageLoaded(url, true);
+ web_state_->OnNavigationCommitted(url);
EXPECT_TRUE(web_state_->GetHttpResponseHeaders()->HasHeader("Content-Type"));
EXPECT_NE("", web_state_->GetContentsMimeType());
EXPECT_NE("", web_state_->GetContentLanguageHeader());
// ... but not after loading another page, nor should there be specific
// parsed values.
- web_state_->OnPageLoaded(GURL("http://elsewhere.com/"), true);
+ web_state_->OnNavigationCommitted(GURL("http://elsewhere.com/"));
EXPECT_EQ(NULL, web_state_->GetHttpResponseHeaders());
EXPECT_EQ("", web_state_->GetContentsMimeType());
EXPECT_EQ("", web_state_->GetContentLanguageHeader());