@@ -22,6 +22,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
2222import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService' ;
2323import { ITunnelService } from 'vs/platform/remote/common/tunnel' ;
2424import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
25+ import { loadLocalResource , WebviewResourceResponse } from 'vs/platform/webview/common/resourceLoader' ;
2526import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService' ;
2627import { BaseWebview , WebviewMessageChannels } from 'vs/workbench/contrib/webview/browser/baseWebviewElement' ;
2728import { Webview , WebviewContentOptions , WebviewExtensionDescription , WebviewOptions } from 'vs/workbench/contrib/webview/browser/webview' ;
@@ -30,6 +31,34 @@ import { WebviewThemeDataProvider } from 'vs/workbench/contrib/webview/common/th
3031import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService' ;
3132import { WebviewFindDelegate , WebviewFindWidget } from '../browser/webviewFindWidget' ;
3233
34+ export function registerFileProtocol (
35+ contents : WebContents ,
36+ protocol : string ,
37+ fileService : IFileService ,
38+ extensionLocation : URI | undefined ,
39+ getRoots : ( ) => ReadonlyArray < URI >
40+ ) {
41+ contents . session . protocol . registerBufferProtocol ( protocol , async ( request , callback : any ) => {
42+ try {
43+ const result = await loadLocalResource ( URI . parse ( request . url ) , fileService , extensionLocation , getRoots ( ) ) ;
44+ if ( result . type === WebviewResourceResponse . Type . Success ) {
45+ return callback ( {
46+ data : Buffer . from ( result . buffer . buffer ) ,
47+ mimeType : result . mimeType
48+ } ) ;
49+ }
50+ if ( result . type === WebviewResourceResponse . Type . AccessDenied ) {
51+ console . error ( 'Webview: Cannot load resource outside of protocol root' ) ;
52+ return callback ( { error : - 10 /* ACCESS_DENIED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ } ) ;
53+ }
54+ } catch {
55+ // noop
56+ }
57+
58+ return callback ( { error : - 2 /* FAILED: https://cs.chromium.org/chromium/src/net/base/net_error_list.h */ } ) ;
59+ } ) ;
60+ }
61+
3362class WebviewTagHandle extends Disposable {
3463
3564 private _webContents : undefined | WebContents | 'destroyed' ;
@@ -123,21 +152,25 @@ class WebviewProtocolProvider extends Disposable {
123152 private _localResourceRoots : ReadonlyArray < URI > ;
124153
125154 constructor (
126- private readonly id : string ,
127- private readonly extension : WebviewExtensionDescription | undefined ,
155+ handle : WebviewTagHandle ,
156+ extension : WebviewExtensionDescription | undefined ,
128157 initialLocalResourceRoots : ReadonlyArray < URI > ,
129- private readonly _webviewManagerService : IWebviewManagerService ,
158+ fileService : IFileService ,
130159 ) {
131160 super ( ) ;
132161
133162 this . _localResourceRoots = initialLocalResourceRoots ;
134163
135- this . _ready = _webviewManagerService . registerWebview ( this . id , {
136- extensionLocation : this . extension ?. location . toJSON ( ) ,
137- localResourceRoots : initialLocalResourceRoots . map ( x => x . toJSON ( ) ) ,
164+ this . _ready = new Promise ( ( resolve , reject ) => {
165+ this . _register ( handle . onFirstLoad ( contents => {
166+ try {
167+ registerFileProtocol ( contents , Schemas . oldVscodeWebviewResource , fileService , extension ?. location , ( ) => this . _localResourceRoots ) ;
168+ resolve ( ) ;
169+ } catch {
170+ reject ( ) ;
171+ }
172+ } ) ) ;
138173 } ) ;
139-
140- this . _register ( toDisposable ( ( ) => this . _webviewManagerService . unregisterWebview ( this . id ) ) ) ;
141174 }
142175
143176 public update ( localResourceRoots : ReadonlyArray < URI > ) {
@@ -146,8 +179,6 @@ class WebviewProtocolProvider extends Disposable {
146179 }
147180
148181 this . _localResourceRoots = localResourceRoots ;
149-
150- this . _ready = this . _webviewManagerService . updateLocalResourceRoots ( this . id , localResourceRoots . map ( x => x . toJSON ( ) ) ) ;
151182 }
152183
153184 async synchronize ( ) : Promise < void > {
@@ -274,12 +305,10 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
274305 ) {
275306 super ( id , options , contentOptions , extension , _webviewThemeDataProvider , telemetryService , environementService , workbenchEnvironmentService ) ;
276307
277- const webviewManagerService = createChannelSender < IWebviewManagerService > ( mainProcessService . getChannel ( 'webview' ) ) ;
278-
279308 const webviewAndContents = this . _register ( new WebviewTagHandle ( this . element ! ) ) ;
280309 const session = this . _register ( new WebviewSession ( webviewAndContents ) ) ;
281310
282- this . _protocolProvider = this . _register ( new WebviewProtocolProvider ( id , extension , this . content . options . localResourceRoots || [ ] , webviewManagerService ) ) ;
311+ this . _protocolProvider = this . _register ( new WebviewProtocolProvider ( webviewAndContents , extension , this . content . options . localResourceRoots || [ ] , fileService ) ) ;
283312
284313 this . _register ( new WebviewPortMappingProvider (
285314 session ,
@@ -361,6 +390,7 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
361390 element . focus = ( ) => {
362391 this . doFocus ( ) ;
363392 } ;
393+ element . setAttribute ( 'partition' , `webview${ Date . now ( ) } ` ) ;
364394 element . setAttribute ( 'webpreferences' , 'contextIsolation=yes' ) ;
365395 element . className = `webview ${ options . customClasses || '' } ` ;
366396
@@ -371,7 +401,6 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
371401
372402 element . preload = require . toUrl ( './pre/electron-index.js' ) ;
373403 element . src = 'data:text/html;charset=utf-8,%3C%21DOCTYPE%20html%3E%0D%0A%3Chtml%20lang%3D%22en%22%20style%3D%22width%3A%20100%25%3B%20height%3A%20100%25%22%3E%0D%0A%3Chead%3E%0D%0A%3Ctitle%3EVirtual%20Document%3C%2Ftitle%3E%0D%0A%3C%2Fhead%3E%0D%0A%3Cbody%20style%3D%22margin%3A%200%3B%20overflow%3A%20hidden%3B%20width%3A%20100%25%3B%20height%3A%20100%25%22%20role%3D%22document%22%3E%0D%0A%3C%2Fbody%3E%0D%0A%3C%2Fhtml%3E' ;
374-
375404 return element ;
376405 }
377406
@@ -392,20 +421,9 @@ export class ElectronWebviewBasedWebview extends BaseWebview<WebviewTag> impleme
392421 }
393422
394423 private preprocessHtml ( value : string ) : string {
395- return value
396- . replace ( / ( [ " ' ] ) v s c o d e - r e s o u r c e : ( \/ \/ ( [ ^ \s \/ ' " ] + ?) (? = \/ ) ) ? ( [ ^ \s ' " ] + ?) ( [ " ' ] ) / gi, ( match , startQuote , _1 , scheme , path , endQuote ) => {
397- if ( scheme ) {
398- return `${ startQuote } ${ Schemas . vscodeWebviewResource } ://${ this . id } /${ scheme } ${ path } ${ endQuote } ` ;
399- }
400- if ( ! path . startsWith ( '//' ) ) {
401- // Add an empty authority if we don't already have one
402- path = '//' + path ;
403- }
404- return `${ startQuote } ${ Schemas . vscodeWebviewResource } ://${ this . id } /file${ path } ${ endQuote } ` ;
405- } ) ;
424+ return value ;
406425 }
407426
408-
409427 public mountTo ( parent : HTMLElement ) {
410428 if ( ! this . element ) {
411429 return ;
0 commit comments