Backed out 6 changesets (bug 1564968) by yzen's request CLOSED TREE

Backed out changeset 4b7516635108 (bug 1564968)
Backed out changeset c3227d4ff4b3 (bug 1564968)
Backed out changeset 868dbd59c79e (bug 1564968)
Backed out changeset db1a396ab58e (bug 1564968)
Backed out changeset e69163dc4683 (bug 1564968)
Backed out changeset c12857bc6980 (bug 1564968)
This commit is contained in:
Bogdan Tara 2019-08-28 16:06:23 +03:00
parent e1ad0f40a4
commit 02e806d54a
56 changed files with 252 additions and 1754 deletions

View File

@ -708,10 +708,6 @@ body {
}
/* Checks */
.checks .list li:last-of-type {
padding-block-end: 4px;
}
.accessibility-check code {
background-color: var(--accessibility-code-background);
border-radius: 2px;
@ -719,7 +715,7 @@ body {
padding: 0 4px;
}
.accessibility-check .icon {
.accessibility-text-label-check .icon {
display: inline;
-moz-context-properties: fill;
vertical-align: top;
@ -727,11 +723,11 @@ body {
margin-inline-end: 4px;
}
.accessibility-check .icon.FAIL {
.accessibility-text-label-check .icon.fail {
fill: var(--theme-icon-error-color);
}
.accessibility-check .icon.WARNING {
.accessibility-text-label-check .icon.WARNING {
fill: var(--theme-icon-warning-color);
}

View File

@ -44,7 +44,6 @@ const FILTER_LABELS = {
[FILTERS.NONE]: "accessibility.filter.none",
[FILTERS.ALL]: "accessibility.filter.all2",
[FILTERS.CONTRAST]: "accessibility.filter.contrast",
[FILTERS.KEYBOARD]: "accessibility.filter.keyboard",
[FILTERS.TEXT_LABEL]: "accessibility.filter.textLabel",
};

View File

@ -26,10 +26,6 @@ const AUDIT_TYPE_TO_FILTER = {
filterKey: FILTERS.CONTRAST,
validator: validateCheck,
},
[AUDIT_TYPE.KEYBOARD]: {
filterKey: FILTERS.KEYBOARD,
validator: validateCheck,
},
[AUDIT_TYPE.TEXT_LABEL]: {
filterKey: FILTERS.TEXT_LABEL,
validator: validateCheck,

View File

@ -21,10 +21,6 @@ loader.lazyGetter(this, "ContrastBadge", () =>
createFactory(require("./ContrastBadge"))
);
loader.lazyGetter(this, "KeyboardBadge", () =>
createFactory(require("./KeyboardBadge"))
);
loader.lazyGetter(this, "TextLabelBadge", () =>
createFactory(require("./TextLabelBadge"))
);
@ -32,7 +28,6 @@ loader.lazyGetter(this, "TextLabelBadge", () =>
function getComponentForAuditType(type) {
const auditTypeToComponentMap = {
[AUDIT_TYPE.CONTRAST]: ContrastBadge,
[AUDIT_TYPE.KEYBOARD]: KeyboardBadge,
[AUDIT_TYPE.TEXT_LABEL]: TextLabelBadge,
};

View File

@ -1,155 +0,0 @@
/* 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 {
Component,
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const ReactDOM = require("devtools/client/shared/vendor/react-dom-factories");
const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const Localized = createFactory(FluentReact.Localized);
const { openDocLink } = require("devtools/client/shared/link");
const {
accessibility: {
SCORES: { BEST_PRACTICES, FAIL, WARNING },
},
} = require("devtools/shared/constants");
/**
* A map of accessibility scores to the text descriptions of check icons.
*/
const SCORE_TO_ICON_MAP = {
[BEST_PRACTICES]: {
l10nId: "accessibility-best-practices",
src: "chrome://devtools/skin/images/info.svg",
},
[FAIL]: {
l10nId: "accessibility-fail",
src: "chrome://devtools/skin/images/error.svg",
},
[WARNING]: {
l10nId: "accessibility-warning",
src: "chrome://devtools/skin/images/alert.svg",
},
};
/**
* Localized "Learn more" link that opens a new tab with relevant documentation.
*/
class LearnMoreClass extends PureComponent {
static get propTypes() {
return {
href: PropTypes.string,
l10nId: PropTypes.string.isRequired,
onClick: PropTypes.func,
};
}
static get defaultProps() {
return {
href: "#",
l10nId: null,
onClick: LearnMoreClass.openDocOnClick,
};
}
static openDocOnClick(event) {
event.preventDefault();
openDocLink(event.target.href);
}
render() {
const { href, l10nId, onClick } = this.props;
const className = "link";
return Localized({ id: l10nId }, ReactDOM.a({ className, href, onClick }));
}
}
const LearnMore = createFactory(LearnMoreClass);
/**
* Renders icon with text description for the accessibility check.
*
* @param {Object}
* Options:
* - score: value from SCORES from "devtools/shared/constants"
*/
function Icon({ score }) {
const { l10nId, src } = SCORE_TO_ICON_MAP[score];
return Localized(
{ id: l10nId, attrs: { alt: true } },
ReactDOM.img({ src, className: `icon ${score}` })
);
}
/**
* Renders text description of the accessibility check.
*
* @param {Object}
* Options:
* - args: arguments for fluent localized string
* - href: url for the learn more link pointing to MDN
* - l10nId: fluent localization id
*/
function Annotation({ args, href, l10nId }) {
return Localized(
{
id: l10nId,
a: LearnMore({ l10nId: "accessibility-learn-more", href }),
...args,
},
ReactDOM.p({ className: "accessibility-check-annotation" })
);
}
/**
* Component for rendering a check for accessibliity checks section,
* warnings and best practices suggestions association with a given
* accessibility object in the accessibility tree.
*/
class Check extends Component {
static get propTypes() {
return {
getAnnotation: PropTypes.func.isRequired,
id: PropTypes.string.isRequired,
issue: PropTypes.string.isRequired,
score: PropTypes.string.isRequired,
};
}
render() {
const { getAnnotation, id, issue, score } = this.props;
return ReactDOM.div(
{
role: "presentation",
className: "accessibility-check",
},
Localized(
{
id,
},
ReactDOM.h3({ className: "accessibility-check-header" })
),
ReactDOM.div(
{
role: "presentation",
},
Icon({ score }),
Annotation({ ...getAnnotation(issue) })
)
);
}
}
module.exports = Check;

View File

@ -19,7 +19,6 @@ const ColorContrastCheck = createFactory(
require("./ColorContrastAccessibility").ColorContrastCheck
);
const TextLabelCheck = createFactory(require("./TextLabelCheck"));
const KeyboardCheck = createFactory(require("./KeyboardCheck"));
const { L10N } = require("../utils/l10n");
const {
@ -50,10 +49,6 @@ class Checks extends Component {
return ColorContrastCheck(contrastRatio);
}
[AUDIT_TYPE.KEYBOARD](keyboardCheck) {
return KeyboardCheck(keyboardCheck);
}
[AUDIT_TYPE.TEXT_LABEL](textLabelCheck) {
return TextLabelCheck(textLabelCheck);
}

View File

@ -5,8 +5,8 @@
// React
const {
Component,
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -23,7 +23,7 @@ loader.lazyGetter(this, "Badge", () => createFactory(require("./Badge")));
* failures association with a given accessibility object in the accessibility
* tree.
*/
class ContrastBadge extends PureComponent {
class ContrastBadge extends Component {
static get propTypes() {
return {
error: PropTypes.string,
@ -33,7 +33,11 @@ class ContrastBadge extends PureComponent {
render() {
const { error, score } = this.props;
if (error || score !== SCORES.FAIL) {
if (error) {
return null;
}
if (score !== SCORES.FAIL) {
return null;
}

View File

@ -1,49 +0,0 @@
/* 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,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { L10N } = require("../utils/l10n");
const {
accessibility: {
SCORES: { BEST_PRACTICES, FAIL, WARNING },
},
} = require("devtools/shared/constants");
loader.lazyGetter(this, "Badge", () => createFactory(require("./Badge")));
/**
* Component for rendering a badge for keyboard accessibliity check failures
* association with a given accessibility object in the accessibility tree.
*/
class KeyboardBadge extends PureComponent {
static get propTypes() {
return {
error: PropTypes.string,
score: PropTypes.string,
};
}
render() {
const { error, score } = this.props;
if (error || ![BEST_PRACTICES, FAIL, WARNING].includes(score)) {
return null;
}
return Badge({
label: L10N.getStr("accessibility.badge.keyboard"),
tooltip: L10N.getStr("accessibility.badge.keyboard.tooltip"),
});
}
}
module.exports = KeyboardBadge;

View File

@ -1,87 +0,0 @@
/* 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,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const ReactDOM = require("devtools/client/shared/vendor/react-dom-factories");
const Check = createFactory(
require("devtools/client/accessibility/components/Check")
);
const { A11Y_KEYBOARD_LINKS } = require("../constants");
const {
accessibility: {
AUDIT_TYPE: { KEYBOARD },
ISSUE_TYPE: {
[KEYBOARD]: {
FOCUSABLE_NO_SEMANTICS,
FOCUSABLE_POSITIVE_TABINDEX,
INTERACTIVE_NO_ACTION,
INTERACTIVE_NOT_FOCUSABLE,
NO_FOCUS_VISIBLE,
},
},
},
} = require("devtools/shared/constants");
/**
* A map from text label issues to annotation component properties.
*/
const ISSUE_TO_ANNOTATION_MAP = {
[FOCUSABLE_NO_SEMANTICS]: {
href: A11Y_KEYBOARD_LINKS.FOCUSABLE_NO_SEMANTICS,
l10nId: "accessibility-keyboard-issue-semantics",
},
[FOCUSABLE_POSITIVE_TABINDEX]: {
href: A11Y_KEYBOARD_LINKS.FOCUSABLE_POSITIVE_TABINDEX,
l10nId: "accessibility-keyboard-issue-tabindex",
args: {
get code() {
return ReactDOM.code({}, "tabindex");
},
},
},
[INTERACTIVE_NO_ACTION]: {
href: A11Y_KEYBOARD_LINKS.INTERACTIVE_NO_ACTION,
l10nId: "accessibility-keyboard-issue-action",
},
[INTERACTIVE_NOT_FOCUSABLE]: {
href: A11Y_KEYBOARD_LINKS.INTERACTIVE_NOT_FOCUSABLE,
l10nId: "accessibility-keyboard-issue-focusable",
},
[NO_FOCUS_VISIBLE]: {
href: A11Y_KEYBOARD_LINKS.NO_FOCUS_VISIBLE,
l10nId: "accessibility-keyboard-issue-focus-visible",
},
};
/**
* Component for rendering a check for text label accessibliity check failures,
* warnings and best practices suggestions association with a given
* accessibility object in the accessibility tree.
*/
class KeyboardCheck extends PureComponent {
static get propTypes() {
return {
issue: PropTypes.string.isRequired,
score: PropTypes.string.isRequired,
};
}
render() {
return Check({
...this.props,
getAnnotation: issue => ISSUE_TO_ANNOTATION_MAP[issue],
id: "accessibility-keyboard-header",
});
}
}
module.exports = KeyboardCheck;

View File

@ -6,8 +6,8 @@
// React
const {
Component,
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -26,7 +26,7 @@ loader.lazyGetter(this, "Badge", () => createFactory(require("./Badge")));
* failures association with a given accessibility object in the accessibility
* tree.
*/
class TextLabelBadge extends PureComponent {
class TextLabelBadge extends Component {
static get propTypes() {
return {
error: PropTypes.string,
@ -36,7 +36,11 @@ class TextLabelBadge extends PureComponent {
render() {
const { error, score } = this.props;
if (error || ![BEST_PRACTICES, FAIL, WARNING].includes(score)) {
if (error) {
return null;
}
if (![BEST_PRACTICES, FAIL, WARNING].includes(score)) {
return null;
}

View File

@ -5,17 +5,19 @@
// React
const {
Component,
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const ReactDOM = require("devtools/client/shared/vendor/react-dom-factories");
const Check = createFactory(
require("devtools/client/accessibility/components/Check")
);
const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const Localized = createFactory(FluentReact.Localized);
const { openDocLink } = require("devtools/client/shared/link");
const { A11Y_TEXT_LABEL_LINKS } = require("../constants");
const {
accessibility: {
AUDIT_TYPE: { TEXT_LABEL },
@ -41,6 +43,7 @@ const {
TOOLBAR_NO_NAME,
},
},
SCORES: { BEST_PRACTICES, FAIL, WARNING },
},
} = require("devtools/shared/constants");
@ -198,12 +201,102 @@ const ISSUE_TO_ANNOTATION_MAP = {
},
};
/**
* A map of accessibility scores to the text descriptions of check icons.
*/
const SCORE_TO_ICON_MAP = {
[BEST_PRACTICES]: {
l10nId: "accessibility-best-practices",
src: "chrome://devtools/skin/images/info.svg",
},
[FAIL]: {
l10nId: "accessibility-fail",
src: "chrome://devtools/skin/images/error.svg",
},
[WARNING]: {
l10nId: "accessibility-warning",
src: "chrome://devtools/skin/images/alert.svg",
},
};
/**
* Localized "Learn more" link that opens a new tab with relevant documentation.
*/
class LearnMoreClass extends Component {
static get propTypes() {
return {
href: PropTypes.string,
l10nId: PropTypes.string.isRequired,
onClick: PropTypes.func,
};
}
static get defaultProps() {
return {
href: "#",
l10nId: null,
onClick: LearnMoreClass.openDocOnClick,
};
}
static openDocOnClick(event) {
event.preventDefault();
openDocLink(event.target.href);
}
render() {
const { href, l10nId, onClick } = this.props;
const className = "link";
return Localized({ id: l10nId }, ReactDOM.a({ className, href, onClick }));
}
}
const LearnMore = createFactory(LearnMoreClass);
/**
* Renders icon with text description for the text label accessibility check.
*
* @param {Object}
* Options:
* - score: value from SCORES from "devtools/shared/constants"
*/
function Icon({ score }) {
const { l10nId, src } = SCORE_TO_ICON_MAP[score];
return Localized(
{ id: l10nId, attrs: { alt: true } },
ReactDOM.img({ src, className: `icon ${score}` })
);
}
/**
* Renders text description of the text label accessibility check.
*
* @param {Object}
* Options:
* - issue: value from ISSUE_TYPE[AUDIT_TYPE.TEXT_LABEL] from
* "devtools/shared/constants"
*/
function Annotation({ issue }) {
const { args, href, l10nId } = ISSUE_TO_ANNOTATION_MAP[issue];
return Localized(
{
id: l10nId,
a: LearnMore({ l10nId: "accessibility-learn-more", href }),
...args,
},
ReactDOM.p({ className: "accessibility-check-annotation" })
);
}
/**
* Component for rendering a check for text label accessibliity check failures,
* warnings and best practices suggestions association with a given
* accessibility object in the accessibility tree.
*/
class TextLabelCheck extends PureComponent {
class TextLabelCheck extends Component {
static get propTypes() {
return {
issue: PropTypes.string.isRequired,
@ -212,11 +305,28 @@ class TextLabelCheck extends PureComponent {
}
render() {
return Check({
...this.props,
getAnnotation: issue => ISSUE_TO_ANNOTATION_MAP[issue],
id: "accessibility-text-label-header",
});
const { issue, score } = this.props;
return ReactDOM.div(
{
role: "presentation",
className: "accessibility-check",
},
Localized(
{
id: "accessibility-text-label-header",
},
ReactDOM.h3({ className: "accessibility-check-header" })
),
ReactDOM.div(
{
role: "presentation",
className: "accessibility-text-label-check",
},
Icon({ score }),
Annotation({ issue })
)
);
}
}

View File

@ -15,13 +15,10 @@ DevToolsModules(
'Badge.js',
'Badges.js',
'Button.js',
'Check.js',
'Checks.js',
'ColorContrastAccessibility.js',
'ContrastBadge.js',
'Description.js',
'KeyboardBadge.js',
'KeyboardCheck.js',
'LearnMoreLink.js',
'MainFrame.js',
'RightSidebar.js',

View File

@ -7,13 +7,6 @@ const {
accessibility: {
AUDIT_TYPE,
ISSUE_TYPE: {
[AUDIT_TYPE.KEYBOARD]: {
FOCUSABLE_NO_SEMANTICS,
FOCUSABLE_POSITIVE_TABINDEX,
INTERACTIVE_NO_ACTION,
INTERACTIVE_NOT_FOCUSABLE,
NO_FOCUS_VISIBLE,
},
[AUDIT_TYPE.TEXT_LABEL]: {
AREA_NO_NAME_FROM_ALT,
DIALOG_NO_NAME,
@ -75,7 +68,6 @@ exports.FILTERS = {
NONE: "NONE",
ALL: "ALL",
[AUDIT_TYPE.CONTRAST]: "CONTRAST",
[AUDIT_TYPE.KEYBOARD]: "KEYBOARD",
[AUDIT_TYPE.TEXT_LABEL]: "TEXT_LABEL",
};
@ -159,29 +151,6 @@ for (const key in A11Y_TEXT_LABEL_LINK_IDS) {
}
exports.A11Y_TEXT_LABEL_LINKS = A11Y_TEXT_LABEL_LINKS;
const A11Y_KEYBOARD_LINK_BASE =
"https://developer.mozilla.org/docs/Web/Accessibility/Understanding_WCAG/Keyboard" +
"?utm_source=devtools&utm_medium=a11y-panel-checks-keyboard";
const A11Y_KEYBOARD_LINK_IDS = {
[FOCUSABLE_NO_SEMANTICS]:
"Focusable_elements_should_have_interactive_semantics",
[FOCUSABLE_POSITIVE_TABINDEX]:
"Avoid_using_tabindex_attribute_greater_than_zero",
[INTERACTIVE_NO_ACTION]:
"Interactive_elements_must_be_able_to_be_activated_using_a_keyboard",
[INTERACTIVE_NOT_FOCUSABLE]: "Interactive_elements_must_be_focusable",
[NO_FOCUS_VISIBLE]: "Focusable_element_must_have_focus_styling",
};
const A11Y_KEYBOARD_LINKS = {};
for (const key in A11Y_KEYBOARD_LINK_IDS) {
A11Y_KEYBOARD_LINKS[key] = `${A11Y_KEYBOARD_LINK_BASE}#${
A11Y_KEYBOARD_LINK_IDS[key]
}`;
}
exports.A11Y_KEYBOARD_LINKS = A11Y_KEYBOARD_LINKS;
// Lists of preference names and keys.
const PREFS = {
SCROLL_INTO_VIEW: "SCROLL_INTO_VIEW",

View File

@ -25,7 +25,6 @@ function getInitialState() {
filters: {
[FILTERS.ALL]: false,
[FILTERS.CONTRAST]: false,
[FILTERS.KEYBOARD]: false,
[FILTERS.TEXT_LABEL]: false,
},
auditing: [],
@ -40,7 +39,6 @@ function allActiveFilters() {
return {
[FILTERS.ALL]: true,
[FILTERS.CONTRAST]: true,
[FILTERS.KEYBOARD]: true,
[FILTERS.TEXT_LABEL]: true,
};
}
@ -64,10 +62,11 @@ function audit(state = getInitialState(), action) {
[filter]: isToggledToActive,
};
const allAuditTypesActive = Object.values(AUDIT_TYPE)
.filter(filterKey => filters.hasOwnProperty(filterKey))
.every(filterKey => filters[filterKey]);
if (isToggledToActive && !filters[FILTERS.ALL] && allAuditTypesActive) {
if (
isToggledToActive &&
!filters[FILTERS.ALL] &&
Object.values(AUDIT_TYPE).every(filterKey => filters[filterKey])
) {
filters[FILTERS.ALL] = true;
} else if (!isToggledToActive && filters[FILTERS.ALL]) {
filters[FILTERS.ALL] = false;

View File

@ -26,7 +26,7 @@ const tests = [
{
desc: "Check initial state.",
expected: {
activeToolbarFilters: [true, false, false, false, false],
activeToolbarFilters: [true, false, false, false],
},
},
{
@ -35,7 +35,7 @@ const tests = [
await toggleMenuItem(doc, 0, 1);
},
expected: {
activeToolbarFilters: [false, true, true, true, true],
activeToolbarFilters: [false, true, true, true],
},
},
{
@ -44,7 +44,7 @@ const tests = [
await toggleMenuItem(doc, 0, 1);
},
expected: {
activeToolbarFilters: [true, false, false, false, false],
activeToolbarFilters: [true, false, false, false],
},
},
{
@ -53,7 +53,7 @@ const tests = [
await toggleMenuItem(doc, 0, 2);
},
expected: {
activeToolbarFilters: [false, false, true, false, false],
activeToolbarFilters: [false, false, true, false],
},
},
{
@ -62,7 +62,7 @@ const tests = [
await toggleMenuItem(doc, 0, 2);
},
expected: {
activeToolbarFilters: [true, false, false, false, false],
activeToolbarFilters: [true, false, false, false],
},
},
{
@ -71,7 +71,7 @@ const tests = [
await toggleMenuItem(doc, 0, 2);
},
expected: {
activeToolbarFilters: [false, false, true, false, false],
activeToolbarFilters: [false, false, true, false],
},
},
{
@ -80,16 +80,7 @@ const tests = [
await toggleMenuItem(doc, 0, 3);
},
expected: {
activeToolbarFilters: [false, false, true, true, false],
},
},
{
desc: "Toggle third custom filter to activate.",
setup: async ({ doc }) => {
await toggleMenuItem(doc, 0, 4);
},
expected: {
activeToolbarFilters: [false, true, true, true, true],
activeToolbarFilters: [false, true, true, true],
},
},
{
@ -98,7 +89,7 @@ const tests = [
await toggleMenuItem(doc, 0, 0);
},
expected: {
activeToolbarFilters: [true, false, false, false, false],
activeToolbarFilters: [true, false, false, false],
},
},
];

View File

@ -3,10 +3,6 @@
"use strict";
const {
accessibility: { SCORES },
} = require("devtools/shared/constants");
const TEST_URI = `<html>
<head>
<meta charset="utf-8"/>
@ -49,7 +45,7 @@ const tests = [
color: [255, 0, 0, 1],
backgroundColor: [255, 255, 255, 1],
isLargeText: false,
score: SCORES.FAIL,
score: "fail",
},
},
},
@ -67,7 +63,7 @@ const tests = [
color: [0, 0, 255, 1],
backgroundColor: [255, 255, 255, 1],
isLargeText: false,
score: SCORES.AAA,
score: "AAA",
},
},
},

View File

@ -40,7 +40,7 @@ const tests = [
selected: true,
},
],
activeToolbarFilters: [true, false, false, false, false],
activeToolbarFilters: [true, false, false, false],
},
},
{
@ -62,7 +62,7 @@ const tests = [
badges: ["contrast"],
},
],
activeToolbarFilters: [false, true, true, true, true],
activeToolbarFilters: [false, true, true, true],
},
},
{
@ -96,7 +96,7 @@ const tests = [
badges: ["contrast"],
},
],
activeToolbarFilters: [true, false, false, false, false],
activeToolbarFilters: [true, false, false, false],
},
},
];

View File

@ -20,11 +20,11 @@ exports[`AccessibilityTreeFilter component: render filters after state changes 3
exports[`AccessibilityTreeFilter component: render filters after state changes 4`] = `"<div role=\\"group\\" class=\\"accessibility-tree-filters\\" aria-labelledby=\\"accessibility-tree-filters-label\\"><span id=\\"accessibility-tree-filters-label\\" role=\\"presentation\\">accessibility.tree.filters</span><button class=\\"devtools-button badge toolbar-menu-button filters\\" aria-expanded=\\"false\\" aria-haspopup=\\"menu\\" aria-controls=\\"accessibility-tree-filters-menu\\">accessibility.filter.all2</button></div>"`;
exports[`AccessibilityTreeFilter component: render filters after state changes 5`] = `"<div role=\\"group\\" class=\\"accessibility-tree-filters\\" aria-labelledby=\\"accessibility-tree-filters-label\\"><span id=\\"accessibility-tree-filters-label\\" role=\\"presentation\\">accessibility.tree.filters</span><button class=\\"devtools-button badge toolbar-menu-button filters\\" aria-expanded=\\"false\\" aria-haspopup=\\"menu\\" aria-controls=\\"accessibility-tree-filters-menu\\">accessibility.filter.keyboard, accessibility.filter.textLabel</button></div>"`;
exports[`AccessibilityTreeFilter component: render filters after state changes 5`] = `"<div role=\\"group\\" class=\\"accessibility-tree-filters\\" aria-labelledby=\\"accessibility-tree-filters-label\\"><span id=\\"accessibility-tree-filters-label\\" role=\\"presentation\\">accessibility.tree.filters</span><button class=\\"devtools-button badge toolbar-menu-button filters\\" aria-expanded=\\"false\\" aria-haspopup=\\"menu\\" aria-controls=\\"accessibility-tree-filters-menu\\">accessibility.filter.textLabel</button></div>"`;
exports[`AccessibilityTreeFilter component: render filters after state changes 6`] = `"<div role=\\"group\\" class=\\"accessibility-tree-filters\\" aria-labelledby=\\"accessibility-tree-filters-label\\"><span id=\\"accessibility-tree-filters-label\\" role=\\"presentation\\">accessibility.tree.filters</span><button class=\\"devtools-button badge toolbar-menu-button filters\\" aria-expanded=\\"false\\" aria-haspopup=\\"menu\\" aria-controls=\\"accessibility-tree-filters-menu\\">accessibility.filter.keyboard, accessibility.filter.textLabel</button></div>"`;
exports[`AccessibilityTreeFilter component: render filters after state changes 6`] = `"<div role=\\"group\\" class=\\"accessibility-tree-filters\\" aria-labelledby=\\"accessibility-tree-filters-label\\"><span id=\\"accessibility-tree-filters-label\\" role=\\"presentation\\">accessibility.tree.filters</span><button class=\\"devtools-button badge toolbar-menu-button filters\\" aria-expanded=\\"false\\" aria-haspopup=\\"menu\\" aria-controls=\\"accessibility-tree-filters-menu\\">accessibility.filter.textLabel</button></div>"`;
exports[`AccessibilityTreeFilter component: render filters after state changes 7`] = `"<div role=\\"group\\" class=\\"accessibility-tree-filters\\" aria-labelledby=\\"accessibility-tree-filters-label\\"><span id=\\"accessibility-tree-filters-label\\" role=\\"presentation\\">accessibility.tree.filters</span><button class=\\"devtools-button badge toolbar-menu-button filters\\" aria-expanded=\\"false\\" aria-haspopup=\\"menu\\" aria-controls=\\"accessibility-tree-filters-menu\\">accessibility.filter.keyboard, accessibility.filter.textLabel</button></div>"`;
exports[`AccessibilityTreeFilter component: render filters after state changes 7`] = `"<div role=\\"group\\" class=\\"accessibility-tree-filters\\" aria-labelledby=\\"accessibility-tree-filters-label\\"><span id=\\"accessibility-tree-filters-label\\" role=\\"presentation\\">accessibility.tree.filters</span><button class=\\"devtools-button badge toolbar-menu-button filters\\" aria-expanded=\\"false\\" aria-haspopup=\\"menu\\" aria-controls=\\"accessibility-tree-filters-menu\\">accessibility.filter.textLabel</button></div>"`;
exports[`AccessibilityTreeFilter component: render filters after state changes 8`] = `"<div role=\\"group\\" class=\\"accessibility-tree-filters\\" aria-labelledby=\\"accessibility-tree-filters-label\\"><span id=\\"accessibility-tree-filters-label\\" role=\\"presentation\\">accessibility.tree.filters</span><button class=\\"devtools-button badge toolbar-menu-button filters\\" aria-expanded=\\"false\\" aria-haspopup=\\"menu\\" aria-controls=\\"accessibility-tree-filters-menu\\">accessibility.filter.all2</button></div>"`;

View File

@ -1,5 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Check component: basic render 1`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/error.svg\\" class=\\"icon FAIL\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`Check component: basic render 2`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/error.svg\\" class=\\"icon FAIL\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;

View File

@ -1,7 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`KeyboardBadge component: error render 1`] = `null`;
exports[`KeyboardBadge component: fail render 1`] = `"<span class=\\"audit-badge badge\\" title=\\"accessibility.badge.keyboard.tooltip\\" aria-label=\\"accessibility.badge.keyboard\\">accessibility.badge.keyboard</span>"`;
exports[`KeyboardBadge component: warning render 1`] = `"<span class=\\"audit-badge badge\\" title=\\"accessibility.badge.keyboard.tooltip\\" aria-label=\\"accessibility.badge.keyboard\\">accessibility.badge.keyboard</span>"`;

View File

@ -1,9 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`KeyboardCheck component: FAIL render 1`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/error.svg\\" class=\\"icon FAIL\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`KeyboardCheck component: FAIL render 2`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/error.svg\\" class=\\"icon FAIL\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`KeyboardCheck component: WARNING render 1`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/alert.svg\\" class=\\"icon WARNING\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`KeyboardCheck component: WARNING render 2`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/alert.svg\\" class=\\"icon WARNING\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;

View File

@ -1,13 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`TextLabelCheck component: BEST_PRACTICES render 1`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/info.svg\\" class=\\"icon BEST_PRACTICES\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`TextLabelCheck component: BEST_PRACTICES render 1`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\" class=\\"accessibility-text-label-check\\"><img src=\\"chrome://devtools/skin/images/info.svg\\" class=\\"icon BEST_PRACTICES\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`TextLabelCheck component: BEST_PRACTICES render 2`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/info.svg\\" class=\\"icon BEST_PRACTICES\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`TextLabelCheck component: WARNING render 1`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\" class=\\"accessibility-text-label-check\\"><img src=\\"chrome://devtools/skin/images/alert.svg\\" class=\\"icon WARNING\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`TextLabelCheck component: FAIL render 1`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/error.svg\\" class=\\"icon FAIL\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`TextLabelCheck component: FAIL render 2`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/error.svg\\" class=\\"icon FAIL\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`TextLabelCheck component: WARNING render 1`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/alert.svg\\" class=\\"icon WARNING\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`TextLabelCheck component: WARNING render 2`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\"><img src=\\"chrome://devtools/skin/images/alert.svg\\" class=\\"icon WARNING\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;
exports[`TextLabelCheck component: fail render 1`] = `"<div role=\\"presentation\\" class=\\"accessibility-check\\"><h3 class=\\"accessibility-check-header\\"></h3><div role=\\"presentation\\" class=\\"accessibility-text-label-check\\"><img src=\\"chrome://devtools/skin/images/error.svg\\" class=\\"icon fail\\"><p class=\\"accessibility-check-annotation\\"></p></div></div>"`;

View File

@ -82,11 +82,6 @@ describe("AccessibilityTreeFilter component:", () => {
disabled: false,
text: "accessibility.filter.contrast",
},
{
active: false,
disabled: false,
text: "accessibility.filter.keyboard",
},
{
active: false,
disabled: false,
@ -103,7 +98,6 @@ describe("AccessibilityTreeFilter component:", () => {
filters: {
[FILTERS.ALL]: true,
[FILTERS.CONTRAST]: true,
[FILTERS.KEYBOARD]: true,
[FILTERS.TEXT_LABEL]: true,
},
auditing: [],
@ -118,7 +112,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: true, disabled: false },
{ active: true, disabled: false },
{ active: true, disabled: false },
{ active: true, disabled: false },
],
});
});
@ -151,7 +144,6 @@ describe("AccessibilityTreeFilter component:", () => {
filters: {
[FILTERS.ALL]: false,
[FILTERS.CONTRAST]: false,
[FILTERS.KEYBOARD]: false,
[FILTERS.TEXT_LABEL]: false,
},
auditing: [FILTERS.CONTRAST],
@ -166,7 +158,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: false },
{ active: false, disabled: true },
{ active: false, disabled: false },
{ active: false, disabled: false },
],
});
});
@ -195,7 +186,6 @@ describe("AccessibilityTreeFilter component:", () => {
filters: {
[FILTERS.ALL]: false,
[FILTERS.CONTRAST]: true,
[FILTERS.KEYBOARD]: false,
[FILTERS.TEXT_LABEL]: false,
},
auditing: [FILTERS.CONTRAST],
@ -210,7 +200,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: false },
{ active: true, disabled: true },
{ active: false, disabled: false },
{ active: false, disabled: false },
],
});
});
@ -237,7 +226,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
],
},
},
@ -252,7 +240,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: true },
{ active: false, disabled: true },
{ active: false, disabled: true },
{ active: false, disabled: true },
],
},
},
@ -267,7 +254,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
],
},
},
@ -282,7 +268,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: true, disabled: false },
{ active: true, disabled: false },
{ active: true, disabled: false },
{ active: true, disabled: false },
],
},
},
@ -297,7 +282,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: true, disabled: false },
{ active: true, disabled: false },
],
},
},
@ -312,7 +296,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: false },
{ active: false, disabled: true },
{ active: true, disabled: false },
{ active: true, disabled: false },
],
},
},
@ -327,7 +310,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: true, disabled: false },
{ active: true, disabled: false },
],
},
},
@ -342,7 +324,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: true, disabled: false },
{ active: true, disabled: false },
{ active: true, disabled: false },
{ active: true, disabled: false },
],
},
},
@ -357,7 +338,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
],
},
},
@ -371,7 +351,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: true, disabled: true },
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: true },
],
},
@ -387,7 +366,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
],
},
},
@ -401,7 +379,6 @@ describe("AccessibilityTreeFilter component:", () => {
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: false, disabled: false },
{ active: true, disabled: false },
],
},

View File

@ -19,10 +19,6 @@ const {
} = require("devtools/client/accessibility/test/jest/helpers");
const { FILTERS } = require("devtools/client/accessibility/constants");
const {
accessibility: { SCORES },
} = require("devtools/shared/constants");
describe("AuditController component:", () => {
it("audit filter not filtered", () => {
const store = setupStore();
@ -71,7 +67,7 @@ describe("AuditController component:", () => {
color: [255, 0, 0, 1],
backgroundColor: [255, 255, 255, 1],
isLargeText: false,
score: SCORES.AA,
score: "AA",
},
},
},
@ -93,7 +89,7 @@ describe("AuditController component:", () => {
color: [255, 0, 0, 1],
backgroundColor: [255, 255, 255, 1],
isLargeText: false,
score: SCORES.FAIL,
score: "fail",
};
const wrapper = mount(
@ -125,7 +121,7 @@ describe("AuditController component:", () => {
backgroundColorMin: [219, 106, 116, 1],
backgroundColorMax: [156, 145, 211, 1],
isLargeText: false,
score: SCORES.FAIL,
score: "fail",
};
const wrapper = mount(

View File

@ -20,10 +20,6 @@ const Badges = createFactory(
);
const ContrastBadge = require("devtools/client/accessibility/components/ContrastBadge");
const {
accessibility: { SCORES },
} = require("devtools/shared/constants");
describe("Badges component:", () => {
const store = setupStore();
@ -62,7 +58,7 @@ describe("Badges component:", () => {
color: [255, 0, 0, 1],
backgroundColor: [255, 255, 255, 1],
isLargeText: false,
score: SCORES.AA,
score: "AA",
},
},
})
@ -78,7 +74,7 @@ describe("Badges component:", () => {
color: [255, 0, 0, 1],
backgroundColor: [255, 255, 255, 1],
isLargeText: false,
score: SCORES.FAIL,
score: "fail",
};
const wrapper = mount(
Provider({ store }, Badges({ checks: { CONTRAST } }))
@ -103,7 +99,7 @@ describe("Badges component:", () => {
backgroundColorMin: [219, 106, 116, 1],
backgroundColorMax: [156, 145, 211, 1],
isLargeText: false,
score: SCORES.FAIL,
score: "fail",
};
const wrapper = mount(
Provider({ store }, Badges({ checks: { CONTRAST } }))

View File

@ -1,48 +0,0 @@
/* 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 { mount } = require("enzyme");
const { createFactory } = require("devtools/client/shared/vendor/react");
const CheckClass = require("devtools/client/accessibility/components/Check");
const Check = createFactory(CheckClass);
const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const LocalizationProvider = createFactory(FluentReact.LocalizationProvider);
const {
accessibility: {
AUDIT_TYPE: { TEXT_LABEL },
ISSUE_TYPE: {
[TEXT_LABEL]: { AREA_NO_NAME_FROM_ALT },
},
SCORES: { FAIL },
},
} = require("devtools/shared/constants");
const {
testCheck,
} = require("devtools/client/accessibility/test/jest/helpers");
describe("Check component:", () => {
const props = {
id: "accessibility-text-label-header",
issue: AREA_NO_NAME_FROM_ALT,
score: FAIL,
getAnnotation: jest.fn(),
};
it("basic render", () => {
const wrapper = mount(LocalizationProvider({ bundles: [] }, Check(props)));
expect(wrapper.html()).toMatchSnapshot();
testCheck(wrapper.childAt(0), {
issue: AREA_NO_NAME_FROM_ALT,
score: FAIL,
});
expect(props.getAnnotation.mock.calls.length).toBe(1);
expect(props.getAnnotation.mock.calls[0]).toEqual([AREA_NO_NAME_FROM_ALT]);
});
});

View File

@ -19,10 +19,6 @@ const Badge = require("devtools/client/accessibility/components/Badge");
const ContrastBadgeClass = require("devtools/client/accessibility/components/ContrastBadge");
const ContrastBadge = createFactory(ContrastBadgeClass);
const {
accessibility: { SCORES },
} = require("devtools/shared/constants");
describe("ContrastBadge component:", () => {
const store = setupStore();
@ -37,7 +33,7 @@ describe("ContrastBadge component:", () => {
ContrastBadge({
value: 5.11,
isLargeText: false,
score: SCORES.AA,
score: "AA",
})
);
expect(wrapper.html()).toMatchSnapshot();
@ -50,7 +46,7 @@ describe("ContrastBadge component:", () => {
min: 5.11,
max: 6.25,
isLargeText: false,
score: SCORES.AA,
score: "AA",
})
);
expect(wrapper.html()).toMatchSnapshot();
@ -62,7 +58,7 @@ describe("ContrastBadge component:", () => {
ContrastBadge({
value: 3.77,
isLargeText: true,
score: SCORES.AA,
score: "AA",
})
);
expect(wrapper.html()).toMatchSnapshot();
@ -76,7 +72,7 @@ describe("ContrastBadge component:", () => {
ContrastBadge({
value: 3.77,
isLargeText: false,
score: SCORES.FAIL,
score: "fail",
})
)
);

View File

@ -1,71 +0,0 @@
/* 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 { shallow, mount } = require("enzyme");
const { createFactory } = require("devtools/client/shared/vendor/react");
const Provider = createFactory(
require("devtools/client/shared/vendor/react-redux").Provider
);
const {
setupStore,
} = require("devtools/client/accessibility/test/jest/helpers");
const Badge = require("devtools/client/accessibility/components/Badge");
const KeyboardBadgeClass = require("devtools/client/accessibility/components/KeyboardBadge");
const KeyboardBadge = createFactory(KeyboardBadgeClass);
const {
accessibility: { SCORES },
} = require("devtools/shared/constants");
function testBadge(wrapper) {
expect(wrapper.html()).toMatchSnapshot();
expect(wrapper.children().length).toBe(1);
const keyboardBadge = wrapper.find(KeyboardBadgeClass);
const badge = keyboardBadge.childAt(0);
expect(badge.type()).toBe(Badge);
expect(badge.props()).toMatchObject({
label: "accessibility.badge.keyboard",
tooltip: "accessibility.badge.keyboard.tooltip",
});
}
describe("KeyboardBadge component:", () => {
const store = setupStore();
it("error render", () => {
const wrapper = shallow(KeyboardBadge({ error: true }));
expect(wrapper.html()).toMatchSnapshot();
expect(wrapper.isEmptyRender()).toBe(true);
});
it("fail render", () => {
const wrapper = mount(
Provider(
{ store },
KeyboardBadge({
score: SCORES.FAIL,
})
)
);
testBadge(wrapper);
});
it("warning render", () => {
const wrapper = mount(
Provider(
{ store },
KeyboardBadge({
score: SCORES.WARNING,
})
)
);
testBadge(wrapper);
});
});

View File

@ -1,45 +0,0 @@
/* 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 { mount } = require("enzyme");
const { createFactory } = require("devtools/client/shared/vendor/react");
const KeyboardCheckClass = require("devtools/client/accessibility/components/KeyboardCheck");
const KeyboardCheck = createFactory(KeyboardCheckClass);
const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const LocalizationProvider = createFactory(FluentReact.LocalizationProvider);
const {
testCustomCheck,
} = require("devtools/client/accessibility/test/jest/helpers");
const {
accessibility: {
AUDIT_TYPE: { KEYBOARD },
ISSUE_TYPE: {
[KEYBOARD]: { INTERACTIVE_NO_ACTION, FOCUSABLE_NO_SEMANTICS },
},
SCORES: { FAIL, WARNING },
},
} = require("devtools/shared/constants");
describe("KeyboardCheck component:", () => {
const testProps = [
{ score: FAIL, issue: INTERACTIVE_NO_ACTION },
{ score: WARNING, issue: FOCUSABLE_NO_SEMANTICS },
];
for (const props of testProps) {
it(`${props.score} render`, () => {
const wrapper = mount(
LocalizationProvider({ bundles: [] }, KeyboardCheck(props))
);
const keyboardCheck = wrapper.find(KeyboardCheckClass);
testCustomCheck(keyboardCheck, props);
});
}
});

View File

@ -12,10 +12,6 @@ const TextLabelCheck = createFactory(TextLabelCheckClass);
const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const LocalizationProvider = createFactory(FluentReact.LocalizationProvider);
const {
testCustomCheck,
} = require("devtools/client/accessibility/test/jest/helpers");
const {
accessibility: {
AUDIT_TYPE: { TEXT_LABEL },
@ -30,6 +26,30 @@ const {
},
} = require("devtools/shared/constants");
function testTextLabelCheck(wrapper, props) {
expect(wrapper.html()).toMatchSnapshot();
expect(wrapper.children().length).toBe(1);
const container = wrapper.childAt(0);
expect(container.hasClass("accessibility-check")).toBe(true);
expect(container.prop("role")).toBe("presentation");
expect(wrapper.props()).toMatchObject(props);
const localized = wrapper.find(FluentReact.Localized);
expect(localized.length).toBe(3);
const heading = localized.at(0).childAt(0);
expect(heading.type()).toBe("h3");
expect(heading.hasClass("accessibility-check-header")).toBe(true);
const icon = localized.at(1).childAt(0);
expect(icon.type()).toBe("img");
expect(icon.hasClass(props.score === FAIL ? "fail" : props.score)).toBe(true);
const annotation = localized.at(2).childAt(0);
expect(annotation.type()).toBe("p");
expect(annotation.hasClass("accessibility-check-annotation")).toBe(true);
}
describe("TextLabelCheck component:", () => {
const testProps = [
{ issue: AREA_NO_NAME_FROM_ALT, score: FAIL },
@ -44,7 +64,7 @@ describe("TextLabelCheck component:", () => {
);
const textLabelCheck = wrapper.find(TextLabelCheckClass);
testCustomCheck(textLabelCheck, props);
testTextLabelCheck(textLabelCheck, props);
});
}
});

View File

@ -4,8 +4,6 @@
"use strict";
const { reducers } = require("devtools/client/accessibility/reducers/index");
const CheckClass = require("devtools/client/accessibility/components/Check");
const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const {
createStore,
@ -72,59 +70,8 @@ function checkMenuItem(menuItem, expected) {
}
}
/**
*
* @param {ReactWrapper}
* React wrapper for the top level check component.
* @param {Object}
* Expected audit properties:
* - score: audit score
* - issue: audit issue type
*/
function testCustomCheck(wrapper, props) {
expect(wrapper.html()).toMatchSnapshot();
expect(wrapper.children().length).toBe(1);
const check = wrapper.childAt(0);
expect(wrapper.find(CheckClass)).toStrictEqual(check);
testCheck(check, props);
}
/**
*
* @param {ReactWrapper}
* React wrapper for the check component.
* @param {Object}
* Expected audit properties:
* - score: audit score
* - issue: audit issue type
*/
function testCheck(wrapper, props) {
expect(wrapper.html()).toMatchSnapshot();
const container = wrapper.childAt(0);
expect(container.hasClass("accessibility-check")).toBe(true);
expect(container.prop("role")).toBe("presentation");
expect(wrapper.props()).toMatchObject(props);
const localized = wrapper.find(FluentReact.Localized);
expect(localized.length).toBe(3);
const heading = localized.at(0).childAt(0);
expect(heading.type()).toBe("h3");
expect(heading.hasClass("accessibility-check-header")).toBe(true);
const icon = localized.at(1).childAt(0);
expect(icon.type()).toBe("img");
expect(icon.hasClass(props.score)).toBe(true);
const annotation = localized.at(2).childAt(0);
expect(annotation.type()).toBe("p");
expect(annotation.hasClass("accessibility-check-annotation")).toBe(true);
}
module.exports = {
checkMenuItem,
mockAccessible,
setupStore,
testCheck,
testCustomCheck,
};

View File

@ -61,7 +61,7 @@ window._snapshots = {
{
type: "span",
props: {
className: "accessibility-contrast-value FAIL",
className: "accessibility-contrast-value fail",
role: "presentation",
style: {
"--accessibility-contrast-color": "rgba(255,0,0,1)",
@ -122,7 +122,7 @@ window._snapshots = {
{
type: "span",
props: {
className: "accessibility-contrast-value FAIL",
className: "accessibility-contrast-value fail",
role: "presentation",
style: {
"--accessibility-contrast-color": "rgba(128,128,128,1)",
@ -142,7 +142,7 @@ window._snapshots = {
{
type: "span",
props: {
className: "accessibility-contrast-value FAIL",
className: "accessibility-contrast-value fail",
role: "presentation",
style: {
"--accessibility-contrast-color": "rgba(128,128,128,1)",

View File

@ -31,10 +31,6 @@ window.onload = async function() {
const { ColorContrastCheck } = browserRequire(
"devtools/client/accessibility/components/ColorContrastAccessibility");
const {
accessibility: { SCORES },
} = browserRequire("devtools/shared/constants");
matchSnapshot("ColorContrastAccessibility error render.",
React.createElement(ColorContrastCheck, { error: true })
);
@ -45,7 +41,7 @@ window.onload = async function() {
"color": [255, 0, 0, 1],
"backgroundColor": [255, 255, 255, 1],
"isLargeText": false,
"score": SCORES.FAIL,
"score": "fail",
})
);
@ -57,9 +53,9 @@ window.onload = async function() {
"backgroundColorMin": [219, 106, 116, 1],
"backgroundColorMax": [156, 145, 211, 1],
"isLargeText": false,
"score": SCORES.FAIL,
"scoreMin": SCORES.FAIL,
"scoreMax": SCORES.FAIL,
"score": "fail",
"scoreMin": "fail",
"scoreMax": "fail",
})
);
@ -69,7 +65,7 @@ window.onload = async function() {
"color": [255, 0, 0, 1],
"backgroundColor": [255, 255, 255, 1],
"isLargeText": true,
"score": SCORES.AA,
"score": "AA",
})
);
} catch (e) {

View File

@ -8,8 +8,6 @@ accessibility-learn-more = Learn more
accessibility-text-label-header = Text Labels and Names
accessibility-keyboard-header = Keyboard
## Text entries that are used as text alternative for icons that depict accessibility isses.
accessibility-warning =
@ -60,17 +58,3 @@ accessibility-text-label-issue-interactive = Interactive elements must be labele
accessibility-text-label-issue-optgroup-label2 = Use a <code>label</code> attribute to label an <span>optgroup</span>. <a>Learn more</a>
accessibility-text-label-issue-toolbar = Toolbars must be labeled when there is more than one toolbar. <a>Learn more</a>
## Text entries for a paragraph used in the accessibility panel sidebar's checks section
## that describe that currently selected accessible object has a keyboard accessibility
## issue.
accessibility-keyboard-issue-semantics = Focusable elements should have interactive semantics. <a>Learn more</a>
accessibility-keyboard-issue-tabindex = Avoid using <code>tabindex</code> attribute greater than zero. <a>Learn more</a>
accessibility-keyboard-issue-action = Interactive elements must be able to be activated using a keyboard. <a>Learn more</a>
accessibility-keyboard-issue-focusable = Interactive elements must be focusable. <a>Learn more</a>
accessibility-keyboard-issue-focus-visible = Focusable element may be missing focus styling. <a>Learn more</a>

View File

@ -146,11 +146,11 @@ accessibility.contrast.annotation.AA=Meets WCAG AA standards for accessible text
# time with the accessibility.learnMore string.
accessibility.contrast.annotation.AAA=Meets WCAG AAA standards for accessible text. %S
# LOCALIZATION NOTE (accessibility.contrast.annotation.FAIL): A title text for the
# LOCALIZATION NOTE (accessibility.contrast.annotation.fail): A title text for the
# paragraph describing that the given colour contrast fails to meet the minimum level from
# Web Content Accessibility Guidelines. %S in the content will be replaced by a link at
# run time with the accessibility.learnMore string.
accessibility.contrast.annotation.FAIL=Does not meet WCAG standards for accessible text. %S
accessibility.contrast.annotation.fail=Does not meet WCAG standards for accessible text. %S
# LOCALIZATION NOTE (accessibility.contrast.annotation.transparent.error): A title text for the
# paragraph suggesting a fix for error in color contrast calculation for text nodes with zero alpha.
@ -181,11 +181,6 @@ accessibility.filter.contrast=Contrast
# filters the tree based on text label and name accessibility failures within it.
accessibility.filter.textLabel=Text Labels
# LOCALIZATION NOTE (accessibility.filter.keyboard): A title text for the filter
# that is rendered within the accessibility panel toolbar for a menu item that
# filters the tree based on keyboard accessibility failures within it.
accessibility.filter.keyboard=Keyboard
# LOCALIZATION NOTE (accessibility.badge.contrast): A title text for the badge
# that is rendered within the accessible row in the accessibility tree for a
# given accessible object that does not satisfy the WCAG guideline for colour
@ -198,12 +193,6 @@ accessibility.badge.contrast=contrast
# WCAG guideline for colour contrast.
accessibility.badge.contrast.warning=contrast warning
# LOCALIZATION NOTE (accessibility.badge.keyboard): A title text for the
# badge that is rendered within the accessible row in the accessibility tree for
# a given accessible object that does not satisfy the WCAG guideline for
# keyboard accessibility.
accessibility.badge.keyboard=keyboard
# LOCALIZATION NOTE (accessibility.badge.textLabel): A title text for the
# badge that is rendered within the accessible row in the accessibility tree for
# a given accessible object that does not satisfy the WCAG guideline for text
@ -216,12 +205,6 @@ accessibility.badge.textLabel=text label
# satisfy the WCAG guideline for colour contrast.
accessibility.badge.contrast.tooltip=Does not meet WCAG standards for accessible text.
# LOCALIZATION NOTE (accessibility.badge.keyboard.tooltip): A title text
# for the badge tooltip that is rendered on mouse hover over the badge in the
# accessible row in the accessibility tree for a given accessible object that
# does not satisfy the WCAG guideline for keyboard accessibility.
accessibility.badge.keyboard.tooltip=Does not meet WCAG standards for keyboard accessibility.
# LOCALIZATION NOTE (accessibility.badge.textLabel.tooltip): A title text
# for the badge tooltip that is rendered on mouse hover over the badge in the
# accessible row in the accessibility tree for a given accessible object that

View File

@ -6,7 +6,7 @@
* Checks panel and color picker tooltip across the Inspector panel.
*
* The section consists of:
* - contrast ratio value (numeric + score badge (AA/AAA/FAIL)):
* - contrast ratio value (numeric + score badge (AA/AAA/fail)):
* Only shows up if contrast ratio can be calculated.
* - large text indicator badge:
* Only shows up if the selected text node contains large text.
@ -31,7 +31,7 @@
}
.accessibility-color-contrast
.accessibility-contrast-value:not(:empty).FAIL:after {
.accessibility-contrast-value:not(:empty).fail:after {
color: #e57180;
content: "⚠️";
}

View File

@ -17,12 +17,6 @@ loader.lazyRequireGetter(
"devtools/server/actors/accessibility/audit/contrast",
true
);
loader.lazyRequireGetter(
this,
"auditKeyboard",
"devtools/server/actors/accessibility/audit/keyboard",
true
);
loader.lazyRequireGetter(
this,
"auditTextLabel",
@ -492,9 +486,6 @@ const AccessibleActor = ActorClassWithSpec(accessibleSpec, {
switch (type) {
case AUDIT_TYPE.CONTRAST:
return this._getContrastRatio();
case AUDIT_TYPE.KEYBOARD:
// Determine if keyboard accessibility is lacking where it is necessary.
return auditKeyboard(this.rawAccessible);
case AUDIT_TYPE.TEXT_LABEL:
// Determine if text alternative is missing for an accessible where it
// is necessary.

View File

@ -1,416 +0,0 @@
/* 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 { Ci, Cu } = require("chrome");
loader.lazyRequireGetter(
this,
"CssLogic",
"devtools/server/actors/inspector/css-logic",
true
);
loader.lazyRequireGetter(
this,
"getCSSStyleRules",
"devtools/shared/inspector/css-logic",
true
);
loader.lazyRequireGetter(this, "InspectorUtils", "InspectorUtils");
loader.lazyRequireGetter(
this,
"nodeConstants",
"devtools/shared/dom-node-constants"
);
const {
accessibility: {
AUDIT_TYPE: { KEYBOARD },
ISSUE_TYPE: {
[KEYBOARD]: {
FOCUSABLE_NO_SEMANTICS,
FOCUSABLE_POSITIVE_TABINDEX,
INTERACTIVE_NO_ACTION,
INTERACTIVE_NOT_FOCUSABLE,
NO_FOCUS_VISIBLE,
},
},
SCORES: { FAIL, WARNING },
},
} = require("devtools/shared/constants");
// Specified by the author CSS rule type.
const STYLE_RULE = 1;
/**
* Focus specific pseudo classes that the keyboard audit simulates to determine
* focus styling.
*/
const FOCUS_PSEUDO_CLASS = ":focus";
const MOZ_FOCUSRING_PSEUDO_CLASS = ":-moz-focusring";
const INTERACTIVE_ROLES = new Set([
Ci.nsIAccessibleRole.ROLE_BUTTONMENU,
Ci.nsIAccessibleRole.ROLE_CHECKBUTTON,
Ci.nsIAccessibleRole.ROLE_CHECK_MENU_ITEM,
Ci.nsIAccessibleRole.ROLE_CHECK_RICH_OPTION,
Ci.nsIAccessibleRole.ROLE_COMBOBOX,
Ci.nsIAccessibleRole.ROLE_COMBOBOX_OPTION,
Ci.nsIAccessibleRole.ROLE_EDITCOMBOBOX,
Ci.nsIAccessibleRole.ROLE_ENTRY,
Ci.nsIAccessibleRole.ROLE_LINK,
Ci.nsIAccessibleRole.ROLE_LISTBOX,
Ci.nsIAccessibleRole.ROLE_MENUITEM,
Ci.nsIAccessibleRole.ROLE_OPTION,
Ci.nsIAccessibleRole.ROLE_PAGETAB,
Ci.nsIAccessibleRole.ROLE_PASSWORD_TEXT,
Ci.nsIAccessibleRole.ROLE_PUSHBUTTON,
Ci.nsIAccessibleRole.ROLE_RADIOBUTTON,
Ci.nsIAccessibleRole.ROLE_RADIO_MENU_ITEM,
Ci.nsIAccessibleRole.ROLE_RICH_OPTION,
Ci.nsIAccessibleRole.ROLE_SLIDER,
Ci.nsIAccessibleRole.ROLE_SPINBUTTON,
Ci.nsIAccessibleRole.ROLE_SWITCH,
Ci.nsIAccessibleRole.ROLE_TOGGLE_BUTTON,
]);
/**
* Determine if a node is dead or is not an element node.
*
* @param {DOMNode} node
* Node to be tested for validity.
*
* @returns {Boolean}
* True if the node is either dead or is not an element node.
*/
function isInvalidNode(node) {
return (
!node ||
Cu.isDeadWrapper(node) ||
node.nodeType !== nodeConstants.ELEMENT_NODE ||
!node.ownerGlobal
);
}
/**
* Determine if a current node has focus specific styling by applying a
* focus-related pseudo class (such as :focus or :-moz-focusring) to a focusable
* node.
*
* @param {DOMNode} focusableNode
* Node to apply focus-related pseudo class to.
* @param {DOMNode} currentNode
* Node to be checked for having focus specific styling.
* @param {String} pseudoClass
* A focus related pseudo-class to be simulated for style comparison.
*
* @returns {Boolean}
* True if the currentNode has focus specific styling.
*/
function hasStylesForFocusRelatedPseudoClass(
focusableNode,
currentNode,
pseudoClass
) {
const defaultRules = getCSSStyleRules(currentNode);
InspectorUtils.addPseudoClassLock(focusableNode, pseudoClass);
// Determine a set of properties that are specific to CSS rules that are only
// present when a focus related pseudo-class is locked in.
const tempRules = getCSSStyleRules(currentNode);
const properties = new Set();
for (const rule of tempRules) {
if (rule.type !== STYLE_RULE) {
continue;
}
if (!defaultRules.includes(rule)) {
for (let index = 0; index < rule.style.length; index++) {
properties.add(rule.style.item(index));
}
}
}
// If there are no focus specific CSS rules or properties, currentNode does
// node have any focus specific styling, we are done.
if (properties.size === 0) {
InspectorUtils.removePseudoClassLock(focusableNode, pseudoClass);
return false;
}
// Determine values for properties that are focus specific.
const tempStyle = CssLogic.getComputedStyle(currentNode);
const focusStyle = {};
for (const name of properties.values()) {
focusStyle[name] = tempStyle.getPropertyValue(name);
}
InspectorUtils.removePseudoClassLock(focusableNode, pseudoClass);
// If values for focus specific properties are different from default style
// values, assume we have focus spefic styles for the currentNode.
const defaultStyle = CssLogic.getComputedStyle(currentNode);
for (const name of properties.values()) {
if (defaultStyle.getPropertyValue(name) !== focusStyle[name]) {
return true;
}
}
return false;
}
/**
* Check if an element node (currentNode) has distinct focus styling. This
* function also takes into account a case when focus styling is applied to a
* descendant too.
*
* @param {DOMNode} focusableNode
* Node to apply focus-related pseudo class to.
* @param {DOMNode} currentNode
* Node to be checked for having focus specific styling.
*
* @returns {Boolean}
* True if the node or its descendant has distinct focus styling.
*/
function hasFocusStyling(focusableNode, currentNode) {
if (isInvalidNode(currentNode)) {
return false;
}
// Check if an element node has distinct :-moz-focusring styling.
const hasStylesForMozFocusring = hasStylesForFocusRelatedPseudoClass(
focusableNode,
currentNode,
MOZ_FOCUSRING_PSEUDO_CLASS
);
if (hasStylesForMozFocusring) {
return true;
}
// Check if an element node has distinct :focus styling.
const hasStylesForFocus = hasStylesForFocusRelatedPseudoClass(
focusableNode,
currentNode,
FOCUS_PSEUDO_CLASS
);
if (hasStylesForFocus) {
return true;
}
// If no element specific focus styles where found, check if its element
// children have them.
for (
let child = currentNode.firstElementChild;
child;
child = currentNode.nextnextElementSibling
) {
if (hasFocusStyling(focusableNode, child)) {
return true;
}
}
return false;
}
/**
* A rule that determines if a focusable accessible object has appropriate focus
* styling.
*
* @param {nsIAccessible} accessible
* Accessible to be checked for being focusable and having focus
* styling.
*
* @return {null|Object}
* Null if accessible has keyboard focus styling, audit report object
* otherwise.
*/
function focusStyleRule(accessible) {
const { DOMNode } = accessible;
if (isInvalidNode(DOMNode)) {
return null;
}
// Ignore non-focusable elements.
const state = {};
accessible.getState(state, {});
if (!(state.value & Ci.nsIAccessibleStates.STATE_FOCUSABLE)) {
return null;
}
if (hasFocusStyling(DOMNode, DOMNode)) {
return null;
}
// If no browser or author focus styling was found, check if the node is a
// widget that is themed by platform native theme.
if (InspectorUtils.isElementThemed(DOMNode)) {
return null;
}
return { score: WARNING, issue: NO_FOCUS_VISIBLE };
}
/**
* A rule that determines if an interactive accessible has any associated
* accessible actions with it. If the element is interactive but and has no
* actions, assistive technology users will not be able to interact with it.
*
* @param {nsIAccessible} accessible
* Accessible to be checked for being interactive and having accessible
* actions.
*
* @return {null|Object}
* Null if accessible is not interactive or if it is and it has
* accessible action associated with it, audit report object otherwise.
*/
function interactiveRule(accessible) {
if (!INTERACTIVE_ROLES.has(accessible.role)) {
return null;
}
if (accessible.actionCount > 0) {
return null;
}
return { score: FAIL, issue: INTERACTIVE_NO_ACTION };
}
/**
* A rule that determines if an interactive accessible is also focusable when
* not disabled.
*
* @param {nsIAccessible} accessible
* Accessible to be checked for being interactive and being focusable
* when enabled.
*
* @return {null|Object}
* Null if accessible is not interactive or if it is and it is focusable
* when enabled, audit report object otherwise.
*/
function focusableRule(accessible) {
if (!INTERACTIVE_ROLES.has(accessible.role)) {
return null;
}
const state = {};
accessible.getState(state, {});
// We only expect in interactive accessible object to be focusable if it is
// not disabled.
if (state.value & Ci.nsIAccessibleStates.STATE_UNAVAILABLE) {
return null;
}
// State will be focusable even if the tabindex is negative.
if (
state.value & Ci.nsIAccessibleStates.STATE_FOCUSABLE &&
accessible.DOMNode.tabIndex > -1
) {
return null;
}
return { score: FAIL, issue: INTERACTIVE_NOT_FOCUSABLE };
}
/**
* A rule that determines if a focusable accessible has an associated
* interactive role.
*
* @param {nsIAccessible} accessible
* Accessible to be checked for having an interactive role if it is
* focusable.
*
* @return {null|Object}
* Null if accessible is not interactive or if it is and it has an
* interactive role, audit report object otherwise.
*/
function semanticsRule(accessible) {
if (INTERACTIVE_ROLES.has(accessible.role)) {
return null;
}
const state = {};
accessible.getState(state, {});
if (state.value & Ci.nsIAccessibleStates.STATE_FOCUSABLE) {
return { score: WARNING, issue: FOCUSABLE_NO_SEMANTICS };
}
return null;
}
/**
* A rule that determines if an element associated with a focusable accessible
* has a positive tabindex.
*
* @param {nsIAccessible} accessible
* Accessible to be checked for having an element with positive tabindex
* attribute.
*
* @return {null|Object}
* Null if accessible is not focusable or if it is and its element's
* tabindex attribute is less than 1, audit report object otherwise.
*/
function tabIndexRule(accessible) {
const { DOMNode } = accessible;
if (isInvalidNode(DOMNode)) {
return null;
}
const state = {};
accessible.getState(state, {});
if (!(state.value & Ci.nsIAccessibleStates.STATE_FOCUSABLE)) {
return null;
}
if (DOMNode.tabIndex > 0) {
return { score: WARNING, issue: FOCUSABLE_POSITIVE_TABINDEX };
}
return null;
}
function auditKeyboard(accessible) {
// Do not test anything on accessible objects for documents or frames.
if (
accessible.role === Ci.nsIAccessibleRole.ROLE_DOCUMENT ||
accessible.role === Ci.nsIAccessibleRole.ROLE_INTERNAL_FRAME
) {
return null;
}
// Check if interactive accessible can be used by the assistive
// technology.
let issue = interactiveRule(accessible);
if (issue) {
return issue;
}
// Check if interactive accessible is also focusable when enabled.
issue = focusableRule(accessible);
if (issue) {
return issue;
}
// Check if accessible object has an element with a positive tabindex.
issue = tabIndexRule(accessible);
if (issue) {
return issue;
}
// Check if a focusable accessible has interactive semantics.
issue = semanticsRule(accessible);
if (issue) {
return issue;
}
// Check if focusable accessible has associated focus styling.
issue = focusStyleRule(accessible);
if (issue) {
return issue;
}
return issue;
}
module.exports.auditKeyboard = auditKeyboard;

View File

@ -4,7 +4,6 @@
DevToolsModules(
'contrast.js',
'keyboard.js',
'text-label.js',
)

View File

@ -743,7 +743,7 @@
color: var(--highlighter-infobar-color);
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty)::before {
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty):before {
content: "";
height: 8px;
width: 8px;
@ -754,48 +754,39 @@
margin-inline-end: 9px;
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty)::after {
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty):after {
margin-inline-start: 2px;
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AA::after,
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AAA::after {
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AA:after,
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AAA:after {
color: #90E274;
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty).FAIL::after {
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty).fail:after {
color: #E57180;
content: "⚠️";
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AA::after {
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AA:after {
content: "AA\2713";
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AAA::after {
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AAA:after {
content: "AAA\2713";
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-label,
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-separator::before {
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-separator:before {
margin-inline-end: 3px;
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-separator::before {
:-moz-native-anonymous .accessible-infobar-audit .accessible-contrast-ratio-separator:before {
content: "-";
margin-inline-start: 3px;
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-audit {
display: block;
padding-block-end: 5px;
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-audit:last-child {
padding-block-end: 0;
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-audit::before {
:-moz-native-anonymous .accessible-infobar-audit .accessible-text-label:before {
display: inline-block;
width: 12px;
height: 12px;
@ -809,17 +800,17 @@
fill: currentColor;
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-audit.FAIL::before {
:-moz-native-anonymous .accessible-infobar-audit .accessible-text-label.fail:before {
background-image: url(chrome://devtools/skin/images/error-small.svg);
fill: var(--red-40);
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-audit.WARNING::before {
:-moz-native-anonymous .accessible-infobar-audit .accessible-text-label.WARNING:before {
background-image: url(chrome://devtools/skin/images/alert-small.svg);
fill: var(--yellow-60);
}
:-moz-native-anonymous .accessible-infobar-audit .accessible-audit.BEST_PRACTICES::before {
:-moz-native-anonymous .accessible-infobar-audit .accessible-text-label.BEST_PRACTICES:before {
background-image: url(chrome://devtools/skin/images/info-small.svg);
}

View File

@ -29,13 +29,6 @@ const {
accessibility: {
AUDIT_TYPE,
ISSUE_TYPE: {
[AUDIT_TYPE.KEYBOARD]: {
FOCUSABLE_NO_SEMANTICS,
FOCUSABLE_POSITIVE_TABINDEX,
INTERACTIVE_NO_ACTION,
INTERACTIVE_NOT_FOCUSABLE,
NO_FOCUS_VISIBLE,
},
[AUDIT_TYPE.TEXT_LABEL]: {
AREA_NO_NAME_FROM_ALT,
DIALOG_NO_NAME,
@ -427,11 +420,7 @@ class Audit {
// A list of audit reports to be shown on the fly when highlighting an accessible
// object.
this.reports = {
[AUDIT_TYPE.CONTRAST]: new ContrastRatio(this),
[AUDIT_TYPE.KEYBOARD]: new Keyboard(this),
[AUDIT_TYPE.TEXT_LABEL]: new TextLabel(this),
};
this.reports = [new ContrastRatio(this), new TextLabel(this)];
}
get prefix() {
@ -453,7 +442,7 @@ class Audit {
prefix: this.prefix,
});
Object.values(this.reports).forEach(report => report.buildMarkup(audit));
this.reports.forEach(report => report.buildMarkup(audit));
}
update(audit = {}) {
@ -461,7 +450,7 @@ class Audit {
el.setAttribute("hidden", true);
let updated = false;
Object.values(this.reports).forEach(report => {
this.reports.forEach(report => {
if (report.update(audit)) {
updated = true;
}
@ -482,7 +471,7 @@ class Audit {
destroy() {
this.infobar = null;
Object.values(this.reports).forEach(report => report.destroy());
this.reports.forEach(report => report.destroy());
this.reports = null;
}
}
@ -670,70 +659,6 @@ class ContrastRatio extends AuditReport {
}
}
/**
* Keyboard audit report that is used to display a problem with keyboard
* accessibility as part of the inforbar.
*/
class Keyboard extends AuditReport {
/**
* A map from keyboard issues to annotation component properties.
*/
static get ISSUE_TO_INFOBAR_LABEL_MAP() {
return {
[FOCUSABLE_NO_SEMANTICS]: "accessibility.keyboard.issue.semantics",
[FOCUSABLE_POSITIVE_TABINDEX]: "accessibility.keyboard.issue.tabindex",
[INTERACTIVE_NO_ACTION]: "accessibility.keyboard.issue.action",
[INTERACTIVE_NOT_FOCUSABLE]: "accessibility.keyboard.issue.focusable",
[NO_FOCUS_VISIBLE]: "accessibility.keyboard.issue.focus.visible",
};
}
buildMarkup(root) {
createNode(this.win, {
nodeType: "span",
parent: root,
attributes: {
class: "audit",
id: "keyboard",
},
prefix: this.prefix,
});
}
/**
* Update keyboard audit infobar markup.
* @param {Object}
* Audit report for a given highlighted accessible.
* @return {Boolean}
* True if the keyboard markup was updated correctly and infobar audit
* block should be visible.
*/
update(audit) {
const el = this.getElement("keyboard");
el.setAttribute("hidden", true);
Object.values(SCORES).forEach(className => el.classList.remove(className));
if (!audit) {
return false;
}
const keyboardAudit = audit[AUDIT_TYPE.KEYBOARD];
if (!keyboardAudit) {
return false;
}
const { issue, score } = keyboardAudit;
this.setTextContent(
el,
L10N.getStr(Keyboard.ISSUE_TO_INFOBAR_LABEL_MAP[issue])
);
el.classList.add(score);
el.removeAttribute("hidden");
return true;
}
}
/**
* Text label audit report that is used to display a problem with text alternatives
* as part of the inforbar.
@ -772,7 +697,7 @@ class TextLabel extends AuditReport {
nodeType: "span",
parent: root,
attributes: {
class: "audit",
class: "text-label",
id: "text-label",
},
prefix: this.prefix,

View File

@ -102,7 +102,7 @@ const ACCESSIBLE_BOUNDS_SHEET =
color: hsl(210, 30%, 85%);
}
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty)::before {
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty):before {
content: "";
height: 8px;
width: 8px;
@ -115,34 +115,34 @@ const ACCESSIBLE_BOUNDS_SHEET =
margin-inline-end: 9px;
}
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty)::after {
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty):after {
margin-inline-start: 2px;
}
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AA::after,
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AAA::after {
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AA:after,
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AAA:after {
color: #90E274;
}
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty).FAIL::after {
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty).fail:after {
color: #E57180;
content: "⚠️";
}
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AA::after {
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AA:after {
content: "AA\u2713";
}
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AAA::after {
.accessible-infobar-audit .accessible-contrast-ratio:not(:empty).AAA:after {
content: "AAA\u2713";
}
.accessible-infobar-audit .accessible-contrast-ratio-label,
.accessible-infobar-audit .accessible-contrast-ratio-separator::before {
.accessible-infobar-audit .accessible-contrast-ratio-separator:before {
margin-inline-end: 3px;
}
.accessible-infobar-audit .accessible-contrast-ratio-separator::before {
.accessible-infobar-audit .accessible-contrast-ratio-separator:before {
content: "-";
margin-inline-start: 3px;
}
@ -153,16 +153,7 @@ const ACCESSIBLE_BOUNDS_SHEET =
padding-inline-start: 6px;
}
.accessible-infobar-audit .accessible-audit {
display: block;
padding-block-end: 5px;
}
.accessible-infobar-audit .accessible-audit:last-child {
padding-block-end: 0;
}
.accessible-infobar-audit .accessible-audit::before {
.accessible-infobar-audit .accessible-text-label:before {
display: inline-block;
width: 12px;
height: 12px;
@ -176,17 +167,17 @@ const ACCESSIBLE_BOUNDS_SHEET =
fill: currentColor;
}
.accessible-infobar-audit .accessible-audit.FAIL::before {
.accessible-infobar-audit .accessible-text-label.fail:before {
background-image: url(chrome://devtools/skin/images/error-small.svg);
fill: var(--red-40);
}
.accessible-infobar-audit .accessible-audit.WARNING::before {
.accessible-infobar-audit .accessible-text-label.WARNING:before {
background-image: url(chrome://devtools/skin/images/alert-small.svg);
fill: var(--yellow-60);
}
.accessible-infobar-audit .accessible-audit.BEST_PRACTICES::before {
.accessible-infobar-audit .accessible-text-label.BEST_PRACTICES:before {
background-image: url(chrome://devtools/skin/images/info-small.svg);
}`);

View File

@ -12,7 +12,6 @@ support-files =
application-manifest-warnings.html
doc_accessibility_audit.html
doc_accessibility_infobar.html
doc_accessibility_keyboard_audit.html
doc_accessibility_text_label_audit_frame.html
doc_accessibility_text_label_audit.html
doc_accessibility.html
@ -50,11 +49,6 @@ support-files =
[browser_accessibility_highlighter_infobar.js]
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533184
[browser_accessibility_infobar_show.js]
[browser_accessibility_keyboard_audit.js]
skip-if =
(os == 'win' && processor == 'aarch64') || # bug 1533184
fission # Fails intermittently under Fission.
[browser_accessibility_infobar_audit_keyboard.js]
[browser_accessibility_infobar_audit_text_label.js]
[browser_accessibility_node.js]
skip-if = (os == 'win' && processor == 'aarch64') # bug 1533184

View File

@ -1,157 +0,0 @@
/* 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";
// Checks for the AccessibleHighlighter's infobar component and its keyboard
// audit.
add_task(async function() {
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: MAIN_DOMAIN + "doc_accessibility_infobar.html",
},
async function(browser) {
await ContentTask.spawn(browser, null, async function() {
const { require } = ChromeUtils.import(
"resource://devtools/shared/Loader.jsm"
);
const {
HighlighterEnvironment,
} = require("devtools/server/actors/highlighters");
const {
AccessibleHighlighter,
} = require("devtools/server/actors/highlighters/accessible");
const { LocalizationHelper } = require("devtools/shared/l10n");
const L10N = new LocalizationHelper(
"devtools/shared/locales/accessibility.properties"
);
const {
accessibility: {
AUDIT_TYPE,
ISSUE_TYPE: {
[AUDIT_TYPE.KEYBOARD]: {
INTERACTIVE_NO_ACTION,
FOCUSABLE_NO_SEMANTICS,
},
},
SCORES: { FAIL, WARNING },
},
} = require("devtools/shared/constants");
/**
* Checks for updated content for an infobar.
*
* @param {Object} infobar
* Accessible highlighter's infobar component.
* @param {Object} audit
* Audit information that is passed on highlighter show.
*/
function checkKeyboard(infobar, audit) {
const { issue, score } = audit || {};
let expected = "";
if (issue) {
const { ISSUE_TO_INFOBAR_LABEL_MAP } = infobar.audit.reports[
AUDIT_TYPE.KEYBOARD
].constructor;
expected = L10N.getStr(ISSUE_TO_INFOBAR_LABEL_MAP[issue]);
}
is(
infobar.getTextContent("keyboard"),
expected,
"infobar keyboard audit text content is correct"
);
if (score) {
ok(infobar.getElement("keyboard").classList.contains(score));
}
}
// Start testing. First, create highlighter environment and initialize.
const env = new HighlighterEnvironment();
env.initFromWindow(content.window);
// Wait for loading highlighter environment content to complete before creating the
// highlighter.
await new Promise(resolve => {
const doc = env.document;
function onContentLoaded() {
if (
doc.readyState === "interactive" ||
doc.readyState === "complete"
) {
resolve();
} else {
doc.addEventListener("DOMContentLoaded", onContentLoaded, {
once: true,
});
}
}
onContentLoaded();
});
// Now, we can test the Infobar's audit content.
const node = content.document.createElement("div");
content.document.body.append(node);
const highlighter = new AccessibleHighlighter(env);
const infobar = highlighter.accessibleInfobar;
const bounds = {
x: 0,
y: 0,
w: 250,
h: 100,
};
const tests = [
{
desc:
"Infobar is shown with no keyboard audit content when no audit.",
},
{
desc:
"Infobar is shown with no keyboard audit content when audit is null.",
audit: null,
},
{
desc:
"Infobar is shown with no keyboard audit content when empty " +
"keyboard audit.",
audit: { [AUDIT_TYPE.KEYBOARD]: null },
},
{
desc: "Infobar is shown with keyboard audit content for an error.",
audit: {
[AUDIT_TYPE.KEYBOARD]: {
score: FAIL,
issue: INTERACTIVE_NO_ACTION,
},
},
},
{
desc: "Infobar is shown with keyboard audit content for a warning.",
audit: {
[AUDIT_TYPE.KEYBOARD]: {
score: WARNING,
issue: FOCUSABLE_NO_SEMANTICS,
},
},
},
];
for (const test of tests) {
const { desc, audit } = test;
info(desc);
highlighter.show(node, { ...bounds, audit });
checkKeyboard(infobar, audit && audit[AUDIT_TYPE.KEYBOARD]);
highlighter.hide();
}
});
}
);
});

View File

@ -55,9 +55,9 @@ add_task(async function() {
const { issue, score } = audit || {};
let expected = "";
if (issue) {
const { ISSUE_TO_INFOBAR_LABEL_MAP } = infobar.audit.reports[
AUDIT_TYPE.TEXT_LABEL
].constructor;
const {
ISSUE_TO_INFOBAR_LABEL_MAP,
} = infobar.audit.reports[1].constructor;
expected = L10N.getStr(ISSUE_TO_INFOBAR_LABEL_MAP[issue]);
}
@ -67,7 +67,11 @@ add_task(async function() {
"infobar text label audit text content is correct"
);
if (score) {
ok(infobar.getElement("text-label").classList.contains(score));
ok(
infobar
.getElement("text-label")
.classList.contains(score === FAIL ? "fail" : score)
);
}
}

View File

@ -1,111 +0,0 @@
/* 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";
/**
* Checks functionality around text label audit for the AccessibleActor.
*/
const {
accessibility: {
AUDIT_TYPE: { KEYBOARD },
SCORES: { FAIL, WARNING },
ISSUE_TYPE: {
[KEYBOARD]: {
FOCUSABLE_NO_SEMANTICS,
FOCUSABLE_POSITIVE_TABINDEX,
INTERACTIVE_NO_ACTION,
INTERACTIVE_NOT_FOCUSABLE,
NO_FOCUS_VISIBLE,
},
},
},
} = require("devtools/shared/constants");
add_task(async function() {
const { target, walker, accessibility } = await initAccessibilityFrontForUrl(
`${MAIN_DOMAIN}doc_accessibility_keyboard_audit.html`
);
const a11yWalker = await accessibility.getWalker();
await accessibility.enable();
const tests = [
[
"Focusable element (styled button) with no semantics.",
"#button-1",
{ score: WARNING, issue: FOCUSABLE_NO_SEMANTICS },
],
["Element (styled button) with no semantics.", "#button-2", null],
[
"Container element for out of order focusable element.",
"#input-container",
null,
],
[
"Interactive element with focus out of order (-1).",
"#input-1",
{
score: FAIL,
issue: INTERACTIVE_NOT_FOCUSABLE,
},
],
[
"Interactive element with focus out of order (-1) when disabled.",
"#input-2",
null,
],
["Interactive element when disabled.", "#input-3", null],
["Focusable interactive element.", "#input-4", null],
[
"Interactive accesible (link with no attributes) with no accessible actions.",
"#link-1",
{
score: FAIL,
issue: INTERACTIVE_NO_ACTION,
},
],
["Interactive accessible (link with valid hred).", "#link-2", null],
["Interactive accessible with no tabindex.", "#button-3", null],
[
"Interactive accessible with -1 tabindex.",
"#button-4",
{
score: FAIL,
issue: INTERACTIVE_NOT_FOCUSABLE,
},
],
["Interactive accessible with 0 tabindex.", "#button-5", null],
[
"Interactive accessible with 1 tabindex.",
"#button-6",
{ score: WARNING, issue: FOCUSABLE_POSITIVE_TABINDEX },
],
[
"Focusable ARIA button with no focus styling.",
"#focusable-1",
{ score: WARNING, issue: NO_FOCUS_VISIBLE },
],
["Focusable ARIA button with focus styling.", "#focusable-2", null],
["Focusable ARIA button with browser styling.", "#focusable-3", null],
];
for (const [description, selector, expected] of tests) {
info(description);
const node = await walker.querySelector(walker.rootNode, selector);
const front = await a11yWalker.getAccessibleFor(node);
const audit = await front.audit({ types: [KEYBOARD] });
Assert.deepEqual(
audit[KEYBOARD],
expected,
`Audit result for ${selector} is correct.`
);
}
await accessibility.disable();
await waitForA11yShutdown();
await target.destroy();
gBrowser.removeCurrentTab();
});

View File

@ -11,7 +11,7 @@
*/
const {
accessibility: { AUDIT_TYPE, SCORES },
accessibility: { AUDIT_TYPE },
} = require("devtools/shared/constants");
const EMPTY_AUDIT = Object.keys(AUDIT_TYPE).reduce((audit, key) => {
audit[key] = null;
@ -23,7 +23,7 @@ const EXPECTED_CONTRAST_DATA = {
color: [0, 0, 0, 1],
backgroundColor: [255, 255, 255, 1],
isLargeText: true,
score: SCORES.AAA,
score: "AAA",
};
const EMPTY_CONTRAST_AUDIT = {

View File

@ -21,7 +21,6 @@ add_task(async function() {
childCount: 2,
checks: {
[AUDIT_TYPE.CONTRAST]: null,
[AUDIT_TYPE.KEYBOARD]: null,
[AUDIT_TYPE.TEXT_LABEL]: {
score: SCORES.FAIL,
issue: ISSUE_TYPE.DOCUMENT_NO_TITLE,
@ -36,7 +35,6 @@ add_task(async function() {
childCount: 1,
checks: {
[AUDIT_TYPE.CONTRAST]: null,
[AUDIT_TYPE.KEYBOARD]: null,
[AUDIT_TYPE.TEXT_LABEL]: null,
},
},
@ -52,9 +50,8 @@ add_task(async function() {
color: [255, 0, 0, 1],
backgroundColor: [255, 255, 255, 1],
isLargeText: false,
score: SCORES.FAIL,
score: "fail",
},
[AUDIT_TYPE.KEYBOARD]: null,
[AUDIT_TYPE.TEXT_LABEL]: null,
},
},
@ -64,7 +61,6 @@ add_task(async function() {
childCount: 1,
checks: {
[AUDIT_TYPE.CONTRAST]: null,
[AUDIT_TYPE.KEYBOARD]: null,
[AUDIT_TYPE.TEXT_LABEL]: null,
},
},
@ -78,9 +74,8 @@ add_task(async function() {
color: [255, 0, 0, 1],
backgroundColor: [255, 255, 255, 1],
isLargeText: false,
score: SCORES.FAIL,
score: "fail",
},
[AUDIT_TYPE.KEYBOARD]: null,
[AUDIT_TYPE.TEXT_LABEL]: null,
},
},

View File

@ -1,33 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
#focusable-1 {
outline: none;
}
#focusable-2:focus {
outline: none;
border: 1px solid black;
}
</style>
</head>
<body>
<div id="button-1" class="Button" tabindex="0">I should really be a button</div>
<div id="button-2" class="Button">I should really be a button</div>
<div id="input-container"><input id="input-1" type="text" tabindex="-1" /></div>
<input id="input-2" type="text" tabindex="-1" disabled />
<input id="input-3" type="text" disabled />
<input id="input-4" type="text" />
<a id="link-1">Though a link, I'm not interactive.</a>
<a id="link-2" href="example.com">I'm a proper link.</a>
<button id="button-3">Button with no tabindex</button>
<button id="button-4" tabindex="-1">Button with -1 tabindex</button>
<button id="button-5" tabindex="0">Button with 0 tabindex</button>
<button id="button-6" tabindex="1">Button with 1 tabindex</button>
<div id="focusable-1" role="button" tabindex="0">Focusable with no focus style.</div>
<div id="focusable-2" role="button" tabindex="0">Focusable with focus style.</div>
<div id="focusable-3" role="button" tabindex="0">Focusable with focus style.</div>
</body>
</html>

View File

@ -13,24 +13,11 @@
// List of audit types.
const AUDIT_TYPE = {
CONTRAST: "CONTRAST",
KEYBOARD: "KEYBOARD",
TEXT_LABEL: "TEXT_LABEL",
};
// Types of issues grouped by audit types.
const ISSUE_TYPE = {
[AUDIT_TYPE.KEYBOARD]: {
// Focusable accessible objects have no semantics.
FOCUSABLE_NO_SEMANTICS: "FOCUSABLE_NO_SEMANTICS",
// Tab index greater than 0 is provided.
FOCUSABLE_POSITIVE_TABINDEX: "FOCUSABLE_POSITIVE_TABINDEX",
// Interactive accesible objects do not have an associated action.
INTERACTIVE_NO_ACTION: "INTERACTIVE_NO_ACTION",
// Interative accessible objcets are not focusable.
INTERACTIVE_NOT_FOCUSABLE: "INTERACTIVE_NOT_FOCUSABLE",
// Focusable accessible objects have no focus styling.
NO_FOCUS_VISIBLE: "NO_FOCUS_VISIBLE",
},
[AUDIT_TYPE.TEXT_LABEL]: {
// <AREA> name is provided via "alt" attribute.
AREA_NO_NAME_FROM_ALT: "AREA_NO_NAME_FROM_ALT",
@ -80,7 +67,7 @@ const SCORES = {
// Elevates accessibility experience.
BEST_PRACTICES: "BEST_PRACTICES",
// Does not satisfy the baseline WCAG guidelines.
FAIL: "FAIL",
FAIL: "fail",
// Partially satisfies the WCAG AA guidelines.
WARNING: "WARNING",
};

View File

@ -109,29 +109,3 @@ accessibility.text.label.issue.optgroup.label2 = Use a “label” attribute to
# describes that currently selected accessible object for a toolbar must have a
# name provided when there is more than one toolbar in the document.
accessibility.text.label.issue.toolbar = Toolbars must be labeled when there is more than one toolbar.
# LOCALIZATION NOTE (accessibility.keyboard.issue.semantics): A title text that
# describes that currently selected accessible object is focusable and should
# indicate that it could be interacted with.
accessibility.keyboard.issue.semantics=Focusable elements should have interactive semantics.
# LOCALIZATION NOTE (accessibility.keyboard.issue.tabindex): A title text that
# describes that currently selected accessible object has a corresponding
# DOMNode that defines a tabindex attribute greater that 0 which can result in
# unexpected behaviour when navigating with keyboard.
accessibility.keyboard.issue.tabindex=Avoid using “tabindex” attribute greater than zero.
# LOCALIZATION NOTE (accessibility.keyboard.issue.action): A title text that
# describes that currently selected accessible object is interactive but can not
# be activated using keyboard or accessibility API.
accessibility.keyboard.issue.action=Interactive elements must be able to be activated using a keyboard.
# LOCALIZATION NOTE (accessibility.keyboard.issue.focusable): A title text that
# describes that currently selected accessible object is interactive but is not
# focusable with a keyboard.
accessibility.keyboard.issue.focusable=Interactive elements must be focusable.
# LOCALIZATION NOTE (accessibility.keyboard.issue.focus.visible): A title text
# that describes that currently selected accessible object is focusable but
# might not have appropriate focus styling.
accessibility.keyboard.issue.focus.visible=Focusable element may be missing focus styling.

View File

@ -74,8 +74,6 @@ namespace InspectorUtils {
[Throws] void parseStyleSheet(CSSStyleSheet sheet, DOMString input);
boolean isCustomElementName([TreatNullAs=EmptyString] DOMString name,
DOMString? namespaceURI);
boolean isElementThemed(Element element);
};
dictionary PropertyNamesOptions {

View File

@ -26,7 +26,6 @@
#include "nsComputedDOMStyle.h"
#include "mozilla/EventStateManager.h"
#include "nsAtom.h"
#include "nsPresContext.h"
#include "nsRange.h"
#include "mozilla/PresShell.h"
#include "mozilla/PresShellInlines.h"
@ -45,7 +44,6 @@
#include "mozilla/ServoBindings.h"
#include "mozilla/ServoStyleRuleMap.h"
#include "mozilla/ServoCSSParser.h"
#include "mozilla/StaticPrefs_layout.h"
#include "mozilla/dom/InspectorUtils.h"
#include "mozilla/dom/InspectorFontFace.h"
@ -701,16 +699,5 @@ bool InspectorUtils::IsCustomElementName(GlobalObject&, const nsAString& aName,
return nsContentUtils::IsCustomElementName(nameElt, namespaceID);
}
/* static */
bool InspectorUtils::IsElementThemed(GlobalObject&, Element& aElement) {
// IsThemed will check if the native theme supports the widget using
// ThemeSupportsWidget which in turn will check that the widget is not
// already styled by content through nsNativeTheme::IsWidgetStyled. We
// assume that if the native theme styles the widget and the author did not
// override the appropriate styles, the theme will provide focus styling.
nsIFrame* frame = aElement.GetPrimaryFrame(FlushType::Frames);
return frame && frame->IsThemed();
}
} // namespace dom
} // namespace mozilla

View File

@ -229,8 +229,6 @@ class InspectorUtils {
const nsAString& aPseudoClass);
static void ClearPseudoClassLocks(GlobalObject& aGlobal, Element& aElement);
static bool IsElementThemed(GlobalObject& aGlobal, Element& aElement);
/**
* Parse CSS and update the style sheet in place.
*

View File

@ -28,7 +28,6 @@ support-files =
[test_getCSSPseudoElementNames.html]
[test_getRelativeRuleLine.html]
[test_get_all_style_sheets.html]
[test_is_element_themed.html]
[test_is_valid_css_color.html]
[test_isinheritableproperty.html]
[test_parseStyleSheet.html]

View File

@ -1,82 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test InspectorUtils::IsElementThemed</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
.not-themed-border:focus {
border: none;
}
.not-themed-background:focus {
background-color: red;
}
</style>
</head>
<body>
<h1>Test InspectorUtils::isValidCSSColor</h1>
<button id="themed-button">Themed Button</button>
<input id="themed-input-number" type="number"/>
<input id="themed-input-text" type="text"/>
<textarea id="themed-textarea"></textarea>
<button id="not-themed-button-(border)" class="not-themed-border">Not Themed Button</button>
<input id="not-themed-input-number-(border)" class="not-themed-border" type="number"/>
<input id="not-themed-input-text-(border)" class="not-themed-border" type="text"/>
<textarea id="not-themed-textarea-(border)" class="not-themed-border"></textarea>
<button id="not-themed-button-(background)" class="not-themed-background">Not Themed Button</button>
<input id="not-themed-input-number-(background)" class="not-themed-background" type="number"/>
<input id="not-themed-input-text-(background)" class="not-themed-background" type="text"/>
<textarea id="not-themed-textarea-(background)" class="not-themed-background"></textarea>
<script type="application/javascript">
const InspectorUtils = SpecialPowers.InspectorUtils;
const tests = [{
id: "themed-button",
themed: true,
}, {
id: "themed-input-number",
themed: true,
}, {
id: "themed-input-text",
themed: true,
}, {
id: "themed-textarea",
themed: true,
}, {
id: "not-themed-button-(border)",
themed: false,
}, {
id: "not-themed-input-number-(border)",
themed: false,
}, {
id: "not-themed-input-text-(border)",
themed: false,
}, {
id: "not-themed-textarea-(border)",
themed: false,
}, {
id: "not-themed-button-(background)",
themed: false,
}, {
id: "not-themed-input-number-(background)",
themed: false,
}, {
id: "not-themed-input-text-(background)",
themed: false,
}, {
id: "not-themed-textarea-(background)",
themed: false,
}];
for (const { id, themed } of tests) {
ok(InspectorUtils.isElementThemed(document.getElementById(id)),
`#${id} is${themed ? " ": " not "}themed natively`);
}
</script>
</body>
</html>