Skip to content

Commit f4550d1

Browse files
committed
Merge pull request #2218 from angular-ui/feature-1.0-raw-types
feat(urlMatcher): add raw encoding flag to Type
2 parents 6ffe878 + 0f52103 commit f4550d1

File tree

3 files changed

+44
-38
lines changed

3 files changed

+44
-38
lines changed

src/params/param.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {isInjectable, extend, isDefined, isString, isArray, filter, map, prop} from "../common/common";
1+
import {isInjectable, extend, isDefined, isString, isArray, filter, map, prop, curry} from "../common/common";
22
import {runtime} from "../common/angular1";
33
import matcherConfig from "../url/urlMatcherConfig";
44
import paramTypes from "./paramTypes";
@@ -76,6 +76,10 @@ export default class Param {
7676
extend(this, {id, type, location, squash, replace, isOptional, dynamic, config, array: arrayMode});
7777
}
7878

79+
isDefaultValue(value: any) {
80+
return this.isOptional && this.type.equals(this.value(), value);
81+
}
82+
7983
/**
8084
* [Internal] Gets the decoded representation of a value if the value is defined, otherwise, returns the
8185
* default value, which may be the result of an injectable function.
@@ -92,15 +96,19 @@ export default class Param {
9296
return defaultValue;
9397
};
9498

95-
function hasReplaceVal(val) { return function(obj) { return obj.from === val; }; }
99+
const hasReplaceVal = curry((val, obj) => obj.from === val);
100+
96101
const $replace = (value) => {
97102
var replacement: any = map(filter(this.replace, hasReplaceVal(value)), prop("to"));
98103
return replacement.length ? replacement[0] : value;
99104
};
105+
100106
value = $replace(value);
101107
return !isDefined(value) ? $$getDefaultValue() : this.type.$normalize(value);
102108
}
103109

104-
toString() { return `{Param:${this.id} ${this.type} squash: '${this.squash}' optional: ${this.isOptional}}`; }
110+
toString() {
111+
return `{Param:${this.id} ${this.type} squash: '${this.squash}' optional: ${this.isOptional}}`;
112+
}
105113

106114
}

src/params/type.ts

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {extend, isArray, isDefined, filter, map} from "../common/common";
3333
export default class Type {
3434
pattern: RegExp;
3535
name: string;
36+
raw: boolean;
3637

3738
constructor(config) {
3839
extend(this, config);

src/url/urlMatcher.ts

+32-35
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,11 @@ export default class UrlMatcher {
138138
segment = pattern.substring(last, m.index);
139139
regexp = isSearch ? m[4] : m[4] || (m[1] == '*' ? '.*' : null);
140140
type = paramTypes.type(regexp || "string") || inherit(paramTypes.type("string"), { pattern: new RegExp(regexp, config.caseInsensitive ? 'i' : undefined) });
141-
return {
142-
id: id, regexp: regexp, segment: segment, type: type, cfg: cfg
143-
};
141+
return {id, regexp, segment, type, cfg};
144142
}
145143

146144
var p, param, segment;
145+
147146
while ((m = placeholder.exec(pattern))) {
148147
p = matchDetails(m, false);
149148
if (p.segment.indexOf('?') >= 0) break; // we're into the search part
@@ -339,49 +338,47 @@ export default class UrlMatcher {
339338
* @param {Object} values the values to substitute for the parameters in this pattern.
340339
* @returns {string} the formatted URL (path and optionally search part).
341340
*/
342-
format(values) {
343-
values = values || {};
344-
var segments = this.segments, params = this.parameters(), paramset = this.params;
345-
if (!this.validates(values)) return null;
341+
format(values = {}) {
342+
const url = {
343+
params: this.parameters(),
344+
paramSet: this.params,
345+
nPath: this.segments.length - 1
346+
};
347+
var i, search = false, result = this.segments[0];
346348

347-
var i, search = false, nPath = segments.length - 1, nTotal = params.length, result = segments[0];
349+
if (!this.validates(values)) return null;
348350

349351
function encodeDashes(str) { // Replace dashes with encoded "\-"
350-
return encodeURIComponent(str).replace(/-/g, function(c) { return `%5C%${c.charCodeAt(0).toString(16).toUpperCase()}`; });
352+
return encodeURIComponent(str).replace(/-/g, c => `%5C%${c.charCodeAt(0).toString(16).toUpperCase()}`);
351353
}
352354

353-
for (i = 0; i < nTotal; i++) {
354-
var isPathParam = i < nPath;
355-
var name = params[i], param: Param = paramset[name], value = param.value(values[name]);
356-
var isDefaultValue = param.isOptional && param.type.equals(param.value(), value);
355+
url.params.map((name, i) => {
356+
var isPathParam = i < url.nPath;
357+
var param: Param = url.paramSet[name], value = param.value(values[name]);
358+
var isDefaultValue = param.isDefaultValue(value);
357359
var squash = isDefaultValue ? param.squash : false;
358360
var encoded = param.type.encode(value);
359361

360-
if (isPathParam) {
361-
var nextSegment = segments[i + 1];
362-
if (squash === false) {
363-
if (encoded != null) {
364-
if (isArray(encoded)) {
365-
result += map(<string[]> encoded, encodeDashes).join("-");
366-
} else {
367-
result += encodeURIComponent(<string>encoded);
368-
}
369-
}
370-
result += nextSegment;
371-
} else if (squash === true) {
372-
var capture = result.match(/\/$/) ? /\/?(.*)/ : /(.*)/;
373-
result += nextSegment.match(capture)[1];
374-
} else if (isString(squash)) {
375-
result += squash + nextSegment;
376-
}
377-
} else {
378-
if (encoded == null || (isDefaultValue && squash !== false)) continue;
379-
if (!isArray(encoded)) encoded = [ <string> encoded ];
380-
encoded = map(<string[]>encoded, encodeURIComponent).join(`&${name}=`);
362+
if (!isPathParam) {
363+
if (encoded == null || (isDefaultValue && squash !== false)) return;
364+
if (!isArray(encoded)) encoded = [<string> encoded];
365+
366+
encoded = map(<string[]> encoded, encodeURIComponent).join(`&${name}=`);
381367
result += (search ? '&' : '?') + (`${name}=${encoded}`);
382368
search = true;
369+
return;
383370
}
384-
}
371+
372+
result += ((segment, result) => {
373+
if (squash === true) return segment.match(result.match(/\/$/) ? /\/?(.*)/ : /(.*)/)[1];
374+
if (isString(squash)) return squash + segment;
375+
if (squash !== false) return "";
376+
if (encoded == null) return segment;
377+
if (isArray(encoded)) return map(<string[]> encoded, encodeDashes).join("-") + segment;
378+
if (param.type.raw) return encoded + segment;
379+
return encodeURIComponent(<string> encoded) + segment;
380+
})(this.segments[i + 1], result);
381+
});
385382

386383
if (values["#"]) result += "#" + values["#"];
387384

0 commit comments

Comments
 (0)