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.
- package/README.md +3 -0
- package/dist/JSXTransformer.js +20344 -0
- package/dist/react-with-addons.js +20276 -0
- package/dist/react-with-addons.min.js +22 -0
- package/dist/react.js +18484 -0
- package/dist/react.min.js +21 -0
- package/lib/BeforeInputEventPlugin.js +222 -0
- package/lib/CSSPropertyOperations.js +3 -3
- package/lib/{ReactMountReady.js → CallbackQueue.js} +32 -24
- package/lib/ChangeEventPlugin.js +1 -1
- package/lib/CompositionEventPlugin.js +5 -1
- package/lib/DOMChildrenOperations.js +21 -14
- package/lib/DOMProperty.js +45 -17
- package/lib/DOMPropertyOperations.js +22 -10
- package/lib/DefaultEventPluginOrder.js +1 -0
- package/lib/EventConstants.js +1 -0
- package/lib/EventListener.js +5 -2
- package/lib/EventPluginHub.js +0 -5
- package/lib/EventPluginRegistry.js +6 -4
- package/lib/EventPluginUtils.js +11 -1
- package/lib/ExecutionEnvironment.js +8 -2
- package/lib/{DefaultDOMPropertyConfig.js → HTMLDOMPropertyConfig.js} +42 -49
- package/lib/LinkedValueUtils.js +21 -22
- package/lib/LocalEventTrapMixin.js +52 -0
- package/lib/React.js +57 -3
- package/lib/ReactBrowserComponentMixin.js +4 -0
- package/lib/{ReactEventEmitter.js → ReactBrowserEventEmitter.js} +115 -94
- package/lib/ReactCSSTransitionGroup.js +2 -0
- package/lib/ReactCSSTransitionGroupChild.js +2 -5
- package/lib/ReactChildren.js +31 -10
- package/lib/ReactComponent.js +88 -237
- package/lib/ReactComponentBrowserEnvironment.js +3 -2
- package/lib/ReactComponentWithPureRenderMixin.js +54 -0
- package/lib/ReactCompositeComponent.js +222 -384
- package/lib/ReactDOM.js +22 -18
- package/lib/ReactDOMComponent.js +26 -24
- package/lib/ReactDOMForm.js +5 -13
- package/lib/ReactDOMIDOperations.js +2 -31
- package/lib/ReactDOMImg.js +5 -14
- package/lib/ReactDOMSelect.js +16 -15
- package/lib/ReactDOMSelection.js +35 -10
- package/lib/ReactDOMTextarea.js +2 -4
- package/lib/ReactDefaultBatchingStrategy.js +3 -3
- package/lib/ReactDefaultInjection.js +18 -15
- package/lib/ReactDefaultPerf.js +28 -11
- package/lib/ReactDefaultPerfAnalysis.js +4 -0
- package/lib/ReactDescriptor.js +251 -0
- package/lib/ReactDescriptorValidator.js +283 -0
- package/lib/ReactEmptyComponent.js +78 -0
- package/lib/ReactEventEmitterMixin.js +1 -3
- package/lib/ReactEventListener.js +189 -0
- package/lib/ReactInjection.js +4 -2
- package/lib/ReactLink.js +24 -0
- package/lib/ReactMount.js +51 -19
- package/lib/ReactMultiChild.js +9 -11
- package/lib/ReactPropTransferer.js +44 -29
- package/lib/ReactPropTypes.js +226 -242
- package/lib/ReactPutListenerQueue.js +2 -2
- package/lib/ReactReconcileTransaction.js +14 -14
- package/lib/ReactServerRendering.js +5 -5
- package/lib/ReactServerRenderingTransaction.js +4 -5
- package/lib/ReactTestUtils.js +39 -21
- package/lib/ReactTextComponent.js +8 -22
- package/lib/ReactTransitionChildMapping.js +2 -2
- package/lib/ReactTransitionEvents.js +19 -0
- package/lib/ReactTransitionGroup.js +9 -6
- package/lib/ReactUpdates.js +139 -22
- package/lib/ReactWithAddons.js +5 -2
- package/lib/SVGDOMPropertyConfig.js +97 -0
- package/lib/SimpleEventPlugin.js +7 -1
- package/lib/SyntheticInputEvent.js +52 -0
- package/lib/SyntheticKeyboardEvent.js +33 -4
- package/lib/SyntheticMouseEvent.js +3 -0
- package/lib/SyntheticTouchEvent.js +4 -1
- package/lib/SyntheticUIEvent.js +24 -2
- package/lib/Transaction.js +0 -32
- package/lib/cloneWithProps.js +3 -1
- package/lib/createFullPageComponent.js +1 -1
- package/lib/dangerousStyleValue.js +11 -5
- package/lib/escapeTextForBrowser.js +2 -3
- package/lib/flattenChildren.js +9 -7
- package/lib/getEventKey.js +35 -5
- package/lib/getEventModifierState.js +52 -0
- package/lib/getMarkupWrap.js +2 -0
- package/lib/getTextContentAccessor.js +1 -1
- package/lib/hyphenate.js +3 -0
- package/lib/hyphenateStyleName.js +46 -0
- package/lib/instantiateReactComponent.js +13 -21
- package/lib/invariant.js +17 -19
- package/lib/{objMap.js → mapObject.js} +8 -3
- package/lib/mergeHelpers.js +11 -0
- package/lib/mergeInto.js +3 -2
- package/lib/onlyChild.js +3 -3
- package/lib/performance.js +33 -0
- package/lib/performanceNow.js +5 -14
- package/lib/setInnerHTML.js +85 -0
- package/lib/shouldUpdateReactComponent.js +12 -29
- package/lib/toArray.js +1 -1
- package/lib/traverseAllChildren.js +7 -4
- package/lib/update.js +57 -45
- package/package.json +4 -3
- package/lib/ReactEventTopLevelCallback.js +0 -149
- package/lib/createObjectFrom.js +0 -61
- package/lib/objMapKeyVal.js +0 -47
|
@@ -28,6 +28,7 @@ var ReactReconcileTransaction = require("./ReactReconcileTransaction");
|
|
|
28
28
|
|
|
29
29
|
var getReactRootElementInContainer = require("./getReactRootElementInContainer");
|
|
30
30
|
var invariant = require("./invariant");
|
|
31
|
+
var setInnerHTML = require("./setInnerHTML");
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
var ELEMENT_NODE_TYPE = 1;
|
|
@@ -98,7 +99,7 @@ var ReactComponentBrowserEnvironment = {
|
|
|
98
99
|
'React attempted to use reuse markup in a container but the ' +
|
|
99
100
|
'checksum was invalid. This generally means that you are ' +
|
|
100
101
|
'using server rendering and the markup generated on the ' +
|
|
101
|
-
'server was not what the client was expecting. React injected' +
|
|
102
|
+
'server was not what the client was expecting. React injected ' +
|
|
102
103
|
'new markup to compensate which works but you have lost many ' +
|
|
103
104
|
'of the benefits of server rendering. Instead, figure out ' +
|
|
104
105
|
'why the markup being generated is different on the client ' +
|
|
@@ -116,7 +117,7 @@ var ReactComponentBrowserEnvironment = {
|
|
|
116
117
|
'See renderComponentToString() for server rendering.'
|
|
117
118
|
) : invariant(container.nodeType !== DOC_NODE_TYPE));
|
|
118
119
|
|
|
119
|
-
container
|
|
120
|
+
setInnerHTML(container, markup);
|
|
120
121
|
}
|
|
121
122
|
)
|
|
122
123
|
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013-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 ReactComponentWithPureRenderMixin
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
"use strict";
|
|
20
|
+
|
|
21
|
+
var shallowEqual = require("./shallowEqual");
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* If your React component's render function is "pure", e.g. it will render the
|
|
25
|
+
* same result given the same props and state, provide this Mixin for a
|
|
26
|
+
* considerable performance boost.
|
|
27
|
+
*
|
|
28
|
+
* Most React components have pure render functions.
|
|
29
|
+
*
|
|
30
|
+
* Example:
|
|
31
|
+
*
|
|
32
|
+
* var ReactComponentWithPureRenderMixin =
|
|
33
|
+
* require('ReactComponentWithPureRenderMixin');
|
|
34
|
+
* React.createClass({
|
|
35
|
+
* mixins: [ReactComponentWithPureRenderMixin],
|
|
36
|
+
*
|
|
37
|
+
* render: function() {
|
|
38
|
+
* return <div className={this.props.className}>foo</div>;
|
|
39
|
+
* }
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* Note: This only checks shallow equality for props and state. If these contain
|
|
43
|
+
* complex data structures this mixin may have false-negatives for deeper
|
|
44
|
+
* differences. Only mixin to components which have simple props and state, or
|
|
45
|
+
* use `forceUpdate()` when you know deep data structures have changed.
|
|
46
|
+
*/
|
|
47
|
+
var ReactComponentWithPureRenderMixin = {
|
|
48
|
+
shouldComponentUpdate: function(nextProps, nextState) {
|
|
49
|
+
return !shallowEqual(this.props, nextProps) ||
|
|
50
|
+
!shallowEqual(this.state, nextState);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
module.exports = ReactComponentWithPureRenderMixin;
|
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
var ReactComponent = require("./ReactComponent");
|
|
22
22
|
var ReactContext = require("./ReactContext");
|
|
23
23
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
24
|
+
var ReactDescriptor = require("./ReactDescriptor");
|
|
25
|
+
var ReactDescriptorValidator = require("./ReactDescriptorValidator");
|
|
26
|
+
var ReactEmptyComponent = require("./ReactEmptyComponent");
|
|
24
27
|
var ReactErrorUtils = require("./ReactErrorUtils");
|
|
25
28
|
var ReactOwner = require("./ReactOwner");
|
|
26
29
|
var ReactPerf = require("./ReactPerf");
|
|
@@ -35,7 +38,7 @@ var keyMirror = require("./keyMirror");
|
|
|
35
38
|
var merge = require("./merge");
|
|
36
39
|
var mixInto = require("./mixInto");
|
|
37
40
|
var monitorCodeUse = require("./monitorCodeUse");
|
|
38
|
-
var
|
|
41
|
+
var mapObject = require("./mapObject");
|
|
39
42
|
var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
|
|
40
43
|
var warning = require("./warning");
|
|
41
44
|
|
|
@@ -326,18 +329,17 @@ var ReactCompositeComponentInterface = {
|
|
|
326
329
|
* which all other static methods are defined.
|
|
327
330
|
*/
|
|
328
331
|
var RESERVED_SPEC_KEYS = {
|
|
329
|
-
displayName: function(
|
|
330
|
-
|
|
332
|
+
displayName: function(Constructor, displayName) {
|
|
333
|
+
Constructor.displayName = displayName;
|
|
331
334
|
},
|
|
332
|
-
mixins: function(
|
|
335
|
+
mixins: function(Constructor, mixins) {
|
|
333
336
|
if (mixins) {
|
|
334
337
|
for (var i = 0; i < mixins.length; i++) {
|
|
335
|
-
mixSpecIntoComponent(
|
|
338
|
+
mixSpecIntoComponent(Constructor, mixins[i]);
|
|
336
339
|
}
|
|
337
340
|
}
|
|
338
341
|
},
|
|
339
|
-
childContextTypes: function(
|
|
340
|
-
var Constructor = ConvenienceConstructor.componentConstructor;
|
|
342
|
+
childContextTypes: function(Constructor, childContextTypes) {
|
|
341
343
|
validateTypeDef(
|
|
342
344
|
Constructor,
|
|
343
345
|
childContextTypes,
|
|
@@ -348,8 +350,7 @@ var RESERVED_SPEC_KEYS = {
|
|
|
348
350
|
childContextTypes
|
|
349
351
|
);
|
|
350
352
|
},
|
|
351
|
-
contextTypes: function(
|
|
352
|
-
var Constructor = ConvenienceConstructor.componentConstructor;
|
|
353
|
+
contextTypes: function(Constructor, contextTypes) {
|
|
353
354
|
validateTypeDef(
|
|
354
355
|
Constructor,
|
|
355
356
|
contextTypes,
|
|
@@ -357,8 +358,21 @@ var RESERVED_SPEC_KEYS = {
|
|
|
357
358
|
);
|
|
358
359
|
Constructor.contextTypes = merge(Constructor.contextTypes, contextTypes);
|
|
359
360
|
},
|
|
360
|
-
|
|
361
|
-
|
|
361
|
+
/**
|
|
362
|
+
* Special case getDefaultProps which should move into statics but requires
|
|
363
|
+
* automatic merging.
|
|
364
|
+
*/
|
|
365
|
+
getDefaultProps: function(Constructor, getDefaultProps) {
|
|
366
|
+
if (Constructor.getDefaultProps) {
|
|
367
|
+
Constructor.getDefaultProps = createMergedResultFunction(
|
|
368
|
+
Constructor.getDefaultProps,
|
|
369
|
+
getDefaultProps
|
|
370
|
+
);
|
|
371
|
+
} else {
|
|
372
|
+
Constructor.getDefaultProps = getDefaultProps;
|
|
373
|
+
}
|
|
374
|
+
},
|
|
375
|
+
propTypes: function(Constructor, propTypes) {
|
|
362
376
|
validateTypeDef(
|
|
363
377
|
Constructor,
|
|
364
378
|
propTypes,
|
|
@@ -366,11 +380,20 @@ var RESERVED_SPEC_KEYS = {
|
|
|
366
380
|
);
|
|
367
381
|
Constructor.propTypes = merge(Constructor.propTypes, propTypes);
|
|
368
382
|
},
|
|
369
|
-
statics: function(
|
|
370
|
-
mixStaticSpecIntoComponent(
|
|
383
|
+
statics: function(Constructor, statics) {
|
|
384
|
+
mixStaticSpecIntoComponent(Constructor, statics);
|
|
371
385
|
}
|
|
372
386
|
};
|
|
373
387
|
|
|
388
|
+
function getDeclarationErrorAddendum(component) {
|
|
389
|
+
var owner = component._owner || null;
|
|
390
|
+
if (owner && owner.constructor && owner.constructor.displayName) {
|
|
391
|
+
return ' Check the render method of `' + owner.constructor.displayName +
|
|
392
|
+
'`.';
|
|
393
|
+
}
|
|
394
|
+
return '';
|
|
395
|
+
}
|
|
396
|
+
|
|
374
397
|
function validateTypeDef(Constructor, typeDef, location) {
|
|
375
398
|
for (var propName in typeDef) {
|
|
376
399
|
if (typeDef.hasOwnProperty(propName)) {
|
|
@@ -387,7 +410,9 @@ function validateTypeDef(Constructor, typeDef, location) {
|
|
|
387
410
|
}
|
|
388
411
|
|
|
389
412
|
function validateMethodOverride(proto, name) {
|
|
390
|
-
var specPolicy = ReactCompositeComponentInterface
|
|
413
|
+
var specPolicy = ReactCompositeComponentInterface.hasOwnProperty(name) ?
|
|
414
|
+
ReactCompositeComponentInterface[name] :
|
|
415
|
+
null;
|
|
391
416
|
|
|
392
417
|
// Disallow overriding of base class methods unless explicitly allowed.
|
|
393
418
|
if (ReactCompositeComponentMixin.hasOwnProperty(name)) {
|
|
@@ -437,19 +462,18 @@ function validateLifeCycleOnReplaceState(instance) {
|
|
|
437
462
|
* Custom version of `mixInto` which handles policy validation and reserved
|
|
438
463
|
* specification keys when building `ReactCompositeComponent` classses.
|
|
439
464
|
*/
|
|
440
|
-
function mixSpecIntoComponent(
|
|
465
|
+
function mixSpecIntoComponent(Constructor, spec) {
|
|
441
466
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
442
|
-
!
|
|
467
|
+
!ReactDescriptor.isValidFactory(spec),
|
|
443
468
|
'ReactCompositeComponent: You\'re attempting to ' +
|
|
444
469
|
'use a component class as a mixin. Instead, just use a regular object.'
|
|
445
|
-
) : invariant(!
|
|
470
|
+
) : invariant(!ReactDescriptor.isValidFactory(spec)));
|
|
446
471
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
447
|
-
!
|
|
472
|
+
!ReactDescriptor.isValidDescriptor(spec),
|
|
448
473
|
'ReactCompositeComponent: You\'re attempting to ' +
|
|
449
474
|
'use a component as a mixin. Instead, just use a regular object.'
|
|
450
|
-
) : invariant(!
|
|
475
|
+
) : invariant(!ReactDescriptor.isValidDescriptor(spec)));
|
|
451
476
|
|
|
452
|
-
var Constructor = ConvenienceConstructor.componentConstructor;
|
|
453
477
|
var proto = Constructor.prototype;
|
|
454
478
|
for (var name in spec) {
|
|
455
479
|
var property = spec[name];
|
|
@@ -460,20 +484,21 @@ function mixSpecIntoComponent(ConvenienceConstructor, spec) {
|
|
|
460
484
|
validateMethodOverride(proto, name);
|
|
461
485
|
|
|
462
486
|
if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
|
|
463
|
-
RESERVED_SPEC_KEYS[name](
|
|
487
|
+
RESERVED_SPEC_KEYS[name](Constructor, property);
|
|
464
488
|
} else {
|
|
465
489
|
// Setup methods on prototype:
|
|
466
490
|
// The following member methods should not be automatically bound:
|
|
467
491
|
// 1. Expected ReactCompositeComponent methods (in the "interface").
|
|
468
492
|
// 2. Overridden methods (that were mixed in).
|
|
469
|
-
var isCompositeComponentMethod =
|
|
470
|
-
|
|
493
|
+
var isCompositeComponentMethod =
|
|
494
|
+
ReactCompositeComponentInterface.hasOwnProperty(name);
|
|
495
|
+
var isAlreadyDefined = proto.hasOwnProperty(name);
|
|
471
496
|
var markedDontBind = property && property.__reactDontBind;
|
|
472
497
|
var isFunction = typeof property === 'function';
|
|
473
498
|
var shouldAutoBind =
|
|
474
499
|
isFunction &&
|
|
475
500
|
!isCompositeComponentMethod &&
|
|
476
|
-
!
|
|
501
|
+
!isAlreadyDefined &&
|
|
477
502
|
!markedDontBind;
|
|
478
503
|
|
|
479
504
|
if (shouldAutoBind) {
|
|
@@ -483,37 +508,60 @@ function mixSpecIntoComponent(ConvenienceConstructor, spec) {
|
|
|
483
508
|
proto.__reactAutoBindMap[name] = property;
|
|
484
509
|
proto[name] = property;
|
|
485
510
|
} else {
|
|
486
|
-
if (
|
|
511
|
+
if (isAlreadyDefined) {
|
|
512
|
+
var specPolicy = ReactCompositeComponentInterface[name];
|
|
513
|
+
|
|
514
|
+
// These cases should already be caught by validateMethodOverride
|
|
515
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
516
|
+
isCompositeComponentMethod && (
|
|
517
|
+
specPolicy === SpecPolicy.DEFINE_MANY_MERGED ||
|
|
518
|
+
specPolicy === SpecPolicy.DEFINE_MANY
|
|
519
|
+
),
|
|
520
|
+
'ReactCompositeComponent: Unexpected spec policy %s for key %s ' +
|
|
521
|
+
'when mixing in component specs.',
|
|
522
|
+
specPolicy,
|
|
523
|
+
name
|
|
524
|
+
) : invariant(isCompositeComponentMethod && (
|
|
525
|
+
specPolicy === SpecPolicy.DEFINE_MANY_MERGED ||
|
|
526
|
+
specPolicy === SpecPolicy.DEFINE_MANY
|
|
527
|
+
)));
|
|
528
|
+
|
|
487
529
|
// For methods which are defined more than once, call the existing
|
|
488
|
-
// methods before calling the new property.
|
|
489
|
-
if (
|
|
490
|
-
SpecPolicy.DEFINE_MANY_MERGED) {
|
|
530
|
+
// methods before calling the new property, merging if appropriate.
|
|
531
|
+
if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) {
|
|
491
532
|
proto[name] = createMergedResultFunction(proto[name], property);
|
|
492
|
-
} else {
|
|
533
|
+
} else if (specPolicy === SpecPolicy.DEFINE_MANY) {
|
|
493
534
|
proto[name] = createChainedFunction(proto[name], property);
|
|
494
535
|
}
|
|
495
536
|
} else {
|
|
496
537
|
proto[name] = property;
|
|
538
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
539
|
+
// Add verbose displayName to the function, which helps when looking
|
|
540
|
+
// at profiling tools.
|
|
541
|
+
if (typeof property === 'function' && spec.displayName) {
|
|
542
|
+
proto[name].displayName = spec.displayName + '_' + name;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
497
545
|
}
|
|
498
546
|
}
|
|
499
547
|
}
|
|
500
548
|
}
|
|
501
549
|
}
|
|
502
550
|
|
|
503
|
-
function mixStaticSpecIntoComponent(
|
|
551
|
+
function mixStaticSpecIntoComponent(Constructor, statics) {
|
|
504
552
|
if (!statics) {
|
|
505
553
|
return;
|
|
506
554
|
}
|
|
507
555
|
for (var name in statics) {
|
|
508
556
|
var property = statics[name];
|
|
509
557
|
if (!statics.hasOwnProperty(name)) {
|
|
510
|
-
|
|
558
|
+
continue;
|
|
511
559
|
}
|
|
512
560
|
|
|
513
|
-
var isInherited = name in
|
|
561
|
+
var isInherited = name in Constructor;
|
|
514
562
|
var result = property;
|
|
515
563
|
if (isInherited) {
|
|
516
|
-
var existingProperty =
|
|
564
|
+
var existingProperty = Constructor[name];
|
|
517
565
|
var existingType = typeof existingProperty;
|
|
518
566
|
var propertyType = typeof property;
|
|
519
567
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
@@ -526,8 +574,7 @@ function mixStaticSpecIntoComponent(ConvenienceConstructor, statics) {
|
|
|
526
574
|
) : invariant(existingType === 'function' && propertyType === 'function'));
|
|
527
575
|
result = createChainedFunction(existingProperty, property);
|
|
528
576
|
}
|
|
529
|
-
|
|
530
|
-
ConvenienceConstructor.componentConstructor[name] = result;
|
|
577
|
+
Constructor[name] = result;
|
|
531
578
|
}
|
|
532
579
|
}
|
|
533
580
|
|
|
@@ -544,7 +591,7 @@ function mergeObjectsWithNoDuplicateKeys(one, two) {
|
|
|
544
591
|
'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects'
|
|
545
592
|
) : invariant(one && two && typeof one === 'object' && typeof two === 'object'));
|
|
546
593
|
|
|
547
|
-
|
|
594
|
+
mapObject(two, function(value, key) {
|
|
548
595
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
549
596
|
one[key] === undefined,
|
|
550
597
|
'mergeObjectsWithNoDuplicateKeys(): ' +
|
|
@@ -592,203 +639,6 @@ function createChainedFunction(one, two) {
|
|
|
592
639
|
};
|
|
593
640
|
}
|
|
594
641
|
|
|
595
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
596
|
-
|
|
597
|
-
var unmountedPropertyWhitelist = {
|
|
598
|
-
constructor: true,
|
|
599
|
-
construct: true,
|
|
600
|
-
isOwnedBy: true, // should be deprecated but can have code mod (internal)
|
|
601
|
-
type: true,
|
|
602
|
-
props: true,
|
|
603
|
-
// currently private but belong on the descriptor and are valid for use
|
|
604
|
-
// inside the framework:
|
|
605
|
-
__keyValidated__: true,
|
|
606
|
-
_owner: true,
|
|
607
|
-
_currentContext: true
|
|
608
|
-
};
|
|
609
|
-
|
|
610
|
-
var componentInstanceProperties = {
|
|
611
|
-
__keyValidated__: true,
|
|
612
|
-
__keySetters: true,
|
|
613
|
-
_compositeLifeCycleState: true,
|
|
614
|
-
_currentContext: true,
|
|
615
|
-
_defaultProps: true,
|
|
616
|
-
_instance: true,
|
|
617
|
-
_lifeCycleState: true,
|
|
618
|
-
_mountDepth: true,
|
|
619
|
-
_owner: true,
|
|
620
|
-
_pendingCallbacks: true,
|
|
621
|
-
_pendingContext: true,
|
|
622
|
-
_pendingForceUpdate: true,
|
|
623
|
-
_pendingOwner: true,
|
|
624
|
-
_pendingProps: true,
|
|
625
|
-
_pendingState: true,
|
|
626
|
-
_renderedComponent: true,
|
|
627
|
-
_rootNodeID: true,
|
|
628
|
-
context: true,
|
|
629
|
-
props: true,
|
|
630
|
-
refs: true,
|
|
631
|
-
state: true,
|
|
632
|
-
|
|
633
|
-
// These are known instance properties coming from other sources
|
|
634
|
-
_pendingQueries: true,
|
|
635
|
-
_queryPropListeners: true,
|
|
636
|
-
queryParams: true
|
|
637
|
-
|
|
638
|
-
};
|
|
639
|
-
|
|
640
|
-
var hasWarnedOnComponentType = {};
|
|
641
|
-
|
|
642
|
-
var warningStackCounter = 0;
|
|
643
|
-
|
|
644
|
-
var issueMembraneWarning = function(instance, key) {
|
|
645
|
-
var isWhitelisted = unmountedPropertyWhitelist.hasOwnProperty(key);
|
|
646
|
-
if (warningStackCounter > 0 || isWhitelisted) {
|
|
647
|
-
return;
|
|
648
|
-
}
|
|
649
|
-
var name = instance.constructor.displayName || 'Unknown';
|
|
650
|
-
var owner = ReactCurrentOwner.current;
|
|
651
|
-
var ownerName = (owner && owner.constructor.displayName) || 'Unknown';
|
|
652
|
-
var warningKey = key + '|' + name + '|' + ownerName;
|
|
653
|
-
if (hasWarnedOnComponentType.hasOwnProperty(warningKey)) {
|
|
654
|
-
// We have already warned for this combination. Skip it this time.
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
hasWarnedOnComponentType[warningKey] = true;
|
|
658
|
-
|
|
659
|
-
var context = owner ? ' in ' + ownerName + '.' : ' at the top level.';
|
|
660
|
-
var staticMethodExample = '<' + name + ' />.type.' + key + '(...)';
|
|
661
|
-
|
|
662
|
-
monitorCodeUse('react_descriptor_property_access', { component: name });
|
|
663
|
-
console.warn(
|
|
664
|
-
'Invalid access to component property "' + key + '" on ' + name +
|
|
665
|
-
context + ' See http://fb.me/react-warning-descriptors .' +
|
|
666
|
-
' Use a static method instead: ' + staticMethodExample
|
|
667
|
-
);
|
|
668
|
-
};
|
|
669
|
-
|
|
670
|
-
var wrapInMembraneFunction = function(fn, thisBinding) {
|
|
671
|
-
if (fn.__reactMembraneFunction && fn.__reactMembraneSelf === thisBinding) {
|
|
672
|
-
return fn.__reactMembraneFunction;
|
|
673
|
-
}
|
|
674
|
-
return fn.__reactMembraneFunction = function() {
|
|
675
|
-
/**
|
|
676
|
-
* By getting this function, you've already received a warning. The
|
|
677
|
-
* internals of this function will likely cause more warnings. To avoid
|
|
678
|
-
* Spamming too much we disable any warning triggered inside of this
|
|
679
|
-
* stack.
|
|
680
|
-
*/
|
|
681
|
-
warningStackCounter++;
|
|
682
|
-
try {
|
|
683
|
-
// If the this binding is unchanged, we defer to the real component.
|
|
684
|
-
// This is important to keep some referential integrity in the
|
|
685
|
-
// internals. E.g. owner equality check.
|
|
686
|
-
var self = this === thisBinding ? this.__realComponentInstance : this;
|
|
687
|
-
return fn.apply(self, arguments);
|
|
688
|
-
} finally {
|
|
689
|
-
warningStackCounter--;
|
|
690
|
-
}
|
|
691
|
-
};
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
var defineMembraneProperty = function(membrane, prototype, key) {
|
|
695
|
-
Object.defineProperty(membrane, key, {
|
|
696
|
-
|
|
697
|
-
configurable: false,
|
|
698
|
-
enumerable: true,
|
|
699
|
-
|
|
700
|
-
get: function() {
|
|
701
|
-
if (this === membrane) {
|
|
702
|
-
// We're allowed to access the prototype directly.
|
|
703
|
-
return prototype[key];
|
|
704
|
-
}
|
|
705
|
-
issueMembraneWarning(this, key);
|
|
706
|
-
|
|
707
|
-
var realValue = this.__realComponentInstance[key];
|
|
708
|
-
// If the real value is a function, we need to provide a wrapper that
|
|
709
|
-
// disables nested warnings. The properties type and constructors are
|
|
710
|
-
// expected to the be constructors and therefore is often use with an
|
|
711
|
-
// equality check and we shouldn't try to rebind those.
|
|
712
|
-
if (typeof realValue === 'function' &&
|
|
713
|
-
key !== 'type' &&
|
|
714
|
-
key !== 'constructor') {
|
|
715
|
-
return wrapInMembraneFunction(realValue, this);
|
|
716
|
-
}
|
|
717
|
-
return realValue;
|
|
718
|
-
},
|
|
719
|
-
|
|
720
|
-
set: function(value) {
|
|
721
|
-
if (this === membrane) {
|
|
722
|
-
// We're allowed to set a value on the prototype directly.
|
|
723
|
-
prototype[key] = value;
|
|
724
|
-
return;
|
|
725
|
-
}
|
|
726
|
-
issueMembraneWarning(this, key);
|
|
727
|
-
this.__realComponentInstance[key] = value;
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
});
|
|
731
|
-
};
|
|
732
|
-
|
|
733
|
-
/**
|
|
734
|
-
* Creates a membrane prototype which wraps the original prototype. If any
|
|
735
|
-
* property is accessed in an unmounted state, a warning is issued.
|
|
736
|
-
*
|
|
737
|
-
* @param {object} prototype Original prototype.
|
|
738
|
-
* @return {object} The membrane prototype.
|
|
739
|
-
* @private
|
|
740
|
-
*/
|
|
741
|
-
var createMountWarningMembrane = function(prototype) {
|
|
742
|
-
var membrane = {};
|
|
743
|
-
var key;
|
|
744
|
-
for (key in prototype) {
|
|
745
|
-
defineMembraneProperty(membrane, prototype, key);
|
|
746
|
-
}
|
|
747
|
-
// These are properties that goes into the instance but not the prototype.
|
|
748
|
-
// We can create the membrane on the prototype even though this will
|
|
749
|
-
// result in a faulty hasOwnProperty check it's better perf.
|
|
750
|
-
for (key in componentInstanceProperties) {
|
|
751
|
-
if (componentInstanceProperties.hasOwnProperty(key) &&
|
|
752
|
-
!(key in prototype)) {
|
|
753
|
-
defineMembraneProperty(membrane, prototype, key);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
return membrane;
|
|
757
|
-
};
|
|
758
|
-
|
|
759
|
-
/**
|
|
760
|
-
* Creates a membrane constructor which wraps the component that gets mounted.
|
|
761
|
-
*
|
|
762
|
-
* @param {function} constructor Original constructor.
|
|
763
|
-
* @return {function} The membrane constructor.
|
|
764
|
-
* @private
|
|
765
|
-
*/
|
|
766
|
-
var createDescriptorProxy = function(constructor) {
|
|
767
|
-
try {
|
|
768
|
-
var ProxyConstructor = function() {
|
|
769
|
-
this.__realComponentInstance = new constructor();
|
|
770
|
-
|
|
771
|
-
// We can only safely pass through known instance variables. Unknown
|
|
772
|
-
// expandos are not safe. Use the real mounted instance to avoid this
|
|
773
|
-
// problem if it blows something up.
|
|
774
|
-
Object.freeze(this);
|
|
775
|
-
};
|
|
776
|
-
|
|
777
|
-
ProxyConstructor.prototype = createMountWarningMembrane(
|
|
778
|
-
constructor.prototype
|
|
779
|
-
);
|
|
780
|
-
|
|
781
|
-
return ProxyConstructor;
|
|
782
|
-
} catch(x) {
|
|
783
|
-
// In IE8 define property will fail on non-DOM objects. If anything in
|
|
784
|
-
// the membrane creation fails, we'll bail out and just use the plain
|
|
785
|
-
// constructor without warnings.
|
|
786
|
-
return constructor;
|
|
787
|
-
}
|
|
788
|
-
};
|
|
789
|
-
|
|
790
|
-
}
|
|
791
|
-
|
|
792
642
|
/**
|
|
793
643
|
* `ReactCompositeComponent` maintains an auxiliary life cycle state in
|
|
794
644
|
* `this._compositeLifeCycleState` (which can be null).
|
|
@@ -846,12 +696,11 @@ var ReactCompositeComponentMixin = {
|
|
|
846
696
|
/**
|
|
847
697
|
* Base constructor for all composite component.
|
|
848
698
|
*
|
|
849
|
-
* @param {
|
|
850
|
-
* @param {*} children
|
|
699
|
+
* @param {ReactDescriptor} descriptor
|
|
851
700
|
* @final
|
|
852
701
|
* @internal
|
|
853
702
|
*/
|
|
854
|
-
construct: function(
|
|
703
|
+
construct: function(descriptor) {
|
|
855
704
|
// Children can be either an array or more than one argument
|
|
856
705
|
ReactComponent.Mixin.construct.apply(this, arguments);
|
|
857
706
|
ReactOwner.Mixin.construct.apply(this, arguments);
|
|
@@ -859,29 +708,13 @@ var ReactCompositeComponentMixin = {
|
|
|
859
708
|
this.state = null;
|
|
860
709
|
this._pendingState = null;
|
|
861
710
|
|
|
711
|
+
// This is the public post-processed context. The real context and pending
|
|
712
|
+
// context lives on the descriptor.
|
|
862
713
|
this.context = null;
|
|
863
|
-
this._currentContext = ReactContext.current;
|
|
864
|
-
this._pendingContext = null;
|
|
865
|
-
|
|
866
|
-
// The descriptor that was used to instantiate this component. Will be
|
|
867
|
-
// set by the instantiator instead of the constructor since this
|
|
868
|
-
// constructor is currently used by both instances and descriptors.
|
|
869
|
-
this._descriptor = null;
|
|
870
714
|
|
|
871
715
|
this._compositeLifeCycleState = null;
|
|
872
716
|
},
|
|
873
717
|
|
|
874
|
-
/**
|
|
875
|
-
* Components in the intermediate state now has cyclic references. To avoid
|
|
876
|
-
* breaking JSON serialization we expose a custom JSON format.
|
|
877
|
-
* @return {object} JSON compatible representation.
|
|
878
|
-
* @internal
|
|
879
|
-
* @final
|
|
880
|
-
*/
|
|
881
|
-
toJSON: function() {
|
|
882
|
-
return { type: this.type, props: this.props };
|
|
883
|
-
},
|
|
884
|
-
|
|
885
718
|
/**
|
|
886
719
|
* Checks whether or not this composite component is mounted.
|
|
887
720
|
* @return {boolean} True if mounted, false otherwise.
|
|
@@ -915,14 +748,13 @@ var ReactCompositeComponentMixin = {
|
|
|
915
748
|
);
|
|
916
749
|
this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
|
|
917
750
|
|
|
918
|
-
this.context = this._processContext(this._currentContext);
|
|
919
|
-
this._defaultProps = this.getDefaultProps ? this.getDefaultProps() : null;
|
|
920
|
-
this.props = this._processProps(this.props);
|
|
921
|
-
|
|
922
751
|
if (this.__reactAutoBindMap) {
|
|
923
752
|
this._bindAutoBindMethods();
|
|
924
753
|
}
|
|
925
754
|
|
|
755
|
+
this.context = this._processContext(this._descriptor._context);
|
|
756
|
+
this.props = this._processProps(this.props);
|
|
757
|
+
|
|
926
758
|
this.state = this.getInitialState ? this.getInitialState() : null;
|
|
927
759
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
928
760
|
typeof this.state === 'object' && !Array.isArray(this.state),
|
|
@@ -955,7 +787,7 @@ var ReactCompositeComponentMixin = {
|
|
|
955
787
|
mountDepth + 1
|
|
956
788
|
);
|
|
957
789
|
if (this.componentDidMount) {
|
|
958
|
-
transaction.getReactMountReady().enqueue(this, this
|
|
790
|
+
transaction.getReactMountReady().enqueue(this.componentDidMount, this);
|
|
959
791
|
}
|
|
960
792
|
return markup;
|
|
961
793
|
}
|
|
@@ -974,8 +806,6 @@ var ReactCompositeComponentMixin = {
|
|
|
974
806
|
}
|
|
975
807
|
this._compositeLifeCycleState = null;
|
|
976
808
|
|
|
977
|
-
this._defaultProps = null;
|
|
978
|
-
|
|
979
809
|
this._renderedComponent.unmountComponent();
|
|
980
810
|
this._renderedComponent = null;
|
|
981
811
|
|
|
@@ -1009,7 +839,7 @@ var ReactCompositeComponentMixin = {
|
|
|
1009
839
|
typeof partialState === 'object' || partialState == null,
|
|
1010
840
|
'setState(...): takes an object of state variables to update.'
|
|
1011
841
|
) : invariant(typeof partialState === 'object' || partialState == null));
|
|
1012
|
-
if ("production" !== process.env.NODE_ENV)
|
|
842
|
+
if ("production" !== process.env.NODE_ENV){
|
|
1013
843
|
("production" !== process.env.NODE_ENV ? warning(
|
|
1014
844
|
partialState != null,
|
|
1015
845
|
'setState(...): You passed an undefined or null state object; ' +
|
|
@@ -1038,7 +868,15 @@ var ReactCompositeComponentMixin = {
|
|
|
1038
868
|
replaceState: function(completeState, callback) {
|
|
1039
869
|
validateLifeCycleOnReplaceState(this);
|
|
1040
870
|
this._pendingState = completeState;
|
|
1041
|
-
|
|
871
|
+
if (this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING) {
|
|
872
|
+
// If we're in a componentWillMount handler, don't enqueue a rerender
|
|
873
|
+
// because ReactUpdates assumes we're in a browser context (which is wrong
|
|
874
|
+
// for server rendering) and we're about to do a render anyway.
|
|
875
|
+
// TODO: The callback here is ignored when setState is called from
|
|
876
|
+
// componentWillMount. Either fix it or disallow doing so completely in
|
|
877
|
+
// favor of getInitialState.
|
|
878
|
+
ReactUpdates.enqueueUpdate(this, callback);
|
|
879
|
+
}
|
|
1042
880
|
},
|
|
1043
881
|
|
|
1044
882
|
/**
|
|
@@ -1113,12 +951,17 @@ var ReactCompositeComponentMixin = {
|
|
|
1113
951
|
* @private
|
|
1114
952
|
*/
|
|
1115
953
|
_processProps: function(newProps) {
|
|
1116
|
-
var
|
|
1117
|
-
var
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
954
|
+
var defaultProps = this.constructor.defaultProps;
|
|
955
|
+
var props;
|
|
956
|
+
if (defaultProps) {
|
|
957
|
+
props = merge(newProps);
|
|
958
|
+
for (var propName in defaultProps) {
|
|
959
|
+
if (typeof props[propName] === 'undefined') {
|
|
960
|
+
props[propName] = defaultProps[propName];
|
|
961
|
+
}
|
|
1121
962
|
}
|
|
963
|
+
} else {
|
|
964
|
+
props = newProps;
|
|
1122
965
|
}
|
|
1123
966
|
if ("production" !== process.env.NODE_ENV) {
|
|
1124
967
|
var propTypes = this.constructor.propTypes;
|
|
@@ -1138,15 +981,32 @@ var ReactCompositeComponentMixin = {
|
|
|
1138
981
|
* @private
|
|
1139
982
|
*/
|
|
1140
983
|
_checkPropTypes: function(propTypes, props, location) {
|
|
984
|
+
// TODO: Stop validating prop types here and only use the descriptor
|
|
985
|
+
// validation.
|
|
1141
986
|
var componentName = this.constructor.displayName;
|
|
1142
987
|
for (var propName in propTypes) {
|
|
1143
988
|
if (propTypes.hasOwnProperty(propName)) {
|
|
1144
|
-
|
|
989
|
+
var error =
|
|
990
|
+
propTypes[propName](props, propName, componentName, location);
|
|
991
|
+
if (error instanceof Error) {
|
|
992
|
+
// We may want to extend this logic for similar errors in
|
|
993
|
+
// renderComponent calls, so I'm abstracting it away into
|
|
994
|
+
// a function to minimize refactoring in the future
|
|
995
|
+
var addendum = getDeclarationErrorAddendum(this);
|
|
996
|
+
("production" !== process.env.NODE_ENV ? warning(false, error.message + addendum) : null);
|
|
997
|
+
}
|
|
1145
998
|
}
|
|
1146
999
|
}
|
|
1147
1000
|
},
|
|
1148
1001
|
|
|
1149
|
-
|
|
1002
|
+
/**
|
|
1003
|
+
* If any of `_pendingDescriptor`, `_pendingState`, or `_pendingForceUpdate`
|
|
1004
|
+
* is set, update the component.
|
|
1005
|
+
*
|
|
1006
|
+
* @param {ReactReconcileTransaction} transaction
|
|
1007
|
+
* @internal
|
|
1008
|
+
*/
|
|
1009
|
+
performUpdateIfNecessary: function(transaction) {
|
|
1150
1010
|
var compositeLifeCycleState = this._compositeLifeCycleState;
|
|
1151
1011
|
// Do not trigger a state transition if we are in the middle of mounting or
|
|
1152
1012
|
// receiving props because both of those will already be doing this.
|
|
@@ -1154,32 +1014,21 @@ var ReactCompositeComponentMixin = {
|
|
|
1154
1014
|
compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) {
|
|
1155
1015
|
return;
|
|
1156
1016
|
}
|
|
1157
|
-
ReactComponent.Mixin.performUpdateIfNecessary.call(this);
|
|
1158
|
-
},
|
|
1159
1017
|
|
|
1160
|
-
|
|
1161
|
-
* If any of `_pendingProps`, `_pendingState`, or `_pendingForceUpdate` is
|
|
1162
|
-
* set, update the component.
|
|
1163
|
-
*
|
|
1164
|
-
* @param {ReactReconcileTransaction} transaction
|
|
1165
|
-
* @internal
|
|
1166
|
-
*/
|
|
1167
|
-
_performUpdateIfNecessary: function(transaction) {
|
|
1168
|
-
if (this._pendingProps == null &&
|
|
1018
|
+
if (this._pendingDescriptor == null &&
|
|
1169
1019
|
this._pendingState == null &&
|
|
1170
|
-
this._pendingContext == null &&
|
|
1171
1020
|
!this._pendingForceUpdate) {
|
|
1172
1021
|
return;
|
|
1173
1022
|
}
|
|
1174
1023
|
|
|
1175
|
-
var
|
|
1176
|
-
var nextContext = this._processContext(nextFullContext);
|
|
1177
|
-
this._pendingContext = null;
|
|
1178
|
-
|
|
1024
|
+
var nextContext = this.context;
|
|
1179
1025
|
var nextProps = this.props;
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1026
|
+
var nextDescriptor = this._descriptor;
|
|
1027
|
+
if (this._pendingDescriptor != null) {
|
|
1028
|
+
nextDescriptor = this._pendingDescriptor;
|
|
1029
|
+
nextContext = this._processContext(nextDescriptor._context);
|
|
1030
|
+
nextProps = this._processProps(nextDescriptor.props);
|
|
1031
|
+
this._pendingDescriptor = null;
|
|
1183
1032
|
|
|
1184
1033
|
this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;
|
|
1185
1034
|
if (this.componentWillReceiveProps) {
|
|
@@ -1189,37 +1038,46 @@ var ReactCompositeComponentMixin = {
|
|
|
1189
1038
|
|
|
1190
1039
|
this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE;
|
|
1191
1040
|
|
|
1192
|
-
// Unlike props, state, and context, we specifically don't want to set
|
|
1193
|
-
// _pendingOwner to null here because it's possible for a component to have
|
|
1194
|
-
// a null owner, so we instead make `this._owner === this._pendingOwner`
|
|
1195
|
-
// mean that there's no owner change pending.
|
|
1196
|
-
var nextOwner = this._pendingOwner;
|
|
1197
|
-
|
|
1198
1041
|
var nextState = this._pendingState || this.state;
|
|
1199
1042
|
this._pendingState = null;
|
|
1200
1043
|
|
|
1201
1044
|
try {
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1045
|
+
var shouldUpdate =
|
|
1046
|
+
this._pendingForceUpdate ||
|
|
1047
|
+
!this.shouldComponentUpdate ||
|
|
1048
|
+
this.shouldComponentUpdate(nextProps, nextState, nextContext);
|
|
1049
|
+
|
|
1050
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
1051
|
+
if (typeof shouldUpdate === "undefined") {
|
|
1052
|
+
console.warn(
|
|
1053
|
+
(this.constructor.displayName || 'ReactCompositeComponent') +
|
|
1054
|
+
'.shouldComponentUpdate(): Returned undefined instead of a ' +
|
|
1055
|
+
'boolean value. Make sure to return true or false.'
|
|
1056
|
+
);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
if (shouldUpdate) {
|
|
1205
1061
|
this._pendingForceUpdate = false;
|
|
1206
1062
|
// Will set `this.props`, `this.state` and `this.context`.
|
|
1207
1063
|
this._performComponentUpdate(
|
|
1064
|
+
nextDescriptor,
|
|
1208
1065
|
nextProps,
|
|
1209
|
-
nextOwner,
|
|
1210
1066
|
nextState,
|
|
1211
|
-
nextFullContext,
|
|
1212
1067
|
nextContext,
|
|
1213
1068
|
transaction
|
|
1214
1069
|
);
|
|
1215
1070
|
} else {
|
|
1216
1071
|
// If it's determined that a component should not update, we still want
|
|
1217
1072
|
// to set props and state.
|
|
1073
|
+
this._descriptor = nextDescriptor;
|
|
1218
1074
|
this.props = nextProps;
|
|
1219
|
-
this._owner = nextOwner;
|
|
1220
1075
|
this.state = nextState;
|
|
1221
|
-
this._currentContext = nextFullContext;
|
|
1222
1076
|
this.context = nextContext;
|
|
1077
|
+
|
|
1078
|
+
// Owner cannot change because shouldUpdateReactComponent doesn't allow
|
|
1079
|
+
// it. TODO: Remove this._owner completely.
|
|
1080
|
+
this._owner = nextDescriptor._owner;
|
|
1223
1081
|
}
|
|
1224
1082
|
} finally {
|
|
1225
1083
|
this._compositeLifeCycleState = null;
|
|
@@ -1230,24 +1088,22 @@ var ReactCompositeComponentMixin = {
|
|
|
1230
1088
|
* Merges new props and state, notifies delegate methods of update and
|
|
1231
1089
|
* performs update.
|
|
1232
1090
|
*
|
|
1233
|
-
* @param {
|
|
1234
|
-
* @param {
|
|
1091
|
+
* @param {ReactDescriptor} nextDescriptor Next descriptor
|
|
1092
|
+
* @param {object} nextProps Next public object to set as properties.
|
|
1235
1093
|
* @param {?object} nextState Next object to set as state.
|
|
1236
|
-
* @param {?object}
|
|
1237
|
-
* @param {?object} nextContext Next object to set as context.
|
|
1094
|
+
* @param {?object} nextContext Next public object to set as context.
|
|
1238
1095
|
* @param {ReactReconcileTransaction} transaction
|
|
1239
1096
|
* @private
|
|
1240
1097
|
*/
|
|
1241
1098
|
_performComponentUpdate: function(
|
|
1099
|
+
nextDescriptor,
|
|
1242
1100
|
nextProps,
|
|
1243
|
-
nextOwner,
|
|
1244
1101
|
nextState,
|
|
1245
|
-
nextFullContext,
|
|
1246
1102
|
nextContext,
|
|
1247
1103
|
transaction
|
|
1248
1104
|
) {
|
|
1105
|
+
var prevDescriptor = this._descriptor;
|
|
1249
1106
|
var prevProps = this.props;
|
|
1250
|
-
var prevOwner = this._owner;
|
|
1251
1107
|
var prevState = this.state;
|
|
1252
1108
|
var prevContext = this.context;
|
|
1253
1109
|
|
|
@@ -1255,43 +1111,44 @@ var ReactCompositeComponentMixin = {
|
|
|
1255
1111
|
this.componentWillUpdate(nextProps, nextState, nextContext);
|
|
1256
1112
|
}
|
|
1257
1113
|
|
|
1114
|
+
this._descriptor = nextDescriptor;
|
|
1258
1115
|
this.props = nextProps;
|
|
1259
|
-
this._owner = nextOwner;
|
|
1260
1116
|
this.state = nextState;
|
|
1261
|
-
this._currentContext = nextFullContext;
|
|
1262
1117
|
this.context = nextContext;
|
|
1263
1118
|
|
|
1119
|
+
// Owner cannot change because shouldUpdateReactComponent doesn't allow
|
|
1120
|
+
// it. TODO: Remove this._owner completely.
|
|
1121
|
+
this._owner = nextDescriptor._owner;
|
|
1122
|
+
|
|
1264
1123
|
this.updateComponent(
|
|
1265
1124
|
transaction,
|
|
1266
|
-
|
|
1267
|
-
prevOwner,
|
|
1268
|
-
prevState,
|
|
1269
|
-
prevContext
|
|
1125
|
+
prevDescriptor
|
|
1270
1126
|
);
|
|
1271
1127
|
|
|
1272
1128
|
if (this.componentDidUpdate) {
|
|
1273
1129
|
transaction.getReactMountReady().enqueue(
|
|
1274
|
-
this,
|
|
1275
|
-
this
|
|
1130
|
+
this.componentDidUpdate.bind(this, prevProps, prevState, prevContext),
|
|
1131
|
+
this
|
|
1276
1132
|
);
|
|
1277
1133
|
}
|
|
1278
1134
|
},
|
|
1279
1135
|
|
|
1280
|
-
receiveComponent: function(
|
|
1281
|
-
if (
|
|
1282
|
-
|
|
1283
|
-
//
|
|
1284
|
-
// if this is a
|
|
1136
|
+
receiveComponent: function(nextDescriptor, transaction) {
|
|
1137
|
+
if (nextDescriptor === this._descriptor &&
|
|
1138
|
+
nextDescriptor._owner != null) {
|
|
1139
|
+
// Since descriptors are immutable after the owner is rendered,
|
|
1140
|
+
// we can do a cheap identity compare here to determine if this is a
|
|
1141
|
+
// superfluous reconcile. It's possible for state to be mutable but such
|
|
1142
|
+
// change should trigger an update of the owner which would recreate
|
|
1143
|
+
// the descriptor. We explicitly check for the existence of an owner since
|
|
1144
|
+
// it's possible for a descriptor created outside a composite to be
|
|
1145
|
+
// deeply mutated and reused.
|
|
1285
1146
|
return;
|
|
1286
1147
|
}
|
|
1287
1148
|
|
|
1288
|
-
// Update the descriptor that was last used by this component instance
|
|
1289
|
-
this._descriptor = nextComponent;
|
|
1290
|
-
|
|
1291
|
-
this._pendingContext = nextComponent._currentContext;
|
|
1292
1149
|
ReactComponent.Mixin.receiveComponent.call(
|
|
1293
1150
|
this,
|
|
1294
|
-
|
|
1151
|
+
nextDescriptor,
|
|
1295
1152
|
transaction
|
|
1296
1153
|
);
|
|
1297
1154
|
},
|
|
@@ -1303,35 +1160,31 @@ var ReactCompositeComponentMixin = {
|
|
|
1303
1160
|
* Sophisticated clients may wish to override this.
|
|
1304
1161
|
*
|
|
1305
1162
|
* @param {ReactReconcileTransaction} transaction
|
|
1306
|
-
* @param {
|
|
1307
|
-
* @param {?ReactComponent} prevOwner
|
|
1308
|
-
* @param {?object} prevState
|
|
1309
|
-
* @param {?object} prevContext
|
|
1163
|
+
* @param {ReactDescriptor} prevDescriptor
|
|
1310
1164
|
* @internal
|
|
1311
1165
|
* @overridable
|
|
1312
1166
|
*/
|
|
1313
1167
|
updateComponent: ReactPerf.measure(
|
|
1314
1168
|
'ReactCompositeComponent',
|
|
1315
1169
|
'updateComponent',
|
|
1316
|
-
function(transaction,
|
|
1170
|
+
function(transaction, prevParentDescriptor) {
|
|
1317
1171
|
ReactComponent.Mixin.updateComponent.call(
|
|
1318
1172
|
this,
|
|
1319
1173
|
transaction,
|
|
1320
|
-
|
|
1321
|
-
prevOwner
|
|
1174
|
+
prevParentDescriptor
|
|
1322
1175
|
);
|
|
1323
1176
|
|
|
1324
|
-
|
|
1325
1177
|
var prevComponentInstance = this._renderedComponent;
|
|
1326
|
-
var
|
|
1327
|
-
|
|
1328
|
-
|
|
1178
|
+
var prevDescriptor = prevComponentInstance._descriptor;
|
|
1179
|
+
var nextDescriptor = this._renderValidatedComponent();
|
|
1180
|
+
if (shouldUpdateReactComponent(prevDescriptor, nextDescriptor)) {
|
|
1181
|
+
prevComponentInstance.receiveComponent(nextDescriptor, transaction);
|
|
1329
1182
|
} else {
|
|
1330
1183
|
// These two IDs are actually the same! But nothing should rely on that.
|
|
1331
1184
|
var thisID = this._rootNodeID;
|
|
1332
1185
|
var prevComponentID = prevComponentInstance._rootNodeID;
|
|
1333
1186
|
prevComponentInstance.unmountComponent();
|
|
1334
|
-
this._renderedComponent = instantiateReactComponent(
|
|
1187
|
+
this._renderedComponent = instantiateReactComponent(nextDescriptor);
|
|
1335
1188
|
var nextMarkup = this._renderedComponent.mountComponent(
|
|
1336
1189
|
thisID,
|
|
1337
1190
|
transaction,
|
|
@@ -1388,20 +1241,28 @@ var ReactCompositeComponentMixin = {
|
|
|
1388
1241
|
function() {
|
|
1389
1242
|
var renderedComponent;
|
|
1390
1243
|
var previousContext = ReactContext.current;
|
|
1391
|
-
ReactContext.current = this._processChildContext(
|
|
1244
|
+
ReactContext.current = this._processChildContext(
|
|
1245
|
+
this._descriptor._context
|
|
1246
|
+
);
|
|
1392
1247
|
ReactCurrentOwner.current = this;
|
|
1393
1248
|
try {
|
|
1394
1249
|
renderedComponent = this.render();
|
|
1250
|
+
if (renderedComponent === null || renderedComponent === false) {
|
|
1251
|
+
renderedComponent = ReactEmptyComponent.getEmptyComponent();
|
|
1252
|
+
ReactEmptyComponent.registerNullComponentID(this._rootNodeID);
|
|
1253
|
+
} else {
|
|
1254
|
+
ReactEmptyComponent.deregisterNullComponentID(this._rootNodeID);
|
|
1255
|
+
}
|
|
1395
1256
|
} finally {
|
|
1396
1257
|
ReactContext.current = previousContext;
|
|
1397
1258
|
ReactCurrentOwner.current = null;
|
|
1398
1259
|
}
|
|
1399
1260
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
1400
|
-
|
|
1261
|
+
ReactDescriptor.isValidDescriptor(renderedComponent),
|
|
1401
1262
|
'%s.render(): A valid ReactComponent must be returned. You may have ' +
|
|
1402
|
-
'returned
|
|
1263
|
+
'returned undefined, an array or some other invalid object.',
|
|
1403
1264
|
this.constructor.displayName || 'ReactCompositeComponent'
|
|
1404
|
-
) : invariant(
|
|
1265
|
+
) : invariant(ReactDescriptor.isValidDescriptor(renderedComponent)));
|
|
1405
1266
|
return renderedComponent;
|
|
1406
1267
|
}
|
|
1407
1268
|
),
|
|
@@ -1475,18 +1336,6 @@ mixInto(ReactCompositeComponentBase, ReactOwner.Mixin);
|
|
|
1475
1336
|
mixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin);
|
|
1476
1337
|
mixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);
|
|
1477
1338
|
|
|
1478
|
-
/**
|
|
1479
|
-
* Checks if a value is a valid component constructor.
|
|
1480
|
-
*
|
|
1481
|
-
* @param {*}
|
|
1482
|
-
* @return {boolean}
|
|
1483
|
-
* @public
|
|
1484
|
-
*/
|
|
1485
|
-
function isValidClass(componentClass) {
|
|
1486
|
-
return componentClass instanceof Function &&
|
|
1487
|
-
'componentConstructor' in componentClass &&
|
|
1488
|
-
componentClass.componentConstructor instanceof Function;
|
|
1489
|
-
}
|
|
1490
1339
|
/**
|
|
1491
1340
|
* Module for creating composite components.
|
|
1492
1341
|
*
|
|
@@ -1509,26 +1358,22 @@ var ReactCompositeComponent = {
|
|
|
1509
1358
|
* @public
|
|
1510
1359
|
*/
|
|
1511
1360
|
createClass: function(spec) {
|
|
1512
|
-
var Constructor = function() {
|
|
1361
|
+
var Constructor = function(props, owner) {
|
|
1362
|
+
this.construct(props, owner);
|
|
1363
|
+
};
|
|
1513
1364
|
Constructor.prototype = new ReactCompositeComponentBase();
|
|
1514
1365
|
Constructor.prototype.constructor = Constructor;
|
|
1515
1366
|
|
|
1516
|
-
var DescriptorConstructor = Constructor;
|
|
1517
|
-
|
|
1518
|
-
var ConvenienceConstructor = function(props, children) {
|
|
1519
|
-
var descriptor = new DescriptorConstructor();
|
|
1520
|
-
descriptor.construct.apply(descriptor, arguments);
|
|
1521
|
-
return descriptor;
|
|
1522
|
-
};
|
|
1523
|
-
ConvenienceConstructor.componentConstructor = Constructor;
|
|
1524
|
-
Constructor.ConvenienceConstructor = ConvenienceConstructor;
|
|
1525
|
-
ConvenienceConstructor.originalSpec = spec;
|
|
1526
|
-
|
|
1527
1367
|
injectedMixins.forEach(
|
|
1528
|
-
mixSpecIntoComponent.bind(null,
|
|
1368
|
+
mixSpecIntoComponent.bind(null, Constructor)
|
|
1529
1369
|
);
|
|
1530
1370
|
|
|
1531
|
-
mixSpecIntoComponent(
|
|
1371
|
+
mixSpecIntoComponent(Constructor, spec);
|
|
1372
|
+
|
|
1373
|
+
// Initialize the defaultProps property after all mixins have been merged
|
|
1374
|
+
if (Constructor.getDefaultProps) {
|
|
1375
|
+
Constructor.defaultProps = Constructor.getDefaultProps();
|
|
1376
|
+
}
|
|
1532
1377
|
|
|
1533
1378
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
1534
1379
|
Constructor.prototype.render,
|
|
@@ -1550,14 +1395,6 @@ var ReactCompositeComponent = {
|
|
|
1550
1395
|
}
|
|
1551
1396
|
}
|
|
1552
1397
|
|
|
1553
|
-
// Expose the convience constructor on the prototype so that it can be
|
|
1554
|
-
// easily accessed on descriptors. E.g. <Foo />.type === Foo.type and for
|
|
1555
|
-
// static methods like <Foo />.type.staticMethod();
|
|
1556
|
-
// This should not be named constructor since this may not be the function
|
|
1557
|
-
// that created the descriptor, and it may not even be a constructor.
|
|
1558
|
-
ConvenienceConstructor.type = Constructor;
|
|
1559
|
-
Constructor.prototype.type = Constructor;
|
|
1560
|
-
|
|
1561
1398
|
// Reduce time spent doing lookups by setting these on the prototype.
|
|
1562
1399
|
for (var methodName in ReactCompositeComponentInterface) {
|
|
1563
1400
|
if (!Constructor.prototype[methodName]) {
|
|
@@ -1565,18 +1402,19 @@ var ReactCompositeComponent = {
|
|
|
1565
1402
|
}
|
|
1566
1403
|
}
|
|
1567
1404
|
|
|
1405
|
+
var descriptorFactory = ReactDescriptor.createFactory(Constructor);
|
|
1406
|
+
|
|
1568
1407
|
if ("production" !== process.env.NODE_ENV) {
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1408
|
+
return ReactDescriptorValidator.createFactory(
|
|
1409
|
+
descriptorFactory,
|
|
1410
|
+
Constructor.propTypes,
|
|
1411
|
+
Constructor.contextTypes
|
|
1412
|
+
);
|
|
1573
1413
|
}
|
|
1574
1414
|
|
|
1575
|
-
return
|
|
1415
|
+
return descriptorFactory;
|
|
1576
1416
|
},
|
|
1577
1417
|
|
|
1578
|
-
isValidClass: isValidClass,
|
|
1579
|
-
|
|
1580
1418
|
injection: {
|
|
1581
1419
|
injectMixin: function(mixin) {
|
|
1582
1420
|
injectedMixins.push(mixin);
|