2015-08-20 14:28:25 -07:00
|
|
|
import {CONST_EXPR, isPresent, isBlank, StringWrapper} from 'angular2/src/core/facade/lang';
|
2015-06-19 12:14:12 -07:00
|
|
|
import {
|
|
|
|
Map,
|
|
|
|
MapWrapper,
|
|
|
|
List,
|
|
|
|
ListWrapper,
|
|
|
|
isListLikeIterable
|
2015-08-20 14:28:25 -07:00
|
|
|
} from 'angular2/src/core/facade/collection';
|
2015-04-28 23:07:55 -07:00
|
|
|
|
2015-07-13 14:47:10 -04:00
|
|
|
function paramParser(rawParams: string = ''): Map<string, List<string>> {
|
2015-06-17 16:21:40 -07:00
|
|
|
var map: Map<string, List<string>> = new Map();
|
2015-07-13 14:47:10 -04:00
|
|
|
if (rawParams.length > 0) {
|
|
|
|
var params: List<string> = StringWrapper.split(rawParams, new RegExp('&'));
|
|
|
|
ListWrapper.forEach(params, (param: string) => {
|
|
|
|
var split: List<string> = StringWrapper.split(param, new RegExp('='));
|
|
|
|
var key = ListWrapper.get(split, 0);
|
|
|
|
var val = ListWrapper.get(split, 1);
|
|
|
|
var list = isPresent(map.get(key)) ? map.get(key) : [];
|
|
|
|
list.push(val);
|
|
|
|
map.set(key, list);
|
|
|
|
});
|
|
|
|
}
|
2015-04-28 23:07:55 -07:00
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
2015-07-13 14:47:10 -04:00
|
|
|
// TODO(caitp): This really should not be needed. Issue with ts2dart.
|
|
|
|
export const URLSearchParamsUnionFixer: string = CONST_EXPR("UnionFixer");
|
|
|
|
|
2015-06-24 00:27:07 -07:00
|
|
|
/**
|
|
|
|
* Map-like representation of url search parameters, based on
|
2015-07-13 14:47:10 -04:00
|
|
|
* [URLSearchParams](https://url.spec.whatwg.org/#urlsearchparams) in the url living standard,
|
|
|
|
* with several extensions for merging URLSearchParams objects:
|
|
|
|
* - setAll()
|
|
|
|
* - appendAll()
|
|
|
|
* - replaceAll()
|
2015-06-24 00:27:07 -07:00
|
|
|
*/
|
2015-04-28 23:07:55 -07:00
|
|
|
export class URLSearchParams {
|
|
|
|
paramsMap: Map<string, List<string>>;
|
2015-07-13 14:47:10 -04:00
|
|
|
constructor(public rawParams: string = '') { this.paramsMap = paramParser(rawParams); }
|
|
|
|
|
|
|
|
clone(): URLSearchParams {
|
|
|
|
var clone = new URLSearchParams();
|
|
|
|
clone.appendAll(this);
|
|
|
|
return clone;
|
|
|
|
}
|
2015-04-28 23:07:55 -07:00
|
|
|
|
2015-06-17 21:42:56 -07:00
|
|
|
has(param: string): boolean { return this.paramsMap.has(param); }
|
2015-04-28 23:07:55 -07:00
|
|
|
|
2015-06-19 12:14:12 -07:00
|
|
|
get(param: string): string {
|
|
|
|
var storedParam = this.paramsMap.get(param);
|
|
|
|
if (isListLikeIterable(storedParam)) {
|
|
|
|
return ListWrapper.first(storedParam);
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2015-04-28 23:07:55 -07:00
|
|
|
|
2015-06-19 12:14:12 -07:00
|
|
|
getAll(param: string): List<string> {
|
|
|
|
var mapParam = this.paramsMap.get(param);
|
|
|
|
return isPresent(mapParam) ? mapParam : [];
|
|
|
|
}
|
2015-04-28 23:07:55 -07:00
|
|
|
|
2015-07-13 14:47:10 -04:00
|
|
|
set(param: string, val: string) {
|
|
|
|
var mapParam = this.paramsMap.get(param);
|
|
|
|
var list = isPresent(mapParam) ? mapParam : [];
|
|
|
|
ListWrapper.clear(list);
|
|
|
|
list.push(val);
|
|
|
|
this.paramsMap.set(param, list);
|
|
|
|
}
|
|
|
|
|
|
|
|
// A merge operation
|
|
|
|
// For each name-values pair in `searchParams`, perform `set(name, values[0])`
|
|
|
|
//
|
|
|
|
// E.g: "a=[1,2,3], c=[8]" + "a=[4,5,6], b=[7]" = "a=[4], c=[8], b=[7]"
|
|
|
|
//
|
|
|
|
// TODO(@caitp): document this better
|
|
|
|
setAll(searchParams: URLSearchParams) {
|
|
|
|
MapWrapper.forEach(searchParams.paramsMap, (value, param) => {
|
|
|
|
var mapParam = this.paramsMap.get(param);
|
|
|
|
var list = isPresent(mapParam) ? mapParam : [];
|
|
|
|
ListWrapper.clear(list);
|
|
|
|
list.push(value[0]);
|
|
|
|
this.paramsMap.set(param, list);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-04-28 23:07:55 -07:00
|
|
|
append(param: string, val: string): void {
|
2015-06-19 12:14:12 -07:00
|
|
|
var mapParam = this.paramsMap.get(param);
|
|
|
|
var list = isPresent(mapParam) ? mapParam : [];
|
2015-06-17 11:17:21 -07:00
|
|
|
list.push(val);
|
2015-06-17 16:21:40 -07:00
|
|
|
this.paramsMap.set(param, list);
|
2015-04-28 23:07:55 -07:00
|
|
|
}
|
|
|
|
|
2015-07-13 14:47:10 -04:00
|
|
|
// A merge operation
|
|
|
|
// For each name-values pair in `searchParams`, perform `append(name, value)`
|
|
|
|
// for each value in `values`.
|
|
|
|
//
|
|
|
|
// E.g: "a=[1,2], c=[8]" + "a=[3,4], b=[7]" = "a=[1,2,3,4], c=[8], b=[7]"
|
|
|
|
//
|
|
|
|
// TODO(@caitp): document this better
|
|
|
|
appendAll(searchParams: URLSearchParams) {
|
|
|
|
MapWrapper.forEach(searchParams.paramsMap, (value, param) => {
|
|
|
|
var mapParam = this.paramsMap.get(param);
|
|
|
|
var list = isPresent(mapParam) ? mapParam : [];
|
|
|
|
for (var i = 0; i < value.length; ++i) {
|
|
|
|
list.push(value[i]);
|
|
|
|
}
|
|
|
|
this.paramsMap.set(param, list);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// A merge operation
|
|
|
|
// For each name-values pair in `searchParams`, perform `delete(name)`,
|
|
|
|
// followed by `set(name, values)`
|
|
|
|
//
|
|
|
|
// E.g: "a=[1,2,3], c=[8]" + "a=[4,5,6], b=[7]" = "a=[4,5,6], c=[8], b=[7]"
|
|
|
|
//
|
|
|
|
// TODO(@caitp): document this better
|
|
|
|
replaceAll(searchParams: URLSearchParams) {
|
|
|
|
MapWrapper.forEach(searchParams.paramsMap, (value, param) => {
|
|
|
|
var mapParam = this.paramsMap.get(param);
|
|
|
|
var list = isPresent(mapParam) ? mapParam : [];
|
|
|
|
ListWrapper.clear(list);
|
|
|
|
for (var i = 0; i < value.length; ++i) {
|
|
|
|
list.push(value[i]);
|
|
|
|
}
|
|
|
|
this.paramsMap.set(param, list);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-04-28 23:07:55 -07:00
|
|
|
toString(): string {
|
2015-06-17 11:17:21 -07:00
|
|
|
var paramsList = [];
|
2015-04-28 23:07:55 -07:00
|
|
|
MapWrapper.forEach(this.paramsMap, (values, k) => {
|
2015-06-17 11:17:21 -07:00
|
|
|
ListWrapper.forEach(values, v => { paramsList.push(k + '=' + v); });
|
2015-04-28 23:07:55 -07:00
|
|
|
});
|
|
|
|
return ListWrapper.join(paramsList, '&');
|
|
|
|
}
|
|
|
|
|
2015-07-07 20:03:00 -07:00
|
|
|
delete (param: string): void { MapWrapper.delete(this.paramsMap, param); }
|
2015-04-28 23:07:55 -07:00
|
|
|
}
|