react 0.14.0-alpha3 → 0.14.0-beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/README.md +5 -2
  2. package/addons.js +2 -2
  3. package/dist/JSXTransformer.js +69 -70
  4. package/dist/react-with-addons.js +2047 -2078
  5. package/dist/react-with-addons.min.js +6 -6
  6. package/dist/react.js +1861 -1904
  7. package/dist/react.min.js +5 -5
  8. package/lib/{AutoFocusMixin.js → AutoFocusUtils.js} +13 -3
  9. package/lib/ChangeEventPlugin.js +4 -2
  10. package/lib/DOMProperty.js +81 -116
  11. package/lib/DOMPropertyOperations.js +70 -25
  12. package/lib/EnterLeaveEventPlugin.js +3 -3
  13. package/lib/EventPluginHub.js +2 -2
  14. package/lib/EventPluginUtils.js +6 -6
  15. package/lib/HTMLDOMPropertyConfig.js +8 -1
  16. package/lib/LinkedValueUtils.js +45 -33
  17. package/lib/PooledClass.js +12 -0
  18. package/lib/React.js +1 -1
  19. package/lib/ReactCSSTransitionGroupChild.js +8 -0
  20. package/lib/ReactChildren.js +3 -3
  21. package/lib/ReactClass.js +29 -47
  22. package/lib/ReactComponent.js +11 -6
  23. package/lib/ReactComponentWithPureRenderMixin.js +2 -2
  24. package/lib/ReactCompositeComponent.js +45 -72
  25. package/lib/ReactDOM.js +1 -0
  26. package/lib/ReactDOMButton.js +15 -26
  27. package/lib/ReactDOMClient.js +9 -4
  28. package/lib/ReactDOMComponent.js +302 -24
  29. package/lib/ReactDOMIDOperations.js +14 -0
  30. package/lib/ReactDOMInput.js +78 -94
  31. package/lib/ReactDOMOption.js +19 -38
  32. package/lib/ReactDOMSelect.js +85 -95
  33. package/lib/ReactDOMTextarea.js +39 -52
  34. package/lib/ReactDefaultInjection.js +0 -47
  35. package/lib/ReactElement.js +18 -79
  36. package/lib/ReactElementValidator.js +29 -98
  37. package/lib/ReactErrorUtils.js +1 -1
  38. package/lib/ReactEventEmitterMixin.js +2 -3
  39. package/lib/ReactEventListener.js +43 -3
  40. package/lib/ReactFragment.js +12 -7
  41. package/lib/ReactInputSelection.js +4 -3
  42. package/lib/ReactInstanceHandles.js +3 -2
  43. package/lib/ReactMount.js +20 -40
  44. package/lib/ReactNativeComponent.js +0 -5
  45. package/lib/ReactNoopUpdateQueue.js +118 -0
  46. package/lib/ReactPropTypes.js +3 -3
  47. package/lib/ReactReconcileTransaction.js +2 -2
  48. package/lib/ReactReconciler.js +8 -10
  49. package/lib/ReactServerBatchingStrategy.js +23 -0
  50. package/lib/ReactServerRendering.js +13 -0
  51. package/lib/ReactServerRenderingTransaction.js +2 -2
  52. package/lib/ReactTestUtils.js +56 -33
  53. package/lib/ReactUpdateQueue.js +51 -26
  54. package/lib/ReactUpdates.js +0 -3
  55. package/lib/ReactWithAddons.js +0 -2
  56. package/lib/SelectEventPlugin.js +6 -7
  57. package/lib/SimpleEventPlugin.js +4 -4
  58. package/lib/SyntheticClipboardEvent.js +2 -2
  59. package/lib/SyntheticCompositionEvent.js +2 -2
  60. package/lib/SyntheticDragEvent.js +2 -2
  61. package/lib/SyntheticEvent.js +6 -5
  62. package/lib/SyntheticFocusEvent.js +2 -2
  63. package/lib/SyntheticInputEvent.js +2 -2
  64. package/lib/SyntheticKeyboardEvent.js +2 -2
  65. package/lib/SyntheticMouseEvent.js +2 -2
  66. package/lib/SyntheticTouchEvent.js +2 -2
  67. package/lib/SyntheticUIEvent.js +2 -2
  68. package/lib/SyntheticWheelEvent.js +2 -2
  69. package/lib/Transaction.js +10 -4
  70. package/lib/cloneWithProps.js +1 -1
  71. package/lib/deprecated.js +47 -0
  72. package/lib/findDOMNode.js +2 -3
  73. package/lib/forEachAccumulated.js +1 -1
  74. package/lib/getEventCharCode.js +1 -1
  75. package/lib/getEventModifierState.js +0 -1
  76. package/lib/getMarkupWrap.js +13 -35
  77. package/lib/instantiateReactComponent.js +13 -9
  78. package/lib/isTextInputElement.js +2 -1
  79. package/lib/joinClasses.js +1 -1
  80. package/lib/setInnerHTML.js +1 -1
  81. package/lib/traverseAllChildren.js +1 -1
  82. package/lib/warning.js +0 -4
  83. package/package.json +1 -1
  84. package/react.js +53 -1
  85. package/addons/CSSTransitionGroup.js +0 -1
  86. package/addons/LinkedStateMixin.js +0 -1
  87. package/addons/Perf.js +0 -1
  88. package/addons/PureRenderMixin.js +0 -1
  89. package/addons/TestUtils.js +0 -1
  90. package/addons/TransitionGroup.js +0 -1
  91. package/addons/batchedUpdates.js +0 -1
  92. package/addons/cloneWithProps.js +0 -1
  93. package/addons/createFragment.js +0 -1
  94. package/addons/renderSubtreeIntoContainer.js +0 -1
  95. package/addons/shallowCompare.js +0 -1
  96. package/addons/update.js +0 -1
  97. package/lib/LocalEventTrapMixin.js +0 -46
  98. package/lib/ReactContext.js +0 -32
  99. package/lib/ReactDOMForm.js +0 -47
  100. package/lib/ReactDOMIframe.js +0 -43
  101. package/lib/ReactDOMImg.js +0 -44
  102. package/lib/ReactLifeCycle.js +0 -35
  103. package/lib/createFullPageComponent.js +0 -51
@@ -11,26 +11,18 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- var AutoFocusMixin = require("./AutoFocusMixin");
15
- var DOMPropertyOperations = require("./DOMPropertyOperations");
16
14
  var LinkedValueUtils = require("./LinkedValueUtils");
17
- var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
18
- var ReactClass = require("./ReactClass");
19
- var ReactElement = require("./ReactElement");
15
+ var ReactDOMIDOperations = require("./ReactDOMIDOperations");
20
16
  var ReactUpdates = require("./ReactUpdates");
21
17
 
22
18
  var assign = require("./Object.assign");
23
- var findDOMNode = require("./findDOMNode");
24
19
  var invariant = require("./invariant");
25
-
26
20
  var warning = require("./warning");
27
21
 
28
- var textarea = ReactElement.createFactory('textarea');
29
-
30
22
  function forceUpdateIfMounted() {
31
- /*jshint validthis:true */
32
- if (this.isMounted()) {
33
- this.forceUpdate();
23
+ if (this._rootNodeID) {
24
+ // DOM component is still mounted; update
25
+ ReactDOMTextarea.updateWrapper(this);
34
26
  }
35
27
  }
36
28
 
@@ -49,16 +41,28 @@ function forceUpdateIfMounted() {
49
41
  * The rendered element will be initialized with an empty value, the prop
50
42
  * `defaultValue` if specified, or the children content (deprecated).
51
43
  */
52
- var ReactDOMTextarea = ReactClass.createClass({
53
- displayName: 'ReactDOMTextarea',
54
- tagName: 'TEXTAREA',
44
+ var ReactDOMTextarea = {
45
+ getNativeProps: function (inst, props, context) {
46
+ !(props.dangerouslySetInnerHTML == null) ? 'production' !== process.env.NODE_ENV ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : invariant(false) : undefined;
47
+
48
+ // Always set children to the same thing. In IE9, the selection range will
49
+ // get reset if `textContent` is mutated.
50
+ var nativeProps = assign({}, props, {
51
+ defaultValue: undefined,
52
+ value: undefined,
53
+ children: inst._wrapperState.initialValue,
54
+ onChange: inst._wrapperState.onChange
55
+ });
56
+
57
+ return nativeProps;
58
+ },
55
59
 
56
- mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
60
+ mountWrapper: function (inst, props) {
61
+ LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner);
57
62
 
58
- getInitialState: function () {
59
- var defaultValue = this.props.defaultValue;
63
+ var defaultValue = props.defaultValue;
60
64
  // TODO (yungsters): Remove support for children content in <textarea>.
61
- var children = this.props.children;
65
+ var children = props.children;
62
66
  if (children != null) {
63
67
  if ('production' !== process.env.NODE_ENV) {
64
68
  'production' !== process.env.NODE_ENV ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : undefined;
@@ -74,51 +78,34 @@ var ReactDOMTextarea = ReactClass.createClass({
74
78
  if (defaultValue == null) {
75
79
  defaultValue = '';
76
80
  }
77
- var value = LinkedValueUtils.getValue(this.props);
78
- return {
81
+ var value = LinkedValueUtils.getValue(props);
82
+
83
+ inst._wrapperState = {
79
84
  // We save the initial value so that `ReactDOMComponent` doesn't update
80
85
  // `textContent` (unnecessary since we update value).
81
86
  // The initial value can be a boolean or object so that's why it's
82
87
  // forced to be a string.
83
- initialValue: '' + (value != null ? value : defaultValue)
88
+ initialValue: '' + (value != null ? value : defaultValue),
89
+ onChange: _handleChange.bind(inst)
84
90
  };
85
91
  },
86
92
 
87
- render: function () {
88
- // Clone `this.props` so we don't mutate the input.
89
- var props = assign({}, this.props);
90
-
91
- !(props.dangerouslySetInnerHTML == null) ? 'production' !== process.env.NODE_ENV ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : invariant(false) : undefined;
92
-
93
- props.defaultValue = null;
94
- props.value = null;
95
- props.onChange = this._handleChange;
96
-
97
- // Always set children to the same thing. In IE9, the selection range will
98
- // get reset if `textContent` is mutated.
99
- return textarea(props, this.state.initialValue);
100
- },
101
-
102
- componentDidUpdate: function (prevProps, prevState, prevContext) {
103
- var value = LinkedValueUtils.getValue(this.props);
93
+ updateWrapper: function (inst) {
94
+ var props = inst._currentElement.props;
95
+ var value = LinkedValueUtils.getValue(props);
104
96
  if (value != null) {
105
- var rootNode = findDOMNode(this);
106
97
  // Cast `value` to a string to ensure the value is set correctly. While
107
98
  // browsers typically do this as necessary, jsdom doesn't.
108
- DOMPropertyOperations.setValueForProperty(rootNode, 'value', '' + value);
99
+ ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value);
109
100
  }
110
- },
111
-
112
- _handleChange: function (event) {
113
- var returnValue;
114
- var onChange = LinkedValueUtils.getOnChange(this.props);
115
- if (onChange) {
116
- returnValue = onChange.call(this, event);
117
- }
118
- ReactUpdates.asap(forceUpdateIfMounted, this);
119
- return returnValue;
120
101
  }
102
+ };
121
103
 
122
- });
104
+ function _handleChange(event) {
105
+ var props = this._currentElement.props;
106
+ var returnValue = LinkedValueUtils.executeOnChange(props, event);
107
+ ReactUpdates.asap(forceUpdateIfMounted, this);
108
+ return returnValue;
109
+ }
123
110
 
124
111
  module.exports = ReactDOMTextarea;
@@ -19,25 +19,14 @@ var EnterLeaveEventPlugin = require("./EnterLeaveEventPlugin");
19
19
  var ExecutionEnvironment = require("./ExecutionEnvironment");
20
20
  var HTMLDOMPropertyConfig = require("./HTMLDOMPropertyConfig");
21
21
  var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
22
- var ReactClass = require("./ReactClass");
23
22
  var ReactComponentBrowserEnvironment = require("./ReactComponentBrowserEnvironment");
24
23
  var ReactDefaultBatchingStrategy = require("./ReactDefaultBatchingStrategy");
25
24
  var ReactDOMComponent = require("./ReactDOMComponent");
26
- var ReactDOMButton = require("./ReactDOMButton");
27
- var ReactDOMForm = require("./ReactDOMForm");
28
- var ReactDOMImg = require("./ReactDOMImg");
29
25
  var ReactDOMIDOperations = require("./ReactDOMIDOperations");
30
- var ReactDOMIframe = require("./ReactDOMIframe");
31
- var ReactDOMInput = require("./ReactDOMInput");
32
- var ReactDOMOption = require("./ReactDOMOption");
33
- var ReactDOMSelect = require("./ReactDOMSelect");
34
- var ReactDOMTextarea = require("./ReactDOMTextarea");
35
26
  var ReactDOMTextComponent = require("./ReactDOMTextComponent");
36
- var ReactElement = require("./ReactElement");
37
27
  var ReactEventListener = require("./ReactEventListener");
38
28
  var ReactInjection = require("./ReactInjection");
39
29
  var ReactInstanceHandles = require("./ReactInstanceHandles");
40
- var ReactInstanceMap = require("./ReactInstanceMap");
41
30
  var ReactMount = require("./ReactMount");
42
31
  var ReactReconcileTransaction = require("./ReactReconcileTransaction");
43
32
  var SelectEventPlugin = require("./SelectEventPlugin");
@@ -45,23 +34,6 @@ var ServerReactRootIndex = require("./ServerReactRootIndex");
45
34
  var SimpleEventPlugin = require("./SimpleEventPlugin");
46
35
  var SVGDOMPropertyConfig = require("./SVGDOMPropertyConfig");
47
36
 
48
- var createFullPageComponent = require("./createFullPageComponent");
49
-
50
- function autoGenerateWrapperClass(type) {
51
- return ReactClass.createClass({
52
- tagName: type.toUpperCase(),
53
- render: function () {
54
- // Copy owner down for debugging info
55
- var internalInstance = ReactInstanceMap.get(this);
56
- return new ReactElement(type, null, // key
57
- null, // ref
58
- internalInstance._currentElement._owner, // owner
59
- null, // context
60
- this.props);
61
- }
62
- });
63
- }
64
-
65
37
  var alreadyInjected = false;
66
38
 
67
39
  function inject() {
@@ -98,27 +70,8 @@ function inject() {
98
70
 
99
71
  ReactInjection.NativeComponent.injectTextComponentClass(ReactDOMTextComponent);
100
72
 
101
- ReactInjection.NativeComponent.injectAutoWrapper(autoGenerateWrapperClass);
102
-
103
- // This needs to happen before createFullPageComponent() otherwise the mixin
104
- // won't be included.
105
73
  ReactInjection.Class.injectMixin(ReactBrowserComponentMixin);
106
74
 
107
- ReactInjection.NativeComponent.injectComponentClasses({
108
- 'button': ReactDOMButton,
109
- 'form': ReactDOMForm,
110
- 'iframe': ReactDOMIframe,
111
- 'img': ReactDOMImg,
112
- 'input': ReactDOMInput,
113
- 'option': ReactDOMOption,
114
- 'select': ReactDOMSelect,
115
- 'textarea': ReactDOMTextarea,
116
-
117
- 'html': createFullPageComponent('html'),
118
- 'head': createFullPageComponent('head'),
119
- 'body': createFullPageComponent('body')
120
- });
121
-
122
75
  ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
123
76
  ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);
124
77
 
@@ -11,79 +11,27 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- var ReactContext = require("./ReactContext");
15
14
  var ReactCurrentOwner = require("./ReactCurrentOwner");
16
15
 
17
16
  var assign = require("./Object.assign");
18
- var warning = require("./warning");
19
17
 
20
18
  var RESERVED_PROPS = {
21
19
  key: true,
22
20
  ref: true
23
21
  };
24
22
 
25
- /**
26
- * Warn for mutations.
27
- *
28
- * @internal
29
- * @param {object} object
30
- * @param {string} key
31
- */
32
- function defineWarningProperty(object, key) {
33
- Object.defineProperty(object, key, {
34
-
35
- configurable: false,
36
- enumerable: true,
37
-
38
- get: function () {
39
- if (!this._store) {
40
- return null;
41
- }
42
- return this._store[key];
43
- },
44
-
45
- set: function (value) {
46
- 'production' !== process.env.NODE_ENV ? warning(false, 'Don\'t set the %s property of the React element. Instead, ' + 'specify the correct value when initially creating the element.', key) : undefined;
47
- this._store[key] = value;
48
- }
49
-
50
- });
51
- }
52
-
53
- /**
54
- * This is updated to true if the membrane is successfully created.
55
- */
56
- var useMutationMembrane = false;
57
-
58
- /**
59
- * Warn for mutations.
60
- *
61
- * @internal
62
- * @param {object} element
63
- */
64
- function defineMutationMembrane(prototype) {
65
- try {
66
- var pseudoFrozenProperties = {
67
- props: true
68
- };
69
- for (var key in pseudoFrozenProperties) {
70
- defineWarningProperty(prototype, key);
71
- }
72
- useMutationMembrane = true;
73
- } catch (x) {}
74
- }
75
-
76
23
  /**
77
24
  * Base constructor for all React elements. This is only used to make this
78
25
  * work with a dynamic instanceof check. Nothing should live on this prototype.
79
26
  *
80
27
  * @param {*} type
81
- * @param {string|object} ref
82
28
  * @param {*} key
29
+ * @param {string|object} ref
30
+ * @param {*} owner
83
31
  * @param {*} props
84
32
  * @internal
85
33
  */
86
- var ReactElement = function (type, key, ref, owner, context, props) {
34
+ var ReactElement = function (type, key, ref, owner, props) {
87
35
  // Built-in properties that belong on the element
88
36
  this.type = type;
89
37
  this.key = key;
@@ -92,12 +40,14 @@ var ReactElement = function (type, key, ref, owner, context, props) {
92
40
  // Record the component responsible for creating this element.
93
41
  this._owner = owner;
94
42
 
43
+ this.props = props;
44
+
95
45
  if ('production' !== process.env.NODE_ENV) {
96
- // The validation flag and props are currently mutative. We put them on
46
+ // The validation flag is currently mutative. We put it on
97
47
  // an external backing store so that we can freeze the whole object.
98
48
  // This can be replaced with a WeakMap once they are implemented in
99
49
  // commonly used development environments.
100
- this._store = { props: props, originalProps: assign({}, props) };
50
+ this._store = {};
101
51
 
102
52
  // To make comparing ReactElements easier for testing purposes, we make
103
53
  // the validation flag non-enumerable (where possible, which should
@@ -107,21 +57,15 @@ var ReactElement = function (type, key, ref, owner, context, props) {
107
57
  Object.defineProperty(this._store, 'validated', {
108
58
  configurable: false,
109
59
  enumerable: false,
110
- writable: true
60
+ writable: true,
61
+ value: false
111
62
  });
112
- } catch (x) {}
113
- this._store.validated = false;
114
-
115
- // We're not allowed to set props directly on the object so we early
116
- // return and rely on the prototype membrane to forward to the backing
117
- // store.
118
- if (useMutationMembrane) {
119
- Object.freeze(this);
120
- return;
63
+ } catch (x) {
64
+ this._store.validated = false;
121
65
  }
66
+ Object.freeze(this.props);
67
+ Object.freeze(this);
122
68
  }
123
-
124
- this.props = props;
125
69
  };
126
70
 
127
71
  // We intentionally don't expose the function on the constructor property.
@@ -130,10 +74,6 @@ ReactElement.prototype = {
130
74
  _isReactElement: true
131
75
  };
132
76
 
133
- if ('production' !== process.env.NODE_ENV) {
134
- defineMutationMembrane(ReactElement.prototype);
135
- }
136
-
137
77
  ReactElement.createElement = function (type, config, children) {
138
78
  var propName;
139
79
 
@@ -177,7 +117,7 @@ ReactElement.createElement = function (type, config, children) {
177
117
  }
178
118
  }
179
119
 
180
- return new ReactElement(type, key, ref, ReactCurrentOwner.current, ReactContext.current, props);
120
+ return new ReactElement(type, key, ref, ReactCurrentOwner.current, props);
181
121
  };
182
122
 
183
123
  ReactElement.createFactory = function (type) {
@@ -192,12 +132,13 @@ ReactElement.createFactory = function (type) {
192
132
  };
193
133
 
194
134
  ReactElement.cloneAndReplaceProps = function (oldElement, newProps) {
195
- var newElement = new ReactElement(oldElement.type, oldElement.key, oldElement.ref, oldElement._owner, oldElement._context, newProps);
135
+ var newElement = new ReactElement(oldElement.type, oldElement.key, oldElement.ref, oldElement._owner, newProps);
196
136
 
197
137
  if ('production' !== process.env.NODE_ENV) {
198
138
  // If the key on the original is valid, then the clone is valid
199
139
  newElement._store.validated = oldElement._store.validated;
200
140
  }
141
+
201
142
  return newElement;
202
143
  };
203
144
 
@@ -244,7 +185,7 @@ ReactElement.cloneElement = function (element, config, children) {
244
185
  props.children = childArray;
245
186
  }
246
187
 
247
- return new ReactElement(element.type, key, ref, owner, element._context, props);
188
+ return new ReactElement(element.type, key, ref, owner, props);
248
189
  };
249
190
 
250
191
  /**
@@ -266,6 +207,4 @@ ReactElement.isValidElement = function (object) {
266
207
  return isElement;
267
208
  };
268
209
 
269
- module.exports = ReactElement;
270
-
271
- // IE will fail on defineProperty
210
+ module.exports = ReactElement;
@@ -23,7 +23,6 @@ var ReactFragment = require("./ReactFragment");
23
23
  var ReactPropTypeLocations = require("./ReactPropTypeLocations");
24
24
  var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
25
25
  var ReactCurrentOwner = require("./ReactCurrentOwner");
26
- var ReactNativeComponent = require("./ReactNativeComponent");
27
26
 
28
27
  var getIteratorFn = require("./getIteratorFn");
29
28
  var invariant = require("./invariant");
@@ -95,7 +94,12 @@ function validateExplicitKey(element, parentType) {
95
94
  }
96
95
  element._store.validated = true;
97
96
 
98
- warnAndMonitorForKeyUse('Each child in an array or iterator should have a unique "key" prop.', element, parentType);
97
+ var addenda = getAddendaForKeyUse('uniqueKey', element, parentType);
98
+ if (addenda === null) {
99
+ // we already showed the warning
100
+ return;
101
+ }
102
+ 'production' !== process.env.NODE_ENV ? warning(false, 'Each child in an array or iterator should have a unique "key" prop.' + '%s%s%s', addenda.parentOrOwner || '', addenda.childOwner || '', addenda.url || '') : undefined;
99
103
  }
100
104
 
101
105
  /**
@@ -111,42 +115,50 @@ function validatePropertyKey(name, element, parentType) {
111
115
  if (!NUMERIC_PROPERTY_REGEX.test(name)) {
112
116
  return;
113
117
  }
114
- warnAndMonitorForKeyUse('Child objects should have non-numeric keys so ordering is preserved.', element, parentType);
118
+ var addenda = getAddendaForKeyUse('numericKeys', element, parentType);
119
+ if (addenda === null) {
120
+ // we already showed the warning
121
+ return;
122
+ }
123
+ 'production' !== process.env.NODE_ENV ? warning(false, 'Child objects should have non-numeric keys so ordering is preserved.' + '%s%s%s', addenda.parentOrOwner || '', addenda.childOwner || '', addenda.url || '') : undefined;
115
124
  }
116
125
 
117
126
  /**
118
127
  * Shared warning and monitoring code for the key warnings.
119
128
  *
120
129
  * @internal
121
- * @param {string} message The base warning that gets output.
130
+ * @param {string} messageType A key used for de-duping warnings.
122
131
  * @param {ReactElement} element Component that requires a key.
123
132
  * @param {*} parentType element's parent's type.
133
+ * @returns {?object} A set of addenda to use in the warning message, or null
134
+ * if the warning has already been shown before (and shouldn't be shown again).
124
135
  */
125
- function warnAndMonitorForKeyUse(message, element, parentType) {
136
+ function getAddendaForKeyUse(messageType, element, parentType) {
126
137
  var ownerName = getCurrentOwnerDisplayName();
127
138
  var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
128
139
 
129
140
  var useName = ownerName || parentName;
130
- var memoizer = ownerHasKeyUseWarning[message] || (ownerHasKeyUseWarning[message] = {});
131
- if (memoizer.hasOwnProperty(useName)) {
132
- return;
141
+ var memoizer = ownerHasKeyUseWarning[messageType] || (ownerHasKeyUseWarning[messageType] = {});
142
+ if (memoizer[useName]) {
143
+ return null;
133
144
  }
134
145
  memoizer[useName] = true;
135
146
 
136
- var parentOrOwnerAddendum = ownerName ? ' Check the render method of ' + ownerName + '.' : parentName ? ' Check the React.render call using <' + parentName + '>.' : '';
147
+ var addenda = {
148
+ parentOrOwner: ownerName ? ' Check the render method of ' + ownerName + '.' : parentName ? ' Check the React.render call using <' + parentName + '>.' : null,
149
+ url: ' See https://fb.me/react-warning-keys for more information.',
150
+ childOwner: null
151
+ };
137
152
 
138
153
  // Usually the current owner is the offender, but if it accepts children as a
139
154
  // property, it may be the creator of the child that's responsible for
140
155
  // assigning it a key.
141
- var childOwnerAddendum = '';
142
156
  if (element && element._owner && element._owner !== ReactCurrentOwner.current) {
143
- // Name of the component that originally created this child.
144
- var childOwnerName = getName(element._owner);
145
-
146
- childOwnerAddendum = ' It was passed a child from ' + childOwnerName + '.';
157
+ // Give the component that originally created this child.
158
+ addenda.childOwner = ' It was passed a child from ' + getName(element._owner) + '.';
147
159
  }
148
160
 
149
- 'production' !== process.env.NODE_ENV ? warning(false, message + '%s%s See https://fb.me/react-warning-keys for more information.', parentOrOwnerAddendum, childOwnerAddendum) : undefined;
161
+ return addenda;
150
162
  }
151
163
 
152
164
  /**
@@ -230,80 +242,6 @@ function checkPropTypes(componentName, propTypes, props, location) {
230
242
  }
231
243
  }
232
244
 
233
- var warnedPropsMutations = {};
234
-
235
- /**
236
- * Warn about mutating props when setting `propName` on `element`.
237
- *
238
- * @param {string} propName The string key within props that was set
239
- * @param {ReactElement} element
240
- */
241
- function warnForPropsMutation(propName, element) {
242
- var type = element.type;
243
- var elementName = typeof type === 'string' ? type : type.displayName;
244
- var ownerName = element._owner ? element._owner.getPublicInstance().constructor.displayName : null;
245
-
246
- var warningKey = propName + '|' + elementName + '|' + ownerName;
247
- if (warnedPropsMutations.hasOwnProperty(warningKey)) {
248
- return;
249
- }
250
- warnedPropsMutations[warningKey] = true;
251
-
252
- var elementInfo = '';
253
- if (elementName) {
254
- elementInfo = ' <' + elementName + ' />';
255
- }
256
- var ownerInfo = '';
257
- if (ownerName) {
258
- ownerInfo = ' The element was created by ' + ownerName + '.';
259
- }
260
-
261
- 'production' !== process.env.NODE_ENV ? warning(false, 'Don\'t set .props.%s of the React component%s. Instead, specify the ' + 'correct value when initially creating the element or use ' + 'React.cloneElement to make a new element with updated props.%s', propName, elementInfo, ownerInfo) : undefined;
262
- }
263
-
264
- // Inline Object.is polyfill
265
- function is(a, b) {
266
- if (a !== a) {
267
- // NaN
268
- return b !== b;
269
- }
270
- if (a === 0 && b === 0) {
271
- // +-0
272
- return 1 / a === 1 / b;
273
- }
274
- return a === b;
275
- }
276
-
277
- /**
278
- * Given an element, check if its props have been mutated since element
279
- * creation (or the last call to this function). In particular, check if any
280
- * new props have been added, which we can't directly catch by defining warning
281
- * properties on the props object.
282
- *
283
- * @param {ReactElement} element
284
- */
285
- function checkAndWarnForMutatedProps(element) {
286
- if (!element._store) {
287
- // Element was created using `new ReactElement` directly or with
288
- // `ReactElement.createElement`; skip mutation checking
289
- return;
290
- }
291
-
292
- var originalProps = element._store.originalProps;
293
- var props = element.props;
294
-
295
- for (var propName in props) {
296
- if (props.hasOwnProperty(propName)) {
297
- if (!originalProps.hasOwnProperty(propName) || !is(originalProps[propName], props[propName])) {
298
- warnForPropsMutation(propName, element);
299
-
300
- // Copy over the new value so that the two props objects match again
301
- originalProps[propName] = props[propName];
302
- }
303
- }
304
- }
305
- }
306
-
307
245
  /**
308
246
  * Given an element, validate that its props follow the propTypes definition,
309
247
  * provided by the type.
@@ -311,15 +249,10 @@ function checkAndWarnForMutatedProps(element) {
311
249
  * @param {ReactElement} element
312
250
  */
313
251
  function validatePropTypes(element) {
314
- if (!(typeof element.type === 'string' || typeof element.type === 'function')) {
315
- // This has already warned. Don't throw.
252
+ var componentClass = element.type;
253
+ if (typeof componentClass !== 'function') {
316
254
  return;
317
255
  }
318
- // Extract the component class from the element. Converts string types
319
- // to a composite class which may have propTypes.
320
- // TODO: Validating a string's propTypes is not decoupled from the
321
- // rendering target which is problematic.
322
- var componentClass = ReactNativeComponent.getComponentClassForElement(element);
323
256
  var name = componentClass.displayName || componentClass.name;
324
257
  if (componentClass.propTypes) {
325
258
  checkPropTypes(name, componentClass.propTypes, element.props, ReactPropTypeLocations.prop);
@@ -331,8 +264,6 @@ function validatePropTypes(element) {
331
264
 
332
265
  var ReactElementValidator = {
333
266
 
334
- checkAndWarnForMutatedProps: checkAndWarnForMutatedProps,
335
-
336
267
  createElement: function (type, props, children) {
337
268
  // We warn in this case but don't throw. We expect the element creation to
338
269
  // succeed and there will likely be errors in render.