From ae6460a6d1ea574c46c6eda51b0de7b87612134a Mon Sep 17 00:00:00 2001 From: Steven Lambert Date: Wed, 8 Jul 2020 10:59:20 -0600 Subject: [PATCH 1/3] fix(virtual-node): default and lowercase type property --- .../base/virtual-node/serial-virtual-node.js | 16 ++++++- lib/core/base/virtual-node/virtual-node.js | 16 ++++++- .../base/virtual-node/serial-virtual-node.js | 42 +++++++++++++++++++ test/core/base/virtual-node/virtual-node.js | 8 ++++ 4 files changed, 79 insertions(+), 3 deletions(-) diff --git a/lib/core/base/virtual-node/serial-virtual-node.js b/lib/core/base/virtual-node/serial-virtual-node.js index f8ec1b5c3c..0fe662456f 100644 --- a/lib/core/base/virtual-node/serial-virtual-node.js +++ b/lib/core/base/virtual-node/serial-virtual-node.js @@ -52,11 +52,25 @@ function normaliseProps(serialNode) { `nodeName has to be a string, got '${nodeName}'` ); + nodeName = nodeName.toLowerCase(); + let type = null; + if (nodeName === 'input') { + type = ( + serialNode.type || + (serialNode.attributes && serialNode.attributes.type) || + 'text' + ).toLowerCase(); + } + const props = { ...serialNode, nodeType, - nodeName: nodeName.toLowerCase() + nodeName }; + if (type) { + props.type = type; + } + delete props.attributes; return Object.freeze(props); } diff --git a/lib/core/base/virtual-node/virtual-node.js b/lib/core/base/virtual-node/virtual-node.js index 830f926354..266c18ccc9 100644 --- a/lib/core/base/virtual-node/virtual-node.js +++ b/lib/core/base/virtual-node/virtual-node.js @@ -26,6 +26,18 @@ class VirtualNode extends AbstractVirtualNode { } this._isXHTML = isXHTMLGlobal; + this._nodeName = this._isXHTML + ? node.nodeName + : node.nodeName.toLowerCase(); + + // we will normalize the type prop for inputs by looking strictly + // at the attribute and not what the browser resolves the type + // to be + if (node.nodeName.toLowerCase() === 'input') { + const type = node.getAttribute('type') || 'text'; + this._type = this._isXHTML ? type : type.toLowerCase(); + } + // TODO: es-modules_cache if (axe._cache.get('nodeMap')) { axe._cache.get('nodeMap').set(node, this); @@ -35,13 +47,13 @@ class VirtualNode extends AbstractVirtualNode { // abstract Node properties so we can run axe in DOM-less environments. // add to the prototype so memory is shared across all virtual nodes get props() { - const { nodeType, nodeName, id, type, multiple } = this.actualNode; + const { nodeType, nodeName, id, multiple } = this.actualNode; return { nodeType, nodeName: this._isXHTML ? nodeName : nodeName.toLowerCase(), id, - type, + type: this._type, multiple }; } diff --git a/test/core/base/virtual-node/serial-virtual-node.js b/test/core/base/virtual-node/serial-virtual-node.js index 4b7209930f..1edc238102 100644 --- a/test/core/base/virtual-node/serial-virtual-node.js +++ b/test/core/base/virtual-node/serial-virtual-node.js @@ -89,6 +89,48 @@ describe('SerialVirtualNode', function() { }); assert.isUndefined(vNode.props.attributes); }); + + it('converts type prop to lower case', function() { + var types = ['text', 'COLOR', 'Month', 'uRL']; + types.forEach(function(type) { + var vNode = new SerialVirtualNode({ + nodeName: 'input', + type: type + }); + assert.equal(vNode.props.type, type.toLowerCase()); + }); + }); + + it('converts type attribute to lower case', function() { + var types = ['text', 'COLOR', 'Month', 'uRL']; + types.forEach(function(type) { + var vNode = new SerialVirtualNode({ + nodeName: 'input', + attributes: { + type: type + } + }); + assert.equal(vNode.props.type, type.toLowerCase()); + }); + }); + + it('defaults type prop to "text"', function() { + var vNode = new SerialVirtualNode({ + nodeName: 'input' + }); + assert.equal(vNode.props.type, 'text'); + }); + + it('uses the type property over the type attribute', function() { + var vNode = new SerialVirtualNode({ + nodeName: 'input', + type: 'month', + attributes: { + type: 'color' + } + }); + assert.equal(vNode.props.type, 'month'); + }); }); describe('attr', function() { diff --git a/test/core/base/virtual-node/virtual-node.js b/test/core/base/virtual-node/virtual-node.js index ef4103125e..9c135e7a7d 100644 --- a/test/core/base/virtual-node/virtual-node.js +++ b/test/core/base/virtual-node/virtual-node.js @@ -39,6 +39,14 @@ describe('VirtualNode', function() { assert.equal(vNode.props.type, 'text'); }); + it('should lowercase type', function() { + var node = document.createElement('input'); + node.setAttribute('type', 'COLOR'); + var vNode = new VirtualNode(node); + + assert.equal(vNode.props.type, 'color'); + }); + it('should lowercase nodeName', function() { var node = { nodeName: 'FOOBAR' From d1daff86d9b6976f530d351893b2e67962c98688 Mon Sep 17 00:00:00 2001 From: Steven Lambert Date: Thu, 9 Jul 2020 14:22:25 -0600 Subject: [PATCH 2/3] validate type --- lib/core/base/virtual-node/serial-virtual-node.js | 8 ++++++-- lib/core/base/virtual-node/virtual-node.js | 12 +++++++++--- .../core/base/virtual-node/serial-virtual-node.js | 10 ++++++++++ test/core/base/virtual-node/virtual-node.js | 15 +++++++++++++++ 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/lib/core/base/virtual-node/serial-virtual-node.js b/lib/core/base/virtual-node/serial-virtual-node.js index 0fe662456f..a94b8c9f7f 100644 --- a/lib/core/base/virtual-node/serial-virtual-node.js +++ b/lib/core/base/virtual-node/serial-virtual-node.js @@ -1,5 +1,5 @@ import AbstractVirtualNode from './abstract-virtual-node'; -import assert from '../../utils/assert'; +import { assert, validInputTypes } from '../../utils'; class SerialVirtualNode extends AbstractVirtualNode { /** @@ -58,8 +58,12 @@ function normaliseProps(serialNode) { type = ( serialNode.type || (serialNode.attributes && serialNode.attributes.type) || - 'text' + '' ).toLowerCase(); + + if (!validInputTypes().includes(type)) { + type = 'text'; + } } const props = { diff --git a/lib/core/base/virtual-node/virtual-node.js b/lib/core/base/virtual-node/virtual-node.js index 266c18ccc9..2b1e3124e0 100644 --- a/lib/core/base/virtual-node/virtual-node.js +++ b/lib/core/base/virtual-node/virtual-node.js @@ -1,5 +1,5 @@ import AbstractVirtualNode from './abstract-virtual-node'; -import { isXHTML } from '../../utils'; +import { isXHTML, validInputTypes } from '../../utils'; import { isFocusable, getTabbableElements } from '../../../commons/dom'; let isXHTMLGlobal; @@ -34,8 +34,14 @@ class VirtualNode extends AbstractVirtualNode { // at the attribute and not what the browser resolves the type // to be if (node.nodeName.toLowerCase() === 'input') { - const type = node.getAttribute('type') || 'text'; - this._type = this._isXHTML ? type : type.toLowerCase(); + let type = node.getAttribute('type'); + type = this._isXHTML ? type : (type || '').toLowerCase(); + + if (!validInputTypes().includes(type)) { + type = 'text'; + } + + this._type = type; } // TODO: es-modules_cache diff --git a/test/core/base/virtual-node/serial-virtual-node.js b/test/core/base/virtual-node/serial-virtual-node.js index 1edc238102..67abbf034e 100644 --- a/test/core/base/virtual-node/serial-virtual-node.js +++ b/test/core/base/virtual-node/serial-virtual-node.js @@ -121,6 +121,16 @@ describe('SerialVirtualNode', function() { assert.equal(vNode.props.type, 'text'); }); + it('default type prop to "text" if type is invalid', function() { + var vNode = new SerialVirtualNode({ + nodeName: 'input', + attributes: { + type: 'woohoo' + } + }); + assert.equal(vNode.props.type, 'text'); + }); + it('uses the type property over the type attribute', function() { var vNode = new SerialVirtualNode({ nodeName: 'input', diff --git a/test/core/base/virtual-node/virtual-node.js b/test/core/base/virtual-node/virtual-node.js index 9c135e7a7d..3236aa38a9 100644 --- a/test/core/base/virtual-node/virtual-node.js +++ b/test/core/base/virtual-node/virtual-node.js @@ -47,6 +47,21 @@ describe('VirtualNode', function() { assert.equal(vNode.props.type, 'color'); }); + it('should default type to text', function() { + var node = document.createElement('input'); + var vNode = new VirtualNode(node); + + assert.equal(vNode.props.type, 'text'); + }); + + it('should default type to text if type is invalid', function() { + var node = document.createElement('input'); + node.setAttribute('type', 'woohoo'); + var vNode = new VirtualNode(node); + + assert.equal(vNode.props.type, 'text'); + }); + it('should lowercase nodeName', function() { var node = { nodeName: 'FOOBAR' From 75840910eda743c106184f62ea0df48464f2a8ee Mon Sep 17 00:00:00 2001 From: Steven Lambert Date: Thu, 9 Jul 2020 14:24:29 -0600 Subject: [PATCH 3/3] typo --- lib/core/base/virtual-node/virtual-node.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/core/base/virtual-node/virtual-node.js b/lib/core/base/virtual-node/virtual-node.js index 2b1e3124e0..7445efd08e 100644 --- a/lib/core/base/virtual-node/virtual-node.js +++ b/lib/core/base/virtual-node/virtual-node.js @@ -26,10 +26,6 @@ class VirtualNode extends AbstractVirtualNode { } this._isXHTML = isXHTMLGlobal; - this._nodeName = this._isXHTML - ? node.nodeName - : node.nodeName.toLowerCase(); - // we will normalize the type prop for inputs by looking strictly // at the attribute and not what the browser resolves the type // to be