UNPKG

saven

Version:
79 lines (63 loc) 1.83 kB
function isAbsolute (pathname) { return pathname.charAt(0) === '/' } // About 1.5x faster than the two-arg version of Array#splice() function spliceOne (list, index) { for (let 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 function resolvePathname (to, from = '') { const toParts = (to && to.split('/')) || [] let fromParts = (from && from.split('/')) || [] const isToAbs = to && isAbsolute(to) const isFromAbs = from && isAbsolute(from) const 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 '/' } let hasTrailingSlash if (fromParts.length) { const last = fromParts[fromParts.length - 1] hasTrailingSlash = last === '.' || last === '..' || last === '' } else { hasTrailingSlash = false } let up = 0 for (let i = fromParts.length; i >= 0; i--) { const 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('') } let result = fromParts.join('/') if (hasTrailingSlash && result.substr(-1) !== '/') { result += '/' } return result } export default resolvePathname