Skip to content

Commit 8ce69d9

Browse files
fix(ui-router): re-add IE8 compatibility for map/filter/keys
- I'm not guaranteeing IE8 compatibility, but I did replace the obvious [].map/filter {}.keys calls with underscore-like replacements. - 0.2.x intends to retain compatibility with angular 1.2.x and, if reasonable, IE8. - 1.0.0+ will drop support for 1.2.x and IE8. fixes #1518 fixes #1383
1 parent 6374a3e commit 8ce69d9

File tree

4 files changed

+80
-39
lines changed

4 files changed

+80
-39
lines changed

src/common.js

+62-16
Original file line numberDiff line numberDiff line change
@@ -61,28 +61,14 @@ function objectKeys(object) {
6161
return result;
6262
}
6363

64-
/**
65-
* like objectKeys, but includes keys from prototype chain.
66-
* @param object the object whose prototypal keys will be returned
67-
* @param ignoreKeys an array of keys to ignore
68-
*/
69-
function protoKeys(object, ignoreKeys) {
70-
var result = [];
71-
for (var key in object) {
72-
if (!ignoreKeys || ignoreKeys.indexOf(key) === -1)
73-
result.push(key);
74-
}
75-
return result;
76-
}
77-
7864
/**
7965
* IE8-safe wrapper for `Array.prototype.indexOf()`.
8066
*
8167
* @param {Array} array A JavaScript array.
8268
* @param {*} value A value to search the array for.
8369
* @return {Number} Returns the array index value of `value`, or `-1` if not present.
8470
*/
85-
function arraySearch(array, value) {
71+
function indexOf(array, value) {
8672
if (Array.prototype.indexOf) {
8773
return array.indexOf(value, Number(arguments[2]) || 0);
8874
}
@@ -115,7 +101,7 @@ function inheritParams(currentParams, newParams, $current, $to) {
115101
if (!parentParams.length) continue;
116102

117103
for (var j in parentParams) {
118-
if (arraySearch(inheritList, parentParams[j]) >= 0) continue;
104+
if (indexOf(inheritList, parentParams[j]) >= 0) continue;
119105
inheritList.push(parentParams[j]);
120106
inherited[parentParams[j]] = currentParams[parentParams[j]];
121107
}
@@ -160,6 +146,66 @@ function filterByKeys(keys, values) {
160146
});
161147
return filtered;
162148
}
149+
150+
// like _.indexBy
151+
// when you know that your index values will be unique, or you want last-one-in to win
152+
function indexBy(array, propName) {
153+
var result = {};
154+
forEach(array, function(item) {
155+
result[item[propName]] = item;
156+
});
157+
return result;
158+
}
159+
160+
// extracted from underscore.js
161+
// Return a copy of the object only containing the whitelisted properties.
162+
function pick(obj) {
163+
var copy = {};
164+
var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
165+
forEach(keys, function(key) {
166+
if (key in obj) copy[key] = obj[key];
167+
});
168+
return copy;
169+
}
170+
171+
// extracted from underscore.js
172+
// Return a copy of the object omitting the blacklisted properties.
173+
function omit(obj) {
174+
var copy = {};
175+
var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
176+
for (var key in obj) {
177+
if (keys.indexOf(key) == -1) copy[key] = obj[key];
178+
}
179+
return copy;
180+
}
181+
182+
function pluck(collection, key) {
183+
var result = isArray(collection) ? [] : {};
184+
185+
forEach(collection, function(val, i) {
186+
result[i] = isFunction(key) ? key(val) : val[key];
187+
});
188+
return result;
189+
}
190+
191+
function filter(collection, callback) {
192+
var result = isArray(collection) ? [] : {};
193+
forEach(collection, function(val, i) {
194+
if (callback(val, i))
195+
result[i] = val;
196+
});
197+
return result;
198+
}
199+
200+
function map(collection, callback) {
201+
var result = isArray(collection) ? [] : {};
202+
203+
forEach(collection, function(val, i) {
204+
result[i] = callback(val, i);
205+
});
206+
return result;
207+
}
208+
163209
/**
164210
* @ngdoc overview
165211
* @name ui.router.util

src/resolve.js

+2-10
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function $Resolve( $q, $injector) {
4141
*/
4242
this.study = function (invocables) {
4343
if (!isObject(invocables)) throw new Error("'invocables' must be an object");
44-
var invocableKeys = Object.keys(invocables || {});
44+
var invocableKeys = objectKeys(invocables || {});
4545

4646
// Perform a topological sort of invocables to build an ordered plan
4747
var plan = [], cycle = [], visited = {};
@@ -50,7 +50,7 @@ function $Resolve( $q, $injector) {
5050

5151
cycle.push(key);
5252
if (visited[key] === VISIT_IN_PROGRESS) {
53-
cycle.splice(0, cycle.indexOf(key));
53+
cycle.splice(0, indexOf(cycle, key));
5454
throw new Error("Cyclic dependency: " + cycle.join(" -> "));
5555
}
5656
visited[key] = VISIT_IN_PROGRESS;
@@ -113,14 +113,6 @@ function $Resolve( $q, $injector) {
113113
resolution.reject(reason);
114114
}
115115

116-
// TODO: Remove this when we merge in 'new' branch
117-
function omit(obj) {
118-
var copy = {}, keys = angular.isArray(arguments[1]) ? arguments[1] : arguments.slice(1);
119-
for (var key in obj)
120-
if (keys.indexOf(key) == -1) copy[key] = obj[key];
121-
return copy;
122-
}
123-
124116
// Short-circuit if parent has already failed
125117
if (isDefined(parent.$$failure)) {
126118
fail(parent.$$failure);

src/state.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,12 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
217217

218218
//match greedy starts
219219
if (globSegments[0] === '**') {
220-
segments = segments.slice(segments.indexOf(globSegments[1]));
220+
segments = segments.slice(indexOf(segments, globSegments[1]));
221221
segments.unshift('**');
222222
}
223223
//match greedy ends
224224
if (globSegments[globSegments.length - 1] === '**') {
225-
segments.splice(segments.indexOf(globSegments[globSegments.length - 2]) + 1, Number.MAX_VALUE);
225+
segments.splice(indexOf(segments, globSegments[globSegments.length - 2]) + 1, Number.MAX_VALUE);
226226
segments.push('**');
227227
}
228228

@@ -1143,7 +1143,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
11431143
* @returns {Object|Array} State configuration object or array of all objects.
11441144
*/
11451145
$state.get = function (stateOrName, context) {
1146-
if (arguments.length === 0) return objectKeys(states).map(function(name) { return states[name].self; });
1146+
if (arguments.length === 0) return map(objectKeys(states), function(name) { return states[name].self; });
11471147
var state = findState(stateOrName, context || $state.$current);
11481148
return (state && state.self) ? state.self : null;
11491149
};

src/urlMatcherFactory.js

+13-10
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,10 @@ UrlMatcher.prototype.exec = function (path, searchParams) {
238238
function decodePathArray(string) {
239239
function reverseString(str) { return str.split("").reverse().join(""); }
240240
function unquoteDashes(str) { return str.replace(/\\-/, "-"); }
241-
return reverseString(string).split(/-(?!\\)/).map(reverseString).map(unquoteDashes).reverse();
241+
242+
var split = reverseString(string).split(/-(?!\\)/);
243+
var allReversed = map(split, reverseString);
244+
return map(allReversed, unquoteDashes).reverse();
242245
}
243246

244247
for (i = 0; i < nPath; i++) {
@@ -334,7 +337,7 @@ UrlMatcher.prototype.format = function (values) {
334337
if (squash === false) {
335338
if (encoded != null) {
336339
if (isArray(encoded)) {
337-
result += encoded.map(encodeDashes).join("-");
340+
result += map(encoded, encodeDashes).join("-");
338341
} else {
339342
result += encodeURIComponent(encoded);
340343
}
@@ -349,7 +352,7 @@ UrlMatcher.prototype.format = function (values) {
349352
} else {
350353
if (encoded == null || (isDefaultValue && squash !== false)) continue;
351354
if (!isArray(encoded)) encoded = [ encoded ];
352-
encoded = encoded.map(encodeURIComponent).join('&' + name + '=');
355+
encoded = map(encoded, encodeURIComponent).join('&' + name + '=');
353356
result += (search ? '&' : '?') + (name + '=' + encoded);
354357
search = true;
355358
}
@@ -498,7 +501,7 @@ Type.prototype.$asArray = function(mode, isSearch) {
498501
// Wraps type functions to operate on each value of an array
499502
return function handleArray(val) {
500503
if (!isArray(val)) val = [ val ];
501-
var result = val.map(callback);
504+
var result = map(val, callback);
502505
if (reducefn)
503506
return result.reduce(reducefn, true);
504507
return (result && result.length == 1 && mode === "auto") ? result[0] : result;
@@ -844,8 +847,8 @@ function $UrlMatcherFactory() {
844847

845848
function getDefaultValueConfig(config) {
846849
var keys = isObject(config) ? objectKeys(config) : [];
847-
var isShorthand = keys.indexOf("value") === -1 && keys.indexOf("type") === -1 &&
848-
keys.indexOf("squash") === -1 && keys.indexOf("array") === -1;
850+
var isShorthand = indexOf(keys, "value") === -1 && indexOf(keys, "type") === -1 &&
851+
indexOf(keys, "squash") === -1 && indexOf(keys, "array") === -1;
849852
var configValue = isShorthand ? config : config.value;
850853
return {
851854
fn: isInjectable(configValue) ? configValue : function () { return configValue; },
@@ -886,8 +889,8 @@ function $UrlMatcherFactory() {
886889
replace = isArray(config.replace) ? config.replace : [];
887890
if (isString(squash))
888891
replace.push({ from: squash, to: undefined });
889-
configuredKeys = replace.map(function(item) { return item.from; } );
890-
return defaultPolicy.filter(function(item) { return configuredKeys.indexOf(item.from) === -1; }).concat(replace);
892+
configuredKeys = map(replace, function(item) { return item.from; } );
893+
return filter(defaultPolicy, function(item) { return indexOf(configuredKeys, item.from) === -1; }).concat(replace);
891894
}
892895

893896
/**
@@ -905,7 +908,7 @@ function $UrlMatcherFactory() {
905908
function $value(value) {
906909
function hasReplaceVal(val) { return function(obj) { return obj.from === val; }; }
907910
function $replace(value) {
908-
var replacement = self.replace.filter(hasReplaceVal(value)).map(function(obj) { return obj.to; });
911+
var replacement = map(filter(self.replace, hasReplaceVal(value)), function(obj) { return obj.to; });
909912
return replacement.length ? replacement[0] : value;
910913
}
911914
value = $replace(value);
@@ -943,7 +946,7 @@ function $UrlMatcherFactory() {
943946
chain.reverse();
944947
forEach(chain, function(paramset) {
945948
forEach(objectKeys(paramset), function(key) {
946-
if (keys.indexOf(key) === -1 && ignore.indexOf(key) === -1) keys.push(key);
949+
if (indexOf(keys, key) === -1 && indexOf(ignore, key) === -1) keys.push(key);
947950
});
948951
});
949952
return keys;

0 commit comments

Comments
 (0)