From b477e0d668ddd7d4563c8c154301d2976921635f Mon Sep 17 00:00:00 2001 From: Steven Lambert Date: Thu, 28 Mar 2019 10:36:05 -0600 Subject: [PATCH] fix: Prevent error when using . + // We can clone the node to isolate it and then return the attributes + return node.cloneNode(false).attributes; +}; diff --git a/lib/core/utils/get-selector.js b/lib/core/utils/get-selector.js index e0af47ad0d..7f2e4775dd 100644 --- a/lib/core/utils/get-selector.js +++ b/lib/core/utils/get-selector.js @@ -119,8 +119,8 @@ axe.utils.getSelectorData = function(domTree) { } // count all the filtered attributes - if (node.attributes) { - Array.from(node.attributes) + if (node.hasAttributes()) { + Array.from(axe.utils.getNodeAttributes(node)) .filter(filterAttributes) .forEach(at => { let atnv = getAttributeNameValue(node, at); @@ -238,8 +238,8 @@ function uncommonAttributes(node, selectorData) { let attData = selectorData.attributes; let tagData = selectorData.tags; - if (node.attributes) { - Array.from(node.attributes) + if (node.hasAttributes()) { + Array.from(axe.utils.getNodeAttributes(node)) .filter(filterAttributes) .forEach(at => { const atnv = getAttributeNameValue(node, at); diff --git a/lib/rules/aria-allowed-attr-matches.js b/lib/rules/aria-allowed-attr-matches.js index 782c99b465..09b5d69edc 100644 --- a/lib/rules/aria-allowed-attr-matches.js +++ b/lib/rules/aria-allowed-attr-matches.js @@ -1,6 +1,6 @@ const aria = /^aria-/; if (node.hasAttributes()) { - let attrs = node.attributes; + let attrs = axe.utils.getNodeAttributes(node); for (let i = 0, l = attrs.length; i < l; i++) { if (aria.test(attrs[i].name)) { return true; diff --git a/lib/rules/aria-has-attr-matches.js b/lib/rules/aria-has-attr-matches.js index a9bdbc4a5a..c12eb40965 100644 --- a/lib/rules/aria-has-attr-matches.js +++ b/lib/rules/aria-has-attr-matches.js @@ -1,6 +1,6 @@ var aria = /^aria-/; if (node.hasAttributes()) { - var attrs = node.attributes; + var attrs = axe.utils.getNodeAttributes(node); for (var i = 0, l = attrs.length; i < l; i++) { if (aria.test(attrs[i].name)) { return true; diff --git a/test/core/utils/get-node-attributes.js b/test/core/utils/get-node-attributes.js new file mode 100644 index 0000000000..bd35887d94 --- /dev/null +++ b/test/core/utils/get-node-attributes.js @@ -0,0 +1,26 @@ +describe('axe.utils.getNodeAttributes', function() { + 'use strict'; + + it('should return the list of attributes', function() { + var node = document.createElement('div'); + node.setAttribute('class', 'foo bar'); + var actual = axe.utils.getNodeAttributes(node); + assert.isTrue(actual instanceof window.NamedNodeMap); + assert.equal(actual.length, 1); + assert.equal(actual[0].name, 'class'); + }); + + it('should return the list of attributes when the DOM is clobbered', function() { + var node = document.createElement('form'); + node.setAttribute('id', '123'); + node.innerHTML = ''; + + // eslint-disable-next-line no-restricted-syntax + assert.isFalse(node.attributes instanceof window.NamedNodeMap); + + var actual = axe.utils.getNodeAttributes(node); + assert.isTrue(actual instanceof window.NamedNodeMap); + assert.equal(actual.length, 1); + assert.equal(actual[0].name, 'id'); + }); +});