diff --git a/src/vs/workbench/contrib/browserView/electron-browser/browserEditor.ts b/src/vs/workbench/contrib/browserView/electron-browser/browserEditor.ts index 004f4829eb9..9f4bfff07a6 100644 --- a/src/vs/workbench/contrib/browserView/electron-browser/browserEditor.ts +++ b/src/vs/workbench/contrib/browserView/electron-browser/browserEditor.ts @@ -49,10 +49,8 @@ import { ILayoutService } from '../../../../platform/layout/browser/layoutServic export const CONTEXT_BROWSER_CAN_GO_BACK = new RawContextKey('browserCanGoBack', false, localize('browser.canGoBack', "Whether the browser can go back")); export const CONTEXT_BROWSER_CAN_GO_FORWARD = new RawContextKey('browserCanGoForward', false, localize('browser.canGoForward', "Whether the browser can go forward")); export const CONTEXT_BROWSER_FOCUSED = new RawContextKey('browserFocused', true, localize('browser.editorFocused', "Whether the browser editor is focused")); -export const CONTEXT_BROWSER_STORAGE_SCOPE = new RawContextKey('browserStorageScope', '', localize('browser.storageScope', "The storage scope of the current browser view")); export const CONTEXT_BROWSER_HAS_URL = new RawContextKey('browserHasUrl', false, localize('browser.hasUrl', "Whether the browser has a URL loaded")); export const CONTEXT_BROWSER_HAS_ERROR = new RawContextKey('browserHasError', false, localize('browser.hasError', "Whether the browser has a load error")); -export const CONTEXT_BROWSER_DEVTOOLS_OPEN = new RawContextKey('browserDevToolsOpen', false, localize('browser.devToolsOpen', "Whether developer tools are open for the current browser view")); // Re-export find widget context keys for use in actions export { CONTEXT_BROWSER_FIND_WIDGET_FOCUSED, CONTEXT_BROWSER_FIND_WIDGET_VISIBLE }; @@ -360,10 +358,8 @@ export class BrowserEditor extends EditorPane { private _findWidget!: Lazy; private _canGoBackContext!: IContextKey; private _canGoForwardContext!: IContextKey; - private _storageScopeContext!: IContextKey; private _hasUrlContext!: IContextKey; private _hasErrorContext!: IContextKey; - private _devToolsOpenContext!: IContextKey; private readonly _inputDisposables = this._register(new DisposableStore()); private overlayManager: BrowserOverlayManager | undefined; @@ -395,10 +391,8 @@ export class BrowserEditor extends EditorPane { // Bind navigation capability context keys this._canGoBackContext = CONTEXT_BROWSER_CAN_GO_BACK.bindTo(contextKeyService); this._canGoForwardContext = CONTEXT_BROWSER_CAN_GO_FORWARD.bindTo(contextKeyService); - this._storageScopeContext = CONTEXT_BROWSER_STORAGE_SCOPE.bindTo(contextKeyService); this._hasUrlContext = CONTEXT_BROWSER_HAS_URL.bindTo(contextKeyService); this._hasErrorContext = CONTEXT_BROWSER_HAS_ERROR.bindTo(contextKeyService); - this._devToolsOpenContext = CONTEXT_BROWSER_DEVTOOLS_OPEN.bindTo(contextKeyService); // Currently this is always true since it is scoped to the editor container CONTEXT_BROWSER_FOCUSED.bindTo(contextKeyService); @@ -533,9 +527,6 @@ export class BrowserEditor extends EditorPane { this._model = model; this._onDidChangeModel.fire(model); - this._storageScopeContext.set(this._model.storageScope); - this._devToolsOpenContext.set(this._model.isDevToolsOpen); - // Update find widget with new model this._findWidget.rawValue?.setModel(this._model); @@ -578,10 +569,6 @@ export class BrowserEditor extends EditorPane { } })); - this._inputDisposables.add(this._model.onDidChangeDevToolsState(e => { - this._devToolsOpenContext.set(e.isDevToolsOpen); - })); - this._inputDisposables.add(this._model.onDidRequestNewPage(({ resource, url, location, position }) => { logBrowserOpen(this.telemetryService, (() => { switch (location) { @@ -1104,8 +1091,6 @@ export class BrowserEditor extends EditorPane { this._canGoForwardContext.reset(); this._hasUrlContext.reset(); this._hasErrorContext.reset(); - this._storageScopeContext.reset(); - this._devToolsOpenContext.reset(); this._navigationBar.clear(); this.setBackgroundImage(undefined); diff --git a/src/vs/workbench/contrib/browserView/electron-browser/browserView.contribution.ts b/src/vs/workbench/contrib/browserView/electron-browser/browserView.contribution.ts index ff65b1dd6a8..f0fd9ca1d74 100644 --- a/src/vs/workbench/contrib/browserView/electron-browser/browserView.contribution.ts +++ b/src/vs/workbench/contrib/browserView/electron-browser/browserView.contribution.ts @@ -13,18 +13,17 @@ import { BrowserEditorInput, BrowserEditorSerializer } from '../common/browserEd import { BrowserViewUri } from '../../../../platform/browserView/common/browserViewUri.js'; import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js'; -import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from '../../../../platform/configuration/common/configurationRegistry.js'; -import { workbenchConfigurationNodeBase } from '../../../common/configuration.js'; import { IEditorResolverService, RegisteredEditorPriority } from '../../../services/editor/common/editorResolverService.js'; import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js'; import { Schemas } from '../../../../base/common/network.js'; import { IBrowserViewCDPService, IBrowserViewWorkbenchService } from '../common/browserView.js'; import { BrowserViewWorkbenchService } from './browserViewWorkbenchService.js'; import { BrowserViewCDPService } from './browserViewCDPService.js'; -import { BrowserViewStorageScope } from '../../../../platform/browserView/common/browserView.js'; // Register actions and browser features import './browserViewActions.js'; +import './features/browserDataStorageFeatures.js'; +import './features/browserDevToolsFeature.js'; import './features/browserEditorChatFeatures.js'; import './features/browserEditorZoomFeature.js'; import './features/browserTabManagementFeatures.js'; @@ -96,30 +95,3 @@ registerWorkbenchContribution2(BrowserEditorResolverContribution.ID, BrowserEdit registerSingleton(IBrowserViewWorkbenchService, BrowserViewWorkbenchService, InstantiationType.Delayed); registerSingleton(IBrowserViewCDPService, BrowserViewCDPService, InstantiationType.Delayed); - -Registry.as(ConfigurationExtensions.Configuration).registerConfiguration({ - ...workbenchConfigurationNodeBase, - properties: { - 'workbench.browser.dataStorage': { - type: 'string', - enum: [ - BrowserViewStorageScope.Global, - BrowserViewStorageScope.Workspace, - BrowserViewStorageScope.Ephemeral - ], - markdownEnumDescriptions: [ - localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'browser.dataStorage.global' }, 'All browser views share a single persistent session across all workspaces.'), - localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'browser.dataStorage.workspace' }, 'Browser views within the same workspace share a persistent session. If no workspace is opened, `ephemeral` storage is used.'), - localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'browser.dataStorage.ephemeral' }, 'Each browser view has its own session that is cleaned up when closed.') - ], - restricted: true, - default: BrowserViewStorageScope.Global, - markdownDescription: localize( - { comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'browser.dataStorage' }, - 'Controls how browser data (cookies, cache, storage) is shared between browser views.\n\n**Note**: In untrusted workspaces, this setting is ignored and `ephemeral` storage is always used.' - ), - scope: ConfigurationScope.WINDOW, - order: 100 - } - } -}); diff --git a/src/vs/workbench/contrib/browserView/electron-browser/browserViewActions.ts b/src/vs/workbench/contrib/browserView/electron-browser/browserViewActions.ts index 04a101b58b3..9a9f4b2d754 100644 --- a/src/vs/workbench/contrib/browserView/electron-browser/browserViewActions.ts +++ b/src/vs/workbench/contrib/browserView/electron-browser/browserViewActions.ts @@ -11,9 +11,8 @@ import { KeybindingWeight } from '../../../../platform/keybinding/common/keybind import { KeyMod, KeyCode } from '../../../../base/common/keyCodes.js'; import { IEditorService } from '../../../services/editor/common/editorService.js'; import { Codicon } from '../../../../base/common/codicons.js'; -import { BrowserEditor, CONTEXT_BROWSER_CAN_GO_BACK, CONTEXT_BROWSER_CAN_GO_FORWARD, CONTEXT_BROWSER_DEVTOOLS_OPEN, CONTEXT_BROWSER_FOCUSED, CONTEXT_BROWSER_HAS_ERROR, CONTEXT_BROWSER_HAS_URL, CONTEXT_BROWSER_STORAGE_SCOPE, CONTEXT_BROWSER_FIND_WIDGET_FOCUSED, CONTEXT_BROWSER_FIND_WIDGET_VISIBLE } from './browserEditor.js'; -import { IBrowserViewWorkbenchService } from '../common/browserView.js'; -import { BrowserViewCommandId, BrowserViewStorageScope } from '../../../../platform/browserView/common/browserView.js'; +import { BrowserEditor, CONTEXT_BROWSER_CAN_GO_BACK, CONTEXT_BROWSER_CAN_GO_FORWARD, CONTEXT_BROWSER_FOCUSED, CONTEXT_BROWSER_HAS_ERROR, CONTEXT_BROWSER_HAS_URL, CONTEXT_BROWSER_FIND_WIDGET_FOCUSED, CONTEXT_BROWSER_FIND_WIDGET_VISIBLE } from './browserEditor.js'; +import { BrowserViewCommandId } from '../../../../platform/browserView/common/browserView.js'; import { IOpenerService } from '../../../../platform/opener/common/opener.js'; import { IPreferencesService } from '../../../services/preferences/common/preferences.js'; import { BrowserEditorInput } from '../common/browserEditorInput.js'; @@ -183,37 +182,6 @@ class FocusUrlInputAction extends Action2 { } } -class ToggleDevToolsAction extends Action2 { - static readonly ID = BrowserViewCommandId.ToggleDevTools; - - constructor() { - super({ - id: ToggleDevToolsAction.ID, - title: localize2('browser.toggleDevToolsAction', 'Toggle Developer Tools'), - category: BrowserActionCategory, - icon: Codicon.terminal, - f1: true, - precondition: ContextKeyExpr.and(BROWSER_EDITOR_ACTIVE, CONTEXT_BROWSER_HAS_URL, CONTEXT_BROWSER_HAS_ERROR.negate()), - toggled: ContextKeyExpr.equals(CONTEXT_BROWSER_DEVTOOLS_OPEN.key, true), - menu: { - id: MenuId.BrowserActionsToolbar, - group: 'actions', - order: 3, - }, - keybinding: { - weight: KeybindingWeight.WorkbenchContrib, - primary: KeyCode.F12 - } - }); - } - - async run(accessor: ServicesAccessor, browserEditor = accessor.get(IEditorService).activeEditorPane): Promise { - if (browserEditor instanceof BrowserEditor) { - await browserEditor.toggleDevTools(); - } - } -} - class OpenInExternalBrowserAction extends Action2 { static readonly ID = BrowserViewCommandId.OpenExternal; @@ -250,83 +218,6 @@ class OpenInExternalBrowserAction extends Action2 { } } -class ClearGlobalBrowserStorageAction extends Action2 { - static readonly ID = BrowserViewCommandId.ClearGlobalStorage; - - constructor() { - super({ - id: ClearGlobalBrowserStorageAction.ID, - title: localize2('browser.clearGlobalStorageAction', 'Clear Storage (Global)'), - category: BrowserActionCategory, - icon: Codicon.clearAll, - f1: true, - menu: { - id: MenuId.BrowserActionsToolbar, - group: BrowserActionGroup.Settings, - order: 1, - when: ContextKeyExpr.equals(CONTEXT_BROWSER_STORAGE_SCOPE.key, BrowserViewStorageScope.Global) - } - }); - } - - async run(accessor: ServicesAccessor): Promise { - const browserViewWorkbenchService = accessor.get(IBrowserViewWorkbenchService); - await browserViewWorkbenchService.clearGlobalStorage(); - } -} - -class ClearWorkspaceBrowserStorageAction extends Action2 { - static readonly ID = BrowserViewCommandId.ClearWorkspaceStorage; - - constructor() { - super({ - id: ClearWorkspaceBrowserStorageAction.ID, - title: localize2('browser.clearWorkspaceStorageAction', 'Clear Storage (Workspace)'), - category: BrowserActionCategory, - icon: Codicon.clearAll, - f1: true, - menu: { - id: MenuId.BrowserActionsToolbar, - group: BrowserActionGroup.Settings, - order: 1, - when: ContextKeyExpr.equals(CONTEXT_BROWSER_STORAGE_SCOPE.key, BrowserViewStorageScope.Workspace) - } - }); - } - - async run(accessor: ServicesAccessor): Promise { - const browserViewWorkbenchService = accessor.get(IBrowserViewWorkbenchService); - await browserViewWorkbenchService.clearWorkspaceStorage(); - } -} - -class ClearEphemeralBrowserStorageAction extends Action2 { - static readonly ID = BrowserViewCommandId.ClearEphemeralStorage; - - constructor() { - super({ - id: ClearEphemeralBrowserStorageAction.ID, - title: localize2('browser.clearEphemeralStorageAction', 'Clear Storage (Ephemeral)'), - category: BrowserActionCategory, - icon: Codicon.clearAll, - f1: true, - precondition: ContextKeyExpr.equals(CONTEXT_BROWSER_STORAGE_SCOPE.key, BrowserViewStorageScope.Ephemeral), - menu: { - id: MenuId.BrowserActionsToolbar, - group: BrowserActionGroup.Settings, - order: 1, - when: ContextKeyExpr.equals(CONTEXT_BROWSER_STORAGE_SCOPE.key, BrowserViewStorageScope.Ephemeral) - } - }); - } - - async run(accessor: ServicesAccessor, browserEditor = accessor.get(IEditorService).activeEditorPane): Promise { - if (browserEditor instanceof BrowserEditor) { - await browserEditor.clearStorage(); - } - } -} - class OpenBrowserSettingsAction extends Action2 { static readonly ID = BrowserViewCommandId.OpenSettings; @@ -474,13 +365,11 @@ registerAction2(GoBackAction); registerAction2(GoForwardAction); registerAction2(ReloadAction); registerAction2(HardReloadAction); + registerAction2(FocusUrlInputAction); -registerAction2(ToggleDevToolsAction); registerAction2(OpenInExternalBrowserAction); -registerAction2(ClearGlobalBrowserStorageAction); -registerAction2(ClearWorkspaceBrowserStorageAction); -registerAction2(ClearEphemeralBrowserStorageAction); registerAction2(OpenBrowserSettingsAction); + registerAction2(ShowBrowserFindAction); registerAction2(HideBrowserFindAction); registerAction2(BrowserFindNextAction); diff --git a/src/vs/workbench/contrib/browserView/electron-browser/features/browserDataStorageFeatures.ts b/src/vs/workbench/contrib/browserView/electron-browser/features/browserDataStorageFeatures.ts new file mode 100644 index 00000000000..d3ecac788fc --- /dev/null +++ b/src/vs/workbench/contrib/browserView/electron-browser/features/browserDataStorageFeatures.ts @@ -0,0 +1,151 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize, localize2 } from '../../../../../nls.js'; +import { Registry } from '../../../../../platform/registry/common/platform.js'; +import { BrowserEditor, BrowserEditorContribution } from '../browserEditor.js'; +import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from '../../../../../platform/configuration/common/configurationRegistry.js'; +import { workbenchConfigurationNodeBase } from '../../../../common/configuration.js'; +import { IBrowserViewModel, IBrowserViewWorkbenchService } from '../../common/browserView.js'; +import { BrowserViewCommandId, BrowserViewStorageScope } from '../../../../../platform/browserView/common/browserView.js'; +import { IContextKey, IContextKeyService, ContextKeyExpr, RawContextKey } from '../../../../../platform/contextkey/common/contextkey.js'; +import { Action2, registerAction2, MenuId } from '../../../../../platform/actions/common/actions.js'; +import { IEditorService } from '../../../../services/editor/common/editorService.js'; +import { Codicon } from '../../../../../base/common/codicons.js'; +import { BrowserActionCategory, BrowserActionGroup } from '../browserViewActions.js'; +import type { ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js'; +import { DisposableStore } from '../../../../../base/common/lifecycle.js'; + +const CONTEXT_BROWSER_STORAGE_SCOPE = new RawContextKey('browserStorageScope', '', localize('browser.storageScope', "The storage scope of the current browser view")); + +class BrowserEditorStorageScopeContribution extends BrowserEditorContribution { + private readonly _storageScopeContext: IContextKey; + + constructor( + editor: BrowserEditor, + @IContextKeyService contextKeyService: IContextKeyService, + ) { + super(editor); + this._storageScopeContext = CONTEXT_BROWSER_STORAGE_SCOPE.bindTo(contextKeyService); + } + + protected override subscribeToModel(model: IBrowserViewModel, _store: DisposableStore): void { + this._storageScopeContext.set(model.storageScope); + } + + override clear(): void { + this._storageScopeContext.reset(); + } +} + +BrowserEditor.registerContribution(BrowserEditorStorageScopeContribution); + +class ClearGlobalBrowserStorageAction extends Action2 { + static readonly ID = BrowserViewCommandId.ClearGlobalStorage; + + constructor() { + super({ + id: ClearGlobalBrowserStorageAction.ID, + title: localize2('browser.clearGlobalStorageAction', 'Clear Storage (Global)'), + category: BrowserActionCategory, + icon: Codicon.clearAll, + f1: true, + menu: { + id: MenuId.BrowserActionsToolbar, + group: BrowserActionGroup.Settings, + order: 1, + when: ContextKeyExpr.equals(CONTEXT_BROWSER_STORAGE_SCOPE.key, BrowserViewStorageScope.Global) + } + }); + } + + async run(accessor: ServicesAccessor): Promise { + const browserViewWorkbenchService = accessor.get(IBrowserViewWorkbenchService); + await browserViewWorkbenchService.clearGlobalStorage(); + } +} + +class ClearWorkspaceBrowserStorageAction extends Action2 { + static readonly ID = BrowserViewCommandId.ClearWorkspaceStorage; + + constructor() { + super({ + id: ClearWorkspaceBrowserStorageAction.ID, + title: localize2('browser.clearWorkspaceStorageAction', 'Clear Storage (Workspace)'), + category: BrowserActionCategory, + icon: Codicon.clearAll, + f1: true, + menu: { + id: MenuId.BrowserActionsToolbar, + group: BrowserActionGroup.Settings, + order: 1, + when: ContextKeyExpr.equals(CONTEXT_BROWSER_STORAGE_SCOPE.key, BrowserViewStorageScope.Workspace) + } + }); + } + + async run(accessor: ServicesAccessor): Promise { + const browserViewWorkbenchService = accessor.get(IBrowserViewWorkbenchService); + await browserViewWorkbenchService.clearWorkspaceStorage(); + } +} + +class ClearEphemeralBrowserStorageAction extends Action2 { + static readonly ID = BrowserViewCommandId.ClearEphemeralStorage; + + constructor() { + super({ + id: ClearEphemeralBrowserStorageAction.ID, + title: localize2('browser.clearEphemeralStorageAction', 'Clear Storage (Ephemeral)'), + category: BrowserActionCategory, + icon: Codicon.clearAll, + f1: true, + precondition: ContextKeyExpr.equals(CONTEXT_BROWSER_STORAGE_SCOPE.key, BrowserViewStorageScope.Ephemeral), + menu: { + id: MenuId.BrowserActionsToolbar, + group: BrowserActionGroup.Settings, + order: 1, + when: ContextKeyExpr.equals(CONTEXT_BROWSER_STORAGE_SCOPE.key, BrowserViewStorageScope.Ephemeral) + } + }); + } + + async run(accessor: ServicesAccessor, browserEditor = accessor.get(IEditorService).activeEditorPane): Promise { + if (browserEditor instanceof BrowserEditor) { + await browserEditor.clearStorage(); + } + } +} + +registerAction2(ClearGlobalBrowserStorageAction); +registerAction2(ClearWorkspaceBrowserStorageAction); +registerAction2(ClearEphemeralBrowserStorageAction); + +Registry.as(ConfigurationExtensions.Configuration).registerConfiguration({ + ...workbenchConfigurationNodeBase, + properties: { + 'workbench.browser.dataStorage': { + type: 'string', + enum: [ + BrowserViewStorageScope.Global, + BrowserViewStorageScope.Workspace, + BrowserViewStorageScope.Ephemeral + ], + markdownEnumDescriptions: [ + localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'browser.dataStorage.global' }, 'All browser views share a single persistent session across all workspaces.'), + localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'browser.dataStorage.workspace' }, 'Browser views within the same workspace share a persistent session. If no workspace is opened, `ephemeral` storage is used.'), + localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'browser.dataStorage.ephemeral' }, 'Each browser view has its own session that is cleaned up when closed.') + ], + restricted: true, + default: BrowserViewStorageScope.Global, + markdownDescription: localize( + { comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'browser.dataStorage' }, + 'Controls how browser data (cookies, cache, storage) is shared between browser views.\n\n**Note**: In untrusted workspaces, this setting is ignored and `ephemeral` storage is always used.' + ), + scope: ConfigurationScope.WINDOW, + order: 100 + } + } +}); diff --git a/src/vs/workbench/contrib/browserView/electron-browser/features/browserDevToolsFeature.ts b/src/vs/workbench/contrib/browserView/electron-browser/features/browserDevToolsFeature.ts new file mode 100644 index 00000000000..c22809d56ee --- /dev/null +++ b/src/vs/workbench/contrib/browserView/electron-browser/features/browserDevToolsFeature.ts @@ -0,0 +1,78 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { localize, localize2 } from '../../../../../nls.js'; +import { DisposableStore } from '../../../../../base/common/lifecycle.js'; +import { Codicon } from '../../../../../base/common/codicons.js'; +import { KeyCode } from '../../../../../base/common/keyCodes.js'; +import { RawContextKey, IContextKey, IContextKeyService, ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js'; +import { Action2, registerAction2, MenuId } from '../../../../../platform/actions/common/actions.js'; +import { ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js'; +import { KeybindingWeight } from '../../../../../platform/keybinding/common/keybindingsRegistry.js'; +import { BrowserViewCommandId } from '../../../../../platform/browserView/common/browserView.js'; +import { IEditorService } from '../../../../services/editor/common/editorService.js'; +import { IBrowserViewModel } from '../../common/browserView.js'; +import { BrowserEditor, BrowserEditorContribution, CONTEXT_BROWSER_HAS_ERROR, CONTEXT_BROWSER_HAS_URL } from '../browserEditor.js'; +import { BROWSER_EDITOR_ACTIVE, BrowserActionCategory } from '../browserViewActions.js'; + +const CONTEXT_BROWSER_DEVTOOLS_OPEN = new RawContextKey('browserDevToolsOpen', false, localize('browser.devToolsOpen', "Whether developer tools are open for the current browser view")); + +class BrowserEditorDevToolsContribution extends BrowserEditorContribution { + private readonly _devToolsOpenContext: IContextKey; + + constructor( + editor: BrowserEditor, + @IContextKeyService contextKeyService: IContextKeyService, + ) { + super(editor); + this._devToolsOpenContext = CONTEXT_BROWSER_DEVTOOLS_OPEN.bindTo(contextKeyService); + } + + protected override subscribeToModel(model: IBrowserViewModel, store: DisposableStore): void { + this._devToolsOpenContext.set(model.isDevToolsOpen); + store.add(model.onDidChangeDevToolsState(e => { + this._devToolsOpenContext.set(e.isDevToolsOpen); + })); + } + + override clear(): void { + this._devToolsOpenContext.reset(); + } +} + +BrowserEditor.registerContribution(BrowserEditorDevToolsContribution); + +class ToggleDevToolsAction extends Action2 { + static readonly ID = BrowserViewCommandId.ToggleDevTools; + + constructor() { + super({ + id: ToggleDevToolsAction.ID, + title: localize2('browser.toggleDevToolsAction', 'Toggle Developer Tools'), + category: BrowserActionCategory, + icon: Codicon.terminal, + f1: true, + precondition: ContextKeyExpr.and(BROWSER_EDITOR_ACTIVE, CONTEXT_BROWSER_HAS_URL, CONTEXT_BROWSER_HAS_ERROR.negate()), + toggled: ContextKeyExpr.equals(CONTEXT_BROWSER_DEVTOOLS_OPEN.key, true), + menu: { + id: MenuId.BrowserActionsToolbar, + group: 'actions', + order: 3, + }, + keybinding: { + weight: KeybindingWeight.WorkbenchContrib, + primary: KeyCode.F12 + } + }); + } + + async run(accessor: ServicesAccessor, browserEditor = accessor.get(IEditorService).activeEditorPane): Promise { + if (browserEditor instanceof BrowserEditor) { + await browserEditor.toggleDevTools(); + } + } +} + +registerAction2(ToggleDevToolsAction); diff --git a/src/vs/workbench/contrib/browserView/electron-browser/features/browserEditorChatFeatures.ts b/src/vs/workbench/contrib/browserView/electron-browser/features/browserEditorChatFeatures.ts index 793dcc0a2e8..f962e57395f 100644 --- a/src/vs/workbench/contrib/browserView/electron-browser/features/browserEditorChatFeatures.ts +++ b/src/vs/workbench/contrib/browserView/electron-browser/features/browserEditorChatFeatures.ts @@ -45,7 +45,7 @@ import { BrowserActionCategory } from '../browserViewActions.js'; const BROWSER_EDITOR_ACTIVE = ContextKeyExpr.equals('activeEditor', BrowserEditorInput.EDITOR_ID); const BrowserCategory = localize2('browserCategory', "Browser"); -export const CONTEXT_BROWSER_ELEMENT_SELECTION_ACTIVE = new RawContextKey('browserElementSelectionActive', false, localize('browser.elementSelectionActive', "Whether element selection is currently active")); +const CONTEXT_BROWSER_ELEMENT_SELECTION_ACTIVE = new RawContextKey('browserElementSelectionActive', false, localize('browser.elementSelectionActive', "Whether element selection is currently active")); const canShareBrowserWithAgentContext = ContextKeyExpr.and( ChatContextKeys.enabled, diff --git a/src/vs/workbench/contrib/browserView/electron-browser/features/browserEditorZoomFeature.ts b/src/vs/workbench/contrib/browserView/electron-browser/features/browserEditorZoomFeature.ts index 881467ec8e7..a527d8ab6c4 100644 --- a/src/vs/workbench/contrib/browserView/electron-browser/features/browserEditorZoomFeature.ts +++ b/src/vs/workbench/contrib/browserView/electron-browser/features/browserEditorZoomFeature.ts @@ -30,8 +30,8 @@ import { InstantiationType, registerSingleton } from '../../../../../platform/in import { workbenchConfigurationNodeBase } from '../../../../common/configuration.js'; import { Registry } from '../../../../../platform/registry/common/platform.js'; -export const CONTEXT_BROWSER_CAN_ZOOM_IN = new RawContextKey('browserCanZoomIn', true, localize('browser.canZoomIn', "Whether the browser can zoom in further")); -export const CONTEXT_BROWSER_CAN_ZOOM_OUT = new RawContextKey('browserCanZoomOut', true, localize('browser.canZoomOut', "Whether the browser can zoom out further")); +const CONTEXT_BROWSER_CAN_ZOOM_IN = new RawContextKey('browserCanZoomIn', true, localize('browser.canZoomIn', "Whether the browser can zoom in further")); +const CONTEXT_BROWSER_CAN_ZOOM_OUT = new RawContextKey('browserCanZoomOut', true, localize('browser.canZoomOut', "Whether the browser can zoom out further")); /** * Transient zoom-level indicator that briefly appears inside the URL bar on zoom changes. diff --git a/src/vs/workbench/contrib/browserView/electron-browser/features/browserTabManagementFeatures.ts b/src/vs/workbench/contrib/browserView/electron-browser/features/browserTabManagementFeatures.ts index 3f2e4e6365e..dc391f59251 100644 --- a/src/vs/workbench/contrib/browserView/electron-browser/features/browserTabManagementFeatures.ts +++ b/src/vs/workbench/contrib/browserView/electron-browser/features/browserTabManagementFeatures.ts @@ -34,7 +34,7 @@ import { CancellationToken } from '../../../../../base/common/cancellation.js'; import { ToggleTitleBarConfigAction } from '../../../../browser/parts/titlebar/titlebarActions.js'; import { Registry } from '../../../../../platform/registry/common/platform.js'; -export const CONTEXT_BROWSER_EDITOR_OPEN = new RawContextKey('browserEditorOpen', false, localize('browser.editorOpen', "Whether any browser editor is currently open")); +const CONTEXT_BROWSER_EDITOR_OPEN = new RawContextKey('browserEditorOpen', false, localize('browser.editorOpen', "Whether any browser editor is currently open")); interface IBrowserQuickPickItem extends IQuickPickItem { groupId: GroupIdentifier;