@stencil/router
Version:
226 lines (225 loc) • 7.17 kB
JavaScript
var hasBasename = function (path, prefix) {
return (new RegExp('^' + prefix + '(\\/|\\?|#|$)', 'i')).test(path);
};
var stripBasename = function (path, prefix) {
return hasBasename(path, prefix) ? path.substr(prefix.length) : path;
};
var stripTrailingSlash = function (path) {
return path.charAt(path.length - 1) === '/' ? path.slice(0, -1) : path;
};
var addLeadingSlash = function (path) {
return path.charAt(0) === '/' ? path : '/' + path;
};
var stripLeadingSlash = function (path) {
return path.charAt(0) === '/' ? path.substr(1) : path;
};
var parsePath = function (path) {
var pathname = path || '/';
var search = '';
var hash = '';
var hashIndex = pathname.indexOf('#');
if (hashIndex !== -1) {
hash = pathname.substr(hashIndex);
pathname = pathname.substr(0, hashIndex);
}
var searchIndex = pathname.indexOf('?');
if (searchIndex !== -1) {
search = pathname.substr(searchIndex);
pathname = pathname.substr(0, searchIndex);
}
return {
pathname: pathname,
search: search === '?' ? '' : search,
hash: hash === '#' ? '' : hash,
query: {},
key: ''
};
};
var createPath = function (location) {
var pathname = location.pathname, search = location.search, hash = location.hash;
var path = pathname || '/';
if (search && search !== '?') {
path += (search.charAt(0) === '?' ? search : "?" + search);
}
if (hash && hash !== '#') {
path += (hash.charAt(0) === '#' ? hash : "#" + hash);
}
return path;
};
var parseQueryString = function (query) {
if (!query) {
return {};
}
return (/^[?#]/.test(query) ? query.slice(1) : query)
.split('&')
.reduce(function (params, param) {
var _a = param.split('='), key = _a[0], value = _a[1];
params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
return params;
}, {});
};
var isAbsolute = function (pathname) {
return pathname.charAt(0) === '/';
};
var createKey = function (keyLength) {
return Math.random().toString(36).substr(2, keyLength);
};
// About 1.5x faster than the two-arg version of Array#splice()
var spliceOne = function (list, index) {
for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) {
list[i] = list[k];
}
list.pop();
};
// This implementation is based heavily on node's url.parse
var resolvePathname = function (to, from) {
if (from === void 0) { from = ''; }
var fromParts = from && from.split('/') || [];
var hasTrailingSlash;
var up = 0;
var toParts = to && to.split('/') || [];
var isToAbs = to && isAbsolute(to);
var isFromAbs = from && isAbsolute(from);
var mustEndAbs = isToAbs || isFromAbs;
if (to && isAbsolute(to)) {
// to is absolute
fromParts = toParts;
}
else if (toParts.length) {
// to is relative, drop the filename
fromParts.pop();
fromParts = fromParts.concat(toParts);
}
if (!fromParts.length) {
return '/';
}
if (fromParts.length) {
var last = fromParts[fromParts.length - 1];
hasTrailingSlash = (last === '.' || last === '..' || last === '');
}
else {
hasTrailingSlash = false;
}
for (var i = fromParts.length; i >= 0; i--) {
var part = fromParts[i];
if (part === '.') {
spliceOne(fromParts, i);
}
else if (part === '..') {
spliceOne(fromParts, i);
up++;
}
else if (up) {
spliceOne(fromParts, i);
up--;
}
}
if (!mustEndAbs) {
for (; up--; up) {
fromParts.unshift('..');
}
}
if (mustEndAbs && fromParts[0] !== '' && (!fromParts[0] || !isAbsolute(fromParts[0]))) {
fromParts.unshift('');
}
var result = fromParts.join('/');
if (hasTrailingSlash && result.substr(-1) !== '/') {
result += '/';
}
return result;
};
var valueEqual = function (a, b) {
if (a === b) {
return true;
}
if (a == null || b == null) {
return false;
}
if (Array.isArray(a)) {
return Array.isArray(b) && a.length === b.length && a.every(function (item, index) {
return valueEqual(item, b[index]);
});
}
var aType = typeof a;
var bType = typeof b;
if (aType !== bType) {
return false;
}
if (aType === 'object') {
var aValue = a.valueOf();
var bValue = b.valueOf();
if (aValue !== a || bValue !== b) {
return valueEqual(aValue, bValue);
}
var aKeys = Object.keys(a);
var bKeys = Object.keys(b);
if (aKeys.length !== bKeys.length) {
return false;
}
return aKeys.every(function (key) {
return valueEqual(a[key], b[key]);
});
}
return false;
};
var locationsAreEqual = function (a, b) {
return a.pathname === b.pathname &&
a.search === b.search &&
a.hash === b.hash &&
a.key === b.key &&
valueEqual(a.state, b.state);
};
var createLocation = function (path, state, key, currentLocation) {
var location;
if (typeof path === 'string') {
// Two-arg form: push(path, state)
location = parsePath(path);
if (state !== undefined) {
location.state = state;
}
}
else {
// One-arg form: push(location)
location = Object.assign({ pathname: '' }, path);
if (location.search && location.search.charAt(0) !== '?') {
location.search = '?' + location.search;
}
if (location.hash && location.hash.charAt(0) !== '#') {
location.hash = '#' + location.hash;
}
if (state !== undefined && location.state === undefined) {
location.state = state;
}
}
try {
location.pathname = decodeURI(location.pathname);
}
catch (e) {
if (e instanceof URIError) {
throw new URIError('Pathname "' + location.pathname + '" could not be decoded. ' +
'This is likely caused by an invalid percent-encoding.');
}
else {
throw e;
}
}
location.key = key;
if (currentLocation) {
// Resolve incomplete/relative pathname relative to current location.
if (!location.pathname) {
location.pathname = currentLocation.pathname;
}
else if (location.pathname.charAt(0) !== '/') {
location.pathname = resolvePathname(location.pathname, currentLocation.pathname);
}
}
else {
// When there is no prior location and pathname is empty, set it to /
if (!location.pathname) {
location.pathname = '/';
}
}
location.query = parseQueryString(location.search || '');
return location;
};
export { addLeadingSlash as a, stripBasename as b, createLocation as c, createKey as d, createPath as e, stripLeadingSlash as f, hasBasename as h, locationsAreEqual as l, stripTrailingSlash as s, valueEqual as v };