react 0.9.0 → 0.11.0

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 (114) hide show
  1. package/README.md +3 -0
  2. package/dist/JSXTransformer.js +13448 -0
  3. package/dist/react-with-addons.js +20235 -0
  4. package/dist/react-with-addons.min.js +22 -0
  5. package/dist/react.js +18443 -0
  6. package/dist/react.min.js +21 -0
  7. package/lib/AutoFocusMixin.js +3 -1
  8. package/lib/BeforeInputEventPlugin.js +222 -0
  9. package/lib/CSSPropertyOperations.js +3 -3
  10. package/lib/{ReactMountReady.js → CallbackQueue.js} +32 -24
  11. package/lib/ChangeEventPlugin.js +1 -1
  12. package/lib/CompositionEventPlugin.js +5 -1
  13. package/lib/DOMChildrenOperations.js +33 -20
  14. package/lib/DOMProperty.js +51 -21
  15. package/lib/DOMPropertyOperations.js +28 -16
  16. package/lib/DefaultEventPluginOrder.js +1 -0
  17. package/lib/EventConstants.js +1 -0
  18. package/lib/EventListener.js +5 -2
  19. package/lib/EventPluginHub.js +2 -5
  20. package/lib/EventPluginRegistry.js +6 -4
  21. package/lib/EventPluginUtils.js +11 -1
  22. package/lib/ExecutionEnvironment.js +8 -2
  23. package/lib/{DefaultDOMPropertyConfig.js → HTMLDOMPropertyConfig.js} +41 -58
  24. package/lib/LinkedValueUtils.js +26 -28
  25. package/lib/LocalEventTrapMixin.js +52 -0
  26. package/lib/React.js +39 -3
  27. package/lib/ReactBrowserComponentMixin.js +46 -0
  28. package/lib/{ReactEventEmitter.js → ReactBrowserEventEmitter.js} +115 -94
  29. package/lib/ReactCSSTransitionGroup.js +12 -10
  30. package/lib/ReactCSSTransitionGroupChild.js +2 -5
  31. package/lib/ReactChildren.js +31 -10
  32. package/lib/ReactComponent.js +119 -223
  33. package/lib/ReactComponentBrowserEnvironment.js +3 -36
  34. package/lib/ReactComponentWithPureRenderMixin.js +54 -0
  35. package/lib/ReactCompositeComponent.js +249 -287
  36. package/lib/ReactDOM.js +25 -23
  37. package/lib/ReactDOMButton.js +2 -1
  38. package/lib/ReactDOMComponent.js +42 -23
  39. package/lib/ReactDOMForm.js +7 -12
  40. package/lib/ReactDOMIDOperations.js +2 -31
  41. package/lib/ReactDOMImg.js +7 -13
  42. package/lib/ReactDOMInput.js +2 -1
  43. package/lib/ReactDOMOption.js +11 -7
  44. package/lib/ReactDOMSelect.js +18 -16
  45. package/lib/ReactDOMSelection.js +35 -10
  46. package/lib/ReactDOMTextarea.js +9 -7
  47. package/lib/ReactDefaultBatchingStrategy.js +3 -3
  48. package/lib/ReactDefaultInjection.js +27 -14
  49. package/lib/ReactDefaultPerf.js +28 -11
  50. package/lib/ReactDefaultPerfAnalysis.js +4 -0
  51. package/lib/ReactDescriptor.js +251 -0
  52. package/lib/ReactDescriptorValidator.js +283 -0
  53. package/lib/ReactEmptyComponent.js +78 -0
  54. package/lib/ReactEventEmitterMixin.js +1 -3
  55. package/lib/ReactEventListener.js +189 -0
  56. package/lib/ReactInjection.js +8 -2
  57. package/lib/ReactInputSelection.js +2 -1
  58. package/lib/ReactLink.js +24 -0
  59. package/lib/ReactMount.js +61 -21
  60. package/lib/ReactMultiChild.js +18 -13
  61. package/lib/ReactOwner.js +6 -1
  62. package/lib/ReactPropTransferer.js +44 -29
  63. package/lib/ReactPropTypes.js +226 -242
  64. package/lib/ReactPutListenerQueue.js +2 -2
  65. package/lib/ReactReconcileTransaction.js +21 -20
  66. package/lib/ReactServerRendering.js +41 -11
  67. package/lib/ReactServerRenderingTransaction.js +115 -0
  68. package/lib/ReactTestUtils.js +39 -21
  69. package/lib/ReactTextComponent.js +21 -13
  70. package/lib/ReactTransitionChildMapping.js +2 -2
  71. package/lib/ReactTransitionEvents.js +19 -0
  72. package/lib/ReactTransitionGroup.js +9 -6
  73. package/lib/ReactUpdates.js +139 -22
  74. package/lib/ReactWithAddons.js +8 -3
  75. package/lib/SVGDOMPropertyConfig.js +97 -0
  76. package/lib/SimpleEventPlugin.js +7 -1
  77. package/lib/SyntheticInputEvent.js +52 -0
  78. package/lib/SyntheticKeyboardEvent.js +33 -4
  79. package/lib/SyntheticMouseEvent.js +3 -0
  80. package/lib/SyntheticTouchEvent.js +4 -1
  81. package/lib/SyntheticUIEvent.js +24 -2
  82. package/lib/Transaction.js +0 -32
  83. package/lib/cloneWithProps.js +10 -8
  84. package/lib/createFullPageComponent.js +1 -1
  85. package/lib/dangerousStyleValue.js +11 -5
  86. package/lib/{ReactComponentEnvironment.js → emptyObject.js} +6 -5
  87. package/lib/escapeTextForBrowser.js +2 -3
  88. package/lib/flattenChildren.js +9 -7
  89. package/lib/focusNode.js +33 -0
  90. package/lib/getEventKey.js +35 -5
  91. package/lib/getEventModifierState.js +52 -0
  92. package/lib/getMarkupWrap.js +2 -0
  93. package/lib/getTextContentAccessor.js +1 -1
  94. package/lib/hyphenate.js +3 -0
  95. package/lib/hyphenateStyleName.js +46 -0
  96. package/lib/instantiateReactComponent.js +62 -0
  97. package/lib/invariant.js +17 -19
  98. package/lib/isNode.js +1 -1
  99. package/lib/{objMap.js → mapObject.js} +8 -3
  100. package/lib/mergeHelpers.js +11 -0
  101. package/lib/mergeInto.js +3 -2
  102. package/lib/monitorCodeUse.js +37 -0
  103. package/lib/onlyChild.js +3 -3
  104. package/lib/performance.js +33 -0
  105. package/lib/performanceNow.js +5 -14
  106. package/lib/setInnerHTML.js +77 -0
  107. package/lib/shouldUpdateReactComponent.js +14 -28
  108. package/lib/toArray.js +1 -1
  109. package/lib/traverseAllChildren.js +9 -5
  110. package/lib/update.js +171 -0
  111. package/package.json +4 -3
  112. package/lib/ReactEventTopLevelCallback.js +0 -149
  113. package/lib/createObjectFrom.js +0 -61
  114. package/lib/objMapKeyVal.js +0 -47
@@ -23,6 +23,7 @@ var ReactComponent = require("./ReactComponent");
23
23
  var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
24
24
 
25
25
  var flattenChildren = require("./flattenChildren");
26
+ var instantiateReactComponent = require("./instantiateReactComponent");
26
27
  var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
27
28
 
28
29
  /**
@@ -192,14 +193,18 @@ var ReactMultiChild = {
192
193
  for (var name in children) {
193
194
  var child = children[name];
194
195
  if (children.hasOwnProperty(name)) {
196
+ // The rendered children must be turned into instances as they're
197
+ // mounted.
198
+ var childInstance = instantiateReactComponent(child);
199
+ children[name] = childInstance;
195
200
  // Inlined for performance, see `ReactInstanceHandles.createReactID`.
196
201
  var rootID = this._rootNodeID + name;
197
- var mountImage = child.mountComponent(
202
+ var mountImage = childInstance.mountComponent(
198
203
  rootID,
199
204
  transaction,
200
205
  this._mountDepth + 1
201
206
  );
202
- child._mountIndex = index;
207
+ childInstance._mountIndex = index;
203
208
  mountImages.push(mountImage);
204
209
  index++;
205
210
  }
@@ -281,11 +286,12 @@ var ReactMultiChild = {
281
286
  continue;
282
287
  }
283
288
  var prevChild = prevChildren && prevChildren[name];
284
- var nextChild = nextChildren[name];
285
- if (shouldUpdateReactComponent(prevChild, nextChild)) {
289
+ var prevDescriptor = prevChild && prevChild._descriptor;
290
+ var nextDescriptor = nextChildren[name];
291
+ if (shouldUpdateReactComponent(prevDescriptor, nextDescriptor)) {
286
292
  this.moveChild(prevChild, nextIndex, lastIndex);
287
293
  lastIndex = Math.max(prevChild._mountIndex, lastIndex);
288
- prevChild.receiveComponent(nextChild, transaction);
294
+ prevChild.receiveComponent(nextDescriptor, transaction);
289
295
  prevChild._mountIndex = nextIndex;
290
296
  } else {
291
297
  if (prevChild) {
@@ -293,8 +299,10 @@ var ReactMultiChild = {
293
299
  lastIndex = Math.max(prevChild._mountIndex, lastIndex);
294
300
  this._unmountChildByName(prevChild, name);
295
301
  }
302
+ // The child must be instantiated before it's mounted.
303
+ var nextChildInstance = instantiateReactComponent(nextDescriptor);
296
304
  this._mountChildByNameAtIndex(
297
- nextChild, name, nextIndex, transaction
305
+ nextChildInstance, name, nextIndex, transaction
298
306
  );
299
307
  }
300
308
  nextIndex++;
@@ -409,13 +417,10 @@ var ReactMultiChild = {
409
417
  * @private
410
418
  */
411
419
  _unmountChildByName: function(child, name) {
412
- // TODO: When is this not true?
413
- if (ReactComponent.isValidComponent(child)) {
414
- this.removeChild(child);
415
- child._mountIndex = null;
416
- child.unmountComponent();
417
- delete this._renderedChildren[name];
418
- }
420
+ this.removeChild(child);
421
+ child._mountIndex = null;
422
+ child.unmountComponent();
423
+ delete this._renderedChildren[name];
419
424
  }
420
425
 
421
426
  }
package/lib/ReactOwner.js CHANGED
@@ -18,6 +18,7 @@
18
18
 
19
19
  "use strict";
20
20
 
21
+ var emptyObject = require("./emptyObject");
21
22
  var invariant = require("./invariant");
22
23
 
23
24
  /**
@@ -118,6 +119,10 @@ var ReactOwner = {
118
119
  */
119
120
  Mixin: {
120
121
 
122
+ construct: function() {
123
+ this.refs = emptyObject;
124
+ },
125
+
121
126
  /**
122
127
  * Lazily allocates the refs object and stores `component` as `ref`.
123
128
  *
@@ -132,7 +137,7 @@ var ReactOwner = {
132
137
  'attachRef(%s, ...): Only a component\'s owner can store a ref to it.',
133
138
  ref
134
139
  ) : invariant(component.isOwnedBy(this)));
135
- var refs = this.refs || (this.refs = {});
140
+ var refs = this.refs === emptyObject ? (this.refs = {}) : this.refs;
136
141
  refs[ref] = component;
137
142
  },
138
143
 
@@ -40,6 +40,13 @@ function createTransferStrategy(mergeStrategy) {
40
40
  };
41
41
  }
42
42
 
43
+ var transferStrategyMerge = createTransferStrategy(function(a, b) {
44
+ // `merge` overrides the first object's (`props[key]` above) keys using the
45
+ // second object's (`value`) keys. An object's style's existing `propA` would
46
+ // get overridden. Flip the order here.
47
+ return merge(b, a);
48
+ });
49
+
43
50
  /**
44
51
  * Transfer strategies dictate how props are transferred by `transferPropsTo`.
45
52
  * NOTE: if you add any more exceptions to this list you should be sure to
@@ -65,9 +72,34 @@ var TransferStrategies = {
65
72
  /**
66
73
  * Transfer the `style` prop (which is an object) by merging them.
67
74
  */
68
- style: createTransferStrategy(merge)
75
+ style: transferStrategyMerge
69
76
  };
70
77
 
78
+ /**
79
+ * Mutates the first argument by transferring the properties from the second
80
+ * argument.
81
+ *
82
+ * @param {object} props
83
+ * @param {object} newProps
84
+ * @return {object}
85
+ */
86
+ function transferInto(props, newProps) {
87
+ for (var thisKey in newProps) {
88
+ if (!newProps.hasOwnProperty(thisKey)) {
89
+ continue;
90
+ }
91
+
92
+ var transferStrategy = TransferStrategies[thisKey];
93
+
94
+ if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) {
95
+ transferStrategy(props, thisKey, newProps[thisKey]);
96
+ } else if (!props.hasOwnProperty(thisKey)) {
97
+ props[thisKey] = newProps[thisKey];
98
+ }
99
+ }
100
+ return props;
101
+ }
102
+
71
103
  /**
72
104
  * ReactPropTransferer are capable of transferring props to another component
73
105
  * using a `transferPropsTo` method.
@@ -86,23 +118,7 @@ var ReactPropTransferer = {
86
118
  * @return {object} a new object containing both sets of props merged.
87
119
  */
88
120
  mergeProps: function(oldProps, newProps) {
89
- var props = merge(oldProps);
90
-
91
- for (var thisKey in newProps) {
92
- if (!newProps.hasOwnProperty(thisKey)) {
93
- continue;
94
- }
95
-
96
- var transferStrategy = TransferStrategies[thisKey];
97
-
98
- if (transferStrategy) {
99
- transferStrategy(props, thisKey, newProps[thisKey]);
100
- } else if (!props.hasOwnProperty(thisKey)) {
101
- props[thisKey] = newProps[thisKey];
102
- }
103
- }
104
-
105
- return props;
121
+ return transferInto(merge(oldProps), newProps);
106
122
  },
107
123
 
108
124
  /**
@@ -118,27 +134,26 @@ var ReactPropTransferer = {
118
134
  *
119
135
  * This is usually used to pass down props to a returned root component.
120
136
  *
121
- * @param {ReactComponent} component Component receiving the properties.
122
- * @return {ReactComponent} The supplied `component`.
137
+ * @param {ReactDescriptor} descriptor Component receiving the properties.
138
+ * @return {ReactDescriptor} The supplied `component`.
123
139
  * @final
124
140
  * @protected
125
141
  */
126
- transferPropsTo: function(component) {
142
+ transferPropsTo: function(descriptor) {
127
143
  ("production" !== process.env.NODE_ENV ? invariant(
128
- component._owner === this,
144
+ descriptor._owner === this,
129
145
  '%s: You can\'t call transferPropsTo() on a component that you ' +
130
146
  'don\'t own, %s. This usually means you are calling ' +
131
147
  'transferPropsTo() on a component passed in as props or children.',
132
148
  this.constructor.displayName,
133
- component.constructor.displayName
134
- ) : invariant(component._owner === this));
149
+ descriptor.type.displayName
150
+ ) : invariant(descriptor._owner === this));
135
151
 
136
- component.props = ReactPropTransferer.mergeProps(
137
- component.props,
138
- this.props
139
- );
152
+ // Because descriptors are immutable we have to merge into the existing
153
+ // props object rather than clone it.
154
+ transferInto(descriptor.props, this.props);
140
155
 
141
- return component;
156
+ return descriptor;
142
157
  }
143
158
 
144
159
  }
@@ -18,11 +18,10 @@
18
18
 
19
19
  "use strict";
20
20
 
21
- var ReactComponent = require("./ReactComponent");
21
+ var ReactDescriptor = require("./ReactDescriptor");
22
22
  var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
23
23
 
24
- var warning = require("./warning");
25
- var createObjectFrom = require("./createObjectFrom");
24
+ var emptyFunction = require("./emptyFunction");
26
25
 
27
26
  /**
28
27
  * Collection of methods that allow declaration and validation of props that are
@@ -51,29 +50,29 @@ var createObjectFrom = require("./createObjectFrom");
51
50
  * Each and every declaration produces a function with the same signature. This
52
51
  * allows the creation of custom validation functions. For example:
53
52
  *
54
- * var Props = require('ReactPropTypes');
55
- * var MyLink = React.createClass({
56
- * propTypes: {
57
- * // An optional string or URI prop named "href".
58
- * href: function(props, propName, componentName) {
59
- * var propValue = props[propName];
60
- * warning(
61
- * propValue == null ||
62
- * typeof propValue === 'string' ||
63
- * propValue instanceof URI,
64
- * 'Invalid `%s` supplied to `%s`, expected string or URI.',
65
- * propName,
66
- * componentName
67
- * );
68
- * }
69
- * },
70
- * render: function() { ... }
71
- * });
53
+ * var MyLink = React.createClass({
54
+ * propTypes: {
55
+ * // An optional string or URI prop named "href".
56
+ * href: function(props, propName, componentName) {
57
+ * var propValue = props[propName];
58
+ * if (propValue != null && typeof propValue !== 'string' &&
59
+ * !(propValue instanceof URI)) {
60
+ * return new Error(
61
+ * 'Expected a string or an URI for ' + propName + ' in ' +
62
+ * componentName
63
+ * );
64
+ * }
65
+ * }
66
+ * },
67
+ * render: function() {...}
68
+ * });
72
69
  *
73
70
  * @internal
74
71
  */
75
- var Props = {
76
72
 
73
+ var ANONYMOUS = '<<anonymous>>';
74
+
75
+ var ReactPropTypes = {
77
76
  array: createPrimitiveTypeChecker('array'),
78
77
  bool: createPrimitiveTypeChecker('boolean'),
79
78
  func: createPrimitiveTypeChecker('function'),
@@ -81,279 +80,264 @@ var Props = {
81
80
  object: createPrimitiveTypeChecker('object'),
82
81
  string: createPrimitiveTypeChecker('string'),
83
82
 
84
- shape: createShapeTypeChecker,
85
- oneOf: createEnumTypeChecker,
86
- oneOfType: createUnionTypeChecker,
83
+ any: createAnyTypeChecker(),
87
84
  arrayOf: createArrayOfTypeChecker,
88
-
85
+ component: createComponentTypeChecker(),
89
86
  instanceOf: createInstanceTypeChecker,
90
-
87
+ objectOf: createObjectOfTypeChecker,
88
+ oneOf: createEnumTypeChecker,
89
+ oneOfType: createUnionTypeChecker,
91
90
  renderable: createRenderableTypeChecker(),
92
-
93
- component: createComponentTypeChecker(),
94
-
95
- any: createAnyTypeChecker()
91
+ shape: createShapeTypeChecker
96
92
  };
97
93
 
98
- var ANONYMOUS = '<<anonymous>>';
99
-
100
- function isRenderable(propValue) {
101
- switch(typeof propValue) {
102
- case 'number':
103
- case 'string':
104
- return true;
105
- case 'object':
106
- if (Array.isArray(propValue)) {
107
- return propValue.every(isRenderable);
108
- }
109
- if (ReactComponent.isValidComponent(propValue)) {
110
- return true;
111
- }
112
- for (var k in propValue) {
113
- if (!isRenderable(propValue[k])) {
114
- return false;
115
- }
94
+ function createChainableTypeChecker(validate) {
95
+ function checkType(isRequired, props, propName, componentName, location) {
96
+ componentName = componentName || ANONYMOUS;
97
+ if (props[propName] == null) {
98
+ var locationName = ReactPropTypeLocationNames[location];
99
+ if (isRequired) {
100
+ return new Error(
101
+ ("Required " + locationName + " `" + propName + "` was not specified in ")+
102
+ ("`" + componentName + "`.")
103
+ );
116
104
  }
117
- return true;
118
- default:
119
- return false;
105
+ } else {
106
+ return validate(props, propName, componentName, location);
107
+ }
120
108
  }
109
+
110
+ var chainedCheckType = checkType.bind(null, false);
111
+ chainedCheckType.isRequired = checkType.bind(null, true);
112
+
113
+ return chainedCheckType;
121
114
  }
122
115
 
123
- // Equivalent of typeof but with special handling for arrays
124
- function getPropType(propValue) {
125
- var propType = typeof propValue;
126
- if (propType === 'object' && Array.isArray(propValue)) {
127
- return 'array';
116
+ function createPrimitiveTypeChecker(expectedType) {
117
+ function validate(props, propName, componentName, location) {
118
+ var propValue = props[propName];
119
+ var propType = getPropType(propValue);
120
+ if (propType !== expectedType) {
121
+ var locationName = ReactPropTypeLocationNames[location];
122
+ // `propValue` being instance of, say, date/regexp, pass the 'object'
123
+ // check, but we can offer a more precise error message here rather than
124
+ // 'of type `object`'.
125
+ var preciseType = getPreciseType(propValue);
126
+
127
+ return new Error(
128
+ ("Invalid " + locationName + " `" + propName + "` of type `" + preciseType + "` ") +
129
+ ("supplied to `" + componentName + "`, expected `" + expectedType + "`.")
130
+ );
131
+ }
128
132
  }
129
- return propType;
133
+ return createChainableTypeChecker(validate);
130
134
  }
131
135
 
132
136
  function createAnyTypeChecker() {
133
- function validateAnyType(
134
- shouldWarn, propValue, propName, componentName, location
135
- ) {
136
- return true; // is always valid
137
- }
138
- return createChainableTypeChecker(validateAnyType);
137
+ return createChainableTypeChecker(emptyFunction.thatReturns());
139
138
  }
140
139
 
141
- function createPrimitiveTypeChecker(expectedType) {
142
- function validatePrimitiveType(
143
- shouldWarn, propValue, propName, componentName, location
144
- ) {
145
- var propType = getPropType(propValue);
146
- var isValid = propType === expectedType;
147
- if (shouldWarn) {
148
- ("production" !== process.env.NODE_ENV ? warning(
149
- isValid,
150
- 'Invalid %s `%s` of type `%s` supplied to `%s`, expected `%s`.',
151
- ReactPropTypeLocationNames[location],
152
- propName,
153
- propType,
154
- componentName,
155
- expectedType
156
- ) : null);
140
+ function createArrayOfTypeChecker(typeChecker) {
141
+ function validate(props, propName, componentName, location) {
142
+ var propValue = props[propName];
143
+ if (!Array.isArray(propValue)) {
144
+ var locationName = ReactPropTypeLocationNames[location];
145
+ var propType = getPropType(propValue);
146
+ return new Error(
147
+ ("Invalid " + locationName + " `" + propName + "` of type ") +
148
+ ("`" + propType + "` supplied to `" + componentName + "`, expected an array.")
149
+ );
150
+ }
151
+ for (var i = 0; i < propValue.length; i++) {
152
+ var error = typeChecker(propValue, i, componentName, location);
153
+ if (error instanceof Error) {
154
+ return error;
155
+ }
157
156
  }
158
- return isValid;
159
157
  }
160
- return createChainableTypeChecker(validatePrimitiveType);
158
+ return createChainableTypeChecker(validate);
161
159
  }
162
160
 
163
- function createEnumTypeChecker(expectedValues) {
164
- var expectedEnum = createObjectFrom(expectedValues);
165
- function validateEnumType(
166
- shouldWarn, propValue, propName, componentName, location
167
- ) {
168
- var isValid = expectedEnum[propValue];
169
- if (shouldWarn) {
170
- ("production" !== process.env.NODE_ENV ? warning(
171
- isValid,
172
- 'Invalid %s `%s` supplied to `%s`, expected one of %s.',
173
- ReactPropTypeLocationNames[location],
174
- propName,
175
- componentName,
176
- JSON.stringify(Object.keys(expectedEnum))
177
- ) : null);
161
+ function createComponentTypeChecker() {
162
+ function validate(props, propName, componentName, location) {
163
+ if (!ReactDescriptor.isValidDescriptor(props[propName])) {
164
+ var locationName = ReactPropTypeLocationNames[location];
165
+ return new Error(
166
+ ("Invalid " + locationName + " `" + propName + "` supplied to ") +
167
+ ("`" + componentName + "`, expected a React component.")
168
+ );
178
169
  }
179
- return isValid;
180
170
  }
181
- return createChainableTypeChecker(validateEnumType);
171
+ return createChainableTypeChecker(validate);
182
172
  }
183
173
 
184
- function createShapeTypeChecker(shapeTypes) {
185
- function validateShapeType(
186
- shouldWarn, propValue, propName, componentName, location
187
- ) {
188
- var propType = getPropType(propValue);
189
- var isValid = propType === 'object';
190
- if (isValid) {
191
- for (var key in shapeTypes) {
192
- var checker = shapeTypes[key];
193
- if (checker && !checker(propValue, key, componentName, location)) {
194
- return false;
195
- }
196
- }
197
- }
198
- if (shouldWarn) {
199
- ("production" !== process.env.NODE_ENV ? warning(
200
- isValid,
201
- 'Invalid %s `%s` of type `%s` supplied to `%s`, expected `object`.',
202
- ReactPropTypeLocationNames[location],
203
- propName,
204
- propType,
205
- componentName
206
- ) : null);
174
+ function createInstanceTypeChecker(expectedClass) {
175
+ function validate(props, propName, componentName, location) {
176
+ if (!(props[propName] instanceof expectedClass)) {
177
+ var locationName = ReactPropTypeLocationNames[location];
178
+ var expectedClassName = expectedClass.name || ANONYMOUS;
179
+ return new Error(
180
+ ("Invalid " + locationName + " `" + propName + "` supplied to ") +
181
+ ("`" + componentName + "`, expected instance of `" + expectedClassName + "`.")
182
+ );
207
183
  }
208
- return isValid;
209
184
  }
210
- return createChainableTypeChecker(validateShapeType);
185
+ return createChainableTypeChecker(validate);
211
186
  }
212
187
 
213
- function createInstanceTypeChecker(expectedClass) {
214
- function validateInstanceType(
215
- shouldWarn, propValue, propName, componentName, location
216
- ) {
217
- var isValid = propValue instanceof expectedClass;
218
- if (shouldWarn) {
219
- ("production" !== process.env.NODE_ENV ? warning(
220
- isValid,
221
- 'Invalid %s `%s` supplied to `%s`, expected instance of `%s`.',
222
- ReactPropTypeLocationNames[location],
223
- propName,
224
- componentName,
225
- expectedClass.name || ANONYMOUS
226
- ) : null);
188
+ function createEnumTypeChecker(expectedValues) {
189
+ function validate(props, propName, componentName, location) {
190
+ var propValue = props[propName];
191
+ for (var i = 0; i < expectedValues.length; i++) {
192
+ if (propValue === expectedValues[i]) {
193
+ return;
194
+ }
227
195
  }
228
- return isValid;
196
+
197
+ var locationName = ReactPropTypeLocationNames[location];
198
+ var valuesString = JSON.stringify(expectedValues);
199
+ return new Error(
200
+ ("Invalid " + locationName + " `" + propName + "` of value `" + propValue + "` ") +
201
+ ("supplied to `" + componentName + "`, expected one of " + valuesString + ".")
202
+ );
229
203
  }
230
- return createChainableTypeChecker(validateInstanceType);
204
+ return createChainableTypeChecker(validate);
231
205
  }
232
206
 
233
- function createArrayOfTypeChecker(propTypeChecker) {
234
- function validateArrayType(
235
- shouldWarn, propValue, propName, componentName, location
236
- ) {
237
- var isValid = Array.isArray(propValue);
238
- if (isValid) {
239
- for (var i = 0; i < propValue.length; i++) {
240
- if (!propTypeChecker(propValue, i, componentName, location)) {
241
- return false;
207
+ function createObjectOfTypeChecker(typeChecker) {
208
+ function validate(props, propName, componentName, location) {
209
+ var propValue = props[propName];
210
+ var propType = getPropType(propValue);
211
+ if (propType !== 'object') {
212
+ var locationName = ReactPropTypeLocationNames[location];
213
+ return new Error(
214
+ ("Invalid " + locationName + " `" + propName + "` of type ") +
215
+ ("`" + propType + "` supplied to `" + componentName + "`, expected an object.")
216
+ );
217
+ }
218
+ for (var key in propValue) {
219
+ if (propValue.hasOwnProperty(key)) {
220
+ var error = typeChecker(propValue, key, componentName, location);
221
+ if (error instanceof Error) {
222
+ return error;
242
223
  }
243
224
  }
244
225
  }
245
- if (shouldWarn) {
246
- ("production" !== process.env.NODE_ENV ? warning(
247
- isValid,
248
- 'Invalid %s `%s` supplied to `%s`, expected an array.',
249
- ReactPropTypeLocationNames[location],
250
- propName,
251
- componentName
252
- ) : null);
253
- }
254
- return isValid;
255
226
  }
256
- return createChainableTypeChecker(validateArrayType);
227
+ return createChainableTypeChecker(validate);
257
228
  }
258
229
 
259
- function createRenderableTypeChecker() {
260
- function validateRenderableType(
261
- shouldWarn, propValue, propName, componentName, location
262
- ) {
263
- var isValid = isRenderable(propValue);
264
- if (shouldWarn) {
265
- ("production" !== process.env.NODE_ENV ? warning(
266
- isValid,
267
- 'Invalid %s `%s` supplied to `%s`, expected a renderable prop.',
268
- ReactPropTypeLocationNames[location],
269
- propName,
270
- componentName
271
- ) : null);
230
+ function createUnionTypeChecker(arrayOfTypeCheckers) {
231
+ function validate(props, propName, componentName, location) {
232
+ for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
233
+ var checker = arrayOfTypeCheckers[i];
234
+ if (checker(props, propName, componentName, location) == null) {
235
+ return;
236
+ }
272
237
  }
273
- return isValid;
238
+
239
+ var locationName = ReactPropTypeLocationNames[location];
240
+ return new Error(
241
+ ("Invalid " + locationName + " `" + propName + "` supplied to ") +
242
+ ("`" + componentName + "`.")
243
+ );
274
244
  }
275
- return createChainableTypeChecker(validateRenderableType);
245
+ return createChainableTypeChecker(validate);
276
246
  }
277
247
 
278
- function createComponentTypeChecker() {
279
- function validateComponentType(
280
- shouldWarn, propValue, propName, componentName, location
281
- ) {
282
- var isValid = ReactComponent.isValidComponent(propValue);
283
- if (shouldWarn) {
284
- ("production" !== process.env.NODE_ENV ? warning(
285
- isValid,
286
- 'Invalid %s `%s` supplied to `%s`, expected a React component.',
287
- ReactPropTypeLocationNames[location],
288
- propName,
289
- componentName
290
- ) : null);
248
+ function createRenderableTypeChecker() {
249
+ function validate(props, propName, componentName, location) {
250
+ if (!isRenderable(props[propName])) {
251
+ var locationName = ReactPropTypeLocationNames[location];
252
+ return new Error(
253
+ ("Invalid " + locationName + " `" + propName + "` supplied to ") +
254
+ ("`" + componentName + "`, expected a renderable prop.")
255
+ );
291
256
  }
292
- return isValid;
293
257
  }
294
- return createChainableTypeChecker(validateComponentType);
258
+ return createChainableTypeChecker(validate);
295
259
  }
296
260
 
297
- function createUnionTypeChecker(arrayOfValidators) {
298
- return function(props, propName, componentName, location) {
299
- var isValid = false;
300
- for (var ii = 0; ii < arrayOfValidators.length; ii++) {
301
- var validate = arrayOfValidators[ii];
302
- if (typeof validate.weak === 'function') {
303
- validate = validate.weak;
261
+ function createShapeTypeChecker(shapeTypes) {
262
+ function validate(props, propName, componentName, location) {
263
+ var propValue = props[propName];
264
+ var propType = getPropType(propValue);
265
+ if (propType !== 'object') {
266
+ var locationName = ReactPropTypeLocationNames[location];
267
+ return new Error(
268
+ ("Invalid " + locationName + " `" + propName + "` of type `" + propType + "` ") +
269
+ ("supplied to `" + componentName + "`, expected `object`.")
270
+ );
271
+ }
272
+ for (var key in shapeTypes) {
273
+ var checker = shapeTypes[key];
274
+ if (!checker) {
275
+ continue;
304
276
  }
305
- if (validate(props, propName, componentName, location)) {
306
- isValid = true;
307
- break;
277
+ var error = checker(propValue, key, componentName, location);
278
+ if (error) {
279
+ return error;
308
280
  }
309
281
  }
310
- ("production" !== process.env.NODE_ENV ? warning(
311
- isValid,
312
- 'Invalid %s `%s` supplied to `%s`.',
313
- ReactPropTypeLocationNames[location],
314
- propName,
315
- componentName || ANONYMOUS
316
- ) : null);
317
- return isValid;
318
- };
282
+ }
283
+ return createChainableTypeChecker(validate, 'expected `object`');
319
284
  }
320
285
 
321
- function createChainableTypeChecker(validate) {
322
- function checkType(
323
- isRequired, shouldWarn, props, propName, componentName, location
324
- ) {
325
- var propValue = props[propName];
326
- if (propValue != null) {
327
- // Only validate if there is a value to check.
328
- return validate(
329
- shouldWarn,
330
- propValue,
331
- propName,
332
- componentName || ANONYMOUS,
333
- location
334
- );
335
- } else {
336
- var isValid = !isRequired;
337
- if (shouldWarn) {
338
- ("production" !== process.env.NODE_ENV ? warning(
339
- isValid,
340
- 'Required %s `%s` was not specified in `%s`.',
341
- ReactPropTypeLocationNames[location],
342
- propName,
343
- componentName || ANONYMOUS
344
- ) : null);
286
+ function isRenderable(propValue) {
287
+ switch(typeof propValue) {
288
+ // TODO: this was probably written with the assumption that we're not
289
+ // returning `this.props.component` directly from `render`. This is
290
+ // currently not supported but we should, to make it consistent.
291
+ case 'number':
292
+ case 'string':
293
+ return true;
294
+ case 'boolean':
295
+ return !propValue;
296
+ case 'object':
297
+ if (Array.isArray(propValue)) {
298
+ return propValue.every(isRenderable);
345
299
  }
346
- return isValid;
347
- }
300
+ if (ReactDescriptor.isValidDescriptor(propValue)) {
301
+ return true;
302
+ }
303
+ for (var k in propValue) {
304
+ if (!isRenderable(propValue[k])) {
305
+ return false;
306
+ }
307
+ }
308
+ return true;
309
+ default:
310
+ return false;
348
311
  }
312
+ }
349
313
 
350
- var checker = checkType.bind(null, false, true);
351
- checker.weak = checkType.bind(null, false, false);
352
- checker.isRequired = checkType.bind(null, true, true);
353
- checker.weak.isRequired = checkType.bind(null, true, false);
354
- checker.isRequired.weak = checker.weak.isRequired;
314
+ // Equivalent of `typeof` but with special handling for array and regexp.
315
+ function getPropType(propValue) {
316
+ var propType = typeof propValue;
317
+ if (Array.isArray(propValue)) {
318
+ return 'array';
319
+ }
320
+ if (propValue instanceof RegExp) {
321
+ // Old webkits (at least until Android 4.0) return 'function' rather than
322
+ // 'object' for typeof a RegExp. We'll normalize this here so that /bla/
323
+ // passes PropTypes.object.
324
+ return 'object';
325
+ }
326
+ return propType;
327
+ }
355
328
 
356
- return checker;
329
+ // This handles more types than `getPropType`. Only used for error messages.
330
+ // See `createPrimitiveTypeChecker`.
331
+ function getPreciseType(propValue) {
332
+ var propType = getPropType(propValue);
333
+ if (propType === 'object') {
334
+ if (propValue instanceof Date) {
335
+ return 'date';
336
+ } else if (propValue instanceof RegExp) {
337
+ return 'regexp';
338
+ }
339
+ }
340
+ return propType;
357
341
  }
358
342
 
359
- module.exports = Props;
343
+ module.exports = ReactPropTypes;