react 0.7.1 → 0.8.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.
Files changed (203) hide show
  1. package/README.md +15 -228
  2. package/ReactJSErrors.js +40 -0
  3. package/addons.js +4 -0
  4. package/lib/$.js +46 -0
  5. package/lib/CSSCore.js +114 -0
  6. package/lib/CSSProperty.js +90 -0
  7. package/lib/CSSPropertyOperations.js +97 -0
  8. package/lib/CallbackRegistry.js +91 -0
  9. package/lib/ChangeEventPlugin.js +365 -0
  10. package/lib/CompositionEventPlugin.js +212 -0
  11. package/lib/DOMChildrenOperations.js +135 -0
  12. package/lib/DOMProperty.js +266 -0
  13. package/lib/DOMPropertyOperations.js +168 -0
  14. package/lib/Danger.js +186 -0
  15. package/lib/DefaultDOMPropertyConfig.js +187 -0
  16. package/lib/DefaultEventPluginOrder.js +44 -0
  17. package/lib/EnterLeaveEventPlugin.js +112 -0
  18. package/lib/EventConstants.js +73 -0
  19. package/lib/EventListener.js +61 -0
  20. package/lib/EventPluginHub.js +190 -0
  21. package/lib/EventPluginRegistry.js +237 -0
  22. package/lib/EventPluginUtils.js +185 -0
  23. package/lib/EventPropagators.js +179 -0
  24. package/lib/ExecutionEnvironment.js +41 -0
  25. package/lib/LinkedStateMixin.js +46 -0
  26. package/lib/LinkedValueMixin.js +68 -0
  27. package/lib/MobileSafariClickEventPlugin.js +63 -0
  28. package/lib/PooledClass.js +113 -0
  29. package/lib/React.js +71 -0
  30. package/lib/ReactChildren.js +132 -0
  31. package/lib/ReactComponent.js +515 -0
  32. package/lib/ReactComponentBrowserEnvironment.js +140 -0
  33. package/lib/ReactComponentEnvironment.js +24 -0
  34. package/lib/ReactCompositeComponent.js +1020 -0
  35. package/lib/ReactCurrentOwner.js +39 -0
  36. package/lib/ReactDOM.js +194 -0
  37. package/lib/ReactDOMButton.js +64 -0
  38. package/lib/ReactDOMComponent.js +374 -0
  39. package/lib/ReactDOMForm.js +52 -0
  40. package/lib/ReactDOMIDOperations.js +173 -0
  41. package/lib/ReactDOMInput.js +169 -0
  42. package/lib/ReactDOMOption.js +50 -0
  43. package/lib/ReactDOMSelect.js +160 -0
  44. package/lib/ReactDOMSelection.js +189 -0
  45. package/lib/ReactDOMTextarea.js +136 -0
  46. package/lib/ReactDefaultBatchingStrategy.js +75 -0
  47. package/lib/ReactDefaultInjection.js +91 -0
  48. package/lib/ReactDefaultPerf.js +407 -0
  49. package/lib/ReactErrorUtils.js +46 -0
  50. package/lib/ReactEventEmitter.js +341 -0
  51. package/lib/ReactEventEmitterMixin.js +89 -0
  52. package/lib/ReactEventTopLevelCallback.js +89 -0
  53. package/lib/ReactInputSelection.js +140 -0
  54. package/lib/ReactInstanceHandles.js +322 -0
  55. package/lib/ReactLink.js +54 -0
  56. package/lib/ReactMarkupChecksum.js +53 -0
  57. package/lib/ReactMount.js +617 -0
  58. package/lib/ReactMountReady.js +95 -0
  59. package/lib/ReactMultiChild.js +441 -0
  60. package/lib/ReactMultiChildUpdateTypes.js +36 -0
  61. package/lib/ReactOwner.js +146 -0
  62. package/lib/ReactPerf.js +88 -0
  63. package/lib/ReactPropTransferer.js +128 -0
  64. package/lib/ReactPropTypes.js +158 -0
  65. package/lib/ReactReconcileTransaction.js +161 -0
  66. package/lib/ReactServerRendering.js +62 -0
  67. package/lib/ReactStateSetters.js +111 -0
  68. package/lib/ReactTextComponent.js +94 -0
  69. package/lib/ReactTransitionEvents.js +97 -0
  70. package/lib/ReactTransitionGroup.js +112 -0
  71. package/lib/ReactTransitionKeySet.js +111 -0
  72. package/lib/ReactTransitionableChild.js +152 -0
  73. package/lib/ReactUpdates.js +145 -0
  74. package/lib/ReactWithAddons.js +41 -0
  75. package/lib/SelectEventPlugin.js +217 -0
  76. package/lib/SimpleEventPlugin.js +365 -0
  77. package/lib/SyntheticClipboardEvent.js +45 -0
  78. package/lib/SyntheticCompositionEvent.js +51 -0
  79. package/lib/SyntheticEvent.js +163 -0
  80. package/lib/SyntheticFocusEvent.js +44 -0
  81. package/lib/SyntheticKeyboardEvent.js +56 -0
  82. package/lib/SyntheticMouseEvent.js +85 -0
  83. package/lib/SyntheticTouchEvent.js +50 -0
  84. package/lib/SyntheticUIEvent.js +45 -0
  85. package/lib/SyntheticWheelEvent.js +63 -0
  86. package/lib/Transaction.js +251 -0
  87. package/lib/ViewportMetrics.js +37 -0
  88. package/lib/accumulate.js +54 -0
  89. package/lib/adler32.js +39 -0
  90. package/lib/containsNode.js +49 -0
  91. package/lib/copyProperties.js +54 -0
  92. package/lib/createArrayFrom.js +94 -0
  93. package/lib/createNodesFromMarkup.js +93 -0
  94. package/lib/createObjectFrom.js +61 -0
  95. package/lib/cx.js +44 -0
  96. package/lib/dangerousStyleValue.js +57 -0
  97. package/lib/emptyFunction.js +43 -0
  98. package/lib/escapeTextForBrowser.js +47 -0
  99. package/lib/ex.js +49 -0
  100. package/lib/filterAttributes.js +45 -0
  101. package/lib/flattenChildren.js +54 -0
  102. package/lib/forEachAccumulated.js +36 -0
  103. package/lib/ge.js +76 -0
  104. package/lib/getActiveElement.js +33 -0
  105. package/lib/getEventTarget.js +36 -0
  106. package/lib/getMarkupWrap.js +108 -0
  107. package/lib/getNodeForCharacterOffset.js +80 -0
  108. package/lib/getReactRootElementInContainer.js +40 -0
  109. package/lib/getTextContentAccessor.js +40 -0
  110. package/lib/getUnboundedScrollPosition.js +45 -0
  111. package/lib/hyphenate.js +35 -0
  112. package/lib/invariant.js +54 -0
  113. package/lib/isEventSupported.js +74 -0
  114. package/lib/isNode.js +33 -0
  115. package/lib/isTextInputElement.js +49 -0
  116. package/lib/isTextNode.js +30 -0
  117. package/lib/joinClasses.js +44 -0
  118. package/lib/keyMirror.js +58 -0
  119. package/lib/keyOf.js +41 -0
  120. package/lib/memoizeStringOnly.js +39 -0
  121. package/lib/merge.js +37 -0
  122. package/lib/mergeHelpers.js +137 -0
  123. package/lib/mergeInto.js +45 -0
  124. package/lib/mixInto.js +34 -0
  125. package/lib/mutateHTMLNodeWithMarkup.js +100 -0
  126. package/lib/objMap.js +47 -0
  127. package/lib/objMapKeyVal.js +47 -0
  128. package/lib/performanceNow.js +42 -0
  129. package/lib/shallowEqual.js +49 -0
  130. package/lib/traverseAllChildren.js +127 -0
  131. package/package.json +33 -31
  132. package/react.js +4 -0
  133. package/.npmignore +0 -7
  134. package/.travis.yml +0 -7
  135. package/Jakefile.js +0 -39
  136. package/LICENSE +0 -19
  137. package/browser-test/dist.html +0 -90
  138. package/browser-test/index.html +0 -86
  139. package/browser-test/min.html +0 -90
  140. package/dist/react.js +0 -3141
  141. package/dist/react.min.js +0 -22
  142. package/doc/advanced.md +0 -175
  143. package/doc/color-def.graffle +0 -938
  144. package/doc/color-def.png +0 -0
  145. package/doc/simple.dot +0 -25
  146. package/doc/simple.png +0 -0
  147. package/examples/longer-example.js +0 -41
  148. package/examples/simple.js +0 -45
  149. package/examples/using-ast-directly.js +0 -30
  150. package/examples/using-events1.js +0 -79
  151. package/examples/using-log-events.js +0 -43
  152. package/lib/base-task.js +0 -120
  153. package/lib/cb-task.js +0 -84
  154. package/lib/core.js +0 -138
  155. package/lib/dsl.js +0 -138
  156. package/lib/error.js +0 -55
  157. package/lib/event-collector.js +0 -81
  158. package/lib/event-manager.js +0 -89
  159. package/lib/eventemitter.js +0 -20
  160. package/lib/finalcb-first-task.js +0 -68
  161. package/lib/finalcb-task.js +0 -65
  162. package/lib/id.js +0 -22
  163. package/lib/input-parser.js +0 -56
  164. package/lib/log-events.js +0 -101
  165. package/lib/parse.js +0 -41
  166. package/lib/promise-resolve.js +0 -50
  167. package/lib/promise-task.js +0 -93
  168. package/lib/react.js +0 -59
  169. package/lib/ret-task.js +0 -71
  170. package/lib/sprintf.js +0 -18
  171. package/lib/status.js +0 -14
  172. package/lib/task.js +0 -251
  173. package/lib/track-tasks.js +0 -74
  174. package/lib/validate.js +0 -159
  175. package/lib/vcon.js +0 -113
  176. package/lib/when-task.js +0 -84
  177. package/src/dist.build.requirejs +0 -20
  178. package/test/ast.mocha.js +0 -136
  179. package/test/cb-task.mocha.js +0 -220
  180. package/test/core-deferred.mocha.js +0 -143
  181. package/test/core-when.mocha.js +0 -96
  182. package/test/core.mocha.js +0 -589
  183. package/test/dsl.mocha.js +0 -352
  184. package/test/event-manager.mocha.js +0 -119
  185. package/test/exec-options.mocha.js +0 -48
  186. package/test/finalcb-task.mocha.js +0 -58
  187. package/test/input-parser.mocha.js +0 -86
  188. package/test/log-events.mocha.js +0 -88
  189. package/test/mocha.opts +0 -2
  190. package/test/module-use.mocha.js +0 -164
  191. package/test/promise-auto-resolve.mocha.js +0 -68
  192. package/test/ret-task.mocha.js +0 -220
  193. package/test/task.mocha.js +0 -42
  194. package/test/validate-cb-task.mocha.js +0 -100
  195. package/test/validate-ret-task.mocha.js +0 -110
  196. package/test/validate.mocha.js +0 -324
  197. package/test/vcon.mocha.js +0 -193
  198. package/vendor/chai/chai.js +0 -4251
  199. package/vendor/jquery/jquery-1.7.1.js +0 -9266
  200. package/vendor/jquery/jquery-1.7.1.min.js +0 -4
  201. package/vendor/node/util.js +0 -531
  202. package/vendor/requirejs/require.js +0 -2045
  203. package/vendor/requirejs/require.min.js +0 -36
@@ -0,0 +1,54 @@
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 ReactLink
17
+ * @typechecks static-only
18
+ */
19
+
20
+ "use strict";
21
+
22
+ /**
23
+ * ReactLink encapsulates a common pattern in which a component wants to modify
24
+ * a prop received from its parent. ReactLink allows the parent to pass down a
25
+ * value coupled with a callback that, when invoked, expresses an intent to
26
+ * modify that value. For example:
27
+ *
28
+ * React.createClass({
29
+ * getInitialState: function() {
30
+ * return {value: ''};
31
+ * },
32
+ * render: function() {
33
+ * var valueLink = new ReactLink(this.state.value, this._handleValueChange);
34
+ * return <input valueLink={valueLink} />;
35
+ * },
36
+ * this._handleValueChange: function(newValue) {
37
+ * this.setState({value: newValue});
38
+ * }
39
+ * });
40
+ *
41
+ * We have provided some sugary mixins to make the creation and
42
+ * consumption of ReactLink easier; see LinkedValueMixin and LinkedStateMixin.
43
+ */
44
+
45
+ /**
46
+ * @param {*} value current value of the link
47
+ * @param {function} requestChange callback to request a change
48
+ */
49
+ function ReactLink(value, requestChange) {
50
+ this.value = value;
51
+ this.requestChange = requestChange;
52
+ }
53
+
54
+ module.exports = ReactLink;
@@ -0,0 +1,53 @@
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 ReactMarkupChecksum
17
+ */
18
+
19
+ "use strict";
20
+
21
+ var adler32 = require("./adler32");
22
+
23
+ var ReactMarkupChecksum = {
24
+ CHECKSUM_ATTR_NAME: 'data-react-checksum',
25
+
26
+ /**
27
+ * @param {string} markup Markup string
28
+ * @return {string} Markup string with checksum attribute attached
29
+ */
30
+ addChecksumToMarkup: function(markup) {
31
+ var checksum = adler32(markup);
32
+ return markup.replace(
33
+ '>',
34
+ ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">'
35
+ );
36
+ },
37
+
38
+ /**
39
+ * @param {string} markup to use
40
+ * @param {DOMElement} element root React element
41
+ * @returns {boolean} whether or not the markup is the same
42
+ */
43
+ canReuseMarkup: function(markup, element) {
44
+ var existingChecksum = element.getAttribute(
45
+ ReactMarkupChecksum.CHECKSUM_ATTR_NAME
46
+ );
47
+ existingChecksum = existingChecksum && parseInt(existingChecksum, 10);
48
+ var markupChecksum = adler32(markup);
49
+ return markupChecksum === existingChecksum;
50
+ }
51
+ };
52
+
53
+ module.exports = ReactMarkupChecksum;
@@ -0,0 +1,617 @@
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 ReactMount
17
+ */
18
+
19
+ "use strict";
20
+
21
+ var ReactEventEmitter = require("./ReactEventEmitter");
22
+ var ReactInstanceHandles = require("./ReactInstanceHandles");
23
+
24
+ var $ = require("./$");
25
+ var containsNode = require("./containsNode");
26
+ var getReactRootElementInContainer = require("./getReactRootElementInContainer");
27
+ var invariant = require("./invariant");
28
+
29
+ var SEPARATOR = ReactInstanceHandles.SEPARATOR;
30
+
31
+ var ATTR_NAME = 'data-reactid';
32
+ var nodeCache = {};
33
+
34
+ var ELEMENT_NODE_TYPE = 1;
35
+ var DOC_NODE_TYPE = 9;
36
+
37
+ /** Mapping from reactRootID to React component instance. */
38
+ var instancesByReactRootID = {};
39
+
40
+ /** Mapping from reactRootID to `container` nodes. */
41
+ var containersByReactRootID = {};
42
+
43
+ if ("production" !== process.env.NODE_ENV) {
44
+ /** __DEV__-only mapping from reactRootID to root elements. */
45
+ var rootElementsByReactRootID = {};
46
+ }
47
+
48
+ /**
49
+ * @param {DOMElement} container DOM element that may contain a React component.
50
+ * @return {?string} A "reactRoot" ID, if a React component is rendered.
51
+ */
52
+ function getReactRootID(container) {
53
+ var rootElement = getReactRootElementInContainer(container);
54
+ return rootElement && ReactMount.getID(rootElement);
55
+ }
56
+
57
+ /**
58
+ * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form
59
+ * element can return its control whose name or ID equals ATTR_NAME. All
60
+ * DOM nodes support `getAttributeNode` but this can also get called on
61
+ * other objects so just return '' if we're given something other than a
62
+ * DOM node (such as window).
63
+ *
64
+ * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node.
65
+ * @return {string} ID of the supplied `domNode`.
66
+ */
67
+ function getID(node) {
68
+ var id = internalGetID(node);
69
+ if (id) {
70
+ if (nodeCache.hasOwnProperty(id)) {
71
+ var cached = nodeCache[id];
72
+ if (cached !== node) {
73
+ ("production" !== process.env.NODE_ENV ? invariant(
74
+ !isValid(cached, id),
75
+ 'ReactMount: Two valid but unequal nodes with the same `%s`: %s',
76
+ ATTR_NAME, id
77
+ ) : invariant(!isValid(cached, id)));
78
+
79
+ nodeCache[id] = node;
80
+ }
81
+ } else {
82
+ nodeCache[id] = node;
83
+ }
84
+ }
85
+
86
+ return id;
87
+ }
88
+
89
+ function internalGetID(node) {
90
+ // If node is something like a window, document, or text node, none of
91
+ // which support attributes or a .getAttribute method, gracefully return
92
+ // the empty string, as if the attribute were missing.
93
+ return node && node.getAttribute && node.getAttribute(ATTR_NAME) || '';
94
+ }
95
+
96
+ /**
97
+ * Sets the React-specific ID of the given node.
98
+ *
99
+ * @param {DOMElement} node The DOM node whose ID will be set.
100
+ * @param {string} id The value of the ID attribute.
101
+ */
102
+ function setID(node, id) {
103
+ var oldID = internalGetID(node);
104
+ if (oldID !== id) {
105
+ delete nodeCache[oldID];
106
+ }
107
+ node.setAttribute(ATTR_NAME, id);
108
+ nodeCache[id] = node;
109
+ }
110
+
111
+ /**
112
+ * Finds the node with the supplied React-generated DOM ID.
113
+ *
114
+ * @param {string} id A React-generated DOM ID.
115
+ * @return {DOMElement} DOM node with the suppled `id`.
116
+ * @internal
117
+ */
118
+ function getNode(id) {
119
+ if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
120
+ nodeCache[id] = ReactMount.findReactNodeByID(id);
121
+ }
122
+ return nodeCache[id];
123
+ }
124
+
125
+ /**
126
+ * A node is "valid" if it is contained by a currently mounted container.
127
+ *
128
+ * This means that the node does not have to be contained by a document in
129
+ * order to be considered valid.
130
+ *
131
+ * @param {?DOMElement} node The candidate DOM node.
132
+ * @param {string} id The expected ID of the node.
133
+ * @return {boolean} Whether the node is contained by a mounted container.
134
+ */
135
+ function isValid(node, id) {
136
+ if (node) {
137
+ ("production" !== process.env.NODE_ENV ? invariant(
138
+ internalGetID(node) === id,
139
+ 'ReactMount: Unexpected modification of `%s`',
140
+ ATTR_NAME
141
+ ) : invariant(internalGetID(node) === id));
142
+
143
+ var container = ReactMount.findReactContainerForID(id);
144
+ if (container && containsNode(container, node)) {
145
+ return true;
146
+ }
147
+ }
148
+
149
+ return false;
150
+ }
151
+
152
+ /**
153
+ * Causes the cache to forget about one React-specific ID.
154
+ *
155
+ * @param {string} id The ID to forget.
156
+ */
157
+ function purgeID(id) {
158
+ delete nodeCache[id];
159
+ }
160
+
161
+ /**
162
+ * Mounting is the process of initializing a React component by creatings its
163
+ * representative DOM elements and inserting them into a supplied `container`.
164
+ * Any prior content inside `container` is destroyed in the process.
165
+ *
166
+ * ReactMount.renderComponent(component, $('container'));
167
+ *
168
+ * <div id="container"> <-- Supplied `container`.
169
+ * <div data-reactid=".r[3]"> <-- Rendered reactRoot of React
170
+ * // ... component.
171
+ * </div>
172
+ * </div>
173
+ *
174
+ * Inside of `container`, the first element rendered is the "reactRoot".
175
+ */
176
+ var ReactMount = {
177
+ /**
178
+ * Safety guard to prevent accidentally rendering over the entire HTML tree.
179
+ */
180
+ allowFullPageRender: false,
181
+
182
+ /** Time spent generating markup. */
183
+ totalInstantiationTime: 0,
184
+
185
+ /** Time spent inserting markup into the DOM. */
186
+ totalInjectionTime: 0,
187
+
188
+ /** Whether support for touch events should be initialized. */
189
+ useTouchEvents: false,
190
+
191
+ /** Exposed for debugging purposes **/
192
+ _instancesByReactRootID: instancesByReactRootID,
193
+
194
+ /**
195
+ * This is a hook provided to support rendering React components while
196
+ * ensuring that the apparent scroll position of its `container` does not
197
+ * change.
198
+ *
199
+ * @param {DOMElement} container The `container` being rendered into.
200
+ * @param {function} renderCallback This must be called once to do the render.
201
+ */
202
+ scrollMonitor: function(container, renderCallback) {
203
+ renderCallback();
204
+ },
205
+
206
+ /**
207
+ * Ensures that the top-level event delegation listener is set up. This will
208
+ * be invoked some time before the first time any React component is rendered.
209
+ * @param {DOMElement} container container we're rendering into
210
+ *
211
+ * @private
212
+ */
213
+ prepareEnvironmentForDOM: function(container) {
214
+ ("production" !== process.env.NODE_ENV ? invariant(
215
+ container && (
216
+ container.nodeType === ELEMENT_NODE_TYPE ||
217
+ container.nodeType === DOC_NODE_TYPE
218
+ ),
219
+ 'prepareEnvironmentForDOM(...): Target container is not a DOM element.'
220
+ ) : invariant(container && (
221
+ container.nodeType === ELEMENT_NODE_TYPE ||
222
+ container.nodeType === DOC_NODE_TYPE
223
+ )));
224
+ var doc = container.nodeType === ELEMENT_NODE_TYPE ?
225
+ container.ownerDocument :
226
+ container;
227
+ ReactEventEmitter.ensureListening(ReactMount.useTouchEvents, doc);
228
+ },
229
+
230
+ /**
231
+ * Take a component that's already mounted into the DOM and replace its props
232
+ * @param {ReactComponent} prevComponent component instance already in the DOM
233
+ * @param {ReactComponent} nextComponent component instance to render
234
+ * @param {DOMElement} container container to render into
235
+ * @param {?function} callback function triggered on completion
236
+ */
237
+ _updateRootComponent: function(
238
+ prevComponent,
239
+ nextComponent,
240
+ container,
241
+ callback) {
242
+ var nextProps = nextComponent.props;
243
+ ReactMount.scrollMonitor(container, function() {
244
+ prevComponent.replaceProps(nextProps, callback);
245
+ });
246
+
247
+ if ("production" !== process.env.NODE_ENV) {
248
+ // Record the root element in case it later gets transplanted.
249
+ rootElementsByReactRootID[getReactRootID(container)] =
250
+ getReactRootElementInContainer(container);
251
+ }
252
+
253
+ return prevComponent;
254
+ },
255
+
256
+ /**
257
+ * Register a component into the instance map and start the events system.
258
+ * @param {ReactComponent} nextComponent component instance to render
259
+ * @param {DOMElement} container container to render into
260
+ * @return {string} reactRoot ID prefix
261
+ */
262
+ _registerComponent: function(nextComponent, container) {
263
+ ReactMount.prepareEnvironmentForDOM(container);
264
+
265
+ var reactRootID = ReactMount.registerContainer(container);
266
+ instancesByReactRootID[reactRootID] = nextComponent;
267
+ return reactRootID;
268
+ },
269
+
270
+ /**
271
+ * Render a new component into the DOM.
272
+ * @param {ReactComponent} nextComponent component instance to render
273
+ * @param {DOMElement} container container to render into
274
+ * @param {boolean} shouldReuseMarkup if we should skip the markup insertion
275
+ * @return {ReactComponent} nextComponent
276
+ */
277
+ _renderNewRootComponent: function(
278
+ nextComponent,
279
+ container,
280
+ shouldReuseMarkup) {
281
+ var reactRootID = ReactMount._registerComponent(nextComponent, container);
282
+ nextComponent.mountComponentIntoNode(
283
+ reactRootID,
284
+ container,
285
+ shouldReuseMarkup
286
+ );
287
+
288
+ if ("production" !== process.env.NODE_ENV) {
289
+ // Record the root element in case it later gets transplanted.
290
+ rootElementsByReactRootID[reactRootID] =
291
+ getReactRootElementInContainer(container);
292
+ }
293
+
294
+ return nextComponent;
295
+ },
296
+
297
+ /**
298
+ * Renders a React component into the DOM in the supplied `container`.
299
+ *
300
+ * If the React component was previously rendered into `container`, this will
301
+ * perform an update on it and only mutate the DOM as necessary to reflect the
302
+ * latest React component.
303
+ *
304
+ * @param {ReactComponent} nextComponent Component instance to render.
305
+ * @param {DOMElement} container DOM element to render into.
306
+ * @param {?function} callback function triggered on completion
307
+ * @return {ReactComponent} Component instance rendered in `container`.
308
+ */
309
+ renderComponent: function(nextComponent, container, callback) {
310
+ var registeredComponent = instancesByReactRootID[getReactRootID(container)];
311
+
312
+ if (registeredComponent) {
313
+ if (registeredComponent.constructor === nextComponent.constructor) {
314
+ return ReactMount._updateRootComponent(
315
+ registeredComponent,
316
+ nextComponent,
317
+ container,
318
+ callback
319
+ );
320
+ } else {
321
+ ReactMount.unmountComponentAtNode(container);
322
+ }
323
+ }
324
+
325
+ var reactRootElement = getReactRootElementInContainer(container);
326
+ var containerHasReactMarkup =
327
+ reactRootElement && ReactMount.isRenderedByReact(reactRootElement);
328
+
329
+ var shouldReuseMarkup = containerHasReactMarkup && !registeredComponent;
330
+
331
+ var component = ReactMount._renderNewRootComponent(
332
+ nextComponent,
333
+ container,
334
+ shouldReuseMarkup
335
+ );
336
+ callback && callback();
337
+ return component;
338
+ },
339
+
340
+ /**
341
+ * Constructs a component instance of `constructor` with `initialProps` and
342
+ * renders it into the supplied `container`.
343
+ *
344
+ * @param {function} constructor React component constructor.
345
+ * @param {?object} props Initial props of the component instance.
346
+ * @param {DOMElement} container DOM element to render into.
347
+ * @return {ReactComponent} Component instance rendered in `container`.
348
+ */
349
+ constructAndRenderComponent: function(constructor, props, container) {
350
+ return ReactMount.renderComponent(constructor(props), container);
351
+ },
352
+
353
+ /**
354
+ * Constructs a component instance of `constructor` with `initialProps` and
355
+ * renders it into a container node identified by supplied `id`.
356
+ *
357
+ * @param {function} componentConstructor React component constructor
358
+ * @param {?object} props Initial props of the component instance.
359
+ * @param {string} id ID of the DOM element to render into.
360
+ * @return {ReactComponent} Component instance rendered in the container node.
361
+ */
362
+ constructAndRenderComponentByID: function(constructor, props, id) {
363
+ return ReactMount.constructAndRenderComponent(constructor, props, $(id));
364
+ },
365
+
366
+ /**
367
+ * Registers a container node into which React components will be rendered.
368
+ * This also creates the "reatRoot" ID that will be assigned to the element
369
+ * rendered within.
370
+ *
371
+ * @param {DOMElement} container DOM element to register as a container.
372
+ * @return {string} The "reactRoot" ID of elements rendered within.
373
+ */
374
+ registerContainer: function(container) {
375
+ var reactRootID = getReactRootID(container);
376
+ if (reactRootID) {
377
+ // If one exists, make sure it is a valid "reactRoot" ID.
378
+ reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID);
379
+ }
380
+ if (!reactRootID) {
381
+ // No valid "reactRoot" ID found, create one.
382
+ reactRootID = ReactInstanceHandles.createReactRootID();
383
+ }
384
+ containersByReactRootID[reactRootID] = container;
385
+ return reactRootID;
386
+ },
387
+
388
+ /**
389
+ * Unmounts and destroys the React component rendered in the `container`.
390
+ *
391
+ * @param {DOMElement} container DOM element containing a React component.
392
+ * @return {boolean} True if a component was found in and unmounted from
393
+ * `container`
394
+ */
395
+ unmountComponentAtNode: function(container) {
396
+ var reactRootID = getReactRootID(container);
397
+ var component = instancesByReactRootID[reactRootID];
398
+ if (!component) {
399
+ return false;
400
+ }
401
+ ReactMount.unmountComponentFromNode(component, container);
402
+ delete instancesByReactRootID[reactRootID];
403
+ delete containersByReactRootID[reactRootID];
404
+ if ("production" !== process.env.NODE_ENV) {
405
+ delete rootElementsByReactRootID[reactRootID];
406
+ }
407
+ return true;
408
+ },
409
+
410
+ /**
411
+ * @deprecated
412
+ */
413
+ unmountAndReleaseReactRootNode: function() {
414
+ if ("production" !== process.env.NODE_ENV) {
415
+ console.warn(
416
+ 'unmountAndReleaseReactRootNode() has been renamed to ' +
417
+ 'unmountComponentAtNode() and will be removed in the next ' +
418
+ 'version of React.'
419
+ );
420
+ }
421
+ return ReactMount.unmountComponentAtNode.apply(this, arguments);
422
+ },
423
+
424
+ /**
425
+ * Unmounts a component and removes it from the DOM.
426
+ *
427
+ * @param {ReactComponent} instance React component instance.
428
+ * @param {DOMElement} container DOM element to unmount from.
429
+ * @final
430
+ * @internal
431
+ * @see {ReactMount.unmountComponentAtNode}
432
+ */
433
+ unmountComponentFromNode: function(instance, container) {
434
+ instance.unmountComponent();
435
+
436
+ if (container.nodeType === DOC_NODE_TYPE) {
437
+ container = container.documentElement;
438
+ }
439
+
440
+ // http://jsperf.com/emptying-a-node
441
+ while (container.lastChild) {
442
+ container.removeChild(container.lastChild);
443
+ }
444
+ },
445
+
446
+ /**
447
+ * Finds the container DOM element that contains React component to which the
448
+ * supplied DOM `id` belongs.
449
+ *
450
+ * @param {string} id The ID of an element rendered by a React component.
451
+ * @return {?DOMElement} DOM element that contains the `id`.
452
+ */
453
+ findReactContainerForID: function(id) {
454
+ var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id);
455
+ var container = containersByReactRootID[reactRootID];
456
+
457
+ if ("production" !== process.env.NODE_ENV) {
458
+ var rootElement = rootElementsByReactRootID[reactRootID];
459
+ if (rootElement && rootElement.parentNode !== container) {
460
+ ("production" !== process.env.NODE_ENV ? invariant(
461
+ // Call internalGetID here because getID calls isValid which calls
462
+ // findReactContainerForID (this function).
463
+ internalGetID(rootElement) === reactRootID,
464
+ 'ReactMount: Root element ID differed from reactRootID.'
465
+ ) : invariant(// Call internalGetID here because getID calls isValid which calls
466
+ // findReactContainerForID (this function).
467
+ internalGetID(rootElement) === reactRootID));
468
+
469
+ var containerChild = container.firstChild;
470
+ if (containerChild &&
471
+ reactRootID === internalGetID(containerChild)) {
472
+ // If the container has a new child with the same ID as the old
473
+ // root element, then rootElementsByReactRootID[reactRootID] is
474
+ // just stale and needs to be updated. The case that deserves a
475
+ // warning is when the container is empty.
476
+ rootElementsByReactRootID[reactRootID] = containerChild;
477
+ } else {
478
+ console.warn(
479
+ 'ReactMount: Root element has been removed from its original ' +
480
+ 'container. New container:', rootElement.parentNode
481
+ );
482
+ }
483
+ }
484
+ }
485
+
486
+ return container;
487
+ },
488
+
489
+ /**
490
+ * Finds an element rendered by React with the supplied ID.
491
+ *
492
+ * @param {string} id ID of a DOM node in the React component.
493
+ * @return {DOMElement} Root DOM node of the React component.
494
+ */
495
+ findReactNodeByID: function(id) {
496
+ var reactRoot = ReactMount.findReactContainerForID(id);
497
+ return ReactMount.findComponentRoot(reactRoot, id);
498
+ },
499
+
500
+ /**
501
+ * True if the supplied `node` is rendered by React.
502
+ *
503
+ * @param {*} node DOM Element to check.
504
+ * @return {boolean} True if the DOM Element appears to be rendered by React.
505
+ * @internal
506
+ */
507
+ isRenderedByReact: function(node) {
508
+ if (node.nodeType !== 1) {
509
+ // Not a DOMElement, therefore not a React component
510
+ return false;
511
+ }
512
+ var id = ReactMount.getID(node);
513
+ return id ? id.charAt(0) === SEPARATOR : false;
514
+ },
515
+
516
+ /**
517
+ * Traverses up the ancestors of the supplied node to find a node that is a
518
+ * DOM representation of a React component.
519
+ *
520
+ * @param {*} node
521
+ * @return {?DOMEventTarget}
522
+ * @internal
523
+ */
524
+ getFirstReactDOM: function(node) {
525
+ var current = node;
526
+ while (current && current.parentNode !== current) {
527
+ if (ReactMount.isRenderedByReact(current)) {
528
+ return current;
529
+ }
530
+ current = current.parentNode;
531
+ }
532
+ return null;
533
+ },
534
+
535
+ /**
536
+ * Finds a node with the supplied `id` inside of the supplied `ancestorNode`.
537
+ * Exploits the ID naming scheme to perform the search quickly.
538
+ *
539
+ * @param {DOMEventTarget} ancestorNode Search from this root.
540
+ * @pararm {string} id ID of the DOM representation of the component.
541
+ * @return {DOMEventTarget} DOM node with the supplied `id`.
542
+ * @internal
543
+ */
544
+ findComponentRoot: function(ancestorNode, id) {
545
+ var firstChildren = [ancestorNode.firstChild];
546
+ var childIndex = 0;
547
+
548
+ while (childIndex < firstChildren.length) {
549
+ var child = firstChildren[childIndex++];
550
+ while (child) {
551
+ var childID = ReactMount.getID(child);
552
+ if (childID) {
553
+ if (id === childID) {
554
+ return child;
555
+ } else if (ReactInstanceHandles.isAncestorIDOf(childID, id)) {
556
+ // If we find a child whose ID is an ancestor of the given ID,
557
+ // then we can be sure that we only want to search the subtree
558
+ // rooted at this child, so we can throw out the rest of the
559
+ // search state.
560
+ firstChildren.length = childIndex = 0;
561
+ firstChildren.push(child.firstChild);
562
+ break;
563
+ } else {
564
+ // TODO This should not be necessary if the ID hierarchy is
565
+ // correct, but is occasionally necessary if the DOM has been
566
+ // modified in unexpected ways.
567
+ firstChildren.push(child.firstChild);
568
+ }
569
+ } else {
570
+ // If this child had no ID, then there's a chance that it was
571
+ // injected automatically by the browser, as when a `<table>`
572
+ // element sprouts an extra `<tbody>` child as a side effect of
573
+ // `.innerHTML` parsing. Optimistically continue down this
574
+ // branch, but not before examining the other siblings.
575
+ firstChildren.push(child.firstChild);
576
+ }
577
+ child = child.nextSibling;
578
+ }
579
+ }
580
+
581
+ if ("production" !== process.env.NODE_ENV) {
582
+ console.error(
583
+ 'Error while invoking `findComponentRoot` with the following ' +
584
+ 'ancestor node:',
585
+ ancestorNode
586
+ );
587
+ }
588
+ ("production" !== process.env.NODE_ENV ? invariant(
589
+ false,
590
+ 'findComponentRoot(..., %s): Unable to find element. This probably ' +
591
+ 'means the DOM was unexpectedly mutated (e.g. by the browser).',
592
+ id,
593
+ ReactMount.getID(ancestorNode)
594
+ ) : invariant(false));
595
+ },
596
+
597
+
598
+ /**
599
+ * React ID utilities.
600
+ */
601
+
602
+ ATTR_NAME: ATTR_NAME,
603
+
604
+ getReactRootID: getReactRootID,
605
+
606
+ getID: getID,
607
+
608
+ setID: setID,
609
+
610
+ getNode: getNode,
611
+
612
+ purgeID: purgeID,
613
+
614
+ injection: {}
615
+ };
616
+
617
+ module.exports = ReactMount;