Commit def17f59 authored by Kurt Horimoto's avatar Kurt Horimoto Committed by Commit Bot

[iOS] Implement hybrid viewport adjustment experiment.

This CL adds an additional fullscreen viewport adjustment experiment.
In this approach, the WKWebView's frame is translated up and down to
account for the bottom inset created by the secondary toolbar.
Meanwhile, the top safe area inset is adjusted to push the top of the
rendered viewport below the toolbars.

Bug: none
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: Idb3ae9fb11ca2b35ee5219a52f9e08aa14363a7b
Reviewed-on: https://chromium-review.googlesource.com/1066975
Commit-Queue: Kurt Horimoto <kkhorimoto@chromium.org>
Reviewed-by: default avatarJustin Cohen <justincohen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#562562}
parent 95e4f867
...@@ -1384,7 +1384,9 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint { ...@@ -1384,7 +1384,9 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
fullscreen::features::ViewportAdjustmentExperiment viewportExperiment = fullscreen::features::ViewportAdjustmentExperiment viewportExperiment =
fullscreen::features::GetActiveViewportExperiment(); fullscreen::features::GetActiveViewportExperiment();
return viewportExperiment == return viewportExperiment ==
fullscreen::features::ViewportAdjustmentExperiment::SAFE_AREA; fullscreen::features::ViewportAdjustmentExperiment::SAFE_AREA ||
viewportExperiment ==
fullscreen::features::ViewportAdjustmentExperiment::HYBRID;
} }
return NO; return NO;
} }
...@@ -4169,6 +4171,11 @@ bubblePresenterForFeature:(const base::Feature&)feature ...@@ -4169,6 +4171,11 @@ bubblePresenterForFeature:(const base::Feature&)feature
AlignValueToPixel(progress * [self secondaryToolbarHeightWithInset]); AlignValueToPixel(progress * [self secondaryToolbarHeightWithInset]);
if (self.usesSafeInsetsForViewportAdjustments) { if (self.usesSafeInsetsForViewportAdjustments) {
if (fullscreen::features::GetActiveViewportExperiment() ==
fullscreen::features::ViewportAdjustmentExperiment::HYBRID) {
[self updateWebViewFrameForBottomOffset:bottom];
}
[self updateBrowserSafeAreaForTopToolbarHeight:top [self updateBrowserSafeAreaForTopToolbarHeight:top
bottomToolbarHeight:bottom]; bottomToolbarHeight:bottom];
} else { } else {
...@@ -4177,6 +4184,27 @@ bubblePresenterForFeature:(const base::Feature&)feature ...@@ -4177,6 +4184,27 @@ bubblePresenterForFeature:(const base::Feature&)feature
} }
} }
// Updates the frame of the web view so that it's |offset| from the bottom of
// the container view.
- (void)updateWebViewFrameForBottomOffset:(CGFloat)offset {
if (!self.currentWebState)
return;
// Move the frame of the container view such that the bottom is aligned with
// the top of the bottom toolbar.
id<CRWWebViewProxy> webViewProxy = self.currentWebState->GetWebViewProxy();
CGRect webViewFrame = webViewProxy.frame;
CGFloat oldOriginY = CGRectGetMinY(webViewFrame);
webViewProxy.contentOffset = CGPointMake(0.0, -offset);
// Update the contentOffset so that the scroll position is maintained
// relative to the screen.
CRWWebViewScrollViewProxy* scrollViewProxy = webViewProxy.scrollViewProxy;
CGFloat originDelta = CGRectGetMinY(webViewProxy.frame) - oldOriginY;
CGPoint contentOffset = scrollViewProxy.contentOffset;
contentOffset.y += originDelta;
scrollViewProxy.contentOffset = contentOffset;
}
// Updates the web view's viewport by changing the safe area insets. // Updates the web view's viewport by changing the safe area insets.
- (void)updateBrowserSafeAreaForTopToolbarHeight:(CGFloat)topToolbarHeight - (void)updateBrowserSafeAreaForTopToolbarHeight:(CGFloat)topToolbarHeight
bottomToolbarHeight:(CGFloat)bottomToolbarHeight { bottomToolbarHeight:(CGFloat)bottomToolbarHeight {
...@@ -4184,7 +4212,9 @@ bubblePresenterForFeature:(const base::Feature&)feature ...@@ -4184,7 +4212,9 @@ bubblePresenterForFeature:(const base::Feature&)feature
_browserContainerCoordinator.viewController; _browserContainerCoordinator.viewController;
if (@available(iOS 11, *)) { if (@available(iOS 11, *)) {
containerViewController.additionalSafeAreaInsets = UIEdgeInsetsMake( containerViewController.additionalSafeAreaInsets = UIEdgeInsetsMake(
topToolbarHeight - self.view.safeAreaInsets.top, 0, 0, 0); topToolbarHeight - self.view.safeAreaInsets.top -
self.currentWebState->GetWebViewProxy().contentOffset.y,
0, 0, 0);
} }
} }
......
...@@ -17,15 +17,17 @@ extern const char kViewportAdjustmentExperimentCommandLineSwitch[]; ...@@ -17,15 +17,17 @@ extern const char kViewportAdjustmentExperimentCommandLineSwitch[];
// The available viewport adjustment experiments. The choices in this array // The available viewport adjustment experiments. The choices in this array
// correspond with the ViewportAdjustmentExperiment values. // correspond with the ViewportAdjustmentExperiment values.
extern const flags_ui::FeatureEntry::Choice extern const flags_ui::FeatureEntry::Choice
kViewportAdjustmentExperimentChoices[3]; kViewportAdjustmentExperimentChoices[4];
// Enum type describing viewport adjustment experiments. // Enum type describing viewport adjustment experiments.
enum class ViewportAdjustmentExperiment : short { enum class ViewportAdjustmentExperiment : short {
FRAME = 0, // Adjust the viewport by resizing the entire WKWebView. FRAME = 0, // Adjust the viewport by resizing the entire WKWebView.
CONTENT_INSET, // Adjust the viewport by updating the WKWebView's scroll view CONTENT_INSET, // Adjust the viewport by updating the WKWebView's scroll view
// contentInset. // contentInset.
SAFE_AREA // Adjust the viewport by updating the safe area of the browser SAFE_AREA, // Adjust the viewport by updating the safe area of the browser
// container view. // container view.
HYBRID, // Translates the web view up and down and updates the viewport using
// safe area insets.
}; };
// Convenience method for retrieving the active viewport adjustment experiment // Convenience method for retrieving the active viewport adjustment experiment
......
...@@ -15,6 +15,7 @@ namespace { ...@@ -15,6 +15,7 @@ namespace {
// choices. // choices.
const char kContentInsetChoiceValue[] = "content-inset"; const char kContentInsetChoiceValue[] = "content-inset";
const char kSafeAreaChoiceValue[] = "safe-area"; const char kSafeAreaChoiceValue[] = "safe-area";
const char kHybridChoiceValue[] = "hybrid";
} }
namespace fullscreen { namespace fullscreen {
...@@ -29,6 +30,8 @@ const flags_ui::FeatureEntry::Choice kViewportAdjustmentExperimentChoices[] = { ...@@ -29,6 +30,8 @@ const flags_ui::FeatureEntry::Choice kViewportAdjustmentExperimentChoices[] = {
"content-inset"}, "content-inset"},
{"Update Safe Area", kViewportAdjustmentExperimentCommandLineSwitch, {"Update Safe Area", kViewportAdjustmentExperimentCommandLineSwitch,
"safe-area"}, "safe-area"},
{"Use Hybrid Implementation",
kViewportAdjustmentExperimentCommandLineSwitch, "hybrid"},
}; };
ViewportAdjustmentExperiment GetActiveViewportExperiment() { ViewportAdjustmentExperiment GetActiveViewportExperiment() {
...@@ -41,6 +44,8 @@ ViewportAdjustmentExperiment GetActiveViewportExperiment() { ...@@ -41,6 +44,8 @@ ViewportAdjustmentExperiment GetActiveViewportExperiment() {
return ViewportAdjustmentExperiment::CONTENT_INSET; return ViewportAdjustmentExperiment::CONTENT_INSET;
if (viewport_experiment == std::string(kSafeAreaChoiceValue)) if (viewport_experiment == std::string(kSafeAreaChoiceValue))
return ViewportAdjustmentExperiment::SAFE_AREA; return ViewportAdjustmentExperiment::SAFE_AREA;
if (viewport_experiment == std::string(kHybridChoiceValue))
return ViewportAdjustmentExperiment::HYBRID;
} }
return ViewportAdjustmentExperiment::FRAME; return ViewportAdjustmentExperiment::FRAME;
} }
......
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
// be a subview of the CRWContentView. // be a subview of the CRWContentView.
@property(nonatomic, strong, readonly) UIScrollView* scrollView; @property(nonatomic, strong, readonly) UIScrollView* scrollView;
// Adds an offset to the content view. This updates the location of the scroll
// view relative to the receiver, and does not update the scroll view's content
// offset.
@property(nonatomic, assign) CGPoint contentOffset;
// Adds an inset to content view. Implementations of this protocol can // Adds an inset to content view. Implementations of this protocol can
// implement this method using UIScrollView.contentInset (where applicable) or // implement this method using UIScrollView.contentInset (where applicable) or
// via resizing a subview's frame. Can be used as a workaround for WKWebView // via resizing a subview's frame. Can be used as a workaround for WKWebView
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
// The web view's frame rectangle. // The web view's frame rectangle.
@property(readonly, assign) CGRect frame; @property(readonly, assign) CGRect frame;
// Adds an offset to the scrollable content's frame.
@property(nonatomic, assign) CGPoint contentOffset;
// Adds an inset to the content view. Implementations of this protocol can // Adds an inset to the content view. Implementations of this protocol can
// implement this method using UIScrollView.contentInset (where applicable) or // implement this method using UIScrollView.contentInset (where applicable) or
// via resizing a subview's frame. Changing this property may impact performance // via resizing a subview's frame. Changing this property may impact performance
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
@end @end
@implementation CRWGenericContentView @implementation CRWGenericContentView
@synthesize contentOffset = _contentOffset;
- (instancetype)initWithView:(UIView*)view { - (instancetype)initWithView:(UIView*)view {
self = [super initWithFrame:CGRectZero]; self = [super initWithFrame:CGRectZero];
......
...@@ -34,7 +34,7 @@ const CGFloat kBackgroundRGBComponents[] = {0.75f, 0.74f, 0.76f}; ...@@ -34,7 +34,7 @@ const CGFloat kBackgroundRGBComponents[] = {0.75f, 0.74f, 0.76f};
@end @end
@implementation CRWWebViewContentView @implementation CRWWebViewContentView
@synthesize contentOffset = _contentOffset;
@synthesize contentInset = _contentInset; @synthesize contentInset = _contentInset;
@synthesize shouldUseViewContentInset = _shouldUseViewContentInset; @synthesize shouldUseViewContentInset = _shouldUseViewContentInset;
@synthesize scrollView = _scrollView; @synthesize scrollView = _scrollView;
...@@ -109,6 +109,13 @@ const CGFloat kBackgroundRGBComponents[] = {0.75f, 0.74f, 0.76f}; ...@@ -109,6 +109,13 @@ const CGFloat kBackgroundRGBComponents[] = {0.75f, 0.74f, 0.76f};
return YES; return YES;
} }
- (void)setContentOffset:(CGPoint)contentOffset {
if (CGPointEqualToPoint(_contentOffset, contentOffset))
return;
_contentOffset = contentOffset;
[self updateWebViewFrame];
}
- (UIEdgeInsets)contentInset { - (UIEdgeInsets)contentInset {
return self.shouldUseViewContentInset ? [_scrollView contentInset] return self.shouldUseViewContentInset ? [_scrollView contentInset]
: _contentInset; : _contentInset;
...@@ -155,13 +162,10 @@ const CGFloat kBackgroundRGBComponents[] = {0.75f, 0.74f, 0.76f}; ...@@ -155,13 +162,10 @@ const CGFloat kBackgroundRGBComponents[] = {0.75f, 0.74f, 0.76f};
#pragma mark Private methods #pragma mark Private methods
- (void)updateWebViewFrame { - (void)updateWebViewFrame {
CGRect webViewFrame = self.bounds; CGRect frame = self.bounds;
webViewFrame.size.height -= _contentInset.top + _contentInset.bottom; frame = UIEdgeInsetsInsetRect(frame, _contentInset);
webViewFrame.origin.y += _contentInset.top; frame = CGRectOffset(frame, _contentOffset.x, _contentOffset.y);
webViewFrame.size.width -= _contentInset.right + _contentInset.left; self.webView.frame = frame;
webViewFrame.origin.x += _contentInset.left;
self.webView.frame = webViewFrame;
} }
@end @end
...@@ -98,6 +98,14 @@ UIView* GetFirstResponderSubview(UIView* view) { ...@@ -98,6 +98,14 @@ UIView* GetFirstResponderSubview(UIView* view) {
return [_contentView frame]; return [_contentView frame];
} }
- (CGPoint)contentOffset {
return _contentView.contentOffset;
}
- (void)setContentOffset:(CGPoint)contentOffset {
_contentView.contentOffset = contentOffset;
}
- (UIEdgeInsets)contentInset { - (UIEdgeInsets)contentInset {
return _contentView.contentInset; return _contentView.contentInset;
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
@end @end
@implementation CRWFakeContentView @implementation CRWFakeContentView
@synthesize contentOffset = _contentOffset;
@synthesize contentInset = _contentInset; @synthesize contentInset = _contentInset;
@synthesize scrollView = _scrollView; @synthesize scrollView = _scrollView;
@synthesize shouldUseViewContentInset = _shouldUseViewContentInset; @synthesize shouldUseViewContentInset = _shouldUseViewContentInset;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment