Added checks for incorrect usage of innerHTML. Fixes #1370
Jim committed
Nov 13, 2014 at 14:51 UTC
aef7c4d1a16133f2f6d3ae3bfd18f01f8fc1403b
2 files changed
+47
-4
src/browser/ui/ReactDOMComponent.js
+17
-4
@@ -27,6 +27,7 @@ var invariant = require('invariant');
27
var isEventSupported = require('isEventSupported');
28
var keyOf = require('keyOf');
29
var monitorCodeUse = require('monitorCodeUse');
30
+var warning = require('warning');
31
32
var deleteListener = ReactBrowserEventEmitter.deleteListener;
33
var listenTo = ReactBrowserEventEmitter.listenTo;
@@ -52,11 +53,23 @@ function assertValidProps(props) {
53
return;
54
}
55
// Note the use of `==` which checks for null or undefined.
55
- invariant(
56
- props.children == null || props.dangerouslySetInnerHTML == null,
57
- 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
58
- );
56
+ if (props.dangerouslySetInnerHTML != null) {
57
+ invariant(
58
+ props.children == null,
59
+ 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
60
+ );
61
+ invariant(
62
+ props.dangerouslySetInnerHTML.__html != null,
63
+ '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
64
+ 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
65
+ );
66
+ }
67
if (__DEV__) {
68
+ warning(
69
+ props.innerHTML == null,
70
+ 'Directly setting property `innerHTML` is not permitted. ' +
71
+ 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
72
+ );
73
if (props.contentEditable && props.children != null) {
74
console.warn(
75
'A component is `contentEditable` and contains `children` managed by ' +
src/browser/ui/__tests__/ReactDOMComponent-test.js
+30
@@ -341,6 +341,36 @@ describe('ReactDOMComponent', function() {
341
);
342
});
343
344
+ it('should validate against use of innerHTML', function() {
345
+
346
+ spyOn(console, 'warn');
347
+ mountComponent({ innerHTML: '<span>Hi Jim!</span>' });
348
+ expect(console.warn.argsForCall.length).toBe(1);
349
+ expect(console.warn.argsForCall[0][0]).toContain(
350
+ 'Directly setting property `innerHTML` is not permitted. '
351
+ );
352
+ });
353
+
354
+ it('should validate use of dangerouslySetInnerHTML', function() {
355
+ expect(function() {
356
+ mountComponent({ dangerouslySetInnerHTML: '<span>Hi Jim!</span>' });
357
+ }).toThrow(
358
+ 'Invariant Violation: ' +
359
+ '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
360
+ 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
361
+ );
362
+ });
363
+
364
+ it('should validate use of dangerouslySetInnerHTML', function() {
365
+ expect(function() {
366
+ mountComponent({ dangerouslySetInnerHTML: {foo: 'bar'} });
367
+ }).toThrow(
368
+ 'Invariant Violation: ' +
369
+ '`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' +
370
+ 'For more information, lookup documentation on `dangerouslySetInnerHTML`.'
371
+ );
372
+ });
373
+
374
it("should warn about contentEditable and children", function() {
375
spyOn(console, 'warn');
376
mountComponent({ contentEditable: true, children: '' });