react 0.13.3 → 0.14.0-beta1

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 (189) hide show
  1. package/README.md +5 -2
  2. package/addons.js +7 -0
  3. package/dist/JSXTransformer.js +4101 -2432
  4. package/dist/react-with-addons.js +4389 -6277
  5. package/dist/react-with-addons.min.js +6 -8
  6. package/dist/react.js +4028 -5697
  7. package/dist/react.min.js +5 -6
  8. package/lib/{AutoFocusMixin.js → AutoFocusUtils.js} +16 -5
  9. package/lib/BeforeInputEventPlugin.js +30 -118
  10. package/lib/CSSCore.js +12 -23
  11. package/lib/CSSProperty.js +4 -3
  12. package/lib/CSSPropertyOperations.js +14 -30
  13. package/lib/CallbackQueue.js +7 -10
  14. package/lib/ChangeEventPlugin.js +26 -88
  15. package/lib/ClientReactRootIndex.js +2 -2
  16. package/lib/DOMChildrenOperations.js +13 -33
  17. package/lib/DOMProperty.js +86 -147
  18. package/lib/DOMPropertyOperations.js +91 -67
  19. package/lib/Danger.js +19 -62
  20. package/lib/DefaultEventPluginOrder.js +2 -12
  21. package/lib/EnterLeaveEventPlugin.js +11 -33
  22. package/lib/EventConstants.js +2 -2
  23. package/lib/EventListener.js +11 -13
  24. package/lib/EventPluginHub.js +44 -47
  25. package/lib/EventPluginRegistry.js +18 -74
  26. package/lib/EventPluginUtils.js +33 -44
  27. package/lib/EventPropagators.js +23 -26
  28. package/lib/ExecutionEnvironment.js +4 -8
  29. package/lib/FallbackCompositionState.js +3 -3
  30. package/lib/HTMLDOMPropertyConfig.js +15 -20
  31. package/lib/LinkedStateMixin.js +3 -6
  32. package/lib/LinkedValueUtils.js +71 -89
  33. package/lib/Object.assign.js +1 -1
  34. package/lib/PooledClass.js +20 -11
  35. package/lib/React.js +9 -129
  36. package/lib/ReactBrowserComponentMixin.js +9 -2
  37. package/lib/ReactBrowserEventEmitter.js +26 -82
  38. package/lib/ReactCSSTransitionGroup.js +13 -24
  39. package/lib/ReactCSSTransitionGroupChild.js +26 -28
  40. package/lib/ReactChildReconciler.js +11 -19
  41. package/lib/ReactChildren.js +24 -31
  42. package/lib/ReactClass.js +96 -267
  43. package/lib/ReactComponent.js +28 -57
  44. package/lib/ReactComponentBrowserEnvironment.js +4 -8
  45. package/lib/ReactComponentEnvironment.js +6 -12
  46. package/lib/ReactComponentWithPureRenderMixin.js +6 -7
  47. package/lib/ReactCompositeComponent.js +115 -381
  48. package/lib/ReactCurrentOwner.js +1 -3
  49. package/lib/ReactDOM.js +4 -2
  50. package/lib/ReactDOMButton.js +16 -28
  51. package/lib/ReactDOMClient.js +90 -0
  52. package/lib/ReactDOMComponent.js +468 -156
  53. package/lib/ReactDOMIDOperations.js +25 -22
  54. package/lib/ReactDOMInput.js +79 -108
  55. package/lib/ReactDOMOption.js +58 -20
  56. package/lib/ReactDOMSelect.js +95 -83
  57. package/lib/ReactDOMSelection.js +5 -20
  58. package/lib/ReactDOMServer.js +24 -0
  59. package/lib/ReactDOMTextComponent.js +17 -18
  60. package/lib/ReactDOMTextarea.js +44 -69
  61. package/lib/ReactDefaultBatchingStrategy.js +9 -13
  62. package/lib/ReactDefaultInjection.js +20 -76
  63. package/lib/ReactDefaultPerf.js +36 -69
  64. package/lib/ReactDefaultPerfAnalysis.js +8 -14
  65. package/lib/ReactElement.js +26 -120
  66. package/lib/ReactElementValidator.js +56 -192
  67. package/lib/ReactEmptyComponent.js +7 -11
  68. package/lib/ReactErrorUtils.js +3 -3
  69. package/lib/ReactEventEmitterMixin.js +3 -13
  70. package/lib/ReactEventListener.js +58 -40
  71. package/lib/ReactFragment.js +33 -59
  72. package/lib/ReactInjection.js +1 -1
  73. package/lib/ReactInputSelection.js +14 -23
  74. package/lib/ReactInstanceHandles.js +29 -58
  75. package/lib/ReactInstanceMap.js +5 -5
  76. package/lib/ReactIsomorphic.js +70 -0
  77. package/lib/ReactLink.js +2 -4
  78. package/lib/ReactMarkupChecksum.js +5 -10
  79. package/lib/ReactMount.js +142 -285
  80. package/lib/ReactMultiChild.js +19 -45
  81. package/lib/ReactMultiChildUpdateTypes.js +1 -1
  82. package/lib/ReactNativeComponent.js +6 -15
  83. package/lib/ReactNoopUpdateQueue.js +118 -0
  84. package/lib/ReactOwner.js +7 -24
  85. package/lib/ReactPerf.js +8 -12
  86. package/lib/ReactPropTransferer.js +4 -4
  87. package/lib/ReactPropTypeLocationNames.js +2 -2
  88. package/lib/ReactPropTypeLocations.js +1 -1
  89. package/lib/ReactPropTypes.js +41 -61
  90. package/lib/ReactReconcileTransaction.js +11 -36
  91. package/lib/ReactReconciler.js +14 -26
  92. package/lib/ReactRef.js +5 -8
  93. package/lib/ReactRootIndex.js +2 -2
  94. package/lib/ReactServerBatchingStrategy.js +23 -0
  95. package/lib/ReactServerRendering.js +20 -15
  96. package/lib/ReactServerRenderingTransaction.js +9 -34
  97. package/lib/ReactStateSetters.js +6 -6
  98. package/lib/ReactTestUtils.js +137 -190
  99. package/lib/ReactTransitionChildMapping.js +5 -7
  100. package/lib/ReactTransitionEvents.js +5 -5
  101. package/lib/ReactTransitionGroup.js +30 -52
  102. package/lib/ReactUpdateQueue.js +69 -107
  103. package/lib/ReactUpdates.js +26 -81
  104. package/lib/ReactWithAddons.js +5 -6
  105. package/lib/SVGDOMPropertyConfig.js +39 -4
  106. package/lib/SelectEventPlugin.js +31 -33
  107. package/lib/ServerReactRootIndex.js +2 -2
  108. package/lib/SimpleEventPlugin.js +138 -130
  109. package/lib/SyntheticClipboardEvent.js +5 -9
  110. package/lib/SyntheticCompositionEvent.js +4 -10
  111. package/lib/SyntheticDragEvent.js +3 -3
  112. package/lib/SyntheticEvent.js +14 -15
  113. package/lib/SyntheticFocusEvent.js +3 -3
  114. package/lib/SyntheticInputEvent.js +4 -10
  115. package/lib/SyntheticKeyboardEvent.js +6 -6
  116. package/lib/SyntheticMouseEvent.js +10 -16
  117. package/lib/SyntheticTouchEvent.js +3 -3
  118. package/lib/SyntheticUIEvent.js +5 -5
  119. package/lib/SyntheticWheelEvent.js +13 -17
  120. package/lib/Transaction.js +22 -28
  121. package/lib/ViewportMetrics.js +2 -2
  122. package/lib/accumulateInto.js +2 -5
  123. package/lib/adler32.js +2 -4
  124. package/lib/camelize.js +4 -2
  125. package/lib/camelizeStyleName.js +2 -2
  126. package/lib/cloneWithProps.js +6 -12
  127. package/lib/containsNode.js +29 -16
  128. package/lib/createArrayFromMixed.js +17 -16
  129. package/lib/createNodesFromMarkup.js +6 -8
  130. package/lib/dangerousStyleValue.js +2 -3
  131. package/lib/deprecated.js +47 -0
  132. package/lib/emptyFunction.js +10 -4
  133. package/lib/emptyObject.js +1 -1
  134. package/lib/escapeTextContentForBrowser.js +1 -1
  135. package/lib/findDOMNode.js +7 -27
  136. package/lib/flattenChildren.js +4 -10
  137. package/lib/focusNode.js +2 -3
  138. package/lib/forEachAccumulated.js +3 -3
  139. package/lib/getActiveElement.js +4 -2
  140. package/lib/getEventCharCode.js +2 -2
  141. package/lib/getEventKey.js +1 -1
  142. package/lib/getEventModifierState.js +1 -2
  143. package/lib/getEventTarget.js +1 -1
  144. package/lib/getIteratorFn.js +2 -4
  145. package/lib/getMarkupWrap.js +18 -40
  146. package/lib/getNodeForCharacterOffset.js +1 -1
  147. package/lib/getTextContentAccessor.js +2 -4
  148. package/lib/getUnboundedScrollPosition.js +1 -1
  149. package/lib/hyphenate.js +3 -1
  150. package/lib/hyphenateStyleName.js +2 -2
  151. package/lib/instantiateReactComponent.js +23 -43
  152. package/lib/invariant.js +8 -12
  153. package/lib/isEventSupported.js +7 -10
  154. package/lib/isNode.js +4 -6
  155. package/lib/isTextInputElement.js +3 -4
  156. package/lib/isTextNode.js +3 -1
  157. package/lib/joinClasses.js +3 -3
  158. package/lib/keyMirror.js +3 -6
  159. package/lib/keyOf.js +4 -3
  160. package/lib/mapObject.js +1 -1
  161. package/lib/memoizeStringOnly.js +2 -2
  162. package/lib/onlyChild.js +2 -5
  163. package/lib/performance.js +2 -5
  164. package/lib/performanceNow.js +3 -1
  165. package/lib/quoteAttributeValueForBrowser.js +1 -1
  166. package/lib/renderSubtreeIntoContainer.js +16 -0
  167. package/lib/setInnerHTML.js +11 -8
  168. package/lib/setTextContent.js +3 -3
  169. package/lib/shallowCompare.js +24 -0
  170. package/lib/shallowEqual.js +17 -11
  171. package/lib/shouldUpdateReactComponent.js +3 -64
  172. package/lib/toArray.js +8 -19
  173. package/lib/traverseAllChildren.js +23 -90
  174. package/lib/update.js +25 -85
  175. package/lib/validateDOMNesting.js +363 -0
  176. package/lib/warning.js +15 -17
  177. package/package.json +3 -3
  178. package/react.js +53 -1
  179. package/lib/LocalEventTrapMixin.js +0 -53
  180. package/lib/MobileSafariClickEventPlugin.js +0 -56
  181. package/lib/ReactContext.js +0 -74
  182. package/lib/ReactDOMForm.js +0 -47
  183. package/lib/ReactDOMIframe.js +0 -43
  184. package/lib/ReactDOMImg.js +0 -44
  185. package/lib/ReactLifeCycle.js +0 -35
  186. package/lib/ReactPutListenerQueue.js +0 -54
  187. package/lib/createFullPageComponent.js +0 -58
  188. package/lib/cx.js +0 -52
  189. package/lib/getReactRootElementInContainer.js +0 -33
package/lib/toArray.js CHANGED
@@ -10,6 +10,8 @@
10
10
  * @typechecks
11
11
  */
12
12
 
13
+ 'use strict';
14
+
13
15
  var invariant = require("./invariant");
14
16
 
15
17
  /**
@@ -26,24 +28,11 @@ function toArray(obj) {
26
28
 
27
29
  // Some browse builtin objects can report typeof 'function' (e.g. NodeList in
28
30
  // old versions of Safari).
29
- ("production" !== process.env.NODE_ENV ? invariant(
30
- !Array.isArray(obj) &&
31
- (typeof obj === 'object' || typeof obj === 'function'),
32
- 'toArray: Array-like object expected'
33
- ) : invariant(!Array.isArray(obj) &&
34
- (typeof obj === 'object' || typeof obj === 'function')));
31
+ !(!Array.isArray(obj) && (typeof obj === 'object' || typeof obj === 'function')) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'toArray: Array-like object expected') : invariant(false) : undefined;
35
32
 
36
- ("production" !== process.env.NODE_ENV ? invariant(
37
- typeof length === 'number',
38
- 'toArray: Object needs a length property'
39
- ) : invariant(typeof length === 'number'));
33
+ !(typeof length === 'number') ? 'production' !== process.env.NODE_ENV ? invariant(false, 'toArray: Object needs a length property') : invariant(false) : undefined;
40
34
 
41
- ("production" !== process.env.NODE_ENV ? invariant(
42
- length === 0 ||
43
- (length - 1) in obj,
44
- 'toArray: Object should have keys for indices'
45
- ) : invariant(length === 0 ||
46
- (length - 1) in obj));
35
+ !(length === 0 || length - 1 in obj) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'toArray: Object should have keys for indices') : invariant(false) : undefined;
47
36
 
48
37
  // Old IE doesn't give collections access to hasOwnProperty. Assume inputs
49
38
  // without method will throw during the slice call and skip straight to the
@@ -51,9 +40,7 @@ function toArray(obj) {
51
40
  if (obj.hasOwnProperty) {
52
41
  try {
53
42
  return Array.prototype.slice.call(obj);
54
- } catch (e) {
55
- // IE < 9 does not support Array#slice on collections objects
56
- }
43
+ } catch (e) {}
57
44
  }
58
45
 
59
46
  // Fall back to copying key by key. This assumes all keys have a value,
@@ -66,3 +53,5 @@ function toArray(obj) {
66
53
  }
67
54
 
68
55
  module.exports = toArray;
56
+
57
+ // IE < 9 does not support Array#slice on collections objects
@@ -60,14 +60,11 @@ function getComponentKey(component, index) {
60
60
  /**
61
61
  * Escape a component key so that it is safe to use in a reactid.
62
62
  *
63
- * @param {*} key Component key to be escaped.
63
+ * @param {*} text Component key to be escaped.
64
64
  * @return {string} An escaped string.
65
65
  */
66
66
  function escapeUserProvidedKey(text) {
67
- return ('' + text).replace(
68
- userProvidedKeyEscapeRegex,
69
- userProvidedKeyEscaper
70
- );
67
+ return ('' + text).replace(userProvidedKeyEscapeRegex, userProvidedKeyEscaper);
71
68
  }
72
69
 
73
70
  /**
@@ -84,19 +81,12 @@ function wrapUserProvidedKey(key) {
84
81
  /**
85
82
  * @param {?*} children Children tree container.
86
83
  * @param {!string} nameSoFar Name of the key path so far.
87
- * @param {!number} indexSoFar Number of children encountered until this point.
88
84
  * @param {!function} callback Callback to invoke with each child found.
89
85
  * @param {?*} traverseContext Used to pass information throughout the traversal
90
86
  * process.
91
87
  * @return {!number} The number of children in this subtree.
92
88
  */
93
- function traverseAllChildrenImpl(
94
- children,
95
- nameSoFar,
96
- indexSoFar,
97
- callback,
98
- traverseContext
99
- ) {
89
+ function traverseAllChildrenImpl(children, nameSoFar, callback, traverseContext) {
100
90
  var type = typeof children;
101
91
 
102
92
  if (type === 'undefined' || type === 'boolean') {
@@ -104,39 +94,23 @@ function traverseAllChildrenImpl(
104
94
  children = null;
105
95
  }
106
96
 
107
- if (children === null ||
108
- type === 'string' ||
109
- type === 'number' ||
110
- ReactElement.isValidElement(children)) {
111
- callback(
112
- traverseContext,
113
- children,
114
- // If it's the only child, treat the name as if it was wrapped in an array
115
- // so that it's consistent if the number of children grows.
116
- nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar,
117
- indexSoFar
118
- );
97
+ if (children === null || type === 'string' || type === 'number' || ReactElement.isValidElement(children)) {
98
+ callback(traverseContext, children,
99
+ // If it's the only child, treat the name as if it was wrapped in an array
100
+ // so that it's consistent if the number of children grows.
101
+ nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar);
119
102
  return 1;
120
103
  }
121
104
 
122
- var child, nextName, nextIndex;
105
+ var child;
106
+ var nextName;
123
107
  var subtreeCount = 0; // Count of children found in the current subtree.
124
108
 
125
109
  if (Array.isArray(children)) {
126
110
  for (var i = 0; i < children.length; i++) {
127
111
  child = children[i];
128
- nextName = (
129
- (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) +
130
- getComponentKey(child, i)
131
- );
132
- nextIndex = indexSoFar + subtreeCount;
133
- subtreeCount += traverseAllChildrenImpl(
134
- child,
135
- nextName,
136
- nextIndex,
137
- callback,
138
- traverseContext
139
- );
112
+ nextName = (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + getComponentKey(child, i);
113
+ subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
140
114
  }
141
115
  } else {
142
116
  var iteratorFn = getIteratorFn(children);
@@ -147,27 +121,12 @@ function traverseAllChildrenImpl(
147
121
  var ii = 0;
148
122
  while (!(step = iterator.next()).done) {
149
123
  child = step.value;
150
- nextName = (
151
- (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) +
152
- getComponentKey(child, ii++)
153
- );
154
- nextIndex = indexSoFar + subtreeCount;
155
- subtreeCount += traverseAllChildrenImpl(
156
- child,
157
- nextName,
158
- nextIndex,
159
- callback,
160
- traverseContext
161
- );
124
+ nextName = (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + getComponentKey(child, ii++);
125
+ subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
162
126
  }
163
127
  } else {
164
- if ("production" !== process.env.NODE_ENV) {
165
- ("production" !== process.env.NODE_ENV ? warning(
166
- didWarnAboutMaps,
167
- 'Using Maps as children is not yet fully supported. It is an ' +
168
- 'experimental feature that might be removed. Convert it to a ' +
169
- 'sequence / iterable of keyed ReactElements instead.'
170
- ) : null);
128
+ if ('production' !== process.env.NODE_ENV) {
129
+ 'production' !== process.env.NODE_ENV ? warning(didWarnAboutMaps, 'Using Maps as children is not yet fully supported. It is an ' + 'experimental feature that might be removed. Convert it to a ' + 'sequence / iterable of keyed ReactElements instead.') : undefined;
171
130
  didWarnAboutMaps = true;
172
131
  }
173
132
  // Iterator will provide entry [k,v] tuples rather than values.
@@ -175,45 +134,19 @@ function traverseAllChildrenImpl(
175
134
  var entry = step.value;
176
135
  if (entry) {
177
136
  child = entry[1];
178
- nextName = (
179
- (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) +
180
- wrapUserProvidedKey(entry[0]) + SUBSEPARATOR +
181
- getComponentKey(child, 0)
182
- );
183
- nextIndex = indexSoFar + subtreeCount;
184
- subtreeCount += traverseAllChildrenImpl(
185
- child,
186
- nextName,
187
- nextIndex,
188
- callback,
189
- traverseContext
190
- );
137
+ nextName = (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + wrapUserProvidedKey(entry[0]) + SUBSEPARATOR + getComponentKey(child, 0);
138
+ subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
191
139
  }
192
140
  }
193
141
  }
194
142
  } else if (type === 'object') {
195
- ("production" !== process.env.NODE_ENV ? invariant(
196
- children.nodeType !== 1,
197
- 'traverseAllChildren(...): Encountered an invalid child; DOM ' +
198
- 'elements are not valid children of React components.'
199
- ) : invariant(children.nodeType !== 1));
143
+ !(children.nodeType !== 1) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'traverseAllChildren(...): Encountered an invalid child; DOM ' + 'elements are not valid children of React components.') : invariant(false) : undefined;
200
144
  var fragment = ReactFragment.extract(children);
201
145
  for (var key in fragment) {
202
146
  if (fragment.hasOwnProperty(key)) {
203
147
  child = fragment[key];
204
- nextName = (
205
- (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) +
206
- wrapUserProvidedKey(key) + SUBSEPARATOR +
207
- getComponentKey(child, 0)
208
- );
209
- nextIndex = indexSoFar + subtreeCount;
210
- subtreeCount += traverseAllChildrenImpl(
211
- child,
212
- nextName,
213
- nextIndex,
214
- callback,
215
- traverseContext
216
- );
148
+ nextName = (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + wrapUserProvidedKey(key) + SUBSEPARATOR + getComponentKey(child, 0);
149
+ subtreeCount += traverseAllChildrenImpl(child, nextName, callback, traverseContext);
217
150
  }
218
151
  }
219
152
  }
@@ -243,7 +176,7 @@ function traverseAllChildren(children, callback, traverseContext) {
243
176
  return 0;
244
177
  }
245
178
 
246
- return traverseAllChildrenImpl(children, '', 0, callback, traverseContext);
179
+ return traverseAllChildrenImpl(children, '', callback, traverseContext);
247
180
  }
248
181
 
249
- module.exports = traverseAllChildren;
182
+ module.exports = traverseAllChildren;
package/lib/update.js CHANGED
@@ -9,14 +9,14 @@
9
9
  * @providesModule update
10
10
  */
11
11
 
12
- /* global hasOwnProperty:true */
12
+ /* global hasOwnProperty:true */
13
13
 
14
14
  'use strict';
15
15
 
16
16
  var assign = require("./Object.assign");
17
17
  var keyOf = require("./keyOf");
18
18
  var invariant = require("./invariant");
19
- var hasOwnProperty = {}.hasOwnProperty;
19
+ var hasOwnProperty = ({}).hasOwnProperty;
20
20
 
21
21
  function shallowCopy(x) {
22
22
  if (Array.isArray(x)) {
@@ -28,60 +28,32 @@ function shallowCopy(x) {
28
28
  }
29
29
  }
30
30
 
31
- var COMMAND_PUSH = keyOf({$push: null});
32
- var COMMAND_UNSHIFT = keyOf({$unshift: null});
33
- var COMMAND_SPLICE = keyOf({$splice: null});
34
- var COMMAND_SET = keyOf({$set: null});
35
- var COMMAND_MERGE = keyOf({$merge: null});
36
- var COMMAND_APPLY = keyOf({$apply: null});
37
-
38
- var ALL_COMMANDS_LIST = [
39
- COMMAND_PUSH,
40
- COMMAND_UNSHIFT,
41
- COMMAND_SPLICE,
42
- COMMAND_SET,
43
- COMMAND_MERGE,
44
- COMMAND_APPLY
45
- ];
31
+ var COMMAND_PUSH = keyOf({ $push: null });
32
+ var COMMAND_UNSHIFT = keyOf({ $unshift: null });
33
+ var COMMAND_SPLICE = keyOf({ $splice: null });
34
+ var COMMAND_SET = keyOf({ $set: null });
35
+ var COMMAND_MERGE = keyOf({ $merge: null });
36
+ var COMMAND_APPLY = keyOf({ $apply: null });
37
+
38
+ var ALL_COMMANDS_LIST = [COMMAND_PUSH, COMMAND_UNSHIFT, COMMAND_SPLICE, COMMAND_SET, COMMAND_MERGE, COMMAND_APPLY];
46
39
 
47
40
  var ALL_COMMANDS_SET = {};
48
41
 
49
- ALL_COMMANDS_LIST.forEach(function(command) {
42
+ ALL_COMMANDS_LIST.forEach(function (command) {
50
43
  ALL_COMMANDS_SET[command] = true;
51
44
  });
52
45
 
53
46
  function invariantArrayCase(value, spec, command) {
54
- ("production" !== process.env.NODE_ENV ? invariant(
55
- Array.isArray(value),
56
- 'update(): expected target of %s to be an array; got %s.',
57
- command,
58
- value
59
- ) : invariant(Array.isArray(value)));
47
+ !Array.isArray(value) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'update(): expected target of %s to be an array; got %s.', command, value) : invariant(false) : undefined;
60
48
  var specValue = spec[command];
61
- ("production" !== process.env.NODE_ENV ? invariant(
62
- Array.isArray(specValue),
63
- 'update(): expected spec of %s to be an array; got %s. ' +
64
- 'Did you forget to wrap your parameter in an array?',
65
- command,
66
- specValue
67
- ) : invariant(Array.isArray(specValue)));
49
+ !Array.isArray(specValue) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'update(): expected spec of %s to be an array; got %s. ' + 'Did you forget to wrap your parameter in an array?', command, specValue) : invariant(false) : undefined;
68
50
  }
69
51
 
70
52
  function update(value, spec) {
71
- ("production" !== process.env.NODE_ENV ? invariant(
72
- typeof spec === 'object',
73
- 'update(): You provided a key path to update() that did not contain one ' +
74
- 'of %s. Did you forget to include {%s: ...}?',
75
- ALL_COMMANDS_LIST.join(', '),
76
- COMMAND_SET
77
- ) : invariant(typeof spec === 'object'));
53
+ !(typeof spec === 'object') ? 'production' !== process.env.NODE_ENV ? invariant(false, 'update(): You provided a key path to update() that did not contain one ' + 'of %s. Did you forget to include {%s: ...}?', ALL_COMMANDS_LIST.join(', '), COMMAND_SET) : invariant(false) : undefined;
78
54
 
79
55
  if (hasOwnProperty.call(spec, COMMAND_SET)) {
80
- ("production" !== process.env.NODE_ENV ? invariant(
81
- Object.keys(spec).length === 1,
82
- 'Cannot have more than one key in an object with %s',
83
- COMMAND_SET
84
- ) : invariant(Object.keys(spec).length === 1));
56
+ !(Object.keys(spec).length === 1) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'Cannot have more than one key in an object with %s', COMMAND_SET) : invariant(false) : undefined;
85
57
 
86
58
  return spec[COMMAND_SET];
87
59
  }
@@ -90,68 +62,36 @@ function update(value, spec) {
90
62
 
91
63
  if (hasOwnProperty.call(spec, COMMAND_MERGE)) {
92
64
  var mergeObj = spec[COMMAND_MERGE];
93
- ("production" !== process.env.NODE_ENV ? invariant(
94
- mergeObj && typeof mergeObj === 'object',
95
- 'update(): %s expects a spec of type \'object\'; got %s',
96
- COMMAND_MERGE,
97
- mergeObj
98
- ) : invariant(mergeObj && typeof mergeObj === 'object'));
99
- ("production" !== process.env.NODE_ENV ? invariant(
100
- nextValue && typeof nextValue === 'object',
101
- 'update(): %s expects a target of type \'object\'; got %s',
102
- COMMAND_MERGE,
103
- nextValue
104
- ) : invariant(nextValue && typeof nextValue === 'object'));
65
+ !(mergeObj && typeof mergeObj === 'object') ? 'production' !== process.env.NODE_ENV ? invariant(false, 'update(): %s expects a spec of type \'object\'; got %s', COMMAND_MERGE, mergeObj) : invariant(false) : undefined;
66
+ !(nextValue && typeof nextValue === 'object') ? 'production' !== process.env.NODE_ENV ? invariant(false, 'update(): %s expects a target of type \'object\'; got %s', COMMAND_MERGE, nextValue) : invariant(false) : undefined;
105
67
  assign(nextValue, spec[COMMAND_MERGE]);
106
68
  }
107
69
 
108
70
  if (hasOwnProperty.call(spec, COMMAND_PUSH)) {
109
71
  invariantArrayCase(value, spec, COMMAND_PUSH);
110
- spec[COMMAND_PUSH].forEach(function(item) {
72
+ spec[COMMAND_PUSH].forEach(function (item) {
111
73
  nextValue.push(item);
112
74
  });
113
75
  }
114
76
 
115
77
  if (hasOwnProperty.call(spec, COMMAND_UNSHIFT)) {
116
78
  invariantArrayCase(value, spec, COMMAND_UNSHIFT);
117
- spec[COMMAND_UNSHIFT].forEach(function(item) {
79
+ spec[COMMAND_UNSHIFT].forEach(function (item) {
118
80
  nextValue.unshift(item);
119
81
  });
120
82
  }
121
83
 
122
84
  if (hasOwnProperty.call(spec, COMMAND_SPLICE)) {
123
- ("production" !== process.env.NODE_ENV ? invariant(
124
- Array.isArray(value),
125
- 'Expected %s target to be an array; got %s',
126
- COMMAND_SPLICE,
127
- value
128
- ) : invariant(Array.isArray(value)));
129
- ("production" !== process.env.NODE_ENV ? invariant(
130
- Array.isArray(spec[COMMAND_SPLICE]),
131
- 'update(): expected spec of %s to be an array of arrays; got %s. ' +
132
- 'Did you forget to wrap your parameters in an array?',
133
- COMMAND_SPLICE,
134
- spec[COMMAND_SPLICE]
135
- ) : invariant(Array.isArray(spec[COMMAND_SPLICE])));
136
- spec[COMMAND_SPLICE].forEach(function(args) {
137
- ("production" !== process.env.NODE_ENV ? invariant(
138
- Array.isArray(args),
139
- 'update(): expected spec of %s to be an array of arrays; got %s. ' +
140
- 'Did you forget to wrap your parameters in an array?',
141
- COMMAND_SPLICE,
142
- spec[COMMAND_SPLICE]
143
- ) : invariant(Array.isArray(args)));
85
+ !Array.isArray(value) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'Expected %s target to be an array; got %s', COMMAND_SPLICE, value) : invariant(false) : undefined;
86
+ !Array.isArray(spec[COMMAND_SPLICE]) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'update(): expected spec of %s to be an array of arrays; got %s. ' + 'Did you forget to wrap your parameters in an array?', COMMAND_SPLICE, spec[COMMAND_SPLICE]) : invariant(false) : undefined;
87
+ spec[COMMAND_SPLICE].forEach(function (args) {
88
+ !Array.isArray(args) ? 'production' !== process.env.NODE_ENV ? invariant(false, 'update(): expected spec of %s to be an array of arrays; got %s. ' + 'Did you forget to wrap your parameters in an array?', COMMAND_SPLICE, spec[COMMAND_SPLICE]) : invariant(false) : undefined;
144
89
  nextValue.splice.apply(nextValue, args);
145
90
  });
146
91
  }
147
92
 
148
93
  if (hasOwnProperty.call(spec, COMMAND_APPLY)) {
149
- ("production" !== process.env.NODE_ENV ? invariant(
150
- typeof spec[COMMAND_APPLY] === 'function',
151
- 'update(): expected spec of %s to be a function; got %s.',
152
- COMMAND_APPLY,
153
- spec[COMMAND_APPLY]
154
- ) : invariant(typeof spec[COMMAND_APPLY] === 'function'));
94
+ !(typeof spec[COMMAND_APPLY] === 'function') ? 'production' !== process.env.NODE_ENV ? invariant(false, 'update(): expected spec of %s to be a function; got %s.', COMMAND_APPLY, spec[COMMAND_APPLY]) : invariant(false) : undefined;
155
95
  nextValue = spec[COMMAND_APPLY](nextValue);
156
96
  }
157
97
 
@@ -164,4 +104,4 @@ function update(value, spec) {
164
104
  return nextValue;
165
105
  }
166
106
 
167
- module.exports = update;
107
+ module.exports = update;
@@ -0,0 +1,363 @@
1
+ /**
2
+ * Copyright 2015, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule validateDOMNesting
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var assign = require("./Object.assign");
15
+ var emptyFunction = require("./emptyFunction");
16
+ var warning = require("./warning");
17
+
18
+ var validateDOMNesting = emptyFunction;
19
+
20
+ if ('production' !== process.env.NODE_ENV) {
21
+ // This validation code was written based on the HTML5 parsing spec:
22
+ // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
23
+ //
24
+ // Note: this does not catch all invalid nesting, nor does it try to (as it's
25
+ // not clear what practical benefit doing so provides); instead, we warn only
26
+ // for cases where the parser will give a parse tree differing from what React
27
+ // intended. For example, <b><div></div></b> is invalid but we don't warn
28
+ // because it still parses correctly; we do warn for other cases like nested
29
+ // <p> tags where the beginning of the second element implicitly closes the
30
+ // first, causing a confusing mess.
31
+
32
+ // https://html.spec.whatwg.org/multipage/syntax.html#special
33
+ var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp'];
34
+
35
+ // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
36
+ var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template',
37
+
38
+ // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
39
+ // TODO: Distinguish by namespace here -- for <title>, including it here
40
+ // errs on the side of fewer warnings
41
+ 'foreignObject', 'desc', 'title'];
42
+
43
+ // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
44
+ var buttonScopeTags = inScopeTags.concat(['button']);
45
+
46
+ // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
47
+ var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
48
+
49
+ var emptyAncestorInfo = {
50
+ parentTag: null,
51
+
52
+ formTag: null,
53
+ aTagInScope: null,
54
+ buttonTagInScope: null,
55
+ nobrTagInScope: null,
56
+ pTagInButtonScope: null,
57
+
58
+ listItemTagAutoclosing: null,
59
+ dlItemTagAutoclosing: null
60
+ };
61
+
62
+ var updatedAncestorInfo = function (oldInfo, tag, instance) {
63
+ var ancestorInfo = assign({}, oldInfo || emptyAncestorInfo);
64
+ var info = { tag: tag, instance: instance };
65
+
66
+ if (inScopeTags.indexOf(tag) !== -1) {
67
+ ancestorInfo.aTagInScope = null;
68
+ ancestorInfo.buttonTagInScope = null;
69
+ ancestorInfo.nobrTagInScope = null;
70
+ }
71
+ if (buttonScopeTags.indexOf(tag) !== -1) {
72
+ ancestorInfo.pTagInButtonScope = null;
73
+ }
74
+
75
+ // See rules for 'li', 'dd', 'dt' start tags in
76
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
77
+ if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
78
+ ancestorInfo.listItemTagAutoclosing = null;
79
+ ancestorInfo.dlItemTagAutoclosing = null;
80
+ }
81
+
82
+ ancestorInfo.parentTag = info;
83
+
84
+ if (tag === 'form') {
85
+ ancestorInfo.formTag = info;
86
+ }
87
+ if (tag === 'a') {
88
+ ancestorInfo.aTagInScope = info;
89
+ }
90
+ if (tag === 'button') {
91
+ ancestorInfo.buttonTagInScope = info;
92
+ }
93
+ if (tag === 'nobr') {
94
+ ancestorInfo.nobrTagInScope = info;
95
+ }
96
+ if (tag === 'p') {
97
+ ancestorInfo.pTagInButtonScope = info;
98
+ }
99
+ if (tag === 'li') {
100
+ ancestorInfo.listItemTagAutoclosing = info;
101
+ }
102
+ if (tag === 'dd' || tag === 'dt') {
103
+ ancestorInfo.dlItemTagAutoclosing = info;
104
+ }
105
+
106
+ return ancestorInfo;
107
+ };
108
+
109
+ /**
110
+ * Returns whether
111
+ */
112
+ var isTagValidWithParent = function (tag, parentTag) {
113
+ // First, let's check if we're in an unusual parsing mode...
114
+ switch (parentTag) {
115
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
116
+ case 'select':
117
+ return tag === 'option' || tag === 'optgroup' || tag === '#text';
118
+ case 'optgroup':
119
+ return tag === 'option' || tag === '#text';
120
+ // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
121
+ // but
122
+ case 'option':
123
+ return tag === '#text';
124
+
125
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
126
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
127
+ // No special behavior since these rules fall back to "in body" mode for
128
+ // all except special table nodes which cause bad parsing behavior anyway.
129
+
130
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
131
+ case 'tr':
132
+ return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
133
+
134
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
135
+ case 'tbody':
136
+ case 'thead':
137
+ case 'tfoot':
138
+ return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
139
+
140
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
141
+ case 'colgroup':
142
+ return tag === 'col' || tag === 'template';
143
+
144
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
145
+ case 'table':
146
+ return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
147
+
148
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
149
+ case 'head':
150
+ return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
151
+
152
+ // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
153
+ case 'html':
154
+ return tag === 'head' || tag === 'body';
155
+ }
156
+
157
+ // Probably in the "in body" parsing mode, so we outlaw only tag combos
158
+ // where the parsing rules cause implicit opens or closes to be added.
159
+ // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
160
+ switch (tag) {
161
+ case 'h1':
162
+ case 'h2':
163
+ case 'h3':
164
+ case 'h4':
165
+ case 'h5':
166
+ case 'h6':
167
+ return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
168
+
169
+ case 'rp':
170
+ case 'rt':
171
+ return impliedEndTags.indexOf(parentTag) === -1;
172
+
173
+ case 'caption':
174
+ case 'col':
175
+ case 'colgroup':
176
+ case 'frame':
177
+ case 'head':
178
+ case 'tbody':
179
+ case 'td':
180
+ case 'tfoot':
181
+ case 'th':
182
+ case 'thead':
183
+ case 'tr':
184
+ // These tags are only valid with a few parents that have special child
185
+ // parsing rules -- if we're down here, then none of those matched and
186
+ // so we allow it only if we don't know what the parent is, as all other
187
+ // cases are invalid.
188
+ return parentTag == null;
189
+ }
190
+
191
+ return true;
192
+ };
193
+
194
+ /**
195
+ * Returns whether
196
+ */
197
+ var findInvalidAncestorForTag = function (tag, ancestorInfo) {
198
+ switch (tag) {
199
+ case 'address':
200
+ case 'article':
201
+ case 'aside':
202
+ case 'blockquote':
203
+ case 'center':
204
+ case 'details':
205
+ case 'dialog':
206
+ case 'dir':
207
+ case 'div':
208
+ case 'dl':
209
+ case 'fieldset':
210
+ case 'figcaption':
211
+ case 'figure':
212
+ case 'footer':
213
+ case 'header':
214
+ case 'hgroup':
215
+ case 'main':
216
+ case 'menu':
217
+ case 'nav':
218
+ case 'ol':
219
+ case 'p':
220
+ case 'section':
221
+ case 'summary':
222
+ case 'ul':
223
+
224
+ case 'pre':
225
+ case 'listing':
226
+
227
+ case 'table':
228
+
229
+ case 'hr':
230
+
231
+ case 'xmp':
232
+
233
+ case 'h1':
234
+ case 'h2':
235
+ case 'h3':
236
+ case 'h4':
237
+ case 'h5':
238
+ case 'h6':
239
+ return ancestorInfo.pTagInButtonScope;
240
+
241
+ case 'form':
242
+ return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
243
+
244
+ case 'li':
245
+ return ancestorInfo.listItemTagAutoclosing;
246
+
247
+ case 'dd':
248
+ case 'dt':
249
+ return ancestorInfo.dlItemTagAutoclosing;
250
+
251
+ case 'button':
252
+ return ancestorInfo.buttonTagInScope;
253
+
254
+ case 'a':
255
+ // Spec says something about storing a list of markers, but it sounds
256
+ // equivalent to this check.
257
+ return ancestorInfo.aTagInScope;
258
+
259
+ case 'nobr':
260
+ return ancestorInfo.nobrTagInScope;
261
+ }
262
+
263
+ return null;
264
+ };
265
+
266
+ /**
267
+ * Given a ReactCompositeComponent instance, return a list of its recursive
268
+ * owners, starting at the root and ending with the instance itself.
269
+ */
270
+ var findOwnerStack = function (instance) {
271
+ if (!instance) {
272
+ return [];
273
+ }
274
+
275
+ var stack = [];
276
+ /*eslint-disable space-after-keywords */
277
+ do {
278
+ /*eslint-enable space-after-keywords */
279
+ stack.push(instance);
280
+ } while (instance = instance._currentElement._owner);
281
+ stack.reverse();
282
+ return stack;
283
+ };
284
+
285
+ var didWarn = {};
286
+
287
+ validateDOMNesting = function (childTag, childInstance, ancestorInfo) {
288
+ ancestorInfo = ancestorInfo || emptyAncestorInfo;
289
+ var parentInfo = ancestorInfo.parentTag;
290
+ var parentTag = parentInfo && parentInfo.tag;
291
+
292
+ var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
293
+ var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
294
+ var problematic = invalidParent || invalidAncestor;
295
+
296
+ if (problematic) {
297
+ var ancestorTag = problematic.tag;
298
+ var ancestorInstance = problematic.instance;
299
+
300
+ var childOwner = childInstance && childInstance._currentElement._owner;
301
+ var ancestorOwner = ancestorInstance && ancestorInstance._currentElement._owner;
302
+
303
+ var childOwners = findOwnerStack(childOwner);
304
+ var ancestorOwners = findOwnerStack(ancestorOwner);
305
+
306
+ var minStackLen = Math.min(childOwners.length, ancestorOwners.length);
307
+ var i;
308
+
309
+ var deepestCommon = -1;
310
+ for (i = 0; i < minStackLen; i++) {
311
+ if (childOwners[i] === ancestorOwners[i]) {
312
+ deepestCommon = i;
313
+ } else {
314
+ break;
315
+ }
316
+ }
317
+
318
+ var UNKNOWN = '(unknown)';
319
+ var childOwnerNames = childOwners.slice(deepestCommon + 1).map(function (inst) {
320
+ return inst.getName() || UNKNOWN;
321
+ });
322
+ var ancestorOwnerNames = ancestorOwners.slice(deepestCommon + 1).map(function (inst) {
323
+ return inst.getName() || UNKNOWN;
324
+ });
325
+ var ownerInfo = [].concat(
326
+ // If the parent and child instances have a common owner ancestor, start
327
+ // with that -- otherwise we just start with the parent's owners.
328
+ deepestCommon !== -1 ? childOwners[deepestCommon].getName() || UNKNOWN : [], ancestorOwnerNames, ancestorTag,
329
+ // If we're warning about an invalid (non-parent) ancestry, add '...'
330
+ invalidAncestor ? ['...'] : [], childOwnerNames, childTag).join(' > ');
331
+
332
+ var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + ownerInfo;
333
+ if (didWarn[warnKey]) {
334
+ return;
335
+ }
336
+ didWarn[warnKey] = true;
337
+
338
+ if (invalidParent) {
339
+ var info = '';
340
+ if (ancestorTag === 'table' && childTag === 'tr') {
341
+ info += ' Add a <tbody> to your code to match the DOM tree generated by ' + 'the browser.';
342
+ }
343
+ 'production' !== process.env.NODE_ENV ? warning(false, 'validateDOMNesting(...): <%s> cannot appear as a child of <%s>. ' + 'See %s.%s', childTag, ancestorTag, ownerInfo, info) : undefined;
344
+ } else {
345
+ 'production' !== process.env.NODE_ENV ? warning(false, 'validateDOMNesting(...): <%s> cannot appear as a descendant of ' + '<%s>. See %s.', childTag, ancestorTag, ownerInfo) : undefined;
346
+ }
347
+ }
348
+ };
349
+
350
+ validateDOMNesting.ancestorInfoContextKey = '__validateDOMNesting_ancestorInfo$' + Math.random().toString(36).slice(2);
351
+
352
+ validateDOMNesting.updatedAncestorInfo = updatedAncestorInfo;
353
+
354
+ // For testing
355
+ validateDOMNesting.isTagValidInContext = function (tag, ancestorInfo) {
356
+ ancestorInfo = ancestorInfo || emptyAncestorInfo;
357
+ var parentInfo = ancestorInfo.parentTag;
358
+ var parentTag = parentInfo && parentInfo.tag;
359
+ return isTagValidWithParent(tag, parentTag) && !findInvalidAncestorForTag(tag, ancestorInfo);
360
+ };
361
+ }
362
+
363
+ module.exports = validateDOMNesting;