From: Eduardo San Martin Morote Date: Sat, 26 Oct 2019 15:32:18 +0000 (+0100) Subject: refactor(matcher): remove class usage X-Git-Tag: v4.0.0-alpha.0~178 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=05764a29fe8a097397c9d18f7ee012068db99d18;p=thirdparty%2Fvuejs%2Frouter.git refactor(matcher): remove class usage --- diff --git a/__tests__/matcher/ranking.spec.ts b/__tests__/matcher/ranking.spec.ts index ac224c20..e820078b 100644 --- a/__tests__/matcher/ranking.spec.ts +++ b/__tests__/matcher/ranking.spec.ts @@ -1,4 +1,4 @@ -import { createRouteMatcher } from '../../src/matcher/path-ranker' +import { createRouteRecordMatcher } from '../../src/matcher/path-ranker' import { RegExpOptions } from 'path-to-regexp' import { RouteComponent } from '../../src/types' import { RouteRecordMatcher } from '../../src/matcher/types' @@ -10,7 +10,7 @@ function stringifyOptions(options: any) { return Object.keys(options).length ? ` (${JSON.stringify(options)})` : '' } -describe('createRouteMatcher', () => { +describe('createRouteRecordMatcher', () => { function checkPathOrder( paths: Array, options: RegExpOptions = {} @@ -29,7 +29,7 @@ describe('createRouteMatcher', () => { // routes with the same ranking .reverse() .map(([path, options]) => ({ - ...createRouteMatcher( + ...createRouteRecordMatcher( { // @ts-ignore types are correct path, diff --git a/__tests__/matcher/resolve.spec.ts b/__tests__/matcher/resolve.spec.ts index 034a5381..0b8dd4c1 100644 --- a/__tests__/matcher/resolve.spec.ts +++ b/__tests__/matcher/resolve.spec.ts @@ -1,4 +1,4 @@ -import { RouterMatcher } from '../../src/matcher' +import { createRouterMatcher } from '../../src/matcher' import { START_LOCATION_NORMALIZED, RouteComponent, @@ -12,10 +12,6 @@ import { normalizeRouteRecord } from '../utils' // @ts-ignore const component: RouteComponent = null -function createRouterMatcher(records: RouteRecord[]) { - return new RouterMatcher(records) -} - // for normalized records const components = { default: component } diff --git a/src/matcher/index.ts b/src/matcher/index.ts index 21257531..b2aae616 100644 --- a/src/matcher/index.ts +++ b/src/matcher/index.ts @@ -9,19 +9,21 @@ import { // MatchedRouteRecord, } from '../types' import { NoRouteMatchError, InvalidRouteMatch } from '../errors' -import { createRouteMatcher, normalizeRouteRecord } from './path-ranker' +import { createRouteRecordMatcher, normalizeRouteRecord } from './path-ranker' import { RouteRecordMatcher } from './types' -export class RouterMatcher { - private matchers: RouteRecordMatcher[] = [] +interface RouterMatcher { + addRoute: (record: Readonly, parent?: RouteRecordMatcher) => void + resolve: ( + location: Readonly, + currentLocation: Readonly + ) => MatcherLocationNormalized | MatcherLocationRedirect +} - constructor(routes: RouteRecord[]) { - for (const route of routes) { - this.addRouteRecord(route) - } - } +export function createRouterMatcher(routes: RouteRecord[]): RouterMatcher { + const matchers: RouteRecordMatcher[] = [] - private addRouteRecord( + function addRoute( record: Readonly, parent?: RouteRecordMatcher ): void { @@ -58,11 +60,15 @@ export class RouterMatcher { for (const normalizedRecord of normalizedRecords) { // create the object before hand so it can be passed to children - const matcher = createRouteMatcher(normalizedRecord, parent, options) + const matcher = createRouteRecordMatcher( + normalizedRecord, + parent, + options + ) if ('children' in record && record.children) { for (const childRecord of record.children) { - this.addRouteRecord(childRecord, matcher) + addRoute(childRecord, matcher) } // TODO: the parent is special, we should match their children. They // reference to the parent so we can render the parent @@ -70,28 +76,22 @@ export class RouterMatcher { // matcher.score = -10 } - this.insertMatcher(matcher) + insertMatcher(matcher) } } - private insertMatcher(matcher: RouteRecordMatcher) { + function insertMatcher(matcher: RouteRecordMatcher) { let i = 0 - while (i < this.matchers.length && matcher.score <= this.matchers[i].score) - i++ - this.matchers.splice(i, 0, matcher) + while (i < matchers.length && matcher.score <= matchers[i].score) i++ + matchers.splice(i, 0, matcher) } /** - * Resolve a location without doing redirections so it can be used for anchors - */ - resolveAsPath() {} - - /** - * Transforms a MatcherLocation object into a normalized location + * Resolves a location. Gives access to the route record that corresponds to the actual path as well as filling the corresponding params objects * @param location MatcherLocation to resolve to a url * @param currentLocation MatcherLocationNormalized of the current location */ - resolve( + function resolve( location: Readonly, currentLocation: Readonly ): MatcherLocationNormalized | MatcherLocationRedirect { @@ -101,7 +101,7 @@ export class RouterMatcher { let name: MatcherLocationNormalized['name'] if ('name' in location && location.name) { - matcher = this.matchers.find(m => m.record.name === location.name) + matcher = matchers.find(m => m.record.name === location.name) if (!matcher) throw new NoRouteMatchError(currentLocation, location) @@ -127,7 +127,7 @@ export class RouterMatcher { } } } else if ('path' in location) { - matcher = this.matchers.find(m => m.re.test(location.path)) + matcher = matchers.find(m => m.re.test(location.path)) // TODO: if no matcher, return the location with an empty matched array // to allow non existent matches @@ -187,8 +187,8 @@ export class RouterMatcher { } else { // match by name or path of current route matcher = currentLocation.name - ? this.matchers.find(m => m.record.name === currentLocation.name) - : this.matchers.find(m => m.re.test(currentLocation.path)) + ? matchers.find(m => m.record.name === currentLocation.name) + : matchers.find(m => m.re.test(currentLocation.path)) if (!matcher) throw new NoRouteMatchError(currentLocation, location) name = matcher.record.name params = location.params || currentLocation.params @@ -217,4 +217,11 @@ export class RouterMatcher { meta: matcher.record.meta || {}, } } + + // add initial routes + for (const route of routes) { + addRoute(route) + } + + return { addRoute, resolve } } diff --git a/src/matcher/path-ranker.ts b/src/matcher/path-ranker.ts index 2c13f325..8e2c1d24 100644 --- a/src/matcher/path-ranker.ts +++ b/src/matcher/path-ranker.ts @@ -89,7 +89,7 @@ const enum PathScore { // allows to check if the user provided a custom regexp const isDefaultPathRegExpRE = /^\[\^[^\]]+\]\+\?$/ -export function createRouteMatcher( +export function createRouteRecordMatcher( record: Readonly, parent: RouteRecordMatcher | void, options: pathToRegexp.RegExpOptions diff --git a/src/router.ts b/src/router.ts index ab20592e..72beb981 100644 --- a/src/router.ts +++ b/src/router.ts @@ -6,7 +6,7 @@ import { HistoryLocationNormalized, START, } from './history/common' -import { RouterMatcher } from './matcher' +import { createRouterMatcher } from './matcher' import { RouteLocation, RouteRecord, @@ -53,7 +53,7 @@ type ErrorHandler = (error: any) => any type OnReadyCallback = [() => void, (reason?: any) => void] export class Router { protected history: RouterHistory - private matcher: RouterMatcher + private matcher: ReturnType private beforeGuards: NavigationGuard[] = [] private afterGuards: PostNavigationGuard[] = [] currentRoute: Readonly = START_LOCATION_NORMALIZED @@ -70,7 +70,7 @@ export class Router { // this.history.ensureLocation() this.scrollBehavior = options.scrollBehavior - this.matcher = new RouterMatcher(options.routes) + this.matcher = createRouterMatcher(options.routes) this.history.listen(async (to, from, info) => { const matchedRoute = this.resolveLocation(to, this.currentRoute)