Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/html-language-features/client/src/customData.ts
3320 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { workspace, extensions, Uri, EventEmitter, Disposable } from 'vscode';
7
import { Runtime } from './htmlClient';
8
import { Utils } from 'vscode-uri';
9
10
11
export function getCustomDataSource(runtime: Runtime, toDispose: Disposable[]) {
12
let localExtensionUris = new Set<string>();
13
let externalExtensionUris = new Set<string>();
14
const workspaceUris = new Set<string>();
15
16
collectInWorkspaces(workspaceUris);
17
collectInExtensions(localExtensionUris, externalExtensionUris);
18
19
const onChange = new EventEmitter<void>();
20
21
toDispose.push(extensions.onDidChange(_ => {
22
const newLocalExtensionUris = new Set<string>();
23
const newExternalExtensionUris = new Set<string>();
24
collectInExtensions(newLocalExtensionUris, newExternalExtensionUris);
25
if (hasChanges(newLocalExtensionUris, localExtensionUris) || hasChanges(newExternalExtensionUris, externalExtensionUris)) {
26
localExtensionUris = newLocalExtensionUris;
27
externalExtensionUris = newExternalExtensionUris;
28
onChange.fire();
29
}
30
}));
31
toDispose.push(workspace.onDidChangeConfiguration(e => {
32
if (e.affectsConfiguration('html.customData')) {
33
workspaceUris.clear();
34
collectInWorkspaces(workspaceUris);
35
onChange.fire();
36
}
37
}));
38
39
toDispose.push(workspace.onDidChangeTextDocument(e => {
40
const path = e.document.uri.toString();
41
if (externalExtensionUris.has(path) || workspaceUris.has(path)) {
42
onChange.fire();
43
}
44
}));
45
46
return {
47
get uris() {
48
return [...localExtensionUris].concat([...externalExtensionUris], [...workspaceUris]);
49
},
50
get onDidChange() {
51
return onChange.event;
52
},
53
getContent(uriString: string): Thenable<string> {
54
const uri = Uri.parse(uriString);
55
if (localExtensionUris.has(uriString)) {
56
return workspace.fs.readFile(uri).then(buffer => {
57
return new runtime.TextDecoder().decode(buffer);
58
});
59
}
60
return workspace.openTextDocument(uri).then(doc => {
61
return doc.getText();
62
});
63
}
64
};
65
}
66
67
function hasChanges(s1: Set<string>, s2: Set<string>) {
68
if (s1.size !== s2.size) {
69
return true;
70
}
71
for (const uri of s1) {
72
if (!s2.has(uri)) {
73
return true;
74
}
75
}
76
return false;
77
}
78
79
function isURI(uriOrPath: string) {
80
return /^(?<scheme>\w[\w\d+.-]*):/.test(uriOrPath);
81
}
82
83
84
function collectInWorkspaces(workspaceUris: Set<string>): Set<string> {
85
const workspaceFolders = workspace.workspaceFolders;
86
87
const dataPaths = new Set<string>();
88
89
if (!workspaceFolders) {
90
return dataPaths;
91
}
92
93
const collect = (uriOrPaths: string[] | undefined, rootFolder: Uri) => {
94
if (Array.isArray(uriOrPaths)) {
95
for (const uriOrPath of uriOrPaths) {
96
if (typeof uriOrPath === 'string') {
97
if (!isURI(uriOrPath)) {
98
// path in the workspace
99
workspaceUris.add(Utils.resolvePath(rootFolder, uriOrPath).toString());
100
} else {
101
// external uri
102
workspaceUris.add(uriOrPath);
103
}
104
}
105
}
106
}
107
};
108
109
for (let i = 0; i < workspaceFolders.length; i++) {
110
const folderUri = workspaceFolders[i].uri;
111
const allHtmlConfig = workspace.getConfiguration('html', folderUri);
112
const customDataInspect = allHtmlConfig.inspect<string[]>('customData');
113
if (customDataInspect) {
114
collect(customDataInspect.workspaceFolderValue, folderUri);
115
if (i === 0) {
116
if (workspace.workspaceFile) {
117
collect(customDataInspect.workspaceValue, workspace.workspaceFile);
118
}
119
collect(customDataInspect.globalValue, folderUri);
120
}
121
}
122
123
}
124
return dataPaths;
125
}
126
127
function collectInExtensions(localExtensionUris: Set<string>, externalUris: Set<string>): void {
128
for (const extension of extensions.allAcrossExtensionHosts) {
129
const customData = extension.packageJSON?.contributes?.html?.customData;
130
if (Array.isArray(customData)) {
131
for (const uriOrPath of customData) {
132
if (!isURI(uriOrPath)) {
133
// relative path in an extension
134
localExtensionUris.add(Uri.joinPath(extension.extensionUri, uriOrPath).toString());
135
} else {
136
// external uri
137
externalUris.add(uriOrPath);
138
}
139
140
}
141
}
142
}
143
}
144
145