-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Integrated Browser #278677
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Integrated Browser #278677
Changes from all commits
Commits
Show all changes
39 commits
Select commit
Hold shift + click to select a range
4bd5ae0
[WIP] Integrated Browser
kycutler 8c37204
clean
kycutler feea74d
refactor
kycutler 4b29dda
structure
kycutler e1ebea2
focus
kycutler aa1e9f1
tooltips
kycutler e2c43db
rename
kycutler 80b1b68
polish
kycutler 33efb28
start unpinned
kycutler 9ecfeda
More polish
kycutler d62b23d
commands
kycutler b34d92e
tweaks, new tab support
kycutler 759a495
clean
kycutler 7557c13
shortcut fixes
kycutler a1336ab
warnings
kycutler 39031a3
Update src/vs/workbench/contrib/browserView/electron-browser/browserE…
kycutler bc6de66
Telemetry
kycutler d2ec0ec
load errors
kycutler d7736eb
PR feedback
kycutler 0245ed4
PR feedback
kycutler 1e54da1
Merge branch 'main' into kycutler/rich-browser
kycutler faf1c6c
Permissions, unloads, trust
kycutler 7c805eb
Storage controls
kycutler 58d54aa
Handle render process gone
kycutler 5a5bf55
Merge branch 'main' into kycutler/rich-browser
kycutler 8229bec
devtools
kycutler 9c00484
Screenshot rect
kycutler d8b430c
close
kycutler 0e95ee2
Fix focused context
kycutler 5b6cfd1
Merge branch 'main' into kycutler/rich-browser
kycutler 86167ee
Fix merge
kycutler aca4396
disposables
kycutler 077294b
Merge branch 'main' into kycutler/rich-browser
bpasero 97e1fad
:lipstick:
bpasero a656469
Merge branch 'main' into kycutler/rich-browser
kycutler ac7df40
Multi-window improvements
kycutler b6a19a8
Fix reopen
kycutler ca8dcbb
PR feedback
kycutler 39beb94
Actions fixes
kycutler File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,216 @@ | ||
| /*--------------------------------------------------------------------------------------------- | ||
| * Copyright (c) Microsoft Corporation. All rights reserved. | ||
| * Licensed under the MIT License. See License.txt in the project root for license information. | ||
| *--------------------------------------------------------------------------------------------*/ | ||
|
|
||
| import { Event } from '../../../base/common/event.js'; | ||
| import { VSBuffer } from '../../../base/common/buffer.js'; | ||
|
|
||
| export interface IBrowserViewBounds { | ||
| windowId: number; | ||
| x: number; | ||
| y: number; | ||
| width: number; | ||
| height: number; | ||
| zoomFactor: number; | ||
| } | ||
|
|
||
| export interface IBrowserViewCaptureScreenshotOptions { | ||
| quality?: number; | ||
| rect?: { x: number; y: number; width: number; height: number }; | ||
| } | ||
|
|
||
| export interface IBrowserViewState { | ||
| url: string; | ||
| title: string; | ||
| canGoBack: boolean; | ||
| canGoForward: boolean; | ||
| loading: boolean; | ||
| isDevToolsOpen: boolean; | ||
| lastScreenshot: VSBuffer | undefined; | ||
| lastFavicon: string | undefined; | ||
| lastError: IBrowserViewLoadError | undefined; | ||
| storageScope: BrowserViewStorageScope; | ||
| } | ||
|
|
||
| export interface IBrowserViewNavigationEvent { | ||
| url: string; | ||
| canGoBack: boolean; | ||
| canGoForward: boolean; | ||
| } | ||
|
|
||
| export interface IBrowserViewLoadingEvent { | ||
| loading: boolean; | ||
| error?: IBrowserViewLoadError; | ||
| } | ||
|
|
||
| export interface IBrowserViewLoadError { | ||
| url: string; | ||
| errorCode: number; | ||
| errorDescription: string; | ||
| } | ||
|
|
||
| export interface IBrowserViewFocusEvent { | ||
| focused: boolean; | ||
| } | ||
|
|
||
| export interface IBrowserViewDevToolsStateEvent { | ||
| isDevToolsOpen: boolean; | ||
| } | ||
|
|
||
| export interface IBrowserViewKeyDownEvent { | ||
| key: string; | ||
| keyCode: number; | ||
| code: string; | ||
| ctrlKey: boolean; | ||
| shiftKey: boolean; | ||
| altKey: boolean; | ||
| metaKey: boolean; | ||
| repeat: boolean; | ||
| } | ||
|
|
||
| export interface IBrowserViewTitleChangeEvent { | ||
| title: string; | ||
| } | ||
|
|
||
| export interface IBrowserViewFaviconChangeEvent { | ||
| favicon: string; | ||
| } | ||
|
|
||
| export interface IBrowserViewNewPageRequest { | ||
| url: string; | ||
| name?: string; | ||
| background: boolean; | ||
| } | ||
|
|
||
| export enum BrowserViewStorageScope { | ||
| Global = 'global', | ||
| Workspace = 'workspace', | ||
| Ephemeral = 'ephemeral' | ||
| } | ||
|
|
||
| export const ipcBrowserViewChannelName = 'browserView'; | ||
|
|
||
| export interface IBrowserViewService { | ||
| /** | ||
| * Dynamic events that return an Event for a specific browser view ID. | ||
| */ | ||
| onDynamicDidNavigate(id: string): Event<IBrowserViewNavigationEvent>; | ||
| onDynamicDidChangeLoadingState(id: string): Event<IBrowserViewLoadingEvent>; | ||
| onDynamicDidChangeFocus(id: string): Event<IBrowserViewFocusEvent>; | ||
| onDynamicDidChangeDevToolsState(id: string): Event<IBrowserViewDevToolsStateEvent>; | ||
| onDynamicDidKeyCommand(id: string): Event<IBrowserViewKeyDownEvent>; | ||
| onDynamicDidChangeTitle(id: string): Event<IBrowserViewTitleChangeEvent>; | ||
| onDynamicDidChangeFavicon(id: string): Event<IBrowserViewFaviconChangeEvent>; | ||
| onDynamicDidRequestNewPage(id: string): Event<IBrowserViewNewPageRequest>; | ||
| onDynamicDidClose(id: string): Event<void>; | ||
|
|
||
| /** | ||
| * Get or create a browser view instance | ||
| * @param id The browser view identifier | ||
| * @param scope The storage scope for the browser view. Ignored if the view already exists. | ||
| * @param workspaceId Workspace identifier for session isolation. Only used if scope is 'workspace'. | ||
| */ | ||
| getOrCreateBrowserView(id: string, scope: BrowserViewStorageScope, workspaceId?: string): Promise<IBrowserViewState>; | ||
|
|
||
| /** | ||
| * Destroy a browser view instance | ||
| * @param id The browser view identifier | ||
| */ | ||
| destroyBrowserView(id: string): Promise<void>; | ||
|
|
||
| /** | ||
| * Update the bounds of a browser view | ||
| * @param id The browser view identifier | ||
| * @param bounds The new bounds for the view | ||
| */ | ||
| layout(id: string, bounds: IBrowserViewBounds): Promise<void>; | ||
|
|
||
| /** | ||
| * Set the visibility of a browser view | ||
| * @param id The browser view identifier | ||
| * @param visible Whether the view should be visible | ||
| */ | ||
| setVisible(id: string, visible: boolean): Promise<void>; | ||
|
|
||
| /** | ||
| * Navigate the browser view to a URL | ||
| * @param id The browser view identifier | ||
| * @param url The URL to navigate to | ||
| */ | ||
| loadURL(id: string, url: string): Promise<void>; | ||
|
|
||
| /** | ||
| * Get the current URL of a browser view | ||
| * @param id The browser view identifier | ||
| */ | ||
| getURL(id: string): Promise<string>; | ||
|
|
||
| /** | ||
| * Go back in navigation history | ||
| * @param id The browser view identifier | ||
| */ | ||
| goBack(id: string): Promise<void>; | ||
|
|
||
| /** | ||
| * Go forward in navigation history | ||
| * @param id The browser view identifier | ||
| */ | ||
| goForward(id: string): Promise<void>; | ||
|
|
||
| /** | ||
| * Reload the current page | ||
| * @param id The browser view identifier | ||
| */ | ||
| reload(id: string): Promise<void>; | ||
|
|
||
| /** | ||
| * Toggle developer tools for the browser view. | ||
| * @param id The browser view identifier | ||
| */ | ||
| toggleDevTools(id: string): Promise<void>; | ||
|
|
||
| /** | ||
| * Check if the view can go back | ||
| * @param id The browser view identifier | ||
| */ | ||
| canGoBack(id: string): Promise<boolean>; | ||
|
|
||
| /** | ||
| * Check if the view can go forward | ||
| * @param id The browser view identifier | ||
| */ | ||
| canGoForward(id: string): Promise<boolean>; | ||
|
|
||
| /** | ||
| * Capture a screenshot of the browser view | ||
| * @param id The browser view identifier | ||
| * @param options Screenshot options (quality and rect) | ||
| * @returns Screenshot as a buffer | ||
| */ | ||
| captureScreenshot(id: string, options?: IBrowserViewCaptureScreenshotOptions): Promise<VSBuffer>; | ||
|
|
||
| /** | ||
| * Dispatch a key event to the browser view | ||
| * @param id The browser view identifier | ||
| * @param keyEvent The key event data | ||
| */ | ||
| dispatchKeyEvent(id: string, keyEvent: IBrowserViewKeyDownEvent): Promise<void>; | ||
|
|
||
| /** | ||
| * Focus the browser view | ||
| * @param id The browser view identifier | ||
| */ | ||
| focus(id: string): Promise<void>; | ||
|
|
||
| /** | ||
| * Clear all storage data for the global browser session | ||
| */ | ||
| clearGlobalStorage(): Promise<void>; | ||
|
|
||
| /** | ||
| * Clear all storage data for a specific workspace browser session | ||
| * @param workspaceId The workspace identifier | ||
| */ | ||
| clearWorkspaceStorage(workspaceId: string): Promise<void>; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| /*--------------------------------------------------------------------------------------------- | ||
| * Copyright (c) Microsoft Corporation. All rights reserved. | ||
| * Licensed under the MIT License. See License.txt in the project root for license information. | ||
| *--------------------------------------------------------------------------------------------*/ | ||
|
|
||
| import { Schemas } from '../../../base/common/network.js'; | ||
| import { URI } from '../../../base/common/uri.js'; | ||
| import { generateUuid } from '../../../base/common/uuid.js'; | ||
|
|
||
| /** | ||
| * Helper for creating and parsing browser view URIs. | ||
| */ | ||
| export namespace BrowserViewUri { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also seems like a good class for unit tests |
||
|
|
||
| export const scheme = Schemas.vscodeBrowser; | ||
|
|
||
| /** | ||
| * Creates a resource URI for a browser view with the given URL. | ||
| * Optionally accepts an ID; if not provided, a new UUID is generated. | ||
| */ | ||
| export function forUrl(url: string | undefined, id?: string): URI { | ||
| const viewId = id ?? generateUuid(); | ||
| return URI.from({ | ||
| scheme, | ||
| path: `/${viewId}`, | ||
| query: url ? `url=${encodeURIComponent(url)}` : undefined | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Parses a browser view resource URI to extract the ID and URL. | ||
| */ | ||
| export function parse(resource: URI): { id: string; url: string } | undefined { | ||
| if (resource.scheme !== scheme) { | ||
| return undefined; | ||
| } | ||
|
|
||
| // Remove leading slash if present | ||
| const id = resource.path.startsWith('/') ? resource.path.substring(1) : resource.path; | ||
| if (!id) { | ||
| return undefined; | ||
| } | ||
|
|
||
| const url = resource.query ? new URLSearchParams(resource.query).get('url') ?? '' : ''; | ||
|
|
||
| return { id, url }; | ||
| } | ||
|
|
||
| /** | ||
| * Extracts the ID from a browser view resource URI. | ||
| */ | ||
| export function getId(resource: URI): string | undefined { | ||
| return parse(resource)?.id; | ||
| } | ||
|
|
||
| /** | ||
| * Extracts the URL from a browser view resource URI. | ||
| */ | ||
| export function getUrl(resource: URI): string | undefined { | ||
| return parse(resource)?.url; | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for such a low level change, it'd be good to have a test.