Skip to content

Commit 542ee2b

Browse files
authored
Merge pull request #32 from oslabs-beta/FL/RL-42-43-44/Memory-Leak_Cleanup
Was able to dispose of the webview resources properly. We are able to…
2 parents 189b7ed + 4625a1e commit 542ee2b

File tree

2 files changed

+79
-26
lines changed

2 files changed

+79
-26
lines changed

src/extension.ts

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,67 @@
11
import * as vscode from 'vscode';
22
import {createPanel} from './panel';
33
import { Parser } from './parser';
4+
import { Tree } from './types/tree';
5+
6+
let tree: Parser | undefined = undefined;
7+
let panel: vscode.WebviewPanel | undefined = undefined
8+
49

510
// This method is called when your extension is activated
611
// Your extension is activated the very first time the command is executed
7-
812
function activate(context: vscode.ExtensionContext) {
913

10-
let disposable = vscode.commands.registerCommand('react-labyrinth.helloWorld', function () {
11-
vscode.window.showInformationMessage('Hello World from React Labyrinth!');
12-
});
14+
// This is the column where Webview will be revealed to
15+
const columnToShowIn : vscode.ViewColumn | undefined = vscode.window.activeTextEditor
16+
? vscode.window.activeTextEditor.viewColumn
17+
: undefined;
18+
19+
20+
// Command that allows for User to select the root file of their React application.
21+
const pickFile: vscode.Disposable = vscode.commands.registerCommand('myExtension.pickFile', async () => {
22+
1323

14-
// pass in the command we want to register (refer to package.json)
15-
// let result = vscode.commands.registerCommand('myExtension.showPanel', () => {
16-
// // call helper func
17-
// createPanel(context);
18-
// });
24+
// Check if there is an existing webview panel, if so display it.
25+
if(panel) {
26+
panel.reveal(columnToShowIn)
27+
}
1928

20-
vscode.commands.registerCommand('myExtension.pickFile', async () => {
21-
const fileArray = await vscode.window.showOpenDialog({ canSelectFolders: false, canSelectFiles: true, canSelectMany: false });
29+
30+
// Opens window for the User to select the root file of React application
31+
const fileArray: vscode.Uri[] = await vscode.window.showOpenDialog({ canSelectFolders: false, canSelectFiles: true, canSelectMany: false });
2232

33+
34+
// Throw error message if no file was selected
2335
if (!fileArray || fileArray.length === 0) {
2436
vscode.window.showErrorMessage('No file selected');
2537
return;
2638
}
27-
28-
const tree = new Parser(fileArray[0].path);
39+
40+
41+
// Create Tree to be inserted into returned HTML
42+
tree = new Parser(fileArray[0].path);
2943
tree.parse();
30-
const data = tree.getTree();
31-
console.log('Data sent back: \n', data);
32-
createPanel(context, data);
44+
const data: Tree = tree.getTree();
45+
46+
47+
// Check if panel currently has a webview, if it does dispose of it and create another with updated root file selected.
48+
// Otherwise create a new webview to display root file selected.
49+
if(!panel) {
50+
panel = createPanel(context, data, columnToShowIn);
51+
} else {
52+
panel.dispose()
53+
panel = createPanel(context, data, columnToShowIn);
54+
}
3355
});
34-
context.subscriptions.push(disposable);
56+
57+
58+
// Command to show panel if it is hidden
59+
const showPanel: vscode.Disposable = vscode.commands.registerCommand('myExtension.showPanel', () => {
60+
panel.reveal(columnToShowIn)
61+
});
62+
63+
64+
context.subscriptions.push(pickFile, showPanel);
3565
}
3666

3767
// This method is called when your extension is deactivated

src/panel.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,58 @@ import * as vscode from 'vscode';
22
import { getNonce } from './getNonce';
33
import { Tree } from './types/tree';
44

5-
export function createPanel(context: vscode.ExtensionContext, data: Tree) {
6-
// if the current panel exists, then reveal the column, else make one?
5+
let panel: vscode.WebviewPanel | undefined = undefined
6+
7+
export function createPanel(context: vscode.ExtensionContext, data: Tree, columnToShowIn: vscode.ViewColumn) {
78

89
// utilize method on vscode.window object to create webview
9-
const panel = vscode.window.createWebviewPanel(
10+
panel = vscode.window.createWebviewPanel(
1011
'reactLabyrinth',
1112
'React Labyrinth',
13+
1214
// create one new tab
1315
vscode.ViewColumn.One,
1416
{
1517
enableScripts: true,
1618
retainContextWhenHidden: true
1719
}
1820
);
21+
1922

23+
// Set the icon logo of extension webview
2024
panel.iconPath = vscode.Uri.joinPath(context.extensionUri, 'media', 'favicon.ico');
25+
26+
27+
// Set URI to be the path to bundle
28+
const bundlePath: vscode.Uri = vscode.Uri.joinPath(context.extensionUri, 'build', 'bundle.js');
2129

22-
const bundlePath = vscode.Uri.joinPath(context.extensionUri, 'build', 'bundle.js');
2330

2431
// set webview URI to pass into html script
25-
const bundleURI = panel.webview.asWebviewUri(bundlePath);
32+
const bundleURI: vscode.Uri = panel.webview.asWebviewUri(bundlePath);
33+
2634

2735
// render html of webview here
2836
panel.webview.html = createWebviewHTML(bundleURI, data);
2937

30-
// will need to use onDidDispose to clear cached data and reset tree when the webview and/or application is closed
3138

39+
// Listens for when webview is closed and disposes of webview resources
40+
panel.onDidDispose(
41+
() => {
42+
panel = undefined;
43+
},
44+
null,
45+
context.subscriptions
46+
);
47+
48+
49+
// Sends data to Flow.tsx to be displayed after parsed data is received
3250
panel.webview.onDidReceiveMessage(
3351
async (msg: any) => {
3452
switch (msg.type) {
3553
case 'onData':
3654
if (!msg.value) break;
3755
context.workspaceState.update('reactLabyrinth', msg.value);
38-
// console.log('msg.value from panel.js: ', msg.value);
56+
3957
panel.webview.postMessage(
4058
{
4159
type: 'parsed-data',
@@ -49,13 +67,18 @@ export function createPanel(context: vscode.ExtensionContext, data: Tree) {
4967
undefined,
5068
context.subscriptions
5169
);
70+
71+
return panel
5272
};
5373

74+
75+
5476
// getNonce generates a new random string each time ext is used to prevent external injection of foreign code into the html
55-
const nonce = getNonce();
77+
const nonce: string = getNonce();
78+
5679

5780
// function to create the HTML page for webview
58-
function createWebviewHTML(URI: vscode.Uri, initialData: Tree) {
81+
function createWebviewHTML(URI: vscode.Uri, initialData: Tree) : string {
5982
return (
6083
`
6184
<!DOCTYPE html>

0 commit comments

Comments
 (0)