зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1602075 - make enable/disable panel UI conditional on the accessibility-panel-auto-init feature. r=mtigley
Differential Revision: https://phabricator.services.mozilla.com/D71584
This commit is contained in:
Родитель
c8683212ad
Коммит
b503cad7f4
|
@ -56,6 +56,16 @@ class AccessibilityProxy {
|
|||
return this.accessibilityFront && this.accessibilityFront.enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the accessibility service is enabled.
|
||||
*/
|
||||
get canBeEnabled() {
|
||||
// TODO: Just use parentAccessibilityFront after Firefox 75.
|
||||
const { canBeEnabled } =
|
||||
this.parentAccessibilityFront || this.accessibilityFront;
|
||||
return canBeEnabled;
|
||||
}
|
||||
|
||||
get currentTarget() {
|
||||
return this._currentTarget;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ class Description extends Component {
|
|||
canBeEnabled: PropTypes.bool,
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
enableAccessibility: PropTypes.func.isRequired,
|
||||
autoInit: PropTypes.bool.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -71,20 +72,37 @@ class Description extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { canBeEnabled } = this.props;
|
||||
const { enabling } = this.state;
|
||||
const enableButtonStr = enabling
|
||||
? "accessibility.enabling"
|
||||
: "accessibility.enable";
|
||||
const { canBeEnabled, autoInit } = this.props;
|
||||
let warningStringName = "accessibility.enable.disabledTitle";
|
||||
let button;
|
||||
if (!autoInit) {
|
||||
const { enabling } = this.state;
|
||||
const enableButtonStr = enabling
|
||||
? "accessibility.enabling"
|
||||
: "accessibility.enable";
|
||||
|
||||
let title;
|
||||
let disableButton = false;
|
||||
let title;
|
||||
let disableButton = false;
|
||||
|
||||
if (canBeEnabled) {
|
||||
title = L10N.getStr("accessibility.enable.enabledTitle");
|
||||
} else {
|
||||
disableButton = true;
|
||||
title = L10N.getStr("accessibility.enable.disabledTitle");
|
||||
if (canBeEnabled) {
|
||||
title = L10N.getStr("accessibility.enable.enabledTitle");
|
||||
} else {
|
||||
disableButton = true;
|
||||
title = L10N.getStr("accessibility.enable.disabledTitle");
|
||||
}
|
||||
|
||||
button = Button(
|
||||
{
|
||||
id: "accessibility-enable-button",
|
||||
onClick: this.onEnable,
|
||||
disabled: enabling || disableButton,
|
||||
busy: enabling,
|
||||
"data-standalone": true,
|
||||
title,
|
||||
},
|
||||
L10N.getStr(enableButtonStr)
|
||||
);
|
||||
warningStringName = "accessibility.description.general.p2";
|
||||
}
|
||||
|
||||
return div(
|
||||
|
@ -105,26 +123,22 @@ class Description extends Component {
|
|||
l10n: L10N,
|
||||
messageStringKey: "accessibility.description.general.p1",
|
||||
}),
|
||||
p({}, L10N.getStr("accessibility.description.general.p2"))
|
||||
p({}, L10N.getStr(warningStringName))
|
||||
)
|
||||
),
|
||||
Button(
|
||||
{
|
||||
id: "accessibility-enable-button",
|
||||
onClick: this.onEnable,
|
||||
disabled: enabling || disableButton,
|
||||
busy: enabling,
|
||||
"data-standalone": true,
|
||||
title,
|
||||
},
|
||||
L10N.getStr(enableButtonStr)
|
||||
)
|
||||
button
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = ({ ui }) => ({
|
||||
canBeEnabled: ui.canBeEnabled,
|
||||
const mapStateToProps = ({
|
||||
ui: {
|
||||
canBeEnabled,
|
||||
supports: { autoInit },
|
||||
},
|
||||
}) => ({
|
||||
canBeEnabled,
|
||||
autoInit,
|
||||
});
|
||||
|
||||
// Exports from this module
|
||||
|
|
|
@ -15,6 +15,7 @@ const {
|
|||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
const {
|
||||
enable,
|
||||
reset,
|
||||
updateCanBeEnabled,
|
||||
updateCanBeDisabled,
|
||||
|
@ -123,7 +124,15 @@ class MainFrame extends Component {
|
|||
}
|
||||
|
||||
onCanBeEnabledChange(canBeEnabled) {
|
||||
this.props.dispatch(updateCanBeEnabled(canBeEnabled));
|
||||
const {
|
||||
enableAccessibility,
|
||||
dispatch,
|
||||
supports: { autoInit },
|
||||
} = this.props;
|
||||
dispatch(updateCanBeEnabled(canBeEnabled));
|
||||
if (canBeEnabled && autoInit) {
|
||||
dispatch(enable(enableAccessibility));
|
||||
}
|
||||
}
|
||||
|
||||
onCanBeDisabledChange(canBeDisabled) {
|
||||
|
|
|
@ -41,6 +41,7 @@ class Toolbar extends Component {
|
|||
toolboxDoc: PropTypes.object.isRequired,
|
||||
audit: PropTypes.func.isRequired,
|
||||
simulate: PropTypes.func,
|
||||
autoInit: PropTypes.bool.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -64,7 +65,7 @@ class Toolbar extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { canBeDisabled, simulate, toolboxDoc, audit } = this.props;
|
||||
const { canBeDisabled, simulate, toolboxDoc, audit, autoInit } = this.props;
|
||||
const { disabling } = this.state;
|
||||
const disableButtonStr = disabling
|
||||
? "accessibility.disabling"
|
||||
|
@ -95,21 +96,23 @@ class Toolbar extends Component {
|
|||
className: "devtools-toolbar",
|
||||
role: "toolbar",
|
||||
},
|
||||
Button(
|
||||
{
|
||||
className: "disable",
|
||||
id: "accessibility-disable-button",
|
||||
onClick: this.onDisable,
|
||||
disabled: disabling || isDisabled,
|
||||
busy: disabling,
|
||||
title,
|
||||
},
|
||||
L10N.getStr(disableButtonStr)
|
||||
),
|
||||
div({
|
||||
role: "separator",
|
||||
className: "devtools-separator",
|
||||
}),
|
||||
!autoInit &&
|
||||
Button(
|
||||
{
|
||||
className: "disable",
|
||||
id: "accessibility-disable-button",
|
||||
onClick: this.onDisable,
|
||||
disabled: disabling || isDisabled,
|
||||
busy: disabling,
|
||||
title,
|
||||
},
|
||||
L10N.getStr(disableButtonStr)
|
||||
),
|
||||
!autoInit &&
|
||||
div({
|
||||
role: "separator",
|
||||
className: "devtools-separator",
|
||||
}),
|
||||
// @remove after release 68 (See Bug 1551574)
|
||||
span(
|
||||
{
|
||||
|
@ -131,8 +134,14 @@ class Toolbar extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = ({ ui }) => ({
|
||||
canBeDisabled: ui.canBeDisabled,
|
||||
const mapStateToProps = ({
|
||||
ui: {
|
||||
canBeDisabled,
|
||||
supports: { autoInit },
|
||||
},
|
||||
}) => ({
|
||||
canBeDisabled,
|
||||
autoInit,
|
||||
});
|
||||
|
||||
// Exports from this module
|
||||
|
|
|
@ -96,6 +96,16 @@ AccessibilityPanel.prototype = {
|
|||
this.onTargetAvailable
|
||||
);
|
||||
|
||||
// Bug 1602075: if auto init feature is enabled, enable accessibility
|
||||
// service if necessary.
|
||||
if (
|
||||
this.accessibilityProxy.supports.autoInit &&
|
||||
this.accessibilityProxy.canBeEnabled &&
|
||||
!this.accessibilityProxy.enabled
|
||||
) {
|
||||
await this.accessibilityProxy.enableAccessibility();
|
||||
}
|
||||
|
||||
this.picker = new Picker(this);
|
||||
this.fluentBundles = await this.createFluentBundles();
|
||||
|
||||
|
@ -185,7 +195,7 @@ AccessibilityPanel.prototype = {
|
|||
// Alright reset the flag we are about to refresh the panel.
|
||||
this.shouldRefresh = false;
|
||||
this.postContentMessage("initialize", {
|
||||
supports: this.supports,
|
||||
supports: this.accessibilityProxy.supports,
|
||||
fluentBundles: this.fluentBundles,
|
||||
toolbox: this._toolbox,
|
||||
getAccessibilityTreeRoot: this.accessibilityProxy
|
||||
|
|
|
@ -123,7 +123,7 @@ function onReceiveChildren(cache, action) {
|
|||
}
|
||||
|
||||
if (accessible.actorID) {
|
||||
console.warn(`Error fetching children: `, accessible, error);
|
||||
console.warn(`Error fetching children: `, error);
|
||||
return cache;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,21 +25,13 @@ function getInitialState() {
|
|||
}
|
||||
|
||||
function simulation(state = getInitialState(), action) {
|
||||
const { error } = action;
|
||||
|
||||
if (error) {
|
||||
console.warn(
|
||||
`Error running simulation: ${
|
||||
typeof error == "string"
|
||||
? error
|
||||
: "simulate function in simulator.js returned an error"
|
||||
}`
|
||||
);
|
||||
return state;
|
||||
}
|
||||
|
||||
switch (action.type) {
|
||||
case SIMULATE:
|
||||
if (action.error) {
|
||||
console.warn("Error running simulation", action.error);
|
||||
return state;
|
||||
}
|
||||
|
||||
const simTypes = action.simTypes;
|
||||
|
||||
if (simTypes.length === 0) {
|
||||
|
|
|
@ -32,7 +32,7 @@ add_task(async function testNoShowAccessibilityPropertiesContextMenu() {
|
|||
);
|
||||
ok(inspectA11YPropsItem.hidden, "Accessibility tools are not enabled.");
|
||||
contextMenu.hidePopup();
|
||||
gBrowser.removeCurrentTab();
|
||||
await removeTab(tab);
|
||||
});
|
||||
|
||||
addA11YPanelTask(
|
||||
|
|
|
@ -57,4 +57,7 @@ add_task(async () => {
|
|||
await runA11yPanelTests(CONTENT_PROCESS_EXPECTED, env);
|
||||
|
||||
await disableAccessibilityInspector(env);
|
||||
await closeToolbox();
|
||||
await shutdownA11y();
|
||||
await removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ add_task(async function tabNotHighlighted() {
|
|||
"should not be highlighted when toolbox opens"
|
||||
);
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
await closeTabAndToolbox();
|
||||
});
|
||||
|
||||
add_task(async function tabHighlighted() {
|
||||
|
@ -27,5 +27,7 @@ add_task(async function tabHighlighted() {
|
|||
await checkHighlighted(toolbox, true);
|
||||
|
||||
a11yService = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
await closeToolbox();
|
||||
await shutdownA11y();
|
||||
await removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
const TEST_URI = '<h1 id="h1">header</h1><p id="p">paragraph</p>';
|
||||
|
||||
add_task(async function() {
|
||||
const { toolbox: toolbox1 } = await addTestTab(buildURL(TEST_URI));
|
||||
const { toolbox: toolbox2 } = await addTestTab(buildURL(TEST_URI));
|
||||
Services.prefs.setBoolPref("devtools.accessibility.auto-init.enabled", false);
|
||||
|
||||
const { toolbox: toolbox1, tab: tab1 } = await addTestTab(buildURL(TEST_URI));
|
||||
const { toolbox: toolbox2, tab: tab2 } = await addTestTab(buildURL(TEST_URI));
|
||||
const options = await openOptions(toolbox2);
|
||||
|
||||
info("Check that initially both accessibility panels are highlighted.");
|
||||
|
@ -42,6 +44,14 @@ add_task(async function() {
|
|||
|
||||
await checkHighlighted(toolbox1, false);
|
||||
await checkHighlighted(toolbox2, false);
|
||||
|
||||
await closeToolbox();
|
||||
await shutdownA11y();
|
||||
await removeTab(tab1);
|
||||
await closeToolbox();
|
||||
await shutdownA11y();
|
||||
await removeTab(tab2);
|
||||
Services.prefs.clearUserPref("devtools.accessibility.auto-init.enabled");
|
||||
});
|
||||
|
||||
async function openOptions(toolbox) {
|
||||
|
|
|
@ -73,21 +73,36 @@ async function initA11y() {
|
|||
return a11yService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force garbage collection.
|
||||
*/
|
||||
function forceGC() {
|
||||
SpecialPowers.gc();
|
||||
SpecialPowers.forceShrinkingGC();
|
||||
SpecialPowers.forceCC();
|
||||
SpecialPowers.gc();
|
||||
SpecialPowers.forceShrinkingGC();
|
||||
SpecialPowers.forceCC();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if accessibility service is enabled.
|
||||
*/
|
||||
function isA11YEnabled() {
|
||||
return Services.appinfo.accessibilityEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for accessibility service to shut down. We consider it shut down when
|
||||
* an "a11y-init-or-shutdown" event is received with a value of "0".
|
||||
*/
|
||||
function shutdownA11y() {
|
||||
if (!Services.appinfo.accessibilityEnabled) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Force collections to speed up accessibility service shutdown.
|
||||
Cu.forceGC();
|
||||
Cu.forceCC();
|
||||
Cu.forceShrinkingGC();
|
||||
|
||||
function waitForA11YShutdown() {
|
||||
return new Promise(resolve => {
|
||||
if (!Services.appinfo.accessibilityEnabled) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
const observe = (subject, topic, data) => {
|
||||
if (data === "0") {
|
||||
Services.obs.removeObserver(observe, "a11y-init-or-shutdown");
|
||||
|
@ -102,6 +117,28 @@ function shutdownA11y() {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that accessibility is completely shutdown.
|
||||
*/
|
||||
async function shutdownA11y() {
|
||||
forceGC();
|
||||
if (isA11YEnabled()) {
|
||||
await waitForA11YShutdown();
|
||||
}
|
||||
|
||||
const browser = gBrowser.selectedBrowser;
|
||||
if (await SpecialPowers.spawn(browser, [], isA11YEnabled)) {
|
||||
await SpecialPowers.spawn(browser, [], waitForA11YShutdown);
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
ok(!isA11YEnabled(), "Accessibility service in parent process is shut down.");
|
||||
ok(
|
||||
!(await SpecialPowers.spawn(browser, [], isA11YEnabled)),
|
||||
"Accessibility service in content process is shut down."
|
||||
);
|
||||
}
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
info("Cleaning up...");
|
||||
await shutdownA11y();
|
||||
|
@ -156,6 +193,15 @@ async function addTestTab(url) {
|
|||
* cleanup function to make sure that the panel is still present.
|
||||
*/
|
||||
async function disableAccessibilityInspector(env) {
|
||||
if (
|
||||
Services.prefs.getBoolPref(
|
||||
"devtools.accessibility.auto-init.enabled",
|
||||
false
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { doc, win, panel } = env;
|
||||
// Disable accessibility service through the panel and wait for the shutdown
|
||||
// event.
|
||||
|
@ -811,6 +857,9 @@ function addA11YPanelTask(msg, uri, task, options = {}) {
|
|||
const env = await addTestTab(buildURL(uri, options));
|
||||
await task(env);
|
||||
await disableAccessibilityInspector(env);
|
||||
await closeToolbox();
|
||||
await shutdownA11y();
|
||||
await removeTab(gBrowser.selectedTab);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -396,11 +396,6 @@ const AccessibleActor = ActorClassWithSpec(accessibleSpec, {
|
|||
const targets = [...relation.getTargets().enumerate(Ci.nsIAccessible)];
|
||||
let relationObject;
|
||||
for (const target of targets) {
|
||||
// Target of the relation is not part of the current root document.
|
||||
if (target.rootDocument !== doc.rawAccessible) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let targetAcc;
|
||||
try {
|
||||
targetAcc = this.walker.attachAccessible(target, doc.rawAccessible);
|
||||
|
|
|
@ -467,7 +467,7 @@ const AccessibleWalkerActor = ActorClassWithSpec(accessibleWalkerSpec, {
|
|||
}
|
||||
|
||||
const doc = this.getRawAccessibleFor(this.rootDoc);
|
||||
if (isStale(doc)) {
|
||||
if (!doc || isStale(doc)) {
|
||||
return this.once("document-ready").then(docAcc => this.addRef(docAcc));
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче