Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
WilcoFiers committed Apr 24, 2018
2 parents 7f9d308 + cff3ce7 commit 0123cfd
Show file tree
Hide file tree
Showing 30 changed files with 315 additions and 62 deletions.
File renamed without changes.
File renamed without changes.
24 changes: 24 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"default": true,
"MD001": false,
"MD002": false,
"MD004": false,
"MD006": false,
"MD007": false,
"MD009": false,
"MD010": false,
"MD012": false,
"MD013": false,
"MD022": false,
"MD024": false,
"MD026": false,
"MD029": false,
"MD030": false,
"MD031": false,
"MD032": false,
"MD033": false,
"MD034": false,
"MD036": false,
"MD040": false,
"MD041": false
}
4 changes: 4 additions & 0 deletions .retireignore.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
"path": "node_modules/grunt-retire",
"justification" : "Used only for testing"
},
{
"path": "node_modules/sshpk",
"justification" : "A dependency of retirejs/request"
},
{
"path": "node_modules/grunt-mocha",
"justification" : "Used only for testing"
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.


<a name="3.0.2"></a>
## [3.0.2](https://github.com/dequelabs/axe-core/compare/v3.0.0-beta.2...v3.0.2) (2018-04-24)


### Bug Fixes

* **rule:** Allow empty aria-labelledby values ([#829](https://github.com/dequelabs/axe-core/issues/829)) ([d280c5f](https://github.com/dequelabs/axe-core/commit/d280c5f))
* Prevent color rules from crashing Chrome 66+ [#856](https://github.com/dequelabs/axe-core/issues/856) ([#861](https://github.com/dequelabs/axe-core/issues/861)) ([147b665](https://github.com/dequelabs/axe-core/commit/147b665))
* **respondable:** Identify the current axe instance by its application name when it exists ([affd75c](https://github.com/dequelabs/axe-core/commit/affd75c))
* **respondable:** Use the hard-coded axe.application name as default ([ab4a49f](https://github.com/dequelabs/axe-core/commit/ab4a49f))
* **rule:** Ignore hashbang URLs for skiplinks ([#827](https://github.com/dequelabs/axe-core/issues/827)) ([e1f0c57](https://github.com/dequelabs/axe-core/commit/e1f0c57))
* **rule:** Tag video-caption only as SC 1.2.2 ([87818e7](https://github.com/dequelabs/axe-core/commit/87818e7))



<a name="3.0.1"></a>
## [3.0.1](https://github.com/dequelabs/axe-core/compare/v3.0.0...v3.0.1) (2018-04-03)

Expand Down
15 changes: 14 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-mocha');
grunt.loadTasks('build/tasks');
grunt.loadNpmTasks('grunt-parallel');
grunt.loadNpmTasks('grunt-markdownlint');

var langs;
if (grunt.option('lang')) {
Expand Down Expand Up @@ -334,6 +335,18 @@ module.exports = function (grunt) {
'!**/node_modules/**/*.js'
]
}
},
markdownlint: {
all: {
options: {
config: grunt.file.readJSON('.markdownlint.json')
},
src: [
'README.md',
'.github/*.md',
'doc/**/*.md'
]
}
}
});

Expand All @@ -343,7 +356,7 @@ module.exports = function (grunt) {
'babel', 'concat:engine', 'uglify']);

grunt.registerTask('test', ['build', 'retire', 'testconfig', 'fixture', 'connect',
'mocha', 'parallel', 'eslint']);
'mocha', 'parallel', 'eslint', 'markdownlint']);

grunt.registerTask('ci-build', ['build', 'retire', 'testconfig', 'fixture', 'connect',
'parallel', 'eslint']);
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,17 @@ axe.run(function (err, results) {
```
## Supported Browsers

The [aXe API](doc/API.md) supports the following browsers:
The [aXe API](doc/API.md) fully supports the following browsers:

* Internet Explorer v9, 10, 11
* Microsoft Edge v40 and above
* Google Chrome v42 and above
* Mozilla Firefox v38 and above
* Apple Safari v7 and above
* Internet Explorer v9, 10, 11

Support means that we will fix bugs and attempt to test each browser regularly. Only Firefox and Chrome are currently tested on every pull request.

There is limited support for JSDOM. We will attempt to make all rules compatible with JSDOM but where this is not possible, we recommend turning those rules off. Currently the `color-contrast` rule is known not to work with JSDOM.

## The Accessibility Rules

Expand All @@ -95,7 +100,7 @@ To update existing translation file, re-run `grunt translate --lang=<langcode>`.

## Contributing

Read the [Proposing Axe-core Rules guide ](./doc/rule-proposal.md)
Read the [Proposing Axe-core Rules guide](./doc/rule-proposal.md)

Read the [documentation on the architecture](./doc/developer-guide.md)

Expand Down
16 changes: 6 additions & 10 deletions axe.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Type definitions for axe-core 3.0.1
// Type definitions for axe-core 3.0.2
// Project: https://github.com/dequelabs/axe-core
// Definitions by: Marcy Sutton <https://github.com/marcysutton>

Expand All @@ -13,18 +13,14 @@ declare module axe {
type RunOnlyType = "rule" | "rules" | "tag" | "tags";

type RunOnlyObject = {
include?: string[],
exclude?: string[]
include?: string[] | string[][],
exclude?: string[] | string[][]
}

type RunCallback = (error: Error, results:AxeResults) => void;

interface ElementContext {
node?: Object,
selector?: string,
include?: any[],
exclude?: any[]
}
type ElementContext = Node | string | RunOnlyObject;

interface RunOnly {
type: RunOnlyType,
values?: TagValue[] | RunOnlyObject
Expand Down Expand Up @@ -132,7 +128,7 @@ declare module axe {
* @param {RunCallback} callback Optional The function to invoke when analysis is complete.
* @returns {Promise<AxeResults>|void} If the callback was not defined, aXe will return a Promise.
*/
function run(context: ElementContext): Promise<AxeResults>
function run(context?: ElementContext): Promise<AxeResults>
function run(options: RunOptions): Promise<AxeResults>
function run(callback: (error: Error, results:AxeResults) => void): void
function run(context: ElementContext, callback: RunCallback): void
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "axe-core",
"version": "3.0.1",
"version": "3.0.2",
"contributors": [
{
"name": "David Sturley",
Expand Down
4 changes: 2 additions & 2 deletions doc/rule-descriptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
| blink | Ensures &lt;blink&gt; elements are not used | cat.time-and-media, wcag2a, wcag222, section508, section508.22.j | true |
| button-name | Ensures buttons have discernible text | cat.name-role-value, wcag2a, wcag412, section508, section508.22.a | true |
| bypass | Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content | cat.keyboard, wcag2a, wcag241, section508, section508.22.o | true |
| checkboxgroup | Ensures related &lt;input type=&quot;checkbox&quot;&gt; elements have a group and that that group designation is consistent | cat.forms, best-practice | true |
| checkboxgroup | Ensures related &lt;input type=&quot;checkbox&quot;&gt; elements have a group and that the group designation is consistent | cat.forms, best-practice | true |
| color-contrast | Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds | cat.color, wcag2aa, wcag143 | true |
| definition-list | Ensures &lt;dl&gt; elements are structured correctly | cat.structure, wcag2a, wcag131 | true |
| dlitem | Ensures &lt;dt&gt; and &lt;dd&gt; elements are contained by a &lt;dl&gt; | cat.structure, wcag2a, wcag131 | true |
Expand Down Expand Up @@ -65,5 +65,5 @@
| td-headers-attr | Ensure that each cell in a table using the headers refers to another cell in that table | cat.tables, wcag2a, wcag131, section508, section508.22.g | true |
| th-has-data-cells | Ensure that each table header in a data table refers to data cells | cat.tables, wcag2a, wcag131, section508, section508.22.g | true |
| valid-lang | Ensures lang attributes have valid values | cat.language, wcag2aa, wcag312 | true |
| video-caption | Ensures &lt;video&gt; elements have captions | cat.text-alternatives, wcag2a, wcag122, wcag123, section508, section508.22.a | true |
| video-caption | Ensures &lt;video&gt; elements have captions | cat.text-alternatives, wcag2a, wcag122, section508, section508.22.a | true |
| video-description | Ensures &lt;video&gt; elements have audio descriptions | cat.text-alternatives, wcag2aa, wcag125, section508, section508.22.b | true |
4 changes: 3 additions & 1 deletion lib/checks/navigation/internal-link-present.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
const links = axe.utils.querySelectorAll(virtualNode, 'a[href]');
return links.some(vLink => vLink.actualNode.getAttribute('href')[0] === '#');
return links.some(vLink => {
return /^#[^/!]/.test(vLink.actualNode.getAttribute('href'))
});
6 changes: 5 additions & 1 deletion lib/commons/aria/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ aria.validateAttr = function (att) {
* @return {Boolean}
*/
aria.validateAttrValue = function (node, attr) {
/*eslint complexity: ["error",15]*/
/*eslint complexity: ["error",17]*/
'use strict';
var matches, list,
value = node.getAttribute(attr),
Expand Down Expand Up @@ -84,6 +84,10 @@ aria.validateAttrValue = function (node, attr) {
return !!(value && doc.getElementById(value));

case 'idrefs':
// exempt attributes that allow empty strings
if ((attrInfo.values && attrInfo.values.indexOf('') !== -1) && value.trim().length === 0) {
return true;
}
list = axe.utils.tokenList(value);
// Check if any value isn't in the list of values
return list.reduce(function (result, token) {
Expand Down
3 changes: 2 additions & 1 deletion lib/commons/aria/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ lookupTable.attributes = {
type: 'string'
},
'aria-labelledby': {
type: 'idrefs'
type: 'idrefs',
values: ['']
},
'aria-level': {
type: 'int'
Expand Down
12 changes: 9 additions & 3 deletions lib/commons/dom/shadow-elements-from-point.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@
* @param {Object} [root] Shadow root or document root
* @return {Array}
*/
dom.shadowElementsFromPoint = function(nodeX, nodeY, root = document) {
return root.elementsFromPoint(nodeX, nodeY)
dom.shadowElementsFromPoint = function(nodeX, nodeY, root = document, i=0) {
if (i > 999) {
throw new Error('Infinite loop detected');
}
return Array.from(root.elementsFromPoint(nodeX, nodeY))
// As of Chrome 66, elementFromPoint will return elements from parent trees.
// We only want to touch each tree once, so we're filtering out nodes on other trees.
.filter(nodes => dom.getRootNode(nodes) === root)
.reduce((stack, elm) => {
if (axe.utils.isShadowRoot(elm)) {
const shadowStack = dom.shadowElementsFromPoint(nodeX, nodeY, elm.shadowRoot);
const shadowStack = dom.shadowElementsFromPoint(nodeX, nodeY, elm.shadowRoot, i+1);
stack = stack.concat(shadowStack);
// filter host nodes which get included regardless of overlap
// TODO: refactor multiline overlap checking inside shadow dom
Expand Down
18 changes: 9 additions & 9 deletions lib/core/utils/respondable.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
* @private
*/
function _getSource() {
var application = 'axe', version = '', src;
if (typeof axe !== 'undefined' && axe._audit && !axe._audit.application) {
var application = 'axeAPI', version = '', src;
if (typeof axe !== 'undefined' && axe._audit && axe._audit.application) {
application = axe._audit.application;
}
if (typeof axe !== 'undefined') {
Expand All @@ -37,8 +37,8 @@
return ( // Check the version matches
postedMessage._source === messageSource ||
// Allow free communication with axe test
postedMessage._source === 'axe.x.y.z' ||
messageSource === 'axe.x.y.z'
postedMessage._source === 'axeAPI.x.y.z' ||
messageSource === 'axeAPI.x.y.z'
);
}
return false;
Expand Down Expand Up @@ -135,16 +135,16 @@
/**
* Publishes the "respondable" message to the appropriate subscriber
* @private
* @param {Event} event The event object of the postMessage
* @param {Object} data The data sent with the message
* @param {Boolean} keepalive Whether to allow multiple responses - default is false
* @param {Window} source The window from which the message originated
* @param {Object} data The data sent with the message
* @param {Boolean} keepalive Whether to allow multiple responses - default is false
*/
function publish(target, data, keepalive) {
function publish(source, data, keepalive) {
var topic = data.topic;
var subscriber = subscribers[topic];

if (subscriber) {
var responder = createResponder(target, null, data.uuid);
var responder = createResponder(source, null, data.uuid);
subscriber(data.message, keepalive, responder);
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/rules/checkboxgroup.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"best-practice"
],
"metadata": {
"description": "Ensures related <input type=\"checkbox\"> elements have a group and that that group designation is consistent",
"description": "Ensures related <input type=\"checkbox\"> elements have a group and that the group designation is consistent",
"help": "Checkbox inputs with the same name attribute value must be part of a group"
},
"all": [],
Expand Down
6 changes: 5 additions & 1 deletion lib/rules/layout-table-matches.js
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
return !axe.commons.table.isDataTable(node);
var role = (node.getAttribute('role') || '').toLowerCase();

return !((role === 'presentation' || role === 'none') &&
!axe.commons.dom.isFocusable(node)) &&
!axe.commons.table.isDataTable(node);
3 changes: 1 addition & 2 deletions lib/rules/skip-link-matches.js
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
const href = node.getAttribute('href');
return (href[0] === '#' && href.length > 1);
return /^#[^/!]/.test(node.getAttribute('href'));
1 change: 0 additions & 1 deletion lib/rules/video-caption.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"cat.text-alternatives",
"wcag2a",
"wcag122",
"wcag123",
"section508",
"section508.22.a"
],
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "axe-core",
"description": "Accessibility engine for automated Web UI testing",
"version": "3.0.1",
"version": "3.0.2",
"license": "MPL-2.0",
"engines": {
"node": ">=4"
Expand Down Expand Up @@ -78,6 +78,7 @@
"grunt-contrib-uglify": "^2.1.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-eslint": "^20.1.0",
"grunt-markdownlint": "^1.1.2",
"grunt-mocha": "^1.0.4",
"grunt-parallel": "^0.5.1",
"grunt-retire": "^1.0.7",
Expand Down
4 changes: 4 additions & 0 deletions sri-history.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,9 @@
"3.0.1": {
"axe.js": "sha256-Vf/arxSrHppK2X5x6VgBZLJnCy8yK6P6uH99WwzQ30s=",
"axe.min.js": "sha256-vMPyo7vifw5RTaVEAlnfwGFa9VyHymsNqanCsHh3Q8c="
},
"3.0.2": {
"axe.js": "sha256-D24i3Yy35gMxOZNTNZyQLAyL3W3wVvW1wUYakK5v1VI=",
"axe.min.js": "sha256-Hsc1oDUNhkVBP4gVUaC9jNm9t0qmLpTJzXW4uzx10bo="
}
}
12 changes: 12 additions & 0 deletions test/checks/aria/valid-attr-value.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ describe('aria-valid-attr-value', function () {

var fixture = document.getElementById('fixture');
var checkContext = axe.testUtils.MockCheckContext();
var fixtureSetup = axe.testUtils.fixtureSetup;

afterEach(function () {
fixture.innerHTML = '';
Expand Down Expand Up @@ -89,6 +90,17 @@ describe('aria-valid-attr-value', function () {
axe.commons.aria.validateAttrValue = orig;
});

it('should allow empty strings rather than idrefs for specific attributes', function () {
fixtureSetup(
'<button aria-labelledby="">Button</button>' +
'<div aria-owns=""></div>'
);
var passing = fixture.querySelector('button');
var failing = fixture.querySelector('div');
assert.isTrue(checks['aria-valid-attr-value'].evaluate.call(checkContext, passing));
assert.isFalse(checks['aria-valid-attr-value'].evaluate.call(checkContext, failing));
});

describe('options', function () {
it('should exclude supplied attributes', function () {
fixture.innerHTML = '<div id="target" aria-live="nope" aria-describedby="no exist k thx"></div>';
Expand Down
Loading

0 comments on commit 0123cfd

Please sign in to comment.