diff --git a/lib/commons/dom/get-element-by-reference.js b/lib/commons/dom/get-element-by-reference.js index 8878f66099..f9d70a6be7 100644 --- a/lib/commons/dom/get-element-by-reference.js +++ b/lib/commons/dom/get-element-by-reference.js @@ -11,19 +11,24 @@ */ dom.getElementByReference = function(node, attr) { let fragment = node.getAttribute(attr); + if (!fragment) { + return null; + } - if (fragment && fragment.charAt(0) === '#') { + if (fragment.charAt(0) === '#') { fragment = decodeURIComponent(fragment.substring(1)); + } else if (fragment.substr(0, 2) === '/#') { + fragment = decodeURIComponent(fragment.substring(2)); + } - let candidate = document.getElementById(fragment); - if (candidate) { - return candidate; - } + let candidate = document.getElementById(fragment); + if (candidate) { + return candidate; + } - candidate = document.getElementsByName(fragment); - if (candidate.length) { - return candidate[0]; - } + candidate = document.getElementsByName(fragment); + if (candidate.length) { + return candidate[0]; } return null; }; diff --git a/test/checks/navigation/region.js b/test/checks/navigation/region.js index 8162ff8a3c..134f4dda6f 100644 --- a/test/checks/navigation/region.js +++ b/test/checks/navigation/region.js @@ -66,6 +66,15 @@ describe('region', function() { assert.equal(checkContext._relatedNodes.length, 0); }); + it('should return true when there is an Angular skiplink', function() { + var checkArgs = checkSetup( + '
Click Here

Introduction

' + ); + + assert.isTrue(checks.region.evaluate.apply(checkContext, checkArgs)); + assert.equal(checkContext._relatedNodes.length, 0); + }); + it('should return false when there is a non-region element', function() { var checkArgs = checkSetup( '
This is random content.

Introduction

' diff --git a/test/checks/navigation/skip-link.js b/test/checks/navigation/skip-link.js index 08239c6eed..d44f3ae71b 100644 --- a/test/checks/navigation/skip-link.js +++ b/test/checks/navigation/skip-link.js @@ -56,4 +56,11 @@ describe('skip-link', function() { var node = fixture.querySelector('a'); assert.isTrue(checks['skip-link'].evaluate(node)); }); + + it('should return true if the URI is an Angular skiplink', function() { + fixture.innerHTML = + 'Click Here

Introduction

'; + var node = fixture.querySelector('a'); + assert.isTrue(checks['skip-link'].evaluate(node)); + }); }); diff --git a/test/commons/dom/get-element-by-reference.js b/test/commons/dom/get-element-by-reference.js index c7e561ec27..f7989e21a6 100644 --- a/test/commons/dom/get-element-by-reference.js +++ b/test/commons/dom/get-element-by-reference.js @@ -68,4 +68,17 @@ describe('dom.getElementByReference', function() { assert.equal(result, expected); }); + + it('returns the first matching element using Angular skiplinks', function() { + fixture.innerHTML = + 'Hi' + + '' + + ''; + + var node = document.getElementById('link'), + expected = document.getElementById('target0'), + result = axe.commons.dom.getElementByReference(node, 'href'); + + assert.equal(result, expected); + }); });