@codingame/monaco-vscode-view-common-service-override 17.2.1 → 18.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +2 -2
- package/package.json +43 -42
- package/service-override/vs/workbench/contrib/webview/browser/pre/service-worker.js +328 -444
- package/vscode/src/vs/workbench/api/browser/viewsExtensionPoint.js +59 -59
- package/vscode/src/vs/workbench/browser/actions/listCommands.js +3 -3
- package/vscode/src/vs/workbench/browser/actions/navigationActions.js +6 -6
- package/vscode/src/vs/workbench/browser/parts/editor/editor.contribution.js +170 -167
- package/vscode/src/vs/workbench/browser/parts/editor/editorConfiguration.js +10 -9
- package/vscode/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution.js +12 -12
- package/vscode/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek.js +5 -5
- package/vscode/src/vs/workbench/contrib/callHierarchy/browser/callHierarchyTree.js +3 -3
- package/vscode/src/vs/workbench/contrib/customEditor/browser/customEditor.contribution.js +1 -1
- package/vscode/src/vs/workbench/contrib/customEditor/browser/customEditorInputFactory.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/customEditor/browser/customEditorInputFactory.js +2 -2
- package/vscode/src/vs/workbench/contrib/customEditor/common/contributedCustomEditors.js +2 -2
- package/vscode/src/vs/workbench/contrib/customEditor/common/customEditor.js +1 -1
- package/vscode/src/vs/workbench/contrib/customEditor/common/extensionPoint.js +12 -12
- package/vscode/src/vs/workbench/contrib/languageStatus/browser/languageStatus.js +7 -7
- package/vscode/src/vs/workbench/contrib/limitIndicator/browser/limitIndicator.contribution.js +8 -8
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.js +30 -30
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.js +14 -14
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/mergeEditor.contribution.js +4 -4
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/mergeEditorAccessibilityHelp.js +5 -5
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/colors.js +13 -13
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.d.ts +3 -3
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/editorGutter.js +8 -9
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/editors/baseCodeEditorView.js +5 -5
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.js +3 -3
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.d.ts +2 -2
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/editors/inputCodeEditorView.js +15 -14
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/editors/resultCodeEditorView.js +10 -10
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/lineAlignment.js +3 -3
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/mergeEditor.js +5 -4
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/scrollSynchronizer.js +3 -3
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.d.ts +5 -5
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/viewModel.js +7 -9
- package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/viewZones.js +3 -3
- package/vscode/src/vs/workbench/contrib/preferences/browser/keyboardLayoutPicker.js +13 -13
- package/vscode/src/vs/workbench/contrib/sash/browser/sash.contribution.js +2 -2
- package/vscode/src/vs/workbench/contrib/typeHierarchy/browser/typeHierarchy.contribution.js +10 -10
- package/vscode/src/vs/workbench/contrib/typeHierarchy/browser/typeHierarchyPeek.js +5 -5
- package/vscode/src/vs/workbench/contrib/typeHierarchy/browser/typeHierarchyTree.js +3 -3
- package/vscode/src/vs/workbench/contrib/webview/browser/overlayWebview.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/webview/browser/overlayWebview.js +1 -1
- package/vscode/src/vs/workbench/contrib/webview/browser/themeing.d.ts +2 -2
- package/vscode/src/vs/workbench/contrib/webview/browser/themeing.js +1 -1
- package/vscode/src/vs/workbench/contrib/webview/browser/webviewElement.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/webview/browser/webviewElement.js +2 -2
- package/vscode/src/vs/workbench/contrib/webview/browser/webviewFindWidget.js +1 -1
- package/vscode/src/vs/workbench/contrib/webview/browser/webviewService.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/webviewPanel/browser/webviewCommands.js +7 -7
- package/vscode/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInputSerializer.d.ts +2 -2
- package/vscode/src/vs/workbench/contrib/webviewPanel/browser/webviewEditorInputSerializer.js +1 -1
- package/vscode/src/vs/workbench/contrib/webviewPanel/browser/webviewPanel.contribution.js +3 -3
- package/vscode/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.js +5 -5
- package/vscode/src/vs/workbench/contrib/webviewView/browser/webviewViewService.d.ts +1 -1
- package/vscode/src/vs/workbench/services/editor/browser/editorPaneService.js +1 -1
- package/vscode/src/vs/workbench/services/editor/browser/editorResolverService.js +15 -11
- package/vscode/src/vs/workbench/services/history/browser/historyService.js +10 -10
- package/vscode/src/vs/workbench/services/progress/browser/progressService.js +11 -11
- package/vscode/src/vs/workbench/services/untitled/common/untitledTextEditorHandler.d.ts +2 -2
- package/vscode/src/vs/workbench/services/untitled/common/untitledTextEditorHandler.js +2 -2
- package/vscode/src/vs/workbench/services/views/browser/viewDescriptorService.js +9 -9
- package/vscode/src/vs/workbench/services/views/common/viewContainerModel.js +4 -4
|
@@ -1,487 +1,371 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*---------------------------------------------------------------------------------------------
|
|
2
3
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
4
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4
5
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
// @ts-check
|
|
6
|
-
|
|
7
6
|
/// <reference lib="webworker" />
|
|
8
|
-
|
|
9
|
-
const sw = /** @type {ServiceWorkerGlobalScope} */ (/** @type {any} */ (self));
|
|
10
|
-
|
|
7
|
+
const sw = self;
|
|
11
8
|
const VERSION = 4;
|
|
12
|
-
|
|
13
9
|
const resourceCacheName = `vscode-resource-cache-${VERSION}`;
|
|
14
|
-
|
|
15
10
|
const rootPath = sw.location.pathname.replace(/\/service-worker.js$/, '');
|
|
16
|
-
|
|
17
11
|
const searchParams = new URL(location.toString()).searchParams;
|
|
18
|
-
|
|
19
12
|
const remoteAuthority = searchParams.get('remoteAuthority');
|
|
20
|
-
|
|
21
|
-
const ID = searchParams.get('id');
|
|
22
|
-
|
|
13
|
+
let outerIframeMessagePort;
|
|
23
14
|
/**
|
|
24
15
|
* Origin used for resources
|
|
25
16
|
*/
|
|
26
17
|
const resourceBaseAuthority = searchParams.get('vscode-resource-base-authority');
|
|
27
|
-
|
|
28
18
|
const resolveTimeout = 30_000;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @template T
|
|
32
|
-
* @typedef {{ status: 'ok'; value: T } | { status: 'timeout' }} RequestStoreResult
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @template T
|
|
37
|
-
* @typedef {{
|
|
38
|
-
* resolve: (x: RequestStoreResult<T>) => void,
|
|
39
|
-
* promise: Promise<RequestStoreResult<T>>
|
|
40
|
-
* }} RequestStoreEntry
|
|
41
|
-
*/
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Caches
|
|
45
|
-
* @template T
|
|
46
|
-
*/
|
|
47
19
|
class RequestStore {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
const timeout = setTimeout(dispose, resolveTimeout);
|
|
82
|
-
return { requestId, promise };
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @param {number} requestId
|
|
87
|
-
* @param {T} result
|
|
88
|
-
* @return {boolean}
|
|
89
|
-
*/
|
|
90
|
-
resolve(requestId, result) {
|
|
91
|
-
const entry = this.map.get(requestId);
|
|
92
|
-
if (!entry) {
|
|
93
|
-
return false;
|
|
94
|
-
}
|
|
95
|
-
entry.resolve({ status: 'ok', value: result });
|
|
96
|
-
this.map.delete(requestId);
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
20
|
+
constructor() {
|
|
21
|
+
this.map = new Map();
|
|
22
|
+
this.requestPool = 0;
|
|
23
|
+
}
|
|
24
|
+
create() {
|
|
25
|
+
const requestId = ++this.requestPool;
|
|
26
|
+
let resolve;
|
|
27
|
+
const promise = new Promise(r => resolve = r);
|
|
28
|
+
const entry = { resolve: resolve, promise };
|
|
29
|
+
this.map.set(requestId, entry);
|
|
30
|
+
const dispose = () => {
|
|
31
|
+
clearTimeout(timeout);
|
|
32
|
+
const existingEntry = this.map.get(requestId);
|
|
33
|
+
if (existingEntry === entry) {
|
|
34
|
+
existingEntry.resolve({ status: 'timeout' });
|
|
35
|
+
this.map.delete(requestId);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const timeout = setTimeout(dispose, resolveTimeout);
|
|
39
|
+
return { requestId, promise };
|
|
40
|
+
}
|
|
41
|
+
resolve(requestId, result) {
|
|
42
|
+
const entry = this.map.get(requestId);
|
|
43
|
+
if (!entry) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
entry.resolve({ status: 'ok', value: result });
|
|
47
|
+
this.map.delete(requestId);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
99
50
|
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* @typedef {{ readonly status: 200; id: number; path: string; mime: string; data: Uint8Array; etag: string | undefined; mtime: number | undefined; }
|
|
103
|
-
* | { readonly status: 304; id: number; path: string; mime: string; mtime: number | undefined }
|
|
104
|
-
* | { readonly status: 401; id: number; path: string }
|
|
105
|
-
* | { readonly status: 404; id: number; path: string }} ResourceResponse
|
|
106
|
-
*/
|
|
107
|
-
|
|
108
51
|
/**
|
|
109
52
|
* Map of requested paths to responses.
|
|
110
|
-
*
|
|
111
|
-
* @type {RequestStore<ResourceResponse>}
|
|
112
53
|
*/
|
|
113
54
|
const resourceRequestStore = new RequestStore();
|
|
114
|
-
|
|
115
55
|
/**
|
|
116
56
|
* Map of requested localhost origins to optional redirects.
|
|
117
|
-
*
|
|
118
|
-
* @type {RequestStore<string | undefined>}
|
|
119
57
|
*/
|
|
120
58
|
const localhostRequestStore = new RequestStore();
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const notFound = () =>
|
|
126
|
-
new Response('Not Found', { status: 404, });
|
|
127
|
-
|
|
128
|
-
const methodNotAllowed = () =>
|
|
129
|
-
new Response('Method Not Allowed', { status: 405, });
|
|
130
|
-
|
|
131
|
-
const requestTimeout = () =>
|
|
132
|
-
new Response('Request Timeout', { status: 408, });
|
|
133
|
-
|
|
59
|
+
const unauthorized = () => new Response('Unauthorized', { status: 401, });
|
|
60
|
+
const notFound = () => new Response('Not Found', { status: 404, });
|
|
61
|
+
const methodNotAllowed = () => new Response('Method Not Allowed', { status: 405, });
|
|
62
|
+
const requestTimeout = () => new Response('Request Timeout', { status: 408, });
|
|
134
63
|
sw.addEventListener('message', async (event) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
64
|
+
if (!event.source) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const source = event.source;
|
|
68
|
+
switch (event.data.channel) {
|
|
69
|
+
case 'version': {
|
|
70
|
+
outerIframeMessagePort = event.ports[0];
|
|
71
|
+
sw.clients.get(source.id).then(client => {
|
|
72
|
+
if (client) {
|
|
73
|
+
client.postMessage({
|
|
74
|
+
channel: 'version',
|
|
75
|
+
version: VERSION
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
case 'did-load-resource': {
|
|
82
|
+
const response = event.data.data;
|
|
83
|
+
if (!resourceRequestStore.resolve(response.id, response)) {
|
|
84
|
+
console.log('Could not resolve unknown resource', response.path);
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
case 'did-load-localhost': {
|
|
89
|
+
const data = event.data.data;
|
|
90
|
+
if (!localhostRequestStore.resolve(data.id, data.location)) {
|
|
91
|
+
console.log('Could not resolve unknown localhost', data.origin);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
default: {
|
|
96
|
+
console.log('Unknown message');
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
168
100
|
});
|
|
169
|
-
|
|
170
101
|
sw.addEventListener('fetch', (event) => {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return event.respondWith(processLocalhostRequest(event, requestUrl));
|
|
216
|
-
}
|
|
102
|
+
const requestUrl = new URL(event.request.url);
|
|
103
|
+
if (typeof resourceBaseAuthority === 'string' && requestUrl.protocol === 'https:' && requestUrl.hostname.endsWith('.' + resourceBaseAuthority)) {
|
|
104
|
+
switch (event.request.method) {
|
|
105
|
+
case 'GET':
|
|
106
|
+
case 'HEAD': {
|
|
107
|
+
const firstHostSegment = requestUrl.hostname.slice(0, requestUrl.hostname.length - (resourceBaseAuthority.length + 1));
|
|
108
|
+
const scheme = firstHostSegment.split('+', 1)[0];
|
|
109
|
+
const authority = firstHostSegment.slice(scheme.length + 1); // may be empty
|
|
110
|
+
return event.respondWith(processResourceRequest(event, {
|
|
111
|
+
scheme,
|
|
112
|
+
authority,
|
|
113
|
+
path: requestUrl.pathname,
|
|
114
|
+
query: requestUrl.search.replace(/^\?/, ''),
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
default: {
|
|
118
|
+
return event.respondWith(methodNotAllowed());
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// If we're making a request against the remote authority, we want to go
|
|
123
|
+
// through VS Code itself so that we are authenticated properly. If the
|
|
124
|
+
// service worker is hosted on the same origin we will have cookies and
|
|
125
|
+
// authentication will not be an issue.
|
|
126
|
+
if (requestUrl.origin !== sw.origin && requestUrl.host === remoteAuthority) {
|
|
127
|
+
switch (event.request.method) {
|
|
128
|
+
case 'GET':
|
|
129
|
+
case 'HEAD': {
|
|
130
|
+
return event.respondWith(processResourceRequest(event, {
|
|
131
|
+
path: requestUrl.pathname,
|
|
132
|
+
scheme: requestUrl.protocol.slice(0, requestUrl.protocol.length - 1),
|
|
133
|
+
authority: requestUrl.host,
|
|
134
|
+
query: requestUrl.search.replace(/^\?/, ''),
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
default: {
|
|
138
|
+
return event.respondWith(methodNotAllowed());
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// See if it's a localhost request
|
|
143
|
+
if (requestUrl.origin !== sw.origin && requestUrl.host.match(/^(localhost|127.0.0.1|0.0.0.0):(\d+)$/)) {
|
|
144
|
+
return event.respondWith(processLocalhostRequest(event, requestUrl));
|
|
145
|
+
}
|
|
217
146
|
});
|
|
218
|
-
|
|
219
147
|
sw.addEventListener('install', (event) => {
|
|
220
|
-
|
|
148
|
+
event.waitUntil(sw.skipWaiting()); // Activate worker immediately
|
|
221
149
|
});
|
|
222
|
-
|
|
223
150
|
sw.addEventListener('activate', (event) => {
|
|
224
|
-
|
|
151
|
+
event.waitUntil(sw.clients.claim()); // Become available to all pages
|
|
225
152
|
});
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* @param {FetchEvent} event
|
|
229
|
-
* @param {{
|
|
230
|
-
* scheme: string;
|
|
231
|
-
* authority: string;
|
|
232
|
-
* path: string;
|
|
233
|
-
* query: string;
|
|
234
|
-
* }} requestUrlComponents
|
|
235
|
-
*/
|
|
236
153
|
async function processResourceRequest(event, requestUrlComponents) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
authority: requestUrlComponents.authority,
|
|
380
|
-
path: requestUrlComponents.path,
|
|
381
|
-
query: requestUrlComponents.query,
|
|
382
|
-
ifNoneMatch: cached?.headers.get('ETag'),
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
return promise.then(entry => resolveResourceEntry(entry, cached));
|
|
154
|
+
let client = await sw.clients.get(event.clientId);
|
|
155
|
+
if (!client) {
|
|
156
|
+
client = await getWorkerClientForId(event.clientId);
|
|
157
|
+
if (!client) {
|
|
158
|
+
console.error('Could not find inner client for request');
|
|
159
|
+
return notFound();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const webviewId = getWebviewIdForClient(client);
|
|
163
|
+
// Refs https://github.com/microsoft/vscode/issues/244143
|
|
164
|
+
// With PlzDedicatedWorker, worker subresources and blob wokers
|
|
165
|
+
// will use clients different from the window client.
|
|
166
|
+
// Since we cannot different a worker main resource from a worker subresource
|
|
167
|
+
// we will use message channel to the outer iframe provided at the time
|
|
168
|
+
// of service worker controller version initialization.
|
|
169
|
+
if (!webviewId && client.type !== 'worker' && client.type !== 'sharedworker') {
|
|
170
|
+
console.error('Could not resolve webview id');
|
|
171
|
+
return notFound();
|
|
172
|
+
}
|
|
173
|
+
const shouldTryCaching = (event.request.method === 'GET');
|
|
174
|
+
const resolveResourceEntry = (result, cachedResponse) => {
|
|
175
|
+
if (result.status === 'timeout') {
|
|
176
|
+
return requestTimeout();
|
|
177
|
+
}
|
|
178
|
+
const entry = result.value;
|
|
179
|
+
if (entry.status === 304) { // Not modified
|
|
180
|
+
if (cachedResponse) {
|
|
181
|
+
return cachedResponse.clone();
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
throw new Error('No cache found');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (entry.status === 401) {
|
|
188
|
+
return unauthorized();
|
|
189
|
+
}
|
|
190
|
+
if (entry.status !== 200) {
|
|
191
|
+
return notFound();
|
|
192
|
+
}
|
|
193
|
+
const commonHeaders = {
|
|
194
|
+
'Access-Control-Allow-Origin': '*',
|
|
195
|
+
};
|
|
196
|
+
const byteLength = entry.data.byteLength;
|
|
197
|
+
const range = event.request.headers.get('range');
|
|
198
|
+
if (range) {
|
|
199
|
+
// To support seeking for videos, we need to handle range requests
|
|
200
|
+
const bytes = range.match(/^bytes\=(\d+)\-(\d+)?$/g);
|
|
201
|
+
if (bytes) {
|
|
202
|
+
// TODO: Right now we are always reading the full file content. This is a bad idea
|
|
203
|
+
// for large video files :)
|
|
204
|
+
const start = Number(bytes[1]);
|
|
205
|
+
const end = Number(bytes[2]) || byteLength - 1;
|
|
206
|
+
return new Response(entry.data.slice(start, end + 1), {
|
|
207
|
+
status: 206,
|
|
208
|
+
headers: {
|
|
209
|
+
...commonHeaders,
|
|
210
|
+
'Content-range': `bytes 0-${end}/${byteLength}`,
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// We don't understand the requested bytes
|
|
216
|
+
return new Response(null, {
|
|
217
|
+
status: 416,
|
|
218
|
+
headers: {
|
|
219
|
+
...commonHeaders,
|
|
220
|
+
'Content-range': `*/${byteLength}`
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const headers = {
|
|
226
|
+
...commonHeaders,
|
|
227
|
+
'Content-Type': entry.mime,
|
|
228
|
+
'Content-Length': byteLength.toString(),
|
|
229
|
+
};
|
|
230
|
+
if (entry.etag) {
|
|
231
|
+
headers['ETag'] = entry.etag;
|
|
232
|
+
headers['Cache-Control'] = 'no-cache';
|
|
233
|
+
}
|
|
234
|
+
if (entry.mtime) {
|
|
235
|
+
headers['Last-Modified'] = new Date(entry.mtime).toUTCString();
|
|
236
|
+
}
|
|
237
|
+
// support COI requests, see network.ts#COI.getHeadersFromQuery(...)
|
|
238
|
+
const coiRequest = new URL(event.request.url).searchParams.get('vscode-coi');
|
|
239
|
+
if (coiRequest === '3') {
|
|
240
|
+
headers['Cross-Origin-Opener-Policy'] = 'same-origin';
|
|
241
|
+
headers['Cross-Origin-Embedder-Policy'] = 'require-corp';
|
|
242
|
+
}
|
|
243
|
+
else if (coiRequest === '2') {
|
|
244
|
+
headers['Cross-Origin-Embedder-Policy'] = 'require-corp';
|
|
245
|
+
}
|
|
246
|
+
else if (coiRequest === '1') {
|
|
247
|
+
headers['Cross-Origin-Opener-Policy'] = 'same-origin';
|
|
248
|
+
}
|
|
249
|
+
const response = new Response(entry.data, {
|
|
250
|
+
status: 200,
|
|
251
|
+
headers
|
|
252
|
+
});
|
|
253
|
+
if (shouldTryCaching && entry.etag) {
|
|
254
|
+
caches.open(resourceCacheName).then(cache => {
|
|
255
|
+
return cache.put(event.request, response);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return response.clone();
|
|
259
|
+
};
|
|
260
|
+
let cached;
|
|
261
|
+
if (shouldTryCaching) {
|
|
262
|
+
const cache = await caches.open(resourceCacheName);
|
|
263
|
+
cached = await cache.match(event.request);
|
|
264
|
+
}
|
|
265
|
+
const { requestId, promise } = resourceRequestStore.create();
|
|
266
|
+
if (webviewId) {
|
|
267
|
+
const parentClients = await getOuterIframeClient(webviewId);
|
|
268
|
+
if (!parentClients.length) {
|
|
269
|
+
console.log('Could not find parent client for request');
|
|
270
|
+
return notFound();
|
|
271
|
+
}
|
|
272
|
+
for (const parentClient of parentClients) {
|
|
273
|
+
parentClient.postMessage({
|
|
274
|
+
channel: 'load-resource',
|
|
275
|
+
id: requestId,
|
|
276
|
+
scheme: requestUrlComponents.scheme,
|
|
277
|
+
authority: requestUrlComponents.authority,
|
|
278
|
+
path: requestUrlComponents.path,
|
|
279
|
+
query: requestUrlComponents.query,
|
|
280
|
+
ifNoneMatch: cached?.headers.get('ETag'),
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else if (client.type === 'worker' || client.type === 'sharedworker') {
|
|
285
|
+
outerIframeMessagePort?.postMessage({
|
|
286
|
+
channel: 'load-resource',
|
|
287
|
+
id: requestId,
|
|
288
|
+
scheme: requestUrlComponents.scheme,
|
|
289
|
+
authority: requestUrlComponents.authority,
|
|
290
|
+
path: requestUrlComponents.path,
|
|
291
|
+
query: requestUrlComponents.query,
|
|
292
|
+
ifNoneMatch: cached?.headers.get('ETag'),
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
return promise.then(entry => resolveResourceEntry(entry, cached));
|
|
387
296
|
}
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* @param {FetchEvent} event
|
|
391
|
-
* @param {URL} requestUrl
|
|
392
|
-
* @return {Promise<Response>}
|
|
393
|
-
*/
|
|
394
297
|
async function processLocalhostRequest(event, requestUrl) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
298
|
+
const client = await sw.clients.get(event.clientId);
|
|
299
|
+
if (!client) {
|
|
300
|
+
// This is expected when requesting resources on other localhost ports
|
|
301
|
+
// that are not spawned by vs code
|
|
302
|
+
return fetch(event.request);
|
|
303
|
+
}
|
|
304
|
+
const webviewId = getWebviewIdForClient(client);
|
|
305
|
+
// Refs https://github.com/microsoft/vscode/issues/244143
|
|
306
|
+
// With PlzDedicatedWorker, worker subresources and blob wokers
|
|
307
|
+
// will use clients different from the window client.
|
|
308
|
+
// Since we cannot different a worker main resource from a worker subresource
|
|
309
|
+
// we will use message channel to the outer iframe provided at the time
|
|
310
|
+
// of service worker controller version initialization.
|
|
311
|
+
if (!webviewId && client.type !== 'worker' && client.type !== 'sharedworker') {
|
|
312
|
+
console.error('Could not resolve webview id');
|
|
313
|
+
return fetch(event.request);
|
|
314
|
+
}
|
|
315
|
+
const origin = requestUrl.origin;
|
|
316
|
+
const resolveRedirect = async (result) => {
|
|
317
|
+
if (result.status !== 'ok' || !result.value) {
|
|
318
|
+
return fetch(event.request);
|
|
319
|
+
}
|
|
320
|
+
const redirectOrigin = result.value;
|
|
321
|
+
const location = event.request.url.replace(new RegExp(`^${requestUrl.origin}(/|$)`), `${redirectOrigin}$1`);
|
|
322
|
+
return new Response(null, {
|
|
323
|
+
status: 302,
|
|
324
|
+
headers: {
|
|
325
|
+
Location: location
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
};
|
|
329
|
+
const { requestId, promise } = localhostRequestStore.create();
|
|
330
|
+
if (webviewId) {
|
|
331
|
+
const parentClients = await getOuterIframeClient(webviewId);
|
|
332
|
+
if (!parentClients.length) {
|
|
333
|
+
console.log('Could not find parent client for request');
|
|
334
|
+
return notFound();
|
|
335
|
+
}
|
|
336
|
+
for (const parentClient of parentClients) {
|
|
337
|
+
parentClient.postMessage({
|
|
338
|
+
channel: 'load-localhost',
|
|
339
|
+
origin: origin,
|
|
340
|
+
id: requestId,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
else if (client.type === 'worker' || client.type === 'sharedworker') {
|
|
345
|
+
outerIframeMessagePort?.postMessage({
|
|
346
|
+
channel: 'load-localhost',
|
|
347
|
+
origin: origin,
|
|
348
|
+
id: requestId,
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
return promise.then(resolveRedirect);
|
|
444
352
|
}
|
|
445
|
-
|
|
446
|
-
/**
|
|
447
|
-
* @param {Client} client
|
|
448
|
-
* @returns {string | null}
|
|
449
|
-
*/
|
|
450
353
|
function getWebviewIdForClient(client) {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
// will use clients different from the window client.
|
|
454
|
-
// Since we cannot different a worker main resource from a worker subresource
|
|
455
|
-
// we will use the global webview ID passed in at the time of
|
|
456
|
-
// service worker registration.
|
|
457
|
-
if (client.type === 'worker' || client.type === 'sharedworker') {
|
|
458
|
-
return ID;
|
|
459
|
-
}
|
|
460
|
-
const requesterClientUrl = new URL(client.url);
|
|
461
|
-
return requesterClientUrl.searchParams.get('id');
|
|
354
|
+
const requesterClientUrl = new URL(client.url);
|
|
355
|
+
return requesterClientUrl.searchParams.get('id');
|
|
462
356
|
}
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* @param {string} webviewId
|
|
466
|
-
* @returns {Promise<Client[]>}
|
|
467
|
-
*/
|
|
468
357
|
async function getOuterIframeClient(webviewId) {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
358
|
+
const allClients = await sw.clients.matchAll({ includeUncontrolled: true });
|
|
359
|
+
return allClients.filter(client => {
|
|
360
|
+
const clientUrl = new URL(client.url);
|
|
361
|
+
return clientUrl.searchParams.get('id') === webviewId;
|
|
362
|
+
});
|
|
474
363
|
}
|
|
475
|
-
|
|
476
|
-
/**
|
|
477
|
-
* @param {string} clientId
|
|
478
|
-
* @returns {Promise<Client|undefined>}
|
|
479
|
-
*/
|
|
480
364
|
async function getWorkerClientForId(clientId) {
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
365
|
+
const allDedicatedWorkerClients = await sw.clients.matchAll({ type: 'worker' });
|
|
366
|
+
const allSharedWorkerClients = await sw.clients.matchAll({ type: 'sharedworker' });
|
|
367
|
+
const allWorkerClients = [...allDedicatedWorkerClients, ...allSharedWorkerClients];
|
|
368
|
+
return allWorkerClients.find(client => {
|
|
369
|
+
return client.id === clientId;
|
|
370
|
+
});
|
|
487
371
|
}
|