UNPKG

axe-core

Version:

Accessibility engine for automated Web UI testing

1,565 lines (1,560 loc) • 430 kB
(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