Skip to content

Instantly share code, notes, and snippets.

@madcampos
Created September 12, 2017 18:55
Show Gist options
  • Save madcampos/cae95ba16abe0c2d5123837a33e34c21 to your computer and use it in GitHub Desktop.
Save madcampos/cae95ba16abe0c2d5123837a33e34c21 to your computer and use it in GitHub Desktop.
Simple URLSearchParams
// It does not implement hooks to URL and HTMLAnchorElement
window.URLSearchParams = class URLSearchParams {
constructor(init) {
this._list = new Map();
if (typeof init === 'string') {
init = init.replace(/^\?|\&$/, '').split('&').map((param) => {
const params = param.split('=');
if (params.length === 1) {
params[1] = '';
}
if (params.length > 2) {
params = [params[0], params.slice(1).join('=')];
}
return params;
});
}
if (!!init && typeof init === 'object' && !Array.isArray(init)) {
init = [...Object.entries(init)];
}
if (Array.isArray(init)) {
init.forEach((param) => {
if (param[0] === '') {
return;
}
if (!param[1]) {
throw new TypeError();
}
if (Array.isArray(param[1])) {
param[1] = param[1].map((el) => decodeURIComponent(el.toString()));
} else {
param[1] = decodeURIComponent(param[1].toString());
}
if (this._list.has(param[0])) {
let originalParams = this._list.get(param[0]);
if (!Array.isArray(originalParams)) {
originalParams = [originalParams];
}
if (Array.isArray(param[1])) {
param[1] = originalParams.concat(param[1]);
} else {
originalParams.push(param[1]);
}
param[1] = originalParams;
}
this._list.set(decodeURIComponent(param[0]), param[1]);
});
}
}
get [Symbol.iterator]() {return this.entries;}
get [Symbol.toStringTag]() {return 'URLSearchParams';}
// Mirror(ish) Map methods
values() {return this._list.values()}
keys() {return this._list.keys()}
entries() {return this._list.entries()}
get(name) {return this.getAll(name)[0] || null}
has(name) {return this._list.has(decodeURIComponent(name))}
sort() {this._list = new Map([...this._list].sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));}
getAll(name) {
if (!this.has(name)) {
return [];
}
const value = this._list.get(decodeURIComponent(name));
if (Array.isArray(value)) {
return value;
}
return [value];
}
append(name, value) {
if (!this.has(name)) {
this.set(name, value);
} else {
if (Array.isArray(this.get(name))) {
this.set(name, [...this.get(name), value]);
} else {
this.set(name, [this.get(name), value]);
}
}
}
set(name, value) {
if (Array.isArray(value)) {
value = value.map((el) => decodeURIComponent(el.toString()));
} else {
value = decodeURIComponent(value.toString());
}
return this._list.set(decodeURIComponent(name), value);
}
delete(name) {
return this._list.delete(decodeURIComponent(name));
}
toString() {
let result = '';
for (let [key, value] of this.entries()) {
key = encodeURIComponent(key).replace('%20', '+').replace(/[!'()~]/g, (c) => `%${c.charCodeAt(0).toString(16)}`);
if (Array.isArray(value)) {
value.forEach((val) => result += `&${key}=${encodeURIComponent(val).replace('%20', '+').replace(/[!'()~]/g, (c) => `%${c.charCodeAt(0).toString(16)}`)}`);
} else {
result += `&${key}=${encodeURIComponent(value).replace('%20', '+').replace(/[!'()~]/g, (c) => `%${c.charCodeAt(0).toString(16)}`)}`;
}
}
return result.replace(/^\&/, '');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment