Skip to content

Commit

Permalink
Merge pull request #2093 from dequelabs/xmlLang
Browse files Browse the repository at this point in the history
fix(has-lang): update message to indicate that xml:lang is not valid on HTML pages
  • Loading branch information
straker authored Mar 12, 2020
2 parents 053b795 + c937816 commit c3a7de2
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 18 deletions.
14 changes: 12 additions & 2 deletions lib/checks/language/has-lang.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,18 @@ const { isXHTML } = axe.utils;
const langValue = (node.getAttribute(`lang`) || '').trim();
const xmlLangValue = (node.getAttribute(`xml:lang`) || '').trim();

if (!langValue && !isXHTML(document)) {
if (!langValue && xmlLangValue && !isXHTML(document)) {
this.data({
messageKey: 'noXHTML'
});
return false;
}

return !!(langValue || xmlLangValue);
if (!(langValue || xmlLangValue)) {
this.data({
messageKey: 'noLang'
});
return false;
}

return true;
5 changes: 4 additions & 1 deletion lib/checks/language/has-lang.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"impact": "serious",
"messages": {
"pass": "The <html> element has a lang attribute",
"fail": "The <html> element does not have a lang attribute"
"fail": {
"noXHTML": "The xml:lang attribute is not valid on HTML pages, use the lang attribute.",
"noLang": "The <html> element does not have a lang attribute"
}
}
}
}
34 changes: 19 additions & 15 deletions test/checks/language/has-lang.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,47 @@ describe('has-lang', function() {
'use strict';

var fixture = document.getElementById('fixture');
var checkContext = axe.testUtils.MockCheckContext();
var checkSetup = axe.testUtils.checkSetup;
var hasLangEvaluate = checks['has-lang'].evaluate;

afterEach(function() {
fixture.innerHTML = '';
checkContext.reset();
});

it('should return true if a lang attribute is present', function() {
var node = document.createElement('div');
node.setAttribute('lang', 'woohoo');
fixture.appendChild(node);
var params = checkSetup('<div id="target" lang="woohoo"></div>');

assert.isTrue(checks['has-lang'].evaluate(node));
assert.isTrue(hasLangEvaluate.apply(checkContext, params));
});

it('should return false if only `xml:lang` attribute is present', function() {
fixture.innerHTML = '<div xml:lang="cats"></div>';
var params = checkSetup('<div id="target" xml:lang="cats"></div>');

assert.isFalse(checks['has-lang'].evaluate(fixture.firstChild));
assert.isFalse(hasLangEvaluate.apply(checkContext, params));
assert.equal(checkContext._data.messageKey, 'noXHTML');
});

it('should return true if both `lang` and `xml:lang` attribute is present', function() {
fixture.innerHTML = '<div lang="cats" xml:lang="cats"></div>';
var params = checkSetup(
'<div id="target" lang="cats" xml:lang="cats"></div>'
);

assert.isTrue(checks['has-lang'].evaluate(fixture.firstChild));
assert.isTrue(hasLangEvaluate.apply(checkContext, params));
});

it('should return false if xml:lang and lang attributes are not present', function() {
var node = document.createElement('div');
fixture.appendChild(node);
var params = checkSetup('<div id="target"></div>');

assert.isFalse(checks['has-lang'].evaluate(node));
assert.isFalse(hasLangEvaluate.apply(checkContext, params));
assert.equal(checkContext._data.messageKey, 'noLang');
});

it('should return false if lang is left empty', function() {
var node = document.createElement('div');
node.setAttribute('lang', '');
fixture.appendChild(node);
var params = checkSetup('<div id="target" lang=""></div>');

assert.isFalse(checks['has-lang'].evaluate(node));
assert.isFalse(hasLangEvaluate.apply(checkContext, params));
assert.equal(checkContext._data.messageKey, 'noLang');
});
});

0 comments on commit c3a7de2

Please sign in to comment.