From 36a5ff6433a140105add1c2b109e6d3cd0604e36 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 May 2024 10:05:16 +0200 Subject: [PATCH 01/30] adding code in order to provide accessibility help for the hover --- .../browser/contentHoverAccessibilityHelp.ts | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/vs/editor/contrib/hover/browser/contentHoverAccessibilityHelp.ts diff --git a/src/vs/editor/contrib/hover/browser/contentHoverAccessibilityHelp.ts b/src/vs/editor/contrib/hover/browser/contentHoverAccessibilityHelp.ts new file mode 100644 index 0000000000000..6844ad5c378f2 --- /dev/null +++ b/src/vs/editor/contrib/hover/browser/contentHoverAccessibilityHelp.ts @@ -0,0 +1,108 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable } from 'vs/base/common/lifecycle'; +import { format } from 'vs/base/common/strings'; +import { localize } from 'vs/nls'; +import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; +import { ICommandService } from 'vs/platform/commands/common/commands'; +import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { ShellIntegrationStatus, TerminalSettingId, WindowsShellType } from 'vs/platform/terminal/common/terminal'; +import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands'; +import { ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; +import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; +import type { Terminal } from '@xterm/xterm'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { TerminalAccessibilitySettingId } from 'vs/workbench/contrib/terminalContrib/accessibility/common/terminalAccessibilityConfiguration'; +import { TerminalAccessibilityCommandId } from 'vs/workbench/contrib/terminalContrib/accessibility/common/terminal.accessibility'; +import { TerminalLinksCommandId } from 'vs/workbench/contrib/terminalContrib/links/common/terminal.links'; +import { IAccessibleViewContentProvider, AccessibleViewProviderId, IAccessibleViewOptions, AccessibleViewType } from 'vs/platform/accessibility/browser/accessibleView'; +import { accessibleViewIsShown, accessibleViewCurrentProviderId, AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; + +export const enum ClassName { + Active = 'active', + EditorTextArea = 'textarea' +} + +export class ContentHoverAccessibilityHelpProvider extends Disposable implements IAccessibleViewContentProvider { + id = AccessibleViewProviderId.TerminalHelp; + private readonly _hasShellIntegration: boolean = false; + onClose() { + const expr = ContextKeyExpr.and(accessibleViewIsShown, ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.TerminalHelp)); + if (expr?.evaluate(this._contextKeyService.getContext(null))) { + this._commandService.executeCommand(TerminalAccessibilityCommandId.FocusAccessibleBuffer); + } else { + this._instance.focus(); + } + this.dispose(); + } + options: IAccessibleViewOptions = { + type: AccessibleViewType.Help, + readMoreUrl: 'https://code.visualstudio.com/docs/editor/accessibility#_terminal-accessibility' + }; + verbositySettingKey = AccessibilityVerbositySettingId.Terminal; + + constructor( + private readonly _instance: Pick, + _xterm: Pick & { raw: Terminal }, + @IInstantiationService _instantiationService: IInstantiationService, + @IKeybindingService private readonly _keybindingService: IKeybindingService, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, + @ICommandService private readonly _commandService: ICommandService, + @IAccessibilityService private readonly _accessibilityService: IAccessibilityService, + @IConfigurationService private readonly _configurationService: IConfigurationService + ) { + super(); + this._hasShellIntegration = _xterm.shellIntegration.status === ShellIntegrationStatus.VSCode; + } + + private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { + if (commandId === TerminalCommandId.RunRecentCommand) { + const kb = this._keybindingService.lookupKeybindings(commandId); + // Run recent command has multiple keybindings. lookupKeybinding just returns the first one regardless of the when context. + // Thus, we have to check if accessibility mode is enabled to determine which keybinding to use. + const isScreenReaderOptimized = this._accessibilityService.isScreenReaderOptimized(); + if (isScreenReaderOptimized && kb[1]) { + format(msg, kb[1].getAriaLabel()); + } else if (kb[0]) { + format(msg, kb[0].getAriaLabel()); + } else { + return format(noKbMsg, commandId); + } + } + const kb = this._keybindingService.lookupKeybinding(commandId, this._contextKeyService)?.getAriaLabel(); + return !kb ? format(noKbMsg, commandId) : format(msg, kb); + } + + provideContent(): string { + const content = []; + content.push(this._descriptionForCommand(TerminalAccessibilityCommandId.FocusAccessibleBuffer, localize('focusAccessibleTerminalView', 'The Focus Accessible Terminal View ({0}) command enables screen readers to read terminal contents.'), localize('focusAccessibleTerminalViewNoKb', 'The Focus Terminal Accessible View command enables screen readers to read terminal contents and is currently not triggerable by a keybinding.'))); + content.push(localize('preserveCursor', 'Customize the behavior of the cursor when toggling between the terminal and accessible view with `terminal.integrated.accessibleViewPreserveCursorPosition.`')); + if (!this._configurationService.getValue(TerminalAccessibilitySettingId.AccessibleViewFocusOnCommandExecution)) { + content.push(localize('focusViewOnExecution', 'Enable `terminal.integrated.accessibleViewFocusOnCommandExecution` to automatically focus the terminal accessible view when a command is executed in the terminal.')); + } + if (this._instance.shellType === WindowsShellType.CommandPrompt) { + content.push(localize('commandPromptMigration', "Consider using powershell instead of command prompt for an improved experience")); + } + if (this._hasShellIntegration) { + const shellIntegrationCommandList = []; + shellIntegrationCommandList.push(localize('shellIntegration', "The terminal has a feature called shell integration that offers an enhanced experience and provides useful commands for screen readers such as:")); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalAccessibilityCommandId.AccessibleBufferGoToNextCommand, localize('goToNextCommand', 'Go to Next Command ({0}) in the accessible view'), localize('goToNextCommandNoKb', 'Go to Next Command in the accessible view is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalAccessibilityCommandId.AccessibleBufferGoToPreviousCommand, localize('goToPreviousCommand', 'Go to Previous Command ({0}) in the accessible view'), localize('goToPreviousCommandNoKb', 'Go to Previous Command in the accessible view is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(AccessibilityCommandId.GoToSymbol, localize('goToSymbol', 'Go to Symbol ({0})'), localize('goToSymbolNoKb', 'Go to symbol is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.RunRecentCommand, localize('runRecentCommand', 'Run Recent Command ({0})'), localize('runRecentCommandNoKb', 'Run Recent Command is currently not triggerable by a keybinding.'))); + shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.GoToRecentDirectory, localize('goToRecentDirectory', 'Go to Recent Directory ({0})'), localize('goToRecentDirectoryNoKb', 'Go to Recent Directory is currently not triggerable by a keybinding.'))); + content.push(shellIntegrationCommandList.join('\n')); + } else { + content.push(this._descriptionForCommand(TerminalCommandId.RunRecentCommand, localize('goToRecentDirectoryNoShellIntegration', 'The Go to Recent Directory command ({0}) enables screen readers to easily navigate to a directory that has been used in the terminal.'), localize('goToRecentDirectoryNoKbNoShellIntegration', 'The Go to Recent Directory command enables screen readers to easily navigate to a directory that has been used in the terminal and is currently not triggerable by a keybinding.'))); + } + content.push(this._descriptionForCommand(TerminalLinksCommandId.OpenDetectedLink, localize('openDetectedLink', 'The Open Detected Link ({0}) command enables screen readers to easily open links found in the terminal.'), localize('openDetectedLinkNoKb', 'The Open Detected Link command enables screen readers to easily open links found in the terminal and is currently not triggerable by a keybinding.'))); + content.push(this._descriptionForCommand(TerminalCommandId.NewWithProfile, localize('newWithProfile', 'The Create New Terminal (With Profile) ({0}) command allows for easy terminal creation using a specific profile.'), localize('newWithProfileNoKb', 'The Create New Terminal (With Profile) command allows for easy terminal creation using a specific profile and is currently not triggerable by a keybinding.'))); + content.push(localize('focusAfterRun', 'Configure what gets focused after running selected text in the terminal with `{0}`.', TerminalSettingId.FocusAfterRun)); + return content.join('\n\n'); + } +} From 34513de211d774ed099a8073458dd8d4de2d9036 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 May 2024 11:44:23 +0200 Subject: [PATCH 02/30] adding the description of the possible commands that can be used --- .../browser/contentHoverAccessibilityHelp.ts | 108 ------------------ .../hover/browser/contentHoverController.ts | 4 + .../hover/browser/hoverAccessibleViews.ts | 100 ++++++++++++---- .../contrib/hover/browser/hoverController.ts | 4 + .../hover/browser/markdownHoverParticipant.ts | 13 +++ 5 files changed, 100 insertions(+), 129 deletions(-) delete mode 100644 src/vs/editor/contrib/hover/browser/contentHoverAccessibilityHelp.ts diff --git a/src/vs/editor/contrib/hover/browser/contentHoverAccessibilityHelp.ts b/src/vs/editor/contrib/hover/browser/contentHoverAccessibilityHelp.ts deleted file mode 100644 index 6844ad5c378f2..0000000000000 --- a/src/vs/editor/contrib/hover/browser/contentHoverAccessibilityHelp.ts +++ /dev/null @@ -1,108 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { Disposable } from 'vs/base/common/lifecycle'; -import { format } from 'vs/base/common/strings'; -import { localize } from 'vs/nls'; -import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; -import { ICommandService } from 'vs/platform/commands/common/commands'; -import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; -import { ShellIntegrationStatus, TerminalSettingId, WindowsShellType } from 'vs/platform/terminal/common/terminal'; -import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands'; -import { ITerminalInstance, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal'; -import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal'; -import type { Terminal } from '@xterm/xterm'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { TerminalAccessibilitySettingId } from 'vs/workbench/contrib/terminalContrib/accessibility/common/terminalAccessibilityConfiguration'; -import { TerminalAccessibilityCommandId } from 'vs/workbench/contrib/terminalContrib/accessibility/common/terminal.accessibility'; -import { TerminalLinksCommandId } from 'vs/workbench/contrib/terminalContrib/links/common/terminal.links'; -import { IAccessibleViewContentProvider, AccessibleViewProviderId, IAccessibleViewOptions, AccessibleViewType } from 'vs/platform/accessibility/browser/accessibleView'; -import { accessibleViewIsShown, accessibleViewCurrentProviderId, AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; - -export const enum ClassName { - Active = 'active', - EditorTextArea = 'textarea' -} - -export class ContentHoverAccessibilityHelpProvider extends Disposable implements IAccessibleViewContentProvider { - id = AccessibleViewProviderId.TerminalHelp; - private readonly _hasShellIntegration: boolean = false; - onClose() { - const expr = ContextKeyExpr.and(accessibleViewIsShown, ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.TerminalHelp)); - if (expr?.evaluate(this._contextKeyService.getContext(null))) { - this._commandService.executeCommand(TerminalAccessibilityCommandId.FocusAccessibleBuffer); - } else { - this._instance.focus(); - } - this.dispose(); - } - options: IAccessibleViewOptions = { - type: AccessibleViewType.Help, - readMoreUrl: 'https://code.visualstudio.com/docs/editor/accessibility#_terminal-accessibility' - }; - verbositySettingKey = AccessibilityVerbositySettingId.Terminal; - - constructor( - private readonly _instance: Pick, - _xterm: Pick & { raw: Terminal }, - @IInstantiationService _instantiationService: IInstantiationService, - @IKeybindingService private readonly _keybindingService: IKeybindingService, - @IContextKeyService private readonly _contextKeyService: IContextKeyService, - @ICommandService private readonly _commandService: ICommandService, - @IAccessibilityService private readonly _accessibilityService: IAccessibilityService, - @IConfigurationService private readonly _configurationService: IConfigurationService - ) { - super(); - this._hasShellIntegration = _xterm.shellIntegration.status === ShellIntegrationStatus.VSCode; - } - - private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { - if (commandId === TerminalCommandId.RunRecentCommand) { - const kb = this._keybindingService.lookupKeybindings(commandId); - // Run recent command has multiple keybindings. lookupKeybinding just returns the first one regardless of the when context. - // Thus, we have to check if accessibility mode is enabled to determine which keybinding to use. - const isScreenReaderOptimized = this._accessibilityService.isScreenReaderOptimized(); - if (isScreenReaderOptimized && kb[1]) { - format(msg, kb[1].getAriaLabel()); - } else if (kb[0]) { - format(msg, kb[0].getAriaLabel()); - } else { - return format(noKbMsg, commandId); - } - } - const kb = this._keybindingService.lookupKeybinding(commandId, this._contextKeyService)?.getAriaLabel(); - return !kb ? format(noKbMsg, commandId) : format(msg, kb); - } - - provideContent(): string { - const content = []; - content.push(this._descriptionForCommand(TerminalAccessibilityCommandId.FocusAccessibleBuffer, localize('focusAccessibleTerminalView', 'The Focus Accessible Terminal View ({0}) command enables screen readers to read terminal contents.'), localize('focusAccessibleTerminalViewNoKb', 'The Focus Terminal Accessible View command enables screen readers to read terminal contents and is currently not triggerable by a keybinding.'))); - content.push(localize('preserveCursor', 'Customize the behavior of the cursor when toggling between the terminal and accessible view with `terminal.integrated.accessibleViewPreserveCursorPosition.`')); - if (!this._configurationService.getValue(TerminalAccessibilitySettingId.AccessibleViewFocusOnCommandExecution)) { - content.push(localize('focusViewOnExecution', 'Enable `terminal.integrated.accessibleViewFocusOnCommandExecution` to automatically focus the terminal accessible view when a command is executed in the terminal.')); - } - if (this._instance.shellType === WindowsShellType.CommandPrompt) { - content.push(localize('commandPromptMigration', "Consider using powershell instead of command prompt for an improved experience")); - } - if (this._hasShellIntegration) { - const shellIntegrationCommandList = []; - shellIntegrationCommandList.push(localize('shellIntegration', "The terminal has a feature called shell integration that offers an enhanced experience and provides useful commands for screen readers such as:")); - shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalAccessibilityCommandId.AccessibleBufferGoToNextCommand, localize('goToNextCommand', 'Go to Next Command ({0}) in the accessible view'), localize('goToNextCommandNoKb', 'Go to Next Command in the accessible view is currently not triggerable by a keybinding.'))); - shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalAccessibilityCommandId.AccessibleBufferGoToPreviousCommand, localize('goToPreviousCommand', 'Go to Previous Command ({0}) in the accessible view'), localize('goToPreviousCommandNoKb', 'Go to Previous Command in the accessible view is currently not triggerable by a keybinding.'))); - shellIntegrationCommandList.push('- ' + this._descriptionForCommand(AccessibilityCommandId.GoToSymbol, localize('goToSymbol', 'Go to Symbol ({0})'), localize('goToSymbolNoKb', 'Go to symbol is currently not triggerable by a keybinding.'))); - shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.RunRecentCommand, localize('runRecentCommand', 'Run Recent Command ({0})'), localize('runRecentCommandNoKb', 'Run Recent Command is currently not triggerable by a keybinding.'))); - shellIntegrationCommandList.push('- ' + this._descriptionForCommand(TerminalCommandId.GoToRecentDirectory, localize('goToRecentDirectory', 'Go to Recent Directory ({0})'), localize('goToRecentDirectoryNoKb', 'Go to Recent Directory is currently not triggerable by a keybinding.'))); - content.push(shellIntegrationCommandList.join('\n')); - } else { - content.push(this._descriptionForCommand(TerminalCommandId.RunRecentCommand, localize('goToRecentDirectoryNoShellIntegration', 'The Go to Recent Directory command ({0}) enables screen readers to easily navigate to a directory that has been used in the terminal.'), localize('goToRecentDirectoryNoKbNoShellIntegration', 'The Go to Recent Directory command enables screen readers to easily navigate to a directory that has been used in the terminal and is currently not triggerable by a keybinding.'))); - } - content.push(this._descriptionForCommand(TerminalLinksCommandId.OpenDetectedLink, localize('openDetectedLink', 'The Open Detected Link ({0}) command enables screen readers to easily open links found in the terminal.'), localize('openDetectedLinkNoKb', 'The Open Detected Link command enables screen readers to easily open links found in the terminal and is currently not triggerable by a keybinding.'))); - content.push(this._descriptionForCommand(TerminalCommandId.NewWithProfile, localize('newWithProfile', 'The Create New Terminal (With Profile) ({0}) command allows for easy terminal creation using a specific profile.'), localize('newWithProfileNoKb', 'The Create New Terminal (With Profile) command allows for easy terminal creation using a specific profile and is currently not triggerable by a keybinding.'))); - content.push(localize('focusAfterRun', 'Configure what gets focused after running selected text in the terminal with `{0}`.', TerminalSettingId.FocusAfterRun)); - return content.join('\n\n'); - } -} diff --git a/src/vs/editor/contrib/hover/browser/contentHoverController.ts b/src/vs/editor/contrib/hover/browser/contentHoverController.ts index 20c441162b5cf..51213f8cdc67d 100644 --- a/src/vs/editor/contrib/hover/browser/contentHoverController.ts +++ b/src/vs/editor/contrib/hover/browser/contentHoverController.ts @@ -355,6 +355,10 @@ export class ContentHoverController extends Disposable implements IHoverWidget { this._markdownHoverParticipant?.updateFocusedMarkdownHoverPartVerbosityLevel(action); } + public isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action: HoverVerbosityAction): boolean { + return this._markdownHoverParticipant?.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action) ?? false; + } + public getWidgetContent(): string | undefined { const node = this._widget.getDomNode(); if (!node.textContent) { diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 557f1fffa8579..7eabcfe0c0c67 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -2,48 +2,106 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ - +import * as nls from 'vs/nls'; +import * as strings from 'vs/base/common/strings'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController'; -import { AccessibleViewType, AccessibleViewProviderId } from 'vs/platform/accessibility/browser/accessibleView'; +import { AccessibleViewType, AccessibleViewProviderId, AdvancedContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions } from 'vs/platform/accessibility/browser/accessibleView'; import { IAccessibleViewImplentation } from 'vs/platform/accessibility/browser/accessibleViewRegistry'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IHoverService } from 'vs/platform/hover/browser/hover'; -import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; +import { HoverVerbosityAction } from 'vs/editor/common/languages'; +import { INCREASE_HOVER_VERBOSITY_ACTION_ID } from 'vs/editor/contrib/hover/browser/hoverActionIds'; + +export namespace HoverAccessibilityHelpNLS { + export const intro = nls.localize('intro', `The hover widget is focused. Press the Tab key to cycle through the hover parts.`); + export const increaseVerbosity = nls.localize('increaseVerbosity', `- The current focused hover part's verbosity level can be increased ({0}).`); + export const increaseVerbosityNoKb = nls.localize('increaseVerbosityNoKb', `- The current focused hover part's verbosity level can be increased, which is currently not triggerable via keybinding.`); + export const decreaseVerbosity = nls.localize('decreaseVerbosity', `- The current focused hover part's verbosity level can be decreased ({0}).`); + export const decreaseVerbosityNoKb = nls.localize('decreaseVerbosityNoKb', `- The current focused hover part's verbosity level can be decreased, which is currently not triggerable via keybinding.`); +} export class HoverAccessibleView implements IAccessibleViewImplentation { + readonly type = AccessibleViewType.View; readonly priority = 95; readonly name = 'hover'; readonly when = EditorContextKeys.hoverFocused; - getProvider(accessor: ServicesAccessor) { - const codeEditorService = accessor.get(ICodeEditorService); - const editor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); - const editorHoverContent = editor ? HoverController.get(editor)?.getWidgetContent() ?? undefined : undefined; - if (!editor || !editorHoverContent) { + + getProvider(accessor: ServicesAccessor): AdvancedContentProvider | undefined { + return accessor.get(IInstantiationService).createInstance(HoverAccessibilityHelpProvider); + } +} + +export class HoverAccessibilityHelpProvider implements IAccessibleViewContentProvider { + + public id = AccessibleViewProviderId.Hover; + public verbositySettingKey = 'accessibility.verbosity.hover'; + public options: IAccessibleViewOptions; + + private _editor: ICodeEditor | null; + + constructor( + @ICodeEditorService private readonly _codeEditorService: ICodeEditorService, + @IKeybindingService private readonly _keybindingService: IKeybindingService + ) { + this._editor = this._codeEditorService.getActiveCodeEditor() || this._codeEditorService.getFocusedCodeEditor(); + this.options = { + language: this._editor?.getModel()?.getLanguageId() ?? 'typescript', + type: AccessibleViewType.View + } + } + + private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { + const kb = this._keybindingService.lookupKeybinding(commandId); + if (kb) { + return strings.format(msg, kb.getAriaLabel()); + } + return strings.format(noKbMsg, commandId); + } + + provideContent(): string { + + const content: string[] = []; + content.push(HoverAccessibilityHelpNLS.intro); + + if (!this._editor) { + return ''; + } + const hoverController = HoverController.get(this._editor); + if (!hoverController) { + return ''; + } + const isFocusOnExpandableMarkdownHover = hoverController.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(HoverVerbosityAction.Increase); + if (isFocusOnExpandableMarkdownHover) { + content.push(this._descriptionForCommand(INCREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.increaseVerbosity, HoverAccessibilityHelpNLS.increaseVerbosityNoKb)); + } + const isFocusOnContractableMarkdownHover = hoverController.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(HoverVerbosityAction.Decrease); + if (isFocusOnContractableMarkdownHover) { + content.push(this._descriptionForCommand(INCREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.decreaseVerbosity, HoverAccessibilityHelpNLS.decreaseVerbosityNoKb)); + } + return content.join('\n'); + } + + onClose(): void { + if (!this._editor) { return; } - return { - id: AccessibleViewProviderId.Hover, - verbositySettingKey: 'accessibility.verbosity.hover', - provideContent() { return editorHoverContent; }, - onClose() { - HoverController.get(editor)?.focus(); - }, - options: { - language: editor?.getModel()?.getLanguageId() ?? 'typescript', - type: AccessibleViewType.View - } - }; + HoverController.get(this._editor)?.focus(); } } export class ExtHoverAccessibleView implements IAccessibleViewImplentation { + readonly type = AccessibleViewType.View; readonly priority = 90; readonly name = 'extension-hover'; - getProvider(accessor: ServicesAccessor) { + + getProvider(accessor: ServicesAccessor): AdvancedContentProvider | undefined { const contextViewService = accessor.get(IContextViewService); const contextViewElement = contextViewService.getContextViewElement(); const extensionHoverContent = contextViewElement?.textContent ?? undefined; diff --git a/src/vs/editor/contrib/hover/browser/hoverController.ts b/src/vs/editor/contrib/hover/browser/hoverController.ts index 5d71cd64144d0..6c44354a7300f 100644 --- a/src/vs/editor/contrib/hover/browser/hoverController.ts +++ b/src/vs/editor/contrib/hover/browser/hoverController.ts @@ -408,6 +408,10 @@ export class HoverController extends Disposable implements IEditorContribution { this._getOrCreateContentWidget().updateFocusedMarkdownHoverVerbosityLevel(action); } + public isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action: HoverVerbosityAction): boolean { + return this._getOrCreateContentWidget().isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action); + } + public focus(): void { this._contentWidget?.focus(); } diff --git a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts index c6f7896a2c742..25a9b76fc5590 100644 --- a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts +++ b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts @@ -194,6 +194,10 @@ export class MarkdownHoverParticipant implements IEditorHoverParticipant= this._renderHoverParts.length || index < 0) { return; From 04cb337e4944e724a42d67f4c56cc07b23da8e54 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 May 2024 12:05:54 +0200 Subject: [PATCH 03/30] reusing the method --- .../hover/browser/hoverAccessibleViews.ts | 22 ++++++++----------- .../comments/browser/commentsAccessibility.ts | 14 +++++++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 7eabcfe0c0c67..3796e3a2122f9 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import * as strings from 'vs/base/common/strings'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; @@ -15,14 +14,15 @@ import { IHoverService } from 'vs/platform/hover/browser/hover'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { HoverVerbosityAction } from 'vs/editor/common/languages'; -import { INCREASE_HOVER_VERBOSITY_ACTION_ID } from 'vs/editor/contrib/hover/browser/hoverActionIds'; +import { DECREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID } from 'vs/editor/contrib/hover/browser/hoverActionIds'; +import { selectDescriptionForCommand } from 'vs/workbench/contrib/comments/browser/commentsAccessibility'; export namespace HoverAccessibilityHelpNLS { - export const intro = nls.localize('intro', `The hover widget is focused. Press the Tab key to cycle through the hover parts.`); - export const increaseVerbosity = nls.localize('increaseVerbosity', `- The current focused hover part's verbosity level can be increased ({0}).`); - export const increaseVerbosityNoKb = nls.localize('increaseVerbosityNoKb', `- The current focused hover part's verbosity level can be increased, which is currently not triggerable via keybinding.`); - export const decreaseVerbosity = nls.localize('decreaseVerbosity', `- The current focused hover part's verbosity level can be decreased ({0}).`); - export const decreaseVerbosityNoKb = nls.localize('decreaseVerbosityNoKb', `- The current focused hover part's verbosity level can be decreased, which is currently not triggerable via keybinding.`); + export const intro = nls.localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); + export const increaseVerbosity = nls.localize('increaseVerbosity', "- The current focused hover part's verbosity level can be increased ({0})."); + export const increaseVerbosityNoKb = nls.localize('increaseVerbosityNoKb', "- The current focused hover part's verbosity level can be increased, which is currently not triggerable via keybinding."); + export const decreaseVerbosity = nls.localize('decreaseVerbosity', "- The current focused hover part's verbosity level can be decreased ({0})."); + export const decreaseVerbosityNoKb = nls.localize('decreaseVerbosityNoKb', "- The current focused hover part's verbosity level can be decreased, which is currently not triggerable via keybinding."); } export class HoverAccessibleView implements IAccessibleViewImplentation { @@ -57,11 +57,7 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro } private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { - const kb = this._keybindingService.lookupKeybinding(commandId); - if (kb) { - return strings.format(msg, kb.getAriaLabel()); - } - return strings.format(noKbMsg, commandId); + return selectDescriptionForCommand(this._keybindingService, commandId, msg, noKbMsg); } provideContent(): string { @@ -82,7 +78,7 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro } const isFocusOnContractableMarkdownHover = hoverController.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(HoverVerbosityAction.Decrease); if (isFocusOnContractableMarkdownHover) { - content.push(this._descriptionForCommand(INCREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.decreaseVerbosity, HoverAccessibilityHelpNLS.decreaseVerbosityNoKb)); + content.push(this._descriptionForCommand(DECREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.decreaseVerbosity, HoverAccessibilityHelpNLS.decreaseVerbosityNoKb)); } return content.join('\n'); } diff --git a/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts b/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts index 2f200bc07887b..dc5f1ad2c7b10 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts @@ -48,11 +48,7 @@ export class CommentsAccessibilityHelpProvider implements IAccessibleViewContent } private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { - const kb = this._keybindingService.lookupKeybinding(commandId); - if (kb) { - return strings.format(msg, kb.getAriaLabel()); - } - return strings.format(noKbMsg, commandId); + return selectDescriptionForCommand(this._keybindingService, commandId, msg, noKbMsg); } provideContent(): string { this._element = getActiveElement() as HTMLElement; @@ -80,3 +76,11 @@ export class CommentsAccessibilityHelp implements IAccessibleViewImplentation { return accessor.get(IInstantiationService).createInstance(CommentsAccessibilityHelpProvider); } } + +export function selectDescriptionForCommand(keybindingService: IKeybindingService, commandId: string, msg: string, noKbMsg: string) { + const kb = keybindingService.lookupKeybinding(commandId); + if (kb) { + return strings.format(msg, kb.getAriaLabel()); + } + return strings.format(noKbMsg, commandId); +} From a1851bd77aa4d74cd6470ae16a38e3582e33c050 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 May 2024 12:20:41 +0200 Subject: [PATCH 04/30] joining the content and changing the text in the help view --- .../contrib/hover/browser/hoverAccessibleViews.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 3796e3a2122f9..fc28a2f4572ee 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -17,12 +17,12 @@ import { HoverVerbosityAction } from 'vs/editor/common/languages'; import { DECREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID } from 'vs/editor/contrib/hover/browser/hoverActionIds'; import { selectDescriptionForCommand } from 'vs/workbench/contrib/comments/browser/commentsAccessibility'; -export namespace HoverAccessibilityHelpNLS { +namespace HoverAccessibilityHelpNLS { export const intro = nls.localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); - export const increaseVerbosity = nls.localize('increaseVerbosity', "- The current focused hover part's verbosity level can be increased ({0})."); - export const increaseVerbosityNoKb = nls.localize('increaseVerbosityNoKb', "- The current focused hover part's verbosity level can be increased, which is currently not triggerable via keybinding."); - export const decreaseVerbosity = nls.localize('decreaseVerbosity', "- The current focused hover part's verbosity level can be decreased ({0})."); - export const decreaseVerbosityNoKb = nls.localize('decreaseVerbosityNoKb', "- The current focused hover part's verbosity level can be decreased, which is currently not triggerable via keybinding."); + export const increaseVerbosity = nls.localize('increaseVerbosity', "- The focused hover part verbosity level can be increased ({0})."); + export const increaseVerbosityNoKb = nls.localize('increaseVerbosityNoKb', "- The focused hover part verbosity level can be increased, which is currently not triggerable via keybinding."); + export const decreaseVerbosity = nls.localize('decreaseVerbosity', "- The focused hover part verbosity level can be decreased ({0})."); + export const decreaseVerbosityNoKb = nls.localize('decreaseVerbosityNoKb', "- The focused hover part verbosity level can be decreased, which is currently not triggerable via keybinding."); } export class HoverAccessibleView implements IAccessibleViewImplentation { @@ -66,11 +66,11 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro content.push(HoverAccessibilityHelpNLS.intro); if (!this._editor) { - return ''; + return content.join('\n'); } const hoverController = HoverController.get(this._editor); if (!hoverController) { - return ''; + return content.join('\n'); } const isFocusOnExpandableMarkdownHover = hoverController.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(HoverVerbosityAction.Increase); if (isFocusOnExpandableMarkdownHover) { From 9a358bf646437a9bc246808f6ba1cf223f981fa8 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 May 2024 15:43:53 +0200 Subject: [PATCH 05/30] polishing the code --- .../hover/browser/hoverAccessibleViews.ts | 39 +++++++++---------- .../comments/browser/commentsAccessibility.ts | 14 +++---- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index fc28a2f4572ee..f5b37726a33e6 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -3,8 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; -import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import * as strings from 'vs/base/common/strings'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController'; import { AccessibleViewType, AccessibleViewProviderId, AdvancedContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions } from 'vs/platform/accessibility/browser/accessibleView'; @@ -15,7 +14,9 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { HoverVerbosityAction } from 'vs/editor/common/languages'; import { DECREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID } from 'vs/editor/contrib/hover/browser/hoverActionIds'; -import { selectDescriptionForCommand } from 'vs/workbench/contrib/comments/browser/commentsAccessibility'; +import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; +import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; +import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; namespace HoverAccessibilityHelpNLS { export const intro = nls.localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); @@ -33,23 +34,25 @@ export class HoverAccessibleView implements IAccessibleViewImplentation { readonly when = EditorContextKeys.hoverFocused; getProvider(accessor: ServicesAccessor): AdvancedContentProvider | undefined { - return accessor.get(IInstantiationService).createInstance(HoverAccessibilityHelpProvider); + const codeEditorService = accessor.get(ICodeEditorService); + let codeEditor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); + if (!codeEditor) { + return undefined; + } + return accessor.get(IInstantiationService).createInstance(HoverAccessibilityHelpProvider, codeEditor); } } export class HoverAccessibilityHelpProvider implements IAccessibleViewContentProvider { - public id = AccessibleViewProviderId.Hover; - public verbositySettingKey = 'accessibility.verbosity.hover'; - public options: IAccessibleViewOptions; - - private _editor: ICodeEditor | null; + public readonly options: IAccessibleViewOptions; + public readonly id = AccessibleViewProviderId.Hover; + public readonly verbositySettingKey = AccessibilityVerbositySettingId.Hover; constructor( - @ICodeEditorService private readonly _codeEditorService: ICodeEditorService, + private readonly _editor: ICodeEditor, @IKeybindingService private readonly _keybindingService: IKeybindingService ) { - this._editor = this._codeEditorService.getActiveCodeEditor() || this._codeEditorService.getFocusedCodeEditor(); this.options = { language: this._editor?.getModel()?.getLanguageId() ?? 'typescript', type: AccessibleViewType.View @@ -57,17 +60,16 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro } private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { - return selectDescriptionForCommand(this._keybindingService, commandId, msg, noKbMsg); + const kb = this._keybindingService.lookupKeybinding(commandId); + if (kb) { + return strings.format(msg, kb.getAriaLabel()); + } + return strings.format(noKbMsg, commandId); } provideContent(): string { - const content: string[] = []; content.push(HoverAccessibilityHelpNLS.intro); - - if (!this._editor) { - return content.join('\n'); - } const hoverController = HoverController.get(this._editor); if (!hoverController) { return content.join('\n'); @@ -84,9 +86,6 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro } onClose(): void { - if (!this._editor) { - return; - } HoverController.get(this._editor)?.focus(); } } diff --git a/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts b/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts index dc5f1ad2c7b10..2f200bc07887b 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts @@ -48,7 +48,11 @@ export class CommentsAccessibilityHelpProvider implements IAccessibleViewContent } private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { - return selectDescriptionForCommand(this._keybindingService, commandId, msg, noKbMsg); + const kb = this._keybindingService.lookupKeybinding(commandId); + if (kb) { + return strings.format(msg, kb.getAriaLabel()); + } + return strings.format(noKbMsg, commandId); } provideContent(): string { this._element = getActiveElement() as HTMLElement; @@ -76,11 +80,3 @@ export class CommentsAccessibilityHelp implements IAccessibleViewImplentation { return accessor.get(IInstantiationService).createInstance(CommentsAccessibilityHelpProvider); } } - -export function selectDescriptionForCommand(keybindingService: IKeybindingService, commandId: string, msg: string, noKbMsg: string) { - const kb = keybindingService.lookupKeybinding(commandId); - if (kb) { - return strings.format(msg, kb.getAriaLabel()); - } - return strings.format(noKbMsg, commandId); -} From f07cd63b2e783c9017e563f16a0e53ef5612b0bd Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 May 2024 15:45:31 +0200 Subject: [PATCH 06/30] removing the question mark --- src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index f5b37726a33e6..d6a1bfbd97e49 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -54,7 +54,7 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro @IKeybindingService private readonly _keybindingService: IKeybindingService ) { this.options = { - language: this._editor?.getModel()?.getLanguageId() ?? 'typescript', + language: this._editor.getModel()?.getLanguageId() ?? 'typescript', type: AccessibleViewType.View } } From 31ea76847c39e06a67f8e247cb68639ead6cd70b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 15 May 2024 17:00:47 +0200 Subject: [PATCH 07/30] changing the import --- .../hover/browser/hoverAccessibleViews.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index d6a1bfbd97e49..873cd260f5ea9 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -2,8 +2,8 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vs/nls'; -import * as strings from 'vs/base/common/strings'; +import { localize } from 'vs/nls'; +import { format } from 'vs/base/common/strings'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController'; import { AccessibleViewType, AccessibleViewProviderId, AdvancedContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions } from 'vs/platform/accessibility/browser/accessibleView'; @@ -19,11 +19,11 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; namespace HoverAccessibilityHelpNLS { - export const intro = nls.localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); - export const increaseVerbosity = nls.localize('increaseVerbosity', "- The focused hover part verbosity level can be increased ({0})."); - export const increaseVerbosityNoKb = nls.localize('increaseVerbosityNoKb', "- The focused hover part verbosity level can be increased, which is currently not triggerable via keybinding."); - export const decreaseVerbosity = nls.localize('decreaseVerbosity', "- The focused hover part verbosity level can be decreased ({0})."); - export const decreaseVerbosityNoKb = nls.localize('decreaseVerbosityNoKb', "- The focused hover part verbosity level can be decreased, which is currently not triggerable via keybinding."); + export const intro = localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); + export const increaseVerbosity = localize('increaseVerbosity', "- The focused hover part verbosity level can be increased ({0})."); + export const increaseVerbosityNoKb = localize('increaseVerbosityNoKb', "- The focused hover part verbosity level can be increased, which is currently not triggerable via keybinding."); + export const decreaseVerbosity = localize('decreaseVerbosity', "- The focused hover part verbosity level can be decreased ({0})."); + export const decreaseVerbosityNoKb = localize('decreaseVerbosityNoKb', "- The focused hover part verbosity level can be decreased, which is currently not triggerable via keybinding."); } export class HoverAccessibleView implements IAccessibleViewImplentation { @@ -62,9 +62,9 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { const kb = this._keybindingService.lookupKeybinding(commandId); if (kb) { - return strings.format(msg, kb.getAriaLabel()); + return format(msg, kb.getAriaLabel()); } - return strings.format(noKbMsg, commandId); + return format(noKbMsg, commandId); } provideContent(): string { From 24062b1cf70730cd80f7462dc268eec3b156ef46 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 16 May 2024 09:01:49 +0200 Subject: [PATCH 08/30] removing the setting ID from imports --- src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 873cd260f5ea9..4ab71dad6b0d6 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -14,7 +14,6 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { HoverVerbosityAction } from 'vs/editor/common/languages'; import { DECREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID } from 'vs/editor/contrib/hover/browser/hoverActionIds'; -import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; @@ -47,7 +46,7 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro public readonly options: IAccessibleViewOptions; public readonly id = AccessibleViewProviderId.Hover; - public readonly verbositySettingKey = AccessibilityVerbositySettingId.Hover; + public readonly verbositySettingKey = 'accessibility.verbosity.hover'; constructor( private readonly _editor: ICodeEditor, From cb92438bf4d3c97a6f63a6ff1f278427cd3bd693 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 16 May 2024 17:29:09 +0200 Subject: [PATCH 09/30] adding code in order to update when the hover updates --- .../hover/browser/contentHoverController.ts | 19 +++++++++-- .../hover/browser/hoverAccessibleViews.ts | 33 ++++++++++++++++--- .../contrib/hover/browser/hoverActionIds.ts | 5 +++ .../contrib/hover/browser/hoverActions.ts | 24 +++++--------- .../contrib/hover/browser/hoverController.ts | 31 +++++++++++++++-- .../hover/browser/markdownHoverParticipant.ts | 30 ++++++++++++----- 6 files changed, 109 insertions(+), 33 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHoverController.ts b/src/vs/editor/contrib/hover/browser/contentHoverController.ts index 51213f8cdc67d..52f0a919aa2f6 100644 --- a/src/vs/editor/contrib/hover/browser/contentHoverController.ts +++ b/src/vs/editor/contrib/hover/browser/contentHoverController.ts @@ -23,9 +23,13 @@ import { ContentHoverWidget } from 'vs/editor/contrib/hover/browser/contentHover import { ContentHoverComputer } from 'vs/editor/contrib/hover/browser/contentHoverComputer'; import { ContentHoverVisibleData, HoverResult } from 'vs/editor/contrib/hover/browser/contentHoverTypes'; import { EditorHoverStatusBar } from 'vs/editor/contrib/hover/browser/contentHoverStatusBar'; +import { Emitter } from 'vs/base/common/event'; export class ContentHoverController extends Disposable implements IHoverWidget { + private readonly _onContentsChanged = this._register(new Emitter()); + public readonly onContentsChanged = this._onContentsChanged.event; + private _currentResult: HoverResult | null = null; private readonly _computer: ContentHoverComputer; @@ -214,7 +218,7 @@ export class ContentHoverController extends Disposable implements IHoverWidget { fragment, statusBar, setColorPicker: (widget) => colorPicker = widget, - onContentsChanged: () => this._widget.onContentsChanged(), + onContentsChanged: () => this._doOnContentsChanged(), setMinimumDimensions: (dimensions: dom.Dimension) => this._widget.setMinimumDimensions(dimensions), hide: () => this.hide() }; @@ -261,6 +265,11 @@ export class ContentHoverController extends Disposable implements IHoverWidget { } } + private _doOnContentsChanged(): void { + this._onContentsChanged.fire(); + this._widget.onContentsChanged(); + } + private static readonly _DECORATION_OPTIONS = ModelDecorationOptions.register({ description: 'content-hover-highlight', className: 'hoverHighlight' @@ -351,8 +360,12 @@ export class ContentHoverController extends Disposable implements IHoverWidget { this._startShowingOrUpdateHover(new HoverRangeAnchor(0, range, undefined, undefined), mode, source, focus, null); } - public async updateFocusedMarkdownHoverVerbosityLevel(action: HoverVerbosityAction): Promise { - this._markdownHoverParticipant?.updateFocusedMarkdownHoverPartVerbosityLevel(action); + public async updateLastFocusedMarkdownHoverVerbosityLevel(action: HoverVerbosityAction, focus: boolean = true): Promise { + this._markdownHoverParticipant?.updateLastFocusedMarkdownHoverPartVerbosityLevel(action, focus); + } + + public lastFocusedMarkdownHoverContent(): string { + return this._markdownHoverParticipant?.lastFocusedMarkdownHoverContent() ?? ''; } public isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action: HoverVerbosityAction): boolean { diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 4ab71dad6b0d6..907d12afbb7c7 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -6,16 +6,20 @@ import { localize } from 'vs/nls'; import { format } from 'vs/base/common/strings'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController'; -import { AccessibleViewType, AccessibleViewProviderId, AdvancedContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions } from 'vs/platform/accessibility/browser/accessibleView'; +import { AccessibleViewType, AccessibleViewProviderId, AdvancedContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions, IAccessibleViewService } from 'vs/platform/accessibility/browser/accessibleView'; import { IAccessibleViewImplentation } from 'vs/platform/accessibility/browser/accessibleViewRegistry'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IHoverService } from 'vs/platform/hover/browser/hover'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { HoverVerbosityAction } from 'vs/editor/common/languages'; -import { DECREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID } from 'vs/editor/contrib/hover/browser/hoverActionIds'; +import { DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL } from 'vs/editor/contrib/hover/browser/hoverActionIds'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; +import { Action, IAction } from 'vs/base/common/actions'; +import { ThemeIcon } from 'vs/base/common/themables'; +import { Codicon } from 'vs/base/common/codicons'; +import { IDisposable } from 'vs/base/common/lifecycle'; namespace HoverAccessibilityHelpNLS { export const intro = localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); @@ -23,6 +27,7 @@ namespace HoverAccessibilityHelpNLS { export const increaseVerbosityNoKb = localize('increaseVerbosityNoKb', "- The focused hover part verbosity level can be increased, which is currently not triggerable via keybinding."); export const decreaseVerbosity = localize('decreaseVerbosity', "- The focused hover part verbosity level can be decreased ({0})."); export const decreaseVerbosityNoKb = localize('decreaseVerbosityNoKb', "- The focused hover part verbosity level can be decreased, which is currently not triggerable via keybinding."); + export const hoverContent = localize('contentHover', "The last focused hover content is the following."); } export class HoverAccessibleView implements IAccessibleViewImplentation { @@ -34,7 +39,7 @@ export class HoverAccessibleView implements IAccessibleViewImplentation { getProvider(accessor: ServicesAccessor): AdvancedContentProvider | undefined { const codeEditorService = accessor.get(ICodeEditorService); - let codeEditor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); + const codeEditor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); if (!codeEditor) { return undefined; } @@ -47,15 +52,25 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro public readonly options: IAccessibleViewOptions; public readonly id = AccessibleViewProviderId.Hover; public readonly verbositySettingKey = 'accessibility.verbosity.hover'; + public readonly actions: IAction[] = []; + + private _onHoverContentsChanged: IDisposable | undefined; constructor( private readonly _editor: ICodeEditor, + @IAccessibleViewService private readonly _accessibleViewService: IAccessibleViewService, @IKeybindingService private readonly _keybindingService: IKeybindingService ) { this.options = { language: this._editor.getModel()?.getLanguageId() ?? 'typescript', type: AccessibleViewType.View - } + }; + this.actions.push(new Action(INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL, ThemeIcon.asClassName(Codicon.add), true, () => { + this._editor.getAction(INCREASE_HOVER_VERBOSITY_ACTION_ID)?.run({ focus: false }); + })); + this.actions.push(new Action(DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, ThemeIcon.asClassName(Codicon.remove), true, () => { + this._editor.getAction(DECREASE_HOVER_VERBOSITY_ACTION_ID)?.run({ focus: false }); + })); } private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { @@ -81,11 +96,21 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro if (isFocusOnContractableMarkdownHover) { content.push(this._descriptionForCommand(DECREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.decreaseVerbosity, HoverAccessibilityHelpNLS.decreaseVerbosityNoKb)); } + const hoverContent = hoverController.lastFocusedMarkdownHoverContent(); + if (hoverContent) { + content.push('\n' + HoverAccessibilityHelpNLS.hoverContent); + content.push('\n' + hoverContent); + } + this._onHoverContentsChanged?.dispose(); + this._onHoverContentsChanged = hoverController.onHoverContentsChanged(() => { + this._accessibleViewService.show(this); + }); return content.join('\n'); } onClose(): void { HoverController.get(this._editor)?.focus(); + this._onHoverContentsChanged?.dispose(); } } diff --git a/src/vs/editor/contrib/hover/browser/hoverActionIds.ts b/src/vs/editor/contrib/hover/browser/hoverActionIds.ts index 5cc42e1aa50b9..2ade6360ac1bf 100644 --- a/src/vs/editor/contrib/hover/browser/hoverActionIds.ts +++ b/src/vs/editor/contrib/hover/browser/hoverActionIds.ts @@ -2,6 +2,7 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as nls from 'vs/nls'; export const SHOW_OR_FOCUS_HOVER_ACTION_ID = 'editor.action.showHover'; export const SHOW_DEFINITION_PREVIEW_HOVER_ACTION_ID = 'editor.action.showDefinitionPreviewHover'; @@ -14,4 +15,8 @@ export const PAGE_DOWN_HOVER_ACTION_ID = 'editor.action.pageDownHover'; export const GO_TO_TOP_HOVER_ACTION_ID = 'editor.action.goToTopHover'; export const GO_TO_BOTTOM_HOVER_ACTION_ID = 'editor.action.goToBottomHover'; export const INCREASE_HOVER_VERBOSITY_ACTION_ID = 'editor.action.increaseHoverVerbosityLevel'; +export const INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID = 'editor.action.increaseHoverVerbosityLevelFromAccessibleView'; +export const INCREASE_HOVER_VERBOSITY_ACTION_LABEL = nls.localize({ key: 'increaseHoverVerbosityLevel', comment: ['Label for action that will increase the hover verbosity level.'] }, "Increase Hover Verbosity Level"); export const DECREASE_HOVER_VERBOSITY_ACTION_ID = 'editor.action.decreaseHoverVerbosityLevel'; +export const DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID = 'editor.action.decreaseHoverVerbosityLevelFromAccessibleView'; +export const DECREASE_HOVER_VERBOSITY_ACTION_LABEL = nls.localize({ key: 'decreaseHoverVerbosityLevel', comment: ['Label for action that will decrease the hover verbosity level.'] }, "Decrease Hover Verbosity Level"); diff --git a/src/vs/editor/contrib/hover/browser/hoverActions.ts b/src/vs/editor/contrib/hover/browser/hoverActions.ts index 9654e7c3d0920..0a06d62abdcd0 100644 --- a/src/vs/editor/contrib/hover/browser/hoverActions.ts +++ b/src/vs/editor/contrib/hover/browser/hoverActions.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { DECREASE_HOVER_VERBOSITY_ACTION_ID, GO_TO_BOTTOM_HOVER_ACTION_ID, GO_TO_TOP_HOVER_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, PAGE_DOWN_HOVER_ACTION_ID, PAGE_UP_HOVER_ACTION_ID, SCROLL_DOWN_HOVER_ACTION_ID, SCROLL_LEFT_HOVER_ACTION_ID, SCROLL_RIGHT_HOVER_ACTION_ID, SCROLL_UP_HOVER_ACTION_ID, SHOW_DEFINITION_PREVIEW_HOVER_ACTION_ID, SHOW_OR_FOCUS_HOVER_ACTION_ID } from 'vs/editor/contrib/hover/browser/hoverActionIds'; +import { DECREASE_HOVER_VERBOSITY_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, GO_TO_BOTTOM_HOVER_ACTION_ID, GO_TO_TOP_HOVER_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL, PAGE_DOWN_HOVER_ACTION_ID, PAGE_UP_HOVER_ACTION_ID, SCROLL_DOWN_HOVER_ACTION_ID, SCROLL_LEFT_HOVER_ACTION_ID, SCROLL_RIGHT_HOVER_ACTION_ID, SCROLL_UP_HOVER_ACTION_ID, SHOW_DEFINITION_PREVIEW_HOVER_ACTION_ID, SHOW_OR_FOCUS_HOVER_ACTION_ID } from 'vs/editor/contrib/hover/browser/hoverActionIds'; import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, ServicesAccessor } from 'vs/editor/browser/editorExtensions'; @@ -425,17 +425,14 @@ export class IncreaseHoverVerbosityLevel extends EditorAction { constructor() { super({ id: INCREASE_HOVER_VERBOSITY_ACTION_ID, - label: nls.localize({ - key: 'increaseHoverVerbosityLevel', - comment: ['Label for action that will increase the hover verbosity level.'] - }, "Increase Hover Verbosity Level"), + label: INCREASE_HOVER_VERBOSITY_ACTION_LABEL, alias: 'Increase Hover Verbosity Level', - precondition: EditorContextKeys.hoverFocused + precondition: EditorContextKeys.hoverVisible }); } - public run(accessor: ServicesAccessor, editor: ICodeEditor): void { - HoverController.get(editor)?.updateFocusedMarkdownHoverVerbosityLevel(HoverVerbosityAction.Increase); + public run(accessor: ServicesAccessor, editor: ICodeEditor, args?: { focus: boolean }): void { + HoverController.get(editor)?.updateFocusedMarkdownHoverVerbosityLevel(HoverVerbosityAction.Increase, args?.focus); } } @@ -444,16 +441,13 @@ export class DecreaseHoverVerbosityLevel extends EditorAction { constructor() { super({ id: DECREASE_HOVER_VERBOSITY_ACTION_ID, - label: nls.localize({ - key: 'decreaseHoverVerbosityLevel', - comment: ['Label for action that will decrease the hover verbosity level.'] - }, "Decrease Hover Verbosity Level"), + label: DECREASE_HOVER_VERBOSITY_ACTION_LABEL, alias: 'Decrease Hover Verbosity Level', - precondition: EditorContextKeys.hoverFocused + precondition: EditorContextKeys.hoverVisible }); } - public run(accessor: ServicesAccessor, editor: ICodeEditor, args: any): void { - HoverController.get(editor)?.updateFocusedMarkdownHoverVerbosityLevel(HoverVerbosityAction.Decrease); + public run(accessor: ServicesAccessor, editor: ICodeEditor, args?: { focus: boolean }): void { + HoverController.get(editor)?.updateFocusedMarkdownHoverVerbosityLevel(HoverVerbosityAction.Decrease, args?.focus); } } diff --git a/src/vs/editor/contrib/hover/browser/hoverController.ts b/src/vs/editor/contrib/hover/browser/hoverController.ts index 6c44354a7300f..016dac6000da3 100644 --- a/src/vs/editor/contrib/hover/browser/hoverController.ts +++ b/src/vs/editor/contrib/hover/browser/hoverController.ts @@ -23,6 +23,10 @@ import { ContentHoverWidget } from 'vs/editor/contrib/hover/browser/contentHover import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController'; import 'vs/css!./hover'; import { MarginHoverWidget } from 'vs/editor/contrib/hover/browser/marginHoverWidget'; +import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; +import { accessibleViewCurrentProviderId, accessibleViewIsShown } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; +import { AccessibleViewProviderId } from 'vs/platform/accessibility/browser/accessibleView'; +import { Emitter } from 'vs/base/common/event'; // sticky hover widget which doesn't disappear on focus out and such const _sticky = false @@ -47,6 +51,9 @@ const enum HoverWidgetType { export class HoverController extends Disposable implements IEditorContribution { + private readonly _onHoverContentsChanged = this._register(new Emitter()); + public readonly onHoverContentsChanged = this._onHoverContentsChanged.event; + public static readonly ID = 'editor.contrib.hover'; private readonly _listenersStore = new DisposableStore(); @@ -65,6 +72,7 @@ export class HoverController extends Disposable implements IEditorContribution { constructor( private readonly _editor: ICodeEditor, + @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IInstantiationService private readonly _instantiationService: IInstantiationService, @IKeybindingService private readonly _keybindingService: IKeybindingService ) { @@ -174,6 +182,9 @@ export class HoverController extends Disposable implements IEditorContribution { } private _onEditorMouseLeave(mouseEvent: IPartialEditorMouseEvent): void { + if (this._isHoverAccessibleViewVisible) { + return; + } this._cancelScheduler(); @@ -223,6 +234,9 @@ export class HoverController extends Disposable implements IEditorContribution { } private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { + if (this._isHoverAccessibleViewVisible) { + return; + } this._mouseMoveEvent = mouseEvent; if (this._contentWidget?.isFocused || this._contentWidget?.isResizing) { @@ -256,6 +270,13 @@ export class HoverController extends Disposable implements IEditorContribution { this._reactToEditorMouseMove(mouseEvent); } + private get _isHoverAccessibleViewVisible(): boolean { + const isHoverAccessibleViewProviderCurrent = ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.Hover); + const isHoverAccessibleViewVisibleContextKey = ContextKeyExpr.and(accessibleViewIsShown, isHoverAccessibleViewProviderCurrent); + const isHoverAccessibleViewVisible = isHoverAccessibleViewVisibleContextKey?.evaluate(this._contextKeyService.getContext(null)) ?? false; + return isHoverAccessibleViewVisible; + } + private _reactToEditorMouseMove(mouseEvent: IEditorMouseEvent | undefined): void { if (!mouseEvent) { @@ -374,6 +395,7 @@ export class HoverController extends Disposable implements IEditorContribution { private _getOrCreateContentWidget(): ContentHoverController { if (!this._contentWidget) { this._contentWidget = this._instantiationService.createInstance(ContentHoverController, this._editor); + this._contentWidget.onContentsChanged(() => this._onHoverContentsChanged.fire()); } return this._contentWidget; } @@ -404,8 +426,12 @@ export class HoverController extends Disposable implements IEditorContribution { return this._contentWidget?.widget.isResizing || false; } - public updateFocusedMarkdownHoverVerbosityLevel(action: HoverVerbosityAction): void { - this._getOrCreateContentWidget().updateFocusedMarkdownHoverVerbosityLevel(action); + public updateFocusedMarkdownHoverVerbosityLevel(action: HoverVerbosityAction, focus: boolean = true): void { + this._getOrCreateContentWidget().updateLastFocusedMarkdownHoverVerbosityLevel(action, focus); + } + + public lastFocusedMarkdownHoverContent(): string { + return this._getOrCreateContentWidget().lastFocusedMarkdownHoverContent(); } public isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action: HoverVerbosityAction): boolean { @@ -466,5 +492,6 @@ export class HoverController extends Disposable implements IEditorContribution { this._listenersStore.dispose(); this._glyphWidget?.dispose(); this._contentWidget?.dispose(); + this._onHoverContentsChanged.dispose(); } } diff --git a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts index 25a9b76fc5590..5dbbc5102195b 100644 --- a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts +++ b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts @@ -191,8 +191,12 @@ export class MarkdownHoverParticipant implements IEditorHoverParticipant this.updateFocusedHoverPartVerbosityLevel(action); + const actionFunction = () => this.updateLastFocusedMarkdownHoverPartVerbosityLevel(action); store.add(new ClickAction(actionElement, actionFunction)); store.add(new KeyDownAction(actionElement, actionFunction, [KeyCode.Enter, KeyCode.Space])); return store; } - public async updateFocusedHoverPartVerbosityLevel(action: HoverVerbosityAction): Promise { + public async updateLastFocusedMarkdownHoverPartVerbosityLevel(action: HoverVerbosityAction, focus: boolean = true): Promise { const model = this._editor.getModel(); if (!model) { return; } - const hoverFocusedPartIndex = this._hoverFocusInfo.hoverPartIndex; - const hoverRenderedPart = this._getRenderedHoverPartAtIndex(hoverFocusedPartIndex); + const hoverLastFocusedPartIndex = this._hoverFocusInfo.hoverPartIndex; + const hoverRenderedPart = this._getRenderedHoverPartAtIndex(hoverLastFocusedPartIndex); if (!hoverRenderedPart || !hoverRenderedPart.hoverSource?.supportsVerbosityAction(action)) { return; } @@ -372,16 +376,24 @@ class MarkdownRenderedHoverParts extends Disposable { const hoverSource = new HoverSource(newHover, hoverProvider, hoverPosition); const renderedHoverPart = this._renderHoverPart( - hoverFocusedPartIndex, + hoverLastFocusedPartIndex, newHover.contents, hoverSource, this._onFinishedRendering ); - this._replaceRenderedHoverPartAtIndex(hoverFocusedPartIndex, renderedHoverPart); - this._focusOnHoverPartWithIndex(hoverFocusedPartIndex); + this._replaceRenderedHoverPartAtIndex(hoverLastFocusedPartIndex, renderedHoverPart); + if (focus) { + this._focusOnHoverPartWithIndex(hoverLastFocusedPartIndex); + } this._onFinishedRendering(); } + public lastFocusedMarkdownHoverContent(): string { + const hoverLastFocusedPartIndex = this._hoverFocusInfo.hoverPartIndex; + const hoverRenderedPart = this._getRenderedHoverPartAtIndex(hoverLastFocusedPartIndex); + return hoverRenderedPart?.renderedMarkdown.innerText ?? ''; + } + public isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action: HoverVerbosityAction): boolean { const hoverFocusedPartIndex = this._hoverFocusInfo.hoverPartIndex; const hoverRenderedPart = this._getRenderedHoverPartAtIndex(hoverFocusedPartIndex); From fa6bc6cc4607150dac09e65ff1a8a925bf6deac4 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 17 May 2024 11:45:25 +0200 Subject: [PATCH 10/30] adding methods to service --- .../hover/browser/contentHoverController.ts | 14 +++++----- .../hover/browser/hoverAccessibleViews.ts | 18 ++++++------ .../contrib/hover/browser/hoverController.ts | 27 +++++++++--------- .../hover/browser/markdownHoverParticipant.ts | 8 +++--- .../accessibility/browser/accessibleView.ts | 3 ++ .../accessibility/browser/accessibleView.ts | 28 ++++++++++++++++++- 6 files changed, 63 insertions(+), 35 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHoverController.ts b/src/vs/editor/contrib/hover/browser/contentHoverController.ts index 52f0a919aa2f6..0176a86d4caf2 100644 --- a/src/vs/editor/contrib/hover/browser/contentHoverController.ts +++ b/src/vs/editor/contrib/hover/browser/contentHoverController.ts @@ -27,9 +27,6 @@ import { Emitter } from 'vs/base/common/event'; export class ContentHoverController extends Disposable implements IHoverWidget { - private readonly _onContentsChanged = this._register(new Emitter()); - public readonly onContentsChanged = this._onContentsChanged.event; - private _currentResult: HoverResult | null = null; private readonly _computer: ContentHoverComputer; @@ -39,6 +36,9 @@ export class ContentHoverController extends Disposable implements IHoverWidget { private readonly _markdownHoverParticipant: MarkdownHoverParticipant | undefined; private readonly _hoverOperation: HoverOperation; + private readonly _onContentsChanged = this._register(new Emitter()); + public readonly onContentsChanged = this._onContentsChanged.event; + constructor( private readonly _editor: ICodeEditor, @IInstantiationService private readonly _instantiationService: IInstantiationService, @@ -364,14 +364,14 @@ export class ContentHoverController extends Disposable implements IHoverWidget { this._markdownHoverParticipant?.updateLastFocusedMarkdownHoverPartVerbosityLevel(action, focus); } - public lastFocusedMarkdownHoverContent(): string { - return this._markdownHoverParticipant?.lastFocusedMarkdownHoverContent() ?? ''; - } - public isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action: HoverVerbosityAction): boolean { return this._markdownHoverParticipant?.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action) ?? false; } + public lastFocusedMarkdownHoverContent(): string { + return this._markdownHoverParticipant?.lastFocusedMarkdownHoverContent() ?? ''; + } + public getWidgetContent(): string | undefined { const node = this._widget.getDomNode(); if (!node.textContent) { diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 907d12afbb7c7..12f41b010e54a 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -73,14 +73,6 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro })); } - private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { - const kb = this._keybindingService.lookupKeybinding(commandId); - if (kb) { - return format(msg, kb.getAriaLabel()); - } - return format(noKbMsg, commandId); - } - provideContent(): string { const content: string[] = []; content.push(HoverAccessibilityHelpNLS.intro); @@ -103,7 +95,7 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro } this._onHoverContentsChanged?.dispose(); this._onHoverContentsChanged = hoverController.onHoverContentsChanged(() => { - this._accessibleViewService.show(this); + this._accessibleViewService.rerender(); }); return content.join('\n'); } @@ -112,6 +104,14 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro HoverController.get(this._editor)?.focus(); this._onHoverContentsChanged?.dispose(); } + + private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { + const kb = this._keybindingService.lookupKeybinding(commandId); + if (kb) { + return format(msg, kb.getAriaLabel()); + } + return format(noKbMsg, commandId); + } } export class ExtHoverAccessibleView implements IAccessibleViewImplentation { diff --git a/src/vs/editor/contrib/hover/browser/hoverController.ts b/src/vs/editor/contrib/hover/browser/hoverController.ts index 016dac6000da3..b3a9f41027325 100644 --- a/src/vs/editor/contrib/hover/browser/hoverController.ts +++ b/src/vs/editor/contrib/hover/browser/hoverController.ts @@ -23,9 +23,7 @@ import { ContentHoverWidget } from 'vs/editor/contrib/hover/browser/contentHover import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController'; import 'vs/css!./hover'; import { MarginHoverWidget } from 'vs/editor/contrib/hover/browser/marginHoverWidget'; -import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -import { accessibleViewCurrentProviderId, accessibleViewIsShown } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration'; -import { AccessibleViewProviderId } from 'vs/platform/accessibility/browser/accessibleView'; +import { AccessibleViewProviderId, IAccessibleViewService } from 'vs/platform/accessibility/browser/accessibleView'; import { Emitter } from 'vs/base/common/event'; // sticky hover widget which doesn't disappear on focus out and such @@ -51,9 +49,11 @@ const enum HoverWidgetType { export class HoverController extends Disposable implements IEditorContribution { + // Listeners private readonly _onHoverContentsChanged = this._register(new Emitter()); public readonly onHoverContentsChanged = this._onHoverContentsChanged.event; + // Other fields public static readonly ID = 'editor.contrib.hover'; private readonly _listenersStore = new DisposableStore(); @@ -72,9 +72,9 @@ export class HoverController extends Disposable implements IEditorContribution { constructor( private readonly _editor: ICodeEditor, - @IContextKeyService private readonly _contextKeyService: IContextKeyService, @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IKeybindingService private readonly _keybindingService: IKeybindingService + @IKeybindingService private readonly _keybindingService: IKeybindingService, + @IAccessibleViewService private readonly _accessibleViewService: IAccessibleViewService, ) { super(); this._reactToEditorMouseMoveRunner = this._register( @@ -271,9 +271,9 @@ export class HoverController extends Disposable implements IEditorContribution { } private get _isHoverAccessibleViewVisible(): boolean { - const isHoverAccessibleViewProviderCurrent = ContextKeyExpr.equals(accessibleViewCurrentProviderId.key, AccessibleViewProviderId.Hover); - const isHoverAccessibleViewVisibleContextKey = ContextKeyExpr.and(accessibleViewIsShown, isHoverAccessibleViewProviderCurrent); - const isHoverAccessibleViewVisible = isHoverAccessibleViewVisibleContextKey?.evaluate(this._contextKeyService.getContext(null)) ?? false; + const isAccessibleViewVisible = this._accessibleViewService.isVisible(); + const isHoverProviderUsed = this._accessibleViewService.providerId() === AccessibleViewProviderId.Hover; + const isHoverAccessibleViewVisible = isAccessibleViewVisible && isHoverProviderUsed; return isHoverAccessibleViewVisible; } @@ -395,7 +395,7 @@ export class HoverController extends Disposable implements IEditorContribution { private _getOrCreateContentWidget(): ContentHoverController { if (!this._contentWidget) { this._contentWidget = this._instantiationService.createInstance(ContentHoverController, this._editor); - this._contentWidget.onContentsChanged(() => this._onHoverContentsChanged.fire()); + this._listenersStore.add(this._contentWidget.onContentsChanged(() => this._onHoverContentsChanged.fire())); } return this._contentWidget; } @@ -430,14 +430,14 @@ export class HoverController extends Disposable implements IEditorContribution { this._getOrCreateContentWidget().updateLastFocusedMarkdownHoverVerbosityLevel(action, focus); } - public lastFocusedMarkdownHoverContent(): string { - return this._getOrCreateContentWidget().lastFocusedMarkdownHoverContent(); - } - public isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action: HoverVerbosityAction): boolean { return this._getOrCreateContentWidget().isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action); } + public lastFocusedMarkdownHoverContent(): string { + return this._getOrCreateContentWidget().lastFocusedMarkdownHoverContent(); + } + public focus(): void { this._contentWidget?.focus(); } @@ -492,6 +492,5 @@ export class HoverController extends Disposable implements IEditorContribution { this._listenersStore.dispose(); this._glyphWidget?.dispose(); this._contentWidget?.dispose(); - this._onHoverContentsChanged.dispose(); } } diff --git a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts index 5dbbc5102195b..1557da9f4852b 100644 --- a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts +++ b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts @@ -195,13 +195,13 @@ export class MarkdownHoverParticipant implements IEditorHoverParticipant { return { x: (getActiveWindow().innerWidth / 2) - ((Math.min(this._layoutService.activeContainerDimension.width * 0.62 /* golden cut */, DIMENSIONS.MAX_WIDTH)) / 2), y: this._layoutService.activeContainerOffset.quickPickTop }; }, render: (container) => { - container.classList.add('accessible-view-container'); + this._currentContainer = container; + this._currentContainer.classList.add('accessible-view-container'); return this._render(provider, container, showAccessibleViewHelp); }, onHide: () => { @@ -289,6 +291,21 @@ export class AccessibleView extends Disposable { } } + rerender(): void { + if (!this._currentProvider || !this._currentContainer) { + return; + } + this._render(this._currentProvider, this._currentContainer, false); + } + + isVisible(): boolean { + return this._accessibleViewIsShown.get() ?? false; + } + + providerId(): string { + return this._accessibleViewCurrentProviderId.get() ?? ''; + } + previous(): void { this._currentProvider?.previous?.(); } @@ -753,6 +770,15 @@ export class AccessibleViewService extends Disposable implements IAccessibleView showLastProvider(id: AccessibleViewProviderId): void { this._accessibleView?.showLastProvider(id); } + rerender(): void { + this._accessibleView?.rerender(); + } + isVisible(): boolean { + return this._accessibleView?.isVisible() ?? false; + } + providerId(): string { + return this._accessibleView?.providerId() ?? ''; + } next(): void { this._accessibleView?.next(); } From a0c67a591f7f129cac09c7beb06e63a1e9a097ab Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 21 May 2024 10:12:18 +0200 Subject: [PATCH 11/30] adding code in order to dispose the accessible hover view --- .../hover/browser/hoverAccessibleViews.ts | 57 ++++++++++++------- .../contrib/hover/browser/hoverController.ts | 16 ++---- .../accessibility/browser/accessibleView.ts | 6 +- .../browser/accessibleViewRegistry.ts | 3 +- .../notificationAccessibleView.ts | 1 + .../accessibility/browser/accessibleView.ts | 33 +++-------- .../extensionAccesibilityHelp.contribution.ts | 3 +- .../browser/actions/chatAccessibilityHelp.ts | 1 + .../browser/chatResponseAccessibleView.ts | 1 + .../browser/diffEditorAccessibilityHelp.ts | 1 + .../comments/browser/commentsAccessibility.ts | 1 + .../browser/inlineChatAccessibilityHelp.ts | 1 + .../browser/inlineChatAccessibleView.ts | 1 + .../browser/notebookAccessibilityHelp.ts | 1 + .../browser/notebookAccessibleView.ts | 1 + .../browser/terminalChatAccessibilityHelp.ts | 1 + .../browser/terminalChatAccessibleView.ts | 1 + 17 files changed, 66 insertions(+), 63 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 12f41b010e54a..1f2061a63d1ca 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -6,7 +6,7 @@ import { localize } from 'vs/nls'; import { format } from 'vs/base/common/strings'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController'; -import { AccessibleViewType, AccessibleViewProviderId, AdvancedContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions, IAccessibleViewService } from 'vs/platform/accessibility/browser/accessibleView'; +import { AccessibleViewType, AccessibleViewProviderId, AdvancedContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions } from 'vs/platform/accessibility/browser/accessibleView'; import { IAccessibleViewImplentation } from 'vs/platform/accessibility/browser/accessibleViewRegistry'; import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IHoverService } from 'vs/platform/hover/browser/hover'; @@ -19,7 +19,8 @@ import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService import { Action, IAction } from 'vs/base/common/actions'; import { ThemeIcon } from 'vs/base/common/themables'; import { Codicon } from 'vs/base/common/codicons'; -import { IDisposable } from 'vs/base/common/lifecycle'; +import { Emitter, Event } from 'vs/base/common/event'; +import { Disposable } from 'vs/base/common/lifecycle'; namespace HoverAccessibilityHelpNLS { export const intro = localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); @@ -37,32 +38,42 @@ export class HoverAccessibleView implements IAccessibleViewImplentation { readonly name = 'hover'; readonly when = EditorContextKeys.hoverFocused; + private _provider: HoverAccessibilityHelpProvider | undefined; + getProvider(accessor: ServicesAccessor): AdvancedContentProvider | undefined { const codeEditorService = accessor.get(ICodeEditorService); const codeEditor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); if (!codeEditor) { return undefined; } - return accessor.get(IInstantiationService).createInstance(HoverAccessibilityHelpProvider, codeEditor); + this._provider = accessor.get(IInstantiationService).createInstance(HoverAccessibilityHelpProvider, codeEditor); + return this._provider; + } + + dispose(): void { + this._provider?.dispose(); } } -export class HoverAccessibilityHelpProvider implements IAccessibleViewContentProvider { +export class HoverAccessibilityHelpProvider extends Disposable implements IAccessibleViewContentProvider { public readonly options: IAccessibleViewOptions; public readonly id = AccessibleViewProviderId.Hover; public readonly verbositySettingKey = 'accessibility.verbosity.hover'; public readonly actions: IAction[] = []; - private _onHoverContentsChanged: IDisposable | undefined; + private readonly _hoverController: HoverController | null = null; + + private _onDidChangeContent: Emitter = this._register(new Emitter()); + public onDidChangeContent: Event = this._onDidChangeContent.event; constructor( private readonly _editor: ICodeEditor, - @IAccessibleViewService private readonly _accessibleViewService: IAccessibleViewService, @IKeybindingService private readonly _keybindingService: IKeybindingService ) { + super(); this.options = { - language: this._editor.getModel()?.getLanguageId() ?? 'typescript', + language: this._editor.getModel()?.getLanguageId(), type: AccessibleViewType.View }; this.actions.push(new Action(INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL, ThemeIcon.asClassName(Codicon.add), true, () => { @@ -71,38 +82,42 @@ export class HoverAccessibilityHelpProvider implements IAccessibleViewContentPro this.actions.push(new Action(DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, ThemeIcon.asClassName(Codicon.remove), true, () => { this._editor.getAction(DECREASE_HOVER_VERBOSITY_ACTION_ID)?.run({ focus: false }); })); + this._hoverController = HoverController.get(this._editor); + if (this._hoverController) { + this._register(this._hoverController.onHoverContentsChanged(() => { + this._onDidChangeContent.fire(); + })); + } } provideContent(): string { - const content: string[] = []; - content.push(HoverAccessibilityHelpNLS.intro); - const hoverController = HoverController.get(this._editor); - if (!hoverController) { + const content: string[] = [HoverAccessibilityHelpNLS.intro]; + if (!this._hoverController) { return content.join('\n'); } - const isFocusOnExpandableMarkdownHover = hoverController.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(HoverVerbosityAction.Increase); + this._hoverController.shouldRemainOpenOnEditorMouseMoveOrLeave = true; + const isFocusOnExpandableMarkdownHover = this._hoverController.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(HoverVerbosityAction.Increase); if (isFocusOnExpandableMarkdownHover) { content.push(this._descriptionForCommand(INCREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.increaseVerbosity, HoverAccessibilityHelpNLS.increaseVerbosityNoKb)); } - const isFocusOnContractableMarkdownHover = hoverController.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(HoverVerbosityAction.Decrease); + const isFocusOnContractableMarkdownHover = this._hoverController.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(HoverVerbosityAction.Decrease); if (isFocusOnContractableMarkdownHover) { content.push(this._descriptionForCommand(DECREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.decreaseVerbosity, HoverAccessibilityHelpNLS.decreaseVerbosityNoKb)); } - const hoverContent = hoverController.lastFocusedMarkdownHoverContent(); + const hoverContent = this._hoverController.lastFocusedMarkdownHoverContent(); if (hoverContent) { content.push('\n' + HoverAccessibilityHelpNLS.hoverContent); content.push('\n' + hoverContent); } - this._onHoverContentsChanged?.dispose(); - this._onHoverContentsChanged = hoverController.onHoverContentsChanged(() => { - this._accessibleViewService.rerender(); - }); return content.join('\n'); } onClose(): void { - HoverController.get(this._editor)?.focus(); - this._onHoverContentsChanged?.dispose(); + if (!this._hoverController) { + return; + } + this._hoverController.focus(); + this._hoverController.shouldRemainOpenOnEditorMouseMoveOrLeave = false; } private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { @@ -140,4 +155,6 @@ export class ExtHoverAccessibleView implements IAccessibleViewImplentation { options: { language: 'typescript', type: AccessibleViewType.View } }; } + + dispose() { } } diff --git a/src/vs/editor/contrib/hover/browser/hoverController.ts b/src/vs/editor/contrib/hover/browser/hoverController.ts index b3a9f41027325..eeea0880c5ab3 100644 --- a/src/vs/editor/contrib/hover/browser/hoverController.ts +++ b/src/vs/editor/contrib/hover/browser/hoverController.ts @@ -23,7 +23,6 @@ import { ContentHoverWidget } from 'vs/editor/contrib/hover/browser/contentHover import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHoverController'; import 'vs/css!./hover'; import { MarginHoverWidget } from 'vs/editor/contrib/hover/browser/marginHoverWidget'; -import { AccessibleViewProviderId, IAccessibleViewService } from 'vs/platform/accessibility/browser/accessibleView'; import { Emitter } from 'vs/base/common/event'; // sticky hover widget which doesn't disappear on focus out and such @@ -55,6 +54,7 @@ export class HoverController extends Disposable implements IEditorContribution { // Other fields public static readonly ID = 'editor.contrib.hover'; + public shouldRemainOpenOnEditorMouseMoveOrLeave: boolean = false; private readonly _listenersStore = new DisposableStore(); @@ -73,8 +73,7 @@ export class HoverController extends Disposable implements IEditorContribution { constructor( private readonly _editor: ICodeEditor, @IInstantiationService private readonly _instantiationService: IInstantiationService, - @IKeybindingService private readonly _keybindingService: IKeybindingService, - @IAccessibleViewService private readonly _accessibleViewService: IAccessibleViewService, + @IKeybindingService private readonly _keybindingService: IKeybindingService ) { super(); this._reactToEditorMouseMoveRunner = this._register( @@ -182,7 +181,7 @@ export class HoverController extends Disposable implements IEditorContribution { } private _onEditorMouseLeave(mouseEvent: IPartialEditorMouseEvent): void { - if (this._isHoverAccessibleViewVisible) { + if (this.shouldRemainOpenOnEditorMouseMoveOrLeave) { return; } @@ -234,7 +233,7 @@ export class HoverController extends Disposable implements IEditorContribution { } private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { - if (this._isHoverAccessibleViewVisible) { + if (this.shouldRemainOpenOnEditorMouseMoveOrLeave) { return; } @@ -270,13 +269,6 @@ export class HoverController extends Disposable implements IEditorContribution { this._reactToEditorMouseMove(mouseEvent); } - private get _isHoverAccessibleViewVisible(): boolean { - const isAccessibleViewVisible = this._accessibleViewService.isVisible(); - const isHoverProviderUsed = this._accessibleViewService.providerId() === AccessibleViewProviderId.Hover; - const isHoverAccessibleViewVisible = isAccessibleViewVisible && isHoverProviderUsed; - return isHoverAccessibleViewVisible; - } - private _reactToEditorMouseMove(mouseEvent: IEditorMouseEvent | undefined): void { if (!mouseEvent) { diff --git a/src/vs/platform/accessibility/browser/accessibleView.ts b/src/vs/platform/accessibility/browser/accessibleView.ts index 26485155cc169..eb1d8ff8303c4 100644 --- a/src/vs/platform/accessibility/browser/accessibleView.ts +++ b/src/vs/platform/accessibility/browser/accessibleView.ts @@ -99,9 +99,6 @@ export interface IAccessibleViewService { show(provider: AccesibleViewContentProvider, position?: IPosition): void; showLastProvider(id: AccessibleViewProviderId): void; showAccessibleViewHelp(): void; - rerender(): void; - isVisible(): boolean; - providerId(): string; next(): void; previous(): void; navigateToCodeBlock(type: 'next' | 'previous'): void; @@ -139,6 +136,7 @@ export class AdvancedContentProvider implements IAccessibleViewContentProvider { public actions?: IAction[], public next?: () => void, public previous?: () => void, + public onDidChangeContent?: Event, public onKeyDown?: (e: IKeyboardEvent) => void, public getSymbols?: () => IAccessibleViewSymbol[], public onDidRequestClearLastProvider?: Event, @@ -155,6 +153,7 @@ export class ExtensionContentProvider implements IBasicContentProvider { public next?: () => void, public previous?: () => void, public actions?: IAction[], + public onDidChangeContent?: Event, ) { } } @@ -166,4 +165,5 @@ export interface IBasicContentProvider { actions?: IAction[]; previous?(): void; next?(): void; + onDidChangeContent?: Event; } diff --git a/src/vs/platform/accessibility/browser/accessibleViewRegistry.ts b/src/vs/platform/accessibility/browser/accessibleViewRegistry.ts index 9390da5a5340c..acbd7fa4ccd65 100644 --- a/src/vs/platform/accessibility/browser/accessibleViewRegistry.ts +++ b/src/vs/platform/accessibility/browser/accessibleViewRegistry.ts @@ -8,7 +8,7 @@ import { AccessibleViewType, AdvancedContentProvider, ExtensionContentProvider } import { ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -export interface IAccessibleViewImplentation { +export interface IAccessibleViewImplentation extends IDisposable { type: AccessibleViewType; priority: number; name: string; @@ -30,6 +30,7 @@ export const AccessibleViewRegistry = new class AccessibleViewRegistry { if (idx !== -1) { this._implementations.splice(idx, 1); } + implementation.dispose(); } }; } diff --git a/src/vs/workbench/browser/parts/notifications/notificationAccessibleView.ts b/src/vs/workbench/browser/parts/notifications/notificationAccessibleView.ts index 066afd7adda36..15a240f91502c 100644 --- a/src/vs/workbench/browser/parts/notifications/notificationAccessibleView.ts +++ b/src/vs/workbench/browser/parts/notifications/notificationAccessibleView.ts @@ -92,6 +92,7 @@ export class NotificationAccessibleView implements IAccessibleViewImplentation { } return getProvider(); } + dispose() { } } diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 43c22f758cb84..60a148a20fb92 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -79,7 +79,6 @@ export class AccessibleView extends Disposable { private readonly _toolbar: WorkbenchToolBar; private _currentProvider: AccesibleViewContentProvider | undefined; - private _currentContainer: HTMLElement | undefined; private _currentContent: string | undefined; private _lastProvider: AccesibleViewContentProvider | undefined; @@ -244,11 +243,12 @@ export class AccessibleView extends Disposable { if (!provider) { return; } + let viewContainer: HTMLElement | undefined; const delegate: IContextViewDelegate = { getAnchor: () => { return { x: (getActiveWindow().innerWidth / 2) - ((Math.min(this._layoutService.activeContainerDimension.width * 0.62 /* golden cut */, DIMENSIONS.MAX_WIDTH)) / 2), y: this._layoutService.activeContainerOffset.quickPickTop }; }, render: (container) => { - this._currentContainer = container; - this._currentContainer.classList.add('accessible-view-container'); + viewContainer = container; + viewContainer.classList.add('accessible-view-container'); return this._render(provider, container, showAccessibleViewHelp); }, onHide: () => { @@ -289,21 +289,10 @@ export class AccessibleView extends Disposable { if (provider instanceof ExtensionContentProvider) { this._storageService.store(`${ACCESSIBLE_VIEW_SHOWN_STORAGE_PREFIX}${provider.id}`, true, StorageScope.APPLICATION, StorageTarget.USER); } - } - - rerender(): void { - if (!this._currentProvider || !this._currentContainer) { - return; - } - this._render(this._currentProvider, this._currentContainer, false); - } - - isVisible(): boolean { - return this._accessibleViewIsShown.get() ?? false; - } + provider.onDidChangeContent?.(() => { + if (viewContainer) { this._render(provider, viewContainer, showAccessibleViewHelp); } + }); - providerId(): string { - return this._accessibleViewCurrentProviderId.get() ?? ''; } previous(): void { @@ -624,6 +613,7 @@ export class AccessibleView extends Disposable { provider.actions, provider.next, provider.previous, + provider.onDidChangeContent, provider.onKeyDown, provider.getSymbols, ) : new ExtensionContentProvider( @@ -770,15 +760,6 @@ export class AccessibleViewService extends Disposable implements IAccessibleView showLastProvider(id: AccessibleViewProviderId): void { this._accessibleView?.showLastProvider(id); } - rerender(): void { - this._accessibleView?.rerender(); - } - isVisible(): boolean { - return this._accessibleView?.isVisible() ?? false; - } - providerId(): string { - return this._accessibleView?.providerId() ?? ''; - } next(): void { this._accessibleView?.next(); } diff --git a/src/vs/workbench/contrib/accessibility/browser/extensionAccesibilityHelp.contribution.ts b/src/vs/workbench/contrib/accessibility/browser/extensionAccesibilityHelp.contribution.ts index 6161c11f1ccd8..470e9609da734 100644 --- a/src/vs/workbench/contrib/accessibility/browser/extensionAccesibilityHelp.contribution.ts +++ b/src/vs/workbench/contrib/accessibility/browser/extensionAccesibilityHelp.contribution.ts @@ -58,7 +58,8 @@ function registerAccessibilityHelpAction(keybindingService: IKeybindingService, () => helpContent.value, () => viewsService.openView(viewDescriptor.id, true) ); - } + }, + dispose: () => { }, })); disposableStore.add(keybindingService.onDidUpdateKeybindings(() => { diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts b/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts index bd6d4053c8181..db8ee595ac14a 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp.ts @@ -27,6 +27,7 @@ export class ChatAccessibilityHelp implements IAccessibleViewImplentation { const codeEditor = accessor.get(ICodeEditorService).getActiveCodeEditor() || accessor.get(ICodeEditorService).getFocusedCodeEditor(); return getChatAccessibilityHelpProvider(accessor, codeEditor ?? undefined, 'panelChat'); } + dispose() { } } export function getAccessibilityHelpText(accessor: ServicesAccessor, type: 'panelChat' | 'inlineChat'): string { diff --git a/src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.ts b/src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.ts index 2babe2b513152..4a7054df0ade8 100644 --- a/src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.ts +++ b/src/vs/workbench/contrib/chat/browser/chatResponseAccessibleView.ts @@ -94,4 +94,5 @@ export class ChatResponseAccessibleView implements IAccessibleViewImplentation { }; } } + dispose() { } } diff --git a/src/vs/workbench/contrib/codeEditor/browser/diffEditorAccessibilityHelp.ts b/src/vs/workbench/contrib/codeEditor/browser/diffEditorAccessibilityHelp.ts index dbc7ffb7a784f..3063201f149c1 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/diffEditorAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/diffEditorAccessibilityHelp.ts @@ -70,4 +70,5 @@ export class DiffEditorAccessibilityHelp implements IAccessibleViewImplentation options: { type: AccessibleViewType.Help } }; } + dispose() { } } diff --git a/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts b/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts index 2f200bc07887b..3038c32118146 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsAccessibility.ts @@ -79,4 +79,5 @@ export class CommentsAccessibilityHelp implements IAccessibleViewImplentation { getProvider(accessor: ServicesAccessor) { return accessor.get(IInstantiationService).createInstance(CommentsAccessibilityHelpProvider); } + dispose() { } } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibilityHelp.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibilityHelp.ts index d168f54f836a5..a2348928fb6c7 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibilityHelp.ts @@ -23,4 +23,5 @@ export class InlineChatAccessibilityHelp implements IAccessibleViewImplentation } return getChatAccessibilityHelpProvider(accessor, codeEditor, 'inlineChat'); } + dispose() { } } diff --git a/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.ts b/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.ts index 4cac306c23f1b..91a719e19996f 100644 --- a/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.ts +++ b/src/vs/workbench/contrib/inlineChat/browser/inlineChatAccessibleView.ts @@ -42,4 +42,5 @@ export class InlineChatAccessibleView implements IAccessibleViewImplentation { options: { type: AccessibleViewType.View } }; } + dispose() { } } diff --git a/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts b/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts index 24ceaf061fabd..5db95c856bfcb 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookAccessibilityHelp.ts @@ -30,6 +30,7 @@ export class NotebookAccessibilityHelp implements IAccessibleViewImplentation { } return; } + dispose() { } } diff --git a/src/vs/workbench/contrib/notebook/browser/notebookAccessibleView.ts b/src/vs/workbench/contrib/notebook/browser/notebookAccessibleView.ts index 3975c17bb9e5d..daa9bae804d5c 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookAccessibleView.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookAccessibleView.ts @@ -20,6 +20,7 @@ export class NotebookAccessibleView implements IAccessibleViewImplentation { const editorService = accessor.get(IEditorService); return showAccessibleOutput(editorService); } + dispose() { } } diff --git a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibilityHelp.ts b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibilityHelp.ts index f0bdac465ba84..35fcdd0410c24 100644 --- a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibilityHelp.ts +++ b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibilityHelp.ts @@ -35,6 +35,7 @@ export class TerminalChatAccessibilityHelp implements IAccessibleViewImplentatio options: { type: AccessibleViewType.Help } }; } + dispose() { } } export function getAccessibilityHelpText(accessor: ServicesAccessor): string { diff --git a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibleView.ts b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibleView.ts index 215f1fe6f05d1..2898dfde41c69 100644 --- a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibleView.ts +++ b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatAccessibleView.ts @@ -33,4 +33,5 @@ export class TerminalInlineChatAccessibleView implements IAccessibleViewImplenta options: { type: AccessibleViewType.View } }; } + dispose() { } } From 4b7792004359cc2f3d6d84c9e04c16b97098fc6b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 21 May 2024 11:21:39 +0200 Subject: [PATCH 12/30] fixing bug --- .../hover/browser/contentHoverController.ts | 16 +++-- .../hover/browser/hoverAccessibleViews.ts | 15 ++-- .../contrib/hover/browser/hoverActions.ts | 8 +-- .../contrib/hover/browser/hoverController.ts | 16 +++-- .../hover/browser/markdownHoverParticipant.ts | 70 +++++++++---------- 5 files changed, 66 insertions(+), 59 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHoverController.ts b/src/vs/editor/contrib/hover/browser/contentHoverController.ts index 0176a86d4caf2..9fd3ebe3c8955 100644 --- a/src/vs/editor/contrib/hover/browser/contentHoverController.ts +++ b/src/vs/editor/contrib/hover/browser/contentHoverController.ts @@ -360,16 +360,20 @@ export class ContentHoverController extends Disposable implements IHoverWidget { this._startShowingOrUpdateHover(new HoverRangeAnchor(0, range, undefined, undefined), mode, source, focus, null); } - public async updateLastFocusedMarkdownHoverVerbosityLevel(action: HoverVerbosityAction, focus: boolean = true): Promise { - this._markdownHoverParticipant?.updateLastFocusedMarkdownHoverPartVerbosityLevel(action, focus); + public async updateMarkdownHoverVerbosityLevel(action: HoverVerbosityAction, index: number = -1, focus: boolean = true): Promise { + this._markdownHoverParticipant?.updateMarkdownHoverVerbosityLevel(action, index, focus); } - public isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action: HoverVerbosityAction): boolean { - return this._markdownHoverParticipant?.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action) ?? false; + public focusedMarkdownHoverIndex(): number { + return this._markdownHoverParticipant?.focusedMarkdownHoverIndex() ?? -1; } - public lastFocusedMarkdownHoverContent(): string { - return this._markdownHoverParticipant?.lastFocusedMarkdownHoverContent() ?? ''; + public markdownHoverContentAtIndex(index: number): string { + return this._markdownHoverParticipant?.markdownHoverContentAtIndex(index) ?? ''; + } + + public doesMarkdownHoverAtIndexSupportVerbosityAction(index: number, action: HoverVerbosityAction): boolean { + return this._markdownHoverParticipant?.doesMarkdownHoverAtIndexSupportVerbosityAction(index, action) ?? false; } public getWidgetContent(): string | undefined { diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 1f2061a63d1ca..7c641f4a69a64 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -63,6 +63,7 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces public readonly actions: IAction[] = []; private readonly _hoverController: HoverController | null = null; + private _markdownHoverFocusedIndex: number = -1; private _onDidChangeContent: Emitter = this._register(new Emitter()); public onDidChangeContent: Event = this._onDidChangeContent.event; @@ -77,10 +78,10 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces type: AccessibleViewType.View }; this.actions.push(new Action(INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL, ThemeIcon.asClassName(Codicon.add), true, () => { - this._editor.getAction(INCREASE_HOVER_VERBOSITY_ACTION_ID)?.run({ focus: false }); + this._editor.getAction(INCREASE_HOVER_VERBOSITY_ACTION_ID)?.run({ index: this._markdownHoverFocusedIndex, focus: false }); })); this.actions.push(new Action(DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, ThemeIcon.asClassName(Codicon.remove), true, () => { - this._editor.getAction(DECREASE_HOVER_VERBOSITY_ACTION_ID)?.run({ focus: false }); + this._editor.getAction(DECREASE_HOVER_VERBOSITY_ACTION_ID)?.run({ index: this._markdownHoverFocusedIndex, focus: false }); })); this._hoverController = HoverController.get(this._editor); if (this._hoverController) { @@ -96,15 +97,18 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces return content.join('\n'); } this._hoverController.shouldRemainOpenOnEditorMouseMoveOrLeave = true; - const isFocusOnExpandableMarkdownHover = this._hoverController.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(HoverVerbosityAction.Increase); + if (this._markdownHoverFocusedIndex === -1) { + this._markdownHoverFocusedIndex = this._hoverController.focusedMarkdownHoverIndex(); + } + const isFocusOnExpandableMarkdownHover = this._hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(this._markdownHoverFocusedIndex, HoverVerbosityAction.Increase); if (isFocusOnExpandableMarkdownHover) { content.push(this._descriptionForCommand(INCREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.increaseVerbosity, HoverAccessibilityHelpNLS.increaseVerbosityNoKb)); } - const isFocusOnContractableMarkdownHover = this._hoverController.isFocusOnMarkdownHoverWhichSupportsVerbosityAction(HoverVerbosityAction.Decrease); + const isFocusOnContractableMarkdownHover = this._hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(this._markdownHoverFocusedIndex, HoverVerbosityAction.Decrease); if (isFocusOnContractableMarkdownHover) { content.push(this._descriptionForCommand(DECREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.decreaseVerbosity, HoverAccessibilityHelpNLS.decreaseVerbosityNoKb)); } - const hoverContent = this._hoverController.lastFocusedMarkdownHoverContent(); + const hoverContent = this._hoverController.markdownHoverContentAtIndex(this._markdownHoverFocusedIndex); if (hoverContent) { content.push('\n' + HoverAccessibilityHelpNLS.hoverContent); content.push('\n' + hoverContent); @@ -118,6 +122,7 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces } this._hoverController.focus(); this._hoverController.shouldRemainOpenOnEditorMouseMoveOrLeave = false; + this._markdownHoverFocusedIndex = -1; } private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { diff --git a/src/vs/editor/contrib/hover/browser/hoverActions.ts b/src/vs/editor/contrib/hover/browser/hoverActions.ts index 0a06d62abdcd0..20a5148fd742b 100644 --- a/src/vs/editor/contrib/hover/browser/hoverActions.ts +++ b/src/vs/editor/contrib/hover/browser/hoverActions.ts @@ -431,8 +431,8 @@ export class IncreaseHoverVerbosityLevel extends EditorAction { }); } - public run(accessor: ServicesAccessor, editor: ICodeEditor, args?: { focus: boolean }): void { - HoverController.get(editor)?.updateFocusedMarkdownHoverVerbosityLevel(HoverVerbosityAction.Increase, args?.focus); + public run(accessor: ServicesAccessor, editor: ICodeEditor, args?: { index: number; focus: boolean }): void { + HoverController.get(editor)?.updateMarkdownHoverVerbosityLevel(HoverVerbosityAction.Increase, args?.index, args?.focus); } } @@ -447,7 +447,7 @@ export class DecreaseHoverVerbosityLevel extends EditorAction { }); } - public run(accessor: ServicesAccessor, editor: ICodeEditor, args?: { focus: boolean }): void { - HoverController.get(editor)?.updateFocusedMarkdownHoverVerbosityLevel(HoverVerbosityAction.Decrease, args?.focus); + public run(accessor: ServicesAccessor, editor: ICodeEditor, args?: { index: number; focus: boolean }): void { + HoverController.get(editor)?.updateMarkdownHoverVerbosityLevel(HoverVerbosityAction.Decrease, args?.index, args?.focus); } } diff --git a/src/vs/editor/contrib/hover/browser/hoverController.ts b/src/vs/editor/contrib/hover/browser/hoverController.ts index eeea0880c5ab3..d6558c7fe5114 100644 --- a/src/vs/editor/contrib/hover/browser/hoverController.ts +++ b/src/vs/editor/contrib/hover/browser/hoverController.ts @@ -418,16 +418,20 @@ export class HoverController extends Disposable implements IEditorContribution { return this._contentWidget?.widget.isResizing || false; } - public updateFocusedMarkdownHoverVerbosityLevel(action: HoverVerbosityAction, focus: boolean = true): void { - this._getOrCreateContentWidget().updateLastFocusedMarkdownHoverVerbosityLevel(action, focus); + public updateMarkdownHoverVerbosityLevel(action: HoverVerbosityAction, index: number = -1, focus: boolean = true): void { + this._getOrCreateContentWidget().updateMarkdownHoverVerbosityLevel(action, index, focus); } - public isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action: HoverVerbosityAction): boolean { - return this._getOrCreateContentWidget().isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action); + public focusedMarkdownHoverIndex(): number { + return this._getOrCreateContentWidget().focusedMarkdownHoverIndex(); } - public lastFocusedMarkdownHoverContent(): string { - return this._getOrCreateContentWidget().lastFocusedMarkdownHoverContent(); + public markdownHoverContentAtIndex(index: number): string { + return this._getOrCreateContentWidget().markdownHoverContentAtIndex(index); + } + + public doesMarkdownHoverAtIndexSupportVerbosityAction(index: number, action: HoverVerbosityAction): boolean { + return this._getOrCreateContentWidget().doesMarkdownHoverAtIndexSupportVerbosityAction(index, action); } public focus(): void { diff --git a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts index 1557da9f4852b..d9060e95c54aa 100644 --- a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts +++ b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts @@ -191,16 +191,20 @@ export class MarkdownHoverParticipant implements IEditorHoverParticipant { - this._hoverFocusInfo = { - hoverPartIndex, - focusRemains: true - }; + this._register(dom.addDisposableListener(renderedMarkdown, dom.EventType.FOCUS_IN, (event: Event) => { + event.stopPropagation(); + this._focusedHoverPartIndex = hoverPartIndex; })); - disposables.add(focusTracker.onDidBlur(() => { - if (this._hoverFocusInfo?.focusRemains) { - this._hoverFocusInfo.focusRemains = false; - return; - } + this._register(dom.addDisposableListener(renderedMarkdown, dom.EventType.FOCUS_OUT, (event: Event) => { + event.stopPropagation(); + this._focusedHoverPartIndex = -1; })); return { renderedMarkdown, disposables, hoverSource }; } @@ -343,19 +336,19 @@ class MarkdownRenderedHoverParts extends Disposable { return store; } actionElement.classList.add('enabled'); - const actionFunction = () => this.updateLastFocusedMarkdownHoverPartVerbosityLevel(action); + const actionFunction = () => this.updateMarkdownHoverPartVerbosityLevel(action); store.add(new ClickAction(actionElement, actionFunction)); store.add(new KeyDownAction(actionElement, actionFunction, [KeyCode.Enter, KeyCode.Space])); return store; } - public async updateLastFocusedMarkdownHoverPartVerbosityLevel(action: HoverVerbosityAction, focus: boolean = true): Promise { + public async updateMarkdownHoverPartVerbosityLevel(action: HoverVerbosityAction, index: number = -1, focus: boolean = true): Promise { const model = this._editor.getModel(); if (!model) { return; } - const hoverLastFocusedPartIndex = this._hoverFocusInfo.hoverPartIndex; - const hoverRenderedPart = this._getRenderedHoverPartAtIndex(hoverLastFocusedPartIndex); + const indexOfInterest = index !== -1 ? index : this._focusedHoverPartIndex; + const hoverRenderedPart = this._getRenderedHoverPartAtIndex(indexOfInterest); if (!hoverRenderedPart || !hoverRenderedPart.hoverSource?.supportsVerbosityAction(action)) { return; } @@ -376,27 +369,29 @@ class MarkdownRenderedHoverParts extends Disposable { const hoverSource = new HoverSource(newHover, hoverProvider, hoverPosition); const renderedHoverPart = this._renderHoverPart( - hoverLastFocusedPartIndex, + indexOfInterest, newHover.contents, hoverSource, this._onFinishedRendering ); - this._replaceRenderedHoverPartAtIndex(hoverLastFocusedPartIndex, renderedHoverPart); + this._replaceRenderedHoverPartAtIndex(indexOfInterest, renderedHoverPart); if (focus) { - this._focusOnHoverPartWithIndex(hoverLastFocusedPartIndex); + this._focusOnHoverPartWithIndex(indexOfInterest); } this._onFinishedRendering(); } - public lastFocusedMarkdownHoverContent(): string { - const hoverLastFocusedPartIndex = this._hoverFocusInfo.hoverPartIndex; - const hoverRenderedPart = this._getRenderedHoverPartAtIndex(hoverLastFocusedPartIndex); + public markdownHoverContentAtIndex(index: number): string { + const hoverRenderedPart = this._getRenderedHoverPartAtIndex(index); return hoverRenderedPart?.renderedMarkdown.innerText ?? ''; } - public isFocusOnMarkdownHoverWhichSupportsVerbosityAction(action: HoverVerbosityAction): boolean { - const hoverFocusedPartIndex = this._hoverFocusInfo.hoverPartIndex; - const hoverRenderedPart = this._getRenderedHoverPartAtIndex(hoverFocusedPartIndex); + public focusedMarkdownHoverIndex(): number { + return this._focusedHoverPartIndex; + } + + public doesMarkdownHoverAtIndexSupportVerbosityAction(index: number, action: HoverVerbosityAction): boolean { + const hoverRenderedPart = this._getRenderedHoverPartAtIndex(index); if (!hoverRenderedPart || !hoverRenderedPart.hoverSource?.supportsVerbosityAction(action)) { return false; } @@ -416,7 +411,6 @@ class MarkdownRenderedHoverParts extends Disposable { private _focusOnHoverPartWithIndex(index: number): void { this._renderedHoverParts[index].renderedMarkdown.focus(); - this._hoverFocusInfo.focusRemains = true; } private _getRenderedHoverPartAtIndex(index: number): RenderedHoverPart | undefined { From 42a77029e77abeec8192abbff5667a4ee872b3a7 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 21 May 2024 12:32:47 +0200 Subject: [PATCH 13/30] polishing the code --- .../hover/browser/contentHoverController.ts | 2 +- .../hover/browser/hoverAccessibleViews.ts | 138 +++++++++++++----- .../contrib/hover/browser/hoverController.ts | 15 +- .../hover/browser/markdownHoverParticipant.ts | 8 +- .../accessibility/browser/accessibleView.ts | 12 +- 5 files changed, 122 insertions(+), 53 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/contentHoverController.ts b/src/vs/editor/contrib/hover/browser/contentHoverController.ts index 9fd3ebe3c8955..81ad7b790edab 100644 --- a/src/vs/editor/contrib/hover/browser/contentHoverController.ts +++ b/src/vs/editor/contrib/hover/browser/contentHoverController.ts @@ -360,7 +360,7 @@ export class ContentHoverController extends Disposable implements IHoverWidget { this._startShowingOrUpdateHover(new HoverRangeAnchor(0, range, undefined, undefined), mode, source, focus, null); } - public async updateMarkdownHoverVerbosityLevel(action: HoverVerbosityAction, index: number = -1, focus: boolean = true): Promise { + public async updateMarkdownHoverVerbosityLevel(action: HoverVerbosityAction, index?: number, focus?: boolean): Promise { this._markdownHoverParticipant?.updateMarkdownHoverVerbosityLevel(action, index, focus); } diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 7c641f4a69a64..4b3b3836dfc25 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -13,7 +13,7 @@ import { IHoverService } from 'vs/platform/hover/browser/hover'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { HoverVerbosityAction } from 'vs/editor/common/languages'; -import { DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL } from 'vs/editor/contrib/hover/browser/hoverActionIds'; +import { DECREASE_HOVER_VERBOSITY_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL } from 'vs/editor/contrib/hover/browser/hoverActionIds'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { Action, IAction } from 'vs/base/common/actions'; @@ -65,6 +65,7 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces private readonly _hoverController: HoverController | null = null; private _markdownHoverFocusedIndex: number = -1; + // Listener private _onDidChangeContent: Emitter = this._register(new Emitter()); public onDidChangeContent: Event = this._onDidChangeContent.event; @@ -73,64 +74,129 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces @IKeybindingService private readonly _keybindingService: IKeybindingService ) { super(); + this._hoverController = HoverController.get(this._editor); this.options = { language: this._editor.getModel()?.getLanguageId(), type: AccessibleViewType.View }; - this.actions.push(new Action(INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL, ThemeIcon.asClassName(Codicon.add), true, () => { - this._editor.getAction(INCREASE_HOVER_VERBOSITY_ACTION_ID)?.run({ index: this._markdownHoverFocusedIndex, focus: false }); - })); - this.actions.push(new Action(DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, ThemeIcon.asClassName(Codicon.remove), true, () => { - this._editor.getAction(DECREASE_HOVER_VERBOSITY_ACTION_ID)?.run({ index: this._markdownHoverFocusedIndex, focus: false }); - })); - this._hoverController = HoverController.get(this._editor); - if (this._hoverController) { - this._register(this._hoverController.onHoverContentsChanged(() => { - this._onDidChangeContent.fire(); - })); - } + this._initializeActions(); + this._hookListeners(); } - provideContent(): string { + public provideContent(): string { const content: string[] = [HoverAccessibilityHelpNLS.intro]; if (!this._hoverController) { return content.join('\n'); } - this._hoverController.shouldRemainOpenOnEditorMouseMoveOrLeave = true; - if (this._markdownHoverFocusedIndex === -1) { - this._markdownHoverFocusedIndex = this._hoverController.focusedMarkdownHoverIndex(); + this._updateMarkdownHoverFocusedIndex(this._hoverController); + this._hoverController.shouldKeepOpenOnEditorMouseMoveOrLeave = true; + content.push(...this._descriptionsOfVerbosityActions(this._hoverController)); + content.push(...this._descriptionOfFocusedMarkdownHover(this._hoverController)); + return content.join('\n'); + } + + public onClose(): void { + if (!this._hoverController) { + return; + } + this._markdownHoverFocusedIndex = -1; + this._hoverController.focus(); + this._hoverController.shouldKeepOpenOnEditorMouseMoveOrLeave = false; + } + + private _initializeActions(): void { + this.actions.push(this._getActionFor(HoverVerbosityAction.Increase)); + this.actions.push(this._getActionFor(HoverVerbosityAction.Decrease)); + } + + private _hookListeners(): void { + if (!this._hoverController) { + return; + } + this._register(this._hoverController.onHoverContentsChanged(() => { + this._onDidChangeContent.fire(); + })); + } + + private _getActionFor(action: HoverVerbosityAction): IAction { + let actionId: string; + let accessibleActionId: string; + let actionLabel: string; + let actionCodicon: ThemeIcon; + switch (action) { + case HoverVerbosityAction.Increase: + actionId = INCREASE_HOVER_VERBOSITY_ACTION_ID; + accessibleActionId = INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID; + actionLabel = INCREASE_HOVER_VERBOSITY_ACTION_LABEL; + actionCodicon = Codicon.add; + break; + case HoverVerbosityAction.Decrease: + actionId = DECREASE_HOVER_VERBOSITY_ACTION_ID; + accessibleActionId = DECREASE_HOVER_VERBOSITY_ACTION_ID; + actionLabel = DECREASE_HOVER_VERBOSITY_ACTION_LABEL; + actionCodicon = Codicon.remove; + break; } - const isFocusOnExpandableMarkdownHover = this._hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(this._markdownHoverFocusedIndex, HoverVerbosityAction.Increase); - if (isFocusOnExpandableMarkdownHover) { - content.push(this._descriptionForCommand(INCREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.increaseVerbosity, HoverAccessibilityHelpNLS.increaseVerbosityNoKb)); + return new Action(accessibleActionId, actionLabel, ThemeIcon.asClassName(actionCodicon), true, () => { + this._editor.getAction(actionId)?.run({ index: this._markdownHoverFocusedIndex, focus: false }); + }); + } + + private _updateMarkdownHoverFocusedIndex(hoverController: HoverController) { + if (this._markdownHoverFocusedIndex === -1) { + this._markdownHoverFocusedIndex = hoverController.focusedMarkdownHoverIndex(); } - const isFocusOnContractableMarkdownHover = this._hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(this._markdownHoverFocusedIndex, HoverVerbosityAction.Decrease); - if (isFocusOnContractableMarkdownHover) { - content.push(this._descriptionForCommand(DECREASE_HOVER_VERBOSITY_ACTION_ID, HoverAccessibilityHelpNLS.decreaseVerbosity, HoverAccessibilityHelpNLS.decreaseVerbosityNoKb)); + } + + private _descriptionsOfVerbosityActions(hoverController: HoverController): string[] { + const content: string[] = []; + const descriptionForIncreaseAction = this._descriptionOfVerbosityAction(hoverController, HoverVerbosityAction.Increase); + if (descriptionForIncreaseAction !== undefined) { + content.push(descriptionForIncreaseAction); } - const hoverContent = this._hoverController.markdownHoverContentAtIndex(this._markdownHoverFocusedIndex); - if (hoverContent) { - content.push('\n' + HoverAccessibilityHelpNLS.hoverContent); - content.push('\n' + hoverContent); + const descriptionForDecreaseAction = this._descriptionOfVerbosityAction(hoverController, HoverVerbosityAction.Decrease); + if (descriptionForDecreaseAction !== undefined) { + content.push(descriptionForDecreaseAction); } - return content.join('\n'); + return content; } - onClose(): void { - if (!this._hoverController) { + private _descriptionOfVerbosityAction(hoverController: HoverController, action: HoverVerbosityAction): string | undefined { + const isActionSupported = hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(this._markdownHoverFocusedIndex, action); + if (isActionSupported) { return; } - this._hoverController.focus(); - this._hoverController.shouldRemainOpenOnEditorMouseMoveOrLeave = false; - this._markdownHoverFocusedIndex = -1; + let actionId: string; + let descriptionWithKb: string; + let descriptionWithoutKb: string; + switch (action) { + case HoverVerbosityAction.Increase: + actionId = INCREASE_HOVER_VERBOSITY_ACTION_ID; + descriptionWithKb = HoverAccessibilityHelpNLS.increaseVerbosity; + descriptionWithoutKb = HoverAccessibilityHelpNLS.increaseVerbosityNoKb; + break; + case HoverVerbosityAction.Decrease: + actionId = DECREASE_HOVER_VERBOSITY_ACTION_ID; + descriptionWithKb = HoverAccessibilityHelpNLS.decreaseVerbosity; + descriptionWithoutKb = HoverAccessibilityHelpNLS.decreaseVerbosityNoKb; + break; + } + return this._descriptionForCommand(actionId, descriptionWithKb, descriptionWithoutKb); } private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { const kb = this._keybindingService.lookupKeybinding(commandId); - if (kb) { - return format(msg, kb.getAriaLabel()); + return kb ? format(msg, kb.getAriaLabel()) : format(noKbMsg, commandId); + } + + private _descriptionOfFocusedMarkdownHover(hoverController: HoverController): string[] { + const content: string[] = []; + const hoverContent = hoverController.markdownHoverContentAtIndex(this._markdownHoverFocusedIndex); + if (hoverContent) { + content.push('\n' + HoverAccessibilityHelpNLS.hoverContent); + content.push('\n' + hoverContent); } - return format(noKbMsg, commandId); + return content; } } diff --git a/src/vs/editor/contrib/hover/browser/hoverController.ts b/src/vs/editor/contrib/hover/browser/hoverController.ts index d6558c7fe5114..e29fa968103e5 100644 --- a/src/vs/editor/contrib/hover/browser/hoverController.ts +++ b/src/vs/editor/contrib/hover/browser/hoverController.ts @@ -54,7 +54,8 @@ export class HoverController extends Disposable implements IEditorContribution { // Other fields public static readonly ID = 'editor.contrib.hover'; - public shouldRemainOpenOnEditorMouseMoveOrLeave: boolean = false; + + public shouldKeepOpenOnEditorMouseMoveOrLeave: boolean = false; private readonly _listenersStore = new DisposableStore(); @@ -181,7 +182,7 @@ export class HoverController extends Disposable implements IEditorContribution { } private _onEditorMouseLeave(mouseEvent: IPartialEditorMouseEvent): void { - if (this.shouldRemainOpenOnEditorMouseMoveOrLeave) { + if (this.shouldKeepOpenOnEditorMouseMoveOrLeave) { return; } @@ -233,7 +234,7 @@ export class HoverController extends Disposable implements IEditorContribution { } private _onEditorMouseMove(mouseEvent: IEditorMouseEvent): void { - if (this.shouldRemainOpenOnEditorMouseMoveOrLeave) { + if (this.shouldKeepOpenOnEditorMouseMoveOrLeave) { return; } @@ -418,10 +419,6 @@ export class HoverController extends Disposable implements IEditorContribution { return this._contentWidget?.widget.isResizing || false; } - public updateMarkdownHoverVerbosityLevel(action: HoverVerbosityAction, index: number = -1, focus: boolean = true): void { - this._getOrCreateContentWidget().updateMarkdownHoverVerbosityLevel(action, index, focus); - } - public focusedMarkdownHoverIndex(): number { return this._getOrCreateContentWidget().focusedMarkdownHoverIndex(); } @@ -434,6 +431,10 @@ export class HoverController extends Disposable implements IEditorContribution { return this._getOrCreateContentWidget().doesMarkdownHoverAtIndexSupportVerbosityAction(index, action); } + public updateMarkdownHoverVerbosityLevel(action: HoverVerbosityAction, index?: number, focus?: boolean): void { + this._getOrCreateContentWidget().updateMarkdownHoverVerbosityLevel(action, index, focus); + } + public focus(): void { this._contentWidget?.focus(); } diff --git a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts index d9060e95c54aa..e71edd909f6e3 100644 --- a/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts +++ b/src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts @@ -191,10 +191,6 @@ export class MarkdownHoverParticipant implements IEditorHoverParticipant { - if (viewContainer) { this._render(provider, viewContainer, showAccessibleViewHelp); } - }); - + if (provider.onDidChangeContent) { + this._register(provider.onDidChangeContent(() => { + if (viewContainer) { this._render(provider, viewContainer, showAccessibleViewHelp); } + })); + } } previous(): void { @@ -623,7 +624,8 @@ export class AccessibleView extends Disposable { provider.onClose, provider.next, provider.previous, - provider.actions + provider.actions, + provider.onDidChangeContent, ); return lastProvider; } From 32120f19611da967d24a6e8cf3f4a10d7e1b8f02 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 21 May 2024 12:52:52 +0200 Subject: [PATCH 14/30] checking that action not supported for the early return --- src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 4b3b3836dfc25..73877ae77c489 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -163,7 +163,7 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces private _descriptionOfVerbosityAction(hoverController: HoverController, action: HoverVerbosityAction): string | undefined { const isActionSupported = hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(this._markdownHoverFocusedIndex, action); - if (isActionSupported) { + if (!isActionSupported) { return; } let actionId: string; From 676ce75bbb2b018e26016b38a285ae717ef7052d Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 21 May 2024 13:10:01 +0200 Subject: [PATCH 15/30] using disposable store instead --- .../contrib/hover/browser/hoverAccessibleViews.ts | 15 ++++++++++++--- .../accessibility/browser/accessibleView.ts | 3 +++ .../accessibility/browser/accessibleView.ts | 3 +++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 73877ae77c489..c7f786cef4832 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -20,7 +20,7 @@ import { Action, IAction } from 'vs/base/common/actions'; import { ThemeIcon } from 'vs/base/common/themables'; import { Codicon } from 'vs/base/common/codicons'; import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; namespace HoverAccessibilityHelpNLS { export const intro = localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); @@ -62,6 +62,7 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces public readonly verbositySettingKey = 'accessibility.verbosity.hover'; public readonly actions: IAction[] = []; + private readonly _disposableStore: DisposableStore = this._register(new DisposableStore()); private readonly _hoverController: HoverController | null = null; private _markdownHoverFocusedIndex: number = -1; @@ -80,7 +81,6 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces type: AccessibleViewType.View }; this._initializeActions(); - this._hookListeners(); } public provideContent(): string { @@ -95,6 +95,10 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces return content.join('\n'); } + public onOpen(): void { + this._hookListeners(); + } + public onClose(): void { if (!this._hoverController) { return; @@ -102,6 +106,7 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces this._markdownHoverFocusedIndex = -1; this._hoverController.focus(); this._hoverController.shouldKeepOpenOnEditorMouseMoveOrLeave = false; + this._unhookListeners(); } private _initializeActions(): void { @@ -113,11 +118,15 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces if (!this._hoverController) { return; } - this._register(this._hoverController.onHoverContentsChanged(() => { + this._disposableStore.add(this._hoverController.onHoverContentsChanged(() => { this._onDidChangeContent.fire(); })); } + private _unhookListeners(): void { + this._disposableStore.clear(); + } + private _getActionFor(action: HoverVerbosityAction): IAction { let actionId: string; let accessibleActionId: string; diff --git a/src/vs/platform/accessibility/browser/accessibleView.ts b/src/vs/platform/accessibility/browser/accessibleView.ts index eb1d8ff8303c4..9bcd4674147ab 100644 --- a/src/vs/platform/accessibility/browser/accessibleView.ts +++ b/src/vs/platform/accessibility/browser/accessibleView.ts @@ -133,6 +133,7 @@ export class AdvancedContentProvider implements IAccessibleViewContentProvider { public provideContent: () => string, public onClose: () => void, public verbositySettingKey: string, + public onOpen?: () => void, public actions?: IAction[], public next?: () => void, public previous?: () => void, @@ -150,6 +151,7 @@ export class ExtensionContentProvider implements IBasicContentProvider { public options: IAccessibleViewOptions, public provideContent: () => string, public onClose: () => void, + public onOpen?: () => void, public next?: () => void, public previous?: () => void, public actions?: IAction[], @@ -162,6 +164,7 @@ export interface IBasicContentProvider { options: IAccessibleViewOptions; onClose(): void; provideContent(): string; + onOpen?(): void; actions?: IAction[]; previous?(): void; next?(): void; diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index a75d519bad818..0f0e0c88a2f78 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -243,6 +243,7 @@ export class AccessibleView extends Disposable { if (!provider) { return; } + provider.onOpen?.(); let viewContainer: HTMLElement | undefined; const delegate: IContextViewDelegate = { getAnchor: () => { return { x: (getActiveWindow().innerWidth / 2) - ((Math.min(this._layoutService.activeContainerDimension.width * 0.62 /* golden cut */, DIMENSIONS.MAX_WIDTH)) / 2), y: this._layoutService.activeContainerOffset.quickPickTop }; }, @@ -611,6 +612,7 @@ export class AccessibleView extends Disposable { provider.provideContent.bind(provider), provider.onClose, provider.verbositySettingKey, + provider.onOpen, provider.actions, provider.next, provider.previous, @@ -622,6 +624,7 @@ export class AccessibleView extends Disposable { provider.options, provider.provideContent.bind(provider), provider.onClose, + provider.onOpen, provider.next, provider.previous, provider.actions, From c03726981a729bc4663d00c9e2afa79dd1f7165a Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Tue, 21 May 2024 16:22:33 +0200 Subject: [PATCH 16/30] using the appropriate string --- src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index c7f786cef4832..ec317e52d1d89 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -13,7 +13,7 @@ import { IHoverService } from 'vs/platform/hover/browser/hover'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { HoverVerbosityAction } from 'vs/editor/common/languages'; -import { DECREASE_HOVER_VERBOSITY_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL } from 'vs/editor/contrib/hover/browser/hoverActionIds'; +import { DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL } from 'vs/editor/contrib/hover/browser/hoverActionIds'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; import { Action, IAction } from 'vs/base/common/actions'; @@ -141,7 +141,7 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces break; case HoverVerbosityAction.Decrease: actionId = DECREASE_HOVER_VERBOSITY_ACTION_ID; - accessibleActionId = DECREASE_HOVER_VERBOSITY_ACTION_ID; + accessibleActionId = DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID; actionLabel = DECREASE_HOVER_VERBOSITY_ACTION_LABEL; actionCodicon = Codicon.remove; break; From 9c71082731d14f66d50b628725206ccc4f7892d8 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Wed, 22 May 2024 16:43:47 +0200 Subject: [PATCH 17/30] polishing the code --- .../hover/browser/hoverAccessibleViews.ts | 39 ++++++------------- .../contrib/hover/browser/hoverController.ts | 2 - 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index ec317e52d1d89..507968918aeee 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -20,7 +20,7 @@ import { Action, IAction } from 'vs/base/common/actions'; import { ThemeIcon } from 'vs/base/common/themables'; import { Codicon } from 'vs/base/common/codicons'; import { Emitter, Event } from 'vs/base/common/event'; -import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; +import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; namespace HoverAccessibilityHelpNLS { export const intro = localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); @@ -62,11 +62,10 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces public readonly verbositySettingKey = 'accessibility.verbosity.hover'; public readonly actions: IAction[] = []; - private readonly _disposableStore: DisposableStore = this._register(new DisposableStore()); private readonly _hoverController: HoverController | null = null; + private _onHoverContentsChanged: IDisposable | undefined; private _markdownHoverFocusedIndex: number = -1; - // Listener private _onDidChangeContent: Emitter = this._register(new Emitter()); public onDidChangeContent: Event = this._onDidChangeContent.event; @@ -75,11 +74,11 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces @IKeybindingService private readonly _keybindingService: IKeybindingService ) { super(); - this._hoverController = HoverController.get(this._editor); this.options = { language: this._editor.getModel()?.getLanguageId(), type: AccessibleViewType.View }; + this._hoverController = HoverController.get(this._editor); this._initializeActions(); } @@ -88,15 +87,20 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces if (!this._hoverController) { return content.join('\n'); } - this._updateMarkdownHoverFocusedIndex(this._hoverController); - this._hoverController.shouldKeepOpenOnEditorMouseMoveOrLeave = true; content.push(...this._descriptionsOfVerbosityActions(this._hoverController)); content.push(...this._descriptionOfFocusedMarkdownHover(this._hoverController)); return content.join('\n'); } public onOpen(): void { - this._hookListeners(); + if (!this._hoverController) { + return; + } + this._hoverController.shouldKeepOpenOnEditorMouseMoveOrLeave = true; + this._markdownHoverFocusedIndex = this._hoverController.focusedMarkdownHoverIndex(); + this._onHoverContentsChanged = this._register(this._hoverController.onHoverContentsChanged(() => { + this._onDidChangeContent.fire(); + })); } public onClose(): void { @@ -106,7 +110,7 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces this._markdownHoverFocusedIndex = -1; this._hoverController.focus(); this._hoverController.shouldKeepOpenOnEditorMouseMoveOrLeave = false; - this._unhookListeners(); + this._onHoverContentsChanged?.dispose(); } private _initializeActions(): void { @@ -114,19 +118,6 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces this.actions.push(this._getActionFor(HoverVerbosityAction.Decrease)); } - private _hookListeners(): void { - if (!this._hoverController) { - return; - } - this._disposableStore.add(this._hoverController.onHoverContentsChanged(() => { - this._onDidChangeContent.fire(); - })); - } - - private _unhookListeners(): void { - this._disposableStore.clear(); - } - private _getActionFor(action: HoverVerbosityAction): IAction { let actionId: string; let accessibleActionId: string; @@ -151,12 +142,6 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces }); } - private _updateMarkdownHoverFocusedIndex(hoverController: HoverController) { - if (this._markdownHoverFocusedIndex === -1) { - this._markdownHoverFocusedIndex = hoverController.focusedMarkdownHoverIndex(); - } - } - private _descriptionsOfVerbosityActions(hoverController: HoverController): string[] { const content: string[] = []; const descriptionForIncreaseAction = this._descriptionOfVerbosityAction(hoverController, HoverVerbosityAction.Increase); diff --git a/src/vs/editor/contrib/hover/browser/hoverController.ts b/src/vs/editor/contrib/hover/browser/hoverController.ts index e29fa968103e5..293902db46d36 100644 --- a/src/vs/editor/contrib/hover/browser/hoverController.ts +++ b/src/vs/editor/contrib/hover/browser/hoverController.ts @@ -48,11 +48,9 @@ const enum HoverWidgetType { export class HoverController extends Disposable implements IEditorContribution { - // Listeners private readonly _onHoverContentsChanged = this._register(new Emitter()); public readonly onHoverContentsChanged = this._onHoverContentsChanged.event; - // Other fields public static readonly ID = 'editor.contrib.hover'; public shouldKeepOpenOnEditorMouseMoveOrLeave: boolean = false; From 1f450dd535c6c71b37a15e20bf48434e11b7badf Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 23 May 2024 09:49:19 +0200 Subject: [PATCH 18/30] using instead the type help and the resolved keybindings --- .../hover/browser/hoverAccessibleViews.ts | 34 ++++--------------- 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 507968918aeee..c371b3957a9ea 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { format } from 'vs/base/common/strings'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController'; import { AccessibleViewType, AccessibleViewProviderId, AdvancedContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions } from 'vs/platform/accessibility/browser/accessibleView'; @@ -11,7 +10,6 @@ import { IAccessibleViewImplentation } from 'vs/platform/accessibility/browser/a import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IHoverService } from 'vs/platform/hover/browser/hover'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { HoverVerbosityAction } from 'vs/editor/common/languages'; import { DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL } from 'vs/editor/contrib/hover/browser/hoverActionIds'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -24,16 +22,14 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; namespace HoverAccessibilityHelpNLS { export const intro = localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); - export const increaseVerbosity = localize('increaseVerbosity', "- The focused hover part verbosity level can be increased ({0})."); - export const increaseVerbosityNoKb = localize('increaseVerbosityNoKb', "- The focused hover part verbosity level can be increased, which is currently not triggerable via keybinding."); - export const decreaseVerbosity = localize('decreaseVerbosity', "- The focused hover part verbosity level can be decreased ({0})."); - export const decreaseVerbosityNoKb = localize('decreaseVerbosityNoKb', "- The focused hover part verbosity level can be decreased, which is currently not triggerable via keybinding."); + export const increaseVerbosity = localize('increaseVerbosity', "- The focused hover part verbosity level can be increased with the Increase Hover Verbosity command.", INCREASE_HOVER_VERBOSITY_ACTION_ID); + export const decreaseVerbosity = localize('decreaseVerbosity', "- The focused hover part verbosity level can be decreased with the Decrease Hover Verbosity command.", DECREASE_HOVER_VERBOSITY_ACTION_ID); export const hoverContent = localize('contentHover', "The last focused hover content is the following."); } export class HoverAccessibleView implements IAccessibleViewImplentation { - readonly type = AccessibleViewType.View; + readonly type = AccessibleViewType.Help; readonly priority = 95; readonly name = 'hover'; readonly when = EditorContextKeys.hoverFocused; @@ -70,13 +66,12 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces public onDidChangeContent: Event = this._onDidChangeContent.event; constructor( - private readonly _editor: ICodeEditor, - @IKeybindingService private readonly _keybindingService: IKeybindingService + private readonly _editor: ICodeEditor ) { super(); this.options = { language: this._editor.getModel()?.getLanguageId(), - type: AccessibleViewType.View + type: AccessibleViewType.Help }; this._hoverController = HoverController.get(this._editor); this._initializeActions(); @@ -160,27 +155,12 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces if (!isActionSupported) { return; } - let actionId: string; - let descriptionWithKb: string; - let descriptionWithoutKb: string; switch (action) { case HoverVerbosityAction.Increase: - actionId = INCREASE_HOVER_VERBOSITY_ACTION_ID; - descriptionWithKb = HoverAccessibilityHelpNLS.increaseVerbosity; - descriptionWithoutKb = HoverAccessibilityHelpNLS.increaseVerbosityNoKb; - break; + return HoverAccessibilityHelpNLS.increaseVerbosity; case HoverVerbosityAction.Decrease: - actionId = DECREASE_HOVER_VERBOSITY_ACTION_ID; - descriptionWithKb = HoverAccessibilityHelpNLS.decreaseVerbosity; - descriptionWithoutKb = HoverAccessibilityHelpNLS.decreaseVerbosityNoKb; - break; + return HoverAccessibilityHelpNLS.decreaseVerbosity; } - return this._descriptionForCommand(actionId, descriptionWithKb, descriptionWithoutKb); - } - - private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { - const kb = this._keybindingService.lookupKeybinding(commandId); - return kb ? format(msg, kb.getAriaLabel()) : format(noKbMsg, commandId); } private _descriptionOfFocusedMarkdownHover(hoverController: HoverController): string[] { From 1b600280a0c61719731d93c4c9c56169fc560454 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Thu, 23 May 2024 09:59:05 +0200 Subject: [PATCH 19/30] hiding also on the `onDidBlurEditorWidget` firing --- .../contrib/accessibility/browser/accessibleView.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 2c44a5236df32..3c7d5fe26e86c 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -567,9 +567,9 @@ export class AccessibleView extends Disposable { }); this._updateToolbar(this._currentProvider.actions, provider.options.type); - const hide = (e: KeyboardEvent | IKeyboardEvent): void => { + const hide = (e?: KeyboardEvent | IKeyboardEvent): void => { provider.onClose(); - e.stopPropagation(); + e?.stopPropagation(); this._contextViewService.hideContextView(); this._updateContextKeys(provider, false); this._lastProvider = undefined; @@ -600,7 +600,7 @@ export class AccessibleView extends Disposable { })); disposableStore.add(this._editorWidget.onDidBlurEditorWidget(() => { if (!isActiveElement(this._toolbar.getElement())) { - this._contextViewService.hideContextView(); + hide(); } })); disposableStore.add(this._editorWidget.onDidContentSizeChange(() => this._layout())); From 12f0cf6143715b3972e15270b4eb113edbdfbf88 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 23 May 2024 11:12:10 -0700 Subject: [PATCH 20/30] Revert "using instead the type help and the resolved keybindings" This reverts commit 1f450dd535c6c71b37a15e20bf48434e11b7badf. --- .../hover/browser/hoverAccessibleViews.ts | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index c371b3957a9ea..507968918aeee 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; +import { format } from 'vs/base/common/strings'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController'; import { AccessibleViewType, AccessibleViewProviderId, AdvancedContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions } from 'vs/platform/accessibility/browser/accessibleView'; @@ -10,6 +11,7 @@ import { IAccessibleViewImplentation } from 'vs/platform/accessibility/browser/a import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IHoverService } from 'vs/platform/hover/browser/hover'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { HoverVerbosityAction } from 'vs/editor/common/languages'; import { DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL } from 'vs/editor/contrib/hover/browser/hoverActionIds'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -22,14 +24,16 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; namespace HoverAccessibilityHelpNLS { export const intro = localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); - export const increaseVerbosity = localize('increaseVerbosity', "- The focused hover part verbosity level can be increased with the Increase Hover Verbosity command.", INCREASE_HOVER_VERBOSITY_ACTION_ID); - export const decreaseVerbosity = localize('decreaseVerbosity', "- The focused hover part verbosity level can be decreased with the Decrease Hover Verbosity command.", DECREASE_HOVER_VERBOSITY_ACTION_ID); + export const increaseVerbosity = localize('increaseVerbosity', "- The focused hover part verbosity level can be increased ({0})."); + export const increaseVerbosityNoKb = localize('increaseVerbosityNoKb', "- The focused hover part verbosity level can be increased, which is currently not triggerable via keybinding."); + export const decreaseVerbosity = localize('decreaseVerbosity', "- The focused hover part verbosity level can be decreased ({0})."); + export const decreaseVerbosityNoKb = localize('decreaseVerbosityNoKb', "- The focused hover part verbosity level can be decreased, which is currently not triggerable via keybinding."); export const hoverContent = localize('contentHover', "The last focused hover content is the following."); } export class HoverAccessibleView implements IAccessibleViewImplentation { - readonly type = AccessibleViewType.Help; + readonly type = AccessibleViewType.View; readonly priority = 95; readonly name = 'hover'; readonly when = EditorContextKeys.hoverFocused; @@ -66,12 +70,13 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces public onDidChangeContent: Event = this._onDidChangeContent.event; constructor( - private readonly _editor: ICodeEditor + private readonly _editor: ICodeEditor, + @IKeybindingService private readonly _keybindingService: IKeybindingService ) { super(); this.options = { language: this._editor.getModel()?.getLanguageId(), - type: AccessibleViewType.Help + type: AccessibleViewType.View }; this._hoverController = HoverController.get(this._editor); this._initializeActions(); @@ -155,12 +160,27 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces if (!isActionSupported) { return; } + let actionId: string; + let descriptionWithKb: string; + let descriptionWithoutKb: string; switch (action) { case HoverVerbosityAction.Increase: - return HoverAccessibilityHelpNLS.increaseVerbosity; + actionId = INCREASE_HOVER_VERBOSITY_ACTION_ID; + descriptionWithKb = HoverAccessibilityHelpNLS.increaseVerbosity; + descriptionWithoutKb = HoverAccessibilityHelpNLS.increaseVerbosityNoKb; + break; case HoverVerbosityAction.Decrease: - return HoverAccessibilityHelpNLS.decreaseVerbosity; + actionId = DECREASE_HOVER_VERBOSITY_ACTION_ID; + descriptionWithKb = HoverAccessibilityHelpNLS.decreaseVerbosity; + descriptionWithoutKb = HoverAccessibilityHelpNLS.decreaseVerbosityNoKb; + break; } + return this._descriptionForCommand(actionId, descriptionWithKb, descriptionWithoutKb); + } + + private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { + const kb = this._keybindingService.lookupKeybinding(commandId); + return kb ? format(msg, kb.getAriaLabel()) : format(noKbMsg, commandId); } private _descriptionOfFocusedMarkdownHover(hoverController: HoverController): string[] { From 592fca05546fa9c80c0ea05fcf887ffe16f52d25 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 23 May 2024 11:45:07 -0700 Subject: [PATCH 21/30] use hover accessible view, provide custom help --- .../hover/browser/hoverAccessibleViews.ts | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 507968918aeee..077968d2841f0 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -38,7 +38,7 @@ export class HoverAccessibleView implements IAccessibleViewImplentation { readonly name = 'hover'; readonly when = EditorContextKeys.hoverFocused; - private _provider: HoverAccessibilityHelpProvider | undefined; + private _provider: HoverAccessibleViewProvider | undefined; getProvider(accessor: ServicesAccessor): AdvancedContentProvider | undefined { const codeEditorService = accessor.get(ICodeEditorService); @@ -46,7 +46,11 @@ export class HoverAccessibleView implements IAccessibleViewImplentation { if (!codeEditor) { return undefined; } - this._provider = accessor.get(IInstantiationService).createInstance(HoverAccessibilityHelpProvider, codeEditor); + const hoverController = HoverController.get(codeEditor); + if (!hoverController?.getWidgetContent()) { + return undefined; + } + this._provider = accessor.get(IInstantiationService).createInstance(HoverAccessibleViewProvider, codeEditor, hoverController); return this._provider; } @@ -55,14 +59,13 @@ export class HoverAccessibleView implements IAccessibleViewImplentation { } } -export class HoverAccessibilityHelpProvider extends Disposable implements IAccessibleViewContentProvider { +export class HoverAccessibleViewProvider extends Disposable implements IAccessibleViewContentProvider { public readonly options: IAccessibleViewOptions; public readonly id = AccessibleViewProviderId.Hover; public readonly verbositySettingKey = 'accessibility.verbosity.hover'; public readonly actions: IAction[] = []; - private readonly _hoverController: HoverController | null = null; private _onHoverContentsChanged: IDisposable | undefined; private _markdownHoverFocusedIndex: number = -1; @@ -71,27 +74,29 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces constructor( private readonly _editor: ICodeEditor, + private readonly _hoverController: HoverController, @IKeybindingService private readonly _keybindingService: IKeybindingService ) { super(); this.options = { language: this._editor.getModel()?.getLanguageId(), - type: AccessibleViewType.View + type: AccessibleViewType.View, + customHelp: this.customHelp.bind(this) }; - this._hoverController = HoverController.get(this._editor); this._initializeActions(); } - public provideContent(): string { + public customHelp(): string { const content: string[] = [HoverAccessibilityHelpNLS.intro]; - if (!this._hoverController) { - return content.join('\n'); - } - content.push(...this._descriptionsOfVerbosityActions(this._hoverController)); - content.push(...this._descriptionOfFocusedMarkdownHover(this._hoverController)); + content.push(...this._descriptionsOfVerbosityActions()); + content.push(...this._descriptionOfFocusedMarkdownHover()); return content.join('\n'); } + public provideContent(): string { + return this._hoverController.getWidgetContent() || ''; + } + public onOpen(): void { if (!this._hoverController) { return; @@ -142,21 +147,21 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces }); } - private _descriptionsOfVerbosityActions(hoverController: HoverController): string[] { + private _descriptionsOfVerbosityActions(): string[] { const content: string[] = []; - const descriptionForIncreaseAction = this._descriptionOfVerbosityAction(hoverController, HoverVerbosityAction.Increase); + const descriptionForIncreaseAction = this._descriptionOfVerbosityAction(HoverVerbosityAction.Increase); if (descriptionForIncreaseAction !== undefined) { content.push(descriptionForIncreaseAction); } - const descriptionForDecreaseAction = this._descriptionOfVerbosityAction(hoverController, HoverVerbosityAction.Decrease); + const descriptionForDecreaseAction = this._descriptionOfVerbosityAction(HoverVerbosityAction.Decrease); if (descriptionForDecreaseAction !== undefined) { content.push(descriptionForDecreaseAction); } return content; } - private _descriptionOfVerbosityAction(hoverController: HoverController, action: HoverVerbosityAction): string | undefined { - const isActionSupported = hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(this._markdownHoverFocusedIndex, action); + private _descriptionOfVerbosityAction(action: HoverVerbosityAction): string | undefined { + const isActionSupported = this._hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(this._markdownHoverFocusedIndex, action); if (!isActionSupported) { return; } @@ -183,9 +188,9 @@ export class HoverAccessibilityHelpProvider extends Disposable implements IAcces return kb ? format(msg, kb.getAriaLabel()) : format(noKbMsg, commandId); } - private _descriptionOfFocusedMarkdownHover(hoverController: HoverController): string[] { + private _descriptionOfFocusedMarkdownHover(): string[] { const content: string[] = []; - const hoverContent = hoverController.markdownHoverContentAtIndex(this._markdownHoverFocusedIndex); + const hoverContent = this._hoverController.markdownHoverContentAtIndex(this._markdownHoverFocusedIndex); if (hoverContent) { content.push('\n' + HoverAccessibilityHelpNLS.hoverContent); content.push('\n' + hoverContent); From bcd5d953261ea13a28f1bd9fdfee661d0493d3ac Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 23 May 2024 11:53:05 -0700 Subject: [PATCH 22/30] Revert "Revert "using instead the type help and the resolved keybindings"" This reverts commit 12f0cf6143715b3972e15270b4eb113edbdfbf88. --- .../hover/browser/hoverAccessibleViews.ts | 28 +++---------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 077968d2841f0..a9a61872e2742 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { localize } from 'vs/nls'; -import { format } from 'vs/base/common/strings'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController'; import { AccessibleViewType, AccessibleViewProviderId, AdvancedContentProvider, IAccessibleViewContentProvider, IAccessibleViewOptions } from 'vs/platform/accessibility/browser/accessibleView'; @@ -11,7 +10,6 @@ import { IAccessibleViewImplentation } from 'vs/platform/accessibility/browser/a import { IContextViewService } from 'vs/platform/contextview/browser/contextView'; import { IHoverService } from 'vs/platform/hover/browser/hover'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; -import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { HoverVerbosityAction } from 'vs/editor/common/languages'; import { DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_ID, DECREASE_HOVER_VERBOSITY_ACTION_LABEL, INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_ID, INCREASE_HOVER_VERBOSITY_ACTION_LABEL } from 'vs/editor/contrib/hover/browser/hoverActionIds'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; @@ -24,10 +22,8 @@ import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; namespace HoverAccessibilityHelpNLS { export const intro = localize('intro', "The hover widget is focused. Press the Tab key to cycle through the hover parts."); - export const increaseVerbosity = localize('increaseVerbosity', "- The focused hover part verbosity level can be increased ({0})."); - export const increaseVerbosityNoKb = localize('increaseVerbosityNoKb', "- The focused hover part verbosity level can be increased, which is currently not triggerable via keybinding."); - export const decreaseVerbosity = localize('decreaseVerbosity', "- The focused hover part verbosity level can be decreased ({0})."); - export const decreaseVerbosityNoKb = localize('decreaseVerbosityNoKb', "- The focused hover part verbosity level can be decreased, which is currently not triggerable via keybinding."); + export const increaseVerbosity = localize('increaseVerbosity', "- The focused hover part verbosity level can be increased with the Increase Hover Verbosity command.", INCREASE_HOVER_VERBOSITY_ACTION_ID); + export const decreaseVerbosity = localize('decreaseVerbosity', "- The focused hover part verbosity level can be decreased with the Decrease Hover Verbosity command.", DECREASE_HOVER_VERBOSITY_ACTION_ID); export const hoverContent = localize('contentHover', "The last focused hover content is the following."); } @@ -75,7 +71,6 @@ export class HoverAccessibleViewProvider extends Disposable implements IAccessib constructor( private readonly _editor: ICodeEditor, private readonly _hoverController: HoverController, - @IKeybindingService private readonly _keybindingService: IKeybindingService ) { super(); this.options = { @@ -165,27 +160,12 @@ export class HoverAccessibleViewProvider extends Disposable implements IAccessib if (!isActionSupported) { return; } - let actionId: string; - let descriptionWithKb: string; - let descriptionWithoutKb: string; switch (action) { case HoverVerbosityAction.Increase: - actionId = INCREASE_HOVER_VERBOSITY_ACTION_ID; - descriptionWithKb = HoverAccessibilityHelpNLS.increaseVerbosity; - descriptionWithoutKb = HoverAccessibilityHelpNLS.increaseVerbosityNoKb; - break; + return HoverAccessibilityHelpNLS.increaseVerbosity; case HoverVerbosityAction.Decrease: - actionId = DECREASE_HOVER_VERBOSITY_ACTION_ID; - descriptionWithKb = HoverAccessibilityHelpNLS.decreaseVerbosity; - descriptionWithoutKb = HoverAccessibilityHelpNLS.decreaseVerbosityNoKb; - break; + return HoverAccessibilityHelpNLS.decreaseVerbosity; } - return this._descriptionForCommand(actionId, descriptionWithKb, descriptionWithoutKb); - } - - private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string { - const kb = this._keybindingService.lookupKeybinding(commandId); - return kb ? format(msg, kb.getAriaLabel()) : format(noKbMsg, commandId); } private _descriptionOfFocusedMarkdownHover(): string[] { From 992e464cfdd47ddc02c87733c6d87c8562ddd994 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Thu, 23 May 2024 12:43:56 -0700 Subject: [PATCH 23/30] add HoverAccessibilityHelp, BaseHoverAccessibleViewProvider --- .../hover/browser/hoverAccessibleViews.ts | 153 +++++++++++------- .../hover/browser/hoverContribution.ts | 3 +- .../accessibility/browser/accessibleView.ts | 24 +-- 3 files changed, 113 insertions(+), 67 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index a9a61872e2742..7e7dfd9ac1b91 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -55,43 +55,49 @@ export class HoverAccessibleView implements IAccessibleViewImplentation { } } -export class HoverAccessibleViewProvider extends Disposable implements IAccessibleViewContentProvider { +export class HoverAccessibilityHelp implements IAccessibleViewImplentation { - public readonly options: IAccessibleViewOptions; - public readonly id = AccessibleViewProviderId.Hover; - public readonly verbositySettingKey = 'accessibility.verbosity.hover'; - public readonly actions: IAction[] = []; + readonly priority = 100; + readonly name = 'hover'; + readonly type = AccessibleViewType.Help; + readonly when = EditorContextKeys.hoverVisible; + + private _provider: HoverAccessibleViewProvider | undefined; + + getProvider(accessor: ServicesAccessor): AdvancedContentProvider | undefined { + const codeEditorService = accessor.get(ICodeEditorService); + const codeEditor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); + if (!codeEditor) { + throw new Error('No active or focused code editor'); + } + const hoverController = HoverController.get(codeEditor); + if (!hoverController) { + return; + } + return accessor.get(IInstantiationService).createInstance(HoverAccessibilityHelpProvider, hoverController); + } + dispose(): void { + this._provider?.dispose(); + } +} + + +abstract class BaseHoverAccessibleViewProvider extends Disposable implements IAccessibleViewContentProvider { + abstract provideContent(): string; + abstract options: IAccessibleViewOptions; + id = AccessibleViewProviderId.Hover; + verbositySettingKey = 'accessibility.verbosity.hover'; private _onHoverContentsChanged: IDisposable | undefined; - private _markdownHoverFocusedIndex: number = -1; + protected _markdownHoverFocusedIndex: number = -1; private _onDidChangeContent: Emitter = this._register(new Emitter()); public onDidChangeContent: Event = this._onDidChangeContent.event; - constructor( - private readonly _editor: ICodeEditor, - private readonly _hoverController: HoverController, + protected readonly _hoverController: HoverController, ) { super(); - this.options = { - language: this._editor.getModel()?.getLanguageId(), - type: AccessibleViewType.View, - customHelp: this.customHelp.bind(this) - }; - this._initializeActions(); } - - public customHelp(): string { - const content: string[] = [HoverAccessibilityHelpNLS.intro]; - content.push(...this._descriptionsOfVerbosityActions()); - content.push(...this._descriptionOfFocusedMarkdownHover()); - return content.join('\n'); - } - - public provideContent(): string { - return this._hoverController.getWidgetContent() || ''; - } - public onOpen(): void { if (!this._hoverController) { return; @@ -112,36 +118,22 @@ export class HoverAccessibleViewProvider extends Disposable implements IAccessib this._hoverController.shouldKeepOpenOnEditorMouseMoveOrLeave = false; this._onHoverContentsChanged?.dispose(); } +} - private _initializeActions(): void { - this.actions.push(this._getActionFor(HoverVerbosityAction.Increase)); - this.actions.push(this._getActionFor(HoverVerbosityAction.Decrease)); - } - private _getActionFor(action: HoverVerbosityAction): IAction { - let actionId: string; - let accessibleActionId: string; - let actionLabel: string; - let actionCodicon: ThemeIcon; - switch (action) { - case HoverVerbosityAction.Increase: - actionId = INCREASE_HOVER_VERBOSITY_ACTION_ID; - accessibleActionId = INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID; - actionLabel = INCREASE_HOVER_VERBOSITY_ACTION_LABEL; - actionCodicon = Codicon.add; - break; - case HoverVerbosityAction.Decrease: - actionId = DECREASE_HOVER_VERBOSITY_ACTION_ID; - accessibleActionId = DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID; - actionLabel = DECREASE_HOVER_VERBOSITY_ACTION_LABEL; - actionCodicon = Codicon.remove; - break; - } - return new Action(accessibleActionId, actionLabel, ThemeIcon.asClassName(actionCodicon), true, () => { - this._editor.getAction(actionId)?.run({ index: this._markdownHoverFocusedIndex, focus: false }); - }); +export class HoverAccessibilityHelpProvider extends BaseHoverAccessibleViewProvider implements IAccessibleViewContentProvider { + options: IAccessibleViewOptions = { type: AccessibleViewType.Help }; + provideContent(): string { + const content: string[] = [HoverAccessibilityHelpNLS.intro]; + content.push(...this._descriptionsOfVerbosityActions()); + content.push(...this._descriptionOfFocusedMarkdownHover()); + return content.join('\n'); + } + constructor( + hoverController: HoverController, + ) { + super(hoverController); } - private _descriptionsOfVerbosityActions(): string[] { const content: string[] = []; const descriptionForIncreaseAction = this._descriptionOfVerbosityAction(HoverVerbosityAction.Increase); @@ -179,6 +171,59 @@ export class HoverAccessibleViewProvider extends Disposable implements IAccessib } } +export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider implements IAccessibleViewContentProvider { + + public readonly options: IAccessibleViewOptions; + public readonly actions: IAction[] = []; + + constructor( + private readonly _editor: ICodeEditor, + hoverController: HoverController, + ) { + super(hoverController); + const helpProvider = this._register(new HoverAccessibilityHelpProvider(hoverController)); + this.options = { + language: this._editor.getModel()?.getLanguageId(), + type: AccessibleViewType.View, + customHelp: helpProvider.provideContent.bind(helpProvider) + }; + this._initializeActions(); + } + + public provideContent(): string { + return this._hoverController.getWidgetContent() || ''; + } + + private _initializeActions(): void { + this.actions.push(this._getActionFor(HoverVerbosityAction.Increase)); + this.actions.push(this._getActionFor(HoverVerbosityAction.Decrease)); + } + + private _getActionFor(action: HoverVerbosityAction): IAction { + let actionId: string; + let accessibleActionId: string; + let actionLabel: string; + let actionCodicon: ThemeIcon; + switch (action) { + case HoverVerbosityAction.Increase: + actionId = INCREASE_HOVER_VERBOSITY_ACTION_ID; + accessibleActionId = INCREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID; + actionLabel = INCREASE_HOVER_VERBOSITY_ACTION_LABEL; + actionCodicon = Codicon.add; + break; + case HoverVerbosityAction.Decrease: + actionId = DECREASE_HOVER_VERBOSITY_ACTION_ID; + accessibleActionId = DECREASE_HOVER_VERBOSITY_ACCESSIBLE_ACTION_ID; + actionLabel = DECREASE_HOVER_VERBOSITY_ACTION_LABEL; + actionCodicon = Codicon.remove; + break; + } + return new Action(accessibleActionId, actionLabel, ThemeIcon.asClassName(actionCodicon), true, () => { + this._editor.getAction(actionId)?.run({ index: this._markdownHoverFocusedIndex, focus: false }); + }); + } +} + export class ExtHoverAccessibleView implements IAccessibleViewImplentation { readonly type = AccessibleViewType.View; diff --git a/src/vs/editor/contrib/hover/browser/hoverContribution.ts b/src/vs/editor/contrib/hover/browser/hoverContribution.ts index 629b189f2dbde..bf24cdc1c69b1 100644 --- a/src/vs/editor/contrib/hover/browser/hoverContribution.ts +++ b/src/vs/editor/contrib/hover/browser/hoverContribution.ts @@ -13,7 +13,7 @@ import { MarkerHoverParticipant } from 'vs/editor/contrib/hover/browser/markerHo import { HoverController } from 'vs/editor/contrib/hover/browser/hoverController'; import 'vs/css!./hover'; import { AccessibleViewRegistry } from 'vs/platform/accessibility/browser/accessibleViewRegistry'; -import { ExtHoverAccessibleView, HoverAccessibleView } from 'vs/editor/contrib/hover/browser/hoverAccessibleViews'; +import { ExtHoverAccessibleView, HoverAccessibilityHelp, HoverAccessibleView } from 'vs/editor/contrib/hover/browser/hoverAccessibleViews'; registerEditorContribution(HoverController.ID, HoverController, EditorContributionInstantiation.BeforeFirstInteraction); registerEditorAction(ShowOrFocusHoverAction); @@ -41,4 +41,5 @@ registerThemingParticipant((theme, collector) => { } }); AccessibleViewRegistry.register(new HoverAccessibleView()); +AccessibleViewRegistry.register(new HoverAccessibilityHelp()); AccessibleViewRegistry.register(new ExtHoverAccessibleView()); diff --git a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts index 3c7d5fe26e86c..813cbd360d9dd 100644 --- a/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts +++ b/src/vs/workbench/contrib/accessibility/browser/accessibleView.ts @@ -656,25 +656,25 @@ export class AccessibleView extends Disposable { provider.id, provider.options, provider.provideContent.bind(provider), - provider.onClose, + provider.onClose.bind(provider), provider.verbositySettingKey, - provider.onOpen, + provider.onOpen?.bind(provider), provider.actions, - provider.next, - provider.previous, - provider.onDidChangeContent, - provider.onKeyDown, - provider.getSymbols, + provider.next?.bind(provider), + provider.previous?.bind(provider), + provider.onDidChangeContent?.bind(provider), + provider.onKeyDown?.bind(provider), + provider.getSymbols?.bind(provider), ) : new ExtensionContentProvider( provider.id, provider.options, provider.provideContent.bind(provider), - provider.onClose, - provider.onOpen, - provider.next, - provider.previous, + provider.onClose.bind(provider), + provider.onOpen?.bind(provider), + provider.next?.bind(provider), + provider.previous?.bind(provider), provider.actions, - provider.onDidChangeContent, + provider.onDidChangeContent?.bind(provider), ); return lastProvider; } From 82b9f4918ecb7d6613800a6317a7571d395a4d80 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 May 2024 09:40:31 +0200 Subject: [PATCH 24/30] polishing the code --- .../hover/browser/hoverAccessibleViews.ts | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 7e7dfd9ac1b91..6af07022ec496 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -40,11 +40,11 @@ export class HoverAccessibleView implements IAccessibleViewImplentation { const codeEditorService = accessor.get(ICodeEditorService); const codeEditor = codeEditorService.getActiveCodeEditor() || codeEditorService.getFocusedCodeEditor(); if (!codeEditor) { - return undefined; + throw new Error('No active or focused code editor'); } const hoverController = HoverController.get(codeEditor); - if (!hoverController?.getWidgetContent()) { - return undefined; + if (!hoverController) { + return; } this._provider = accessor.get(IInstantiationService).createInstance(HoverAccessibleViewProvider, codeEditor, hoverController); return this._provider; @@ -84,20 +84,23 @@ export class HoverAccessibilityHelp implements IAccessibleViewImplentation { abstract class BaseHoverAccessibleViewProvider extends Disposable implements IAccessibleViewContentProvider { + abstract provideContent(): string; abstract options: IAccessibleViewOptions; - id = AccessibleViewProviderId.Hover; - verbositySettingKey = 'accessibility.verbosity.hover'; + public id = AccessibleViewProviderId.Hover; + public verbositySettingKey = 'accessibility.verbosity.hover'; private _onHoverContentsChanged: IDisposable | undefined; protected _markdownHoverFocusedIndex: number = -1; private _onDidChangeContent: Emitter = this._register(new Emitter()); public onDidChangeContent: Event = this._onDidChangeContent.event; + constructor( protected readonly _hoverController: HoverController, ) { super(); } + public onOpen(): void { if (!this._hoverController) { return; @@ -122,18 +125,22 @@ abstract class BaseHoverAccessibleViewProvider extends Disposable implements IAc export class HoverAccessibilityHelpProvider extends BaseHoverAccessibleViewProvider implements IAccessibleViewContentProvider { - options: IAccessibleViewOptions = { type: AccessibleViewType.Help }; + + public readonly options: IAccessibleViewOptions = { type: AccessibleViewType.Help }; + + constructor( + hoverController: HoverController, + ) { + super(hoverController); + } + provideContent(): string { const content: string[] = [HoverAccessibilityHelpNLS.intro]; content.push(...this._descriptionsOfVerbosityActions()); content.push(...this._descriptionOfFocusedMarkdownHover()); return content.join('\n'); } - constructor( - hoverController: HoverController, - ) { - super(hoverController); - } + private _descriptionsOfVerbosityActions(): string[] { const content: string[] = []; const descriptionForIncreaseAction = this._descriptionOfVerbosityAction(HoverVerbosityAction.Increase); From 107b1ab28adc6fead057213bb028c3c7a541946b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 May 2024 10:23:08 +0200 Subject: [PATCH 25/30] polishing the code --- .../editor/contrib/hover/browser/hoverAccessibleViews.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 6af07022ec496..71a49a046a16e 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -135,7 +135,8 @@ export class HoverAccessibilityHelpProvider extends BaseHoverAccessibleViewProvi } provideContent(): string { - const content: string[] = [HoverAccessibilityHelpNLS.intro]; + const content: string[] = []; + content.push(HoverAccessibilityHelpNLS.intro); content.push(...this._descriptionsOfVerbosityActions()); content.push(...this._descriptionOfFocusedMarkdownHover()); return content.join('\n'); @@ -167,7 +168,7 @@ export class HoverAccessibilityHelpProvider extends BaseHoverAccessibleViewProvi } } - private _descriptionOfFocusedMarkdownHover(): string[] { + protected _descriptionOfFocusedMarkdownHover(): string[] { const content: string[] = []; const hoverContent = this._hoverController.markdownHoverContentAtIndex(this._markdownHoverFocusedIndex); if (hoverContent) { @@ -198,7 +199,8 @@ export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider } public provideContent(): string { - return this._hoverController.getWidgetContent() || ''; + const hoverContent = this._hoverController.markdownHoverContentAtIndex(this._markdownHoverFocusedIndex); + return hoverContent.length > 0 ? hoverContent : HoverAccessibilityHelpNLS.intro; } private _initializeActions(): void { From 80870b3851f4fc7005b8e5be4e0bdabc8ce43b3b Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 May 2024 10:46:38 +0200 Subject: [PATCH 26/30] provide content at a specific index from the hover accessibility help provider --- .../hover/browser/hoverAccessibleViews.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 71a49a046a16e..55937a57bd464 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -135,28 +135,32 @@ export class HoverAccessibilityHelpProvider extends BaseHoverAccessibleViewProvi } provideContent(): string { + return this.provideContentAtIndex(this._markdownHoverFocusedIndex); + } + + provideContentAtIndex(index: number): string { const content: string[] = []; content.push(HoverAccessibilityHelpNLS.intro); - content.push(...this._descriptionsOfVerbosityActions()); - content.push(...this._descriptionOfFocusedMarkdownHover()); + content.push(...this._descriptionsOfVerbosityActionsForIndex(index)); + content.push(...this._descriptionOfFocusedMarkdownHoverAtIndex(index)); return content.join('\n'); } - private _descriptionsOfVerbosityActions(): string[] { + private _descriptionsOfVerbosityActionsForIndex(index: number): string[] { const content: string[] = []; - const descriptionForIncreaseAction = this._descriptionOfVerbosityAction(HoverVerbosityAction.Increase); + const descriptionForIncreaseAction = this._descriptionOfVerbosityActionForIndex(HoverVerbosityAction.Increase, index); if (descriptionForIncreaseAction !== undefined) { content.push(descriptionForIncreaseAction); } - const descriptionForDecreaseAction = this._descriptionOfVerbosityAction(HoverVerbosityAction.Decrease); + const descriptionForDecreaseAction = this._descriptionOfVerbosityActionForIndex(HoverVerbosityAction.Decrease, index); if (descriptionForDecreaseAction !== undefined) { content.push(descriptionForDecreaseAction); } return content; } - private _descriptionOfVerbosityAction(action: HoverVerbosityAction): string | undefined { - const isActionSupported = this._hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(this._markdownHoverFocusedIndex, action); + private _descriptionOfVerbosityActionForIndex(action: HoverVerbosityAction, index: number): string | undefined { + const isActionSupported = this._hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(index, action); if (!isActionSupported) { return; } @@ -168,9 +172,9 @@ export class HoverAccessibilityHelpProvider extends BaseHoverAccessibleViewProvi } } - protected _descriptionOfFocusedMarkdownHover(): string[] { + protected _descriptionOfFocusedMarkdownHoverAtIndex(index: number): string[] { const content: string[] = []; - const hoverContent = this._hoverController.markdownHoverContentAtIndex(this._markdownHoverFocusedIndex); + const hoverContent = this._hoverController.markdownHoverContentAtIndex(index); if (hoverContent) { content.push('\n' + HoverAccessibilityHelpNLS.hoverContent); content.push('\n' + hoverContent); @@ -193,7 +197,7 @@ export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider this.options = { language: this._editor.getModel()?.getLanguageId(), type: AccessibleViewType.View, - customHelp: helpProvider.provideContent.bind(helpProvider) + customHelp: () => { return helpProvider.provideContentAtIndex(this._markdownHoverFocusedIndex); } }; this._initializeActions(); } From c2b2b7887e3ef032b95f8bf3f0736c98ca2944e7 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 May 2024 10:54:29 +0200 Subject: [PATCH 27/30] introducing method _initializeOptions --- .../hover/browser/hoverAccessibleViews.ts | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 55937a57bd464..a805322c402f0 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -185,21 +185,16 @@ export class HoverAccessibilityHelpProvider extends BaseHoverAccessibleViewProvi export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider implements IAccessibleViewContentProvider { - public readonly options: IAccessibleViewOptions; + public readonly options: IAccessibleViewOptions = { type: AccessibleViewType.View }; public readonly actions: IAction[] = []; constructor( - private readonly _editor: ICodeEditor, + editor: ICodeEditor, hoverController: HoverController, ) { super(hoverController); - const helpProvider = this._register(new HoverAccessibilityHelpProvider(hoverController)); - this.options = { - language: this._editor.getModel()?.getLanguageId(), - type: AccessibleViewType.View, - customHelp: () => { return helpProvider.provideContentAtIndex(this._markdownHoverFocusedIndex); } - }; - this._initializeActions(); + this._initializeActions(editor); + this._initializeOptions(editor, hoverController); } public provideContent(): string { @@ -207,12 +202,12 @@ export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider return hoverContent.length > 0 ? hoverContent : HoverAccessibilityHelpNLS.intro; } - private _initializeActions(): void { - this.actions.push(this._getActionFor(HoverVerbosityAction.Increase)); - this.actions.push(this._getActionFor(HoverVerbosityAction.Decrease)); + private _initializeActions(editor: ICodeEditor): void { + this.actions.push(this._getActionFor(editor, HoverVerbosityAction.Increase)); + this.actions.push(this._getActionFor(editor, HoverVerbosityAction.Decrease)); } - private _getActionFor(action: HoverVerbosityAction): IAction { + private _getActionFor(editor: ICodeEditor, action: HoverVerbosityAction): IAction { let actionId: string; let accessibleActionId: string; let actionLabel: string; @@ -232,9 +227,15 @@ export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider break; } return new Action(accessibleActionId, actionLabel, ThemeIcon.asClassName(actionCodicon), true, () => { - this._editor.getAction(actionId)?.run({ index: this._markdownHoverFocusedIndex, focus: false }); + editor.getAction(actionId)?.run({ index: this._markdownHoverFocusedIndex, focus: false }); }); } + + private _initializeOptions(editor: ICodeEditor, hoverController: HoverController): void { + const helpProvider = this._register(new HoverAccessibilityHelpProvider(hoverController)); + this.options.language = editor.getModel()?.getLanguageId(); + this.options.customHelp = () => { return helpProvider.provideContentAtIndex(this._markdownHoverFocusedIndex); }; + } } export class ExtHoverAccessibleView implements IAccessibleViewImplentation { From 56f21d53ba8296448700a62b40692631b6ba4198 Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 May 2024 10:57:13 +0200 Subject: [PATCH 28/30] using readonly where possible --- .../contrib/hover/browser/hoverAccessibleViews.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index a805322c402f0..b0a6d10456392 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -87,13 +87,15 @@ abstract class BaseHoverAccessibleViewProvider extends Disposable implements IAc abstract provideContent(): string; abstract options: IAccessibleViewOptions; - public id = AccessibleViewProviderId.Hover; - public verbositySettingKey = 'accessibility.verbosity.hover'; - private _onHoverContentsChanged: IDisposable | undefined; - protected _markdownHoverFocusedIndex: number = -1; - private _onDidChangeContent: Emitter = this._register(new Emitter()); - public onDidChangeContent: Event = this._onDidChangeContent.event; + public readonly id = AccessibleViewProviderId.Hover; + public readonly verbositySettingKey = 'accessibility.verbosity.hover'; + + private readonly _onDidChangeContent: Emitter = this._register(new Emitter()); + public readonly onDidChangeContent: Event = this._onDidChangeContent.event; + + protected _markdownHoverFocusedIndex: number = -1; + private _onHoverContentsChanged: IDisposable | undefined; constructor( protected readonly _hoverController: HoverController, From b8615680a65b68063707709fe49d7c97007540bb Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 May 2024 10:58:39 +0200 Subject: [PATCH 29/30] using public everywhere --- .../hover/browser/hoverAccessibleViews.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index b0a6d10456392..079ff9b4ac63b 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -29,10 +29,10 @@ namespace HoverAccessibilityHelpNLS { export class HoverAccessibleView implements IAccessibleViewImplentation { - readonly type = AccessibleViewType.View; - readonly priority = 95; - readonly name = 'hover'; - readonly when = EditorContextKeys.hoverFocused; + public readonly type = AccessibleViewType.View; + public readonly priority = 95; + public readonly name = 'hover'; + public readonly when = EditorContextKeys.hoverFocused; private _provider: HoverAccessibleViewProvider | undefined; @@ -57,10 +57,10 @@ export class HoverAccessibleView implements IAccessibleViewImplentation { export class HoverAccessibilityHelp implements IAccessibleViewImplentation { - readonly priority = 100; - readonly name = 'hover'; - readonly type = AccessibleViewType.Help; - readonly when = EditorContextKeys.hoverVisible; + public readonly priority = 100; + public readonly name = 'hover'; + public readonly type = AccessibleViewType.Help; + public readonly when = EditorContextKeys.hoverVisible; private _provider: HoverAccessibleViewProvider | undefined; @@ -242,9 +242,9 @@ export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider export class ExtHoverAccessibleView implements IAccessibleViewImplentation { - readonly type = AccessibleViewType.View; - readonly priority = 90; - readonly name = 'extension-hover'; + public readonly type = AccessibleViewType.View; + public readonly priority = 90; + public readonly name = 'extension-hover'; getProvider(accessor: ServicesAccessor): AdvancedContentProvider | undefined { const contextViewService = accessor.get(IContextViewService); From 09f5d26db100dda8a84c38f762c3e3e4959edd4e Mon Sep 17 00:00:00 2001 From: Aiday Marlen Kyzy Date: Fri, 24 May 2024 11:32:20 +0200 Subject: [PATCH 30/30] using a getter for the actions --- .../hover/browser/hoverAccessibleViews.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts index 079ff9b4ac63b..5cf65a5b39924 100644 --- a/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts +++ b/src/vs/editor/contrib/hover/browser/hoverAccessibleViews.ts @@ -188,15 +188,13 @@ export class HoverAccessibilityHelpProvider extends BaseHoverAccessibleViewProvi export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider implements IAccessibleViewContentProvider { public readonly options: IAccessibleViewOptions = { type: AccessibleViewType.View }; - public readonly actions: IAction[] = []; constructor( - editor: ICodeEditor, + private readonly _editor: ICodeEditor, hoverController: HoverController, ) { super(hoverController); - this._initializeActions(editor); - this._initializeOptions(editor, hoverController); + this._initializeOptions(this._editor, hoverController); } public provideContent(): string { @@ -204,9 +202,11 @@ export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider return hoverContent.length > 0 ? hoverContent : HoverAccessibilityHelpNLS.intro; } - private _initializeActions(editor: ICodeEditor): void { - this.actions.push(this._getActionFor(editor, HoverVerbosityAction.Increase)); - this.actions.push(this._getActionFor(editor, HoverVerbosityAction.Decrease)); + public get actions(): IAction[] { + const actions: IAction[] = []; + actions.push(this._getActionFor(this._editor, HoverVerbosityAction.Increase)); + actions.push(this._getActionFor(this._editor, HoverVerbosityAction.Decrease)); + return actions; } private _getActionFor(editor: ICodeEditor, action: HoverVerbosityAction): IAction { @@ -228,7 +228,8 @@ export class HoverAccessibleViewProvider extends BaseHoverAccessibleViewProvider actionCodicon = Codicon.remove; break; } - return new Action(accessibleActionId, actionLabel, ThemeIcon.asClassName(actionCodicon), true, () => { + const actionEnabled = this._hoverController.doesMarkdownHoverAtIndexSupportVerbosityAction(this._markdownHoverFocusedIndex, action); + return new Action(accessibleActionId, actionLabel, ThemeIcon.asClassName(actionCodicon), actionEnabled, () => { editor.getAction(actionId)?.run({ index: this._markdownHoverFocusedIndex, focus: false }); }); }