react 0.7.1 → 0.10.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.
Files changed (223) hide show
  1. package/README.md +10 -231
  2. package/addons.js +1 -0
  3. package/lib/AutoFocusMixin.js +32 -0
  4. package/lib/CSSCore.js +115 -0
  5. package/lib/CSSProperty.js +121 -0
  6. package/lib/CSSPropertyOperations.js +97 -0
  7. package/lib/ChangeEventPlugin.js +387 -0
  8. package/lib/ClientReactRootIndex.js +30 -0
  9. package/lib/CompositionEventPlugin.js +260 -0
  10. package/lib/DOMChildrenOperations.js +171 -0
  11. package/lib/DOMProperty.js +270 -0
  12. package/lib/DOMPropertyOperations.js +181 -0
  13. package/lib/Danger.js +187 -0
  14. package/lib/DefaultDOMPropertyConfig.js +196 -0
  15. package/lib/DefaultEventPluginOrder.js +44 -0
  16. package/lib/EnterLeaveEventPlugin.js +145 -0
  17. package/lib/EventConstants.js +76 -0
  18. package/lib/EventListener.js +69 -0
  19. package/lib/EventPluginHub.js +295 -0
  20. package/lib/EventPluginRegistry.js +281 -0
  21. package/lib/EventPluginUtils.js +214 -0
  22. package/lib/EventPropagators.js +143 -0
  23. package/lib/ExecutionEnvironment.js +44 -0
  24. package/lib/LinkedStateMixin.js +46 -0
  25. package/lib/LinkedValueUtils.js +160 -0
  26. package/lib/MobileSafariClickEventPlugin.js +63 -0
  27. package/lib/PooledClass.js +119 -0
  28. package/lib/React.js +97 -0
  29. package/lib/ReactBrowserComponentMixin.js +42 -0
  30. package/lib/ReactCSSTransitionGroup.js +65 -0
  31. package/lib/ReactCSSTransitionGroupChild.js +138 -0
  32. package/lib/ReactChildren.js +132 -0
  33. package/lib/ReactComponent.js +595 -0
  34. package/lib/ReactComponentBrowserEnvironment.js +124 -0
  35. package/lib/ReactCompositeComponent.js +1587 -0
  36. package/lib/ReactContext.js +67 -0
  37. package/lib/ReactCurrentOwner.js +39 -0
  38. package/lib/ReactDOM.js +207 -0
  39. package/lib/ReactDOMButton.js +69 -0
  40. package/lib/ReactDOMComponent.js +416 -0
  41. package/lib/ReactDOMForm.js +62 -0
  42. package/lib/ReactDOMIDOperations.js +218 -0
  43. package/lib/ReactDOMImg.js +61 -0
  44. package/lib/ReactDOMInput.js +182 -0
  45. package/lib/ReactDOMOption.js +55 -0
  46. package/lib/ReactDOMSelect.js +180 -0
  47. package/lib/ReactDOMSelection.js +189 -0
  48. package/lib/ReactDOMTextarea.js +144 -0
  49. package/lib/ReactDefaultBatchingStrategy.js +75 -0
  50. package/lib/ReactDefaultInjection.js +125 -0
  51. package/lib/ReactDefaultPerf.js +244 -0
  52. package/lib/ReactDefaultPerfAnalysis.js +199 -0
  53. package/lib/ReactErrorUtils.js +37 -0
  54. package/lib/ReactEventEmitter.js +339 -0
  55. package/lib/ReactEventEmitterMixin.js +57 -0
  56. package/lib/ReactEventTopLevelCallback.js +149 -0
  57. package/lib/ReactInjection.js +43 -0
  58. package/lib/ReactInputSelection.js +141 -0
  59. package/lib/ReactInstanceHandles.js +338 -0
  60. package/lib/ReactLink.js +54 -0
  61. package/lib/ReactMarkupChecksum.js +53 -0
  62. package/lib/ReactMount.js +649 -0
  63. package/lib/ReactMountReady.js +95 -0
  64. package/lib/ReactMultiChild.js +432 -0
  65. package/lib/ReactMultiChildUpdateTypes.js +38 -0
  66. package/lib/ReactOwner.js +159 -0
  67. package/lib/ReactPerf.js +85 -0
  68. package/lib/ReactPropTransferer.js +147 -0
  69. package/lib/ReactPropTypeLocationNames.js +31 -0
  70. package/lib/ReactPropTypeLocations.js +29 -0
  71. package/lib/ReactPropTypes.js +359 -0
  72. package/lib/ReactPutListenerQueue.js +61 -0
  73. package/lib/ReactReconcileTransaction.js +182 -0
  74. package/lib/ReactRootIndex.js +36 -0
  75. package/lib/ReactServerRendering.js +89 -0
  76. package/lib/ReactServerRenderingTransaction.js +116 -0
  77. package/lib/ReactStateSetters.js +111 -0
  78. package/lib/ReactTestUtils.js +394 -0
  79. package/lib/ReactTextComponent.js +121 -0
  80. package/lib/ReactTransitionChildMapping.js +106 -0
  81. package/lib/ReactTransitionEvents.js +97 -0
  82. package/lib/ReactTransitionGroup.js +187 -0
  83. package/lib/ReactUpdates.js +148 -0
  84. package/lib/ReactWithAddons.js +53 -0
  85. package/lib/SelectEventPlugin.js +200 -0
  86. package/lib/ServerReactRootIndex.js +36 -0
  87. package/lib/SimpleEventPlugin.js +413 -0
  88. package/lib/SyntheticClipboardEvent.js +51 -0
  89. package/lib/SyntheticCompositionEvent.js +51 -0
  90. package/lib/SyntheticDragEvent.js +44 -0
  91. package/lib/SyntheticEvent.js +164 -0
  92. package/lib/SyntheticFocusEvent.js +44 -0
  93. package/lib/SyntheticKeyboardEvent.js +58 -0
  94. package/lib/SyntheticMouseEvent.js +85 -0
  95. package/lib/SyntheticTouchEvent.js +50 -0
  96. package/lib/SyntheticUIEvent.js +45 -0
  97. package/lib/SyntheticWheelEvent.js +66 -0
  98. package/lib/Transaction.js +276 -0
  99. package/lib/ViewportMetrics.js +37 -0
  100. package/lib/accumulate.js +54 -0
  101. package/lib/adler32.js +39 -0
  102. package/lib/cloneWithProps.js +59 -0
  103. package/lib/containsNode.js +49 -0
  104. package/lib/copyProperties.js +54 -0
  105. package/lib/createArrayFrom.js +91 -0
  106. package/lib/createFullPageComponent.js +63 -0
  107. package/lib/createNodesFromMarkup.js +93 -0
  108. package/lib/createObjectFrom.js +61 -0
  109. package/lib/cx.js +44 -0
  110. package/lib/dangerousStyleValue.js +57 -0
  111. package/lib/emptyFunction.js +43 -0
  112. package/lib/emptyObject.js +27 -0
  113. package/lib/escapeTextForBrowser.js +47 -0
  114. package/lib/flattenChildren.js +57 -0
  115. package/lib/focusNode.js +33 -0
  116. package/lib/forEachAccumulated.js +36 -0
  117. package/lib/getActiveElement.js +34 -0
  118. package/lib/getEventKey.js +85 -0
  119. package/lib/getEventTarget.js +36 -0
  120. package/lib/getMarkupWrap.js +118 -0
  121. package/lib/getNodeForCharacterOffset.js +80 -0
  122. package/lib/getReactRootElementInContainer.js +40 -0
  123. package/lib/getTextContentAccessor.js +42 -0
  124. package/lib/getUnboundedScrollPosition.js +45 -0
  125. package/lib/hyphenate.js +35 -0
  126. package/lib/instantiateReactComponent.js +70 -0
  127. package/lib/invariant.js +62 -0
  128. package/lib/isEventSupported.js +70 -0
  129. package/lib/isNode.js +33 -0
  130. package/lib/isTextInputElement.js +49 -0
  131. package/lib/isTextNode.js +30 -0
  132. package/lib/joinClasses.js +44 -0
  133. package/lib/keyMirror.js +58 -0
  134. package/lib/keyOf.js +41 -0
  135. package/lib/memoizeStringOnly.js +39 -0
  136. package/lib/merge.js +37 -0
  137. package/lib/mergeHelpers.js +136 -0
  138. package/lib/mergeInto.js +45 -0
  139. package/lib/mixInto.js +34 -0
  140. package/lib/monitorCodeUse.js +37 -0
  141. package/lib/objMap.js +47 -0
  142. package/lib/objMapKeyVal.js +47 -0
  143. package/lib/onlyChild.js +43 -0
  144. package/lib/performanceNow.js +42 -0
  145. package/lib/shallowEqual.js +49 -0
  146. package/lib/shouldUpdateReactComponent.js +61 -0
  147. package/lib/toArray.js +75 -0
  148. package/lib/traverseAllChildren.js +190 -0
  149. package/lib/update.js +159 -0
  150. package/lib/warning.js +48 -0
  151. package/package.json +33 -31
  152. package/react.js +1 -0
  153. package/.npmignore +0 -7
  154. package/.travis.yml +0 -7
  155. package/Jakefile.js +0 -39
  156. package/LICENSE +0 -19
  157. package/browser-test/dist.html +0 -90
  158. package/browser-test/index.html +0 -86
  159. package/browser-test/min.html +0 -90
  160. package/dist/react.js +0 -3141
  161. package/dist/react.min.js +0 -22
  162. package/doc/advanced.md +0 -175
  163. package/doc/color-def.graffle +0 -938
  164. package/doc/color-def.png +0 -0
  165. package/doc/simple.dot +0 -25
  166. package/doc/simple.png +0 -0
  167. package/examples/longer-example.js +0 -41
  168. package/examples/simple.js +0 -45
  169. package/examples/using-ast-directly.js +0 -30
  170. package/examples/using-events1.js +0 -79
  171. package/examples/using-log-events.js +0 -43
  172. package/lib/base-task.js +0 -120
  173. package/lib/cb-task.js +0 -84
  174. package/lib/core.js +0 -138
  175. package/lib/dsl.js +0 -138
  176. package/lib/error.js +0 -55
  177. package/lib/event-collector.js +0 -81
  178. package/lib/event-manager.js +0 -89
  179. package/lib/eventemitter.js +0 -20
  180. package/lib/finalcb-first-task.js +0 -68
  181. package/lib/finalcb-task.js +0 -65
  182. package/lib/id.js +0 -22
  183. package/lib/input-parser.js +0 -56
  184. package/lib/log-events.js +0 -101
  185. package/lib/parse.js +0 -41
  186. package/lib/promise-resolve.js +0 -50
  187. package/lib/promise-task.js +0 -93
  188. package/lib/react.js +0 -59
  189. package/lib/ret-task.js +0 -71
  190. package/lib/sprintf.js +0 -18
  191. package/lib/status.js +0 -14
  192. package/lib/task.js +0 -251
  193. package/lib/track-tasks.js +0 -74
  194. package/lib/validate.js +0 -159
  195. package/lib/vcon.js +0 -113
  196. package/lib/when-task.js +0 -84
  197. package/src/dist.build.requirejs +0 -20
  198. package/test/ast.mocha.js +0 -136
  199. package/test/cb-task.mocha.js +0 -220
  200. package/test/core-deferred.mocha.js +0 -143
  201. package/test/core-when.mocha.js +0 -96
  202. package/test/core.mocha.js +0 -589
  203. package/test/dsl.mocha.js +0 -352
  204. package/test/event-manager.mocha.js +0 -119
  205. package/test/exec-options.mocha.js +0 -48
  206. package/test/finalcb-task.mocha.js +0 -58
  207. package/test/input-parser.mocha.js +0 -86
  208. package/test/log-events.mocha.js +0 -88
  209. package/test/mocha.opts +0 -2
  210. package/test/module-use.mocha.js +0 -164
  211. package/test/promise-auto-resolve.mocha.js +0 -68
  212. package/test/ret-task.mocha.js +0 -220
  213. package/test/task.mocha.js +0 -42
  214. package/test/validate-cb-task.mocha.js +0 -100
  215. package/test/validate-ret-task.mocha.js +0 -110
  216. package/test/validate.mocha.js +0 -324
  217. package/test/vcon.mocha.js +0 -193
  218. package/vendor/chai/chai.js +0 -4251
  219. package/vendor/jquery/jquery-1.7.1.js +0 -9266
  220. package/vendor/jquery/jquery-1.7.1.min.js +0 -4
  221. package/vendor/node/util.js +0 -531
  222. package/vendor/requirejs/require.js +0 -2045
  223. package/vendor/requirejs/require.min.js +0 -36
@@ -0,0 +1,124 @@
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 ReactComponentBrowserEnvironment
17
+ */
18
+
19
+ /*jslint evil: true */
20
+
21
+ "use strict";
22
+
23
+ var ReactDOMIDOperations = require("./ReactDOMIDOperations");
24
+ var ReactMarkupChecksum = require("./ReactMarkupChecksum");
25
+ var ReactMount = require("./ReactMount");
26
+ var ReactPerf = require("./ReactPerf");
27
+ var ReactReconcileTransaction = require("./ReactReconcileTransaction");
28
+
29
+ var getReactRootElementInContainer = require("./getReactRootElementInContainer");
30
+ var invariant = require("./invariant");
31
+
32
+
33
+ var ELEMENT_NODE_TYPE = 1;
34
+ var DOC_NODE_TYPE = 9;
35
+
36
+
37
+ /**
38
+ * Abstracts away all functionality of `ReactComponent` requires knowledge of
39
+ * the browser context.
40
+ */
41
+ var ReactComponentBrowserEnvironment = {
42
+ ReactReconcileTransaction: ReactReconcileTransaction,
43
+
44
+ BackendIDOperations: ReactDOMIDOperations,
45
+
46
+ /**
47
+ * If a particular environment requires that some resources be cleaned up,
48
+ * specify this in the injected Mixin. In the DOM, we would likely want to
49
+ * purge any cached node ID lookups.
50
+ *
51
+ * @private
52
+ */
53
+ unmountIDFromEnvironment: function(rootNodeID) {
54
+ ReactMount.purgeID(rootNodeID);
55
+ },
56
+
57
+ /**
58
+ * @param {string} markup Markup string to place into the DOM Element.
59
+ * @param {DOMElement} container DOM Element to insert markup into.
60
+ * @param {boolean} shouldReuseMarkup Should reuse the existing markup in the
61
+ * container if possible.
62
+ */
63
+ mountImageIntoNode: ReactPerf.measure(
64
+ 'ReactComponentBrowserEnvironment',
65
+ 'mountImageIntoNode',
66
+ function(markup, container, shouldReuseMarkup) {
67
+ ("production" !== process.env.NODE_ENV ? invariant(
68
+ container && (
69
+ container.nodeType === ELEMENT_NODE_TYPE ||
70
+ container.nodeType === DOC_NODE_TYPE
71
+ ),
72
+ 'mountComponentIntoNode(...): Target container is not valid.'
73
+ ) : invariant(container && (
74
+ container.nodeType === ELEMENT_NODE_TYPE ||
75
+ container.nodeType === DOC_NODE_TYPE
76
+ )));
77
+
78
+ if (shouldReuseMarkup) {
79
+ if (ReactMarkupChecksum.canReuseMarkup(
80
+ markup,
81
+ getReactRootElementInContainer(container))) {
82
+ return;
83
+ } else {
84
+ ("production" !== process.env.NODE_ENV ? invariant(
85
+ container.nodeType !== DOC_NODE_TYPE,
86
+ 'You\'re trying to render a component to the document using ' +
87
+ 'server rendering but the checksum was invalid. This usually ' +
88
+ 'means you rendered a different component type or props on ' +
89
+ 'the client from the one on the server, or your render() ' +
90
+ 'methods are impure. React cannot handle this case due to ' +
91
+ 'cross-browser quirks by rendering at the document root. You ' +
92
+ 'should look for environment dependent code in your components ' +
93
+ 'and ensure the props are the same client and server side.'
94
+ ) : invariant(container.nodeType !== DOC_NODE_TYPE));
95
+
96
+ if ("production" !== process.env.NODE_ENV) {
97
+ console.warn(
98
+ 'React attempted to use reuse markup in a container but the ' +
99
+ 'checksum was invalid. This generally means that you are ' +
100
+ 'using server rendering and the markup generated on the ' +
101
+ 'server was not what the client was expecting. React injected' +
102
+ 'new markup to compensate which works but you have lost many ' +
103
+ 'of the benefits of server rendering. Instead, figure out ' +
104
+ 'why the markup being generated is different on the client ' +
105
+ 'or server.'
106
+ );
107
+ }
108
+ }
109
+ }
110
+
111
+ ("production" !== process.env.NODE_ENV ? invariant(
112
+ container.nodeType !== DOC_NODE_TYPE,
113
+ 'You\'re trying to render a component to the document but ' +
114
+ 'you didn\'t use server rendering. We can\'t do this ' +
115
+ 'without using server rendering due to cross-browser quirks. ' +
116
+ 'See renderComponentToString() for server rendering.'
117
+ ) : invariant(container.nodeType !== DOC_NODE_TYPE));
118
+
119
+ container.innerHTML = markup;
120
+ }
121
+ )
122
+ };
123
+
124
+ module.exports = ReactComponentBrowserEnvironment;
@@ -0,0 +1,1587 @@
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 ReactCompositeComponent
17
+ */
18
+
19
+ "use strict";
20
+
21
+ var ReactComponent = require("./ReactComponent");
22
+ var ReactContext = require("./ReactContext");
23
+ var ReactCurrentOwner = require("./ReactCurrentOwner");
24
+ var ReactErrorUtils = require("./ReactErrorUtils");
25
+ var ReactOwner = require("./ReactOwner");
26
+ var ReactPerf = require("./ReactPerf");
27
+ var ReactPropTransferer = require("./ReactPropTransferer");
28
+ var ReactPropTypeLocations = require("./ReactPropTypeLocations");
29
+ var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames");
30
+ var ReactUpdates = require("./ReactUpdates");
31
+
32
+ var instantiateReactComponent = require("./instantiateReactComponent");
33
+ var invariant = require("./invariant");
34
+ var keyMirror = require("./keyMirror");
35
+ var merge = require("./merge");
36
+ var mixInto = require("./mixInto");
37
+ var monitorCodeUse = require("./monitorCodeUse");
38
+ var objMap = require("./objMap");
39
+ var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
40
+ var warning = require("./warning");
41
+
42
+ /**
43
+ * Policies that describe methods in `ReactCompositeComponentInterface`.
44
+ */
45
+ var SpecPolicy = keyMirror({
46
+ /**
47
+ * These methods may be defined only once by the class specification or mixin.
48
+ */
49
+ DEFINE_ONCE: null,
50
+ /**
51
+ * These methods may be defined by both the class specification and mixins.
52
+ * Subsequent definitions will be chained. These methods must return void.
53
+ */
54
+ DEFINE_MANY: null,
55
+ /**
56
+ * These methods are overriding the base ReactCompositeComponent class.
57
+ */
58
+ OVERRIDE_BASE: null,
59
+ /**
60
+ * These methods are similar to DEFINE_MANY, except we assume they return
61
+ * objects. We try to merge the keys of the return values of all the mixed in
62
+ * functions. If there is a key conflict we throw.
63
+ */
64
+ DEFINE_MANY_MERGED: null
65
+ });
66
+
67
+
68
+ var injectedMixins = [];
69
+
70
+ /**
71
+ * Composite components are higher-level components that compose other composite
72
+ * or native components.
73
+ *
74
+ * To create a new type of `ReactCompositeComponent`, pass a specification of
75
+ * your new class to `React.createClass`. The only requirement of your class
76
+ * specification is that you implement a `render` method.
77
+ *
78
+ * var MyComponent = React.createClass({
79
+ * render: function() {
80
+ * return <div>Hello World</div>;
81
+ * }
82
+ * });
83
+ *
84
+ * The class specification supports a specific protocol of methods that have
85
+ * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for
86
+ * more the comprehensive protocol. Any other properties and methods in the
87
+ * class specification will available on the prototype.
88
+ *
89
+ * @interface ReactCompositeComponentInterface
90
+ * @internal
91
+ */
92
+ var ReactCompositeComponentInterface = {
93
+
94
+ /**
95
+ * An array of Mixin objects to include when defining your component.
96
+ *
97
+ * @type {array}
98
+ * @optional
99
+ */
100
+ mixins: SpecPolicy.DEFINE_MANY,
101
+
102
+ /**
103
+ * An object containing properties and methods that should be defined on
104
+ * the component's constructor instead of its prototype (static methods).
105
+ *
106
+ * @type {object}
107
+ * @optional
108
+ */
109
+ statics: SpecPolicy.DEFINE_MANY,
110
+
111
+ /**
112
+ * Definition of prop types for this component.
113
+ *
114
+ * @type {object}
115
+ * @optional
116
+ */
117
+ propTypes: SpecPolicy.DEFINE_MANY,
118
+
119
+ /**
120
+ * Definition of context types for this component.
121
+ *
122
+ * @type {object}
123
+ * @optional
124
+ */
125
+ contextTypes: SpecPolicy.DEFINE_MANY,
126
+
127
+ /**
128
+ * Definition of context types this component sets for its children.
129
+ *
130
+ * @type {object}
131
+ * @optional
132
+ */
133
+ childContextTypes: SpecPolicy.DEFINE_MANY,
134
+
135
+ // ==== Definition methods ====
136
+
137
+ /**
138
+ * Invoked when the component is mounted. Values in the mapping will be set on
139
+ * `this.props` if that prop is not specified (i.e. using an `in` check).
140
+ *
141
+ * This method is invoked before `getInitialState` and therefore cannot rely
142
+ * on `this.state` or use `this.setState`.
143
+ *
144
+ * @return {object}
145
+ * @optional
146
+ */
147
+ getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED,
148
+
149
+ /**
150
+ * Invoked once before the component is mounted. The return value will be used
151
+ * as the initial value of `this.state`.
152
+ *
153
+ * getInitialState: function() {
154
+ * return {
155
+ * isOn: false,
156
+ * fooBaz: new BazFoo()
157
+ * }
158
+ * }
159
+ *
160
+ * @return {object}
161
+ * @optional
162
+ */
163
+ getInitialState: SpecPolicy.DEFINE_MANY_MERGED,
164
+
165
+ /**
166
+ * @return {object}
167
+ * @optional
168
+ */
169
+ getChildContext: SpecPolicy.DEFINE_MANY_MERGED,
170
+
171
+ /**
172
+ * Uses props from `this.props` and state from `this.state` to render the
173
+ * structure of the component.
174
+ *
175
+ * No guarantees are made about when or how often this method is invoked, so
176
+ * it must not have side effects.
177
+ *
178
+ * render: function() {
179
+ * var name = this.props.name;
180
+ * return <div>Hello, {name}!</div>;
181
+ * }
182
+ *
183
+ * @return {ReactComponent}
184
+ * @nosideeffects
185
+ * @required
186
+ */
187
+ render: SpecPolicy.DEFINE_ONCE,
188
+
189
+
190
+
191
+ // ==== Delegate methods ====
192
+
193
+ /**
194
+ * Invoked when the component is initially created and about to be mounted.
195
+ * This may have side effects, but any external subscriptions or data created
196
+ * by this method must be cleaned up in `componentWillUnmount`.
197
+ *
198
+ * @optional
199
+ */
200
+ componentWillMount: SpecPolicy.DEFINE_MANY,
201
+
202
+ /**
203
+ * Invoked when the component has been mounted and has a DOM representation.
204
+ * However, there is no guarantee that the DOM node is in the document.
205
+ *
206
+ * Use this as an opportunity to operate on the DOM when the component has
207
+ * been mounted (initialized and rendered) for the first time.
208
+ *
209
+ * @param {DOMElement} rootNode DOM element representing the component.
210
+ * @optional
211
+ */
212
+ componentDidMount: SpecPolicy.DEFINE_MANY,
213
+
214
+ /**
215
+ * Invoked before the component receives new props.
216
+ *
217
+ * Use this as an opportunity to react to a prop transition by updating the
218
+ * state using `this.setState`. Current props are accessed via `this.props`.
219
+ *
220
+ * componentWillReceiveProps: function(nextProps, nextContext) {
221
+ * this.setState({
222
+ * likesIncreasing: nextProps.likeCount > this.props.likeCount
223
+ * });
224
+ * }
225
+ *
226
+ * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop
227
+ * transition may cause a state change, but the opposite is not true. If you
228
+ * need it, you are probably looking for `componentWillUpdate`.
229
+ *
230
+ * @param {object} nextProps
231
+ * @optional
232
+ */
233
+ componentWillReceiveProps: SpecPolicy.DEFINE_MANY,
234
+
235
+ /**
236
+ * Invoked while deciding if the component should be updated as a result of
237
+ * receiving new props, state and/or context.
238
+ *
239
+ * Use this as an opportunity to `return false` when you're certain that the
240
+ * transition to the new props/state/context will not require a component
241
+ * update.
242
+ *
243
+ * shouldComponentUpdate: function(nextProps, nextState, nextContext) {
244
+ * return !equal(nextProps, this.props) ||
245
+ * !equal(nextState, this.state) ||
246
+ * !equal(nextContext, this.context);
247
+ * }
248
+ *
249
+ * @param {object} nextProps
250
+ * @param {?object} nextState
251
+ * @param {?object} nextContext
252
+ * @return {boolean} True if the component should update.
253
+ * @optional
254
+ */
255
+ shouldComponentUpdate: SpecPolicy.DEFINE_ONCE,
256
+
257
+ /**
258
+ * Invoked when the component is about to update due to a transition from
259
+ * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState`
260
+ * and `nextContext`.
261
+ *
262
+ * Use this as an opportunity to perform preparation before an update occurs.
263
+ *
264
+ * NOTE: You **cannot** use `this.setState()` in this method.
265
+ *
266
+ * @param {object} nextProps
267
+ * @param {?object} nextState
268
+ * @param {?object} nextContext
269
+ * @param {ReactReconcileTransaction} transaction
270
+ * @optional
271
+ */
272
+ componentWillUpdate: SpecPolicy.DEFINE_MANY,
273
+
274
+ /**
275
+ * Invoked when the component's DOM representation has been updated.
276
+ *
277
+ * Use this as an opportunity to operate on the DOM when the component has
278
+ * been updated.
279
+ *
280
+ * @param {object} prevProps
281
+ * @param {?object} prevState
282
+ * @param {?object} prevContext
283
+ * @param {DOMElement} rootNode DOM element representing the component.
284
+ * @optional
285
+ */
286
+ componentDidUpdate: SpecPolicy.DEFINE_MANY,
287
+
288
+ /**
289
+ * Invoked when the component is about to be removed from its parent and have
290
+ * its DOM representation destroyed.
291
+ *
292
+ * Use this as an opportunity to deallocate any external resources.
293
+ *
294
+ * NOTE: There is no `componentDidUnmount` since your component will have been
295
+ * destroyed by that point.
296
+ *
297
+ * @optional
298
+ */
299
+ componentWillUnmount: SpecPolicy.DEFINE_MANY,
300
+
301
+
302
+
303
+ // ==== Advanced methods ====
304
+
305
+ /**
306
+ * Updates the component's currently mounted DOM representation.
307
+ *
308
+ * By default, this implements React's rendering and reconciliation algorithm.
309
+ * Sophisticated clients may wish to override this.
310
+ *
311
+ * @param {ReactReconcileTransaction} transaction
312
+ * @internal
313
+ * @overridable
314
+ */
315
+ updateComponent: SpecPolicy.OVERRIDE_BASE
316
+
317
+ };
318
+
319
+ /**
320
+ * Mapping from class specification keys to special processing functions.
321
+ *
322
+ * Although these are declared like instance properties in the specification
323
+ * when defining classes using `React.createClass`, they are actually static
324
+ * and are accessible on the constructor instead of the prototype. Despite
325
+ * being static, they must be defined outside of the "statics" key under
326
+ * which all other static methods are defined.
327
+ */
328
+ var RESERVED_SPEC_KEYS = {
329
+ displayName: function(ConvenienceConstructor, displayName) {
330
+ ConvenienceConstructor.componentConstructor.displayName = displayName;
331
+ },
332
+ mixins: function(ConvenienceConstructor, mixins) {
333
+ if (mixins) {
334
+ for (var i = 0; i < mixins.length; i++) {
335
+ mixSpecIntoComponent(ConvenienceConstructor, mixins[i]);
336
+ }
337
+ }
338
+ },
339
+ childContextTypes: function(ConvenienceConstructor, childContextTypes) {
340
+ var Constructor = ConvenienceConstructor.componentConstructor;
341
+ validateTypeDef(
342
+ Constructor,
343
+ childContextTypes,
344
+ ReactPropTypeLocations.childContext
345
+ );
346
+ Constructor.childContextTypes = merge(
347
+ Constructor.childContextTypes,
348
+ childContextTypes
349
+ );
350
+ },
351
+ contextTypes: function(ConvenienceConstructor, contextTypes) {
352
+ var Constructor = ConvenienceConstructor.componentConstructor;
353
+ validateTypeDef(
354
+ Constructor,
355
+ contextTypes,
356
+ ReactPropTypeLocations.context
357
+ );
358
+ Constructor.contextTypes = merge(Constructor.contextTypes, contextTypes);
359
+ },
360
+ propTypes: function(ConvenienceConstructor, propTypes) {
361
+ var Constructor = ConvenienceConstructor.componentConstructor;
362
+ validateTypeDef(
363
+ Constructor,
364
+ propTypes,
365
+ ReactPropTypeLocations.prop
366
+ );
367
+ Constructor.propTypes = merge(Constructor.propTypes, propTypes);
368
+ },
369
+ statics: function(ConvenienceConstructor, statics) {
370
+ mixStaticSpecIntoComponent(ConvenienceConstructor, statics);
371
+ }
372
+ };
373
+
374
+ function validateTypeDef(Constructor, typeDef, location) {
375
+ for (var propName in typeDef) {
376
+ if (typeDef.hasOwnProperty(propName)) {
377
+ ("production" !== process.env.NODE_ENV ? invariant(
378
+ typeof typeDef[propName] == 'function',
379
+ '%s: %s type `%s` is invalid; it must be a function, usually from ' +
380
+ 'React.PropTypes.',
381
+ Constructor.displayName || 'ReactCompositeComponent',
382
+ ReactPropTypeLocationNames[location],
383
+ propName
384
+ ) : invariant(typeof typeDef[propName] == 'function'));
385
+ }
386
+ }
387
+ }
388
+
389
+ function validateMethodOverride(proto, name) {
390
+ var specPolicy = ReactCompositeComponentInterface[name];
391
+
392
+ // Disallow overriding of base class methods unless explicitly allowed.
393
+ if (ReactCompositeComponentMixin.hasOwnProperty(name)) {
394
+ ("production" !== process.env.NODE_ENV ? invariant(
395
+ specPolicy === SpecPolicy.OVERRIDE_BASE,
396
+ 'ReactCompositeComponentInterface: You are attempting to override ' +
397
+ '`%s` from your class specification. Ensure that your method names ' +
398
+ 'do not overlap with React methods.',
399
+ name
400
+ ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE));
401
+ }
402
+
403
+ // Disallow defining methods more than once unless explicitly allowed.
404
+ if (proto.hasOwnProperty(name)) {
405
+ ("production" !== process.env.NODE_ENV ? invariant(
406
+ specPolicy === SpecPolicy.DEFINE_MANY ||
407
+ specPolicy === SpecPolicy.DEFINE_MANY_MERGED,
408
+ 'ReactCompositeComponentInterface: You are attempting to define ' +
409
+ '`%s` on your component more than once. This conflict may be due ' +
410
+ 'to a mixin.',
411
+ name
412
+ ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY ||
413
+ specPolicy === SpecPolicy.DEFINE_MANY_MERGED));
414
+ }
415
+ }
416
+
417
+ function validateLifeCycleOnReplaceState(instance) {
418
+ var compositeLifeCycleState = instance._compositeLifeCycleState;
419
+ ("production" !== process.env.NODE_ENV ? invariant(
420
+ instance.isMounted() ||
421
+ compositeLifeCycleState === CompositeLifeCycle.MOUNTING,
422
+ 'replaceState(...): Can only update a mounted or mounting component.'
423
+ ) : invariant(instance.isMounted() ||
424
+ compositeLifeCycleState === CompositeLifeCycle.MOUNTING));
425
+ ("production" !== process.env.NODE_ENV ? invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE,
426
+ 'replaceState(...): Cannot update during an existing state transition ' +
427
+ '(such as within `render`). This could potentially cause an infinite ' +
428
+ 'loop so it is forbidden.'
429
+ ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE));
430
+ ("production" !== process.env.NODE_ENV ? invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
431
+ 'replaceState(...): Cannot update while unmounting component. This ' +
432
+ 'usually means you called setState() on an unmounted component.'
433
+ ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING));
434
+ }
435
+
436
+ /**
437
+ * Custom version of `mixInto` which handles policy validation and reserved
438
+ * specification keys when building `ReactCompositeComponent` classses.
439
+ */
440
+ function mixSpecIntoComponent(ConvenienceConstructor, spec) {
441
+ ("production" !== process.env.NODE_ENV ? invariant(
442
+ !isValidClass(spec),
443
+ 'ReactCompositeComponent: You\'re attempting to ' +
444
+ 'use a component class as a mixin. Instead, just use a regular object.'
445
+ ) : invariant(!isValidClass(spec)));
446
+ ("production" !== process.env.NODE_ENV ? invariant(
447
+ !ReactComponent.isValidComponent(spec),
448
+ 'ReactCompositeComponent: You\'re attempting to ' +
449
+ 'use a component as a mixin. Instead, just use a regular object.'
450
+ ) : invariant(!ReactComponent.isValidComponent(spec)));
451
+
452
+ var Constructor = ConvenienceConstructor.componentConstructor;
453
+ var proto = Constructor.prototype;
454
+ for (var name in spec) {
455
+ var property = spec[name];
456
+ if (!spec.hasOwnProperty(name)) {
457
+ continue;
458
+ }
459
+
460
+ validateMethodOverride(proto, name);
461
+
462
+ if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) {
463
+ RESERVED_SPEC_KEYS[name](ConvenienceConstructor, property);
464
+ } else {
465
+ // Setup methods on prototype:
466
+ // The following member methods should not be automatically bound:
467
+ // 1. Expected ReactCompositeComponent methods (in the "interface").
468
+ // 2. Overridden methods (that were mixed in).
469
+ var isCompositeComponentMethod = name in ReactCompositeComponentInterface;
470
+ var isInherited = name in proto;
471
+ var markedDontBind = property && property.__reactDontBind;
472
+ var isFunction = typeof property === 'function';
473
+ var shouldAutoBind =
474
+ isFunction &&
475
+ !isCompositeComponentMethod &&
476
+ !isInherited &&
477
+ !markedDontBind;
478
+
479
+ if (shouldAutoBind) {
480
+ if (!proto.__reactAutoBindMap) {
481
+ proto.__reactAutoBindMap = {};
482
+ }
483
+ proto.__reactAutoBindMap[name] = property;
484
+ proto[name] = property;
485
+ } else {
486
+ if (isInherited) {
487
+ // For methods which are defined more than once, call the existing
488
+ // methods before calling the new property.
489
+ if (ReactCompositeComponentInterface[name] ===
490
+ SpecPolicy.DEFINE_MANY_MERGED) {
491
+ proto[name] = createMergedResultFunction(proto[name], property);
492
+ } else {
493
+ proto[name] = createChainedFunction(proto[name], property);
494
+ }
495
+ } else {
496
+ proto[name] = property;
497
+ }
498
+ }
499
+ }
500
+ }
501
+ }
502
+
503
+ function mixStaticSpecIntoComponent(ConvenienceConstructor, statics) {
504
+ if (!statics) {
505
+ return;
506
+ }
507
+ for (var name in statics) {
508
+ var property = statics[name];
509
+ if (!statics.hasOwnProperty(name)) {
510
+ return;
511
+ }
512
+
513
+ var isInherited = name in ConvenienceConstructor;
514
+ var result = property;
515
+ if (isInherited) {
516
+ var existingProperty = ConvenienceConstructor[name];
517
+ var existingType = typeof existingProperty;
518
+ var propertyType = typeof property;
519
+ ("production" !== process.env.NODE_ENV ? invariant(
520
+ existingType === 'function' && propertyType === 'function',
521
+ 'ReactCompositeComponent: You are attempting to define ' +
522
+ '`%s` on your component more than once, but that is only supported ' +
523
+ 'for functions, which are chained together. This conflict may be ' +
524
+ 'due to a mixin.',
525
+ name
526
+ ) : invariant(existingType === 'function' && propertyType === 'function'));
527
+ result = createChainedFunction(existingProperty, property);
528
+ }
529
+ ConvenienceConstructor[name] = result;
530
+ ConvenienceConstructor.componentConstructor[name] = result;
531
+ }
532
+ }
533
+
534
+ /**
535
+ * Merge two objects, but throw if both contain the same key.
536
+ *
537
+ * @param {object} one The first object, which is mutated.
538
+ * @param {object} two The second object
539
+ * @return {object} one after it has been mutated to contain everything in two.
540
+ */
541
+ function mergeObjectsWithNoDuplicateKeys(one, two) {
542
+ ("production" !== process.env.NODE_ENV ? invariant(
543
+ one && two && typeof one === 'object' && typeof two === 'object',
544
+ 'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects'
545
+ ) : invariant(one && two && typeof one === 'object' && typeof two === 'object'));
546
+
547
+ objMap(two, function(value, key) {
548
+ ("production" !== process.env.NODE_ENV ? invariant(
549
+ one[key] === undefined,
550
+ 'mergeObjectsWithNoDuplicateKeys(): ' +
551
+ 'Tried to merge two objects with the same key: %s',
552
+ key
553
+ ) : invariant(one[key] === undefined));
554
+ one[key] = value;
555
+ });
556
+ return one;
557
+ }
558
+
559
+ /**
560
+ * Creates a function that invokes two functions and merges their return values.
561
+ *
562
+ * @param {function} one Function to invoke first.
563
+ * @param {function} two Function to invoke second.
564
+ * @return {function} Function that invokes the two argument functions.
565
+ * @private
566
+ */
567
+ function createMergedResultFunction(one, two) {
568
+ return function mergedResult() {
569
+ var a = one.apply(this, arguments);
570
+ var b = two.apply(this, arguments);
571
+ if (a == null) {
572
+ return b;
573
+ } else if (b == null) {
574
+ return a;
575
+ }
576
+ return mergeObjectsWithNoDuplicateKeys(a, b);
577
+ };
578
+ }
579
+
580
+ /**
581
+ * Creates a function that invokes two functions and ignores their return vales.
582
+ *
583
+ * @param {function} one Function to invoke first.
584
+ * @param {function} two Function to invoke second.
585
+ * @return {function} Function that invokes the two argument functions.
586
+ * @private
587
+ */
588
+ function createChainedFunction(one, two) {
589
+ return function chainedFunction() {
590
+ one.apply(this, arguments);
591
+ two.apply(this, arguments);
592
+ };
593
+ }
594
+
595
+ if ("production" !== process.env.NODE_ENV) {
596
+
597
+ var unmountedPropertyWhitelist = {
598
+ constructor: true,
599
+ construct: true,
600
+ isOwnedBy: true, // should be deprecated but can have code mod (internal)
601
+ type: true,
602
+ props: true,
603
+ // currently private but belong on the descriptor and are valid for use
604
+ // inside the framework:
605
+ __keyValidated__: true,
606
+ _owner: true,
607
+ _currentContext: true
608
+ };
609
+
610
+ var componentInstanceProperties = {
611
+ __keyValidated__: true,
612
+ __keySetters: true,
613
+ _compositeLifeCycleState: true,
614
+ _currentContext: true,
615
+ _defaultProps: true,
616
+ _instance: true,
617
+ _lifeCycleState: true,
618
+ _mountDepth: true,
619
+ _owner: true,
620
+ _pendingCallbacks: true,
621
+ _pendingContext: true,
622
+ _pendingForceUpdate: true,
623
+ _pendingOwner: true,
624
+ _pendingProps: true,
625
+ _pendingState: true,
626
+ _renderedComponent: true,
627
+ _rootNodeID: true,
628
+ context: true,
629
+ props: true,
630
+ refs: true,
631
+ state: true,
632
+
633
+ // These are known instance properties coming from other sources
634
+ _pendingQueries: true,
635
+ _queryPropListeners: true,
636
+ queryParams: true
637
+
638
+ };
639
+
640
+ var hasWarnedOnComponentType = {};
641
+
642
+ var warningStackCounter = 0;
643
+
644
+ var issueMembraneWarning = function(instance, key) {
645
+ var isWhitelisted = unmountedPropertyWhitelist.hasOwnProperty(key);
646
+ if (warningStackCounter > 0 || isWhitelisted) {
647
+ return;
648
+ }
649
+ var name = instance.constructor.displayName || 'Unknown';
650
+ var owner = ReactCurrentOwner.current;
651
+ var ownerName = (owner && owner.constructor.displayName) || 'Unknown';
652
+ var warningKey = key + '|' + name + '|' + ownerName;
653
+ if (hasWarnedOnComponentType.hasOwnProperty(warningKey)) {
654
+ // We have already warned for this combination. Skip it this time.
655
+ return;
656
+ }
657
+ hasWarnedOnComponentType[warningKey] = true;
658
+
659
+ var context = owner ? ' in ' + ownerName + '.' : ' at the top level.';
660
+ var staticMethodExample = '<' + name + ' />.type.' + key + '(...)';
661
+
662
+ monitorCodeUse('react_descriptor_property_access', { component: name });
663
+ console.warn(
664
+ 'Invalid access to component property "' + key + '" on ' + name +
665
+ context + ' See http://fb.me/react-warning-descriptors .' +
666
+ ' Use a static method instead: ' + staticMethodExample
667
+ );
668
+ };
669
+
670
+ var wrapInMembraneFunction = function(fn, thisBinding) {
671
+ if (fn.__reactMembraneFunction && fn.__reactMembraneSelf === thisBinding) {
672
+ return fn.__reactMembraneFunction;
673
+ }
674
+ return fn.__reactMembraneFunction = function() {
675
+ /**
676
+ * By getting this function, you've already received a warning. The
677
+ * internals of this function will likely cause more warnings. To avoid
678
+ * Spamming too much we disable any warning triggered inside of this
679
+ * stack.
680
+ */
681
+ warningStackCounter++;
682
+ try {
683
+ // If the this binding is unchanged, we defer to the real component.
684
+ // This is important to keep some referential integrity in the
685
+ // internals. E.g. owner equality check.
686
+ var self = this === thisBinding ? this.__realComponentInstance : this;
687
+ return fn.apply(self, arguments);
688
+ } finally {
689
+ warningStackCounter--;
690
+ }
691
+ };
692
+ };
693
+
694
+ var defineMembraneProperty = function(membrane, prototype, key) {
695
+ Object.defineProperty(membrane, key, {
696
+
697
+ configurable: false,
698
+ enumerable: true,
699
+
700
+ get: function() {
701
+ if (this === membrane) {
702
+ // We're allowed to access the prototype directly.
703
+ return prototype[key];
704
+ }
705
+ issueMembraneWarning(this, key);
706
+
707
+ var realValue = this.__realComponentInstance[key];
708
+ // If the real value is a function, we need to provide a wrapper that
709
+ // disables nested warnings. The properties type and constructors are
710
+ // expected to the be constructors and therefore is often use with an
711
+ // equality check and we shouldn't try to rebind those.
712
+ if (typeof realValue === 'function' &&
713
+ key !== 'type' &&
714
+ key !== 'constructor') {
715
+ return wrapInMembraneFunction(realValue, this);
716
+ }
717
+ return realValue;
718
+ },
719
+
720
+ set: function(value) {
721
+ if (this === membrane) {
722
+ // We're allowed to set a value on the prototype directly.
723
+ prototype[key] = value;
724
+ return;
725
+ }
726
+ issueMembraneWarning(this, key);
727
+ this.__realComponentInstance[key] = value;
728
+ }
729
+
730
+ });
731
+ };
732
+
733
+ /**
734
+ * Creates a membrane prototype which wraps the original prototype. If any
735
+ * property is accessed in an unmounted state, a warning is issued.
736
+ *
737
+ * @param {object} prototype Original prototype.
738
+ * @return {object} The membrane prototype.
739
+ * @private
740
+ */
741
+ var createMountWarningMembrane = function(prototype) {
742
+ var membrane = {};
743
+ var key;
744
+ for (key in prototype) {
745
+ defineMembraneProperty(membrane, prototype, key);
746
+ }
747
+ // These are properties that goes into the instance but not the prototype.
748
+ // We can create the membrane on the prototype even though this will
749
+ // result in a faulty hasOwnProperty check it's better perf.
750
+ for (key in componentInstanceProperties) {
751
+ if (componentInstanceProperties.hasOwnProperty(key) &&
752
+ !(key in prototype)) {
753
+ defineMembraneProperty(membrane, prototype, key);
754
+ }
755
+ }
756
+ return membrane;
757
+ };
758
+
759
+ /**
760
+ * Creates a membrane constructor which wraps the component that gets mounted.
761
+ *
762
+ * @param {function} constructor Original constructor.
763
+ * @return {function} The membrane constructor.
764
+ * @private
765
+ */
766
+ var createDescriptorProxy = function(constructor) {
767
+ try {
768
+ var ProxyConstructor = function() {
769
+ this.__realComponentInstance = new constructor();
770
+
771
+ // We can only safely pass through known instance variables. Unknown
772
+ // expandos are not safe. Use the real mounted instance to avoid this
773
+ // problem if it blows something up.
774
+ Object.freeze(this);
775
+ };
776
+
777
+ ProxyConstructor.prototype = createMountWarningMembrane(
778
+ constructor.prototype
779
+ );
780
+
781
+ return ProxyConstructor;
782
+ } catch(x) {
783
+ // In IE8 define property will fail on non-DOM objects. If anything in
784
+ // the membrane creation fails, we'll bail out and just use the plain
785
+ // constructor without warnings.
786
+ return constructor;
787
+ }
788
+ };
789
+
790
+ }
791
+
792
+ /**
793
+ * `ReactCompositeComponent` maintains an auxiliary life cycle state in
794
+ * `this._compositeLifeCycleState` (which can be null).
795
+ *
796
+ * This is different from the life cycle state maintained by `ReactComponent` in
797
+ * `this._lifeCycleState`. The following diagram shows how the states overlap in
798
+ * time. There are times when the CompositeLifeCycle is null - at those times it
799
+ * is only meaningful to look at ComponentLifeCycle alone.
800
+ *
801
+ * Top Row: ReactComponent.ComponentLifeCycle
802
+ * Low Row: ReactComponent.CompositeLifeCycle
803
+ *
804
+ * +-------+------------------------------------------------------+--------+
805
+ * | UN | MOUNTED | UN |
806
+ * |MOUNTED| | MOUNTED|
807
+ * +-------+------------------------------------------------------+--------+
808
+ * | ^--------+ +------+ +------+ +------+ +--------^ |
809
+ * | | | | | | | | | | | |
810
+ * | 0--|MOUNTING|-0-|RECEIV|-0-|RECEIV|-0-|RECEIV|-0-| UN |--->0 |
811
+ * | | | |PROPS | | PROPS| | STATE| |MOUNTING| |
812
+ * | | | | | | | | | | | |
813
+ * | | | | | | | | | | | |
814
+ * | +--------+ +------+ +------+ +------+ +--------+ |
815
+ * | | | |
816
+ * +-------+------------------------------------------------------+--------+
817
+ */
818
+ var CompositeLifeCycle = keyMirror({
819
+ /**
820
+ * Components in the process of being mounted respond to state changes
821
+ * differently.
822
+ */
823
+ MOUNTING: null,
824
+ /**
825
+ * Components in the process of being unmounted are guarded against state
826
+ * changes.
827
+ */
828
+ UNMOUNTING: null,
829
+ /**
830
+ * Components that are mounted and receiving new props respond to state
831
+ * changes differently.
832
+ */
833
+ RECEIVING_PROPS: null,
834
+ /**
835
+ * Components that are mounted and receiving new state are guarded against
836
+ * additional state changes.
837
+ */
838
+ RECEIVING_STATE: null
839
+ });
840
+
841
+ /**
842
+ * @lends {ReactCompositeComponent.prototype}
843
+ */
844
+ var ReactCompositeComponentMixin = {
845
+
846
+ /**
847
+ * Base constructor for all composite component.
848
+ *
849
+ * @param {?object} initialProps
850
+ * @param {*} children
851
+ * @final
852
+ * @internal
853
+ */
854
+ construct: function(initialProps, children) {
855
+ // Children can be either an array or more than one argument
856
+ ReactComponent.Mixin.construct.apply(this, arguments);
857
+ ReactOwner.Mixin.construct.apply(this, arguments);
858
+
859
+ this.state = null;
860
+ this._pendingState = null;
861
+
862
+ this.context = null;
863
+ this._currentContext = ReactContext.current;
864
+ this._pendingContext = null;
865
+
866
+ // The descriptor that was used to instantiate this component. Will be
867
+ // set by the instantiator instead of the constructor since this
868
+ // constructor is currently used by both instances and descriptors.
869
+ this._descriptor = null;
870
+
871
+ this._compositeLifeCycleState = null;
872
+ },
873
+
874
+ /**
875
+ * Components in the intermediate state now has cyclic references. To avoid
876
+ * breaking JSON serialization we expose a custom JSON format.
877
+ * @return {object} JSON compatible representation.
878
+ * @internal
879
+ * @final
880
+ */
881
+ toJSON: function() {
882
+ return { type: this.type, props: this.props };
883
+ },
884
+
885
+ /**
886
+ * Checks whether or not this composite component is mounted.
887
+ * @return {boolean} True if mounted, false otherwise.
888
+ * @protected
889
+ * @final
890
+ */
891
+ isMounted: function() {
892
+ return ReactComponent.Mixin.isMounted.call(this) &&
893
+ this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING;
894
+ },
895
+
896
+ /**
897
+ * Initializes the component, renders markup, and registers event listeners.
898
+ *
899
+ * @param {string} rootID DOM ID of the root node.
900
+ * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
901
+ * @param {number} mountDepth number of components in the owner hierarchy
902
+ * @return {?string} Rendered markup to be inserted into the DOM.
903
+ * @final
904
+ * @internal
905
+ */
906
+ mountComponent: ReactPerf.measure(
907
+ 'ReactCompositeComponent',
908
+ 'mountComponent',
909
+ function(rootID, transaction, mountDepth) {
910
+ ReactComponent.Mixin.mountComponent.call(
911
+ this,
912
+ rootID,
913
+ transaction,
914
+ mountDepth
915
+ );
916
+ this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING;
917
+
918
+ this.context = this._processContext(this._currentContext);
919
+ this._defaultProps = this.getDefaultProps ? this.getDefaultProps() : null;
920
+ this.props = this._processProps(this.props);
921
+
922
+ if (this.__reactAutoBindMap) {
923
+ this._bindAutoBindMethods();
924
+ }
925
+
926
+ this.state = this.getInitialState ? this.getInitialState() : null;
927
+ ("production" !== process.env.NODE_ENV ? invariant(
928
+ typeof this.state === 'object' && !Array.isArray(this.state),
929
+ '%s.getInitialState(): must return an object or null',
930
+ this.constructor.displayName || 'ReactCompositeComponent'
931
+ ) : invariant(typeof this.state === 'object' && !Array.isArray(this.state)));
932
+
933
+ this._pendingState = null;
934
+ this._pendingForceUpdate = false;
935
+
936
+ if (this.componentWillMount) {
937
+ this.componentWillMount();
938
+ // When mounting, calls to `setState` by `componentWillMount` will set
939
+ // `this._pendingState` without triggering a re-render.
940
+ if (this._pendingState) {
941
+ this.state = this._pendingState;
942
+ this._pendingState = null;
943
+ }
944
+ }
945
+
946
+ this._renderedComponent = instantiateReactComponent(
947
+ this._renderValidatedComponent()
948
+ );
949
+
950
+ // Done with mounting, `setState` will now trigger UI changes.
951
+ this._compositeLifeCycleState = null;
952
+ var markup = this._renderedComponent.mountComponent(
953
+ rootID,
954
+ transaction,
955
+ mountDepth + 1
956
+ );
957
+ if (this.componentDidMount) {
958
+ transaction.getReactMountReady().enqueue(this, this.componentDidMount);
959
+ }
960
+ return markup;
961
+ }
962
+ ),
963
+
964
+ /**
965
+ * Releases any resources allocated by `mountComponent`.
966
+ *
967
+ * @final
968
+ * @internal
969
+ */
970
+ unmountComponent: function() {
971
+ this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING;
972
+ if (this.componentWillUnmount) {
973
+ this.componentWillUnmount();
974
+ }
975
+ this._compositeLifeCycleState = null;
976
+
977
+ this._defaultProps = null;
978
+
979
+ this._renderedComponent.unmountComponent();
980
+ this._renderedComponent = null;
981
+
982
+ ReactComponent.Mixin.unmountComponent.call(this);
983
+
984
+ // Some existing components rely on this.props even after they've been
985
+ // destroyed (in event handlers).
986
+ // TODO: this.props = null;
987
+ // TODO: this.state = null;
988
+ },
989
+
990
+ /**
991
+ * Sets a subset of the state. Always use this or `replaceState` to mutate
992
+ * state. You should treat `this.state` as immutable.
993
+ *
994
+ * There is no guarantee that `this.state` will be immediately updated, so
995
+ * accessing `this.state` after calling this method may return the old value.
996
+ *
997
+ * There is no guarantee that calls to `setState` will run synchronously,
998
+ * as they may eventually be batched together. You can provide an optional
999
+ * callback that will be executed when the call to setState is actually
1000
+ * completed.
1001
+ *
1002
+ * @param {object} partialState Next partial state to be merged with state.
1003
+ * @param {?function} callback Called after state is updated.
1004
+ * @final
1005
+ * @protected
1006
+ */
1007
+ setState: function(partialState, callback) {
1008
+ ("production" !== process.env.NODE_ENV ? invariant(
1009
+ typeof partialState === 'object' || partialState == null,
1010
+ 'setState(...): takes an object of state variables to update.'
1011
+ ) : invariant(typeof partialState === 'object' || partialState == null));
1012
+ if ("production" !== process.env.NODE_ENV) {
1013
+ ("production" !== process.env.NODE_ENV ? warning(
1014
+ partialState != null,
1015
+ 'setState(...): You passed an undefined or null state object; ' +
1016
+ 'instead, use forceUpdate().'
1017
+ ) : null);
1018
+ }
1019
+ // Merge with `_pendingState` if it exists, otherwise with existing state.
1020
+ this.replaceState(
1021
+ merge(this._pendingState || this.state, partialState),
1022
+ callback
1023
+ );
1024
+ },
1025
+
1026
+ /**
1027
+ * Replaces all of the state. Always use this or `setState` to mutate state.
1028
+ * You should treat `this.state` as immutable.
1029
+ *
1030
+ * There is no guarantee that `this.state` will be immediately updated, so
1031
+ * accessing `this.state` after calling this method may return the old value.
1032
+ *
1033
+ * @param {object} completeState Next state.
1034
+ * @param {?function} callback Called after state is updated.
1035
+ * @final
1036
+ * @protected
1037
+ */
1038
+ replaceState: function(completeState, callback) {
1039
+ validateLifeCycleOnReplaceState(this);
1040
+ this._pendingState = completeState;
1041
+ ReactUpdates.enqueueUpdate(this, callback);
1042
+ },
1043
+
1044
+ /**
1045
+ * Filters the context object to only contain keys specified in
1046
+ * `contextTypes`, and asserts that they are valid.
1047
+ *
1048
+ * @param {object} context
1049
+ * @return {?object}
1050
+ * @private
1051
+ */
1052
+ _processContext: function(context) {
1053
+ var maskedContext = null;
1054
+ var contextTypes = this.constructor.contextTypes;
1055
+ if (contextTypes) {
1056
+ maskedContext = {};
1057
+ for (var contextName in contextTypes) {
1058
+ maskedContext[contextName] = context[contextName];
1059
+ }
1060
+ if ("production" !== process.env.NODE_ENV) {
1061
+ this._checkPropTypes(
1062
+ contextTypes,
1063
+ maskedContext,
1064
+ ReactPropTypeLocations.context
1065
+ );
1066
+ }
1067
+ }
1068
+ return maskedContext;
1069
+ },
1070
+
1071
+ /**
1072
+ * @param {object} currentContext
1073
+ * @return {object}
1074
+ * @private
1075
+ */
1076
+ _processChildContext: function(currentContext) {
1077
+ var childContext = this.getChildContext && this.getChildContext();
1078
+ var displayName = this.constructor.displayName || 'ReactCompositeComponent';
1079
+ if (childContext) {
1080
+ ("production" !== process.env.NODE_ENV ? invariant(
1081
+ typeof this.constructor.childContextTypes === 'object',
1082
+ '%s.getChildContext(): childContextTypes must be defined in order to ' +
1083
+ 'use getChildContext().',
1084
+ displayName
1085
+ ) : invariant(typeof this.constructor.childContextTypes === 'object'));
1086
+ if ("production" !== process.env.NODE_ENV) {
1087
+ this._checkPropTypes(
1088
+ this.constructor.childContextTypes,
1089
+ childContext,
1090
+ ReactPropTypeLocations.childContext
1091
+ );
1092
+ }
1093
+ for (var name in childContext) {
1094
+ ("production" !== process.env.NODE_ENV ? invariant(
1095
+ name in this.constructor.childContextTypes,
1096
+ '%s.getChildContext(): key "%s" is not defined in childContextTypes.',
1097
+ displayName,
1098
+ name
1099
+ ) : invariant(name in this.constructor.childContextTypes));
1100
+ }
1101
+ return merge(currentContext, childContext);
1102
+ }
1103
+ return currentContext;
1104
+ },
1105
+
1106
+ /**
1107
+ * Processes props by setting default values for unspecified props and
1108
+ * asserting that the props are valid. Does not mutate its argument; returns
1109
+ * a new props object with defaults merged in.
1110
+ *
1111
+ * @param {object} newProps
1112
+ * @return {object}
1113
+ * @private
1114
+ */
1115
+ _processProps: function(newProps) {
1116
+ var props = merge(newProps);
1117
+ var defaultProps = this._defaultProps;
1118
+ for (var propName in defaultProps) {
1119
+ if (typeof props[propName] === 'undefined') {
1120
+ props[propName] = defaultProps[propName];
1121
+ }
1122
+ }
1123
+ if ("production" !== process.env.NODE_ENV) {
1124
+ var propTypes = this.constructor.propTypes;
1125
+ if (propTypes) {
1126
+ this._checkPropTypes(propTypes, props, ReactPropTypeLocations.prop);
1127
+ }
1128
+ }
1129
+ return props;
1130
+ },
1131
+
1132
+ /**
1133
+ * Assert that the props are valid
1134
+ *
1135
+ * @param {object} propTypes Map of prop name to a ReactPropType
1136
+ * @param {object} props
1137
+ * @param {string} location e.g. "prop", "context", "child context"
1138
+ * @private
1139
+ */
1140
+ _checkPropTypes: function(propTypes, props, location) {
1141
+ var componentName = this.constructor.displayName;
1142
+ for (var propName in propTypes) {
1143
+ if (propTypes.hasOwnProperty(propName)) {
1144
+ propTypes[propName](props, propName, componentName, location);
1145
+ }
1146
+ }
1147
+ },
1148
+
1149
+ performUpdateIfNecessary: function() {
1150
+ var compositeLifeCycleState = this._compositeLifeCycleState;
1151
+ // Do not trigger a state transition if we are in the middle of mounting or
1152
+ // receiving props because both of those will already be doing this.
1153
+ if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING ||
1154
+ compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) {
1155
+ return;
1156
+ }
1157
+ ReactComponent.Mixin.performUpdateIfNecessary.call(this);
1158
+ },
1159
+
1160
+ /**
1161
+ * If any of `_pendingProps`, `_pendingState`, or `_pendingForceUpdate` is
1162
+ * set, update the component.
1163
+ *
1164
+ * @param {ReactReconcileTransaction} transaction
1165
+ * @internal
1166
+ */
1167
+ _performUpdateIfNecessary: function(transaction) {
1168
+ if (this._pendingProps == null &&
1169
+ this._pendingState == null &&
1170
+ this._pendingContext == null &&
1171
+ !this._pendingForceUpdate) {
1172
+ return;
1173
+ }
1174
+
1175
+ var nextFullContext = this._pendingContext || this._currentContext;
1176
+ var nextContext = this._processContext(nextFullContext);
1177
+ this._pendingContext = null;
1178
+
1179
+ var nextProps = this.props;
1180
+ if (this._pendingProps != null) {
1181
+ nextProps = this._processProps(this._pendingProps);
1182
+ this._pendingProps = null;
1183
+
1184
+ this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS;
1185
+ if (this.componentWillReceiveProps) {
1186
+ this.componentWillReceiveProps(nextProps, nextContext);
1187
+ }
1188
+ }
1189
+
1190
+ this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_STATE;
1191
+
1192
+ // Unlike props, state, and context, we specifically don't want to set
1193
+ // _pendingOwner to null here because it's possible for a component to have
1194
+ // a null owner, so we instead make `this._owner === this._pendingOwner`
1195
+ // mean that there's no owner change pending.
1196
+ var nextOwner = this._pendingOwner;
1197
+
1198
+ var nextState = this._pendingState || this.state;
1199
+ this._pendingState = null;
1200
+
1201
+ try {
1202
+ if (this._pendingForceUpdate ||
1203
+ !this.shouldComponentUpdate ||
1204
+ this.shouldComponentUpdate(nextProps, nextState, nextContext)) {
1205
+ this._pendingForceUpdate = false;
1206
+ // Will set `this.props`, `this.state` and `this.context`.
1207
+ this._performComponentUpdate(
1208
+ nextProps,
1209
+ nextOwner,
1210
+ nextState,
1211
+ nextFullContext,
1212
+ nextContext,
1213
+ transaction
1214
+ );
1215
+ } else {
1216
+ // If it's determined that a component should not update, we still want
1217
+ // to set props and state.
1218
+ this.props = nextProps;
1219
+ this._owner = nextOwner;
1220
+ this.state = nextState;
1221
+ this._currentContext = nextFullContext;
1222
+ this.context = nextContext;
1223
+ }
1224
+ } finally {
1225
+ this._compositeLifeCycleState = null;
1226
+ }
1227
+ },
1228
+
1229
+ /**
1230
+ * Merges new props and state, notifies delegate methods of update and
1231
+ * performs update.
1232
+ *
1233
+ * @param {object} nextProps Next object to set as properties.
1234
+ * @param {?ReactComponent} nextOwner Next component to set as owner
1235
+ * @param {?object} nextState Next object to set as state.
1236
+ * @param {?object} nextFullContext Next object to set as _currentContext.
1237
+ * @param {?object} nextContext Next object to set as context.
1238
+ * @param {ReactReconcileTransaction} transaction
1239
+ * @private
1240
+ */
1241
+ _performComponentUpdate: function(
1242
+ nextProps,
1243
+ nextOwner,
1244
+ nextState,
1245
+ nextFullContext,
1246
+ nextContext,
1247
+ transaction
1248
+ ) {
1249
+ var prevProps = this.props;
1250
+ var prevOwner = this._owner;
1251
+ var prevState = this.state;
1252
+ var prevContext = this.context;
1253
+
1254
+ if (this.componentWillUpdate) {
1255
+ this.componentWillUpdate(nextProps, nextState, nextContext);
1256
+ }
1257
+
1258
+ this.props = nextProps;
1259
+ this._owner = nextOwner;
1260
+ this.state = nextState;
1261
+ this._currentContext = nextFullContext;
1262
+ this.context = nextContext;
1263
+
1264
+ this.updateComponent(
1265
+ transaction,
1266
+ prevProps,
1267
+ prevOwner,
1268
+ prevState,
1269
+ prevContext
1270
+ );
1271
+
1272
+ if (this.componentDidUpdate) {
1273
+ transaction.getReactMountReady().enqueue(
1274
+ this,
1275
+ this.componentDidUpdate.bind(this, prevProps, prevState, prevContext)
1276
+ );
1277
+ }
1278
+ },
1279
+
1280
+ receiveComponent: function(nextComponent, transaction) {
1281
+ if (nextComponent === this._descriptor) {
1282
+ // Since props and context are immutable after the component is
1283
+ // mounted, we can do a cheap identity compare here to determine
1284
+ // if this is a superfluous reconcile.
1285
+ return;
1286
+ }
1287
+
1288
+ // Update the descriptor that was last used by this component instance
1289
+ this._descriptor = nextComponent;
1290
+
1291
+ this._pendingContext = nextComponent._currentContext;
1292
+ ReactComponent.Mixin.receiveComponent.call(
1293
+ this,
1294
+ nextComponent,
1295
+ transaction
1296
+ );
1297
+ },
1298
+
1299
+ /**
1300
+ * Updates the component's currently mounted DOM representation.
1301
+ *
1302
+ * By default, this implements React's rendering and reconciliation algorithm.
1303
+ * Sophisticated clients may wish to override this.
1304
+ *
1305
+ * @param {ReactReconcileTransaction} transaction
1306
+ * @param {object} prevProps
1307
+ * @param {?ReactComponent} prevOwner
1308
+ * @param {?object} prevState
1309
+ * @param {?object} prevContext
1310
+ * @internal
1311
+ * @overridable
1312
+ */
1313
+ updateComponent: ReactPerf.measure(
1314
+ 'ReactCompositeComponent',
1315
+ 'updateComponent',
1316
+ function(transaction, prevProps, prevOwner, prevState, prevContext) {
1317
+ ReactComponent.Mixin.updateComponent.call(
1318
+ this,
1319
+ transaction,
1320
+ prevProps,
1321
+ prevOwner
1322
+ );
1323
+
1324
+
1325
+ var prevComponentInstance = this._renderedComponent;
1326
+ var nextComponent = this._renderValidatedComponent();
1327
+ if (shouldUpdateReactComponent(prevComponentInstance, nextComponent)) {
1328
+ prevComponentInstance.receiveComponent(nextComponent, transaction);
1329
+ } else {
1330
+ // These two IDs are actually the same! But nothing should rely on that.
1331
+ var thisID = this._rootNodeID;
1332
+ var prevComponentID = prevComponentInstance._rootNodeID;
1333
+ prevComponentInstance.unmountComponent();
1334
+ this._renderedComponent = instantiateReactComponent(nextComponent);
1335
+ var nextMarkup = this._renderedComponent.mountComponent(
1336
+ thisID,
1337
+ transaction,
1338
+ this._mountDepth + 1
1339
+ );
1340
+ ReactComponent.BackendIDOperations.dangerouslyReplaceNodeWithMarkupByID(
1341
+ prevComponentID,
1342
+ nextMarkup
1343
+ );
1344
+ }
1345
+ }
1346
+ ),
1347
+
1348
+ /**
1349
+ * Forces an update. This should only be invoked when it is known with
1350
+ * certainty that we are **not** in a DOM transaction.
1351
+ *
1352
+ * You may want to call this when you know that some deeper aspect of the
1353
+ * component's state has changed but `setState` was not called.
1354
+ *
1355
+ * This will not invoke `shouldUpdateComponent`, but it will invoke
1356
+ * `componentWillUpdate` and `componentDidUpdate`.
1357
+ *
1358
+ * @param {?function} callback Called after update is complete.
1359
+ * @final
1360
+ * @protected
1361
+ */
1362
+ forceUpdate: function(callback) {
1363
+ var compositeLifeCycleState = this._compositeLifeCycleState;
1364
+ ("production" !== process.env.NODE_ENV ? invariant(
1365
+ this.isMounted() ||
1366
+ compositeLifeCycleState === CompositeLifeCycle.MOUNTING,
1367
+ 'forceUpdate(...): Can only force an update on mounted or mounting ' +
1368
+ 'components.'
1369
+ ) : invariant(this.isMounted() ||
1370
+ compositeLifeCycleState === CompositeLifeCycle.MOUNTING));
1371
+ ("production" !== process.env.NODE_ENV ? invariant(
1372
+ compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
1373
+ compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING,
1374
+ 'forceUpdate(...): Cannot force an update while unmounting component ' +
1375
+ 'or during an existing state transition (such as within `render`).'
1376
+ ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.RECEIVING_STATE &&
1377
+ compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING));
1378
+ this._pendingForceUpdate = true;
1379
+ ReactUpdates.enqueueUpdate(this, callback);
1380
+ },
1381
+
1382
+ /**
1383
+ * @private
1384
+ */
1385
+ _renderValidatedComponent: ReactPerf.measure(
1386
+ 'ReactCompositeComponent',
1387
+ '_renderValidatedComponent',
1388
+ function() {
1389
+ var renderedComponent;
1390
+ var previousContext = ReactContext.current;
1391
+ ReactContext.current = this._processChildContext(this._currentContext);
1392
+ ReactCurrentOwner.current = this;
1393
+ try {
1394
+ renderedComponent = this.render();
1395
+ } finally {
1396
+ ReactContext.current = previousContext;
1397
+ ReactCurrentOwner.current = null;
1398
+ }
1399
+ ("production" !== process.env.NODE_ENV ? invariant(
1400
+ ReactComponent.isValidComponent(renderedComponent),
1401
+ '%s.render(): A valid ReactComponent must be returned. You may have ' +
1402
+ 'returned null, undefined, an array, or some other invalid object.',
1403
+ this.constructor.displayName || 'ReactCompositeComponent'
1404
+ ) : invariant(ReactComponent.isValidComponent(renderedComponent)));
1405
+ return renderedComponent;
1406
+ }
1407
+ ),
1408
+
1409
+ /**
1410
+ * @private
1411
+ */
1412
+ _bindAutoBindMethods: function() {
1413
+ for (var autoBindKey in this.__reactAutoBindMap) {
1414
+ if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) {
1415
+ continue;
1416
+ }
1417
+ var method = this.__reactAutoBindMap[autoBindKey];
1418
+ this[autoBindKey] = this._bindAutoBindMethod(ReactErrorUtils.guard(
1419
+ method,
1420
+ this.constructor.displayName + '.' + autoBindKey
1421
+ ));
1422
+ }
1423
+ },
1424
+
1425
+ /**
1426
+ * Binds a method to the component.
1427
+ *
1428
+ * @param {function} method Method to be bound.
1429
+ * @private
1430
+ */
1431
+ _bindAutoBindMethod: function(method) {
1432
+ var component = this;
1433
+ var boundMethod = function() {
1434
+ return method.apply(component, arguments);
1435
+ };
1436
+ if ("production" !== process.env.NODE_ENV) {
1437
+ boundMethod.__reactBoundContext = component;
1438
+ boundMethod.__reactBoundMethod = method;
1439
+ boundMethod.__reactBoundArguments = null;
1440
+ var componentName = component.constructor.displayName;
1441
+ var _bind = boundMethod.bind;
1442
+ boundMethod.bind = function(newThis ) {var args=Array.prototype.slice.call(arguments,1);
1443
+ // User is trying to bind() an autobound method; we effectively will
1444
+ // ignore the value of "this" that the user is trying to use, so
1445
+ // let's warn.
1446
+ if (newThis !== component && newThis !== null) {
1447
+ monitorCodeUse('react_bind_warning', { component: componentName });
1448
+ console.warn(
1449
+ 'bind(): React component methods may only be bound to the ' +
1450
+ 'component instance. See ' + componentName
1451
+ );
1452
+ } else if (!args.length) {
1453
+ monitorCodeUse('react_bind_warning', { component: componentName });
1454
+ console.warn(
1455
+ 'bind(): You are binding a component method to the component. ' +
1456
+ 'React does this for you automatically in a high-performance ' +
1457
+ 'way, so you can safely remove this call. See ' + componentName
1458
+ );
1459
+ return boundMethod;
1460
+ }
1461
+ var reboundMethod = _bind.apply(boundMethod, arguments);
1462
+ reboundMethod.__reactBoundContext = component;
1463
+ reboundMethod.__reactBoundMethod = method;
1464
+ reboundMethod.__reactBoundArguments = args;
1465
+ return reboundMethod;
1466
+ };
1467
+ }
1468
+ return boundMethod;
1469
+ }
1470
+ };
1471
+
1472
+ var ReactCompositeComponentBase = function() {};
1473
+ mixInto(ReactCompositeComponentBase, ReactComponent.Mixin);
1474
+ mixInto(ReactCompositeComponentBase, ReactOwner.Mixin);
1475
+ mixInto(ReactCompositeComponentBase, ReactPropTransferer.Mixin);
1476
+ mixInto(ReactCompositeComponentBase, ReactCompositeComponentMixin);
1477
+
1478
+ /**
1479
+ * Checks if a value is a valid component constructor.
1480
+ *
1481
+ * @param {*}
1482
+ * @return {boolean}
1483
+ * @public
1484
+ */
1485
+ function isValidClass(componentClass) {
1486
+ return componentClass instanceof Function &&
1487
+ 'componentConstructor' in componentClass &&
1488
+ componentClass.componentConstructor instanceof Function;
1489
+ }
1490
+ /**
1491
+ * Module for creating composite components.
1492
+ *
1493
+ * @class ReactCompositeComponent
1494
+ * @extends ReactComponent
1495
+ * @extends ReactOwner
1496
+ * @extends ReactPropTransferer
1497
+ */
1498
+ var ReactCompositeComponent = {
1499
+
1500
+ LifeCycle: CompositeLifeCycle,
1501
+
1502
+ Base: ReactCompositeComponentBase,
1503
+
1504
+ /**
1505
+ * Creates a composite component class given a class specification.
1506
+ *
1507
+ * @param {object} spec Class specification (which must define `render`).
1508
+ * @return {function} Component constructor function.
1509
+ * @public
1510
+ */
1511
+ createClass: function(spec) {
1512
+ var Constructor = function() {};
1513
+ Constructor.prototype = new ReactCompositeComponentBase();
1514
+ Constructor.prototype.constructor = Constructor;
1515
+
1516
+ var DescriptorConstructor = Constructor;
1517
+
1518
+ var ConvenienceConstructor = function(props, children) {
1519
+ var descriptor = new DescriptorConstructor();
1520
+ descriptor.construct.apply(descriptor, arguments);
1521
+ return descriptor;
1522
+ };
1523
+ ConvenienceConstructor.componentConstructor = Constructor;
1524
+ Constructor.ConvenienceConstructor = ConvenienceConstructor;
1525
+ ConvenienceConstructor.originalSpec = spec;
1526
+
1527
+ injectedMixins.forEach(
1528
+ mixSpecIntoComponent.bind(null, ConvenienceConstructor)
1529
+ );
1530
+
1531
+ mixSpecIntoComponent(ConvenienceConstructor, spec);
1532
+
1533
+ ("production" !== process.env.NODE_ENV ? invariant(
1534
+ Constructor.prototype.render,
1535
+ 'createClass(...): Class specification must implement a `render` method.'
1536
+ ) : invariant(Constructor.prototype.render));
1537
+
1538
+ if ("production" !== process.env.NODE_ENV) {
1539
+ if (Constructor.prototype.componentShouldUpdate) {
1540
+ monitorCodeUse(
1541
+ 'react_component_should_update_warning',
1542
+ { component: spec.displayName }
1543
+ );
1544
+ console.warn(
1545
+ (spec.displayName || 'A component') + ' has a method called ' +
1546
+ 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' +
1547
+ 'The name is phrased as a question because the function is ' +
1548
+ 'expected to return a value.'
1549
+ );
1550
+ }
1551
+ }
1552
+
1553
+ // Expose the convience constructor on the prototype so that it can be
1554
+ // easily accessed on descriptors. E.g. <Foo />.type === Foo.type and for
1555
+ // static methods like <Foo />.type.staticMethod();
1556
+ // This should not be named constructor since this may not be the function
1557
+ // that created the descriptor, and it may not even be a constructor.
1558
+ ConvenienceConstructor.type = Constructor;
1559
+ Constructor.prototype.type = Constructor;
1560
+
1561
+ // Reduce time spent doing lookups by setting these on the prototype.
1562
+ for (var methodName in ReactCompositeComponentInterface) {
1563
+ if (!Constructor.prototype[methodName]) {
1564
+ Constructor.prototype[methodName] = null;
1565
+ }
1566
+ }
1567
+
1568
+ if ("production" !== process.env.NODE_ENV) {
1569
+ // In DEV the convenience constructor generates a proxy to another
1570
+ // instance around it to warn about access to properties on the
1571
+ // descriptor.
1572
+ DescriptorConstructor = createDescriptorProxy(Constructor);
1573
+ }
1574
+
1575
+ return ConvenienceConstructor;
1576
+ },
1577
+
1578
+ isValidClass: isValidClass,
1579
+
1580
+ injection: {
1581
+ injectMixin: function(mixin) {
1582
+ injectedMixins.push(mixin);
1583
+ }
1584
+ }
1585
+ };
1586
+
1587
+ module.exports = ReactCompositeComponent;