diff options
Diffstat (limited to 'app/assets/javascripts/lib/utils/url_utility.js')
-rw-r--r-- | app/assets/javascripts/lib/utils/url_utility.js | 66 |
1 files changed, 56 insertions, 10 deletions
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js index a495d2040d3..966e6d42b80 100644 --- a/app/assets/javascripts/lib/utils/url_utility.js +++ b/app/assets/javascripts/lib/utils/url_utility.js @@ -63,15 +63,22 @@ export function getParameterValues(sParam, url = window.location) { }, []); } -// @param {Object} params - url keys and value to merge -// @param {String} url +/** + * Merges a URL to a set of params replacing value for + * those already present. + * + * Also removes `null` param values from the resulting URL. + * + * @param {Object} params - url keys and value to merge + * @param {String} url + */ export function mergeUrlParams(params, url) { const re = /^([^?#]*)(\?[^#]*)?(.*)/; const merged = {}; - const urlparts = url.match(re); + const [, fullpath, query, fragment] = url.match(re); - if (urlparts[2]) { - urlparts[2] + if (query) { + query .substr(1) .split('&') .forEach(part => { @@ -84,11 +91,15 @@ export function mergeUrlParams(params, url) { Object.assign(merged, params); - const query = Object.keys(merged) + const newQuery = Object.keys(merged) + .filter(key => merged[key] !== null) .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(merged[key])}`) .join('&'); - return `${urlparts[1]}?${query}${urlparts[3]}`; + if (newQuery) { + return `${fullpath}?${newQuery}${fragment}`; + } + return `${fullpath}${fragment}`; } /** @@ -213,12 +224,45 @@ export function getBaseURL() { } /** + * Returns true if url is an absolute URL + * + * @param {String} url + */ +export function isAbsolute(url) { + return /^https?:\/\//.test(url); +} + +/** + * Returns true if url is a root-relative URL + * + * @param {String} url + */ +export function isRootRelative(url) { + return /^\//.test(url); +} + +/** * Returns true if url is an absolute or root-relative URL * * @param {String} url */ export function isAbsoluteOrRootRelative(url) { - return /^(https?:)?\//.test(url); + return isAbsolute(url) || isRootRelative(url); +} + +/** + * Converts a relative path to an absolute or a root relative path depending + * on what is passed as a basePath. + * + * @param {String} path Relative path, eg. ../img/img.png + * @param {String} basePath Absolute or root relative path, eg. /user/project or + * https://gitlab.com/user/project + */ +export function relativePathToAbsolute(path, basePath) { + const absolute = isAbsolute(basePath); + const base = absolute ? basePath : `file:///${basePath}`; + const url = new URL(path, base); + return absolute ? url.href : decodeURIComponent(url.pathname); } /** @@ -259,8 +303,10 @@ export function getWebSocketUrl(path) { export function queryToObject(query) { const removeQuestionMarkFromQuery = String(query).startsWith('?') ? query.slice(1) : query; return removeQuestionMarkFromQuery.split('&').reduce((accumulator, curr) => { - const p = curr.split('='); - accumulator[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); + const [key, value] = curr.split('='); + if (value !== undefined) { + accumulator[decodeURIComponent(key)] = decodeURIComponent(value); + } return accumulator; }, {}); } |