forked from dequelabs/axe-core
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcheck.js
107 lines (92 loc) · 2.83 KB
/
check.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*global CheckResult */
function Check(spec) {
'use strict';
/**
* Unique ID for the check. Checks may be re-used, so there may be additional instances of checks
* with the same ID.
* @type {String}
*/
this.id = spec.id;
/**
* Free-form options that are passed as the second parameter to the `evaluate`
* @type {Mixed}
*/
this.options = spec.options;
/**
* Optional. If specified, only nodes that match this CSS selector are tested
* @type {String}
*/
this.selector = spec.selector;
/**
* The actual code, accepts 2 parameters: node (the node under test), options (see this.options).
* This function is run in the context of a checkHelper, which has the following methods
* - `async()` - if called, the check is considered to be asynchronous; returns a callback function
* - `data()` - free-form data object, associated to the `CheckResult` which is specific to each node
* @type {Function}
*/
this.evaluate = spec.evaluate;
/**
* Optional. Filter and/or modify checks for all nodes
* @type {Function}
*/
if (spec.after) {
this.after = spec.after;
}
if (spec.matches) {
/**
* Optional function to test if check should be run against a node, overrides Check#matches
* @type {Function}
*/
this.matches = spec.matches;
}
/**
* enabled by default, if false, this check will not be included in the rule's evaluation
* @type {Boolean}
*/
this.enabled = spec.hasOwnProperty('enabled') ? spec.enabled : true;
}
/**
* Determines whether the check should be run against a node
* @param {HTMLElement} node The node to test
* @return {Boolean} Whether the check should be run
*/
Check.prototype.matches = function (node) {
'use strict';
if (!this.selector || utils.matchesSelector(node, this.selector)) {
return true;
}
return false;
};
/**
* Run the check's evaluate function (call `this.evaluate(node, options)`)
* @param {HTMLElement} node The node to test
* @param {Object} options The options that override the defaults and provide additional
* information for the check
* @param {Function} callback Function to fire when check is complete
*/
Check.prototype.run = function (node, options, callback) {
'use strict';
options = options || {};
var enabled = options.hasOwnProperty('enabled') ? options.enabled : this.enabled,
checkOptions = options.options || this.options;
if (enabled && this.matches(node)) {
var checkResult = new CheckResult(this);
var checkHelper = utils.checkHelper(checkResult, callback);
var result;
try {
result = this.evaluate.call(checkHelper, node, checkOptions);
} catch (e) {
axe.log(e.message, e.stack);
callback(null);
return;
}
if (!checkHelper.isAsync) {
checkResult.result = result;
setTimeout(function () {
callback(checkResult);
}, 0);
}
} else {
callback(null);
}
};