diff options
author | kkhorimoto <kkhorimoto@chromium.org> | 2015-06-08 14:47:52 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-06-08 21:48:27 +0000 |
commit | e0480417e2113a881182583a8d205ebe0738e4ce (patch) | |
tree | c843b460738a937c97ec2280ae3067d17b4eddad /ios/web | |
parent | e937e5fb5e6136ef27280fc7aad5502aa5a3cce2 (diff) | |
download | chromium_src-e0480417e2113a881182583a8d205ebe0738e4ce.zip chromium_src-e0480417e2113a881182583a8d205ebe0738e4ce.tar.gz chromium_src-e0480417e2113a881182583a8d205ebe0738e4ce.tar.bz2 |
Fixed zoom scale rotation bugs.
The percentage into the available zoom scale ranges for the scroll views
must be maintained after orientation changes. These bugs occur when pages
specify hardcoded values for their viewport widths. In UIWebView, rotation
that occurs after zooming has occurred will not trigger a relayout of the
scroll view's zoom scales. Similarly, WKWebView will not be zoomed properly
after a rotation that occurs after a pinch gesture.
BUG=462393, 488766
TEST= WKWebView: load en.wikipedia.org, pinch in and release so
that the zoom bounces back to 1.0, then rotate the device. The scale
should remain at 1.0. UIWebView: load www.reddit.com, pinch in, and release
so the zoom bounces back, then rotate the device. The page should
be zoomed in to fit with landscape width.
Review URL: https://codereview.chromium.org/1154163011
Cr-Commit-Position: refs/heads/master@{#333351}
Diffstat (limited to 'ios/web')
-rw-r--r-- | ios/web/public/web_state/page_scroll_state.h | 5 | ||||
-rw-r--r-- | ios/web/web_state/ui/crw_web_controller.mm | 57 |
2 files changed, 56 insertions, 6 deletions
diff --git a/ios/web/public/web_state/page_scroll_state.h b/ios/web/public/web_state/page_scroll_state.h index 9984019..b68598a 100644 --- a/ios/web/public/web_state/page_scroll_state.h +++ b/ios/web/public/web_state/page_scroll_state.h @@ -39,6 +39,11 @@ class PageScrollState { // can only be applied to CRWUIWebViewWebControllers. bool IsZoomScaleLegacyFormat() const; + // Returns the allowed zoom scale range for this scroll state. + double GetMinMaxZoomDifference() const { + return maximum_zoom_scale_ - minimum_zoom_scale_; + } + // Accessors for scroll offsets and zoom scale. double scroll_offset_x() const { return scroll_offset_x_; } void set_scroll_offset_x(double scroll_offset_x) { diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index c566bf0..1be4d7c 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm @@ -298,6 +298,11 @@ void CancelAllTouches(UIScrollView* web_scroll_view) { - (NSString*)javascriptToReplaceWebViewURL:(const GURL&)url stateObjectJSON:(NSString*)stateObject; - (BOOL)isLoaded; +// Called by NSNotificationCenter upon orientation changes. +- (void)orientationDidChange; +// Queries the web view for the user-scalable meta tag and calls +// |-applyPageScrollState:userScalable:| with the result. +- (void)applyPageScrollState:(const web::PageScrollState&)scrollState; // Restores state of the web view's scroll view from |scrollState|. // |isUserScalable| represents the value of user-scalable meta tag. - (void)applyPageScrollState:(const web::PageScrollState&)scrollState @@ -580,6 +585,11 @@ const NSTimeInterval kSnapshotOverlayTransition = 0.5; _gestureRecognizers.reset([[NSMutableArray alloc] init]); _webViewToolbars.reset([[NSMutableArray alloc] init]); _pendingLoadCompleteActions.reset([[NSMutableArray alloc] init]); + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(orientationDidChange) + name:UIApplicationDidChangeStatusBarOrientationNotification + object:nil]; } return self; } @@ -678,6 +688,7 @@ const NSTimeInterval kSnapshotOverlayTransition = 0.5; DCHECK(_isBeingDestroyed); // 'close' must have been called already. DCHECK(!self.webView); _touchTrackingRecognizer.get().touchTrackingDelegate = nil; + [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } @@ -3301,16 +3312,50 @@ const NSTimeInterval kSnapshotOverlayTransition = 0.5; _scrollStateOnStartLoading.scroll_offset_y() && [self absoluteZoomScaleForScrollState:currentScrollState] == [self absoluteZoomScaleForScrollState:_scrollStateOnStartLoading]) { - base::WeakNSObject<CRWWebController> weakSelf(self); - [self queryUserScalableProperty:^(BOOL isUserScalable) { - base::scoped_nsobject<CRWWebController> strongSelf([weakSelf retain]); - [strongSelf applyPageScrollState:pageScrollState - userScalable:isUserScalable]; - }]; + [self applyPageScrollState:pageScrollState]; } } } +- (void)orientationDidChange { + // When rotating, the available zoom scale range may change, zoomScale's + // percentage into this range should remain constant. However, there are + // two known bugs with respect to adjusting the zoomScale on rotation: + // - WKWebView sometimes erroneously resets the scroll view's zoom scale to + // an incorrect value ( rdar://20100815 ). + // - After zooming occurs in a UIWebView that's displaying a page with a hard- + // coded viewport width, the zoom will not be updated upon rotation + // ( crbug.com/485055 ). + if (!self.webView) + return; + web::NavigationItem* currentItem = self.currentNavItem; + if (!currentItem) + return; + web::PageScrollState scrollState = currentItem->GetPageScrollState(); + if (!scrollState.IsValid()) + return; + CGFloat zoomPercentage = + (scrollState.zoom_scale() - scrollState.minimum_zoom_scale()) / + scrollState.GetMinMaxZoomDifference(); + scrollState.set_minimum_zoom_scale(self.webScrollView.minimumZoomScale); + scrollState.set_maximum_zoom_scale(self.webScrollView.maximumZoomScale); + scrollState.set_zoom_scale(scrollState.minimum_zoom_scale() + + zoomPercentage * + scrollState.GetMinMaxZoomDifference()); + currentItem->SetPageScrollState(scrollState); + [self applyPageScrollState:currentItem->GetPageScrollState()]; +} + +- (void)applyPageScrollState:(const web::PageScrollState&)scrollState { + if (!scrollState.IsValid()) + return; + base::WeakNSObject<CRWWebController> weakSelf(self); + [self queryUserScalableProperty:^(BOOL isUserScalable) { + base::scoped_nsobject<CRWWebController> strongSelf([weakSelf retain]); + [strongSelf applyPageScrollState:scrollState userScalable:isUserScalable]; + }]; +} + - (void)applyPageScrollState:(const web::PageScrollState&)scrollState userScalable:(BOOL)isUserScalable { DCHECK(scrollState.IsValid()); |