Path: blob/main/extensions/html-language-features/client/src/customData.ts
3320 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { workspace, extensions, Uri, EventEmitter, Disposable } from 'vscode';6import { Runtime } from './htmlClient';7import { Utils } from 'vscode-uri';8910export function getCustomDataSource(runtime: Runtime, toDispose: Disposable[]) {11let localExtensionUris = new Set<string>();12let externalExtensionUris = new Set<string>();13const workspaceUris = new Set<string>();1415collectInWorkspaces(workspaceUris);16collectInExtensions(localExtensionUris, externalExtensionUris);1718const onChange = new EventEmitter<void>();1920toDispose.push(extensions.onDidChange(_ => {21const newLocalExtensionUris = new Set<string>();22const newExternalExtensionUris = new Set<string>();23collectInExtensions(newLocalExtensionUris, newExternalExtensionUris);24if (hasChanges(newLocalExtensionUris, localExtensionUris) || hasChanges(newExternalExtensionUris, externalExtensionUris)) {25localExtensionUris = newLocalExtensionUris;26externalExtensionUris = newExternalExtensionUris;27onChange.fire();28}29}));30toDispose.push(workspace.onDidChangeConfiguration(e => {31if (e.affectsConfiguration('html.customData')) {32workspaceUris.clear();33collectInWorkspaces(workspaceUris);34onChange.fire();35}36}));3738toDispose.push(workspace.onDidChangeTextDocument(e => {39const path = e.document.uri.toString();40if (externalExtensionUris.has(path) || workspaceUris.has(path)) {41onChange.fire();42}43}));4445return {46get uris() {47return [...localExtensionUris].concat([...externalExtensionUris], [...workspaceUris]);48},49get onDidChange() {50return onChange.event;51},52getContent(uriString: string): Thenable<string> {53const uri = Uri.parse(uriString);54if (localExtensionUris.has(uriString)) {55return workspace.fs.readFile(uri).then(buffer => {56return new runtime.TextDecoder().decode(buffer);57});58}59return workspace.openTextDocument(uri).then(doc => {60return doc.getText();61});62}63};64}6566function hasChanges(s1: Set<string>, s2: Set<string>) {67if (s1.size !== s2.size) {68return true;69}70for (const uri of s1) {71if (!s2.has(uri)) {72return true;73}74}75return false;76}7778function isURI(uriOrPath: string) {79return /^(?<scheme>\w[\w\d+.-]*):/.test(uriOrPath);80}818283function collectInWorkspaces(workspaceUris: Set<string>): Set<string> {84const workspaceFolders = workspace.workspaceFolders;8586const dataPaths = new Set<string>();8788if (!workspaceFolders) {89return dataPaths;90}9192const collect = (uriOrPaths: string[] | undefined, rootFolder: Uri) => {93if (Array.isArray(uriOrPaths)) {94for (const uriOrPath of uriOrPaths) {95if (typeof uriOrPath === 'string') {96if (!isURI(uriOrPath)) {97// path in the workspace98workspaceUris.add(Utils.resolvePath(rootFolder, uriOrPath).toString());99} else {100// external uri101workspaceUris.add(uriOrPath);102}103}104}105}106};107108for (let i = 0; i < workspaceFolders.length; i++) {109const folderUri = workspaceFolders[i].uri;110const allHtmlConfig = workspace.getConfiguration('html', folderUri);111const customDataInspect = allHtmlConfig.inspect<string[]>('customData');112if (customDataInspect) {113collect(customDataInspect.workspaceFolderValue, folderUri);114if (i === 0) {115if (workspace.workspaceFile) {116collect(customDataInspect.workspaceValue, workspace.workspaceFile);117}118collect(customDataInspect.globalValue, folderUri);119}120}121122}123return dataPaths;124}125126function collectInExtensions(localExtensionUris: Set<string>, externalUris: Set<string>): void {127for (const extension of extensions.allAcrossExtensionHosts) {128const customData = extension.packageJSON?.contributes?.html?.customData;129if (Array.isArray(customData)) {130for (const uriOrPath of customData) {131if (!isURI(uriOrPath)) {132// relative path in an extension133localExtensionUris.add(Uri.joinPath(extension.extensionUri, uriOrPath).toString());134} else {135// external uri136externalUris.add(uriOrPath);137}138139}140}141}142}143144145