Skip to content
This repository was archived by the owner on Dec 7, 2022. It is now read-only.

Commit ac6079e

Browse files
ricksbrownaddyosmani
authored andcommitted
Performance (#265)
* precursor performance changes * Allow caller to bypass entire DOM walk * Allow for other 'requires' beyond 'consoleAPI' * Collect 'hidden' and 'disabled' info during DOM traversal * Start using new 'hidden' and 'disabled' flags * Optionally collect 'idreferrers' while traversing DOM * Start using new 'idreferrers' flag
1 parent d902464 commit ac6079e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1941
-1046
lines changed

Changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### Enhancements
2+
3+
* Performance enhancements (#263)
4+
15
## 2.10.1-rc.0 - 2016-01-13
26

37
### Bug fixes:

src/audits/ControlsWithoutLabel.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ axs.AuditRules.addRule({
4747
}
4848
return true;
4949
},
50-
test: function(control) {
51-
if (axs.utils.isElementOrAncestorHidden(control))
50+
test: function(control, flags) {
51+
if (flags.hidden)
5252
return false;
5353
if (control.tagName.toLowerCase() == 'input' &&
5454
control.type == 'button' &&

src/audits/DuplicateId.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,35 @@ axs.AuditRules.addRule({
2525
heading: 'Any ID referred to via an IDREF must be unique in the DOM',
2626
url: 'https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_html_02',
2727
severity: axs.constants.Severity.SEVERE,
28-
relevantElementMatcher: function(element) {
29-
if (element.hasAttribute('id')) {
30-
var referrers = axs.utils.getIdReferrers(element);
31-
return referrers.some(function(referrer) {
32-
return !axs.utils.isElementOrAncestorHidden(referrer);
28+
opt_requires: {
29+
idRefs: true
30+
},
31+
/**
32+
* @this {axs.AuditRule}
33+
*/
34+
relevantElementMatcher: function(element, flags) {
35+
if (flags.idrefs.length && !flags.hidden) {
36+
this.relatedElements.push({
37+
element: element,
38+
flags: flags
3339
});
3440
}
41+
if (element.hasAttribute('id')) {
42+
return true;
43+
}
3544
return false;
3645
},
46+
/**
47+
* @this {axs.AuditRule}
48+
*/
49+
isRelevant: function(element, flags) {
50+
var id = element.id;
51+
var level = flags.level;
52+
return this.relatedElements.some(function(related) {
53+
var idrefs = related.flags.idrefs;
54+
return related.flags.level === level && idrefs.indexOf(id) >= 0;
55+
});
56+
},
3757
test: function(element) {
3858
/*
3959
* Checks for duplicate IDs within the context of this element.

src/audits/FocusableElementNotVisibleAndNotAriaHidden.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ axs.AuditRules.addRule({
5050
return true;
5151

5252
},
53-
test: function(element) {
54-
if (axs.utils.isElementOrAncestorHidden(element))
53+
test: function(element, flags) {
54+
if (flags.hidden)
5555
return false;
5656
element.focus();
5757
return !axs.utils.elementIsVisible(element);

src/audits/ImageWithoutAltText.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ axs.AuditRules.addRule({
2323
heading: 'Images should have a text alternative or presentational role',
2424
url: 'https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_text_02',
2525
severity: axs.constants.Severity.WARNING,
26-
relevantElementMatcher: function(element) {
27-
return axs.browserUtils.matchSelector(element, 'img') &&
28-
!axs.utils.isElementOrAncestorHidden(element);
26+
relevantElementMatcher: function(element, flags) {
27+
return axs.browserUtils.matchSelector(element, 'img') && !flags.hidden;
2928
},
3029
test: function(image) {
3130
var imageIsPresentational = (image.hasAttribute('alt') && image.alt == '') || image.getAttribute('role') == 'presentation';

src/audits/LinkWithUnclearPurpose.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ axs.AuditRules.addRule({
2828
* @param {Element} element
2929
* @return {boolean}
3030
*/
31-
relevantElementMatcher: function(element) {
32-
return axs.browserUtils.matchSelector(element, 'a[href]') && !axs.utils.isElementOrAncestorHidden(element);
31+
relevantElementMatcher: function(element, flags) {
32+
return axs.browserUtils.matchSelector(element, 'a[href]') && !flags.hidden;
3333
},
3434
/**
3535
* @param {Element} anchor
3636
* @param {Object=} opt_config
3737
* @return {boolean}
3838
*/
39-
test: function(anchor, opt_config) {
39+
test: function(anchor, flags, opt_config) {
4040
var config = opt_config || {};
4141
var blacklistPhrases = config['blacklistPhrases'] || [];
4242
var whitespaceRE = /\s+/;

src/audits/LowContrast.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ axs.AuditRules.addRule({
2525
heading: 'Text elements should have a reasonable contrast ratio',
2626
url: 'https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_color_01',
2727
severity: axs.constants.Severity.WARNING,
28-
relevantElementMatcher: function(element) {
29-
return axs.properties.hasDirectTextDescendant(element) &&
30-
!axs.utils.isElementDisabled(element);
28+
relevantElementMatcher: function(element, flags) {
29+
return !flags.disabled && axs.properties.hasDirectTextDescendant(element);
3130
},
3231
test: function(element) {
3332
var style = window.getComputedStyle(element, null);

src/audits/MeaningfulBackgroundImage.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ goog.require('axs.utils');
2222
axs.AuditRules.addRule({
2323
name: 'elementsWithMeaningfulBackgroundImage',
2424
severity: axs.constants.Severity.WARNING,
25-
relevantElementMatcher: function(element) {
26-
return !axs.utils.isElementOrAncestorHidden(element);
25+
relevantElementMatcher: function(element, flags) {
26+
return !flags.hidden;
2727
},
2828
heading: 'Meaningful images should not be used in element backgrounds',
2929
url: 'https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_image_01',

src/audits/NonExistentAriaRelatedElement.js

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,40 +17,27 @@ goog.require('axs.browserUtils');
1717
goog.require('axs.constants.Severity');
1818
goog.require('axs.utils');
1919

20-
// TODO(RickSBrown): Consider expanding this beyond ARIA? e.g. 'for' on label.
21-
2220
/**
23-
* 'ARIA attributes which refer to other elements by ID should refer to elements which exist in the DOM'
21+
* Attributes which refer to other elements by ID should refer to elements which exist in the DOM'.
2422
*/
2523
axs.AuditRules.addRule({
26-
name: 'nonExistentAriaRelatedElement',
27-
heading: 'ARIA attributes which refer to other elements by ID should refer to elements which exist in the DOM',
28-
url: 'https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_02',
24+
name: 'nonExistentRelatedElement',
25+
heading: 'Attributes which refer to other elements by ID should refer to elements which exist in the DOM',
26+
url: 'https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_html_03',
2927
severity: axs.constants.Severity.SEVERE,
30-
relevantElementMatcher: function(element) {
31-
var idrefTypes = ['idref', 'idref_list'];
32-
var idRefProps = axs.utils.getAriaPropertiesByValueType(idrefTypes);
33-
var selector = axs.utils.getSelectorForAriaProperties(idRefProps);
34-
return axs.browserUtils.matchSelector(element, selector);
28+
opt_requires: {
29+
idRefs: true
30+
},
31+
relevantElementMatcher: function(element, flags) {
32+
return flags.idrefs.length > 0;
3533
},
36-
test: function(element) {
37-
var idrefTypes = ['idref', 'idref_list'];
38-
var idRefProps = axs.utils.getAriaPropertiesByValueType(idrefTypes);
39-
var selector = axs.utils.getSelectorForAriaProperties(idRefProps);
40-
var selectors = selector.split(',');
41-
for (var i = 0, len = selectors.length; i < len; i++) {
42-
var nextSelector = selectors[i];
43-
if (axs.browserUtils.matchSelector(element, nextSelector)) {
44-
var propertyName = nextSelector.match(/aria-[^\]]+/)[0];
45-
var propertyValueText = element.getAttribute(propertyName);
46-
var propertyValue = axs.utils.getAriaPropertyValue(propertyName,
47-
propertyValueText,
48-
element);
49-
if (!propertyValue.valid)
50-
return true;
51-
}
52-
}
53-
return false;
34+
test: function(element, flags) {
35+
var idRefs = flags.idrefs;
36+
var missing = idRefs.some(function(id) {
37+
var refElement = document.getElementById(id);
38+
return !refElement;
39+
});
40+
return missing;
5441
},
55-
code: 'AX_ARIA_02'
42+
code: 'AX_HTML_03'
5643
});

src/audits/RoleTooltipRequiresDescribedBy.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ axs.AuditRules.addRule({
2525
heading: 'Elements with role=tooltip should have a corresponding element with aria-describedby',
2626
url: 'https://github.com/GoogleChrome/accessibility-developer-tools/wiki/Audit-Rules#ax_aria_02',
2727
severity: axs.constants.Severity.SEVERE,
28-
relevantElementMatcher: function(element) {
29-
return axs.browserUtils.matchSelector(element, '[role=tooltip]') &&
30-
!axs.utils.isElementOrAncestorHidden(element);
28+
relevantElementMatcher: function(element, flags) {
29+
return axs.browserUtils.matchSelector(element, '[role=tooltip]') && !flags.hidden;
3130
},
3231
test: function(element) {
3332
var referrers = axs.utils.getAriaIdReferrers(element, 'aria-describedby');

0 commit comments

Comments
 (0)