Skip to content

Commit 8f998e7

Browse files
fix($urlMatcherFactory): made path params default value "" for backwards 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
1 parent e0dbb73 commit 8f998e7

File tree

2 files changed

+15
-12
lines changed

2 files changed

+15
-12
lines changed

src/state.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
6868
ownParams: function(state) {
6969
var params = state.url && state.url.params || new $$UMFP.ParamSet();
7070
forEach(state.params || {}, function(config, id) {
71-
if (!params[id]) params[id] = new $$UMFP.Param(id, null, config, false);
71+
if (!params[id]) params[id] = new $$UMFP.Param(id, null, config);
7272
});
7373
return params;
7474
},

src/urlMatcherFactory.js

+14-11
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,11 @@ function UrlMatcher(pattern, config, parentMatcher) {
8888
parentParams = parentMatcher ? parentMatcher.params : {},
8989
params = this.params = parentMatcher ? parentMatcher.params.$$new() : new $$UMFP.ParamSet();
9090

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

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

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

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

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

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

839-
this.Param = function Param(id, type, config, isSearch) {
839+
this.Param = function Param(id, type, config, location) {
840840
var self = this;
841841
var defaultValueConfig = getDefaultValueConfig(config);
842842
config = config || {};
843843
type = getType(config, type);
844844
var arrayMode = getArrayMode();
845-
type = arrayMode ? type.$asArray(arrayMode, isSearch) : type;
845+
type = arrayMode ? type.$asArray(arrayMode, location === "search") : type;
846+
if (type.name === "string" && !arrayMode && location === "path" && defaultValueConfig.value === undefined)
847+
defaultValueConfig.value = ""; // for 0.2.x; in 0.3.0+ do not automatically default to ""
846848
var isOptional = defaultValueConfig.value !== undefined;
847849
var squash = getSquashPolicy(config, isOptional);
848850
var replace = getReplace(config, arrayMode, isOptional, squash);
@@ -852,10 +854,11 @@ function $UrlMatcherFactory() {
852854
var isShorthand = indexOf(keys, "value") === -1 && indexOf(keys, "type") === -1 &&
853855
indexOf(keys, "squash") === -1 && indexOf(keys, "array") === -1;
854856
var configValue = isShorthand ? config : config.value;
855-
return {
856-
fn: isInjectable(configValue) ? configValue : function () { return configValue; },
857+
var result = {
858+
fn: isInjectable(configValue) ? configValue : function () { return result.value; },
857859
value: configValue
858860
};
861+
return result;
859862
}
860863

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

868871
// array config: param name (param[]) overrides default settings. explicit config overrides param name.
869872
function getArrayMode() {
870-
var arrayDefaults = { array: isSearch ? "auto" : false };
873+
var arrayDefaults = { array: (location === "search" ? "auto" : false) };
871874
var arrayParamNomenclature = id.match(/\[\]$/) ? { array: true } : {};
872875
return extend(arrayDefaults, arrayParamNomenclature, config).array;
873876
}

0 commit comments

Comments
 (0)