react 0.12.2 → 0.13.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/JSXTransformer.js +6 -4
- package/dist/react-with-addons.js +4022 -3267
- package/dist/react-with-addons.min.js +6 -6
- package/dist/react.js +3853 -3358
- package/dist/react.min.js +6 -6
- package/lib/BeforeInputEventPlugin.js +388 -111
- package/lib/CSSPropertyOperations.js +20 -0
- package/lib/ChangeEventPlugin.js +2 -2
- package/lib/Danger.js +1 -1
- package/lib/DefaultEventPluginOrder.js +0 -1
- package/lib/ExecutionEnvironment.js +2 -3
- package/lib/FallbackCompositionState.js +87 -0
- package/lib/HTMLDOMPropertyConfig.js +1 -0
- package/lib/Object.assign.js +3 -1
- package/lib/React.js +14 -49
- package/lib/ReactBrowserComponentMixin.js +2 -12
- package/lib/ReactBrowserEventEmitter.js +2 -4
- package/lib/ReactCSSTransitionGroup.js +3 -0
- package/lib/ReactCSSTransitionGroupChild.js +8 -0
- package/lib/ReactChildReconciler.js +121 -0
- package/lib/ReactClass.js +916 -0
- package/lib/ReactComponent.js +36 -286
- package/lib/ReactComponentBrowserEnvironment.js +9 -82
- package/lib/ReactComponentEnvironment.js +57 -0
- package/lib/ReactCompositeComponent.js +608 -1026
- package/lib/ReactContext.js +5 -1
- package/lib/ReactDOM.js +2 -7
- package/lib/ReactDOMButton.js +4 -5
- package/lib/ReactDOMComponent.js +97 -69
- package/lib/ReactDOMForm.js +4 -5
- package/lib/ReactDOMIDOperations.js +55 -73
- package/lib/ReactDOMImg.js +3 -5
- package/lib/ReactDOMInput.js +4 -5
- package/lib/ReactDOMOption.js +4 -5
- package/lib/ReactDOMSelect.js +55 -63
- package/lib/ReactDOMSelection.js +5 -1
- package/lib/{ReactTextComponent.js → ReactDOMTextComponent.js} +54 -34
- package/lib/ReactDOMTextarea.js +4 -5
- package/lib/ReactDefaultInjection.js +13 -7
- package/lib/ReactDefaultPerf.js +6 -5
- package/lib/ReactDefaultPerfAnalysis.js +1 -1
- package/lib/ReactElement.js +17 -11
- package/lib/ReactElementValidator.js +74 -37
- package/lib/ReactEmptyComponent.js +17 -10
- package/lib/ReactInjection.js +6 -4
- package/lib/ReactInputSelection.js +2 -3
- package/lib/ReactInstanceMap.js +47 -0
- package/lib/ReactMount.js +193 -64
- package/lib/ReactMultiChild.js +32 -42
- package/lib/ReactNativeComponent.js +45 -8
- package/lib/ReactOwner.js +3 -47
- package/lib/ReactPerf.js +20 -0
- package/lib/ReactPropTransferer.js +0 -55
- package/lib/ReactPropTypes.js +1 -17
- package/lib/ReactRef.js +96 -0
- package/lib/ReactServerRendering.js +3 -2
- package/lib/ReactTestUtils.js +82 -25
- package/lib/ReactTransitionGroup.js +47 -6
- package/lib/ReactUpdates.js +43 -42
- package/lib/SyntheticMouseEvent.js +1 -3
- package/lib/ViewportMetrics.js +1 -4
- package/lib/accumulate.js +47 -0
- package/lib/cloneWithProps.js +2 -2
- package/lib/copyProperties.js +2 -0
- package/lib/createFullPageComponent.js +2 -2
- package/lib/findDOMNode.js +52 -0
- package/lib/flattenChildren.js +1 -14
- package/lib/getIteratorFn.js +42 -0
- package/lib/instantiateReactComponent.js +88 -65
- package/lib/isNode.js +3 -4
- package/lib/isTextInputElement.js +1 -2
- package/lib/shouldUpdateReactComponent.js +13 -5
- package/lib/traverseAllChildren.js +110 -54
- package/package.json +1 -1
- package/lib/CompositionEventPlugin.js +0 -257
- package/lib/ReactLegacyElement.js +0 -243
- package/lib/deprecated.js +0 -47
|
@@ -31,9 +31,8 @@ var ReactInputSelection = {
|
|
|
31
31
|
|
|
32
32
|
hasSelectionCapabilities: function(elem) {
|
|
33
33
|
return elem && (
|
|
34
|
-
(elem.nodeName === 'INPUT' && elem.type === 'text') ||
|
|
35
|
-
elem.nodeName === 'TEXTAREA' ||
|
|
36
|
-
elem.contentEditable === 'true'
|
|
34
|
+
((elem.nodeName === 'INPUT' && elem.type === 'text') ||
|
|
35
|
+
elem.nodeName === 'TEXTAREA' || elem.contentEditable === 'true')
|
|
37
36
|
);
|
|
38
37
|
},
|
|
39
38
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013-2014, Facebook, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the BSD-style license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree. An additional grant
|
|
7
|
+
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
|
+
*
|
|
9
|
+
* @providesModule ReactInstanceMap
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
"use strict";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* `ReactInstanceMap` maintains a mapping from a public facing stateful
|
|
16
|
+
* instance (key) and the internal representation (value). This allows public
|
|
17
|
+
* methods to accept the user facing instance as an argument and map them back
|
|
18
|
+
* to internal methods.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// TODO: Replace this with ES6: var ReactInstanceMap = new Map();
|
|
22
|
+
var ReactInstanceMap = {
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* This API should be called `delete` but we'd have to make sure to always
|
|
26
|
+
* transform these to strings for IE support. When this transform is fully
|
|
27
|
+
* supported we can rename it.
|
|
28
|
+
*/
|
|
29
|
+
remove: function(key) {
|
|
30
|
+
key._reactInternalInstance = undefined;
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
get: function(key) {
|
|
34
|
+
return key._reactInternalInstance;
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
has: function(key) {
|
|
38
|
+
return key._reactInternalInstance !== undefined;
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
set: function(key, value) {
|
|
42
|
+
key._reactInternalInstance = value;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
module.exports = ReactInstanceMap;
|
package/lib/ReactMount.js
CHANGED
|
@@ -15,22 +15,22 @@ var DOMProperty = require("./DOMProperty");
|
|
|
15
15
|
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
16
16
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
17
17
|
var ReactElement = require("./ReactElement");
|
|
18
|
-
var
|
|
18
|
+
var ReactEmptyComponent = require("./ReactEmptyComponent");
|
|
19
19
|
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
20
|
+
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
21
|
+
var ReactMarkupChecksum = require("./ReactMarkupChecksum");
|
|
20
22
|
var ReactPerf = require("./ReactPerf");
|
|
23
|
+
var ReactUpdates = require("./ReactUpdates");
|
|
21
24
|
|
|
25
|
+
var emptyObject = require("./emptyObject");
|
|
22
26
|
var containsNode = require("./containsNode");
|
|
23
|
-
var deprecated = require("./deprecated");
|
|
24
27
|
var getReactRootElementInContainer = require("./getReactRootElementInContainer");
|
|
25
28
|
var instantiateReactComponent = require("./instantiateReactComponent");
|
|
26
29
|
var invariant = require("./invariant");
|
|
30
|
+
var setInnerHTML = require("./setInnerHTML");
|
|
27
31
|
var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
|
|
28
32
|
var warning = require("./warning");
|
|
29
33
|
|
|
30
|
-
var createElement = ReactLegacyElement.wrapCreateElement(
|
|
31
|
-
ReactElement.createElement
|
|
32
|
-
);
|
|
33
|
-
|
|
34
34
|
var SEPARATOR = ReactInstanceHandles.SEPARATOR;
|
|
35
35
|
|
|
36
36
|
var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
|
|
@@ -53,6 +53,22 @@ if ("production" !== process.env.NODE_ENV) {
|
|
|
53
53
|
// Used to store breadth-first search state in findComponentRoot.
|
|
54
54
|
var findComponentRootReusableArray = [];
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Finds the index of the first character
|
|
58
|
+
* that's not common between the two given strings.
|
|
59
|
+
*
|
|
60
|
+
* @return {number} the index of the character where the strings diverge
|
|
61
|
+
*/
|
|
62
|
+
function firstDifferenceIndex(string1, string2) {
|
|
63
|
+
var minLen = Math.min(string1.length, string2.length);
|
|
64
|
+
for (var i = 0; i < minLen; i++) {
|
|
65
|
+
if (string1.charAt(i) !== string2.charAt(i)) {
|
|
66
|
+
return i;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return string1.length === string2.length ? -1 : minLen;
|
|
70
|
+
}
|
|
71
|
+
|
|
56
72
|
/**
|
|
57
73
|
* @param {DOMElement} container DOM element that may contain a React component.
|
|
58
74
|
* @return {?string} A "reactRoot" ID, if a React component is rendered.
|
|
@@ -130,6 +146,24 @@ function getNode(id) {
|
|
|
130
146
|
return nodeCache[id];
|
|
131
147
|
}
|
|
132
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Finds the node with the supplied public React instance.
|
|
151
|
+
*
|
|
152
|
+
* @param {*} instance A public React instance.
|
|
153
|
+
* @return {?DOMElement} DOM node with the suppled `id`.
|
|
154
|
+
* @internal
|
|
155
|
+
*/
|
|
156
|
+
function getNodeFromInstance(instance) {
|
|
157
|
+
var id = ReactInstanceMap.get(instance)._rootNodeID;
|
|
158
|
+
if (ReactEmptyComponent.isNullComponentID(id)) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
|
|
162
|
+
nodeCache[id] = ReactMount.findReactNodeByID(id);
|
|
163
|
+
}
|
|
164
|
+
return nodeCache[id];
|
|
165
|
+
}
|
|
166
|
+
|
|
133
167
|
/**
|
|
134
168
|
* A node is "valid" if it is contained by a currently mounted container.
|
|
135
169
|
*
|
|
@@ -193,6 +227,24 @@ function findDeepestCachedAncestor(targetID) {
|
|
|
193
227
|
return foundNode;
|
|
194
228
|
}
|
|
195
229
|
|
|
230
|
+
/**
|
|
231
|
+
* Mounts this component and inserts it into the DOM.
|
|
232
|
+
*
|
|
233
|
+
* @param {string} rootID DOM ID of the root node.
|
|
234
|
+
* @param {DOMElement} container DOM element to mount into.
|
|
235
|
+
* @param {ReactReconcileTransaction} transaction
|
|
236
|
+
* @param {boolean} shouldReuseMarkup If true, do not insert markup
|
|
237
|
+
*/
|
|
238
|
+
function mountComponentIntoNode(
|
|
239
|
+
rootID,
|
|
240
|
+
container,
|
|
241
|
+
transaction,
|
|
242
|
+
shouldReuseMarkup) {
|
|
243
|
+
var markup = this.mountComponent(rootID, transaction, emptyObject);
|
|
244
|
+
this._isTopLevel = true;
|
|
245
|
+
ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup);
|
|
246
|
+
}
|
|
247
|
+
|
|
196
248
|
/**
|
|
197
249
|
* Mounting is the process of initializing a React component by creatings its
|
|
198
250
|
* representative DOM elements and inserting them into a supplied `container`.
|
|
@@ -230,16 +282,16 @@ var ReactMount = {
|
|
|
230
282
|
/**
|
|
231
283
|
* Take a component that's already mounted into the DOM and replace its props
|
|
232
284
|
* @param {ReactComponent} prevComponent component instance already in the DOM
|
|
233
|
-
* @param {
|
|
285
|
+
* @param {ReactElement} nextElement component instance to render
|
|
234
286
|
* @param {DOMElement} container container to render into
|
|
235
287
|
* @param {?function} callback function triggered on completion
|
|
236
288
|
*/
|
|
237
289
|
_updateRootComponent: function(
|
|
238
290
|
prevComponent,
|
|
239
|
-
|
|
291
|
+
nextElement,
|
|
240
292
|
container,
|
|
241
293
|
callback) {
|
|
242
|
-
var nextProps =
|
|
294
|
+
var nextProps = nextElement.props;
|
|
243
295
|
ReactMount.scrollMonitor(container, function() {
|
|
244
296
|
prevComponent.replaceProps(nextProps, callback);
|
|
245
297
|
});
|
|
@@ -263,13 +315,11 @@ var ReactMount = {
|
|
|
263
315
|
_registerComponent: function(nextComponent, container) {
|
|
264
316
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
265
317
|
container && (
|
|
266
|
-
container.nodeType === ELEMENT_NODE_TYPE ||
|
|
267
|
-
container.nodeType === DOC_NODE_TYPE
|
|
318
|
+
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
268
319
|
),
|
|
269
320
|
'_registerComponent(...): Target container is not a DOM element.'
|
|
270
321
|
) : invariant(container && (
|
|
271
|
-
container.nodeType === ELEMENT_NODE_TYPE ||
|
|
272
|
-
container.nodeType === DOC_NODE_TYPE
|
|
322
|
+
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
273
323
|
)));
|
|
274
324
|
|
|
275
325
|
ReactBrowserEventEmitter.ensureScrollValueMonitoring();
|
|
@@ -286,44 +336,47 @@ var ReactMount = {
|
|
|
286
336
|
* @param {boolean} shouldReuseMarkup if we should skip the markup insertion
|
|
287
337
|
* @return {ReactComponent} nextComponent
|
|
288
338
|
*/
|
|
289
|
-
_renderNewRootComponent:
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
'componentDidUpdate.'
|
|
305
|
-
) : null);
|
|
306
|
-
|
|
307
|
-
var componentInstance = instantiateReactComponent(nextComponent, null);
|
|
308
|
-
var reactRootID = ReactMount._registerComponent(
|
|
309
|
-
componentInstance,
|
|
310
|
-
container
|
|
311
|
-
);
|
|
312
|
-
componentInstance.mountComponentIntoNode(
|
|
313
|
-
reactRootID,
|
|
314
|
-
container,
|
|
315
|
-
shouldReuseMarkup
|
|
316
|
-
);
|
|
317
|
-
|
|
318
|
-
if ("production" !== process.env.NODE_ENV) {
|
|
319
|
-
// Record the root element in case it later gets transplanted.
|
|
320
|
-
rootElementsByReactRootID[reactRootID] =
|
|
321
|
-
getReactRootElementInContainer(container);
|
|
322
|
-
}
|
|
339
|
+
_renderNewRootComponent: function(
|
|
340
|
+
nextComponent,
|
|
341
|
+
container,
|
|
342
|
+
shouldReuseMarkup
|
|
343
|
+
) {
|
|
344
|
+
// Various parts of our code (such as ReactCompositeComponent's
|
|
345
|
+
// _renderValidatedComponent) assume that calls to render aren't nested;
|
|
346
|
+
// verify that that's the case.
|
|
347
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
348
|
+
ReactCurrentOwner.current == null,
|
|
349
|
+
'_renderNewRootComponent(): Render methods should be a pure function ' +
|
|
350
|
+
'of props and state; triggering nested component updates from ' +
|
|
351
|
+
'render is not allowed. If necessary, trigger nested updates in ' +
|
|
352
|
+
'componentDidUpdate.'
|
|
353
|
+
) : null);
|
|
323
354
|
|
|
324
|
-
|
|
355
|
+
var componentInstance = instantiateReactComponent(nextComponent, null);
|
|
356
|
+
var reactRootID = ReactMount._registerComponent(
|
|
357
|
+
componentInstance,
|
|
358
|
+
container
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
|
|
362
|
+
transaction.perform(
|
|
363
|
+
mountComponentIntoNode,
|
|
364
|
+
componentInstance,
|
|
365
|
+
reactRootID,
|
|
366
|
+
container,
|
|
367
|
+
transaction,
|
|
368
|
+
shouldReuseMarkup
|
|
369
|
+
);
|
|
370
|
+
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
|
371
|
+
|
|
372
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
373
|
+
// Record the root element in case it later gets transplanted.
|
|
374
|
+
rootElementsByReactRootID[reactRootID] =
|
|
375
|
+
getReactRootElementInContainer(container);
|
|
325
376
|
}
|
|
326
|
-
|
|
377
|
+
|
|
378
|
+
return componentInstance;
|
|
379
|
+
},
|
|
327
380
|
|
|
328
381
|
/**
|
|
329
382
|
* Renders a React component into the DOM in the supplied `container`.
|
|
@@ -340,16 +393,16 @@ var ReactMount = {
|
|
|
340
393
|
render: function(nextElement, container, callback) {
|
|
341
394
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
342
395
|
ReactElement.isValidElement(nextElement),
|
|
343
|
-
'
|
|
396
|
+
'React.render(): Invalid component element.%s',
|
|
344
397
|
(
|
|
345
398
|
typeof nextElement === 'string' ?
|
|
346
399
|
' Instead of passing an element string, make sure to instantiate ' +
|
|
347
400
|
'it by passing it to React.createElement.' :
|
|
348
|
-
|
|
401
|
+
typeof nextElement === 'function' ?
|
|
349
402
|
' Instead of passing a component class, make sure to instantiate ' +
|
|
350
403
|
'it by passing it to React.createElement.' :
|
|
351
|
-
// Check if it quacks like
|
|
352
|
-
|
|
404
|
+
// Check if it quacks like an element
|
|
405
|
+
nextElement != null && nextElement.props !== undefined ?
|
|
353
406
|
' This may be caused by unintentionally loading two independent ' +
|
|
354
407
|
'copies of React.' :
|
|
355
408
|
''
|
|
@@ -366,7 +419,7 @@ var ReactMount = {
|
|
|
366
419
|
nextElement,
|
|
367
420
|
container,
|
|
368
421
|
callback
|
|
369
|
-
);
|
|
422
|
+
).getPublicInstance();
|
|
370
423
|
} else {
|
|
371
424
|
ReactMount.unmountComponentAtNode(container);
|
|
372
425
|
}
|
|
@@ -382,7 +435,7 @@ var ReactMount = {
|
|
|
382
435
|
nextElement,
|
|
383
436
|
container,
|
|
384
437
|
shouldReuseMarkup
|
|
385
|
-
);
|
|
438
|
+
).getPublicInstance();
|
|
386
439
|
callback && callback.call(component);
|
|
387
440
|
return component;
|
|
388
441
|
},
|
|
@@ -397,7 +450,7 @@ var ReactMount = {
|
|
|
397
450
|
* @return {ReactComponent} Component instance rendered in `container`.
|
|
398
451
|
*/
|
|
399
452
|
constructAndRenderComponent: function(constructor, props, container) {
|
|
400
|
-
var element = createElement(constructor, props);
|
|
453
|
+
var element = ReactElement.createElement(constructor, props);
|
|
401
454
|
return ReactMount.render(element, container);
|
|
402
455
|
},
|
|
403
456
|
|
|
@@ -462,6 +515,15 @@ var ReactMount = {
|
|
|
462
515
|
'componentDidUpdate.'
|
|
463
516
|
) : null);
|
|
464
517
|
|
|
518
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
519
|
+
container && (
|
|
520
|
+
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
521
|
+
),
|
|
522
|
+
'unmountComponentAtNode(...): Target container is not a DOM element.'
|
|
523
|
+
) : invariant(container && (
|
|
524
|
+
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
525
|
+
)));
|
|
526
|
+
|
|
465
527
|
var reactRootID = getReactRootID(container);
|
|
466
528
|
var component = instancesByReactRootID[reactRootID];
|
|
467
529
|
if (!component) {
|
|
@@ -666,6 +728,75 @@ var ReactMount = {
|
|
|
666
728
|
) : invariant(false));
|
|
667
729
|
},
|
|
668
730
|
|
|
731
|
+
_mountImageIntoNode: function(markup, container, shouldReuseMarkup) {
|
|
732
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
733
|
+
container && (
|
|
734
|
+
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
735
|
+
),
|
|
736
|
+
'mountComponentIntoNode(...): Target container is not valid.'
|
|
737
|
+
) : invariant(container && (
|
|
738
|
+
(container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE)
|
|
739
|
+
)));
|
|
740
|
+
|
|
741
|
+
if (shouldReuseMarkup) {
|
|
742
|
+
var rootElement = getReactRootElementInContainer(container);
|
|
743
|
+
if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) {
|
|
744
|
+
return;
|
|
745
|
+
} else {
|
|
746
|
+
var checksum = rootElement.getAttribute(
|
|
747
|
+
ReactMarkupChecksum.CHECKSUM_ATTR_NAME
|
|
748
|
+
);
|
|
749
|
+
rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME);
|
|
750
|
+
|
|
751
|
+
var rootMarkup = rootElement.outerHTML;
|
|
752
|
+
rootElement.setAttribute(
|
|
753
|
+
ReactMarkupChecksum.CHECKSUM_ATTR_NAME,
|
|
754
|
+
checksum
|
|
755
|
+
);
|
|
756
|
+
|
|
757
|
+
var diffIndex = firstDifferenceIndex(markup, rootMarkup);
|
|
758
|
+
var difference = ' (client) ' +
|
|
759
|
+
markup.substring(diffIndex - 20, diffIndex + 20) +
|
|
760
|
+
'\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20);
|
|
761
|
+
|
|
762
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
763
|
+
container.nodeType !== DOC_NODE_TYPE,
|
|
764
|
+
'You\'re trying to render a component to the document using ' +
|
|
765
|
+
'server rendering but the checksum was invalid. This usually ' +
|
|
766
|
+
'means you rendered a different component type or props on ' +
|
|
767
|
+
'the client from the one on the server, or your render() ' +
|
|
768
|
+
'methods are impure. React cannot handle this case due to ' +
|
|
769
|
+
'cross-browser quirks by rendering at the document root. You ' +
|
|
770
|
+
'should look for environment dependent code in your components ' +
|
|
771
|
+
'and ensure the props are the same client and server side:\n%s',
|
|
772
|
+
difference
|
|
773
|
+
) : invariant(container.nodeType !== DOC_NODE_TYPE));
|
|
774
|
+
|
|
775
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
776
|
+
console.warn(
|
|
777
|
+
'React attempted to use reuse markup in a container but the ' +
|
|
778
|
+
'checksum was invalid. This generally means that you are ' +
|
|
779
|
+
'using server rendering and the markup generated on the ' +
|
|
780
|
+
'server was not what the client was expecting. React injected ' +
|
|
781
|
+
'new markup to compensate which works but you have lost many ' +
|
|
782
|
+
'of the benefits of server rendering. Instead, figure out ' +
|
|
783
|
+
'why the markup being generated is different on the client ' +
|
|
784
|
+
'or server:\n' + difference
|
|
785
|
+
);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
791
|
+
container.nodeType !== DOC_NODE_TYPE,
|
|
792
|
+
'You\'re trying to render a component to the document but ' +
|
|
793
|
+
'you didn\'t use server rendering. We can\'t do this ' +
|
|
794
|
+
'without using server rendering due to cross-browser quirks. ' +
|
|
795
|
+
'See React.renderToString() for server rendering.'
|
|
796
|
+
) : invariant(container.nodeType !== DOC_NODE_TYPE));
|
|
797
|
+
|
|
798
|
+
setInnerHTML(container, markup);
|
|
799
|
+
},
|
|
669
800
|
|
|
670
801
|
/**
|
|
671
802
|
* React ID utilities.
|
|
@@ -679,16 +810,14 @@ var ReactMount = {
|
|
|
679
810
|
|
|
680
811
|
getNode: getNode,
|
|
681
812
|
|
|
813
|
+
getNodeFromInstance: getNodeFromInstance,
|
|
814
|
+
|
|
682
815
|
purgeID: purgeID
|
|
683
816
|
};
|
|
684
817
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
'
|
|
688
|
-
|
|
689
|
-
'render',
|
|
690
|
-
this,
|
|
691
|
-
ReactMount.render
|
|
692
|
-
);
|
|
818
|
+
ReactPerf.measureMethods(ReactMount, 'ReactMount', {
|
|
819
|
+
_renderNewRootComponent: '_renderNewRootComponent',
|
|
820
|
+
_mountImageIntoNode: '_mountImageIntoNode'
|
|
821
|
+
});
|
|
693
822
|
|
|
694
823
|
module.exports = ReactMount;
|
package/lib/ReactMultiChild.js
CHANGED
|
@@ -12,12 +12,10 @@
|
|
|
12
12
|
|
|
13
13
|
"use strict";
|
|
14
14
|
|
|
15
|
-
var
|
|
15
|
+
var ReactComponentEnvironment = require("./ReactComponentEnvironment");
|
|
16
16
|
var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
|
|
17
17
|
|
|
18
|
-
var
|
|
19
|
-
var instantiateReactComponent = require("./instantiateReactComponent");
|
|
20
|
-
var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
|
|
18
|
+
var ReactChildReconciler = require("./ReactChildReconciler");
|
|
21
19
|
|
|
22
20
|
/**
|
|
23
21
|
* Updating children of a component may trigger recursive updates. The depth is
|
|
@@ -135,7 +133,7 @@ function enqueueTextContent(parentID, textContent) {
|
|
|
135
133
|
*/
|
|
136
134
|
function processQueue() {
|
|
137
135
|
if (updateQueue.length) {
|
|
138
|
-
|
|
136
|
+
ReactComponentEnvironment.processChildrenUpdates(
|
|
139
137
|
updateQueue,
|
|
140
138
|
markupQueue
|
|
141
139
|
);
|
|
@@ -178,26 +176,24 @@ var ReactMultiChild = {
|
|
|
178
176
|
* @return {array} An array of mounted representations.
|
|
179
177
|
* @internal
|
|
180
178
|
*/
|
|
181
|
-
mountChildren: function(nestedChildren, transaction) {
|
|
182
|
-
var children =
|
|
179
|
+
mountChildren: function(nestedChildren, transaction, context) {
|
|
180
|
+
var children = ReactChildReconciler.instantiateChildren(
|
|
181
|
+
nestedChildren, transaction, context
|
|
182
|
+
);
|
|
183
|
+
this._renderedChildren = children;
|
|
183
184
|
var mountImages = [];
|
|
184
185
|
var index = 0;
|
|
185
|
-
this._renderedChildren = children;
|
|
186
186
|
for (var name in children) {
|
|
187
187
|
var child = children[name];
|
|
188
188
|
if (children.hasOwnProperty(name)) {
|
|
189
|
-
// The rendered children must be turned into instances as they're
|
|
190
|
-
// mounted.
|
|
191
|
-
var childInstance = instantiateReactComponent(child, null);
|
|
192
|
-
children[name] = childInstance;
|
|
193
189
|
// Inlined for performance, see `ReactInstanceHandles.createReactID`.
|
|
194
190
|
var rootID = this._rootNodeID + name;
|
|
195
|
-
var mountImage =
|
|
191
|
+
var mountImage = child.mountComponent(
|
|
196
192
|
rootID,
|
|
197
193
|
transaction,
|
|
198
|
-
|
|
194
|
+
context
|
|
199
195
|
);
|
|
200
|
-
|
|
196
|
+
child._mountIndex = index;
|
|
201
197
|
mountImages.push(mountImage);
|
|
202
198
|
index++;
|
|
203
199
|
}
|
|
@@ -217,6 +213,8 @@ var ReactMultiChild = {
|
|
|
217
213
|
try {
|
|
218
214
|
var prevChildren = this._renderedChildren;
|
|
219
215
|
// Remove any rendered children.
|
|
216
|
+
ReactChildReconciler.unmountChildren(prevChildren);
|
|
217
|
+
// TODO: The setTextContent operation should be enough
|
|
220
218
|
for (var name in prevChildren) {
|
|
221
219
|
if (prevChildren.hasOwnProperty(name)) {
|
|
222
220
|
this._unmountChildByName(prevChildren[name], name);
|
|
@@ -240,11 +238,11 @@ var ReactMultiChild = {
|
|
|
240
238
|
* @param {ReactReconcileTransaction} transaction
|
|
241
239
|
* @internal
|
|
242
240
|
*/
|
|
243
|
-
updateChildren: function(nextNestedChildren, transaction) {
|
|
241
|
+
updateChildren: function(nextNestedChildren, transaction, context) {
|
|
244
242
|
updateDepth++;
|
|
245
243
|
var errorThrown = true;
|
|
246
244
|
try {
|
|
247
|
-
this._updateChildren(nextNestedChildren, transaction);
|
|
245
|
+
this._updateChildren(nextNestedChildren, transaction, context);
|
|
248
246
|
errorThrown = false;
|
|
249
247
|
} finally {
|
|
250
248
|
updateDepth--;
|
|
@@ -263,9 +261,12 @@ var ReactMultiChild = {
|
|
|
263
261
|
* @final
|
|
264
262
|
* @protected
|
|
265
263
|
*/
|
|
266
|
-
_updateChildren: function(nextNestedChildren, transaction) {
|
|
267
|
-
var nextChildren = flattenChildren(nextNestedChildren);
|
|
264
|
+
_updateChildren: function(nextNestedChildren, transaction, context) {
|
|
268
265
|
var prevChildren = this._renderedChildren;
|
|
266
|
+
var nextChildren = ReactChildReconciler.updateChildren(
|
|
267
|
+
prevChildren, nextNestedChildren, transaction, context
|
|
268
|
+
);
|
|
269
|
+
this._renderedChildren = nextChildren;
|
|
269
270
|
if (!nextChildren && !prevChildren) {
|
|
270
271
|
return;
|
|
271
272
|
}
|
|
@@ -279,12 +280,10 @@ var ReactMultiChild = {
|
|
|
279
280
|
continue;
|
|
280
281
|
}
|
|
281
282
|
var prevChild = prevChildren && prevChildren[name];
|
|
282
|
-
var
|
|
283
|
-
|
|
284
|
-
if (shouldUpdateReactComponent(prevElement, nextElement)) {
|
|
283
|
+
var nextChild = nextChildren[name];
|
|
284
|
+
if (prevChild === nextChild) {
|
|
285
285
|
this.moveChild(prevChild, nextIndex, lastIndex);
|
|
286
286
|
lastIndex = Math.max(prevChild._mountIndex, lastIndex);
|
|
287
|
-
prevChild.receiveComponent(nextElement, transaction);
|
|
288
287
|
prevChild._mountIndex = nextIndex;
|
|
289
288
|
} else {
|
|
290
289
|
if (prevChild) {
|
|
@@ -293,12 +292,8 @@ var ReactMultiChild = {
|
|
|
293
292
|
this._unmountChildByName(prevChild, name);
|
|
294
293
|
}
|
|
295
294
|
// The child must be instantiated before it's mounted.
|
|
296
|
-
var nextChildInstance = instantiateReactComponent(
|
|
297
|
-
nextElement,
|
|
298
|
-
null
|
|
299
|
-
);
|
|
300
295
|
this._mountChildByNameAtIndex(
|
|
301
|
-
|
|
296
|
+
nextChild, name, nextIndex, transaction, context
|
|
302
297
|
);
|
|
303
298
|
}
|
|
304
299
|
nextIndex++;
|
|
@@ -306,7 +301,7 @@ var ReactMultiChild = {
|
|
|
306
301
|
// Remove children that are no longer present.
|
|
307
302
|
for (name in prevChildren) {
|
|
308
303
|
if (prevChildren.hasOwnProperty(name) &&
|
|
309
|
-
!(nextChildren && nextChildren
|
|
304
|
+
!(nextChildren && nextChildren.hasOwnProperty(name))) {
|
|
310
305
|
this._unmountChildByName(prevChildren[name], name);
|
|
311
306
|
}
|
|
312
307
|
}
|
|
@@ -320,13 +315,7 @@ var ReactMultiChild = {
|
|
|
320
315
|
*/
|
|
321
316
|
unmountChildren: function() {
|
|
322
317
|
var renderedChildren = this._renderedChildren;
|
|
323
|
-
|
|
324
|
-
var renderedChild = renderedChildren[name];
|
|
325
|
-
// TODO: When is this not true?
|
|
326
|
-
if (renderedChild.unmountComponent) {
|
|
327
|
-
renderedChild.unmountComponent();
|
|
328
|
-
}
|
|
329
|
-
}
|
|
318
|
+
ReactChildReconciler.unmountChildren(renderedChildren);
|
|
330
319
|
this._renderedChildren = null;
|
|
331
320
|
},
|
|
332
321
|
|
|
@@ -389,18 +378,21 @@ var ReactMultiChild = {
|
|
|
389
378
|
* @param {ReactReconcileTransaction} transaction
|
|
390
379
|
* @private
|
|
391
380
|
*/
|
|
392
|
-
_mountChildByNameAtIndex: function(
|
|
381
|
+
_mountChildByNameAtIndex: function(
|
|
382
|
+
child,
|
|
383
|
+
name,
|
|
384
|
+
index,
|
|
385
|
+
transaction,
|
|
386
|
+
context) {
|
|
393
387
|
// Inlined for performance, see `ReactInstanceHandles.createReactID`.
|
|
394
388
|
var rootID = this._rootNodeID + name;
|
|
395
389
|
var mountImage = child.mountComponent(
|
|
396
390
|
rootID,
|
|
397
391
|
transaction,
|
|
398
|
-
|
|
392
|
+
context
|
|
399
393
|
);
|
|
400
394
|
child._mountIndex = index;
|
|
401
395
|
this.createChild(child, mountImage);
|
|
402
|
-
this._renderedChildren = this._renderedChildren || {};
|
|
403
|
-
this._renderedChildren[name] = child;
|
|
404
396
|
},
|
|
405
397
|
|
|
406
398
|
/**
|
|
@@ -415,8 +407,6 @@ var ReactMultiChild = {
|
|
|
415
407
|
_unmountChildByName: function(child, name) {
|
|
416
408
|
this.removeChild(child);
|
|
417
409
|
child._mountIndex = null;
|
|
418
|
-
child.unmountComponent();
|
|
419
|
-
delete this._renderedChildren[name];
|
|
420
410
|
}
|
|
421
411
|
|
|
422
412
|
}
|