mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-24 12:19:20 +00:00
Add simple browser extension (#109276)
* Add support for TS's Hierarchical refactorings API https://github.com/microsoft/TypeScript/pull/41975 * Add simple browser extension This change adds a new 'simple browser' extension. This extension uses a webview to render webpages directly in VS Code. We plan on using it for optionally previewing local servers in both desktop and codespaces The browser itself has a number of limitations due to the security around iframes: - It traps keyboard focus - We can't detect if a page fails to load - We can't track the current url of the iframe * Add experimental alert when the iframe is focused * Disable events on focus warning * Hooking up simple browser to opener
This commit is contained in:
86
extensions/simple-browser/preview-src/index.ts
Normal file
86
extensions/simple-browser/preview-src/index.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { onceDocumentLoaded } from './events';
|
||||
|
||||
declare let acquireVsCodeApi: any;
|
||||
const vscode = acquireVsCodeApi();
|
||||
|
||||
function getSettings() {
|
||||
const element = document.getElementById('simple-browser-settings');
|
||||
if (element) {
|
||||
const data = element.getAttribute('data-settings');
|
||||
if (data) {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Could not load settings`);
|
||||
}
|
||||
|
||||
const settings = getSettings();
|
||||
|
||||
const iframe = document.querySelector('iframe')!;
|
||||
const header = document.querySelector('.header')!;
|
||||
const input = header.querySelector<HTMLInputElement>('.url-input')!;
|
||||
const forwardButton = header.querySelector<HTMLButtonElement>('.forward-button')!;
|
||||
const backButton = header.querySelector<HTMLButtonElement>('.back-button')!;
|
||||
const reloadButton = header.querySelector<HTMLButtonElement>('.reload-button')!;
|
||||
const openExternalButton = header.querySelector<HTMLButtonElement>('.open-external-button')!;
|
||||
|
||||
window.addEventListener('message', e => {
|
||||
switch (e.data.type) {
|
||||
case 'focus':
|
||||
{
|
||||
iframe.focus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
onceDocumentLoaded(() => {
|
||||
setInterval(() => {
|
||||
const iframeFocused = document.activeElement?.tagName === 'IFRAME';
|
||||
document.body.classList.toggle('iframe-focused', iframeFocused);
|
||||
}, 50);
|
||||
|
||||
iframe.addEventListener('load', () => {
|
||||
// Noop
|
||||
});
|
||||
|
||||
input.addEventListener('change', e => {
|
||||
const url = (e.target as HTMLInputElement).value;
|
||||
navigateTo(url);
|
||||
});
|
||||
|
||||
forwardButton.addEventListener('click', () => {
|
||||
history.forward();
|
||||
});
|
||||
|
||||
backButton.addEventListener('click', () => {
|
||||
history.back();
|
||||
});
|
||||
|
||||
openExternalButton.addEventListener('click', () => {
|
||||
vscode.postMessage({
|
||||
type: 'openExternal',
|
||||
url: input.value
|
||||
});
|
||||
});
|
||||
|
||||
reloadButton.addEventListener('click', () => {
|
||||
// This does not seem to trigger what we want
|
||||
// history.go(0);
|
||||
|
||||
// This incorrectly adds entries to the history but does reload
|
||||
iframe.src = input.value;
|
||||
});
|
||||
|
||||
navigateTo(settings.url);
|
||||
|
||||
function navigateTo(url: string): void {
|
||||
iframe.src = url;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user