Skip to content

Commit

Permalink
fix(ui-router): re-add IE8 compatibility for map/filter/keys
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
christopherthielen committed Nov 12, 2014
1 parent 6374a3e commit 8ce69d9
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 39 deletions.
78 changes: 62 additions & 16 deletions src/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,28 +61,14 @@ function objectKeys(object) {
return result;
}

/**
* like objectKeys, but includes keys from prototype chain.
* @param object the object whose prototypal keys will be returned
* @param ignoreKeys an array of keys to ignore
*/
function protoKeys(object, ignoreKeys) {
var result = [];
for (var key in object) {
if (!ignoreKeys || ignoreKeys.indexOf(key) === -1)
result.push(key);
}
return result;
}

/**
* IE8-safe wrapper for `Array.prototype.indexOf()`.
*
* @param {Array} array A JavaScript array.
* @param {*} value A value to search the array for.
* @return {Number} Returns the array index value of `value`, or `-1` if not present.
*/
function arraySearch(array, value) {
function indexOf(array, value) {
if (Array.prototype.indexOf) {
return array.indexOf(value, Number(arguments[2]) || 0);
}
Expand Down Expand Up @@ -115,7 +101,7 @@ function inheritParams(currentParams, newParams, $current, $to) {
if (!parentParams.length) continue;

for (var j in parentParams) {
if (arraySearch(inheritList, parentParams[j]) >= 0) continue;
if (indexOf(inheritList, parentParams[j]) >= 0) continue;
inheritList.push(parentParams[j]);
inherited[parentParams[j]] = currentParams[parentParams[j]];
}
Expand Down Expand Up @@ -160,6 +146,66 @@ function filterByKeys(keys, values) {
});
return filtered;
}

// like _.indexBy
// when you know that your index values will be unique, or you want last-one-in to win
function indexBy(array, propName) {
var result = {};
forEach(array, function(item) {
result[item[propName]] = item;
});
return result;
}

// extracted from underscore.js
// Return a copy of the object only containing the whitelisted properties.
function pick(obj) {
var copy = {};
var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
forEach(keys, function(key) {
if (key in obj) copy[key] = obj[key];
});
return copy;
}

// extracted from underscore.js
// Return a copy of the object omitting the blacklisted properties.
function omit(obj) {
var copy = {};
var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
for (var key in obj) {
if (keys.indexOf(key) == -1) copy[key] = obj[key];
}
return copy;
}

function pluck(collection, key) {
var result = isArray(collection) ? [] : {};

forEach(collection, function(val, i) {
result[i] = isFunction(key) ? key(val) : val[key];
});
return result;
}

function filter(collection, callback) {
var result = isArray(collection) ? [] : {};
forEach(collection, function(val, i) {
if (callback(val, i))
result[i] = val;
});
return result;
}

function map(collection, callback) {
var result = isArray(collection) ? [] : {};

forEach(collection, function(val, i) {
result[i] = callback(val, i);
});
return result;
}

/**
* @ngdoc overview
* @name ui.router.util
Expand Down
12 changes: 2 additions & 10 deletions src/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function $Resolve( $q, $injector) {
*/
this.study = function (invocables) {
if (!isObject(invocables)) throw new Error("'invocables' must be an object");
var invocableKeys = Object.keys(invocables || {});
var invocableKeys = objectKeys(invocables || {});

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

cycle.push(key);
if (visited[key] === VISIT_IN_PROGRESS) {
cycle.splice(0, cycle.indexOf(key));
cycle.splice(0, indexOf(cycle, key));
throw new Error("Cyclic dependency: " + cycle.join(" -> "));
}
visited[key] = VISIT_IN_PROGRESS;
Expand Down Expand Up @@ -113,14 +113,6 @@ function $Resolve( $q, $injector) {
resolution.reject(reason);
}

// TODO: Remove this when we merge in 'new' branch
function omit(obj) {
var copy = {}, keys = angular.isArray(arguments[1]) ? arguments[1] : arguments.slice(1);
for (var key in obj)
if (keys.indexOf(key) == -1) copy[key] = obj[key];
return copy;
}

// Short-circuit if parent has already failed
if (isDefined(parent.$$failure)) {
fail(parent.$$failure);
Expand Down
6 changes: 3 additions & 3 deletions src/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,12 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {

//match greedy starts
if (globSegments[0] === '**') {
segments = segments.slice(segments.indexOf(globSegments[1]));
segments = segments.slice(indexOf(segments, globSegments[1]));
segments.unshift('**');
}
//match greedy ends
if (globSegments[globSegments.length - 1] === '**') {
segments.splice(segments.indexOf(globSegments[globSegments.length - 2]) + 1, Number.MAX_VALUE);
segments.splice(indexOf(segments, globSegments[globSegments.length - 2]) + 1, Number.MAX_VALUE);
segments.push('**');
}

Expand Down Expand Up @@ -1143,7 +1143,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
* @returns {Object|Array} State configuration object or array of all objects.
*/
$state.get = function (stateOrName, context) {
if (arguments.length === 0) return objectKeys(states).map(function(name) { return states[name].self; });
if (arguments.length === 0) return map(objectKeys(states), function(name) { return states[name].self; });
var state = findState(stateOrName, context || $state.$current);
return (state && state.self) ? state.self : null;
};
Expand Down
23 changes: 13 additions & 10 deletions src/urlMatcherFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,10 @@ UrlMatcher.prototype.exec = function (path, searchParams) {
function decodePathArray(string) {
function reverseString(str) { return str.split("").reverse().join(""); }
function unquoteDashes(str) { return str.replace(/\\-/, "-"); }
return reverseString(string).split(/-(?!\\)/).map(reverseString).map(unquoteDashes).reverse();

var split = reverseString(string).split(/-(?!\\)/);
var allReversed = map(split, reverseString);
return map(allReversed, unquoteDashes).reverse();
}

for (i = 0; i < nPath; i++) {
Expand Down Expand Up @@ -334,7 +337,7 @@ UrlMatcher.prototype.format = function (values) {
if (squash === false) {
if (encoded != null) {
if (isArray(encoded)) {
result += encoded.map(encodeDashes).join("-");
result += map(encoded, encodeDashes).join("-");
} else {
result += encodeURIComponent(encoded);
}
Expand All @@ -349,7 +352,7 @@ UrlMatcher.prototype.format = function (values) {
} else {
if (encoded == null || (isDefaultValue && squash !== false)) continue;
if (!isArray(encoded)) encoded = [ encoded ];
encoded = encoded.map(encodeURIComponent).join('&' + name + '=');
encoded = map(encoded, encodeURIComponent).join('&' + name + '=');
result += (search ? '&' : '?') + (name + '=' + encoded);
search = true;
}
Expand Down Expand Up @@ -498,7 +501,7 @@ Type.prototype.$asArray = function(mode, isSearch) {
// Wraps type functions to operate on each value of an array
return function handleArray(val) {
if (!isArray(val)) val = [ val ];
var result = val.map(callback);
var result = map(val, callback);
if (reducefn)
return result.reduce(reducefn, true);
return (result && result.length == 1 && mode === "auto") ? result[0] : result;
Expand Down Expand Up @@ -844,8 +847,8 @@ function $UrlMatcherFactory() {

function getDefaultValueConfig(config) {
var keys = isObject(config) ? objectKeys(config) : [];
var isShorthand = keys.indexOf("value") === -1 && keys.indexOf("type") === -1 &&
keys.indexOf("squash") === -1 && keys.indexOf("array") === -1;
var isShorthand = indexOf(keys, "value") === -1 && indexOf(keys, "type") === -1 &&
indexOf(keys, "squash") === -1 && indexOf(keys, "array") === -1;
var configValue = isShorthand ? config : config.value;
return {
fn: isInjectable(configValue) ? configValue : function () { return configValue; },
Expand Down Expand Up @@ -886,8 +889,8 @@ function $UrlMatcherFactory() {
replace = isArray(config.replace) ? config.replace : [];
if (isString(squash))
replace.push({ from: squash, to: undefined });
configuredKeys = replace.map(function(item) { return item.from; } );
return defaultPolicy.filter(function(item) { return configuredKeys.indexOf(item.from) === -1; }).concat(replace);
configuredKeys = map(replace, function(item) { return item.from; } );
return filter(defaultPolicy, function(item) { return indexOf(configuredKeys, item.from) === -1; }).concat(replace);
}

/**
Expand All @@ -905,7 +908,7 @@ function $UrlMatcherFactory() {
function $value(value) {
function hasReplaceVal(val) { return function(obj) { return obj.from === val; }; }
function $replace(value) {
var replacement = self.replace.filter(hasReplaceVal(value)).map(function(obj) { return obj.to; });
var replacement = map(filter(self.replace, hasReplaceVal(value)), function(obj) { return obj.to; });
return replacement.length ? replacement[0] : value;
}
value = $replace(value);
Expand Down Expand Up @@ -943,7 +946,7 @@ function $UrlMatcherFactory() {
chain.reverse();
forEach(chain, function(paramset) {
forEach(objectKeys(paramset), function(key) {
if (keys.indexOf(key) === -1 && ignore.indexOf(key) === -1) keys.push(key);
if (indexOf(keys, key) === -1 && indexOf(ignore, key) === -1) keys.push(key);
});
});
return keys;
Expand Down

0 comments on commit 8ce69d9

Please sign in to comment.