11// Copyright (c) Microsoft Corporation. All rights reserved.
22// Licensed under the MIT License.
3-
3+ import * as fs from 'fs-extra' ;
44import { ChildProcess } from 'child_process' ;
55import * as path from 'path' ;
66import {
77 CancellationToken ,
88 CancellationTokenSource ,
9+ Position ,
910 Progress ,
1011 ProgressLocation ,
1112 ProgressOptions ,
1213 QuickPickItem ,
14+ Selection ,
15+ Uri ,
1316 ViewColumn ,
1417 WebviewPanel ,
1518 window ,
19+ workspace ,
1620} from 'vscode' ;
1721import { IApplicationShell , ICommandManager , IWorkspaceService } from '../common/application/types' ;
1822import { createPromiseFromCancellation } from '../common/cancellation' ;
@@ -29,6 +33,10 @@ import { EventName } from '../telemetry/constants';
2933import { ImportTracker } from '../telemetry/importTracker' ;
3034import { TensorBoardPromptSelection , TensorBoardSessionStartResult } from './constants' ;
3135
36+ enum Messages {
37+ JumpToSource = 'jump_to_source' ,
38+ }
39+
3240/**
3341 * Manages the lifecycle of a TensorBoard session.
3442 * Specifically, it:
@@ -372,6 +380,7 @@ export class TensorBoardSession {
372380 this . url = match [ 1 ] ;
373381 urlThatTensorBoardIsRunningAt . resolve ( 'success' ) ;
374382 }
383+ traceInfo ( output . out ) ;
375384 } else if ( output . source === 'stderr' ) {
376385 traceError ( output . out ) ;
377386 }
@@ -405,15 +414,26 @@ export class TensorBoardSession {
405414 </head>
406415 <body>
407416 <script type="text/javascript">
417+ const vscode = acquireVsCodeApi();
408418 function resizeFrame() {
409419 var f = window.document.getElementById('vscode-tensorboard-iframe');
410420 if (f) {
411- f.style.height = window.innerHeight / 0.7 + "px";
412- f.style.width = window.innerWidth / 0.7 + "px";
421+ f.style.height = window.innerHeight / 0.8 + "px";
422+ f.style.width = window.innerWidth / 0.8 + "px";
413423 }
414424 }
415425 resizeFrame();
426+ window.onload = function() {
427+ resizeFrame();
428+ }
416429 window.addEventListener('resize', resizeFrame);
430+ window.addEventListener('message', (event) => {
431+ if (!"${ this . url } ".startsWith(event.origin) || !event.data || !event.data.filename || !event.data.line) {
432+ return;
433+ }
434+ const args = { filename: event.data.filename, line: event.data.line };
435+ vscode.postMessage({ command: '${ Messages . JumpToSource } ', args: args });
436+ });
417437 </script>
418438 <iframe
419439 id="vscode-tensorboard-iframe"
@@ -426,7 +446,7 @@ export class TensorBoardSession {
426446 ></iframe>
427447 <style>
428448 .responsive-iframe {
429- transform: scale(0.7 );
449+ transform: scale(0.8 );
430450 transform-origin: 0 0;
431451 position: absolute;
432452 top: 0;
@@ -447,6 +467,18 @@ export class TensorBoardSession {
447467 this . process = undefined ;
448468 } ) ,
449469 ) ;
470+ this . disposables . push (
471+ webviewPanel . webview . onDidReceiveMessage ( ( message ) => {
472+ // Handle messages posted from the webview
473+ switch ( message . command ) {
474+ case Messages . JumpToSource :
475+ jumpToSource ( message . args . filename , message . args . line ) ;
476+ break ;
477+ default :
478+ break ;
479+ }
480+ } ) ,
481+ ) ;
450482 return webviewPanel ;
451483 }
452484
@@ -461,3 +493,21 @@ export class TensorBoardSession {
461493 return undefined ;
462494 }
463495}
496+
497+ function jumpToSource ( fsPath : string , line : number ) {
498+ if ( fs . existsSync ( fsPath ) ) {
499+ const uri = Uri . file ( fsPath ) ;
500+ workspace
501+ . openTextDocument ( uri )
502+ . then ( ( doc ) => window . showTextDocument ( doc , ViewColumn . Beside ) )
503+ . then ( ( editor ) => {
504+ // Select the line if it exists in the document
505+ if ( line < editor . document . lineCount ) {
506+ const position = new Position ( line , 0 ) ;
507+ editor . selection = new Selection ( position , editor . document . lineAt ( line ) . range . end ) ;
508+ }
509+ } ) ;
510+ } else {
511+ traceError ( `Requested jump to source filepath ${ fsPath } does not exist` ) ;
512+ }
513+ }
0 commit comments