diff --git a/extensions/html-language-features/client/src/customData.ts b/extensions/html-language-features/client/src/customData.ts index 146fef2f3ee..02c5b0d0a7d 100644 --- a/extensions/html-language-features/client/src/customData.ts +++ b/extensions/html-language-features/client/src/customData.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { workspace, extensions, Uri, EventEmitter, Disposable } from 'vscode'; -import { resolvePath, joinPath, uriScheme } from './requests'; +import { resolvePath, joinPath } from './requests'; export function getCustomDataSource(toDispose: Disposable[]) { @@ -44,6 +44,10 @@ export function getCustomDataSource(toDispose: Disposable[]) { }; } +function isURI(uriOrPath: string) { + return /^(?\w[\w\d+.-]*):/.test(uriOrPath); +} + function getCustomDataPathsInAllWorkspaces(): Set { const workspaceFolders = workspace.workspaceFolders; @@ -54,16 +58,16 @@ function getCustomDataPathsInAllWorkspaces(): Set { return dataPaths; } - const collect = (paths: string[] | undefined, rootFolder: Uri) => { - if (Array.isArray(paths)) { - for (const path of paths) { - if (typeof path === 'string') { - if (!uriScheme.test(path)) { - // only resolve file paths relative to extension - dataPaths.add(resolvePath(rootFolder, path).toString()); + const collect = (uriOrPaths: string[] | undefined, rootFolder: Uri) => { + if (Array.isArray(uriOrPaths)) { + for (const uriOrPath of uriOrPaths) { + if (typeof uriOrPath === 'string') { + if (!isURI(uriOrPath)) { + // path in the workspace + dataPaths.add(resolvePath(rootFolder, uriOrPath).toString()); } else { - // others schemes - dataPaths.add(path); + // external uri + dataPaths.add(uriOrPath); } } } @@ -93,13 +97,13 @@ function getCustomDataPathsFromAllExtensions(): Set { for (const extension of extensions.all) { const customData = extension.packageJSON?.contributes?.html?.customData; if (Array.isArray(customData)) { - for (const rp of customData) { - if (!uriScheme.test(rp)) { - // no schame -> resolve relative to extension - dataPaths.add(joinPath(extension.extensionUri, rp).toString()); + for (const uriOrPath of customData) { + if (!isURI(uriOrPath)) { + // relative path in an extension + dataPaths.add(joinPath(extension.extensionUri, uriOrPath).toString()); } else { - // actual schemes - dataPaths.add(rp); + // external uri + dataPaths.add(uriOrPath); } } diff --git a/extensions/html-language-features/client/src/htmlClient.ts b/extensions/html-language-features/client/src/htmlClient.ts index 3e7ca38be7e..bfb241c2250 100644 --- a/extensions/html-language-features/client/src/htmlClient.ts +++ b/extensions/html-language-features/client/src/htmlClient.ts @@ -120,7 +120,7 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua toDispose.push(disposable); client.onReady().then(() => { - serveFileSystemRequests(client, runtime, context.subscriptions); + toDispose.push(serveFileSystemRequests(client, runtime)); client.sendNotification(CustomDataChangedNotification.type, customDataSource.uris); customDataSource.onDidChange(() => { diff --git a/extensions/html-language-features/client/src/requests.ts b/extensions/html-language-features/client/src/requests.ts index aa75e6b615f..867ad6fc7d4 100644 --- a/extensions/html-language-features/client/src/requests.ts +++ b/extensions/html-language-features/client/src/requests.ts @@ -3,12 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Uri, workspace } from 'vscode'; +import { Uri, workspace, Disposable } from 'vscode'; import { RequestType, CommonLanguageClient } from 'vscode-languageclient'; import { Runtime } from './htmlClient'; -export const uriScheme = /^(?\w[\w\d+.-]*):/; - export namespace FsContentRequest { export const type: RequestType<{ uri: string; encoding?: string; }, string, any> = new RequestType('fs/content'); } @@ -20,37 +18,32 @@ export namespace FsReadDirRequest { export const type: RequestType = new RequestType('fs/readDir'); } -export function serveFileSystemRequests(client: CommonLanguageClient, runtime: Runtime, subscriptions: { dispose(): any }[]) { - subscriptions.push(client.onRequest(FsContentRequest.type, (param: { uri: string; encoding?: string; }) => { - const uri = param.uri.match(uriScheme); - if (uri?.groups?.scheme === 'file') { - if (runtime.fs) { - return runtime.fs.getContent(param.uri); - } else { - return workspace.fs.readFile(Uri.parse(param.uri)).then(buffer => { - return new runtime.TextDecoder(param.encoding).decode(buffer); - }); - } - } else { - return workspace.openTextDocument(Uri.parse(param.uri)).then(doc => { - return doc.getText(); - }); +export function serveFileSystemRequests(client: CommonLanguageClient, runtime: Runtime): Disposable { + const disposables = []; + disposables.push(client.onRequest(FsContentRequest.type, (param: { uri: string; encoding?: string; }) => { + const uri = Uri.parse(param.uri); + if (uri.scheme === 'file' && runtime.fs) { + return runtime.fs.getContent(param.uri); } + return workspace.fs.readFile(uri).then(buffer => { + return new runtime.TextDecoder(param.encoding).decode(buffer); + }); })); - subscriptions.push(client.onRequest(FsReadDirRequest.type, (uriString: string) => { - const uri = uriString.match(uriScheme); - if (uri?.groups?.scheme === 'file' && runtime.fs) { + disposables.push(client.onRequest(FsReadDirRequest.type, (uriString: string) => { + const uri = Uri.parse(uriString); + if (uri.scheme === 'file' && runtime.fs) { return runtime.fs.readDirectory(uriString); } - return workspace.fs.readDirectory(Uri.parse(uriString)); + return workspace.fs.readDirectory(uri); })); - subscriptions.push(client.onRequest(FsStatRequest.type, (uriString: string) => { - const uri = uriString.match(uriScheme); - if (uri?.groups?.scheme === 'file' && runtime.fs) { + disposables.push(client.onRequest(FsStatRequest.type, (uriString: string) => { + const uri = Uri.parse(uriString); + if (uri.scheme === 'file' && runtime.fs) { return runtime.fs.stat(uriString); } - return workspace.fs.stat(Uri.parse(uriString)); + return workspace.fs.stat(uri); })); + return Disposable.from(...disposables); } export enum FileType {