Skip to content
This repository was archived by the owner on Sep 17, 2021. It is now read-only.

Commit c6ce493

Browse files
authored
Merge pull request #5 from CodeMooseUS/addLaunchOnDebugSessionStart
Add launch on debug session start
2 parents 90fc046 + 7b65b4d commit c6ce493

File tree

4 files changed

+123
-27
lines changed

4 files changed

+123
-27
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ npm-debug.log
66
lib/
77
node_modules/
88
/out/
9-
typings/
9+
typings/
10+
/.vs
11+
/src/.vs/src/v16/.suo
12+
/src/.vs

package.json

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
"activationEvents": [
3636
"onCommand:devtools-for-chrome.launch",
3737
"onCommand:devtools-for-chrome.attach",
38-
"onWebviewPanel:devtools-for-chrome"
38+
"onWebviewPanel:devtools-for-chrome",
39+
"onDebug"
3940
],
4041
"main": "./out/extension",
4142
"contributes": {
@@ -51,6 +52,36 @@
5152
"category": "DevTools for Chrome"
5253
}
5354
],
55+
"debuggers": [
56+
{
57+
"type": "devtools-for-chrome",
58+
"label": "DevTools for Chrome",
59+
"configurationAttributes": {
60+
"launch": {
61+
"required": [
62+
"url"
63+
],
64+
"properties": {
65+
"url": {
66+
"type": "string",
67+
"description": "Absolute uri to launch.",
68+
"default": "http://localhost:8080"
69+
},
70+
"request": {
71+
"type": "string",
72+
"description": "A value representing whether the debugger should launch a new Chrome tab or attach to an exsisting one.",
73+
"default": "launch"
74+
},
75+
"chromePath": {
76+
"type": "string",
77+
"description": "Absolute path to the Chrome instance to launch.",
78+
"default": ""
79+
}
80+
}
81+
}
82+
}
83+
}
84+
],
5485
"configuration": {
5586
"title": "DevTools for Chrome",
5687
"type": "object",
@@ -98,4 +129,4 @@
98129
"tslint": "^5.11.0",
99130
"typescript": "^3.1.1"
100131
}
101-
}
132+
}

src/extension.ts

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,86 @@ import * as path from 'path';
22
import * as vscode from 'vscode';
33
import WebSocket from 'ws';
44
import QuickPickItem = vscode.QuickPickItem;
5-
import QuickPickOptions = vscode.QuickPickOptions;
65
import * as utils from './utils';
76

7+
let settings: vscode.WorkspaceConfiguration;
8+
let hostname: string;
9+
let port: number;
10+
const debuggerType: string = 'devtools-for-chrome';
11+
812
export function activate(context: vscode.ExtensionContext) {
9-
context.subscriptions.push(vscode.commands.registerCommand('devtools-for-chrome.attach', async () => {
10-
runCommand(context, attach);
11-
}));
13+
settings = vscode.workspace.getConfiguration('vscode-devtools-for-chrome');
14+
hostname = settings.get('hostname') as string || 'localhost';
15+
port = settings.get('port') as number || 9222;
1216

1317
context.subscriptions.push(vscode.commands.registerCommand('devtools-for-chrome.launch', async () => {
14-
runCommand(context, launch);
18+
launch(context);
1519
}));
16-
}
1720

18-
function runCommand(context: vscode.ExtensionContext, command: (context: vscode.ExtensionContext, hostname: string, port: number) => void) {
19-
const settings = vscode.workspace.getConfiguration('vscode-devtools-for-chrome');
20-
const hostname = settings.get('hostname') as string || 'localhost';
21-
const port = settings.get('port') as number || 9222;
21+
context.subscriptions.push(vscode.commands.registerCommand('devtools-for-chrome.attach', async () => {
22+
attach(context);
23+
}));
2224

23-
command(context, hostname, port);
25+
vscode.debug.registerDebugConfigurationProvider(debuggerType, {
26+
provideDebugConfigurations(folder: vscode.WorkspaceFolder | undefined, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration[]> {
27+
return [{
28+
type: debuggerType,
29+
name: 'Launch Chrome against localhost',
30+
request: 'launch',
31+
url: 'http://localhost:8080',
32+
}];
33+
},
34+
35+
resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration> {
36+
if (config && config.type == debuggerType) {
37+
if (config.request && config.request.localeCompare('attach', 'en', { sensitivity: 'base' }) == 0) {
38+
attach(context);
39+
} else {
40+
let launchUri: string = '';
41+
if (folder.uri.scheme == 'file') {
42+
const baseUrl: string = config.file || config.url;
43+
const replacedUri: string = baseUrl.replace('${workspaceFolder}', folder.uri.path);
44+
launchUri = utils.pathToFileURL(replacedUri);
45+
} else {
46+
launchUri = config.url;
47+
}
48+
launch(context, launchUri, config.chromePath);
49+
}
50+
} else {
51+
vscode.window.showErrorMessage('No supported launch config was found.');
52+
}
53+
return;
54+
}
55+
});
2456
}
2557

26-
async function launch(context: vscode.ExtensionContext, hostname: string, port: number) {
58+
async function launch(context: vscode.ExtensionContext, launchUrl?: string, chromePathFromLaunchConfig?: string) {
2759
const portFree = await utils.isPortFree(hostname, port);
60+
2861
if (portFree) {
29-
const settings = vscode.workspace.getConfiguration('vscode-devtools-for-chrome');
30-
const pathToChrome = settings.get('chromePath') as string || utils.getPathToChrome();
62+
const pathToChrome = settings.get('chromePath') as string || chromePathFromLaunchConfig || utils.getPathToChrome();
63+
3164
if (!pathToChrome || !utils.existsSync(pathToChrome)) {
32-
vscode.window.showErrorMessage('Chrome was not found. Chrome must be installed for this extension to function. If you have Chrome installed at a custom location you can speficy it in the \'chromePath\' setting.');
65+
vscode.window.showErrorMessage('Chrome was not found. Chrome must be installed for this extension to function. If you have Chrome installed at a custom location you can specify it in the \'chromePath\' setting.');
3366
return;
3467
}
68+
3569
utils.launchLocalChrome(pathToChrome, port, 'about:blank');
3670
}
3771

38-
attach(context, hostname, port);
39-
}
72+
const target = JSON.parse(await utils.getURL(`http://${hostname}:${port}/json/new?${launchUrl}`));
4073

41-
async function attach(context: vscode.ExtensionContext, hostname: string, port: number) {
42-
const checkDiscoveryEndpoint = (url: string) => {
43-
return utils.getURL(url, { headers: { Host: 'localhost' } });
44-
};
74+
if (!target || !target.webSocketDebuggerUrl || target.webSocketDebuggerUrl == '') {
75+
vscode.window.showErrorMessage(`Could not find the launched Chrome tab: (${launchUrl}).`);
76+
attach(context);
77+
} else {
78+
DevToolsPanel.createOrShow(context.extensionPath, target.webSocketDebuggerUrl);
79+
}
80+
}
4581

46-
const jsonResponse = await checkDiscoveryEndpoint(`http://${hostname}:${port}/json/list`)
47-
.catch(() => checkDiscoveryEndpoint(`http://${hostname}:${port}/json`));
82+
async function attach(context: vscode.ExtensionContext) {
83+
const responseArray = await getListOfTargets();
4884

49-
const responseArray = JSON.parse(jsonResponse);
5085
if (Array.isArray(responseArray)) {
5186
const items: QuickPickItem[] = [];
5287

@@ -63,6 +98,17 @@ async function attach(context: vscode.ExtensionContext, hostname: string, port:
6398
}
6499
}
65100

101+
async function getListOfTargets(): Promise<Array<any>> {
102+
const checkDiscoveryEndpoint = (url: string) => {
103+
return utils.getURL(url, { headers: { Host: 'localhost' } });
104+
};
105+
106+
const jsonResponse = await checkDiscoveryEndpoint(`http://${hostname}:${port}/json/list`)
107+
.catch(() => checkDiscoveryEndpoint(`http://${hostname}:${port}/json`));
108+
109+
return JSON.parse(jsonResponse);
110+
}
111+
66112
class DevToolsPanel {
67113
private static currentPanel: DevToolsPanel;
68114
private readonly _panel: vscode.WebviewPanel;

src/utils.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,20 @@ export function getPathToChrome(): string {
124124
} else {
125125
return existsSync(DEFAULT_CHROME_PATH.LINUX) ? DEFAULT_CHROME_PATH.LINUX : '';
126126
}
127+
}
128+
129+
export function pathToFileURL(absPath: string, normalize?: boolean): string {
130+
if (normalize) {
131+
absPath = path.normalize(absPath);
132+
absPath = forceForwardSlashes(absPath);
133+
}
134+
135+
absPath = (absPath.startsWith('/') ? 'file://' : 'file:///') + absPath;
136+
return encodeURI(absPath);
137+
}
138+
139+
export function forceForwardSlashes(aUrl: string): string {
140+
return aUrl
141+
.replace(/\\\//g, '/') // Replace \/ (unnecessarily escaped forward slash)
142+
.replace(/\\/g, '/');
127143
}

0 commit comments

Comments
 (0)