Skip to content

Commit ffb263c

Browse files
committed
Pulled from main and resolved autocomplete and distinguishable links conflicts
2 parents 9c0ec1b + db03143 commit ffb263c

File tree

7 files changed

+282
-6
lines changed

7 files changed

+282
-6
lines changed

lib/checks/color/link-in-text-block-evaluate.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ function linkInTextBlockEvaluate(node, options) {
4646
this.relatedNodes([parentBlock]);
4747

4848
if (evaluateOptions.a11yRule) {
49+
if (
50+
node.getAttribute('type') === 'button' ||
51+
node.nodeName.toLowerCase() === 'button' ||
52+
node.getAttribute('role') === 'button'
53+
) {
54+
return true;
55+
}
4956
return a11yEngineCommons.distinguishableLinkEvaluate(node, parentBlock);
5057
}
5158

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { isValidAutocomplete } from '../../commons/text';
2+
3+
function checkIsElementValidAutocomplete(node, options, virtualNode) {
4+
const autocomplete = virtualNode.attr('autocomplete')?.toLowerCase().trim();
5+
// if element has autocomplete attribute as off then it is not a violation
6+
if (autocomplete === 'off' || autocomplete === 'chrome-off') {
7+
return true;
8+
}
9+
10+
// if it is on then we check whether name / id have valid autocomplete value or not
11+
// same for the case if autocomplete is not present or has a non-standard value
12+
if (
13+
!autocomplete ||
14+
autocomplete === 'on' ||
15+
!isValidAutocomplete(autocomplete, options)
16+
) {
17+
const name = virtualNode.attr('name');
18+
const id = virtualNode.attr('id');
19+
if (
20+
(name && isValidAutocomplete(name, options)) ||
21+
(id && isValidAutocomplete(id, options))
22+
) {
23+
return true;
24+
}
25+
return false;
26+
}
27+
28+
// if element autocomplete attribute is neither off nor on then we check if its a standard value
29+
if (isValidAutocomplete(autocomplete, options)) {
30+
return true;
31+
}
32+
33+
return false;
34+
}
35+
36+
function autocompleteA11yEvaluate(node, options, virtualNode) {
37+
try {
38+
const autocomplete = virtualNode.attr('autocomplete');
39+
40+
// check if the autocomplete applicable element is inside form or exist freely
41+
const closestForm = virtualNode.actualNode.closest('form');
42+
43+
//if it exists inside the form and autocomplete for form is off
44+
if (
45+
closestForm &&
46+
(closestForm.getAttribute('autocomplete')?.toLowerCase().trim() ===
47+
'off' ||
48+
closestForm.getAttribute('autocomplete')?.toLowerCase().trim() ===
49+
'chrome-off')
50+
) {
51+
// if autocomplete attribute is not present for element then its a pass in this scenario
52+
// otherwise check all posibilities with the method
53+
return autocomplete
54+
? checkIsElementValidAutocomplete(node, options, virtualNode)
55+
: true;
56+
} else {
57+
// The else case is if form is present and it has autocomplete as on or not set and
58+
// the other case this handles is that element exists independently
59+
60+
// this method would check for all posibilities
61+
return checkIsElementValidAutocomplete(node, options, virtualNode);
62+
}
63+
} catch (err) {
64+
// ErrorHandler.addCheckError('autocomplete-attribute-valid-check', err);
65+
return undefined;
66+
}
67+
}
68+
69+
export default autocompleteA11yEvaluate;

lib/commons/a11yCommons/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { getColorContrast } from '../../checks/color/link-in-text-block-evaluate';
2+
export { getContrast } from '../../checks/color/link-in-text-block-evaluate';

lib/commons/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import * as standards from './standards';
1616
import * as table from './table';
1717
import * as text from './text';
1818
import * as utils from '../core/utils';
19+
import * as a11yCommons from './a11yCommons';
1920

2021
var commons = {
2122
aria,
@@ -35,10 +36,10 @@ export {
3536
color,
3637
dom,
3738
forms,
38-
math,
3939
matches,
4040
standards,
4141
table,
4242
text,
43-
utils
43+
utils,
44+
a11yCommons
4445
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import autocompleteMatches from './autocomplete-matches';
2+
3+
function autocompleteA11yMatches(node, virtualNode) {
4+
const a11yEngineFlag = true;
5+
// the flag is used to tell autocomplete matcher that it is being called
6+
// by a11y-engine and thus bypass an if block
7+
return autocompleteMatches(node, virtualNode, a11yEngineFlag);
8+
}
9+
10+
export default autocompleteA11yMatches;

lib/rules/autocomplete-matches.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { sanitize } from '../commons/text';
22
import standards from '../standards';
33
import { isVisibleToScreenReaders, isVisibleOnScreen } from '../commons/dom';
44

5-
function autocompleteMatches(node, virtualNode) {
5+
function autocompleteMatches(node, virtualNode, flag = false) {
66
const autocomplete = virtualNode.attr('autocomplete');
7-
if (!autocomplete || sanitize(autocomplete) === '') {
7+
if ((!autocomplete || sanitize(autocomplete) === '') && !flag) {
88
return false;
99
}
1010

@@ -13,8 +13,17 @@ function autocompleteMatches(node, virtualNode) {
1313
return false;
1414
}
1515

16-
// The element is an `input` element a `type` of `hidden`, `button`, `submit` or `reset`
17-
const excludedInputTypes = ['submit', 'reset', 'button', 'hidden'];
16+
// The element is an `input` element a `type` of `hidden`, `reset`,`button`, `submit` , 'checkbox', 'file', 'image', or 'radio'
17+
const excludedInputTypes = [
18+
'submit',
19+
'reset',
20+
'button',
21+
'hidden',
22+
'checkbox',
23+
'file',
24+
'image',
25+
'radio'
26+
];
1827
if (
1928
nodeName === 'input' &&
2029
excludedInputTypes.includes(virtualNode.props.type)

test/checks/forms/autocomplete-valid.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ describe('autocomplete-valid', function () {
1111
checkContext.reset();
1212
});
1313

14+
// original axe-core's check test
15+
1416
it('returns true if autocomplete is valid', function () {
1517
var params = checkSetup('<input autocomplete="on" id="target" />');
1618
assert.isTrue(evaluate.apply(checkContext, params));
@@ -29,4 +31,180 @@ describe('autocomplete-valid', function () {
2931
);
3032
assert.isTrue(evaluate.apply(checkContext, params));
3133
});
34+
35+
// it("evaluate() passes a document if form element has autocomplete set off and child elements don't have autocomplete", function() {
36+
// console.log('Our functions are running fine');
37+
// var params = checkSetup(
38+
// '<html> <form autocomplete="off" onsubmit="javascript(0)"> <input type="text" id="target"/> <button>Save</button> </form> </html>'
39+
// );
40+
// assert.isTrue(evaluate.apply(checkContext, params));
41+
// });
42+
43+
// it('evaluate() passes a document if form element has autocomplete set off and child elements have autocomplete as off', function() {
44+
// var params = checkSetup(
45+
// '<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </form> </html>'
46+
// );
47+
// assert.isTrue(evaluate.apply(checkContext, params));
48+
// });
49+
50+
// it('evaluate() passes a document if form element has autocomplete set off and child elements have standard autcomplete value', function() {
51+
// var params = checkSetup(
52+
// '<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="username" type="text" id="target"/> <button>Save</button> </form> </html>'
53+
// );
54+
// assert.isTrue(evaluate.apply(checkContext, params));
55+
// });
56+
57+
// it('evaluate() passes a document if form element has autocomplete set off, child elements have on autocomplete value and name or id has standard autocomplete value', function() {
58+
// var params = checkSetup(
59+
// '<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="on" name="name" type="text" id="target"/> <button>Save</button> </form> </html>'
60+
// );
61+
// assert.isTrue(evaluate.apply(checkContext, params));
62+
// });
63+
64+
// it('evaluate() fails a document if form element has autocomplete set off and child elements have on autocomplete value and name or id has non-standard autocomplete value', function() {
65+
// var params = checkSetup(
66+
// '<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="on" name="xname" type="text" id="target"/> <button>Save</button> </form> </html>'
67+
// );
68+
// assert.isFalse(evaluate.apply(checkContext, params));
69+
// });
70+
71+
// it('evaluate() passes a document if form element has autocomplete set off, child elements have non-standard autocomplete value and name or id has standard autocomplete value', function() {
72+
// var params = checkSetup(
73+
// '<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="xname" name="name" type="text" id="target"/> <button>Save</button> </form> </html>'
74+
// );
75+
// assert.isTrue(evaluate.apply(checkContext, params));
76+
// });
77+
78+
// it('evaluate() fails a document if form element has autocomplete set off, child elements have non-standard autocomplete value and name or id has non-standard autocomplete value', function() {
79+
// var params = checkSetup(
80+
// '<html> <form autocomplete="off" onsubmit="javascript(0)"> <input autocomplete="xname" name="xname" type="text" id="target"/> <button>Save</button> </form> </html>'
81+
// );
82+
// assert.isFalse(evaluate.apply(checkContext, params));
83+
// });
84+
85+
// it('evaluate() passes a document if form element has autocomplete set on and child elements have autocomplete set to off', function() {
86+
// var params = checkSetup(
87+
// '<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </form> </html>'
88+
// );
89+
// assert.isTrue(evaluate.apply(checkContext, params));
90+
// });
91+
92+
// it("evaluate() passes a document if form element doesn't have autocomplete set and child elements have autocomplete set to off", function() {
93+
// var params = checkSetup(
94+
// '<html> <form onsubmit="javascript(0)"> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </form> </html>'
95+
// );
96+
// assert.isTrue(evaluate.apply(checkContext, params));
97+
// });
98+
99+
// it('evaluate() passes a document if form element has autocomplete set on and child elements have autocomplete set to standard irrespective of name and id', function() {
100+
// var params = checkSetup(
101+
// '<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="name" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
102+
// );
103+
// assert.isTrue(evaluate.apply(checkContext, params));
104+
// });
105+
106+
// it("evaluate() passes a document if form element doesn't have autocomplete set and child elements have autocomplete set to standard irrespective of name and id", function() {
107+
// var params = checkSetup(
108+
// '<html> <form onsubmit="javascript(0)"> <input autocomplete="name" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
109+
// );
110+
// assert.isTrue(evaluate.apply(checkContext, params));
111+
// });
112+
113+
// it('evaluate() passes a document if form element has autocomplete set on and child elements have autocomplete set on and name/id have a standard autocomplete value', function() {
114+
// var params = checkSetup(
115+
// '<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
116+
// );
117+
// assert.isTrue(evaluate.apply(checkContext, params));
118+
// });
119+
120+
// it("evaluate() passes a document if form element doesn't have autocomplete set and child elements have autocomplete set on and name/id have a standard autocomplete value", function() {
121+
// var params = checkSetup(
122+
// '<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
123+
// );
124+
// assert.isTrue(evaluate.apply(checkContext, params));
125+
// });
126+
127+
// it('evaluate() fails a document if form element has autocomplete set on and child elements have autocomplete set on and name/id have a non-standard autocomplete value', function() {
128+
// var params = checkSetup(
129+
// '<html> <form autocomplete="on" onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
130+
// );
131+
// assert.isFalse(evaluate.apply(checkContext, params));
132+
// });
133+
134+
// it("evaluate() fails a document if form element doesn't have autcomplete set and child elements have autocomplete set on and name/id have a non-standard autocomplete value", function() {
135+
// var params = checkSetup(
136+
// '<html> <form onsubmit="javascript(0)"> <input autocomplete="on" type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
137+
// );
138+
// assert.isFalse(evaluate.apply(checkContext, params));
139+
// });
140+
141+
// it("evaluate() passes a document if form element has autocomplete set on and child elements don't have autocomplete set and name/id have a standard autocomplete value", function() {
142+
// var params = checkSetup(
143+
// '<html> <form autocomplete="on" onsubmit="javascript(0)"> <input type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
144+
// );
145+
// assert.isTrue(evaluate.apply(checkContext, params));
146+
// });
147+
148+
// it("evaluate() passes a document if form element doesn't have autocomplete set and child elements don't have autocomplete set and name/id have a standard autocomplete value", function() {
149+
// var params = checkSetup(
150+
// '<html> <form onsubmit="javascript(0)"> <input type="text" name="name" id="target"/> <button>Save</button> </form> </html>'
151+
// );
152+
// assert.isTrue(evaluate.apply(checkContext, params));
153+
// });
154+
155+
// it("evaluate() fails a document if form element has autocomplete set on and child elements don't have autocomplete set and name/id have a non-standard autocomplete value", function() {
156+
// var params = checkSetup(
157+
// '<html> <form autocomplete="on" onsubmit="javascript(0)"> <input type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
158+
// );
159+
// assert.isFalse(evaluate.apply(checkContext, params));
160+
// });
161+
162+
// it("evaluate() fails a document if form element doesn't have autocomplete set and child elements don't have autocomplete set and name/id have a non-standard autocomplete value", function() {
163+
// var params = checkSetup(
164+
// '<html> <form onsubmit="javascript(0)"> <input type="text" name="xname" id="target"/> <button>Save</button> </form> </html>'
165+
// );
166+
// assert.isFalse(evaluate.apply(checkContext, params));
167+
// });
168+
169+
// it('evaluate() passes a document if element is independent and have autocomplete set to off', function() {
170+
// var params = checkSetup(
171+
// '<html> <input autocomplete="off" type="text" id="target"/> <button>Save</button> </html>'
172+
// );
173+
// assert.isTrue(evaluate.apply(checkContext, params));
174+
// });
175+
176+
// it('evaluate() passes a document if element is independent and have autocomplete set to standard irrespective of name and id', function() {
177+
// var params = checkSetup(
178+
// '<html> <input autocomplete="name" type="text" name="xname" id="target"/> <button>Save</button> </html>'
179+
// );
180+
// assert.isTrue(evaluate.apply(checkContext, params));
181+
// });
182+
183+
// it('evaluate() passes a document if element is independent and have autocomplete set on and name/id have a standard autocomplete value', function() {
184+
// var params = checkSetup(
185+
// '<html> <input autocomplete="on" type="text" name="name" id="target"/> <button>Save</button> </html>'
186+
// );
187+
// assert.isTrue(evaluate.apply(checkContext, params));
188+
// });
189+
190+
// it('evaluate() fails a document if element is independent and have autocomplete set on and name/id have a non-standard autocomplete value', function() {
191+
// var params = checkSetup(
192+
// '<html> <input autocomplete="on" type="text" name="xname" id="target"/> <button>Save</button> </html>'
193+
// );
194+
// assert.isFalse(evaluate.apply(checkContext, params));
195+
// });
196+
197+
// it("evaluate()passes a document if element is independent and don't have autocomplete set and name/id have a standard autocomplete value", function() {
198+
// var params = checkSetup(
199+
// '<html> <input type="text" name="name" id="target"/> <button>Save</button> </html>'
200+
// );
201+
// assert.isTrue(evaluate.apply(checkContext, params));
202+
// });
203+
204+
// it("evaluate() fails a document if element is independent and don't have autocomplete set and name/id have a non-standard autocomplete value", function() {
205+
// var params = checkSetup(
206+
// '<html> <input type="text" name="xname" id="target"/> <button>Save</button> </html>'
207+
// );
208+
// assert.isFalse(evaluate.apply(checkContext, params));
209+
// });
32210
});

0 commit comments

Comments
 (0)