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,78 @@
|
|
|
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 ReactEmptyComponent
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
"use strict";
|
|
20
|
+
|
|
21
|
+
var invariant = require("./invariant");
|
|
22
|
+
|
|
23
|
+
var component;
|
|
24
|
+
// This registry keeps track of the React IDs of the components that rendered to
|
|
25
|
+
// `null` (in reality a placeholder such as `noscript`)
|
|
26
|
+
var nullComponentIdsRegistry = {};
|
|
27
|
+
|
|
28
|
+
var ReactEmptyComponentInjection = {
|
|
29
|
+
injectEmptyComponent: function(emptyComponent) {
|
|
30
|
+
component = emptyComponent;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @return {ReactComponent} component The injected empty component.
|
|
36
|
+
*/
|
|
37
|
+
function getEmptyComponent() {
|
|
38
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
39
|
+
component,
|
|
40
|
+
'Trying to return null from a render, but no null placeholder component ' +
|
|
41
|
+
'was injected.'
|
|
42
|
+
) : invariant(component));
|
|
43
|
+
return component();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Mark the component as having rendered to null.
|
|
48
|
+
* @param {string} id Component's `_rootNodeID`.
|
|
49
|
+
*/
|
|
50
|
+
function registerNullComponentID(id) {
|
|
51
|
+
nullComponentIdsRegistry[id] = true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Unmark the component as having rendered to null: it renders to something now.
|
|
56
|
+
* @param {string} id Component's `_rootNodeID`.
|
|
57
|
+
*/
|
|
58
|
+
function deregisterNullComponentID(id) {
|
|
59
|
+
delete nullComponentIdsRegistry[id];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @param {string} id Component's `_rootNodeID`.
|
|
64
|
+
* @return {boolean} True if the component is rendered to null.
|
|
65
|
+
*/
|
|
66
|
+
function isNullComponentID(id) {
|
|
67
|
+
return nullComponentIdsRegistry[id];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var ReactEmptyComponent = {
|
|
71
|
+
deregisterNullComponentID: deregisterNullComponentID,
|
|
72
|
+
getEmptyComponent: getEmptyComponent,
|
|
73
|
+
injection: ReactEmptyComponentInjection,
|
|
74
|
+
isNullComponentID: isNullComponentID,
|
|
75
|
+
registerNullComponentID: registerNullComponentID
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
module.exports = ReactEmptyComponent;
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"use strict";
|
|
20
20
|
|
|
21
21
|
var EventPluginHub = require("./EventPluginHub");
|
|
22
|
-
var ReactUpdates = require("./ReactUpdates");
|
|
23
22
|
|
|
24
23
|
function runEventQueueInBatch(events) {
|
|
25
24
|
EventPluginHub.enqueueEvents(events);
|
|
@@ -49,8 +48,7 @@ var ReactEventEmitterMixin = {
|
|
|
49
48
|
nativeEvent
|
|
50
49
|
);
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
ReactUpdates.batchedUpdates(runEventQueueInBatch, events);
|
|
51
|
+
runEventQueueInBatch(events);
|
|
54
52
|
}
|
|
55
53
|
};
|
|
56
54
|
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013-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 ReactEventListener
|
|
17
|
+
* @typechecks static-only
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
"use strict";
|
|
21
|
+
|
|
22
|
+
var EventListener = require("./EventListener");
|
|
23
|
+
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
24
|
+
var PooledClass = require("./PooledClass");
|
|
25
|
+
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
26
|
+
var ReactMount = require("./ReactMount");
|
|
27
|
+
var ReactUpdates = require("./ReactUpdates");
|
|
28
|
+
|
|
29
|
+
var getEventTarget = require("./getEventTarget");
|
|
30
|
+
var getUnboundedScrollPosition = require("./getUnboundedScrollPosition");
|
|
31
|
+
var mixInto = require("./mixInto");
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Finds the parent React component of `node`.
|
|
35
|
+
*
|
|
36
|
+
* @param {*} node
|
|
37
|
+
* @return {?DOMEventTarget} Parent container, or `null` if the specified node
|
|
38
|
+
* is not nested.
|
|
39
|
+
*/
|
|
40
|
+
function findParent(node) {
|
|
41
|
+
// TODO: It may be a good idea to cache this to prevent unnecessary DOM
|
|
42
|
+
// traversal, but caching is difficult to do correctly without using a
|
|
43
|
+
// mutation observer to listen for all DOM changes.
|
|
44
|
+
var nodeID = ReactMount.getID(node);
|
|
45
|
+
var rootID = ReactInstanceHandles.getReactRootIDFromNodeID(nodeID);
|
|
46
|
+
var container = ReactMount.findReactContainerForID(rootID);
|
|
47
|
+
var parent = ReactMount.getFirstReactDOM(container);
|
|
48
|
+
return parent;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Used to store ancestor hierarchy in top level callback
|
|
52
|
+
function TopLevelCallbackBookKeeping(topLevelType, nativeEvent) {
|
|
53
|
+
this.topLevelType = topLevelType;
|
|
54
|
+
this.nativeEvent = nativeEvent;
|
|
55
|
+
this.ancestors = [];
|
|
56
|
+
}
|
|
57
|
+
mixInto(TopLevelCallbackBookKeeping, {
|
|
58
|
+
destructor: function() {
|
|
59
|
+
this.topLevelType = null;
|
|
60
|
+
this.nativeEvent = null;
|
|
61
|
+
this.ancestors.length = 0;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
PooledClass.addPoolingTo(
|
|
65
|
+
TopLevelCallbackBookKeeping,
|
|
66
|
+
PooledClass.twoArgumentPooler
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
function handleTopLevelImpl(bookKeeping) {
|
|
70
|
+
var topLevelTarget = ReactMount.getFirstReactDOM(
|
|
71
|
+
getEventTarget(bookKeeping.nativeEvent)
|
|
72
|
+
) || window;
|
|
73
|
+
|
|
74
|
+
// Loop through the hierarchy, in case there's any nested components.
|
|
75
|
+
// It's important that we build the array of ancestors before calling any
|
|
76
|
+
// event handlers, because event handlers can modify the DOM, leading to
|
|
77
|
+
// inconsistencies with ReactMount's node cache. See #1105.
|
|
78
|
+
var ancestor = topLevelTarget;
|
|
79
|
+
while (ancestor) {
|
|
80
|
+
bookKeeping.ancestors.push(ancestor);
|
|
81
|
+
ancestor = findParent(ancestor);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for (var i = 0, l = bookKeeping.ancestors.length; i < l; i++) {
|
|
85
|
+
topLevelTarget = bookKeeping.ancestors[i];
|
|
86
|
+
var topLevelTargetID = ReactMount.getID(topLevelTarget) || '';
|
|
87
|
+
ReactEventListener._handleTopLevel(
|
|
88
|
+
bookKeeping.topLevelType,
|
|
89
|
+
topLevelTarget,
|
|
90
|
+
topLevelTargetID,
|
|
91
|
+
bookKeeping.nativeEvent
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function scrollValueMonitor(cb) {
|
|
97
|
+
var scrollPosition = getUnboundedScrollPosition(window);
|
|
98
|
+
cb(scrollPosition);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
var ReactEventListener = {
|
|
102
|
+
_enabled: true,
|
|
103
|
+
_handleTopLevel: null,
|
|
104
|
+
|
|
105
|
+
WINDOW_HANDLE: ExecutionEnvironment.canUseDOM ? window : null,
|
|
106
|
+
|
|
107
|
+
setHandleTopLevel: function(handleTopLevel) {
|
|
108
|
+
ReactEventListener._handleTopLevel = handleTopLevel;
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
setEnabled: function(enabled) {
|
|
112
|
+
ReactEventListener._enabled = !!enabled;
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
isEnabled: function() {
|
|
116
|
+
return ReactEventListener._enabled;
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Traps top-level events by using event bubbling.
|
|
122
|
+
*
|
|
123
|
+
* @param {string} topLevelType Record from `EventConstants`.
|
|
124
|
+
* @param {string} handlerBaseName Event name (e.g. "click").
|
|
125
|
+
* @param {object} handle Element on which to attach listener.
|
|
126
|
+
* @return {object} An object with a remove function which will forcefully
|
|
127
|
+
* remove the listener.
|
|
128
|
+
* @internal
|
|
129
|
+
*/
|
|
130
|
+
trapBubbledEvent: function(topLevelType, handlerBaseName, handle) {
|
|
131
|
+
var element = handle;
|
|
132
|
+
if (!element) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
return EventListener.listen(
|
|
136
|
+
element,
|
|
137
|
+
handlerBaseName,
|
|
138
|
+
ReactEventListener.dispatchEvent.bind(null, topLevelType)
|
|
139
|
+
);
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Traps a top-level event by using event capturing.
|
|
144
|
+
*
|
|
145
|
+
* @param {string} topLevelType Record from `EventConstants`.
|
|
146
|
+
* @param {string} handlerBaseName Event name (e.g. "click").
|
|
147
|
+
* @param {object} handle Element on which to attach listener.
|
|
148
|
+
* @return {object} An object with a remove function which will forcefully
|
|
149
|
+
* remove the listener.
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
trapCapturedEvent: function(topLevelType, handlerBaseName, handle) {
|
|
153
|
+
var element = handle;
|
|
154
|
+
if (!element) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
return EventListener.capture(
|
|
158
|
+
element,
|
|
159
|
+
handlerBaseName,
|
|
160
|
+
ReactEventListener.dispatchEvent.bind(null, topLevelType)
|
|
161
|
+
);
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
monitorScrollValue: function(refresh) {
|
|
165
|
+
var callback = scrollValueMonitor.bind(null, refresh);
|
|
166
|
+
EventListener.listen(window, 'scroll', callback);
|
|
167
|
+
EventListener.listen(window, 'resize', callback);
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
dispatchEvent: function(topLevelType, nativeEvent) {
|
|
171
|
+
if (!ReactEventListener._enabled) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
var bookKeeping = TopLevelCallbackBookKeeping.getPooled(
|
|
176
|
+
topLevelType,
|
|
177
|
+
nativeEvent
|
|
178
|
+
);
|
|
179
|
+
try {
|
|
180
|
+
// Event queue being processed in the same cycle allows
|
|
181
|
+
// `preventDefault`.
|
|
182
|
+
ReactUpdates.batchedUpdates(handleTopLevelImpl, bookKeeping);
|
|
183
|
+
} finally {
|
|
184
|
+
TopLevelCallbackBookKeeping.release(bookKeeping);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
module.exports = ReactEventListener;
|
package/lib/ReactInjection.js
CHANGED
|
@@ -20,17 +20,23 @@
|
|
|
20
20
|
|
|
21
21
|
var DOMProperty = require("./DOMProperty");
|
|
22
22
|
var EventPluginHub = require("./EventPluginHub");
|
|
23
|
+
var ReactComponent = require("./ReactComponent");
|
|
24
|
+
var ReactCompositeComponent = require("./ReactCompositeComponent");
|
|
23
25
|
var ReactDOM = require("./ReactDOM");
|
|
24
|
-
var
|
|
26
|
+
var ReactEmptyComponent = require("./ReactEmptyComponent");
|
|
27
|
+
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
25
28
|
var ReactPerf = require("./ReactPerf");
|
|
26
29
|
var ReactRootIndex = require("./ReactRootIndex");
|
|
27
30
|
var ReactUpdates = require("./ReactUpdates");
|
|
28
31
|
|
|
29
32
|
var ReactInjection = {
|
|
33
|
+
Component: ReactComponent.injection,
|
|
34
|
+
CompositeComponent: ReactCompositeComponent.injection,
|
|
30
35
|
DOMProperty: DOMProperty.injection,
|
|
36
|
+
EmptyComponent: ReactEmptyComponent.injection,
|
|
31
37
|
EventPluginHub: EventPluginHub.injection,
|
|
32
38
|
DOM: ReactDOM.injection,
|
|
33
|
-
EventEmitter:
|
|
39
|
+
EventEmitter: ReactBrowserEventEmitter.injection,
|
|
34
40
|
Perf: ReactPerf.injection,
|
|
35
41
|
RootIndex: ReactRootIndex.injection,
|
|
36
42
|
Updates: ReactUpdates.injection
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
var ReactDOMSelection = require("./ReactDOMSelection");
|
|
22
22
|
|
|
23
23
|
var containsNode = require("./containsNode");
|
|
24
|
+
var focusNode = require("./focusNode");
|
|
24
25
|
var getActiveElement = require("./getActiveElement");
|
|
25
26
|
|
|
26
27
|
function isInDocument(node) {
|
|
@@ -71,7 +72,7 @@ var ReactInputSelection = {
|
|
|
71
72
|
priorSelectionRange
|
|
72
73
|
);
|
|
73
74
|
}
|
|
74
|
-
priorFocusedElem
|
|
75
|
+
focusNode(priorFocusedElem);
|
|
75
76
|
}
|
|
76
77
|
},
|
|
77
78
|
|
package/lib/ReactLink.js
CHANGED
|
@@ -42,6 +42,8 @@
|
|
|
42
42
|
* consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin.
|
|
43
43
|
*/
|
|
44
44
|
|
|
45
|
+
var React = require("./React");
|
|
46
|
+
|
|
45
47
|
/**
|
|
46
48
|
* @param {*} value current value of the link
|
|
47
49
|
* @param {function} requestChange callback to request a change
|
|
@@ -51,4 +53,26 @@ function ReactLink(value, requestChange) {
|
|
|
51
53
|
this.requestChange = requestChange;
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Creates a PropType that enforces the ReactLink API and optionally checks the
|
|
58
|
+
* type of the value being passed inside the link. Example:
|
|
59
|
+
*
|
|
60
|
+
* MyComponent.propTypes = {
|
|
61
|
+
* tabIndexLink: ReactLink.PropTypes.link(React.PropTypes.number)
|
|
62
|
+
* }
|
|
63
|
+
*/
|
|
64
|
+
function createLinkTypeChecker(linkType) {
|
|
65
|
+
var shapes = {
|
|
66
|
+
value: typeof linkType === 'undefined' ?
|
|
67
|
+
React.PropTypes.any.isRequired :
|
|
68
|
+
linkType.isRequired,
|
|
69
|
+
requestChange: React.PropTypes.func.isRequired
|
|
70
|
+
};
|
|
71
|
+
return React.PropTypes.shape(shapes);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
ReactLink.PropTypes = {
|
|
75
|
+
link: createLinkTypeChecker
|
|
76
|
+
};
|
|
77
|
+
|
|
54
78
|
module.exports = ReactLink;
|
package/lib/ReactMount.js
CHANGED
|
@@ -19,14 +19,18 @@
|
|
|
19
19
|
"use strict";
|
|
20
20
|
|
|
21
21
|
var DOMProperty = require("./DOMProperty");
|
|
22
|
-
var
|
|
22
|
+
var ReactBrowserEventEmitter = require("./ReactBrowserEventEmitter");
|
|
23
|
+
var ReactCurrentOwner = require("./ReactCurrentOwner");
|
|
24
|
+
var ReactDescriptor = require("./ReactDescriptor");
|
|
23
25
|
var ReactInstanceHandles = require("./ReactInstanceHandles");
|
|
24
26
|
var ReactPerf = require("./ReactPerf");
|
|
25
27
|
|
|
26
28
|
var containsNode = require("./containsNode");
|
|
27
29
|
var getReactRootElementInContainer = require("./getReactRootElementInContainer");
|
|
30
|
+
var instantiateReactComponent = require("./instantiateReactComponent");
|
|
28
31
|
var invariant = require("./invariant");
|
|
29
32
|
var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
|
|
33
|
+
var warning = require("./warning");
|
|
30
34
|
|
|
31
35
|
var SEPARATOR = ReactInstanceHandles.SEPARATOR;
|
|
32
36
|
|
|
@@ -209,15 +213,6 @@ function findDeepestCachedAncestor(targetID) {
|
|
|
209
213
|
* Inside of `container`, the first element rendered is the "reactRoot".
|
|
210
214
|
*/
|
|
211
215
|
var ReactMount = {
|
|
212
|
-
/** Time spent generating markup. */
|
|
213
|
-
totalInstantiationTime: 0,
|
|
214
|
-
|
|
215
|
-
/** Time spent inserting markup into the DOM. */
|
|
216
|
-
totalInjectionTime: 0,
|
|
217
|
-
|
|
218
|
-
/** Whether support for touch events should be initialized. */
|
|
219
|
-
useTouchEvents: false,
|
|
220
|
-
|
|
221
216
|
/** Exposed for debugging purposes **/
|
|
222
217
|
_instancesByReactRootID: instancesByReactRootID,
|
|
223
218
|
|
|
@@ -278,7 +273,7 @@ var ReactMount = {
|
|
|
278
273
|
container.nodeType === DOC_NODE_TYPE
|
|
279
274
|
)));
|
|
280
275
|
|
|
281
|
-
|
|
276
|
+
ReactBrowserEventEmitter.ensureScrollValueMonitoring();
|
|
282
277
|
|
|
283
278
|
var reactRootID = ReactMount.registerContainer(container);
|
|
284
279
|
instancesByReactRootID[reactRootID] = nextComponent;
|
|
@@ -299,8 +294,23 @@ var ReactMount = {
|
|
|
299
294
|
nextComponent,
|
|
300
295
|
container,
|
|
301
296
|
shouldReuseMarkup) {
|
|
302
|
-
|
|
303
|
-
|
|
297
|
+
// Various parts of our code (such as ReactCompositeComponent's
|
|
298
|
+
// _renderValidatedComponent) assume that calls to render aren't nested;
|
|
299
|
+
// verify that that's the case.
|
|
300
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
301
|
+
ReactCurrentOwner.current == null,
|
|
302
|
+
'_renderNewRootComponent(): Render methods should be a pure function ' +
|
|
303
|
+
'of props and state; triggering nested component updates from ' +
|
|
304
|
+
'render is not allowed. If necessary, trigger nested updates in ' +
|
|
305
|
+
'componentDidUpdate.'
|
|
306
|
+
) : null);
|
|
307
|
+
|
|
308
|
+
var componentInstance = instantiateReactComponent(nextComponent);
|
|
309
|
+
var reactRootID = ReactMount._registerComponent(
|
|
310
|
+
componentInstance,
|
|
311
|
+
container
|
|
312
|
+
);
|
|
313
|
+
componentInstance.mountComponentIntoNode(
|
|
304
314
|
reactRootID,
|
|
305
315
|
container,
|
|
306
316
|
shouldReuseMarkup
|
|
@@ -312,7 +322,7 @@ var ReactMount = {
|
|
|
312
322
|
getReactRootElementInContainer(container);
|
|
313
323
|
}
|
|
314
324
|
|
|
315
|
-
return
|
|
325
|
+
return componentInstance;
|
|
316
326
|
}
|
|
317
327
|
),
|
|
318
328
|
|
|
@@ -323,19 +333,35 @@ var ReactMount = {
|
|
|
323
333
|
* perform an update on it and only mutate the DOM as necessary to reflect the
|
|
324
334
|
* latest React component.
|
|
325
335
|
*
|
|
326
|
-
* @param {
|
|
336
|
+
* @param {ReactDescriptor} nextDescriptor Component descriptor to render.
|
|
327
337
|
* @param {DOMElement} container DOM element to render into.
|
|
328
338
|
* @param {?function} callback function triggered on completion
|
|
329
339
|
* @return {ReactComponent} Component instance rendered in `container`.
|
|
330
340
|
*/
|
|
331
|
-
renderComponent: function(
|
|
341
|
+
renderComponent: function(nextDescriptor, container, callback) {
|
|
342
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
343
|
+
ReactDescriptor.isValidDescriptor(nextDescriptor),
|
|
344
|
+
'renderComponent(): Invalid component descriptor.%s',
|
|
345
|
+
(
|
|
346
|
+
ReactDescriptor.isValidFactory(nextDescriptor) ?
|
|
347
|
+
' Instead of passing a component class, make sure to instantiate ' +
|
|
348
|
+
'it first by calling it with props.' :
|
|
349
|
+
// Check if it quacks like a descriptor
|
|
350
|
+
typeof nextDescriptor.props !== "undefined" ?
|
|
351
|
+
' This may be caused by unintentionally loading two independent ' +
|
|
352
|
+
'copies of React.' :
|
|
353
|
+
''
|
|
354
|
+
)
|
|
355
|
+
) : invariant(ReactDescriptor.isValidDescriptor(nextDescriptor)));
|
|
356
|
+
|
|
332
357
|
var prevComponent = instancesByReactRootID[getReactRootID(container)];
|
|
333
358
|
|
|
334
359
|
if (prevComponent) {
|
|
335
|
-
|
|
360
|
+
var prevDescriptor = prevComponent._descriptor;
|
|
361
|
+
if (shouldUpdateReactComponent(prevDescriptor, nextDescriptor)) {
|
|
336
362
|
return ReactMount._updateRootComponent(
|
|
337
363
|
prevComponent,
|
|
338
|
-
|
|
364
|
+
nextDescriptor,
|
|
339
365
|
container,
|
|
340
366
|
callback
|
|
341
367
|
);
|
|
@@ -351,7 +377,7 @@ var ReactMount = {
|
|
|
351
377
|
var shouldReuseMarkup = containerHasReactMarkup && !prevComponent;
|
|
352
378
|
|
|
353
379
|
var component = ReactMount._renderNewRootComponent(
|
|
354
|
-
|
|
380
|
+
nextDescriptor,
|
|
355
381
|
container,
|
|
356
382
|
shouldReuseMarkup
|
|
357
383
|
);
|
|
@@ -421,6 +447,18 @@ var ReactMount = {
|
|
|
421
447
|
* `container`
|
|
422
448
|
*/
|
|
423
449
|
unmountComponentAtNode: function(container) {
|
|
450
|
+
// Various parts of our code (such as ReactCompositeComponent's
|
|
451
|
+
// _renderValidatedComponent) assume that calls to render aren't nested;
|
|
452
|
+
// verify that that's the case. (Strictly speaking, unmounting won't cause a
|
|
453
|
+
// render but we still don't expect to be in a render call here.)
|
|
454
|
+
("production" !== process.env.NODE_ENV ? warning(
|
|
455
|
+
ReactCurrentOwner.current == null,
|
|
456
|
+
'unmountComponentAtNode(): Render methods should be a pure function of ' +
|
|
457
|
+
'props and state; triggering nested component updates from render is ' +
|
|
458
|
+
'not allowed. If necessary, trigger nested updates in ' +
|
|
459
|
+
'componentDidUpdate.'
|
|
460
|
+
) : null);
|
|
461
|
+
|
|
424
462
|
var reactRootID = getReactRootID(container);
|
|
425
463
|
var component = instancesByReactRootID[reactRootID];
|
|
426
464
|
if (!component) {
|
|
@@ -615,8 +653,10 @@ var ReactMount = {
|
|
|
615
653
|
("production" !== process.env.NODE_ENV ? invariant(
|
|
616
654
|
false,
|
|
617
655
|
'findComponentRoot(..., %s): Unable to find element. This probably ' +
|
|
618
|
-
'means the DOM was unexpectedly mutated (e.g., by the browser)
|
|
619
|
-
'
|
|
656
|
+
'means the DOM was unexpectedly mutated (e.g., by the browser), ' +
|
|
657
|
+
'usually due to forgetting a <tbody> when using tables, nesting <p> ' +
|
|
658
|
+
'or <a> tags, or using non-SVG elements in an <svg> parent. Try ' +
|
|
659
|
+
'inspecting the child nodes of the element with React ID `%s`.',
|
|
620
660
|
targetID,
|
|
621
661
|
ReactMount.getID(ancestorNode)
|
|
622
662
|
) : invariant(false));
|