diff --git a/src/browser/ui/ReactDOMComponent.js b/src/browser/ui/ReactDOMComponent.js
index fbeee7e8fe62c..0bf886a7a57c9 100644
--- a/src/browser/ui/ReactDOMComponent.js
+++ b/src/browser/ui/ReactDOMComponent.js
@@ -18,6 +18,7 @@ var CSSPropertyOperations = require('CSSPropertyOperations');
var DOMProperty = require('DOMProperty');
var DOMPropertyOperations = require('DOMPropertyOperations');
var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');
+var ReactChildren = require('ReactChildren');
var ReactComponentBrowserEnvironment =
require('ReactComponentBrowserEnvironment');
var ReactMount = require('ReactMount');
@@ -232,6 +233,26 @@ function processChildContext(context, tagName) {
return context;
}
+var onlyNestTextTags = {
+ 'option': true
+};
+
+function getChildrenTextContent(tag, children) {
+ var childrenContent = '';
+ ReactChildren.forEach(children, function (c) {
+ var childType = typeof c;
+ if (childType !== 'string' && childType !== 'number') {
+ // not null/undefined/boolean
+ if (c !== null) {
+ warning(false, '%s can not have complex children/content', tag);
+ }
+ } else {
+ childrenContent += c;
+ }
+ });
+ return childrenContent;
+}
+
/**
* Creates a new React class that is idempotent and capable of containing other
* React components. It accepts event listeners and DOM properties that are
@@ -369,6 +390,10 @@ ReactDOMComponent.Mixin = {
ret = innerHTML.__html;
}
} else {
+ if (onlyNestTextTags[this._tag]) {
+ var childrenContent = getChildrenTextContent(this._tag, props.children);
+ return escapeTextContentForBrowser(childrenContent);
+ }
var contentToUse =
CONTENT_TYPES[typeof props.children] ? props.children : null;
var childrenToUse = contentToUse != null ? null : props.children;
@@ -567,6 +592,11 @@ ReactDOMComponent.Mixin = {
var nextContent =
CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
+ if (onlyNestTextTags[this._tag]) {
+ lastContent = getChildrenTextContent(this._tag, lastProps.children);
+ nextContent = getChildrenTextContent(this._tag, nextProps.children);
+ }
+
var lastHtml =
lastProps.dangerouslySetInnerHTML &&
lastProps.dangerouslySetInnerHTML.__html;
diff --git a/src/browser/ui/__tests__/ReactDOMComponent-test.js b/src/browser/ui/__tests__/ReactDOMComponent-test.js
index e8c776a4803b3..38176532515d2 100644
--- a/src/browser/ui/__tests__/ReactDOMComponent-test.js
+++ b/src/browser/ui/__tests__/ReactDOMComponent-test.js
@@ -775,4 +775,36 @@ describe('ReactDOMComponent', function() {
});
});
+ describe('option update', function(){
+ var container;
+
+ beforeEach(() => {
+ container = document.createElement('div');
+ React.render(, container);
+ });
+
+ it('supports number update', () => {
+ React.render(, container);
+ expect(container.firstChild.firstChild.innerHTML).toEqual('20$');
+ });
+
+ it('supports string update', () => {
+ React.render(, container);
+ expect(container.firstChild.firstChild.innerHTML).toEqual('20$');
+ });
+
+ it('supports boolean update', () => {
+ React.render(, container);
+ expect(container.firstChild.firstChild.innerHTML).toEqual('20$');
+ React.render(, container);
+ expect(container.firstChild.firstChild.innerHTML).toEqual('$');
+ });
+
+ it('supports null/undefined update', () => {
+ React.render(, container);
+ expect(container.firstChild.firstChild.innerHTML).toEqual('$');
+ React.render(, container);
+ expect(container.firstChild.firstChild.innerHTML).toEqual('$');
+ });
+ });
});