diff --git a/src/connectionInfo/connection.ts b/src/connectionInfo/connection.ts index 7e8a8bb..e6037ea 100644 --- a/src/connectionInfo/connection.ts +++ b/src/connectionInfo/connection.ts @@ -157,7 +157,8 @@ export class Connection extends Disposable { const workspaceRoot = this.rootPath; if (workspaceRoot && this._absPathInWorkspace(path)) { - return PathUtil.ConvertToPosixPath(path.substring(workspaceRoot.length)); + const relativePath = PathUtil.ConvertToPosixPath(path.substring(workspaceRoot.length)); + return relativePath.startsWith('/') || relativePath === '' ? relativePath : `/${relativePath}`; } else { return undefined; } diff --git a/src/editorPreview/webviewComm.ts b/src/editorPreview/webviewComm.ts index c051f6b..a2856c1 100644 --- a/src/editorPreview/webviewComm.ts +++ b/src/editorPreview/webviewComm.ts @@ -80,15 +80,19 @@ export class WebviewComm extends Disposable { * @param {string} hostURI the (optional) URI of the host; alternatively, the function will manually generate the connection manager's HTTP URI if not provided with it initially. * @returns {Promise} a promise for the address for the content. */ - public async constructAddress( - URLExt: string, - connection: Connection = this.currentConnection, - hostURI?: vscode.Uri, - windowId?: number | undefined, - ): Promise { - if (URLExt.length > 0 && URLExt[0] == '/') { - URLExt = URLExt.substring(1); - } + public async constructAddress( + URLExt: string, + connection: Connection = this.currentConnection, + hostURI?: vscode.Uri, + windowId?: number | undefined, + ): Promise { + if (/^https?:\/\//i.test(URLExt)) { + return URLExt; + } + + if (URLExt.length > 0 && URLExt[0] == '/') { + URLExt = URLExt.substring(1); + } if (!hostURI) { hostURI = await this.resolveHost(connection); diff --git a/src/test/suite/connectionInfo.test.ts b/src/test/suite/connectionInfo.test.ts index 3d36374..1235f45 100644 --- a/src/test/suite/connectionInfo.test.ts +++ b/src/test/suite/connectionInfo.test.ts @@ -5,6 +5,7 @@ import assert from 'assert'; import sinon from 'sinon'; import vscode from 'vscode'; +import { Connection } from '../../connectionInfo/connection'; import { ConnectionManager } from '../../connectionInfo/connectionManager'; import { PathUtil } from '../../utils/pathUtil'; @@ -87,6 +88,14 @@ describe('ConnectionInfo', () => { }); + it('should include a leading slash when workspace root already ends with a separator', () => { + const connection = new Connection(testWorkspaces[0], '', 3000, 3001, '127.0.0.1'); + sandbox.stub(connection, 'rootPath').get(() => 'C:\\Users\\TestUser\\workspace1\\'); + + assert.deepEqual(connection.getFileRelativeToWorkspace('C:\\Users\\TestUser\\workspace1\\index.html'), '/index.html'); + + connection.dispose(); + }); it('should be able to create a Connection with an undefined workspace', async () => { const target = sinon.spy(); sandbox.stub(SettingUtil, 'GetConfig').returns(makeSetting({})); @@ -116,4 +125,4 @@ describe('ConnectionInfo', () => { } ], target.args[0]); }); -}); \ No newline at end of file +}); diff --git a/src/test/suite/preview.test.ts b/src/test/suite/preview.test.ts index b210461..cba53cf 100644 --- a/src/test/suite/preview.test.ts +++ b/src/test/suite/preview.test.ts @@ -95,4 +95,12 @@ describe('PreviewManager', () => { assert.ok(executeCommand.calledOnce); assert.ok(executeCommand.getCall(0).calledWith('extension.js-debug.debugLink', `http://${connection.host}:${connection.httpPort}/index.html`)); }); -}); \ No newline at end of file + + it("does not prefix absolute URLs with the preview host", async () => { + const webviewComm = Object.create(WebviewComm.prototype) as WebviewComm; + const hostUri = vscode.Uri.parse(`http://${connection.host}:${connection.httpPort}/`); + + assert.equal(await webviewComm.constructAddress('http://example.test/page.html', connection, hostUri), 'http://example.test/page.html'); + assert.equal(await webviewComm.constructAddress('https://example.test/page.html', connection, hostUri), 'https://example.test/page.html'); + }); +});