summaryrefslogtreecommitdiffstats
path: root/ios/web
diff options
context:
space:
mode:
authorkkhorimoto <kkhorimoto@chromium.org>2015-06-08 14:47:52 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-08 21:48:27 +0000
commite0480417e2113a881182583a8d205ebe0738e4ce (patch)
treec843b460738a937c97ec2280ae3067d17b4eddad /ios/web
parente937e5fb5e6136ef27280fc7aad5502aa5a3cce2 (diff)
downloadchromium_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.h5
-rw-r--r--ios/web/web_state/ui/crw_web_controller.mm57
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());