fix: refactor to only use accessibility when actually used

This commit is contained in:
Martin Guillon
2021-10-02 14:04:40 +02:00
parent be5514beb0
commit 709c4bf04e
9 changed files with 112 additions and 110 deletions

View File

@ -4,264 +4,264 @@ export enum AccessibilityTrait {
/**
* The element allows direct touch interaction for VoiceOver users.
*/
AllowsDirectInteraction = 'allowsDirectInteraction',
AllowsDirectInteraction,
/**
* The element should cause an automatic page turn when VoiceOver finishes reading the text within it.
* Note: Requires custom view with accessibilityScroll(...)
*/
CausesPageTurn = 'pageTurn',
CausesPageTurn,
/**
* The element is not enabled and does not respond to user interaction.
*/
NotEnabled = 'disabled',
NotEnabled,
/**
* The element is currently selected.
*/
Selected = 'selected',
Selected,
/**
* The element frequently updates its label or value.
*/
UpdatesFrequently = 'frequentUpdates',
UpdatesFrequently,
}
export enum AccessibilityRole {
/**
* The element allows continuous adjustment through a range of values.
*/
Adjustable = 'adjustable',
Adjustable,
/**
* The element should be treated as a button.
*/
Button = 'button',
Button,
/**
* The element behaves like a Checkbox
*/
Checkbox = 'checkbox',
Checkbox,
/**
* The element is a header that divides content into sections, such as the title of a navigation bar.
*/
Header = 'header',
Header,
/**
* The element should be treated as an image.
*/
Image = 'image',
Image,
/**
* The element should be treated as a image button.
*/
ImageButton = 'imageButton',
ImageButton,
/**
* The element behaves as a keyboard key.
*/
KeyboardKey = 'keyboardKey',
KeyboardKey,
/**
* The element should be treated as a link.
*/
Link = 'link',
Link,
/**
* The element has no traits.
*/
None = 'none',
None,
/**
* The element plays its own sound when activated.
*/
PlaysSound = 'plays',
PlaysSound,
/**
* The element behaves like a ProgressBar
*/
ProgressBar = 'progressBar',
ProgressBar,
/**
* The element behaves like a RadioButton
*/
RadioButton = 'radioButton',
RadioButton,
/**
* The element should be treated as a search field.
*/
Search = 'search',
Search,
/**
* The element behaves like a SpinButton
*/
SpinButton = 'spinButton',
SpinButton,
/**
* The element starts a media session when it is activated.
*/
StartsMediaSession = 'startsMedia',
StartsMediaSession,
/**
* The element should be treated as static text that cannot change.
*/
StaticText = 'text',
StaticText,
/**
* The element provides summary information when the application starts.
*/
Summary = 'summary',
Summary,
/**
* The element behaves like a switch
*/
Switch = 'switch',
Switch,
}
export enum AccessibilityState {
Selected = 'selected',
Checked = 'checked',
Unchecked = 'unchecked',
Disabled = 'disabled',
Selected,
Checked,
Unchecked,
Disabled,
}
export enum AccessibilityLiveRegion {
None = 'none',
Polite = 'polite',
Assertive = 'assertive',
None,
Polite,
Assertive,
}
export enum IOSPostAccessibilityNotificationType {
Announcement = 'announcement',
Screen = 'screen',
Layout = 'layout',
Announcement,
Screen,
Layout,
}
export enum AndroidAccessibilityEvent {
/**
* Invalid selection/focus position.
*/
INVALID_POSITION = 'invalid_position',
INVALID_POSITION,
/**
* Maximum length of the text fields.
*/
MAX_TEXT_LENGTH = 'max_text_length',
MAX_TEXT_LENGTH,
/**
* Represents the event of clicking on a android.view.View like android.widget.Button, android.widget.CompoundButton, etc.
*/
VIEW_CLICKED = 'view_clicked',
VIEW_CLICKED,
/**
* Represents the event of long clicking on a android.view.View like android.widget.Button, android.widget.CompoundButton, etc.
*/
VIEW_LONG_CLICKED = 'view_long_clicked',
VIEW_LONG_CLICKED,
/**
* Represents the event of selecting an item usually in the context of an android.widget.AdapterView.
*/
VIEW_SELECTED = 'view_selected',
VIEW_SELECTED,
/**
* Represents the event of setting input focus of a android.view.View.
*/
VIEW_FOCUSED = 'view_focused',
VIEW_FOCUSED,
/**
* Represents the event of changing the text of an android.widget.EditText.
*/
VIEW_TEXT_CHANGED = 'view_text_changed',
VIEW_TEXT_CHANGED,
/**
* Represents the event of opening a android.widget.PopupWindow, android.view.Menu, android.app.Dialog, etc.
*/
WINDOW_STATE_CHANGED = 'window_state_changed',
WINDOW_STATE_CHANGED,
/**
* Represents the event showing a android.app.Notification.
*/
NOTIFICATION_STATE_CHANGED = 'notification_state_changed',
NOTIFICATION_STATE_CHANGED,
/**
* Represents the event of a hover enter over a android.view.View.
*/
VIEW_HOVER_ENTER = 'view_hover_enter',
VIEW_HOVER_ENTER,
/**
* Represents the event of a hover exit over a android.view.View.
*/
VIEW_HOVER_EXIT = 'view_hover_exit',
VIEW_HOVER_EXIT,
/**
* Represents the event of starting a touch exploration gesture.
*/
TOUCH_EXPLORATION_GESTURE_START = 'touch_exploration_gesture_start',
TOUCH_EXPLORATION_GESTURE_START,
/**
* Represents the event of ending a touch exploration gesture.
*/
TOUCH_EXPLORATION_GESTURE_END = 'touch_exploration_gesture_end',
TOUCH_EXPLORATION_GESTURE_END,
/**
* Represents the event of changing the content of a window and more specifically the sub-tree rooted at the event's source.
*/
WINDOW_CONTENT_CHANGED = 'window_content_changed',
WINDOW_CONTENT_CHANGED,
/**
* Represents the event of scrolling a view.
*/
VIEW_SCROLLED = 'view_scrolled',
VIEW_SCROLLED,
/**
* Represents the event of changing the selection in an android.widget.EditText.
*/
VIEW_TEXT_SELECTION_CHANGED = 'view_text_selection_changed',
VIEW_TEXT_SELECTION_CHANGED,
/**
* Represents the event of an application making an announcement.
*/
ANNOUNCEMENT = 'announcement',
ANNOUNCEMENT,
/**
* Represents the event of gaining accessibility focus.
*/
VIEW_ACCESSIBILITY_FOCUSED = 'view_accessibility_focused',
VIEW_ACCESSIBILITY_FOCUSED,
/**
* Represents the event of clearing accessibility focus.
*/
VIEW_ACCESSIBILITY_FOCUS_CLEARED = 'view_accessibility_focus_cleared',
VIEW_ACCESSIBILITY_FOCUS_CLEARED,
/**
* Represents the event of traversing the text of a view at a given movement granularity.
*/
VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY = 'view_text_traversed_at_movement_granularity',
VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
/**
* Represents the event of beginning gesture detection.
*/
GESTURE_DETECTION_START = 'gesture_detection_start',
GESTURE_DETECTION_START,
/**
* Represents the event of ending gesture detection.
*/
GESTURE_DETECTION_END = 'gesture_detection_end',
GESTURE_DETECTION_END,
/**
* Represents the event of the user starting to touch the screen.
*/
TOUCH_INTERACTION_START = 'touch_interaction_start',
TOUCH_INTERACTION_START,
/**
* Represents the event of the user ending to touch the screen.
*/
TOUCH_INTERACTION_END = 'touch_interaction_end',
TOUCH_INTERACTION_END,
/**
* Mask for AccessibilityEvent all types.
*/
ALL_MASK = 'all',
ALL_MASK,
}
export interface AccessibilityEventPerformEscape extends EventData {

View File

@ -1,8 +1,10 @@
import { initAccessibilityFontScale } from 'accessibility';
import * as Application from '../application';
import { Trace } from '../trace';
import type { View } from '../ui/core/view';
import { GestureTypes } from '../ui/gestures';
import { notifyAccessibilityFocusState } from './accessibility-common';
import { initAccessibilityCssHelper } from './accessibility-css-helper';
import { getAndroidAccessibilityManager } from './accessibility-service';
import { AccessibilityRole, AccessibilityState, AndroidAccessibilityEvent } from './accessibility-types';
@ -10,7 +12,7 @@ export * from './accessibility-common';
export * from './accessibility-types';
export * from './font-scale';
let clickableRolesMap = new Set<string>();
let clickableRolesMap = new Set<AccessibilityRole>();
let lastFocusedView: WeakRef<Partial<View>>;
function accessibilityEventHelper(view: Partial<View>, eventType: number) {
@ -105,7 +107,7 @@ let TNSAccessibilityDelegate: android.view.View.androidviewViewAccessibilityDele
const androidViewToTNSView = new WeakMap<android.view.View, WeakRef<Partial<View>>>();
let accessibilityEventMap: Map<AndroidAccessibilityEvent, number>;
let accessibilityEventTypeMap: Map<number, string>;
let accessibilityEventTypeMap: Map<number, AndroidAccessibilityEvent>;
function ensureNativeClasses() {
if (TNSAccessibilityDelegate) {
@ -130,7 +132,7 @@ function ensureNativeClasses() {
[AccessibilityRole.ProgressBar, android.widget.ProgressBar.class.getName()],
]);
clickableRolesMap = new Set<string>([AccessibilityRole.Button, AccessibilityRole.ImageButton]);
clickableRolesMap = new Set<AccessibilityRole>([AccessibilityRole.Button, AccessibilityRole.ImageButton]);
const ignoreRoleTypesForTrace = new Set([AccessibilityRole.Header, AccessibilityRole.Link, AccessibilityRole.None, AccessibilityRole.Summary]);
@ -437,9 +439,9 @@ export function isAccessibilityServiceEnabled(): boolean {
return accessibilityServiceEnabled;
}
export function setupAccessibleView(view: Partial<View>): void {
updateAccessibilityProperties(view);
}
// export function setupAccessibleView(view: Partial<View>): void {
// updateAccessibilityProperties(view);
// }
export function updateAccessibilityProperties(view: Partial<View>): void {
if (!view.nativeViewProtected) {
@ -537,10 +539,17 @@ export function updateContentDescription(view: View, forceUpdate?: boolean): str
return applyContentDescription(view, forceUpdate);
}
let started = false;
function setAccessibilityDelegate(view: Partial<View>): void {
if (!view.nativeViewProtected) {
return;
}
if (!started) {
started = true;
initAccessibilityCssHelper();
initAccessibilityFontScale();
}
ensureNativeClasses();

View File

@ -1,6 +1,8 @@
import { initAccessibilityFontScale } from 'accessibility';
import * as Application from '../application';
import type { View } from '../ui/core/view';
import { notifyAccessibilityFocusState } from './accessibility-common';
import { initAccessibilityCssHelper } from './accessibility-css-helper';
import { AccessibilityLiveRegion, AccessibilityRole, AccessibilityState, AccessibilityTrait } from './accessibility-types';
export * from './accessibility-common';
@ -35,7 +37,7 @@ function inputArrayToBitMask(values: string | string[], map: Map<string, number>
);
}
let AccessibilityTraitsMap: Map<string, number>;
let AccessibilityTraitsMap: Map<number, number>;
let RoleTypeMap: Map<AccessibilityRole, number>;
let nativeFocusedNotificationObserver;
@ -120,27 +122,32 @@ function ensureNativeClasses() {
});
}
export function setupAccessibleView(view: View): void {
const uiView = view.nativeViewProtected as UIView;
if (!uiView) {
return;
}
// export function setupAccessibleView(view: View): void {
// const uiView = view.nativeViewProtected as UIView;
// if (!uiView) {
// return;
// }
/**
* We need to map back from the UIView to the NativeScript View.
*
* We do that by setting the uiView's tag to the View's domId.
* This way we can do reverse lookup.
*/
uiView.tag = view._domId;
}
// /**
// * We need to map back from the UIView to the NativeScript View.
// *
// * We do that by setting the uiView's tag to the View's domId.
// * This way we can do reverse lookup.
// */
// uiView.tag = view._domId;
// }
let started = false;
export function updateAccessibilityProperties(view: View): void {
const uiView = view.nativeViewProtected as UIView;
if (!uiView) {
return;
}
if (!started) {
started = true;
initAccessibilityCssHelper();
initAccessibilityFontScale();
}
ensureNativeClasses();
const accessibilityRole = view.accessibilityRole;

View File

@ -14,8 +14,6 @@ import { NavigationEntry, AndroidActivityCallbacks } from '../ui/frame/frame-int
import { Observable } from '../data/observable';
import { profile } from '../profiling';
import { initAccessibilityCssHelper } from '../accessibility/accessibility-css-helper';
import { initAccessibilityFontScale } from '../accessibility/font-scale';
const ActivityCreated = 'activityCreated';
const ActivityDestroyed = 'activityDestroyed';
@ -177,9 +175,6 @@ export function run(entry?: NavigationEntry | string) {
const nativeApp = getNativeApplication();
androidApp.init(nativeApp);
}
initAccessibilityCssHelper();
initAccessibilityFontScale();
}
export function addCss(cssText: string, attributeScoped?: boolean): void {

View File

@ -18,8 +18,6 @@ import { IOSHelper } from '../ui/core/view/view-helper';
import { Device } from '../platform';
import { profile } from '../profiling';
import { iOSNativeHelper } from '../utils';
import { initAccessibilityCssHelper } from '../accessibility/accessibility-css-helper';
import { initAccessibilityFontScale } from '../accessibility/font-scale';
const IOS_PLATFORM = 'ios';
@ -437,9 +435,6 @@ export function run(entry?: string | NavigationEntry) {
}
}
}
initAccessibilityCssHelper();
initAccessibilityFontScale();
}
export function addCss(cssText: string, attributeScoped?: boolean): void {

View File

@ -22,7 +22,7 @@ import { AndroidActivityBackPressedEventData, android as androidApp } from '../.
import { Device } from '../../../platform';
import lazy from '../../../utils/lazy';
import { accessibilityEnabledProperty, accessibilityHiddenProperty, accessibilityHintProperty, accessibilityIdentifierProperty, accessibilityLabelProperty, accessibilityLanguageProperty, accessibilityLiveRegionProperty, accessibilityMediaSessionProperty, accessibilityRoleProperty, accessibilityStateProperty, accessibilityValueProperty } from '../../../accessibility/accessibility-properties';
import { AccessibilityLiveRegion, AccessibilityRole, AndroidAccessibilityEvent, setupAccessibleView, isAccessibilityServiceEnabled, sendAccessibilityEvent, updateAccessibilityProperties, updateContentDescription, AccessibilityState } from '../../../accessibility';
import { AccessibilityLiveRegion, AccessibilityRole, AndroidAccessibilityEvent, isAccessibilityServiceEnabled, sendAccessibilityEvent, updateAccessibilityProperties, updateContentDescription, AccessibilityState } from '../../../accessibility';
import * as Utils from '../../../utils';
import { CSSShadow } from 'ui/styling/css-shadow';
@ -324,12 +324,6 @@ export class View extends ViewCommon {
nativeViewProtected: android.view.View;
constructor() {
super();
this.on(View.loadedEvent, () => setupAccessibleView(this));
}
// TODO: Implement unobserve that detach the touchListener.
_observe(type: GestureTypes, callback: (args: GestureEventData) => void, thisArg?: any): void {
super._observe(type, callback, thisArg);

View File

@ -11,7 +11,7 @@ import { ios as iosBackground, Background } from '../../styling/background';
import { perspectiveProperty, visibilityProperty, opacityProperty, rotateProperty, rotateXProperty, rotateYProperty, scaleXProperty, scaleYProperty, translateXProperty, translateYProperty, zIndexProperty, backgroundInternalProperty, clipPathProperty } from '../../styling/style-properties';
import { profile } from '../../../profiling';
import { accessibilityEnabledProperty, accessibilityHiddenProperty, accessibilityHintProperty, accessibilityIdentifierProperty, accessibilityLabelProperty, accessibilityLanguageProperty, accessibilityLiveRegionProperty, accessibilityMediaSessionProperty, accessibilityRoleProperty, accessibilityStateProperty, accessibilityValueProperty, accessibilityIgnoresInvertColorsProperty } from '../../../accessibility/accessibility-properties';
import { setupAccessibleView, IOSPostAccessibilityNotificationType, isAccessibilityServiceEnabled, updateAccessibilityProperties, AccessibilityEventOptions, AccessibilityRole, AccessibilityState } from '../../../accessibility';
import { IOSPostAccessibilityNotificationType, isAccessibilityServiceEnabled, updateAccessibilityProperties, AccessibilityEventOptions, AccessibilityRole, AccessibilityState } from '../../../accessibility';
import { CoreTypes } from '../../../core-types';
export * from './view-common';
@ -56,11 +56,16 @@ export class View extends ViewCommon implements ViewDefinition {
get isLayoutRequested(): boolean {
return (this._privateFlags & PFLAG_FORCE_LAYOUT) === PFLAG_FORCE_LAYOUT;
}
constructor() {
super();
this.once(View.loadedEvent, () => setupAccessibleView(this));
initNativeView() {
super.initNativeView()
const nativeView = this.nativeViewProtected;
/**
* We need to map back from the UIView to the NativeScript View for accessibility.
*
* We do that by setting the uiView's tag to the View's domId.
* This way we can do reverse lookup.
*/
nativeView.tag = this._domId;
}
requestlayoutIfNeeded() {
@ -785,7 +790,7 @@ export class View extends ViewCommon implements ViewDefinition {
args = msg;
}
switch (options.iosNotificationType) {
switch (options.iosNotificationType as IOSPostAccessibilityNotificationType) {
case IOSPostAccessibilityNotificationType.Announcement: {
notification = UIAccessibilityAnnouncementNotification;
break;

View File

@ -24,7 +24,7 @@ import { LinearGradient } from '../../styling/linear-gradient';
import * as am from '../../animation';
import { AccessibilityEventOptions, AccessibilityLiveRegion, AccessibilityRole, AccessibilityState, AccessibilityTrait } from '../../../accessibility/accessibility-types';
import { accessibilityHintProperty, accessibilityIdentifierProperty, accessibilityLabelProperty, accessibilityValueProperty, accessibilityIgnoresInvertColorsProperty } from '../../../accessibility/accessibility-properties';
import { accessibilityBlurEvent, accessibilityFocusChangedEvent, accessibilityFocusEvent, accessibilityPerformEscapeEvent, getCurrentFontScale } from '../../../accessibility';
import { getCurrentFontScale } from '../../../accessibility';
import { CSSShadow } from '../../styling/css-shadow';
// helpers (these are okay re-exported here)
@ -72,10 +72,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
public static shownModallyEvent = 'shownModally';
public static showingModallyEvent = 'showingModally';
public static closingModallyEvent = 'closingModally';
public static accessibilityBlurEvent = accessibilityBlurEvent;
public static accessibilityFocusEvent = accessibilityFocusEvent;
public static accessibilityFocusChangedEvent = accessibilityFocusChangedEvent;
public static accessibilityPerformEscapeEvent = accessibilityPerformEscapeEvent;
public accessibilityIdentifier: string;
public accessibilityLabel: string;

View File

@ -150,7 +150,8 @@ export class Page extends PageBase {
return;
}
this.actionBar.accessibilityScreenChanged();
if (this.hasActionBar) {
this.actionBar.accessibilityScreenChanged();
}
}
}