Last active
March 27, 2023 16:47
-
-
Save westc/50745e43dd7dd34efe9b1bff2d89a5e8 to your computer and use it in GitHub Desktop.
parseUrlParams() - Parses URL parameters.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @param {string} url | |
* A URL or a query string starting with a question mark that will be parsed. | |
* @return {{ | |
* first: {[k: string]: (boolean|number|string|undefined)}; | |
* multi: {[k: string]: (boolean|number|string|undefined)[]}; | |
* last: {[k: string]: (boolean|number|string|undefined)}; | |
* }} | |
* An object containing the URL parameters. The `first` property will be an | |
* object where a key corresponds to a URL parameter name and the value | |
* corresponds to the first value for that key. The `multi` property will be | |
* an object where a key corresponds to a URL parameter name and the value is | |
* an array containing all of the values for that key. The `last` property | |
* will be an object where a key corresponds to a URL parameter name and the | |
* value corresponds to the last value for that key. The values `"on"`, | |
* `"yes"` and `"true"` will be interpreted as `true`. The values `"off"`, | |
* `"no"` and `"false"` will be interpreted as `false`. Values that look like | |
* numbers will be interpreted as numbers. | |
*/ | |
function parseUrlParams(url) { | |
const result = {first: {}, multi: {}, last: {}}; | |
url = url.replace(/\+/g, ' ').replace(/^[^?#]*(\?)|#[^]*$/g, '$1'); | |
const rgxIter = /\?[^?]*/.exec(url)?.[0]?.matchAll(/[?&]([^=&]+)(?:=([^&]*))?/g); | |
for (let [_, key, value] of rgxIter) { | |
// Decodes the key and the value. | |
key = decodeURIComponent(key); | |
value = value && decodeURIComponent(value); | |
// Test if the value is a boolean. | |
const m = /^(?:(on|yes|true)|off|no|false)$/.exec(value); | |
if (m) { | |
value = !!m[1]; | |
} | |
// Test if the value is a number. | |
else if (/^-?(?:(?:(?:\d+|\d+\.\d+|\.\d+)(?:e-?\d+)?)|Infinity)$/.test(value)) { | |
let num = +value; | |
// If value was turned into a number other than NaN use it as the value. | |
if (num === num) value = num; | |
} | |
// If the key has not yet been seen go ahead and define it for `first` and | |
// start an array for `multi`. | |
if (!result.hasOwnProperty.call(result.last, key)) { | |
result.first[key] = value; | |
result.multi[key] = []; | |
} | |
result.last[key] = value; | |
result.multi[key].push(value); | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment