diff --git a/src/renderers/dom/shared/ReactDOMComponent.js b/src/renderers/dom/shared/ReactDOMComponent.js index 21a43102300b4..f4a95edbe0259 100644 --- a/src/renderers/dom/shared/ReactDOMComponent.js +++ b/src/renderers/dom/shared/ReactDOMComponent.js @@ -53,9 +53,14 @@ var registrationNameModules = EventPluginRegistry.registrationNameModules; // For quickly matching children type, to test if can be treated as content. var CONTENT_TYPES = {'string': true, 'number': true}; -var CHILDREN = keyOf({children: null}); var STYLE = keyOf({style: null}); var HTML = keyOf({__html: null}); +var RESERVED_PROPS = { + children: null, + dangerouslySetInnerHTML: null, + suppressContentEditableWarning: null, +}; + function getDeclarationErrorAddendum(internalInstance) { if (internalInstance) { @@ -635,7 +640,7 @@ ReactDOMComponent.Mixin = { } var markup = null; if (this._tag != null && isCustomComponent(this._tag, props)) { - if (propKey !== CHILDREN) { + if (!RESERVED_PROPS.hasOwnProperty(propKey)) { markup = DOMPropertyOperations.createMarkupForCustomAttribute(propKey, propValue); } } else { @@ -907,14 +912,13 @@ ReactDOMComponent.Mixin = { deleteListener(this, propKey); } } else if (isCustomComponent(this._tag, nextProps)) { - if (propKey === CHILDREN) { - nextProp = null; + if (!RESERVED_PROPS.hasOwnProperty(propKey)) { + DOMPropertyOperations.setValueForAttribute( + getNode(this), + propKey, + nextProp + ); } - DOMPropertyOperations.setValueForAttribute( - getNode(this), - propKey, - nextProp - ); } else if ( DOMProperty.properties[propKey] || DOMProperty.isCustomAttribute(propKey)) { diff --git a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js index d349620b4711f..0fbbee1e17a9a 100644 --- a/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js +++ b/src/renderers/dom/shared/__tests__/ReactDOMComponent-test.js @@ -236,16 +236,52 @@ describe('ReactDOMComponent', function() { expect(stubStyle.display).toEqual(''); }); - it('should skip child object attribute on web components', function() { + it('should skip reserved props on web components', function() { var container = document.createElement('div'); - // Test initial render to null - ReactDOM.render(, container); + ReactDOM.render( + , + container + ); expect(container.firstChild.hasAttribute('children')).toBe(false); + expect( + container.firstChild.hasAttribute('suppressContentEditableWarning') + ).toBe(false); - // Test updates to null - ReactDOM.render(, container); + ReactDOM.render( + , + container + ); expect(container.firstChild.hasAttribute('children')).toBe(false); + expect( + container.firstChild.hasAttribute('suppressContentEditableWarning') + ).toBe(false); + }); + + it('should skip dangerouslySetInnerHTML on web components', function() { + var container = document.createElement('div'); + + ReactDOM.render( + , + container + ); + expect( + container.firstChild.hasAttribute('dangerouslySetInnerHTML') + ).toBe(false); + + ReactDOM.render( + , + container + ); + expect( + container.firstChild.hasAttribute('dangerouslySetInnerHTML') + ).toBe(false); }); it('should remove attributes', function() {