testilo 17.0.0 → 17.0.1
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/package.json +1 -1
- package/procs/analyze/coverage.js +69 -0
- package/procs/analyze/credit.js +16 -6
- package/procs/score/tic34.js +1 -1
- package/procs/score/tic35.js +48 -176
package/package.json
CHANGED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
coverage.js
|
|
3
|
+
Checks coverage of Testaro tests in an issue classification.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Returns a tabulation of the instance counts of issues reported by tools in scored reports.
|
|
7
|
+
const coverage = ticID => {
|
|
8
|
+
const evalRules = {
|
|
9
|
+
allCaps: 'leaf elements with entirely upper-case text longer than 7 characters',
|
|
10
|
+
allHidden: 'page that is entirely or mostly hidden',
|
|
11
|
+
allSlanted: 'leaf elements with entirely italic or oblique text longer than 39 characters',
|
|
12
|
+
autocomplete: 'name and email inputs without autocomplete attributes',
|
|
13
|
+
bulk: 'large count of visible elements',
|
|
14
|
+
buttonMenu: 'nonstandard keyboard navigation between items of button-controlled menus',
|
|
15
|
+
captionLoc: 'caption elements that are not first children of table elements',
|
|
16
|
+
distortion: 'distorted text',
|
|
17
|
+
docType: 'document without a doctype property',
|
|
18
|
+
dupAtt: 'elements with duplicate attributes',
|
|
19
|
+
embAc: 'active elements embedded in links or buttons',
|
|
20
|
+
filter: 'filter styles on elements',
|
|
21
|
+
focAll: 'discrepancies between focusable and Tab-focused elements',
|
|
22
|
+
focInd: 'missing and nonstandard focus indicators',
|
|
23
|
+
focOp: 'Tab-focusable elements that are not operable',
|
|
24
|
+
focVis: 'links that are invisible when focused',
|
|
25
|
+
headEl: 'invalid elements within the head',
|
|
26
|
+
headingAmb: 'same-level sibling headings with identical texts',
|
|
27
|
+
hover: 'hover-caused content changes',
|
|
28
|
+
hovInd: 'hover indication nonstandard',
|
|
29
|
+
hr: 'hr element instead of styles used for vertical segmentation',
|
|
30
|
+
labClash: 'labeling inconsistencies',
|
|
31
|
+
legendLoc: 'legend elements that are not first children of fieldset elements',
|
|
32
|
+
lineHeight: 'text with a line height less than 1.5 times its font size',
|
|
33
|
+
linkExt: 'links that automatically open new windows',
|
|
34
|
+
linkAmb: 'links with identical texts but different destinations',
|
|
35
|
+
linkOldAtt: 'links with deprecated attributes',
|
|
36
|
+
linkTitle: 'links with title attributes repeating text content',
|
|
37
|
+
linkTo: 'links without destinations',
|
|
38
|
+
linkUl: 'missing underlines on inline links',
|
|
39
|
+
miniText: 'text smaller than 11 pixels',
|
|
40
|
+
motion: 'motion without user request',
|
|
41
|
+
nonTable: 'table elements used for layout',
|
|
42
|
+
opFoc: 'Operable elements that are not Tab-focusable',
|
|
43
|
+
optRoleSel: 'Non-option elements with option roles that have no aria-selected attributes',
|
|
44
|
+
phOnly: 'input elements with placeholders but no accessible names',
|
|
45
|
+
pseudoP: 'adjacent br elements suspected of nonsemantically simulating p elements',
|
|
46
|
+
radioSet: 'radio buttons not grouped into standard field sets',
|
|
47
|
+
role: 'invalid and native-replacing explicit roles',
|
|
48
|
+
styleDiff: 'style inconsistencies',
|
|
49
|
+
tabNav: 'nonstandard keyboard navigation between elements with the tab role',
|
|
50
|
+
targetSize: 'buttons, inputs, and non-inline links smaller than 44 pixels wide and high',
|
|
51
|
+
titledEl: 'title attributes on inappropriate elements',
|
|
52
|
+
zIndex: 'non-default Z indexes'
|
|
53
|
+
};
|
|
54
|
+
const {issues} = require(`${__dirname}/../score/${ticID}`);
|
|
55
|
+
const testaroRuleIDs = new Set();
|
|
56
|
+
Object.values(issues).forEach(issue => {
|
|
57
|
+
if (issue.tools && issue.tools.testaro) {
|
|
58
|
+
Object.keys(issue.tools.testaro).forEach(ruleID => {
|
|
59
|
+
testaroRuleIDs.add(ruleID);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
Object.keys(evalRules).forEach(ruleID => {
|
|
64
|
+
if (! testaroRuleIDs.has(ruleID)) {
|
|
65
|
+
console.log(`${ticID} is missing ${ruleID}`);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
coverage('tic35');
|
package/procs/analyze/credit.js
CHANGED
|
@@ -17,7 +17,7 @@ exports.credit = reports => {
|
|
|
17
17
|
// If it is valid:
|
|
18
18
|
if (report.score && report.score.details && report.score.details.issue) {
|
|
19
19
|
// For each issue:
|
|
20
|
-
const issues = report.score.details.issue;
|
|
20
|
+
const issues = report.score.details && report.score.details.issue;
|
|
21
21
|
Object.keys(issues).forEach(issueID => {
|
|
22
22
|
// For each tool with any complaints about it:
|
|
23
23
|
if (! counts[issueID]) {
|
|
@@ -28,19 +28,29 @@ exports.credit = reports => {
|
|
|
28
28
|
Object.keys(issueTools).forEach(toolID => {
|
|
29
29
|
// For each rule cited by any of those complaints:
|
|
30
30
|
if (! counts[issueID][toolID]) {
|
|
31
|
-
counts[issueID][toolID] =
|
|
31
|
+
counts[issueID][toolID] = {
|
|
32
|
+
total: 0,
|
|
33
|
+
rules: {}
|
|
34
|
+
};
|
|
32
35
|
}
|
|
33
36
|
Object.keys(issueTools[toolID]).forEach(ruleID => {
|
|
34
37
|
// If an instance count was recorded:
|
|
35
38
|
const {complaints} = issueTools[toolID][ruleID];
|
|
36
39
|
if (complaints && complaints.countTotal) {
|
|
37
40
|
// Add it to the tally.
|
|
38
|
-
counts[issueID][toolID] += complaints.countTotal;
|
|
41
|
+
counts[issueID][toolID].total += complaints.countTotal;
|
|
42
|
+
// Add a rule itemization to the tally.
|
|
43
|
+
if (! counts[issueID][toolID].rules[ruleID]) {
|
|
44
|
+
counts[issueID][toolID].rules[ruleID] = 0;
|
|
45
|
+
}
|
|
46
|
+
counts[issueID][toolID].rules[ruleID] += complaints.countTotal;
|
|
39
47
|
}
|
|
40
48
|
// Otherwise, i.e. if no instance count was recorded:
|
|
41
49
|
else {
|
|
42
50
|
// Report this.
|
|
43
|
-
console.log(
|
|
51
|
+
console.log(
|
|
52
|
+
`ERROR: Report ${report.id} missing countTotal for ${toolID} in ${issueID}`
|
|
53
|
+
);
|
|
44
54
|
}
|
|
45
55
|
});
|
|
46
56
|
});
|
|
@@ -69,9 +79,9 @@ exports.credit = reports => {
|
|
|
69
79
|
// Add the tools with the maximum instance count to the tally.
|
|
70
80
|
const maxCount = Object
|
|
71
81
|
.values(counts[issueID])
|
|
72
|
-
.reduce((max, current) => Math.max(max, current));
|
|
82
|
+
.reduce((max, current) => Math.max(max, current ? current.total : 0), 0);
|
|
73
83
|
Object.keys(counts[issueID]).forEach(toolID => {
|
|
74
|
-
if (counts[issueID][toolID] === maxCount) {
|
|
84
|
+
if (maxCount && counts[issueID][toolID].total === maxCount) {
|
|
75
85
|
if (! mosts[issueID]) {
|
|
76
86
|
mosts[issueID] = [];
|
|
77
87
|
}
|
package/procs/score/tic34.js
CHANGED
package/procs/score/tic35.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
tic35
|
|
3
|
-
CONTINUUM NOT YET REMOVED
|
|
4
3
|
Testilo issue classification 35
|
|
5
4
|
|
|
6
|
-
Classifies
|
|
5
|
+
Classifies about 650 rules of the tools of Testaro into 256 issues.
|
|
7
6
|
|
|
8
7
|
Issue properties:
|
|
9
8
|
why: expected impact
|
|
@@ -351,11 +350,11 @@ exports.issues = {
|
|
|
351
350
|
wcag: '4.1.2',
|
|
352
351
|
weight: 3,
|
|
353
352
|
tools: {
|
|
354
|
-
|
|
355
|
-
|
|
353
|
+
testaro: {
|
|
354
|
+
phOnly: {
|
|
356
355
|
variable: false,
|
|
357
356
|
quality: 1,
|
|
358
|
-
what: 'input element has
|
|
357
|
+
what: 'input element has a placeholder but no accessible name'
|
|
359
358
|
}
|
|
360
359
|
}
|
|
361
360
|
}
|
|
@@ -1365,8 +1364,8 @@ exports.issues = {
|
|
|
1365
1364
|
wcag: '1.3.1',
|
|
1366
1365
|
weight: 4,
|
|
1367
1366
|
tools: {
|
|
1368
|
-
|
|
1369
|
-
|
|
1367
|
+
testaro: {
|
|
1368
|
+
adbBadID: {
|
|
1370
1369
|
variable: false,
|
|
1371
1370
|
quality: 1,
|
|
1372
1371
|
what: 'aria-describedby attribute references an invalid or duplicate ID'
|
|
@@ -1678,13 +1677,6 @@ exports.issues = {
|
|
|
1678
1677
|
wcag: '1.3.1',
|
|
1679
1678
|
weight: 4,
|
|
1680
1679
|
tools: {
|
|
1681
|
-
continuum: {
|
|
1682
|
-
872: {
|
|
1683
|
-
variable: false,
|
|
1684
|
-
quality: 1,
|
|
1685
|
-
what: 'textarea element has no accessible name, but only a placeholder attribute'
|
|
1686
|
-
}
|
|
1687
|
-
},
|
|
1688
1680
|
htmlcs: {
|
|
1689
1681
|
'AAA.4_1_2.H91.Textarea.Name': {
|
|
1690
1682
|
variable: false,
|
|
@@ -2081,13 +2073,6 @@ exports.issues = {
|
|
|
2081
2073
|
what: 'svg element with an img role has no text alternative'
|
|
2082
2074
|
}
|
|
2083
2075
|
},
|
|
2084
|
-
continuum: {
|
|
2085
|
-
123: {
|
|
2086
|
-
variable: false,
|
|
2087
|
-
quality: 1,
|
|
2088
|
-
what: 'svg element has no machanism allowing an accessible name to be calculated'
|
|
2089
|
-
}
|
|
2090
|
-
},
|
|
2091
2076
|
qualWeb: {
|
|
2092
2077
|
'QW-ACT-R21': {
|
|
2093
2078
|
variable: false,
|
|
@@ -2961,28 +2946,6 @@ exports.issues = {
|
|
|
2961
2946
|
what: 'Element does not have all required states and properties'
|
|
2962
2947
|
}
|
|
2963
2948
|
},
|
|
2964
|
-
continuum: {
|
|
2965
|
-
1039: {
|
|
2966
|
-
variable: false,
|
|
2967
|
-
quality: 1,
|
|
2968
|
-
what: 'Element with a checkbox role has no aria-checked attribute'
|
|
2969
|
-
},
|
|
2970
|
-
1040: {
|
|
2971
|
-
variable: false,
|
|
2972
|
-
quality: 1,
|
|
2973
|
-
what: 'Element with a combobox role has no aria-controls or no aria-expanded attribute'
|
|
2974
|
-
},
|
|
2975
|
-
1042: {
|
|
2976
|
-
variable: false,
|
|
2977
|
-
quality: 1,
|
|
2978
|
-
what: 'Element with an option role has no aria-selected attribute'
|
|
2979
|
-
},
|
|
2980
|
-
1043: {
|
|
2981
|
-
variable: false,
|
|
2982
|
-
quality: 1,
|
|
2983
|
-
what: 'Element with a radio role has no aria-checked attribute'
|
|
2984
|
-
}
|
|
2985
|
-
},
|
|
2986
2949
|
nuVal: {
|
|
2987
2950
|
'^Element .+ is missing required attribute aria-.+$': {
|
|
2988
2951
|
variable: true,
|
|
@@ -2999,6 +2962,20 @@ exports.issues = {
|
|
|
2999
2962
|
}
|
|
3000
2963
|
}
|
|
3001
2964
|
},
|
|
2965
|
+
ariaMissingRisk: {
|
|
2966
|
+
why: 'Item may behave improperly',
|
|
2967
|
+
wcag: '4.1.2',
|
|
2968
|
+
weight: 2,
|
|
2969
|
+
tools: {
|
|
2970
|
+
testaro: {
|
|
2971
|
+
optRoleSel: {
|
|
2972
|
+
variable: false,
|
|
2973
|
+
quality: 1,
|
|
2974
|
+
what: 'Non-option element with an explicit option role has no aria-selected attribute'
|
|
2975
|
+
}
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
},
|
|
3002
2979
|
ariaAttributeBad: {
|
|
3003
2980
|
why: 'Item behavior violates user expectations',
|
|
3004
2981
|
wcag: '4.1.2',
|
|
@@ -3043,108 +3020,6 @@ exports.issues = {
|
|
|
3043
3020
|
what: 'aria-roledescription is on an element with no semantic role'
|
|
3044
3021
|
}
|
|
3045
3022
|
},
|
|
3046
|
-
continuum: {
|
|
3047
|
-
16: {
|
|
3048
|
-
variable: false,
|
|
3049
|
-
quality: 1,
|
|
3050
|
-
what: 'Element has an aria-multiline attribute, which is not allowed'
|
|
3051
|
-
},
|
|
3052
|
-
38: {
|
|
3053
|
-
variable: false,
|
|
3054
|
-
quality: 1,
|
|
3055
|
-
what: 'Element has an aria-pressed attribute, which is not allowed'
|
|
3056
|
-
},
|
|
3057
|
-
64: {
|
|
3058
|
-
variable: false,
|
|
3059
|
-
quality: 1,
|
|
3060
|
-
what: 'Element has an aria-valuemax attribute that is not set to an integer'
|
|
3061
|
-
},
|
|
3062
|
-
257: {
|
|
3063
|
-
variable: false,
|
|
3064
|
-
quality: 1,
|
|
3065
|
-
what: 'Element has an aria-checked attribute, which is not allowed'
|
|
3066
|
-
},
|
|
3067
|
-
260: {
|
|
3068
|
-
variable: false,
|
|
3069
|
-
quality: 1,
|
|
3070
|
-
what: 'Element has an aria-level attribute, which is not allowed'
|
|
3071
|
-
},
|
|
3072
|
-
261: {
|
|
3073
|
-
variable: false,
|
|
3074
|
-
quality: 1,
|
|
3075
|
-
what: 'Element has an aria-multiselectable attribute, which is not allowed'
|
|
3076
|
-
},
|
|
3077
|
-
264: {
|
|
3078
|
-
variable: false,
|
|
3079
|
-
quality: 1,
|
|
3080
|
-
what: 'Element has an aria-selected attribute, which is not allowed'
|
|
3081
|
-
},
|
|
3082
|
-
270: {
|
|
3083
|
-
variable: false,
|
|
3084
|
-
quality: 1,
|
|
3085
|
-
what: 'Element has an aria-required attribute, which is not allowed'
|
|
3086
|
-
},
|
|
3087
|
-
278: {
|
|
3088
|
-
variable: false,
|
|
3089
|
-
quality: 1,
|
|
3090
|
-
what: 'Element has an aria-modal attribute, which is not allowed'
|
|
3091
|
-
},
|
|
3092
|
-
279: {
|
|
3093
|
-
variable: false,
|
|
3094
|
-
quality: 1,
|
|
3095
|
-
what: 'Element has an aria-posinset attribute without having a compatible role'
|
|
3096
|
-
},
|
|
3097
|
-
280: {
|
|
3098
|
-
variable: false,
|
|
3099
|
-
quality: 1,
|
|
3100
|
-
what: 'Element has aria-posinset and aria-setsize attributes without having a compatible role'
|
|
3101
|
-
},
|
|
3102
|
-
281: {
|
|
3103
|
-
variable: false,
|
|
3104
|
-
quality: 1,
|
|
3105
|
-
what: 'Element has an aria-expanded attribute, which is not allowed'
|
|
3106
|
-
},
|
|
3107
|
-
282: {
|
|
3108
|
-
variable: false,
|
|
3109
|
-
quality: 1,
|
|
3110
|
-
what: 'Element has an aria-autocomplete attribute, which is not allowed'
|
|
3111
|
-
},
|
|
3112
|
-
283: {
|
|
3113
|
-
variable: false,
|
|
3114
|
-
quality: 1,
|
|
3115
|
-
what: 'Element has an aria-activedescendant attribute, which is not allowed'
|
|
3116
|
-
},
|
|
3117
|
-
331: {
|
|
3118
|
-
variable: false,
|
|
3119
|
-
quality: 1,
|
|
3120
|
-
what: 'Element has an aria-owns attribute set to a non-null value'
|
|
3121
|
-
},
|
|
3122
|
-
333: {
|
|
3123
|
-
variable: false,
|
|
3124
|
-
quality: 1,
|
|
3125
|
-
what: 'Element with a textbox role has an aria-owns attribute, which is not allowed'
|
|
3126
|
-
},
|
|
3127
|
-
334: {
|
|
3128
|
-
variable: false,
|
|
3129
|
-
quality: 1,
|
|
3130
|
-
what: 'Element with a searchbox role has an aria-owns attribute, which is not allowed'
|
|
3131
|
-
},
|
|
3132
|
-
609: {
|
|
3133
|
-
variable: false,
|
|
3134
|
-
quality: 1,
|
|
3135
|
-
what: 'Element has an aria-setsize attribute but has no aria-posinset attribute'
|
|
3136
|
-
},
|
|
3137
|
-
610: {
|
|
3138
|
-
variable: false,
|
|
3139
|
-
quality: 1,
|
|
3140
|
-
what: 'Element has an aria-setsize attribute without having a compatible role'
|
|
3141
|
-
},
|
|
3142
|
-
1066: {
|
|
3143
|
-
variable: false,
|
|
3144
|
-
quality: 1,
|
|
3145
|
-
what: 'Element has an ARIA attribute which is not valid'
|
|
3146
|
-
}
|
|
3147
|
-
},
|
|
3148
3023
|
ibm: {
|
|
3149
3024
|
aria_semantics_attribute: {
|
|
3150
3025
|
variable: false,
|
|
@@ -4336,18 +4211,6 @@ exports.issues = {
|
|
|
4336
4211
|
quality: 1,
|
|
4337
4212
|
what: 'li element is not contained by a ul or ol element'
|
|
4338
4213
|
}
|
|
4339
|
-
},
|
|
4340
|
-
continuum: {
|
|
4341
|
-
99: {
|
|
4342
|
-
variable: false,
|
|
4343
|
-
quality: 1,
|
|
4344
|
-
what: 'li element has no ul, ol, or list-role parent'
|
|
4345
|
-
},
|
|
4346
|
-
385: {
|
|
4347
|
-
variable: false,
|
|
4348
|
-
quality: 1,
|
|
4349
|
-
what: 'list item has no ul, ol, or list-role parent or owner'
|
|
4350
|
-
}
|
|
4351
4214
|
}
|
|
4352
4215
|
}
|
|
4353
4216
|
},
|
|
@@ -4583,8 +4446,8 @@ exports.issues = {
|
|
|
4583
4446
|
wcag: '4.1.2',
|
|
4584
4447
|
weight: 4,
|
|
4585
4448
|
tools: {
|
|
4586
|
-
|
|
4587
|
-
|
|
4449
|
+
testaro: {
|
|
4450
|
+
legendLoc: {
|
|
4588
4451
|
variable: false,
|
|
4589
4452
|
quality: 1,
|
|
4590
4453
|
what: 'legend element is not the first child of its fieldset element'
|
|
@@ -4766,6 +4629,20 @@ exports.issues = {
|
|
|
4766
4629
|
}
|
|
4767
4630
|
}
|
|
4768
4631
|
},
|
|
4632
|
+
tableCaptionLoc: {
|
|
4633
|
+
why: 'User cannot get help on the topic of a table',
|
|
4634
|
+
wcag: '1.3.1',
|
|
4635
|
+
weight: 3,
|
|
4636
|
+
tools: {
|
|
4637
|
+
testaro: {
|
|
4638
|
+
captionLoc: {
|
|
4639
|
+
variable: false,
|
|
4640
|
+
quality: 1,
|
|
4641
|
+
what: 'caption element is not the first child of a table element'
|
|
4642
|
+
}
|
|
4643
|
+
}
|
|
4644
|
+
}
|
|
4645
|
+
},
|
|
4769
4646
|
cellHeadersNotInferrable: {
|
|
4770
4647
|
why: 'User cannot get help on relationships in a table',
|
|
4771
4648
|
wcag: '1.3.1',
|
|
@@ -4775,7 +4652,7 @@ exports.issues = {
|
|
|
4775
4652
|
'AAA.1_3_1.H43.HeadersRequired': {
|
|
4776
4653
|
variable: false,
|
|
4777
4654
|
quality: 1,
|
|
4778
|
-
what: 'Complex table
|
|
4655
|
+
what: 'Complex table is missing headers attributes of cells'
|
|
4779
4656
|
}
|
|
4780
4657
|
},
|
|
4781
4658
|
ibm: {
|
|
@@ -5752,18 +5629,6 @@ exports.issues = {
|
|
|
5752
5629
|
wcag: '1.3.6',
|
|
5753
5630
|
weight: 3,
|
|
5754
5631
|
tools: {
|
|
5755
|
-
continuum: {
|
|
5756
|
-
531: {
|
|
5757
|
-
variable: false,
|
|
5758
|
-
quality: 1,
|
|
5759
|
-
what: 'nav element has an accessible name that is non-unique among the nav elements'
|
|
5760
|
-
},
|
|
5761
|
-
533: {
|
|
5762
|
-
variable: false,
|
|
5763
|
-
quality: 1,
|
|
5764
|
-
what: 'nav element is not the only nav element but has no accessible name'
|
|
5765
|
-
}
|
|
5766
|
-
},
|
|
5767
5632
|
ibm: {
|
|
5768
5633
|
Rpt_Aria_MultipleNavigationLandmarks_Implicit: {
|
|
5769
5634
|
variable: false,
|
|
@@ -5884,7 +5749,7 @@ exports.issues = {
|
|
|
5884
5749
|
weight: 4,
|
|
5885
5750
|
tools: {
|
|
5886
5751
|
testaro: {
|
|
5887
|
-
|
|
5752
|
+
opFoc: {
|
|
5888
5753
|
variable: false,
|
|
5889
5754
|
quality: 1,
|
|
5890
5755
|
what: 'Operable element is not Tab-focusable'
|
|
@@ -6207,8 +6072,8 @@ exports.issues = {
|
|
|
6207
6072
|
wcag: '1.3.3',
|
|
6208
6073
|
weight: 1,
|
|
6209
6074
|
tools: {
|
|
6210
|
-
|
|
6211
|
-
|
|
6075
|
+
testaro: {
|
|
6076
|
+
imageLink: {
|
|
6212
6077
|
variable: false,
|
|
6213
6078
|
quality: 1,
|
|
6214
6079
|
what: 'a element has an href attribute set to an image file reference'
|
|
@@ -6445,7 +6310,7 @@ exports.issues = {
|
|
|
6445
6310
|
weight: 1,
|
|
6446
6311
|
tools: {
|
|
6447
6312
|
testaro: {
|
|
6448
|
-
|
|
6313
|
+
filter: {
|
|
6449
6314
|
variable: false,
|
|
6450
6315
|
quality: 1,
|
|
6451
6316
|
what: 'Element styles include filter'
|
|
@@ -7034,6 +6899,13 @@ exports.issues = {
|
|
|
7034
6899
|
what: 'HTML element is used to control the visual presentation of content'
|
|
7035
6900
|
}
|
|
7036
6901
|
},
|
|
6902
|
+
testaro: {
|
|
6903
|
+
linkOldAtt: {
|
|
6904
|
+
variable: false,
|
|
6905
|
+
quality: 1,
|
|
6906
|
+
what: 'a element has a deprecated attribute'
|
|
6907
|
+
}
|
|
6908
|
+
},
|
|
7037
6909
|
wave: {
|
|
7038
6910
|
longdesc: {
|
|
7039
6911
|
variable: false,
|