summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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());