Skip to content

Commit

Permalink
fix($urlMatcherFactory): made path params default value "" for backwa…
Browse files Browse the repository at this point in the history
…rds compat

- 0.2.x will continue to treat path params as optional, coerced to an empty string ""
- 0.3.0 will treat path parameters without default values as required, and thus the transition without required params will fail.

closes #1476
  • Loading branch information
christopherthielen committed Nov 13, 2014
1 parent e0dbb73 commit 8f998e7
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
ownParams: function(state) {
var params = state.url && state.url.params || new $$UMFP.ParamSet();
forEach(state.params || {}, function(config, id) {
if (!params[id]) params[id] = new $$UMFP.Param(id, null, config, false);
if (!params[id]) params[id] = new $$UMFP.Param(id, null, config);
});
return params;
},
Expand Down
25 changes: 14 additions & 11 deletions src/urlMatcherFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ function UrlMatcher(pattern, config, parentMatcher) {
parentParams = parentMatcher ? parentMatcher.params : {},
params = this.params = parentMatcher ? parentMatcher.params.$$new() : new $$UMFP.ParamSet();

function addParameter(id, type, config, isSearch) {
function addParameter(id, type, config, location) {
if (parentParams[id]) return parentParams[id];
if (!/^\w+(-+\w+)*(?:\[\])?$/.test(id)) throw new Error("Invalid parameter name '" + id + "' in pattern '" + pattern + "'");
if (params[id]) throw new Error("Duplicate parameter name '" + id + "' in pattern '" + pattern + "'");
params[id] = new $$UMFP.Param(id, type, config, isSearch);
params[id] = new $$UMFP.Param(id, type, config, location);
return params[id];
}

Expand Down Expand Up @@ -128,7 +128,7 @@ function UrlMatcher(pattern, config, parentMatcher) {
p = matchDetails(m, false);
if (p.segment.indexOf('?') >= 0) break; // we're into the search part

param = addParameter(p.id, p.type, p.cfg, false);
param = addParameter(p.id, p.type, p.cfg, "path");
compiled += quoteRegExp(p.segment, param.type.pattern.source, param.squash);
segments.push(p.segment);
last = placeholder.lastIndex;
Expand All @@ -147,7 +147,7 @@ function UrlMatcher(pattern, config, parentMatcher) {
last = 0;
while ((m = searchPlaceholder.exec(search))) {
p = matchDetails(m, true);
param = addParameter(p.id, p.type, p.cfg, true);
param = addParameter(p.id, p.type, p.cfg, "search");
last = placeholder.lastIndex;
// check if ?&
}
Expand Down Expand Up @@ -803,7 +803,7 @@ function $UrlMatcherFactory() {
if (!isDefined(definition)) return $types[name];
if ($types.hasOwnProperty(name)) throw new Error("A type named '" + name + "' has already been defined.");

$types[name] = new Type(extend({}, { name: name }, definition));
$types[name] = new Type(extend({ name: name }, definition));
if (definitionFn) {
typeQueue.push({ name: name, def: definitionFn });
if (!enqueue) flushTypeQueue();
Expand All @@ -821,7 +821,7 @@ function $UrlMatcherFactory() {
}

// Register default types. Store them in the prototype of $types.
forEach(defaultTypes, function(type, name) { $types[name] = new Type(type); });
forEach(defaultTypes, function(type, name) { $types[name] = new Type(extend({name: name}, type)); });
$types = inherit($types, {});

/* No need to document $get, since it returns this */
Expand All @@ -836,13 +836,15 @@ function $UrlMatcherFactory() {
return this;
}];

this.Param = function Param(id, type, config, isSearch) {
this.Param = function Param(id, type, config, location) {
var self = this;
var defaultValueConfig = getDefaultValueConfig(config);
config = config || {};
type = getType(config, type);
var arrayMode = getArrayMode();
type = arrayMode ? type.$asArray(arrayMode, isSearch) : type;
type = arrayMode ? type.$asArray(arrayMode, location === "search") : type;
if (type.name === "string" && !arrayMode && location === "path" && defaultValueConfig.value === undefined)
defaultValueConfig.value = ""; // for 0.2.x; in 0.3.0+ do not automatically default to ""
var isOptional = defaultValueConfig.value !== undefined;
var squash = getSquashPolicy(config, isOptional);
var replace = getReplace(config, arrayMode, isOptional, squash);
Expand All @@ -852,10 +854,11 @@ function $UrlMatcherFactory() {
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; },
var result = {
fn: isInjectable(configValue) ? configValue : function () { return result.value; },
value: configValue
};
return result;
}

function getType(config, urlType) {
Expand All @@ -867,7 +870,7 @@ function $UrlMatcherFactory() {

// array config: param name (param[]) overrides default settings. explicit config overrides param name.
function getArrayMode() {
var arrayDefaults = { array: isSearch ? "auto" : false };
var arrayDefaults = { array: (location === "search" ? "auto" : false) };
var arrayParamNomenclature = id.match(/\[\]$/) ? { array: true } : {};
return extend(arrayDefaults, arrayParamNomenclature, config).array;
}
Expand Down

0 comments on commit 8f998e7

Please sign in to comment.