Skip to content
This repository has been archived by the owner on Oct 2, 2021. It is now read-only.

Enhance path matching #202

Merged
merged 5 commits into from
May 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 46 additions & 16 deletions src/chrome/chromeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,62 @@ import {ITarget} from './chromeConnection';

export function targetUrlToClientPathByPathMappings(scriptUrl: string, pathMapping: any): string {
const parsedUrl = url.parse(scriptUrl);
const origin = `${parsedUrl.protocol}//${parsedUrl.host}`;
if (!parsedUrl.protocol || parsedUrl.protocol.startsWith('file') || !parsedUrl.pathname) {
// Skip file: URLs and paths, and invalid things
return '';
}

let pSegments = parsedUrl.pathname.split('/');
while (pSegments.length) {
let p = pSegments.join('/');

if (pSegments.length === 1 && p === '') {
// Root path segment.
p = '/';
const urlWithoutQuery = parsedUrl.protocol + "//" + parsedUrl.host + parsedUrl.pathname;
for (let pattern of Object.keys(pathMapping)) {
// empty pattern match nothing use / to match root
if (pattern) {
const localPath = pathMapping[pattern];
const parsedPattern = url.parse(pattern);

if (parsedPattern.protocol) {
// pattern is an url with protocol
if (urlWithoutQuery.startsWith(pattern)) {
const clientPath = toClientPath(localPath, parsedUrl.pathname, pattern);
if (clientPath) {
return clientPath;
}
}
} else if (pattern[0] === "/") {
// pattern is absolute
if (parsedUrl.pathname.startsWith(pattern)) {
const clientPath = toClientPath(localPath, parsedUrl.pathname, pattern);
if (clientPath) {
return clientPath;
}
}
} else {
// pattern is relative
// avoid matching whole segment
pattern = "/" + pattern;
const indexOf = parsedUrl.pathname.indexOf(pattern);
if (indexOf !== -1) {
const clientPath = toClientPath(localPath, parsedUrl.pathname.substring(indexOf), pattern);
if (clientPath) {
return clientPath;
}
}
}
}
}
return '';
}

let localPath = pathMapping[origin + p] || pathMapping[origin + p + '/'] ||
pathMapping[p + '/'] || pathMapping[p];

if (localPath) {
const r = decodeURIComponent(parsedUrl.pathname.substring(p.length));
function toClientPath(localPath: string, source: string, pattern: string): string {
if (source.length === pattern.length) {
return localPath;
} else {
// Verify that matching whole segment of the pattern
if (source[pattern.length - 1] === "/"
|| source[pattern.length] === "/") {
const r = decodeURIComponent(source.substring(pattern.length));
return path.join(localPath, r);
}

pSegments.pop();
}

return '';
}

Expand Down
12 changes: 10 additions & 2 deletions test/chrome/chromeUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ suite('ChromeUtils', () => {

const ROOT_MAPPING = { '/': TEST_WEB_ROOT };
const PAGE_MAPPING = { '/page/': TEST_WEB_ROOT };
const PARTIAL_PAGE_MAPPING = { '/page': TEST_WEB_ROOT };
const PARTIAL_PAGE_MAPPING = { '/page': TEST_WEB_ROOT, 'page': TEST_WEB_ROOT};
const FILE_MAPPING = { '/page.js': TEST_CLIENT_PATH };
const RELATIVE_FILE_MAPPING = { 'page.js': TEST_CLIENT_PATH};

test('an empty string is returned for a missing url', () => {
assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings('', { }), '');
Expand Down Expand Up @@ -145,7 +146,7 @@ suite('ChromeUtils', () => {
TEST_CLIENT_PATH);
});

test('resolves webroot-style mapping without tailing slash', () => {
test('resolves webroot-style mapping without trailing slash', () => {
assert.equal(
getChromeUtils().targetUrlToClientPathByPathMappings(TEST_TARGET_HTTP_URL, PARTIAL_PAGE_MAPPING),
TEST_CLIENT_PATH);
Expand All @@ -168,6 +169,13 @@ suite('ChromeUtils', () => {

assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings(url, PARTIAL_PAGE_MAPPING), '');
});

test('resolves pathMapping for a particular relative file', () => {
const url = 'http://site.com/page.js';

assert.equal(getChromeUtils().targetUrlToClientPathByPathMappings(url, RELATIVE_FILE_MAPPING), TEST_CLIENT_PATH);
});

});

suite('remoteObjectToValue()', () => {
Expand Down