axe-core
Version:
Accessibility engine for automated Web UI testing
1,565 lines (1,560 loc) • 430 kB
JavaScript
(function axeFunction(window) {
var global = window;
var document = window.document;
'use strict';
var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
return typeof obj;
} : function(obj) {
return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
};
var axe = axe || {};
axe.version = '3.0.4';
if (typeof define === 'function' && define.amd) {
define('axe-core', [], function() {
'use strict';
return axe;
});
}
if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object' && module.exports && typeof axeFunction.toString === 'function') {
axe.source = '(' + axeFunction.toString() + ')(typeof window === "object" ? window : this);';
module.exports = axe;
}
if (typeof window.getComputedStyle === 'function') {
window.axe = axe;
}
var commons;
function SupportError(error) {
this.name = 'SupportError';
this.cause = error.cause;
this.message = '`' + error.cause + '` - feature unsupported in your environment.';
if (error.ruleId) {
this.ruleId = error.ruleId;
this.message += ' Skipping ' + this.ruleId + ' rule.';
}
this.stack = new Error().stack;
}
SupportError.prototype = Object.create(Error.prototype);
SupportError.prototype.constructor = SupportError;
'use strict';
var utils = axe.utils = {};
'use strict';
var helpers = {};
'use strict';
var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
return typeof obj;
} : function(obj) {
return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
};
function getDefaultConfiguration(audit) {
'use strict';
var config;
if (audit) {
config = axe.utils.clone(audit);
config.commons = audit.commons;
} else {
config = {};
}
config.reporter = config.reporter || null;
config.noHtml = config.noHtml || false;
config.rules = config.rules || [];
config.checks = config.checks || [];
config.data = Object.assign({
checks: {},
rules: {}
}, config.data);
return config;
}
function unpackToObject(collection, audit, method) {
'use strict';
var i, l;
for (i = 0, l = collection.length; i < l; i++) {
audit[method](collection[i]);
}
}
function Audit(audit) {
this.brand = 'axe';
this.application = 'axeAPI';
this.tagExclude = [ 'experimental' ];
this.defaultConfig = audit;
this._init();
}
Audit.prototype._init = function() {
var audit = getDefaultConfiguration(this.defaultConfig);
axe.commons = commons = audit.commons;
this.reporter = audit.reporter;
this.commands = {};
this.rules = [];
this.checks = {};
this.noHtml = audit.noHtml;
unpackToObject(audit.rules, this, 'addRule');
unpackToObject(audit.checks, this, 'addCheck');
this.data = {};
this.data.checks = audit.data && audit.data.checks || {};
this.data.rules = audit.data && audit.data.rules || {};
this.data.failureSummaries = audit.data && audit.data.failureSummaries || {};
this.data.incompleteFallbackMessage = audit.data && audit.data.incompleteFallbackMessage || '';
this._constructHelpUrls();
};
Audit.prototype.registerCommand = function(command) {
'use strict';
this.commands[command.id] = command.callback;
};
Audit.prototype.addRule = function(spec) {
'use strict';
if (spec.metadata) {
this.data.rules[spec.id] = spec.metadata;
}
var rule = this.getRule(spec.id);
if (rule) {
rule.configure(spec);
} else {
this.rules.push(new Rule(spec, this));
}
};
Audit.prototype.addCheck = function(spec) {
'use strict';
var metadata = spec.metadata;
if ((typeof metadata === 'undefined' ? 'undefined' : _typeof(metadata)) === 'object') {
this.data.checks[spec.id] = metadata;
if (_typeof(metadata.messages) === 'object') {
Object.keys(metadata.messages).filter(function(prop) {
return metadata.messages.hasOwnProperty(prop) && typeof metadata.messages[prop] === 'string';
}).forEach(function(prop) {
if (metadata.messages[prop].indexOf('function') === 0) {
metadata.messages[prop] = new Function('return ' + metadata.messages[prop] + ';')();
}
});
}
}
if (this.checks[spec.id]) {
this.checks[spec.id].configure(spec);
} else {
this.checks[spec.id] = new Check(spec);
}
};
Audit.prototype.run = function(context, options, resolve, reject) {
'use strict';
this.normalizeOptions(options);
axe._selectCache = [];
var q = axe.utils.queue();
this.rules.forEach(function(rule) {
if (axe.utils.ruleShouldRun(rule, context, options)) {
if (options.performanceTimer) {
var markEnd = 'mark_rule_end_' + rule.id;
var markStart = 'mark_rule_start_' + rule.id;
axe.utils.performanceTimer.mark(markStart);
}
q.defer(function(res, rej) {
rule.run(context, options, function(out) {
if (options.performanceTimer) {
axe.utils.performanceTimer.mark(markEnd);
axe.utils.performanceTimer.measure('rule_' + rule.id, markStart, markEnd);
}
res(out);
}, function(err) {
if (!options.debug) {
var errResult = Object.assign(new RuleResult(rule), {
result: axe.constants.CANTTELL,
description: 'An error occured while running this rule',
message: err.message,
stack: err.stack,
error: err
});
res(errResult);
} else {
rej(err);
}
});
});
}
});
q.then(function(results) {
axe._selectCache = undefined;
resolve(results.filter(function(result) {
return !!result;
}));
}).catch(reject);
};
Audit.prototype.after = function(results, options) {
'use strict';
var rules = this.rules;
return results.map(function(ruleResult) {
var rule = axe.utils.findBy(rules, 'id', ruleResult.id);
if (!rule) {
throw new Error('Result for unknown rule. You may be running mismatch aXe-core versions');
}
return rule.after(ruleResult, options);
});
};
Audit.prototype.getRule = function(ruleId) {
return this.rules.find(function(rule) {
return rule.id === ruleId;
});
};
Audit.prototype.normalizeOptions = function(options) {
'use strict';
var audit = this;
if (_typeof(options.runOnly) === 'object') {
if (Array.isArray(options.runOnly)) {
options.runOnly = {
type: 'tag',
values: options.runOnly
};
}
var only = options.runOnly;
if (only.value && !only.values) {
only.values = only.value;
delete only.value;
}
if (!Array.isArray(only.values) || only.values.length === 0) {
throw new Error('runOnly.values must be a non-empty array');
}
if ([ 'rule', 'rules' ].includes(only.type)) {
only.type = 'rule';
only.values.forEach(function(ruleId) {
if (!audit.getRule(ruleId)) {
throw new Error('unknown rule `' + ruleId + '` in options.runOnly');
}
});
} else if ([ 'tag', 'tags', undefined ].includes(only.type)) {
only.type = 'tag';
var unmatchedTags = audit.rules.reduce(function(unmatchedTags, rule) {
return unmatchedTags.length ? unmatchedTags.filter(function(tag) {
return !rule.tags.includes(tag);
}) : unmatchedTags;
}, only.values);
if (unmatchedTags.length !== 0) {
throw new Error('Could not find tags `' + unmatchedTags.join('`, `') + '`');
}
} else {
throw new Error('Unknown runOnly type \'' + only.type + '\'');
}
}
if (_typeof(options.rules) === 'object') {
Object.keys(options.rules).forEach(function(ruleId) {
if (!audit.getRule(ruleId)) {
throw new Error('unknown rule `' + ruleId + '` in options.rules');
}
});
}
return options;
};
Audit.prototype.setBranding = function(branding) {
'use strict';
var previous = {
brand: this.brand,
application: this.application
};
if (branding && branding.hasOwnProperty('brand') && branding.brand && typeof branding.brand === 'string') {
this.brand = branding.brand;
}
if (branding && branding.hasOwnProperty('application') && branding.application && typeof branding.application === 'string') {
this.application = branding.application;
}
this._constructHelpUrls(previous);
};
function getHelpUrl(_ref, ruleId, version) {
var brand = _ref.brand, application = _ref.application;
return axe.constants.helpUrlBase + brand + '/' + (version || axe.version.substring(0, axe.version.lastIndexOf('.'))) + '/' + ruleId + '?application=' + application;
}
Audit.prototype._constructHelpUrls = function() {
var _this = this;
var previous = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var version = (axe.version.match(/^[1-9][0-9]*\.[0-9]+/) || [ 'x.y' ])[0];
this.rules.forEach(function(rule) {
if (!_this.data.rules[rule.id]) {
_this.data.rules[rule.id] = {};
}
var metaData = _this.data.rules[rule.id];
if (typeof metaData.helpUrl !== 'string' || previous && metaData.helpUrl === getHelpUrl(previous, rule.id, version)) {
metaData.helpUrl = getHelpUrl(_this, rule.id, version);
}
});
};
Audit.prototype.resetRulesAndChecks = function() {
'use strict';
this._init();
};
'use strict';
function CheckResult(check) {
'use strict';
this.id = check.id;
this.data = null;
this.relatedNodes = [];
this.result = null;
}
'use strict';
function createExecutionContext(spec) {
'use strict';
if (typeof spec === 'string') {
return new Function('return ' + spec + ';')();
}
return spec;
}
function Check(spec) {
if (spec) {
this.id = spec.id;
this.configure(spec);
}
}
Check.prototype.enabled = true;
Check.prototype.run = function(node, options, resolve, reject) {
'use strict';
options = options || {};
var enabled = options.hasOwnProperty('enabled') ? options.enabled : this.enabled, checkOptions = options.options || this.options;
if (enabled) {
var checkResult = new CheckResult(this);
var checkHelper = axe.utils.checkHelper(checkResult, options, resolve, reject);
var result;
try {
result = this.evaluate.call(checkHelper, node.actualNode, checkOptions, node);
} catch (e) {
reject(e);
return;
}
if (!checkHelper.isAsync) {
checkResult.result = result;
setTimeout(function() {
resolve(checkResult);
}, 0);
}
} else {
resolve(null);
}
};
Check.prototype.configure = function(spec) {
var _this = this;
[ 'options', 'enabled' ].filter(function(prop) {
return spec.hasOwnProperty(prop);
}).forEach(function(prop) {
return _this[prop] = spec[prop];
});
[ 'evaluate', 'after' ].filter(function(prop) {
return spec.hasOwnProperty(prop);
}).forEach(function(prop) {
return _this[prop] = createExecutionContext(spec[prop]);
});
};
'use strict';
var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
return typeof obj;
} : function(obj) {
return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
};
function pushUniqueFrame(collection, frame) {
'use strict';
if (axe.utils.isHidden(frame)) {
return;
}
var fr = axe.utils.findBy(collection, 'node', frame);
if (!fr) {
collection.push({
node: frame,
include: [],
exclude: []
});
}
}
function pushUniqueFrameSelector(context, type, selectorArray) {
'use strict';
context.frames = context.frames || [];
var result, frame;
var frames = document.querySelectorAll(selectorArray.shift());
frameloop: for (var i = 0, l = frames.length; i < l; i++) {
frame = frames[i];
for (var j = 0, l2 = context.frames.length; j < l2; j++) {
if (context.frames[j].node === frame) {
context.frames[j][type].push(selectorArray);
break frameloop;
}
}
result = {
node: frame,
include: [],
exclude: []
};
if (selectorArray) {
result[type].push(selectorArray);
}
context.frames.push(result);
}
}
function normalizeContext(context) {
'use strict';
if (context && (typeof context === 'undefined' ? 'undefined' : _typeof(context)) === 'object' || context instanceof NodeList) {
if (context instanceof Node) {
return {
include: [ context ],
exclude: []
};
}
if (context.hasOwnProperty('include') || context.hasOwnProperty('exclude')) {
return {
include: context.include && +context.include.length ? context.include : [ document ],
exclude: context.exclude || []
};
}
if (context.length === +context.length) {
return {
include: context,
exclude: []
};
}
}
if (typeof context === 'string') {
return {
include: [ context ],
exclude: []
};
}
return {
include: [ document ],
exclude: []
};
}
function parseSelectorArray(context, type) {
'use strict';
var item, result = [], nodeList;
for (var i = 0, l = context[type].length; i < l; i++) {
item = context[type][i];
if (typeof item === 'string') {
nodeList = Array.from(document.querySelectorAll(item));
result = result.concat(nodeList.map(function(node) {
return axe.utils.getNodeFromTree(context.flatTree[0], node);
}));
break;
} else if (item && item.length && !(item instanceof Node)) {
if (item.length > 1) {
pushUniqueFrameSelector(context, type, item);
} else {
nodeList = Array.from(document.querySelectorAll(item[0]));
result = result.concat(nodeList.map(function(node) {
return axe.utils.getNodeFromTree(context.flatTree[0], node);
}));
}
} else if (item instanceof Node) {
if (item.documentElement instanceof Node) {
result.push(context.flatTree[0]);
} else {
result.push(axe.utils.getNodeFromTree(context.flatTree[0], item));
}
}
}
return result.filter(function(r) {
return r;
});
}
function validateContext(context) {
'use strict';
if (context.include.length === 0) {
if (context.frames.length === 0) {
var env = axe.utils.respondable.isInFrame() ? 'frame' : 'page';
return new Error('No elements found for include in ' + env + ' Context');
}
context.frames.forEach(function(frame, i) {
if (frame.include.length === 0) {
return new Error('No elements found for include in Context of frame ' + i);
}
});
}
}
function getRootNode(_ref) {
var include = _ref.include, exclude = _ref.exclude;
var selectors = Array.from(include).concat(Array.from(exclude));
var localDocument = selectors.reduce(function(result, item) {
if (result) {
return result;
} else if (item instanceof Element) {
return item.ownerDocument;
} else if (item instanceof Document) {
return item;
}
}, null);
return (localDocument || document).documentElement;
}
function Context(spec) {
'use strict';
var _this = this;
this.frames = [];
this.initiator = spec && typeof spec.initiator === 'boolean' ? spec.initiator : true;
this.page = false;
spec = normalizeContext(spec);
this.flatTree = axe.utils.getFlattenedTree(getRootNode(spec));
this.exclude = spec.exclude;
this.include = spec.include;
this.include = parseSelectorArray(this, 'include');
this.exclude = parseSelectorArray(this, 'exclude');
axe.utils.select('frame, iframe', this).forEach(function(frame) {
if (isNodeInContext(frame, _this)) {
pushUniqueFrame(_this.frames, frame.actualNode);
}
});
if (this.include.length === 1 && this.include[0].actualNode === document.documentElement) {
this.page = true;
}
var err = validateContext(this);
if (err instanceof Error) {
throw err;
}
if (!Array.isArray(this.include)) {
this.include = Array.from(this.include);
}
this.include.sort(axe.utils.nodeSorter);
}
'use strict';
function RuleResult(rule) {
'use strict';
this.id = rule.id;
this.result = axe.constants.NA;
this.pageLevel = rule.pageLevel;
this.impact = null;
this.nodes = [];
}
'use strict';
function Rule(spec, parentAudit) {
'use strict';
this._audit = parentAudit;
this.id = spec.id;
this.selector = spec.selector || '*';
this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;
this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;
this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;
this.any = spec.any || [];
this.all = spec.all || [];
this.none = spec.none || [];
this.tags = spec.tags || [];
if (spec.matches) {
this.matches = createExecutionContext(spec.matches);
}
}
Rule.prototype.matches = function() {
'use strict';
return true;
};
Rule.prototype.gather = function(context) {
'use strict';
var elements = axe.utils.select(this.selector, context);
if (this.excludeHidden) {
return elements.filter(function(element) {
return !axe.utils.isHidden(element.actualNode);
});
}
return elements;
};
Rule.prototype.runChecks = function(type, node, options, resolve, reject) {
'use strict';
var self = this;
var checkQueue = axe.utils.queue();
this[type].forEach(function(c) {
var check = self._audit.checks[c.id || c];
var option = axe.utils.getCheckOption(check, self.id, options);
checkQueue.defer(function(res, rej) {
check.run(node, option, res, rej);
});
});
checkQueue.then(function(results) {
results = results.filter(function(check) {
return check;
});
resolve({
type: type,
results: results
});
}).catch(reject);
};
Rule.prototype.run = function(context, options, resolve, reject) {
var _this = this;
var q = axe.utils.queue();
var ruleResult = new RuleResult(this);
var markStart = 'mark_runchecks_start_' + this.id;
var markEnd = 'mark_runchecks_end_' + this.id;
var nodes = void 0;
try {
nodes = this.gather(context).filter(function(node) {
return _this.matches(node.actualNode, node);
});
} catch (error) {
reject(new SupportError({
cause: error,
ruleId: this.id
}));
return;
}
if (options.performanceTimer) {
axe.log('gather (', nodes.length, '):', axe.utils.performanceTimer.timeElapsed() + 'ms');
axe.utils.performanceTimer.mark(markStart);
}
nodes.forEach(function(node) {
q.defer(function(resolveNode, rejectNode) {
var checkQueue = axe.utils.queue();
checkQueue.defer(function(res, rej) {
_this.runChecks('any', node, options, res, rej);
});
checkQueue.defer(function(res, rej) {
_this.runChecks('all', node, options, res, rej);
});
checkQueue.defer(function(res, rej) {
_this.runChecks('none', node, options, res, rej);
});
checkQueue.then(function(results) {
if (results.length) {
var hasResults = false, result = {};
results.forEach(function(r) {
var res = r.results.filter(function(result) {
return result;
});
result[r.type] = res;
if (res.length) {
hasResults = true;
}
});
if (hasResults) {
result.node = new axe.utils.DqElement(node.actualNode, options);
ruleResult.nodes.push(result);
}
}
resolveNode();
}).catch(function(err) {
return rejectNode(err);
});
});
});
if (options.performanceTimer) {
axe.utils.performanceTimer.mark(markEnd);
axe.utils.performanceTimer.measure('runchecks_' + this.id, markStart, markEnd);
}
q.then(function() {
return resolve(ruleResult);
}).catch(function(error) {
return reject(error);
});
};
function findAfterChecks(rule) {
'use strict';
return axe.utils.getAllChecks(rule).map(function(c) {
var check = rule._audit.checks[c.id || c];
return check && typeof check.after === 'function' ? check : null;
}).filter(Boolean);
}
function findCheckResults(nodes, checkID) {
'use strict';
var checkResults = [];
nodes.forEach(function(nodeResult) {
var checks = axe.utils.getAllChecks(nodeResult);
checks.forEach(function(checkResult) {
if (checkResult.id === checkID) {
checkResults.push(checkResult);
}
});
});
return checkResults;
}
function filterChecks(checks) {
'use strict';
return checks.filter(function(check) {
return check.filtered !== true;
});
}
function sanitizeNodes(result) {
'use strict';
var checkTypes = [ 'any', 'all', 'none' ];
var nodes = result.nodes.filter(function(detail) {
var length = 0;
checkTypes.forEach(function(type) {
detail[type] = filterChecks(detail[type]);
length += detail[type].length;
});
return length > 0;
});
if (result.pageLevel && nodes.length) {
nodes = [ nodes.reduce(function(a, b) {
if (a) {
checkTypes.forEach(function(type) {
a[type].push.apply(a[type], b[type]);
});
return a;
}
}) ];
}
return nodes;
}
Rule.prototype.after = function(result, options) {
'use strict';
var afterChecks = findAfterChecks(this);
var ruleID = this.id;
afterChecks.forEach(function(check) {
var beforeResults = findCheckResults(result.nodes, check.id);
var option = axe.utils.getCheckOption(check, ruleID, options);
var afterResults = check.after(beforeResults, option);
beforeResults.forEach(function(item) {
if (afterResults.indexOf(item) === -1) {
item.filtered = true;
}
});
});
result.nodes = sanitizeNodes(result);
return result;
};
Rule.prototype.configure = function(spec) {
'use strict';
if (spec.hasOwnProperty('selector')) {
this.selector = spec.selector;
}
if (spec.hasOwnProperty('excludeHidden')) {
this.excludeHidden = typeof spec.excludeHidden === 'boolean' ? spec.excludeHidden : true;
}
if (spec.hasOwnProperty('enabled')) {
this.enabled = typeof spec.enabled === 'boolean' ? spec.enabled : true;
}
if (spec.hasOwnProperty('pageLevel')) {
this.pageLevel = typeof spec.pageLevel === 'boolean' ? spec.pageLevel : false;
}
if (spec.hasOwnProperty('any')) {
this.any = spec.any;
}
if (spec.hasOwnProperty('all')) {
this.all = spec.all;
}
if (spec.hasOwnProperty('none')) {
this.none = spec.none;
}
if (spec.hasOwnProperty('tags')) {
this.tags = spec.tags;
}
if (spec.hasOwnProperty('matches')) {
if (typeof spec.matches === 'string') {
this.matches = new Function('return ' + spec.matches + ';')();
} else {
this.matches = spec.matches;
}
}
};
'use strict';
(function(axe) {
var definitions = [ {
name: 'NA',
value: 'inapplicable',
priority: 0,
group: 'inapplicable'
}, {
name: 'PASS',
value: 'passed',
priority: 1,
group: 'passes'
}, {
name: 'CANTTELL',
value: 'cantTell',
priority: 2,
group: 'incomplete'
}, {
name: 'FAIL',
value: 'failed',
priority: 3,
group: 'violations'
} ];
var constants = {
helpUrlBase: 'https://dequeuniversity.com/rules/',
results: [],
resultGroups: [],
resultGroupMap: {},
impact: Object.freeze([ 'minor', 'moderate', 'serious', 'critical' ])
};
definitions.forEach(function(definition) {
var name = definition.name;
var value = definition.value;
var priority = definition.priority;
var group = definition.group;
constants[name] = value;
constants[name + '_PRIO'] = priority;
constants[name + '_GROUP'] = group;
constants.results[priority] = value;
constants.resultGroups[priority] = group;
constants.resultGroupMap[value] = group;
});
Object.freeze(constants.results);
Object.freeze(constants.resultGroups);
Object.freeze(constants.resultGroupMap);
Object.freeze(constants);
Object.defineProperty(axe, 'constants', {
value: constants,
enumerable: true,
configurable: false,
writable: false
});
})(axe);
'use strict';
var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
return typeof obj;
} : function(obj) {
return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
};
axe.log = function() {
'use strict';
if ((typeof console === 'undefined' ? 'undefined' : _typeof(console)) === 'object' && console.log) {
Function.prototype.apply.call(console.log, console, arguments);
}
};
'use strict';
function cleanupPlugins(resolve, reject) {
'use strict';
resolve = resolve || function() {};
reject = reject || axe.log;
if (!axe._audit) {
throw new Error('No audit configured');
}
var q = axe.utils.queue();
var cleanupErrors = [];
Object.keys(axe.plugins).forEach(function(key) {
q.defer(function(res) {
var rej = function rej(err) {
cleanupErrors.push(err);
res();
};
try {
axe.plugins[key].cleanup(res, rej);
} catch (err) {
rej(err);
}
});
});
var flattenedTree = axe.utils.getFlattenedTree(document.body);
axe.utils.querySelectorAll(flattenedTree, 'iframe, frame').forEach(function(node) {
q.defer(function(res, rej) {
return axe.utils.sendCommandToFrame(node.actualNode, {
command: 'cleanup-plugin'
}, res, rej);
});
});
q.then(function(results) {
if (cleanupErrors.length === 0) {
resolve(results);
} else {
reject(cleanupErrors);
}
}).catch(reject);
}
axe.cleanup = cleanupPlugins;
'use strict';
function configureChecksRulesAndBranding(spec) {
'use strict';
var audit;
audit = axe._audit;
if (!audit) {
throw new Error('No audit configured');
}
if (spec.reporter && (typeof spec.reporter === 'function' || reporters[spec.reporter])) {
audit.reporter = spec.reporter;
}
if (spec.checks) {
spec.checks.forEach(function(check) {
audit.addCheck(check);
});
}
var modifiedRules = [];
if (spec.rules) {
spec.rules.forEach(function(rule) {
modifiedRules.push(rule.id);
audit.addRule(rule);
});
}
if (spec.disableOtherRules) {
audit.rules.forEach(function(rule) {
if (modifiedRules.includes(rule.id) === false) {
rule.enabled = false;
}
});
}
if (typeof spec.branding !== 'undefined') {
audit.setBranding(spec.branding);
} else {
audit._constructHelpUrls();
}
if (spec.tagExclude) {
audit.tagExclude = spec.tagExclude;
}
if (spec.noHtml) {
audit.noHtml = true;
}
}
axe.configure = configureChecksRulesAndBranding;
'use strict';
axe.getRules = function(tags) {
'use strict';
tags = tags || [];
var matchingRules = !tags.length ? axe._audit.rules : axe._audit.rules.filter(function(item) {
return !!tags.filter(function(tag) {
return item.tags.indexOf(tag) !== -1;
}).length;
});
var ruleData = axe._audit.data.rules || {};
return matchingRules.map(function(matchingRule) {
var rd = ruleData[matchingRule.id] || {};
return {
ruleId: matchingRule.id,
description: rd.description,
help: rd.help,
helpUrl: rd.helpUrl,
tags: matchingRule.tags
};
});
};
'use strict';
function runCommand(data, keepalive, callback) {
'use strict';
var resolve = callback;
var reject = function reject(err) {
if (err instanceof Error === false) {
err = new Error(err);
}
callback(err);
};
var context = data && data.context || {};
if (context.hasOwnProperty('include') && !context.include.length) {
context.include = [ document ];
}
var options = data && data.options || {};
switch (data.command) {
case 'rules':
return runRules(context, options, function(results, cleanup) {
resolve(results);
cleanup();
}, reject);
case 'cleanup-plugin':
return cleanupPlugins(resolve, reject);
default:
if (axe._audit && axe._audit.commands && axe._audit.commands[data.command]) {
return axe._audit.commands[data.command](data, callback);
}
}
}
axe._load = function(audit) {
'use strict';
axe.utils.respondable.subscribe('axe.ping', function(data, keepalive, respond) {
respond({
axe: true
});
});
axe.utils.respondable.subscribe('axe.start', runCommand);
axe._audit = new Audit(audit);
};
'use strict';
var axe = axe || {};
axe.plugins = {};
function Plugin(spec) {
'use strict';
this._run = spec.run;
this._collect = spec.collect;
this._registry = {};
spec.commands.forEach(function(command) {
axe._audit.registerCommand(command);
});
}
Plugin.prototype.run = function() {
'use strict';
return this._run.apply(this, arguments);
};
Plugin.prototype.collect = function() {
'use strict';
return this._collect.apply(this, arguments);
};
Plugin.prototype.cleanup = function(done) {
'use strict';
var q = axe.utils.queue();
var that = this;
Object.keys(this._registry).forEach(function(key) {
q.defer(function(done) {
that._registry[key].cleanup(done);
});
});
q.then(function() {
done();
});
};
Plugin.prototype.add = function(impl) {
'use strict';
this._registry[impl.id] = impl;
};
axe.registerPlugin = function(plugin) {
'use strict';
axe.plugins[plugin.id] = new Plugin(plugin);
};
'use strict';
var reporters = {};
var defaultReporter;
axe.getReporter = function(reporter) {
'use strict';
if (typeof reporter === 'string' && reporters[reporter]) {
return reporters[reporter];
}
if (typeof reporter === 'function') {
return reporter;
}
return defaultReporter;
};
axe.addReporter = function registerReporter(name, cb, isDefault) {
'use strict';
reporters[name] = cb;
if (isDefault) {
defaultReporter = cb;
}
};
'use strict';
function resetConfiguration() {
'use strict';
var audit = axe._audit;
if (!audit) {
throw new Error('No audit configured');
}
audit.resetRulesAndChecks();
}
axe.reset = resetConfiguration;
'use strict';
function cleanup() {
axe._tree = undefined;
axe._selectorData = undefined;
}
function runRules(context, options, resolve, reject) {
'use strict';
try {
context = new Context(context);
axe._tree = context.flatTree;
axe._selectorData = axe.utils.getSelectorData(context.flatTree);
} catch (e) {
cleanup();
return reject(e);
}
var q = axe.utils.queue();
var audit = axe._audit;
if (options.performanceTimer) {
axe.utils.performanceTimer.auditStart();
}
if (context.frames.length && options.iframes !== false) {
q.defer(function(res, rej) {
axe.utils.collectResultsFromFrames(context, options, 'rules', null, res, rej);
});
}
var scrollState = void 0;
q.defer(function(res, rej) {
if (options.restoreScroll) {
scrollState = axe.utils.getScrollState();
}
audit.run(context, options, res, rej);
});
q.then(function(data) {
try {
if (scrollState) {
axe.utils.setScrollState(scrollState);
}
if (options.performanceTimer) {
axe.utils.performanceTimer.auditEnd();
}
var results = axe.utils.mergeResults(data.map(function(results) {
return {
results: results
};
}));
if (context.initiator) {
results = audit.after(results, options);
results.forEach(axe.utils.publishMetaData);
results = results.map(axe.utils.finalizeRuleResult);
}
try {
resolve(results, cleanup);
} catch (e) {
cleanup();
axe.log(e);
}
} catch (e) {
cleanup();
reject(e);
}
}).catch(function(e) {
cleanup();
reject(e);
});
}
axe._runRules = runRules;
'use strict';
var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
return typeof obj;
} : function(obj) {
return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
};
function isContext(potential) {
'use strict';
switch (true) {
case typeof potential === 'string':
case Array.isArray(potential):
case Node && potential instanceof Node:
case NodeList && potential instanceof NodeList:
return true;
case (typeof potential === 'undefined' ? 'undefined' : _typeof(potential)) !== 'object':
return false;
case potential.include !== undefined:
case potential.exclude !== undefined:
case typeof potential.length === 'number':
return true;
default:
return false;
}
}
var noop = function noop() {};
function normalizeRunParams(context, options, callback) {
'use strict';
var typeErr = new TypeError('axe.run arguments are invalid');
if (!isContext(context)) {
if (callback !== undefined) {
throw typeErr;
}
callback = options;
options = context;
context = document;
}
if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
if (callback !== undefined) {
throw typeErr;
}
callback = options;
options = {};
}
if (typeof callback !== 'function' && callback !== undefined) {
throw typeErr;
}
return {
context: context,
options: options,
callback: callback || noop
};
}
axe.run = function(context, options, callback) {
'use strict';
if (!axe._audit) {
throw new Error('No audit configured');
}
var args = normalizeRunParams(context, options, callback);
context = args.context;
options = args.options;
callback = args.callback;
options.reporter = options.reporter || axe._audit.reporter || 'v1';
if (options.performanceTimer) {
axe.utils.performanceTimer.start();
}
var p = void 0;
var reject = noop;
var resolve = noop;
if (window.Promise && callback === noop) {
p = new Promise(function(_resolve, _reject) {
reject = _reject;
resolve = _resolve;
});
}
axe._runRules(context, options, function(rawResults, cleanup) {
var respond = function respond(results) {
cleanup();
try {
callback(null, results);
} catch (e) {
axe.log(e);
}
resolve(results);
};
if (options.performanceTimer) {
axe.utils.performanceTimer.end();
}
try {
var reporter = axe.getReporter(options.reporter);
var results = reporter(rawResults, options, respond);
if (results !== undefined) {
respond(results);
}
} catch (err) {
cleanup();
callback(err);
reject(err);
}
}, function(err) {
callback(err);
reject(err);
});
return p;
};
'use strict';
helpers.failureSummary = function failureSummary(nodeData) {
'use strict';
var failingChecks = {};
failingChecks.none = nodeData.none.concat(nodeData.all);
failingChecks.any = nodeData.any;
return Object.keys(failingChecks).map(function(key) {
if (!failingChecks[key].length) {
return;
}
var sum = axe._audit.data.failureSummaries[key];
if (sum && typeof sum.failureMessage === 'function') {
return sum.failureMessage(failingChecks[key].map(function(check) {
return check.message || '';
}));
}
}).filter(function(i) {
return i !== undefined;
}).join('\n\n');
};
'use strict';
helpers.incompleteFallbackMessage = function incompleteFallbackMessage() {
'use strict';
return axe._audit.data.incompleteFallbackMessage();
};
'use strict';
var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
return typeof obj;
} : function(obj) {
return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
};
function normalizeRelatedNodes(node, options) {
'use strict';
[ 'any', 'all', 'none' ].forEach(function(type) {
if (!Array.isArray(node[type])) {
return;
}
node[type].filter(function(checkRes) {
return Array.isArray(checkRes.relatedNodes);
}).forEach(function(checkRes) {
checkRes.relatedNodes = checkRes.relatedNodes.map(function(relatedNode) {
var res = {
html: relatedNode.source
};
if (options.elementRef && !relatedNode.fromFrame) {
res.element = relatedNode.element;
}
if (options.selectors !== false || relatedNode.fromFrame) {
res.target = relatedNode.selector;
}
if (options.xpath) {
res.xpath = relatedNode.xpath;
}
return res;
});
});
});
}
var resultKeys = axe.constants.resultGroups;
helpers.processAggregate = function(results, options) {
var resultObject = axe.utils.aggregateResult(results);
resultObject.timestamp = new Date().toISOString();
resultObject.url = window.location.href;
resultKeys.forEach(function(key) {
if (options.resultTypes && !options.resultTypes.includes(key)) {
(resultObject[key] || []).forEach(function(ruleResult) {
if (Array.isArray(ruleResult.nodes) && ruleResult.nodes.length > 0) {
ruleResult.nodes = [ ruleResult.nodes[0] ];
}
});
}
resultObject[key] = (resultObject[key] || []).map(function(ruleResult) {
ruleResult = Object.assign({}, ruleResult);
if (Array.isArray(ruleResult.nodes) && ruleResult.nodes.length > 0) {
ruleResult.nodes = ruleResult.nodes.map(function(subResult) {
if (_typeof(subResult.node) === 'object') {
subResult.html = subResult.node.source;
if (options.elementRef && !subResult.node.fromFrame) {
subResult.element = subResult.node.element;
}
if (options.selectors !== false || subResult.node.fromFrame) {
subResult.target = subResult.node.selector;
}
if (options.xpath) {
subResult.xpath = subResult.node.xpath;
}
}
delete subResult.result;
delete subResult.node;
normalizeRelatedNodes(subResult, options);
return subResult;
});
}
resultKeys.forEach(function(key) {
return delete ruleResult[key];
});
delete ruleResult.pageLevel;
delete ruleResult.result;
return ruleResult;
});
});
return resultObject;
};
'use strict';
axe.addReporter('na', function(results, options, callback) {
'use strict';
if (typeof options === 'function') {
callback = options;
options = {};
}
var out = helpers.processAggregate(results, options);
callback({
violations: out.violations,
passes: out.passes,
incomplete: out.incomplete,
inapplicable: out.inapplicable,
timestamp: out.timestamp,
url: out.url
});
});
'use strict';
axe.addReporter('no-passes', function(results, options, callback) {
'use strict';
if (typeof options === 'function') {
callback = options;
options = {};
}
options.resultTypes = [ 'violations' ];
var out = helpers.processAggregate(results, options);
callback({
violations: out.violations,
timestamp: out.timestamp,
url: out.url
});
});
'use strict';
axe.addReporter('raw', function(results, options, callback) {
'use strict';
if (typeof options === 'function') {
callback = options;
options = {};
}
callback(results);
});
'use strict';
axe.addReporter('v1', function(results, options, callback) {
'use strict';
if (typeof options === 'function') {
callback = options;
options = {};
}
var out = helpers.processAggregate(results, options);
out.violations.forEach(function(result) {
return result.nodes.forEach(function(nodeResult) {
nodeResult.failureSummary = helpers.failureSummary(nodeResult);
});
});
callback({
violations: out.violations,
passes: out.passes,
incomplete: out.incomplete,
inapplicable: out.inapplicable,
timestamp: out.timestamp,
url: out.url
});
});
'use strict';
axe.addReporter('v2', function(results, options, callback) {
'use strict';
if (typeof options === 'function') {
callback = options;
options = {};
}
var out = helpers.processAggregate(results, options);
callback({
violations: out.violations,
passes: out.passes,
incomplete: out.incomplete,
inapplicable: out.inapplicable,
timestamp: out.timestamp,
url: out.url
});
}, true);
'use strict';
axe.utils.aggregate = function(map, values, initial) {
values = values.slice();
if (initial) {
values.push(initial);
}
var sorting = values.map(function(val) {
return map.indexOf(val);
}).sort();
return map[sorting.pop()];
};
'use strict';
var _axe$constants = axe.constants, CANTTELL_PRIO = _axe$constants.CANTTELL_PRIO, FAIL_PRIO = _axe$constants.FAIL_PRIO;
var checkMap = [];
checkMap[axe.constants.PASS_PRIO] = true;
checkMap[axe.constants.CANTTELL_PRIO] = null;
checkMap[axe.constants.FAIL_PRIO] = false;
var checkTypes = [ 'any', 'all', 'none' ];
function anyAllNone(obj, functor) {
return checkTypes.reduce(function(out, type) {
out[type] = (obj[type] || []).map(function(val) {
return functor(val, type);
});
return out;
}, {});
}
axe.utils.aggregateChecks = function(nodeResOriginal) {
var nodeResult = Object.assign({}, nodeResOriginal);
anyAllNone(nodeResult, function(check, type) {
var i = checkMap.indexOf(check.result);
check.priority = i !== -1 ? i : axe.constants.CANTTELL_PRIO;
if (type === 'none') {
check.priority = 4 - check.priority;
}
});
var priorities = {
all: nodeResult.all.reduce(function(a, b) {
return Math.max(a, b.priority);
}, 0),
none: nodeResult.none.reduce(function(a, b) {
return Math.max(a, b.priority);
}, 0),
any: nodeResult.any.reduce(function(a, b) {
return Math.min(a, b.priority);
}, 4) % 4
};
nodeResult.priority = Math.max(priorities.all, priorities.none, priorities.any);
var impacts = [];
checkTypes.forEach(function(type) {
nodeResult[type] = nodeResult[type].filter(function(check) {
return check.priority === nodeResult.priority && check.priority === priorities[type];
});
nodeResult[type].forEach(function(check) {
return impacts.push(check.impact);
});
});
if ([ CANTTELL_PRIO, FAIL_PRIO ].includes(nodeResult.priority)) {
nodeResult.impact = axe.utils.aggregate(axe.constants.impact, impacts);
} else {
nodeResult.impact = null;
}
anyAllNone(nodeResult, function(c) {
delete c.result;
delete c.priority;
});
nodeResult.result = axe.constants.results[nodeResult.priority];
delete nodeResult.priority;
return nodeResult;
};
'use strict';
(function() {
axe.utils.aggregateNodeResults = function(nodeResults) {
var ruleResult = {};
nodeResults = nodeResults.map(function(nodeResult) {
if (nodeResult.any && nodeResult.all && nodeResult.none) {
return axe.utils.aggregateChecks(nodeResult);
} else if (Array.isArray(nodeResult.node)) {
return axe.utils.finalizeRuleResult(nodeResult);
} else {
throw new TypeError('Invalid Result type');
}
});
if (nodeResults && nodeResults.length) {
var resultList = nodeResults.map(function(node) {
return node.result;
});
ruleResult.result = axe.utils.aggregate(axe.constants.results, resultList, ruleResult.result);
} else {
ruleResult.result = 'inapplicable';
}
axe.constants.resultGroups.forEach(function(group) {
return ruleResult[group] = [];
});
nodeResults.forEach(function(nodeResult) {
var groupName = axe.constants.resultGroupMap[nodeResult.result];
ruleResult[groupName].push(nodeResult);
});
var impactGroup = axe.constants.FAIL_GROUP;
if (ruleResult[impactGroup].length === 0) {
impactGroup = axe.constants.CANTTELL_GROUP;
}
if (ruleResult[impactGroup].length > 0) {
var impactList = ruleResult[impactGroup].map(function(failure) {
return failure.impact;
});
ruleResult.impact = axe.utils.aggregate(axe.constants.impact, impactList) || null;
} else {
ruleResult.impact = null;
}
return ruleResult;
};
})();
'use strict';
function copyToGroup(resultObject, subResult, group) {
var resultCopy = Object.assign({}, subResult);
resultCopy.nodes = (resultCopy[group] || []).concat();
axe.constants.resultGroups.forEach(function(group) {
delete resultCopy[group];
});
resultObject[group].push(resultCopy);
}
axe.utils.aggregateResult = function(results) {
var resultObject = {};
axe.constants.resultGroups.forEach(function(groupName) {
return resultObject[groupName] = [];
});
results.forEach(function(subResult) {
if (subResult.error) {
copyToGroup(resultObject, subResult, axe.constants.CANTTELL_GROUP);
} else if (subResult.result === axe.constants.NA) {
copyToGroup(resultObject, subResult, axe.constants.NA_GROUP);
} else {
axe.constants.resultGroups.forEach(function(group) {
if (Array.isArray(subResult[group]) && subResult[group].length > 0) {
copyToGroup(resultObject, subResult, group);
}
});
}
});
return resultObject;
};
'use strict';
function areStylesSet(el, styles, stopAt) {
'use strict';
var styl = window.getComputedStyle(el, null);
var set = false;
if (!styl) {
return false;
}
styles.forEach(function(att) {
if (styl.getPropertyValue(att.property) === att.value) {
set = true;
}
});
if (set) {
return true;
}
if (el.nodeName.toUpperCase() === stopAt.toUpperCase() || !el.parentNode) {
return false;
}
return areStylesSet(el.parentNode, styles, stopAt);
}
axe.utils.areStylesSet = areStylesSet;
'use strict';
axe.utils.checkHelper = function checkHelper(checkResult, options, resolve, reject) {
'use strict';
return {
isAsync: false,
async: function async() {
this.isAsync = true;
return function(result) {
if (result instanceof Error === false) {
checkResult.result = result;
resolve(checkResult);
} else {
reject(result);
}
};
},
data: function data(_data) {
checkResult.data = _data;
},
relatedNodes: function relatedNodes(nodes) {
nodes = nodes instanceof Node ? [ nodes ] : axe.utils.toArray(nodes);
checkResult.relatedNodes = nodes.map(function(element) {
return new axe.utils.DqElement(element, options);
});
}
};
};
'use strict';
var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
return typeof obj;
} : function(obj) {
return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
};
axe.utils.clon