Set input .type before .value always

In IE11 (and below), if you run

```
var input = document.createElement('input');
input.value = 'wat';
input.type = 'radio';
console.log(input.value);
```

you get the string "on" logged. Because that makes sense.

So we set the type first.
This commit is contained in:
Ben Alpert
2015-12-23 15:34:48 -08:00
parent 0d5312559a
commit 07c0bc6166
2 changed files with 33 additions and 1 deletions
@@ -67,7 +67,11 @@ var ReactDOMInput = {
var value = LinkedValueUtils.getValue(props);
var checked = LinkedValueUtils.getChecked(props);
var nativeProps = assign({}, props, {
var nativeProps = assign({
// Make sure we set .type before any other properties (setting .value
// before .type means .value is lost in IE11 and below)
type: undefined,
}, props, {
defaultChecked: undefined,
defaultValue: undefined,
value: value != null ? value : inst._wrapperState.initialValue,
@@ -414,4 +414,32 @@ describe('ReactDOMInput', function() {
ReactTestUtils.renderIntoDocument(<input type="text" value={null} />);
expect(console.error.argsForCall.length).toBe(1);
});
it('sets type before value always', function() {
var log = [];
var originalCreateElement = document.createElement;
spyOn(document, 'createElement').andCallFake(function(type) {
var el = originalCreateElement.apply(this, arguments);
if (type === 'input') {
Object.defineProperty(el, 'value', {
get: function() {},
set: function() {
log.push('set value');
},
});
spyOn(el, 'setAttribute').andCallFake(function(name, value) {
log.push('set ' + name);
});
}
return el;
});
ReactTestUtils.renderIntoDocument(<input value="hi" type="radio" />);
// Setting value before type does bad things. Make sure we set type first.
expect(log).toEqual([
'set data-reactroot',
'set type',
'set value',
]);
});
});