react 0.10.0 → 0.11.2

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 (104) hide show
  1. package/README.md +3 -0
  2. package/dist/JSXTransformer.js +20344 -0
  3. package/dist/react-with-addons.js +20276 -0
  4. package/dist/react-with-addons.min.js +22 -0
  5. package/dist/react.js +18484 -0
  6. package/dist/react.min.js +21 -0
  7. package/lib/BeforeInputEventPlugin.js +222 -0
  8. package/lib/CSSPropertyOperations.js +3 -3
  9. package/lib/{ReactMountReady.js → CallbackQueue.js} +32 -24
  10. package/lib/ChangeEventPlugin.js +1 -1
  11. package/lib/CompositionEventPlugin.js +5 -1
  12. package/lib/DOMChildrenOperations.js +21 -14
  13. package/lib/DOMProperty.js +45 -17
  14. package/lib/DOMPropertyOperations.js +22 -10
  15. package/lib/DefaultEventPluginOrder.js +1 -0
  16. package/lib/EventConstants.js +1 -0
  17. package/lib/EventListener.js +5 -2
  18. package/lib/EventPluginHub.js +0 -5
  19. package/lib/EventPluginRegistry.js +6 -4
  20. package/lib/EventPluginUtils.js +11 -1
  21. package/lib/ExecutionEnvironment.js +8 -2
  22. package/lib/{DefaultDOMPropertyConfig.js → HTMLDOMPropertyConfig.js} +42 -49
  23. package/lib/LinkedValueUtils.js +21 -22
  24. package/lib/LocalEventTrapMixin.js +52 -0
  25. package/lib/React.js +57 -3
  26. package/lib/ReactBrowserComponentMixin.js +4 -0
  27. package/lib/{ReactEventEmitter.js → ReactBrowserEventEmitter.js} +115 -94
  28. package/lib/ReactCSSTransitionGroup.js +2 -0
  29. package/lib/ReactCSSTransitionGroupChild.js +2 -5
  30. package/lib/ReactChildren.js +31 -10
  31. package/lib/ReactComponent.js +88 -237
  32. package/lib/ReactComponentBrowserEnvironment.js +3 -2
  33. package/lib/ReactComponentWithPureRenderMixin.js +54 -0
  34. package/lib/ReactCompositeComponent.js +222 -384
  35. package/lib/ReactDOM.js +22 -18
  36. package/lib/ReactDOMComponent.js +26 -24
  37. package/lib/ReactDOMForm.js +5 -13
  38. package/lib/ReactDOMIDOperations.js +2 -31
  39. package/lib/ReactDOMImg.js +5 -14
  40. package/lib/ReactDOMSelect.js +16 -15
  41. package/lib/ReactDOMSelection.js +35 -10
  42. package/lib/ReactDOMTextarea.js +2 -4
  43. package/lib/ReactDefaultBatchingStrategy.js +3 -3
  44. package/lib/ReactDefaultInjection.js +18 -15
  45. package/lib/ReactDefaultPerf.js +28 -11
  46. package/lib/ReactDefaultPerfAnalysis.js +4 -0
  47. package/lib/ReactDescriptor.js +251 -0
  48. package/lib/ReactDescriptorValidator.js +283 -0
  49. package/lib/ReactEmptyComponent.js +78 -0
  50. package/lib/ReactEventEmitterMixin.js +1 -3
  51. package/lib/ReactEventListener.js +189 -0
  52. package/lib/ReactInjection.js +4 -2
  53. package/lib/ReactLink.js +24 -0
  54. package/lib/ReactMount.js +51 -19
  55. package/lib/ReactMultiChild.js +9 -11
  56. package/lib/ReactPropTransferer.js +44 -29
  57. package/lib/ReactPropTypes.js +226 -242
  58. package/lib/ReactPutListenerQueue.js +2 -2
  59. package/lib/ReactReconcileTransaction.js +14 -14
  60. package/lib/ReactServerRendering.js +5 -5
  61. package/lib/ReactServerRenderingTransaction.js +4 -5
  62. package/lib/ReactTestUtils.js +39 -21
  63. package/lib/ReactTextComponent.js +8 -22
  64. package/lib/ReactTransitionChildMapping.js +2 -2
  65. package/lib/ReactTransitionEvents.js +19 -0
  66. package/lib/ReactTransitionGroup.js +9 -6
  67. package/lib/ReactUpdates.js +139 -22
  68. package/lib/ReactWithAddons.js +5 -2
  69. package/lib/SVGDOMPropertyConfig.js +97 -0
  70. package/lib/SimpleEventPlugin.js +7 -1
  71. package/lib/SyntheticInputEvent.js +52 -0
  72. package/lib/SyntheticKeyboardEvent.js +33 -4
  73. package/lib/SyntheticMouseEvent.js +3 -0
  74. package/lib/SyntheticTouchEvent.js +4 -1
  75. package/lib/SyntheticUIEvent.js +24 -2
  76. package/lib/Transaction.js +0 -32
  77. package/lib/cloneWithProps.js +3 -1
  78. package/lib/createFullPageComponent.js +1 -1
  79. package/lib/dangerousStyleValue.js +11 -5
  80. package/lib/escapeTextForBrowser.js +2 -3
  81. package/lib/flattenChildren.js +9 -7
  82. package/lib/getEventKey.js +35 -5
  83. package/lib/getEventModifierState.js +52 -0
  84. package/lib/getMarkupWrap.js +2 -0
  85. package/lib/getTextContentAccessor.js +1 -1
  86. package/lib/hyphenate.js +3 -0
  87. package/lib/hyphenateStyleName.js +46 -0
  88. package/lib/instantiateReactComponent.js +13 -21
  89. package/lib/invariant.js +17 -19
  90. package/lib/{objMap.js → mapObject.js} +8 -3
  91. package/lib/mergeHelpers.js +11 -0
  92. package/lib/mergeInto.js +3 -2
  93. package/lib/onlyChild.js +3 -3
  94. package/lib/performance.js +33 -0
  95. package/lib/performanceNow.js +5 -14
  96. package/lib/setInnerHTML.js +85 -0
  97. package/lib/shouldUpdateReactComponent.js +12 -29
  98. package/lib/toArray.js +1 -1
  99. package/lib/traverseAllChildren.js +7 -4
  100. package/lib/update.js +57 -45
  101. package/package.json +4 -3
  102. package/lib/ReactEventTopLevelCallback.js +0 -149
  103. package/lib/createObjectFrom.js +0 -61
  104. package/lib/objMapKeyVal.js +0 -47
@@ -88,8 +88,7 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
88
88
  // `textContent` (unnecessary since we update value).
89
89
  // The initial value can be a boolean or object so that's why it's
90
90
  // forced to be a string.
91
- initialValue: '' + (value != null ? value : defaultValue),
92
- value: defaultValue
91
+ initialValue: '' + (value != null ? value : defaultValue)
93
92
  };
94
93
  },
95
94
 
@@ -101,7 +100,6 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
101
100
  render: function() {
102
101
  // Clone `this.props` so we don't mutate the input.
103
102
  var props = merge(this.props);
104
- var value = LinkedValueUtils.getValue(this);
105
103
 
106
104
  ("production" !== process.env.NODE_ENV ? invariant(
107
105
  props.dangerouslySetInnerHTML == null,
@@ -109,7 +107,7 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
109
107
  ) : invariant(props.dangerouslySetInnerHTML == null));
110
108
 
111
109
  props.defaultValue = null;
112
- props.value = value != null ? value : this.state.value;
110
+ props.value = null;
113
111
  props.onChange = this._handleChange;
114
112
 
115
113
  // Always set children to the same thing. In IE9, the selection range will
@@ -58,16 +58,16 @@ var ReactDefaultBatchingStrategy = {
58
58
  * Call the provided function in a context within which calls to `setState`
59
59
  * and friends are batched such that components aren't updated unnecessarily.
60
60
  */
61
- batchedUpdates: function(callback, param) {
61
+ batchedUpdates: function(callback, a, b) {
62
62
  var alreadyBatchingUpdates = ReactDefaultBatchingStrategy.isBatchingUpdates;
63
63
 
64
64
  ReactDefaultBatchingStrategy.isBatchingUpdates = true;
65
65
 
66
66
  // The code is written this way to avoid extra allocations
67
67
  if (alreadyBatchingUpdates) {
68
- callback(param);
68
+ callback(a, b);
69
69
  } else {
70
- transaction.perform(callback, null, param);
70
+ transaction.perform(callback, null, a, b);
71
71
  }
72
72
  }
73
73
  };
@@ -18,22 +18,19 @@
18
18
 
19
19
  "use strict";
20
20
 
21
- var ReactInjection = require("./ReactInjection");
22
-
23
- var ExecutionEnvironment = require("./ExecutionEnvironment");
24
-
25
- var DefaultDOMPropertyConfig = require("./DefaultDOMPropertyConfig");
26
-
21
+ var BeforeInputEventPlugin = require("./BeforeInputEventPlugin");
27
22
  var ChangeEventPlugin = require("./ChangeEventPlugin");
28
23
  var ClientReactRootIndex = require("./ClientReactRootIndex");
29
24
  var CompositionEventPlugin = require("./CompositionEventPlugin");
30
25
  var DefaultEventPluginOrder = require("./DefaultEventPluginOrder");
31
26
  var EnterLeaveEventPlugin = require("./EnterLeaveEventPlugin");
27
+ var ExecutionEnvironment = require("./ExecutionEnvironment");
28
+ var HTMLDOMPropertyConfig = require("./HTMLDOMPropertyConfig");
32
29
  var MobileSafariClickEventPlugin = require("./MobileSafariClickEventPlugin");
33
30
  var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
34
31
  var ReactComponentBrowserEnvironment =
35
32
  require("./ReactComponentBrowserEnvironment");
36
- var ReactEventTopLevelCallback = require("./ReactEventTopLevelCallback");
33
+ var ReactDefaultBatchingStrategy = require("./ReactDefaultBatchingStrategy");
37
34
  var ReactDOM = require("./ReactDOM");
38
35
  var ReactDOMButton = require("./ReactDOMButton");
39
36
  var ReactDOMForm = require("./ReactDOMForm");
@@ -42,19 +39,20 @@ var ReactDOMInput = require("./ReactDOMInput");
42
39
  var ReactDOMOption = require("./ReactDOMOption");
43
40
  var ReactDOMSelect = require("./ReactDOMSelect");
44
41
  var ReactDOMTextarea = require("./ReactDOMTextarea");
42
+ var ReactEventListener = require("./ReactEventListener");
43
+ var ReactInjection = require("./ReactInjection");
45
44
  var ReactInstanceHandles = require("./ReactInstanceHandles");
46
45
  var ReactMount = require("./ReactMount");
47
46
  var SelectEventPlugin = require("./SelectEventPlugin");
48
47
  var ServerReactRootIndex = require("./ServerReactRootIndex");
49
48
  var SimpleEventPlugin = require("./SimpleEventPlugin");
50
-
51
- var ReactDefaultBatchingStrategy = require("./ReactDefaultBatchingStrategy");
49
+ var SVGDOMPropertyConfig = require("./SVGDOMPropertyConfig");
52
50
 
53
51
  var createFullPageComponent = require("./createFullPageComponent");
54
52
 
55
53
  function inject() {
56
- ReactInjection.EventEmitter.injectTopLevelCallbackCreator(
57
- ReactEventTopLevelCallback
54
+ ReactInjection.EventEmitter.injectReactEventListener(
55
+ ReactEventListener
58
56
  );
59
57
 
60
58
  /**
@@ -74,7 +72,8 @@ function inject() {
74
72
  ChangeEventPlugin: ChangeEventPlugin,
75
73
  CompositionEventPlugin: CompositionEventPlugin,
76
74
  MobileSafariClickEventPlugin: MobileSafariClickEventPlugin,
77
- SelectEventPlugin: SelectEventPlugin
75
+ SelectEventPlugin: SelectEventPlugin,
76
+ BeforeInputEventPlugin: BeforeInputEventPlugin
78
77
  });
79
78
 
80
79
  ReactInjection.DOM.injectComponentClasses({
@@ -88,17 +87,21 @@ function inject() {
88
87
 
89
88
  html: createFullPageComponent(ReactDOM.html),
90
89
  head: createFullPageComponent(ReactDOM.head),
91
- title: createFullPageComponent(ReactDOM.title),
92
90
  body: createFullPageComponent(ReactDOM.body)
93
91
  });
94
92
 
95
-
96
93
  // This needs to happen after createFullPageComponent() otherwise the mixin
97
94
  // gets double injected.
98
95
  ReactInjection.CompositeComponent.injectMixin(ReactBrowserComponentMixin);
99
96
 
100
- ReactInjection.DOMProperty.injectDOMPropertyConfig(DefaultDOMPropertyConfig);
97
+ ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
98
+ ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);
99
+
100
+ ReactInjection.EmptyComponent.injectEmptyComponent(ReactDOM.noscript);
101
101
 
102
+ ReactInjection.Updates.injectReconcileTransaction(
103
+ ReactComponentBrowserEnvironment.ReactReconcileTransaction
104
+ );
102
105
  ReactInjection.Updates.injectBatchingStrategy(
103
106
  ReactDefaultBatchingStrategy
104
107
  );
@@ -30,8 +30,13 @@ function roundFloat(val) {
30
30
  return Math.floor(val * 100) / 100;
31
31
  }
32
32
 
33
+ function addValue(obj, key, val) {
34
+ obj[key] = (obj[key] || 0) + val;
35
+ }
36
+
33
37
  var ReactDefaultPerf = {
34
38
  _allMeasurements: [], // last item in the list is the current one
39
+ _mountStack: [0],
35
40
  _injected: false,
36
41
 
37
42
  start: function() {
@@ -58,15 +63,15 @@ var ReactDefaultPerf = {
58
63
  return {
59
64
  'Component class name': item.componentName,
60
65
  'Total inclusive time (ms)': roundFloat(item.inclusive),
61
- 'Total exclusive time (ms)': roundFloat(item.exclusive),
62
- 'Exclusive time per instance (ms)': roundFloat(item.exclusive / item.count),
66
+ 'Exclusive mount time (ms)': roundFloat(item.exclusive),
67
+ 'Exclusive render time (ms)': roundFloat(item.render),
68
+ 'Mount time per instance (ms)': roundFloat(item.exclusive / item.count),
69
+ 'Render time per instance (ms)': roundFloat(item.render / item.count),
63
70
  'Instances': item.count
64
71
  };
65
72
  }));
66
- console.log(
67
- 'Total time:',
68
- ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms'
69
- );
73
+ // TODO: ReactDefaultPerfAnalysis.getTotalTime() does not return the correct
74
+ // number.
70
75
  },
71
76
 
72
77
  printInclusive: function(measurements) {
@@ -149,6 +154,7 @@ var ReactDefaultPerf = {
149
154
  ReactDefaultPerf._allMeasurements.push({
150
155
  exclusive: {},
151
156
  inclusive: {},
157
+ render: {},
152
158
  counts: {},
153
159
  writes: {},
154
160
  displayNames: {},
@@ -211,22 +217,33 @@ var ReactDefaultPerf = {
211
217
  args[0] :
212
218
  this._rootNodeID;
213
219
  var isRender = fnName === '_renderValidatedComponent';
220
+ var isMount = fnName === 'mountComponent';
221
+
222
+ var mountStack = ReactDefaultPerf._mountStack;
214
223
  var entry = ReactDefaultPerf._allMeasurements[
215
224
  ReactDefaultPerf._allMeasurements.length - 1
216
225
  ];
217
226
 
218
227
  if (isRender) {
219
- entry.counts[rootNodeID] = entry.counts[rootNodeID] || 0;
220
- entry.counts[rootNodeID] += 1;
228
+ addValue(entry.counts, rootNodeID, 1);
229
+ } else if (isMount) {
230
+ mountStack.push(0);
221
231
  }
222
232
 
223
233
  start = performanceNow();
224
234
  rv = func.apply(this, args);
225
235
  totalTime = performanceNow() - start;
226
236
 
227
- var typeOfLog = isRender ? entry.exclusive : entry.inclusive;
228
- typeOfLog[rootNodeID] = typeOfLog[rootNodeID] || 0;
229
- typeOfLog[rootNodeID] += totalTime;
237
+ if (isRender) {
238
+ addValue(entry.render, rootNodeID, totalTime);
239
+ } else if (isMount) {
240
+ var subMountTime = mountStack.pop();
241
+ mountStack[mountStack.length - 1] += totalTime;
242
+ addValue(entry.exclusive, rootNodeID, totalTime - subMountTime);
243
+ addValue(entry.inclusive, rootNodeID, totalTime);
244
+ } else {
245
+ addValue(entry.inclusive, rootNodeID, totalTime);
246
+ }
230
247
 
231
248
  entry.displayNames[rootNodeID] = {
232
249
  current: this.constructor.displayName,
@@ -80,8 +80,12 @@ function getExclusiveSummary(measurements) {
80
80
  componentName: displayName,
81
81
  inclusive: 0,
82
82
  exclusive: 0,
83
+ render: 0,
83
84
  count: 0
84
85
  };
86
+ if (measurement.render[id]) {
87
+ candidates[displayName].render += measurement.render[id];
88
+ }
85
89
  if (measurement.exclusive[id]) {
86
90
  candidates[displayName].exclusive += measurement.exclusive[id];
87
91
  }
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Copyright 2014 Facebook, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @providesModule ReactDescriptor
17
+ */
18
+
19
+ "use strict";
20
+
21
+ var ReactContext = require("./ReactContext");
22
+ var ReactCurrentOwner = require("./ReactCurrentOwner");
23
+
24
+ var merge = require("./merge");
25
+ var warning = require("./warning");
26
+
27
+ /**
28
+ * Warn for mutations.
29
+ *
30
+ * @internal
31
+ * @param {object} object
32
+ * @param {string} key
33
+ */
34
+ function defineWarningProperty(object, key) {
35
+ Object.defineProperty(object, key, {
36
+
37
+ configurable: false,
38
+ enumerable: true,
39
+
40
+ get: function() {
41
+ if (!this._store) {
42
+ return null;
43
+ }
44
+ return this._store[key];
45
+ },
46
+
47
+ set: function(value) {
48
+ ("production" !== process.env.NODE_ENV ? warning(
49
+ false,
50
+ 'Don\'t set the ' + key + ' property of the component. ' +
51
+ 'Mutate the existing props object instead.'
52
+ ) : null);
53
+ this._store[key] = value;
54
+ }
55
+
56
+ });
57
+ }
58
+
59
+ /**
60
+ * This is updated to true if the membrane is successfully created.
61
+ */
62
+ var useMutationMembrane = false;
63
+
64
+ /**
65
+ * Warn for mutations.
66
+ *
67
+ * @internal
68
+ * @param {object} descriptor
69
+ */
70
+ function defineMutationMembrane(prototype) {
71
+ try {
72
+ var pseudoFrozenProperties = {
73
+ props: true
74
+ };
75
+ for (var key in pseudoFrozenProperties) {
76
+ defineWarningProperty(prototype, key);
77
+ }
78
+ useMutationMembrane = true;
79
+ } catch (x) {
80
+ // IE will fail on defineProperty
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Transfer static properties from the source to the target. Functions are
86
+ * rebound to have this reflect the original source.
87
+ */
88
+ function proxyStaticMethods(target, source) {
89
+ if (typeof source !== 'function') {
90
+ return;
91
+ }
92
+ for (var key in source) {
93
+ if (source.hasOwnProperty(key)) {
94
+ var value = source[key];
95
+ if (typeof value === 'function') {
96
+ var bound = value.bind(source);
97
+ // Copy any properties defined on the function, such as `isRequired` on
98
+ // a PropTypes validator. (mergeInto refuses to work on functions.)
99
+ for (var k in value) {
100
+ if (value.hasOwnProperty(k)) {
101
+ bound[k] = value[k];
102
+ }
103
+ }
104
+ target[key] = bound;
105
+ } else {
106
+ target[key] = value;
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Base constructor for all React descriptors. This is only used to make this
114
+ * work with a dynamic instanceof check. Nothing should live on this prototype.
115
+ *
116
+ * @param {*} type
117
+ * @internal
118
+ */
119
+ var ReactDescriptor = function() {};
120
+
121
+ if ("production" !== process.env.NODE_ENV) {
122
+ defineMutationMembrane(ReactDescriptor.prototype);
123
+ }
124
+
125
+ ReactDescriptor.createFactory = function(type) {
126
+
127
+ var descriptorPrototype = Object.create(ReactDescriptor.prototype);
128
+
129
+ var factory = function(props, children) {
130
+ // For consistency we currently allocate a new object for every descriptor.
131
+ // This protects the descriptor from being mutated by the original props
132
+ // object being mutated. It also protects the original props object from
133
+ // being mutated by children arguments and default props. This behavior
134
+ // comes with a performance cost and could be deprecated in the future.
135
+ // It could also be optimized with a smarter JSX transform.
136
+ if (props == null) {
137
+ props = {};
138
+ } else if (typeof props === 'object') {
139
+ props = merge(props);
140
+ }
141
+
142
+ // Children can be more than one argument, and those are transferred onto
143
+ // the newly allocated props object.
144
+ var childrenLength = arguments.length - 1;
145
+ if (childrenLength === 1) {
146
+ props.children = children;
147
+ } else if (childrenLength > 1) {
148
+ var childArray = Array(childrenLength);
149
+ for (var i = 0; i < childrenLength; i++) {
150
+ childArray[i] = arguments[i + 1];
151
+ }
152
+ props.children = childArray;
153
+ }
154
+
155
+ // Initialize the descriptor object
156
+ var descriptor = Object.create(descriptorPrototype);
157
+
158
+ // Record the component responsible for creating this descriptor.
159
+ descriptor._owner = ReactCurrentOwner.current;
160
+
161
+ // TODO: Deprecate withContext, and then the context becomes accessible
162
+ // through the owner.
163
+ descriptor._context = ReactContext.current;
164
+
165
+ if ("production" !== process.env.NODE_ENV) {
166
+ // The validation flag and props are currently mutative. We put them on
167
+ // an external backing store so that we can freeze the whole object.
168
+ // This can be replaced with a WeakMap once they are implemented in
169
+ // commonly used development environments.
170
+ descriptor._store = { validated: false, props: props };
171
+
172
+ // We're not allowed to set props directly on the object so we early
173
+ // return and rely on the prototype membrane to forward to the backing
174
+ // store.
175
+ if (useMutationMembrane) {
176
+ Object.freeze(descriptor);
177
+ return descriptor;
178
+ }
179
+ }
180
+
181
+ descriptor.props = props;
182
+ return descriptor;
183
+ };
184
+
185
+ // Currently we expose the prototype of the descriptor so that
186
+ // <Foo /> instanceof Foo works. This is controversial pattern.
187
+ factory.prototype = descriptorPrototype;
188
+
189
+ // Expose the type on the factory and the prototype so that it can be
190
+ // easily accessed on descriptors. E.g. <Foo />.type === Foo.type and for
191
+ // static methods like <Foo />.type.staticMethod();
192
+ // This should not be named constructor since this may not be the function
193
+ // that created the descriptor, and it may not even be a constructor.
194
+ factory.type = type;
195
+ descriptorPrototype.type = type;
196
+
197
+ proxyStaticMethods(factory, type);
198
+
199
+ // Expose a unique constructor on the prototype is that this works with type
200
+ // systems that compare constructor properties: <Foo />.constructor === Foo
201
+ // This may be controversial since it requires a known factory function.
202
+ descriptorPrototype.constructor = factory;
203
+
204
+ return factory;
205
+
206
+ };
207
+
208
+ ReactDescriptor.cloneAndReplaceProps = function(oldDescriptor, newProps) {
209
+ var newDescriptor = Object.create(oldDescriptor.constructor.prototype);
210
+ // It's important that this property order matches the hidden class of the
211
+ // original descriptor to maintain perf.
212
+ newDescriptor._owner = oldDescriptor._owner;
213
+ newDescriptor._context = oldDescriptor._context;
214
+
215
+ if ("production" !== process.env.NODE_ENV) {
216
+ newDescriptor._store = {
217
+ validated: oldDescriptor._store.validated,
218
+ props: newProps
219
+ };
220
+ if (useMutationMembrane) {
221
+ Object.freeze(newDescriptor);
222
+ return newDescriptor;
223
+ }
224
+ }
225
+
226
+ newDescriptor.props = newProps;
227
+ return newDescriptor;
228
+ };
229
+
230
+ /**
231
+ * Checks if a value is a valid descriptor constructor.
232
+ *
233
+ * @param {*}
234
+ * @return {boolean}
235
+ * @public
236
+ */
237
+ ReactDescriptor.isValidFactory = function(factory) {
238
+ return typeof factory === 'function' &&
239
+ factory.prototype instanceof ReactDescriptor;
240
+ };
241
+
242
+ /**
243
+ * @param {?object} object
244
+ * @return {boolean} True if `object` is a valid component.
245
+ * @final
246
+ */
247
+ ReactDescriptor.isValidDescriptor = function(object) {
248
+ return object instanceof ReactDescriptor;
249
+ };
250
+
251
+ module.exports = ReactDescriptor;