react 0.9.0 → 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 (44) hide show
  1. package/lib/AutoFocusMixin.js +3 -1
  2. package/lib/DOMChildrenOperations.js +12 -6
  3. package/lib/DOMProperty.js +6 -4
  4. package/lib/DOMPropertyOperations.js +6 -6
  5. package/lib/DefaultDOMPropertyConfig.js +5 -12
  6. package/lib/EventPluginHub.js +2 -0
  7. package/lib/LinkedValueUtils.js +22 -23
  8. package/lib/React.js +3 -1
  9. package/lib/ReactBrowserComponentMixin.js +42 -0
  10. package/lib/ReactCSSTransitionGroup.js +10 -10
  11. package/lib/ReactComponent.js +76 -31
  12. package/lib/ReactComponentBrowserEnvironment.js +1 -35
  13. package/lib/ReactCompositeComponent.js +199 -67
  14. package/lib/ReactDOM.js +5 -5
  15. package/lib/ReactDOMButton.js +2 -1
  16. package/lib/ReactDOMComponent.js +22 -5
  17. package/lib/ReactDOMForm.js +3 -0
  18. package/lib/ReactDOMImg.js +3 -0
  19. package/lib/ReactDOMInput.js +2 -1
  20. package/lib/ReactDOMOption.js +11 -7
  21. package/lib/ReactDOMSelect.js +2 -1
  22. package/lib/ReactDOMTextarea.js +7 -3
  23. package/lib/ReactDefaultInjection.js +10 -0
  24. package/lib/ReactInjection.js +4 -0
  25. package/lib/ReactInputSelection.js +2 -1
  26. package/lib/ReactMount.js +13 -5
  27. package/lib/ReactMultiChild.js +10 -3
  28. package/lib/ReactOwner.js +6 -1
  29. package/lib/ReactPropTransferer.js +1 -1
  30. package/lib/ReactReconcileTransaction.js +7 -6
  31. package/lib/ReactServerRendering.js +38 -8
  32. package/lib/ReactServerRenderingTransaction.js +116 -0
  33. package/lib/ReactTextComponent.js +24 -2
  34. package/lib/ReactWithAddons.js +3 -1
  35. package/lib/cloneWithProps.js +7 -7
  36. package/lib/{ReactComponentEnvironment.js → emptyObject.js} +6 -5
  37. package/lib/focusNode.js +33 -0
  38. package/lib/instantiateReactComponent.js +70 -0
  39. package/lib/isNode.js +1 -1
  40. package/lib/monitorCodeUse.js +37 -0
  41. package/lib/shouldUpdateReactComponent.js +17 -14
  42. package/lib/traverseAllChildren.js +2 -1
  43. package/lib/update.js +159 -0
  44. package/package.json +1 -1
package/lib/ReactDOM.js CHANGED
@@ -72,12 +72,12 @@ var ReactDOM = objMapKeyVal({
72
72
  a: false,
73
73
  abbr: false,
74
74
  address: false,
75
- area: false,
75
+ area: true,
76
76
  article: false,
77
77
  aside: false,
78
78
  audio: false,
79
79
  b: false,
80
- base: false,
80
+ base: true,
81
81
  bdi: false,
82
82
  bdo: false,
83
83
  big: false,
@@ -127,7 +127,7 @@ var ReactDOM = objMapKeyVal({
127
127
  label: false,
128
128
  legend: false,
129
129
  li: false,
130
- link: false,
130
+ link: true,
131
131
  main: false,
132
132
  map: false,
133
133
  mark: false,
@@ -156,7 +156,7 @@ var ReactDOM = objMapKeyVal({
156
156
  section: false,
157
157
  select: false,
158
158
  small: false,
159
- source: false,
159
+ source: true,
160
160
  span: false,
161
161
  strong: false,
162
162
  style: false,
@@ -178,7 +178,7 @@ var ReactDOM = objMapKeyVal({
178
178
  ul: false,
179
179
  'var': false,
180
180
  video: false,
181
- wbr: false,
181
+ wbr: true,
182
182
 
183
183
  // SVG
184
184
  circle: false,
@@ -19,6 +19,7 @@
19
19
  "use strict";
20
20
 
21
21
  var AutoFocusMixin = require("./AutoFocusMixin");
22
+ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
22
23
  var ReactCompositeComponent = require("./ReactCompositeComponent");
23
24
  var ReactDOM = require("./ReactDOM");
24
25
 
@@ -47,7 +48,7 @@ var mouseListenerNames = keyMirror({
47
48
  var ReactDOMButton = ReactCompositeComponent.createClass({
48
49
  displayName: 'ReactDOMButton',
49
50
 
50
- mixins: [AutoFocusMixin],
51
+ mixins: [AutoFocusMixin, ReactBrowserComponentMixin],
51
52
 
52
53
  render: function() {
53
54
  var props = {};
@@ -22,6 +22,7 @@
22
22
  var CSSPropertyOperations = require("./CSSPropertyOperations");
23
23
  var DOMProperty = require("./DOMProperty");
24
24
  var DOMPropertyOperations = require("./DOMPropertyOperations");
25
+ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
25
26
  var ReactComponent = require("./ReactComponent");
26
27
  var ReactEventEmitter = require("./ReactEventEmitter");
27
28
  var ReactMount = require("./ReactMount");
@@ -99,7 +100,7 @@ ReactDOMComponent.Mixin = {
99
100
  *
100
101
  * @internal
101
102
  * @param {string} rootID The root DOM ID for this node.
102
- * @param {ReactReconcileTransaction} transaction
103
+ * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
103
104
  * @param {number} mountDepth number of components in the owner hierarchy
104
105
  * @return {string} The computed markup.
105
106
  */
@@ -131,7 +132,7 @@ ReactDOMComponent.Mixin = {
131
132
  * @see http://jsperf.com/obj-vs-arr-iteration
132
133
  *
133
134
  * @private
134
- * @param {ReactReconcileTransaction} transaction
135
+ * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
135
136
  * @return {string} Markup of opening tag.
136
137
  */
137
138
  _createOpenTagMarkupAndPutListeners: function(transaction) {
@@ -163,15 +164,21 @@ ReactDOMComponent.Mixin = {
163
164
  }
164
165
  }
165
166
 
166
- var idMarkup = DOMPropertyOperations.createMarkupForID(this._rootNodeID);
167
- return ret + ' ' + idMarkup + '>';
167
+ // For static pages, no need to put React ID and checksum. Saves lots of
168
+ // bytes.
169
+ if (transaction.renderToStaticMarkup) {
170
+ return ret + '>';
171
+ }
172
+
173
+ var markupForID = DOMPropertyOperations.createMarkupForID(this._rootNodeID);
174
+ return ret + ' ' + markupForID + '>';
168
175
  },
169
176
 
170
177
  /**
171
178
  * Creates markup for the content between the tags.
172
179
  *
173
180
  * @private
174
- * @param {ReactReconcileTransaction} transaction
181
+ * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction
175
182
  * @return {string} Content markup.
176
183
  */
177
184
  _createContentMarkup: function(transaction) {
@@ -199,6 +206,15 @@ ReactDOMComponent.Mixin = {
199
206
  },
200
207
 
201
208
  receiveComponent: function(nextComponent, transaction) {
209
+ if (nextComponent === this) {
210
+ // Since props and context are immutable after the component is
211
+ // mounted, we can do a cheap identity compare here to determine
212
+ // if this is a superfluous reconcile.
213
+
214
+ // TODO: compare the descriptor
215
+ return;
216
+ }
217
+
202
218
  assertValidProps(nextComponent.props);
203
219
  ReactComponent.Mixin.receiveComponent.call(
204
220
  this,
@@ -395,5 +411,6 @@ ReactDOMComponent.Mixin = {
395
411
  mixInto(ReactDOMComponent, ReactComponent.Mixin);
396
412
  mixInto(ReactDOMComponent, ReactDOMComponent.Mixin);
397
413
  mixInto(ReactDOMComponent, ReactMultiChild.Mixin);
414
+ mixInto(ReactDOMComponent, ReactBrowserComponentMixin);
398
415
 
399
416
  module.exports = ReactDOMComponent;
@@ -18,6 +18,7 @@
18
18
 
19
19
  "use strict";
20
20
 
21
+ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
21
22
  var ReactCompositeComponent = require("./ReactCompositeComponent");
22
23
  var ReactDOM = require("./ReactDOM");
23
24
  var ReactEventEmitter = require("./ReactEventEmitter");
@@ -35,6 +36,8 @@ var form = ReactDOM.form;
35
36
  var ReactDOMForm = ReactCompositeComponent.createClass({
36
37
  displayName: 'ReactDOMForm',
37
38
 
39
+ mixins: [ReactBrowserComponentMixin],
40
+
38
41
  render: function() {
39
42
  // TODO: Instead of using `ReactDOM` directly, we should use JSX. However,
40
43
  // `jshint` fails to parse JSX so in order for linting to work in the open
@@ -18,6 +18,7 @@
18
18
 
19
19
  "use strict";
20
20
 
21
+ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
21
22
  var ReactCompositeComponent = require("./ReactCompositeComponent");
22
23
  var ReactDOM = require("./ReactDOM");
23
24
  var ReactEventEmitter = require("./ReactEventEmitter");
@@ -36,6 +37,8 @@ var ReactDOMImg = ReactCompositeComponent.createClass({
36
37
  displayName: 'ReactDOMImg',
37
38
  tagName: 'IMG',
38
39
 
40
+ mixins: [ReactBrowserComponentMixin],
41
+
39
42
  render: function() {
40
43
  return img(this.props);
41
44
  },
@@ -21,6 +21,7 @@
21
21
  var AutoFocusMixin = require("./AutoFocusMixin");
22
22
  var DOMPropertyOperations = require("./DOMPropertyOperations");
23
23
  var LinkedValueUtils = require("./LinkedValueUtils");
24
+ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
24
25
  var ReactCompositeComponent = require("./ReactCompositeComponent");
25
26
  var ReactDOM = require("./ReactDOM");
26
27
  var ReactMount = require("./ReactMount");
@@ -52,7 +53,7 @@ var instancesByReactID = {};
52
53
  var ReactDOMInput = ReactCompositeComponent.createClass({
53
54
  displayName: 'ReactDOMInput',
54
55
 
55
- mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],
56
+ mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
56
57
 
57
58
  getInitialState: function() {
58
59
  var defaultValue = this.props.defaultValue;
@@ -18,9 +18,12 @@
18
18
 
19
19
  "use strict";
20
20
 
21
+ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
21
22
  var ReactCompositeComponent = require("./ReactCompositeComponent");
22
23
  var ReactDOM = require("./ReactDOM");
23
24
 
25
+ var warning = require("./warning");
26
+
24
27
  // Store a reference to the <option> `ReactDOMComponent`.
25
28
  var option = ReactDOM.option;
26
29
 
@@ -30,15 +33,16 @@ var option = ReactDOM.option;
30
33
  var ReactDOMOption = ReactCompositeComponent.createClass({
31
34
  displayName: 'ReactDOMOption',
32
35
 
36
+ mixins: [ReactBrowserComponentMixin],
37
+
33
38
  componentWillMount: function() {
34
39
  // TODO (yungsters): Remove support for `selected` in <option>.
35
- if (this.props.selected != null) {
36
- if ("production" !== process.env.NODE_ENV) {
37
- console.warn(
38
- 'Use the `defaultValue` or `value` props on <select> instead of ' +
39
- 'setting `selected` on <option>.'
40
- );
41
- }
40
+ if ("production" !== process.env.NODE_ENV) {
41
+ ("production" !== process.env.NODE_ENV ? warning(
42
+ this.props.selected == null,
43
+ 'Use the `defaultValue` or `value` props on <select> instead of ' +
44
+ 'setting `selected` on <option>.'
45
+ ) : null);
42
46
  }
43
47
  },
44
48
 
@@ -20,6 +20,7 @@
20
20
 
21
21
  var AutoFocusMixin = require("./AutoFocusMixin");
22
22
  var LinkedValueUtils = require("./LinkedValueUtils");
23
+ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
23
24
  var ReactCompositeComponent = require("./ReactCompositeComponent");
24
25
  var ReactDOM = require("./ReactDOM");
25
26
 
@@ -103,7 +104,7 @@ function updateOptions(component, propValue) {
103
104
  var ReactDOMSelect = ReactCompositeComponent.createClass({
104
105
  displayName: 'ReactDOMSelect',
105
106
 
106
- mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],
107
+ mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
107
108
 
108
109
  propTypes: {
109
110
  defaultValue: selectValueType,
@@ -21,12 +21,15 @@
21
21
  var AutoFocusMixin = require("./AutoFocusMixin");
22
22
  var DOMPropertyOperations = require("./DOMPropertyOperations");
23
23
  var LinkedValueUtils = require("./LinkedValueUtils");
24
+ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
24
25
  var ReactCompositeComponent = require("./ReactCompositeComponent");
25
26
  var ReactDOM = require("./ReactDOM");
26
27
 
27
28
  var invariant = require("./invariant");
28
29
  var merge = require("./merge");
29
30
 
31
+ var warning = require("./warning");
32
+
30
33
  // Store a reference to the <textarea> `ReactDOMComponent`.
31
34
  var textarea = ReactDOM.textarea;
32
35
 
@@ -48,7 +51,7 @@ var textarea = ReactDOM.textarea;
48
51
  var ReactDOMTextarea = ReactCompositeComponent.createClass({
49
52
  displayName: 'ReactDOMTextarea',
50
53
 
51
- mixins: [AutoFocusMixin, LinkedValueUtils.Mixin],
54
+ mixins: [AutoFocusMixin, LinkedValueUtils.Mixin, ReactBrowserComponentMixin],
52
55
 
53
56
  getInitialState: function() {
54
57
  var defaultValue = this.props.defaultValue;
@@ -56,10 +59,11 @@ var ReactDOMTextarea = ReactCompositeComponent.createClass({
56
59
  var children = this.props.children;
57
60
  if (children != null) {
58
61
  if ("production" !== process.env.NODE_ENV) {
59
- console.warn(
62
+ ("production" !== process.env.NODE_ENV ? warning(
63
+ false,
60
64
  'Use the `defaultValue` or `value` props instead of setting ' +
61
65
  'children on <textarea>.'
62
- );
66
+ ) : null);
63
67
  }
64
68
  ("production" !== process.env.NODE_ENV ? invariant(
65
69
  defaultValue == null,
@@ -30,6 +30,9 @@ var CompositionEventPlugin = require("./CompositionEventPlugin");
30
30
  var DefaultEventPluginOrder = require("./DefaultEventPluginOrder");
31
31
  var EnterLeaveEventPlugin = require("./EnterLeaveEventPlugin");
32
32
  var MobileSafariClickEventPlugin = require("./MobileSafariClickEventPlugin");
33
+ var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin");
34
+ var ReactComponentBrowserEnvironment =
35
+ require("./ReactComponentBrowserEnvironment");
33
36
  var ReactEventTopLevelCallback = require("./ReactEventTopLevelCallback");
34
37
  var ReactDOM = require("./ReactDOM");
35
38
  var ReactDOMButton = require("./ReactDOMButton");
@@ -89,6 +92,11 @@ function inject() {
89
92
  body: createFullPageComponent(ReactDOM.body)
90
93
  });
91
94
 
95
+
96
+ // This needs to happen after createFullPageComponent() otherwise the mixin
97
+ // gets double injected.
98
+ ReactInjection.CompositeComponent.injectMixin(ReactBrowserComponentMixin);
99
+
92
100
  ReactInjection.DOMProperty.injectDOMPropertyConfig(DefaultDOMPropertyConfig);
93
101
 
94
102
  ReactInjection.Updates.injectBatchingStrategy(
@@ -101,6 +109,8 @@ function inject() {
101
109
  ServerReactRootIndex.createReactRootIndex
102
110
  );
103
111
 
112
+ ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment);
113
+
104
114
  if ("production" !== process.env.NODE_ENV) {
105
115
  var url = (ExecutionEnvironment.canUseDOM && window.location.href) || '';
106
116
  if ((/[?&]react_perf\b/).test(url)) {
@@ -20,6 +20,8 @@
20
20
 
21
21
  var DOMProperty = require("./DOMProperty");
22
22
  var EventPluginHub = require("./EventPluginHub");
23
+ var ReactComponent = require("./ReactComponent");
24
+ var ReactCompositeComponent = require("./ReactCompositeComponent");
23
25
  var ReactDOM = require("./ReactDOM");
24
26
  var ReactEventEmitter = require("./ReactEventEmitter");
25
27
  var ReactPerf = require("./ReactPerf");
@@ -27,6 +29,8 @@ var ReactRootIndex = require("./ReactRootIndex");
27
29
  var ReactUpdates = require("./ReactUpdates");
28
30
 
29
31
  var ReactInjection = {
32
+ Component: ReactComponent.injection,
33
+ CompositeComponent: ReactCompositeComponent.injection,
30
34
  DOMProperty: DOMProperty.injection,
31
35
  EventPluginHub: EventPluginHub.injection,
32
36
  DOM: ReactDOM.injection,
@@ -21,6 +21,7 @@
21
21
  var ReactDOMSelection = require("./ReactDOMSelection");
22
22
 
23
23
  var containsNode = require("./containsNode");
24
+ var focusNode = require("./focusNode");
24
25
  var getActiveElement = require("./getActiveElement");
25
26
 
26
27
  function isInDocument(node) {
@@ -71,7 +72,7 @@ var ReactInputSelection = {
71
72
  priorSelectionRange
72
73
  );
73
74
  }
74
- priorFocusedElem.focus();
75
+ focusNode(priorFocusedElem);
75
76
  }
76
77
  },
77
78
 
package/lib/ReactMount.js CHANGED
@@ -25,6 +25,7 @@ var ReactPerf = require("./ReactPerf");
25
25
 
26
26
  var containsNode = require("./containsNode");
27
27
  var getReactRootElementInContainer = require("./getReactRootElementInContainer");
28
+ var instantiateReactComponent = require("./instantiateReactComponent");
28
29
  var invariant = require("./invariant");
29
30
  var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
30
31
 
@@ -299,8 +300,13 @@ var ReactMount = {
299
300
  nextComponent,
300
301
  container,
301
302
  shouldReuseMarkup) {
302
- var reactRootID = ReactMount._registerComponent(nextComponent, container);
303
- nextComponent.mountComponentIntoNode(
303
+
304
+ var componentInstance = instantiateReactComponent(nextComponent);
305
+ var reactRootID = ReactMount._registerComponent(
306
+ componentInstance,
307
+ container
308
+ );
309
+ componentInstance.mountComponentIntoNode(
304
310
  reactRootID,
305
311
  container,
306
312
  shouldReuseMarkup
@@ -312,7 +318,7 @@ var ReactMount = {
312
318
  getReactRootElementInContainer(container);
313
319
  }
314
320
 
315
- return nextComponent;
321
+ return componentInstance;
316
322
  }
317
323
  ),
318
324
 
@@ -615,8 +621,10 @@ var ReactMount = {
615
621
  ("production" !== process.env.NODE_ENV ? invariant(
616
622
  false,
617
623
  'findComponentRoot(..., %s): Unable to find element. This probably ' +
618
- 'means the DOM was unexpectedly mutated (e.g., by the browser). ' +
619
- 'Try inspecting the child nodes of the element with React ID `%s`.',
624
+ 'means the DOM was unexpectedly mutated (e.g., by the browser), ' +
625
+ 'usually due to forgetting a <tbody> when using tables or nesting <p> ' +
626
+ 'or <a> tags. Try inspecting the child nodes of the element with React ' +
627
+ 'ID `%s`.',
620
628
  targetID,
621
629
  ReactMount.getID(ancestorNode)
622
630
  ) : invariant(false));
@@ -23,6 +23,7 @@ var ReactComponent = require("./ReactComponent");
23
23
  var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes");
24
24
 
25
25
  var flattenChildren = require("./flattenChildren");
26
+ var instantiateReactComponent = require("./instantiateReactComponent");
26
27
  var shouldUpdateReactComponent = require("./shouldUpdateReactComponent");
27
28
 
28
29
  /**
@@ -192,14 +193,18 @@ var ReactMultiChild = {
192
193
  for (var name in children) {
193
194
  var child = children[name];
194
195
  if (children.hasOwnProperty(name)) {
196
+ // The rendered children must be turned into instances as they're
197
+ // mounted.
198
+ var childInstance = instantiateReactComponent(child);
199
+ children[name] = childInstance;
195
200
  // Inlined for performance, see `ReactInstanceHandles.createReactID`.
196
201
  var rootID = this._rootNodeID + name;
197
- var mountImage = child.mountComponent(
202
+ var mountImage = childInstance.mountComponent(
198
203
  rootID,
199
204
  transaction,
200
205
  this._mountDepth + 1
201
206
  );
202
- child._mountIndex = index;
207
+ childInstance._mountIndex = index;
203
208
  mountImages.push(mountImage);
204
209
  index++;
205
210
  }
@@ -293,8 +298,10 @@ var ReactMultiChild = {
293
298
  lastIndex = Math.max(prevChild._mountIndex, lastIndex);
294
299
  this._unmountChildByName(prevChild, name);
295
300
  }
301
+ // The child must be instantiated before it's mounted.
302
+ var nextChildInstance = instantiateReactComponent(nextChild);
296
303
  this._mountChildByNameAtIndex(
297
- nextChild, name, nextIndex, transaction
304
+ nextChildInstance, name, nextIndex, transaction
298
305
  );
299
306
  }
300
307
  nextIndex++;
package/lib/ReactOwner.js CHANGED
@@ -18,6 +18,7 @@
18
18
 
19
19
  "use strict";
20
20
 
21
+ var emptyObject = require("./emptyObject");
21
22
  var invariant = require("./invariant");
22
23
 
23
24
  /**
@@ -118,6 +119,10 @@ var ReactOwner = {
118
119
  */
119
120
  Mixin: {
120
121
 
122
+ construct: function() {
123
+ this.refs = emptyObject;
124
+ },
125
+
121
126
  /**
122
127
  * Lazily allocates the refs object and stores `component` as `ref`.
123
128
  *
@@ -132,7 +137,7 @@ var ReactOwner = {
132
137
  'attachRef(%s, ...): Only a component\'s owner can store a ref to it.',
133
138
  ref
134
139
  ) : invariant(component.isOwnedBy(this)));
135
- var refs = this.refs || (this.refs = {});
140
+ var refs = this.refs === emptyObject ? (this.refs = {}) : this.refs;
136
141
  refs[ref] = component;
137
142
  },
138
143