Skip to content

Commit

Permalink
Add command for opening an HTML file in a browser (#6071)
Browse files Browse the repository at this point in the history
This change adds an "Open in Browser" command to HTML files to go with
"Open in Viewer", based on user feedback that it is not obvious how to
open an HTML file in a browser if you're looking at it in Positron.

Addresses #6047. 

### Release Notes

#### New Features

- New "Open in Browser" command for HTML files (#6047)

#### Bug Fixes

- N/A


### QA Notes

- This change exists only in the Positron Proxy extension and thus
should not affect any core scenarios.
- I changed the icon for the "Open in Viewer" command to "preview" since
I think it's better suited to the gesture.
  • Loading branch information
jmcphers authored Jan 29, 2025
1 parent 8b04874 commit c35daad
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 5 deletions.
17 changes: 16 additions & 1 deletion extensions/positron-proxy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,36 @@
"when": "resourceLangId == html && resourceScheme == file",
"command": "positronProxy.showHtmlPreview",
"group": "navigation"
},
{
"when": "resourceLangId == html && resourceScheme == file",
"command": "positronProxy.openBrowserPreview",
"group": "navigation"
}
],
"editor/title": [
{
"when": "resourceLangId == html && resourceScheme == file",
"command": "positronProxy.showHtmlPreview",
"group": "navigation"
},
{
"when": "resourceLangId == html && resourceScheme == file",
"command": "positronProxy.openBrowserPreview",
"group": "navigation"
}
]
},
"commands": [
{
"command": "positronProxy.showHtmlPreview",
"title": "%command.positronProxy.showHtmlPreview.title%",
"icon": "$(eye)"
"icon": "$(open-preview)"
},
{
"command": "positronProxy.openBrowserPreview",
"title": "%command.positronProxy.openBrowserPreview.title%",
"icon": "$(browser)"
}
]
},
Expand Down
3 changes: 2 additions & 1 deletion extensions/positron-proxy/package.nls.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"displayName": "Positron Proxy",
"description": "HTTP proxying for Positron",
"command.positronProxy.showHtmlPreview.title": "Open in Viewer"
"command.positronProxy.showHtmlPreview.title": "Open in Viewer",
"command.positronProxy.openBrowserPreview.title": "Open in Browser"
}
50 changes: 49 additions & 1 deletion extensions/positron-proxy/src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*---------------------------------------------------------------------------------------------
* Copyright (C) 2022-2024 Posit Software, PBC. All rights reserved.
* Copyright (C) 2022-2025 Posit Software, PBC. All rights reserved.
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
*--------------------------------------------------------------------------------------------*/

Expand Down Expand Up @@ -85,6 +85,54 @@ export function activate(context: vscode.ExtensionContext) {
})
);

// Register the positronProxy.showHtmlPreview command and add its disposable.
context.subscriptions.push(
vscode.commands.registerCommand(
'positronProxy.openBrowserPreview',
async (path: vscode.Uri) => {
let targetPath = path;

// If the path isn't supplied, use the active text editor's path.
if (!targetPath) {
const activeEditor = vscode.window.activeTextEditor;
if (activeEditor) {
targetPath = activeEditor.document.uri;

// Check that the URI refers to an HTML file. We are
// ultimately going to call `openExternal` which
// doesn't invoke a web browser unless the file is
// actually HTML since it relies on the system open
// behavior in desktop environments.
const extension = targetPath.fsPath.split('.').pop()?.toLowerCase();
if (extension !== 'html' && extension !== 'htm') {
vscode.window.showErrorMessage(vscode.l10n.t('The file {0} does not appear to be an HTML file, so it will not be opened in the browser.', targetPath.fsPath));
return;
}
} else {
vscode.window.showErrorMessage(vscode.l10n.t('No selected file to open in the browser. Open an HTML file in an editor before running this command.'));
return;
}
}

// On a native desktop build, we can open the file directly in
// the browser, without starting a proxy server. But in all
// other cases (web, remote SSH, etc), the file is not likely
// to be accessible to the browser, so we need to start a proxy
// server.
if (vscode.env.uiKind === vscode.UIKind.Web || vscode.env.remoteName) {
// Create a proxy server and get the URI to open in the browser.
const proxyUri = await positronProxy.startHtmlProxyServer(path.toString());

// Translate the proxy URI to an external URI.
targetPath = await vscode.env.asExternalUri(vscode.Uri.parse(proxyUri));
}


// Open the external URI in the default browser.
vscode.env.openExternal(targetPath);
})
);

// Add the PositronProxy object disposable.
context.subscriptions.push(positronProxy);
}
4 changes: 2 additions & 2 deletions extensions/positron-proxy/src/positronProxy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*---------------------------------------------------------------------------------------------
* Copyright (C) 2022-2024 Posit Software, PBC. All rights reserved.
* Copyright (C) 2022-2025 Posit Software, PBC. All rights reserved.
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
*--------------------------------------------------------------------------------------------*/

Expand Down Expand Up @@ -169,7 +169,7 @@ export class PositronProxy implements Disposable {
* @param targetPath The target path
* @returns The server URL.
*/
async startHtmlProxyServer(targetPath: string) {
async startHtmlProxyServer(targetPath: string): Promise<string> {
log.debug(`Starting an HTML proxy server for target: ${targetPath}...`);

if (!this._htmlProxyServer) {
Expand Down

0 comments on commit c35daad

Please sign in to comment.