Bug 1564999 - Add menu with simulation options to the a11y panel, r=yzen

Differential Revision: https://phabricator.services.mozilla.com/D38885

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Maliha Islam 2019-08-29 05:01:52 +00:00
Родитель deacf348f4
Коммит 973268af17
20 изменённых файлов: 570 добавлений и 43 удалений

Просмотреть файл

@ -59,11 +59,13 @@ class AccessibilityStartup {
this._supports.snapshot,
this._supports.audit,
this._supports.hydration,
this._supports.simulation,
] = await Promise.all([
this.target.actorHasMethod("accessible", "getRelations"),
this.target.actorHasMethod("accessible", "snapshot"),
this.target.actorHasMethod("accessible", "audit"),
this.target.actorHasMethod("accessible", "hydrate"),
this.target.actorHasMethod("accessibility", "getSimulator"),
]);
await this._accessibility.bootstrap();

Просмотреть файл

@ -47,19 +47,28 @@ AccessibilityView.prototype = {
* Initialize accessibility view, create its top level component and set the
* data store.
*
* @param {Object} accessibility front that can initialize accessibility
* @param {Object}
* Object that contains the following properties:
* - front {Object}
* front that can initialize accessibility
* walker and enable/disable accessibility
* services.
* @param {Object} walker front for accessibility walker actor responsible for
* - walker {Object}
* front for accessibility walker actor responsible for
* managing accessible objects actors/fronts.
* @param {JSON} supports a collection of flags indicating which accessibility
* - supports {JSON}
* a collection of flags indicating which accessibility
* panel features are supported by the current serverside
* version.
* @param {Array} fluentBundles array of FluentBundles elements for localization
* - fluentBundles {Array}
* array of FluentBundles elements for localization
* - simulator {Object}
* front for simulator actor responsible for setting
* color matrices in docShell
*/
async initialize(accessibility, walker, supports, fluentBundles) {
async initialize({ front, walker, supports, fluentBundles, simulator }) {
// Make sure state is reset every time accessibility panel is initialized.
await this.store.dispatch(reset(accessibility, supports));
await this.store.dispatch(reset(front, supports));
const container = document.getElementById("content");
if (!supports.enableDisable) {
@ -68,9 +77,10 @@ AccessibilityView.prototype = {
}
const mainFrame = MainFrame({
accessibility,
accessibility: front,
accessibilityWalker: walker,
fluentBundles,
simulator,
});
// Render top level component
const provider = createElement(Provider, { store: this.store }, mainFrame);

Просмотреть файл

@ -140,13 +140,13 @@ body {
margin-inline: 5px;
}
.devtools-toolbar .accessibility-tree-filters {
.devtools-toolbar .accessibility-tree-filters,
.devtools-toolbar .accessibility-simulation {
display: flex;
flex-wrap: nowrap;
flex-direction: row;
align-items: center;
white-space: nowrap;
margin-inline-end: 5px;
}
.devtools-toolbar .toolbar-menu-button {
@ -156,12 +156,21 @@ body {
.devtools-toolbar .toolbar-menu-button.filters {
max-width: 100px;
}
.devtools-toolbar .toolbar-menu-button.simulation {
max-width: 200px;
}
.devtools-toolbar .toolbar-menu-button.filters,
.devtools-toolbar .toolbar-menu-button.simulation {
text-overflow: ellipsis;
overflow-x: hidden;
margin-inline-start: 3px;
}
.devtools-toolbar .toolbar-menu-button::after {
.devtools-toolbar .toolbar-menu-button::after,
.devtools-toolbar .toolbar-menu-button.simulation::before {
content: "";
display: inline-block;
-moz-context-properties: fill;
@ -169,7 +178,8 @@ body {
margin-inline-start: 3px;
}
.devtools-toolbar .toolbar-menu-button.filters::after {
.devtools-toolbar .toolbar-menu-button.filters::after,
.devtools-toolbar .toolbar-menu-button.simulation::after {
background: url("chrome://devtools/skin/images/select-arrow.svg") no-repeat;
width: 8px;
height: 8px;
@ -286,22 +296,26 @@ body {
margin: auto;
}
.description .link {
.description .link,
.accessibility-check-annotation .link {
color: var(--accessibility-link-color);
cursor: pointer;
outline: 0;
}
.description .link:hover:not(:focus) {
.description .link:hover:not(:focus),
.accessibility-check-annotation .link:hover:not(:focus) {
text-decoration: underline;
}
.description .link:focus:not(:active) {
.description .link:focus:not(:active),
.accessibility-check-annotation .link:focus:not(:active) {
box-shadow: 0 0 0 2px var(--accessibility-toolbar-focus), 0 0 0 4px var(--accessibility-toolbar-focus-alpha30);
border-radius: 2px;
}
.description .link:active {
.description .link:active,
.accessibility-check-annotation .link:active {
color: var(--accessibility-link-color-active);
text-decoration: underline;
}
@ -764,27 +778,10 @@ body {
}
.accessibility-check-annotation .link {
color: var(--accessibility-link-color);
cursor: pointer;
outline: 0;
white-space: nowrap;
font-style: normal;
}
.accessibility-check-annotation .link:hover:not(:focus) {
text-decoration: underline;
}
.accessibility-check-annotation .link:focus:not(:active) {
box-shadow: 0 0 0 2px var(--accessibility-toolbar-focus), 0 0 0 4px var(--accessibility-toolbar-focus-alpha30);
border-radius: 2px;
}
.accessibility-check-annotation .link:active {
color: var(--accessibility-link-color-active);
text-decoration: underline;
}
.accessibility-color-contrast .accessibility-contrast-value:not(:empty) {
margin-block-end: 4px;
}
@ -815,3 +812,35 @@ body {
.accessibility-color-contrast .accessibility-color-contrast-separator:before {
margin-inline-end: 3px;
}
.devtools-toolbar .toolbar-menu-button.simulation::before {
width: 12px;
height: 12px;
margin-inline-end: 3px;
margin-inline-start: 0px;
background: url("chrome://devtools/skin/images/eye.svg") no-repeat;
-moz-context-properties: fill, stroke;
fill: var(--theme-icon-color);
stroke: var(--theme-icon-color);
vertical-align: -2px;
}
.devtools-toolbar .toolbar-menu-button.active,
.devtools-toolbar .toolbar-menu-button.active.devtools-button:not(:empty):not(.checked):not(:disabled):focus {
color: var(--theme-toolbar-selected-color);
}
.devtools-toolbar .toolbar-menu-button.simulation.active::before {
fill: var(--theme-toolbar-selected-color);
stroke: var(--theme-toolbar-selected-color);
}
#simulation-menu-button-menu .link {
background-color: transparent;
border: none;
}
#simulation-menu-button-menu .link:focus,
#simulation-menu-button-menu .link:hover {
background-color: var(--theme-arrowpanel-dimmed);
}

Просмотреть файл

@ -6,5 +6,6 @@ DevToolsModules(
'accessibles.js',
'audit.js',
'details.js',
'simulation.js',
'ui.js'
)

Просмотреть файл

@ -0,0 +1,13 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { SIMULATE } = require("devtools/client/accessibility/constants");
exports.simulate = (simulator, simTypes = []) => dispatch =>
simulator
.simulate({ types: simTypes })
.then(success => dispatch({ error: !success, simTypes, type: SIMULATE }))
.catch(error => dispatch({ error, type: SIMULATE }));

Просмотреть файл

@ -47,6 +47,7 @@ class MainFrame extends Component {
dispatch: PropTypes.func.isRequired,
auditing: PropTypes.array.isRequired,
supports: PropTypes.object,
simulator: PropTypes.object,
};
}
@ -115,6 +116,7 @@ class MainFrame extends Component {
fluentBundles,
enabled,
auditing,
simulator,
} = this.props;
if (!enabled) {
@ -128,7 +130,7 @@ class MainFrame extends Component {
{ bundles: fluentBundles },
div(
{ className: "mainFrame", role: "presentation" },
Toolbar({ accessibility, accessibilityWalker }),
Toolbar({ accessibility, accessibilityWalker, simulator }),
isAuditing && AuditProgressOverlay(),
span(
{

Просмотреть файл

@ -0,0 +1,155 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
// React
const {
createFactory,
Component,
} = require("devtools/client/shared/vendor/react");
const {
hr,
span,
div,
} = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { L10N } = require("../utils/l10n");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const MenuButton = createFactory(
require("devtools/client/shared/components/menu/MenuButton")
);
const { openDocLink } = require("devtools/client/shared/link");
const {
A11Y_SIMULATION_DOCUMENTATION_LINK,
} = require("devtools/client/accessibility/constants");
const {
accessibility: { SIMULATION_TYPE },
} = require("devtools/shared/constants");
const actions = require("../actions/simulation");
loader.lazyGetter(this, "MenuItem", function() {
return createFactory(
require("devtools/client/shared/components/menu/MenuItem")
);
});
loader.lazyGetter(this, "MenuList", function() {
return createFactory(
require("devtools/client/shared/components/menu/MenuList")
);
});
const SIMULATION_MENU_LABELS = {
NONE: "accessibility.filter.none",
[SIMULATION_TYPE.DEUTERANOMALY]: "accessibility.simulation.deuteranomaly",
[SIMULATION_TYPE.PROTANOMALY]: "accessibility.simulation.protanomaly",
[SIMULATION_TYPE.PROTANOPIA]: "accessibility.simulation.protanopia",
[SIMULATION_TYPE.DEUTERANOPIA]: "accessibility.simulation.deuteranopia",
[SIMULATION_TYPE.TRITANOPIA]: "accessibility.simulation.tritanopia",
[SIMULATION_TYPE.TRITANOMALY]: "accessibility.simulation.tritanomaly",
[SIMULATION_TYPE.CONTRAST_LOSS]: "accessibility.simulation.contrastLoss",
DOCUMENTATION: "accessibility.documentation.label",
};
class SimulationMenuButton extends Component {
static get propTypes() {
return {
simulator: PropTypes.object.isRequired,
simulation: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
};
}
constructor(props) {
super(props);
this.disableSimulation = this.disableSimulation.bind(this);
}
disableSimulation() {
const { dispatch, simulator } = this.props;
dispatch(actions.simulate(simulator));
}
toggleSimulation(simKey) {
const { dispatch, simulation, simulator } = this.props;
if (simulation[simKey]) {
this.disableSimulation();
} else {
dispatch(actions.simulate(simulator, [simKey]));
}
}
render() {
const { simulation } = this.props;
const simulationMenuButtonId = "simulation-menu-button";
const toolbarLabelID = "accessibility-simulation-label";
const currSimulation = Object.entries(simulation).find(
simEntry => simEntry[1]
);
const items = [
// No simulation option
MenuItem({
key: "simulation-none",
label: L10N.getStr(SIMULATION_MENU_LABELS.NONE),
checked: !currSimulation,
onClick: this.disableSimulation,
}),
hr(),
// Simulation options
...Object.keys(SIMULATION_TYPE).map(simType =>
MenuItem({
key: `simulation-${simType}`,
label: L10N.getStr(SIMULATION_MENU_LABELS[simType]),
checked: simulation[simType],
onClick: this.toggleSimulation.bind(this, simType),
})
),
hr(),
// Documentation link
MenuItem({
className: "link",
key: "simulation-documentation",
label: L10N.getStr(SIMULATION_MENU_LABELS.DOCUMENTATION),
role: "link",
onClick: () => openDocLink(A11Y_SIMULATION_DOCUMENTATION_LINK),
}),
];
return div(
{
role: "group",
className: "accessibility-simulation",
"aria-labelledby": toolbarLabelID,
},
span(
{ id: toolbarLabelID, role: "presentation" },
L10N.getStr("accessibility.simulation")
),
MenuButton(
{
id: simulationMenuButtonId,
menuId: simulationMenuButtonId + "-menu",
className: `devtools-button toolbar-menu-button simulation${
currSimulation ? " active" : ""
}`,
doc: document,
label: L10N.getStr(
SIMULATION_MENU_LABELS[currSimulation ? currSimulation[0] : "NONE"]
),
},
MenuList({}, items)
)
);
}
}
const mapStateToProps = ({ simulation }) => {
return { simulation };
};
// Exports from this module
module.exports = connect(mapStateToProps)(SimulationMenuButton);

Просмотреть файл

@ -19,6 +19,9 @@ const AccessibilityTreeFilter = createFactory(
require("./AccessibilityTreeFilter")
);
const AccessibilityPrefs = createFactory(require("./AccessibilityPrefs"));
loader.lazyGetter(this, "SimulationMenuButton", function() {
return createFactory(require("./SimulationMenuButton"));
});
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { disable, updateCanBeDisabled } = require("../actions/ui");
@ -30,6 +33,7 @@ class Toolbar extends Component {
dispatch: PropTypes.func.isRequired,
accessibility: PropTypes.object.isRequired,
canBeDisabled: PropTypes.bool.isRequired,
simulator: PropTypes.object,
};
}
@ -72,7 +76,7 @@ class Toolbar extends Component {
}
render() {
const { canBeDisabled, accessibilityWalker } = this.props;
const { canBeDisabled, accessibilityWalker, simulator } = this.props;
const { disabling } = this.state;
const disableButtonStr = disabling
? "accessibility.disabling"
@ -88,6 +92,16 @@ class Toolbar extends Component {
title = L10N.getStr("accessibility.disable.disabledTitle");
}
const optionalSimulationSection = simulator
? [
div({
role: "separator",
className: "devtools-separator",
}),
SimulationMenuButton({ simulator }),
]
: [];
return div(
{
className: "devtools-toolbar",
@ -118,6 +132,8 @@ class Toolbar extends Component {
L10N.getStr("accessibility.beta")
),
AccessibilityTreeFilter({ accessibilityWalker, describedby: betaID }),
// Simulation section is shown if webrender is enabled
...optionalSimulationSection,
AccessibilityPrefs()
);
}

Просмотреть файл

@ -25,6 +25,7 @@ DevToolsModules(
'LearnMoreLink.js',
'MainFrame.js',
'RightSidebar.js',
'SimulationMenuButton.js',
'TextLabelBadge.js',
'TextLabelCheck.js',
'Toolbar.js'

Просмотреть файл

@ -69,6 +69,7 @@ exports.FILTER_TOGGLE = "FILTER_TOGGLE";
exports.AUDIT = "AUDIT";
exports.AUDITING = "AUDITING";
exports.AUDIT_PROGRESS = "AUDIT_PROGRESS";
exports.SIMULATE = "SIMULATE";
// List of filters for accessibility checks.
exports.FILTERS = {
@ -122,6 +123,8 @@ exports.A11Y_LEARN_MORE_LINK =
exports.A11Y_CONTRAST_LEARN_MORE_LINK =
"https://developer.mozilla.org/docs/Web/Accessibility/Understanding_WCAG/Perceivable/" +
"Color_contrast?utm_source=devtools&utm_medium=a11y-panel-checks-color-contrast";
exports.A11Y_SIMULATION_DOCUMENTATION_LINK =
"https://developer.mozilla.org/docs/Tools/Accessibility_inspector/Simulation";
const A11Y_TEXT_LABEL_LINK_BASE =
"https://developer.mozilla.org/docs/Web/Accessibility/Understanding_WCAG/Text_labels_and_names" +

Просмотреть файл

@ -94,6 +94,10 @@ AccessibilityPanel.prototype = {
this.picker = new Picker(this);
}
if (this.supports.simulation) {
this.simulator = await this.front.getSimulator();
}
this.fluentBundles = await this.createFluentBundles();
this.updateA11YServiceDurationTimer();
@ -168,13 +172,13 @@ AccessibilityPanel.prototype = {
}
// Alright reset the flag we are about to refresh the panel.
this.shouldRefresh = false;
this.postContentMessage(
"initialize",
this.front,
this.walker,
this.supports,
this.fluentBundles
);
this.postContentMessage("initialize", {
front: this.front,
walker: this.walker,
supports: this.supports,
fluentBundles: this.fluentBundles,
simulator: this.simulator,
});
},
updateA11YServiceDurationTimer() {

Просмотреть файл

@ -6,11 +6,13 @@
const { accessibles } = require("./accessibles");
const { audit } = require("./audit");
const { details } = require("./details");
const { simulation } = require("./simulation");
const { ui } = require("./ui");
exports.reducers = {
accessibles,
audit,
details,
simulation,
ui,
};

Просмотреть файл

@ -7,5 +7,6 @@ DevToolsModules(
'audit.js',
'details.js',
'index.js',
'simulation.js',
'ui.js'
)

Просмотреть файл

@ -0,0 +1,60 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {
accessibility: { SIMULATION_TYPE },
} = require("devtools/shared/constants");
const { SIMULATE } = require("devtools/client/accessibility/constants");
/**
* Initial state definition
*/
function getInitialState() {
return {
[SIMULATION_TYPE.PROTANOMALY]: false,
[SIMULATION_TYPE.DEUTERANOMALY]: false,
[SIMULATION_TYPE.TRITANOMALY]: false,
[SIMULATION_TYPE.PROTANOPIA]: false,
[SIMULATION_TYPE.DEUTERANOPIA]: false,
[SIMULATION_TYPE.TRITANOPIA]: false,
[SIMULATION_TYPE.CONTRAST_LOSS]: false,
};
}
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:
const simTypes = action.simTypes;
if (simTypes.length === 0) {
return getInitialState();
}
const updatedState = getInitialState();
simTypes.forEach(simType => {
updatedState[simType] = true;
});
return updatedState;
default:
return state;
}
}
exports.simulation = simulation;

Просмотреть файл

@ -26,6 +26,7 @@ skip-if = (os == 'linux' && debug && bits == 64) # Bug 1511247
[browser_accessibility_reload.js]
[browser_accessibility_sidebar_checks.js]
[browser_accessibility_sidebar.js]
[browser_accessibility_simulation.js]
[browser_accessibility_tree_audit_long.js]
[browser_accessibility_tree_audit_reset.js]
[browser_accessibility_tree_audit_toolbar.js]

Просмотреть файл

@ -0,0 +1,120 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
/* global openSimulationMenu, toggleSimulationOption */
const {
isWebRenderEnabled,
} = require("devtools/server/actors/utils/accessibility");
const TEST_URI = `<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Simulations Test</title>
</head>
<body>
<h1 style="color:blue; background-color:rgba(255,255,255,1);">
Top level header
</h1>
<h2 style="color:green; background-color:rgba(255,255,255,1);">
Second level header
</h2>
</body>
</html>`;
if (!isWebRenderEnabled(window)) {
addA11YPanelTask(
"Test that simulation menu button does not exist without WebRender.",
TEST_URI,
async function({ doc }) {
ok(
!doc.querySelector("#simulation-menu-button"),
"Simulation menu is not shown without WebRender."
);
}
);
} else {
/**
* Test data has the format of:
* {
* desc {String} description for better logging
* setup {Function} An optional setup that needs to be performed before
* the state of the simulation components can be checked.
* expected {JSON} An expected states for the simulation components.
* }
*/
const tests = [
{
desc:
"Check that the menu button is inactivate and the menu is closed initially.",
expected: {
simulation: {
buttonActive: false,
},
},
},
{
desc:
"Clicking the menu button shows the menu with No Simulation selected.",
setup: async ({ doc }) => {
await openSimulationMenu(doc);
},
expected: {
simulation: {
buttonActive: false,
checkedOptionIndices: [0],
},
},
},
{
desc:
"Selecting an option renders the menu button active and closes the menu.",
setup: async ({ doc }) => {
await toggleSimulationOption(doc, 2);
},
expected: {
simulation: {
buttonActive: true,
checkedOptionIndices: [2],
},
},
},
{
desc: "Reopening the menu preserves the previously selected option.",
setup: async ({ doc }) => {
await openSimulationMenu(doc);
},
expected: {
simulation: {
buttonActive: true,
checkedOptionIndices: [2],
},
},
},
{
desc:
"Unselecting the option renders the button inactive and closes the menu.",
setup: async ({ doc }) => {
await toggleSimulationOption(doc, 2);
},
expected: {
simulation: {
buttonActive: false,
checkedOptionIndices: [0],
},
},
},
];
/**
* Test that checks state of simulation button and menu when
* options are selected/unselected with web render enabled.
*/
addA11yPanelTestsTask(
tests,
TEST_URI,
"Test selecting and unselecting simulation options updates UI."
);
}

Просмотреть файл

@ -6,7 +6,7 @@
/* global waitUntilState, gBrowser */
/* exported addTestTab, checkTreeState, checkSidebarState, checkAuditState, selectRow,
toggleRow, toggleMenuItem, addA11yPanelTestsTask, reload, navigate */
toggleRow, toggleMenuItem, addA11yPanelTestsTask, reload, navigate, openSimulationMenu, toggleSimulationOption */
"use strict";
@ -36,6 +36,8 @@ const {
// Enable the Accessibility panel
Services.prefs.setBoolPref("devtools.accessibility.enabled", true);
const SIMULATION_MENU_BUTTON_ID = "#simulation-menu-button";
/**
* Enable accessibility service and wait for a11y init event.
* @return {Object} instance of accessibility service.
@ -470,6 +472,42 @@ async function checkToolbarState(doc, activeToolbarFilters) {
ok(hasExpectedStructure, "Toolbar state is correct.");
}
/**
* Check the state of the simulation button and menu components.
* @param {Object} doc Panel document.
* @param {Object} expected Expected states of the simulation components:
* menuVisible, buttonActive, checkedOptionIndices (Optional)
*/
async function checkSimulationState(doc, expected) {
const { buttonActive, checkedOptionIndices } = expected;
const simulationMenuOptions = doc
.querySelector(SIMULATION_MENU_BUTTON_ID + "-menu")
.querySelectorAll(".menuitem");
// Check simulation menu button state
is(
doc.querySelector(SIMULATION_MENU_BUTTON_ID).className,
`devtools-button toolbar-menu-button simulation${
buttonActive ? " active" : ""
}`,
`Simulation menu button contains ${buttonActive ? "active" : "base"} class.`
);
// Check simulation menu options states, if specified
if (checkedOptionIndices) {
simulationMenuOptions.forEach((menuListItem, index) => {
const isChecked = checkedOptionIndices.includes(index);
const button = menuListItem.firstChild;
is(
button.getAttribute("aria-checked"),
isChecked ? "true" : null,
`Simulation option ${index} is ${isChecked ? "" : "not "}selected.`
);
});
}
}
/**
* Focus accessibility properties tree in the a11y inspector sidebar. If focused for the
* first time, the tree will select first rendered node as defult selection for keyboard
@ -590,6 +628,25 @@ async function toggleMenuItem(doc, menuButtonIndex, menuItemIndex) {
);
}
async function openSimulationMenu(doc) {
doc.querySelector(SIMULATION_MENU_BUTTON_ID).click();
await BrowserTestUtils.waitForCondition(() =>
doc
.querySelector(SIMULATION_MENU_BUTTON_ID + "-menu")
.classList.contains("tooltip-visible")
);
}
async function toggleSimulationOption(doc, optionIndex) {
const simulationMenu = doc.querySelector(SIMULATION_MENU_BUTTON_ID + "-menu");
simulationMenu.querySelectorAll(".menuitem")[optionIndex].firstChild.click();
await BrowserTestUtils.waitForCondition(
() => !simulationMenu.classList.contains("tooltip-visible")
);
}
async function findAccessibleFor(
{ toolbox: { target }, panel: { walker: accessibilityWalker } },
selector
@ -648,6 +705,7 @@ async function runA11yPanelTests(tests, env) {
audit,
toolbarPrefValues,
activeToolbarFilters,
simulation,
} = expected;
if (tree) {
await checkTreeState(env.doc, tree);
@ -668,6 +726,10 @@ async function runA11yPanelTests(tests, env) {
if (typeof audit !== "undefined") {
await checkAuditState(env.store, audit);
}
if (simulation) {
await checkSimulationState(env.doc, simulation);
}
}
}

Просмотреть файл

@ -152,6 +152,7 @@ devtools.jar:
skin/images/item-arrow-ltr.svg (themes/images/item-arrow-ltr.svg)
skin/images/dropmarker.svg (themes/images/dropmarker.svg)
skin/boxmodel.css (themes/boxmodel.css)
skin/images/eye.svg (themes/images/eye.svg)
skin/images/geometry-editor.svg (themes/images/geometry-editor.svg)
skin/images/open-inspector.svg (themes/images/open-inspector.svg)
skin/images/more.svg (themes/images/more.svg)

Просмотреть файл

@ -163,7 +163,8 @@ accessibility.badges=Accessibility checks
# LOCALIZATION NOTE (accessibility.filter.none): A title text for the filter
# that is rendered within the accessibility panel toolbar for a menu item that
# resets all filtering in tree.
# resets all filtering in tree, and for the simulation menu item that resets
# applied color matrices to the default matrix.
accessibility.filter.none=None
# LOCALIZATION NOTE (accessibility.filter.all2): A title text for the filter
@ -268,3 +269,38 @@ accessibility.pref.scroll.into.view.label=Scroll into view
# LOCALIZATION NOTE (accessibility.documentation.label): This is the label for
# the Documentation menu item.
accessibility.documentation.label=Documentation…
# LOCALIZATION NOTE (accessibility.simulation): A title text for the toolbar
# within the main accessibility panel that contains a list of simulations for
# vision deficiencies.
accessibility.simulation=Simulate:
# LOCALIZATION NOTE (accessibility.simulation.deuteranomaly): This label is shown
# in the "Simulate" menu in the accessibility panel and represent the deuteranomaly simulation option.
accessibility.simulation.deuteranomaly=Deuteranomaly (low green)
# LOCALIZATION NOTE (accessibility.simulation.protanomaly): This label is shown
# in the "Simulate" menu in the accessibility panel and represent the protanomaly simulation option.
accessibility.simulation.protanomaly=Protanomaly (low red)
# LOCALIZATION NOTE (accessibility.simulation.protanopia): This label is shown
# in the "Simulate" menu in the accessibility panel and represent the protanopia simulation option.
accessibility.simulation.protanopia=Protanopia (no red)
# LOCALIZATION NOTE (accessibility.simulation.deuteranopia): This label is shown
# in the "Simulate" menu in the accessibility panel and represent the deuteranopia simulation option.
accessibility.simulation.deuteranopia=Deuteranopia (no green)
# LOCALIZATION NOTE (accessibility.simulation.tritanopia): This label is shown
# in the "Simulate" menu in the accessibility panel and represent the tritanopia simulation option.
accessibility.simulation.tritanopia=Tritanopia (no blue)
# LOCALIZATION NOTE (accessibility.simulation.tritanomaly): This label is shown
# in the "Simulate" menu in the accessibility panel and represent the tritanomaly simulation option.
accessibility.simulation.tritanomaly=Tritanomaly (low blue)
# LOCALIZATION NOTE (accessibility.simulation.contrastLoss): This label is shown
# in the "Simulate" menu in the accessibility panel and represent the contrast loss simulation option.
# It is also shown in the simulation menu button in the accessibility panel and represent the
# contrast loss simulation option currently selected.
accessibility.simulation.contrastLoss=Contrast loss

Просмотреть файл

@ -0,0 +1,8 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12">
<path d="M6,2.2c-2.1,0-4.3,2-5.1,3.5c-0.1,0.1-0.1,0.3,0,0.4c0.8,1.5,3,3.5,5.1,3.5s4.3-2,5.1-3.5
c0.1-0.1,0.1-0.3,0-0.4C10.3,4.3,8.1,2.2,6,2.2z" stroke="context-stroke" fill="none" stroke-linejoin="round"/>
<path d="M6,7.9C7,7.9,7.9,7,7.9,6S7,4.1,6,4.1S4.1,5,4.1,6S5,7.9,6,7.9z" fill="context-fill"/>
</svg>

После

Ширина:  |  Высота:  |  Размер: 581 B