From 4933f5075ad4de09b7b0225e46551f715493dc0b Mon Sep 17 00:00:00 2001 From: Michael Jordan Date: Wed, 13 Apr 2016 18:24:42 -0400 Subject: [PATCH] Add additional iOS accessibility features Adds support for detecting: - Bold Text - Darker System Colors - Grayscale - Reduce Motion - Reduce Transparency - Speak Screen - Speak Selection - Switch Control Running --- README.md | 542 ++++++++++++++++++++---- src/ios/CDVMobileAccessibility.h | 33 +- src/ios/CDVMobileAccessibility.m | 182 ++++++-- www/MobileAccessibilityNotifications.js | 7 + www/mobile-accessibility.js | 143 ++++++- 5 files changed, 772 insertions(+), 135 deletions(-) diff --git a/README.md b/README.md index 1117b00..dc8b25d 100644 --- a/README.md +++ b/README.md @@ -168,10 +168,37 @@ If TalkBack is running but ChromeVox is not active, this method is useful to ale - Amazon Fire OS - Android +-------------------------------------------------------- +#### MobileAccessibility.isBoldTextEnabled(callback) + +Makes an asynchronous call to native `MobileAccessibility` to determine if Bold Text is enabled. + +##### Parameters + +- __callback__ (Function) A callback method to receive the boolean result asynchronously from the native `MobileAccessibility` plugin. + +##### Usage + +```javascript + function isBoldTextEnabledCallback(boolean) { + if (boolean) { + console.log("Bold Text: ON"); + // Do something to improve the behavior of the application while Bold Text is enabled. + } else { + console.log("Bold Text: OFF"); + } + } + + MobileAccessibility.isBoldTextEnabled(isBoldTextEnabledCallback); +``` + +##### Supported Platforms + +- iOS + ------------------------------------------------------------ #### MobileAccessibility.isClosedCaptioningEnabled(callback) - Makes an asynchronous call to native `MobileAccessibility` to determine if system-level closed captioning is enabled on the device. ##### Parameters @@ -200,8 +227,63 @@ Makes an asynchronous call to native `MobileAccessibility` to determine if syste - iOS -------------------------------------------------------- -#### MobileAccessibility.isGuidedAccessEnabled(callback) +#### MobileAccessibility.isDarkerSystemColorsEnabled(callback) +Makes an asynchronous call to native `MobileAccessibility` to determine if Darker System Colors is enabled. + +##### Parameters + +- __callback__ (Function) A callback method to receive the boolean result asynchronously from the native `MobileAccessibility` plugin. + +##### Usage + +```javascript + function isDarkerSystemColorsEnabledCallback(boolean) { + if (boolean) { + console.log("Darker System Colors: ON"); + // Do something to improve the behavior of the application while Darker System Colors is enabled. + } else { + console.log("Darker System Colors: OFF"); + } + } + + MobileAccessibility.isDarkerSystemColorsEnabled(isDarkerSystemColorsEnabledCallback); +``` + +##### Supported Platforms + +- iOS + +-------------------------------------------------------- +#### MobileAccessibility.isGrayscaleEnabled(callback) + +Makes an asynchronous call to native `MobileAccessibility` to determine if Grayscale is enabled. + +##### Parameters + +- __callback__ (Function) A callback method to receive the boolean result asynchronously from the native `MobileAccessibility` plugin. + +##### Usage + +```javascript + function isGrayscaleEnabledCallback(boolean) { + if (boolean) { + console.log("Grayscale: ON"); + // Do something to improve the behavior of the application while Grayscale is enabled. + } else { + console.log("Grayscale: OFF"); + } + } + + MobileAccessibility.isGrayscaleEnabled(isGrayscaleEnabledCallback); +``` + +##### Supported Platforms + +- iOS + +-------------------------------------------------------- +#### MobileAccessibility.isGuidedAccessEnabled(callback) Makes an asynchronous call to native `MobileAccessibility` to determine if Guided Access is enabled. @@ -231,7 +313,6 @@ Makes an asynchronous call to native `MobileAccessibility` to determine if Guide -------------------------------------------------------- #### MobileAccessibility.isInvertColorsEnabled(callback) - Makes an asynchronous call to native `MobileAccessibility` to determine if the display colors have been inverted. ##### Parameters @@ -288,8 +369,7 @@ Makes an asynchronous call to native `MobileAccessibility` to determine if mono ---------------------------------------------------- #### MobileAccessibility.isReduceMotionEnabled(callback) - -An iOS-specific proxy for the `MobileAccessibility.UIAccessibilityIsReduceMotionEnabled` method. +Makes an asynchronous call to native `MobileAccessibility` to determine if reduce motion is enabled. ##### Parameters @@ -314,6 +394,118 @@ An iOS-specific proxy for the `MobileAccessibility.UIAccessibilityIsReduceMotion - iOS +---------------------------------------------------- +#### MobileAccessibility.isReduceTransparencyEnabled(callback) + +Makes an asynchronous call to native `MobileAccessibility` to determine if reduce transparency is enabled. + +##### Parameters + +- __callback__ (Function) A callback method to receive the boolean result asynchronously from the native `MobileAccessibility` plugin. + +##### Usage + +```javascript + function isReduceTransparencyEnabledCallback(boolean) { + if (boolean) { + console.log("Reduce Transparency: ON"); + // Do something to improve the behavior of the application when reduce transparency is enabled. + } else { + console.log("Reduce Transparency: OFF"); + } + } + + MobileAccessibility.isReduceTransparencyEnabled(isReduceTransparencyEnabledCallback); +``` + +##### Supported Platforms + +- iOS + +---------------------------------------------------- +#### MobileAccessibility.isSpeakScreenEnabled(callback) + +Makes an asynchronous call to native `MobileAccessibility` to determine if speak screen is enabled. + +##### Parameters + +- __callback__ (Function) A callback method to receive the boolean result asynchronously from the native `MobileAccessibility` plugin. + +##### Usage + +```javascript + function isSpeakScreenEnabledCallback(boolean) { + if (boolean) { + console.log("Speak Screen: ON"); + // Do something to improve the behavior of the application when Speak Screen is enabled. + } else { + console.log("Speak Screen: OFF"); + } + } + + MobileAccessibility.isSpeakScreenEnabled(isSpeakScreenEnabledCallback); +``` + +##### Supported Platforms + +- iOS + +---------------------------------------------------- +#### MobileAccessibility.isSpeakSelectionEnabled(callback) + +Makes an asynchronous call to native `MobileAccessibility` to determine if speak selection is enabled. + +##### Parameters + +- __callback__ (Function) A callback method to receive the boolean result asynchronously from the native `MobileAccessibility` plugin. + +##### Usage + +```javascript + function isSpeakSelectionEnabledCallback(boolean) { + if (boolean) { + console.log("Speak Selection: ON"); + // Do something to improve the behavior of the application when Speak Selection is enabled. + } else { + console.log("Speak Selection: OFF"); + } + } + + MobileAccessibility.isSpeakSelectionEnabled(isSpeakSelectionEnabledCallback); +``` + +##### Supported Platforms + +- iOS + +---------------------------------------------------- +#### MobileAccessibility.isSwitchControlRunning(callback) + +Makes an asynchronous call to native `MobileAccessibility` to determine if switch control is running. + +##### Parameters + +- __callback__ (Function) A callback method to receive the boolean result asynchronously from the native `MobileAccessibility` plugin. + +##### Usage + +```javascript + function isSwitchControlRunningCallback(boolean) { + if (boolean) { + console.log("Switch Control: ON"); + // Do something to improve the behavior of the application when Switch Control is running. + } else { + console.log("Switch Control: OFF"); + } + } + + MobileAccessibility.isSwitchControlRunning(isSwitchControlRunningCallback); +``` + +##### Supported Platforms + +- iOS + ------------------------------------------------------------ #### MobileAccessibility.isTouchExplorationEnabled(callback) @@ -528,14 +720,237 @@ Stops speech. The following event constants are for `window` events, to which an application can listen for notification of changes in the status of the accessibility features on the device. -- MobileAccessibilityNotifications.SCREEN_READER_STATUS_CHANGED +- MobileAccessibilityNotifications.BOLD_TEXT_STATUS_CHANGED - MobileAccessibilityNotifications.CLOSED_CAPTIONING_STATUS_CHANGED +- MobileAccessibilityNotifications.DARKER_SYSTEM_COLORS_STATUS_CHANGED +- MobileAccessibilityNotifications.GRAYSCALE_STATUS_CHANGED - MobileAccessibilityNotifications.GUIDED_ACCESS_STATUS_CHANGED - MobileAccessibilityNotifications.INVERT_COLORS_STATUS_CHANGED - MobileAccessibilityNotifications.MONO_AUDIO_STATUS_CHANGED - MobileAccessibilityNotifications.REDUCE_MOTION_STATUS_CHANGED +- MobileAccessibilityNotifications.REDUCE_TRANSPARENCY_STATUS_CHANGED +- MobileAccessibilityNotifications.SCREEN_READER_STATUS_CHANGED +- MobileAccessibilityNotifications.SPEAK_SCREEN_STATUS_CHANGED +- MobileAccessibilityNotifications.SPEAK_SELECTION_STATUS_CHANGED +- MobileAccessibilityNotifications.SWITCH_CONTROL_STATUS_CHANGED - MobileAccessibilityNotifications.TOUCH_EXPLORATION_STATUS_CHANGED +---------------------------------------------------------------------------------------------- +#### MobileAccessibilityNotifications.BOLD_TEXT_STATUS_CHANGED (boldtextstatuschanged) + +The event fires when Bold Text has been enabled on an iOS device. +The event returns an object, `info`, with the current status of accessibility features on the device. +If Bold Text is active, `info.isBoldTextEnabled` will equal `true`. + +```javascript + // Define a persistent callback method to handle the event + function onBoldTextStatusChanged(info) { + if (info && typeof info.isBoldTextEnabled !== "undefined") { + if (info.isBoldTextEnabled) { + console.log("Bold Text: ON"); + // Do something to improve the behavior of the application while Bold Text is enabled. + } else { + console.log("Bold Text: OFF"); + } + } + } + + // Register the callback method to handle the event + window.addEventListener(MobileAccessibilityNotifications.BOLD_TEXT_STATUS_CHANGED, onBoldTextStatusChanged, false); +``` + +------------------------------------------------------------------------------------------------------ +#### MobileAccessibilityNotifications.CLOSED_CAPTIONING_STATUS_CHANGED (closedcaptioningstatuschanged) + +The event fires when system-level closed captioning on the device turns on or off. +The event returns an object, `info`, with the current status of accessibility features on the device. +If closed captioning is active, `info.isClosedCaptioningEnabled` will equal `true`. + +```javascript + // Define a persistent callback method to handle the event + function onClosedCaptioningStatusChanged(info) { + if (info && typeof info.isClosedCaptioningEnabled !== "undefined") { + if (info.isClosedCaptioningEnabled) { + console.log("Closed Captioning: ON"); + // Do something to improve the behavior of the application while closed captioning is enabled. + } else { + console.log("Closed Captioning: OFF"); + } + } + } + + // Register the callback method to handle the event + window.addEventListener(MobileAccessibilityNotifications.CLOSED_CAPTIONING_STATUS_CHANGED, onClosedCaptioningStatusChanged, false); +``` + +---------------------------------------------------------------------------------------------- +#### MobileAccessibilityNotifications.DARKER_SYSTEM_COLORS_STATUS_CHANGED (darkersystemcolorsstatuschanged) + +The event fires when Darker System Colors has been enabled on an iOS device. +The event returns an object, `info`, with the current status of accessibility features on the device. +If Darker System Colors is active, `info.isDarkerSystemColorsEnabled` will equal `true`. + +```javascript + // Define a persistent callback method to handle the event + function onDarkerSystemColorsStatusChanged(info) { + if (info && typeof info.isDarkerSystemColorsEnabled !== "undefined") { + if (info.isDarkerSystemColorsEnabled) { + console.log("Darker System Colors: ON"); + // Do something to improve the behavior of the application while Darker System Colors is enabled. + } else { + console.log("Darker System Colors: OFF"); + } + } + } + + // Register the callback method to handle the event + window.addEventListener(MobileAccessibilityNotifications.DARKER_SYSTEM_COLORS_STATUS_CHANGED, onDarkerSystemColorsStatusChanged, false); +``` + +---------------------------------------------------------------------------------------------- +#### MobileAccessibilityNotifications.GRAYSCALE_STATUS_CHANGED (grayscalestatuschanged) + +The event fires when Grayscale has been enabled on an iOS device. +The event returns an object, `info`, with the current status of accessibility features on the device. +If Grayscale is active, `info.isGrayscaleEnabled` will equal `true`. + +```javascript + // Define a persistent callback method to handle the event + function onGrayscaleStatusChanged(info) { + if (info && typeof info.isGrayscaleEnabled !== "undefined") { + if (info.isGrayscaleEnabled) { + console.log("Grayscale: ON"); + // Do something to improve the behavior of the application while Grayscale is enabled. + } else { + console.log("Grayscale: OFF"); + } + } + } + + // Register the callback method to handle the event + window.addEventListener(MobileAccessibilityNotifications.GRAYSCALE_STATUS_CHANGED, onGrayscaleStatusChanged, false); +``` + +---------------------------------------------------------------------------------------------- +#### MobileAccessibilityNotifications.GUIDED_ACCESS_STATUS_CHANGED (guidedaccessstatuschanged) + +The event fires when Guided Access has been enabled on an iOS device. +The event returns an object, `info`, with the current status of accessibility features on the device. +If Guided Access is active, `info.isGuidedAccessEnabled` will equal `true`. + +```javascript + // Define a persistent callback method to handle the event + function onGuidedAccessStatusChanged(info) { + if (info && typeof info.isGuidedAccessEnabled !== "undefined") { + if (info.isGuidedAccessEnabled) { + console.log("Guided Access: ON"); + // Do something to improve the behavior of the application while Guided Access is enabled. + } else { + console.log("Guided Access: OFF"); + } + } + } + + // Register the callback method to handle the event + window.addEventListener(MobileAccessibilityNotifications.GUIDED_ACCESS_STATUS_CHANGED, onGuidedAccessStatusChanged, false); +``` + +---------------------------------------------------------------------------------------------- +#### MobileAccessibilityNotifications.INVERT_COLORS_STATUS_CHANGED (invertcolorsstatuschanged) + +The event fires when Invert Colors has been enabled on an iOS device. +The event returns an object, `info`, with the current status of accessibility features on the device. +If Invert Colors is active, `info.isInvertColorsEnabled` will equal `true`. + +```javascript + // Define a persistent callback method to handle the event + function onInvertColorsStatusChanged(info) { + if (info && typeof info.isInvertColorsEnabled !== "undefined") { + if (info.isInvertColorsEnabled) { + console.log("Invert Colors: ON"); + // Do something to improve the behavior of the application while Invert Colors is enabled. + } else { + console.log("Invert Colors: OFF"); + } + } + } + + // Register the callback method to handle the event + window.addEventListener(MobileAccessibilityNotifications.INVERT_COLORS_STATUS_CHANGED, onInvertColorsStatusChanged, false); +``` + +---------------------------------------------------------------------------------------- +#### MobileAccessibilityNotifications.MONO_AUDIO_STATUS_CHANGED (monoaudiostatuschanged) + +The event fires when Mono Audio has been enabled on an iOS device. +The event returns an object, `info`, with the current status of accessibility features on the device. +If Mono Audio is active, `info.isMonoAudioEnabled` will equal `true`. + +```javascript + // Define a persistent callback method to handle the event + function onMonoAudioStatusChanged(info) { + if (info && typeof info.isMonoAudioEnabled !== "undefined") { + if (info.isMonoAudioEnabled) { + console.log("Mono Audio: ON"); + // Do something to improve the behavior of the application while Mono Audio is enabled. + } else { + console.log("Mono Audio: OFF"); + } + } + } + + // Register the callback method to handle the event + window.addEventListener(MobileAccessibilityNotifications.MONO_AUDIO_STATUS_CHANGED, onMonoAudioStatusChanged, false); +``` + +---------------------------------------------------------------------------------------- +#### MobileAccessibilityNotifications.REDUCE_MOTION_STATUS_CHANGED (reducemotionstatuschanged) + +The event fires when Reduce Motion has been enabled on an iOS device. +The event returns an object, `info`, with the current status of accessibility features on the device. +If Reduce Motion is active, `info.isReduceMotionEnabled` will equal `true`. + +```javascript + // Define a persistent callback method to handle the event + function onReduceMotionStatusChanged(info) { + if (info && typeof info.isReduceMotionEnabled !== "undefined") { + if (info.isReduceMotionEnabled) { + console.log("Reduce Motion: ON"); + // Do something to improve the behavior of the application while Reduce Motion is enabled. + } else { + console.log("Reduce Motion: OFF"); + } + } + } + + // Register the callback method to handle the event + window.addEventListener(MobileAccessibilityNotifications.REDUCE_MOTION_STATUS_CHANGED, onMReduceMotionStatusChanged, false); +``` + +---------------------------------------------------------------------------------------- +#### MobileAccessibilityNotifications.REDUCE_TRANSPARENCY_STATUS_CHANGED (reducetransparencystatuschanged) + +The event fires when Reduce Transparency has been enabled on an iOS device. +The event returns an object, `info`, with the current status of accessibility features on the device. +If Reduce Transparency is active, `info.isReduceTransparencyEnabled` will equal `true`. + +```javascript + // Define a persistent callback method to handle the event + function onReduceTransparencyStatusChanged(info) { + if (info && typeof info.isReduceTransparencyEnabled !== "undefined") { + if (info.isReduceTransparencyEnabled) { + console.log("Reduce Transparency: ON"); + // Do something to improve the behavior of the application while Reduce Transparency is enabled. + } else { + console.log("Reduce Transparency: OFF"); + } + } + } + + // Register the callback method to handle the event + window.addEventListener(MobileAccessibilityNotifications.REDUCE_TRANSPARENCY_STATUS_CHANGED, onReduceTransparencyStatusChanged, false); +``` + ---------------------------------------------------------------------------------------------- #### MobileAccessibilityNotifications.SCREEN_READER_STATUS_CHANGED (screenreaderstatuschanged) @@ -560,124 +975,77 @@ If a screen reader is active, `info.isScreenReaderRunning` will equal `true`. window.addEventListener(MobileAccessibilityNotifications.SCREEN_READER_STATUS_CHANGED, onScreenReaderStatusChanged, false); ``` ------------------------------------------------------------------------------------------------------- -#### MobileAccessibilityNotifications.CLOSED_CAPTIONING_STATUS_CHANGED (closedcaptioningstatuschanged) +---------------------------------------------------------------------------------------- +#### MobileAccessibilityNotifications.SPEAK_SCREEN_STATUS_CHANGED (speakscreenstatuschanged) -The event fires when system-level closed captioning on the device turns on or off. +The event fires when Speak Screen has been enabled on an iOS device. The event returns an object, `info`, with the current status of accessibility features on the device. -If a screen reader is active, `info.isClosedCaptioningEnabled` will equal `true`. +If Speak Screen is active, `info.isSpeakScreenEnabled` will equal `true`. ```javascript // Define a persistent callback method to handle the event - function onClosedCaptioningStatusChanged(info) { - if (info && typeof info.isClosedCaptioningEnabled !== "undefined") { - if (info.isClosedCaptioningEnabled) { - console.log("Closed Captioning: ON"); - // Do something to improve the behavior of the application while closed captioning is enabled. + function onSpeakScreenStatusChanged(info) { + if (info && typeof info.isSpeakScreenEnabled !== "undefined") { + if (info.isSpeakScreenEnabled) { + console.log("Speak Screen: ON"); + // Do something to improve the behavior of the application while Speak Screen is enabled. } else { - console.log("Closed Captioning: OFF"); + console.log("Speak Screen: OFF"); } } } // Register the callback method to handle the event - window.addEventListener(MobileAccessibilityNotifications.CLOSED_CAPTIONING_STATUS_CHANGED, onClosedCaptioningStatusChanged, false); -``` - ----------------------------------------------------------------------------------------------- -#### MobileAccessibilityNotifications.GUIDED_ACCESS_STATUS_CHANGED (guidedaccessstatuschanged) - -The event fires when Guided Access has been enabled on an iOS device. -The event returns an object, `info`, with the current status of accessibility features on the device. -If a screen reader is active, `info.isGuidedAccessEnabled` will equal `true`. - -```javascript - // Define a persistent callback method to handle the event - function onGuidedAccessStatusChanged(info) { - if (info && typeof info.isGuidedAccessEnabled !== "undefined") { - if (info.isGuidedAccessEnabled) { - console.log("Guided Access: ON"); - // Do something to improve the behavior of the application while Guided Access is enabled. - } else { - console.log("Guided Access: OFF"); - } - } - } - - // Register the callback method to handle the event - window.addEventListener(MobileAccessibilityNotifications.GUIDED_ACCESS_STATUS_CHANGED, onGuidedAccessStatusChanged, false); -``` - ----------------------------------------------------------------------------------------------- -#### MobileAccessibilityNotifications.INVERT_COLORS_STATUS_CHANGED (invertcolorsstatuschanged) - -The event fires when Invert Colors has been enabled on an iOS device. -The event returns an object, `info`, with the current status of accessibility features on the device. -If a screen reader is active, `info.isInvertColorsEnabled` will equal `true`. - -```javascript - // Define a persistent callback method to handle the event - function onInvertColorsStatusChanged(info) { - if (info && typeof info.isInvertColorsEnabled !== "undefined") { - if (info.isInvertColorsEnabled) { - console.log("Invert Colors: ON"); - // Do something to improve the behavior of the application while Invert Colors is enabled. - } else { - console.log("Invert Colors: OFF"); - } - } - } - - // Register the callback method to handle the event - window.addEventListener(MobileAccessibilityNotifications.INVERT_COLORS_STATUS_CHANGED, onInvertColorsStatusChanged, false); + window.addEventListener(MobileAccessibilityNotifications.SPEAK_SCREEN_STATUS_CHANGED, onSpeakScreenStatusChanged, false); ``` ---------------------------------------------------------------------------------------- -#### MobileAccessibilityNotifications.MONO_AUDIO_STATUS_CHANGED (monoaudiostatuschanged) +#### MobileAccessibilityNotifications.SPEAK_SELECTION_STATUS_CHANGED (speakselectionstatuschanged) -The event fires when Mono Audio has been enabled on an iOS device. +The event fires when Speak Selection has been enabled on an iOS device. The event returns an object, `info`, with the current status of accessibility features on the device. -If a screen reader is active, `info.isMonoAudioEnabled` will equal `true`. +If Speak Selection is active, `info.isSpeakSelectionEnabled` will equal `true`. ```javascript // Define a persistent callback method to handle the event - function onMonoAudioStatusChanged(info) { - if (info && typeof info.isMonoAudioEnabled !== "undefined") { - if (info.isMonoAudioEnabled) { - console.log("Mono Audio: ON"); - // Do something to improve the behavior of the application while Mono Audio is enabled. + function onSpeakSelectionStatusChanged(info) { + if (info && typeof info.isSpeakSelectionEnabled !== "undefined") { + if (info.isSpeakSelectionEnabled) { + console.log("Speak Selection: ON"); + // Do something to improve the behavior of the application while Speak Selection is enabled. } else { - console.log("Mono Audio: OFF"); + console.log("Speak Selection: OFF"); } } } // Register the callback method to handle the event - window.addEventListener(MobileAccessibilityNotifications.MONO_AUDIO_STATUS_CHANGED, onMonoAudioStatusChanged, false); + window.addEventListener(MobileAccessibilityNotifications.SPEAK_SELECTION_STATUS_CHANGED, onSpeakSelectionStatusChanged, false); ``` ----------------------------------------------------------------------------------------- -#### MobileAccessibilityNotifications.REDUCE_MOTION_STATUS_CHANGED (reducemotionstatuschanged) -The event fires when Reduce Motion has been enabled on an iOS device. +---------------------------------------------------------------------------------------- +#### MobileAccessibilityNotifications.SWITCH_CONTROL_STATUS_CHANGED (switchcontrolstatuschanged) + +The event fires when Switch Control is running on an iOS device. The event returns an object, `info`, with the current status of accessibility features on the device. -If a screen reader is active, `info.isReduceMotionEnabled` will equal `true`. +If Switch Control is running, `info.isSwitchControlRunning` will equal `true`. ```javascript // Define a persistent callback method to handle the event - function onReduceMotionStatusChanged(info) { - if (info && typeof info.isReduceMotionEnabled !== "undefined") { - if (info.isReduceMotionEnabled) { - console.log("Reduce Motion: ON"); - // Do something to improve the behavior of the application while Reduce Motion is enabled. + function onSwitchControlStatusChanged(info) { + if (info && typeof info.isSwitchControlRunning !== "undefined") { + if (info.isSwitchControlRunning) { + console.log("Switch Control: ON"); + // Do something to improve the behavior of the application while Switch Control is running. } else { - console.log("Reduce Motion: OFF"); + console.log("Switch Control: OFF"); } } } // Register the callback method to handle the event - window.addEventListener(MobileAccessibilityNotifications.REDUCE_MOTION_STATUS_CHANGED, onMReduceMotionStatusChanged, false); + window.addEventListener(MobileAccessibilityNotifications.SWITCH_CONTROL_STATUS_CHANGED, onSwitchControlStatusChanged, false); ``` ------------------------------------------------------------------------------------------------------ @@ -685,7 +1053,7 @@ If a screen reader is active, `info.isReduceMotionEnabled` will equal `true`. The event fires when Touch Exploration has been enabled on an Android device. The event returns an object, `info`, with the current status of accessibility features on the device. -If a screen reader is active, `info.isTouchExplorationEnabled` will equal `true`. +If Touch Exploration is active, `info.isTouchExplorationEnabled` will equal `true`. ```javascript // Define a persistent callback method to handle the event diff --git a/src/ios/CDVMobileAccessibility.h b/src/ios/CDVMobileAccessibility.h index 9aa698a..662abbe 100644 --- a/src/ios/CDVMobileAccessibility.h +++ b/src/ios/CDVMobileAccessibility.h @@ -26,38 +26,57 @@ static const int BASE_UI_FONT_TEXT_STYLE_BODY_POINT_SIZE = 16; @interface CDVMobileAccessibility : CDVPlugin { NSString* callbackId; NSString* commandCallbackId; - BOOL voiceOverRunning; + BOOL boldTextEnabled; BOOL closedCaptioningEnabled; + BOOL darkerSystemColorsEnabled; + BOOL grayscaleEnabled; BOOL guidedAccessEnabled; BOOL invertColorsEnabled; BOOL monoAudioEnabled; BOOL reduceMotionEnabled; + BOOL reduceTransparencyEnabled; + BOOL speakScreenEnabled; + BOOL speakSelectionEnabled; + BOOL switchControlRunning; + BOOL voiceOverRunning; } @property (strong) NSString* callbackId; @property (strong) NSString* commandCallbackId; -@property BOOL voiceOverRunning; +@property BOOL boldTextEnabled; @property BOOL closedCaptioningEnabled; +@property BOOL darkerSystemColorsEnabled; +@property BOOL grayscaleEnabled; @property BOOL guidedAccessEnabled; @property BOOL invertColorsEnabled; @property BOOL monoAudioEnabled; @property BOOL reduceMotionEnabled; +@property BOOL reduceTransparencyEnabled; +@property BOOL speakScreenEnabled; +@property BOOL speakSelectionEnabled; +@property BOOL switchControlRunning; +@property BOOL voiceOverRunning; @property double mFontScale; -- (void) isScreenReaderRunning:(CDVInvokedUrlCommand*)command; +- (void) isBoldTextEnabled:(CDVInvokedUrlCommand*)command; - (void) isClosedCaptioningEnabled:(CDVInvokedUrlCommand*)command; +- (void) isDarkerSystemColorsEnabled:(CDVInvokedUrlCommand*)command; +- (void) isGrayscaleEnabled:(CDVInvokedUrlCommand*)command; - (void) isGuidedAccessEnabled:(CDVInvokedUrlCommand*)command; - (void) isInvertColorsEnabled:(CDVInvokedUrlCommand*)command; - (void) isMonoAudioEnabled:(CDVInvokedUrlCommand*)command; +- (void) isReduceMotionEnabled:(CDVInvokedUrlCommand*)command; +- (void) isReduceTransparencyEnabled:(CDVInvokedUrlCommand*)command; +- (void) isScreenReaderRunning:(CDVInvokedUrlCommand*)command; +- (void) isSpeakScreenEnabled:(CDVInvokedUrlCommand*)command; +- (void) isSpeakSelectionEnabled:(CDVInvokedUrlCommand*)command; +- (void) isSwitchControlRunning:(CDVInvokedUrlCommand*)command; - (void) getTextZoom:(CDVInvokedUrlCommand*)command; - (void) setTextZoom:(CDVInvokedUrlCommand*)command; - (void) updateTextZoom:(CDVInvokedUrlCommand*)command; -- (void) isReduceMotionEnabled:(CDVInvokedUrlCommand*)command; - (void) postNotification:(CDVInvokedUrlCommand*)command; - (void) start:(CDVInvokedUrlCommand*)command; - (void) stop:(CDVInvokedUrlCommand*)command; -@end - - +@end \ No newline at end of file diff --git a/src/ios/CDVMobileAccessibility.m b/src/ios/CDVMobileAccessibility.m index 4143584..ad8da02 100644 --- a/src/ios/CDVMobileAccessibility.m +++ b/src/ios/CDVMobileAccessibility.m @@ -33,13 +33,20 @@ @synthesize callbackId; @synthesize commandCallbackId; -@synthesize voiceOverRunning; +@synthesize boldTextEnabled; @synthesize closedCaptioningEnabled; +@synthesize darkerSystemColorsEnabled; +@synthesize grayscaleEnabled; @synthesize guidedAccessEnabled; @synthesize invertColorsEnabled; @synthesize monoAudioEnabled; -@synthesize mFontScale; @synthesize reduceMotionEnabled; +@synthesize reduceTransparencyEnabled; +@synthesize speakScreenEnabled; +@synthesize speakSelectionEnabled; +@synthesize switchControlRunning; +@synthesize voiceOverRunning; +@synthesize mFontScale; #define iOS7Delta (([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 ) ? 20 : 0 ) #define iOS8Delta (([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0 ) ? 30 : 0 ) @@ -106,11 +113,15 @@ #pragma Plugin interface -- (void)isScreenReaderRunning:(CDVInvokedUrlCommand*)command +- (void)isBoldTextEnabled:(CDVInvokedUrlCommand*)command { [self.commandDelegate runInBackground:^{ - self.voiceOverRunning = UIAccessibilityIsVoiceOverRunning(); - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.voiceOverRunning]; + if (iOS8Delta) { + self.boldTextEnabled = UIAccessibilityIsBoldTextEnabled(); + } else { + self.boldTextEnabled = false; + } + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.boldTextEnabled]; [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; }]; } @@ -124,6 +135,32 @@ }]; } +- (void)isDarkerSystemColorsEnabled:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + if (iOS8Delta) { + self.darkerSystemColorsEnabled = UIAccessibilityDarkerSystemColorsEnabled(); + } else { + self.darkerSystemColorsEnabled = false; + } + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.darkerSystemColorsEnabled]; + [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; + }]; +} + +- (void)isGrayscaleEnabled:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + if (iOS8Delta) { + self.grayscaleEnabled = UIAccessibilityIsGrayscaleEnabled(); + } else { + self.grayscaleEnabled = false; + } + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.grayscaleEnabled]; + [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; + }]; +} + - (void)isGuidedAccessEnabled:(CDVInvokedUrlCommand*)command { [self.commandDelegate runInBackground:^{ @@ -151,6 +188,80 @@ }]; } +- (void)isReduceMotionEnabled:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + if (iOS8Delta) { + self.reduceMotionEnabled = UIAccessibilityIsReduceMotionEnabled(); + } else { + self.reduceMotionEnabled = false; + } + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.reduceMotionEnabled]; + [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; + }]; +} + +- (void)isReduceTransparencyEnabled:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + if (iOS8Delta) { + self.reduceTransparencyEnabled = UIAccessibilityIsReduceTransparencyEnabled(); + } else { + self.reduceTransparencyEnabled = false; + } + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.reduceTransparencyEnabled]; + [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; + }]; +} + +- (void)isScreenReaderRunning:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + self.voiceOverRunning = UIAccessibilityIsVoiceOverRunning(); + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.voiceOverRunning]; + [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; + }]; +} + +- (void)isSpeakScreenEnabled:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + if (iOS8Delta) { + self.speakScreenEnabled = UIAccessibilityIsSpeakScreenEnabled(); + } else { + self.speakScreenEnabled = false; + } + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.speakScreenEnabled]; + [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; + }]; +} + +- (void)isSpeakSelectionEnabled:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + if (iOS8Delta) { + self.speakSelectionEnabled = UIAccessibilityIsSpeakSelectionEnabled(); + } else { + self.speakSelectionEnabled = false; + } + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.speakSelectionEnabled]; + [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; + }]; +} + +- (void)isSwitchControlRunning:(CDVInvokedUrlCommand*)command +{ + [self.commandDelegate runInBackground:^{ + if (iOS8Delta) { + self.switchControlRunning = UIAccessibilityIsSwitchControlRunning(); + } else { + self.switchControlRunning = false; + } + CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.switchControlRunning]; + [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; + }]; +} + -(double) mGetFontScale { double fontScale = 1; @@ -217,20 +328,6 @@ } } -- (void)isReduceMotionEnabled:(CDVInvokedUrlCommand*)command -{ - [self.commandDelegate runInBackground:^{ - if (iOS8Delta) { - self.reduceMotionEnabled = UIAccessibilityIsReduceMotionEnabled(); - } else { - self.reduceMotionEnabled = false; - } - CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:self.reduceMotionEnabled]; - [self.commandDelegate sendPluginResult:result callbackId:command.callbackId]; - }]; -} - - - (void)postNotification:(CDVInvokedUrlCommand *)command { CDVPluginResult* result = nil; @@ -240,7 +337,6 @@ if (notificationString == nil) { notificationString = @""; } - if (UIAccessibilityIsVoiceOverRunning() && [self isValidNotificationType:notificationType]) { [self.commandDelegate runInBackground:^{ @@ -319,20 +415,34 @@ /* Get the current mobile accessibility status. */ - (NSDictionary*)getMobileAccessibilityStatus { - self.voiceOverRunning = UIAccessibilityIsVoiceOverRunning(); + self.boldTextEnabled = UIAccessibilityIsBoldTextEnabled(); self.closedCaptioningEnabled = [self getClosedCaptioningEnabledStatus]; + self.darkerSystemColorsEnabled = UIAccessibilityDarkerSystemColorsEnabled(); + self.grayscaleEnabled = UIAccessibilityIsGrayscaleEnabled(); self.guidedAccessEnabled = UIAccessibilityIsGuidedAccessEnabled(); self.invertColorsEnabled = UIAccessibilityIsInvertColorsEnabled(); self.monoAudioEnabled = UIAccessibilityIsMonoAudioEnabled(); self.reduceMotionEnabled = UIAccessibilityIsReduceMotionEnabled(); + self.reduceTransparencyEnabled = UIAccessibilityIsReduceTransparencyEnabled(); + self.speakScreenEnabled = UIAccessibilityIsSpeakScreenEnabled(); + self.speakSelectionEnabled = UIAccessibilityIsSpeakSelectionEnabled(); + self.switchControlRunning = UIAccessibilityIsSwitchControlRunning(); + self.voiceOverRunning = UIAccessibilityIsVoiceOverRunning(); NSMutableDictionary* mobileAccessibilityData = [NSMutableDictionary dictionaryWithCapacity:5]; - [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.voiceOverRunning] forKey:@"isScreenReaderRunning"]; + [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.boldTextEnabled] forKey:@"isBoldTextEnabled"]; [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.closedCaptioningEnabled] forKey:@"isClosedCaptioningEnabled"]; + [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.darkerSystemColorsEnabled] forKey:@"isDarkerSystemColorsEnabled"]; + [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.grayscaleEnabled] forKey:@"isGrayscaleEnabled"]; [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.guidedAccessEnabled] forKey:@"isGuidedAccessEnabled"]; [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.invertColorsEnabled] forKey:@"isInvertColorsEnabled"]; [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.monoAudioEnabled] forKey:@"isMonoAudioEnabled"]; [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.reduceMotionEnabled] forKey:@"isReduceMotionEnabled"]; + [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.reduceTransparencyEnabled] forKey:@"isReduceTransparencyEnabled"]; + [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.speakScreenEnabled] forKey:@"isSpeakScreenEnabled"]; + [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.speakSelectionEnabled] forKey:@"isSpeakSelectionEnabled"]; + [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.switchControlRunning] forKey:@"isSwitchControlRunning"]; + [mobileAccessibilityData setObject:[NSNumber numberWithBool:self.voiceOverRunning] forKey:@"isScreenReaderRunning"]; return mobileAccessibilityData; } @@ -342,12 +452,22 @@ { [self.commandDelegate runInBackground:^{ self.callbackId = command.callbackId; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityVoiceOverStatusChanged object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityClosedCaptioningStatusDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityGuidedAccessStatusDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityInvertColorsStatusDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityMonoAudioStatusDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityReduceMotionStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityVoiceOverStatusChanged object:nil]; + + if (iOS8Delta) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityBoldTextStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityDarkerSystemColorsStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityGrayscaleStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityReduceMotionStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilityReduceTransparencyStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilitySpeakScreenStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilitySpeakSelectionStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mobileAccessibilityStatusChanged:) name:UIAccessibilitySwitchControlStatusDidChangeNotification object:nil]; + } // Update the callback on start CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:[self getMobileAccessibilityStatus]]; @@ -368,13 +488,23 @@ [self.commandDelegate sendPluginResult:result callbackId:self.callbackId]; } self.callbackId = nil; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityVoiceOverStatusChanged object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityClosedCaptioningStatusDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityGuidedAccessStatusDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityInvertColorsStatusDidChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityAnnouncementDidFinishNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityMonoAudioStatusDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityReduceMotionStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityVoiceOverStatusChanged object:nil]; + + if (iOS8Delta) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityBoldTextStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityDarkerSystemColorsStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityGrayscaleStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityReduceMotionStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityReduceTransparencyStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilitySpeakScreenStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilitySpeakSelectionStatusDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilitySwitchControlStatusDidChangeNotification object:nil]; + } }]; } diff --git a/www/MobileAccessibilityNotifications.js b/www/MobileAccessibilityNotifications.js index 0cbcaa4..6972902 100644 --- a/www/MobileAccessibilityNotifications.js +++ b/www/MobileAccessibilityNotifications.js @@ -31,6 +31,13 @@ module.exports = { MONO_AUDIO_STATUS_CHANGED : "monoaudiostatuschanged", REDUCE_MOTION_STATUS_CHANGED : "reducemotionstatuschanged", TOUCH_EXPLORATION_STATUS_CHANGED : "touchexplorationstatechanged", + BOLD_TEXT_STATUS_CHANGED : "boldtextstatuschanged", + DARKER_SYSTEM_COLORS_STATUS_CHANGED : "darkersystemcolorsstatuschanged", + GRAYSCALE_STATUS_CHANGED : "grayscalestatuschanged", + REDUCE_TRANSPARENCY_STATUS_CHANGED : "reducetransparencystatuschanged", + SPEAK_SCREEN_STATUS_CHANGED : "speakscreenstatuschanged", + SPEAK_SELECTION_STATUS_CHANGED : "speakselectionstatuschanged", + SWITCH_CONTROL_STATUS_CHANGED : "switchcontrolstatuschanged", /* iOS specific UIAccessibilityNotifications */ SCREEN_CHANGED : 1000, diff --git a/www/mobile-accessibility.js b/www/mobile-accessibility.js index 8f7667a..4800c0c 100644 --- a/www/mobile-accessibility.js +++ b/www/mobile-accessibility.js @@ -28,12 +28,19 @@ var argscheck = require('cordova/argscheck'), MobileAccessibilityNotifications = require('phonegap-plugin-mobile-accessibility.MobileAccessibilityNotifications'); var MobileAccessibility = function() { - this._isScreenReaderRunning = false; + this._isBoldTextEnabled = false; this._isClosedCaptioningEnabled = false; + this._isDarkerSystemColorsEnabled = false; + this._isGrayscaleEnabled = false; this._isGuidedAccessEnabled = false; this._isInvertColorsEnabled = false; this._isMonoAudioEnabled = false; this._isReduceMotionEnabled = false; + this._isReduceTransparencyEnabled = false; + this._isScreenReaderRunning = false; + this._isSpeakScreenEnabled = false; + this._isSpeakSelectionEnabled = false; + this._isSwitchControlRunning = false; this._isTouchExplorationEnabled = false; this._usePreferredTextZoom = false; this._isHighContrastEnabled = false; @@ -41,12 +48,19 @@ var MobileAccessibility = function() { // Create new event handlers on the window (returns a channel instance) this.channels = { - screenreaderstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.SCREEN_READER_STATUS_CHANGED), + boldtextstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.BOLD_TEXT_STATUS_CHANGED), closedcaptioningstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.CLOSED_CAPTIONING_STATUS_CHANGED), + darkersystemcolorsstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.DARKER_SYSTEM_COLORS_STATUS_CHANGED), + grayscalestatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.GRAYSCALE_STATUS_CHANGED), guidedaccessstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.GUIDED_ACCESS_STATUS_CHANGED), invertcolorsstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.INVERT_COLORS_STATUS_CHANGED), monoaudiostatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.MONO_AUDIO_STATUS_CHANGED), - reducemotionstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.REDUCE_MOTION_STATUS_CHANGED), + reducemotionstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.REDUCE_MOTION_STATUS_CHANGED), + reducetransparencystatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.REDUCE_TRANSPARENCY_STATUS_CHANGED), + screenreaderstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.SCREEN_READER_STATUS_CHANGED), + speakscreenstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.SPEAK_SCREEN_STATUS_CHANGED), + speakselectionstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.SPEAK_SELECTION_STATUS_CHANGED), + switchcontrolstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.SWITCH_CONTROL_STATUS_CHANGED), touchexplorationstatechanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.TOUCH_EXPLORATION_STATUS_CHANGED), highcontrastchanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.HIGH_CONTRAST_CHANGED) }; @@ -60,12 +74,19 @@ var MobileAccessibility = function() { * @ignore */ function handlers() { - return mobileAccessibility.channels.screenreaderstatuschanged.numHandlers + + return mobileAccessibility.channels.boldtextstatuschanged.numHandlers + mobileAccessibility.channels.closedcaptioningstatuschanged.numHandlers + + mobileAccessibility.channels.darkersystemcolorsstatuschanged.numHandlers + + mobileAccessibility.channels.grayscalestatuschanged.numHandlers + + mobileAccessibility.channels.guidedaccessstatuschanged.numHandlers + mobileAccessibility.channels.invertcolorsstatuschanged.numHandlers + mobileAccessibility.channels.monoaudiostatuschanged.numHandlers + mobileAccessibility.channels.reducemotionstatuschanged.numHandlers + - mobileAccessibility.channels.guidedaccessstatuschanged.numHandlers + + mobileAccessibility.channels.reducetransparencystatuschanged.numHandlers + + mobileAccessibility.channels.screenreaderstatuschanged.numHandlers + + mobileAccessibility.channels.speakscreenstatuschanged.numHandlers + + mobileAccessibility.channels.speakselectionstatuschanged.numHandlers + + mobileAccessibility.channels.switchcontrolstatuschanged.numHandlers + mobileAccessibility.channels.touchexplorationstatechanged.numHandlers + mobileAccessibility.channels.highcontrastchanged.numHandlers; }; @@ -175,13 +196,45 @@ MobileAccessibility.prototype.injectLocalAndroidVoxScript = function() { }; /** - * Asynchronous call to native MobileAccessibility to determine if closed captioning is enabled. + * Asynchronous call to native MobileAccessibility to determine if Bold Text is enabled. + * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. + */ +MobileAccessibility.prototype.isBoldTextEnabled = function(callback) { + exec(callback, null, "MobileAccessibility", "isBoldTextEnabled", []); +}; + +/** + * Asynchronous call to native MobileAccessibility to determine if Closed Captioning is enabled. * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. */ MobileAccessibility.prototype.isClosedCaptioningEnabled = function(callback) { exec(callback, null, "MobileAccessibility", "isClosedCaptioningEnabled", []); }; +/** + * Asynchronous call to native MobileAccessibility to determine if Darker System Colors are enabled. + * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. + */ +MobileAccessibility.prototype.isDarkerSystemColorsEnabled = function(callback) { + exec(callback, null, "MobileAccessibility", "isDarkerSystemColorsEnabled", []); +}; + +/** + * Asynchronous call to native MobileAccessibility to determine if Grayscale is enabled. + * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. + */ +MobileAccessibility.prototype.isGrayscaleEnabled = function(callback) { + exec(callback, null, "MobileAccessibility", "isGrayscaleEnabled", []); +}; + +/** + * Asynchronous call to native MobileAccessibility to determine if Guided Access is enabled. + * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. + */ +MobileAccessibility.prototype.isGuidedAccessEnabled = function(callback) { + exec(callback, null, "MobileAccessibility", "isGuidedAccessEnabled", []); +}; + /** * Asynchronous call to native MobileAccessibility to determine if the display colors have been inverted. * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. @@ -191,7 +244,7 @@ MobileAccessibility.prototype.isInvertColorsEnabled = function(callback) { }; /** - * Asynchronous call to native MobileAccessibility to determine if mono audio is enabled. + * Asynchronous call to native MobileAccessibility to determine if Mono Audio is enabled. * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. */ MobileAccessibility.prototype.isMonoAudioEnabled = function(callback) { @@ -199,7 +252,7 @@ MobileAccessibility.prototype.isMonoAudioEnabled = function(callback) { }; /** - * Asynchronous call to native MobileAccessibility to determine if mono audio is enabled. + * Asynchronous call to native MobileAccessibility to determine if Reduce Motion is enabled. * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. */ MobileAccessibility.prototype.isReduceMotionEnabled = function(callback) { @@ -207,11 +260,35 @@ MobileAccessibility.prototype.isReduceMotionEnabled = function(callback) { }; /** - * Asynchronous call to native MobileAccessibility to determine if Guided Access is enabled. + * Asynchronous call to native MobileAccessibility to determine if Reduce Transparency is enabled. * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. */ -MobileAccessibility.prototype.isGuidedAccessEnabled = function(callback) { - exec(callback, null, "MobileAccessibility", "isGuidedAccessEnabled", []); +MobileAccessibility.prototype.isReduceTransparencyEnabled = function(callback) { + exec(callback, null, "MobileAccessibility", "isReduceTransparencyEnabled", []); +}; + +/** + * Asynchronous call to native MobileAccessibility to determine if Speak Screen is enabled. + * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. + */ +MobileAccessibility.prototype.isSpeakScreenEnabled = function(callback) { + exec(callback, null, "MobileAccessibility", "isSpeakScreenEnabled", []); +}; + +/** + * Asynchronous call to native MobileAccessibility to determine if Speak Selection is enabled. + * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. + */ +MobileAccessibility.prototype.isSpeakSelectionEnabled = function(callback) { + exec(callback, null, "MobileAccessibility", "isSpeakSelectionEnabled", []); +}; + +/** + * Asynchronous call to native MobileAccessibility to determine if Switch Control is running. + * @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility. + */ +MobileAccessibility.prototype.isSwitchControlRunning = function(callback) { + exec(callback, null, "MobileAccessibility", "isSwitchControlRunning", []); }; /** @@ -328,24 +405,40 @@ MobileAccessibility.prototype.stop = function() { * Callback from native MobileAccessibility returning an object which describes the status of MobileAccessibility features. * * @param {Object} info - * @config {Boolean} [isScreenReaderRunning] Boolean to indicate screen reader status. + * @config {Boolean} [isBoldTextEnabled] Boolean to indicate bold text status (ios). * @config {Boolean} [isClosedCaptioningEnabled] Boolean to indicate closed captioning status. + * @config {Boolean} [isDarkerSystemColorsEnabled] Boolean to indicate darker system colors status (ios). + * @config {Boolean} [isGrayscaleEnabled] Boolean to indicate grayscale status (ios). * @config {Boolean} [isGuidedAccessEnabled] Boolean to indicate guided access status (ios). * @config {Boolean} [isInvertColorsEnabled] Boolean to indicate invert colors status (ios). * @config {Boolean} [isMonoAudioEnabled] Boolean to indicate mono audio status (ios). + * @config {Boolean} [isReduceMotionEnabled] Boolean to indicate reduce motion status (ios). + * @config {Boolean} [isReduceTransparencyEnabled] Boolean to indicate reduce transparency status (ios). + * @config {Boolean} [isScreenReaderRunning] Boolean to indicate screen reader status. + * @config {Boolean} [isSpeakScreenEnabled] Boolean to indicate speak screen status (ios). + * @config {Boolean} [isSpeakSelectionEnabled] Boolean to indicate speak selection status (ios). + * @config {Boolean} [isSwitchControlRunning] Boolean to indicate switch control status (ios). * @config {Boolean} [isTouchExplorationEnabled] Boolean to indicate touch exploration status (android). */ MobileAccessibility.prototype._status = function(info) { if (info) { mobileAccessibility.activateOrDeactivateChromeVox(info.isScreenReaderRunning); - if (mobileAccessibility._isScreenReaderRunning !== info.isScreenReaderRunning) { - mobileAccessibility._isScreenReaderRunning = info.isScreenReaderRunning; - cordova.fireWindowEvent(MobileAccessibilityNotifications.SCREEN_READER_STATUS_CHANGED, info); + if (mobileAccessibility._isBoldTextEnabled !== info.isBoldTextEnabled) { + mobileAccessibility._isBoldTextEnabled = info.isBoldTextEnabled; + cordova.fireWindowEvent(MobileAccessibilityNotifications.BOLD_TEXT_STATUS_CHANGED, info); } if (mobileAccessibility._isClosedCaptioningEnabled !== info.isClosedCaptioningEnabled) { mobileAccessibility._isClosedCaptioningEnabled = info.isClosedCaptioningEnabled; cordova.fireWindowEvent(MobileAccessibilityNotifications.CLOSED_CAPTIONING_STATUS_CHANGED, info); } + if (mobileAccessibility._isDarkerSystemColorsEnabled !== info.isDarkerSystemColorsEnabled) { + mobileAccessibility._isDarkerSystemColorsEnabled = info.isDarkerSystemColorsEnabled; + cordova.fireWindowEvent(MobileAccessibilityNotifications.DARKER_SYSTEM_COLORS_STATUS_CHANGED, info); + } + if (mobileAccessibility._isGrayscaleEnabled !== info.isGrayscaleEnabled) { + mobileAccessibility._isGrayscaleEnabled = info.isGrayscaleEnabled; + cordova.fireWindowEvent(MobileAccessibilityNotifications.GRAYSCALE_STATUS_CHANGED, info); + } if (mobileAccessibility._isGuidedAccessEnabled !== info.isGuidedAccessEnabled) { mobileAccessibility._isGuidedAccessEnabled = info.isGuidedAccessEnabled; cordova.fireWindowEvent(MobileAccessibilityNotifications.GUIDED_ACCESS_STATUS_CHANGED, info); @@ -362,6 +455,26 @@ MobileAccessibility.prototype._status = function(info) { mobileAccessibility._isReduceMotionEnabled = info.isReduceMotionEnabled; cordova.fireWindowEvent(MobileAccessibilityNotifications.REDUCE_MOTION_STATUS_CHANGED, info); } + if (mobileAccessibility._isReduceTransparencyEnabled !== info.isReduceTransparencyEnabled) { + mobileAccessibility._isReduceTransparencyEnabled = info.isReduceTransparencyEnabled; + cordova.fireWindowEvent(MobileAccessibilityNotifications.REDUCE_TRANSPARENCY_STATUS_CHANGED, info); + } + if (mobileAccessibility._isScreenReaderRunning !== info.isScreenReaderRunning) { + mobileAccessibility._isScreenReaderRunning = info.isScreenReaderRunning; + cordova.fireWindowEvent(MobileAccessibilityNotifications.SCREEN_READER_STATUS_CHANGED, info); + } + if (mobileAccessibility._isSpeakScreenEnabled !== info.isSpeakScreenEnabled) { + mobileAccessibility._isSpeakScreenEnabled = info.isSpeakScreenEnabled; + cordova.fireWindowEvent(MobileAccessibilityNotifications.SPEAK_SCREEN_STATUS_CHANGED, info); + } + if (mobileAccessibility._isSpeakSelectionEnabled !== info.isSpeakSelectionEnabled) { + mobileAccessibility._isSpeakSelectionEnabled = info.isSpeakSelectionEnabled; + cordova.fireWindowEvent(MobileAccessibilityNotifications.SPEAK_SELECTION_STATUS_CHANGED, info); + } + if (mobileAccessibility._isSwitchControlRunning !== info.isSwitchControlRunning) { + mobileAccessibility._isSwitchControlRunning = info.isSwitchControlRunning; + cordova.fireWindowEvent(MobileAccessibilityNotifications.SWITCH_CONTROL_STATUS_CHANGED, info); + } if (mobileAccessibility._isTouchExplorationEnabled !== info.isTouchExplorationEnabled) { mobileAccessibility._isTouchExplorationEnabled = info.isTouchExplorationEnabled; cordova.fireWindowEvent(MobileAccessibilityNotifications.TOUCH_EXPLORATION_STATUS_CHANGED, info);