Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: deprecate the use doT.js for messages #1938

Merged
merged 11 commits into from
Dec 18, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 1 addition & 19 deletions build/configure.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@
'use strict';

var clone = require('clone');
var dot = require('@deque/dot');
straker marked this conversation as resolved.
Show resolved Hide resolved
var templates = require('./templates');
var buildManual = require('./build-manual');
var entities = new (require('html-entities')).AllHtmlEntities();

var descriptionHeaders =
'| Rule ID | Description | Impact | Tags | Enabled by default | Failures | Needs Review |\n| :------- | :------- | :------- | :------- | :------- | :------- | :------- |\n';

dot.templateSettings.strip = false;

function getLocale(grunt, options) {
var localeFile;
if (options.locale) {
Expand Down Expand Up @@ -55,21 +52,6 @@ function buildRules(grunt, options, commons, callback) {
}
var result = clone(data) || {};

if (result.messages) {
Object.keys(result.messages).forEach(function(key) {
// only convert to templated function for strings
// objects handled later in publish-metadata.js
if (typeof result.messages[key] !== 'object') {
result.messages[key] = dot
.template(result.messages[key])
.toString();
}
});
}
//TODO this is actually failureSummaries, property name should better reflect that
if (result.failureMessage) {
result.failureMessage = dot.template(result.failureMessage).toString();
}
return result;
}

Expand All @@ -87,7 +69,7 @@ function buildRules(grunt, options, commons, callback) {
var result = {};
summaries.forEach(function(summary) {
if (summary.incompleteFallbackMessage) {
result = dot.template(summary.incompleteFallbackMessage).toString();
result = summary.incompleteFallbackMessage;
}
});
return result;
Expand Down
2 changes: 0 additions & 2 deletions build/tasks/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ function hasMultipleOutcomes(messages) {
switch (key) {
case 'pass':
case 'fail':
return typeof messages[key] === 'string';

case 'incomplete':
return ['string', 'object'].includes(typeof messages[key]);

Expand Down
5 changes: 4 additions & 1 deletion lib/checks/aria/allowed-attr.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"impact": "critical",
"messages": {
"pass": "ARIA attributes are used correctly for the defined role",
"fail": "ARIA attribute{{=it.data && it.data.length > 1 ? 's are' : ' is'}} not allowed:{{~it.data:value}} {{=value}}{{~}}"
"fail": {
"singular": "ARIA attribute is not allowed: ${data.values}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is 1,000,000x easier to read/follow ❤️

"plural": "ARIA attributes are not allowed: ${data.values}"
}
}
}
}
10 changes: 8 additions & 2 deletions lib/checks/aria/aria-allowed-role.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@
"impact": "minor",
"messages": {
"pass": "ARIA role is allowed for given element",
"fail": "ARIA role{{=it.data && it.data.length > 1 ? 's' : ''}} {{=it.data.join(', ')}} {{=it.data && it.data.length > 1 ? 'are' : ' is'}} not allowed for given element",
"incomplete": "ARIA role{{=it.data && it.data.length > 1 ? 's' : ''}} {{=it.data.join(', ')}} must be removed when the element is made visible, as {{=it.data && it.data.length > 1 ? 'they are' : 'it is'}} not allowed for the element"
"fail": {
"singular": "ARIA role ${data.values} is not allowed for given element",
"plural": "ARIA roles ${data.values} are not allowed for given element"
},
"incomplete": {
"singular": "ARIA role ${data.values} must be removed when the element is made visible, as it is not allowed for the element",
"plural": "ARIA roles ${data.values} must be removed when the element is made visible, as they are not allowed for the element"
}
}
}
}
5 changes: 4 additions & 1 deletion lib/checks/aria/errormessage.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"impact": "critical",
"messages": {
"pass": "Uses a supported aria-errormessage technique",
"fail": "aria-errormessage value{{=it.data && it.data.length > 1 ? 's' : ''}} {{~it.data:value}} `{{=value}}{{~}}` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)"
"fail": {
"singular": "aria-errormessage value `${data.values}` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)",
"plural": "aria-errormessage values `${data.values}` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)"
}
}
}
}
2 changes: 1 addition & 1 deletion lib/checks/aria/no-implicit-explicit-label.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"impact": "moderate",
"messages": {
"pass": "There is no mismatch between a <label> and accessible name",
"incomplete": "Check that the <label> does not need be part of the ARIA {{=it.data}} field's name"
"incomplete": "Check that the <label> does not need be part of the ARIA ${data} field's name"
}
}
}
5 changes: 4 additions & 1 deletion lib/checks/aria/required-attr.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"impact": "critical",
"messages": {
"pass": "All required ARIA attributes are present",
"fail": "Required ARIA attribute{{=it.data && it.data.length > 1 ? 's' : ''}} not present:{{~it.data:value}} {{=value}}{{~}}"
"fail": {
"singular": "Required ARIA attribute not present: ${data.values}",
"plural": "Required ARIA attributes not present: ${data.values}"
}
}
}
}
10 changes: 8 additions & 2 deletions lib/checks/aria/required-children.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@
"impact": "critical",
"messages": {
"pass": "Required ARIA children are present",
"fail": "Required ARIA {{=it.data && it.data.length > 1 ? 'children' : 'child'}} role not present:{{~it.data:value}} {{=value}}{{~}}",
"incomplete": "Expecting ARIA {{=it.data && it.data.length > 1 ? 'children' : 'child'}} role to be added:{{~it.data:value}} {{=value}}{{~}}"
"fail": {
"singular": "Required ARIA child role not present: ${data.values}",
"plural": "Required ARIA children role not present: ${data.values}"
},
"incomplete": {
"singular": "Expecting ARIA child role to be added: ${data.values}",
"plural": "Expecting ARIA children role to be added: ${data.values}"
}
}
}
}
5 changes: 4 additions & 1 deletion lib/checks/aria/required-parent.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"impact": "critical",
"messages": {
"pass": "Required ARIA parent role present",
"fail": "Required ARIA parent{{=it.data && it.data.length > 1 ? 's' : ''}} role not present:{{~it.data:value}} {{=value}}{{~}}"
"fail": {
"singular": "Required ARIA parent role not present: ${data.values}",
"plural": "Required ARIA parents role not present: ${data.values}"
}
}
}
}
2 changes: 1 addition & 1 deletion lib/checks/aria/unsupportedattr.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"impact": "critical",
"messages": {
"pass": "ARIA attribute is supported",
"fail": "ARIA attribute is not widely supported in screen readers and assistive technologies: {{~it.data:value}} {{=value}}{{~}}"
"fail": "ARIA attribute is not widely supported in screen readers and assistive technologies: ${data.values}"
}
}
}
2 changes: 1 addition & 1 deletion lib/checks/aria/unsupportedrole.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"impact": "critical",
"messages": {
"pass": "ARIA role is supported",
"fail": "The role used is not widely supported in screen readers and assistive technologies: {{~it.data:value}} {{=value}}{{~}}"
"fail": "The role used is not widely supported in screen readers and assistive technologies: ${data.values}"
}
}
}
10 changes: 8 additions & 2 deletions lib/checks/aria/valid-attr-value.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@
"impact": "critical",
"messages": {
"pass": "ARIA attribute values are valid",
"fail": "Invalid ARIA attribute value{{=it.data && it.data.length > 1 ? 's' : ''}}:{{~it.data:value}} {{=value}}{{~}}",
"incomplete": "ARIA attribute{{=it.data && it.data.length > 1 ? 's' : ''}} element ID does not exist on the page:{{~it.data:value}} {{=value}}{{~}}"
"fail": {
"singular": "Invalid ARIA attribute value: ${data.values}",
"plural": "Invalid ARIA attribute values: ${data.values}"
},
"incomplete": {
"singular": "ARIA attribute element ID does not exist on the page: ${data.values}",
"plural": "ARIA attributes element ID does not exist on the page: ${data.values}"
}
}
}
}
7 changes: 5 additions & 2 deletions lib/checks/aria/valid-attr.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@
"metadata": {
"impact": "critical",
"messages": {
"pass": "ARIA attribute name{{=it.data && it.data.length > 1 ? 's' : ''}} are valid",
"fail": "Invalid ARIA attribute name{{=it.data && it.data.length > 1 ? 's' : ''}}:{{~it.data:value}} {{=value}}{{~}}"
"pass": "ARIA attribute name is valid",
"fail": {
"singular": "Invalid ARIA attribute name: ${data.values}",
"plural": "Invalid ARIA attribute names: ${data.values}"
}
}
}
}
28 changes: 15 additions & 13 deletions lib/checks/color/color-contrast.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@
"metadata": {
"impact": "serious",
"messages": {
"pass": "Element has sufficient color contrast of {{=it.data.contrastRatio}}",
"fail": "Element has insufficient color contrast of {{=it.data.contrastRatio}} (foreground color: {{=it.data.fgColor}}, background color: {{=it.data.bgColor}}, font size: {{=it.data.fontSize}}, font weight: {{=it.data.fontWeight}}). Expected contrast ratio of {{=it.data.expectedContrastRatio}}",
"pass": "Element has sufficient color contrast of ${data.contrastRatio}",
"fail": "Element has insufficient color contrast of ${data.contrastRatio} (foreground color: ${data.fgColor}, background color: ${data.bgColor}, font size: ${data.fontSize}, font weight: ${data.fontWeight}). Expected contrast ratio of ${data.expectedContrastRatio}",
"incomplete": {
"bgImage": "Element's background color could not be determined due to a background image",
"bgGradient": "Element's background color could not be determined due to a background gradient",
"imgNode": "Element's background color could not be determined because element contains an image node",
"bgOverlap": "Element's background color could not be determined because it is overlapped by another element",
"fgAlpha": "Element's foreground color could not be determined because of alpha transparency",
"elmPartiallyObscured": "Element's background color could not be determined because it's partially obscured by another element",
"elmPartiallyObscuring": "Element's background color could not be determined because it partially overlaps other elements",
"outsideViewport": "Element's background color could not be determined because it's outside the viewport",
"equalRatio": "Element has a 1:1 contrast ratio with the background",
"shortTextContent": "Element content is too short to determine if it is actual text content",
"default": "Unable to determine contrast ratio"
"default": "Unable to determine contrast ratio",
"missingData": {
"bgImage": "Element's background color could not be determined due to a background image",
"bgGradient": "Element's background color could not be determined due to a background gradient",
"imgNode": "Element's background color could not be determined because element contains an image node",
"bgOverlap": "Element's background color could not be determined because it is overlapped by another element",
"fgAlpha": "Element's foreground color could not be determined because of alpha transparency",
"elmPartiallyObscured": "Element's background color could not be determined because it's partially obscured by another element",
"elmPartiallyObscuring": "Element's background color could not be determined because it partially overlaps other elements",
"outsideViewport": "Element's background color could not be determined because it's outside the viewport",
"equalRatio": "Element has a 1:1 contrast ratio with the background",
"shortTextContent": "Element content is too short to determine if it is actual text content"
}
}
}
}
Expand Down
14 changes: 8 additions & 6 deletions lib/checks/color/link-in-text-block.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
"pass": "Links can be distinguished from surrounding text in some way other than by color",
"fail": "Links need to be distinguished from surrounding text in some way other than by color",
"incomplete": {
"bgContrast": "Element's contrast ratio could not be determined. Check for a distinct hover/focus style",
"bgImage": "Element's contrast ratio could not be determined due to a background image",
"bgGradient": "Element's contrast ratio could not be determined due to a background gradient",
"imgNode": "Element's contrast ratio could not be determined because element contains an image node",
"bgOverlap": "Element's contrast ratio could not be determined because of element overlap",
"default": "Unable to determine contrast ratio"
"default": "Unable to determine contrast ratio",
"missingData": {
"bgContrast": "Element's contrast ratio could not be determined. Check for a distinct hover/focus style",
"bgImage": "Element's contrast ratio could not be determined due to a background image",
"bgGradient": "Element's contrast ratio could not be determined due to a background gradient",
"imgNode": "Element's contrast ratio could not be determined because element contains an image node",
"bgOverlap": "Element's contrast ratio could not be determined because of element overlap"
}
}
}
}
Expand Down
11 changes: 10 additions & 1 deletion lib/checks/forms/fieldset.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,16 @@
"impact": "critical",
"messages": {
"pass": "Element is contained in a fieldset",
"fail": "{{var code = it.data && it.data.failureCode;}}{{? code === 'no-legend'}}Fieldset does not have a legend as its first child{{?? code === 'empty-legend'}}Legend does not have text that is visible to screen readers{{?? code === 'mixed-inputs'}}Fieldset contains unrelated inputs{{?? code === 'no-group-label'}}ARIA group does not have aria-label or aria-labelledby{{?? code === 'group-mixed-inputs'}}ARIA group contains unrelated inputs{{??}}Element does not have a containing fieldset or ARIA group{{?}}"
"fail": {
"default": "Element does not have a containing fieldset or ARIA group",
"failureCode": {
"no-legend": "Fieldset does not have a legend as its first child",
"empty-legend": "Legend does not have text that is visible to screen readers",
"mixed-inputs": "Fieldset contains unrelated inputs",
"no-group-label": "ARIA group does not have aria-label or aria-labelledby",
"group-mixed-inputs": "ARIA group contains unrelated inputs"
}
}
}
}
}
10 changes: 8 additions & 2 deletions lib/checks/forms/group-labelledby.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@
"metadata": {
"impact": "critical",
"messages": {
"pass": "Elements with the name \"{{=it.data.name}}\" have both a shared label, and a unique label, referenced through aria-labelledby",
"fail": "{{var code = it.data && it.data.failureCode;}}Elements with the name \"{{=it.data.name}}\" do not all have {{? code === 'no-shared-label' }}a shared label{{?? code === 'no-unique-label' }}a unique label{{??}}both a shared label, and a unique label{{?}}, referenced through aria-labelledby"
"pass": "Elements with the name \"${data.name}\" have both a shared label, and a unique label, referenced through aria-labelledby",
"fail": {
"default": "Elements with the name \"${data.name}\" do not all have both a shared label, and a unique label referenced through aria-labelledby",
"failureCode": {
"no-shared-label": "Elements with the name \"${data.name}\" do not all have a shared label referenced through aria-labelledby",
"no-unique-label": "Elements with the name \"${data.name}\" do not all have a unique label referenced through aria-labelledby"
}
}
}
}
}
4 changes: 2 additions & 2 deletions lib/checks/keyboard/landmark-is-top-level.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"metadata": {
"impact": "moderate",
"messages": {
"pass": "The {{=it.data.role }} landmark is at the top level.",
"fail": "The {{=it.data.role }} landmark is contained in another landmark."
"pass": "The ${data.role} landmark is at the top level.",
"fail": "The ${data.role} landmark is contained in another landmark."
}
}
}
5 changes: 4 additions & 1 deletion lib/checks/lists/listitem.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"impact": "serious",
"messages": {
"pass": "List item has a <ul>, <ol> or role=\"list\" parent element",
"fail": "List item does not have a <ul>, <ol>{{? it.data === 'roleNotValid'}} without a role, or a role=\"list\"{{?}} parent element"
"fail": {
"default": "List item does not have a <ul>, <ol> parent element",
"roleNotValid": "List item does not have a <ul>, <ol> without a role, or a role=\"list\" parent element"
straker marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
}
2 changes: 1 addition & 1 deletion lib/checks/mobile/meta-viewport.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"impact": "critical",
"messages": {
"pass": "<meta> tag does not disable zooming on mobile devices",
"fail": "{{=it.data}} on <meta> tag disables zooming on mobile devices"
"fail": "${data} on <meta> tag disables zooming on mobile devices"
}
}
}
2 changes: 1 addition & 1 deletion lib/checks/parsing/duplicate-id-active.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"impact": "serious",
"messages": {
"pass": "Document has no active elements that share the same id attribute",
"fail": "Document has active elements with the same id attribute: {{=it.data}}"
"fail": "Document has active elements with the same id attribute: ${data}"
}
}
}
2 changes: 1 addition & 1 deletion lib/checks/parsing/duplicate-id-aria.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"impact": "critical",
"messages": {
"pass": "Document has no elements referenced with ARIA or labels that share the same id attribute",
"fail": "Document has multiple elements referenced with ARIA with the same id attribute: {{=it.data}}"
"fail": "Document has multiple elements referenced with ARIA with the same id attribute: ${data}"
}
}
}
5 changes: 4 additions & 1 deletion lib/checks/shared/avoid-inline-spacing.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"impact": "serious",
"messages": {
"pass": "No inline styles with '!important' that affect text spacing has been specified",
"fail": "Remove '!important' from inline style{{=it.data && it.data.length > 1 ? 's' : ''}} {{=it.data.join(', ')}}, as overriding this is not supported by most browsers"
"fail": {
"singular": "Remove '!important' from inline style ${data.values}, as overriding this is not supported by most browsers",
"plural": "Remove '!important' from inline styles ${data.values}, as overriding this is not supported by most browsers"
}
}
}
}
4 changes: 3 additions & 1 deletion lib/checks/shared/non-empty-if-present.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ let nodeName = node.nodeName.toUpperCase();
let type = (node.getAttribute('type') || '').toLowerCase();
let label = node.getAttribute('value');

this.data(label);
if (label) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message for this check used the existence of a label to determine the output, which doesn't work with the current schema. So I updated it since the data only needed to know a label was present and not what it was.

this.data('has-label');
}

if (nodeName === 'INPUT' && ['submit', 'reset'].includes(type)) {
return label === null;
Expand Down
5 changes: 4 additions & 1 deletion lib/checks/shared/non-empty-if-present.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
"metadata": {
"impact": "critical",
"messages": {
"pass": "Element {{?it.data}}has a non-empty value attribute{{??}}does not have a value attribute{{?}}",
"pass": {
"default": "Element does not have a value attribute",
"has-label": "Element has a non-empty value attribute"
},
"fail": "Element has a value attribute and the value attribute is empty"
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/core/reporters/helpers/incomplete-fallback-msg.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
*/
helpers.incompleteFallbackMessage = function incompleteFallbackMessage() {
'use strict';
return axe._audit.data.incompleteFallbackMessage();
return axe._audit.data.incompleteFallbackMessage;
};