react 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/JSXTransformer.js +13448 -0
- package/dist/react-with-addons.js +20235 -0
- package/dist/react-with-addons.min.js +22 -0
- package/dist/react.js +18443 -0
- package/dist/react.min.js +21 -0
- package/lib/AutoFocusMixin.js +3 -1
- 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 +33 -20
- package/lib/DOMProperty.js +51 -21
- package/lib/DOMPropertyOperations.js +28 -16
- package/lib/DefaultEventPluginOrder.js +1 -0
- package/lib/EventConstants.js +1 -0
- package/lib/EventListener.js +5 -2
- package/lib/EventPluginHub.js +2 -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} +41 -58
- package/lib/LinkedValueUtils.js +26 -28
- package/lib/LocalEventTrapMixin.js +52 -0
- package/lib/React.js +39 -3
- package/lib/ReactBrowserComponentMixin.js +46 -0
- package/lib/{ReactEventEmitter.js → ReactBrowserEventEmitter.js} +115 -94
- package/lib/ReactCSSTransitionGroup.js +12 -10
- package/lib/ReactCSSTransitionGroupChild.js +2 -5
- package/lib/ReactChildren.js +31 -10
- package/lib/ReactComponent.js +119 -223
- package/lib/ReactComponentBrowserEnvironment.js +3 -36
- package/lib/ReactComponentWithPureRenderMixin.js +54 -0
- package/lib/ReactCompositeComponent.js +249 -287
- package/lib/ReactDOM.js +25 -23
- package/lib/ReactDOMButton.js +2 -1
- package/lib/ReactDOMComponent.js +42 -23
- package/lib/ReactDOMForm.js +7 -12
- package/lib/ReactDOMIDOperations.js +2 -31
- package/lib/ReactDOMImg.js +7 -13
- package/lib/ReactDOMInput.js +2 -1
- package/lib/ReactDOMOption.js +11 -7
- package/lib/ReactDOMSelect.js +18 -16
- package/lib/ReactDOMSelection.js +35 -10
- package/lib/ReactDOMTextarea.js +9 -7
- package/lib/ReactDefaultBatchingStrategy.js +3 -3
- package/lib/ReactDefaultInjection.js +27 -14
- 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 +8 -2
- package/lib/ReactInputSelection.js +2 -1
- package/lib/ReactLink.js +24 -0
- package/lib/ReactMount.js +61 -21
- package/lib/ReactMultiChild.js +18 -13
- package/lib/ReactOwner.js +6 -1
- package/lib/ReactPropTransferer.js +44 -29
- package/lib/ReactPropTypes.js +226 -242
- package/lib/ReactPutListenerQueue.js +2 -2
- package/lib/ReactReconcileTransaction.js +21 -20
- package/lib/ReactServerRendering.js +41 -11
- package/lib/ReactServerRenderingTransaction.js +115 -0
- package/lib/ReactTestUtils.js +39 -21
- package/lib/ReactTextComponent.js +21 -13
- 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 +8 -3
- 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 +10 -8
- package/lib/createFullPageComponent.js +1 -1
- package/lib/dangerousStyleValue.js +11 -5
- package/lib/{ReactComponentEnvironment.js → emptyObject.js} +6 -5
- package/lib/escapeTextForBrowser.js +2 -3
- package/lib/flattenChildren.js +9 -7
- package/lib/focusNode.js +33 -0
- 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 +62 -0
- package/lib/invariant.js +17 -19
- package/lib/isNode.js +1 -1
- package/lib/{objMap.js → mapObject.js} +8 -3
- package/lib/mergeHelpers.js +11 -0
- package/lib/mergeInto.js +3 -2
- package/lib/monitorCodeUse.js +37 -0
- package/lib/onlyChild.js +3 -3
- package/lib/performance.js +33 -0
- package/lib/performanceNow.js +5 -14
- package/lib/setInnerHTML.js +77 -0
- package/lib/shouldUpdateReactComponent.js +14 -28
- package/lib/toArray.js +1 -1
- package/lib/traverseAllChildren.js +9 -5
- package/lib/update.js +171 -0
- package/package.json +4 -3
- package/lib/ReactEventTopLevelCallback.js +0 -149
- package/lib/createObjectFrom.js +0 -61
- package/lib/objMapKeyVal.js +0 -47
|
@@ -15,7 +15,6 @@
|
|
|
15
15
|
*
|
|
16
16
|
* @typechecks
|
|
17
17
|
* @providesModule ReactCSSTransitionGroup
|
|
18
|
-
* @jsx React.DOM
|
|
19
18
|
*/
|
|
20
19
|
|
|
21
20
|
"use strict";
|
|
@@ -25,7 +24,9 @@ var React = require("./React");
|
|
|
25
24
|
var ReactTransitionGroup = require("./ReactTransitionGroup");
|
|
26
25
|
var ReactCSSTransitionGroupChild = require("./ReactCSSTransitionGroupChild");
|
|
27
26
|
|
|
28
|
-
var ReactCSSTransitionGroup = React.createClass({
|
|
27
|
+
var ReactCSSTransitionGroup = React.createClass({
|
|
28
|
+
displayName: 'ReactCSSTransitionGroup',
|
|
29
|
+
|
|
29
30
|
propTypes: {
|
|
30
31
|
transitionName: React.PropTypes.string.isRequired,
|
|
31
32
|
transitionEnter: React.PropTypes.bool,
|
|
@@ -43,19 +44,20 @@ var ReactCSSTransitionGroup = React.createClass({displayName: 'ReactCSSTransitio
|
|
|
43
44
|
// We need to provide this childFactory so that
|
|
44
45
|
// ReactCSSTransitionGroupChild can receive updates to name, enter, and
|
|
45
46
|
// leave while it is leaving.
|
|
46
|
-
return (
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
enter:this.props.transitionEnter,
|
|
50
|
-
leave:this.props.transitionLeave
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
return ReactCSSTransitionGroupChild(
|
|
48
|
+
{
|
|
49
|
+
name: this.props.transitionName,
|
|
50
|
+
enter: this.props.transitionEnter,
|
|
51
|
+
leave: this.props.transitionLeave
|
|
52
|
+
},
|
|
53
|
+
child
|
|
53
54
|
);
|
|
54
55
|
},
|
|
55
56
|
|
|
56
57
|
render: function() {
|
|
57
58
|
return this.transferPropsTo(
|
|
58
|
-
ReactTransitionGroup(
|
|
59
|
+
ReactTransitionGroup(
|
|
60
|
+
{childFactory: this._wrapChild},
|
|
59
61
|
this.props.children
|
|
60
62
|
)
|
|
61
63
|
);
|
|
@@ -48,6 +48,8 @@ if ("production" !== process.env.NODE_ENV) {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
var ReactCSSTransitionGroupChild = React.createClass({
|
|
51
|
+
displayName: 'ReactCSSTransitionGroupChild',
|
|
52
|
+
|
|
51
53
|
transition: function(animationType, finishCallback) {
|
|
52
54
|
var node = this.getDOMNode();
|
|
53
55
|
var className = this.props.name + '-' + animationType;
|
|
@@ -84,11 +86,6 @@ var ReactCSSTransitionGroupChild = React.createClass({
|
|
|
84
86
|
queueClass: function(className) {
|
|
85
87
|
this.classNameQueue.push(className);
|
|
86
88
|
|
|
87
|
-
if (this.props.runNextTick) {
|
|
88
|
-
this.props.runNextTick(this.flushClassNameQueue);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
89
|
if (!this.timeout) {
|
|
93
90
|
this.timeout = setTimeout(this.flushClassNameQueue, TICK);
|
|
94
91
|
}
|
package/lib/ReactChildren.js
CHANGED
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
|
|
21
21
|
var PooledClass = require("./PooledClass");
|
|
22
22
|
|
|
23
|
-
var invariant = require("./invariant");
|
|
24
23
|
var traverseAllChildren = require("./traverseAllChildren");
|
|
24
|
+
var warning = require("./warning");
|
|
25
25
|
|
|
26
26
|
var twoArgumentPooler = PooledClass.twoArgumentPooler;
|
|
27
27
|
var threeArgumentPooler = PooledClass.threeArgumentPooler;
|
|
@@ -86,16 +86,21 @@ PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler);
|
|
|
86
86
|
function mapSingleChildIntoContext(traverseContext, child, name, i) {
|
|
87
87
|
var mapBookKeeping = traverseContext;
|
|
88
88
|
var mapResult = mapBookKeeping.mapResult;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
!mapResult.hasOwnProperty(name),
|
|
89
|
+
|
|
90
|
+
var keyUnique = !mapResult.hasOwnProperty(name);
|
|
91
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
92
|
+
keyUnique,
|
|
94
93
|
'ReactChildren.map(...): Encountered two children with the same key, ' +
|
|
95
|
-
'`%s`.
|
|
94
|
+
'`%s`. Child keys must be unique; when two children share a key, only ' +
|
|
95
|
+
'the first child will be used.',
|
|
96
96
|
name
|
|
97
|
-
) :
|
|
98
|
-
|
|
97
|
+
) : null);
|
|
98
|
+
|
|
99
|
+
if (keyUnique) {
|
|
100
|
+
var mappedChild =
|
|
101
|
+
mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i);
|
|
102
|
+
mapResult[name] = mappedChild;
|
|
103
|
+
}
|
|
99
104
|
}
|
|
100
105
|
|
|
101
106
|
/**
|
|
@@ -124,9 +129,25 @@ function mapChildren(children, func, context) {
|
|
|
124
129
|
return mapResult;
|
|
125
130
|
}
|
|
126
131
|
|
|
132
|
+
function forEachSingleChildDummy(traverseContext, child, name, i) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Count the number of children that are typically specified as
|
|
138
|
+
* `props.children`.
|
|
139
|
+
*
|
|
140
|
+
* @param {?*} children Children tree container.
|
|
141
|
+
* @return {number} The number of children.
|
|
142
|
+
*/
|
|
143
|
+
function countChildren(children, context) {
|
|
144
|
+
return traverseAllChildren(children, forEachSingleChildDummy, null);
|
|
145
|
+
}
|
|
146
|
+
|
|
127
147
|
var ReactChildren = {
|
|
128
148
|
forEach: forEachChildren,
|
|
129
|
-
map: mapChildren
|
|
149
|
+
map: mapChildren,
|
|
150
|
+
count: countChildren
|
|
130
151
|
};
|
|
131
152
|
|
|
132
153
|
module.exports = ReactChildren;
|
package/lib/ReactComponent.js
CHANGED
|
@@ -18,8 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
"use strict";
|
|
20
20
|
|
|
21
|
-
var
|
|
22
|
-
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
21
|
+
var ReactDescriptor = require("./ReactDescriptor");
|
|
23
22
|
var ReactOwner = require("./ReactOwner");
|
|
24
23
|
var ReactUpdates = require("./ReactUpdates");
|
|
25
24
|
|
|
@@ -42,113 +41,27 @@ var ComponentLifeCycle = keyMirror({
|
|
|
42
41
|
UNMOUNTED: null
|
|
43
42
|
});
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
* Warn if there's no key explicitly set on dynamic arrays of children or
|
|
47
|
-
* object keys are not valid. This allows us to keep track of children between
|
|
48
|
-
* updates.
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
var ownerHasExplicitKeyWarning = {};
|
|
52
|
-
var ownerHasPropertyWarning = {};
|
|
53
|
-
|
|
54
|
-
var NUMERIC_PROPERTY_REGEX = /^\d+$/;
|
|
44
|
+
var injected = false;
|
|
55
45
|
|
|
56
46
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* have a "key" property assigned to it.
|
|
47
|
+
* Optionally injectable environment dependent cleanup hook. (server vs.
|
|
48
|
+
* browser etc). Example: A browser system caches DOM nodes based on component
|
|
49
|
+
* ID and must remove that cache entry when this instance is unmounted.
|
|
61
50
|
*
|
|
62
|
-
* @
|
|
63
|
-
* @param {ReactComponent} component Component that requires a key.
|
|
51
|
+
* @private
|
|
64
52
|
*/
|
|
65
|
-
|
|
66
|
-
if (component.__keyValidated__ || component.props.key != null) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
component.__keyValidated__ = true;
|
|
70
|
-
|
|
71
|
-
// We can't provide friendly warnings for top level components.
|
|
72
|
-
if (!ReactCurrentOwner.current) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Name of the component whose render method tried to pass children.
|
|
77
|
-
var currentName = ReactCurrentOwner.current.constructor.displayName;
|
|
78
|
-
if (ownerHasExplicitKeyWarning.hasOwnProperty(currentName)) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
ownerHasExplicitKeyWarning[currentName] = true;
|
|
82
|
-
|
|
83
|
-
var message = 'Each child in an array should have a unique "key" prop. ' +
|
|
84
|
-
'Check the render method of ' + currentName + '.';
|
|
85
|
-
if (!component.isOwnedBy(ReactCurrentOwner.current)) {
|
|
86
|
-
// Name of the component that originally created this child.
|
|
87
|
-
var childOwnerName =
|
|
88
|
-
component._owner &&
|
|
89
|
-
component._owner.constructor.displayName;
|
|
90
|
-
|
|
91
|
-
// Usually the current owner is the offender, but if it accepts
|
|
92
|
-
// children as a property, it may be the creator of the child that's
|
|
93
|
-
// responsible for assigning it a key.
|
|
94
|
-
message += ' It was passed a child from ' + childOwnerName + '.';
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
message += ' See http://fb.me/react-warning-keys for more information.';
|
|
98
|
-
console.warn(message);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Warn if the key is being defined as an object property but has an incorrect
|
|
103
|
-
* value.
|
|
104
|
-
*
|
|
105
|
-
* @internal
|
|
106
|
-
* @param {string} name Property name of the key.
|
|
107
|
-
* @param {ReactComponent} component Component that requires a key.
|
|
108
|
-
*/
|
|
109
|
-
function validatePropertyKey(name) {
|
|
110
|
-
if (NUMERIC_PROPERTY_REGEX.test(name)) {
|
|
111
|
-
// Name of the component whose render method tried to pass children.
|
|
112
|
-
var currentName = ReactCurrentOwner.current.constructor.displayName;
|
|
113
|
-
if (ownerHasPropertyWarning.hasOwnProperty(currentName)) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
ownerHasPropertyWarning[currentName] = true;
|
|
117
|
-
|
|
118
|
-
console.warn(
|
|
119
|
-
'Child objects should have non-numeric keys so ordering is preserved. ' +
|
|
120
|
-
'Check the render method of ' + currentName + '. ' +
|
|
121
|
-
'See http://fb.me/react-warning-keys for more information.'
|
|
122
|
-
);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
53
|
+
var unmountIDFromEnvironment = null;
|
|
125
54
|
|
|
126
55
|
/**
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
56
|
+
* The "image" of a component tree, is the platform specific (typically
|
|
57
|
+
* serialized) data that represents a tree of lower level UI building blocks.
|
|
58
|
+
* On the web, this "image" is HTML markup which describes a construction of
|
|
59
|
+
* low level `div` and `span` nodes. Other platforms may have different
|
|
60
|
+
* encoding of this "image". This must be injected.
|
|
130
61
|
*
|
|
131
|
-
* @
|
|
132
|
-
* @param {*} component Statically passed child of any type.
|
|
133
|
-
* @return {boolean}
|
|
62
|
+
* @private
|
|
134
63
|
*/
|
|
135
|
-
|
|
136
|
-
if (Array.isArray(component)) {
|
|
137
|
-
for (var i = 0; i < component.length; i++) {
|
|
138
|
-
var child = component[i];
|
|
139
|
-
if (ReactComponent.isValidComponent(child)) {
|
|
140
|
-
validateExplicitKey(child);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
} else if (ReactComponent.isValidComponent(component)) {
|
|
144
|
-
// This component was passed in a valid location.
|
|
145
|
-
component.__keyValidated__ = true;
|
|
146
|
-
} else if (component && typeof component === 'object') {
|
|
147
|
-
for (var name in component) {
|
|
148
|
-
validatePropertyKey(name, component);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
64
|
+
var mountImageIntoNode = null;
|
|
152
65
|
|
|
153
66
|
/**
|
|
154
67
|
* Components are the basic units of composition in React.
|
|
@@ -177,24 +90,19 @@ function validateChildKeys(component) {
|
|
|
177
90
|
*/
|
|
178
91
|
var ReactComponent = {
|
|
179
92
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
93
|
+
injection: {
|
|
94
|
+
injectEnvironment: function(ReactComponentEnvironment) {
|
|
95
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
96
|
+
!injected,
|
|
97
|
+
'ReactComponent: injectEnvironment() can only be called once.'
|
|
98
|
+
) : invariant(!injected));
|
|
99
|
+
mountImageIntoNode = ReactComponentEnvironment.mountImageIntoNode;
|
|
100
|
+
unmountIDFromEnvironment =
|
|
101
|
+
ReactComponentEnvironment.unmountIDFromEnvironment;
|
|
102
|
+
ReactComponent.BackendIDOperations =
|
|
103
|
+
ReactComponentEnvironment.BackendIDOperations;
|
|
104
|
+
injected = true;
|
|
188
105
|
}
|
|
189
|
-
// This is the safer way of duck checking the type of instance this is.
|
|
190
|
-
// The object can be a generic descriptor but the type property refers to
|
|
191
|
-
// the constructor and it's prototype can be used to inspect the type that
|
|
192
|
-
// will actually get mounted.
|
|
193
|
-
var prototype = object.type.prototype;
|
|
194
|
-
return (
|
|
195
|
-
typeof prototype.mountComponentIntoNode === 'function' &&
|
|
196
|
-
typeof prototype.receiveComponent === 'function'
|
|
197
|
-
);
|
|
198
106
|
},
|
|
199
107
|
|
|
200
108
|
/**
|
|
@@ -209,36 +117,7 @@ var ReactComponent = {
|
|
|
209
117
|
*
|
|
210
118
|
* @internal
|
|
211
119
|
*/
|
|
212
|
-
BackendIDOperations:
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Optionally injectable environment dependent cleanup hook. (server vs.
|
|
216
|
-
* browser etc). Example: A browser system caches DOM nodes based on component
|
|
217
|
-
* ID and must remove that cache entry when this instance is unmounted.
|
|
218
|
-
*
|
|
219
|
-
* @private
|
|
220
|
-
*/
|
|
221
|
-
unmountIDFromEnvironment: ReactComponentEnvironment.unmountIDFromEnvironment,
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* The "image" of a component tree, is the platform specific (typically
|
|
225
|
-
* serialized) data that represents a tree of lower level UI building blocks.
|
|
226
|
-
* On the web, this "image" is HTML markup which describes a construction of
|
|
227
|
-
* low level `div` and `span` nodes. Other platforms may have different
|
|
228
|
-
* encoding of this "image". This must be injected.
|
|
229
|
-
*
|
|
230
|
-
* @private
|
|
231
|
-
*/
|
|
232
|
-
mountImageIntoNode: ReactComponentEnvironment.mountImageIntoNode,
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* React references `ReactReconcileTransaction` using this property in order
|
|
236
|
-
* to allow dependency injection.
|
|
237
|
-
*
|
|
238
|
-
* @internal
|
|
239
|
-
*/
|
|
240
|
-
ReactReconcileTransaction:
|
|
241
|
-
ReactComponentEnvironment.ReactReconcileTransaction,
|
|
120
|
+
BackendIDOperations: null,
|
|
242
121
|
|
|
243
122
|
/**
|
|
244
123
|
* Base functionality for every ReactComponent constructor. Mixed into the
|
|
@@ -246,7 +125,7 @@ var ReactComponent = {
|
|
|
246
125
|
*
|
|
247
126
|
* @lends {ReactComponent.prototype}
|
|
248
127
|
*/
|
|
249
|
-
Mixin:
|
|
128
|
+
Mixin: {
|
|
250
129
|
|
|
251
130
|
/**
|
|
252
131
|
* Checks whether or not this component is mounted.
|
|
@@ -268,9 +147,11 @@ var ReactComponent = {
|
|
|
268
147
|
* @public
|
|
269
148
|
*/
|
|
270
149
|
setProps: function(partialProps, callback) {
|
|
271
|
-
// Merge with
|
|
150
|
+
// Merge with the pending descriptor if it exists, otherwise with existing
|
|
151
|
+
// descriptor props.
|
|
152
|
+
var descriptor = this._pendingDescriptor || this._descriptor;
|
|
272
153
|
this.replaceProps(
|
|
273
|
-
merge(
|
|
154
|
+
merge(descriptor.props, partialProps),
|
|
274
155
|
callback
|
|
275
156
|
);
|
|
276
157
|
},
|
|
@@ -296,7 +177,31 @@ var ReactComponent = {
|
|
|
296
177
|
'`render` method to pass the correct value as props to the component ' +
|
|
297
178
|
'where it is created.'
|
|
298
179
|
) : invariant(this._mountDepth === 0));
|
|
299
|
-
|
|
180
|
+
// This is a deoptimized path. We optimize for always having a descriptor.
|
|
181
|
+
// This creates an extra internal descriptor.
|
|
182
|
+
this._pendingDescriptor = ReactDescriptor.cloneAndReplaceProps(
|
|
183
|
+
this._pendingDescriptor || this._descriptor,
|
|
184
|
+
props
|
|
185
|
+
);
|
|
186
|
+
ReactUpdates.enqueueUpdate(this, callback);
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Schedule a partial update to the props. Only used for internal testing.
|
|
191
|
+
*
|
|
192
|
+
* @param {object} partialProps Subset of the next props.
|
|
193
|
+
* @param {?function} callback Called after props are updated.
|
|
194
|
+
* @final
|
|
195
|
+
* @internal
|
|
196
|
+
*/
|
|
197
|
+
_setPropsInternal: function(partialProps, callback) {
|
|
198
|
+
// This is a deoptimized path. We optimize for always having a descriptor.
|
|
199
|
+
// This creates an extra internal descriptor.
|
|
200
|
+
var descriptor = this._pendingDescriptor || this._descriptor;
|
|
201
|
+
this._pendingDescriptor = ReactDescriptor.cloneAndReplaceProps(
|
|
202
|
+
descriptor,
|
|
203
|
+
merge(descriptor.props, partialProps)
|
|
204
|
+
);
|
|
300
205
|
ReactUpdates.enqueueUpdate(this, callback);
|
|
301
206
|
},
|
|
302
207
|
|
|
@@ -306,43 +211,30 @@ var ReactComponent = {
|
|
|
306
211
|
* Subclasses that override this method should make sure to invoke
|
|
307
212
|
* `ReactComponent.Mixin.construct.call(this, ...)`.
|
|
308
213
|
*
|
|
309
|
-
* @param {
|
|
310
|
-
* @param {*} children
|
|
214
|
+
* @param {ReactDescriptor} descriptor
|
|
311
215
|
* @internal
|
|
312
216
|
*/
|
|
313
|
-
construct: function(
|
|
314
|
-
|
|
217
|
+
construct: function(descriptor) {
|
|
218
|
+
// This is the public exposed props object after it has been processed
|
|
219
|
+
// with default props. The descriptor's props represents the true internal
|
|
220
|
+
// state of the props.
|
|
221
|
+
this.props = descriptor.props;
|
|
315
222
|
// Record the component responsible for creating this component.
|
|
316
|
-
|
|
223
|
+
// This is accessible through the descriptor but we maintain an extra
|
|
224
|
+
// field for compatibility with devtools and as a way to make an
|
|
225
|
+
// incremental update. TODO: Consider deprecating this field.
|
|
226
|
+
this._owner = descriptor._owner;
|
|
227
|
+
|
|
317
228
|
// All components start unmounted.
|
|
318
229
|
this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
|
|
319
230
|
|
|
320
|
-
|
|
231
|
+
// See ReactUpdates.
|
|
321
232
|
this._pendingCallbacks = null;
|
|
322
233
|
|
|
323
|
-
//
|
|
324
|
-
//
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
this._pendingOwner = this._owner;
|
|
328
|
-
|
|
329
|
-
// Children can be more than one argument
|
|
330
|
-
var childrenLength = arguments.length - 1;
|
|
331
|
-
if (childrenLength === 1) {
|
|
332
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
333
|
-
validateChildKeys(children);
|
|
334
|
-
}
|
|
335
|
-
this.props.children = children;
|
|
336
|
-
} else if (childrenLength > 1) {
|
|
337
|
-
var childArray = Array(childrenLength);
|
|
338
|
-
for (var i = 0; i < childrenLength; i++) {
|
|
339
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
340
|
-
validateChildKeys(arguments[i + 1]);
|
|
341
|
-
}
|
|
342
|
-
childArray[i] = arguments[i + 1];
|
|
343
|
-
}
|
|
344
|
-
this.props.children = childArray;
|
|
345
|
-
}
|
|
234
|
+
// We keep the old descriptor and a reference to the pending descriptor
|
|
235
|
+
// to track updates.
|
|
236
|
+
this._descriptor = descriptor;
|
|
237
|
+
this._pendingDescriptor = null;
|
|
346
238
|
},
|
|
347
239
|
|
|
348
240
|
/**
|
|
@@ -354,7 +246,7 @@ var ReactComponent = {
|
|
|
354
246
|
* `ReactComponent.Mixin.mountComponent.call(this, ...)`.
|
|
355
247
|
*
|
|
356
248
|
* @param {string} rootID DOM ID of the root node.
|
|
357
|
-
* @param {ReactReconcileTransaction} transaction
|
|
249
|
+
* @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
|
|
358
250
|
* @param {number} mountDepth number of components in the owner hierarchy.
|
|
359
251
|
* @return {?string} Rendered markup to be inserted into the DOM.
|
|
360
252
|
* @internal
|
|
@@ -367,9 +259,10 @@ var ReactComponent = {
|
|
|
367
259
|
'single component instance in multiple places.',
|
|
368
260
|
rootID
|
|
369
261
|
) : invariant(!this.isMounted()));
|
|
370
|
-
var props = this.props;
|
|
262
|
+
var props = this._descriptor.props;
|
|
371
263
|
if (props.ref != null) {
|
|
372
|
-
|
|
264
|
+
var owner = this._descriptor._owner;
|
|
265
|
+
ReactOwner.addComponentAsRefTo(this, props.ref, owner);
|
|
373
266
|
}
|
|
374
267
|
this._rootNodeID = rootID;
|
|
375
268
|
this._lifeCycleState = ComponentLifeCycle.MOUNTED;
|
|
@@ -396,7 +289,7 @@ var ReactComponent = {
|
|
|
396
289
|
if (props.ref != null) {
|
|
397
290
|
ReactOwner.removeComponentAsRefFrom(this, props.ref, this._owner);
|
|
398
291
|
}
|
|
399
|
-
|
|
292
|
+
unmountIDFromEnvironment(this._rootNodeID);
|
|
400
293
|
this._rootNodeID = null;
|
|
401
294
|
this._lifeCycleState = ComponentLifeCycle.UNMOUNTED;
|
|
402
295
|
},
|
|
@@ -412,67 +305,70 @@ var ReactComponent = {
|
|
|
412
305
|
* @param {ReactReconcileTransaction} transaction
|
|
413
306
|
* @internal
|
|
414
307
|
*/
|
|
415
|
-
receiveComponent: function(
|
|
308
|
+
receiveComponent: function(nextDescriptor, transaction) {
|
|
416
309
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
417
310
|
this.isMounted(),
|
|
418
311
|
'receiveComponent(...): Can only update a mounted component.'
|
|
419
312
|
) : invariant(this.isMounted()));
|
|
420
|
-
this.
|
|
421
|
-
this.
|
|
422
|
-
this._performUpdateIfNecessary(transaction);
|
|
423
|
-
},
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* Call `_performUpdateIfNecessary` within a new transaction.
|
|
427
|
-
*
|
|
428
|
-
* @param {ReactReconcileTransaction} transaction
|
|
429
|
-
* @internal
|
|
430
|
-
*/
|
|
431
|
-
performUpdateIfNecessary: function() {
|
|
432
|
-
var transaction = ReactComponent.ReactReconcileTransaction.getPooled();
|
|
433
|
-
transaction.perform(this._performUpdateIfNecessary, this, transaction);
|
|
434
|
-
ReactComponent.ReactReconcileTransaction.release(transaction);
|
|
313
|
+
this._pendingDescriptor = nextDescriptor;
|
|
314
|
+
this.performUpdateIfNecessary(transaction);
|
|
435
315
|
},
|
|
436
316
|
|
|
437
317
|
/**
|
|
438
|
-
* If `
|
|
318
|
+
* If `_pendingDescriptor` is set, update the component.
|
|
439
319
|
*
|
|
440
320
|
* @param {ReactReconcileTransaction} transaction
|
|
441
321
|
* @internal
|
|
442
322
|
*/
|
|
443
|
-
|
|
444
|
-
if (this.
|
|
323
|
+
performUpdateIfNecessary: function(transaction) {
|
|
324
|
+
if (this._pendingDescriptor == null) {
|
|
445
325
|
return;
|
|
446
326
|
}
|
|
447
|
-
var
|
|
448
|
-
var
|
|
449
|
-
this.
|
|
450
|
-
this.
|
|
451
|
-
this.
|
|
452
|
-
this.
|
|
327
|
+
var prevDescriptor = this._descriptor;
|
|
328
|
+
var nextDescriptor = this._pendingDescriptor;
|
|
329
|
+
this._descriptor = nextDescriptor;
|
|
330
|
+
this.props = nextDescriptor.props;
|
|
331
|
+
this._owner = nextDescriptor._owner;
|
|
332
|
+
this._pendingDescriptor = null;
|
|
333
|
+
this.updateComponent(transaction, prevDescriptor);
|
|
453
334
|
},
|
|
454
335
|
|
|
455
336
|
/**
|
|
456
337
|
* Updates the component's currently mounted representation.
|
|
457
338
|
*
|
|
458
339
|
* @param {ReactReconcileTransaction} transaction
|
|
459
|
-
* @param {object}
|
|
340
|
+
* @param {object} prevDescriptor
|
|
460
341
|
* @internal
|
|
461
342
|
*/
|
|
462
|
-
updateComponent: function(transaction,
|
|
463
|
-
var
|
|
343
|
+
updateComponent: function(transaction, prevDescriptor) {
|
|
344
|
+
var nextDescriptor = this._descriptor;
|
|
345
|
+
|
|
464
346
|
// If either the owner or a `ref` has changed, make sure the newest owner
|
|
465
347
|
// has stored a reference to `this`, and the previous owner (if different)
|
|
466
|
-
// has forgotten the reference to `this`.
|
|
467
|
-
|
|
468
|
-
|
|
348
|
+
// has forgotten the reference to `this`. We use the descriptor instead
|
|
349
|
+
// of the public this.props because the post processing cannot determine
|
|
350
|
+
// a ref. The ref conceptually lives on the descriptor.
|
|
351
|
+
|
|
352
|
+
// TODO: Should this even be possible? The owner cannot change because
|
|
353
|
+
// it's forbidden by shouldUpdateReactComponent. The ref can change
|
|
354
|
+
// if you swap the keys of but not the refs. Reconsider where this check
|
|
355
|
+
// is made. It probably belongs where the key checking and
|
|
356
|
+
// instantiateReactComponent is done.
|
|
357
|
+
|
|
358
|
+
if (nextDescriptor._owner !== prevDescriptor._owner ||
|
|
359
|
+
nextDescriptor.props.ref !== prevDescriptor.props.ref) {
|
|
360
|
+
if (prevDescriptor.props.ref != null) {
|
|
469
361
|
ReactOwner.removeComponentAsRefFrom(
|
|
470
|
-
this,
|
|
362
|
+
this, prevDescriptor.props.ref, prevDescriptor._owner
|
|
471
363
|
);
|
|
472
364
|
}
|
|
473
365
|
// Correct, even if the owner is the same, and only the ref has changed.
|
|
474
|
-
if (props.ref != null) {
|
|
475
|
-
ReactOwner.addComponentAsRefTo(
|
|
366
|
+
if (nextDescriptor.props.ref != null) {
|
|
367
|
+
ReactOwner.addComponentAsRefTo(
|
|
368
|
+
this,
|
|
369
|
+
nextDescriptor.props.ref,
|
|
370
|
+
nextDescriptor._owner
|
|
371
|
+
);
|
|
476
372
|
}
|
|
477
373
|
}
|
|
478
374
|
},
|
|
@@ -488,7 +384,7 @@ var ReactComponent = {
|
|
|
488
384
|
* @see {ReactMount.renderComponent}
|
|
489
385
|
*/
|
|
490
386
|
mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) {
|
|
491
|
-
var transaction =
|
|
387
|
+
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
|
|
492
388
|
transaction.perform(
|
|
493
389
|
this._mountComponentIntoNode,
|
|
494
390
|
this,
|
|
@@ -497,7 +393,7 @@ var ReactComponent = {
|
|
|
497
393
|
transaction,
|
|
498
394
|
shouldReuseMarkup
|
|
499
395
|
);
|
|
500
|
-
|
|
396
|
+
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
|
501
397
|
},
|
|
502
398
|
|
|
503
399
|
/**
|
|
@@ -514,7 +410,7 @@ var ReactComponent = {
|
|
|
514
410
|
transaction,
|
|
515
411
|
shouldReuseMarkup) {
|
|
516
412
|
var markup = this.mountComponent(rootID, transaction, 0);
|
|
517
|
-
|
|
413
|
+
mountImageIntoNode(markup, container, shouldReuseMarkup);
|
|
518
414
|
},
|
|
519
415
|
|
|
520
416
|
/**
|
|
@@ -544,7 +440,7 @@ var ReactComponent = {
|
|
|
544
440
|
}
|
|
545
441
|
return owner.refs[ref];
|
|
546
442
|
}
|
|
547
|
-
}
|
|
443
|
+
}
|
|
548
444
|
};
|
|
549
445
|
|
|
550
446
|
module.exports = ReactComponent;
|