Skip to content

Commit

Permalink
retrieve child node description
Browse files Browse the repository at this point in the history
AccessibilityNodeInfoCompat getRoleDescription returns null with custom
roles, for this reason a custom logic needs to be implemented to
retrieve custom role descriptions

Previously child node description were never announced as allways
returning null

The commit includes also an examples of test which includes a TextInput
non accessible child component. The issue is that the TextInput is
allays accessible with talkback so I will need to understand how to handle
this scenario
  • Loading branch information
fabOnReact committed May 31, 2022
1 parent abed89e commit 388911e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,15 @@ public static AccessibilityRole fromValue(@Nullable String value) {
}
throw new IllegalArgumentException("Invalid accessibility role value: " + value);
}

public static @Nullable String fromAnyValue(@Nullable String value) {
for (AccessibilityRole role : AccessibilityRole.values()) {
if (getValue(role).equalsIgnoreCase(value)) {
return role.toString();
}
}
return null;
}
}

private final HashMap<Integer, String> mAccessibilityActionsMap;
Expand Down Expand Up @@ -304,8 +313,11 @@ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCo
if (testId != null) {
info.setViewIdResourceName(testId);
}
boolean missingTextOrDescription =
info.getText() == null && info.getContentDescription() == null;
// need to check that string length is not == 0
boolean missingContentDescription = TextUtils.isEmpty(info.getContentDescription());
boolean missingText = TextUtils.isEmpty(info.getText());
boolean missingTextOrDescription = missingContentDescription && missingText;
// add check on placeholder
boolean hasContentToAnnounce =
accessibilityActions != null
|| accessibilityState != null
Expand Down Expand Up @@ -963,6 +975,20 @@ private static void addStateSegments(
}
}

public static @Nullable String getRoleDescription(AccessibilityNodeInfoCompat node) {
CharSequence role = node.getRoleDescription();
String roleDescription;

if (role == null || role == "") {
roleDescription =
ReactAccessibilityDelegate.AccessibilityRole.fromAnyValue((String) node.getClassName());
} else {
roleDescription = role.toString();
}

return roleDescription;
}

/**
* Creates the text that Google's TalkBack screen reader will read aloud for a given {@link View}.
* This may be any combination of the {@link View}'s {@code text}, {@code contentDescription}, and
Expand Down Expand Up @@ -994,7 +1020,7 @@ public static CharSequence getTalkbackDescription(

final boolean hasNodeText = !TextUtils.isEmpty(nodeText);
final boolean isEditText = view instanceof EditText;
CharSequence roleDescription = node.getRoleDescription();
String roleDescription = getRoleDescription(node);
// The original flipper implementation would check isActionableForAccessibility
// The check was removed for this reason https://bit.ly/3wPnmPE
boolean disabled = !node.isEnabled();
Expand Down Expand Up @@ -1037,8 +1063,7 @@ public static CharSequence getTalkbackDescription(

// role
if (roleDescription != null) {
String roleString = roleDescription.toString();
talkbackSegments.append(roleString + delimiter);
talkbackSegments.append(roleDescription + delimiter);
}

// disabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,16 +281,21 @@ class AccessibilityExample extends React.Component<{}> {
</RNTesterBlock>

<RNTesterBlock title="TouchableNativeFeedback with non-accessible child Texts, one of them is an EditText">
<TouchableNativeFeedback
<View
accessible={true}
importantForAccessibility="yes"
accessibilityRole="button">
<TextInput
accessible={false}
style={styles.default}
placeholder="this is the placeholder"
/>
</TouchableNativeFeedback>
<View>
<Text accessible={false}>Text number 1</Text>
<TouchableNativeFeedback accessible={false} focusable={false}>
<TextInput
accessible={false}
focusable={false}
style={styles.default}
/>
</TouchableNativeFeedback>
</View>
</View>
</RNTesterBlock>
</View>
);
Expand Down

0 comments on commit 388911e

Please sign in to comment.