testaro 27.0.0 → 28.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +3 -1
- package/README.md +14 -3
- package/package.json +2 -1
- package/procs/aslint.js +83 -0
- package/procs/nav.js +56 -14
- package/procs/standardize.js +36 -0
- package/run.js +35 -22
- package/tests/aslint.js +83 -0
- package/tests/axe.js +4 -0
- package/tests/qualWeb.js +6 -0
- package/aslint/LICENSE +0 -362
- package/aslint/README.md +0 -260
- package/aslint/app/rules/abstract-rule.ts +0 -83
- package/aslint/app/rules/aslint/incorrect-technique-for-hiding-content/incorrect-technique-for-hiding-content.documentation.md +0 -36
- package/aslint/app/rules/aslint/incorrect-technique-for-hiding-content/incorrect-technique-for-hiding-content.test.ts +0 -113
- package/aslint/app/rules/aslint/incorrect-technique-for-hiding-content/incorrect-technique-for-hiding-content.ts +0 -103
- package/aslint/app/rules/aslint/invalid-attribute-dir-value/invalid-attribute-dir-value.documentation.md +0 -34
- package/aslint/app/rules/aslint/invalid-attribute-dir-value/invalid-attribute-dir-value.test.ts +0 -82
- package/aslint/app/rules/aslint/invalid-attribute-dir-value/invalid-attribute-dir-value.ts +0 -44
- package/aslint/app/rules/aslint/label-duplicated-content-title/label-duplicated-content-title.documentation.md +0 -40
- package/aslint/app/rules/aslint/label-duplicated-content-title/label-duplicated-content-title.test.ts +0 -48
- package/aslint/app/rules/aslint/label-duplicated-content-title/label-duplicated-content-title.ts +0 -37
- package/aslint/app/rules/aslint/links-language-destination/links-language-destination.test.ts +0 -50
- package/aslint/app/rules/aslint/links-language-destination/links-language-destination.ts +0 -70
- package/aslint/app/rules/aslint/main-element-only-one/main-element-only-one.test.ts +0 -55
- package/aslint/app/rules/aslint/main-element-only-one/main-element-only-one.ts +0 -83
- package/aslint/app/rules/aslint/main-landmark-must-be-top-level/main-landmark-must-be-top-level.test.ts +0 -12
- package/aslint/app/rules/aslint/main-landmark-must-be-top-level/main-landmark-must-be-top-level.ts +0 -73
- package/aslint/app/rules/aslint/minimum-font-size/minimum-font-size.test.ts +0 -12
- package/aslint/app/rules/aslint/minimum-font-size/minimum-font-size.ts +0 -87
- package/aslint/app/rules/aslint/missing-href-on-a/missing-href-on-a.test.ts +0 -48
- package/aslint/app/rules/aslint/missing-href-on-a/missing-href-on-a.ts +0 -40
- package/aslint/app/rules/aslint/misused-aria-on-focusable-element/misused-aria-on-focusable-element.test.ts +0 -12
- package/aslint/app/rules/aslint/misused-aria-on-focusable-element/misused-aria-on-focusable-element.ts +0 -66
- package/aslint/app/rules/aslint/misused-input-attribute/misused-input-attribute.test.ts +0 -12
- package/aslint/app/rules/aslint/misused-input-attribute/misused-input-attribute.ts +0 -134
- package/aslint/app/rules/aslint/misused-required-attribute/misused-required-attribute.test.ts +0 -12
- package/aslint/app/rules/aslint/misused-required-attribute/misused-required-attribute.ts +0 -90
- package/aslint/app/rules/aslint/navigation-landmark-restrictions/navigation-landmark-restrictions.test.ts +0 -12
- package/aslint/app/rules/aslint/navigation-landmark-restrictions/navigation-landmark-restrictions.ts +0 -48
- package/aslint/app/rules/aslint/obsolete-html-attributes/obsolete-html-attributes.test.ts +0 -12
- package/aslint/app/rules/aslint/obsolete-html-attributes/obsolete-html-attributes.ts +0 -148
- package/aslint/app/rules/aslint/obsolete-html-elements/obsolete-html-elements.test.ts +0 -12
- package/aslint/app/rules/aslint/obsolete-html-elements/obsolete-html-elements.ts +0 -66
- package/aslint/app/rules/aslint/outline-zero/outline-zero.test.ts +0 -12
- package/aslint/app/rules/aslint/outline-zero/outline-zero.ts +0 -85
- package/aslint/app/rules/aslint/overlay/overlay.test.ts +0 -122
- package/aslint/app/rules/aslint/overlay/overlay.ts +0 -141
- package/aslint/app/rules/aslint/redundant/aria-role-dialog/aria-role-dialog.documentation.md +0 -49
- package/aslint/app/rules/aslint/redundant/aria-role-dialog/aria-role-dialog.test.ts +0 -91
- package/aslint/app/rules/aslint/redundant/aria-role-dialog/aria-role-dialog.ts +0 -62
- package/aslint/app/rules/aslint/redundant/capital-letters-words/capital-letters-words.documentation.md +0 -44
- package/aslint/app/rules/aslint/redundant/capital-letters-words/capital-letters-words.test.ts +0 -111
- package/aslint/app/rules/aslint/redundant/capital-letters-words/capital-letters-words.ts +0 -120
- package/aslint/app/rules/aslint/redundant/contentinfo-landmark-only-one/contentinfo-landmark-only-one.documentation.md +0 -45
- package/aslint/app/rules/aslint/redundant/contentinfo-landmark-only-one/contentinfo-landmark-only-one.test.ts +0 -63
- package/aslint/app/rules/aslint/redundant/contentinfo-landmark-only-one/contentinfo-landmark-only-one.ts +0 -44
- package/aslint/app/rules/aslint/redundant/empty-title-attribute/empty-title-attribute.documentation.md +0 -55
- package/aslint/app/rules/aslint/redundant/empty-title-attribute/empty-title-attribute.test.ts +0 -80
- package/aslint/app/rules/aslint/redundant/empty-title-attribute/empty-title-attribute.ts +0 -58
- package/aslint/app/rules/aslint/redundant/flash-content/flash-content.documentation.md +0 -48
- package/aslint/app/rules/aslint/redundant/flash-content/flash-content.test.ts +0 -52
- package/aslint/app/rules/aslint/redundant/flash-content/flash-content.ts +0 -32
- package/aslint/app/rules/aslint/redundant/font-style-italic/font-style-italic.documentation.md +0 -44
- package/aslint/app/rules/aslint/redundant/font-style-italic/font-style-italic.test.ts +0 -12
- package/aslint/app/rules/aslint/redundant/font-style-italic/font-style-italic.ts +0 -83
- package/aslint/app/rules/aslint/redundant/h1-must-be/h1-must-be.documentation.md +0 -46
- package/aslint/app/rules/aslint/redundant/h1-must-be/h1-must-be.test.ts +0 -46
- package/aslint/app/rules/aslint/redundant/h1-must-be/h1-must-be.ts +0 -36
- package/aslint/app/rules/aslint/role-application/role-application.test.ts +0 -48
- package/aslint/app/rules/aslint/role-application/role-application.ts +0 -38
- package/aslint/app/rules/aslint/rtl-content/rtl-content.test.ts +0 -12
- package/aslint/app/rules/aslint/rtl-content/rtl-content.ts +0 -75
- package/aslint/app/rules/aslint/unclear-uri-on-a/unclear-anchor-uri.test.ts +0 -12
- package/aslint/app/rules/aslint/unclear-uri-on-a/unclear-anchor-uri.ts +0 -48
- package/aslint/app/rules/aslint/unimportant/aria-hidden-false/aria-hidden-false.test.ts +0 -73
- package/aslint/app/rules/aslint/unimportant/aria-hidden-false/aria-hidden-false.ts +0 -34
- package/aslint/app/rules/aslint/unimportant/aria-hidden-false/aria-hidden.documentation.md +0 -32
- package/aslint/app/rules/aslint/unimportant/content-editable-missing-attributes/content-editable-missing-attributes.docmentation.md +0 -48
- package/aslint/app/rules/aslint/unimportant/content-editable-missing-attributes/content-editable-missing-attributes.test.ts +0 -67
- package/aslint/app/rules/aslint/unimportant/content-editable-missing-attributes/content-editable-missing-attributes.ts +0 -63
- package/aslint/app/rules/aslint/unsupported-role-on-element/unsupported-role-on-element.test.ts +0 -12
- package/aslint/app/rules/aslint/unsupported-role-on-element/unsupported-role-on-element.ts +0 -63
- package/aslint/app/rules/aslint/used/elements-not-allowed-in-head/elements-not-allowed-in-head.documentation.md +0 -65
- package/aslint/app/rules/aslint/used/elements-not-allowed-in-head/elements-not-allowed-in-head.test.ts +0 -53
- package/aslint/app/rules/aslint/used/elements-not-allowed-in-head/elements-not-allowed-in-head.ts +0 -47
- package/aslint/app/rules/aslint/used/headings-sibling-unique/headings-sibling-unique.documentation.md +0 -57
- package/aslint/app/rules/aslint/used/headings-sibling-unique/headings-sibling-unique.test.ts +0 -52
- package/aslint/app/rules/aslint/used/headings-sibling-unique/headings-sibling-unique.ts +0 -63
- package/aslint/app/rules/aslint/used/horizontal-rule/horizontal-rule.documentation.md +0 -39
- package/aslint/app/rules/aslint/used/horizontal-rule/horizontal-rule.test.ts +0 -66
- package/aslint/app/rules/aslint/used/horizontal-rule/horizontal-rule.ts +0 -37
- package/aslint/utils/aria.test.ts +0 -12
- package/aslint/utils/aria.ts +0 -120
- package/aslint/utils/async.test.ts +0 -25
- package/aslint/utils/async.ts +0 -22
- package/aslint/utils/common.test.ts +0 -239
- package/aslint/utils/common.ts +0 -168
- package/aslint/utils/console.test.ts +0 -85
- package/aslint/utils/console.ts +0 -89
- package/aslint/utils/css.test.ts +0 -153
- package/aslint/utils/css.ts +0 -191
- package/aslint/utils/dom.test.ts +0 -627
- package/aslint/utils/dom.ts +0 -1051
- package/aslint/utils/env.test.ts +0 -14
- package/aslint/utils/env.ts +0 -8
- package/aslint/utils/func.test.ts +0 -160
- package/aslint/utils/func.ts +0 -70
- package/aslint/utils/global.test.ts +0 -12
- package/aslint/utils/global.ts +0 -25
- package/aslint/utils/object.test.ts +0 -524
- package/aslint/utils/object.ts +0 -278
- package/aslint/utils/report.test.ts +0 -56
- package/aslint/utils/report.ts +0 -36
- package/aslint/utils/text.test.ts +0 -270
- package/aslint/utils/text.ts +0 -165
- package/aslint/utils/time.test.ts +0 -43
- package/aslint/utils/time.ts +0 -33
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { CATEGORY_TYPE } from '../../../constants/categoryType';
|
|
2
|
-
import { IIssueReport } from '../../../interfaces/rule-issue.interface';
|
|
3
|
-
import { TextUtility } from '../../../utils/text';
|
|
4
|
-
import { TranslateService } from '../../../services/translate';
|
|
5
|
-
import { $severity } from '../../../constants/accessibility';
|
|
6
|
-
import { $accessibilityAuditRules } from '../../../constants/accessibility';
|
|
7
|
-
import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
|
|
8
|
-
|
|
9
|
-
export class MisusedInputAttribute extends AbstractRule {
|
|
10
|
-
protected selector: string = 'input';
|
|
11
|
-
protected ruleConfig: IAbstractRuleConfig = {
|
|
12
|
-
id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.misused_input_attribute),
|
|
13
|
-
links: [
|
|
14
|
-
{
|
|
15
|
-
content: 'HTML5 form additions',
|
|
16
|
-
url: 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input'
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
content: 'Common input element attributes',
|
|
20
|
-
url: 'https://www.w3.org/TR/html5/forms.html#common-input-element-attributes'
|
|
21
|
-
}
|
|
22
|
-
],
|
|
23
|
-
recommendations: [],
|
|
24
|
-
severity: $severity.high,
|
|
25
|
-
type: CATEGORY_TYPE.BEST_PRACTICE
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
public validate(elements: Element[]): void {
|
|
29
|
-
const SUPPORTED_INPUT_ATTRIBUTES: string[] = [
|
|
30
|
-
'accept',
|
|
31
|
-
'accessKey',
|
|
32
|
-
'autocapitalize',
|
|
33
|
-
'autocomplete',
|
|
34
|
-
'autofocus',
|
|
35
|
-
'checked',
|
|
36
|
-
'defaultChecked',
|
|
37
|
-
'defaultValue',
|
|
38
|
-
'dirName',
|
|
39
|
-
'disabled',
|
|
40
|
-
'indeterminate',
|
|
41
|
-
'list',
|
|
42
|
-
'maxLength',
|
|
43
|
-
'minLength',
|
|
44
|
-
'min',
|
|
45
|
-
'max',
|
|
46
|
-
'multiple',
|
|
47
|
-
'name',
|
|
48
|
-
'pattern',
|
|
49
|
-
'placeholder',
|
|
50
|
-
'readOnly',
|
|
51
|
-
'required',
|
|
52
|
-
'selectionDirection',
|
|
53
|
-
'selectionEnd',
|
|
54
|
-
'selectionStart',
|
|
55
|
-
'size',
|
|
56
|
-
'src',
|
|
57
|
-
'step',
|
|
58
|
-
'tabIndex',
|
|
59
|
-
'type',
|
|
60
|
-
'useMap',
|
|
61
|
-
'value',
|
|
62
|
-
'valueAsDate',
|
|
63
|
-
'valueAsNumber',
|
|
64
|
-
'width',
|
|
65
|
-
'willValidate'
|
|
66
|
-
];
|
|
67
|
-
|
|
68
|
-
const attributeAliases: any = {
|
|
69
|
-
accesskey: 'accessKey',
|
|
70
|
-
cellpadding: 'cellPadding',
|
|
71
|
-
cellspacing: 'cellSpacing',
|
|
72
|
-
class: 'className',
|
|
73
|
-
codebase: 'codeBase',
|
|
74
|
-
colspan: 'colSpan',
|
|
75
|
-
defaultchecked: 'defaultChecked',
|
|
76
|
-
defaultvalue: 'defaultValue',
|
|
77
|
-
dirname: 'dirName',
|
|
78
|
-
for: 'htmlFor',
|
|
79
|
-
formaction: 'formAction',
|
|
80
|
-
formenctype: 'formEncType',
|
|
81
|
-
formmethod: 'formMethod',
|
|
82
|
-
formnovalidate: 'formNoValidate',
|
|
83
|
-
formtarget: 'formTarget',
|
|
84
|
-
frameborder: 'frameBorder',
|
|
85
|
-
framespacing: 'frameSpacing',
|
|
86
|
-
ismap: 'isMap',
|
|
87
|
-
longdesc: 'longDesc',
|
|
88
|
-
maxlength: 'maxLength',
|
|
89
|
-
nowrap: 'noWrap',
|
|
90
|
-
placeholder: 'placeholder',
|
|
91
|
-
readonly: 'readOnly',
|
|
92
|
-
rowspan: 'rowSpan',
|
|
93
|
-
selectiondirection: 'selectionDirection',
|
|
94
|
-
selectionend: 'selectionEnd',
|
|
95
|
-
selectionstart: 'selectionStart',
|
|
96
|
-
tabindex: 'tabIndex',
|
|
97
|
-
usemap: 'useMap',
|
|
98
|
-
validationmessage: 'validationMessage',
|
|
99
|
-
valueasdate: 'valueAsDate',
|
|
100
|
-
valueasnumber: 'valueAsNumber',
|
|
101
|
-
willvalidate: 'willValidate'
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const isSupportedAttribute = (element: Element, attribute: string): boolean => {
|
|
105
|
-
const alias: string = attributeAliases[attribute.toLowerCase()] || attribute;
|
|
106
|
-
|
|
107
|
-
return alias in element;
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const checkSupportForInputAttribute = (element: Element): void => {
|
|
111
|
-
let nodeAttrValue: string | null;
|
|
112
|
-
|
|
113
|
-
const checkAttributes = (attr: string): void => {
|
|
114
|
-
nodeAttrValue = element.getAttribute(attr);
|
|
115
|
-
|
|
116
|
-
if (typeof nodeAttrValue === 'string' && isSupportedAttribute(element, attr) === false) {
|
|
117
|
-
const reportMessage: string = TranslateService.instant('misused_input_attribute_report_message', [attr]);
|
|
118
|
-
|
|
119
|
-
const report: IIssueReport = {
|
|
120
|
-
message: reportMessage,
|
|
121
|
-
node: element,
|
|
122
|
-
ruleId: this.ruleConfig.id
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
this.validator.report(report);
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
SUPPORTED_INPUT_ATTRIBUTES.forEach(checkAttributes);
|
|
130
|
-
};
|
|
131
|
-
|
|
132
|
-
elements.forEach(checkSupportForInputAttribute);
|
|
133
|
-
}
|
|
134
|
-
}
|
package/aslint/app/rules/aslint/misused-required-attribute/misused-required-attribute.test.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { MisusedRequiredAttribute } from './misused-required-attribute';
|
|
2
|
-
|
|
3
|
-
describe('Rules', () => {
|
|
4
|
-
|
|
5
|
-
describe('MisusedRequiredAttribute', () => {
|
|
6
|
-
|
|
7
|
-
it('should indicate that class exists', () => {
|
|
8
|
-
expect(MisusedRequiredAttribute).toBeDefined();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
});
|
|
12
|
-
});
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { CATEGORY_TYPE } from '../../../constants/categoryType';
|
|
2
|
-
import { IIssueReport } from '../../../interfaces/rule-issue.interface';
|
|
3
|
-
import { TextUtility } from '../../../utils/text';
|
|
4
|
-
import { TranslateService } from '../../../services/translate';
|
|
5
|
-
import { $severity } from '../../../constants/accessibility';
|
|
6
|
-
import { $accessibilityAuditRules } from '../../../constants/accessibility';
|
|
7
|
-
import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
|
|
8
|
-
export class MisusedRequiredAttribute extends AbstractRule {
|
|
9
|
-
protected selector: string = '[required][aria-required]';
|
|
10
|
-
|
|
11
|
-
protected ruleConfig: IAbstractRuleConfig = {
|
|
12
|
-
id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.misused_required_attribute),
|
|
13
|
-
links: [
|
|
14
|
-
{
|
|
15
|
-
content: 'Attribute required',
|
|
16
|
-
url: 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-required'
|
|
17
|
-
}
|
|
18
|
-
],
|
|
19
|
-
recommendations: [],
|
|
20
|
-
severity: $severity.high,
|
|
21
|
-
type: CATEGORY_TYPE.BEST_PRACTICE
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
public validate(elements: HTMLElement[]): void {
|
|
25
|
-
const requiredElms: HTMLElement[] = elements;
|
|
26
|
-
const notUseOnType: string[] = [
|
|
27
|
-
'hidden',
|
|
28
|
-
'image'
|
|
29
|
-
];
|
|
30
|
-
const notUseOnButtonType: string[] = [
|
|
31
|
-
'submit',
|
|
32
|
-
'reset',
|
|
33
|
-
'button'
|
|
34
|
-
];
|
|
35
|
-
|
|
36
|
-
const showMessage = (element: HTMLElement): void => {
|
|
37
|
-
let report: IIssueReport | undefined;
|
|
38
|
-
const ariaRequiredValue: string | null = element.getAttribute('aria-required');
|
|
39
|
-
const elementRequiredValue: string | null = element.getAttribute('required');
|
|
40
|
-
const nodeName: string = element.nodeName.toLowerCase();
|
|
41
|
-
|
|
42
|
-
if (ariaRequiredValue && elementRequiredValue === null ||
|
|
43
|
-
(typeof (element as any).type === 'string' && notUseOnType.indexOf((element as any).type) !== -1 ||
|
|
44
|
-
nodeName === 'button' && notUseOnButtonType.indexOf((element as HTMLButtonElement).type) !== -1)
|
|
45
|
-
) {
|
|
46
|
-
const reportMessage: string = TranslateService.instant('misused_required_attribute_report_message1', [ariaRequiredValue]);
|
|
47
|
-
|
|
48
|
-
report = {
|
|
49
|
-
message: reportMessage,
|
|
50
|
-
node: element,
|
|
51
|
-
ruleId: this.ruleConfig.id
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
this.validator.report(report);
|
|
55
|
-
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (elementRequiredValue === null) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (elementRequiredValue === ariaRequiredValue) {
|
|
64
|
-
const reportMessage: string = TranslateService.instant('misused_required_attribute_report_message2', [ariaRequiredValue]);
|
|
65
|
-
|
|
66
|
-
report = {
|
|
67
|
-
message: reportMessage,
|
|
68
|
-
node: element,
|
|
69
|
-
ruleId: this.ruleConfig.id
|
|
70
|
-
};
|
|
71
|
-
} else {
|
|
72
|
-
const reportMessage: string = TranslateService.instant('misused_required_attribute_report_message3', [ariaRequiredValue, element.getAttribute('required')]);
|
|
73
|
-
|
|
74
|
-
report = {
|
|
75
|
-
message: reportMessage,
|
|
76
|
-
node: element,
|
|
77
|
-
ruleId: this.ruleConfig.id
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (typeof report === 'undefined') {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
this.validator.report(report);
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
requiredElms.forEach(showMessage);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { NavigationLandmarkRestrictions } from './navigation-landmark-restrictions';
|
|
2
|
-
|
|
3
|
-
describe('Rules', () => {
|
|
4
|
-
|
|
5
|
-
describe('NavigationLandmarkRestrictions', () => {
|
|
6
|
-
|
|
7
|
-
it('should indicate that class exists', () => {
|
|
8
|
-
expect(NavigationLandmarkRestrictions).toBeDefined();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
});
|
|
12
|
-
});
|
package/aslint/app/rules/aslint/navigation-landmark-restrictions/navigation-landmark-restrictions.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { DomUtility } from '../../../utils/dom';
|
|
2
|
-
import { CATEGORY_TYPE } from '../../../constants/categoryType';
|
|
3
|
-
import { IIssueReport } from '../../../interfaces/rule-issue.interface';
|
|
4
|
-
import { TextUtility } from '../../../utils/text';
|
|
5
|
-
import { TranslateService } from '../../../services/translate';
|
|
6
|
-
import { $severity } from '../../../constants/accessibility';
|
|
7
|
-
import { $accessibilityAuditRules } from '../../../constants/accessibility';
|
|
8
|
-
import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
|
|
9
|
-
|
|
10
|
-
export class NavigationLandmarkRestrictions extends AbstractRule {
|
|
11
|
-
protected selector: string = '[role="navigation"]';
|
|
12
|
-
|
|
13
|
-
protected ruleConfig: IAbstractRuleConfig = {
|
|
14
|
-
id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.navigation_landmark_restrictions),
|
|
15
|
-
links: [
|
|
16
|
-
{
|
|
17
|
-
content: 'Accessible Rich Internet Applications (WAI-ARIA) 1.0 Specification: navigation role',
|
|
18
|
-
url: 'https://www.w3.org/TR/wai-aria-1.1/#navigation'
|
|
19
|
-
}
|
|
20
|
-
],
|
|
21
|
-
recommendations: [],
|
|
22
|
-
severity: $severity.high,
|
|
23
|
-
type: CATEGORY_TYPE.BEST_PRACTICE
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
public validate(elements: Element[]): void {
|
|
27
|
-
const selector: string = '[role]:not([role="region"]):not([role="search"])';
|
|
28
|
-
const reportMessage: string = TranslateService.instant('navigation_landmark_restrictions_report_message');
|
|
29
|
-
|
|
30
|
-
const checkRoleNavigationContent = (htmlElement: Element): void => {
|
|
31
|
-
const childs: HTMLElement[] = DomUtility.querySelectorAll(selector, htmlElement);
|
|
32
|
-
|
|
33
|
-
const reportIssue = (element: Element): void => {
|
|
34
|
-
const report: IIssueReport = {
|
|
35
|
-
message: reportMessage,
|
|
36
|
-
node: element,
|
|
37
|
-
ruleId: this.ruleConfig.id
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
this.validator.report(report);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
childs.forEach(reportIssue);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
elements.forEach(checkRoleNavigationContent);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { ObsoleteHtmlAttributes } from './obsolete-html-attributes';
|
|
2
|
-
|
|
3
|
-
describe('Rules', () => {
|
|
4
|
-
|
|
5
|
-
describe('ObsoleteHtmlAttributes', () => {
|
|
6
|
-
|
|
7
|
-
it('should indicate that class exists', () => {
|
|
8
|
-
expect(ObsoleteHtmlAttributes).toBeDefined();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
});
|
|
12
|
-
});
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
import { CATEGORY_TYPE } from '../../../constants/categoryType';
|
|
2
|
-
import { IIssueReport } from '../../../interfaces/rule-issue.interface';
|
|
3
|
-
import { TextUtility } from '../../../utils/text';
|
|
4
|
-
import { TranslateService } from '../../../services/translate';
|
|
5
|
-
import { $severity } from '../../../constants/accessibility';
|
|
6
|
-
import { $accessibilityAuditRules } from '../../../constants/accessibility';
|
|
7
|
-
import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
|
|
8
|
-
|
|
9
|
-
const OBSOLETE_HTML_ATTRIBUTES: { [key: string]: string[] } = {
|
|
10
|
-
accept: ['form'],
|
|
11
|
-
align: ['caption', 'col', 'div', 'embed', 'hr', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'iframe', 'input', 'img', 'legend', 'object', 'p', 'table', 'tbody', 'thead', 'tfoot', 'td', 'th', 'tr'],
|
|
12
|
-
alink: ['body'],
|
|
13
|
-
allowtransparency: ['iframe'],
|
|
14
|
-
archive: ['object'],
|
|
15
|
-
axis: ['td', 'th'],
|
|
16
|
-
background: ['body', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'td', 'th'],
|
|
17
|
-
bgcolor: ['body', 'table', 'td', 'th', 'tr'],
|
|
18
|
-
border: ['img', 'object'],
|
|
19
|
-
bordercolor: ['table'],
|
|
20
|
-
cellpadding: ['table'],
|
|
21
|
-
cellspacing: ['table'],
|
|
22
|
-
char: ['col', 'tbody', 'thead', 'tfoot', 'td', 'th', 'tr'],
|
|
23
|
-
charoff: ['col', 'tbody', 'thead', 'tfoot', 'td', 'th', 'tr'],
|
|
24
|
-
charset: ['a', 'link'],
|
|
25
|
-
classid: ['object'],
|
|
26
|
-
clear: ['br'],
|
|
27
|
-
code: ['object'],
|
|
28
|
-
codebase: ['object'],
|
|
29
|
-
codetype: ['object'],
|
|
30
|
-
color: ['hr'],
|
|
31
|
-
compact: ['dl', 'ol', 'ul'],
|
|
32
|
-
coords: ['a'],
|
|
33
|
-
datafld: ['a', 'applet', 'button', 'div', 'fieldset', 'frame', 'iframe', 'img', 'input', 'label', 'legend', 'marquee', 'object', 'param', 'select', 'span', 'textarea'],
|
|
34
|
-
dataformatas: ['button', 'div', 'input', 'label', 'legend', 'marquee', 'object', 'option', 'select', 'span', 'table'],
|
|
35
|
-
datapagesize: ['table'],
|
|
36
|
-
datasrc: ['a', 'applet', 'button', 'div', 'frame', 'iframe', 'img', 'input', 'label', 'legend', 'marquee', 'object', 'option', 'select', 'span', 'table', 'textarea'],
|
|
37
|
-
declare: ['object'],
|
|
38
|
-
event: ['script'],
|
|
39
|
-
for: ['script'],
|
|
40
|
-
frame: ['table'],
|
|
41
|
-
frameborder: ['iframe'],
|
|
42
|
-
height: ['td', 'th'],
|
|
43
|
-
hspace: ['embed', 'iframe', 'input', 'img', 'object'],
|
|
44
|
-
ismap: ['input'],
|
|
45
|
-
language: ['script'],
|
|
46
|
-
link: ['body'],
|
|
47
|
-
lowsrc: ['img'],
|
|
48
|
-
marginbottom: ['body'],
|
|
49
|
-
marginheight: ['body', 'iframe'],
|
|
50
|
-
marginleft: ['body'],
|
|
51
|
-
marginright: ['body'],
|
|
52
|
-
margintop: ['body'],
|
|
53
|
-
marginwidth: ['body', 'iframe'],
|
|
54
|
-
methods: ['a', 'link'],
|
|
55
|
-
name: ['a', 'embed', 'img', 'option'],
|
|
56
|
-
nohref: ['area'],
|
|
57
|
-
noshade: ['hr'],
|
|
58
|
-
nowrap: ['td', 'th'],
|
|
59
|
-
profile: ['head'],
|
|
60
|
-
rules: ['table'],
|
|
61
|
-
scheme: ['meta'],
|
|
62
|
-
scope: ['td'],
|
|
63
|
-
scrolling: ['iframe'],
|
|
64
|
-
shape: ['a'],
|
|
65
|
-
size: ['hr'],
|
|
66
|
-
standby: ['object'],
|
|
67
|
-
summary: ['table'],
|
|
68
|
-
target: ['link'],
|
|
69
|
-
text: ['body'],
|
|
70
|
-
type: ['param', 'li', 'ul'],
|
|
71
|
-
urn: ['a', 'link'],
|
|
72
|
-
usemap: ['input'],
|
|
73
|
-
valign: ['col', 'tbody', 'thead', 'tfoot', 'td', 'th', 'tr'],
|
|
74
|
-
valuetype: ['param'],
|
|
75
|
-
version: ['html'],
|
|
76
|
-
vlink: ['body'],
|
|
77
|
-
vspace: ['embed', 'iframe', 'input', 'img', 'object'],
|
|
78
|
-
width: ['col', 'hr', 'pre', 'table', 'td', 'th']
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
export class ObsoleteHtmlAttributes extends AbstractRule {
|
|
82
|
-
protected selector: string = (() => {
|
|
83
|
-
const createSelector = (elementData: [string, string[]]): string => {
|
|
84
|
-
const attribute: string = elementData[0];
|
|
85
|
-
const elements: string[] = elementData[1];
|
|
86
|
-
|
|
87
|
-
const create = (elementName: string): string => {
|
|
88
|
-
return `${elementName}[${attribute}]`;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
return elements.map(create).join(',');
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const selector: string = Object.entries(OBSOLETE_HTML_ATTRIBUTES).map(createSelector)
|
|
95
|
-
.join(',');
|
|
96
|
-
|
|
97
|
-
return selector;
|
|
98
|
-
})();
|
|
99
|
-
|
|
100
|
-
protected ruleConfig: IAbstractRuleConfig = {
|
|
101
|
-
id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.obsolete_html_attributes),
|
|
102
|
-
links: [
|
|
103
|
-
{
|
|
104
|
-
content: 'Non-conforming features',
|
|
105
|
-
url: 'https://www.w3.org/TR/html5/obsolete.html#non-conforming-features'
|
|
106
|
-
}
|
|
107
|
-
],
|
|
108
|
-
recommendations: [],
|
|
109
|
-
severity: $severity.high,
|
|
110
|
-
type: CATEGORY_TYPE.BEST_PRACTICE
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
public validate(elements: HTMLElement[]): void {
|
|
114
|
-
const reportNode = (element: HTMLElement): void => {
|
|
115
|
-
|
|
116
|
-
const attributes: Attr[] = Array.from(element.attributes);
|
|
117
|
-
const foundedAttributes: string[] = [];
|
|
118
|
-
|
|
119
|
-
const checkAttribute = (attr: Attr): void => {
|
|
120
|
-
const elms: string[] | undefined = OBSOLETE_HTML_ATTRIBUTES[attr.localName];
|
|
121
|
-
|
|
122
|
-
if (Array.isArray(elms)) {
|
|
123
|
-
if (elms.includes(element.nodeName.toLowerCase())) {
|
|
124
|
-
foundedAttributes.push(attr.localName);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
attributes.forEach(checkAttribute);
|
|
130
|
-
|
|
131
|
-
if (foundedAttributes.length === 0) {
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const reportMessage: string = TranslateService.instant('obsolete_html_attributes_report_message', foundedAttributes.join(', '));
|
|
136
|
-
|
|
137
|
-
const report: IIssueReport = {
|
|
138
|
-
message: reportMessage,
|
|
139
|
-
node: element,
|
|
140
|
-
ruleId: this.ruleConfig.id
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
this.validator.report(report);
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
elements.forEach(reportNode);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { ObsoleteHtmlElements } from './obsolete-html-elements';
|
|
2
|
-
|
|
3
|
-
describe('Rules', () => {
|
|
4
|
-
|
|
5
|
-
describe('ObsoleteHtmlElements', () => {
|
|
6
|
-
|
|
7
|
-
it('should indicate that class exists', () => {
|
|
8
|
-
expect(ObsoleteHtmlElements).toBeDefined();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
});
|
|
12
|
-
});
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { CATEGORY_TYPE } from '../../../constants/categoryType';
|
|
2
|
-
import { IIssueReport } from '../../../interfaces/rule-issue.interface';
|
|
3
|
-
import { TextUtility } from '../../../utils/text';
|
|
4
|
-
import { TranslateService } from '../../../services/translate';
|
|
5
|
-
import { $severity } from '../../../constants/accessibility';
|
|
6
|
-
import { $accessibilityAuditRules } from '../../../constants/accessibility';
|
|
7
|
-
import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
|
|
8
|
-
|
|
9
|
-
export class ObsoleteHtmlElements extends AbstractRule {
|
|
10
|
-
protected selector: string = [
|
|
11
|
-
'acronym',
|
|
12
|
-
'applet',
|
|
13
|
-
'basefont',
|
|
14
|
-
'bgsound',
|
|
15
|
-
'big',
|
|
16
|
-
'blink',
|
|
17
|
-
'center',
|
|
18
|
-
'dir',
|
|
19
|
-
'font',
|
|
20
|
-
'frame',
|
|
21
|
-
'frameset',
|
|
22
|
-
'hgroup',
|
|
23
|
-
'isindex',
|
|
24
|
-
'listing',
|
|
25
|
-
'marquee',
|
|
26
|
-
'multicol',
|
|
27
|
-
'nextid',
|
|
28
|
-
'nobr',
|
|
29
|
-
'noembed',
|
|
30
|
-
'noframes',
|
|
31
|
-
'plaintext',
|
|
32
|
-
's',
|
|
33
|
-
'spacer',
|
|
34
|
-
'strike',
|
|
35
|
-
'tt',
|
|
36
|
-
'u',
|
|
37
|
-
'xmp'
|
|
38
|
-
].join(', ');
|
|
39
|
-
|
|
40
|
-
protected ruleConfig: IAbstractRuleConfig = {
|
|
41
|
-
id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.obsolete_html_elements),
|
|
42
|
-
links: [
|
|
43
|
-
{
|
|
44
|
-
content: 'Non-conforming features',
|
|
45
|
-
url: 'https://www.w3.org/TR/html5/obsolete.html#non-conforming-features'
|
|
46
|
-
}
|
|
47
|
-
],
|
|
48
|
-
recommendations: [],
|
|
49
|
-
severity: $severity.high,
|
|
50
|
-
type: CATEGORY_TYPE.BEST_PRACTICE
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
public validate(elements: HTMLElement[]): void {
|
|
54
|
-
const reportNode = (element: HTMLElement): void => {
|
|
55
|
-
const problem: IIssueReport = {
|
|
56
|
-
message: TranslateService.instant('obsolete_html_elements_report_message', [element.nodeName.toLowerCase()]),
|
|
57
|
-
node: element,
|
|
58
|
-
ruleId: this.ruleConfig.id
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
this.validator.report(problem);
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
elements.forEach(reportNode);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import { DomUtility } from '../../../utils/dom';
|
|
2
|
-
import { CATEGORY_TYPE } from '../../../constants/categoryType';
|
|
3
|
-
import { IIssueReport } from '../../../interfaces/rule-issue.interface';
|
|
4
|
-
import { TextUtility } from '../../../utils/text';
|
|
5
|
-
import { TranslateService } from '../../../services/translate';
|
|
6
|
-
import { $severity } from '../../../constants/accessibility';
|
|
7
|
-
import { Config } from '../../../config';
|
|
8
|
-
import { $accessibilityAuditRules } from '../../../constants/accessibility';
|
|
9
|
-
import { AbstractRule, IAbstractRuleConfig } from '../../abstract-rule';
|
|
10
|
-
|
|
11
|
-
export class OutlineZero extends AbstractRule {
|
|
12
|
-
private appConfig: Config = Config.getInstance();
|
|
13
|
-
|
|
14
|
-
protected selector: () => CSSStyleSheet[] = (): CSSStyleSheet[] => {
|
|
15
|
-
return Array.from(document.styleSheets);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
protected ruleConfig: IAbstractRuleConfig = {
|
|
19
|
-
id: TextUtility.convertUnderscoresToDashes($accessibilityAuditRules.outline_zero),
|
|
20
|
-
links: [
|
|
21
|
-
{
|
|
22
|
-
content: 'F55: Failure of Success Criteria 2.1.1, 2.4.7, and 3.2.1 due to using script to remove focus when focus is received',
|
|
23
|
-
url: 'https://www.w3.org/TR/WCAG20-TECHS/F55.html'
|
|
24
|
-
}
|
|
25
|
-
],
|
|
26
|
-
recommendations: [],
|
|
27
|
-
severity: $severity.high,
|
|
28
|
-
type: CATEGORY_TYPE.BEST_PRACTICE
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
public validate(styleSheets: CSSStyleSheet[]): void {
|
|
32
|
-
if (styleSheets.length === 0) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const findOutlineZero = (styles: CSSStyleSheet): void => {
|
|
37
|
-
let currentRule: CSSRule;
|
|
38
|
-
let outlineWidthSize: number;
|
|
39
|
-
let selector: string;
|
|
40
|
-
let styleObject: any;
|
|
41
|
-
let isCSSembededInline: string;
|
|
42
|
-
let href: string | null;
|
|
43
|
-
const defaultSizeValues: string[] = ['thin', 'medium', 'thick'];
|
|
44
|
-
|
|
45
|
-
if (styles.hasOwnProperty('rules') === false || styles.href && styles.href.indexOf(this.appConfig.get('cssTitle')) !== -1) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const rules: CSSRuleList = styles.rules;
|
|
50
|
-
const rulesLength: number = rules.length;
|
|
51
|
-
|
|
52
|
-
for (let i: number = 0; i < rulesLength; i += 1) {
|
|
53
|
-
currentRule = rules[i];
|
|
54
|
-
styleObject = (currentRule as CSSStyleRule).style;
|
|
55
|
-
|
|
56
|
-
if (styleObject && styleObject.outlineWidth !== '' && defaultSizeValues.indexOf(styleObject.outlineWidth) === -1) {
|
|
57
|
-
outlineWidthSize = Number(styleObject.outlineWidth.replace(/[^\d.-]/g, ''));
|
|
58
|
-
|
|
59
|
-
if (outlineWidthSize === 0) {
|
|
60
|
-
href = (currentRule as any).parentStyleSheet.href;
|
|
61
|
-
|
|
62
|
-
if (href) {
|
|
63
|
-
isCSSembededInline = TranslateService.instant('outline_zero_css_embeded_1', [href]);
|
|
64
|
-
} else {
|
|
65
|
-
isCSSembededInline = TranslateService.instant('outline_zero_css_embeded_2', [DomUtility.getEscapedOuterHTML((currentRule as any).parentStyleSheet.ownerNode)]);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
selector = currentRule.cssText.replace(/(outline.*?;)/i, '<em>$1</em>');
|
|
69
|
-
const reportMessage: string = TranslateService.instant('outline_zero_report_message', [styleObject.outlineWidth, selector, isCSSembededInline]);
|
|
70
|
-
|
|
71
|
-
const report: IIssueReport = {
|
|
72
|
-
message: reportMessage,
|
|
73
|
-
node: null,
|
|
74
|
-
ruleId: this.ruleConfig.id
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
this.validator.report(report);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
styleSheets.forEach(findOutlineZero);
|
|
84
|
-
}
|
|
85
|
-
}
|