UNPKG

@stencil/router

Version:
226 lines (225 loc) 7.17 kB
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 };