react 0.14.0-alpha3 → 0.14.0-beta1
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 +5 -2
- package/addons.js +2 -2
- package/dist/JSXTransformer.js +69 -70
- package/dist/react-with-addons.js +2047 -2078
- package/dist/react-with-addons.min.js +6 -6
- package/dist/react.js +1861 -1904
- package/dist/react.min.js +5 -5
- package/lib/{AutoFocusMixin.js → AutoFocusUtils.js} +13 -3
- package/lib/ChangeEventPlugin.js +4 -2
- package/lib/DOMProperty.js +81 -116
- package/lib/DOMPropertyOperations.js +70 -25
- package/lib/EnterLeaveEventPlugin.js +3 -3
- package/lib/EventPluginHub.js +2 -2
- package/lib/EventPluginUtils.js +6 -6
- package/lib/HTMLDOMPropertyConfig.js +8 -1
- package/lib/LinkedValueUtils.js +45 -33
- package/lib/PooledClass.js +12 -0
- package/lib/React.js +1 -1
- package/lib/ReactCSSTransitionGroupChild.js +8 -0
- package/lib/ReactChildren.js +3 -3
- package/lib/ReactClass.js +29 -47
- package/lib/ReactComponent.js +11 -6
- package/lib/ReactComponentWithPureRenderMixin.js +2 -2
- package/lib/ReactCompositeComponent.js +45 -72
- package/lib/ReactDOM.js +1 -0
- package/lib/ReactDOMButton.js +15 -26
- package/lib/ReactDOMClient.js +9 -4
- package/lib/ReactDOMComponent.js +302 -24
- package/lib/ReactDOMIDOperations.js +14 -0
- package/lib/ReactDOMInput.js +78 -94
- package/lib/ReactDOMOption.js +19 -38
- package/lib/ReactDOMSelect.js +85 -95
- package/lib/ReactDOMTextarea.js +39 -52
- package/lib/ReactDefaultInjection.js +0 -47
- package/lib/ReactElement.js +18 -79
- package/lib/ReactElementValidator.js +29 -98
- package/lib/ReactErrorUtils.js +1 -1
- package/lib/ReactEventEmitterMixin.js +2 -3
- package/lib/ReactEventListener.js +43 -3
- package/lib/ReactFragment.js +12 -7
- package/lib/ReactInputSelection.js +4 -3
- package/lib/ReactInstanceHandles.js +3 -2
- package/lib/ReactMount.js +20 -40
- package/lib/ReactNativeComponent.js +0 -5
- package/lib/ReactNoopUpdateQueue.js +118 -0
- package/lib/ReactPropTypes.js +3 -3
- package/lib/ReactReconcileTransaction.js +2 -2
- package/lib/ReactReconciler.js +8 -10
- package/lib/ReactServerBatchingStrategy.js +23 -0
- package/lib/ReactServerRendering.js +13 -0
- package/lib/ReactServerRenderingTransaction.js +2 -2
- package/lib/ReactTestUtils.js +56 -33
- package/lib/ReactUpdateQueue.js +51 -26
- package/lib/ReactUpdates.js +0 -3
- package/lib/ReactWithAddons.js +0 -2
- package/lib/SelectEventPlugin.js +6 -7
- package/lib/SimpleEventPlugin.js +4 -4
- package/lib/SyntheticClipboardEvent.js +2 -2
- package/lib/SyntheticCompositionEvent.js +2 -2
- package/lib/SyntheticDragEvent.js +2 -2
- package/lib/SyntheticEvent.js +6 -5
- package/lib/SyntheticFocusEvent.js +2 -2
- package/lib/SyntheticInputEvent.js +2 -2
- package/lib/SyntheticKeyboardEvent.js +2 -2
- package/lib/SyntheticMouseEvent.js +2 -2
- package/lib/SyntheticTouchEvent.js +2 -2
- package/lib/SyntheticUIEvent.js +2 -2
- package/lib/SyntheticWheelEvent.js +2 -2
- package/lib/Transaction.js +10 -4
- package/lib/cloneWithProps.js +1 -1
- package/lib/deprecated.js +47 -0
- package/lib/findDOMNode.js +2 -3
- package/lib/forEachAccumulated.js +1 -1
- package/lib/getEventCharCode.js +1 -1
- package/lib/getEventModifierState.js +0 -1
- package/lib/getMarkupWrap.js +13 -35
- package/lib/instantiateReactComponent.js +13 -9
- package/lib/isTextInputElement.js +2 -1
- package/lib/joinClasses.js +1 -1
- package/lib/setInnerHTML.js +1 -1
- package/lib/traverseAllChildren.js +1 -1
- package/lib/warning.js +0 -4
- package/package.json +1 -1
- package/react.js +53 -1
- package/addons/CSSTransitionGroup.js +0 -1
- package/addons/LinkedStateMixin.js +0 -1
- package/addons/Perf.js +0 -1
- package/addons/PureRenderMixin.js +0 -1
- package/addons/TestUtils.js +0 -1
- package/addons/TransitionGroup.js +0 -1
- package/addons/batchedUpdates.js +0 -1
- package/addons/cloneWithProps.js +0 -1
- package/addons/createFragment.js +0 -1
- package/addons/renderSubtreeIntoContainer.js +0 -1
- package/addons/shallowCompare.js +0 -1
- package/addons/update.js +0 -1
- package/lib/LocalEventTrapMixin.js +0 -46
- package/lib/ReactContext.js +0 -32
- package/lib/ReactDOMForm.js +0 -47
- package/lib/ReactDOMIframe.js +0 -43
- package/lib/ReactDOMImg.js +0 -44
- package/lib/ReactLifeCycle.js +0 -35
- package/lib/createFullPageComponent.js +0 -51
package/lib/ReactDOMTextarea.js
CHANGED
|
@@ -11,26 +11,18 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
-
var AutoFocusMixin = require("./AutoFocusMixin");
|
|
15
|
-
var DOMPropertyOperations = require("./DOMPropertyOperations");
|
|
16
14
|
var LinkedValueUtils = require("./LinkedValueUtils");
|
|
17
|
-
var
|
|
18
|
-
var ReactClass = require("./ReactClass");
|
|
19
|
-
var ReactElement = require("./ReactElement");
|
|
15
|
+
var ReactDOMIDOperations = require("./ReactDOMIDOperations");
|
|
20
16
|
var ReactUpdates = require("./ReactUpdates");
|
|
21
17
|
|
|
22
18
|
var assign = require("./Object.assign");
|
|
23
|
-
var findDOMNode = require("./findDOMNode");
|
|
24
19
|
var invariant = require("./invariant");
|
|
25
|
-
|
|
26
20
|
var warning = require("./warning");
|
|
27
21
|
|
|
28
|
-
var textarea = ReactElement.createFactory('textarea');
|
|
29
|
-
|
|
30
22
|
function forceUpdateIfMounted() {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
if (this._rootNodeID) {
|
|
24
|
+
// DOM component is still mounted; update
|
|
25
|
+
ReactDOMTextarea.updateWrapper(this);
|
|
34
26
|
}
|
|
35
27
|
}
|
|
36
28
|
|
|
@@ -49,16 +41,28 @@ function forceUpdateIfMounted() {
|
|
|
49
41
|
* The rendered element will be initialized with an empty value, the prop
|
|
50
42
|
* `defaultValue` if specified, or the children content (deprecated).
|
|
51
43
|
*/
|
|
52
|
-
var ReactDOMTextarea =
|
|
53
|
-
|
|
54
|
-
|
|
44
|
+
var ReactDOMTextarea = {
|
|
45
|
+
getNativeProps: function (inst, props, context) {
|
|
46
|
+
!(props.dangerouslySetInnerHTML == null) ? 'production' !== process.env.NODE_ENV ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : invariant(false) : undefined;
|
|
47
|
+
|
|
48
|
+
// Always set children to the same thing. In IE9, the selection range will
|
|
49
|
+
// get reset if `textContent` is mutated.
|
|
50
|
+
var nativeProps = assign({}, props, {
|
|
51
|
+
defaultValue: undefined,
|
|
52
|
+
value: undefined,
|
|
53
|
+
children: inst._wrapperState.initialValue,
|
|
54
|
+
onChange: inst._wrapperState.onChange
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return nativeProps;
|
|
58
|
+
},
|
|
55
59
|
|
|
56
|
-
|
|
60
|
+
mountWrapper: function (inst, props) {
|
|
61
|
+
LinkedValueUtils.checkPropTypes('textarea', props, inst._currentElement._owner);
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
var defaultValue = this.props.defaultValue;
|
|
63
|
+
var defaultValue = props.defaultValue;
|
|
60
64
|
// TODO (yungsters): Remove support for children content in <textarea>.
|
|
61
|
-
var children =
|
|
65
|
+
var children = props.children;
|
|
62
66
|
if (children != null) {
|
|
63
67
|
if ('production' !== process.env.NODE_ENV) {
|
|
64
68
|
'production' !== process.env.NODE_ENV ? warning(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.') : undefined;
|
|
@@ -74,51 +78,34 @@ var ReactDOMTextarea = ReactClass.createClass({
|
|
|
74
78
|
if (defaultValue == null) {
|
|
75
79
|
defaultValue = '';
|
|
76
80
|
}
|
|
77
|
-
var value = LinkedValueUtils.getValue(
|
|
78
|
-
|
|
81
|
+
var value = LinkedValueUtils.getValue(props);
|
|
82
|
+
|
|
83
|
+
inst._wrapperState = {
|
|
79
84
|
// We save the initial value so that `ReactDOMComponent` doesn't update
|
|
80
85
|
// `textContent` (unnecessary since we update value).
|
|
81
86
|
// The initial value can be a boolean or object so that's why it's
|
|
82
87
|
// forced to be a string.
|
|
83
|
-
initialValue: '' + (value != null ? value : defaultValue)
|
|
88
|
+
initialValue: '' + (value != null ? value : defaultValue),
|
|
89
|
+
onChange: _handleChange.bind(inst)
|
|
84
90
|
};
|
|
85
91
|
},
|
|
86
92
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
var
|
|
90
|
-
|
|
91
|
-
!(props.dangerouslySetInnerHTML == null) ? 'production' !== process.env.NODE_ENV ? invariant(false, '`dangerouslySetInnerHTML` does not make sense on <textarea>.') : invariant(false) : undefined;
|
|
92
|
-
|
|
93
|
-
props.defaultValue = null;
|
|
94
|
-
props.value = null;
|
|
95
|
-
props.onChange = this._handleChange;
|
|
96
|
-
|
|
97
|
-
// Always set children to the same thing. In IE9, the selection range will
|
|
98
|
-
// get reset if `textContent` is mutated.
|
|
99
|
-
return textarea(props, this.state.initialValue);
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
componentDidUpdate: function (prevProps, prevState, prevContext) {
|
|
103
|
-
var value = LinkedValueUtils.getValue(this.props);
|
|
93
|
+
updateWrapper: function (inst) {
|
|
94
|
+
var props = inst._currentElement.props;
|
|
95
|
+
var value = LinkedValueUtils.getValue(props);
|
|
104
96
|
if (value != null) {
|
|
105
|
-
var rootNode = findDOMNode(this);
|
|
106
97
|
// Cast `value` to a string to ensure the value is set correctly. While
|
|
107
98
|
// browsers typically do this as necessary, jsdom doesn't.
|
|
108
|
-
|
|
99
|
+
ReactDOMIDOperations.updatePropertyByID(inst._rootNodeID, 'value', '' + value);
|
|
109
100
|
}
|
|
110
|
-
},
|
|
111
|
-
|
|
112
|
-
_handleChange: function (event) {
|
|
113
|
-
var returnValue;
|
|
114
|
-
var onChange = LinkedValueUtils.getOnChange(this.props);
|
|
115
|
-
if (onChange) {
|
|
116
|
-
returnValue = onChange.call(this, event);
|
|
117
|
-
}
|
|
118
|
-
ReactUpdates.asap(forceUpdateIfMounted, this);
|
|
119
|
-
return returnValue;
|
|
120
101
|
}
|
|
102
|
+
};
|
|
121
103
|
|
|
122
|
-
|
|
104
|
+
function _handleChange(event) {
|
|
105
|
+
var props = this._currentElement.props;
|
|
106
|
+
var returnValue = LinkedValueUtils.executeOnChange(props, event);
|
|
107
|
+
ReactUpdates.asap(forceUpdateIfMounted, this);
|
|
108
|
+
return returnValue;
|
|
109
|
+
}
|
|
123
110
|
|
|
124
111
|
module.exports = ReactDOMTextarea;
|
|
@@ -19,25 +19,14 @@ var EnterLeaveEventPlugin = require("./EnterLeaveEventPlugin");
|
|
|
19
19
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
20
20
|
var HTMLDOMPropertyConfig = require("./HTMLDOMPropertyConfig");
|
|
21
21
|
var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
|
|
22
|
-
var ReactClass = require("./ReactClass");
|
|
23
22
|
var ReactComponentBrowserEnvironment = require("./ReactComponentBrowserEnvironment");
|
|
24
23
|
var ReactDefaultBatchingStrategy = require("./ReactDefaultBatchingStrategy");
|
|
25
24
|
var ReactDOMComponent = require("./ReactDOMComponent");
|
|
26
|
-
var ReactDOMButton = require("./ReactDOMButton");
|
|
27
|
-
var ReactDOMForm = require("./ReactDOMForm");
|
|
28
|
-
var ReactDOMImg = require("./ReactDOMImg");
|
|
29
25
|
var ReactDOMIDOperations = require("./ReactDOMIDOperations");
|
|
30
|
-
var ReactDOMIframe = require("./ReactDOMIframe");
|
|
31
|
-
var ReactDOMInput = require("./ReactDOMInput");
|
|
32
|
-
var ReactDOMOption = require("./ReactDOMOption");
|
|
33
|
-
var ReactDOMSelect = require("./ReactDOMSelect");
|
|
34
|
-
var ReactDOMTextarea = require("./ReactDOMTextarea");
|
|
35
26
|
var ReactDOMTextComponent = require("./ReactDOMTextComponent");
|
|
36
|
-
var ReactElement = require("./ReactElement");
|
|
37
27
|
var ReactEventListener = require("./ReactEventListener");
|
|
38
28
|
var ReactInjection = require("./ReactInjection");
|
|
39
29
|
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
40
|
-
var ReactInstanceMap = require("./ReactInstanceMap");
|
|
41
30
|
var ReactMount = require("./ReactMount");
|
|
42
31
|
var ReactReconcileTransaction = require("./ReactReconcileTransaction");
|
|
43
32
|
var SelectEventPlugin = require("./SelectEventPlugin");
|
|
@@ -45,23 +34,6 @@ var ServerReactRootIndex = require("./ServerReactRootIndex");
|
|
|
45
34
|
var SimpleEventPlugin = require("./SimpleEventPlugin");
|
|
46
35
|
var SVGDOMPropertyConfig = require("./SVGDOMPropertyConfig");
|
|
47
36
|
|
|
48
|
-
var createFullPageComponent = require("./createFullPageComponent");
|
|
49
|
-
|
|
50
|
-
function autoGenerateWrapperClass(type) {
|
|
51
|
-
return ReactClass.createClass({
|
|
52
|
-
tagName: type.toUpperCase(),
|
|
53
|
-
render: function () {
|
|
54
|
-
// Copy owner down for debugging info
|
|
55
|
-
var internalInstance = ReactInstanceMap.get(this);
|
|
56
|
-
return new ReactElement(type, null, // key
|
|
57
|
-
null, // ref
|
|
58
|
-
internalInstance._currentElement._owner, // owner
|
|
59
|
-
null, // context
|
|
60
|
-
this.props);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
37
|
var alreadyInjected = false;
|
|
66
38
|
|
|
67
39
|
function inject() {
|
|
@@ -98,27 +70,8 @@ function inject() {
|
|
|
98
70
|
|
|
99
71
|
ReactInjection.NativeComponent.injectTextComponentClass(ReactDOMTextComponent);
|
|
100
72
|
|
|
101
|
-
ReactInjection.NativeComponent.injectAutoWrapper(autoGenerateWrapperClass);
|
|
102
|
-
|
|
103
|
-
// This needs to happen before createFullPageComponent() otherwise the mixin
|
|
104
|
-
// won't be included.
|
|
105
73
|
ReactInjection.Class.injectMixin(ReactBrowserComponentMixin);
|
|
106
74
|
|
|
107
|
-
ReactInjection.NativeComponent.injectComponentClasses({
|
|
108
|
-
'button': ReactDOMButton,
|
|
109
|
-
'form': ReactDOMForm,
|
|
110
|
-
'iframe': ReactDOMIframe,
|
|
111
|
-
'img': ReactDOMImg,
|
|
112
|
-
'input': ReactDOMInput,
|
|
113
|
-
'option': ReactDOMOption,
|
|
114
|
-
'select': ReactDOMSelect,
|
|
115
|
-
'textarea': ReactDOMTextarea,
|
|
116
|
-
|
|
117
|
-
'html': createFullPageComponent('html'),
|
|
118
|
-
'head': createFullPageComponent('head'),
|
|
119
|
-
'body': createFullPageComponent('body')
|
|
120
|
-
});
|
|
121
|
-
|
|
122
75
|
ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
|
|
123
76
|
ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);
|
|
124
77
|
|
package/lib/ReactElement.js
CHANGED
|
@@ -11,79 +11,27 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
-
var ReactContext = require("./ReactContext");
|
|
15
14
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
16
15
|
|
|
17
16
|
var assign = require("./Object.assign");
|
|
18
|
-
var warning = require("./warning");
|
|
19
17
|
|
|
20
18
|
var RESERVED_PROPS = {
|
|
21
19
|
key: true,
|
|
22
20
|
ref: true
|
|
23
21
|
};
|
|
24
22
|
|
|
25
|
-
/**
|
|
26
|
-
* Warn for mutations.
|
|
27
|
-
*
|
|
28
|
-
* @internal
|
|
29
|
-
* @param {object} object
|
|
30
|
-
* @param {string} key
|
|
31
|
-
*/
|
|
32
|
-
function defineWarningProperty(object, key) {
|
|
33
|
-
Object.defineProperty(object, key, {
|
|
34
|
-
|
|
35
|
-
configurable: false,
|
|
36
|
-
enumerable: true,
|
|
37
|
-
|
|
38
|
-
get: function () {
|
|
39
|
-
if (!this._store) {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
return this._store[key];
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
set: function (value) {
|
|
46
|
-
'production' !== process.env.NODE_ENV ? warning(false, 'Don\'t set the %s property of the React element. Instead, ' + 'specify the correct value when initially creating the element.', key) : undefined;
|
|
47
|
-
this._store[key] = value;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* This is updated to true if the membrane is successfully created.
|
|
55
|
-
*/
|
|
56
|
-
var useMutationMembrane = false;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Warn for mutations.
|
|
60
|
-
*
|
|
61
|
-
* @internal
|
|
62
|
-
* @param {object} element
|
|
63
|
-
*/
|
|
64
|
-
function defineMutationMembrane(prototype) {
|
|
65
|
-
try {
|
|
66
|
-
var pseudoFrozenProperties = {
|
|
67
|
-
props: true
|
|
68
|
-
};
|
|
69
|
-
for (var key in pseudoFrozenProperties) {
|
|
70
|
-
defineWarningProperty(prototype, key);
|
|
71
|
-
}
|
|
72
|
-
useMutationMembrane = true;
|
|
73
|
-
} catch (x) {}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
23
|
/**
|
|
77
24
|
* Base constructor for all React elements. This is only used to make this
|
|
78
25
|
* work with a dynamic instanceof check. Nothing should live on this prototype.
|
|
79
26
|
*
|
|
80
27
|
* @param {*} type
|
|
81
|
-
* @param {string|object} ref
|
|
82
28
|
* @param {*} key
|
|
29
|
+
* @param {string|object} ref
|
|
30
|
+
* @param {*} owner
|
|
83
31
|
* @param {*} props
|
|
84
32
|
* @internal
|
|
85
33
|
*/
|
|
86
|
-
var ReactElement = function (type, key, ref, owner,
|
|
34
|
+
var ReactElement = function (type, key, ref, owner, props) {
|
|
87
35
|
// Built-in properties that belong on the element
|
|
88
36
|
this.type = type;
|
|
89
37
|
this.key = key;
|
|
@@ -92,12 +40,14 @@ var ReactElement = function (type, key, ref, owner, context, props) {
|
|
|
92
40
|
// Record the component responsible for creating this element.
|
|
93
41
|
this._owner = owner;
|
|
94
42
|
|
|
43
|
+
this.props = props;
|
|
44
|
+
|
|
95
45
|
if ('production' !== process.env.NODE_ENV) {
|
|
96
|
-
// The validation flag
|
|
46
|
+
// The validation flag is currently mutative. We put it on
|
|
97
47
|
// an external backing store so that we can freeze the whole object.
|
|
98
48
|
// This can be replaced with a WeakMap once they are implemented in
|
|
99
49
|
// commonly used development environments.
|
|
100
|
-
this._store = {
|
|
50
|
+
this._store = {};
|
|
101
51
|
|
|
102
52
|
// To make comparing ReactElements easier for testing purposes, we make
|
|
103
53
|
// the validation flag non-enumerable (where possible, which should
|
|
@@ -107,21 +57,15 @@ var ReactElement = function (type, key, ref, owner, context, props) {
|
|
|
107
57
|
Object.defineProperty(this._store, 'validated', {
|
|
108
58
|
configurable: false,
|
|
109
59
|
enumerable: false,
|
|
110
|
-
writable: true
|
|
60
|
+
writable: true,
|
|
61
|
+
value: false
|
|
111
62
|
});
|
|
112
|
-
} catch (x) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
// We're not allowed to set props directly on the object so we early
|
|
116
|
-
// return and rely on the prototype membrane to forward to the backing
|
|
117
|
-
// store.
|
|
118
|
-
if (useMutationMembrane) {
|
|
119
|
-
Object.freeze(this);
|
|
120
|
-
return;
|
|
63
|
+
} catch (x) {
|
|
64
|
+
this._store.validated = false;
|
|
121
65
|
}
|
|
66
|
+
Object.freeze(this.props);
|
|
67
|
+
Object.freeze(this);
|
|
122
68
|
}
|
|
123
|
-
|
|
124
|
-
this.props = props;
|
|
125
69
|
};
|
|
126
70
|
|
|
127
71
|
// We intentionally don't expose the function on the constructor property.
|
|
@@ -130,10 +74,6 @@ ReactElement.prototype = {
|
|
|
130
74
|
_isReactElement: true
|
|
131
75
|
};
|
|
132
76
|
|
|
133
|
-
if ('production' !== process.env.NODE_ENV) {
|
|
134
|
-
defineMutationMembrane(ReactElement.prototype);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
77
|
ReactElement.createElement = function (type, config, children) {
|
|
138
78
|
var propName;
|
|
139
79
|
|
|
@@ -177,7 +117,7 @@ ReactElement.createElement = function (type, config, children) {
|
|
|
177
117
|
}
|
|
178
118
|
}
|
|
179
119
|
|
|
180
|
-
return new ReactElement(type, key, ref, ReactCurrentOwner.current,
|
|
120
|
+
return new ReactElement(type, key, ref, ReactCurrentOwner.current, props);
|
|
181
121
|
};
|
|
182
122
|
|
|
183
123
|
ReactElement.createFactory = function (type) {
|
|
@@ -192,12 +132,13 @@ ReactElement.createFactory = function (type) {
|
|
|
192
132
|
};
|
|
193
133
|
|
|
194
134
|
ReactElement.cloneAndReplaceProps = function (oldElement, newProps) {
|
|
195
|
-
var newElement = new ReactElement(oldElement.type, oldElement.key, oldElement.ref, oldElement._owner,
|
|
135
|
+
var newElement = new ReactElement(oldElement.type, oldElement.key, oldElement.ref, oldElement._owner, newProps);
|
|
196
136
|
|
|
197
137
|
if ('production' !== process.env.NODE_ENV) {
|
|
198
138
|
// If the key on the original is valid, then the clone is valid
|
|
199
139
|
newElement._store.validated = oldElement._store.validated;
|
|
200
140
|
}
|
|
141
|
+
|
|
201
142
|
return newElement;
|
|
202
143
|
};
|
|
203
144
|
|
|
@@ -244,7 +185,7 @@ ReactElement.cloneElement = function (element, config, children) {
|
|
|
244
185
|
props.children = childArray;
|
|
245
186
|
}
|
|
246
187
|
|
|
247
|
-
return new ReactElement(element.type, key, ref, owner,
|
|
188
|
+
return new ReactElement(element.type, key, ref, owner, props);
|
|
248
189
|
};
|
|
249
190
|
|
|
250
191
|
/**
|
|
@@ -266,6 +207,4 @@ ReactElement.isValidElement = function (object) {
|
|
|
266
207
|
return isElement;
|
|
267
208
|
};
|
|
268
209
|
|
|
269
|
-
module.exports = ReactElement;
|
|
270
|
-
|
|
271
|
-
// IE will fail on defineProperty
|
|
210
|
+
module.exports = ReactElement;
|
|
@@ -23,7 +23,6 @@ var ReactFragment = require("./ReactFragment");
|
|
|
23
23
|
var ReactPropTypeLocations = require("./ReactPropTypeLocations");
|
|
24
24
|
var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
|
|
25
25
|
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
26
|
-
var ReactNativeComponent = require("./ReactNativeComponent");
|
|
27
26
|
|
|
28
27
|
var getIteratorFn = require("./getIteratorFn");
|
|
29
28
|
var invariant = require("./invariant");
|
|
@@ -95,7 +94,12 @@ function validateExplicitKey(element, parentType) {
|
|
|
95
94
|
}
|
|
96
95
|
element._store.validated = true;
|
|
97
96
|
|
|
98
|
-
|
|
97
|
+
var addenda = getAddendaForKeyUse('uniqueKey', element, parentType);
|
|
98
|
+
if (addenda === null) {
|
|
99
|
+
// we already showed the warning
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'Each child in an array or iterator should have a unique "key" prop.' + '%s%s%s', addenda.parentOrOwner || '', addenda.childOwner || '', addenda.url || '') : undefined;
|
|
99
103
|
}
|
|
100
104
|
|
|
101
105
|
/**
|
|
@@ -111,42 +115,50 @@ function validatePropertyKey(name, element, parentType) {
|
|
|
111
115
|
if (!NUMERIC_PROPERTY_REGEX.test(name)) {
|
|
112
116
|
return;
|
|
113
117
|
}
|
|
114
|
-
|
|
118
|
+
var addenda = getAddendaForKeyUse('numericKeys', element, parentType);
|
|
119
|
+
if (addenda === null) {
|
|
120
|
+
// we already showed the warning
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
'production' !== process.env.NODE_ENV ? warning(false, 'Child objects should have non-numeric keys so ordering is preserved.' + '%s%s%s', addenda.parentOrOwner || '', addenda.childOwner || '', addenda.url || '') : undefined;
|
|
115
124
|
}
|
|
116
125
|
|
|
117
126
|
/**
|
|
118
127
|
* Shared warning and monitoring code for the key warnings.
|
|
119
128
|
*
|
|
120
129
|
* @internal
|
|
121
|
-
* @param {string}
|
|
130
|
+
* @param {string} messageType A key used for de-duping warnings.
|
|
122
131
|
* @param {ReactElement} element Component that requires a key.
|
|
123
132
|
* @param {*} parentType element's parent's type.
|
|
133
|
+
* @returns {?object} A set of addenda to use in the warning message, or null
|
|
134
|
+
* if the warning has already been shown before (and shouldn't be shown again).
|
|
124
135
|
*/
|
|
125
|
-
function
|
|
136
|
+
function getAddendaForKeyUse(messageType, element, parentType) {
|
|
126
137
|
var ownerName = getCurrentOwnerDisplayName();
|
|
127
138
|
var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
|
|
128
139
|
|
|
129
140
|
var useName = ownerName || parentName;
|
|
130
|
-
var memoizer = ownerHasKeyUseWarning[
|
|
131
|
-
if (memoizer
|
|
132
|
-
return;
|
|
141
|
+
var memoizer = ownerHasKeyUseWarning[messageType] || (ownerHasKeyUseWarning[messageType] = {});
|
|
142
|
+
if (memoizer[useName]) {
|
|
143
|
+
return null;
|
|
133
144
|
}
|
|
134
145
|
memoizer[useName] = true;
|
|
135
146
|
|
|
136
|
-
var
|
|
147
|
+
var addenda = {
|
|
148
|
+
parentOrOwner: ownerName ? ' Check the render method of ' + ownerName + '.' : parentName ? ' Check the React.render call using <' + parentName + '>.' : null,
|
|
149
|
+
url: ' See https://fb.me/react-warning-keys for more information.',
|
|
150
|
+
childOwner: null
|
|
151
|
+
};
|
|
137
152
|
|
|
138
153
|
// Usually the current owner is the offender, but if it accepts children as a
|
|
139
154
|
// property, it may be the creator of the child that's responsible for
|
|
140
155
|
// assigning it a key.
|
|
141
|
-
var childOwnerAddendum = '';
|
|
142
156
|
if (element && element._owner && element._owner !== ReactCurrentOwner.current) {
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
childOwnerAddendum = ' It was passed a child from ' + childOwnerName + '.';
|
|
157
|
+
// Give the component that originally created this child.
|
|
158
|
+
addenda.childOwner = ' It was passed a child from ' + getName(element._owner) + '.';
|
|
147
159
|
}
|
|
148
160
|
|
|
149
|
-
|
|
161
|
+
return addenda;
|
|
150
162
|
}
|
|
151
163
|
|
|
152
164
|
/**
|
|
@@ -230,80 +242,6 @@ function checkPropTypes(componentName, propTypes, props, location) {
|
|
|
230
242
|
}
|
|
231
243
|
}
|
|
232
244
|
|
|
233
|
-
var warnedPropsMutations = {};
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Warn about mutating props when setting `propName` on `element`.
|
|
237
|
-
*
|
|
238
|
-
* @param {string} propName The string key within props that was set
|
|
239
|
-
* @param {ReactElement} element
|
|
240
|
-
*/
|
|
241
|
-
function warnForPropsMutation(propName, element) {
|
|
242
|
-
var type = element.type;
|
|
243
|
-
var elementName = typeof type === 'string' ? type : type.displayName;
|
|
244
|
-
var ownerName = element._owner ? element._owner.getPublicInstance().constructor.displayName : null;
|
|
245
|
-
|
|
246
|
-
var warningKey = propName + '|' + elementName + '|' + ownerName;
|
|
247
|
-
if (warnedPropsMutations.hasOwnProperty(warningKey)) {
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
warnedPropsMutations[warningKey] = true;
|
|
251
|
-
|
|
252
|
-
var elementInfo = '';
|
|
253
|
-
if (elementName) {
|
|
254
|
-
elementInfo = ' <' + elementName + ' />';
|
|
255
|
-
}
|
|
256
|
-
var ownerInfo = '';
|
|
257
|
-
if (ownerName) {
|
|
258
|
-
ownerInfo = ' The element was created by ' + ownerName + '.';
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
'production' !== process.env.NODE_ENV ? warning(false, 'Don\'t set .props.%s of the React component%s. Instead, specify the ' + 'correct value when initially creating the element or use ' + 'React.cloneElement to make a new element with updated props.%s', propName, elementInfo, ownerInfo) : undefined;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Inline Object.is polyfill
|
|
265
|
-
function is(a, b) {
|
|
266
|
-
if (a !== a) {
|
|
267
|
-
// NaN
|
|
268
|
-
return b !== b;
|
|
269
|
-
}
|
|
270
|
-
if (a === 0 && b === 0) {
|
|
271
|
-
// +-0
|
|
272
|
-
return 1 / a === 1 / b;
|
|
273
|
-
}
|
|
274
|
-
return a === b;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Given an element, check if its props have been mutated since element
|
|
279
|
-
* creation (or the last call to this function). In particular, check if any
|
|
280
|
-
* new props have been added, which we can't directly catch by defining warning
|
|
281
|
-
* properties on the props object.
|
|
282
|
-
*
|
|
283
|
-
* @param {ReactElement} element
|
|
284
|
-
*/
|
|
285
|
-
function checkAndWarnForMutatedProps(element) {
|
|
286
|
-
if (!element._store) {
|
|
287
|
-
// Element was created using `new ReactElement` directly or with
|
|
288
|
-
// `ReactElement.createElement`; skip mutation checking
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
var originalProps = element._store.originalProps;
|
|
293
|
-
var props = element.props;
|
|
294
|
-
|
|
295
|
-
for (var propName in props) {
|
|
296
|
-
if (props.hasOwnProperty(propName)) {
|
|
297
|
-
if (!originalProps.hasOwnProperty(propName) || !is(originalProps[propName], props[propName])) {
|
|
298
|
-
warnForPropsMutation(propName, element);
|
|
299
|
-
|
|
300
|
-
// Copy over the new value so that the two props objects match again
|
|
301
|
-
originalProps[propName] = props[propName];
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
245
|
/**
|
|
308
246
|
* Given an element, validate that its props follow the propTypes definition,
|
|
309
247
|
* provided by the type.
|
|
@@ -311,15 +249,10 @@ function checkAndWarnForMutatedProps(element) {
|
|
|
311
249
|
* @param {ReactElement} element
|
|
312
250
|
*/
|
|
313
251
|
function validatePropTypes(element) {
|
|
314
|
-
|
|
315
|
-
|
|
252
|
+
var componentClass = element.type;
|
|
253
|
+
if (typeof componentClass !== 'function') {
|
|
316
254
|
return;
|
|
317
255
|
}
|
|
318
|
-
// Extract the component class from the element. Converts string types
|
|
319
|
-
// to a composite class which may have propTypes.
|
|
320
|
-
// TODO: Validating a string's propTypes is not decoupled from the
|
|
321
|
-
// rendering target which is problematic.
|
|
322
|
-
var componentClass = ReactNativeComponent.getComponentClassForElement(element);
|
|
323
256
|
var name = componentClass.displayName || componentClass.name;
|
|
324
257
|
if (componentClass.propTypes) {
|
|
325
258
|
checkPropTypes(name, componentClass.propTypes, element.props, ReactPropTypeLocations.prop);
|
|
@@ -331,8 +264,6 @@ function validatePropTypes(element) {
|
|
|
331
264
|
|
|
332
265
|
var ReactElementValidator = {
|
|
333
266
|
|
|
334
|
-
checkAndWarnForMutatedProps: checkAndWarnForMutatedProps,
|
|
335
|
-
|
|
336
267
|
createElement: function (type, props, children) {
|
|
337
268
|
// We warn in this case but don't throw. We expect the element creation to
|
|
338
269
|
// succeed and there will likely be errors in render.
|