fix(router): root prop

This commit is contained in:
Manu Mtz.-Almeida
2018-04-26 23:17:15 +02:00
parent 4965dcc49e
commit 89d5a358a7
3 changed files with 127 additions and 13 deletions

View File

@@ -34,9 +34,9 @@
}
},
"@stencil/core": {
"version": "0.7.27-0",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-0.7.27-0.tgz",
"integrity": "sha512-Lh2826KcXW7O1K8rr4Ga4OCcZiwS0BTQCCIboZVTTAhMjgHJ4Ocv2/AIxMKhQea4O46Y93UA+7GopFGF0AMQZw==",
"version": "0.7.27-3",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-0.7.27-3.tgz",
"integrity": "sha512-WGrT8o29wBu+4lFwOWgQEMKr9LCBlSiGuvWoIf/nyM3bIZ5ywtGI6/QrTy1fXsXeMC7yGlB+YTCqaSCC+eHdfw==",
"dev": true,
"requires": {
"chokidar": "2.0.3",
@@ -47,7 +47,7 @@
"rollup-plugin-node-globals": "1.2.0",
"rollup-plugin-node-resolve": "3.3.0",
"rollup-pluginutils": "2.0.1",
"typescript": "^2.8.1",
"typescript": "^2.8.3",
"uglify-es": "3.3.9",
"workbox-build": "^3.1.0"
}

View File

@@ -1,11 +1,16 @@
import { RouteChain } from '../utils/interface';
import { chainToPath, generatePath, parsePath } from '../utils/path';
import { chainToPath, generatePath, parsePath, readPath } from '../utils/path';
describe('parseURL', () => {
it('should parse empty path', () => {
expect(parsePath('')).toEqual(['']);
});
it('should parse slash path', () => {
expect(parsePath('/')).toEqual(['']);
expect(parsePath(' / ')).toEqual(['']);
});
it('should parse empty path (2)', () => {
expect(parsePath(' ')).toEqual(['']);
});
@@ -18,6 +23,13 @@ describe('parseURL', () => {
expect(parsePath(undefined)).toEqual(['']);
});
it('should parse single segment', () => {
expect(parsePath('path')).toEqual(['path']);
expect(parsePath('path/')).toEqual(['path']);
expect(parsePath('/path/')).toEqual(['path']);
expect(parsePath('/path')).toEqual(['path']);
});
it('should parse relative path', () => {
expect(parsePath('path/to/file.js')).toEqual(['path', 'to', 'file.js']);
});
@@ -90,3 +102,84 @@ describe('chainToPath', () => {
});
});
describe('readPath', () => {
it('should read the URL from root (no hash)', () => {
const loc = mockLocation('/', '');
expect(readPath(loc, '', false)).toEqual(['']);
expect(readPath(loc, '/', false)).toEqual(['']);
expect(readPath(loc, ' / ', false)).toEqual(['']);
expect(readPath(loc, '', true)).toEqual(['']);
expect(readPath(loc, '/', true)).toEqual(['']);
expect(readPath(loc, ' / ', true)).toEqual(['']);
});
it('should read the URL from root (hash)', () => {
const loc = mockLocation('/', '#');
expect(readPath(loc, '', true)).toEqual(['']);
expect(readPath(loc, '/', true)).toEqual(['']);
expect(readPath(loc, ' / ', true)).toEqual(['']);
const loc2 = mockLocation('/', '#/');
expect(readPath(loc2, '', true)).toEqual(['']);
expect(readPath(loc2, '/', true)).toEqual(['']);
expect(readPath(loc2, ' / ', true)).toEqual(['']);
});
it('should not read the URL from root', () => {
const loc = mockLocation('/', '');
expect(readPath(loc, '/hola', false)).toBeNull();
expect(readPath(loc, 'hola', false)).toBeNull();
expect(readPath(loc, '/hola', true)).toBeNull();
expect(readPath(loc, 'hola', true)).toBeNull();
});
it('should read the URL from non root (no hash)', () => {
const loc = mockLocation('/path/to/component', '#hello');
expect(readPath(loc, '', false)).toEqual(['path', 'to', 'component']);
expect(readPath(loc, '/', false)).toEqual(['path', 'to', 'component']);
expect(readPath(loc, 'path', false)).toEqual(['to', 'component']);
expect(readPath(loc, '/path', false)).toEqual(['to', 'component']);
expect(readPath(loc, '/path/', false)).toEqual(['to', 'component']);
expect(readPath(loc, '/path/to', false)).toEqual(['component']);
expect(readPath(loc, '/path/to/component', false)).toEqual(['']);
expect(readPath(loc, '/path/to/component/', false)).toEqual(['']);
expect(readPath(loc, '/path/to/component/path', false)).toBeNull();
});
it('should read the URL from non root (hash)', () => {
const loc = mockLocation('/index.html', '#path/to/component');
expect(readPath(loc, '', true)).toEqual(['path', 'to', 'component']);
expect(readPath(loc, '/', true)).toEqual(['path', 'to', 'component']);
expect(readPath(loc, 'path', true)).toEqual(['to', 'component']);
expect(readPath(loc, '/path', true)).toEqual(['to', 'component']);
expect(readPath(loc, '/path/', true)).toEqual(['to', 'component']);
expect(readPath(loc, '/path/to', true)).toEqual(['component']);
expect(readPath(loc, '/path/to/component', true)).toEqual(['']);
expect(readPath(loc, '/path/to/component/', true)).toEqual(['']);
expect(readPath(loc, '/path/to/component/path', true)).toBeNull();
expect(readPath(loc, '/path/to/component2', true)).toBeNull();
});
it('should read the URL from non root (hash) 2', () => {
const loc = mockLocation('/index.html', '#/path/to/component');
expect(readPath(loc, '', true)).toEqual(['path', 'to', 'component']);
expect(readPath(loc, '/', true)).toEqual(['path', 'to', 'component']);
expect(readPath(loc, 'path', true)).toEqual(['to', 'component']);
expect(readPath(loc, '/path', true)).toEqual(['to', 'component']);
expect(readPath(loc, '/path/', true)).toEqual(['to', 'component']);
expect(readPath(loc, '/path/to', true)).toEqual(['component']);
expect(readPath(loc, '/path/to/component', true)).toEqual(['']);
expect(readPath(loc, '/path/to/component/', true)).toEqual(['']);
expect(readPath(loc, '/path/to/component/path', true)).toBeNull();
});
});
function mockLocation(pathname: string, hash: string): Location {
return {
pathname,
hash
} as Location;
}

View File

@@ -39,15 +39,36 @@ export function writePath(history: History, base: string, usePath: boolean, path
}
}
export function readPath(loc: Location, base: string, useHash: boolean): string[] | null {
const path = useHash
? loc.hash.substr(1)
: loc.pathname;
if (path.startsWith(base)) {
return parsePath(path.slice(base.length));
export function removePrefix(prefix: string[], path: string[]): string[] | null {
if (prefix.length > path.length) {
return null;
}
return null;
if (prefix.length <= 1 && prefix[0] === '') {
return path;
}
for (let i = 0; i < prefix.length; i++) {
if (prefix[i].length > 0 && prefix[i] !== path[i]) {
return null;
}
}
if (path.length === prefix.length) {
return [''];
}
return path.slice(prefix.length);
}
export function readPath(loc: Location, root: string, useHash: boolean): string[] | null {
let pathname = loc.pathname;
if (useHash) {
const hash = loc.hash;
pathname = (hash[0] === '#')
? hash.slice(1)
: '';
}
const prefix = parsePath(root);
const path = parsePath(pathname);
return removePrefix(prefix, path);
}
export function parsePath(path: string|undefined|null): string[] {