mirror of
https://gitee.com/shuto-github/phonegap-mobile-accessibility.git
synced 2024-10-06 03:12:07 +08:00
Add preliminary support for Windows 8.1
This commit is contained in:
parent
226a7745fb
commit
cb94a6c8eb
19
plugin.xml
19
plugin.xml
@ -62,4 +62,23 @@
|
||||
<source-file src="src/android/com/phonegap/plugin/mobileaccessibility/KitKatMobileAccessibilityHelper.java" target-dir="src/com/phonegap/plugin/mobileaccessibility" />
|
||||
<asset src="www/android" target="plugins/com.phonegap.plugin.mobile-accessibility/android" />
|
||||
</platform>
|
||||
|
||||
<!-- windows -->
|
||||
<platform name="windows">
|
||||
<js-module src="src/windows/mobile-accessibility-proxy.js" name="MobileAccessibilityProxy">
|
||||
<merges target="" />
|
||||
</js-module>
|
||||
|
||||
<config-file target="package.phone.appxmanifest" parent="/Package/Capabilities">
|
||||
<DeviceCapability Name="microphone" />
|
||||
</config-file>
|
||||
|
||||
<config-file target="package.windows.appxmanifest" parent="/Package/Capabilities">
|
||||
<DeviceCapability Name="microphone" />
|
||||
</config-file>
|
||||
|
||||
<config-file target="package.windows80.appxmanifest" parent="/Package/Capabilities">
|
||||
<DeviceCapability Name="microphone" />
|
||||
</config-file>
|
||||
</platform>
|
||||
</plugin>
|
||||
|
261
src/windows/mobile-accessibility-proxy.js
Normal file
261
src/windows/mobile-accessibility-proxy.js
Normal file
@ -0,0 +1,261 @@
|
||||
/**
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/*global Windows:true*/
|
||||
|
||||
var cordova = require('cordova'),
|
||||
accessibilitySettings,
|
||||
uiSettings,
|
||||
callbackContext,
|
||||
fontScale = 1,
|
||||
styleElement,
|
||||
bodyStyleDeclaration,
|
||||
audio,
|
||||
synth;
|
||||
|
||||
function getAccessibilitySettings() {
|
||||
if (!accessibilitySettings) {
|
||||
accessibilitySettings = new Windows.UI.ViewManagement.AccessibilitySettings();
|
||||
}
|
||||
return accessibilitySettings;
|
||||
}
|
||||
|
||||
function getUISettings() {
|
||||
if (!uiSettings) {
|
||||
uiSettings = new Windows.UI.ViewManagement.UISettings();
|
||||
}
|
||||
return uiSettings;
|
||||
}
|
||||
|
||||
function getFontScale() {
|
||||
if (!uiSettings) {
|
||||
uiSettings = getUISettings();
|
||||
}
|
||||
var scale = uiSettings.textScaleFactor;
|
||||
// console.log("getFontScale " + scale);
|
||||
return scale;
|
||||
}
|
||||
|
||||
function getTextZoom() {
|
||||
var zoom = Math.round(fontScale * 100);
|
||||
// console.log("getTextZoom " + zoom);
|
||||
return zoom;
|
||||
}
|
||||
|
||||
function createStyleElement() {
|
||||
if (!styleElement) {
|
||||
styleElement = document.createElement("style");
|
||||
styleElement.type = "text/css";
|
||||
document.head.appendChild(styleElement);
|
||||
}
|
||||
}
|
||||
|
||||
function setTextZoom(zoom) {
|
||||
// console.log("setTextZoom " + zoom);
|
||||
fontScale = zoom/100;
|
||||
|
||||
createStyleElement();
|
||||
|
||||
if (bodyStyleDeclaration) {
|
||||
styleElement.removeChild(bodyStyleDeclaration);
|
||||
}
|
||||
|
||||
bodyStyleDeclaration = document.createTextNode("body {-ms-text-size-adjust: " + zoom + "%}");
|
||||
|
||||
styleElement.appendChild(bodyStyleDeclaration);
|
||||
}
|
||||
|
||||
function onHighContrastChanged(event) {
|
||||
cordova.fireWindowEvent(MobileAccessibilityNotifications.HIGH_CONTRAST_CHANGED,
|
||||
getMobileAccessibilityStatus());
|
||||
sendMobileAccessibilityStatusChangedCallback();
|
||||
}
|
||||
|
||||
function sendMobileAccessibilityStatusChangedCallback() {
|
||||
console.log("sendMobileAccessibilityStatusChangedCallback");
|
||||
if (callbackContext && typeof callbackContext === "function") {
|
||||
callbackContext(getMobileAccessibilityStatus());
|
||||
}
|
||||
}
|
||||
|
||||
function getMobileAccessibilityStatus() {
|
||||
return {
|
||||
isScreenReaderRunning: false,
|
||||
isClosedCaptioningEnabled: false,
|
||||
isHighContrastEnabled: accessibilitySettings.highContrast,
|
||||
highContrastScheme: (accessibilitySettings.highContrast ? accessibilitySettings.highContrastScheme : undefined)
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
start:function(win, fail, args) {
|
||||
if (typeof win === "function") {
|
||||
callbackContext = win;
|
||||
}
|
||||
if (!accessibilitySettings) {
|
||||
accessibilitySettings = getAccessibilitySettings();
|
||||
}
|
||||
accessibilitySettings.addEventListener("highcontrastchanged", onHighContrastChanged);
|
||||
|
||||
if (!uiSettings) {
|
||||
uiSettings = getUISettings();
|
||||
}
|
||||
},
|
||||
stop:function(win, fail, args) {
|
||||
if (accessibilitySettings) {
|
||||
accessibilitySettings.removeEventListener("highcontrastchanged", onHighContrastChanged);
|
||||
}
|
||||
|
||||
if (synth) {
|
||||
synth.close();
|
||||
synth = null;
|
||||
}
|
||||
|
||||
if (audio) {
|
||||
audio = null;
|
||||
}
|
||||
|
||||
if (callbackContext) {
|
||||
callbackContext = null;
|
||||
}
|
||||
},
|
||||
isScreenReaderRunning:function(win, fail, args) {
|
||||
console && console.error && console.error("Error : Windows 8.1 does not yet have a way to detect that Narrator is running.");
|
||||
fail && setTimeout(function() {
|
||||
fail(new Error("Windows Phone 8.1 does not yet have a way to detect that Narrator is running."));
|
||||
}, 0);
|
||||
if (win && typeof win === "function") {
|
||||
win(false);
|
||||
}
|
||||
},
|
||||
isClosedCaptioningEnabled:function(win, fail, args) {
|
||||
console && console.error && console.error("Error : MobileAccessibility.isClosedCaptioningEnabled is not yet implemented on Windows 8.1.");
|
||||
fail && setTimeout(function() {
|
||||
fail(new Error("MobileAccessibility.isClosedCaptioningEnabled is not yet implemented on Windows 8.1."));
|
||||
}, 0);
|
||||
if (win && typeof win === "function") {
|
||||
win(false);
|
||||
}
|
||||
},
|
||||
isHighContrastEnabled:function(win, fail, args) {
|
||||
if (!accessibilitySettings) {
|
||||
accessibilitySettings = getAccessibilitySettings();
|
||||
}
|
||||
|
||||
if (win && typeof win === "function") {
|
||||
win(accessibilitySettings.highContrast);
|
||||
}
|
||||
return accessibilitySettings.highContrast;
|
||||
},
|
||||
getHighContrastScheme:function(win, fail, args) {
|
||||
if (!accessibilitySettings) {
|
||||
accessibilitySettings = getAccessibilitySettings();
|
||||
}
|
||||
|
||||
var highContrastScheme = accessibilitySettings.highContrast ? accessibilitySettings.highContrastScheme : undefined;
|
||||
|
||||
if (win) {
|
||||
win(highContrastScheme);
|
||||
}
|
||||
return highContrastScheme;
|
||||
},
|
||||
getTextZoom:function(win, fail, args) {
|
||||
var zoom = Math.round(fontScale * 100);
|
||||
|
||||
if (win) {
|
||||
win(zoom);
|
||||
}
|
||||
|
||||
return zoom;
|
||||
},
|
||||
setTextZoom:function(win, fail, args) {
|
||||
var zoom = args[0];
|
||||
setTextZoom(args[0]);
|
||||
|
||||
if (win) {
|
||||
win(zoom);
|
||||
}
|
||||
|
||||
return zoom;
|
||||
},
|
||||
updateTextZoom:function(win, fail, args) {
|
||||
var scale = getFontScale(),
|
||||
zoom;
|
||||
if (scale !== fontScale) {
|
||||
fontScale = scale;
|
||||
}
|
||||
zoom = getTextZoom();
|
||||
setTextZoom(zoom);
|
||||
|
||||
if (win) {
|
||||
win(zoom);
|
||||
}
|
||||
|
||||
return zoom;
|
||||
},
|
||||
postNotification:function(win, fail, args) {
|
||||
var str = args[1];
|
||||
|
||||
if (str && typeof str === "string") {
|
||||
// The object for controlling and playing audio.
|
||||
if (!audio) {
|
||||
audio = new Audio();
|
||||
} else if (audio.pause) {
|
||||
audio.pause();
|
||||
audio.src = null;
|
||||
}
|
||||
|
||||
// The object for controlling the speech synthesis engine (voice).
|
||||
if (!synth) {
|
||||
synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
|
||||
}
|
||||
|
||||
if (str && str.length && str !== "\u200b") {
|
||||
|
||||
// Generate the audio stream from plain text.
|
||||
synth.synthesizeTextToStreamAsync(str).then(function (markersStream) {
|
||||
|
||||
// Convert the stream to a URL Blob.
|
||||
var blob = MSApp.createBlobFromRandomAccessStream(markersStream.contentType, markersStream);
|
||||
// Send the Blob to the audio object.
|
||||
audio.src = URL.createObjectURL(blob, { oneTimeOnly: true });
|
||||
// Start at beginning when speak is hit
|
||||
markersStream.seek(0);
|
||||
audio.AutoPlay = Boolean(true);
|
||||
|
||||
// Audio on completed
|
||||
audio.onended = function () {
|
||||
if (win) {
|
||||
win({
|
||||
stringValue: str,
|
||||
wasSuccessful: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
audio.play();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
require("cordova/exec/proxy").add("MobileAccessibility", module.exports);
|
@ -35,5 +35,8 @@ module.exports = {
|
||||
SCREEN_CHANGED : 1000,
|
||||
LAYOUT_CHANGED : 1001,
|
||||
ANNOUNCEMENT : 1008,
|
||||
PAGE_SCROLLED : 1009
|
||||
PAGE_SCROLLED : 1009,
|
||||
|
||||
/* Windows specific high contrast event */
|
||||
HIGH_CONTRAST_CHANGED : "highcontrastchanged"
|
||||
};
|
||||
|
@ -35,6 +35,9 @@ var MobileAccessibility = function() {
|
||||
this._isMonoAudioEnabled = false;
|
||||
this._isTouchExplorationEnabled = false;
|
||||
this._usePreferredTextZoom = false;
|
||||
this._isHighContrastEnabled = false;
|
||||
this._highContrastScheme = undefined;
|
||||
|
||||
// Create new event handlers on the window (returns a channel instance)
|
||||
this.channels = {
|
||||
screenreaderstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.SCREEN_READER_STATUS_CHANGED),
|
||||
@ -42,7 +45,8 @@ var MobileAccessibility = function() {
|
||||
guidedaccessstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.GUIDED_ACCESS_STATUS_CHANGED),
|
||||
invertcolorsstatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.INVERT_COLORS_STATUS_CHANGED),
|
||||
monoaudiostatuschanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.MONO_AUDIO_STATUS_CHANGED),
|
||||
touchexplorationstatechanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.TOUCH_EXPLORATION_STATUS_CHANGED)
|
||||
touchexplorationstatechanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.TOUCH_EXPLORATION_STATUS_CHANGED),
|
||||
highcontrastchanged : cordova.addWindowEventHandler(MobileAccessibilityNotifications.HIGH_CONTRAST_CHANGED)
|
||||
};
|
||||
for (var key in this.channels) {
|
||||
this.channels[key].onHasSubscribersChange = MobileAccessibility.onHasSubscribersChange;
|
||||
@ -59,7 +63,8 @@ function handlers() {
|
||||
mobileAccessibility.channels.invertcolorsstatuschanged.numHandlers +
|
||||
mobileAccessibility.channels.monoaudiostatuschanged.numHandlers +
|
||||
mobileAccessibility.channels.guidedaccessstatuschanged.numHandlers +
|
||||
mobileAccessibility.channels.touchexplorationstatechanged.numHandlers;
|
||||
mobileAccessibility.channels.touchexplorationstatechanged.numHandlers +
|
||||
mobileAccessibility.channels.highcontrastchanged.numHandlers;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -206,6 +211,14 @@ MobileAccessibility.prototype.isTouchExplorationEnabled = function(callback) {
|
||||
exec(callback, null, "MobileAccessibility", "isTouchExplorationEnabled", []);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asynchronous call to native MobileAccessibility to determine if High Contrast is enabled on Windows.
|
||||
* @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility.
|
||||
*/
|
||||
MobileAccessibility.prototype.isHighContrastEnabled = function(callback) {
|
||||
exec(callback, null, "MobileAccessibility", "isHighContrastEnabled", []);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asynchronous call to native MobileAccessibility to return the current text zoom percent value for the WebView.
|
||||
* @param {function} callback A callback method to receive the asynchronous result from the native MobileAccessibility.
|
||||
@ -293,7 +306,7 @@ MobileAccessibility.prototype.stop = function() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from native MobileAccessibility returning an which describes the status of MobileAccessibility features.
|
||||
* 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.
|
||||
@ -329,7 +342,12 @@ MobileAccessibility.prototype._status = function(info) {
|
||||
if (mobileAccessibility._isTouchExplorationEnabled !== info.isTouchExplorationEnabled) {
|
||||
mobileAccessibility._isTouchExplorationEnabled = info.isTouchExplorationEnabled;
|
||||
cordova.fireWindowEvent(MobileAccessibilityNotifications.TOUCH_EXPLORATION_STATUS_CHANGED, info);
|
||||
}
|
||||
}
|
||||
if (mobileAccessibility._isHighContrastEnabled !== info.isHighContrastEnabled) {
|
||||
mobileAccessibility._isHighContrastEnabled = info.isHighContrastEnabled;
|
||||
mobileAccessibility._highContrastScheme = info.highContrastScheme;
|
||||
cordova.fireWindowEvent(MobileAccessibilityNotifications.HIGH_CONTRAST_CHANGED, info);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user