Skip to content

Commit

Permalink
fix(virtual-node): default and lowercase type property (#2350)
Browse files Browse the repository at this point in the history
* fix(virtual-node): default and lowercase type property

* validate type

* typo
  • Loading branch information
straker committed Jul 10, 2020
1 parent e5fb01e commit f6b3484
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 5 deletions.
22 changes: 20 additions & 2 deletions 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 {
/**
Expand Down Expand Up @@ -52,11 +52,29 @@ 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) ||
''
).toLowerCase();

if (!validInputTypes().includes(type)) {
type = 'text';
}
}

const props = {
...serialNode,
nodeType,
nodeName: nodeName.toLowerCase()
nodeName
};
if (type) {
props.type = type;
}

delete props.attributes;
return Object.freeze(props);
}
Expand Down
20 changes: 17 additions & 3 deletions 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;
Expand All @@ -26,6 +26,20 @@ class VirtualNode extends AbstractVirtualNode {
}
this._isXHTML = isXHTMLGlobal;

// 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') {
let type = node.getAttribute('type');
type = this._isXHTML ? type : (type || '').toLowerCase();

if (!validInputTypes().includes(type)) {
type = 'text';
}

this._type = type;
}

// TODO: es-modules_cache
if (axe._cache.get('nodeMap')) {
axe._cache.get('nodeMap').set(node, this);
Expand All @@ -35,13 +49,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
};
}
Expand Down
52 changes: 52 additions & 0 deletions test/core/base/virtual-node/serial-virtual-node.js
Expand Up @@ -89,6 +89,58 @@ 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('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',
type: 'month',
attributes: {
type: 'color'
}
});
assert.equal(vNode.props.type, 'month');
});
});

describe('attr', function() {
Expand Down
23 changes: 23 additions & 0 deletions test/core/base/virtual-node/virtual-node.js
Expand Up @@ -39,6 +39,29 @@ 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 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'
Expand Down

0 comments on commit f6b3484

Please sign in to comment.