From e0b60266a21918994aac2f473ef9d79565f58a7f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Wed, 24 Jul 2019 11:27:30 +0200 Subject: [PATCH] force refetch of remote resources that have been added before the SW is ready, #75061 --- src/vs/base/browser/dom.ts | 2 +- .../browser/resourceServiceWorker.ts | 14 +++--- .../browser/resourceServiceWorkerClient.ts | 50 ++++++++++++++++++- .../browser/resourceServiceWorkerMain.ts | 2 +- 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 7e9580db4d8e3..fa12f62900086 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -1200,7 +1200,7 @@ export function asDomUri(uri: URI): URI { if (Schemas.vscodeRemote === uri.scheme) { // rewrite vscode-remote-uris to uris of the window location // so that they can be intercepted by the service worker - return _location.with({ path: '/vscode-resources/fetch', query: JSON.stringify({ u: uri.toJSON(), i: 1 }) }); + return _location.with({ path: '/vscode-resources/fetch', query: `u=${JSON.stringify(uri)}` }); } return uri; } diff --git a/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts b/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts index ce0cb13dd2c3a..622bb7889bec2 100644 --- a/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts +++ b/src/vs/workbench/contrib/resources/browser/resourceServiceWorker.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { URI, UriComponents } from 'vs/base/common/uri'; +import { URI } from 'vs/base/common/uri'; import { generateUuid } from 'vs/base/common/uuid'; import { getMediaMime } from 'vs/base/common/mime'; @@ -71,7 +71,8 @@ async function respondWithDefault(event: FetchEvent): Promise { } async function respondWithResource(event: FetchEvent, uri: URI): Promise { - const cachedValue = await caches.open(_cacheName).then(cache => cache.match(event.request)); + const cacheKey = event.request.url.replace('&r=1', ''); + const cachedValue = await caches.open(_cacheName).then(cache => cache.match(cacheKey)); if (cachedValue) { return cachedValue; } @@ -79,26 +80,27 @@ async function respondWithResource(event: FetchEvent, uri: URI): Promise(resolve => { const token = generateUuid(); - const query: { u: UriComponents, i: number } = JSON.parse(uri.query); + const [first] = uri.query.split('&'); + const components = JSON.parse(first.substr(2)); _pendingFetch.set(token, async (data: ArrayBuffer, isExtensionResource: boolean) => { const res = new Response(data, { status: 200, - headers: { 'Content-Type': getMediaMime(query.u.path) || 'text/plain' } + headers: { 'Content-Type': getMediaMime(components.path) || 'text/plain' } }); if (isExtensionResource) { // only cache extension resources but not other // resources, esp not workspace resources - await caches.open(_cacheName).then(cache => cache.put(event.request, res.clone())); + await caches.open(_cacheName).then(cache => cache.put(cacheKey, res.clone())); } return resolve(res); }); self.clients.get(event.clientId).then(client => { - client.postMessage({ uri: query.u, token }); + client.postMessage({ uri: components, token }); }); }); } diff --git a/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts b/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts index a04930f1fb6d7..dfda6a1cfbba2 100644 --- a/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts +++ b/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerClient.ts @@ -65,11 +65,12 @@ class ResourceServiceWorker { @IExtensionService private readonly _extensionService: IExtensionService, @ILogService private readonly _logService: ILogService, ) { + this._updateEarlyResourceUris(); _serviceWorker.claim(e => this._handleMessage(e)); } private _handleMessage(event: ExtendableMessageEvent): void { - this._logService.trace('SW#fetch', event.data.uri); + this._logService.trace('SW - fetch', event.data.uri); const uri = URI.revive(event.data.uri); Promise.all([ @@ -95,6 +96,53 @@ class ResourceServiceWorker { } return false; } + + private _updateEarlyResourceUris(): void { + + let updateCount = 0; + + // find style-tags + const styleElements = document.querySelectorAll('style'); + for (let i = 0; i < styleElements.length; i++) { + const el = styleElements.item(i); + if (!el.sheet) { + continue; + } + const rules = (el.sheet).rules; + for (let j = 0; j < rules.length; j++) { + const rule = rules[j]; + const newCssText = this._updateResourceUris(rule.cssText); + if (newCssText) { + (el.sheet).deleteRule(j); + (el.sheet).insertRule(newCssText, j); + updateCount += 1; + } + } + } + + // find any tag using remote uris + const htmlElements = document.querySelectorAll('[style*="/vscode-resources/fetch"]'); + for (let i = 0; i < htmlElements.length; i++) { + const el = htmlElements.item(i); + const newCssText = this._updateResourceUris(el.style.cssText); + if (newCssText) { + el.style.cssText = newCssText; + updateCount += 1; + } + } + + this._logService.trace('SW - count of changed, early dom element: ', updateCount); + } + + private _updateResourceUris(cssText: string): string | undefined { + let changed = false; + let newCssText = cssText.replace(/url\((["'])?(.+?\/vscode-resources\/fetch\?.+?)\1\)/g, (_match, g1, g2, _offset, _input) => { + changed = true; + return `url(${g1 || ''}${g2}&r=1${g1 || ''})`; + }); + + return changed ? newCssText : undefined; + } } Registry.as(Extensions.Workbench).registerWorkbenchContribution( diff --git a/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.ts b/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.ts index 3138288942e41..49f317ecd5502 100644 --- a/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.ts +++ b/src/vs/workbench/contrib/resources/browser/resourceServiceWorkerMain.ts @@ -10,7 +10,7 @@ // statement. // trigger service worker updates -const _tag = '66399613-d758-4b88-b073-ff4195611d70'; +const _tag = 'a6f9835e-c10e-4299-ab39-b8e29547c20a'; // loader world const baseUrl = '../../../../../';