react 0.12.2 → 0.13.0-alpha.1

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 (77) hide show
  1. package/dist/JSXTransformer.js +6 -4
  2. package/dist/react-with-addons.js +4022 -3267
  3. package/dist/react-with-addons.min.js +6 -6
  4. package/dist/react.js +3853 -3358
  5. package/dist/react.min.js +6 -6
  6. package/lib/BeforeInputEventPlugin.js +388 -111
  7. package/lib/CSSPropertyOperations.js +20 -0
  8. package/lib/ChangeEventPlugin.js +2 -2
  9. package/lib/Danger.js +1 -1
  10. package/lib/DefaultEventPluginOrder.js +0 -1
  11. package/lib/ExecutionEnvironment.js +2 -3
  12. package/lib/FallbackCompositionState.js +87 -0
  13. package/lib/HTMLDOMPropertyConfig.js +1 -0
  14. package/lib/Object.assign.js +3 -1
  15. package/lib/React.js +14 -49
  16. package/lib/ReactBrowserComponentMixin.js +2 -12
  17. package/lib/ReactBrowserEventEmitter.js +2 -4
  18. package/lib/ReactCSSTransitionGroup.js +3 -0
  19. package/lib/ReactCSSTransitionGroupChild.js +8 -0
  20. package/lib/ReactChildReconciler.js +121 -0
  21. package/lib/ReactClass.js +916 -0
  22. package/lib/ReactComponent.js +36 -286
  23. package/lib/ReactComponentBrowserEnvironment.js +9 -82
  24. package/lib/ReactComponentEnvironment.js +57 -0
  25. package/lib/ReactCompositeComponent.js +608 -1026
  26. package/lib/ReactContext.js +5 -1
  27. package/lib/ReactDOM.js +2 -7
  28. package/lib/ReactDOMButton.js +4 -5
  29. package/lib/ReactDOMComponent.js +97 -69
  30. package/lib/ReactDOMForm.js +4 -5
  31. package/lib/ReactDOMIDOperations.js +55 -73
  32. package/lib/ReactDOMImg.js +3 -5
  33. package/lib/ReactDOMInput.js +4 -5
  34. package/lib/ReactDOMOption.js +4 -5
  35. package/lib/ReactDOMSelect.js +55 -63
  36. package/lib/ReactDOMSelection.js +5 -1
  37. package/lib/{ReactTextComponent.js → ReactDOMTextComponent.js} +54 -34
  38. package/lib/ReactDOMTextarea.js +4 -5
  39. package/lib/ReactDefaultInjection.js +13 -7
  40. package/lib/ReactDefaultPerf.js +6 -5
  41. package/lib/ReactDefaultPerfAnalysis.js +1 -1
  42. package/lib/ReactElement.js +17 -11
  43. package/lib/ReactElementValidator.js +74 -37
  44. package/lib/ReactEmptyComponent.js +17 -10
  45. package/lib/ReactInjection.js +6 -4
  46. package/lib/ReactInputSelection.js +2 -3
  47. package/lib/ReactInstanceMap.js +47 -0
  48. package/lib/ReactMount.js +193 -64
  49. package/lib/ReactMultiChild.js +32 -42
  50. package/lib/ReactNativeComponent.js +45 -8
  51. package/lib/ReactOwner.js +3 -47
  52. package/lib/ReactPerf.js +20 -0
  53. package/lib/ReactPropTransferer.js +0 -55
  54. package/lib/ReactPropTypes.js +1 -17
  55. package/lib/ReactRef.js +96 -0
  56. package/lib/ReactServerRendering.js +3 -2
  57. package/lib/ReactTestUtils.js +82 -25
  58. package/lib/ReactTransitionGroup.js +47 -6
  59. package/lib/ReactUpdates.js +43 -42
  60. package/lib/SyntheticMouseEvent.js +1 -3
  61. package/lib/ViewportMetrics.js +1 -4
  62. package/lib/accumulate.js +47 -0
  63. package/lib/cloneWithProps.js +2 -2
  64. package/lib/copyProperties.js +2 -0
  65. package/lib/createFullPageComponent.js +2 -2
  66. package/lib/findDOMNode.js +52 -0
  67. package/lib/flattenChildren.js +1 -14
  68. package/lib/getIteratorFn.js +42 -0
  69. package/lib/instantiateReactComponent.js +88 -65
  70. package/lib/isNode.js +3 -4
  71. package/lib/isTextInputElement.js +1 -2
  72. package/lib/shouldUpdateReactComponent.js +13 -5
  73. package/lib/traverseAllChildren.js +110 -54
  74. package/package.json +1 -1
  75. package/lib/CompositionEventPlugin.js +0 -257
  76. package/lib/ReactLegacyElement.js +0 -243
  77. package/lib/deprecated.js +0 -47
@@ -0,0 +1,916 @@
1
+ /**
2
+ * Copyright 2013-2014, 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
+ * @providesModule ReactClass
10
+ */
11
+
12
+ "use strict";
13
+
14
+ var ReactElement = require("./ReactElement");
15
+ var ReactErrorUtils = require("./ReactErrorUtils");
16
+ var ReactInstanceMap = require("./ReactInstanceMap");
17
+ var ReactPropTypeLocations = require("./ReactPropTypeLocations");
18
+ var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
19
+
20
+ var assign = require("./Object.assign");
21
+ var invariant = require("./invariant");
22
+ var keyMirror = require("./keyMirror");
23
+ var keyOf = require("./keyOf");
24
+ var monitorCodeUse = require("./monitorCodeUse");
25
+ var warning = require("./warning");
26
+
27
+ var MIXINS_KEY = keyOf({mixins: null});
28
+
29
+ /**
30
+ * Policies that describe methods in `ReactClassInterface`.
31
+ */
32
+ var SpecPolicy = keyMirror({
33
+ /**
34
+ * These methods may be defined only once by the class specification or mixin.
35
+ */
36
+ DEFINE_ONCE: null,
37
+ /**
38
+ * These methods may be defined by both the class specification and mixins.
39
+ * Subsequent definitions will be chained. These methods must return void.
40
+ */
41
+ DEFINE_MANY: null,
42
+ /**
43
+ * These methods are overriding the base class.
44
+ */
45
+ OVERRIDE_BASE: null,
46
+ /**
47
+ * These methods are similar to DEFINE_MANY, except we assume they return
48
+ * objects. We try to merge the keys of the return values of all the mixed in
49
+ * functions. If there is a key conflict we throw.
50
+ */
51
+ DEFINE_MANY_MERGED: null
52
+ });
53
+
54
+
55
+ var injectedMixins = [];
56
+
57
+ /**
58
+ * Composite components are higher-level components that compose other composite
59
+ * or native components.
60
+ *
61
+ * To create a new type of `ReactClass`, pass a specification of
62
+ * your new class to `React.createClass`. The only requirement of your class
63
+ * specification is that you implement a `render` method.
64
+ *
65
+ * var MyComponent = React.createClass({
66
+ * render: function() {
67
+ * return <div>Hello World</div>;
68
+ * }
69
+ * });
70
+ *
71
+ * The class specification supports a specific protocol of methods that have
72
+ * special meaning (e.g. `render`). See `ReactClassInterface` for
73
+ * more the comprehensive protocol. Any other properties and methods in the
74
+ * class specification will available on the prototype.
75
+ *
76
+ * @interface ReactClassInterface
77
+ * @internal
78
+ */
79
+ var ReactClassInterface = {
80
+
81
+ /**
82
+ * An array of Mixin objects to include when defining your component.
83
+ *
84
+ * @type {array}
85
+ * @optional
86
+ */
87
+ mixins: SpecPolicy.DEFINE_MANY,
88
+
89
+ /**
90
+ * An object containing properties and methods that should be defined on
91
+ * the component's constructor instead of its prototype (static methods).
92
+ *
93
+ * @type {object}
94
+ * @optional
95
+ */
96
+ statics: SpecPolicy.DEFINE_MANY,
97
+
98
+ /**
99
+ * Definition of prop types for this component.
100
+ *
101
+ * @type {object}
102
+ * @optional
103
+ */
104
+ propTypes: SpecPolicy.DEFINE_MANY,
105
+
106
+ /**
107
+ * Definition of context types for this component.
108
+ *
109
+ * @type {object}
110
+ * @optional
111
+ */
112
+ contextTypes: SpecPolicy.DEFINE_MANY,
113
+
114
+ /**
115
+ * Definition of context types this component sets for its children.
116
+ *
117
+ * @type {object}
118
+ * @optional
119
+ */
120
+ childContextTypes: SpecPolicy.DEFINE_MANY,
121
+
122
+ // ==== Definition methods ====
123
+
124
+ /**
125
+ * Invoked when the component is mounted. Values in the mapping will be set on
126
+ * `this.props` if that prop is not specified (i.e. using an `in` check).
127
+ *
128
+ * This method is invoked before `getInitialState` and therefore cannot rely
129
+ * on `this.state` or use `this.setState`.
130
+ *
131
+ * @return {object}
132
+ * @optional
133
+ */
134
+ getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED,
135
+
136
+ /**
137
+ * Invoked once before the component is mounted. The return value will be used
138
+ * as the initial value of `this.state`.
139
+ *
140
+ * getInitialState: function() {
141
+ * return {
142
+ * isOn: false,
143
+ * fooBaz: new BazFoo()
144
+ * }
145
+ * }
146
+ *
147
+ * @return {object}
148
+ * @optional
149
+ */
150
+ getInitialState: SpecPolicy.DEFINE_MANY_MERGED,
151
+
152
+ /**
153
+ * @return {object}
154
+ * @optional
155
+ */
156
+ getChildContext: SpecPolicy.DEFINE_MANY_MERGED,
157
+
158
+ /**
159
+ * Uses props from `this.props` and state from `this.state` to render the
160
+ * structure of the component.
161
+ *
162
+ * No guarantees are made about when or how often this method is invoked, so
163
+ * it must not have side effects.
164
+ *
165
+ * render: function() {
166
+ * var name = this.props.name;
167
+ * return <div>Hello, {name}!</div>;
168
+ * }
169
+ *
170
+ * @return {ReactComponent}
171
+ * @nosideeffects
172
+ * @required
173
+ */
174
+ render: SpecPolicy.DEFINE_ONCE,
175
+
176
+
177
+
178
+ // ==== Delegate methods ====
179
+
180
+ /**
181
+ * Invoked when the component is initially created and about to be mounted.
182
+ * This may have side effects, but any external subscriptions or data created
183
+ * by this method must be cleaned up in `componentWillUnmount`.
184
+ *
185
+ * @optional
186
+ */
187
+ componentWillMount: SpecPolicy.DEFINE_MANY,
188
+
189
+ /**
190
+ * Invoked when the component has been mounted and has a DOM representation.
191
+ * However, there is no guarantee that the DOM node is in the document.
192
+ *
193
+ * Use this as an opportunity to operate on the DOM when the component has
194
+ * been mounted (initialized and rendered) for the first time.
195
+ *
196
+ * @param {DOMElement} rootNode DOM element representing the component.
197
+ * @optional
198
+ */
199
+ componentDidMount: SpecPolicy.DEFINE_MANY,
200
+
201
+ /**
202
+ * Invoked before the component receives new props.
203
+ *
204
+ * Use this as an opportunity to react to a prop transition by updating the
205
+ * state using `this.setState`. Current props are accessed via `this.props`.
206
+ *
207
+ * componentWillReceiveProps: function(nextProps, nextContext) {
208
+ * this.setState({
209
+ * likesIncreasing: nextProps.likeCount > this.props.likeCount
210
+ * });
211
+ * }
212
+ *
213
+ * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
214
+ * transition may cause a state change, but the opposite is not true. If you
215
+ * need it, you are probably looking for `componentWillUpdate`.
216
+ *
217
+ * @param {object} nextProps
218
+ * @optional
219
+ */
220
+ componentWillReceiveProps: SpecPolicy.DEFINE_MANY,
221
+
222
+ /**
223
+ * Invoked while deciding if the component should be updated as a result of
224
+ * receiving new props, state and/or context.
225
+ *
226
+ * Use this as an opportunity to `return false` when you're certain that the
227
+ * transition to the new props/state/context will not require a component
228
+ * update.
229
+ *
230
+ * shouldComponentUpdate: function(nextProps, nextState, nextContext) {
231
+ * return !equal(nextProps, this.props) ||
232
+ * !equal(nextState, this.state) ||
233
+ * !equal(nextContext, this.context);
234
+ * }
235
+ *
236
+ * @param {object} nextProps
237
+ * @param {?object} nextState
238
+ * @param {?object} nextContext
239
+ * @return {boolean} True if the component should update.
240
+ * @optional
241
+ */
242
+ shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,
243
+
244
+ /**
245
+ * Invoked when the component is about to update due to a transition from
246
+ * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState`
247
+ * and `nextContext`.
248
+ *
249
+ * Use this as an opportunity to perform preparation before an update occurs.
250
+ *
251
+ * NOTE: You **cannot** use `this.setState()` in this method.
252
+ *
253
+ * @param {object} nextProps
254
+ * @param {?object} nextState
255
+ * @param {?object} nextContext
256
+ * @param {ReactReconcileTransaction} transaction
257
+ * @optional
258
+ */
259
+ componentWillUpdate: SpecPolicy.DEFINE_MANY,
260
+
261
+ /**
262
+ * Invoked when the component's DOM representation has been updated.
263
+ *
264
+ * Use this as an opportunity to operate on the DOM when the component has
265
+ * been updated.
266
+ *
267
+ * @param {object} prevProps
268
+ * @param {?object} prevState
269
+ * @param {?object} prevContext
270
+ * @param {DOMElement} rootNode DOM element representing the component.
271
+ * @optional
272
+ */
273
+ componentDidUpdate: SpecPolicy.DEFINE_MANY,
274
+
275
+ /**
276
+ * Invoked when the component is about to be removed from its parent and have
277
+ * its DOM representation destroyed.
278
+ *
279
+ * Use this as an opportunity to deallocate any external resources.
280
+ *
281
+ * NOTE: There is no `componentDidUnmount` since your component will have been
282
+ * destroyed by that point.
283
+ *
284
+ * @optional
285
+ */
286
+ componentWillUnmount: SpecPolicy.DEFINE_MANY,
287
+
288
+
289
+
290
+ // ==== Advanced methods ====
291
+
292
+ /**
293
+ * Updates the component's currently mounted DOM representation.
294
+ *
295
+ * By default, this implements React's rendering and reconciliation algorithm.
296
+ * Sophisticated clients may wish to override this.
297
+ *
298
+ * @param {ReactReconcileTransaction} transaction
299
+ * @internal
300
+ * @overridable
301
+ */
302
+ updateComponent: SpecPolicy.OVERRIDE_BASE
303
+
304
+ };
305
+
306
+ /**
307
+ * Mapping from class specification keys to special processing functions.
308
+ *
309
+ * Although these are declared like instance properties in the specification
310
+ * when defining classes using `React.createClass`, they are actually static
311
+ * and are accessible on the constructor instead of the prototype. Despite
312
+ * being static, they must be defined outside of the "statics" key under
313
+ * which all other static methods are defined.
314
+ */
315
+ var RESERVED_SPEC_KEYS = {
316
+ displayName: function(Constructor, displayName) {
317
+ Constructor.displayName = displayName;
318
+ },
319
+ mixins: function(Constructor, mixins) {
320
+ if (mixins) {
321
+ for (var i = 0; i < mixins.length; i++) {
322
+ mixSpecIntoComponent(Constructor, mixins[i]);
323
+ }
324
+ }
325
+ },
326
+ childContextTypes: function(Constructor, childContextTypes) {
327
+ validateTypeDef(
328
+ Constructor,
329
+ childContextTypes,
330
+ ReactPropTypeLocations.childContext
331
+ );
332
+ Constructor.childContextTypes = assign(
333
+ {},
334
+ Constructor.childContextTypes,
335
+ childContextTypes
336
+ );
337
+ },
338
+ contextTypes: function(Constructor, contextTypes) {
339
+ validateTypeDef(
340
+ Constructor,
341
+ contextTypes,
342
+ ReactPropTypeLocations.context
343
+ );
344
+ Constructor.contextTypes = assign(
345
+ {},
346
+ Constructor.contextTypes,
347
+ contextTypes
348
+ );
349
+ },
350
+ /**
351
+ * Special case getDefaultProps which should move into statics but requires
352
+ * automatic merging.
353
+ */
354
+ getDefaultProps: function(Constructor, getDefaultProps) {
355
+ if (Constructor.getDefaultProps) {
356
+ Constructor.getDefaultProps = createMergedResultFunction(
357
+ Constructor.getDefaultProps,
358
+ getDefaultProps
359
+ );
360
+ } else {
361
+ Constructor.getDefaultProps = getDefaultProps;
362
+ }
363
+ },
364
+ propTypes: function(Constructor, propTypes) {
365
+ validateTypeDef(
366
+ Constructor,
367
+ propTypes,
368
+ ReactPropTypeLocations.prop
369
+ );
370
+ Constructor.propTypes = assign(
371
+ {},
372
+ Constructor.propTypes,
373
+ propTypes
374
+ );
375
+ },
376
+ statics: function(Constructor, statics) {
377
+ mixStaticSpecIntoComponent(Constructor, statics);
378
+ }
379
+ };
380
+
381
+ function validateTypeDef(Constructor, typeDef, location) {
382
+ for (var propName in typeDef) {
383
+ if (typeDef.hasOwnProperty(propName)) {
384
+ ("production" !== process.env.NODE_ENV ? invariant(
385
+ typeof typeDef[propName] == 'function',
386
+ '%s: %s type `%s` is invalid; it must be a function, usually from ' +
387
+ 'React.PropTypes.',
388
+ Constructor.displayName || 'ReactClass',
389
+ ReactPropTypeLocationNames[location],
390
+ propName
391
+ ) : invariant(typeof typeDef[propName] == 'function'));
392
+ }
393
+ }
394
+ }
395
+
396
+ function validateMethodOverride(proto, name) {
397
+ var specPolicy = ReactClassInterface.hasOwnProperty(name) ?
398
+ ReactClassInterface[name] :
399
+ null;
400
+
401
+ // Disallow overriding of base class methods unless explicitly allowed.
402
+ if (ReactClassMixin.hasOwnProperty(name)) {
403
+ ("production" !== process.env.NODE_ENV ? invariant(
404
+ specPolicy === SpecPolicy.OVERRIDE_BASE,
405
+ 'ReactClassInterface: You are attempting to override ' +
406
+ '`%s` from your class specification. Ensure that your method names ' +
407
+ 'do not overlap with React methods.',
408
+ name
409
+ ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE));
410
+ }
411
+
412
+ // Disallow defining methods more than once unless explicitly allowed.
413
+ if (proto.hasOwnProperty(name)) {
414
+ ("production" !== process.env.NODE_ENV ? invariant(
415
+ specPolicy === SpecPolicy.DEFINE_MANY ||
416
+ specPolicy === SpecPolicy.DEFINE_MANY_MERGED,
417
+ 'ReactClassInterface: You are attempting to define ' +
418
+ '`%s` on your component more than once. This conflict may be due ' +
419
+ 'to a mixin.',
420
+ name
421
+ ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY ||
422
+ specPolicy === SpecPolicy.DEFINE_MANY_MERGED));
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Mixin helper which handles policy validation and reserved
428
+ * specification keys when building React classses.
429
+ */
430
+ function mixSpecIntoComponent(Constructor, spec) {
431
+ if (!spec) {
432
+ return;
433
+ }
434
+
435
+ ("production" !== process.env.NODE_ENV ? invariant(
436
+ typeof spec !== 'function',
437
+ 'ReactClass: You\'re attempting to ' +
438
+ 'use a component class as a mixin. Instead, just use a regular object.'
439
+ ) : invariant(typeof spec !== 'function'));
440
+ ("production" !== process.env.NODE_ENV ? invariant(
441
+ !ReactElement.isValidElement(spec),
442
+ 'ReactClass: You\'re attempting to ' +
443
+ 'use a component as a mixin. Instead, just use a regular object.'
444
+ ) : invariant(!ReactElement.isValidElement(spec)));
445
+
446
+ var proto = Constructor.prototype;
447
+
448
+ // By handling mixins before any other properties, we ensure the same
449
+ // chaining order is applied to methods with DEFINE_MANY policy, whether
450
+ // mixins are listed before or after these methods in the spec.
451
+ if (spec.hasOwnProperty(MIXINS_KEY)) {
452
+ RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins);
453
+ }
454
+
455
+ for (var name in spec) {
456
+ if (!spec.hasOwnProperty(name)) {
457
+ continue;
458
+ }
459
+
460
+ if (name === MIXINS_KEY) {
461
+ // We have already handled mixins in a special case above
462
+ continue;
463
+ }
464
+
465
+ var property = spec[name];
466
+ validateMethodOverride(proto, name);
467
+
468
+ if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
469
+ RESERVED_SPEC_KEYS[name](Constructor, property);
470
+ } else {
471
+ // Setup methods on prototype:
472
+ // The following member methods should not be automatically bound:
473
+ // 1. Expected ReactClass methods (in the "interface").
474
+ // 2. Overridden methods (that were mixed in).
475
+ var isReactClassMethod =
476
+ ReactClassInterface.hasOwnProperty(name);
477
+ var isAlreadyDefined = proto.hasOwnProperty(name);
478
+ var markedDontBind = property && property.__reactDontBind;
479
+ var isFunction = typeof property === 'function';
480
+ var shouldAutoBind =
481
+ isFunction &&
482
+ !isReactClassMethod &&
483
+ !isAlreadyDefined &&
484
+ !markedDontBind;
485
+
486
+ if (shouldAutoBind) {
487
+ if (!proto.__reactAutoBindMap) {
488
+ proto.__reactAutoBindMap = {};
489
+ }
490
+ proto.__reactAutoBindMap[name] = property;
491
+ proto[name] = property;
492
+ } else {
493
+ if (isAlreadyDefined) {
494
+ var specPolicy = ReactClassInterface[name];
495
+
496
+ // These cases should already be caught by validateMethodOverride
497
+ ("production" !== process.env.NODE_ENV ? invariant(
498
+ isReactClassMethod && (
499
+ (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY)
500
+ ),
501
+ 'ReactClass: Unexpected spec policy %s for key %s ' +
502
+ 'when mixing in component specs.',
503
+ specPolicy,
504
+ name
505
+ ) : invariant(isReactClassMethod && (
506
+ (specPolicy === SpecPolicy.DEFINE_MANY_MERGED || specPolicy === SpecPolicy.DEFINE_MANY)
507
+ )));
508
+
509
+ // For methods which are defined more than once, call the existing
510
+ // methods before calling the new property, merging if appropriate.
511
+ if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) {
512
+ proto[name] = createMergedResultFunction(proto[name], property);
513
+ } else if (specPolicy === SpecPolicy.DEFINE_MANY) {
514
+ proto[name] = createChainedFunction(proto[name], property);
515
+ }
516
+ } else {
517
+ proto[name] = property;
518
+ if ("production" !== process.env.NODE_ENV) {
519
+ // Add verbose displayName to the function, which helps when looking
520
+ // at profiling tools.
521
+ if (typeof property === 'function' && spec.displayName) {
522
+ proto[name].displayName = spec.displayName + '_' + name;
523
+ }
524
+ }
525
+ }
526
+ }
527
+ }
528
+ }
529
+ }
530
+
531
+ function mixStaticSpecIntoComponent(Constructor, statics) {
532
+ if (!statics) {
533
+ return;
534
+ }
535
+ for (var name in statics) {
536
+ var property = statics[name];
537
+ if (!statics.hasOwnProperty(name)) {
538
+ continue;
539
+ }
540
+
541
+ var isReserved = name in RESERVED_SPEC_KEYS;
542
+ ("production" !== process.env.NODE_ENV ? invariant(
543
+ !isReserved,
544
+ 'ReactClass: You are attempting to define a reserved ' +
545
+ 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' +
546
+ 'as an instance property instead; it will still be accessible on the ' +
547
+ 'constructor.',
548
+ name
549
+ ) : invariant(!isReserved));
550
+
551
+ var isInherited = name in Constructor;
552
+ ("production" !== process.env.NODE_ENV ? invariant(
553
+ !isInherited,
554
+ 'ReactClass: You are attempting to define ' +
555
+ '`%s` on your component more than once. This conflict may be ' +
556
+ 'due to a mixin.',
557
+ name
558
+ ) : invariant(!isInherited));
559
+ Constructor[name] = property;
560
+ }
561
+ }
562
+
563
+ /**
564
+ * Merge two objects, but throw if both contain the same key.
565
+ *
566
+ * @param {object} one The first object, which is mutated.
567
+ * @param {object} two The second object
568
+ * @return {object} one after it has been mutated to contain everything in two.
569
+ */
570
+ function mergeIntoWithNoDuplicateKeys(one, two) {
571
+ ("production" !== process.env.NODE_ENV ? invariant(
572
+ one && two && typeof one === 'object' && typeof two === 'object',
573
+ 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.'
574
+ ) : invariant(one && two && typeof one === 'object' && typeof two === 'object'));
575
+
576
+ for (var key in two) {
577
+ if (two.hasOwnProperty(key)) {
578
+ ("production" !== process.env.NODE_ENV ? invariant(
579
+ one[key] === undefined,
580
+ 'mergeIntoWithNoDuplicateKeys(): ' +
581
+ 'Tried to merge two objects with the same key: `%s`. This conflict ' +
582
+ 'may be due to a mixin; in particular, this may be caused by two ' +
583
+ 'getInitialState() or getDefaultProps() methods returning objects ' +
584
+ 'with clashing keys.',
585
+ key
586
+ ) : invariant(one[key] === undefined));
587
+ one[key] = two[key];
588
+ }
589
+ }
590
+ return one;
591
+ }
592
+
593
+ /**
594
+ * Creates a function that invokes two functions and merges their return values.
595
+ *
596
+ * @param {function} one Function to invoke first.
597
+ * @param {function} two Function to invoke second.
598
+ * @return {function} Function that invokes the two argument functions.
599
+ * @private
600
+ */
601
+ function createMergedResultFunction(one, two) {
602
+ return function mergedResult() {
603
+ var a = one.apply(this, arguments);
604
+ var b = two.apply(this, arguments);
605
+ if (a == null) {
606
+ return b;
607
+ } else if (b == null) {
608
+ return a;
609
+ }
610
+ var c = {};
611
+ mergeIntoWithNoDuplicateKeys(c, a);
612
+ mergeIntoWithNoDuplicateKeys(c, b);
613
+ return c;
614
+ };
615
+ }
616
+
617
+ /**
618
+ * Creates a function that invokes two functions and ignores their return vales.
619
+ *
620
+ * @param {function} one Function to invoke first.
621
+ * @param {function} two Function to invoke second.
622
+ * @return {function} Function that invokes the two argument functions.
623
+ * @private
624
+ */
625
+ function createChainedFunction(one, two) {
626
+ return function chainedFunction() {
627
+ one.apply(this, arguments);
628
+ two.apply(this, arguments);
629
+ };
630
+ }
631
+
632
+ /**
633
+ * Binds a method to the component.
634
+ *
635
+ * @param {object} component Component whose method is going to be bound.
636
+ * @param {function} method Method to be bound.
637
+ * @return {function} The bound method.
638
+ */
639
+ function bindAutoBindMethod(component, method) {
640
+ var boundMethod = method.bind(component);
641
+ if ("production" !== process.env.NODE_ENV) {
642
+ boundMethod.__reactBoundContext = component;
643
+ boundMethod.__reactBoundMethod = method;
644
+ boundMethod.__reactBoundArguments = null;
645
+ var componentName = component.constructor.displayName;
646
+ var _bind = boundMethod.bind;
647
+ boundMethod.bind = function(newThis ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]);
648
+ // User is trying to bind() an autobound method; we effectively will
649
+ // ignore the value of "this" that the user is trying to use, so
650
+ // let's warn.
651
+ if (newThis !== component && newThis !== null) {
652
+ monitorCodeUse('react_bind_warning', { component: componentName });
653
+ console.warn(
654
+ 'bind(): React component methods may only be bound to the ' +
655
+ 'component instance. See ' + componentName
656
+ );
657
+ } else if (!args.length) {
658
+ monitorCodeUse('react_bind_warning', { component: componentName });
659
+ console.warn(
660
+ 'bind(): You are binding a component method to the component. ' +
661
+ 'React does this for you automatically in a high-performance ' +
662
+ 'way, so you can safely remove this call. See ' + componentName
663
+ );
664
+ return boundMethod;
665
+ }
666
+ var reboundMethod = _bind.apply(boundMethod, arguments);
667
+ reboundMethod.__reactBoundContext = component;
668
+ reboundMethod.__reactBoundMethod = method;
669
+ reboundMethod.__reactBoundArguments = args;
670
+ return reboundMethod;
671
+ };
672
+ }
673
+ return boundMethod;
674
+ }
675
+
676
+ /**
677
+ * Binds all auto-bound methods in a component.
678
+ *
679
+ * @param {object} component Component whose method is going to be bound.
680
+ */
681
+ function bindAutoBindMethods(component) {
682
+ for (var autoBindKey in component.__reactAutoBindMap) {
683
+ if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {
684
+ var method = component.__reactAutoBindMap[autoBindKey];
685
+ component[autoBindKey] = bindAutoBindMethod(
686
+ component,
687
+ ReactErrorUtils.guard(
688
+ method,
689
+ component.constructor.displayName + '.' + autoBindKey
690
+ )
691
+ );
692
+ }
693
+ }
694
+ }
695
+
696
+ /**
697
+ * @lends {ReactClass.prototype}
698
+ */
699
+ var ReactClassMixin = {
700
+
701
+ /**
702
+ * Sets a subset of the state. Always use this or `replaceState` to mutate
703
+ * state. You should treat `this.state` as immutable.
704
+ *
705
+ * There is no guarantee that `this.state` will be immediately updated, so
706
+ * accessing `this.state` after calling this method may return the old value.
707
+ *
708
+ * There is no guarantee that calls to `setState` will run synchronously,
709
+ * as they may eventually be batched together. You can provide an optional
710
+ * callback that will be executed when the call to setState is actually
711
+ * completed.
712
+ *
713
+ * @param {object} partialState Next partial state to be merged with state.
714
+ * @param {?function} callback Called after state is updated.
715
+ * @final
716
+ * @protected
717
+ */
718
+ setState: function(partialState, callback) {
719
+ ("production" !== process.env.NODE_ENV ? invariant(
720
+ typeof partialState === 'object' || partialState == null,
721
+ 'setState(...): takes an object of state variables to update.'
722
+ ) : invariant(typeof partialState === 'object' || partialState == null));
723
+ if ("production" !== process.env.NODE_ENV) {
724
+ ("production" !== process.env.NODE_ENV ? warning(
725
+ partialState != null,
726
+ 'setState(...): You passed an undefined or null state object; ' +
727
+ 'instead, use forceUpdate().'
728
+ ) : null);
729
+ }
730
+ var internalInstance = ReactInstanceMap.get(this);
731
+ ("production" !== process.env.NODE_ENV ? invariant(
732
+ internalInstance,
733
+ 'setState(...): Can only update a mounted or mounting component.'
734
+ ) : invariant(internalInstance));
735
+ internalInstance.setState(
736
+ partialState, callback && callback.bind(this)
737
+ );
738
+ },
739
+
740
+ /**
741
+ * TODO: This will be deprecated because state should always keep a consistent
742
+ * type signature and the only use case for this, is to avoid that.
743
+ */
744
+ replaceState: function(newState, callback) {
745
+ var internalInstance = ReactInstanceMap.get(this);
746
+ ("production" !== process.env.NODE_ENV ? invariant(
747
+ internalInstance,
748
+ 'replaceState(...): Can only update a mounted or mounting component.'
749
+ ) : invariant(internalInstance));
750
+ internalInstance.replaceState(
751
+ newState,
752
+ callback && callback.bind(this)
753
+ );
754
+ },
755
+
756
+ /**
757
+ * Forces an update. This should only be invoked when it is known with
758
+ * certainty that we are **not** in a DOM transaction.
759
+ *
760
+ * You may want to call this when you know that some deeper aspect of the
761
+ * component's state has changed but `setState` was not called.
762
+ *
763
+ * This will not invoke `shouldUpdateComponent`, but it will invoke
764
+ * `componentWillUpdate` and `componentDidUpdate`.
765
+ *
766
+ * @param {?function} callback Called after update is complete.
767
+ * @final
768
+ * @protected
769
+ */
770
+ forceUpdate: function(callback) {
771
+ var internalInstance = ReactInstanceMap.get(this);
772
+ ("production" !== process.env.NODE_ENV ? invariant(
773
+ internalInstance,
774
+ 'forceUpdate(...): Can only force an update on mounted or mounting ' +
775
+ 'components.'
776
+ ) : invariant(internalInstance));
777
+ internalInstance.forceUpdate(callback && callback.bind(this));
778
+ },
779
+
780
+ /**
781
+ * Checks whether or not this composite component is mounted.
782
+ * @return {boolean} True if mounted, false otherwise.
783
+ * @protected
784
+ * @final
785
+ */
786
+ isMounted: function() {
787
+ var internalInstance = ReactInstanceMap.get(this);
788
+ // In theory, isMounted is always true if it exists in the map.
789
+ // TODO: Remove the internal isMounted method.
790
+ return internalInstance && internalInstance.isMounted();
791
+ },
792
+
793
+ /**
794
+ * Sets a subset of the props.
795
+ *
796
+ * @param {object} partialProps Subset of the next props.
797
+ * @param {?function} callback Called after props are updated.
798
+ * @final
799
+ * @public
800
+ * @deprecated
801
+ */
802
+ setProps: function(partialProps, callback) {
803
+ var internalInstance = ReactInstanceMap.get(this);
804
+ ("production" !== process.env.NODE_ENV ? invariant(
805
+ internalInstance,
806
+ 'setProps(...): Can only update a mounted component.'
807
+ ) : invariant(internalInstance));
808
+ internalInstance.setProps(
809
+ partialProps,
810
+ callback && callback.bind(this)
811
+ );
812
+ },
813
+
814
+ /**
815
+ * Replace all the props.
816
+ *
817
+ * @param {object} newProps Subset of the next props.
818
+ * @param {?function} callback Called after props are updated.
819
+ * @final
820
+ * @public
821
+ * @deprecated
822
+ */
823
+ replaceProps: function(newProps, callback) {
824
+ ReactInstanceMap.get(this).replaceProps(
825
+ newProps,
826
+ callback && callback.bind(this)
827
+ );
828
+ }
829
+ };
830
+
831
+ var ReactClassBase = function() {};
832
+ assign(
833
+ ReactClassBase.prototype,
834
+ ReactClassMixin
835
+ );
836
+
837
+ /**
838
+ * Module for creating composite components.
839
+ *
840
+ * @class ReactClass
841
+ */
842
+ var ReactClass = {
843
+
844
+ /**
845
+ * Creates a composite component class given a class specification.
846
+ *
847
+ * @param {object} spec Class specification (which must define `render`).
848
+ * @return {function} Component constructor function.
849
+ * @public
850
+ */
851
+ createClass: function(spec) {
852
+ var Constructor = function(props) {
853
+ // This constructor is overridden by mocks. The argument is used
854
+ // by mocks to assert on what gets mounted.
855
+
856
+ // Wire up auto-binding
857
+ if (this.__reactAutoBindMap) {
858
+ bindAutoBindMethods(this);
859
+ }
860
+ };
861
+ Constructor.prototype = new ReactClassBase();
862
+ Constructor.prototype.constructor = Constructor;
863
+
864
+ injectedMixins.forEach(
865
+ mixSpecIntoComponent.bind(null, Constructor)
866
+ );
867
+
868
+ mixSpecIntoComponent(Constructor, spec);
869
+
870
+ // Initialize the defaultProps property after all mixins have been merged
871
+ if (Constructor.getDefaultProps) {
872
+ Constructor.defaultProps = Constructor.getDefaultProps();
873
+ }
874
+
875
+ ("production" !== process.env.NODE_ENV ? invariant(
876
+ Constructor.prototype.render,
877
+ 'createClass(...): Class specification must implement a `render` method.'
878
+ ) : invariant(Constructor.prototype.render));
879
+
880
+ if ("production" !== process.env.NODE_ENV) {
881
+ if (Constructor.prototype.componentShouldUpdate) {
882
+ monitorCodeUse(
883
+ 'react_component_should_update_warning',
884
+ { component: spec.displayName }
885
+ );
886
+ console.warn(
887
+ (spec.displayName || 'A component') + ' has a method called ' +
888
+ 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
889
+ 'The name is phrased as a question because the function is ' +
890
+ 'expected to return a value.'
891
+ );
892
+ }
893
+ }
894
+
895
+ // Reduce time spent doing lookups by setting these on the prototype.
896
+ for (var methodName in ReactClassInterface) {
897
+ if (!Constructor.prototype[methodName]) {
898
+ Constructor.prototype[methodName] = null;
899
+ }
900
+ }
901
+
902
+ // Legacy hook TODO: Warn if this is accessed
903
+ Constructor.type = Constructor;
904
+
905
+ return Constructor;
906
+ },
907
+
908
+ injection: {
909
+ injectMixin: function(mixin) {
910
+ injectedMixins.push(mixin);
911
+ }
912
+ }
913
+
914
+ };
915
+
916
+ module.exports = ReactClass;