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,39 @@
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 ReactCurrentOwner
17
+ */
18
+
19
+ "use strict";
20
+
21
+ /**
22
+ * Keeps track of the current owner.
23
+ *
24
+ * The current owner is the component who should own any components that are
25
+ * currently being constructed.
26
+ *
27
+ * The depth indicate how many composite components are above this render level.
28
+ */
29
+ var ReactCurrentOwner = {
30
+
31
+ /**
32
+ * @internal
33
+ * @type {ReactComponent}
34
+ */
35
+ current: null
36
+
37
+ };
38
+
39
+ module.exports = ReactCurrentOwner;
@@ -0,0 +1,194 @@
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 ReactDOM
17
+ * @typechecks static-only
18
+ */
19
+
20
+ "use strict";
21
+
22
+ var ReactDOMComponent = require("./ReactDOMComponent");
23
+
24
+ var mergeInto = require("./mergeInto");
25
+ var objMapKeyVal = require("./objMapKeyVal");
26
+
27
+ /**
28
+ * Creates a new React class that is idempotent and capable of containing other
29
+ * React components. It accepts event listeners and DOM properties that are
30
+ * valid according to `DOMProperty`.
31
+ *
32
+ * - Event listeners: `onClick`, `onMouseDown`, etc.
33
+ * - DOM properties: `className`, `name`, `title`, etc.
34
+ *
35
+ * The `style` property functions differently from the DOM API. It accepts an
36
+ * object mapping of style properties to values.
37
+ *
38
+ * @param {string} tag Tag name (e.g. `div`).
39
+ * @param {boolean} omitClose True if the close tag should be omitted.
40
+ * @private
41
+ */
42
+ function createDOMComponentClass(tag, omitClose) {
43
+ var Constructor = function() {};
44
+ Constructor.prototype = new ReactDOMComponent(tag, omitClose);
45
+ Constructor.prototype.constructor = Constructor;
46
+ Constructor.displayName = tag;
47
+
48
+ var ConvenienceConstructor = function(props, children) {
49
+ var instance = new Constructor();
50
+ instance.construct.apply(instance, arguments);
51
+ return instance;
52
+ };
53
+ ConvenienceConstructor.componentConstructor = Constructor;
54
+ return ConvenienceConstructor;
55
+ }
56
+
57
+ /**
58
+ * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes.
59
+ * This is also accessible via `React.DOM`.
60
+ *
61
+ * @public
62
+ */
63
+ var ReactDOM = objMapKeyVal({
64
+ a: false,
65
+ abbr: false,
66
+ address: false,
67
+ area: false,
68
+ article: false,
69
+ aside: false,
70
+ audio: false,
71
+ b: false,
72
+ base: false,
73
+ bdi: false,
74
+ bdo: false,
75
+ big: false,
76
+ blockquote: false,
77
+ body: false,
78
+ br: true,
79
+ button: false,
80
+ canvas: false,
81
+ caption: false,
82
+ cite: false,
83
+ code: false,
84
+ col: true,
85
+ colgroup: false,
86
+ data: false,
87
+ datalist: false,
88
+ dd: false,
89
+ del: false,
90
+ details: false,
91
+ dfn: false,
92
+ div: false,
93
+ dl: false,
94
+ dt: false,
95
+ em: false,
96
+ embed: true,
97
+ fieldset: false,
98
+ figcaption: false,
99
+ figure: false,
100
+ footer: false,
101
+ form: false, // NOTE: Injected, see `ReactDOMForm`.
102
+ h1: false,
103
+ h2: false,
104
+ h3: false,
105
+ h4: false,
106
+ h5: false,
107
+ h6: false,
108
+ head: false,
109
+ header: false,
110
+ hr: true,
111
+ html: false,
112
+ i: false,
113
+ iframe: false,
114
+ img: true,
115
+ input: true,
116
+ ins: false,
117
+ kbd: false,
118
+ keygen: true,
119
+ label: false,
120
+ legend: false,
121
+ li: false,
122
+ link: false,
123
+ main: false,
124
+ map: false,
125
+ mark: false,
126
+ menu: false,
127
+ menuitem: false, // NOTE: Close tag should be omitted, but causes problems.
128
+ meta: true,
129
+ meter: false,
130
+ nav: false,
131
+ noscript: false,
132
+ object: false,
133
+ ol: false,
134
+ optgroup: false,
135
+ option: false,
136
+ output: false,
137
+ p: false,
138
+ param: true,
139
+ pre: false,
140
+ progress: false,
141
+ q: false,
142
+ rp: false,
143
+ rt: false,
144
+ ruby: false,
145
+ s: false,
146
+ samp: false,
147
+ script: false,
148
+ section: false,
149
+ select: false,
150
+ small: false,
151
+ source: false,
152
+ span: false,
153
+ strong: false,
154
+ style: false,
155
+ sub: false,
156
+ summary: false,
157
+ sup: false,
158
+ table: false,
159
+ tbody: false,
160
+ td: false,
161
+ textarea: false, // NOTE: Injected, see `ReactDOMTextarea`.
162
+ tfoot: false,
163
+ th: false,
164
+ thead: false,
165
+ time: false,
166
+ title: false,
167
+ tr: false,
168
+ track: true,
169
+ u: false,
170
+ ul: false,
171
+ 'var': false,
172
+ video: false,
173
+ wbr: false,
174
+
175
+ // SVG
176
+ circle: false,
177
+ g: false,
178
+ line: false,
179
+ path: false,
180
+ polyline: false,
181
+ rect: false,
182
+ svg: false,
183
+ text: false
184
+ }, createDOMComponentClass);
185
+
186
+ var injection = {
187
+ injectComponentClasses: function(componentClasses) {
188
+ mergeInto(ReactDOM, componentClasses);
189
+ }
190
+ };
191
+
192
+ ReactDOM.injection = injection;
193
+
194
+ module.exports = ReactDOM;
@@ -0,0 +1,64 @@
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 ReactDOMButton
17
+ */
18
+
19
+ "use strict";
20
+
21
+ var ReactCompositeComponent = require("./ReactCompositeComponent");
22
+ var ReactDOM = require("./ReactDOM");
23
+
24
+ var keyMirror = require("./keyMirror");
25
+
26
+ // Store a reference to the <button> `ReactDOMComponent`.
27
+ var button = ReactDOM.button;
28
+
29
+ var mouseListenerNames = keyMirror({
30
+ onClick: true,
31
+ onDoubleClick: true,
32
+ onMouseDown: true,
33
+ onMouseMove: true,
34
+ onMouseUp: true,
35
+ onClickCapture: true,
36
+ onDoubleClickCapture: true,
37
+ onMouseDownCapture: true,
38
+ onMouseMoveCapture: true,
39
+ onMouseUpCapture: true
40
+ });
41
+
42
+ /**
43
+ * Implements a <button> native component that does not receive mouse events
44
+ * when `disabled` is set.
45
+ */
46
+ var ReactDOMButton = ReactCompositeComponent.createClass({
47
+
48
+ render: function() {
49
+ var props = {};
50
+
51
+ // Copy the props; except the mouse listeners if we're disabled
52
+ for (var key in this.props) {
53
+ if (this.props.hasOwnProperty(key) &&
54
+ (!this.props.disabled || !mouseListenerNames[key])) {
55
+ props[key] = this.props[key];
56
+ }
57
+ }
58
+
59
+ return button(props, this.props.children);
60
+ }
61
+
62
+ });
63
+
64
+ module.exports = ReactDOMButton;
@@ -0,0 +1,374 @@
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 ReactDOMComponent
17
+ * @typechecks static-only
18
+ */
19
+
20
+ "use strict";
21
+
22
+ var CSSPropertyOperations = require("./CSSPropertyOperations");
23
+ var DOMProperty = require("./DOMProperty");
24
+ var DOMPropertyOperations = require("./DOMPropertyOperations");
25
+ var ReactComponent = require("./ReactComponent");
26
+ var ReactEventEmitter = require("./ReactEventEmitter");
27
+ var ReactMultiChild = require("./ReactMultiChild");
28
+ var ReactMount = require("./ReactMount");
29
+ var ReactPerf = require("./ReactPerf");
30
+
31
+ var escapeTextForBrowser = require("./escapeTextForBrowser");
32
+ var invariant = require("./invariant");
33
+ var keyOf = require("./keyOf");
34
+ var merge = require("./merge");
35
+ var mixInto = require("./mixInto");
36
+
37
+ var putListener = ReactEventEmitter.putListener;
38
+ var deleteListener = ReactEventEmitter.deleteListener;
39
+ var registrationNames = ReactEventEmitter.registrationNames;
40
+
41
+ // For quickly matching children type, to test if can be treated as content.
42
+ var CONTENT_TYPES = {'string': true, 'number': true};
43
+
44
+ var STYLE = keyOf({style: null});
45
+
46
+ /**
47
+ * @param {?object} props
48
+ */
49
+ function assertValidProps(props) {
50
+ if (!props) {
51
+ return;
52
+ }
53
+ // Note the use of `==` which checks for null or undefined.
54
+ ("production" !== process.env.NODE_ENV ? invariant(
55
+ props.children == null || props.dangerouslySetInnerHTML == null,
56
+ 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.'
57
+ ) : invariant(props.children == null || props.dangerouslySetInnerHTML == null));
58
+ ("production" !== process.env.NODE_ENV ? invariant(
59
+ props.style == null || typeof props.style === 'object',
60
+ 'The `style` prop expects a mapping from style properties to values, ' +
61
+ 'not a string.'
62
+ ) : invariant(props.style == null || typeof props.style === 'object'));
63
+ }
64
+
65
+ /**
66
+ * @constructor ReactDOMComponent
67
+ * @extends ReactComponent
68
+ * @extends ReactMultiChild
69
+ */
70
+ function ReactDOMComponent(tag, omitClose) {
71
+ this._tagOpen = '<' + tag;
72
+ this._tagClose = omitClose ? '' : '</' + tag + '>';
73
+ this.tagName = tag.toUpperCase();
74
+ }
75
+
76
+ ReactDOMComponent.Mixin = {
77
+
78
+ /**
79
+ * Generates root tag markup then recurses. This method has side effects and
80
+ * is not idempotent.
81
+ *
82
+ * @internal
83
+ * @param {string} rootID The root DOM ID for this node.
84
+ * @param {ReactReconcileTransaction} transaction
85
+ * @param {number} mountDepth number of components in the owner hierarchy
86
+ * @return {string} The computed markup.
87
+ */
88
+ mountComponent: ReactPerf.measure(
89
+ 'ReactDOMComponent',
90
+ 'mountComponent',
91
+ function(rootID, transaction, mountDepth) {
92
+ ReactComponent.Mixin.mountComponent.call(
93
+ this,
94
+ rootID,
95
+ transaction,
96
+ mountDepth
97
+ );
98
+ assertValidProps(this.props);
99
+ return (
100
+ this._createOpenTagMarkup() +
101
+ this._createContentMarkup(transaction) +
102
+ this._tagClose
103
+ );
104
+ }
105
+ ),
106
+
107
+ /**
108
+ * Creates markup for the open tag and all attributes.
109
+ *
110
+ * This method has side effects because events get registered.
111
+ *
112
+ * Iterating over object properties is faster than iterating over arrays.
113
+ * @see http://jsperf.com/obj-vs-arr-iteration
114
+ *
115
+ * @private
116
+ * @return {string} Markup of opening tag.
117
+ */
118
+ _createOpenTagMarkup: function() {
119
+ var props = this.props;
120
+ var ret = this._tagOpen;
121
+
122
+ for (var propKey in props) {
123
+ if (!props.hasOwnProperty(propKey)) {
124
+ continue;
125
+ }
126
+ var propValue = props[propKey];
127
+ if (propValue == null) {
128
+ continue;
129
+ }
130
+ if (registrationNames[propKey]) {
131
+ putListener(this._rootNodeID, propKey, propValue);
132
+ } else {
133
+ if (propKey === STYLE) {
134
+ if (propValue) {
135
+ propValue = props.style = merge(props.style);
136
+ }
137
+ propValue = CSSPropertyOperations.createMarkupForStyles(propValue);
138
+ }
139
+ var markup =
140
+ DOMPropertyOperations.createMarkupForProperty(propKey, propValue);
141
+ if (markup) {
142
+ ret += ' ' + markup;
143
+ }
144
+ }
145
+ }
146
+
147
+ var escapedID = escapeTextForBrowser(this._rootNodeID);
148
+ return ret + ' ' + ReactMount.ATTR_NAME + '="' + escapedID + '">';
149
+ },
150
+
151
+ /**
152
+ * Creates markup for the content between the tags.
153
+ *
154
+ * @private
155
+ * @param {ReactReconcileTransaction} transaction
156
+ * @return {string} Content markup.
157
+ */
158
+ _createContentMarkup: function(transaction) {
159
+ // Intentional use of != to avoid catching zero/false.
160
+ var innerHTML = this.props.dangerouslySetInnerHTML;
161
+ if (innerHTML != null) {
162
+ if (innerHTML.__html != null) {
163
+ return innerHTML.__html;
164
+ }
165
+ } else {
166
+ var contentToUse =
167
+ CONTENT_TYPES[typeof this.props.children] ? this.props.children : null;
168
+ var childrenToUse = contentToUse != null ? null : this.props.children;
169
+ if (contentToUse != null) {
170
+ return escapeTextForBrowser(contentToUse);
171
+ } else if (childrenToUse != null) {
172
+ var mountImages = this.mountChildren(
173
+ childrenToUse,
174
+ transaction
175
+ );
176
+ return mountImages.join('');
177
+ }
178
+ }
179
+ return '';
180
+ },
181
+
182
+ receiveComponent: function(nextComponent, transaction) {
183
+ assertValidProps(nextComponent.props);
184
+ ReactComponent.Mixin.receiveComponent.call(
185
+ this,
186
+ nextComponent,
187
+ transaction
188
+ );
189
+ },
190
+
191
+ /**
192
+ * Updates a native DOM component after it has already been allocated and
193
+ * attached to the DOM. Reconciles the root DOM node, then recurses.
194
+ *
195
+ * @param {ReactReconcileTransaction} transaction
196
+ * @param {object} prevProps
197
+ * @internal
198
+ * @overridable
199
+ */
200
+ updateComponent: ReactPerf.measure(
201
+ 'ReactDOMComponent',
202
+ 'updateComponent',
203
+ function(transaction, prevProps) {
204
+ ReactComponent.Mixin.updateComponent.call(this, transaction, prevProps);
205
+ this._updateDOMProperties(prevProps);
206
+ this._updateDOMChildren(prevProps, transaction);
207
+ }
208
+ ),
209
+
210
+ /**
211
+ * Reconciles the properties by detecting differences in property values and
212
+ * updating the DOM as necessary. This function is probably the single most
213
+ * critical path for performance optimization.
214
+ *
215
+ * TODO: Benchmark whether checking for changed values in memory actually
216
+ * improves performance (especially statically positioned elements).
217
+ * TODO: Benchmark the effects of putting this at the top since 99% of props
218
+ * do not change for a given reconciliation.
219
+ * TODO: Benchmark areas that can be improved with caching.
220
+ *
221
+ * @private
222
+ * @param {object} lastProps
223
+ */
224
+ _updateDOMProperties: function(lastProps) {
225
+ var nextProps = this.props;
226
+ var propKey;
227
+ var styleName;
228
+ var styleUpdates;
229
+ for (propKey in lastProps) {
230
+ if (nextProps.hasOwnProperty(propKey) ||
231
+ !lastProps.hasOwnProperty(propKey)) {
232
+ continue;
233
+ }
234
+ if (propKey === STYLE) {
235
+ var lastStyle = lastProps[propKey];
236
+ for (styleName in lastStyle) {
237
+ if (lastStyle.hasOwnProperty(styleName)) {
238
+ styleUpdates = styleUpdates || {};
239
+ styleUpdates[styleName] = '';
240
+ }
241
+ }
242
+ } else if (registrationNames[propKey]) {
243
+ deleteListener(this._rootNodeID, propKey);
244
+ } else if (
245
+ DOMProperty.isStandardName[propKey] ||
246
+ DOMProperty.isCustomAttribute(propKey)) {
247
+ ReactComponent.DOMIDOperations.deletePropertyByID(
248
+ this._rootNodeID,
249
+ propKey
250
+ );
251
+ }
252
+ }
253
+ for (propKey in nextProps) {
254
+ var nextProp = nextProps[propKey];
255
+ var lastProp = lastProps[propKey];
256
+ if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp) {
257
+ continue;
258
+ }
259
+ if (propKey === STYLE) {
260
+ if (nextProp) {
261
+ nextProp = nextProps.style = merge(nextProp);
262
+ }
263
+ if (lastProp) {
264
+ // Unset styles on `lastProp` but not on `nextProp`.
265
+ for (styleName in lastProp) {
266
+ if (lastProp.hasOwnProperty(styleName) &&
267
+ !nextProp.hasOwnProperty(styleName)) {
268
+ styleUpdates = styleUpdates || {};
269
+ styleUpdates[styleName] = '';
270
+ }
271
+ }
272
+ // Update styles that changed since `lastProp`.
273
+ for (styleName in nextProp) {
274
+ if (nextProp.hasOwnProperty(styleName) &&
275
+ lastProp[styleName] !== nextProp[styleName]) {
276
+ styleUpdates = styleUpdates || {};
277
+ styleUpdates[styleName] = nextProp[styleName];
278
+ }
279
+ }
280
+ } else {
281
+ // Relies on `updateStylesByID` not mutating `styleUpdates`.
282
+ styleUpdates = nextProp;
283
+ }
284
+ } else if (registrationNames[propKey]) {
285
+ putListener(this._rootNodeID, propKey, nextProp);
286
+ } else if (
287
+ DOMProperty.isStandardName[propKey] ||
288
+ DOMProperty.isCustomAttribute(propKey)) {
289
+ ReactComponent.DOMIDOperations.updatePropertyByID(
290
+ this._rootNodeID,
291
+ propKey,
292
+ nextProp
293
+ );
294
+ }
295
+ }
296
+ if (styleUpdates) {
297
+ ReactComponent.DOMIDOperations.updateStylesByID(
298
+ this._rootNodeID,
299
+ styleUpdates
300
+ );
301
+ }
302
+ },
303
+
304
+ /**
305
+ * Reconciles the children with the various properties that affect the
306
+ * children content.
307
+ *
308
+ * @param {object} lastProps
309
+ * @param {ReactReconcileTransaction} transaction
310
+ */
311
+ _updateDOMChildren: function(lastProps, transaction) {
312
+ var nextProps = this.props;
313
+
314
+ var lastContent =
315
+ CONTENT_TYPES[typeof lastProps.children] ? lastProps.children : null;
316
+ var nextContent =
317
+ CONTENT_TYPES[typeof nextProps.children] ? nextProps.children : null;
318
+
319
+ var lastHtml =
320
+ lastProps.dangerouslySetInnerHTML &&
321
+ lastProps.dangerouslySetInnerHTML.__html;
322
+ var nextHtml =
323
+ nextProps.dangerouslySetInnerHTML &&
324
+ nextProps.dangerouslySetInnerHTML.__html;
325
+
326
+ // Note the use of `!=` which checks for null or undefined.
327
+ var lastChildren = lastContent != null ? null : lastProps.children;
328
+ var nextChildren = nextContent != null ? null : nextProps.children;
329
+
330
+ // If we're switching from children to content/html or vice versa, remove
331
+ // the old content
332
+ var lastHasContentOrHtml = lastContent != null || lastHtml != null;
333
+ var nextHasContentOrHtml = nextContent != null || nextHtml != null;
334
+ if (lastChildren != null && nextChildren == null) {
335
+ this.updateChildren(null, transaction);
336
+ } else if (lastHasContentOrHtml && !nextHasContentOrHtml) {
337
+ this.updateTextContent('');
338
+ }
339
+
340
+ if (nextContent != null) {
341
+ if (lastContent !== nextContent) {
342
+ this.updateTextContent('' + nextContent);
343
+ }
344
+ } else if (nextHtml != null) {
345
+ if (lastHtml !== nextHtml) {
346
+ ReactComponent.DOMIDOperations.updateInnerHTMLByID(
347
+ this._rootNodeID,
348
+ nextHtml
349
+ );
350
+ }
351
+ } else if (nextChildren != null) {
352
+ this.updateChildren(nextChildren, transaction);
353
+ }
354
+ },
355
+
356
+ /**
357
+ * Destroys all event registrations for this instance. Does not remove from
358
+ * the DOM. That must be done by the parent.
359
+ *
360
+ * @internal
361
+ */
362
+ unmountComponent: function() {
363
+ ReactEventEmitter.deleteAllListeners(this._rootNodeID);
364
+ ReactComponent.Mixin.unmountComponent.call(this);
365
+ this.unmountChildren();
366
+ }
367
+
368
+ };
369
+
370
+ mixInto(ReactDOMComponent, ReactComponent.Mixin);
371
+ mixInto(ReactDOMComponent, ReactDOMComponent.Mixin);
372
+ mixInto(ReactDOMComponent, ReactMultiChild.Mixin);
373
+
374
+ module.exports = ReactDOMComponent;