@@ -67,31 +67,63 @@ class ToolsWebSocket {
6767 }
6868}
6969
70+ class ToolsResourceLoader {
71+ private _window : Window ;
72+ private _realLoadResource : ( url : string ) => Promise < string > ;
73+ private _urlLoadNextId : number ;
74+ private _urlLoadResolvers : Map < number , ( url : string ) => void > ;
75+
76+ constructor ( dtWindow : Window ) {
77+ this . _window = dtWindow ;
78+ this . _realLoadResource = ( this . _window as any ) . Runtime . loadResourcePromise ;
79+ this . _urlLoadNextId = 0 ;
80+ this . _urlLoadResolvers = new Map ( ) ;
81+ ( this . _window as any ) . Runtime . loadResourcePromise = this . loadResource . bind ( this ) ;
82+ }
83+
84+ public resolveUrlRequest ( message : string ) {
85+ // Parse the request from the message and store it
86+ const response = JSON . parse ( message ) as { id : number , content : string } ;
87+
88+ if ( this . _urlLoadResolvers . has ( response . id ) ) {
89+ this . _urlLoadResolvers . get ( response . id ) ( response . content ) ;
90+ this . _urlLoadResolvers . delete ( response . id ) ;
91+ }
92+ }
93+
94+ private async loadResource ( url : string ) : Promise < string > {
95+ if ( url === 'sources/module.json' ) {
96+ // Override the paused event revealer so that hitting a bp will not switch to the sources tab
97+ const content = await this . _realLoadResource ( url ) ;
98+ return content . replace ( / { [ ^ } ] + D e b u g g e r P a u s e d D e t a i l s R e v e a l e r [ ^ } ] + } , / gm, '' ) ;
99+ } if ( url . substr ( 0 , 7 ) === 'http://' || url . substr ( 0 , 8 ) === 'https://' ) {
100+ // Forward the cross domain request over to the extension
101+ return new Promise ( ( resolve : ( url : string ) => void , reject ) => {
102+ const id = this . _urlLoadNextId ++ ;
103+ this . _urlLoadResolvers . set ( id , resolve ) ;
104+ window . parent . postMessage ( `getUrl:${ JSON . stringify ( { id, url } ) } ` , '*' ) ;
105+ } ) ;
106+ } else {
107+ return this . _realLoadResource ( url ) ;
108+ }
109+ }
110+ }
111+
70112const devToolsFrame = document . getElementById ( 'devtools' ) as HTMLIFrameElement ;
71113devToolsFrame . onload = ( ) => {
72114 const dtWindow = devToolsFrame . contentWindow ;
73115
74116 // Override the apis and websocket so that we can control them
75117 ( dtWindow as any ) . InspectorFrontendHost = new ToolsHost ( ) ;
76118 ( dtWindow as any ) . WebSocket = ToolsWebSocket ;
119+ ( dtWindow as any ) . ResourceLoaderOverride = new ToolsResourceLoader ( dtWindow ) ;
77120
78121 // Prevent the devtools from using localStorage since it doesn't exist in data uris
79122 Object . defineProperty ( dtWindow , 'localStorage' , {
80123 get : function ( ) { return undefined ; } ,
81124 set : function ( ) { }
82125 } ) ;
83126
84- // Override the paused event revealer so that hitting a bp will not switch to the sources tab
85- const realLoadResource = ( dtWindow as any ) . Runtime . loadResourcePromise as ( url : string ) => Promise < string > ;
86- ( dtWindow as any ) . Runtime . loadResourcePromise = async function ( url : string ) : Promise < string > {
87- if ( url === 'sources/module.json' ) {
88- const content = await realLoadResource ( url ) ;
89- return content . replace ( / { [ ^ } ] + D e b u g g e r P a u s e d D e t a i l s R e v e a l e r [ ^ } ] + } , / gm, '' ) ;
90- } else {
91- return realLoadResource ( url ) ;
92- }
93- } ;
94-
95127 // Add unhandled exception listeners for telemetry
96128 const reportError = function ( name : string , stack : string ) {
97129 const telemetry = {
@@ -115,5 +147,7 @@ devToolsFrame.onload = () => {
115147window . addEventListener ( 'message' , ( e ) => {
116148 if ( e . data . substr ( 0 , 12 ) === 'preferences:' ) {
117149 ( devToolsFrame . contentWindow as any ) . InspectorFrontendHost . fireGetStateCallback ( e . data . substr ( 12 ) ) ;
150+ } else if ( e . data . substr ( 0 , 7 ) === 'setUrl:' ) {
151+ ( devToolsFrame . contentWindow as any ) . ResourceLoaderOverride . resolveUrlRequest ( e . data . substr ( 7 ) ) ;
118152 }
119153} ) ;
0 commit comments