2019-10-16 20:03:47 +03:00
|
|
|
/*
|
2018-09-12 01:27:47 +03:00
|
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
2015-07-31 17:37:12 +03:00
|
|
|
*
|
2018-02-17 05:24:55 +03:00
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
2015-07-31 17:37:12 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
#import "RCTAccessibilityManager.h"
|
|
|
|
|
2019-08-23 21:58:36 +03:00
|
|
|
#import <FBReactNativeSpec/FBReactNativeSpec.h>
|
|
|
|
#import <React/RCTBridge.h>
|
|
|
|
#import <React/RCTConvert.h>
|
2020-10-14 12:37:51 +03:00
|
|
|
#import <React/RCTEventDispatcherProtocol.h>
|
2019-08-23 21:58:36 +03:00
|
|
|
#import <React/RCTLog.h>
|
2020-03-09 08:58:01 +03:00
|
|
|
#import <React/RCTUIManager.h>
|
2015-07-31 17:37:12 +03:00
|
|
|
|
2019-08-23 21:58:36 +03:00
|
|
|
#import "CoreModulesPlugins.h"
|
2015-07-31 17:37:12 +03:00
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
NSString *const RCTAccessibilityManagerDidUpdateMultiplierNotification =
|
|
|
|
@"RCTAccessibilityManagerDidUpdateMultiplierNotification";
|
2015-07-31 17:37:12 +03:00
|
|
|
|
2019-08-23 21:58:36 +03:00
|
|
|
@interface RCTAccessibilityManager () <NativeAccessibilityManagerSpec>
|
2017-08-07 16:45:24 +03:00
|
|
|
|
|
|
|
@property (nonatomic, copy) NSString *contentSizeCategory;
|
|
|
|
@property (nonatomic, assign) CGFloat multiplier;
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation RCTAccessibilityManager
|
|
|
|
|
|
|
|
@synthesize bridge = _bridge;
|
|
|
|
@synthesize multipliers = _multipliers;
|
|
|
|
|
|
|
|
RCT_EXPORT_MODULE()
|
|
|
|
|
|
|
|
+ (BOOL)requiresMainQueueSetup
|
2015-07-31 17:37:12 +03:00
|
|
|
{
|
2017-08-07 16:45:24 +03:00
|
|
|
return YES;
|
2015-07-31 17:37:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
- (instancetype)init
|
|
|
|
{
|
2018-01-24 10:17:57 +03:00
|
|
|
if (self = [super init]) {
|
|
|
|
_multiplier = 1.0;
|
2015-11-25 14:09:00 +03:00
|
|
|
|
|
|
|
// TODO: can this be moved out of the startup path?
|
2015-07-31 17:37:12 +03:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(didReceiveNewContentSizeCategory:)
|
|
|
|
name:UIContentSizeCategoryDidChangeNotification
|
2017-08-18 09:36:58 +03:00
|
|
|
object:nil];
|
2015-10-02 04:07:06 +03:00
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
2019-03-15 21:17:42 +03:00
|
|
|
selector:@selector(accessibilityAnnouncementDidFinish:)
|
|
|
|
name:UIAccessibilityAnnouncementDidFinishNotification
|
2015-10-02 04:07:06 +03:00
|
|
|
object:nil];
|
2017-08-07 16:45:24 +03:00
|
|
|
|
2017-05-30 14:35:52 +03:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
2019-03-15 21:17:42 +03:00
|
|
|
selector:@selector(boldTextStatusDidChange:)
|
|
|
|
name:UIAccessibilityBoldTextStatusDidChangeNotification
|
|
|
|
object:nil];
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(grayscaleStatusDidChange:)
|
|
|
|
name:UIAccessibilityGrayscaleStatusDidChangeNotification
|
|
|
|
object:nil];
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(invertColorsStatusDidChange:)
|
|
|
|
name:UIAccessibilityInvertColorsStatusDidChangeNotification
|
2017-05-30 14:35:52 +03:00
|
|
|
object:nil];
|
2015-10-02 04:07:06 +03:00
|
|
|
|
- Add support for "reduce motion" into AccessibilityInfo (#23839)
Summary:
This PR adds `isReduceMotionEnabled()` to `AccessibilityInfo` in other to add support for "reduce motion", exposing the Operational System's settings option. Additionally, it adds a new event, `reduceMotionChanged`, in order to listen for this flag's update.
With this feature, developers will be able to disable or reduce animations, _**something that will be required as soon as WCAG 2.1 draft got approved**._ See [WCAG 2.1 — 2.3.3 Animations from Interaction criteria](https://knowbility.org/blog/2018/WCAG21-233Animations/)
It's exposed by [`UIAccessibility`' isReduceMotionEnabled ](https://developer.apple.com/documentation/uikit/uiaccessibility/1615133-isreducemotionenabled
) on iOS and [Settings.Global.TRANSITION_ANIMATION_SCALE](https://developer.android.com/reference/android/provider/Settings.Global#TRANSITION_ANIMATION_SCALE) on Android.
Up until now, `AccessibilityInfo` only exposes screen reader flag. By adding this second accessibility option, it's a good opportunity to rename `fetch` method to an appropriate name, `isScreenReaderEnabled`, as well as rename `change` event to `screenReaderChanged`, which will make it clearer and more specific.
(In case it's approved, a follow-up PR could exposes [more iOS acessibility flags](https://developer.apple.com/documentation/uikit/uiaccessibility), such as `isShakeToUndoEnabled`, `isReduceTransparencyEnabled`, `isGrayscaleEnabled`, `isInvertColorsEnabled`)
(iOS code inspired by [phonegap-mobile-accessibility](https://github.com/phonegap/phonegap-mobile-accessibility). And Android by [Flutter](https://github.com/flutter/engine/blob/master/shell/platform/android/io/flutter/view/AccessibilityBridge.java
))
Pull Request resolved: https://github.com/facebook/react-native/pull/23839
Differential Revision: D14406227
Pulled By: hramos
fbshipit-source-id: adf43be84c488522bf1e29d862681220ad193883
2019-03-13 06:23:54 +03:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(reduceMotionStatusDidChange:)
|
|
|
|
name:UIAccessibilityReduceMotionStatusDidChangeNotification
|
|
|
|
object:nil];
|
|
|
|
|
2019-03-15 21:17:42 +03:00
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(reduceTransparencyStatusDidChange:)
|
|
|
|
name:UIAccessibilityReduceTransparencyStatusDidChangeNotification
|
|
|
|
object:nil];
|
|
|
|
|
|
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
|
|
selector:@selector(voiceVoiceOverStatusDidChange:)
|
|
|
|
name:UIAccessibilityVoiceOverStatusChanged
|
|
|
|
object:nil];
|
|
|
|
|
2017-04-01 13:16:52 +03:00
|
|
|
self.contentSizeCategory = RCTSharedApplication().preferredContentSizeCategory;
|
2019-03-15 21:17:42 +03:00
|
|
|
_isBoldTextEnabled = UIAccessibilityIsBoldTextEnabled();
|
|
|
|
_isGrayscaleEnabled = UIAccessibilityIsGrayscaleEnabled();
|
|
|
|
_isInvertColorsEnabled = UIAccessibilityIsInvertColorsEnabled();
|
- Add support for "reduce motion" into AccessibilityInfo (#23839)
Summary:
This PR adds `isReduceMotionEnabled()` to `AccessibilityInfo` in other to add support for "reduce motion", exposing the Operational System's settings option. Additionally, it adds a new event, `reduceMotionChanged`, in order to listen for this flag's update.
With this feature, developers will be able to disable or reduce animations, _**something that will be required as soon as WCAG 2.1 draft got approved**._ See [WCAG 2.1 — 2.3.3 Animations from Interaction criteria](https://knowbility.org/blog/2018/WCAG21-233Animations/)
It's exposed by [`UIAccessibility`' isReduceMotionEnabled ](https://developer.apple.com/documentation/uikit/uiaccessibility/1615133-isreducemotionenabled
) on iOS and [Settings.Global.TRANSITION_ANIMATION_SCALE](https://developer.android.com/reference/android/provider/Settings.Global#TRANSITION_ANIMATION_SCALE) on Android.
Up until now, `AccessibilityInfo` only exposes screen reader flag. By adding this second accessibility option, it's a good opportunity to rename `fetch` method to an appropriate name, `isScreenReaderEnabled`, as well as rename `change` event to `screenReaderChanged`, which will make it clearer and more specific.
(In case it's approved, a follow-up PR could exposes [more iOS acessibility flags](https://developer.apple.com/documentation/uikit/uiaccessibility), such as `isShakeToUndoEnabled`, `isReduceTransparencyEnabled`, `isGrayscaleEnabled`, `isInvertColorsEnabled`)
(iOS code inspired by [phonegap-mobile-accessibility](https://github.com/phonegap/phonegap-mobile-accessibility). And Android by [Flutter](https://github.com/flutter/engine/blob/master/shell/platform/android/io/flutter/view/AccessibilityBridge.java
))
Pull Request resolved: https://github.com/facebook/react-native/pull/23839
Differential Revision: D14406227
Pulled By: hramos
fbshipit-source-id: adf43be84c488522bf1e29d862681220ad193883
2019-03-13 06:23:54 +03:00
|
|
|
_isReduceMotionEnabled = UIAccessibilityIsReduceMotionEnabled();
|
2019-03-15 21:17:42 +03:00
|
|
|
_isReduceTransparencyEnabled = UIAccessibilityIsReduceTransparencyEnabled();
|
2015-10-02 04:07:06 +03:00
|
|
|
_isVoiceOverEnabled = UIAccessibilityIsVoiceOverRunning();
|
2015-07-31 17:37:12 +03:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)didReceiveNewContentSizeCategory:(NSNotification *)note
|
|
|
|
{
|
|
|
|
self.contentSizeCategory = note.userInfo[UIContentSizeCategoryNewValueKey];
|
|
|
|
}
|
|
|
|
|
2019-03-15 21:17:42 +03:00
|
|
|
- (void)accessibilityAnnouncementDidFinish:(__unused NSNotification *)notification
|
2015-10-02 04:07:06 +03:00
|
|
|
{
|
2019-03-15 21:17:42 +03:00
|
|
|
NSDictionary *userInfo = notification.userInfo;
|
|
|
|
// Response dictionary to populate the event with.
|
2020-03-09 08:58:01 +03:00
|
|
|
NSDictionary *response = @{
|
|
|
|
@"announcement" : userInfo[UIAccessibilityAnnouncementKeyStringValue],
|
|
|
|
@"success" : userInfo[UIAccessibilityAnnouncementKeyWasSuccessful]
|
|
|
|
};
|
2019-03-15 21:17:42 +03:00
|
|
|
|
2016-05-25 14:17:35 +03:00
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
2020-03-09 08:58:01 +03:00
|
|
|
[_bridge.eventDispatcher sendDeviceEventWithName:@"announcementFinished" body:response];
|
2019-03-15 21:17:42 +03:00
|
|
|
#pragma clang diagnostic pop
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)boldTextStatusDidChange:(__unused NSNotification *)notification
|
|
|
|
{
|
|
|
|
BOOL newBoldTextEnabled = UIAccessibilityIsBoldTextEnabled();
|
|
|
|
if (_isBoldTextEnabled != newBoldTextEnabled) {
|
|
|
|
_isBoldTextEnabled = newBoldTextEnabled;
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
2020-03-09 08:58:01 +03:00
|
|
|
[_bridge.eventDispatcher sendDeviceEventWithName:@"boldTextChanged" body:@(_isBoldTextEnabled)];
|
2016-05-25 14:17:35 +03:00
|
|
|
#pragma clang diagnostic pop
|
2015-10-02 04:07:06 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-15 21:17:42 +03:00
|
|
|
- (void)grayscaleStatusDidChange:(__unused NSNotification *)notification
|
2017-05-30 14:35:52 +03:00
|
|
|
{
|
2019-03-15 21:17:42 +03:00
|
|
|
BOOL newGrayscaleEnabled = UIAccessibilityIsGrayscaleEnabled();
|
|
|
|
if (_isGrayscaleEnabled != newGrayscaleEnabled) {
|
|
|
|
_isGrayscaleEnabled = newGrayscaleEnabled;
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
2020-03-09 08:58:01 +03:00
|
|
|
[_bridge.eventDispatcher sendDeviceEventWithName:@"grayscaleChanged" body:@(_isGrayscaleEnabled)];
|
2019-03-15 21:17:42 +03:00
|
|
|
#pragma clang diagnostic pop
|
|
|
|
}
|
|
|
|
}
|
2017-08-07 16:45:24 +03:00
|
|
|
|
2019-03-15 21:17:42 +03:00
|
|
|
- (void)invertColorsStatusDidChange:(__unused NSNotification *)notification
|
|
|
|
{
|
|
|
|
BOOL newInvertColorsEnabled = UIAccessibilityIsInvertColorsEnabled();
|
|
|
|
if (_isInvertColorsEnabled != newInvertColorsEnabled) {
|
|
|
|
_isInvertColorsEnabled = newInvertColorsEnabled;
|
2017-05-30 14:35:52 +03:00
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
2020-03-09 08:58:01 +03:00
|
|
|
[_bridge.eventDispatcher sendDeviceEventWithName:@"invertColorsChanged" body:@(_isInvertColorsEnabled)];
|
2017-05-30 14:35:52 +03:00
|
|
|
#pragma clang diagnostic pop
|
2019-03-15 21:17:42 +03:00
|
|
|
}
|
2017-05-30 14:35:52 +03:00
|
|
|
}
|
|
|
|
|
- Add support for "reduce motion" into AccessibilityInfo (#23839)
Summary:
This PR adds `isReduceMotionEnabled()` to `AccessibilityInfo` in other to add support for "reduce motion", exposing the Operational System's settings option. Additionally, it adds a new event, `reduceMotionChanged`, in order to listen for this flag's update.
With this feature, developers will be able to disable or reduce animations, _**something that will be required as soon as WCAG 2.1 draft got approved**._ See [WCAG 2.1 — 2.3.3 Animations from Interaction criteria](https://knowbility.org/blog/2018/WCAG21-233Animations/)
It's exposed by [`UIAccessibility`' isReduceMotionEnabled ](https://developer.apple.com/documentation/uikit/uiaccessibility/1615133-isreducemotionenabled
) on iOS and [Settings.Global.TRANSITION_ANIMATION_SCALE](https://developer.android.com/reference/android/provider/Settings.Global#TRANSITION_ANIMATION_SCALE) on Android.
Up until now, `AccessibilityInfo` only exposes screen reader flag. By adding this second accessibility option, it's a good opportunity to rename `fetch` method to an appropriate name, `isScreenReaderEnabled`, as well as rename `change` event to `screenReaderChanged`, which will make it clearer and more specific.
(In case it's approved, a follow-up PR could exposes [more iOS acessibility flags](https://developer.apple.com/documentation/uikit/uiaccessibility), such as `isShakeToUndoEnabled`, `isReduceTransparencyEnabled`, `isGrayscaleEnabled`, `isInvertColorsEnabled`)
(iOS code inspired by [phonegap-mobile-accessibility](https://github.com/phonegap/phonegap-mobile-accessibility). And Android by [Flutter](https://github.com/flutter/engine/blob/master/shell/platform/android/io/flutter/view/AccessibilityBridge.java
))
Pull Request resolved: https://github.com/facebook/react-native/pull/23839
Differential Revision: D14406227
Pulled By: hramos
fbshipit-source-id: adf43be84c488522bf1e29d862681220ad193883
2019-03-13 06:23:54 +03:00
|
|
|
- (void)reduceMotionStatusDidChange:(__unused NSNotification *)notification
|
|
|
|
{
|
|
|
|
BOOL newReduceMotionEnabled = UIAccessibilityIsReduceMotionEnabled();
|
|
|
|
if (_isReduceMotionEnabled != newReduceMotionEnabled) {
|
|
|
|
_isReduceMotionEnabled = newReduceMotionEnabled;
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
2020-03-09 08:58:01 +03:00
|
|
|
[_bridge.eventDispatcher sendDeviceEventWithName:@"reduceMotionChanged" body:@(_isReduceMotionEnabled)];
|
- Add support for "reduce motion" into AccessibilityInfo (#23839)
Summary:
This PR adds `isReduceMotionEnabled()` to `AccessibilityInfo` in other to add support for "reduce motion", exposing the Operational System's settings option. Additionally, it adds a new event, `reduceMotionChanged`, in order to listen for this flag's update.
With this feature, developers will be able to disable or reduce animations, _**something that will be required as soon as WCAG 2.1 draft got approved**._ See [WCAG 2.1 — 2.3.3 Animations from Interaction criteria](https://knowbility.org/blog/2018/WCAG21-233Animations/)
It's exposed by [`UIAccessibility`' isReduceMotionEnabled ](https://developer.apple.com/documentation/uikit/uiaccessibility/1615133-isreducemotionenabled
) on iOS and [Settings.Global.TRANSITION_ANIMATION_SCALE](https://developer.android.com/reference/android/provider/Settings.Global#TRANSITION_ANIMATION_SCALE) on Android.
Up until now, `AccessibilityInfo` only exposes screen reader flag. By adding this second accessibility option, it's a good opportunity to rename `fetch` method to an appropriate name, `isScreenReaderEnabled`, as well as rename `change` event to `screenReaderChanged`, which will make it clearer and more specific.
(In case it's approved, a follow-up PR could exposes [more iOS acessibility flags](https://developer.apple.com/documentation/uikit/uiaccessibility), such as `isShakeToUndoEnabled`, `isReduceTransparencyEnabled`, `isGrayscaleEnabled`, `isInvertColorsEnabled`)
(iOS code inspired by [phonegap-mobile-accessibility](https://github.com/phonegap/phonegap-mobile-accessibility). And Android by [Flutter](https://github.com/flutter/engine/blob/master/shell/platform/android/io/flutter/view/AccessibilityBridge.java
))
Pull Request resolved: https://github.com/facebook/react-native/pull/23839
Differential Revision: D14406227
Pulled By: hramos
fbshipit-source-id: adf43be84c488522bf1e29d862681220ad193883
2019-03-13 06:23:54 +03:00
|
|
|
#pragma clang diagnostic pop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-15 21:17:42 +03:00
|
|
|
- (void)reduceTransparencyStatusDidChange:(__unused NSNotification *)notification
|
|
|
|
{
|
|
|
|
BOOL newReduceTransparencyEnabled = UIAccessibilityIsReduceTransparencyEnabled();
|
|
|
|
if (_isReduceTransparencyEnabled != newReduceTransparencyEnabled) {
|
|
|
|
_isReduceTransparencyEnabled = newReduceTransparencyEnabled;
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
2020-03-09 08:58:01 +03:00
|
|
|
[_bridge.eventDispatcher sendDeviceEventWithName:@"reduceTransparencyChanged" body:@(_isReduceTransparencyEnabled)];
|
2019-03-15 21:17:42 +03:00
|
|
|
#pragma clang diagnostic pop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)voiceVoiceOverStatusDidChange:(__unused NSNotification *)notification
|
|
|
|
{
|
|
|
|
BOOL newIsVoiceOverEnabled = UIAccessibilityIsVoiceOverRunning();
|
|
|
|
if (_isVoiceOverEnabled != newIsVoiceOverEnabled) {
|
|
|
|
_isVoiceOverEnabled = newIsVoiceOverEnabled;
|
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
2020-03-09 08:58:01 +03:00
|
|
|
[_bridge.eventDispatcher sendDeviceEventWithName:@"screenReaderChanged" body:@(_isVoiceOverEnabled)];
|
2019-03-15 21:17:42 +03:00
|
|
|
#pragma clang diagnostic pop
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 17:37:12 +03:00
|
|
|
- (void)setContentSizeCategory:(NSString *)contentSizeCategory
|
|
|
|
{
|
|
|
|
if (_contentSizeCategory != contentSizeCategory) {
|
|
|
|
_contentSizeCategory = [contentSizeCategory copy];
|
2015-08-07 12:32:00 +03:00
|
|
|
[self invalidateMultiplier];
|
2015-07-31 17:37:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-07 12:32:00 +03:00
|
|
|
- (void)invalidateMultiplier
|
|
|
|
{
|
|
|
|
self.multiplier = [self multiplierForContentSizeCategory:_contentSizeCategory];
|
2020-03-09 08:58:01 +03:00
|
|
|
[[NSNotificationCenter defaultCenter] postNotificationName:RCTAccessibilityManagerDidUpdateMultiplierNotification
|
|
|
|
object:self];
|
2015-08-07 12:32:00 +03:00
|
|
|
}
|
|
|
|
|
2015-07-31 17:37:12 +03:00
|
|
|
- (CGFloat)multiplierForContentSizeCategory:(NSString *)category
|
|
|
|
{
|
|
|
|
NSNumber *m = self.multipliers[category];
|
|
|
|
if (m.doubleValue <= 0.0) {
|
2019-07-23 13:19:41 +03:00
|
|
|
RCTLogError(@"Can't determine multiplier for category %@. Using 1.0.", category);
|
2015-07-31 17:37:12 +03:00
|
|
|
m = @1.0;
|
|
|
|
}
|
|
|
|
return m.doubleValue;
|
|
|
|
}
|
|
|
|
|
2015-11-14 21:25:00 +03:00
|
|
|
- (void)setMultipliers:(NSDictionary<NSString *, NSNumber *> *)multipliers
|
2015-08-07 12:32:00 +03:00
|
|
|
{
|
|
|
|
if (_multipliers != multipliers) {
|
|
|
|
_multipliers = [multipliers copy];
|
|
|
|
[self invalidateMultiplier];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-14 21:25:00 +03:00
|
|
|
- (NSDictionary<NSString *, NSNumber *> *)multipliers
|
2015-07-31 17:37:12 +03:00
|
|
|
{
|
|
|
|
if (_multipliers == nil) {
|
2020-03-09 08:58:01 +03:00
|
|
|
_multipliers = @{
|
|
|
|
UIContentSizeCategoryExtraSmall : @0.823,
|
|
|
|
UIContentSizeCategorySmall : @0.882,
|
|
|
|
UIContentSizeCategoryMedium : @0.941,
|
|
|
|
UIContentSizeCategoryLarge : @1.0,
|
|
|
|
UIContentSizeCategoryExtraLarge : @1.118,
|
|
|
|
UIContentSizeCategoryExtraExtraLarge : @1.235,
|
|
|
|
UIContentSizeCategoryExtraExtraExtraLarge : @1.353,
|
|
|
|
UIContentSizeCategoryAccessibilityMedium : @1.786,
|
|
|
|
UIContentSizeCategoryAccessibilityLarge : @2.143,
|
|
|
|
UIContentSizeCategoryAccessibilityExtraLarge : @2.643,
|
|
|
|
UIContentSizeCategoryAccessibilityExtraExtraLarge : @3.143,
|
|
|
|
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @3.571
|
|
|
|
};
|
2015-07-31 17:37:12 +03:00
|
|
|
}
|
|
|
|
return _multipliers;
|
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
RCT_EXPORT_METHOD(setAccessibilityContentSizeMultipliers
|
|
|
|
: (JS::NativeAccessibilityManager::SpecSetAccessibilityContentSizeMultipliersJSMultipliers &)
|
|
|
|
JSMultipliers)
|
2015-07-31 17:37:12 +03:00
|
|
|
{
|
2015-11-14 21:25:00 +03:00
|
|
|
NSMutableDictionary<NSString *, NSNumber *> *multipliers = [NSMutableDictionary new];
|
2019-08-23 21:58:36 +03:00
|
|
|
setMultipliers(multipliers, UIContentSizeCategoryExtraSmall, JSMultipliers.extraSmall());
|
|
|
|
setMultipliers(multipliers, UIContentSizeCategorySmall, JSMultipliers.small());
|
|
|
|
setMultipliers(multipliers, UIContentSizeCategoryMedium, JSMultipliers.medium());
|
|
|
|
setMultipliers(multipliers, UIContentSizeCategoryLarge, JSMultipliers.large());
|
|
|
|
setMultipliers(multipliers, UIContentSizeCategoryExtraLarge, JSMultipliers.extraLarge());
|
|
|
|
setMultipliers(multipliers, UIContentSizeCategoryExtraExtraLarge, JSMultipliers.extraExtraLarge());
|
|
|
|
setMultipliers(multipliers, UIContentSizeCategoryExtraExtraExtraLarge, JSMultipliers.extraExtraExtraLarge());
|
|
|
|
setMultipliers(multipliers, UIContentSizeCategoryAccessibilityMedium, JSMultipliers.accessibilityMedium());
|
|
|
|
setMultipliers(multipliers, UIContentSizeCategoryAccessibilityLarge, JSMultipliers.accessibilityLarge());
|
|
|
|
setMultipliers(multipliers, UIContentSizeCategoryAccessibilityExtraLarge, JSMultipliers.accessibilityExtraLarge());
|
2020-03-09 08:58:01 +03:00
|
|
|
setMultipliers(
|
|
|
|
multipliers, UIContentSizeCategoryAccessibilityExtraExtraLarge, JSMultipliers.accessibilityExtraExtraLarge());
|
|
|
|
setMultipliers(
|
|
|
|
multipliers,
|
|
|
|
UIContentSizeCategoryAccessibilityExtraExtraExtraLarge,
|
|
|
|
JSMultipliers.accessibilityExtraExtraExtraLarge());
|
2015-07-31 17:37:12 +03:00
|
|
|
self.multipliers = multipliers;
|
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
static void setMultipliers(
|
|
|
|
NSMutableDictionary<NSString *, NSNumber *> *multipliers,
|
|
|
|
NSString *key,
|
|
|
|
folly::Optional<double> optionalDouble)
|
2019-08-23 21:58:36 +03:00
|
|
|
{
|
|
|
|
if (optionalDouble.hasValue()) {
|
|
|
|
multipliers[key] = @(optionalDouble.value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
RCT_EXPORT_METHOD(setAccessibilityFocus : (double)reactTag)
|
2017-05-26 13:07:49 +03:00
|
|
|
{
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
2019-08-23 21:58:36 +03:00
|
|
|
UIView *view = [self.bridge.uiManager viewForReactTag:@(reactTag)];
|
2017-05-26 13:07:49 +03:00
|
|
|
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, view);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
RCT_EXPORT_METHOD(announceForAccessibility : (NSString *)announcement)
|
2017-05-30 14:35:52 +03:00
|
|
|
{
|
|
|
|
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, announcement);
|
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
RCT_EXPORT_METHOD(getMultiplier : (RCTResponseSenderBlock)callback)
|
2015-07-31 17:37:12 +03:00
|
|
|
{
|
|
|
|
if (callback) {
|
|
|
|
callback(@[ @(self.multiplier) ]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
RCT_EXPORT_METHOD(getCurrentBoldTextState
|
|
|
|
: (RCTResponseSenderBlock)onSuccess onError
|
|
|
|
: (__unused RCTResponseSenderBlock)onError)
|
2019-08-23 21:58:36 +03:00
|
|
|
{
|
2020-03-09 08:58:01 +03:00
|
|
|
onSuccess(@[ @(_isBoldTextEnabled) ]);
|
2019-08-23 21:58:36 +03:00
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
RCT_EXPORT_METHOD(getCurrentGrayscaleState
|
|
|
|
: (RCTResponseSenderBlock)onSuccess onError
|
|
|
|
: (__unused RCTResponseSenderBlock)onError)
|
2015-10-02 04:07:06 +03:00
|
|
|
{
|
2020-03-09 08:58:01 +03:00
|
|
|
onSuccess(@[ @(_isGrayscaleEnabled) ]);
|
2019-03-15 21:17:42 +03:00
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
RCT_EXPORT_METHOD(getCurrentInvertColorsState
|
|
|
|
: (RCTResponseSenderBlock)onSuccess onError
|
|
|
|
: (__unused RCTResponseSenderBlock)onError)
|
2019-03-15 21:17:42 +03:00
|
|
|
{
|
2020-03-09 08:58:01 +03:00
|
|
|
onSuccess(@[ @(_isInvertColorsEnabled) ]);
|
2019-03-15 21:17:42 +03:00
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
RCT_EXPORT_METHOD(getCurrentReduceMotionState
|
|
|
|
: (RCTResponseSenderBlock)onSuccess onError
|
|
|
|
: (__unused RCTResponseSenderBlock)onError)
|
2019-03-15 21:17:42 +03:00
|
|
|
{
|
2020-03-09 08:58:01 +03:00
|
|
|
onSuccess(@[ @(_isReduceMotionEnabled) ]);
|
2015-10-02 04:07:06 +03:00
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
RCT_EXPORT_METHOD(getCurrentReduceTransparencyState
|
|
|
|
: (RCTResponseSenderBlock)onSuccess onError
|
|
|
|
: (__unused RCTResponseSenderBlock)onError)
|
- Add support for "reduce motion" into AccessibilityInfo (#23839)
Summary:
This PR adds `isReduceMotionEnabled()` to `AccessibilityInfo` in other to add support for "reduce motion", exposing the Operational System's settings option. Additionally, it adds a new event, `reduceMotionChanged`, in order to listen for this flag's update.
With this feature, developers will be able to disable or reduce animations, _**something that will be required as soon as WCAG 2.1 draft got approved**._ See [WCAG 2.1 — 2.3.3 Animations from Interaction criteria](https://knowbility.org/blog/2018/WCAG21-233Animations/)
It's exposed by [`UIAccessibility`' isReduceMotionEnabled ](https://developer.apple.com/documentation/uikit/uiaccessibility/1615133-isreducemotionenabled
) on iOS and [Settings.Global.TRANSITION_ANIMATION_SCALE](https://developer.android.com/reference/android/provider/Settings.Global#TRANSITION_ANIMATION_SCALE) on Android.
Up until now, `AccessibilityInfo` only exposes screen reader flag. By adding this second accessibility option, it's a good opportunity to rename `fetch` method to an appropriate name, `isScreenReaderEnabled`, as well as rename `change` event to `screenReaderChanged`, which will make it clearer and more specific.
(In case it's approved, a follow-up PR could exposes [more iOS acessibility flags](https://developer.apple.com/documentation/uikit/uiaccessibility), such as `isShakeToUndoEnabled`, `isReduceTransparencyEnabled`, `isGrayscaleEnabled`, `isInvertColorsEnabled`)
(iOS code inspired by [phonegap-mobile-accessibility](https://github.com/phonegap/phonegap-mobile-accessibility). And Android by [Flutter](https://github.com/flutter/engine/blob/master/shell/platform/android/io/flutter/view/AccessibilityBridge.java
))
Pull Request resolved: https://github.com/facebook/react-native/pull/23839
Differential Revision: D14406227
Pulled By: hramos
fbshipit-source-id: adf43be84c488522bf1e29d862681220ad193883
2019-03-13 06:23:54 +03:00
|
|
|
{
|
2020-03-09 08:58:01 +03:00
|
|
|
onSuccess(@[ @(_isReduceTransparencyEnabled) ]);
|
- Add support for "reduce motion" into AccessibilityInfo (#23839)
Summary:
This PR adds `isReduceMotionEnabled()` to `AccessibilityInfo` in other to add support for "reduce motion", exposing the Operational System's settings option. Additionally, it adds a new event, `reduceMotionChanged`, in order to listen for this flag's update.
With this feature, developers will be able to disable or reduce animations, _**something that will be required as soon as WCAG 2.1 draft got approved**._ See [WCAG 2.1 — 2.3.3 Animations from Interaction criteria](https://knowbility.org/blog/2018/WCAG21-233Animations/)
It's exposed by [`UIAccessibility`' isReduceMotionEnabled ](https://developer.apple.com/documentation/uikit/uiaccessibility/1615133-isreducemotionenabled
) on iOS and [Settings.Global.TRANSITION_ANIMATION_SCALE](https://developer.android.com/reference/android/provider/Settings.Global#TRANSITION_ANIMATION_SCALE) on Android.
Up until now, `AccessibilityInfo` only exposes screen reader flag. By adding this second accessibility option, it's a good opportunity to rename `fetch` method to an appropriate name, `isScreenReaderEnabled`, as well as rename `change` event to `screenReaderChanged`, which will make it clearer and more specific.
(In case it's approved, a follow-up PR could exposes [more iOS acessibility flags](https://developer.apple.com/documentation/uikit/uiaccessibility), such as `isShakeToUndoEnabled`, `isReduceTransparencyEnabled`, `isGrayscaleEnabled`, `isInvertColorsEnabled`)
(iOS code inspired by [phonegap-mobile-accessibility](https://github.com/phonegap/phonegap-mobile-accessibility). And Android by [Flutter](https://github.com/flutter/engine/blob/master/shell/platform/android/io/flutter/view/AccessibilityBridge.java
))
Pull Request resolved: https://github.com/facebook/react-native/pull/23839
Differential Revision: D14406227
Pulled By: hramos
fbshipit-source-id: adf43be84c488522bf1e29d862681220ad193883
2019-03-13 06:23:54 +03:00
|
|
|
}
|
|
|
|
|
2020-03-09 08:58:01 +03:00
|
|
|
RCT_EXPORT_METHOD(getCurrentVoiceOverState
|
|
|
|
: (RCTResponseSenderBlock)onSuccess onError
|
|
|
|
: (__unused RCTResponseSenderBlock)onError)
|
2019-03-15 21:17:42 +03:00
|
|
|
{
|
2020-03-09 08:58:01 +03:00
|
|
|
onSuccess(@[ @(_isVoiceOverEnabled) ]);
|
2019-03-15 21:17:42 +03:00
|
|
|
}
|
|
|
|
|
Part 2: Update ObjC++ codegen classes to use ObjCTurboModule::InitParams
Summary:
## Summary
Please check out D21035209.
## Changes
- Codemod all ObjC NativeModule `getTurboModuleWithJsInvoker:nativeInvoker:perfLogger` methods to `getTurboModule:(const ObjCTurboModule::Args)`
## Script
```
var withSpaces = (...args) => args.join('\s*')
var regexString = withSpaces(
'-',
'\(',
'std::shared_ptr',
'<',
'(?<turboModuleClass>(facebook::react::|react::|::|)TurboModule)',
'>',
'\)',
'getTurboModuleWithJsInvoker',
':',
'\(',
'std::shared_ptr',
'<',
'(?<fbNamespace>(facebook::react::|react::|::|))CallInvoker',
'>',
'\)',
'(?<jsInvokerInstance>[A-Za-z0-9]+)',
'nativeInvoker',
':',
'\(',
'std::shared_ptr',
'<',
'(facebook::react::|react::|::|)CallInvoker',
'>',
'\)',
'(?<nativeInvokerInstance>[A-Za-z0-9]+)',
'perfLogger',
':',
'\(',
'id',
'<',
'RCTTurboModulePerformanceLogger',
'>',
'\)',
'(?<perfLoggerInstance>[A-Za-z0-9]+)',
'{',
'return',
'std::make_shared',
'<',
'(?<specName>(facebook::react::|react::|::|)Native[%A-Za-z0-9]+SpecJSI)',
'>',
'\(',
'self',
',',
'\k<jsInvokerInstance>',
',',
'\k<nativeInvokerInstance>',
',',
'\k<perfLoggerInstance>',
'\)',
';',
'}',
)
var replaceString = `- (std::shared_ptr<$<turboModuleClass>>) getTurboModule:(const $<fbNamespace>ObjCTurboModule::InitParams &)params
{
return std::make_shared<$<specName>>(params);
}`
const exec = require('../lib/exec');
const abspath = require('../lib/abspath');
const relpath = require('../lib/relpath');
const readFile = (filename) => require('fs').readFileSync(filename, 'utf8');
const writeFile = (filename, content) => require('fs').writeFileSync(filename, content);
function main() {
const tmFiles = exec('cd ~/fbsource && xbgs -n 10000 -l getTurboModuleWithJsInvoker:').split('\n').filter(Boolean);
tmFiles
.filter((filename) => !filename.includes('microsoft-fork-of-react-native'))
.map(abspath)
.forEach((filename) => {
const source = readFile(filename);
const newSource = source.replace(new RegExp(regexString, 'g'), replaceString);
if (source == newSource) {
console.log(relpath(filename));
}
writeFile(filename, newSource);
});
}
if (!module.parent) {
main();
}
```
## Re-generating diff
```
> hg revert -r .^ --all
> node index.js # run script
```
Changelog: [iOS][Changed] - Make all ObjC NativeModules create TurboModules using ObjCTurboModule::Args
Reviewed By: PeteTheHeat
Differential Revision: D21036265
fbshipit-source-id: 404bcc548d1775ef23d793527606d02fe384a0a2
2020-04-17 03:23:39 +03:00
|
|
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
|
|
(const facebook::react::ObjCTurboModule::InitParams &)params
|
2019-03-15 21:17:42 +03:00
|
|
|
{
|
Part 2: Update ObjC++ codegen classes to use ObjCTurboModule::InitParams
Summary:
## Summary
Please check out D21035209.
## Changes
- Codemod all ObjC NativeModule `getTurboModuleWithJsInvoker:nativeInvoker:perfLogger` methods to `getTurboModule:(const ObjCTurboModule::Args)`
## Script
```
var withSpaces = (...args) => args.join('\s*')
var regexString = withSpaces(
'-',
'\(',
'std::shared_ptr',
'<',
'(?<turboModuleClass>(facebook::react::|react::|::|)TurboModule)',
'>',
'\)',
'getTurboModuleWithJsInvoker',
':',
'\(',
'std::shared_ptr',
'<',
'(?<fbNamespace>(facebook::react::|react::|::|))CallInvoker',
'>',
'\)',
'(?<jsInvokerInstance>[A-Za-z0-9]+)',
'nativeInvoker',
':',
'\(',
'std::shared_ptr',
'<',
'(facebook::react::|react::|::|)CallInvoker',
'>',
'\)',
'(?<nativeInvokerInstance>[A-Za-z0-9]+)',
'perfLogger',
':',
'\(',
'id',
'<',
'RCTTurboModulePerformanceLogger',
'>',
'\)',
'(?<perfLoggerInstance>[A-Za-z0-9]+)',
'{',
'return',
'std::make_shared',
'<',
'(?<specName>(facebook::react::|react::|::|)Native[%A-Za-z0-9]+SpecJSI)',
'>',
'\(',
'self',
',',
'\k<jsInvokerInstance>',
',',
'\k<nativeInvokerInstance>',
',',
'\k<perfLoggerInstance>',
'\)',
';',
'}',
)
var replaceString = `- (std::shared_ptr<$<turboModuleClass>>) getTurboModule:(const $<fbNamespace>ObjCTurboModule::InitParams &)params
{
return std::make_shared<$<specName>>(params);
}`
const exec = require('../lib/exec');
const abspath = require('../lib/abspath');
const relpath = require('../lib/relpath');
const readFile = (filename) => require('fs').readFileSync(filename, 'utf8');
const writeFile = (filename, content) => require('fs').writeFileSync(filename, content);
function main() {
const tmFiles = exec('cd ~/fbsource && xbgs -n 10000 -l getTurboModuleWithJsInvoker:').split('\n').filter(Boolean);
tmFiles
.filter((filename) => !filename.includes('microsoft-fork-of-react-native'))
.map(abspath)
.forEach((filename) => {
const source = readFile(filename);
const newSource = source.replace(new RegExp(regexString, 'g'), replaceString);
if (source == newSource) {
console.log(relpath(filename));
}
writeFile(filename, newSource);
});
}
if (!module.parent) {
main();
}
```
## Re-generating diff
```
> hg revert -r .^ --all
> node index.js # run script
```
Changelog: [iOS][Changed] - Make all ObjC NativeModules create TurboModules using ObjCTurboModule::Args
Reviewed By: PeteTheHeat
Differential Revision: D21036265
fbshipit-source-id: 404bcc548d1775ef23d793527606d02fe384a0a2
2020-04-17 03:23:39 +03:00
|
|
|
return std::make_shared<facebook::react::NativeAccessibilityManagerSpecJSI>(params);
|
2019-03-15 21:17:42 +03:00
|
|
|
}
|
|
|
|
|
2015-07-31 17:37:12 +03:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation RCTBridge (RCTAccessibilityManager)
|
|
|
|
|
|
|
|
- (RCTAccessibilityManager *)accessibilityManager
|
|
|
|
{
|
2015-11-25 14:09:00 +03:00
|
|
|
return [self moduleForClass:[RCTAccessibilityManager class]];
|
2015-07-31 17:37:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
2019-08-23 21:58:36 +03:00
|
|
|
|
|
|
|
Class RCTAccessibilityManagerCls(void)
|
|
|
|
{
|
|
|
|
return RCTAccessibilityManager.class;
|
|
|
|
}
|