react 0.14.0-beta3 → 0.14.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 +4 -4
- package/addons.js +2 -0
- package/dist/react-with-addons.js +1941 -1364
- package/dist/react-with-addons.min.js +6 -6
- package/dist/react.js +1704 -1242
- package/dist/react.min.js +6 -6
- package/lib/CSSProperty.js +15 -3
- package/lib/CSSPropertyOperations.js +15 -2
- package/lib/ChangeEventPlugin.js +5 -2
- package/lib/DOMChildrenOperations.js +12 -1
- package/lib/DOMPropertyOperations.js +14 -1
- package/lib/Danger.js +9 -4
- package/lib/EnterLeaveEventPlugin.js +13 -5
- package/lib/EventConstants.js +1 -1
- package/lib/EventPluginHub.js +18 -10
- package/lib/EventPluginUtils.js +23 -27
- package/lib/EventPropagators.js +1 -1
- package/lib/FallbackCompositionState.js +6 -0
- package/lib/HTMLDOMPropertyConfig.js +26 -2
- package/lib/PooledClass.js +1 -3
- package/lib/React.js +14 -3
- package/lib/ReactBrowserComponentMixin.js +1 -1
- package/lib/ReactBrowserEventEmitter.js +9 -3
- package/lib/ReactCSSTransitionGroup.js +33 -18
- package/lib/ReactCSSTransitionGroupChild.js +42 -25
- package/lib/ReactChildReconciler.js +3 -5
- package/lib/ReactChildren.js +70 -30
- package/lib/ReactClass.js +6 -6
- package/lib/ReactComponent.js +7 -6
- package/lib/ReactCompositeComponent.js +58 -7
- package/lib/ReactDOM.js +7 -5
- package/lib/ReactDOMComponent.js +146 -46
- package/lib/ReactDOMFeatureFlags.js +18 -0
- package/lib/ReactDOMIDOperations.js +1 -60
- package/lib/ReactDOMInput.js +10 -1
- package/lib/ReactDOMSelect.js +1 -1
- package/lib/ReactDOMSelection.js +16 -0
- package/lib/ReactDOMServer.js +3 -1
- package/lib/ReactDOMTextComponent.js +23 -10
- package/lib/ReactDOMTextarea.js +3 -1
- package/lib/ReactDefaultInjection.js +0 -2
- package/lib/ReactDefaultPerf.js +10 -4
- package/lib/ReactDefaultPerfAnalysis.js +7 -3
- package/lib/ReactElement.js +72 -35
- package/lib/ReactElementValidator.js +31 -75
- package/lib/ReactEmptyComponent.js +25 -61
- package/lib/ReactEmptyComponentRegistry.js +48 -0
- package/lib/ReactErrorUtils.js +56 -9
- package/lib/ReactEventEmitterMixin.js +1 -1
- package/lib/ReactEventListener.js +16 -9
- package/lib/ReactFragment.js +25 -116
- package/lib/ReactInjection.js +0 -2
- package/lib/ReactIsomorphic.js +4 -0
- package/lib/ReactLink.js +1 -1
- package/lib/ReactMount.js +127 -41
- package/lib/ReactMultiChild.js +37 -4
- package/lib/ReactOwner.js +2 -2
- package/lib/ReactPropTransferer.js +1 -1
- package/lib/ReactPropTypes.js +11 -8
- package/lib/ReactReconcileTransaction.js +4 -2
- package/lib/ReactReconciler.js +16 -17
- package/lib/ReactRef.js +13 -1
- package/lib/ReactServerRenderingTransaction.js +1 -0
- package/lib/ReactTestUtils.js +27 -15
- package/lib/ReactTransitionChildMapping.js +3 -6
- package/lib/ReactUpdateQueue.js +4 -4
- package/lib/ReactUpdates.js +1 -1
- package/lib/ReactVersion.js +14 -0
- package/lib/ReactWithAddons.js +10 -1
- package/lib/ResponderEventPlugin.js +1 -1
- package/lib/SelectEventPlugin.js +11 -1
- package/lib/SimpleEventPlugin.js +2 -23
- package/lib/SyntheticEvent.js +15 -1
- package/lib/Transaction.js +1 -1
- package/lib/canDefineProperty.js +24 -0
- package/lib/createHierarchyRenderer.js +1 -1
- package/lib/deprecated.js +3 -2
- package/lib/findDOMNode.js +1 -1
- package/lib/getTestDocument.js +4 -11
- package/lib/instantiateReactComponent.js +3 -5
- package/lib/reactComponentExpect.js +6 -0
- package/lib/shouldUpdateReactComponent.js +12 -8
- package/lib/sliceChildren.js +3 -20
- package/lib/traverseAllChildren.js +15 -9
- package/package.json +2 -2
- package/react.js +1 -51
- package/dist/JSXTransformer.js +0 -17949
- package/lib/joinClasses.js +0 -39
- package/lib/memoizeStringOnly.js +0 -31
package/lib/ReactFragment.js
CHANGED
|
@@ -11,8 +11,11 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
+
var ReactChildren = require('./ReactChildren');
|
|
14
15
|
var ReactElement = require('./ReactElement');
|
|
15
16
|
|
|
17
|
+
var emptyFunction = require('fbjs/lib/emptyFunction');
|
|
18
|
+
var invariant = require('fbjs/lib/invariant');
|
|
16
19
|
var warning = require('fbjs/lib/warning');
|
|
17
20
|
|
|
18
21
|
/**
|
|
@@ -20,135 +23,41 @@ var warning = require('fbjs/lib/warning');
|
|
|
20
23
|
* or nested sets. This allowed us a way to explicitly key a set a fragment of
|
|
21
24
|
* components. This is now being replaced with an opaque data structure.
|
|
22
25
|
* The upgrade path is to call React.addons.createFragment({ key: value }) to
|
|
23
|
-
* create a keyed fragment. The resulting data structure is
|
|
26
|
+
* create a keyed fragment. The resulting data structure is an array.
|
|
24
27
|
*/
|
|
25
28
|
|
|
26
|
-
var
|
|
27
|
-
var didWarnKey;
|
|
28
|
-
var canWarnForReactFragment;
|
|
29
|
+
var numericPropertyRegex = /^\d+$/;
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
fragmentKey = '_reactFragment';
|
|
32
|
-
didWarnKey = '_reactDidWarn';
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
// Feature test. Don't even try to issue this warning if we can't use
|
|
36
|
-
// enumerable: false.
|
|
37
|
-
|
|
38
|
-
var dummy = function () {
|
|
39
|
-
return 1;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
Object.defineProperty({}, fragmentKey, { enumerable: false, value: true });
|
|
43
|
-
|
|
44
|
-
Object.defineProperty({}, 'key', { enumerable: true, get: dummy });
|
|
45
|
-
|
|
46
|
-
canWarnForReactFragment = true;
|
|
47
|
-
} catch (x) {
|
|
48
|
-
canWarnForReactFragment = false;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
var proxyPropertyAccessWithWarning = function (obj, key) {
|
|
52
|
-
Object.defineProperty(obj, key, {
|
|
53
|
-
enumerable: true,
|
|
54
|
-
get: function () {
|
|
55
|
-
process.env.NODE_ENV !== 'production' ? warning(this[didWarnKey], 'A ReactFragment is an opaque type. Accessing any of its ' + 'properties is deprecated. Pass it to one of the React.Children ' + 'helpers.') : undefined;
|
|
56
|
-
this[didWarnKey] = true;
|
|
57
|
-
return this[fragmentKey][key];
|
|
58
|
-
},
|
|
59
|
-
set: function (value) {
|
|
60
|
-
process.env.NODE_ENV !== 'production' ? warning(this[didWarnKey], 'A ReactFragment is an immutable opaque type. Mutating its ' + 'properties is deprecated.') : undefined;
|
|
61
|
-
this[didWarnKey] = true;
|
|
62
|
-
this[fragmentKey][key] = value;
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
var issuedWarnings = {};
|
|
68
|
-
|
|
69
|
-
var didWarnForFragment = function (fragment) {
|
|
70
|
-
// We use the keys and the type of the value as a heuristic to dedupe the
|
|
71
|
-
// warning to avoid spamming too much.
|
|
72
|
-
var fragmentCacheKey = '';
|
|
73
|
-
for (var key in fragment) {
|
|
74
|
-
fragmentCacheKey += key + ':' + typeof fragment[key] + ',';
|
|
75
|
-
}
|
|
76
|
-
var alreadyWarnedOnce = !!issuedWarnings[fragmentCacheKey];
|
|
77
|
-
issuedWarnings[fragmentCacheKey] = true;
|
|
78
|
-
return alreadyWarnedOnce;
|
|
79
|
-
};
|
|
80
|
-
}
|
|
31
|
+
var warnedAboutNumeric = false;
|
|
81
32
|
|
|
82
33
|
var ReactFragment = {
|
|
83
34
|
// Wrap a keyed object in an opaque proxy that warns you if you access any
|
|
84
35
|
// of its properties.
|
|
85
36
|
create: function (object) {
|
|
86
|
-
if (
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return object;
|
|
90
|
-
}
|
|
91
|
-
if (ReactElement.isValidElement(object)) {
|
|
92
|
-
process.env.NODE_ENV !== 'production' ? warning(false, 'React.addons.createFragment does not accept a ReactElement ' + 'without a wrapper object.') : undefined;
|
|
93
|
-
return object;
|
|
94
|
-
}
|
|
95
|
-
if (canWarnForReactFragment) {
|
|
96
|
-
var proxy = {};
|
|
97
|
-
Object.defineProperty(proxy, fragmentKey, {
|
|
98
|
-
enumerable: false,
|
|
99
|
-
value: object
|
|
100
|
-
});
|
|
101
|
-
Object.defineProperty(proxy, didWarnKey, {
|
|
102
|
-
writable: true,
|
|
103
|
-
enumerable: false,
|
|
104
|
-
value: false
|
|
105
|
-
});
|
|
106
|
-
for (var key in object) {
|
|
107
|
-
proxyPropertyAccessWithWarning(proxy, key);
|
|
108
|
-
}
|
|
109
|
-
Object.preventExtensions(proxy);
|
|
110
|
-
return proxy;
|
|
111
|
-
}
|
|
37
|
+
if (typeof object !== 'object' || !object || Array.isArray(object)) {
|
|
38
|
+
process.env.NODE_ENV !== 'production' ? warning(false, 'React.addons.createFragment only accepts a single object. Got: %s', object) : undefined;
|
|
39
|
+
return object;
|
|
112
40
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// a plain object is passed here.
|
|
117
|
-
extract: function (fragment) {
|
|
118
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
119
|
-
if (canWarnForReactFragment) {
|
|
120
|
-
if (!fragment[fragmentKey]) {
|
|
121
|
-
process.env.NODE_ENV !== 'production' ? warning(didWarnForFragment(fragment), 'Any use of a keyed object should be wrapped in ' + 'React.addons.createFragment(object) before being passed as a ' + 'child.') : undefined;
|
|
122
|
-
return fragment;
|
|
123
|
-
}
|
|
124
|
-
return fragment[fragmentKey];
|
|
125
|
-
}
|
|
41
|
+
if (ReactElement.isValidElement(object)) {
|
|
42
|
+
process.env.NODE_ENV !== 'production' ? warning(false, 'React.addons.createFragment does not accept a ReactElement ' + 'without a wrapper object.') : undefined;
|
|
43
|
+
return object;
|
|
126
44
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return fragment[fragmentKey];
|
|
138
|
-
}
|
|
139
|
-
// Otherwise, check each property if it has an element, if it does
|
|
140
|
-
// it is probably meant as a fragment, so we can warn early. Defer,
|
|
141
|
-
// the warning to extract.
|
|
142
|
-
for (var key in fragment) {
|
|
143
|
-
if (fragment.hasOwnProperty(key) && ReactElement.isValidElement(fragment[key])) {
|
|
144
|
-
// This looks like a fragment object, we should provide an
|
|
145
|
-
// early warning.
|
|
146
|
-
return ReactFragment.extract(fragment);
|
|
147
|
-
}
|
|
45
|
+
|
|
46
|
+
!(object.nodeType !== 1) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'React.addons.createFragment(...): Encountered an invalid child; DOM ' + 'elements are not valid children of React components.') : invariant(false) : undefined;
|
|
47
|
+
|
|
48
|
+
var result = [];
|
|
49
|
+
|
|
50
|
+
for (var key in object) {
|
|
51
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
52
|
+
if (!warnedAboutNumeric && numericPropertyRegex.test(key)) {
|
|
53
|
+
process.env.NODE_ENV !== 'production' ? warning(false, 'React.addons.createFragment(...): Child objects should have ' + 'non-numeric keys so ordering is preserved.') : undefined;
|
|
54
|
+
warnedAboutNumeric = true;
|
|
148
55
|
}
|
|
149
56
|
}
|
|
57
|
+
ReactChildren.mapIntoWithKeyPrefixInternal(object[key], result, key, emptyFunction.thatReturnsArgument);
|
|
150
58
|
}
|
|
151
|
-
|
|
59
|
+
|
|
60
|
+
return result;
|
|
152
61
|
}
|
|
153
62
|
};
|
|
154
63
|
|
package/lib/ReactInjection.js
CHANGED
|
@@ -18,7 +18,6 @@ var ReactClass = require('./ReactClass');
|
|
|
18
18
|
var ReactEmptyComponent = require('./ReactEmptyComponent');
|
|
19
19
|
var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');
|
|
20
20
|
var ReactNativeComponent = require('./ReactNativeComponent');
|
|
21
|
-
var ReactDOMComponent = require('./ReactDOMComponent');
|
|
22
21
|
var ReactPerf = require('./ReactPerf');
|
|
23
22
|
var ReactRootIndex = require('./ReactRootIndex');
|
|
24
23
|
var ReactUpdates = require('./ReactUpdates');
|
|
@@ -26,7 +25,6 @@ var ReactUpdates = require('./ReactUpdates');
|
|
|
26
25
|
var ReactInjection = {
|
|
27
26
|
Component: ReactComponentEnvironment.injection,
|
|
28
27
|
Class: ReactClass.injection,
|
|
29
|
-
DOMComponent: ReactDOMComponent.injection,
|
|
30
28
|
DOMProperty: DOMProperty.injection,
|
|
31
29
|
EmptyComponent: ReactEmptyComponent.injection,
|
|
32
30
|
EventPluginHub: EventPluginHub.injection,
|
package/lib/ReactIsomorphic.js
CHANGED
|
@@ -18,6 +18,7 @@ var ReactDOMFactories = require('./ReactDOMFactories');
|
|
|
18
18
|
var ReactElement = require('./ReactElement');
|
|
19
19
|
var ReactElementValidator = require('./ReactElementValidator');
|
|
20
20
|
var ReactPropTypes = require('./ReactPropTypes');
|
|
21
|
+
var ReactVersion = require('./ReactVersion');
|
|
21
22
|
|
|
22
23
|
var assign = require('./Object.assign');
|
|
23
24
|
var onlyChild = require('./onlyChild');
|
|
@@ -40,6 +41,7 @@ var React = {
|
|
|
40
41
|
map: ReactChildren.map,
|
|
41
42
|
forEach: ReactChildren.forEach,
|
|
42
43
|
count: ReactChildren.count,
|
|
44
|
+
toArray: ReactChildren.toArray,
|
|
43
45
|
only: onlyChild
|
|
44
46
|
},
|
|
45
47
|
|
|
@@ -63,6 +65,8 @@ var React = {
|
|
|
63
65
|
// since they are just generating DOM strings.
|
|
64
66
|
DOM: ReactDOMFactories,
|
|
65
67
|
|
|
68
|
+
version: ReactVersion,
|
|
69
|
+
|
|
66
70
|
// Hook for JSX spread, don't use this for anything else.
|
|
67
71
|
__spread: assign
|
|
68
72
|
};
|
package/lib/ReactLink.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* var valueLink = new ReactLink(this.state.value, this._handleValueChange);
|
|
27
27
|
* return <input valueLink={valueLink} />;
|
|
28
28
|
* },
|
|
29
|
-
*
|
|
29
|
+
* _handleValueChange: function(newValue) {
|
|
30
30
|
* this.setState({value: newValue});
|
|
31
31
|
* }
|
|
32
32
|
* });
|
package/lib/ReactMount.js
CHANGED
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
var DOMProperty = require('./DOMProperty');
|
|
15
15
|
var ReactBrowserEventEmitter = require('./ReactBrowserEventEmitter');
|
|
16
16
|
var ReactCurrentOwner = require('./ReactCurrentOwner');
|
|
17
|
+
var ReactDOMFeatureFlags = require('./ReactDOMFeatureFlags');
|
|
17
18
|
var ReactElement = require('./ReactElement');
|
|
18
|
-
var
|
|
19
|
+
var ReactEmptyComponentRegistry = require('./ReactEmptyComponentRegistry');
|
|
19
20
|
var ReactInstanceHandles = require('./ReactInstanceHandles');
|
|
20
21
|
var ReactInstanceMap = require('./ReactInstanceMap');
|
|
21
22
|
var ReactMarkupChecksum = require('./ReactMarkupChecksum');
|
|
@@ -24,6 +25,7 @@ var ReactReconciler = require('./ReactReconciler');
|
|
|
24
25
|
var ReactUpdateQueue = require('./ReactUpdateQueue');
|
|
25
26
|
var ReactUpdates = require('./ReactUpdates');
|
|
26
27
|
|
|
28
|
+
var assign = require('./Object.assign');
|
|
27
29
|
var emptyObject = require('fbjs/lib/emptyObject');
|
|
28
30
|
var containsNode = require('fbjs/lib/containsNode');
|
|
29
31
|
var instantiateReactComponent = require('./instantiateReactComponent');
|
|
@@ -33,8 +35,6 @@ var shouldUpdateReactComponent = require('./shouldUpdateReactComponent');
|
|
|
33
35
|
var validateDOMNesting = require('./validateDOMNesting');
|
|
34
36
|
var warning = require('fbjs/lib/warning');
|
|
35
37
|
|
|
36
|
-
var SEPARATOR = ReactInstanceHandles.SEPARATOR;
|
|
37
|
-
|
|
38
38
|
var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME;
|
|
39
39
|
var nodeCache = {};
|
|
40
40
|
|
|
@@ -42,6 +42,8 @@ var ELEMENT_NODE_TYPE = 1;
|
|
|
42
42
|
var DOC_NODE_TYPE = 9;
|
|
43
43
|
var DOCUMENT_FRAGMENT_NODE_TYPE = 11;
|
|
44
44
|
|
|
45
|
+
var ownerDocumentContextKey = '__ReactMount_ownerDocument$' + Math.random().toString(36).slice(2);
|
|
46
|
+
|
|
45
47
|
/** Mapping from reactRootID to React component instance. */
|
|
46
48
|
var instancesByReactRootID = {};
|
|
47
49
|
|
|
@@ -171,7 +173,7 @@ function getNode(id) {
|
|
|
171
173
|
*/
|
|
172
174
|
function getNodeFromInstance(instance) {
|
|
173
175
|
var id = ReactInstanceMap.get(instance)._rootNodeID;
|
|
174
|
-
if (
|
|
176
|
+
if (ReactEmptyComponentRegistry.isNullComponentID(id)) {
|
|
175
177
|
return null;
|
|
176
178
|
}
|
|
177
179
|
if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
|
|
@@ -246,6 +248,14 @@ function findDeepestCachedAncestor(targetID) {
|
|
|
246
248
|
* @param {boolean} shouldReuseMarkup If true, do not insert markup
|
|
247
249
|
*/
|
|
248
250
|
function mountComponentIntoNode(componentInstance, rootID, container, transaction, shouldReuseMarkup, context) {
|
|
251
|
+
if (ReactDOMFeatureFlags.useCreateElement) {
|
|
252
|
+
context = assign({}, context);
|
|
253
|
+
if (container.nodeType === DOC_NODE_TYPE) {
|
|
254
|
+
context[ownerDocumentContextKey] = container;
|
|
255
|
+
} else {
|
|
256
|
+
context[ownerDocumentContextKey] = container.ownerDocument;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
249
259
|
if (process.env.NODE_ENV !== 'production') {
|
|
250
260
|
if (context === emptyObject) {
|
|
251
261
|
context = {};
|
|
@@ -255,7 +265,7 @@ function mountComponentIntoNode(componentInstance, rootID, container, transactio
|
|
|
255
265
|
}
|
|
256
266
|
var markup = ReactReconciler.mountComponent(componentInstance, rootID, transaction, context);
|
|
257
267
|
componentInstance._renderedComponent._topLevelWrapper = componentInstance;
|
|
258
|
-
ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup);
|
|
268
|
+
ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup, transaction);
|
|
259
269
|
}
|
|
260
270
|
|
|
261
271
|
/**
|
|
@@ -267,7 +277,8 @@ function mountComponentIntoNode(componentInstance, rootID, container, transactio
|
|
|
267
277
|
* @param {boolean} shouldReuseMarkup If true, do not insert markup
|
|
268
278
|
*/
|
|
269
279
|
function batchedMountComponentIntoNode(componentInstance, rootID, container, shouldReuseMarkup, context) {
|
|
270
|
-
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(
|
|
280
|
+
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(
|
|
281
|
+
/* forceHTML */shouldReuseMarkup);
|
|
271
282
|
transaction.perform(mountComponentIntoNode, null, componentInstance, rootID, container, transaction, shouldReuseMarkup, context);
|
|
272
283
|
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
|
273
284
|
}
|
|
@@ -294,12 +305,72 @@ function unmountComponentFromNode(instance, container) {
|
|
|
294
305
|
}
|
|
295
306
|
}
|
|
296
307
|
|
|
308
|
+
/**
|
|
309
|
+
* True if the supplied DOM node has a direct React-rendered child that is
|
|
310
|
+
* not a React root element. Useful for warning in `render`,
|
|
311
|
+
* `unmountComponentAtNode`, etc.
|
|
312
|
+
*
|
|
313
|
+
* @param {?DOMElement} node The candidate DOM node.
|
|
314
|
+
* @return {boolean} True if the DOM element contains a direct child that was
|
|
315
|
+
* rendered by React but is not a root element.
|
|
316
|
+
* @internal
|
|
317
|
+
*/
|
|
318
|
+
function hasNonRootReactChild(node) {
|
|
319
|
+
var reactRootID = getReactRootID(node);
|
|
320
|
+
return reactRootID ? reactRootID !== ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID) : false;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Returns the first (deepest) ancestor of a node which is rendered by this copy
|
|
325
|
+
* of React.
|
|
326
|
+
*/
|
|
327
|
+
function findFirstReactDOMImpl(node) {
|
|
328
|
+
// This node might be from another React instance, so we make sure not to
|
|
329
|
+
// examine the node cache here
|
|
330
|
+
for (; node && node.parentNode !== node; node = node.parentNode) {
|
|
331
|
+
if (node.nodeType !== 1) {
|
|
332
|
+
// Not a DOMElement, therefore not a React component
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
var nodeID = internalGetID(node);
|
|
336
|
+
if (!nodeID) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);
|
|
340
|
+
|
|
341
|
+
// If containersByReactRootID contains the container we find by crawling up
|
|
342
|
+
// the tree, we know that this instance of React rendered the node.
|
|
343
|
+
// nb. isValid's strategy (with containsNode) does not work because render
|
|
344
|
+
// trees may be nested and we don't want a false positive in that case.
|
|
345
|
+
var current = node;
|
|
346
|
+
var lastID;
|
|
347
|
+
do {
|
|
348
|
+
lastID = internalGetID(current);
|
|
349
|
+
current = current.parentNode;
|
|
350
|
+
if (current == null) {
|
|
351
|
+
// The passed-in node has been detached from the container it was
|
|
352
|
+
// originally rendered into.
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
} while (lastID !== reactRootID);
|
|
356
|
+
|
|
357
|
+
if (current === containersByReactRootID[reactRootID]) {
|
|
358
|
+
return node;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
|
|
297
364
|
/**
|
|
298
365
|
* Temporary (?) hack so that we can store all top-level pending updates on
|
|
299
366
|
* composites instead of having to worry about different types of components
|
|
300
367
|
* here.
|
|
301
368
|
*/
|
|
302
369
|
var TopLevelWrapper = function () {};
|
|
370
|
+
TopLevelWrapper.prototype.isReactComponent = {};
|
|
371
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
372
|
+
TopLevelWrapper.displayName = 'TopLevelWrapper';
|
|
373
|
+
}
|
|
303
374
|
TopLevelWrapper.prototype.render = function () {
|
|
304
375
|
// this.props is actually a ReactElement
|
|
305
376
|
return this.props;
|
|
@@ -324,6 +395,9 @@ TopLevelWrapper.prototype.render = function () {
|
|
|
324
395
|
* Inside of `container`, the first element rendered is the "reactRoot".
|
|
325
396
|
*/
|
|
326
397
|
var ReactMount = {
|
|
398
|
+
|
|
399
|
+
TopLevelWrapper: TopLevelWrapper,
|
|
400
|
+
|
|
327
401
|
/** Exposed for debugging purposes **/
|
|
328
402
|
_instancesByReactRootID: instancesByReactRootID,
|
|
329
403
|
|
|
@@ -428,13 +502,13 @@ var ReactMount = {
|
|
|
428
502
|
},
|
|
429
503
|
|
|
430
504
|
_renderSubtreeIntoContainer: function (parentComponent, nextElement, container, callback) {
|
|
431
|
-
!ReactElement.isValidElement(nextElement) ? process.env.NODE_ENV !== 'production' ? invariant(false, '
|
|
505
|
+
!ReactElement.isValidElement(nextElement) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'ReactDOM.render(): Invalid component element.%s', typeof nextElement === 'string' ? ' Instead of passing an element string, make sure to instantiate ' + 'it by passing it to React.createElement.' : typeof nextElement === 'function' ? ' Instead of passing a component class, make sure to instantiate ' + 'it by passing it to React.createElement.' :
|
|
432
506
|
// Check if it quacks like an element
|
|
433
507
|
nextElement != null && nextElement.props !== undefined ? ' This may be caused by unintentionally loading two independent ' + 'copies of React.' : '') : invariant(false) : undefined;
|
|
434
508
|
|
|
435
509
|
process.env.NODE_ENV !== 'production' ? warning(!container || !container.tagName || container.tagName.toUpperCase() !== 'BODY', 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.') : undefined;
|
|
436
510
|
|
|
437
|
-
var nextWrappedElement = new ReactElement(TopLevelWrapper, null, null, null, nextElement);
|
|
511
|
+
var nextWrappedElement = new ReactElement(TopLevelWrapper, null, null, null, null, null, nextElement);
|
|
438
512
|
|
|
439
513
|
var prevComponent = instancesByReactRootID[getReactRootID(container)];
|
|
440
514
|
|
|
@@ -442,30 +516,37 @@ var ReactMount = {
|
|
|
442
516
|
var prevWrappedElement = prevComponent._currentElement;
|
|
443
517
|
var prevElement = prevWrappedElement.props;
|
|
444
518
|
if (shouldUpdateReactComponent(prevElement, nextElement)) {
|
|
445
|
-
|
|
519
|
+
var publicInst = prevComponent._renderedComponent.getPublicInstance();
|
|
520
|
+
var updatedCallback = callback && function () {
|
|
521
|
+
callback.call(publicInst);
|
|
522
|
+
};
|
|
523
|
+
ReactMount._updateRootComponent(prevComponent, nextWrappedElement, container, updatedCallback);
|
|
524
|
+
return publicInst;
|
|
446
525
|
} else {
|
|
447
526
|
ReactMount.unmountComponentAtNode(container);
|
|
448
527
|
}
|
|
449
528
|
}
|
|
450
529
|
|
|
451
530
|
var reactRootElement = getReactRootElementInContainer(container);
|
|
452
|
-
var containerHasReactMarkup = reactRootElement &&
|
|
531
|
+
var containerHasReactMarkup = reactRootElement && !!internalGetID(reactRootElement);
|
|
532
|
+
var containerHasNonRootReactChild = hasNonRootReactChild(container);
|
|
453
533
|
|
|
454
534
|
if (process.env.NODE_ENV !== 'production') {
|
|
535
|
+
process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.') : undefined;
|
|
536
|
+
|
|
455
537
|
if (!containerHasReactMarkup || reactRootElement.nextSibling) {
|
|
456
538
|
var rootElementSibling = reactRootElement;
|
|
457
539
|
while (rootElementSibling) {
|
|
458
|
-
if (
|
|
540
|
+
if (internalGetID(rootElementSibling)) {
|
|
459
541
|
process.env.NODE_ENV !== 'production' ? warning(false, 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.') : undefined;
|
|
460
542
|
break;
|
|
461
543
|
}
|
|
462
|
-
|
|
463
544
|
rootElementSibling = rootElementSibling.nextSibling;
|
|
464
545
|
}
|
|
465
546
|
}
|
|
466
547
|
}
|
|
467
548
|
|
|
468
|
-
var shouldReuseMarkup = containerHasReactMarkup && !prevComponent;
|
|
549
|
+
var shouldReuseMarkup = containerHasReactMarkup && !prevComponent && !containerHasNonRootReactChild;
|
|
469
550
|
var component = ReactMount._renderNewRootComponent(nextWrappedElement, container, shouldReuseMarkup, parentComponent != null ? parentComponent._reactInternalInstance._processChildContext(parentComponent._reactInternalInstance._context) : emptyObject)._renderedComponent.getPublicInstance();
|
|
470
551
|
if (callback) {
|
|
471
552
|
callback.call(component);
|
|
@@ -530,6 +611,18 @@ var ReactMount = {
|
|
|
530
611
|
var reactRootID = getReactRootID(container);
|
|
531
612
|
var component = instancesByReactRootID[reactRootID];
|
|
532
613
|
if (!component) {
|
|
614
|
+
// Check if the node being unmounted was rendered by React, but isn't a
|
|
615
|
+
// root node.
|
|
616
|
+
var containerHasNonRootReactChild = hasNonRootReactChild(container);
|
|
617
|
+
|
|
618
|
+
// Check if the container itself is a React root node.
|
|
619
|
+
var containerID = internalGetID(container);
|
|
620
|
+
var isContainerReactRoot = containerID && containerID === ReactInstanceHandles.getReactRootIDFromNodeID(containerID);
|
|
621
|
+
|
|
622
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
623
|
+
process.env.NODE_ENV !== 'production' ? warning(!containerHasNonRootReactChild, 'unmountComponentAtNode(): The node you\'re attempting to unmount ' + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.') : undefined;
|
|
624
|
+
}
|
|
625
|
+
|
|
533
626
|
return false;
|
|
534
627
|
}
|
|
535
628
|
ReactUpdates.batchedUpdates(unmountComponentFromNode, component, container);
|
|
@@ -586,39 +679,16 @@ var ReactMount = {
|
|
|
586
679
|
return ReactMount.findComponentRoot(reactRoot, id);
|
|
587
680
|
},
|
|
588
681
|
|
|
589
|
-
/**
|
|
590
|
-
* True if the supplied `node` is rendered by React.
|
|
591
|
-
*
|
|
592
|
-
* @param {*} node DOM Element to check.
|
|
593
|
-
* @return {boolean} True if the DOM Element appears to be rendered by React.
|
|
594
|
-
* @internal
|
|
595
|
-
*/
|
|
596
|
-
isRenderedByReact: function (node) {
|
|
597
|
-
if (node.nodeType !== 1) {
|
|
598
|
-
// Not a DOMElement, therefore not a React component
|
|
599
|
-
return false;
|
|
600
|
-
}
|
|
601
|
-
var id = ReactMount.getID(node);
|
|
602
|
-
return id ? id.charAt(0) === SEPARATOR : false;
|
|
603
|
-
},
|
|
604
|
-
|
|
605
682
|
/**
|
|
606
683
|
* Traverses up the ancestors of the supplied node to find a node that is a
|
|
607
|
-
* DOM representation of a React component.
|
|
684
|
+
* DOM representation of a React component rendered by this copy of React.
|
|
608
685
|
*
|
|
609
686
|
* @param {*} node
|
|
610
687
|
* @return {?DOMEventTarget}
|
|
611
688
|
* @internal
|
|
612
689
|
*/
|
|
613
690
|
getFirstReactDOM: function (node) {
|
|
614
|
-
|
|
615
|
-
while (current && current.parentNode !== current) {
|
|
616
|
-
if (ReactMount.isRenderedByReact(current)) {
|
|
617
|
-
return current;
|
|
618
|
-
}
|
|
619
|
-
current = current.parentNode;
|
|
620
|
-
}
|
|
621
|
-
return null;
|
|
691
|
+
return findFirstReactDOMImpl(node);
|
|
622
692
|
},
|
|
623
693
|
|
|
624
694
|
/**
|
|
@@ -637,6 +707,11 @@ var ReactMount = {
|
|
|
637
707
|
|
|
638
708
|
var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode;
|
|
639
709
|
|
|
710
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
711
|
+
// This will throw on the next line; give an early warning
|
|
712
|
+
process.env.NODE_ENV !== 'production' ? warning(deepestAncestor != null, 'React can\'t find the root component node for data-reactid value ' + '`%s`. If you\'re seeing this message, it probably means that ' + 'you\'ve loaded two copies of React on the page. At this time, only ' + 'a single copy of React can be loaded at a time.', targetID) : undefined;
|
|
713
|
+
}
|
|
714
|
+
|
|
640
715
|
firstChildren[0] = deepestAncestor.firstChild;
|
|
641
716
|
firstChildren.length = 1;
|
|
642
717
|
|
|
@@ -689,7 +764,7 @@ var ReactMount = {
|
|
|
689
764
|
!false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'findComponentRoot(..., %s): Unable to find element. This probably ' + 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + 'usually due to forgetting a <tbody> when using tables, nesting tags ' + 'like <form>, <p>, or <a>, or using non-SVG elements in an <svg> ' + 'parent. ' + 'Try inspecting the child nodes of the element with React ID `%s`.', targetID, ReactMount.getID(ancestorNode)) : invariant(false) : undefined;
|
|
690
765
|
},
|
|
691
766
|
|
|
692
|
-
_mountImageIntoNode: function (markup, container, shouldReuseMarkup) {
|
|
767
|
+
_mountImageIntoNode: function (markup, container, shouldReuseMarkup, transaction) {
|
|
693
768
|
!(container && (container.nodeType === ELEMENT_NODE_TYPE || container.nodeType === DOC_NODE_TYPE || container.nodeType === DOCUMENT_FRAGMENT_NODE_TYPE)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mountComponentIntoNode(...): Target container is not valid.') : invariant(false) : undefined;
|
|
694
769
|
|
|
695
770
|
if (shouldReuseMarkup) {
|
|
@@ -734,11 +809,20 @@ var ReactMount = {
|
|
|
734
809
|
}
|
|
735
810
|
}
|
|
736
811
|
|
|
737
|
-
!(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document but ' + 'you didn\'t use server rendering. We can\'t do this ' + 'without using server rendering due to cross-browser quirks. ' + 'See
|
|
812
|
+
!(container.nodeType !== DOC_NODE_TYPE) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'You\'re trying to render a component to the document but ' + 'you didn\'t use server rendering. We can\'t do this ' + 'without using server rendering due to cross-browser quirks. ' + 'See ReactDOMServer.renderToString() for server rendering.') : invariant(false) : undefined;
|
|
738
813
|
|
|
739
|
-
|
|
814
|
+
if (transaction.useCreateElement) {
|
|
815
|
+
while (container.lastChild) {
|
|
816
|
+
container.removeChild(container.lastChild);
|
|
817
|
+
}
|
|
818
|
+
container.appendChild(markup);
|
|
819
|
+
} else {
|
|
820
|
+
setInnerHTML(container, markup);
|
|
821
|
+
}
|
|
740
822
|
},
|
|
741
823
|
|
|
824
|
+
ownerDocumentContextKey: ownerDocumentContextKey,
|
|
825
|
+
|
|
742
826
|
/**
|
|
743
827
|
* React ID utilities.
|
|
744
828
|
*/
|
|
@@ -753,6 +837,8 @@ var ReactMount = {
|
|
|
753
837
|
|
|
754
838
|
getNodeFromInstance: getNodeFromInstance,
|
|
755
839
|
|
|
840
|
+
isValid: isValid,
|
|
841
|
+
|
|
756
842
|
purgeID: purgeID
|
|
757
843
|
};
|
|
758
844
|
|