Commit 0305551b authored by Robbie Gibson's avatar Robbie Gibson Committed by Commit Bot

[iOS] Add actual communication between text zoom UI and the zoom level

This CL adds the TextZoomMediator to handle communication between the
UI and the FontSizeTabHelper that actually does the zooming. The actual
zoom does not happen yet, but that will be added in the next CL.

Bug: 1028938
Change-Id: I9e90814990beddd674285d5fdd7025351cc1ce51
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1991621
Commit-Queue: Robbie Gibson <rkgibson@google.com>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#732430}
parent 978fade8
...@@ -6,6 +6,8 @@ source_set("text_zoom") { ...@@ -6,6 +6,8 @@ source_set("text_zoom") {
sources = [ sources = [
"text_zoom_coordinator.h", "text_zoom_coordinator.h",
"text_zoom_coordinator.mm", "text_zoom_coordinator.mm",
"text_zoom_mediator.h",
"text_zoom_mediator.mm",
] ]
deps = [ deps = [
":text_zoom_ui", ":text_zoom_ui",
...@@ -16,6 +18,8 @@ source_set("text_zoom") { ...@@ -16,6 +18,8 @@ source_set("text_zoom") {
"//ios/chrome/browser/ui/presenters", "//ios/chrome/browser/ui/presenters",
"//ios/chrome/browser/ui/toolbar/accessory", "//ios/chrome/browser/ui/toolbar/accessory",
"//ios/chrome/browser/ui/toolbar/public:constants", "//ios/chrome/browser/ui/toolbar/public:constants",
"//ios/chrome/browser/web",
"//ios/chrome/browser/web_state_list",
"//ios/chrome/common/colors", "//ios/chrome/common/colors",
] ]
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
...@@ -23,6 +27,7 @@ source_set("text_zoom") { ...@@ -23,6 +27,7 @@ source_set("text_zoom") {
source_set("text_zoom_ui") { source_set("text_zoom_ui") {
sources = [ sources = [
"text_zoom_consumer.h",
"text_zoom_view_controller.h", "text_zoom_view_controller.h",
"text_zoom_view_controller.mm", "text_zoom_view_controller.mm",
] ]
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_TEXT_ZOOM_TEXT_ZOOM_CONSUMER_H_
#define IOS_CHROME_BROWSER_UI_TEXT_ZOOM_TEXT_ZOOM_CONSUMER_H_
@protocol TextZoomConsumer <NSObject>
// Tells the consumer that the user can currently zoom in.
- (void)setZoomInEnabled:(BOOL)enabled;
// Tells the consumer that the user can currently zoom out.
- (void)setZoomOutEnabled:(BOOL)enabled;
@end
#endif // IOS_CHROME_BROWSER_UI_TEXT_ZOOM_TEXT_ZOOM_CONSUMER_H_
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#import "ios/chrome/browser/ui/commands/browser_commands.h" #import "ios/chrome/browser/ui/commands/browser_commands.h"
#import "ios/chrome/browser/ui/commands/command_dispatcher.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
#include "ios/chrome/browser/ui/presenters/contained_presenter_delegate.h" #include "ios/chrome/browser/ui/presenters/contained_presenter_delegate.h"
#import "ios/chrome/browser/ui/text_zoom/text_zoom_mediator.h"
#import "ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.h" #import "ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.h"
#import "ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_coordinator_delegate.h" #import "ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_coordinator_delegate.h"
#import "ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_presenter.h" #import "ios/chrome/browser/ui/toolbar/accessory/toolbar_accessory_presenter.h"
...@@ -26,6 +27,8 @@ ...@@ -26,6 +27,8 @@
@property(nonatomic, strong, readwrite) @property(nonatomic, strong, readwrite)
TextZoomViewController* textZoomViewController; TextZoomViewController* textZoomViewController;
@property(nonatomic, strong) TextZoomMediator* mediator;
@end @end
@implementation TextZoomCoordinator @implementation TextZoomCoordinator
...@@ -35,17 +38,29 @@ ...@@ -35,17 +38,29 @@
- (void)start { - (void)start {
DCHECK(self.browser); DCHECK(self.browser);
DCHECK(self.browserState); DCHECK(self.browserState);
self.mediator = [[TextZoomMediator alloc]
initWithWebStateList:self.browser->GetWebStateList()
commandHandler:HandlerForProtocol(
self.browser->GetCommandDispatcher(),
BrowserCommands)];
self.textZoomViewController = [[TextZoomViewController alloc] self.textZoomViewController = [[TextZoomViewController alloc]
initWithDarkAppearance:self.browserState->IsOffTheRecord()]; initWithDarkAppearance:self.browserState->IsOffTheRecord()];
self.textZoomViewController.commandHandler = self.textZoomViewController.commandHandler =
HandlerForProtocol(self.browser->GetCommandDispatcher(), BrowserCommands); HandlerForProtocol(self.browser->GetCommandDispatcher(), BrowserCommands);
self.textZoomViewController.zoomHandler = self.mediator;
self.mediator.consumer = self.textZoomViewController;
[self showAnimated:YES]; [self showAnimated:YES];
} }
- (void)stop { - (void)stop {
[self.presenter dismissAnimated:YES]; [self.presenter dismissAnimated:YES];
self.textZoomViewController = nil; self.textZoomViewController = nil;
[self.mediator disconnect];
} }
- (void)showAnimated:(BOOL)animated { - (void)showAnimated:(BOOL)animated {
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_TEXT_ZOOM_TEXT_ZOOM_MEDIATOR_H_
#define IOS_CHROME_BROWSER_UI_TEXT_ZOOM_TEXT_ZOOM_MEDIATOR_H_
#import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/text_zoom/text_zoom_view_controller.h"
@protocol TextZoomConsumer;
class WebStateList;
@interface TextZoomMediator : NSObject <TextZoomHandler>
@property(nonatomic, weak) id<TextZoomConsumer> consumer;
- (instancetype)initWithWebStateList:(WebStateList*)webStateList
commandHandler:(id<BrowserCommands>)commandHandler
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
// Stops observing all objects.
- (void)disconnect;
@end
#endif // IOS_CHROME_BROWSER_UI_TEXT_ZOOM_TEXT_ZOOM_MEDIATOR_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/text_zoom/text_zoom_mediator.h"
#import "ios/chrome/browser/main/browser.h"
#import "ios/chrome/browser/ui/commands/browser_commands.h"
#import "ios/chrome/browser/ui/text_zoom/text_zoom_consumer.h"
#import "ios/chrome/browser/web/font_size_tab_helper.h"
#import "ios/chrome/browser/web_state_list/active_web_state_observation_forwarder.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h"
#import "ios/chrome/browser/web_state_list/web_state_list_observer_bridge.h"
#import "ios/web/public/web_state.h"
#import "ios/web/public/web_state_observer_bridge.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface TextZoomMediator () <WebStateListObserving, CRWWebStateObserver> {
std::unique_ptr<WebStateListObserver> _webStateListObserver;
std::unique_ptr<web::WebStateObserverBridge> _observer;
std::unique_ptr<ActiveWebStateObservationForwarder> _forwarder;
}
// The WebStateList that this mediator listens for any changes on the active web
// state.
@property(nonatomic, readonly) WebStateList* webStateList;
// The active WebState's font size tab helper.
@property(nonatomic, readonly) FontSizeTabHelper* fontSizeTabHelper;
// Handler for any BrowserCommands.
@property(nonatomic, weak) id<BrowserCommands> commandHandler;
@end
@implementation TextZoomMediator
- (instancetype)initWithWebStateList:(WebStateList*)webStateList
commandHandler:(id<BrowserCommands>)commandHandler {
self = [super init];
if (self) {
_commandHandler = commandHandler;
DCHECK(webStateList);
// Set up the WebStateList and its observer.
_webStateList = webStateList;
_webStateListObserver = std::make_unique<WebStateListObserverBridge>(self);
_webStateList->AddObserver(_webStateListObserver.get());
// Set up the active web state observer.
_observer = std::make_unique<web::WebStateObserverBridge>(self);
_forwarder = std::make_unique<ActiveWebStateObservationForwarder>(
webStateList, _observer.get());
}
return self;
}
- (void)dealloc {
// |-disconnect| must be called before deallocation.
DCHECK(!_webStateList);
}
- (void)disconnect {
if (_webStateList) {
_webStateList->RemoveObserver(_webStateListObserver.get());
_webStateListObserver = nullptr;
_webStateList = nullptr;
}
}
#pragma mark - Accessors
- (FontSizeTabHelper*)fontSizeTabHelper {
if (!self.webStateList) {
return nullptr;
}
web::WebState* activeWebState = self.webStateList->GetActiveWebState();
return activeWebState ? FontSizeTabHelper::FromWebState(activeWebState)
: nullptr;
}
- (void)setConsumer:(id<TextZoomConsumer>)consumer {
_consumer = consumer;
[self updateConsumerState];
}
#pragma mark - WebStateListObserver
- (void)webStateList:(WebStateList*)webStateList
didReplaceWebState:(web::WebState*)oldWebState
withWebState:(web::WebState*)newWebState
atIndex:(int)atIndex {
DCHECK_EQ(self.webStateList, webStateList);
if (atIndex == webStateList->active_index()) {
[self.commandHandler hideTextZoom];
}
}
- (void)webStateList:(WebStateList*)webStateList
didChangeActiveWebState:(web::WebState*)newWebState
oldWebState:(web::WebState*)oldWebState
atIndex:(int)atIndex
reason:(int)reason {
[self.commandHandler hideTextZoom];
}
#pragma mark - TextZoomHandler
- (void)zoomIn {
self.fontSizeTabHelper->UserZoom(ZOOM_IN);
[self updateConsumerState];
}
- (void)zoomOut {
self.fontSizeTabHelper->UserZoom(ZOOM_OUT);
[self updateConsumerState];
}
- (void)resetZoom {
self.fontSizeTabHelper->UserZoom(ZOOM_RESET);
[self updateConsumerState];
}
- (void)updateConsumerState {
[self.consumer setZoomInEnabled:self.fontSizeTabHelper->CanUserZoomIn()];
[self.consumer setZoomOutEnabled:self.fontSizeTabHelper->CanUserZoomOut()];
}
#pragma mark - CRWWebStateObserver
- (void)webState:(web::WebState*)webState
didFinishNavigation:(web::NavigationContext*)navigation {
[self.commandHandler hideTextZoom];
}
@end
...@@ -7,10 +7,23 @@ ...@@ -7,10 +7,23 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/text_zoom/text_zoom_consumer.h"
@protocol BrowserCommands; @protocol BrowserCommands;
@class TextZoomViewController; @class TextZoomViewController;
@interface TextZoomViewController : UIViewController @protocol TextZoomHandler <NSObject>
// Asks the handler to zoom in.
- (void)zoomIn;
// Asks the handler to zoom out.
- (void)zoomOut;
// Asks the handler to reset the zoom level to the default.
- (void)resetZoom;
@end
@interface TextZoomViewController : UIViewController <TextZoomConsumer>
- (instancetype)initWithDarkAppearance:(BOOL)darkAppearance - (instancetype)initWithDarkAppearance:(BOOL)darkAppearance
NS_DESIGNATED_INITIALIZER; NS_DESIGNATED_INITIALIZER;
...@@ -21,6 +34,7 @@ ...@@ -21,6 +34,7 @@
- (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE; - (instancetype)initWithCoder:(NSCoder*)coder NS_UNAVAILABLE;
@property(nonatomic, weak) id<BrowserCommands> commandHandler; @property(nonatomic, weak) id<BrowserCommands> commandHandler;
@property(nonatomic, weak) id<TextZoomHandler> zoomHandler;
@end @end
......
...@@ -42,8 +42,6 @@ const CGFloat kDividerWidth = 1; ...@@ -42,8 +42,6 @@ const CGFloat kDividerWidth = 1;
@property(nonatomic, strong) UIButton* incrementButton; @property(nonatomic, strong) UIButton* incrementButton;
@property(nonatomic, strong) UIButton* decrementButton; @property(nonatomic, strong) UIButton* decrementButton;
@property(nonatomic, assign) int stepperValue;
@end @end
@implementation TextZoomViewController @implementation TextZoomViewController
...@@ -97,34 +95,6 @@ const CGFloat kDividerWidth = 1; ...@@ -97,34 +95,6 @@ const CGFloat kDividerWidth = 1;
forAxis:UILayoutConstraintAxisHorizontal]; forAxis:UILayoutConstraintAxisHorizontal];
} }
#pragma mark - Private methods (control actions)
- (void)closeButtonWasTapped:(id)sender {
[self.commandHandler hideTextZoom];
}
- (void)resetButtonWasTapped:(id)sender {
self.stepperValue = 0;
}
- (void)incrementButtonWasTapped:(id)sender {
self.stepperValue += 1;
}
- (void)decrementButtonWasTapped:(id)sender {
self.stepperValue -= 1;
}
- (void)updateStepperState {
self.incrementButton.enabled = self.stepperValue < 5;
self.decrementButton.enabled = self.stepperValue > -5;
}
- (void)setStepperValue:(int)stepperValue {
_stepperValue = stepperValue;
[self updateStepperState];
}
#pragma mark - Private property Accessors #pragma mark - Private property Accessors
// Creates and returns the close button. // Creates and returns the close button.
...@@ -134,8 +104,8 @@ const CGFloat kDividerWidth = 1; ...@@ -134,8 +104,8 @@ const CGFloat kDividerWidth = 1;
[_closeButton setTitle:l10n_util::GetNSString(IDS_DONE) [_closeButton setTitle:l10n_util::GetNSString(IDS_DONE)
forState:UIControlStateNormal]; forState:UIControlStateNormal];
_closeButton.accessibilityIdentifier = kTextZoomCloseButtonID; _closeButton.accessibilityIdentifier = kTextZoomCloseButtonID;
[_closeButton addTarget:self [_closeButton addTarget:self.commandHandler
action:@selector(closeButtonWasTapped:) action:@selector(hideTextZoom)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
} }
return _closeButton; return _closeButton;
...@@ -147,8 +117,8 @@ const CGFloat kDividerWidth = 1; ...@@ -147,8 +117,8 @@ const CGFloat kDividerWidth = 1;
_resetButton = [self newButtonWithDefaultStyling]; _resetButton = [self newButtonWithDefaultStyling];
[_resetButton setTitle:l10n_util::GetNSString(IDS_IOS_RESET_ZOOM) [_resetButton setTitle:l10n_util::GetNSString(IDS_IOS_RESET_ZOOM)
forState:UIControlStateNormal]; forState:UIControlStateNormal];
[_resetButton addTarget:self [_resetButton addTarget:self.zoomHandler
action:@selector(resetButtonWasTapped:) action:@selector(resetZoom)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
} }
return _resetButton; return _resetButton;
...@@ -160,8 +130,8 @@ const CGFloat kDividerWidth = 1; ...@@ -160,8 +130,8 @@ const CGFloat kDividerWidth = 1;
_incrementButton = [self newButtonWithDefaultStyling]; _incrementButton = [self newButtonWithDefaultStyling];
UIImage* image = [UIImage imageNamed:@"text_zoom_zoom_in"]; UIImage* image = [UIImage imageNamed:@"text_zoom_zoom_in"];
[_incrementButton setImage:image forState:UIControlStateNormal]; [_incrementButton setImage:image forState:UIControlStateNormal];
[_incrementButton addTarget:self [_incrementButton addTarget:self.zoomHandler
action:@selector(incrementButtonWasTapped:) action:@selector(zoomIn)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[_incrementButton.heightAnchor constraintEqualToConstant:kButtonSize], [_incrementButton.heightAnchor constraintEqualToConstant:kButtonSize],
...@@ -178,8 +148,8 @@ const CGFloat kDividerWidth = 1; ...@@ -178,8 +148,8 @@ const CGFloat kDividerWidth = 1;
_decrementButton = [self newButtonWithDefaultStyling]; _decrementButton = [self newButtonWithDefaultStyling];
UIImage* image = [UIImage imageNamed:@"text_zoom_zoom_out"]; UIImage* image = [UIImage imageNamed:@"text_zoom_zoom_out"];
[_decrementButton setImage:image forState:UIControlStateNormal]; [_decrementButton setImage:image forState:UIControlStateNormal];
[_decrementButton addTarget:self [_decrementButton addTarget:self.zoomHandler
action:@selector(decrementButtonWasTapped:) action:@selector(zoomOut)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[_decrementButton.heightAnchor constraintEqualToConstant:kButtonSize], [_decrementButton.heightAnchor constraintEqualToConstant:kButtonSize],
...@@ -228,4 +198,14 @@ const CGFloat kDividerWidth = 1; ...@@ -228,4 +198,14 @@ const CGFloat kDividerWidth = 1;
return button; return button;
} }
#pragma mark - TextZoomConsumer
- (void)setZoomInEnabled:(BOOL)enabled {
self.incrementButton.enabled = enabled;
}
- (void)setZoomOutEnabled:(BOOL)enabled {
self.decrementButton.enabled = enabled;
}
@end @end
...@@ -13,6 +13,12 @@ namespace web { ...@@ -13,6 +13,12 @@ namespace web {
class WebState; class WebState;
} // namespace web } // namespace web
enum Zoom {
ZOOM_OUT = -1,
ZOOM_RESET = 0,
ZOOM_IN = 1,
};
// Adjusts font size of web page by mapping // Adjusts font size of web page by mapping
// |UIApplication.sharedApplication.preferredContentSizeCategory| to a scaling // |UIApplication.sharedApplication.preferredContentSizeCategory| to a scaling
// percentage and setting it to "-webkit-font-size-adjust" style on <body> when // percentage and setting it to "-webkit-font-size-adjust" style on <body> when
...@@ -22,6 +28,16 @@ class FontSizeTabHelper : public web::WebStateObserver, ...@@ -22,6 +28,16 @@ class FontSizeTabHelper : public web::WebStateObserver,
public: public:
~FontSizeTabHelper() override; ~FontSizeTabHelper() override;
// Performs a zoom in the given direction on the WebState this is attached to.
void UserZoom(Zoom zoom);
// Returns whether the user can still zoom in. (I.e., They have not reached
// the max zoom level.).
bool CanUserZoomIn() const;
// Returns whether the user can still zoom out. (I.e., They have not reached
// the min zoom level.).
bool CanUserZoomOut() const;
private: private:
friend class web::WebStateUserData<FontSizeTabHelper>; friend class web::WebStateUserData<FontSizeTabHelper>;
...@@ -30,9 +46,13 @@ class FontSizeTabHelper : public web::WebStateObserver, ...@@ -30,9 +46,13 @@ class FontSizeTabHelper : public web::WebStateObserver,
// Sets font size in web page by scaling percentage. // Sets font size in web page by scaling percentage.
void SetPageFontSize(int size); void SetPageFontSize(int size);
// Returns system suggested font size in scaling percentage(e.g. 150 for // Returns the true font size in scaling percentage (e.g. 150 for
// 150%). // 150%) taking all sources into account (system level and user zoom).
int GetSystemSuggestedFontSize() const; int GetFontSize() const;
// Returns the current user zoom multiplier (i.e. not counting any additional
// zoom due to the system accessibility settings).
double GetCurrentUserZoomMultiplier() const;
// web::WebStateObserver overrides: // web::WebStateObserver overrides:
void PageLoaded( void PageLoaded(
......
...@@ -29,7 +29,7 @@ FontSizeTabHelper::FontSizeTabHelper(web::WebState* web_state) ...@@ -29,7 +29,7 @@ FontSizeTabHelper::FontSizeTabHelper(web::WebState* web_state)
object:nil object:nil
queue:nil queue:nil
usingBlock:^(NSNotification* _Nonnull note) { usingBlock:^(NSNotification* _Nonnull note) {
SetPageFontSize(GetSystemSuggestedFontSize()); SetPageFontSize(GetFontSize());
}]; }];
} }
...@@ -41,9 +41,29 @@ void FontSizeTabHelper::SetPageFontSize(int size) { ...@@ -41,9 +41,29 @@ void FontSizeTabHelper::SetPageFontSize(int size) {
} }
} }
int FontSizeTabHelper::GetSystemSuggestedFontSize() const { void FontSizeTabHelper::UserZoom(Zoom zoom) {
// TODO(crbug.com/1028938): Replace with actual logic.
return;
}
bool FontSizeTabHelper::CanUserZoomIn() const {
// TODO(crbug.com/1028938): Replace with actual logic.
return true;
}
bool FontSizeTabHelper::CanUserZoomOut() const {
// TODO(crbug.com/1028938): Replace with actual logic.
return true;
}
int FontSizeTabHelper::GetFontSize() const {
// Multiply by 100 as the web property needs a percentage. // Multiply by 100 as the web property needs a percentage.
return SystemSuggestedFontSizeMultiplier() * 100; return SystemSuggestedFontSizeMultiplier() * GetCurrentUserZoomMultiplier() *
100;
}
double FontSizeTabHelper::GetCurrentUserZoomMultiplier() const {
return 1;
} }
void FontSizeTabHelper::WebStateDestroyed(web::WebState* web_state) { void FontSizeTabHelper::WebStateDestroyed(web::WebState* web_state) {
...@@ -54,7 +74,7 @@ void FontSizeTabHelper::PageLoaded( ...@@ -54,7 +74,7 @@ void FontSizeTabHelper::PageLoaded(
web::WebState* web_state, web::WebState* web_state,
web::PageLoadCompletionStatus load_completion_status) { web::PageLoadCompletionStatus load_completion_status) {
DCHECK_EQ(web_state, web_state_); DCHECK_EQ(web_state, web_state_);
int size = GetSystemSuggestedFontSize(); int size = GetFontSize();
if (size != 100) if (size != 100)
SetPageFontSize(size); SetPageFontSize(size);
} }
......
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