react 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/JSXTransformer.js +13448 -0
- package/dist/react-with-addons.js +20235 -0
- package/dist/react-with-addons.min.js +22 -0
- package/dist/react.js +18443 -0
- package/dist/react.min.js +21 -0
- package/lib/AutoFocusMixin.js +3 -1
- package/lib/BeforeInputEventPlugin.js +222 -0
- package/lib/CSSPropertyOperations.js +3 -3
- package/lib/{ReactMountReady.js → CallbackQueue.js} +32 -24
- package/lib/ChangeEventPlugin.js +1 -1
- package/lib/CompositionEventPlugin.js +5 -1
- package/lib/DOMChildrenOperations.js +33 -20
- package/lib/DOMProperty.js +51 -21
- package/lib/DOMPropertyOperations.js +28 -16
- package/lib/DefaultEventPluginOrder.js +1 -0
- package/lib/EventConstants.js +1 -0
- package/lib/EventListener.js +5 -2
- package/lib/EventPluginHub.js +2 -5
- package/lib/EventPluginRegistry.js +6 -4
- package/lib/EventPluginUtils.js +11 -1
- package/lib/ExecutionEnvironment.js +8 -2
- package/lib/{DefaultDOMPropertyConfig.js → HTMLDOMPropertyConfig.js} +41 -58
- package/lib/LinkedValueUtils.js +26 -28
- package/lib/LocalEventTrapMixin.js +52 -0
- package/lib/React.js +39 -3
- package/lib/ReactBrowserComponentMixin.js +46 -0
- package/lib/{ReactEventEmitter.js → ReactBrowserEventEmitter.js} +115 -94
- package/lib/ReactCSSTransitionGroup.js +12 -10
- package/lib/ReactCSSTransitionGroupChild.js +2 -5
- package/lib/ReactChildren.js +31 -10
- package/lib/ReactComponent.js +119 -223
- package/lib/ReactComponentBrowserEnvironment.js +3 -36
- package/lib/ReactComponentWithPureRenderMixin.js +54 -0
- package/lib/ReactCompositeComponent.js +249 -287
- package/lib/ReactDOM.js +25 -23
- package/lib/ReactDOMButton.js +2 -1
- package/lib/ReactDOMComponent.js +42 -23
- package/lib/ReactDOMForm.js +7 -12
- package/lib/ReactDOMIDOperations.js +2 -31
- package/lib/ReactDOMImg.js +7 -13
- package/lib/ReactDOMInput.js +2 -1
- package/lib/ReactDOMOption.js +11 -7
- package/lib/ReactDOMSelect.js +18 -16
- package/lib/ReactDOMSelection.js +35 -10
- package/lib/ReactDOMTextarea.js +9 -7
- package/lib/ReactDefaultBatchingStrategy.js +3 -3
- package/lib/ReactDefaultInjection.js +27 -14
- package/lib/ReactDefaultPerf.js +28 -11
- package/lib/ReactDefaultPerfAnalysis.js +4 -0
- package/lib/ReactDescriptor.js +251 -0
- package/lib/ReactDescriptorValidator.js +283 -0
- package/lib/ReactEmptyComponent.js +78 -0
- package/lib/ReactEventEmitterMixin.js +1 -3
- package/lib/ReactEventListener.js +189 -0
- package/lib/ReactInjection.js +8 -2
- package/lib/ReactInputSelection.js +2 -1
- package/lib/ReactLink.js +24 -0
- package/lib/ReactMount.js +61 -21
- package/lib/ReactMultiChild.js +18 -13
- package/lib/ReactOwner.js +6 -1
- package/lib/ReactPropTransferer.js +44 -29
- package/lib/ReactPropTypes.js +226 -242
- package/lib/ReactPutListenerQueue.js +2 -2
- package/lib/ReactReconcileTransaction.js +21 -20
- package/lib/ReactServerRendering.js +41 -11
- package/lib/ReactServerRenderingTransaction.js +115 -0
- package/lib/ReactTestUtils.js +39 -21
- package/lib/ReactTextComponent.js +21 -13
- package/lib/ReactTransitionChildMapping.js +2 -2
- package/lib/ReactTransitionEvents.js +19 -0
- package/lib/ReactTransitionGroup.js +9 -6
- package/lib/ReactUpdates.js +139 -22
- package/lib/ReactWithAddons.js +8 -3
- package/lib/SVGDOMPropertyConfig.js +97 -0
- package/lib/SimpleEventPlugin.js +7 -1
- package/lib/SyntheticInputEvent.js +52 -0
- package/lib/SyntheticKeyboardEvent.js +33 -4
- package/lib/SyntheticMouseEvent.js +3 -0
- package/lib/SyntheticTouchEvent.js +4 -1
- package/lib/SyntheticUIEvent.js +24 -2
- package/lib/Transaction.js +0 -32
- package/lib/cloneWithProps.js +10 -8
- package/lib/createFullPageComponent.js +1 -1
- package/lib/dangerousStyleValue.js +11 -5
- package/lib/{ReactComponentEnvironment.js → emptyObject.js} +6 -5
- package/lib/escapeTextForBrowser.js +2 -3
- package/lib/flattenChildren.js +9 -7
- package/lib/focusNode.js +33 -0
- package/lib/getEventKey.js +35 -5
- package/lib/getEventModifierState.js +52 -0
- package/lib/getMarkupWrap.js +2 -0
- package/lib/getTextContentAccessor.js +1 -1
- package/lib/hyphenate.js +3 -0
- package/lib/hyphenateStyleName.js +46 -0
- package/lib/instantiateReactComponent.js +62 -0
- package/lib/invariant.js +17 -19
- package/lib/isNode.js +1 -1
- package/lib/{objMap.js → mapObject.js} +8 -3
- package/lib/mergeHelpers.js +11 -0
- package/lib/mergeInto.js +3 -2
- package/lib/monitorCodeUse.js +37 -0
- package/lib/onlyChild.js +3 -3
- package/lib/performance.js +33 -0
- package/lib/performanceNow.js +5 -14
- package/lib/setInnerHTML.js +77 -0
- package/lib/shouldUpdateReactComponent.js +14 -28
- package/lib/toArray.js +1 -1
- package/lib/traverseAllChildren.js +9 -5
- package/lib/update.js +171 -0
- package/package.json +4 -3
- package/lib/ReactEventTopLevelCallback.js +0 -149
- package/lib/createObjectFrom.js +0 -61
- package/lib/objMapKeyVal.js +0 -47
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2014 Facebook, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
* @providesModule ReactDescriptor
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
"use strict";
|
|
20
|
+
|
|
21
|
+
var ReactContext = require("./ReactContext");
|
|
22
|
+
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
23
|
+
|
|
24
|
+
var merge = require("./merge");
|
|
25
|
+
var warning = require("./warning");
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Warn for mutations.
|
|
29
|
+
*
|
|
30
|
+
* @internal
|
|
31
|
+
* @param {object} object
|
|
32
|
+
* @param {string} key
|
|
33
|
+
*/
|
|
34
|
+
function defineWarningProperty(object, key) {
|
|
35
|
+
Object.defineProperty(object, key, {
|
|
36
|
+
|
|
37
|
+
configurable: false,
|
|
38
|
+
enumerable: true,
|
|
39
|
+
|
|
40
|
+
get: function() {
|
|
41
|
+
if (!this._store) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
return this._store[key];
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
set: function(value) {
|
|
48
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
49
|
+
false,
|
|
50
|
+
'Don\'t set the ' + key + ' property of the component. ' +
|
|
51
|
+
'Mutate the existing props object instead.'
|
|
52
|
+
) : null);
|
|
53
|
+
this._store[key] = value;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* This is updated to true if the membrane is successfully created.
|
|
61
|
+
*/
|
|
62
|
+
var useMutationMembrane = false;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Warn for mutations.
|
|
66
|
+
*
|
|
67
|
+
* @internal
|
|
68
|
+
* @param {object} descriptor
|
|
69
|
+
*/
|
|
70
|
+
function defineMutationMembrane(prototype) {
|
|
71
|
+
try {
|
|
72
|
+
var pseudoFrozenProperties = {
|
|
73
|
+
props: true
|
|
74
|
+
};
|
|
75
|
+
for (var key in pseudoFrozenProperties) {
|
|
76
|
+
defineWarningProperty(prototype, key);
|
|
77
|
+
}
|
|
78
|
+
useMutationMembrane = true;
|
|
79
|
+
} catch (x) {
|
|
80
|
+
// IE will fail on defineProperty
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Transfer static properties from the source to the target. Functions are
|
|
86
|
+
* rebound to have this reflect the original source.
|
|
87
|
+
*/
|
|
88
|
+
function proxyStaticMethods(target, source) {
|
|
89
|
+
if (typeof source !== 'function') {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
for (var key in source) {
|
|
93
|
+
if (source.hasOwnProperty(key)) {
|
|
94
|
+
var value = source[key];
|
|
95
|
+
if (typeof value === 'function') {
|
|
96
|
+
var bound = value.bind(source);
|
|
97
|
+
// Copy any properties defined on the function, such as `isRequired` on
|
|
98
|
+
// a PropTypes validator. (mergeInto refuses to work on functions.)
|
|
99
|
+
for (var k in value) {
|
|
100
|
+
if (value.hasOwnProperty(k)) {
|
|
101
|
+
bound[k] = value[k];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
target[key] = bound;
|
|
105
|
+
} else {
|
|
106
|
+
target[key] = value;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Base constructor for all React descriptors. This is only used to make this
|
|
114
|
+
* work with a dynamic instanceof check. Nothing should live on this prototype.
|
|
115
|
+
*
|
|
116
|
+
* @param {*} type
|
|
117
|
+
* @internal
|
|
118
|
+
*/
|
|
119
|
+
var ReactDescriptor = function() {};
|
|
120
|
+
|
|
121
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
122
|
+
defineMutationMembrane(ReactDescriptor.prototype);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
ReactDescriptor.createFactory = function(type) {
|
|
126
|
+
|
|
127
|
+
var descriptorPrototype = Object.create(ReactDescriptor.prototype);
|
|
128
|
+
|
|
129
|
+
var factory = function(props, children) {
|
|
130
|
+
// For consistency we currently allocate a new object for every descriptor.
|
|
131
|
+
// This protects the descriptor from being mutated by the original props
|
|
132
|
+
// object being mutated. It also protects the original props object from
|
|
133
|
+
// being mutated by children arguments and default props. This behavior
|
|
134
|
+
// comes with a performance cost and could be deprecated in the future.
|
|
135
|
+
// It could also be optimized with a smarter JSX transform.
|
|
136
|
+
if (props == null) {
|
|
137
|
+
props = {};
|
|
138
|
+
} else if (typeof props === 'object') {
|
|
139
|
+
props = merge(props);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Children can be more than one argument, and those are transferred onto
|
|
143
|
+
// the newly allocated props object.
|
|
144
|
+
var childrenLength = arguments.length - 1;
|
|
145
|
+
if (childrenLength === 1) {
|
|
146
|
+
props.children = children;
|
|
147
|
+
} else if (childrenLength > 1) {
|
|
148
|
+
var childArray = Array(childrenLength);
|
|
149
|
+
for (var i = 0; i < childrenLength; i++) {
|
|
150
|
+
childArray[i] = arguments[i + 1];
|
|
151
|
+
}
|
|
152
|
+
props.children = childArray;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Initialize the descriptor object
|
|
156
|
+
var descriptor = Object.create(descriptorPrototype);
|
|
157
|
+
|
|
158
|
+
// Record the component responsible for creating this descriptor.
|
|
159
|
+
descriptor._owner = ReactCurrentOwner.current;
|
|
160
|
+
|
|
161
|
+
// TODO: Deprecate withContext, and then the context becomes accessible
|
|
162
|
+
// through the owner.
|
|
163
|
+
descriptor._context = ReactContext.current;
|
|
164
|
+
|
|
165
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
166
|
+
// The validation flag and props are currently mutative. We put them on
|
|
167
|
+
// an external backing store so that we can freeze the whole object.
|
|
168
|
+
// This can be replaced with a WeakMap once they are implemented in
|
|
169
|
+
// commonly used development environments.
|
|
170
|
+
descriptor._store = { validated: false, props: props };
|
|
171
|
+
|
|
172
|
+
// We're not allowed to set props directly on the object so we early
|
|
173
|
+
// return and rely on the prototype membrane to forward to the backing
|
|
174
|
+
// store.
|
|
175
|
+
if (useMutationMembrane) {
|
|
176
|
+
Object.freeze(descriptor);
|
|
177
|
+
return descriptor;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
descriptor.props = props;
|
|
182
|
+
return descriptor;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// Currently we expose the prototype of the descriptor so that
|
|
186
|
+
// <Foo /> instanceof Foo works. This is controversial pattern.
|
|
187
|
+
factory.prototype = descriptorPrototype;
|
|
188
|
+
|
|
189
|
+
// Expose the type on the factory and the prototype so that it can be
|
|
190
|
+
// easily accessed on descriptors. E.g. <Foo />.type === Foo.type and for
|
|
191
|
+
// static methods like <Foo />.type.staticMethod();
|
|
192
|
+
// This should not be named constructor since this may not be the function
|
|
193
|
+
// that created the descriptor, and it may not even be a constructor.
|
|
194
|
+
factory.type = type;
|
|
195
|
+
descriptorPrototype.type = type;
|
|
196
|
+
|
|
197
|
+
proxyStaticMethods(factory, type);
|
|
198
|
+
|
|
199
|
+
// Expose a unique constructor on the prototype is that this works with type
|
|
200
|
+
// systems that compare constructor properties: <Foo />.constructor === Foo
|
|
201
|
+
// This may be controversial since it requires a known factory function.
|
|
202
|
+
descriptorPrototype.constructor = factory;
|
|
203
|
+
|
|
204
|
+
return factory;
|
|
205
|
+
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
ReactDescriptor.cloneAndReplaceProps = function(oldDescriptor, newProps) {
|
|
209
|
+
var newDescriptor = Object.create(oldDescriptor.constructor.prototype);
|
|
210
|
+
// It's important that this property order matches the hidden class of the
|
|
211
|
+
// original descriptor to maintain perf.
|
|
212
|
+
newDescriptor._owner = oldDescriptor._owner;
|
|
213
|
+
newDescriptor._context = oldDescriptor._context;
|
|
214
|
+
|
|
215
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
216
|
+
newDescriptor._store = {
|
|
217
|
+
validated: oldDescriptor._store.validated,
|
|
218
|
+
props: newProps
|
|
219
|
+
};
|
|
220
|
+
if (useMutationMembrane) {
|
|
221
|
+
Object.freeze(newDescriptor);
|
|
222
|
+
return newDescriptor;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
newDescriptor.props = newProps;
|
|
227
|
+
return newDescriptor;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Checks if a value is a valid descriptor constructor.
|
|
232
|
+
*
|
|
233
|
+
* @param {*}
|
|
234
|
+
* @return {boolean}
|
|
235
|
+
* @public
|
|
236
|
+
*/
|
|
237
|
+
ReactDescriptor.isValidFactory = function(factory) {
|
|
238
|
+
return typeof factory === 'function' &&
|
|
239
|
+
factory.prototype instanceof ReactDescriptor;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* @param {?object} object
|
|
244
|
+
* @return {boolean} True if `object` is a valid component.
|
|
245
|
+
* @final
|
|
246
|
+
*/
|
|
247
|
+
ReactDescriptor.isValidDescriptor = function(object) {
|
|
248
|
+
return object instanceof ReactDescriptor;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
module.exports = ReactDescriptor;
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2014 Facebook, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*
|
|
16
|
+
* @providesModule ReactDescriptorValidator
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* ReactDescriptorValidator provides a wrapper around a descriptor factory
|
|
21
|
+
* which validates the props passed to the descriptor. This is intended to be
|
|
22
|
+
* used only in DEV and could be replaced by a static type checker for languages
|
|
23
|
+
* that support it.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
"use strict";
|
|
27
|
+
|
|
28
|
+
var ReactDescriptor = require("./ReactDescriptor");
|
|
29
|
+
var ReactPropTypeLocations = require("./ReactPropTypeLocations");
|
|
30
|
+
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
31
|
+
|
|
32
|
+
var monitorCodeUse = require("./monitorCodeUse");
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Warn if there's no key explicitly set on dynamic arrays of children or
|
|
36
|
+
* object keys are not valid. This allows us to keep track of children between
|
|
37
|
+
* updates.
|
|
38
|
+
*/
|
|
39
|
+
var ownerHasKeyUseWarning = {
|
|
40
|
+
'react_key_warning': {},
|
|
41
|
+
'react_numeric_key_warning': {}
|
|
42
|
+
};
|
|
43
|
+
var ownerHasMonitoredObjectMap = {};
|
|
44
|
+
|
|
45
|
+
var loggedTypeFailures = {};
|
|
46
|
+
|
|
47
|
+
var NUMERIC_PROPERTY_REGEX = /^\d+$/;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Gets the current owner's displayName for use in warnings.
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
* @return {?string} Display name or undefined
|
|
54
|
+
*/
|
|
55
|
+
function getCurrentOwnerDisplayName() {
|
|
56
|
+
var current = ReactCurrentOwner.current;
|
|
57
|
+
return current && current.constructor.displayName || undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Warn if the component doesn't have an explicit key assigned to it.
|
|
62
|
+
* This component is in an array. The array could grow and shrink or be
|
|
63
|
+
* reordered. All children that haven't already been validated are required to
|
|
64
|
+
* have a "key" property assigned to it.
|
|
65
|
+
*
|
|
66
|
+
* @internal
|
|
67
|
+
* @param {ReactComponent} component Component that requires a key.
|
|
68
|
+
* @param {*} parentType component's parent's type.
|
|
69
|
+
*/
|
|
70
|
+
function validateExplicitKey(component, parentType) {
|
|
71
|
+
if (component._store.validated || component.props.key != null) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
component._store.validated = true;
|
|
75
|
+
|
|
76
|
+
warnAndMonitorForKeyUse(
|
|
77
|
+
'react_key_warning',
|
|
78
|
+
'Each child in an array should have a unique "key" prop.',
|
|
79
|
+
component,
|
|
80
|
+
parentType
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Warn if the key is being defined as an object property but has an incorrect
|
|
86
|
+
* value.
|
|
87
|
+
*
|
|
88
|
+
* @internal
|
|
89
|
+
* @param {string} name Property name of the key.
|
|
90
|
+
* @param {ReactComponent} component Component that requires a key.
|
|
91
|
+
* @param {*} parentType component's parent's type.
|
|
92
|
+
*/
|
|
93
|
+
function validatePropertyKey(name, component, parentType) {
|
|
94
|
+
if (!NUMERIC_PROPERTY_REGEX.test(name)) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
warnAndMonitorForKeyUse(
|
|
98
|
+
'react_numeric_key_warning',
|
|
99
|
+
'Child objects should have non-numeric keys so ordering is preserved.',
|
|
100
|
+
component,
|
|
101
|
+
parentType
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Shared warning and monitoring code for the key warnings.
|
|
107
|
+
*
|
|
108
|
+
* @internal
|
|
109
|
+
* @param {string} warningID The id used when logging.
|
|
110
|
+
* @param {string} message The base warning that gets output.
|
|
111
|
+
* @param {ReactComponent} component Component that requires a key.
|
|
112
|
+
* @param {*} parentType component's parent's type.
|
|
113
|
+
*/
|
|
114
|
+
function warnAndMonitorForKeyUse(warningID, message, component, parentType) {
|
|
115
|
+
var ownerName = getCurrentOwnerDisplayName();
|
|
116
|
+
var parentName = parentType.displayName;
|
|
117
|
+
|
|
118
|
+
var useName = ownerName || parentName;
|
|
119
|
+
var memoizer = ownerHasKeyUseWarning[warningID];
|
|
120
|
+
if (memoizer.hasOwnProperty(useName)) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
memoizer[useName] = true;
|
|
124
|
+
|
|
125
|
+
message += ownerName ?
|
|
126
|
+
(" Check the render method of " + ownerName + ".") :
|
|
127
|
+
(" Check the renderComponent call using <" + parentName + ">.");
|
|
128
|
+
|
|
129
|
+
// Usually the current owner is the offender, but if it accepts children as a
|
|
130
|
+
// property, it may be the creator of the child that's responsible for
|
|
131
|
+
// assigning it a key.
|
|
132
|
+
var childOwnerName = null;
|
|
133
|
+
if (component._owner && component._owner !== ReactCurrentOwner.current) {
|
|
134
|
+
// Name of the component that originally created this child.
|
|
135
|
+
childOwnerName = component._owner.constructor.displayName;
|
|
136
|
+
|
|
137
|
+
message += (" It was passed a child from " + childOwnerName + ".");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
message += ' See http://fb.me/react-warning-keys for more information.';
|
|
141
|
+
monitorCodeUse(warningID, {
|
|
142
|
+
component: useName,
|
|
143
|
+
componentOwner: childOwnerName
|
|
144
|
+
});
|
|
145
|
+
console.warn(message);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Log that we're using an object map. We're considering deprecating this
|
|
150
|
+
* feature and replace it with proper Map and ImmutableMap data structures.
|
|
151
|
+
*
|
|
152
|
+
* @internal
|
|
153
|
+
*/
|
|
154
|
+
function monitorUseOfObjectMap() {
|
|
155
|
+
var currentName = getCurrentOwnerDisplayName() || '';
|
|
156
|
+
if (ownerHasMonitoredObjectMap.hasOwnProperty(currentName)) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
ownerHasMonitoredObjectMap[currentName] = true;
|
|
160
|
+
monitorCodeUse('react_object_map_children');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Ensure that every component either is passed in a static location, in an
|
|
165
|
+
* array with an explicit keys property defined, or in an object literal
|
|
166
|
+
* with valid key property.
|
|
167
|
+
*
|
|
168
|
+
* @internal
|
|
169
|
+
* @param {*} component Statically passed child of any type.
|
|
170
|
+
* @param {*} parentType component's parent's type.
|
|
171
|
+
* @return {boolean}
|
|
172
|
+
*/
|
|
173
|
+
function validateChildKeys(component, parentType) {
|
|
174
|
+
if (Array.isArray(component)) {
|
|
175
|
+
for (var i = 0; i < component.length; i++) {
|
|
176
|
+
var child = component[i];
|
|
177
|
+
if (ReactDescriptor.isValidDescriptor(child)) {
|
|
178
|
+
validateExplicitKey(child, parentType);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
} else if (ReactDescriptor.isValidDescriptor(component)) {
|
|
182
|
+
// This component was passed in a valid location.
|
|
183
|
+
component._store.validated = true;
|
|
184
|
+
} else if (component && typeof component === 'object') {
|
|
185
|
+
monitorUseOfObjectMap();
|
|
186
|
+
for (var name in component) {
|
|
187
|
+
validatePropertyKey(name, component[name], parentType);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Assert that the props are valid
|
|
194
|
+
*
|
|
195
|
+
* @param {string} componentName Name of the component for error messages.
|
|
196
|
+
* @param {object} propTypes Map of prop name to a ReactPropType
|
|
197
|
+
* @param {object} props
|
|
198
|
+
* @param {string} location e.g. "prop", "context", "child context"
|
|
199
|
+
* @private
|
|
200
|
+
*/
|
|
201
|
+
function checkPropTypes(componentName, propTypes, props, location) {
|
|
202
|
+
for (var propName in propTypes) {
|
|
203
|
+
if (propTypes.hasOwnProperty(propName)) {
|
|
204
|
+
var error;
|
|
205
|
+
// Prop type validation may throw. In case they do, we don't want to
|
|
206
|
+
// fail the render phase where it didn't fail before. So we log it.
|
|
207
|
+
// After these have been cleaned up, we'll let them throw.
|
|
208
|
+
try {
|
|
209
|
+
error = propTypes[propName](props, propName, componentName, location);
|
|
210
|
+
} catch (ex) {
|
|
211
|
+
error = ex;
|
|
212
|
+
}
|
|
213
|
+
if (error instanceof Error && !(error.message in loggedTypeFailures)) {
|
|
214
|
+
// Only monitor this failure once because there tends to be a lot of the
|
|
215
|
+
// same error.
|
|
216
|
+
loggedTypeFailures[error.message] = true;
|
|
217
|
+
// This will soon use the warning module
|
|
218
|
+
monitorCodeUse(
|
|
219
|
+
'react_failed_descriptor_type_check',
|
|
220
|
+
{ message: error.message }
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
var ReactDescriptorValidator = {
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Wraps a descriptor factory function in another function which validates
|
|
231
|
+
* the props and context of the descriptor and warns about any failed type
|
|
232
|
+
* checks.
|
|
233
|
+
*
|
|
234
|
+
* @param {function} factory The original descriptor factory
|
|
235
|
+
* @param {object?} propTypes A prop type definition set
|
|
236
|
+
* @param {object?} contextTypes A context type definition set
|
|
237
|
+
* @return {object} The component descriptor, which may be invalid.
|
|
238
|
+
* @private
|
|
239
|
+
*/
|
|
240
|
+
createFactory: function(factory, propTypes, contextTypes) {
|
|
241
|
+
var validatedFactory = function(props, children) {
|
|
242
|
+
var descriptor = factory.apply(this, arguments);
|
|
243
|
+
|
|
244
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
245
|
+
validateChildKeys(arguments[i], descriptor.type);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
var name = descriptor.type.displayName;
|
|
249
|
+
if (propTypes) {
|
|
250
|
+
checkPropTypes(
|
|
251
|
+
name,
|
|
252
|
+
propTypes,
|
|
253
|
+
descriptor.props,
|
|
254
|
+
ReactPropTypeLocations.prop
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
if (contextTypes) {
|
|
258
|
+
checkPropTypes(
|
|
259
|
+
name,
|
|
260
|
+
contextTypes,
|
|
261
|
+
descriptor._context,
|
|
262
|
+
ReactPropTypeLocations.context
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
return descriptor;
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
validatedFactory.prototype = factory.prototype;
|
|
269
|
+
validatedFactory.type = factory.type;
|
|
270
|
+
|
|
271
|
+
// Copy static properties
|
|
272
|
+
for (var key in factory) {
|
|
273
|
+
if (factory.hasOwnProperty(key)) {
|
|
274
|
+
validatedFactory[key] = factory[key];
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return validatedFactory;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
module.exports = ReactDescriptorValidator;
|