react 0.12.1 → 0.13.0-beta.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.
- package/dist/JSXTransformer.js +352 -251
- package/dist/react-with-addons.js +5409 -4242
- package/dist/react-with-addons.min.js +5 -6
- package/dist/react.js +5012 -4136
- package/dist/react.min.js +5 -6
- package/lib/AutoFocusMixin.js +1 -1
- package/lib/BeforeInputEventPlugin.js +389 -112
- package/lib/CSSProperty.js +6 -3
- package/lib/CSSPropertyOperations.js +57 -10
- package/lib/CallbackQueue.js +2 -2
- package/lib/ChangeEventPlugin.js +3 -3
- package/lib/ClientReactRootIndex.js +1 -1
- package/lib/DOMChildrenOperations.js +6 -4
- package/lib/DOMProperty.js +1 -1
- package/lib/DOMPropertyOperations.js +4 -2
- package/lib/Danger.js +7 -6
- package/lib/DefaultEventPluginOrder.js +1 -2
- package/lib/EnterLeaveEventPlugin.js +1 -1
- package/lib/EventConstants.js +1 -1
- package/lib/EventPluginHub.js +9 -7
- package/lib/EventPluginRegistry.js +1 -1
- package/lib/EventPluginUtils.js +1 -1
- package/lib/EventPropagators.js +1 -1
- package/lib/ExecutionEnvironment.js +2 -3
- package/lib/FallbackCompositionState.js +89 -0
- package/lib/HTMLDOMPropertyConfig.js +19 -7
- package/lib/LinkedStateMixin.js +1 -1
- package/lib/LinkedValueUtils.js +3 -3
- package/lib/LocalEventTrapMixin.js +9 -2
- package/lib/MobileSafariClickEventPlugin.js +1 -1
- package/lib/Object.assign.js +3 -1
- package/lib/PooledClass.js +1 -1
- package/lib/React.js +17 -51
- package/lib/ReactBrowserComponentMixin.js +3 -13
- package/lib/ReactBrowserEventEmitter.js +4 -6
- package/lib/ReactCSSTransitionGroup.js +4 -1
- package/lib/ReactCSSTransitionGroupChild.js +12 -2
- package/lib/ReactChildReconciler.js +125 -0
- package/lib/ReactChildren.js +10 -8
- package/lib/ReactClass.js +916 -0
- package/lib/ReactComponent.js +81 -404
- package/lib/ReactComponentBrowserEnvironment.js +10 -83
- package/lib/ReactComponentEnvironment.js +57 -0
- package/lib/ReactComponentWithPureRenderMixin.js +1 -1
- package/lib/ReactCompositeComponent.js +533 -1132
- package/lib/ReactContext.js +6 -2
- package/lib/ReactCurrentOwner.js +1 -1
- package/lib/ReactDOM.js +3 -8
- package/lib/ReactDOMButton.js +5 -6
- package/lib/ReactDOMComponent.js +110 -92
- package/lib/ReactDOMForm.js +5 -6
- package/lib/ReactDOMIDOperations.js +56 -74
- package/lib/ReactDOMImg.js +4 -6
- package/lib/ReactDOMInput.js +5 -6
- package/lib/ReactDOMOption.js +5 -6
- package/lib/ReactDOMSelect.js +57 -65
- package/lib/ReactDOMSelection.js +6 -2
- package/lib/{ReactTextComponent.js → ReactDOMTextComponent.js} +48 -35
- package/lib/ReactDOMTextarea.js +5 -6
- package/lib/ReactDefaultBatchingStrategy.js +4 -4
- package/lib/ReactDefaultInjection.js +14 -8
- package/lib/ReactDefaultPerf.js +16 -7
- package/lib/ReactDefaultPerfAnalysis.js +1 -1
- package/lib/ReactElement.js +23 -15
- package/lib/ReactElementValidator.js +209 -57
- package/lib/ReactEmptyComponent.js +29 -11
- package/lib/ReactEventEmitterMixin.js +1 -1
- package/lib/ReactEventListener.js +3 -4
- package/lib/ReactInjection.js +7 -5
- package/lib/ReactInputSelection.js +3 -4
- package/lib/ReactInstanceHandles.js +3 -2
- package/lib/ReactInstanceMap.js +47 -0
- package/lib/ReactLifeCycle.js +35 -0
- package/lib/ReactLink.js +1 -1
- package/lib/ReactMarkupChecksum.js +1 -1
- package/lib/ReactMount.js +239 -68
- package/lib/ReactMultiChild.js +49 -47
- package/lib/ReactMultiChildUpdateTypes.js +1 -1
- package/lib/ReactNativeComponent.js +72 -25
- package/lib/ReactOwner.js +4 -48
- package/lib/ReactPerf.js +21 -1
- package/lib/ReactPropTransferer.js +2 -57
- package/lib/ReactPropTypeLocationNames.js +1 -1
- package/lib/ReactPropTypeLocations.js +1 -1
- package/lib/ReactPropTypes.js +14 -22
- package/lib/ReactPutListenerQueue.js +1 -1
- package/lib/ReactReconcileTransaction.js +1 -1
- package/lib/ReactReconciler.js +107 -0
- package/lib/ReactRef.js +70 -0
- package/lib/ReactRootIndex.js +1 -1
- package/lib/ReactServerRendering.js +5 -3
- package/lib/ReactServerRenderingTransaction.js +1 -1
- package/lib/ReactStateSetters.js +1 -1
- package/lib/ReactTestUtils.js +112 -26
- package/lib/ReactTransitionChildMapping.js +1 -1
- package/lib/ReactTransitionEvents.js +1 -1
- package/lib/ReactTransitionGroup.js +48 -7
- package/lib/ReactUpdateQueue.js +264 -0
- package/lib/ReactUpdates.js +48 -61
- package/lib/ReactWithAddons.js +1 -1
- package/lib/SVGDOMPropertyConfig.js +1 -1
- package/lib/SelectEventPlugin.js +3 -3
- package/lib/ServerReactRootIndex.js +1 -1
- package/lib/SimpleEventPlugin.js +1 -1
- package/lib/SyntheticClipboardEvent.js +1 -2
- package/lib/SyntheticCompositionEvent.js +1 -2
- package/lib/SyntheticDragEvent.js +1 -1
- package/lib/SyntheticEvent.js +11 -3
- package/lib/SyntheticFocusEvent.js +1 -1
- package/lib/SyntheticInputEvent.js +1 -2
- package/lib/SyntheticKeyboardEvent.js +1 -1
- package/lib/SyntheticMouseEvent.js +2 -4
- package/lib/SyntheticTouchEvent.js +1 -1
- package/lib/SyntheticUIEvent.js +1 -1
- package/lib/SyntheticWheelEvent.js +1 -1
- package/lib/Transaction.js +3 -3
- package/lib/ViewportMetrics.js +2 -5
- package/lib/accumulateInto.js +1 -1
- package/lib/adler32.js +1 -1
- package/lib/cloneWithProps.js +3 -3
- package/lib/copyProperties.js +2 -0
- package/lib/createFullPageComponent.js +3 -3
- package/lib/dangerousStyleValue.js +1 -1
- package/lib/escapeTextForBrowser.js +6 -6
- package/lib/findDOMNode.js +51 -0
- package/lib/flattenChildren.js +11 -22
- package/lib/forEachAccumulated.js +1 -1
- package/lib/getEventCharCode.js +1 -1
- package/lib/getEventKey.js +1 -1
- package/lib/getEventModifierState.js +1 -1
- package/lib/getEventTarget.js +1 -1
- package/lib/getIteratorFn.js +42 -0
- package/lib/getNodeForCharacterOffset.js +2 -2
- package/lib/getReactRootElementInContainer.js +1 -1
- package/lib/getTextContentAccessor.js +1 -1
- package/lib/instantiateReactComponent.js +85 -67
- package/lib/isEventSupported.js +1 -1
- package/lib/isNode.js +3 -4
- package/lib/isTextInputElement.js +2 -3
- package/lib/joinClasses.js +1 -1
- package/lib/keyMirror.js +1 -1
- package/lib/memoizeStringOnly.js +4 -5
- package/lib/onlyChild.js +1 -1
- package/lib/setInnerHTML.js +12 -1
- package/lib/shallowEqual.js +1 -1
- package/lib/shouldUpdateReactComponent.js +48 -6
- package/lib/traverseAllChildren.js +111 -55
- package/lib/update.js +1 -1
- package/lib/warning.js +12 -1
- package/package.json +1 -1
- package/lib/CompositionEventPlugin.js +0 -257
- package/lib/ReactLegacyElement.js +0 -243
- package/lib/deprecated.js +0 -47
package/lib/ReactStateSetters.js
CHANGED
package/lib/ReactTestUtils.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @providesModule ReactTestUtils
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
'use strict';
|
|
13
13
|
|
|
14
14
|
var EventConstants = require("./EventConstants");
|
|
15
15
|
var EventPluginHub = require("./EventPluginHub");
|
|
@@ -17,8 +17,10 @@ var EventPropagators = require("./EventPropagators");
|
|
|
17
17
|
var React = require("./React");
|
|
18
18
|
var ReactElement = require("./ReactElement");
|
|
19
19
|
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
20
|
+
var ReactCompositeComponent = require("./ReactCompositeComponent");
|
|
21
|
+
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
22
|
+
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
20
23
|
var ReactMount = require("./ReactMount");
|
|
21
|
-
var ReactTextComponent = require("./ReactTextComponent");
|
|
22
24
|
var ReactUpdates = require("./ReactUpdates");
|
|
23
25
|
var SyntheticEvent = require("./SyntheticEvent");
|
|
24
26
|
|
|
@@ -55,12 +57,14 @@ var ReactTestUtils = {
|
|
|
55
57
|
isElementOfType: function(inst, convenienceConstructor) {
|
|
56
58
|
return (
|
|
57
59
|
ReactElement.isValidElement(inst) &&
|
|
58
|
-
inst.type === convenienceConstructor
|
|
60
|
+
inst.type === convenienceConstructor
|
|
59
61
|
);
|
|
60
62
|
},
|
|
61
63
|
|
|
62
64
|
isDOMComponent: function(inst) {
|
|
63
|
-
|
|
65
|
+
// TODO: Fix this heuristic. It's just here because composites can currently
|
|
66
|
+
// pretend to be DOM components.
|
|
67
|
+
return !!(inst && inst.getDOMNode && inst.tagName);
|
|
64
68
|
},
|
|
65
69
|
|
|
66
70
|
isDOMComponentElement: function(inst) {
|
|
@@ -76,7 +80,7 @@ var ReactTestUtils = {
|
|
|
76
80
|
|
|
77
81
|
isCompositeComponentWithType: function(inst, type) {
|
|
78
82
|
return !!(ReactTestUtils.isCompositeComponent(inst) &&
|
|
79
|
-
(inst.constructor === type
|
|
83
|
+
(inst.constructor === type));
|
|
80
84
|
},
|
|
81
85
|
|
|
82
86
|
isCompositeComponentElement: function(inst) {
|
|
@@ -97,8 +101,12 @@ var ReactTestUtils = {
|
|
|
97
101
|
(inst.constructor === type));
|
|
98
102
|
},
|
|
99
103
|
|
|
100
|
-
|
|
101
|
-
|
|
104
|
+
getRenderedChildOfCompositeComponent: function(inst) {
|
|
105
|
+
if (!ReactTestUtils.isCompositeComponent(inst)) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
var internalInstance = ReactInstanceMap.get(inst);
|
|
109
|
+
return internalInstance._renderedComponent.getPublicInstance();
|
|
102
110
|
},
|
|
103
111
|
|
|
104
112
|
findAllInRenderedTree: function(inst, test) {
|
|
@@ -107,19 +115,31 @@ var ReactTestUtils = {
|
|
|
107
115
|
}
|
|
108
116
|
var ret = test(inst) ? [inst] : [];
|
|
109
117
|
if (ReactTestUtils.isDOMComponent(inst)) {
|
|
110
|
-
var
|
|
118
|
+
var internalInstance = ReactInstanceMap.get(inst);
|
|
119
|
+
var renderedChildren = internalInstance
|
|
120
|
+
._renderedComponent
|
|
121
|
+
._renderedChildren;
|
|
111
122
|
var key;
|
|
112
123
|
for (key in renderedChildren) {
|
|
113
124
|
if (!renderedChildren.hasOwnProperty(key)) {
|
|
114
125
|
continue;
|
|
115
126
|
}
|
|
127
|
+
if (!renderedChildren[key].getPublicInstance) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
116
130
|
ret = ret.concat(
|
|
117
|
-
ReactTestUtils.findAllInRenderedTree(
|
|
131
|
+
ReactTestUtils.findAllInRenderedTree(
|
|
132
|
+
renderedChildren[key].getPublicInstance(),
|
|
133
|
+
test
|
|
134
|
+
)
|
|
118
135
|
);
|
|
119
136
|
}
|
|
120
137
|
} else if (ReactTestUtils.isCompositeComponent(inst)) {
|
|
121
138
|
ret = ret.concat(
|
|
122
|
-
ReactTestUtils.findAllInRenderedTree(
|
|
139
|
+
ReactTestUtils.findAllInRenderedTree(
|
|
140
|
+
ReactTestUtils.getRenderedChildOfCompositeComponent(inst),
|
|
141
|
+
test
|
|
142
|
+
)
|
|
123
143
|
);
|
|
124
144
|
}
|
|
125
145
|
return ret;
|
|
@@ -134,8 +154,7 @@ var ReactTestUtils = {
|
|
|
134
154
|
return ReactTestUtils.findAllInRenderedTree(root, function(inst) {
|
|
135
155
|
var instClassName = inst.props.className;
|
|
136
156
|
return ReactTestUtils.isDOMComponent(inst) && (
|
|
137
|
-
instClassName &&
|
|
138
|
-
(' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1
|
|
157
|
+
(instClassName && (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1)
|
|
139
158
|
);
|
|
140
159
|
});
|
|
141
160
|
},
|
|
@@ -150,7 +169,9 @@ var ReactTestUtils = {
|
|
|
150
169
|
var all =
|
|
151
170
|
ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className);
|
|
152
171
|
if (all.length !== 1) {
|
|
153
|
-
throw new Error('Did not find exactly one match
|
|
172
|
+
throw new Error('Did not find exactly one match '+
|
|
173
|
+
'(found: ' + all.length + ') for class:' + className
|
|
174
|
+
);
|
|
154
175
|
}
|
|
155
176
|
return all[0];
|
|
156
177
|
},
|
|
@@ -231,21 +252,14 @@ var ReactTestUtils = {
|
|
|
231
252
|
mockComponent: function(module, mockTagName) {
|
|
232
253
|
mockTagName = mockTagName || module.mockTagName || "div";
|
|
233
254
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
);
|
|
241
|
-
}
|
|
255
|
+
module.prototype.render.mockImplementation(function() {
|
|
256
|
+
return React.createElement(
|
|
257
|
+
mockTagName,
|
|
258
|
+
null,
|
|
259
|
+
this.props.children
|
|
260
|
+
);
|
|
242
261
|
});
|
|
243
262
|
|
|
244
|
-
module.mockImplementation(ConvenienceConstructor);
|
|
245
|
-
|
|
246
|
-
module.type = ConvenienceConstructor.type;
|
|
247
|
-
module.isReactLegacyFactory = true;
|
|
248
|
-
|
|
249
263
|
return this;
|
|
250
264
|
},
|
|
251
265
|
|
|
@@ -290,10 +304,82 @@ var ReactTestUtils = {
|
|
|
290
304
|
};
|
|
291
305
|
},
|
|
292
306
|
|
|
307
|
+
createRenderer: function() {
|
|
308
|
+
return new ReactShallowRenderer();
|
|
309
|
+
},
|
|
310
|
+
|
|
293
311
|
Simulate: null,
|
|
294
312
|
SimulateNative: {}
|
|
295
313
|
};
|
|
296
314
|
|
|
315
|
+
/**
|
|
316
|
+
* @class ReactShallowRenderer
|
|
317
|
+
*/
|
|
318
|
+
var ReactShallowRenderer = function() {
|
|
319
|
+
this._instance = null;
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
ReactShallowRenderer.prototype.getRenderOutput = function() {
|
|
323
|
+
return (
|
|
324
|
+
(this._instance && this._instance._renderedComponent &&
|
|
325
|
+
this._instance._renderedComponent._currentElement)
|
|
326
|
+
|| null
|
|
327
|
+
);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
var NoopInternalComponent = function(element) {
|
|
331
|
+
this._currentElement = element;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
NoopInternalComponent.prototype = {
|
|
335
|
+
|
|
336
|
+
mountComponent: function() {
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
receiveComponent: function(element) {
|
|
340
|
+
this._currentElement = element;
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
unmountComponent: function() {
|
|
344
|
+
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
var ShallowComponentWrapper = function() { };
|
|
350
|
+
assign(
|
|
351
|
+
ShallowComponentWrapper.prototype,
|
|
352
|
+
ReactCompositeComponent.Mixin, {
|
|
353
|
+
_instantiateReactComponent: function(element) {
|
|
354
|
+
return new NoopInternalComponent(element);
|
|
355
|
+
},
|
|
356
|
+
_replaceNodeWithMarkupByID: function() {},
|
|
357
|
+
_renderValidatedComponent:
|
|
358
|
+
ReactCompositeComponent.Mixin.
|
|
359
|
+
_renderValidatedComponentWithoutOwnerOrContext
|
|
360
|
+
}
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
ReactShallowRenderer.prototype.render = function(element, context) {
|
|
364
|
+
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
|
|
365
|
+
this._render(element, transaction, context);
|
|
366
|
+
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
ReactShallowRenderer.prototype._render = function(element, transaction, context) {
|
|
370
|
+
if (!this._instance) {
|
|
371
|
+
var rootID = ReactInstanceHandles.createReactRootID();
|
|
372
|
+
var instance = new ShallowComponentWrapper(element.type);
|
|
373
|
+
instance.construct(element);
|
|
374
|
+
|
|
375
|
+
instance.mountComponent(rootID, transaction, context);
|
|
376
|
+
|
|
377
|
+
this._instance = instance;
|
|
378
|
+
} else {
|
|
379
|
+
this._instance.receiveComponent(element, transaction, context);
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
|
|
297
383
|
/**
|
|
298
384
|
* Exports:
|
|
299
385
|
*
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @providesModule ReactTransitionGroup
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
'use strict';
|
|
13
13
|
|
|
14
14
|
var React = require("./React");
|
|
15
15
|
var ReactTransitionChildMapping = require("./ReactTransitionChildMapping");
|
|
@@ -39,6 +39,21 @@ var ReactTransitionGroup = React.createClass({
|
|
|
39
39
|
};
|
|
40
40
|
},
|
|
41
41
|
|
|
42
|
+
componentWillMount: function() {
|
|
43
|
+
this.currentlyTransitioningKeys = {};
|
|
44
|
+
this.keysToEnter = [];
|
|
45
|
+
this.keysToLeave = [];
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
componentDidMount: function() {
|
|
49
|
+
var initialChildMapping = this.state.children;
|
|
50
|
+
for (var key in initialChildMapping) {
|
|
51
|
+
if (initialChildMapping[key]) {
|
|
52
|
+
this.performAppear(key);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
|
|
42
57
|
componentWillReceiveProps: function(nextProps) {
|
|
43
58
|
var nextChildMapping = ReactTransitionChildMapping.getChildMapping(
|
|
44
59
|
nextProps.children
|
|
@@ -73,12 +88,6 @@ var ReactTransitionGroup = React.createClass({
|
|
|
73
88
|
// If we want to someday check for reordering, we could do it here.
|
|
74
89
|
},
|
|
75
90
|
|
|
76
|
-
componentWillMount: function() {
|
|
77
|
-
this.currentlyTransitioningKeys = {};
|
|
78
|
-
this.keysToEnter = [];
|
|
79
|
-
this.keysToLeave = [];
|
|
80
|
-
},
|
|
81
|
-
|
|
82
91
|
componentDidUpdate: function() {
|
|
83
92
|
var keysToEnter = this.keysToEnter;
|
|
84
93
|
this.keysToEnter = [];
|
|
@@ -89,6 +98,38 @@ var ReactTransitionGroup = React.createClass({
|
|
|
89
98
|
keysToLeave.forEach(this.performLeave);
|
|
90
99
|
},
|
|
91
100
|
|
|
101
|
+
performAppear: function(key) {
|
|
102
|
+
this.currentlyTransitioningKeys[key] = true;
|
|
103
|
+
|
|
104
|
+
var component = this.refs[key];
|
|
105
|
+
|
|
106
|
+
if (component.componentWillAppear) {
|
|
107
|
+
component.componentWillAppear(
|
|
108
|
+
this._handleDoneAppearing.bind(this, key)
|
|
109
|
+
);
|
|
110
|
+
} else {
|
|
111
|
+
this._handleDoneAppearing(key);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
_handleDoneAppearing: function(key) {
|
|
116
|
+
var component = this.refs[key];
|
|
117
|
+
if (component.componentDidAppear) {
|
|
118
|
+
component.componentDidAppear();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
delete this.currentlyTransitioningKeys[key];
|
|
122
|
+
|
|
123
|
+
var currentChildMapping = ReactTransitionChildMapping.getChildMapping(
|
|
124
|
+
this.props.children
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) {
|
|
128
|
+
// This was removed before it had fully appeared. Remove it.
|
|
129
|
+
this.performLeave(key);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
|
|
92
133
|
performEnter: function(key) {
|
|
93
134
|
this.currentlyTransitioningKeys[key] = true;
|
|
94
135
|
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2015, 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 ReactUpdateQueue
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
"use strict";
|
|
13
|
+
|
|
14
|
+
var ReactLifeCycle = require("./ReactLifeCycle");
|
|
15
|
+
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
16
|
+
var ReactElement = require("./ReactElement");
|
|
17
|
+
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
18
|
+
var ReactUpdates = require("./ReactUpdates");
|
|
19
|
+
|
|
20
|
+
var assign = require("./Object.assign");
|
|
21
|
+
var invariant = require("./invariant");
|
|
22
|
+
|
|
23
|
+
function enqueueUpdate(internalInstance) {
|
|
24
|
+
if (internalInstance !== ReactLifeCycle.currentlyMountingInstance) {
|
|
25
|
+
// If we're in a componentWillMount handler, don't enqueue a rerender
|
|
26
|
+
// because ReactUpdates assumes we're in a browser context (which is
|
|
27
|
+
// wrong for server rendering) and we're about to do a render anyway.
|
|
28
|
+
// See bug in #1740.
|
|
29
|
+
ReactUpdates.enqueueUpdate(internalInstance);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getInternalInstanceReadyForUpdate(publicInstance, callerName) {
|
|
34
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
35
|
+
ReactCurrentOwner.current == null,
|
|
36
|
+
'%s(...): Cannot update during an existing state transition ' +
|
|
37
|
+
'(such as within `render`). Render methods should be a pure function ' +
|
|
38
|
+
'of props and state.',
|
|
39
|
+
callerName
|
|
40
|
+
) : invariant(ReactCurrentOwner.current == null));
|
|
41
|
+
|
|
42
|
+
var internalInstance = ReactInstanceMap.get(publicInstance);
|
|
43
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
44
|
+
internalInstance,
|
|
45
|
+
'%s(...): Can only update a mounted or mounting component. ' +
|
|
46
|
+
'This usually means you called %s() on an unmounted ' +
|
|
47
|
+
'component.',
|
|
48
|
+
callerName,
|
|
49
|
+
callerName
|
|
50
|
+
) : invariant(internalInstance));
|
|
51
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
52
|
+
internalInstance !== ReactLifeCycle.currentlyUnmountingInstance,
|
|
53
|
+
'%s(...): Cannot call %s() on an unmounting component.',
|
|
54
|
+
callerName,
|
|
55
|
+
callerName
|
|
56
|
+
) : invariant(internalInstance !== ReactLifeCycle.currentlyUnmountingInstance));
|
|
57
|
+
return internalInstance;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* ReactUpdateQueue allows for state updates to be scheduled into a later
|
|
62
|
+
* reconciliation step.
|
|
63
|
+
*/
|
|
64
|
+
var ReactUpdateQueue = {
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Enqueue a callback that will be executed after all the pending updates
|
|
68
|
+
* have processed.
|
|
69
|
+
*
|
|
70
|
+
* @param {ReactClass} publicInstance The instance to use as `this` context.
|
|
71
|
+
* @param {?function} callback Called after state is updated.
|
|
72
|
+
* @internal
|
|
73
|
+
*/
|
|
74
|
+
enqueueCallback: function(publicInstance, callback) {
|
|
75
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
76
|
+
typeof callback === 'function',
|
|
77
|
+
'enqueueCallback(...): You called `setProps`, `replaceProps`, ' +
|
|
78
|
+
'`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
|
|
79
|
+
'isn\'t callable.'
|
|
80
|
+
) : invariant(typeof callback === 'function'));
|
|
81
|
+
var internalInstance = ReactInstanceMap.get(publicInstance);
|
|
82
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
83
|
+
internalInstance,
|
|
84
|
+
'Cannot enqueue a callback on an instance that is unmounted.'
|
|
85
|
+
) : invariant(internalInstance));
|
|
86
|
+
if (internalInstance === ReactLifeCycle.currentlyMountingInstance) {
|
|
87
|
+
// Ignore callbacks in componentWillMount. See enqueueUpdate.
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (internalInstance._pendingCallbacks) {
|
|
91
|
+
internalInstance._pendingCallbacks.push(callback);
|
|
92
|
+
} else {
|
|
93
|
+
internalInstance._pendingCallbacks = [callback];
|
|
94
|
+
}
|
|
95
|
+
// TODO: The callback here is ignored when setState is called from
|
|
96
|
+
// componentWillMount. Either fix it or disallow doing so completely in
|
|
97
|
+
// favor of getInitialState. Alternatively, we can disallow
|
|
98
|
+
// componentWillMount during server-side rendering.
|
|
99
|
+
enqueueUpdate(internalInstance);
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
enqueueCallbackInternal: function(internalInstance, callback) {
|
|
103
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
104
|
+
typeof callback === "function",
|
|
105
|
+
'enqueueCallback(...): You called `setProps`, `replaceProps`, ' +
|
|
106
|
+
'`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
|
|
107
|
+
'isn\'t callable.'
|
|
108
|
+
) : invariant(typeof callback === "function"));
|
|
109
|
+
if (internalInstance._pendingCallbacks) {
|
|
110
|
+
internalInstance._pendingCallbacks.push(callback);
|
|
111
|
+
} else {
|
|
112
|
+
internalInstance._pendingCallbacks = [callback];
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Forces an update. This should only be invoked when it is known with
|
|
118
|
+
* certainty that we are **not** in a DOM transaction.
|
|
119
|
+
*
|
|
120
|
+
* You may want to call this when you know that some deeper aspect of the
|
|
121
|
+
* component's state has changed but `setState` was not called.
|
|
122
|
+
*
|
|
123
|
+
* This will not invoke `shouldUpdateComponent`, but it will invoke
|
|
124
|
+
* `componentWillUpdate` and `componentDidUpdate`.
|
|
125
|
+
*
|
|
126
|
+
* @param {ReactClass} publicInstance The instance that should rerender.
|
|
127
|
+
* @internal
|
|
128
|
+
*/
|
|
129
|
+
enqueueForceUpdate: function(publicInstance) {
|
|
130
|
+
var internalInstance = getInternalInstanceReadyForUpdate(
|
|
131
|
+
publicInstance,
|
|
132
|
+
'forceUpdate'
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
internalInstance._pendingForceUpdate = true;
|
|
136
|
+
|
|
137
|
+
enqueueUpdate(internalInstance);
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Replaces all of the state. Always use this or `setState` to mutate state.
|
|
142
|
+
* You should treat `this.state` as immutable.
|
|
143
|
+
*
|
|
144
|
+
* There is no guarantee that `this.state` will be immediately updated, so
|
|
145
|
+
* accessing `this.state` after calling this method may return the old value.
|
|
146
|
+
*
|
|
147
|
+
* @param {ReactClass} publicInstance The instance that should rerender.
|
|
148
|
+
* @param {object} completeState Next state.
|
|
149
|
+
* @internal
|
|
150
|
+
*/
|
|
151
|
+
enqueueReplaceState: function(publicInstance, completeState) {
|
|
152
|
+
var internalInstance = getInternalInstanceReadyForUpdate(
|
|
153
|
+
publicInstance,
|
|
154
|
+
'replaceState'
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
internalInstance._pendingState = completeState;
|
|
158
|
+
|
|
159
|
+
enqueueUpdate(internalInstance);
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Sets a subset of the state. This only exists because _pendingState is
|
|
164
|
+
* internal. This provides a merging strategy that is not available to deep
|
|
165
|
+
* properties which is confusing. TODO: Expose pendingState or don't use it
|
|
166
|
+
* during the merge.
|
|
167
|
+
*
|
|
168
|
+
* @param {ReactClass} publicInstance The instance that should rerender.
|
|
169
|
+
* @param {object} partialState Next partial state to be merged with state.
|
|
170
|
+
* @internal
|
|
171
|
+
*/
|
|
172
|
+
enqueueSetState: function(publicInstance, partialState) {
|
|
173
|
+
var internalInstance = getInternalInstanceReadyForUpdate(
|
|
174
|
+
publicInstance,
|
|
175
|
+
'setState'
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
// Merge with `_pendingState` if it exists, otherwise with existing state.
|
|
179
|
+
internalInstance._pendingState = assign(
|
|
180
|
+
{},
|
|
181
|
+
internalInstance._pendingState || internalInstance._instance.state,
|
|
182
|
+
partialState
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
enqueueUpdate(internalInstance);
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Sets a subset of the props.
|
|
190
|
+
*
|
|
191
|
+
* @param {ReactClass} publicInstance The instance that should rerender.
|
|
192
|
+
* @param {object} partialProps Subset of the next props.
|
|
193
|
+
* @internal
|
|
194
|
+
*/
|
|
195
|
+
enqueueSetProps: function(publicInstance, partialProps) {
|
|
196
|
+
var internalInstance = getInternalInstanceReadyForUpdate(
|
|
197
|
+
publicInstance,
|
|
198
|
+
'setProps'
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
202
|
+
internalInstance._isTopLevel,
|
|
203
|
+
'setProps(...): You called `setProps` on a ' +
|
|
204
|
+
'component with a parent. This is an anti-pattern since props will ' +
|
|
205
|
+
'get reactively updated when rendered. Instead, change the owner\'s ' +
|
|
206
|
+
'`render` method to pass the correct value as props to the component ' +
|
|
207
|
+
'where it is created.'
|
|
208
|
+
) : invariant(internalInstance._isTopLevel));
|
|
209
|
+
|
|
210
|
+
// Merge with the pending element if it exists, otherwise with existing
|
|
211
|
+
// element props.
|
|
212
|
+
var element = internalInstance._pendingElement ||
|
|
213
|
+
internalInstance._currentElement;
|
|
214
|
+
var props = assign({}, element.props, partialProps);
|
|
215
|
+
internalInstance._pendingElement = ReactElement.cloneAndReplaceProps(
|
|
216
|
+
element,
|
|
217
|
+
props
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
enqueueUpdate(internalInstance);
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Replaces all of the props.
|
|
225
|
+
*
|
|
226
|
+
* @param {ReactClass} publicInstance The instance that should rerender.
|
|
227
|
+
* @param {object} props New props.
|
|
228
|
+
* @internal
|
|
229
|
+
*/
|
|
230
|
+
enqueueReplaceProps: function(publicInstance, props) {
|
|
231
|
+
var internalInstance = getInternalInstanceReadyForUpdate(
|
|
232
|
+
publicInstance,
|
|
233
|
+
'replaceProps'
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
237
|
+
internalInstance._isTopLevel,
|
|
238
|
+
'replaceProps(...): You called `replaceProps` on a ' +
|
|
239
|
+
'component with a parent. This is an anti-pattern since props will ' +
|
|
240
|
+
'get reactively updated when rendered. Instead, change the owner\'s ' +
|
|
241
|
+
'`render` method to pass the correct value as props to the component ' +
|
|
242
|
+
'where it is created.'
|
|
243
|
+
) : invariant(internalInstance._isTopLevel));
|
|
244
|
+
|
|
245
|
+
// Merge with the pending element if it exists, otherwise with existing
|
|
246
|
+
// element props.
|
|
247
|
+
var element = internalInstance._pendingElement ||
|
|
248
|
+
internalInstance._currentElement;
|
|
249
|
+
internalInstance._pendingElement = ReactElement.cloneAndReplaceProps(
|
|
250
|
+
element,
|
|
251
|
+
props
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
enqueueUpdate(internalInstance);
|
|
255
|
+
},
|
|
256
|
+
|
|
257
|
+
enqueueElementInternal: function(internalInstance, newElement) {
|
|
258
|
+
internalInstance._pendingElement = newElement;
|
|
259
|
+
enqueueUpdate(internalInstance);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
module.exports = ReactUpdateQueue;
|