react 0.14.0-beta1 → 0.14.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 (173) hide show
  1. package/addons.js +8 -3
  2. package/dist/react-with-addons.js +5048 -4095
  3. package/dist/react-with-addons.min.js +6 -6
  4. package/dist/react.js +4555 -3729
  5. package/dist/react.min.js +6 -5
  6. package/lib/AutoFocusUtils.js +3 -3
  7. package/lib/BeforeInputEventPlugin.js +13 -13
  8. package/lib/CSSProperty.js +18 -3
  9. package/lib/CSSPropertyOperations.js +27 -14
  10. package/lib/CallbackQueue.js +4 -4
  11. package/lib/ChangeEventPlugin.js +15 -14
  12. package/lib/DOMChildrenOperations.js +22 -7
  13. package/lib/DOMProperty.js +8 -8
  14. package/lib/DOMPropertyOperations.js +23 -10
  15. package/lib/Danger.js +21 -16
  16. package/lib/DefaultEventPluginOrder.js +2 -2
  17. package/lib/EnterLeaveEventPlugin.js +18 -10
  18. package/lib/EventConstants.js +23 -1
  19. package/lib/EventPluginHub.js +29 -21
  20. package/lib/EventPluginRegistry.js +8 -8
  21. package/lib/EventPluginUtils.js +34 -38
  22. package/lib/EventPropagators.js +8 -8
  23. package/lib/FallbackCompositionState.js +9 -3
  24. package/lib/HTMLDOMPropertyConfig.js +24 -4
  25. package/lib/LinkedStateMixin.js +2 -2
  26. package/lib/LinkedValueUtils.js +8 -8
  27. package/lib/MetaMatchers.js +118 -0
  28. package/lib/OrderedMap.js +453 -0
  29. package/lib/PooledClass.js +3 -5
  30. package/lib/React.js +18 -7
  31. package/lib/ReactBrowserComponentMixin.js +4 -4
  32. package/lib/ReactBrowserEventEmitter.js +36 -7
  33. package/lib/ReactCSSTransitionGroup.js +35 -9
  34. package/lib/ReactCSSTransitionGroupChild.js +48 -30
  35. package/lib/ReactChildReconciler.js +24 -19
  36. package/lib/ReactChildren.js +72 -32
  37. package/lib/ReactClass.js +46 -46
  38. package/lib/ReactComponent.js +18 -16
  39. package/lib/ReactComponentBrowserEnvironment.js +2 -2
  40. package/lib/ReactComponentEnvironment.js +2 -2
  41. package/lib/ReactComponentWithPureRenderMixin.js +1 -1
  42. package/lib/ReactCompositeComponent.js +95 -44
  43. package/lib/ReactDOM.js +74 -159
  44. package/lib/ReactDOMComponent.js +235 -93
  45. package/lib/ReactDOMFactories.js +177 -0
  46. package/lib/{emptyObject.js → ReactDOMFeatureFlags.js} +6 -8
  47. package/lib/ReactDOMIDOperations.js +8 -81
  48. package/lib/ReactDOMInput.js +18 -9
  49. package/lib/ReactDOMOption.js +7 -7
  50. package/lib/ReactDOMSelect.js +9 -9
  51. package/lib/ReactDOMSelection.js +19 -3
  52. package/lib/ReactDOMServer.js +5 -3
  53. package/lib/ReactDOMTextComponent.js +33 -20
  54. package/lib/ReactDOMTextarea.js +14 -12
  55. package/lib/ReactDefaultBatchingStrategy.js +4 -4
  56. package/lib/ReactDefaultInjection.js +23 -25
  57. package/lib/ReactDefaultPerf.js +17 -11
  58. package/lib/ReactDefaultPerfAnalysis.js +13 -12
  59. package/lib/ReactElement.js +85 -39
  60. package/lib/ReactElementValidator.js +47 -90
  61. package/lib/ReactEmptyComponent.js +26 -62
  62. package/lib/ReactEmptyComponentRegistry.js +48 -0
  63. package/lib/ReactErrorUtils.js +53 -9
  64. package/lib/ReactEventEmitterMixin.js +2 -2
  65. package/lib/ReactEventListener.js +33 -21
  66. package/lib/ReactFragment.js +27 -118
  67. package/lib/ReactInjection.js +10 -12
  68. package/lib/ReactInputSelection.js +4 -4
  69. package/lib/ReactInstanceHandles.js +10 -11
  70. package/lib/ReactIsomorphic.js +15 -11
  71. package/lib/ReactLink.js +2 -2
  72. package/lib/ReactMarkupChecksum.js +6 -2
  73. package/lib/ReactMount.js +186 -85
  74. package/lib/ReactMultiChild.js +119 -25
  75. package/lib/ReactMultiChildUpdateTypes.js +2 -1
  76. package/lib/ReactNativeComponent.js +3 -3
  77. package/lib/ReactNoopUpdateQueue.js +3 -3
  78. package/lib/ReactOwner.js +3 -3
  79. package/lib/ReactPerf.js +2 -2
  80. package/lib/ReactPropTransferer.js +3 -3
  81. package/lib/ReactPropTypeLocationNames.js +1 -1
  82. package/lib/ReactPropTypeLocations.js +1 -1
  83. package/lib/ReactPropTypes.js +38 -9
  84. package/lib/ReactReconcileTransaction.js +10 -8
  85. package/lib/ReactReconciler.js +5 -6
  86. package/lib/ReactRef.js +14 -2
  87. package/lib/ReactServerBatchingStrategy.js +5 -5
  88. package/lib/ReactServerRendering.js +12 -12
  89. package/lib/ReactServerRenderingTransaction.js +6 -5
  90. package/lib/ReactTestUtils.js +47 -39
  91. package/lib/ReactTransitionChildMapping.js +3 -6
  92. package/lib/ReactTransitionEvents.js +1 -1
  93. package/lib/ReactTransitionGroup.js +5 -6
  94. package/lib/ReactUpdateQueue.js +19 -19
  95. package/lib/ReactUpdates.js +15 -15
  96. package/lib/{performance.js → ReactVersion.js} +3 -12
  97. package/lib/ReactWithAddons.js +24 -15
  98. package/lib/ResponderEventPlugin.js +514 -0
  99. package/lib/ResponderSyntheticEvent.js +40 -0
  100. package/lib/ResponderTouchHistoryStore.js +180 -0
  101. package/lib/SVGDOMPropertyConfig.js +1 -1
  102. package/lib/SelectEventPlugin.js +19 -9
  103. package/lib/SimpleEventPlugin.js +198 -43
  104. package/lib/SyntheticClipboardEvent.js +1 -1
  105. package/lib/SyntheticCompositionEvent.js +1 -1
  106. package/lib/SyntheticDragEvent.js +1 -1
  107. package/lib/SyntheticEvent.js +18 -4
  108. package/lib/SyntheticFocusEvent.js +1 -1
  109. package/lib/SyntheticInputEvent.js +1 -1
  110. package/lib/SyntheticKeyboardEvent.js +4 -4
  111. package/lib/SyntheticMouseEvent.js +3 -3
  112. package/lib/SyntheticTouchEvent.js +2 -2
  113. package/lib/SyntheticUIEvent.js +2 -2
  114. package/lib/SyntheticWheelEvent.js +1 -1
  115. package/lib/TapEventPlugin.js +119 -0
  116. package/lib/Transaction.js +7 -7
  117. package/lib/accumulate.js +44 -0
  118. package/lib/accumulateInto.js +2 -2
  119. package/lib/adler32.js +19 -7
  120. package/lib/cloneWithProps.js +11 -6
  121. package/lib/createHierarchyRenderer.js +85 -0
  122. package/lib/dangerousStyleValue.js +1 -1
  123. package/lib/deprecated.js +7 -6
  124. package/lib/findDOMNode.js +9 -9
  125. package/lib/flattenChildren.js +4 -4
  126. package/lib/getEventKey.js +1 -1
  127. package/lib/{isTextNode.js → getTestDocument.js} +7 -11
  128. package/lib/getTextContentAccessor.js +1 -1
  129. package/lib/instantiateReactComponent.js +15 -17
  130. package/lib/isEventSupported.js +1 -1
  131. package/lib/onlyChild.js +3 -3
  132. package/lib/quoteAttributeValueForBrowser.js +1 -1
  133. package/lib/reactComponentExpect.js +216 -0
  134. package/lib/renderSubtreeIntoContainer.js +1 -1
  135. package/lib/setInnerHTML.js +1 -1
  136. package/lib/setTextContent.js +3 -3
  137. package/lib/shallowCompare.js +1 -1
  138. package/lib/shouldUpdateReactComponent.js +12 -8
  139. package/lib/sliceChildren.js +34 -0
  140. package/lib/traverseAllChildren.js +25 -18
  141. package/lib/update.js +13 -13
  142. package/lib/validateDOMNesting.js +6 -6
  143. package/lib/webcomponents.js +6379 -0
  144. package/package.json +4 -6
  145. package/react.js +1 -51
  146. package/dist/JSXTransformer.js +0 -17588
  147. package/lib/CSSCore.js +0 -97
  148. package/lib/EventListener.js +0 -84
  149. package/lib/ExecutionEnvironment.js +0 -38
  150. package/lib/ReactDOMClient.js +0 -90
  151. package/lib/camelize.js +0 -32
  152. package/lib/camelizeStyleName.js +0 -40
  153. package/lib/containsNode.js +0 -55
  154. package/lib/createArrayFromMixed.js +0 -85
  155. package/lib/createNodesFromMarkup.js +0 -84
  156. package/lib/emptyFunction.js +0 -38
  157. package/lib/focusNode.js +0 -26
  158. package/lib/getActiveElement.js +0 -29
  159. package/lib/getMarkupWrap.js +0 -93
  160. package/lib/getUnboundedScrollPosition.js +0 -38
  161. package/lib/hyphenate.js +0 -33
  162. package/lib/hyphenateStyleName.js +0 -39
  163. package/lib/invariant.js +0 -49
  164. package/lib/isNode.js +0 -23
  165. package/lib/joinClasses.js +0 -39
  166. package/lib/keyMirror.js +0 -48
  167. package/lib/keyOf.js +0 -35
  168. package/lib/mapObject.js +0 -51
  169. package/lib/memoizeStringOnly.js +0 -31
  170. package/lib/performanceNow.js +0 -28
  171. package/lib/shallowEqual.js +0 -48
  172. package/lib/toArray.js +0 -57
  173. package/lib/warning.js +0 -57
@@ -0,0 +1,453 @@
1
+ /**
2
+ * Copyright 2013-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 OrderedMap
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var assign = require('./Object.assign');
15
+ var invariant = require('fbjs/lib/invariant');
16
+
17
+ var PREFIX = 'key:';
18
+
19
+ /**
20
+ * Utility to extract a backing object from an initialization `Array`, allowing
21
+ * the caller to assist in resolving the unique ID for each entry via the
22
+ * `keyExtractor` callback. The `keyExtractor` must extract non-empty strings or
23
+ * numbers.
24
+ * @param {Array<Object!>} arr Array of items.
25
+ * @param {function} keyExtractor Extracts a unique key from each item.
26
+ * @return {Object} Map from unique key to originating value that the key was
27
+ * extracted from.
28
+ * @throws Exception if the initialization array has duplicate extracted keys.
29
+ */
30
+ function extractObjectFromArray(arr, keyExtractor) {
31
+ var normalizedObj = {};
32
+ for (var i = 0; i < arr.length; i++) {
33
+ var item = arr[i];
34
+ var key = keyExtractor(item);
35
+ assertValidPublicKey(key);
36
+ var normalizedKey = PREFIX + key;
37
+ !!(normalizedKey in normalizedObj) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap: IDs returned by the key extraction function must be unique.') : invariant(false) : undefined;
38
+ normalizedObj[normalizedKey] = item;
39
+ }
40
+ return normalizedObj;
41
+ }
42
+
43
+ /**
44
+ * Utility class for mappings with ordering. This class is to be used in an
45
+ * immutable manner. A `OrderedMap` is very much like the native JavaScript
46
+ * object, where keys map to values via the `get()` function. Also, like the
47
+ * native JavaScript object, there is an ordering associated with the mapping.
48
+ * This class is helpful because it eliminates many of the pitfalls that come
49
+ * with the native JavaScript ordered mappings. Specifically, there are
50
+ * inconsistencies with numeric keys in some JavaScript implementations
51
+ * (enumeration ordering). This class protects against those pitfalls and
52
+ * provides functional utilities for dealing with these `OrderedMap`s.
53
+ *
54
+ * - TODO:
55
+ * - orderedMergeExclusive: Merges mutually exclusive `OrderedMap`s.
56
+ * - mapReverse().
57
+ *
58
+ * @class {OrderedMap}
59
+ * @constructor {OrderedMap}
60
+ * @param {Object} normalizedObj Object that is known to be a defensive copy of
61
+ * caller supplied data. We require a defensive copy to guard against callers
62
+ * mutating. It is also assumed that the keys of `normalizedObj` have been
63
+ * normalized and do not contain any numeric-appearing strings.
64
+ * @param {number} computedLength The precomputed length of `_normalizedObj`
65
+ * keys.
66
+ * @private
67
+ */
68
+ function OrderedMapImpl(normalizedObj, computedLength) {
69
+ this._normalizedObj = normalizedObj;
70
+ this._computedPositions = null;
71
+ this.length = computedLength;
72
+ }
73
+
74
+ /**
75
+ * Validates a "public" key - that is, one that the public facing API supplies.
76
+ * The key is then normalized for internal storage. In order to be considered
77
+ * valid, all keys must be non-empty, defined, non-null strings or numbers.
78
+ *
79
+ * @param {string?} key Validates that the key is suitable for use in a
80
+ * `OrderedMap`.
81
+ * @throws Error if key is not appropriate for use in `OrderedMap`.
82
+ */
83
+ function assertValidPublicKey(key) {
84
+ !(key !== '' && (typeof key === 'string' || typeof key === 'number')) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap: Key must be non-empty, non-null string or number.') : invariant(false) : undefined;
85
+ }
86
+
87
+ /**
88
+ * Validates that arguments to range operations are within the correct limits.
89
+ *
90
+ * @param {number} start Start of range.
91
+ * @param {number} length Length of range.
92
+ * @param {number} actualLen Actual length of range that should not be
93
+ * exceeded.
94
+ * @throws Error if range arguments are out of bounds.
95
+ */
96
+ function assertValidRangeIndices(start, length, actualLen) {
97
+ !(typeof start === 'number' && typeof length === 'number' && length >= 0 && start >= 0 && start + length <= actualLen) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap: `mapRange` and `forEachRange` expect non-negative start and ' + 'length arguments within the bounds of the instance.') : invariant(false) : undefined;
98
+ }
99
+
100
+ /**
101
+ * Merges two "normalized" objects (objects who's key have been normalized) into
102
+ * a `OrderedMap`.
103
+ *
104
+ * @param {Object} a Object of key value pairs.
105
+ * @param {Object} b Object of key value pairs.
106
+ * @return {OrderedMap} new `OrderedMap` that results in merging `a` and `b`.
107
+ */
108
+ function _fromNormalizedObjects(a, b) {
109
+ // Second optional, both must be plain JavaScript objects.
110
+ !(a && a.constructor === Object && (!b || b.constructor === Object)) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap: Corrupted instance of OrderedMap detected.') : invariant(false) : undefined;
111
+
112
+ var newSet = {};
113
+ var length = 0;
114
+ var key;
115
+ for (key in a) {
116
+ if (a.hasOwnProperty(key)) {
117
+ newSet[key] = a[key];
118
+ length++;
119
+ }
120
+ }
121
+
122
+ for (key in b) {
123
+ if (b.hasOwnProperty(key)) {
124
+ // Increment length if not already added via first object (a)
125
+ if (!(key in newSet)) {
126
+ length++;
127
+ }
128
+ newSet[key] = b[key];
129
+ }
130
+ }
131
+ return new OrderedMapImpl(newSet, length);
132
+ }
133
+
134
+ /**
135
+ * Methods for `OrderedMap` instances.
136
+ *
137
+ * @lends OrderedMap.prototype
138
+ * TODO: Make this data structure lazy, unify with LazyArray.
139
+ * TODO: Unify this with ImmutableObject - it is to be used immutably.
140
+ * TODO: If so, consider providing `fromObject` API.
141
+ * TODO: Create faster implementation of merging/mapping from original Array,
142
+ * without having to first create an object - simply for the sake of merging.
143
+ */
144
+ var OrderedMapMethods = {
145
+
146
+ /**
147
+ * Returns whether or not a given key is present in the map.
148
+ *
149
+ * @param {string} key Valid string key to lookup membership for.
150
+ * @return {boolean} Whether or not `key` is a member of the map.
151
+ * @throws Error if provided known invalid key.
152
+ */
153
+ has: function (key) {
154
+ assertValidPublicKey(key);
155
+ var normalizedKey = PREFIX + key;
156
+ return normalizedKey in this._normalizedObj;
157
+ },
158
+
159
+ /**
160
+ * Returns the object for a given key, or `undefined` if not present. To
161
+ * distinguish an undefined entry vs not being in the set, use `has()`.
162
+ *
163
+ * @param {string} key String key to lookup the value for.
164
+ * @return {Object?} Object at key `key`, or undefined if not in map.
165
+ * @throws Error if provided known invalid key.
166
+ */
167
+ get: function (key) {
168
+ assertValidPublicKey(key);
169
+ var normalizedKey = PREFIX + key;
170
+ return this.has(key) ? this._normalizedObj[normalizedKey] : undefined;
171
+ },
172
+
173
+ /**
174
+ * Merges, appending new keys to the end of the ordering. Keys in `orderedMap`
175
+ * that are redundant with `this`, maintain the same ordering index that they
176
+ * had in `this`. This is how standard JavaScript object merging would work.
177
+ * If you wish to prepend a `OrderedMap` to the beginning of another
178
+ * `OrderedMap` then simply reverse the order of operation. This is the analog
179
+ * to `merge(x, y)`.
180
+ *
181
+ * @param {OrderedMap} orderedMap OrderedMap to merge onto the end.
182
+ * @return {OrderedMap} New OrderedMap that represents the result of the
183
+ * merge.
184
+ */
185
+ merge: function (orderedMap) {
186
+ !(orderedMap instanceof OrderedMapImpl) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap.merge(...): Expected an OrderedMap instance.') : invariant(false) : undefined;
187
+ return _fromNormalizedObjects(this._normalizedObj, orderedMap._normalizedObj);
188
+ },
189
+
190
+ /**
191
+ * Functional map API. Returns a new `OrderedMap`.
192
+ *
193
+ * @param {Function} cb Callback to invoke for each item.
194
+ * @param {Object?=} context Context to invoke callback from.
195
+ * @return {OrderedMap} OrderedMap that results from mapping.
196
+ */
197
+ map: function (cb, context) {
198
+ return this.mapRange(cb, 0, this.length, context);
199
+ },
200
+
201
+ /**
202
+ * The callback `cb` is invoked with the arguments (item, key,
203
+ * indexInOriginal).
204
+ *
205
+ * @param {Function} cb Determines result for each item.
206
+ * @param {number} start Start index of map range.
207
+ * @param {end} length End index of map range.
208
+ * @param {*!?} context Context of callback invocation.
209
+ * @return {OrderedMap} OrderedMap resulting from mapping the range.
210
+ */
211
+ mapRange: function (cb, start, length, context) {
212
+ var thisSet = this._normalizedObj;
213
+ var newSet = {};
214
+ var i = 0;
215
+ assertValidRangeIndices(start, length, this.length);
216
+ var end = start + length - 1;
217
+ for (var key in thisSet) {
218
+ if (thisSet.hasOwnProperty(key)) {
219
+ if (i >= start) {
220
+ if (i > end) {
221
+ break;
222
+ }
223
+ var item = thisSet[key];
224
+ newSet[key] = cb.call(context, item, key.substr(PREFIX.length), i);
225
+ }
226
+ i++;
227
+ }
228
+ }
229
+ return new OrderedMapImpl(newSet, length);
230
+ },
231
+
232
+ /**
233
+ * Function filter API. Returns new `OrderedMap`.
234
+ *
235
+ * @param {Function} cb Callback to invoke for each item.
236
+ * @param {Object?=} context Context to invoke callback from.
237
+ * @return {OrderedMap} OrderedMap that results from filtering.
238
+ */
239
+ filter: function (cb, context) {
240
+ return this.filterRange(cb, 0, this.length, context);
241
+ },
242
+
243
+ /**
244
+ * The callback `cb` is invoked with the arguments (item, key,
245
+ * indexInOriginal).
246
+ *
247
+ * @param {Function} cb Returns true if item should be in result.
248
+ * @param {number} start Start index of filter range.
249
+ * @param {number} length End index of map range.
250
+ * @param {*!?} context Context of callback invocation.
251
+ * @return {OrderedMap} OrderedMap resulting from filtering the range.
252
+ */
253
+ filterRange: function (cb, start, length, context) {
254
+ var newSet = {};
255
+ var newSetLength = 0;
256
+ this.forEachRange(function (item, key, originalIndex) {
257
+ if (cb.call(context, item, key, originalIndex)) {
258
+ var normalizedKey = PREFIX + key;
259
+ newSet[normalizedKey] = item;
260
+ newSetLength++;
261
+ }
262
+ }, start, length);
263
+ return new OrderedMapImpl(newSet, newSetLength);
264
+ },
265
+
266
+ forEach: function (cb, context) {
267
+ this.forEachRange(cb, 0, this.length, context);
268
+ },
269
+
270
+ forEachRange: function (cb, start, length, context) {
271
+ assertValidRangeIndices(start, length, this.length);
272
+ var thisSet = this._normalizedObj;
273
+ var i = 0;
274
+ var end = start + length - 1;
275
+ for (var key in thisSet) {
276
+ if (thisSet.hasOwnProperty(key)) {
277
+ if (i >= start) {
278
+ if (i > end) {
279
+ break;
280
+ }
281
+ var item = thisSet[key];
282
+ cb.call(context, item, key.substr(PREFIX.length), i);
283
+ }
284
+ i++;
285
+ }
286
+ }
287
+ },
288
+
289
+ /**
290
+ * Even though `mapRange`/`forEachKeyRange` allow zero length mappings, we'll
291
+ * impose an additional restriction here that the length of mapping be greater
292
+ * than zero - the only reason is that there are many ways to express length
293
+ * zero in terms of two keys and that is confusing.
294
+ */
295
+ mapKeyRange: function (cb, startKey, endKey, context) {
296
+ var startIndex = this.indexOfKey(startKey);
297
+ var endIndex = this.indexOfKey(endKey);
298
+ !(startIndex !== undefined && endIndex !== undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'mapKeyRange must be given keys that are present.') : invariant(false) : undefined;
299
+ !(endIndex >= startIndex) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap.mapKeyRange(...): `endKey` must not come before `startIndex`.') : invariant(false) : undefined;
300
+ return this.mapRange(cb, startIndex, endIndex - startIndex + 1, context);
301
+ },
302
+
303
+ forEachKeyRange: function (cb, startKey, endKey, context) {
304
+ var startIndex = this.indexOfKey(startKey);
305
+ var endIndex = this.indexOfKey(endKey);
306
+ !(startIndex !== undefined && endIndex !== undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'forEachKeyRange must be given keys that are present.') : invariant(false) : undefined;
307
+ !(endIndex >= startIndex) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap.forEachKeyRange(...): `endKey` must not come before ' + '`startIndex`.') : invariant(false) : undefined;
308
+ this.forEachRange(cb, startIndex, endIndex - startIndex + 1, context);
309
+ },
310
+
311
+ /**
312
+ * @param {number} pos Index to search for key at.
313
+ * @return {string|undefined} Either the key at index `pos` or undefined if
314
+ * not in map.
315
+ */
316
+ keyAtIndex: function (pos) {
317
+ var computedPositions = this._getOrComputePositions();
318
+ var keyAtPos = computedPositions.keyByIndex[pos];
319
+ return keyAtPos ? keyAtPos.substr(PREFIX.length) : undefined;
320
+ },
321
+
322
+ /**
323
+ * @param {string} key String key from which to find the next key.
324
+ * @return {string|undefined} Either the next key, or undefined if there is no
325
+ * next key.
326
+ * @throws Error if `key` is not in this `OrderedMap`.
327
+ */
328
+ keyAfter: function (key) {
329
+ return this.nthKeyAfter(key, 1);
330
+ },
331
+
332
+ /**
333
+ * @param {string} key String key from which to find the preceding key.
334
+ * @return {string|undefined} Either the preceding key, or undefined if there
335
+ * is no preceding.key.
336
+ * @throws Error if `key` is not in this `OrderedMap`.
337
+ */
338
+ keyBefore: function (key) {
339
+ return this.nthKeyBefore(key, 1);
340
+ },
341
+
342
+ /**
343
+ * @param {string} key String key from which to find a following key.
344
+ * @param {number} n Distance to scan forward after `key`.
345
+ * @return {string|undefined} Either the nth key after `key`, or undefined if
346
+ * there is no next key.
347
+ * @throws Error if `key` is not in this `OrderedMap`.
348
+ */
349
+ nthKeyAfter: function (key, n) {
350
+ var curIndex = this.indexOfKey(key);
351
+ !(curIndex !== undefined) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap.nthKeyAfter: The key `%s` does not exist in this instance.', key) : invariant(false) : undefined;
352
+ return this.keyAtIndex(curIndex + n);
353
+ },
354
+
355
+ /**
356
+ * @param {string} key String key from which to find a preceding key.
357
+ * @param {number} n Distance to scan backwards before `key`.
358
+ * @return {string|undefined} Either the nth key before `key`, or undefined if
359
+ * there is no previous key.
360
+ * @throws Error if `key` is not in this `OrderedMap`.
361
+ */
362
+ nthKeyBefore: function (key, n) {
363
+ return this.nthKeyAfter(key, -n);
364
+ },
365
+
366
+ /**
367
+ * @param {string} key Key to find the index of.
368
+ * @return {number|undefined} Index of the provided key, or `undefined` if the
369
+ * key is not found.
370
+ */
371
+ indexOfKey: function (key) {
372
+ assertValidPublicKey(key);
373
+ var normalizedKey = PREFIX + key;
374
+ var computedPositions = this._getOrComputePositions();
375
+ var computedPosition = computedPositions.indexByKey[normalizedKey];
376
+ // Just writing it this way to make it clear this is intentional.
377
+ return computedPosition === undefined ? undefined : computedPosition;
378
+ },
379
+
380
+ /**
381
+ * @return {Array} An ordered array of this object's values.
382
+ */
383
+ toArray: function () {
384
+ var result = [];
385
+ var thisSet = this._normalizedObj;
386
+ for (var key in thisSet) {
387
+ if (thisSet.hasOwnProperty(key)) {
388
+ result.push(thisSet[key]);
389
+ }
390
+ }
391
+ return result;
392
+ },
393
+
394
+ /**
395
+ * Finds the key at a given position, or indicates via `undefined` that that
396
+ * position does not exist in the `OrderedMap`. It is appropriate to return
397
+ * undefined, indicating that the key doesn't exist in the `OrderedMap`
398
+ * because `undefined` is not ever a valid `OrderedMap` key.
399
+ *
400
+ * @private
401
+ * @return {string?} Name of the item at position `pos`, or `undefined` if
402
+ * there is no item at that position.
403
+ */
404
+ _getOrComputePositions: function () {
405
+ // TODO: Entertain computing this at construction time in some less
406
+ // performance critical paths.
407
+ var computedPositions = this._computedPositions;
408
+ if (!computedPositions) {
409
+ this._computePositions();
410
+ }
411
+ return this._computedPositions;
412
+ },
413
+
414
+ /**
415
+ * Precomputes the index/key mapping for future lookup. Since `OrderedMap`s
416
+ * are immutable, there is only ever a need to perform this once.
417
+ * @private
418
+ */
419
+ _computePositions: function () {
420
+ this._computedPositions = {
421
+ keyByIndex: {},
422
+ indexByKey: {}
423
+ };
424
+ var keyByIndex = this._computedPositions.keyByIndex;
425
+ var indexByKey = this._computedPositions.indexByKey;
426
+ var index = 0;
427
+ var thisSet = this._normalizedObj;
428
+ for (var key in thisSet) {
429
+ if (thisSet.hasOwnProperty(key)) {
430
+ keyByIndex[index] = key;
431
+ indexByKey[key] = index;
432
+ index++;
433
+ }
434
+ }
435
+ }
436
+ };
437
+
438
+ assign(OrderedMapImpl.prototype, OrderedMapMethods);
439
+
440
+ var OrderedMap = {
441
+ from: function (orderedMap) {
442
+ !(orderedMap instanceof OrderedMapImpl) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap.from(...): Expected an OrderedMap instance.') : invariant(false) : undefined;
443
+ return _fromNormalizedObjects(orderedMap._normalizedObj, null);
444
+ },
445
+
446
+ fromArray: function (arr, keyExtractor) {
447
+ !Array.isArray(arr) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap.fromArray(...): First argument must be an array.') : invariant(false) : undefined;
448
+ !(typeof keyExtractor === 'function') ? process.env.NODE_ENV !== 'production' ? invariant(false, 'OrderedMap.fromArray(...): Second argument must be a function used ' + 'to determine the unique key for each entry.') : invariant(false) : undefined;
449
+ return new OrderedMapImpl(extractObjectFromArray(arr, keyExtractor), arr.length);
450
+ }
451
+ };
452
+
453
+ module.exports = OrderedMap;