Skip to content

Instantly share code, notes, and snippets.

@andyearnshaw
Created April 30, 2015 12:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andyearnshaw/03ee8d51f4e11b4fea9a to your computer and use it in GitHub Desktop.
Save andyearnshaw/03ee8d51f4e11b4fea9a to your computer and use it in GitHub Desktop.
URLSearchParams.js

Compatibility implementation of URLSearchParams, which is only supported in Firefox at the time of writing.

Notes

  • When stringified, will group keys together instead of returning them in their original order. Values will remain in the right order, however.
  • Aimed at ES5+ environments, e.g. not IE 8. Untested with polyfills.
  • A private property is exposed in browsers that don't support Symbol. Don't use it unless you want unpredictable behaviour across browsers.
(function (global, factory) {
var exp = global.URLSearchParams || factory(global);
if (typeof module !== 'undefined' && module.exports) {
module.exports = exp;
}
else if (typeof define === 'function' && define.amd) {
define(exp);
}
else {
Object.defineProperty(global, 'URLSearchParams', { value: exp, configurable: true, writable: true });
}
})(Function('return this')(), function (global) {
var hop = Object.prototype.hasOwnProperty,
ts = String,
priv = global.Symbol ? Symbol() : '_params',
toSpace = /\+/g,
toPlus = /%20/g,
decode = function (s) { return decodeURIComponent(s.replace(toSpace, ' ')); },
encode = function (s) { return encodeURIComponent(s).replace(toPlus, '+'); },
methods = {
append: append,
get: get,
getAll: getAll,
has: has,
set: set,
toString: toString,
delete: del
};
function URLSearchParams(init) {
var match, m1,
params = Object.create(null),
search = /([^&=]+)=?([^&]*)/g,
init = init || '';
while (match = search.exec(init)) {
m1 = decode(match[1]);
if (!params[m1]) {
params[m1] = [];
}
params[m1].push(decode(match[2]) || '');
}
Object.defineProperty(this, priv, { value: params });
}
function append(k, v) {
(this[priv][ts(k)] = this[priv][ts(k)] || []).push(ts(v));
}
function del(k) {
delete this[priv][ts(k)];
}
function get(k) {
var a = getAll.call(this, k);
return a.length ? a.pop() : null;
}
function getAll(k) {
return (this[priv][ts(k)] || []).slice(0);
}
function has(k) {
return hop.call(this[priv], ts(k));
}
function set(k, v) {
(this[priv][ts(k)] = []).push(ts(v));
}
function toString() {
var obj = this[priv];
return Object.keys(obj).map(function (k) {
var key = encode(k);
return obj[k].map(function (p) {
return key + '=' + encode(p);
}).join('&');
}).join('&');
}
Object.getOwnPropertyNames(methods).forEach(function (k) {
Object.defineProperty(URLSearchParams.prototype, k, { value: methods[k], configurable: true, writable: true });
});
return URLSearchParams;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment