/* @flow */ import type VueRouter from '../index' import { parsePath, resolvePath } from './path' import { resolveQuery } from './query' import { fillParams } from './params' import { warn } from './warn' import { extend } from './misc' export function normalizeLocation ( raw: RawLocation, current: ?Route, append: ?boolean, router: ?VueRouter ): Location { let next: Location = typeof raw === 'string' ? { path: raw } : raw // named target if (next._normalized) { return next } else if (next.name) { next = extend({}, raw) const params = next.params if (params && typeof params === 'object') { next.params = extend({}, params) } return next } // relative params if (!next.path && next.params && current) { next = extend({}, next) next._normalized = true const params: any = extend(extend({}, current.params), next.params) if (current.name) { next.name = current.name next.params = params } else if (current.matched.length) { const rawPath = current.matched[current.matched.length - 1].path next.path = fillParams(rawPath, params, `path ${current.path}`) } else if (process.env.NODE_ENV !== 'production') { warn(false, `relative params navigation requires a current route.`) } return next } const parsedPath = parsePath(next.path || '') const basePath = (current && current.path) || '/' const path = parsedPath.path ? resolvePath(parsedPath.path, basePath, append || next.append) : basePath const query = resolveQuery( parsedPath.query, next.query, router && router.options.parseQuery ) let hash = next.hash || parsedPath.hash if (hash && hash.charAt(0) !== '#') { hash = `#${hash}` } return { _normalized: true, path, query, hash } }