Skip to content

Commit

Permalink
Merge branch 'aria-label'
Browse files Browse the repository at this point in the history
Resolves #160.
  • Loading branch information
ironikart committed Aug 26, 2016
2 parents 53c7093 + cb9ac89 commit 47d41a8
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 37 deletions.
33 changes: 33 additions & 0 deletions HTMLCS.Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,39 @@ _global.HTMLCS.util = function() {

};

/**
* Returns true if the element has a valid aria label.
*
* @param {Node} element The element we are checking.
*
* @return {Boolean}
*/
self.hasValidAriaLabel = function(element)
{
var found = false;
if (element.hasAttribute('aria-labelledby') === true) {
// Checking aria-labelled by where the label exists AND it has text available
// to an accessibility API.
var labelledByIds = element.getAttribute('aria-labelledby').split(/\s+/);
labelledByIds.forEach(function(id) {
var elem = document.getElementById(id);
if (elem) {
var text = self.getElementTextContent(elem);
if (/^\s*$/.test(text) === false) {
found = true;
}
}
});
} else if (element.hasAttribute('aria-label') === true) {
var text = element.getAttribute('aria-label');
if (/^\s*$/.test(text) === false) {
found = true;
}
}

return found;
};

/**
* Return the appropriate computed style object for an element.
*
Expand Down
36 changes: 12 additions & 24 deletions Standards/WCAG2AAA/Sniffs/Principle1/Guideline1_3/1_3_1.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,8 @@ _global.HTMLCS_WCAG2AAA_Sniffs_Principle1_Guideline1_3_1_3_1 = {
}

// Find an aria-label attribute.
var ariaLabel = element.getAttribute('aria-label');
if (ariaLabel !== null) {
if ((/^\s*$/.test(ariaLabel) === true) && (needsLabel === true)) {
if (element.hasAttribute('aria-label') === true) {
if (HTMLCS.util.hasValidAriaLabel(element) === false) {
HTMLCS.addMessage(
HTMLCS.WARNING,
element,
Expand All @@ -270,28 +269,17 @@ _global.HTMLCS_WCAG2AAA_Sniffs_Principle1_Guideline1_3_1_3_1 = {
}
}

// Find an aria-labelledby attribute.
var ariaLabelledBy = element.getAttribute('aria-labelledby');
if (ariaLabelledBy && (/^\s*$/.test(ariaLabelledBy) === false)) {
var labelledByIds = ariaLabelledBy.split(/\s+/);
var ok = true;

// First check that all of the IDs (space separated) are present and correct.
for (var x = 0; x < labelledByIds.length; x++) {
var labelledByElement = element.ownerDocument.querySelector('#' + labelledByIds[x]);
if (!labelledByElement) {
HTMLCS.addMessage(
HTMLCS.WARNING,
element,
'This form control contains an aria-labelledby attribute, however it includes an ID "' + labelledByIds[x] + '" that does not exist on an element. The aria-labelledby attribute will be ignored for labelling test purposes.',
'ARIA16,ARIA9'
);
ok = false;
}
}

// We are all OK, add as a successful label technique.
if (ok === true) {
// Find an aria-labelledby attribute.
if (element.hasAttribute('aria-labelledby') === true) {
if (HTMLCS.util.hasValidAriaLabel(element) === false) {
HTMLCS.addMessage(
HTMLCS.WARNING,
element,
'This form control contains an aria-labelledby attribute, however it includes an ID "' + element.getAttribute('aria-labelledby') + '" that does not exist on an element. The aria-labelledby attribute will be ignored for labelling test purposes.',
'ARIA16,ARIA9'
);
} else {
addToLabelList('aria-labelledby');
}
}
Expand Down
35 changes: 22 additions & 13 deletions Standards/WCAG2AAA/Sniffs/Principle4/Guideline4_1/4_1_2.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,17 @@ _global.HTMLCS_WCAG2AAA_Sniffs_Principle4_Guideline4_1_4_1_2 = {
var warnings = [];

var requiredNames = {
button: ['@title', '_content'],
fieldset: ['legend'],
input_button: ['@value'],
input_text: ['label', '@title'],
input_file: ['label', '@title'],
input_password: ['label', '@title'],
input_checkbox: ['label', '@title'],
input_radio: ['label', '@title'],
input_image: ['@alt', '@title'],
select: ['label', '@title'],
textarea: ['label', '@title']
button: ['@title', '_content', '@aria-label', '@aria-labelledby'],
fieldset: ['legend', '@aria-label', '@aria-labelledby'],
input_button: ['@value', '@aria-label', '@aria-labelledby'],
input_text: ['label', '@title', '@aria-label', '@aria-labelledby'],
input_file: ['label', '@title', '@aria-label', '@aria-labelledby'],
input_password: ['label', '@title', '@aria-label', '@aria-labelledby'],
input_checkbox: ['label', '@title', '@aria-label', '@aria-labelledby'],
input_radio: ['label', '@title', '@aria-label', '@aria-labelledby'],
input_image: ['@alt', '@title', '@aria-label', '@aria-labelledby'],
select: ['label', '@title', '@aria-label', '@aria-labelledby'],
textarea: ['label', '@title', '@aria-label', '@aria-labelledby']
}

var requiredValues = {
Expand Down Expand Up @@ -218,12 +218,16 @@ _global.HTMLCS_WCAG2AAA_Sniffs_Principle4_Guideline4_1_4_1_2 = {
// functions in SC 1.3.1.
var hasLabel = HTMLCS_WCAG2AAA_Sniffs_Principle1_Guideline1_3_1_3_1.testLabelsOnInputs(element, top, true);
if (hasLabel !== false) {
found = true;
break;
}
} else if (requiredName.charAt(0) === '@') {
// Attribute.
requiredName = requiredName.substr(1, requiredName.length);

if ((requiredName === 'aria-label' || requiredName === 'aria-labelledby') && HTMLCS.util.hasValidAriaLabel(element)) {
break;
}

if ((element.hasAttribute(requiredName) === true) && (/^\s*$/.test(element.getAttribute(requiredName)) === false)) {
break;
}
Expand Down Expand Up @@ -300,14 +304,19 @@ _global.HTMLCS_WCAG2AAA_Sniffs_Principle4_Guideline4_1_4_1_2 = {
}
}//end if

// Check for valid aria labels.
if (valueFound === false) {
valuFound = HTMLCS.util.hasValidAriaLabel(element);
}

if (valueFound === false) {
var msgNodeType = nodeName + ' element';
if (nodeName.substr(0, 6) === 'input_') {
msgNodeType = nodeName.substr(6) + ' input element';
}

var msg = 'This ' + msgNodeType + ' does not have a value available to an accessibility API.';

var builtAttr = '';
var warning = false;
if (requiredValue === '_content') {
Expand Down
37 changes: 37 additions & 0 deletions Tests/WCAG2/4_1_2_Aria_Labels.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>
<head>
<title>4.1.2 Aria Labels</title>
<!-- @HTMLCS_Test@
Name: SC 4.1.2 Aria Labels
Standard: WCAG2AAA
Assert: Error *.H91.* on #unlabelledButton
Assert: No Error *.H91 on #labelledButton
Assert: Error *.H91.* on #emptyLabelledButton
Assert: No Error * on #labelledByButton
-->
</head>
<body>
<form>

<button id="unlabelledButton">
<span class="dd-icon glyph glyphicon-heart" aria-hidden="true"></span>
</button>

<button id="labelledButton" aria-label="my icon button">
<span class="dd-icon glyph glyphicon-heart" aria-hidden="true"></span>
</button>

<button id="emptyLabelledButton" aria-label="">
<span class="dd-icon glyph glyphicon-heart" aria-hidden="true"></span>
</button>

<div id="billing">Billing Address</div>
<div>
<div id="name">Name</div>
<input id="labelledByButton" type="text" aria-labelledby="billing name"/>
</div>

</form>
</body>
</html>

0 comments on commit 47d41a8

Please sign in to comment.