提交 74eacec3 编写于 作者: J Joao Moreno

extension viewlet keyboard accessibility

fixes #8621
上级 b904d13d
......@@ -7,7 +7,9 @@ import 'vs/css!./list';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { isNumber } from 'vs/base/common/types';
import * as DOM from 'vs/base/browser/dom';
import Event, { Emitter, mapEvent, EventBufferer } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import Event, { Emitter, mapEvent, EventBufferer, filterEvent } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IDelegate, IRenderer, IListMouseEvent, IFocusChangeEvent, ISelectionChangeEvent } from './list';
import { ListView, IListViewOptions } from './listView';
......@@ -120,15 +122,23 @@ class FocusTrait<T> extends Trait<T> {
class Controller<T> implements IDisposable {
private toDispose: IDisposable[];
private disposables: IDisposable[];
constructor(
private list: List<T>,
private view: ListView<T>
) {
this.toDispose = [];
this.toDispose.push(view.addListener('mousedown', e => this.onMouseDown(e)));
this.toDispose.push(view.addListener('click', e => this.onClick(e)));
this.disposables = [];
this.disposables.push(view.addListener('mousedown', e => this.onMouseDown(e)));
this.disposables.push(view.addListener('click', e => this.onClick(e)));
const onRawKeyDown = domEvent(view.domNode, 'keydown');
const onKeyDown = mapEvent(onRawKeyDown, e => new StandardKeyboardEvent(e));
filterEvent(onKeyDown, e => e.keyCode === KeyCode.Enter)(this.onEnter, this, this.disposables);
filterEvent(onKeyDown, e => e.keyCode === KeyCode.UpArrow)(this.onUpArrow, this, this.disposables);
filterEvent(onKeyDown, e => e.keyCode === KeyCode.DownArrow)(this.onDownArrow, this, this.disposables);
filterEvent(onKeyDown, e => e.keyCode === KeyCode.PageUp)(this.onPageUpArrow, this, this.disposables);
filterEvent(onKeyDown, e => e.keyCode === KeyCode.PageDown)(this.onPageDownArrow, this, this.disposables);
}
private onMouseDown(e: IListMouseEvent<T>) {
......@@ -144,8 +154,46 @@ class Controller<T> implements IDisposable {
this.list.setSelection(e.index);
}
private onEnter(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.setSelection(...this.list.getFocus());
}
private onUpArrow(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.focusPrevious();
this.list.reveal(this.list.getFocus()[0]);
this.view.domNode.focus();
}
private onDownArrow(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.focusNext();
this.list.reveal(this.list.getFocus()[0]);
this.view.domNode.focus();
}
private onPageUpArrow(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.focusPreviousPage();
this.list.reveal(this.list.getFocus()[0]);
this.view.domNode.focus();
}
private onPageDownArrow(e: StandardKeyboardEvent): void {
e.preventDefault();
e.stopPropagation();
this.list.focusNextPage();
this.list.reveal(this.list.getFocus()[0]);
this.view.domNode.focus();
}
dispose() {
this.toDispose = dispose(this.toDispose);
this.disposables = dispose(this.disposables);
}
}
......
......@@ -39,7 +39,6 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
private extensionsBox: HTMLElement;
private list: PagedList<IExtension>;
private disposables: IDisposable[] = [];
private focusInvokedByTab: boolean;
private clearAction: ClearExtensionsInputAction;
constructor(
......@@ -80,7 +79,6 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
const onDownArrow = filterEvent(onKeyDown, e => e.keyCode === KeyCode.DownArrow);
const onPageUpArrow = filterEvent(onKeyDown, e => e.keyCode === KeyCode.PageUp);
const onPageDownArrow = filterEvent(onKeyDown, e => e.keyCode === KeyCode.PageDown);
const onTab = filterEvent(onKeyDown, e => e.keyCode === KeyCode.Tab);
onEnter(this.onEnter, this, this.disposables);
onEscape(this.onEscape, this, this.disposables);
......@@ -88,19 +86,10 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
onDownArrow(this.onDownArrow, this, this.disposables);
onPageUpArrow(this.onPageUpArrow, this, this.disposables);
onPageDownArrow(this.onPageDownArrow, this, this.disposables);
onTab(this.onTab, this, this.disposables);
const onInput = domEvent(this.searchBox, 'input');
onInput(() => this.triggerSearch(), null, this.disposables);
this.list.onDOMFocus(focusEvent => {
// Allow tab to move focus out of search box #7966
if (!this.focusInvokedByTab) {
this.searchBox.focus();
}
this.focusInvokedByTab = false;
}, null, this.disposables);
const onSelectedExtension = filterEvent(mapEvent(this.list.onSelectionChange, e => e.elements[0]), e => !!e);
onSelectedExtension(this.onExtensionSelected, this, this.disposables);
......@@ -229,10 +218,6 @@ export class ExtensionsViewlet extends Viewlet implements IExtensionsViewlet {
this.list.reveal(this.list.getFocus()[0]);
}
private onTab(): void {
this.focusInvokedByTab = true;
}
dispose(): void {
this.disposables = dispose(this.disposables);
super.dispose();
......
......@@ -50,6 +50,11 @@
background-color: #6DA770;
}
.monaco-action-bar .action-item:not(.disabled) .action-label:focus.extension-action.install,
.monaco-action-bar .action-item:not(.disabled) .action-label:focus.extension-action.update {
outline: 1px solid rgb(14, 99, 156) !important;
}
.monaco-action-bar .action-item .action-label.extension-action.enable {
color: white;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册