react 0.6.3 → 0.9.0-rc1
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 +10 -222
- package/addons.js +1 -0
- package/lib/AutoFocusMixin.js +30 -0
- package/lib/CSSCore.js +115 -0
- package/lib/CSSProperty.js +121 -0
- package/lib/CSSPropertyOperations.js +97 -0
- package/lib/ChangeEventPlugin.js +387 -0
- package/lib/ClientReactRootIndex.js +30 -0
- package/lib/CompositionEventPlugin.js +260 -0
- package/lib/DOMChildrenOperations.js +165 -0
- package/lib/DOMProperty.js +268 -0
- package/lib/DOMPropertyOperations.js +181 -0
- package/lib/Danger.js +187 -0
- package/lib/DefaultDOMPropertyConfig.js +197 -0
- package/lib/DefaultEventPluginOrder.js +44 -0
- package/lib/EnterLeaveEventPlugin.js +145 -0
- package/lib/EventConstants.js +76 -0
- package/lib/EventListener.js +69 -0
- package/lib/EventPluginHub.js +291 -0
- package/lib/EventPluginRegistry.js +260 -0
- package/lib/EventPluginUtils.js +214 -0
- package/lib/EventPropagators.js +143 -0
- package/lib/ExecutionEnvironment.js +44 -0
- package/lib/LinkedStateMixin.js +46 -0
- package/lib/LinkedValueUtils.js +161 -0
- package/lib/MobileSafariClickEventPlugin.js +63 -0
- package/lib/PooledClass.js +119 -0
- package/lib/React.js +95 -0
- package/lib/ReactCSSTransitionGroup.js +65 -0
- package/lib/ReactCSSTransitionGroupChild.js +138 -0
- package/lib/ReactChildren.js +132 -0
- package/lib/ReactComponent.js +550 -0
- package/lib/ReactComponentBrowserEnvironment.js +158 -0
- package/lib/ReactComponentEnvironment.js +26 -0
- package/lib/ReactCompositeComponent.js +1455 -0
- package/lib/ReactContext.js +67 -0
- package/lib/ReactCurrentOwner.js +39 -0
- package/lib/ReactDOM.js +207 -0
- package/lib/ReactDOMButton.js +68 -0
- package/lib/ReactDOMComponent.js +399 -0
- package/lib/ReactDOMForm.js +59 -0
- package/lib/ReactDOMIDOperations.js +218 -0
- package/lib/ReactDOMImg.js +58 -0
- package/lib/ReactDOMInput.js +181 -0
- package/lib/ReactDOMOption.js +51 -0
- package/lib/ReactDOMSelect.js +179 -0
- package/lib/ReactDOMSelection.js +189 -0
- package/lib/ReactDOMTextarea.js +140 -0
- package/lib/ReactDefaultBatchingStrategy.js +75 -0
- package/lib/ReactDefaultInjection.js +115 -0
- package/lib/ReactDefaultPerf.js +244 -0
- package/lib/ReactDefaultPerfAnalysis.js +199 -0
- package/lib/ReactErrorUtils.js +37 -0
- package/lib/ReactEventEmitter.js +337 -0
- package/lib/ReactEventEmitterMixin.js +57 -0
- package/lib/ReactEventTopLevelCallback.js +109 -0
- package/lib/ReactInjection.js +39 -0
- package/lib/ReactInputSelection.js +140 -0
- package/lib/ReactInstanceHandles.js +338 -0
- package/lib/ReactLink.js +54 -0
- package/lib/ReactMarkupChecksum.js +53 -0
- package/lib/ReactMount.js +641 -0
- package/lib/ReactMountReady.js +95 -0
- package/lib/ReactMultiChild.js +425 -0
- package/lib/ReactMultiChildUpdateTypes.js +38 -0
- package/lib/ReactOwner.js +154 -0
- package/lib/ReactPerf.js +85 -0
- package/lib/ReactPropTransferer.js +147 -0
- package/lib/ReactPropTypeLocationNames.js +31 -0
- package/lib/ReactPropTypeLocations.js +29 -0
- package/lib/ReactPropTypes.js +359 -0
- package/lib/ReactPutListenerQueue.js +61 -0
- package/lib/ReactReconcileTransaction.js +181 -0
- package/lib/ReactRootIndex.js +36 -0
- package/lib/ReactServerRendering.js +59 -0
- package/lib/ReactStateSetters.js +111 -0
- package/lib/ReactTextComponent.js +99 -0
- package/lib/ReactTransitionChildMapping.js +106 -0
- package/lib/ReactTransitionEvents.js +97 -0
- package/lib/ReactTransitionGroup.js +187 -0
- package/lib/ReactUpdates.js +148 -0
- package/lib/ReactWithAddons.js +46 -0
- package/lib/SelectEventPlugin.js +200 -0
- package/lib/ServerReactRootIndex.js +36 -0
- package/lib/SimpleEventPlugin.js +413 -0
- package/lib/SyntheticClipboardEvent.js +51 -0
- package/lib/SyntheticCompositionEvent.js +51 -0
- package/lib/SyntheticDragEvent.js +44 -0
- package/lib/SyntheticEvent.js +164 -0
- package/lib/SyntheticFocusEvent.js +44 -0
- package/lib/SyntheticKeyboardEvent.js +58 -0
- package/lib/SyntheticMouseEvent.js +85 -0
- package/lib/SyntheticTouchEvent.js +50 -0
- package/lib/SyntheticUIEvent.js +45 -0
- package/lib/SyntheticWheelEvent.js +66 -0
- package/lib/Transaction.js +276 -0
- package/lib/ViewportMetrics.js +37 -0
- package/lib/accumulate.js +54 -0
- package/lib/adler32.js +39 -0
- package/lib/cloneWithProps.js +59 -0
- package/lib/containsNode.js +49 -0
- package/lib/copyProperties.js +54 -0
- package/lib/createArrayFrom.js +91 -0
- package/lib/createFullPageComponent.js +63 -0
- package/lib/createNodesFromMarkup.js +93 -0
- package/lib/createObjectFrom.js +61 -0
- package/lib/cx.js +44 -0
- package/lib/dangerousStyleValue.js +57 -0
- package/lib/emptyFunction.js +43 -0
- package/lib/escapeTextForBrowser.js +47 -0
- package/lib/flattenChildren.js +57 -0
- package/lib/forEachAccumulated.js +36 -0
- package/lib/getActiveElement.js +34 -0
- package/lib/getEventKey.js +85 -0
- package/lib/getEventTarget.js +36 -0
- package/lib/getMarkupWrap.js +118 -0
- package/lib/getNodeForCharacterOffset.js +80 -0
- package/lib/getReactRootElementInContainer.js +40 -0
- package/lib/getTextContentAccessor.js +42 -0
- package/lib/getUnboundedScrollPosition.js +45 -0
- package/lib/hyphenate.js +35 -0
- package/lib/invariant.js +62 -0
- package/lib/isEventSupported.js +70 -0
- package/lib/isNode.js +33 -0
- package/lib/isTextInputElement.js +49 -0
- package/lib/isTextNode.js +30 -0
- package/lib/joinClasses.js +44 -0
- package/lib/keyMirror.js +58 -0
- package/lib/keyOf.js +41 -0
- package/lib/memoizeStringOnly.js +39 -0
- package/lib/merge.js +37 -0
- package/lib/mergeHelpers.js +136 -0
- package/lib/mergeInto.js +45 -0
- package/lib/mixInto.js +34 -0
- package/lib/objMap.js +47 -0
- package/lib/objMapKeyVal.js +47 -0
- package/lib/onlyChild.js +43 -0
- package/lib/performanceNow.js +42 -0
- package/lib/shallowEqual.js +49 -0
- package/lib/shouldUpdateReactComponent.js +58 -0
- package/lib/toArray.js +75 -0
- package/lib/traverseAllChildren.js +189 -0
- package/lib/warning.js +40 -0
- package/package.json +32 -21
- package/react.js +1 -0
- package/.npmignore +0 -7
- package/.travis.yml +0 -5
- package/Jakefile.js +0 -39
- package/LICENSE +0 -19
- package/browser-test/dist.html +0 -90
- package/browser-test/index.html +0 -86
- package/browser-test/min.html +0 -90
- package/dist/react.js +0 -3107
- package/dist/react.min.js +0 -22
- package/doc/advanced.md +0 -174
- package/doc/color-def.graffle +0 -938
- package/doc/color-def.png +0 -0
- package/doc/simple.dot +0 -25
- package/doc/simple.png +0 -0
- package/examples/longer-example.js +0 -41
- package/examples/simple.js +0 -45
- package/examples/using-ast-directly.js +0 -30
- package/examples/using-events1.js +0 -79
- package/examples/using-log-events.js +0 -43
- package/lib/base-task.js +0 -123
- package/lib/cb-task.js +0 -84
- package/lib/core.js +0 -138
- package/lib/dsl.js +0 -138
- package/lib/error.js +0 -55
- package/lib/event-collector.js +0 -81
- package/lib/event-manager.js +0 -89
- package/lib/eventemitter.js +0 -20
- package/lib/finalcb-first-task.js +0 -68
- package/lib/finalcb-task.js +0 -65
- package/lib/id.js +0 -22
- package/lib/input-parser.js +0 -56
- package/lib/log-events.js +0 -101
- package/lib/parse.js +0 -41
- package/lib/promise-resolve.js +0 -50
- package/lib/promise-task.js +0 -93
- package/lib/react.js +0 -59
- package/lib/ret-task.js +0 -71
- package/lib/sprintf.js +0 -18
- package/lib/status.js +0 -14
- package/lib/task.js +0 -251
- package/lib/track-tasks.js +0 -74
- package/lib/validate.js +0 -159
- package/lib/vcon.js +0 -90
- package/lib/when-task.js +0 -85
- package/src/dist.build.requirejs +0 -20
- package/test/ast.mocha.js +0 -136
- package/test/cb-task.mocha.js +0 -220
- package/test/core-deferred.mocha.js +0 -143
- package/test/core-when.mocha.js +0 -96
- package/test/core.mocha.js +0 -589
- package/test/dsl.mocha.js +0 -350
- package/test/event-manager.mocha.js +0 -119
- package/test/exec-options.mocha.js +0 -48
- package/test/finalcb-task.mocha.js +0 -58
- package/test/input-parser.mocha.js +0 -86
- package/test/log-events.mocha.js +0 -88
- package/test/mocha.opts +0 -2
- package/test/module-use.mocha.js +0 -147
- package/test/promise-auto-resolve.mocha.js +0 -68
- package/test/ret-task.mocha.js +0 -220
- package/test/task.mocha.js +0 -42
- package/test/validate-cb-task.mocha.js +0 -100
- package/test/validate-ret-task.mocha.js +0 -110
- package/test/validate.mocha.js +0 -324
- package/test/vcon.mocha.js +0 -193
- package/vendor/chai/chai.js +0 -2038
- package/vendor/jquery/jquery-1.7.1.js +0 -9266
- package/vendor/jquery/jquery-1.7.1.min.js +0 -4
- package/vendor/mocha/mocha.css +0 -135
- package/vendor/mocha/mocha.js +0 -3589
- package/vendor/node/util.js +0 -531
- package/vendor/requirejs/require.js +0 -2053
- package/vendor/requirejs/require.min.js +0 -33
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013 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
|
+
* @typechecks static-only
|
|
17
|
+
* @providesModule ReactTransitionChildMapping
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
"use strict";
|
|
21
|
+
|
|
22
|
+
var ReactChildren = require("./ReactChildren");
|
|
23
|
+
|
|
24
|
+
var ReactTransitionChildMapping = {
|
|
25
|
+
/**
|
|
26
|
+
* Given `this.props.children`, return an object mapping key to child. Just
|
|
27
|
+
* simple syntactic sugar around ReactChildren.map().
|
|
28
|
+
*
|
|
29
|
+
* @param {*} children `this.props.children`
|
|
30
|
+
* @return {object} Mapping of key to child
|
|
31
|
+
*/
|
|
32
|
+
getChildMapping: function(children) {
|
|
33
|
+
return ReactChildren.map(children, function(child) {
|
|
34
|
+
return child;
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* When you're adding or removing children some may be added or removed in the
|
|
40
|
+
* same render pass. We want ot show *both* since we want to simultaneously
|
|
41
|
+
* animate elements in and out. This function takes a previous set of keys
|
|
42
|
+
* and a new set of keys and merges them with its best guess of the correct
|
|
43
|
+
* ordering. In the future we may expose some of the utilities in
|
|
44
|
+
* ReactMultiChild to make this easy, but for now React itself does not
|
|
45
|
+
* directly have this concept of the union of prevChildren and nextChildren
|
|
46
|
+
* so we implement it here.
|
|
47
|
+
*
|
|
48
|
+
* @param {object} prev prev children as returned from
|
|
49
|
+
* `ReactTransitionChildMapping.getChildMapping()`.
|
|
50
|
+
* @param {object} next next children as returned from
|
|
51
|
+
* `ReactTransitionChildMapping.getChildMapping()`.
|
|
52
|
+
* @return {object} a key set that contains all keys in `prev` and all keys
|
|
53
|
+
* in `next` in a reasonable order.
|
|
54
|
+
*/
|
|
55
|
+
mergeChildMappings: function(prev, next) {
|
|
56
|
+
prev = prev || {};
|
|
57
|
+
next = next || {};
|
|
58
|
+
|
|
59
|
+
function getValueForKey(key) {
|
|
60
|
+
if (next.hasOwnProperty(key)) {
|
|
61
|
+
return next[key];
|
|
62
|
+
} else {
|
|
63
|
+
return prev[key];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// For each key of `next`, the list of keys to insert before that key in
|
|
68
|
+
// the combined list
|
|
69
|
+
var nextKeysPending = {};
|
|
70
|
+
|
|
71
|
+
var pendingKeys = [];
|
|
72
|
+
for (var prevKey in prev) {
|
|
73
|
+
if (next[prevKey]) {
|
|
74
|
+
if (pendingKeys.length) {
|
|
75
|
+
nextKeysPending[prevKey] = pendingKeys;
|
|
76
|
+
pendingKeys = [];
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
pendingKeys.push(prevKey);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
var i;
|
|
84
|
+
var childMapping = {};
|
|
85
|
+
for (var nextKey in next) {
|
|
86
|
+
if (nextKeysPending[nextKey]) {
|
|
87
|
+
for (i = 0; i < nextKeysPending[nextKey].length; i++) {
|
|
88
|
+
var pendingNextKey = nextKeysPending[nextKey][i];
|
|
89
|
+
childMapping[nextKeysPending[nextKey][i]] = getValueForKey(
|
|
90
|
+
pendingNextKey
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
childMapping[nextKey] = getValueForKey(nextKey);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Finally, add the keys which didn't appear before any key in `next`
|
|
98
|
+
for (i = 0; i < pendingKeys.length; i++) {
|
|
99
|
+
childMapping[pendingKeys[i]] = getValueForKey(pendingKeys[i]);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return childMapping;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
module.exports = ReactTransitionChildMapping;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013 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 ReactTransitionEvents
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
"use strict";
|
|
20
|
+
|
|
21
|
+
var ExecutionEnvironment = require("./ExecutionEnvironment");
|
|
22
|
+
|
|
23
|
+
var EVENT_NAME_MAP = {
|
|
24
|
+
transitionend: {
|
|
25
|
+
'transition': 'transitionend',
|
|
26
|
+
'WebkitTransition': 'webkitTransitionEnd',
|
|
27
|
+
'MozTransition': 'mozTransitionEnd',
|
|
28
|
+
'OTransition': 'oTransitionEnd',
|
|
29
|
+
'msTransition': 'MSTransitionEnd'
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
animationend: {
|
|
33
|
+
'animation': 'animationend',
|
|
34
|
+
'WebkitAnimation': 'webkitAnimationEnd',
|
|
35
|
+
'MozAnimation': 'mozAnimationEnd',
|
|
36
|
+
'OAnimation': 'oAnimationEnd',
|
|
37
|
+
'msAnimation': 'MSAnimationEnd'
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
var endEvents = [];
|
|
42
|
+
|
|
43
|
+
function detectEvents() {
|
|
44
|
+
var testEl = document.createElement('div');
|
|
45
|
+
var style = testEl.style;
|
|
46
|
+
for (var baseEventName in EVENT_NAME_MAP) {
|
|
47
|
+
var baseEvents = EVENT_NAME_MAP[baseEventName];
|
|
48
|
+
for (var styleName in baseEvents) {
|
|
49
|
+
if (styleName in style) {
|
|
50
|
+
endEvents.push(baseEvents[styleName]);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (ExecutionEnvironment.canUseDOM) {
|
|
58
|
+
detectEvents();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// We use the raw {add|remove}EventListener() call because EventListener
|
|
62
|
+
// does not know how to remove event listeners and we really should
|
|
63
|
+
// clean up. Also, these events are not triggered in older browsers
|
|
64
|
+
// so we should be A-OK here.
|
|
65
|
+
|
|
66
|
+
function addEventListener(node, eventName, eventListener) {
|
|
67
|
+
node.addEventListener(eventName, eventListener, false);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function removeEventListener(node, eventName, eventListener) {
|
|
71
|
+
node.removeEventListener(eventName, eventListener, false);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
var ReactTransitionEvents = {
|
|
75
|
+
addEndEventListener: function(node, eventListener) {
|
|
76
|
+
if (endEvents.length === 0) {
|
|
77
|
+
// If CSS transitions are not supported, trigger an "end animation"
|
|
78
|
+
// event immediately.
|
|
79
|
+
window.setTimeout(eventListener, 0);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
endEvents.forEach(function(endEvent) {
|
|
83
|
+
addEventListener(node, endEvent, eventListener);
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
removeEndEventListener: function(node, eventListener) {
|
|
88
|
+
if (endEvents.length === 0) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
endEvents.forEach(function(endEvent) {
|
|
92
|
+
removeEventListener(node, endEvent, eventListener);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
module.exports = ReactTransitionEvents;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013 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 ReactTransitionGroup
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
"use strict";
|
|
20
|
+
|
|
21
|
+
var React = require("./React");
|
|
22
|
+
var ReactTransitionChildMapping = require("./ReactTransitionChildMapping");
|
|
23
|
+
|
|
24
|
+
var cloneWithProps = require("./cloneWithProps");
|
|
25
|
+
var emptyFunction = require("./emptyFunction");
|
|
26
|
+
var merge = require("./merge");
|
|
27
|
+
|
|
28
|
+
var ReactTransitionGroup = React.createClass({
|
|
29
|
+
|
|
30
|
+
propTypes: {
|
|
31
|
+
component: React.PropTypes.func,
|
|
32
|
+
childFactory: React.PropTypes.func
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
getDefaultProps: function() {
|
|
36
|
+
return {
|
|
37
|
+
component: React.DOM.span,
|
|
38
|
+
childFactory: emptyFunction.thatReturnsArgument
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
getInitialState: function() {
|
|
43
|
+
return {
|
|
44
|
+
children: ReactTransitionChildMapping.getChildMapping(this.props.children)
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
componentWillReceiveProps: function(nextProps) {
|
|
49
|
+
var nextChildMapping = ReactTransitionChildMapping.getChildMapping(
|
|
50
|
+
nextProps.children
|
|
51
|
+
);
|
|
52
|
+
var prevChildMapping = this.state.children;
|
|
53
|
+
|
|
54
|
+
this.setState({
|
|
55
|
+
children: ReactTransitionChildMapping.mergeChildMappings(
|
|
56
|
+
prevChildMapping,
|
|
57
|
+
nextChildMapping
|
|
58
|
+
)
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
var key;
|
|
62
|
+
|
|
63
|
+
for (key in nextChildMapping) {
|
|
64
|
+
if (!prevChildMapping.hasOwnProperty(key) &&
|
|
65
|
+
!this.currentlyTransitioningKeys[key]) {
|
|
66
|
+
this.keysToEnter.push(key);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
for (key in prevChildMapping) {
|
|
71
|
+
if (!nextChildMapping.hasOwnProperty(key) &&
|
|
72
|
+
!this.currentlyTransitioningKeys[key]) {
|
|
73
|
+
this.keysToLeave.push(key);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// If we want to someday check for reordering, we could do it here.
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
componentWillMount: function() {
|
|
81
|
+
this.currentlyTransitioningKeys = {};
|
|
82
|
+
this.keysToEnter = [];
|
|
83
|
+
this.keysToLeave = [];
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
componentDidUpdate: function() {
|
|
87
|
+
var keysToEnter = this.keysToEnter;
|
|
88
|
+
this.keysToEnter = [];
|
|
89
|
+
keysToEnter.forEach(this.performEnter);
|
|
90
|
+
|
|
91
|
+
var keysToLeave = this.keysToLeave;
|
|
92
|
+
this.keysToLeave = [];
|
|
93
|
+
keysToLeave.forEach(this.performLeave);
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
performEnter: function(key) {
|
|
97
|
+
this.currentlyTransitioningKeys[key] = true;
|
|
98
|
+
|
|
99
|
+
var component = this.refs[key];
|
|
100
|
+
|
|
101
|
+
if (component.componentWillEnter) {
|
|
102
|
+
component.componentWillEnter(
|
|
103
|
+
this._handleDoneEntering.bind(this, key)
|
|
104
|
+
);
|
|
105
|
+
} else {
|
|
106
|
+
this._handleDoneEntering(key);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
|
|
110
|
+
_handleDoneEntering: function(key) {
|
|
111
|
+
var component = this.refs[key];
|
|
112
|
+
if (component.componentDidEnter) {
|
|
113
|
+
component.componentDidEnter();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
delete this.currentlyTransitioningKeys[key];
|
|
117
|
+
|
|
118
|
+
var currentChildMapping = ReactTransitionChildMapping.getChildMapping(
|
|
119
|
+
this.props.children
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (!currentChildMapping.hasOwnProperty(key)) {
|
|
123
|
+
// This was removed before it had fully entered. Remove it.
|
|
124
|
+
this.performLeave(key);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
performLeave: function(key) {
|
|
129
|
+
this.currentlyTransitioningKeys[key] = true;
|
|
130
|
+
|
|
131
|
+
var component = this.refs[key];
|
|
132
|
+
if (component.componentWillLeave) {
|
|
133
|
+
component.componentWillLeave(this._handleDoneLeaving.bind(this, key));
|
|
134
|
+
} else {
|
|
135
|
+
// Note that this is somewhat dangerous b/c it calls setState()
|
|
136
|
+
// again, effectively mutating the component before all the work
|
|
137
|
+
// is done.
|
|
138
|
+
this._handleDoneLeaving(key);
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
_handleDoneLeaving: function(key) {
|
|
143
|
+
var component = this.refs[key];
|
|
144
|
+
|
|
145
|
+
if (component.componentDidLeave) {
|
|
146
|
+
component.componentDidLeave();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
delete this.currentlyTransitioningKeys[key];
|
|
150
|
+
|
|
151
|
+
var currentChildMapping = ReactTransitionChildMapping.getChildMapping(
|
|
152
|
+
this.props.children
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
if (currentChildMapping.hasOwnProperty(key)) {
|
|
156
|
+
// This entered again before it fully left. Add it again.
|
|
157
|
+
this.performEnter(key);
|
|
158
|
+
} else {
|
|
159
|
+
var newChildren = merge(this.state.children);
|
|
160
|
+
delete newChildren[key];
|
|
161
|
+
this.setState({children: newChildren});
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
render: function() {
|
|
166
|
+
// TODO: we could get rid of the need for the wrapper node
|
|
167
|
+
// by cloning a single child
|
|
168
|
+
var childrenToRender = {};
|
|
169
|
+
for (var key in this.state.children) {
|
|
170
|
+
var child = this.state.children[key];
|
|
171
|
+
if (child) {
|
|
172
|
+
// You may need to apply reactive updates to a child as it is leaving.
|
|
173
|
+
// The normal React way to do it won't work since the child will have
|
|
174
|
+
// already been removed. In case you need this behavior you can provide
|
|
175
|
+
// a childFactory function to wrap every child, even the ones that are
|
|
176
|
+
// leaving.
|
|
177
|
+
childrenToRender[key] = cloneWithProps(
|
|
178
|
+
this.props.childFactory(child),
|
|
179
|
+
{ref: key}
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return this.transferPropsTo(this.props.component(null, childrenToRender));
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
module.exports = ReactTransitionGroup;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2013 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 ReactUpdates
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
"use strict";
|
|
20
|
+
|
|
21
|
+
var ReactPerf = require("./ReactPerf");
|
|
22
|
+
|
|
23
|
+
var invariant = require("./invariant");
|
|
24
|
+
|
|
25
|
+
var dirtyComponents = [];
|
|
26
|
+
|
|
27
|
+
var batchingStrategy = null;
|
|
28
|
+
|
|
29
|
+
function ensureBatchingStrategy() {
|
|
30
|
+
("production" !== process.env.NODE_ENV ? invariant(batchingStrategy, 'ReactUpdates: must inject a batching strategy') : invariant(batchingStrategy));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function batchedUpdates(callback, param) {
|
|
34
|
+
ensureBatchingStrategy();
|
|
35
|
+
batchingStrategy.batchedUpdates(callback, param);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Array comparator for ReactComponents by owner depth
|
|
40
|
+
*
|
|
41
|
+
* @param {ReactComponent} c1 first component you're comparing
|
|
42
|
+
* @param {ReactComponent} c2 second component you're comparing
|
|
43
|
+
* @return {number} Return value usable by Array.prototype.sort().
|
|
44
|
+
*/
|
|
45
|
+
function mountDepthComparator(c1, c2) {
|
|
46
|
+
return c1._mountDepth - c2._mountDepth;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function runBatchedUpdates() {
|
|
50
|
+
// Since reconciling a component higher in the owner hierarchy usually (not
|
|
51
|
+
// always -- see shouldComponentUpdate()) will reconcile children, reconcile
|
|
52
|
+
// them before their children by sorting the array.
|
|
53
|
+
|
|
54
|
+
dirtyComponents.sort(mountDepthComparator);
|
|
55
|
+
|
|
56
|
+
for (var i = 0; i < dirtyComponents.length; i++) {
|
|
57
|
+
// If a component is unmounted before pending changes apply, ignore them
|
|
58
|
+
// TODO: Queue unmounts in the same list to avoid this happening at all
|
|
59
|
+
var component = dirtyComponents[i];
|
|
60
|
+
if (component.isMounted()) {
|
|
61
|
+
// If performUpdateIfNecessary happens to enqueue any new updates, we
|
|
62
|
+
// shouldn't execute the callbacks until the next render happens, so
|
|
63
|
+
// stash the callbacks first
|
|
64
|
+
var callbacks = component._pendingCallbacks;
|
|
65
|
+
component._pendingCallbacks = null;
|
|
66
|
+
component.performUpdateIfNecessary();
|
|
67
|
+
if (callbacks) {
|
|
68
|
+
for (var j = 0; j < callbacks.length; j++) {
|
|
69
|
+
callbacks[j].call(component);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function clearDirtyComponents() {
|
|
77
|
+
dirtyComponents.length = 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
var flushBatchedUpdates = ReactPerf.measure(
|
|
81
|
+
'ReactUpdates',
|
|
82
|
+
'flushBatchedUpdates',
|
|
83
|
+
function() {
|
|
84
|
+
// Run these in separate functions so the JIT can optimize
|
|
85
|
+
try {
|
|
86
|
+
runBatchedUpdates();
|
|
87
|
+
} finally {
|
|
88
|
+
clearDirtyComponents();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Mark a component as needing a rerender, adding an optional callback to a
|
|
95
|
+
* list of functions which will be executed once the rerender occurs.
|
|
96
|
+
*/
|
|
97
|
+
function enqueueUpdate(component, callback) {
|
|
98
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
99
|
+
!callback || typeof callback === "function",
|
|
100
|
+
'enqueueUpdate(...): You called `setProps`, `replaceProps`, ' +
|
|
101
|
+
'`setState`, `replaceState`, or `forceUpdate` with a callback that ' +
|
|
102
|
+
'isn\'t callable.'
|
|
103
|
+
) : invariant(!callback || typeof callback === "function"));
|
|
104
|
+
ensureBatchingStrategy();
|
|
105
|
+
|
|
106
|
+
if (!batchingStrategy.isBatchingUpdates) {
|
|
107
|
+
component.performUpdateIfNecessary();
|
|
108
|
+
callback && callback.call(component);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
dirtyComponents.push(component);
|
|
113
|
+
|
|
114
|
+
if (callback) {
|
|
115
|
+
if (component._pendingCallbacks) {
|
|
116
|
+
component._pendingCallbacks.push(callback);
|
|
117
|
+
} else {
|
|
118
|
+
component._pendingCallbacks = [callback];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
var ReactUpdatesInjection = {
|
|
124
|
+
injectBatchingStrategy: function(_batchingStrategy) {
|
|
125
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
126
|
+
_batchingStrategy,
|
|
127
|
+
'ReactUpdates: must provide a batching strategy'
|
|
128
|
+
) : invariant(_batchingStrategy));
|
|
129
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
130
|
+
typeof _batchingStrategy.batchedUpdates === 'function',
|
|
131
|
+
'ReactUpdates: must provide a batchedUpdates() function'
|
|
132
|
+
) : invariant(typeof _batchingStrategy.batchedUpdates === 'function'));
|
|
133
|
+
("production" !== process.env.NODE_ENV ? invariant(
|
|
134
|
+
typeof _batchingStrategy.isBatchingUpdates === 'boolean',
|
|
135
|
+
'ReactUpdates: must provide an isBatchingUpdates boolean attribute'
|
|
136
|
+
) : invariant(typeof _batchingStrategy.isBatchingUpdates === 'boolean'));
|
|
137
|
+
batchingStrategy = _batchingStrategy;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
var ReactUpdates = {
|
|
142
|
+
batchedUpdates: batchedUpdates,
|
|
143
|
+
enqueueUpdate: enqueueUpdate,
|
|
144
|
+
flushBatchedUpdates: flushBatchedUpdates,
|
|
145
|
+
injection: ReactUpdatesInjection
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
module.exports = ReactUpdates;
|