64 lines
2.3 KiB
JavaScript
64 lines
2.3 KiB
JavaScript
|
// require the whatwg compatible URL library (same behaviour in node and browser)
|
||
|
const {URL} = require('url');
|
||
|
const stripSubdirectoryFromPath = require('./strip-subdirectory-from-path');
|
||
|
|
||
|
/**
|
||
|
* Convert an absolute URL to a root-relative path if it matches the supplied root domain.
|
||
|
*
|
||
|
* @param {string} url Absolute URL to convert to relative if possible
|
||
|
* @param {string} rootUrl Absolute URL to which the returned relative URL will match the domain root
|
||
|
* @param {Object} [options] Options that affect the conversion
|
||
|
* @param {boolean} [options.ignoreProtocol=true] Ignore protocol when matching url to root
|
||
|
* @param {boolean} [options.withoutSubdirectory=false] Strip the root subdirectory from the returned path
|
||
|
* @returns {string} The passed-in url or a relative path
|
||
|
*/
|
||
|
const absoluteToRelative = function absoluteToRelative(url, rootUrl, _options = {}) {
|
||
|
const defaultOptions = {
|
||
|
ignoreProtocol: true,
|
||
|
withoutSubdirectory: false,
|
||
|
assetsOnly: false,
|
||
|
staticImageUrlPrefix: 'content/images'
|
||
|
};
|
||
|
const options = Object.assign({}, defaultOptions, _options);
|
||
|
|
||
|
if (options.assetsOnly) {
|
||
|
const staticImageUrlPrefixRegex = new RegExp(options.staticImageUrlPrefix);
|
||
|
if (!url.match(staticImageUrlPrefixRegex)) {
|
||
|
return url;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let parsedUrl;
|
||
|
let parsedRoot;
|
||
|
|
||
|
try {
|
||
|
parsedUrl = new URL(url, 'http://relative');
|
||
|
parsedRoot = parsedUrl.origin === 'null' ? undefined : new URL(rootUrl || parsedUrl.origin);
|
||
|
|
||
|
// return the url as-is if it was relative or non-http
|
||
|
if (parsedUrl.origin === 'null' || parsedUrl.origin === 'http://relative') {
|
||
|
return url;
|
||
|
}
|
||
|
} catch (e) {
|
||
|
return url;
|
||
|
}
|
||
|
|
||
|
const matchesHost = parsedUrl.host === parsedRoot.host;
|
||
|
const matchesProtocol = parsedUrl.protocol === parsedRoot.protocol;
|
||
|
const matchesPath = parsedUrl.pathname.indexOf(parsedRoot.pathname) === 0;
|
||
|
|
||
|
if (matchesHost && (options.ignoreProtocol || matchesProtocol) && matchesPath) {
|
||
|
let path = parsedUrl.href.replace(parsedUrl.origin, '');
|
||
|
|
||
|
if (options.withoutSubdirectory) {
|
||
|
path = stripSubdirectoryFromPath(path, rootUrl);
|
||
|
}
|
||
|
|
||
|
return path;
|
||
|
}
|
||
|
|
||
|
return url;
|
||
|
};
|
||
|
|
||
|
module.exports = absoluteToRelative;
|