<option> added children flatten, & warn if invalid
Matthias Le Brun committed
May 9, 2015 at 01:19 UTC
4a012b07417354992be465dd593f84aaadb96d9b
2 files changed
+85
-1
src/browser/ui/dom/components/ReactDOMOption.js
+20
-1
@@ -12,6 +12,7 @@
12
'use strict';
13
14
var ReactBrowserComponentMixin = require('ReactBrowserComponentMixin');
15
+var ReactChildren = require('ReactChildren');
16
var ReactClass = require('ReactClass');
17
var ReactDOMSelect = require('ReactDOMSelect');
18
var ReactElement = require('ReactElement');
@@ -86,7 +87,25 @@ var ReactDOMOption = ReactClass.createClass({
87
props = assign({}, props, {selected: this.state.selected});
88
}
89
89
- return option(props, this.props.children);
90
+ var content = '';
91
+
92
+ // Flatten children and warn if they aren't strings or numbers;
93
+ // invalid types are ignored.
94
+ ReactChildren.forEach(this.props.children, function(child) {
95
+ if (child == null) {
96
+ return;
97
+ }
98
+ if (typeof child === 'string' || typeof child === 'number') {
99
+ content += child;
100
+ } else {
101
+ warning(
102
+ false,
103
+ 'Only strings and numbers are supported as <option> children.'
104
+ );
105
+ }
106
+ });
107
+
108
+ return option(props, content);
109
}
110
111
});
src/browser/ui/dom/components/__tests__/ReactDOMOption-test.js
new
+65
@@ -0,0 +1,65 @@
1
+/**
2
+ * Copyright 2013-2015, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @emails react-core
10
+ */
11
+
12
+'use strict';
13
+
14
+/*jshint evil:true */
15
+
16
+describe('ReactDOMOption', function() {
17
+ var React;
18
+ var ReactTestUtils;
19
+
20
+ beforeEach(function() {
21
+ React = require('React');
22
+ ReactTestUtils = require('ReactTestUtils');
23
+ });
24
+
25
+ it('should flatten children to a string', function() {
26
+ var stub = <option>{1} {'foo'}</option>;
27
+ stub = ReactTestUtils.renderIntoDocument(stub);
28
+ var node = React.findDOMNode(stub);
29
+
30
+ expect(node.innerHTML).toBe('1 foo');
31
+ });
32
+
33
+ it('should ignore invalid children types', function() {
34
+ var stub = <option>{1} <div /> {2}</option>;
35
+ stub = ReactTestUtils.renderIntoDocument(stub);
36
+ var node = React.findDOMNode(stub);
37
+
38
+ expect(node.innerHTML).toBe('1 2');
39
+ });
40
+
41
+ it('should warn when passing invalid children', function() {
42
+ var stub = <option>{1} <div /></option>;
43
+ spyOn(console, 'error');
44
+ stub = ReactTestUtils.renderIntoDocument(stub);
45
+
46
+ var node = React.findDOMNode(stub);
47
+
48
+ expect(console.error.calls.length).toBe(1);
49
+ expect(console.error.calls[0].args[0]).toContain(
50
+ 'Only strings and numbers are supported as <option> children.'
51
+ );
52
+ });
53
+
54
+ it('should ignore null/undefined/false children without warning', function() {
55
+ var stub = <option>{1} {false}{true}{null}{undefined} {2}</option>;
56
+ spyOn(console, 'error');
57
+ stub = ReactTestUtils.renderIntoDocument(stub);
58
+
59
+ var node = React.findDOMNode(stub);
60
+
61
+ expect(console.error.calls.length).toBe(0);
62
+ expect(node.innerHTML).toBe('1 2');
63
+ });
64
+
65
+});