react 0.14.0-rc1 → 0.14.3
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/LICENSE +31 -0
- package/PATENTS +33 -0
- package/README.md +4 -4
- package/dist/react-with-addons.js +745 -516
- package/dist/react-with-addons.min.js +6 -6
- package/dist/react.js +491 -279
- package/dist/react.min.js +6 -6
- package/lib/CSSPropertyOperations.js +6 -1
- package/lib/ChangeEventPlugin.js +3 -1
- package/lib/DOMChildrenOperations.js +5 -0
- package/lib/DOMPropertyOperations.js +7 -0
- package/lib/EventPluginHub.js +15 -4
- package/lib/EventPluginUtils.js +10 -5
- package/lib/HTMLDOMPropertyConfig.js +21 -2
- package/lib/React.js +1 -0
- package/lib/ReactBrowserEventEmitter.js +6 -0
- package/lib/ReactCSSTransitionGroup.js +1 -1
- package/lib/ReactCSSTransitionGroupChild.js +5 -0
- package/lib/ReactClass.js +0 -1
- package/lib/ReactComponent.js +3 -4
- package/lib/ReactCompositeComponent.js +24 -11
- package/lib/ReactDOMComponent.js +74 -21
- package/lib/ReactDOMIDOperations.js +0 -1
- package/lib/ReactDOMInput.js +6 -1
- package/lib/ReactDOMSelection.js +16 -0
- package/lib/ReactDOMTextarea.js +3 -1
- package/lib/ReactDefaultPerf.js +10 -4
- package/lib/ReactDefaultPerfAnalysis.js +7 -1
- package/lib/ReactElement.js +4 -13
- package/lib/ReactElementValidator.js +14 -7
- package/lib/ReactErrorUtils.js +31 -20
- package/lib/ReactEventEmitterMixin.js +1 -1
- package/lib/ReactLink.js +1 -1
- package/lib/ReactMount.js +15 -3
- package/lib/ReactPropTransferer.js +1 -1
- package/lib/ReactRef.js +1 -2
- package/lib/ReactTestUtils.js +21 -9
- package/lib/ReactVersion.js +1 -1
- package/lib/SyntheticEvent.js +0 -1
- package/lib/canDefineProperty.js +24 -0
- package/lib/createHierarchyRenderer.js +1 -1
- package/lib/getTestDocument.js +4 -11
- package/lib/traverseAllChildren.js +7 -2
- package/package.json +4 -2
- package/dist/react-dom.js +0 -42
- package/dist/react-dom.min.js +0 -12
- package/lib/joinClasses.js +0 -39
- package/lib/memoizeStringOnly.js +0 -31
|
@@ -87,7 +87,6 @@ var ReactDOMIDOperations = {
|
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
ReactPerf.measureMethods(ReactDOMIDOperations, 'ReactDOMIDOperations', {
|
|
90
|
-
updatePropertyByID: 'updatePropertyByID',
|
|
91
90
|
dangerouslyReplaceNodeWithMarkupByID: 'dangerouslyReplaceNodeWithMarkupByID',
|
|
92
91
|
dangerouslyProcessChildrenUpdates: 'dangerouslyProcessChildrenUpdates'
|
|
93
92
|
});
|
package/lib/ReactDOMInput.js
CHANGED
|
@@ -61,7 +61,9 @@ var ReactDOMInput = {
|
|
|
61
61
|
},
|
|
62
62
|
|
|
63
63
|
mountWrapper: function (inst, props) {
|
|
64
|
-
|
|
64
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
65
|
+
LinkedValueUtils.checkPropTypes('input', props, inst._currentElement._owner);
|
|
66
|
+
}
|
|
65
67
|
|
|
66
68
|
var defaultValue = props.defaultValue;
|
|
67
69
|
inst._wrapperState = {
|
|
@@ -69,7 +71,10 @@ var ReactDOMInput = {
|
|
|
69
71
|
initialValue: defaultValue != null ? defaultValue : null,
|
|
70
72
|
onChange: _handleChange.bind(inst)
|
|
71
73
|
};
|
|
74
|
+
},
|
|
72
75
|
|
|
76
|
+
mountReadyWrapper: function (inst) {
|
|
77
|
+
// Can't be in mountWrapper or else server rendering leaks.
|
|
73
78
|
instancesByReactID[inst._rootNodeID] = inst;
|
|
74
79
|
},
|
|
75
80
|
|
package/lib/ReactDOMSelection.js
CHANGED
|
@@ -76,6 +76,22 @@ function getModernOffsets(node) {
|
|
|
76
76
|
|
|
77
77
|
var currentRange = selection.getRangeAt(0);
|
|
78
78
|
|
|
79
|
+
// In Firefox, range.startContainer and range.endContainer can be "anonymous
|
|
80
|
+
// divs", e.g. the up/down buttons on an <input type="number">. Anonymous
|
|
81
|
+
// divs do not seem to expose properties, triggering a "Permission denied
|
|
82
|
+
// error" if any of its properties are accessed. The only seemingly possible
|
|
83
|
+
// way to avoid erroring is to access a property that typically works for
|
|
84
|
+
// non-anonymous divs and catch any error that may otherwise arise. See
|
|
85
|
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=208427
|
|
86
|
+
try {
|
|
87
|
+
/* eslint-disable no-unused-expressions */
|
|
88
|
+
currentRange.startContainer.nodeType;
|
|
89
|
+
currentRange.endContainer.nodeType;
|
|
90
|
+
/* eslint-enable no-unused-expressions */
|
|
91
|
+
} catch (e) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
79
95
|
// If the node and offset values are the same, the selection is collapsed.
|
|
80
96
|
// `Selection.isCollapsed` is available natively, but IE sometimes gets
|
|
81
97
|
// this value wrong.
|
package/lib/ReactDOMTextarea.js
CHANGED
|
@@ -58,7 +58,9 @@ var ReactDOMTextarea = {
|
|
|
58
58
|
},
|
|
59
59
|
|
|
60
60
|
mountWrapper: function (inst, props) {
|
|
61
|
-
|
|
61
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
62
|
+
LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner);
|
|
63
|
+
}
|
|
62
64
|
|
|
63
65
|
var defaultValue = props.defaultValue;
|
|
64
66
|
// TODO (yungsters): Remove support for children content in <textarea>.
|
package/lib/ReactDefaultPerf.js
CHANGED
|
@@ -143,13 +143,14 @@ var ReactDefaultPerf = {
|
|
|
143
143
|
counts: {},
|
|
144
144
|
writes: {},
|
|
145
145
|
displayNames: {},
|
|
146
|
-
totalTime: 0
|
|
146
|
+
totalTime: 0,
|
|
147
|
+
created: {}
|
|
147
148
|
});
|
|
148
149
|
start = performanceNow();
|
|
149
150
|
rv = func.apply(this, args);
|
|
150
151
|
ReactDefaultPerf._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1].totalTime = performanceNow() - start;
|
|
151
152
|
return rv;
|
|
152
|
-
} else if (fnName === '_mountImageIntoNode' || moduleName === 'ReactDOMIDOperations') {
|
|
153
|
+
} else if (fnName === '_mountImageIntoNode' || moduleName === 'ReactBrowserEventEmitter' || moduleName === 'ReactDOMIDOperations' || moduleName === 'CSSPropertyOperations' || moduleName === 'DOMChildrenOperations' || moduleName === 'DOMPropertyOperations') {
|
|
153
154
|
start = performanceNow();
|
|
154
155
|
rv = func.apply(this, args);
|
|
155
156
|
totalTime = performanceNow() - start;
|
|
@@ -177,13 +178,17 @@ var ReactDefaultPerf = {
|
|
|
177
178
|
});
|
|
178
179
|
} else {
|
|
179
180
|
// basic format
|
|
180
|
-
|
|
181
|
+
var id = args[0];
|
|
182
|
+
if (typeof id === 'object') {
|
|
183
|
+
id = ReactMount.getID(args[0]);
|
|
184
|
+
}
|
|
185
|
+
ReactDefaultPerf._recordWrite(id, fnName, totalTime, Array.prototype.slice.call(args, 1));
|
|
181
186
|
}
|
|
182
187
|
return rv;
|
|
183
188
|
} else if (moduleName === 'ReactCompositeComponent' && (fnName === 'mountComponent' || fnName === 'updateComponent' || // TODO: receiveComponent()?
|
|
184
189
|
fnName === '_renderValidatedComponent')) {
|
|
185
190
|
|
|
186
|
-
if (
|
|
191
|
+
if (this._currentElement.type === ReactMount.TopLevelWrapper) {
|
|
187
192
|
return func.apply(this, args);
|
|
188
193
|
}
|
|
189
194
|
|
|
@@ -197,6 +202,7 @@ var ReactDefaultPerf = {
|
|
|
197
202
|
if (isRender) {
|
|
198
203
|
addValue(entry.counts, rootNodeID, 1);
|
|
199
204
|
} else if (isMount) {
|
|
205
|
+
entry.created[rootNodeID] = true;
|
|
200
206
|
mountStack.push(0);
|
|
201
207
|
}
|
|
202
208
|
|
|
@@ -22,7 +22,9 @@ var DOM_OPERATION_TYPES = {
|
|
|
22
22
|
REMOVE_NODE: 'remove',
|
|
23
23
|
SET_MARKUP: 'set innerHTML',
|
|
24
24
|
TEXT_CONTENT: 'set textContent',
|
|
25
|
-
'
|
|
25
|
+
'setValueForProperty': 'update attribute',
|
|
26
|
+
'setValueForAttribute': 'update attribute',
|
|
27
|
+
'deleteValueForProperty': 'remove attribute',
|
|
26
28
|
'dangerouslyReplaceNodeWithMarkupByID': 'replace'
|
|
27
29
|
};
|
|
28
30
|
|
|
@@ -176,6 +178,10 @@ function getUnchangedComponents(measurement) {
|
|
|
176
178
|
break;
|
|
177
179
|
}
|
|
178
180
|
}
|
|
181
|
+
// check if component newly created
|
|
182
|
+
if (measurement.created[id]) {
|
|
183
|
+
isDirty = true;
|
|
184
|
+
}
|
|
179
185
|
if (!isDirty && measurement.counts[id] > 0) {
|
|
180
186
|
cleanComponents[id] = true;
|
|
181
187
|
}
|
package/lib/ReactElement.js
CHANGED
|
@@ -14,10 +14,11 @@
|
|
|
14
14
|
var ReactCurrentOwner = require('./ReactCurrentOwner');
|
|
15
15
|
|
|
16
16
|
var assign = require('./Object.assign');
|
|
17
|
+
var canDefineProperty = require('./canDefineProperty');
|
|
17
18
|
|
|
18
19
|
// The Symbol used to tag the ReactElement type. If there is no native Symbol
|
|
19
20
|
// nor polyfill, then a plain number is used for performance.
|
|
20
|
-
var
|
|
21
|
+
var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7;
|
|
21
22
|
|
|
22
23
|
var RESERVED_PROPS = {
|
|
23
24
|
key: true,
|
|
@@ -26,16 +27,6 @@ var RESERVED_PROPS = {
|
|
|
26
27
|
__source: true
|
|
27
28
|
};
|
|
28
29
|
|
|
29
|
-
var canDefineProperty = false;
|
|
30
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
31
|
-
try {
|
|
32
|
-
Object.defineProperty({}, 'x', {});
|
|
33
|
-
canDefineProperty = true;
|
|
34
|
-
} catch (x) {
|
|
35
|
-
// IE will fail on defineProperty
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
30
|
/**
|
|
40
31
|
* Base constructor for all React elements. This is only used to make this
|
|
41
32
|
* work with a dynamic instanceof check. Nothing should live on this prototype.
|
|
@@ -57,7 +48,7 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
57
48
|
var ReactElement = function (type, key, ref, self, source, owner, props) {
|
|
58
49
|
var element = {
|
|
59
50
|
// This tag allow us to uniquely identify this as a React Element
|
|
60
|
-
$$typeof:
|
|
51
|
+
$$typeof: REACT_ELEMENT_TYPE,
|
|
61
52
|
|
|
62
53
|
// Built-in properties that belong on the element
|
|
63
54
|
type: type,
|
|
@@ -250,7 +241,7 @@ ReactElement.cloneElement = function (element, config, children) {
|
|
|
250
241
|
* @final
|
|
251
242
|
*/
|
|
252
243
|
ReactElement.isValidElement = function (object) {
|
|
253
|
-
return typeof object === 'object' && object !== null && object.$$typeof ===
|
|
244
|
+
return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
|
|
254
245
|
};
|
|
255
246
|
|
|
256
247
|
module.exports = ReactElement;
|
|
@@ -23,6 +23,7 @@ var ReactPropTypeLocations = require('./ReactPropTypeLocations');
|
|
|
23
23
|
var ReactPropTypeLocationNames = require('./ReactPropTypeLocationNames');
|
|
24
24
|
var ReactCurrentOwner = require('./ReactCurrentOwner');
|
|
25
25
|
|
|
26
|
+
var canDefineProperty = require('./canDefineProperty');
|
|
26
27
|
var getIteratorFn = require('./getIteratorFn');
|
|
27
28
|
var invariant = require('fbjs/lib/invariant');
|
|
28
29
|
var warning = require('fbjs/lib/warning');
|
|
@@ -57,7 +58,7 @@ var loggedTypeFailures = {};
|
|
|
57
58
|
* @param {*} parentType element's parent's type.
|
|
58
59
|
*/
|
|
59
60
|
function validateExplicitKey(element, parentType) {
|
|
60
|
-
if (element._store.validated || element.key != null) {
|
|
61
|
+
if (!element._store || element._store.validated || element.key != null) {
|
|
61
62
|
return;
|
|
62
63
|
}
|
|
63
64
|
element._store.validated = true;
|
|
@@ -214,9 +215,10 @@ function validatePropTypes(element) {
|
|
|
214
215
|
var ReactElementValidator = {
|
|
215
216
|
|
|
216
217
|
createElement: function (type, props, children) {
|
|
218
|
+
var validType = typeof type === 'string' || typeof type === 'function';
|
|
217
219
|
// We warn in this case but don't throw. We expect the element creation to
|
|
218
220
|
// succeed and there will likely be errors in render.
|
|
219
|
-
process.env.NODE_ENV !== 'production' ? warning(
|
|
221
|
+
process.env.NODE_ENV !== 'production' ? warning(validType, 'React.createElement: type should not be null, undefined, boolean, or ' + 'number. It should be a string (for DOM elements) or a ReactClass ' + '(for composite components).%s', getDeclarationErrorAddendum()) : undefined;
|
|
220
222
|
|
|
221
223
|
var element = ReactElement.createElement.apply(this, arguments);
|
|
222
224
|
|
|
@@ -226,8 +228,15 @@ var ReactElementValidator = {
|
|
|
226
228
|
return element;
|
|
227
229
|
}
|
|
228
230
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
+
// Skip key warning if the type isn't valid since our key validation logic
|
|
232
|
+
// doesn't expect a non-string/function type and can throw confusing errors.
|
|
233
|
+
// We don't want exception behavior to differ between dev and prod.
|
|
234
|
+
// (Rendering will throw with a helpful message and as soon as the type is
|
|
235
|
+
// fixed, the key warnings will appear.)
|
|
236
|
+
if (validType) {
|
|
237
|
+
for (var i = 2; i < arguments.length; i++) {
|
|
238
|
+
validateChildKeys(arguments[i], type);
|
|
239
|
+
}
|
|
231
240
|
}
|
|
232
241
|
|
|
233
242
|
validatePropTypes(element);
|
|
@@ -241,7 +250,7 @@ var ReactElementValidator = {
|
|
|
241
250
|
validatedFactory.type = type;
|
|
242
251
|
|
|
243
252
|
if (process.env.NODE_ENV !== 'production') {
|
|
244
|
-
|
|
253
|
+
if (canDefineProperty) {
|
|
245
254
|
Object.defineProperty(validatedFactory, 'type', {
|
|
246
255
|
enumerable: false,
|
|
247
256
|
get: function () {
|
|
@@ -252,8 +261,6 @@ var ReactElementValidator = {
|
|
|
252
261
|
return type;
|
|
253
262
|
}
|
|
254
263
|
});
|
|
255
|
-
} catch (x) {
|
|
256
|
-
// IE will fail on defineProperty (es5-shim/sham too)
|
|
257
264
|
}
|
|
258
265
|
}
|
|
259
266
|
|
package/lib/ReactErrorUtils.js
CHANGED
|
@@ -14,25 +14,33 @@
|
|
|
14
14
|
|
|
15
15
|
var caughtError = null;
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Call a function while guarding against errors that happens within it.
|
|
19
|
+
*
|
|
20
|
+
* @param {?String} name of the guard to use for logging or debugging
|
|
21
|
+
* @param {Function} func The function to invoke
|
|
22
|
+
* @param {*} a First argument
|
|
23
|
+
* @param {*} b Second argument
|
|
24
|
+
*/
|
|
25
|
+
function invokeGuardedCallback(name, func, a, b) {
|
|
26
|
+
try {
|
|
27
|
+
return func(a, b);
|
|
28
|
+
} catch (x) {
|
|
29
|
+
if (caughtError === null) {
|
|
30
|
+
caughtError = x;
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
17
36
|
var ReactErrorUtils = {
|
|
37
|
+
invokeGuardedCallback: invokeGuardedCallback,
|
|
38
|
+
|
|
18
39
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* @param {?String} name of the guard to use for logging or debugging
|
|
22
|
-
* @param {Function} func The function to invoke
|
|
23
|
-
* @param {*} a First argument
|
|
24
|
-
* @param {*} b Second argument
|
|
40
|
+
* Invoked by ReactTestUtils.Simulate so that any errors thrown by the event
|
|
41
|
+
* handler are sure to be rethrown by rethrowCaughtError.
|
|
25
42
|
*/
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
return func(a, b);
|
|
29
|
-
} catch (x) {
|
|
30
|
-
if (caughtError === null) {
|
|
31
|
-
caughtError = x;
|
|
32
|
-
}
|
|
33
|
-
return undefined;
|
|
34
|
-
}
|
|
35
|
-
},
|
|
43
|
+
invokeGuardedCallbackWithCatch: invokeGuardedCallback,
|
|
36
44
|
|
|
37
45
|
/**
|
|
38
46
|
* During execution of guarded functions we will capture the first error which
|
|
@@ -52,13 +60,16 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
52
60
|
* To help development we can get better devtools integration by simulating a
|
|
53
61
|
* real browser event.
|
|
54
62
|
*/
|
|
55
|
-
if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof
|
|
63
|
+
if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
|
|
56
64
|
var fakeNode = document.createElement('react');
|
|
57
65
|
ReactErrorUtils.invokeGuardedCallback = function (name, func, a, b) {
|
|
58
66
|
var boundFunc = func.bind(null, a, b);
|
|
59
|
-
|
|
60
|
-
fakeNode.
|
|
61
|
-
|
|
67
|
+
var evtType = 'react-' + name;
|
|
68
|
+
fakeNode.addEventListener(evtType, boundFunc, false);
|
|
69
|
+
var evt = document.createEvent('Event');
|
|
70
|
+
evt.initEvent(evtType, false, false);
|
|
71
|
+
fakeNode.dispatchEvent(evt);
|
|
72
|
+
fakeNode.removeEventListener(evtType, boundFunc, false);
|
|
62
73
|
};
|
|
63
74
|
}
|
|
64
75
|
}
|
|
@@ -15,7 +15,7 @@ var EventPluginHub = require('./EventPluginHub');
|
|
|
15
15
|
|
|
16
16
|
function runEventQueueInBatch(events) {
|
|
17
17
|
EventPluginHub.enqueueEvents(events);
|
|
18
|
-
EventPluginHub.processEventQueue();
|
|
18
|
+
EventPluginHub.processEventQueue(false);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
var ReactEventEmitterMixin = {
|
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
|
@@ -347,7 +347,11 @@ function findFirstReactDOMImpl(node) {
|
|
|
347
347
|
do {
|
|
348
348
|
lastID = internalGetID(current);
|
|
349
349
|
current = current.parentNode;
|
|
350
|
-
|
|
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
|
+
}
|
|
351
355
|
} while (lastID !== reactRootID);
|
|
352
356
|
|
|
353
357
|
if (current === containersByReactRootID[reactRootID]) {
|
|
@@ -363,7 +367,7 @@ function findFirstReactDOMImpl(node) {
|
|
|
363
367
|
* here.
|
|
364
368
|
*/
|
|
365
369
|
var TopLevelWrapper = function () {};
|
|
366
|
-
TopLevelWrapper.
|
|
370
|
+
TopLevelWrapper.prototype.isReactComponent = {};
|
|
367
371
|
if (process.env.NODE_ENV !== 'production') {
|
|
368
372
|
TopLevelWrapper.displayName = 'TopLevelWrapper';
|
|
369
373
|
}
|
|
@@ -391,6 +395,9 @@ TopLevelWrapper.prototype.render = function () {
|
|
|
391
395
|
* Inside of `container`, the first element rendered is the "reactRoot".
|
|
392
396
|
*/
|
|
393
397
|
var ReactMount = {
|
|
398
|
+
|
|
399
|
+
TopLevelWrapper: TopLevelWrapper,
|
|
400
|
+
|
|
394
401
|
/** Exposed for debugging purposes **/
|
|
395
402
|
_instancesByReactRootID: instancesByReactRootID,
|
|
396
403
|
|
|
@@ -509,7 +516,12 @@ var ReactMount = {
|
|
|
509
516
|
var prevWrappedElement = prevComponent._currentElement;
|
|
510
517
|
var prevElement = prevWrappedElement.props;
|
|
511
518
|
if (shouldUpdateReactComponent(prevElement, nextElement)) {
|
|
512
|
-
|
|
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;
|
|
513
525
|
} else {
|
|
514
526
|
ReactMount.unmountComponentAtNode(container);
|
|
515
527
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
var assign = require('./Object.assign');
|
|
15
15
|
var emptyFunction = require('fbjs/lib/emptyFunction');
|
|
16
|
-
var joinClasses = require('
|
|
16
|
+
var joinClasses = require('fbjs/lib/joinClasses');
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Creates a transfer strategy that will merge prop values using the supplied
|
package/lib/ReactRef.js
CHANGED
|
@@ -59,8 +59,7 @@ ReactRef.shouldUpdateRefs = function (prevElement, nextElement) {
|
|
|
59
59
|
var prevEmpty = prevElement === null || prevElement === false;
|
|
60
60
|
var nextEmpty = nextElement === null || nextElement === false;
|
|
61
61
|
|
|
62
|
-
return
|
|
63
|
-
// This has a few false positives w/r/t empty components.
|
|
62
|
+
return(
|
|
64
63
|
// This has a few false positives w/r/t empty components.
|
|
65
64
|
prevEmpty || nextEmpty || nextElement._owner !== prevElement._owner || nextElement.ref !== prevElement.ref
|
|
66
65
|
);
|
package/lib/ReactTestUtils.js
CHANGED
|
@@ -44,6 +44,7 @@ function findAllInRenderedTreeInternal(inst, test) {
|
|
|
44
44
|
}
|
|
45
45
|
var publicInst = inst.getPublicInstance();
|
|
46
46
|
var ret = test(publicInst) ? [publicInst] : [];
|
|
47
|
+
var currentElement = inst._currentElement;
|
|
47
48
|
if (ReactTestUtils.isDOMComponent(publicInst)) {
|
|
48
49
|
var renderedChildren = inst._renderedChildren;
|
|
49
50
|
var key;
|
|
@@ -53,7 +54,7 @@ function findAllInRenderedTreeInternal(inst, test) {
|
|
|
53
54
|
}
|
|
54
55
|
ret = ret.concat(findAllInRenderedTreeInternal(renderedChildren[key], test));
|
|
55
56
|
}
|
|
56
|
-
} else if (
|
|
57
|
+
} else if (ReactElement.isValidElement(currentElement) && typeof currentElement.type === 'function') {
|
|
57
58
|
ret = ret.concat(findAllInRenderedTreeInternal(inst._renderedComponent, test));
|
|
58
59
|
}
|
|
59
60
|
return ret;
|
|
@@ -84,8 +85,6 @@ var ReactTestUtils = {
|
|
|
84
85
|
},
|
|
85
86
|
|
|
86
87
|
isDOMComponent: function (inst) {
|
|
87
|
-
// TODO: Fix this heuristic. It's just here because composites can currently
|
|
88
|
-
// pretend to be DOM components.
|
|
89
88
|
return !!(inst && inst.nodeType === 1 && inst.tagName);
|
|
90
89
|
},
|
|
91
90
|
|
|
@@ -99,7 +98,7 @@ var ReactTestUtils = {
|
|
|
99
98
|
// this returns when we have DOM nodes as refs directly
|
|
100
99
|
return false;
|
|
101
100
|
}
|
|
102
|
-
return typeof inst.render === 'function' && typeof inst.setState === 'function';
|
|
101
|
+
return inst != null && typeof inst.render === 'function' && typeof inst.setState === 'function';
|
|
103
102
|
},
|
|
104
103
|
|
|
105
104
|
isCompositeComponentWithType: function (inst, type) {
|
|
@@ -150,11 +149,21 @@ var ReactTestUtils = {
|
|
|
150
149
|
* components with the class name matching `className`.
|
|
151
150
|
* @return {array} an array of all the matches.
|
|
152
151
|
*/
|
|
153
|
-
scryRenderedDOMComponentsWithClass: function (root,
|
|
152
|
+
scryRenderedDOMComponentsWithClass: function (root, classNames) {
|
|
153
|
+
if (!Array.isArray(classNames)) {
|
|
154
|
+
classNames = classNames.split(/\s+/);
|
|
155
|
+
}
|
|
154
156
|
return ReactTestUtils.findAllInRenderedTree(root, function (inst) {
|
|
155
157
|
if (ReactTestUtils.isDOMComponent(inst)) {
|
|
156
|
-
var
|
|
157
|
-
|
|
158
|
+
var className = inst.className;
|
|
159
|
+
if (typeof className !== 'string') {
|
|
160
|
+
// SVG, probably.
|
|
161
|
+
className = inst.getAttribute('class') || '';
|
|
162
|
+
}
|
|
163
|
+
var classList = className.split(/\s+/);
|
|
164
|
+
return classNames.every(function (name) {
|
|
165
|
+
return classList.indexOf(name) !== -1;
|
|
166
|
+
});
|
|
158
167
|
}
|
|
159
168
|
return false;
|
|
160
169
|
});
|
|
@@ -308,8 +317,11 @@ NoopInternalComponent.prototype = {
|
|
|
308
317
|
this._currentElement = element;
|
|
309
318
|
},
|
|
310
319
|
|
|
311
|
-
unmountComponent: function () {}
|
|
320
|
+
unmountComponent: function () {},
|
|
312
321
|
|
|
322
|
+
getPublicInstance: function () {
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
313
325
|
};
|
|
314
326
|
|
|
315
327
|
var ShallowComponentWrapper = function () {};
|
|
@@ -387,7 +399,7 @@ function makeSimulator(eventType) {
|
|
|
387
399
|
|
|
388
400
|
ReactUpdates.batchedUpdates(function () {
|
|
389
401
|
EventPluginHub.enqueueEvents(event);
|
|
390
|
-
EventPluginHub.processEventQueue();
|
|
402
|
+
EventPluginHub.processEventQueue(true);
|
|
391
403
|
});
|
|
392
404
|
};
|
|
393
405
|
}
|