react 0.8.0 → 0.10.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 +0 -8
- package/addons.js +0 -3
- package/lib/AutoFocusMixin.js +32 -0
- package/lib/CSSCore.js +23 -22
- package/lib/CSSProperty.js +32 -1
- package/lib/CSSPropertyOperations.js +1 -1
- package/lib/ChangeEventPlugin.js +27 -5
- package/lib/ClientReactRootIndex.js +30 -0
- package/lib/CompositionEventPlugin.js +58 -10
- package/lib/DOMChildrenOperations.js +39 -3
- package/lib/DOMProperty.js +9 -5
- package/lib/DOMPropertyOperations.js +21 -8
- package/lib/Danger.js +9 -8
- package/lib/DefaultDOMPropertyConfig.js +23 -14
- package/lib/DefaultEventPluginOrder.js +1 -1
- package/lib/EnterLeaveEventPlugin.js +38 -5
- package/lib/EventConstants.js +4 -1
- package/lib/EventListener.js +42 -34
- package/lib/EventPluginHub.js +118 -13
- package/lib/EventPluginRegistry.js +62 -18
- package/lib/EventPluginUtils.js +33 -4
- package/lib/EventPropagators.js +7 -43
- package/lib/ExecutionEnvironment.js +4 -1
- package/lib/LinkedStateMixin.js +1 -1
- package/lib/LinkedValueUtils.js +160 -0
- package/lib/MobileSafariClickEventPlugin.js +1 -1
- package/lib/PooledClass.js +7 -1
- package/lib/React.js +30 -4
- package/lib/ReactBrowserComponentMixin.js +42 -0
- package/lib/ReactCSSTransitionGroup.js +65 -0
- package/lib/{ReactTransitionableChild.js → ReactCSSTransitionGroupChild.js} +22 -36
- package/lib/ReactChildren.js +4 -4
- package/lib/ReactComponent.js +163 -83
- package/lib/ReactComponentBrowserEnvironment.js +55 -71
- package/lib/ReactCompositeComponent.js +686 -119
- package/lib/ReactContext.js +67 -0
- package/lib/ReactCurrentOwner.js +1 -1
- package/lib/ReactDOM.js +19 -6
- package/lib/ReactDOMButton.js +6 -1
- package/lib/ReactDOMComponent.js +66 -24
- package/lib/ReactDOMForm.js +13 -3
- package/lib/ReactDOMIDOperations.js +106 -61
- package/lib/ReactDOMImg.js +61 -0
- package/lib/ReactDOMInput.js +28 -15
- package/lib/ReactDOMOption.js +13 -8
- package/lib/ReactDOMSelect.js +38 -18
- package/lib/ReactDOMSelection.js +1 -1
- package/lib/ReactDOMTextarea.js +19 -11
- package/lib/ReactDefaultBatchingStrategy.js +1 -1
- package/lib/ReactDefaultInjection.js +60 -26
- package/lib/ReactDefaultPerf.js +208 -371
- package/lib/ReactDefaultPerfAnalysis.js +199 -0
- package/lib/ReactErrorUtils.js +6 -15
- package/lib/ReactEventEmitter.js +144 -146
- package/lib/ReactEventEmitterMixin.js +1 -33
- package/lib/ReactEventTopLevelCallback.js +75 -15
- package/lib/ReactInjection.js +43 -0
- package/lib/ReactInputSelection.js +3 -2
- package/lib/ReactInstanceHandles.js +36 -20
- package/lib/ReactLink.js +2 -2
- package/lib/ReactMarkupChecksum.js +1 -1
- package/lib/ReactMount.js +136 -104
- package/lib/ReactMountReady.js +2 -2
- package/lib/ReactMultiChild.js +40 -49
- package/lib/ReactMultiChildUpdateTypes.js +3 -1
- package/lib/ReactOwner.js +17 -4
- package/lib/ReactPerf.js +6 -9
- package/lib/ReactPropTransferer.js +41 -22
- package/lib/ReactPropTypeLocationNames.js +31 -0
- package/lib/{ReactComponentEnvironment.js → ReactPropTypeLocations.js} +11 -6
- package/lib/ReactPropTypes.js +249 -48
- package/lib/ReactPutListenerQueue.js +61 -0
- package/lib/ReactReconcileTransaction.js +28 -7
- package/lib/ReactRootIndex.js +36 -0
- package/lib/ReactServerRendering.js +46 -19
- package/lib/ReactServerRenderingTransaction.js +116 -0
- package/lib/ReactStateSetters.js +1 -1
- package/lib/ReactTestUtils.js +394 -0
- package/lib/ReactTextComponent.js +33 -6
- package/lib/{ReactTransitionKeySet.js → ReactTransitionChildMapping.js} +43 -48
- package/lib/ReactTransitionEvents.js +1 -1
- package/lib/ReactTransitionGroup.js +133 -58
- package/lib/ReactUpdates.js +15 -12
- package/lib/ReactWithAddons.js +15 -3
- package/lib/SelectEventPlugin.js +23 -40
- package/lib/ServerReactRootIndex.js +36 -0
- package/lib/SimpleEventPlugin.js +55 -7
- package/lib/SyntheticClipboardEvent.js +8 -2
- package/lib/SyntheticCompositionEvent.js +1 -1
- package/lib/SyntheticDragEvent.js +44 -0
- package/lib/SyntheticEvent.js +3 -2
- package/lib/SyntheticFocusEvent.js +1 -1
- package/lib/SyntheticKeyboardEvent.js +5 -3
- package/lib/SyntheticMouseEvent.js +1 -1
- package/lib/SyntheticTouchEvent.js +1 -1
- package/lib/SyntheticUIEvent.js +1 -1
- package/lib/SyntheticWheelEvent.js +11 -8
- package/lib/Transaction.js +62 -37
- package/lib/ViewportMetrics.js +1 -1
- package/lib/accumulate.js +1 -1
- package/lib/adler32.js +1 -1
- package/lib/cloneWithProps.js +59 -0
- package/lib/containsNode.js +1 -1
- package/lib/copyProperties.js +1 -1
- package/lib/createArrayFrom.js +11 -14
- package/lib/createFullPageComponent.js +63 -0
- package/lib/createNodesFromMarkup.js +1 -1
- package/lib/createObjectFrom.js +1 -1
- package/lib/cx.js +3 -3
- package/lib/dangerousStyleValue.js +1 -1
- package/lib/emptyFunction.js +1 -1
- package/lib/emptyObject.js +27 -0
- package/lib/escapeTextForBrowser.js +1 -1
- package/lib/flattenChildren.js +6 -3
- package/lib/focusNode.js +33 -0
- package/lib/forEachAccumulated.js +1 -1
- package/lib/getActiveElement.js +5 -4
- package/lib/getEventKey.js +85 -0
- package/lib/getEventTarget.js +1 -1
- package/lib/getMarkupWrap.js +11 -1
- package/lib/getNodeForCharacterOffset.js +1 -1
- package/lib/getReactRootElementInContainer.js +1 -1
- package/lib/getTextContentAccessor.js +6 -4
- package/lib/getUnboundedScrollPosition.js +3 -3
- package/lib/hyphenate.js +1 -1
- package/lib/instantiateReactComponent.js +70 -0
- package/lib/invariant.js +20 -12
- package/lib/isEventSupported.js +8 -12
- package/lib/isNode.js +2 -2
- package/lib/isTextInputElement.js +1 -1
- package/lib/isTextNode.js +1 -1
- package/lib/joinClasses.js +1 -1
- package/lib/keyMirror.js +1 -1
- package/lib/keyOf.js +1 -1
- package/lib/memoizeStringOnly.js +1 -1
- package/lib/merge.js +1 -1
- package/lib/mergeHelpers.js +6 -7
- package/lib/mergeInto.js +1 -1
- package/lib/mixInto.js +1 -1
- package/lib/monitorCodeUse.js +37 -0
- package/lib/objMap.js +1 -1
- package/lib/objMapKeyVal.js +1 -1
- package/lib/onlyChild.js +43 -0
- package/lib/performanceNow.js +1 -1
- package/lib/shallowEqual.js +1 -1
- package/lib/shouldUpdateReactComponent.js +61 -0
- package/lib/toArray.js +75 -0
- package/lib/traverseAllChildren.js +72 -9
- package/lib/update.js +159 -0
- package/lib/warning.js +48 -0
- package/package.json +3 -3
- package/react.js +0 -3
- package/ReactJSErrors.js +0 -40
- package/lib/$.js +0 -46
- package/lib/CallbackRegistry.js +0 -91
- package/lib/LinkedValueMixin.js +0 -68
- package/lib/ex.js +0 -49
- package/lib/filterAttributes.js +0 -45
- package/lib/ge.js +0 -76
- package/lib/mutateHTMLNodeWithMarkup.js +0 -100
|
@@ -0,0 +1,199 @@
|
|
|
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 ReactDefaultPerfAnalysis
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
var merge = require("./merge");
|
|
20
|
+
|
|
21
|
+
// Don't try to save users less than 1.2ms (a number I made up)
|
|
22
|
+
var DONT_CARE_THRESHOLD = 1.2;
|
|
23
|
+
var DOM_OPERATION_TYPES = {
|
|
24
|
+
'mountImageIntoNode': 'set innerHTML',
|
|
25
|
+
INSERT_MARKUP: 'set innerHTML',
|
|
26
|
+
MOVE_EXISTING: 'move',
|
|
27
|
+
REMOVE_NODE: 'remove',
|
|
28
|
+
TEXT_CONTENT: 'set textContent',
|
|
29
|
+
'updatePropertyByID': 'update attribute',
|
|
30
|
+
'deletePropertyByID': 'delete attribute',
|
|
31
|
+
'updateStylesByID': 'update styles',
|
|
32
|
+
'updateInnerHTMLByID': 'set innerHTML',
|
|
33
|
+
'dangerouslyReplaceNodeWithMarkupByID': 'replace'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function getTotalTime(measurements) {
|
|
37
|
+
// TODO: return number of DOM ops? could be misleading.
|
|
38
|
+
// TODO: measure dropped frames after reconcile?
|
|
39
|
+
// TODO: log total time of each reconcile and the top-level component
|
|
40
|
+
// class that triggered it.
|
|
41
|
+
var totalTime = 0;
|
|
42
|
+
for (var i = 0; i < measurements.length; i++) {
|
|
43
|
+
var measurement = measurements[i];
|
|
44
|
+
totalTime += measurement.totalTime;
|
|
45
|
+
}
|
|
46
|
+
return totalTime;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getDOMSummary(measurements) {
|
|
50
|
+
var items = [];
|
|
51
|
+
for (var i = 0; i < measurements.length; i++) {
|
|
52
|
+
var measurement = measurements[i];
|
|
53
|
+
var id;
|
|
54
|
+
|
|
55
|
+
for (id in measurement.writes) {
|
|
56
|
+
measurement.writes[id].forEach(function(write) {
|
|
57
|
+
items.push({
|
|
58
|
+
id: id,
|
|
59
|
+
type: DOM_OPERATION_TYPES[write.type] || write.type,
|
|
60
|
+
args: write.args
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return items;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getExclusiveSummary(measurements) {
|
|
69
|
+
var candidates = {};
|
|
70
|
+
var displayName;
|
|
71
|
+
|
|
72
|
+
for (var i = 0; i < measurements.length; i++) {
|
|
73
|
+
var measurement = measurements[i];
|
|
74
|
+
var allIDs = merge(measurement.exclusive, measurement.inclusive);
|
|
75
|
+
|
|
76
|
+
for (var id in allIDs) {
|
|
77
|
+
displayName = measurement.displayNames[id].current;
|
|
78
|
+
|
|
79
|
+
candidates[displayName] = candidates[displayName] || {
|
|
80
|
+
componentName: displayName,
|
|
81
|
+
inclusive: 0,
|
|
82
|
+
exclusive: 0,
|
|
83
|
+
count: 0
|
|
84
|
+
};
|
|
85
|
+
if (measurement.exclusive[id]) {
|
|
86
|
+
candidates[displayName].exclusive += measurement.exclusive[id];
|
|
87
|
+
}
|
|
88
|
+
if (measurement.inclusive[id]) {
|
|
89
|
+
candidates[displayName].inclusive += measurement.inclusive[id];
|
|
90
|
+
}
|
|
91
|
+
if (measurement.counts[id]) {
|
|
92
|
+
candidates[displayName].count += measurement.counts[id];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Now make a sorted array with the results.
|
|
98
|
+
var arr = [];
|
|
99
|
+
for (displayName in candidates) {
|
|
100
|
+
if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) {
|
|
101
|
+
arr.push(candidates[displayName]);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
arr.sort(function(a, b) {
|
|
106
|
+
return b.exclusive - a.exclusive;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
return arr;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function getInclusiveSummary(measurements, onlyClean) {
|
|
113
|
+
var candidates = {};
|
|
114
|
+
var inclusiveKey;
|
|
115
|
+
|
|
116
|
+
for (var i = 0; i < measurements.length; i++) {
|
|
117
|
+
var measurement = measurements[i];
|
|
118
|
+
var allIDs = merge(measurement.exclusive, measurement.inclusive);
|
|
119
|
+
var cleanComponents;
|
|
120
|
+
|
|
121
|
+
if (onlyClean) {
|
|
122
|
+
cleanComponents = getUnchangedComponents(measurement);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
for (var id in allIDs) {
|
|
126
|
+
if (onlyClean && !cleanComponents[id]) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
var displayName = measurement.displayNames[id];
|
|
131
|
+
|
|
132
|
+
// Inclusive time is not useful for many components without knowing where
|
|
133
|
+
// they are instantiated. So we aggregate inclusive time with both the
|
|
134
|
+
// owner and current displayName as the key.
|
|
135
|
+
inclusiveKey = displayName.owner + ' > ' + displayName.current;
|
|
136
|
+
|
|
137
|
+
candidates[inclusiveKey] = candidates[inclusiveKey] || {
|
|
138
|
+
componentName: inclusiveKey,
|
|
139
|
+
time: 0,
|
|
140
|
+
count: 0
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
if (measurement.inclusive[id]) {
|
|
144
|
+
candidates[inclusiveKey].time += measurement.inclusive[id];
|
|
145
|
+
}
|
|
146
|
+
if (measurement.counts[id]) {
|
|
147
|
+
candidates[inclusiveKey].count += measurement.counts[id];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Now make a sorted array with the results.
|
|
153
|
+
var arr = [];
|
|
154
|
+
for (inclusiveKey in candidates) {
|
|
155
|
+
if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) {
|
|
156
|
+
arr.push(candidates[inclusiveKey]);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
arr.sort(function(a, b) {
|
|
161
|
+
return b.time - a.time;
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
return arr;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function getUnchangedComponents(measurement) {
|
|
168
|
+
// For a given reconcile, look at which components did not actually
|
|
169
|
+
// render anything to the DOM and return a mapping of their ID to
|
|
170
|
+
// the amount of time it took to render the entire subtree.
|
|
171
|
+
var cleanComponents = {};
|
|
172
|
+
var dirtyLeafIDs = Object.keys(measurement.writes);
|
|
173
|
+
var allIDs = merge(measurement.exclusive, measurement.inclusive);
|
|
174
|
+
|
|
175
|
+
for (var id in allIDs) {
|
|
176
|
+
var isDirty = false;
|
|
177
|
+
// For each component that rendered, see if a component that triggerd
|
|
178
|
+
// a DOM op is in its subtree.
|
|
179
|
+
for (var i = 0; i < dirtyLeafIDs.length; i++) {
|
|
180
|
+
if (dirtyLeafIDs[i].indexOf(id) === 0) {
|
|
181
|
+
isDirty = true;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (!isDirty && measurement.counts[id] > 0) {
|
|
186
|
+
cleanComponents[id] = true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return cleanComponents;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
var ReactDefaultPerfAnalysis = {
|
|
193
|
+
getExclusiveSummary: getExclusiveSummary,
|
|
194
|
+
getInclusiveSummary: getInclusiveSummary,
|
|
195
|
+
getDOMSummary: getDOMSummary,
|
|
196
|
+
getTotalTime: getTotalTime
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
module.exports = ReactDefaultPerfAnalysis;
|
package/lib/ReactErrorUtils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2013 Facebook, Inc.
|
|
2
|
+
* Copyright 2013-2014 Facebook, Inc.
|
|
3
3
|
*
|
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
5
|
* you may not use this file except in compliance with the License.
|
|
@@ -17,29 +17,20 @@
|
|
|
17
17
|
* @typechecks
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
"use strict";
|
|
21
|
+
|
|
20
22
|
var ReactErrorUtils = {
|
|
21
23
|
/**
|
|
22
24
|
* Creates a guarded version of a function. This is supposed to make debugging
|
|
23
|
-
* of event handlers easier.
|
|
24
|
-
*
|
|
25
|
+
* of event handlers easier. To aid debugging with the browser's debugger,
|
|
26
|
+
* this currently simply returns the original function.
|
|
25
27
|
*
|
|
26
28
|
* @param {function} func Function to be executed
|
|
27
29
|
* @param {string} name The name of the guard
|
|
28
30
|
* @return {function}
|
|
29
31
|
*/
|
|
30
32
|
guard: function(func, name) {
|
|
31
|
-
|
|
32
|
-
return function guarded() {
|
|
33
|
-
try {
|
|
34
|
-
return func.apply(this, arguments);
|
|
35
|
-
} catch(ex) {
|
|
36
|
-
console.error(name + ': ' + ex.message);
|
|
37
|
-
throw ex;
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
} else {
|
|
41
|
-
return func;
|
|
42
|
-
}
|
|
33
|
+
return func;
|
|
43
34
|
}
|
|
44
35
|
};
|
|
45
36
|
|
package/lib/ReactEventEmitter.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright 2013 Facebook, Inc.
|
|
2
|
+
* Copyright 2013-2014 Facebook, Inc.
|
|
3
3
|
*
|
|
4
4
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
5
|
* you may not use this file except in compliance with the License.
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
var EventConstants = require("./EventConstants");
|
|
23
23
|
var EventListener = require("./EventListener");
|
|
24
24
|
var EventPluginHub = require("./EventPluginHub");
|
|
25
|
+
var EventPluginRegistry = require("./EventPluginRegistry");
|
|
25
26
|
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
26
27
|
var ReactEventEmitterMixin = require("./ReactEventEmitterMixin");
|
|
27
28
|
var ViewportMetrics = require("./ViewportMetrics");
|
|
@@ -60,21 +61,80 @@ var merge = require("./merge");
|
|
|
60
61
|
* | ReactEvent | . | | |TapEvent | |------------|
|
|
61
62
|
* | Emitter | . | |<---+|Plugin | |other plugin|
|
|
62
63
|
* | | . | | +-----------+ | utilities |
|
|
63
|
-
* |
|
|
64
|
-
* | | | .
|
|
65
|
-
* +-----|------+ .
|
|
66
|
-
* | .
|
|
67
|
-
* + .
|
|
68
|
-
* +-------------+ .
|
|
69
|
-
* | application | .
|
|
70
|
-
* |-------------| .
|
|
71
|
-
* | | .
|
|
72
|
-
* | | .
|
|
64
|
+
* | +-----------.--->| | +------------+
|
|
65
|
+
* | | | . +--------------+
|
|
66
|
+
* +-----|------+ . ^ +-----------+
|
|
67
|
+
* | . | |Enter/Leave|
|
|
68
|
+
* + . +-------+|Plugin |
|
|
69
|
+
* +-------------+ . +-----------+
|
|
70
|
+
* | application | .
|
|
71
|
+
* |-------------| .
|
|
72
|
+
* | | .
|
|
73
|
+
* | | .
|
|
73
74
|
* +-------------+ .
|
|
74
75
|
* .
|
|
75
76
|
* React Core . General Purpose Event Plugin System
|
|
76
77
|
*/
|
|
77
78
|
|
|
79
|
+
var alreadyListeningTo = {};
|
|
80
|
+
var isMonitoringScrollValue = false;
|
|
81
|
+
var reactTopListenersCounter = 0;
|
|
82
|
+
|
|
83
|
+
// For events like 'submit' which don't consistently bubble (which we trap at a
|
|
84
|
+
// lower node than `document`), binding at `document` would cause duplicate
|
|
85
|
+
// events so we don't include them here
|
|
86
|
+
var topEventMapping = {
|
|
87
|
+
topBlur: 'blur',
|
|
88
|
+
topChange: 'change',
|
|
89
|
+
topClick: 'click',
|
|
90
|
+
topCompositionEnd: 'compositionend',
|
|
91
|
+
topCompositionStart: 'compositionstart',
|
|
92
|
+
topCompositionUpdate: 'compositionupdate',
|
|
93
|
+
topContextMenu: 'contextmenu',
|
|
94
|
+
topCopy: 'copy',
|
|
95
|
+
topCut: 'cut',
|
|
96
|
+
topDoubleClick: 'dblclick',
|
|
97
|
+
topDrag: 'drag',
|
|
98
|
+
topDragEnd: 'dragend',
|
|
99
|
+
topDragEnter: 'dragenter',
|
|
100
|
+
topDragExit: 'dragexit',
|
|
101
|
+
topDragLeave: 'dragleave',
|
|
102
|
+
topDragOver: 'dragover',
|
|
103
|
+
topDragStart: 'dragstart',
|
|
104
|
+
topDrop: 'drop',
|
|
105
|
+
topFocus: 'focus',
|
|
106
|
+
topInput: 'input',
|
|
107
|
+
topKeyDown: 'keydown',
|
|
108
|
+
topKeyPress: 'keypress',
|
|
109
|
+
topKeyUp: 'keyup',
|
|
110
|
+
topMouseDown: 'mousedown',
|
|
111
|
+
topMouseMove: 'mousemove',
|
|
112
|
+
topMouseOut: 'mouseout',
|
|
113
|
+
topMouseOver: 'mouseover',
|
|
114
|
+
topMouseUp: 'mouseup',
|
|
115
|
+
topPaste: 'paste',
|
|
116
|
+
topScroll: 'scroll',
|
|
117
|
+
topSelectionChange: 'selectionchange',
|
|
118
|
+
topTouchCancel: 'touchcancel',
|
|
119
|
+
topTouchEnd: 'touchend',
|
|
120
|
+
topTouchMove: 'touchmove',
|
|
121
|
+
topTouchStart: 'touchstart',
|
|
122
|
+
topWheel: 'wheel'
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* To ensure no conflicts with other potential React instances on the page
|
|
127
|
+
*/
|
|
128
|
+
var topListenersIDKey = "_reactListenersID" + String(Math.random()).slice(2);
|
|
129
|
+
|
|
130
|
+
function getListeningForDocument(mountAt) {
|
|
131
|
+
if (mountAt[topListenersIDKey] == null) {
|
|
132
|
+
mountAt[topListenersIDKey] = reactTopListenersCounter++;
|
|
133
|
+
alreadyListeningTo[mountAt[topListenersIDKey]] = {};
|
|
134
|
+
}
|
|
135
|
+
return alreadyListeningTo[mountAt[topListenersIDKey]];
|
|
136
|
+
}
|
|
137
|
+
|
|
78
138
|
/**
|
|
79
139
|
* Traps top-level events by using event bubbling.
|
|
80
140
|
*
|
|
@@ -111,21 +171,6 @@ function trapCapturedEvent(topLevelType, handlerBaseName, element) {
|
|
|
111
171
|
);
|
|
112
172
|
}
|
|
113
173
|
|
|
114
|
-
/**
|
|
115
|
-
* Listens to window scroll and resize events. We cache scroll values so that
|
|
116
|
-
* application code can access them without triggering reflows.
|
|
117
|
-
*
|
|
118
|
-
* NOTE: Scroll events do not bubble.
|
|
119
|
-
*
|
|
120
|
-
* @private
|
|
121
|
-
* @see http://www.quirksmode.org/dom/events/scroll.html
|
|
122
|
-
*/
|
|
123
|
-
function registerScrollValueMonitoring() {
|
|
124
|
-
var refresh = ViewportMetrics.refreshScrollValues;
|
|
125
|
-
EventListener.listen(window, 'scroll', refresh);
|
|
126
|
-
EventListener.listen(window, 'resize', refresh);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
174
|
/**
|
|
130
175
|
* `ReactEventEmitter` is used to attach top-level event listeners. For example:
|
|
131
176
|
*
|
|
@@ -143,37 +188,13 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
|
|
|
143
188
|
*/
|
|
144
189
|
TopLevelCallbackCreator: null,
|
|
145
190
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
*
|
|
154
|
-
* @param {boolean} touchNotMouse Listen to touch events instead of mouse.
|
|
155
|
-
* @param {DOMDocument} contentDocument DOM document to listen on
|
|
156
|
-
*/
|
|
157
|
-
ensureListening: function(touchNotMouse, contentDocument) {
|
|
158
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
159
|
-
ExecutionEnvironment.canUseDOM,
|
|
160
|
-
'ensureListening(...): Cannot toggle event listening in a Worker ' +
|
|
161
|
-
'thread. This is likely a bug in the framework. Please report ' +
|
|
162
|
-
'immediately.'
|
|
163
|
-
) : invariant(ExecutionEnvironment.canUseDOM));
|
|
164
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
165
|
-
ReactEventEmitter.TopLevelCallbackCreator,
|
|
166
|
-
'ensureListening(...): Cannot be called without a top level callback ' +
|
|
167
|
-
'creator being injected.'
|
|
168
|
-
) : invariant(ReactEventEmitter.TopLevelCallbackCreator));
|
|
169
|
-
// Call out to base implementation.
|
|
170
|
-
ReactEventEmitterMixin.ensureListening.call(
|
|
171
|
-
ReactEventEmitter,
|
|
172
|
-
{
|
|
173
|
-
touchNotMouse: touchNotMouse,
|
|
174
|
-
contentDocument: contentDocument
|
|
175
|
-
}
|
|
176
|
-
);
|
|
191
|
+
injection: {
|
|
192
|
+
/**
|
|
193
|
+
* @param {function} TopLevelCallbackCreator
|
|
194
|
+
*/
|
|
195
|
+
injectTopLevelCallbackCreator: function(TopLevelCallbackCreator) {
|
|
196
|
+
ReactEventEmitter.TopLevelCallbackCreator = TopLevelCallbackCreator;
|
|
197
|
+
}
|
|
177
198
|
},
|
|
178
199
|
|
|
179
200
|
/**
|
|
@@ -220,108 +241,86 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
|
|
|
220
241
|
* Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
|
|
221
242
|
* they bubble to document.
|
|
222
243
|
*
|
|
223
|
-
* @param {
|
|
244
|
+
* @param {string} registrationName Name of listener (e.g. `onClick`).
|
|
224
245
|
* @param {DOMDocument} contentDocument Document which owns the container
|
|
225
|
-
* @private
|
|
226
|
-
* @see http://www.quirksmode.org/dom/events/keys.html.
|
|
227
246
|
*/
|
|
228
|
-
|
|
229
|
-
("production" !== process.env.NODE_ENV ? invariant(
|
|
230
|
-
!contentDocument._isListening,
|
|
231
|
-
'listenAtTopLevel(...): Cannot setup top-level listener more than once.'
|
|
232
|
-
) : invariant(!contentDocument._isListening));
|
|
233
|
-
var topLevelTypes = EventConstants.topLevelTypes;
|
|
247
|
+
listenTo: function(registrationName, contentDocument) {
|
|
234
248
|
var mountAt = contentDocument;
|
|
249
|
+
var isListening = getListeningForDocument(mountAt);
|
|
250
|
+
var dependencies = EventPluginRegistry.
|
|
251
|
+
registrationNameDependencies[registrationName];
|
|
235
252
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
trapBubbledEvent(topLevelTypes.topMouseOut, 'mouseout', mountAt);
|
|
242
|
-
trapBubbledEvent(topLevelTypes.topClick, 'click', mountAt);
|
|
243
|
-
trapBubbledEvent(topLevelTypes.topDoubleClick, 'dblclick', mountAt);
|
|
244
|
-
trapBubbledEvent(topLevelTypes.topContextMenu, 'contextmenu', mountAt);
|
|
245
|
-
if (touchNotMouse) {
|
|
246
|
-
trapBubbledEvent(topLevelTypes.topTouchStart, 'touchstart', mountAt);
|
|
247
|
-
trapBubbledEvent(topLevelTypes.topTouchEnd, 'touchend', mountAt);
|
|
248
|
-
trapBubbledEvent(topLevelTypes.topTouchMove, 'touchmove', mountAt);
|
|
249
|
-
trapBubbledEvent(topLevelTypes.topTouchCancel, 'touchcancel', mountAt);
|
|
250
|
-
}
|
|
251
|
-
trapBubbledEvent(topLevelTypes.topKeyUp, 'keyup', mountAt);
|
|
252
|
-
trapBubbledEvent(topLevelTypes.topKeyPress, 'keypress', mountAt);
|
|
253
|
-
trapBubbledEvent(topLevelTypes.topKeyDown, 'keydown', mountAt);
|
|
254
|
-
trapBubbledEvent(topLevelTypes.topInput, 'input', mountAt);
|
|
255
|
-
trapBubbledEvent(topLevelTypes.topChange, 'change', mountAt);
|
|
256
|
-
trapBubbledEvent(
|
|
257
|
-
topLevelTypes.topSelectionChange,
|
|
258
|
-
'selectionchange',
|
|
259
|
-
mountAt
|
|
260
|
-
);
|
|
253
|
+
var topLevelTypes = EventConstants.topLevelTypes;
|
|
254
|
+
for (var i = 0, l = dependencies.length; i < l; i++) {
|
|
255
|
+
var dependency = dependencies[i];
|
|
256
|
+
if (!isListening[dependency]) {
|
|
257
|
+
var topLevelType = topLevelTypes[dependency];
|
|
261
258
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
);
|
|
259
|
+
if (topLevelType === topLevelTypes.topWheel) {
|
|
260
|
+
if (isEventSupported('wheel')) {
|
|
261
|
+
trapBubbledEvent(topLevelTypes.topWheel, 'wheel', mountAt);
|
|
262
|
+
} else if (isEventSupported('mousewheel')) {
|
|
263
|
+
trapBubbledEvent(topLevelTypes.topWheel, 'mousewheel', mountAt);
|
|
264
|
+
} else {
|
|
265
|
+
// Firefox needs to capture a different mouse scroll event.
|
|
266
|
+
// @see http://www.quirksmode.org/dom/events/tests/scroll.html
|
|
267
|
+
trapBubbledEvent(
|
|
268
|
+
topLevelTypes.topWheel,
|
|
269
|
+
'DOMMouseScroll',
|
|
270
|
+
mountAt);
|
|
271
|
+
}
|
|
272
|
+
} else if (topLevelType === topLevelTypes.topScroll) {
|
|
277
273
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
trapBubbledEvent(topLevelTypes.topDragStart, 'dragstart', mountAt);
|
|
286
|
-
trapBubbledEvent(topLevelTypes.topDrop, 'drop', mountAt);
|
|
287
|
-
}
|
|
274
|
+
if (isEventSupported('scroll', true)) {
|
|
275
|
+
trapCapturedEvent(topLevelTypes.topScroll, 'scroll', mountAt);
|
|
276
|
+
} else {
|
|
277
|
+
trapBubbledEvent(topLevelTypes.topScroll, 'scroll', window);
|
|
278
|
+
}
|
|
279
|
+
} else if (topLevelType === topLevelTypes.topFocus ||
|
|
280
|
+
topLevelType === topLevelTypes.topBlur) {
|
|
288
281
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
282
|
+
if (isEventSupported('focus', true)) {
|
|
283
|
+
trapCapturedEvent(topLevelTypes.topFocus, 'focus', mountAt);
|
|
284
|
+
trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt);
|
|
285
|
+
} else if (isEventSupported('focusin')) {
|
|
286
|
+
// IE has `focusin` and `focusout` events which bubble.
|
|
287
|
+
// @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
|
|
288
|
+
trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt);
|
|
289
|
+
trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt);
|
|
290
|
+
}
|
|
298
291
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
292
|
+
// to make sure blur and focus event listeners are only attached once
|
|
293
|
+
isListening[topLevelTypes.topBlur] = true;
|
|
294
|
+
isListening[topLevelTypes.topFocus] = true;
|
|
295
|
+
} else if (topEventMapping[dependency]) {
|
|
296
|
+
trapBubbledEvent(topLevelType, topEventMapping[dependency], mountAt);
|
|
297
|
+
}
|
|
305
298
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
trapCapturedEvent(topLevelTypes.topBlur, 'blur', mountAt);
|
|
309
|
-
} else if (isEventSupported('focusin')) {
|
|
310
|
-
// IE has `focusin` and `focusout` events which bubble.
|
|
311
|
-
// @see
|
|
312
|
-
// http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html
|
|
313
|
-
trapBubbledEvent(topLevelTypes.topFocus, 'focusin', mountAt);
|
|
314
|
-
trapBubbledEvent(topLevelTypes.topBlur, 'focusout', mountAt);
|
|
299
|
+
isListening[dependency] = true;
|
|
300
|
+
}
|
|
315
301
|
}
|
|
302
|
+
},
|
|
316
303
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
304
|
+
/**
|
|
305
|
+
* Listens to window scroll and resize events. We cache scroll values so that
|
|
306
|
+
* application code can access them without triggering reflows.
|
|
307
|
+
*
|
|
308
|
+
* NOTE: Scroll events do not bubble.
|
|
309
|
+
*
|
|
310
|
+
* @see http://www.quirksmode.org/dom/events/scroll.html
|
|
311
|
+
*/
|
|
312
|
+
ensureScrollValueMonitoring: function(){
|
|
313
|
+
if (!isMonitoringScrollValue) {
|
|
314
|
+
var refresh = ViewportMetrics.refreshScrollValues;
|
|
315
|
+
EventListener.listen(window, 'scroll', refresh);
|
|
316
|
+
EventListener.listen(window, 'resize', refresh);
|
|
317
|
+
isMonitoringScrollValue = true;
|
|
321
318
|
}
|
|
322
319
|
},
|
|
323
320
|
|
|
324
|
-
|
|
321
|
+
eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs,
|
|
322
|
+
|
|
323
|
+
registrationNameModules: EventPluginHub.registrationNameModules,
|
|
325
324
|
|
|
326
325
|
putListener: EventPluginHub.putListener,
|
|
327
326
|
|
|
@@ -337,5 +336,4 @@ var ReactEventEmitter = merge(ReactEventEmitterMixin, {
|
|
|
337
336
|
|
|
338
337
|
});
|
|
339
338
|
|
|
340
|
-
|
|
341
339
|
module.exports = ReactEventEmitter;
|