react 0.14.0-alpha2 → 0.14.0-beta3
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.
- package/README.md +5 -2
- package/addons.js +6 -3
- package/dist/JSXTransformer.js +634 -274
- package/dist/react-with-addons.js +5350 -4954
- package/dist/react-with-addons.min.js +6 -6
- package/dist/react.js +4777 -4408
- package/dist/react.min.js +6 -5
- package/lib/{AutoFocusMixin.js → AutoFocusUtils.js} +15 -5
- package/lib/BeforeInputEventPlugin.js +13 -13
- package/lib/CSSProperty.js +3 -0
- package/lib/CSSPropertyOperations.js +13 -13
- package/lib/CallbackQueue.js +4 -4
- package/lib/ChangeEventPlugin.js +16 -14
- package/lib/DOMChildrenOperations.js +10 -6
- package/lib/DOMProperty.js +82 -117
- package/lib/DOMPropertyOperations.js +78 -33
- package/lib/Danger.js +14 -14
- package/lib/DefaultEventPluginOrder.js +2 -2
- package/lib/EnterLeaveEventPlugin.js +8 -8
- package/lib/EventConstants.js +23 -1
- package/lib/EventPluginHub.js +13 -13
- package/lib/EventPluginRegistry.js +8 -8
- package/lib/EventPluginUtils.js +17 -17
- package/lib/EventPropagators.js +7 -7
- package/lib/FallbackCompositionState.js +3 -3
- package/lib/HTMLDOMPropertyConfig.js +13 -3
- package/lib/LinkedStateMixin.js +2 -2
- package/lib/LinkedValueUtils.js +50 -38
- package/lib/MetaMatchers.js +118 -0
- package/lib/OrderedMap.js +453 -0
- package/lib/PooledClass.js +14 -2
- package/lib/React.js +6 -6
- package/lib/ReactBrowserComponentMixin.js +4 -4
- package/lib/ReactBrowserEventEmitter.js +30 -7
- package/lib/ReactCSSTransitionGroup.js +16 -5
- package/lib/ReactCSSTransitionGroupChild.js +20 -11
- package/lib/ReactChildReconciler.js +25 -18
- package/lib/ReactChildren.js +9 -9
- package/lib/ReactClass.js +65 -83
- package/lib/ReactComponent.js +22 -17
- package/lib/ReactComponentBrowserEnvironment.js +2 -2
- package/lib/ReactComponentEnvironment.js +2 -2
- package/lib/ReactComponentWithPureRenderMixin.js +3 -3
- package/lib/ReactCompositeComponent.js +80 -111
- package/lib/ReactDOM.js +72 -158
- package/lib/ReactDOMButton.js +15 -26
- package/lib/ReactDOMComponent.js +378 -56
- package/lib/ReactDOMFactories.js +177 -0
- package/lib/ReactDOMIDOperations.js +23 -23
- package/lib/ReactDOMInput.js +83 -99
- package/lib/ReactDOMOption.js +25 -45
- package/lib/ReactDOMSelect.js +88 -98
- package/lib/ReactDOMSelection.js +3 -3
- package/lib/ReactDOMServer.js +2 -2
- package/lib/ReactDOMTextComponent.js +11 -11
- package/lib/ReactDOMTextarea.js +48 -61
- package/lib/ReactDefaultBatchingStrategy.js +4 -4
- package/lib/ReactDefaultInjection.js +24 -71
- package/lib/ReactDefaultPerf.js +7 -7
- package/lib/ReactDefaultPerfAnalysis.js +6 -9
- package/lib/ReactElement.js +22 -83
- package/lib/ReactElementValidator.js +48 -117
- package/lib/ReactEmptyComponent.js +4 -4
- package/lib/ReactErrorUtils.js +1 -1
- package/lib/ReactEventEmitterMixin.js +3 -4
- package/lib/ReactEventListener.js +57 -12
- package/lib/ReactFragment.js +22 -17
- package/lib/ReactInjection.js +11 -11
- package/lib/ReactInputSelection.js +8 -7
- package/lib/ReactInstanceHandles.js +12 -12
- package/lib/ReactIsomorphic.js +11 -11
- package/lib/ReactLink.js +1 -1
- package/lib/ReactMarkupChecksum.js +6 -2
- package/lib/ReactMount.js +88 -88
- package/lib/ReactMultiChild.js +83 -22
- package/lib/ReactMultiChildUpdateTypes.js +2 -1
- package/lib/ReactNativeComponent.js +3 -8
- package/lib/ReactNoopUpdateQueue.js +118 -0
- package/lib/ReactOwner.js +3 -3
- package/lib/ReactPerf.js +2 -2
- package/lib/ReactPropTransferer.js +3 -3
- package/lib/ReactPropTypeLocationNames.js +1 -1
- package/lib/ReactPropTypeLocations.js +1 -1
- package/lib/ReactPropTypes.js +49 -11
- package/lib/ReactReconcileTransaction.js +8 -8
- package/lib/ReactReconciler.js +18 -20
- package/lib/ReactRef.js +1 -1
- package/lib/ReactServerBatchingStrategy.js +23 -0
- package/lib/ReactServerRendering.js +22 -9
- package/lib/ReactServerRenderingTransaction.js +7 -7
- package/lib/ReactTestUtils.js +80 -58
- package/lib/ReactTransitionChildMapping.js +2 -2
- package/lib/ReactTransitionEvents.js +1 -1
- package/lib/ReactTransitionGroup.js +5 -6
- package/lib/ReactUpdateQueue.js +61 -36
- package/lib/ReactUpdates.js +14 -17
- package/lib/ReactWithAddons.js +14 -16
- package/lib/ResponderEventPlugin.js +514 -0
- package/lib/ResponderSyntheticEvent.js +40 -0
- package/lib/ResponderTouchHistoryStore.js +180 -0
- package/lib/SVGDOMPropertyConfig.js +1 -1
- package/lib/SelectEventPlugin.js +14 -15
- package/lib/SimpleEventPlugin.js +205 -29
- package/lib/SyntheticClipboardEvent.js +3 -3
- package/lib/SyntheticCompositionEvent.js +3 -3
- package/lib/SyntheticDragEvent.js +3 -3
- package/lib/SyntheticEvent.js +9 -8
- package/lib/SyntheticFocusEvent.js +3 -3
- package/lib/SyntheticInputEvent.js +3 -3
- package/lib/SyntheticKeyboardEvent.js +6 -6
- package/lib/SyntheticMouseEvent.js +5 -5
- package/lib/SyntheticTouchEvent.js +4 -4
- package/lib/SyntheticUIEvent.js +4 -4
- package/lib/SyntheticWheelEvent.js +3 -3
- package/lib/TapEventPlugin.js +119 -0
- package/lib/Transaction.js +16 -10
- package/lib/accumulate.js +44 -0
- package/lib/accumulateInto.js +2 -2
- package/lib/adler32.js +19 -7
- package/lib/cloneWithProps.js +12 -7
- package/lib/createHierarchyRenderer.js +85 -0
- package/lib/dangerousStyleValue.js +1 -1
- package/lib/deprecated.js +47 -0
- package/lib/findDOMNode.js +11 -12
- package/lib/flattenChildren.js +4 -4
- package/lib/forEachAccumulated.js +1 -1
- package/lib/getEventCharCode.js +1 -1
- package/lib/getEventKey.js +1 -1
- package/lib/getEventModifierState.js +0 -1
- package/lib/getTestDocument.js +28 -0
- package/lib/getTextContentAccessor.js +1 -1
- package/lib/instantiateReactComponent.js +24 -20
- package/lib/isEventSupported.js +1 -1
- package/lib/isTextInputElement.js +2 -1
- package/lib/joinClasses.js +1 -1
- package/lib/onlyChild.js +3 -3
- package/lib/quoteAttributeValueForBrowser.js +1 -1
- package/lib/reactComponentExpect.js +210 -0
- package/lib/renderSubtreeIntoContainer.js +1 -1
- package/lib/setInnerHTML.js +2 -2
- package/lib/setTextContent.js +3 -3
- package/lib/shallowCompare.js +1 -1
- package/lib/sliceChildren.js +51 -0
- package/lib/traverseAllChildren.js +15 -14
- package/lib/update.js +13 -13
- package/lib/validateDOMNesting.js +14 -6
- package/lib/webcomponents.js +6379 -0
- package/package.json +4 -6
- package/react.js +53 -1
- package/addons/CSSTransitionGroup.js +0 -1
- package/addons/LinkedStateMixin.js +0 -1
- package/addons/Perf.js +0 -1
- package/addons/PureRenderMixin.js +0 -1
- package/addons/TestUtils.js +0 -1
- package/addons/TransitionGroup.js +0 -1
- package/addons/batchedUpdates.js +0 -1
- package/addons/cloneWithProps.js +0 -1
- package/addons/createFragment.js +0 -1
- package/addons/renderSubtreeIntoContainer.js +0 -1
- package/addons/shallowCompare.js +0 -1
- package/addons/update.js +0 -1
- package/lib/CSSCore.js +0 -97
- package/lib/EventListener.js +0 -84
- package/lib/ExecutionEnvironment.js +0 -38
- package/lib/LocalEventTrapMixin.js +0 -46
- package/lib/ReactContext.js +0 -32
- package/lib/ReactDOMClient.js +0 -85
- package/lib/ReactDOMForm.js +0 -47
- package/lib/ReactDOMIframe.js +0 -43
- package/lib/ReactDOMImg.js +0 -44
- package/lib/ReactLifeCycle.js +0 -35
- package/lib/camelize.js +0 -32
- package/lib/camelizeStyleName.js +0 -40
- package/lib/containsNode.js +0 -55
- package/lib/createArrayFromMixed.js +0 -85
- package/lib/createFullPageComponent.js +0 -51
- package/lib/createNodesFromMarkup.js +0 -84
- package/lib/emptyFunction.js +0 -38
- package/lib/emptyObject.js +0 -20
- package/lib/focusNode.js +0 -26
- package/lib/getActiveElement.js +0 -29
- package/lib/getMarkupWrap.js +0 -115
- package/lib/getUnboundedScrollPosition.js +0 -38
- package/lib/hyphenate.js +0 -33
- package/lib/hyphenateStyleName.js +0 -39
- package/lib/invariant.js +0 -49
- package/lib/isNode.js +0 -23
- package/lib/isTextNode.js +0 -25
- package/lib/keyMirror.js +0 -48
- package/lib/keyOf.js +0 -35
- package/lib/mapObject.js +0 -51
- package/lib/performance.js +0 -23
- package/lib/performanceNow.js +0 -28
- package/lib/shallowEqual.js +0 -48
- package/lib/toArray.js +0 -57
- package/lib/warning.js +0 -61
|
@@ -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;
|