From aac33da5bf3fbb5a6aefb807c0634b86b1e0a508 Mon Sep 17 00:00:00 2001 From: Tom Underhill Date: Mon, 21 Sep 2020 12:27:43 +0200 Subject: [PATCH] VoiceOver accessibility issues in RN .62 (#603) * Update scripts to publish react-native-macos-init * Clean up merge markers * Restored ios:macos RNTester parity except for InputAccessoryView. * Revert "Restored ios:macos RNTester parity except for InputAccessoryView." This reverts commit 5a67ae06b01301ac43533e7e20dd7fed24a0937f. * Remove unnecessary android builds and tar file upload. * RN .62 accessiblity fixes. * Fix regression in recursive accessiblityLabel text. * Changed per PR feedback. * Add "disclosure" role for mac mapping to NSAccessibilityDisclosureTriangleRole. Make accessibilityValue return "checked" state for checkbox, radiobutton, and disclosure roles. * CocoaPods does not like podspec version numbers that are 0.0.0. The canary builds set the version to 0.0.0- via `node scripts/bump-oss-version.js --nigh tly` which causes the "Verify react-native-macos-init MacDebug" CI test to fail bec ause `pod install` fails due to `.podspec` versions that are 0.0.0. Add a `--testi ng` switch to `bump-oss-version.js` that changes the version to 1000.0.0 and use th at switch in `react-native-macos-init.yml`. Co-authored-by: React-Native Bot <53619745+rnbot@users.noreply.github.com> --- .ado/templates/react-native-macos-init.yml | 2 +- React/Base/RCTConvert.m | 58 ++++-- React/Base/RCTUIKit.h | 3 + React/Views/RCTView.m | 203 +++++++++++++++++++-- React/Views/RCTViewManager.m | 27 ++- React/Views/UIView+React.h | 2 +- React/Views/UIView+React.m | 8 +- scripts/bump-oss-version.js | 10 +- 8 files changed, 267 insertions(+), 46 deletions(-) diff --git a/.ado/templates/react-native-macos-init.yml b/.ado/templates/react-native-macos-init.yml index e9aee47eec..df819ba316 100644 --- a/.ado/templates/react-native-macos-init.yml +++ b/.ado/templates/react-native-macos-init.yml @@ -63,7 +63,7 @@ steps: - task: CmdLine@2 displayName: Bump package version inputs: - script: node scripts/bump-oss-version.js --nightly + script: node scripts/bump-oss-version.js --testing - script: | npm publish --registry http://localhost:4873 diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index e4802a305d..3e1b9d7b88 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -1145,22 +1145,50 @@ RCT_ENUM_CONVERTER(RCTAnimationType, (@{ #if TARGET_OS_OSX // [TODO(macOS ISS#2323203) + (NSString*)accessibilityRoleFromTrait:(NSString*)trait { - // a subset of iOS accessibilityTraits map to macOS accessiblityRoles: - if ([trait isEqualToString:@"button"]) { - return NSAccessibilityButtonRole; - } else if ([trait isEqualToString:@"text"]) { - return NSAccessibilityStaticTextRole; - } else if ([trait isEqualToString:@"link"]) { - return NSAccessibilityLinkRole; - } else if ([trait isEqualToString:@"image"]) { - return NSAccessibilityImageRole; - // a set of RN accessibilityTraits are macOS specific accessiblity roles: - } else if ([trait isEqualToString:@"group"]) { - return NSAccessibilityGroupRole; - } else if ([trait isEqualToString:@"list"]) { - return NSAccessibilityListRole; + static NSDictionary *traitOrRoleToAccessibilityRole; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + traitOrRoleToAccessibilityRole = @{ + // from https://reactnative.dev/docs/accessibility#accessibilityrole + @"adjustable": NSAccessibilitySliderRole, + @"alert": NSAccessibilityStaticTextRole, // no exact match on macOS + @"button": NSAccessibilityButtonRole, // also a legacy iOS accessibilityTraits + @"checkbox": NSAccessibilityCheckBoxRole, + @"combobox": NSAccessibilityComboBoxRole, + @"header": NSAccessibilityStaticTextRole, // no exact match on macOS + @"image": NSAccessibilityImageRole, // also a legacy iOS accessibilityTraits + @"imagebutton": NSAccessibilityButtonRole, // no exact match on macOS + @"keyboardkey": NSAccessibilityButtonRole, // no exact match on macOS + @"link": NSAccessibilityLinkRole, // also a legacy iOS accessibilityTraits + @"menu": NSAccessibilityMenuRole, + @"menubar": NSAccessibilityMenuBarRole, + @"menuitem": NSAccessibilityMenuBarItemRole, + @"none": NSAccessibilityUnknownRole, + @"progressbar": NSAccessibilityProgressIndicatorRole, + @"radio": NSAccessibilityRadioButtonRole, + @"radiogroup": NSAccessibilityRadioGroupRole, + @"scrollbar": NSAccessibilityScrollBarRole, + @"search": NSAccessibilityTextFieldRole, // no exact match on macOS + @"spinbutton": NSAccessibilityIncrementorRole, + @"summary": NSAccessibilityStaticTextRole, // no exact match on macOS + @"switch": NSAccessibilityCheckBoxRole, // no exact match on macOS + @"tab": NSAccessibilityButtonRole, // no exact match on macOS + @"tablist": NSAccessibilityTabGroupRole, + @"text": NSAccessibilityStaticTextRole, // also a legacy iOS accessibilityTraits + @"timer": NSAccessibilityStaticTextRole, // no exact match on macOS + @"toolbar": NSAccessibilityToolbarRole, + // Roles/traits that are macOS specific and are used by some of the core components (Lists): + @"disclosure": NSAccessibilityDisclosureTriangleRole, + @"group": NSAccessibilityGroupRole, + @"list": NSAccessibilityListRole, + }; + }); + + NSString *role = [traitOrRoleToAccessibilityRole valueForKey:trait]; + if (role == nil) { + role = NSAccessibilityUnknownRole; } - return NSAccessibilityUnknownRole; + return role; } + (NSString *)accessibilityRoleFromTraits:(id)json diff --git a/React/Base/RCTUIKit.h b/React/Base/RCTUIKit.h index a0479a343f..6bc22ef83e 100644 --- a/React/Base/RCTUIKit.h +++ b/React/Base/RCTUIKit.h @@ -270,6 +270,9 @@ void UIGraphicsEndImageContext(void); // semantically equivalent types // +// UIAccessibility.h/NSAccessibility.h +@compatibility_alias UIAccessibilityCustomAction NSAccessibilityCustomAction; + // UIColor.h/NSColor.h #define RCTUIColor NSColor diff --git a/React/Views/RCTView.m b/React/Views/RCTView.m index 9ce0af7f3a..a634ed33f6 100644 --- a/React/Views/RCTView.m +++ b/React/Views/RCTView.m @@ -16,6 +16,9 @@ #import "RCTUtils.h" #import "UIView+React.h" #import "RCTI18nUtil.h" +#if TARGET_OS_OSX // [TODO(macOS ISS#2323203) +#import "RCTTextView.h" +#endif // ]TODO(macOS ISS#2323203) #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) UIAccessibilityTraits const SwitchAccessibilityTrait = 0x20000000000001; @@ -92,7 +95,18 @@ static NSString *RCTRecursiveAccessibilityLabel(RCTUIView *view) // TODO(macOS I { NSMutableString *str = [NSMutableString stringWithString:@""]; for (RCTUIView *subview in view.subviews) { // TODO(macOS ISS#3536887) +#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) NSString *label = subview.accessibilityLabel; +#else // [TODO(macOS ISS#2323203) + NSString *label; + if ([subview isKindOfClass:[RCTTextView class]]) { + // on macOS VoiceOver a text element will always have its accessibilityValue read, but will only read it's accessibilityLabel if it's value is set. + // the macOS RCTTextView accessibilityValue will return its accessibilityLabel if set otherwise return its text. + label = subview.accessibilityValue; + } else { + label = subview.accessibilityLabel; + } +#endif // ]TODO(macOS ISS#2323203) if (!label) { label = RCTRecursiveAccessibilityLabel(subview); } @@ -188,10 +202,14 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:unused) if (label) { return label; } +#if TARGET_OS_OSX // [TODO(macOS ISS#2323203) + // calling super.accessibilityLabel above on macOS causes the return value of this accessor to be ignored by VoiceOver. + // Calling the super's setAccessibilityLabel with nil ensures that the return value of this accessor is used by VoiceOver. + [super setAccessibilityLabel:nil]; +#endif // ]TODO(macOS ISS#2323203) return RCTRecursiveAccessibilityLabel(self); } -#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - (NSArray *)accessibilityCustomActions { if (!self.accessibilityActions.count) { @@ -233,11 +251,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:unused) } return YES; } -#endif // TODO(macOS ISS#2323203) +#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - (NSString *)accessibilityValue { -#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) if ((self.accessibilityTraits & SwitchAccessibilityTrait) == SwitchAccessibilityTrait) { for (NSString *state in self.accessibilityState) { id val = self.accessibilityState[state]; @@ -248,17 +265,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:unused) return [val boolValue] ? @"1" : @"0"; } } - for (NSString *state in self.accessibilityState) { - id val = self.accessibilityState[state]; - if (!val) { - continue; - } - if ([state isEqualToString:@"checked"] && [val isKindOfClass:[NSNumber class]]) { - return [val boolValue] ? @"1" : @"0"; - } - } } -#endif // TODO(macOS ISS#2323203) NSMutableArray *valueComponents = [NSMutableArray new]; static NSDictionary *roleDescriptions = nil; static dispatch_once_t onceToken1; @@ -294,7 +301,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:unused) @"mixed": @"mixed", }; }); - NSString *roleDescription = self.accessibilityRole ? roleDescriptions[self.accessibilityRole]: nil; + NSString *roleDescription = self.accessibilityRoleInternal ? roleDescriptions[self.accessibilityRoleInternal]: nil; // TODO(OSS Candidate ISS#2710739): renamed prop so it doesn't conflict with -[NSAccessibility accessibilityRole]. if (roleDescription) { [valueComponents addObject:roleDescription]; } @@ -341,6 +348,147 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:unused) } return nil; } +#else // [TODO(macOS ISS#2323203) +- (id)accessibilityValue { + id accessibilityValue = nil; + NSAccessibilityRole role = [self accessibilityRole]; + if (role == NSAccessibilityCheckBoxRole || + role == NSAccessibilityRadioButtonRole || + role == NSAccessibilityDisclosureTriangleRole) { + for (NSString *state in [self accessibilityState]) { + id val = [self accessibilityState][state]; + if (val != nil) { + if ([state isEqualToString:@"checked"]) { + if ([val isKindOfClass:[NSNumber class]]) { + accessibilityValue = @([val boolValue]); + } else if ([val isKindOfClass:[NSString class]] && [val isEqualToString:@"mixed"]) { + accessibilityValue = @(2); // undocumented by Apple: @(2) is the accessibilityValue an NSButton has when its state is NSMixedState (-1) and causes VoiceOver to announced "mixed". + } + } + } + } + } else if ([self accessibilityRole] == NSAccessibilityStaticTextRole) { + // On macOS if the role is static text, VoiceOver will only read the text returned by accessibilityValue. + // So return accessibilityLabel which has the logic to return either either the ivar or a computed value of all the children's text. + // If the accessibilityValueInternal "text" is present, it will override this value below. + accessibilityValue = [self accessibilityLabel]; + } + + // handle accessibilityValue + + id accessibilityValueInternal = [self accessibilityValueInternal]; + if (accessibilityValueInternal != nil) { + id now = accessibilityValueInternal[@"now"]; + id text = accessibilityValueInternal[@"text"]; + if (text != nil && [text isKindOfClass:[NSString class]]) { + accessibilityValue = text; + } else if (now != nil && [now isKindOfClass:[NSNumber class]]) { + accessibilityValue = now; + } + } + + return accessibilityValue; +} + +- (BOOL)isAccessibilitySelectorAllowed:(SEL)selector { + BOOL isAllowed = NO; + if (selector == @selector(isAccessibilityEnabled)) { + if (self.accessibilityState != nil) { + id disabled = self.accessibilityState[@"disabled"]; + if ([disabled isKindOfClass:[NSNumber class]]) { + isAllowed = YES; + } + } + } else if (selector == @selector(isAccessibilitySelected)) { + if (self.accessibilityState != nil) { + id selected = self.accessibilityState[@"selected"]; + if ([selected isKindOfClass:[NSNumber class]]) { + isAllowed = YES; + } + } + } else if (selector == @selector(isAccessibilityExpanded)) { + if (self.accessibilityState != nil) { + id expanded = self.accessibilityState[@"expanded"]; + if ([expanded isKindOfClass:[NSNumber class]]) { + isAllowed = YES; + } + } + } else if (selector == @selector(accessibilityPerformPress)) { + if (_onAccessibilityTap != nil || + (_onAccessibilityAction != nil && accessibilityActionsNameMap[@"activate"]) || + _onClick != nil) { + isAllowed = YES; + } + } else if (selector == @selector(accessibilityPerformIncrement)) { + if (_onAccessibilityAction != nil && accessibilityActionsNameMap[@"increment"]) { + isAllowed = YES; + } + } else if (selector == @selector(accessibilityPerformDecrement)) { + if (_onAccessibilityAction != nil && accessibilityActionsNameMap[@"decrement"]) { + isAllowed = YES; + } + } else { + isAllowed = YES; + } + return isAllowed; +} + +- (BOOL)isAccessibilityEnabled { + BOOL isAccessibilityEnabled = YES; + if (self.accessibilityState != nil) { + id disabled = self.accessibilityState[@"disabled"]; + if ([disabled isKindOfClass:[NSNumber class]]) { + isAccessibilityEnabled = [disabled boolValue] ? NO : YES; + } + } + return isAccessibilityEnabled; +} + +- (BOOL)isAccessibilitySelected { + BOOL isAccessibilitySelected = NO; + if (self.accessibilityState != nil) { + id selected = self.accessibilityState[@"selected"]; + if ([selected isKindOfClass:[NSNumber class]]) { + isAccessibilitySelected = [selected boolValue]; + } + } + return isAccessibilitySelected; +} + +- (BOOL)isAccessibilityExpanded { + BOOL isAccessibilityExpanded = NO; + if (self.accessibilityState != nil) { + id expanded = self.accessibilityState[@"expanded"]; + if ([expanded isKindOfClass:[NSNumber class]]) { + isAccessibilityExpanded = [expanded boolValue]; + } + } + return isAccessibilityExpanded; +} + +- (id)accessibilityMinValue { + id accessibilityMinValue = nil; + if (self.accessibilityValueInternal != nil) { + id min = self.accessibilityValueInternal[@"min"]; + if ([min isKindOfClass:[NSNumber class]]) { + accessibilityMinValue = min; + } + } + return accessibilityMinValue; +} + +- (id)accessibilityMaxValue { + id accessibilityMaxValue = nil; + if (self.accessibilityValueInternal != nil) { + id max = self.accessibilityValueInternal[@"max"]; + if ([max isKindOfClass:[NSNumber class]]) { + accessibilityMaxValue = max; + } + } + return accessibilityMaxValue; +} + +#endif // ]TODO(macOS ISS#2323203) - (void)setPointerEvents:(RCTPointerEvents)pointerEvents { @@ -445,17 +593,28 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:unused) return NO; } -#if !TARGET_OS_OSX // ]TODO(macOS ISS#2323203) +#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - (BOOL)accessibilityActivate #else // [TODO(macOS ISS#2323203) - (BOOL)accessibilityPerformPress #endif // ]TODO(macOS ISS#2323203) { +#if TARGET_OS_OSX // [TODO(macOS ISS#2323203) + if ([self isAccessibilityEnabled] == NO) { + return NO; + } +#endif // ]TODO(macOS ISS#2323203) if ([self performAccessibilityAction:@"activate"]) { return YES; } else if (_onAccessibilityTap) { _onAccessibilityTap(nil); return YES; +#if TARGET_OS_OSX // [TODO(macOS ISS#2323203) + } else if (_onClick != nil) { + // macOS is not simulating a click if there is no onAccessibilityAction like it does on iOS, so we simulate it here. + _onClick(nil); + return YES; +#endif // ]TODO(macOS ISS#2323203) } else { return NO; } @@ -487,15 +646,29 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:unused) } } +#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - (void)accessibilityIncrement { [self performAccessibilityAction:@"increment"]; } +#else // [TODO(macOS ISS#2323203) +- (BOOL)accessibilityPerformIncrement +{ + return [self performAccessibilityAction:@"increment"]; +} +#endif // ]TODO(macOS ISS#2323203) +#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) - (void)accessibilityDecrement { [self performAccessibilityAction:@"decrement"]; } +#else // [TODO(macOS ISS#2323203) +- (BOOL)accessibilityPerformDecrement +{ + return [self performAccessibilityAction:@"decrement"]; +} +#endif // ]TODO(macOS ISS#2323203) - (NSString *)description { diff --git a/React/Views/RCTViewManager.m b/React/Views/RCTViewManager.m index c42f0fff40..164bb949e6 100644 --- a/React/Views/RCTViewManager.m +++ b/React/Views/RCTViewManager.m @@ -48,7 +48,8 @@ RCT_MULTI_ENUM_CONVERTER(UIAccessibilityTraits, (@{ @"allowsDirectInteraction": @(UIAccessibilityTraitAllowsDirectInteraction), @"pageTurn": @(UIAccessibilityTraitCausesPageTurn), // [TODO(macOS ISS#2323203): - // a set of RN accessibilityTraits are macOS specific accessiblity roles and map to nothing on iOS: + // a set of RN accessibilityTraits are macOS specific accessibility roles and map to nothing on iOS: + @"disclosure": @(UIAccessibilityTraitNone), @"group": @(UIAccessibilityTraitNone), @"list": @(UIAccessibilityTraitNone), // ]TODO(macOS ISS#2323203) @@ -138,18 +139,20 @@ RCT_REMAP_VIEW_PROPERTY(accessibilityActions, reactAccessibilityElement.accessib RCT_REMAP_VIEW_PROPERTY(accessibilityLabel, reactAccessibilityElement.accessibilityLabel, NSString) #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) RCT_REMAP_VIEW_PROPERTY(accessibilityHint, reactAccessibilityElement.accessibilityHint, NSString) +#else // [TODO(macOS ISS#2323203) +RCT_REMAP_VIEW_PROPERTY(accessibilityHint, reactAccessibilityElement.accessibilityHelp, NSString) +#endif // TODO(macOS ISS#2323203) RCT_REMAP_VIEW_PROPERTY(accessibilityValue, reactAccessibilityElement.accessibilityValueInternal, NSDictionary) +#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) RCT_REMAP_VIEW_PROPERTY(accessibilityViewIsModal, reactAccessibilityElement.accessibilityViewIsModal, BOOL) RCT_REMAP_VIEW_PROPERTY(accessibilityElementsHidden, reactAccessibilityElement.accessibilityElementsHidden, BOOL) RCT_REMAP_VIEW_PROPERTY(accessibilityIgnoresInvertColors, reactAccessibilityElement.shouldAccessibilityIgnoresInvertColors, BOOL) -RCT_REMAP_VIEW_PROPERTY(onAccessibilityAction, reactAccessibilityElement.onAccessibilityAction, RCTDirectEventBlock) -#else // [TODO(macOS ISS#2323203) -RCT_REMAP_VIEW_PROPERTY(accessibilityHint, reactAccessibilityElement.accessibilityHelp, NSString) #endif // ]TODO(macOS ISS#2323203) +RCT_REMAP_VIEW_PROPERTY(onAccessibilityAction, reactAccessibilityElement.onAccessibilityAction, RCTDirectEventBlock) RCT_REMAP_VIEW_PROPERTY(onAccessibilityTap, reactAccessibilityElement.onAccessibilityTap, RCTDirectEventBlock) #if !TARGET_OS_OSX // TODO(macOS ISS#2323203) RCT_REMAP_VIEW_PROPERTY(onMagicTap, reactAccessibilityElement.onMagicTap, RCTDirectEventBlock) -#else // [TODO(macOS ISS#2323203) +#else // [TODO(macOS ISS#2323203): accessibilityTraits is gone in react-native and deprecated in react-native-macos, use accessibilityRole instead RCT_CUSTOM_VIEW_PROPERTY(accessibilityTraits, NSString, RCTView) { if (json) { @@ -214,7 +217,7 @@ RCT_CUSTOM_VIEW_PROPERTY(accessibilityRole, UIAccessibilityTraits, RCTView) view.reactAccessibilityElement.accessibilityTraits |= maskedTraits; } else { NSString *role = json ? [RCTConvert NSString:json] : @""; - view.reactAccessibilityElement.accessibilityRole = role; + view.reactAccessibilityElement.accessibilityRoleInternal = role; // TODO(OSS Candidate ISS#2710739): renamed prop so it doesn't conflict with -[NSAccessibility accessibilityRole]. } #else // [TODO(macOS ISS#2323203) if (json) { @@ -227,7 +230,6 @@ RCT_CUSTOM_VIEW_PROPERTY(accessibilityRole, UIAccessibilityTraits, RCTView) RCT_CUSTOM_VIEW_PROPERTY(accessibilityState, NSDictionary, RCTView) { -#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) NSDictionary *state = json ? [RCTConvert NSDictionary:json] : nil; NSMutableDictionary *newState = [[NSMutableDictionary alloc] init]; @@ -235,6 +237,7 @@ RCT_CUSTOM_VIEW_PROPERTY(accessibilityState, NSDictionary, RCTView) return; } +#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) const UIAccessibilityTraits AccessibilityStatesMask = UIAccessibilityTraitNotEnabled | UIAccessibilityTraitSelected; view.reactAccessibilityElement.accessibilityTraits = view.reactAccessibilityElement.accessibilityTraits & ~AccessibilityStatesMask; @@ -251,12 +254,20 @@ RCT_CUSTOM_VIEW_PROPERTY(accessibilityState, NSDictionary, RCTView) newState[s] = val; } } +#else // [TODO(macOS ISS#2323203) + for (NSString *s in state) { + id val = [state objectForKey:s]; + if (val == nil) { + continue; + } + newState[s] = val; + } +#endif // ]TODO(macOS ISS#2323203) if (newState.count > 0) { view.reactAccessibilityElement.accessibilityState = newState; } else { view.reactAccessibilityElement.accessibilityState = nil; } -#endif // TODO(macOS ISS#2323203) } RCT_CUSTOM_VIEW_PROPERTY(nativeID, NSString *, RCTView) diff --git a/React/Views/UIView+React.h b/React/Views/UIView+React.h index 1e6e626976..6c2db1a4e7 100644 --- a/React/Views/UIView+React.h +++ b/React/Views/UIView+React.h @@ -118,7 +118,7 @@ /** * Accessibility properties */ -@property (nonatomic, copy) NSString *accessibilityRole; +@property (nonatomic, copy) NSString *accessibilityRoleInternal; // TODO(OSS Candidate ISS#2710739): renamed so it doesn't conflict with -[NSAccessibility accessibilityRole]. @property (nonatomic, copy) NSDictionary *accessibilityState; @property (nonatomic, copy) NSArray *accessibilityActions; @property (nonatomic, copy) NSDictionary *accessibilityValueInternal; diff --git a/React/Views/UIView+React.m b/React/Views/UIView+React.m index 8d9e235482..12af79cac2 100644 --- a/React/Views/UIView+React.m +++ b/React/Views/UIView+React.m @@ -351,17 +351,15 @@ objc_setAssociatedObject(self, @selector(accessibilityActions), accessibilityActions, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -#if !TARGET_OS_OSX // TODO(macOS ISS#2323203) -- (NSString *)accessibilityRole +- (NSString *)accessibilityRoleInternal // TODO(OSS Candidate ISS#2710739): renamed so it doesn't conflict with -[NSAccessibility accessibilityRole]. { return objc_getAssociatedObject(self, _cmd); } -- (void)setAccessibilityRole:(NSString *)accessibilityRole +- (void)setAccessibilityRoleInternal:(NSString *)accessibilityRole // TODO(OSS Candidate ISS#2710739): renamed so it doesn't conflict with -[NSAccessibility setAccessibilityRole]. { - objc_setAssociatedObject(self, @selector(accessibilityRole), accessibilityRole, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + objc_setAssociatedObject(self, @selector(accessibilityRoleInternal), accessibilityRole, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -#endif // TODO(macOS ISS#2323203) - (NSDictionary *)accessibilityState { diff --git a/scripts/bump-oss-version.js b/scripts/bump-oss-version.js index 7b8af9a97e..30a3bc5084 100755 --- a/scripts/bump-oss-version.js +++ b/scripts/bump-oss-version.js @@ -28,14 +28,22 @@ let argv = yargs.option('r', { alias: 'nightly', type: 'boolean', default: false, +}).option('t', { + alias: 'testing', + type: 'boolean', + default: false, }).argv; const nightlyBuild = argv.nightly; +const testingBuild = argv.testing; let version, branch; if (nightlyBuild) { const currentCommit = exec('git rev-parse HEAD', {silent: true}).stdout.trim(); version = `0.0.0-${currentCommit.slice(0, 9)}`; +} else if (testingBuild) { + const currentCommit = exec('git rev-parse HEAD', {silent: true}).stdout.trim(); + version = `1000.0.0-${currentCommit.slice(0, 9)}`; } else { // Check we are in release branch, e.g. 0.33-stable branch = exec('git symbolic-ref --short HEAD', { @@ -151,7 +159,7 @@ let numberOfChangedLinesWithNewVersion = exec( // Release builds should commit the version bumps, and create tags. // Nightly builds do not need to do that. -if (!nightlyBuild) { +if (!nightlyBuild && !testingBuild) { if (+numberOfChangedLinesWithNewVersion !== 3) { echo( 'Failed to update all the files. package.json and gradle.properties must have versions in them',