diff --git a/src/dom/DOMPropertyOperations.js b/src/dom/DOMPropertyOperations.js index f0165a6ce1..6f629d4083 100644 --- a/src/dom/DOMPropertyOperations.js +++ b/src/dom/DOMPropertyOperations.js @@ -109,7 +109,7 @@ var DOMPropertyOperations = { if (DOMProperty.hasBooleanValue[name] && !value) { node.removeAttribute(DOMProperty.getAttributeName[name]); } else { - node.setAttribute(DOMProperty.getAttributeName[name], value); + node.setAttribute(DOMProperty.getAttributeName[name], '' + value); } } else { var propName = DOMProperty.getPropertyName[name]; @@ -118,7 +118,7 @@ var DOMPropertyOperations = { } } } else if (DOMProperty.isCustomAttribute(name)) { - node.setAttribute(name, value); + node.setAttribute(name, '' + value); } else if (__DEV__) { warnUnknownProperty(name); } diff --git a/src/dom/__tests__/DOMPropertyOperations-test.js b/src/dom/__tests__/DOMPropertyOperations-test.js index 25adde6809..1c4b222b5e 100644 --- a/src/dom/__tests__/DOMPropertyOperations-test.js +++ b/src/dom/__tests__/DOMPropertyOperations-test.js @@ -132,6 +132,14 @@ describe('DOMPropertyOperations', function() { expect(stubNode.role).toBeUndefined(); }); + it('should convert attribute values to string first', function() { + // Browsers default to this behavior, but some test environments do not. + // This ensures that we have consistent behavior. + var obj = {toString: function() { return ''; }}; + DOMPropertyOperations.setValueForProperty(stubNode, 'role', obj); + expect(stubNode.getAttribute('role')).toBe(''); + }); + it('should remove for falsey boolean properties', function() { DOMPropertyOperations.setValueForProperty( stubNode,