mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-25 15:35:43 +01:00
Add NativeResolvedKeybinding & tests
This commit is contained in:
@@ -410,4 +410,6 @@ export const enum KeyboardEventCode {
|
||||
MailReply,
|
||||
MailForward,
|
||||
MailSend,
|
||||
|
||||
MAX_VALUE
|
||||
}
|
||||
@@ -6,10 +6,12 @@
|
||||
'use strict';
|
||||
|
||||
import { OperatingSystem } from 'vs/base/common/platform';
|
||||
import { SimpleKeybinding, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { SimpleKeybinding, KeyCode, ResolvedKeybinding, Keybinding, KeyCodeUtils } from 'vs/base/common/keyCodes';
|
||||
import { KeyboardEventCode, KeyboardEventCodeUtils } from 'vs/workbench/services/keybinding/common/keyboardEventCode';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
|
||||
import { IHTMLContentElement } from 'vs/base/common/htmlContent';
|
||||
import { PrintableKeypress, UILabelProvider, AriaLabelProvider } from 'vs/platform/keybinding/common/keybindingLabels';
|
||||
|
||||
export interface IKeyMapping {
|
||||
value: string;
|
||||
@@ -43,6 +45,7 @@ function cannotMapSimpleKeybinding(keybinding: SimpleKeybinding, OS: OperatingSy
|
||||
* -1 if a KeyCode => keyboardEvent.code mapping depends on kb layout.
|
||||
*/
|
||||
const IMMUTABLE_KEY_CODE_TO_CODE: KeyboardEventCode[] = [];
|
||||
const IMMUTABLE_CODE_TO_KEY_CODE: KeyCode[] = [];
|
||||
|
||||
/**
|
||||
* Chars that will be remapped.
|
||||
@@ -130,7 +133,7 @@ const enum ModifierState {
|
||||
ShiftAltGr = 3
|
||||
}
|
||||
|
||||
export class HardwareKeyPress {
|
||||
export class HardwareKeypress {
|
||||
readonly ctrlKey: boolean;
|
||||
readonly shiftKey: boolean;
|
||||
readonly altKey: boolean;
|
||||
@@ -144,35 +147,131 @@ export class HardwareKeyPress {
|
||||
this.metaKey = metaKey;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public toPrintableKeypress(key: string): PrintableKeypress {
|
||||
return new PrintableKeypress(this.ctrlKey, this.shiftKey, this.altKey, this.metaKey, key);
|
||||
}
|
||||
}
|
||||
|
||||
export class NativeResolvedKeybinding extends ResolvedKeybinding {
|
||||
|
||||
private readonly _mapper: KeyboardMapper;
|
||||
private readonly _OS: OperatingSystem;
|
||||
private readonly _firstPart: HardwareKeypress;
|
||||
private readonly _chordPart: HardwareKeypress;
|
||||
|
||||
constructor(mapper: KeyboardMapper, OS: OperatingSystem, firstPart: HardwareKeypress, chordPart: HardwareKeypress) {
|
||||
super();
|
||||
this._mapper = mapper;
|
||||
this._OS = OS;
|
||||
this._firstPart = firstPart;
|
||||
this._chordPart = chordPart;
|
||||
}
|
||||
|
||||
public getLabel(): string {
|
||||
let firstPart = this._firstPart.toPrintableKeypress(this._mapper.getUILabelForHardwareCode(this._firstPart.code));
|
||||
let chordPart = this._chordPart ? this._chordPart.toPrintableKeypress(this._mapper.getUILabelForHardwareCode(this._chordPart.code)) : null;
|
||||
|
||||
return UILabelProvider.toLabel2(firstPart, chordPart, this._OS);
|
||||
}
|
||||
|
||||
public getAriaLabel(): string {
|
||||
let firstPart = this._firstPart.toPrintableKeypress(this._mapper.getAriaLabelForHardwareCode(this._firstPart.code));
|
||||
let chordPart = this._chordPart ? this._chordPart.toPrintableKeypress(this._mapper.getAriaLabelForHardwareCode(this._chordPart.code)) : null;
|
||||
|
||||
return AriaLabelProvider.toLabel2(firstPart, chordPart, this._OS);
|
||||
}
|
||||
|
||||
public getHTMLLabel(): IHTMLContentElement[] {
|
||||
let firstPart = this._firstPart.toPrintableKeypress(this._mapper.getUILabelForHardwareCode(this._firstPart.code));
|
||||
let chordPart = this._chordPart ? this._chordPart.toPrintableKeypress(this._mapper.getUILabelForHardwareCode(this._chordPart.code)) : null;
|
||||
|
||||
return UILabelProvider.toHTMLLabel2(firstPart, chordPart, this._OS);
|
||||
}
|
||||
|
||||
public getElectronAccelerator(): string {
|
||||
throw new Error('TODO!');
|
||||
// const usResolvedKeybinding = new USLayoutResolvedKeybinding(this._actual, OS);
|
||||
|
||||
// if (OS === OperatingSystem.Windows) {
|
||||
// // electron menus always do the correct rendering on Windows
|
||||
// return usResolvedKeybinding.getElectronAccelerator();
|
||||
// }
|
||||
|
||||
// let usLabel = usResolvedKeybinding.getLabel();
|
||||
// let label = this.getLabel();
|
||||
// if (usLabel !== label) {
|
||||
// // electron menus are incorrect in rendering (linux) and in rendering and interpreting (mac)
|
||||
// // for non US standard keyboard layouts
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// return usResolvedKeybinding.getElectronAccelerator();
|
||||
}
|
||||
|
||||
public getUserSettingsLabel(): string {
|
||||
throw new Error('TODO!');
|
||||
// return KeybindingIO.writeKeybinding(this._actual, OS);
|
||||
}
|
||||
}
|
||||
|
||||
interface IHardwareCodeMapping {
|
||||
value: number;
|
||||
withShift: number;
|
||||
withAltGr: number;
|
||||
withShiftAltGr: number;
|
||||
|
||||
valueIsDeadKey: boolean;
|
||||
withShiftIsDeadKey: boolean;
|
||||
withAltGrIsDeadKey: boolean;
|
||||
withShiftAltGrIsDeadKey: boolean;
|
||||
}
|
||||
|
||||
export class KeyboardMapper {
|
||||
|
||||
private readonly _OS: OperatingSystem;
|
||||
private readonly _remapChars2: HardwareKeyPress[][];
|
||||
private readonly _remapChars: HardwareKeypress[][];
|
||||
private readonly _mappings: IHardwareCodeMapping[];
|
||||
|
||||
constructor(mapping: IKeyboardMapping, OS: OperatingSystem) {
|
||||
constructor(mappings: IKeyboardMapping, OS: OperatingSystem) {
|
||||
|
||||
this._remapChars2 = [];
|
||||
this._remapChars = [];
|
||||
let maxCharCode = REMAP_CHARS.reduce((prev, curr) => Math.max(prev, curr));
|
||||
for (let i = 0; i <= maxCharCode; i++) {
|
||||
this._remapChars2[i] = null;
|
||||
this._remapChars[i] = null;
|
||||
}
|
||||
|
||||
for (let strCode in mapping) {
|
||||
if (mapping.hasOwnProperty(strCode)) {
|
||||
this._mappings = [];
|
||||
for (let strCode in mappings) {
|
||||
if (mappings.hasOwnProperty(strCode)) {
|
||||
const code = KeyboardEventCodeUtils.toEnum(strCode);
|
||||
if (code === KeyboardEventCode.None) {
|
||||
log(`Unknown code ${strCode} in mapping.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const results = mapping[strCode];
|
||||
const mapping = mappings[strCode];
|
||||
const value = KeyboardMapper._getCharCode(mapping.value);
|
||||
const withShift = KeyboardMapper._getCharCode(mapping.withShift);
|
||||
const withAltGr = KeyboardMapper._getCharCode(mapping.withAltGr);
|
||||
const withShiftAltGr = KeyboardMapper._getCharCode(mapping.withShiftAltGr);
|
||||
|
||||
this._register(code, false, false, false, KeyboardMapper._getCharCode(results.value));
|
||||
this._register(code, false, true, false, KeyboardMapper._getCharCode(results.withShift));
|
||||
this._register(code, true, false, true, KeyboardMapper._getCharCode(results.withAltGr));
|
||||
this._register(code, true, true, true, KeyboardMapper._getCharCode(results.withShiftAltGr));
|
||||
this._mappings[code] = {
|
||||
value: value,
|
||||
withShift: withShift,
|
||||
withAltGr: withAltGr,
|
||||
withShiftAltGr: withShiftAltGr,
|
||||
|
||||
valueIsDeadKey: mapping.valueIsDeadKey,
|
||||
withShiftIsDeadKey: mapping.withShiftIsDeadKey,
|
||||
withAltGrIsDeadKey: mapping.withAltGrIsDeadKey,
|
||||
withShiftAltGrIsDeadKey: mapping.withShiftAltGrIsDeadKey,
|
||||
};
|
||||
|
||||
this._register(code, false, false, false, value);
|
||||
this._register(code, false, true, false, withShift);
|
||||
this._register(code, true, false, true, withAltGr);
|
||||
this._register(code, true, true, true, withShiftAltGr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +279,7 @@ export class KeyboardMapper {
|
||||
|
||||
for (let i = 0; i < REMAP_CHARS.length; i++) {
|
||||
const charCode = REMAP_CHARS[i];
|
||||
let combos = this._remapChars2[charCode];
|
||||
let combos = this._remapChars[charCode];
|
||||
if (combos === null) {
|
||||
log(`Could not find any key combination producing '${String.fromCharCode(charCode)}'`);
|
||||
} else if (combos.length > 1) {
|
||||
@@ -238,15 +337,15 @@ export class KeyboardMapper {
|
||||
return;
|
||||
}
|
||||
|
||||
let entry = new HardwareKeyPress(ctrlKey, shiftKey, altKey, false, code);
|
||||
let entry = new HardwareKeypress(ctrlKey, shiftKey, altKey, false, code);
|
||||
|
||||
if (this._remapChars2[charCode] === null) {
|
||||
if (this._remapChars[charCode] === null) {
|
||||
// no duplicates so far
|
||||
this._remapChars2[charCode] = [entry];
|
||||
this._remapChars[charCode] = [entry];
|
||||
return;
|
||||
}
|
||||
|
||||
const list = this._remapChars2[charCode];
|
||||
const list = this._remapChars[charCode];
|
||||
// Do not register if it already sits under the same code
|
||||
for (let i = 0, len = list.length; i < len; i++) {
|
||||
if (list[i].code === code) {
|
||||
@@ -256,7 +355,7 @@ export class KeyboardMapper {
|
||||
list.push(entry);
|
||||
}
|
||||
|
||||
private _doMapSimpleKeybinding(source: SimpleKeybinding, keyCombo: HardwareKeyPress, ctrlKey: boolean, altKey: boolean, metaKey: boolean, charCode: number): HardwareKeyPress {
|
||||
private _doMapSimpleKeybinding(source: SimpleKeybinding, keyCombo: HardwareKeypress, ctrlKey: boolean, altKey: boolean, metaKey: boolean, charCode: number): HardwareKeypress {
|
||||
if ((keyCombo.ctrlKey && ctrlKey) || (keyCombo.altKey && altKey)) {
|
||||
cannotMapSimpleKeybinding(source, this._OS, `ctrl or alt modifiers are needed to produce '${String.fromCharCode(charCode)}'`);
|
||||
return null;
|
||||
@@ -270,13 +369,13 @@ export class KeyboardMapper {
|
||||
altKey = true;
|
||||
}
|
||||
|
||||
return new HardwareKeyPress(ctrlKey, shiftKey, altKey, metaKey, keyCombo.code);
|
||||
return new HardwareKeypress(ctrlKey, shiftKey, altKey, metaKey, keyCombo.code);
|
||||
}
|
||||
|
||||
private _mapSimpleKeybinding(source: SimpleKeybinding, ctrlKey: boolean, altKey: boolean, metaKey: boolean, charCode: number): HardwareKeyPress[] {
|
||||
const keyCombos = this._remapChars2[charCode];
|
||||
private _mapSimpleKeybinding(source: SimpleKeybinding, ctrlKey: boolean, altKey: boolean, metaKey: boolean, charCode: number): HardwareKeypress[] {
|
||||
const keyCombos = this._remapChars[charCode];
|
||||
|
||||
let result: HardwareKeyPress[] = [], resultLen = 0;
|
||||
let result: HardwareKeypress[] = [], resultLen = 0;
|
||||
if (keyCombos !== null) {
|
||||
for (let i = 0, len = keyCombos.length; i < len; i++) {
|
||||
const keyCombo = keyCombos[i];
|
||||
@@ -292,7 +391,7 @@ export class KeyboardMapper {
|
||||
return result;
|
||||
}
|
||||
|
||||
public mapSimpleKeybinding(keybinding: SimpleKeybinding): HardwareKeyPress[] {
|
||||
public mapSimpleKeybinding(keybinding: SimpleKeybinding): HardwareKeypress[] {
|
||||
const ctrlCmd = keybinding.hasCtrlCmd();
|
||||
const winCtrl = keybinding.hasWinCtrl();
|
||||
|
||||
@@ -304,7 +403,7 @@ export class KeyboardMapper {
|
||||
|
||||
if (IMMUTABLE_KEY_CODE_TO_CODE[keyCode] !== -1) {
|
||||
const keyboardEventCode = IMMUTABLE_KEY_CODE_TO_CODE[keyCode];
|
||||
return [new HardwareKeyPress(ctrlKey, shiftKey, altKey, metaKey, keyboardEventCode)];
|
||||
return [new HardwareKeypress(ctrlKey, shiftKey, altKey, metaKey, keyboardEventCode)];
|
||||
}
|
||||
|
||||
let desiredCharCode = 0;
|
||||
@@ -362,18 +461,90 @@ export class KeyboardMapper {
|
||||
|
||||
return this._mapSimpleKeybinding(keybinding, ctrlKey, altKey, metaKey, desiredCharCode);
|
||||
}
|
||||
|
||||
public getUILabelForHardwareCode(code: KeyboardEventCode): string {
|
||||
return this._getLabelForHardwareCode(code, true);
|
||||
}
|
||||
|
||||
public getAriaLabelForHardwareCode(code: KeyboardEventCode): string {
|
||||
return this._getLabelForHardwareCode(code, false);
|
||||
}
|
||||
|
||||
private _getLabelForHardwareCode(code: KeyboardEventCode, isUI: boolean): string {
|
||||
if (isUI && this._OS === OperatingSystem.Macintosh) {
|
||||
switch (code) {
|
||||
case KeyboardEventCode.ArrowLeft:
|
||||
return '←';
|
||||
case KeyboardEventCode.ArrowUp:
|
||||
return '↑';
|
||||
case KeyboardEventCode.ArrowRight:
|
||||
return '→';
|
||||
case KeyboardEventCode.ArrowDown:
|
||||
return '↓';
|
||||
}
|
||||
}
|
||||
if (IMMUTABLE_CODE_TO_KEY_CODE[code] !== -1) {
|
||||
const keyCode = IMMUTABLE_CODE_TO_KEY_CODE[code];
|
||||
return KeyCodeUtils.toString(keyCode);
|
||||
}
|
||||
|
||||
const mapping = this._mappings[code];
|
||||
if (!mapping) {
|
||||
// uh-oh
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
if (mapping.value >= CharCode.a && mapping.value <= CharCode.z) {
|
||||
return String.fromCharCode(CharCode.A + (mapping.value - CharCode.a));
|
||||
}
|
||||
|
||||
if (mapping.value) {
|
||||
return String.fromCharCode(mapping.value);
|
||||
}
|
||||
|
||||
throw new Error('TODO!');
|
||||
}
|
||||
|
||||
public resolveKeybinding(keybinding: Keybinding): NativeResolvedKeybinding[] {
|
||||
let result: NativeResolvedKeybinding[] = [], resultLen = 0;
|
||||
|
||||
if (keybinding.isChord()) {
|
||||
const firstParts = this.mapSimpleKeybinding(keybinding.extractFirstPart());
|
||||
const chordParts = this.mapSimpleKeybinding(keybinding.extractChordPart());
|
||||
|
||||
for (let i = 0, len = firstParts.length; i < len; i++) {
|
||||
const firstPart = firstParts[i];
|
||||
for (let j = 0, lenJ = chordParts.length; j < lenJ; j++) {
|
||||
const chordPart = chordParts[j];
|
||||
|
||||
result[resultLen++] = new NativeResolvedKeybinding(this, this._OS, firstPart, chordPart);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const firstParts = this.mapSimpleKeybinding(keybinding);
|
||||
|
||||
for (let i = 0, len = firstParts.length; i < len; i++) {
|
||||
const firstPart = firstParts[i];
|
||||
|
||||
result[resultLen++] = new NativeResolvedKeybinding(this, this._OS, firstPart, null);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
let currentLength = 0;
|
||||
for (let i = 0; i <= KeyCode.MAX_VALUE; i++) {
|
||||
IMMUTABLE_KEY_CODE_TO_CODE[i] = -1;
|
||||
}
|
||||
for (let i = 0; i <= KeyboardEventCode.MAX_VALUE; i++) {
|
||||
IMMUTABLE_CODE_TO_KEY_CODE[i] = -1;
|
||||
}
|
||||
|
||||
function d(keyCode: KeyCode, code: KeyboardEventCode): void {
|
||||
if (keyCode > currentLength) {
|
||||
for (let i = currentLength; i < keyCode; i++) {
|
||||
IMMUTABLE_KEY_CODE_TO_CODE[i] = -1;
|
||||
}
|
||||
}
|
||||
IMMUTABLE_KEY_CODE_TO_CODE[keyCode] = code;
|
||||
currentLength = keyCode + 1;
|
||||
IMMUTABLE_CODE_TO_KEY_CODE[code] = keyCode;
|
||||
}
|
||||
|
||||
// Unknown = 0,
|
||||
|
||||
@@ -8,12 +8,13 @@
|
||||
import * as assert from 'assert';
|
||||
import { mac_de_ch } from 'vs/workbench/services/keybinding/test/mac_de_ch';
|
||||
import { linux_de_ch } from 'vs/workbench/services/keybinding/test/linux_de_ch';
|
||||
import { KeyMod, KeyCode, SimpleKeybinding, createKeybinding } from 'vs/base/common/keyCodes';
|
||||
import { KeyMod, KeyCode, SimpleKeybinding, createKeybinding, Keybinding } from 'vs/base/common/keyCodes';
|
||||
import { KeyboardMapper } from 'vs/workbench/services/keybinding/common/keyboardMapper';
|
||||
import { OperatingSystem } from 'vs/base/common/platform';
|
||||
import { UserSettingsLabelProvider, PrintableKeypress } from 'vs/platform/keybinding/common/keybindingLabels';
|
||||
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/abstractKeybindingService';
|
||||
import { KeyboardEventCodeUtils } from "vs/workbench/services/keybinding/common/keyboardEventCode";
|
||||
import { KeyboardEventCodeUtils } from 'vs/workbench/services/keybinding/common/keyboardEventCode';
|
||||
import { IHTMLContentElement } from "vs/base/common/htmlContent";
|
||||
|
||||
function _assertKeybindingTranslation(mapper: KeyboardMapper, OS: OperatingSystem, kb: number, expected: string[]): void {
|
||||
let actualHardwareKeypresses = mapper.mapSimpleKeybinding(new SimpleKeybinding(kb));
|
||||
@@ -325,6 +326,104 @@ suite('keyboardMapper - MAC de_ch', () => {
|
||||
// OEM_8
|
||||
// OEM_102
|
||||
});
|
||||
|
||||
test('resolveKeybinding - all labels', () => {
|
||||
function _assertAllLabels(keybinding: Keybinding, labels: string[], ariaLabels: string[], htmlLabel: IHTMLContentElement[][]): void {
|
||||
const kb = mapper.resolveKeybinding(keybinding);
|
||||
|
||||
let actualLabels = kb.map(k => k.getLabel());
|
||||
assert.deepEqual(actualLabels, labels);
|
||||
|
||||
let actualAriaLabels = kb.map(k => k.getAriaLabel());
|
||||
assert.deepEqual(actualAriaLabels, ariaLabels);
|
||||
|
||||
let actualHTMLLabels = kb.map(k => k.getHTMLLabel());
|
||||
assert.deepEqual(actualHTMLLabels, htmlLabel);
|
||||
}
|
||||
|
||||
function assertAllLabels(keybinding: Keybinding, label: string | string[], ariaLabel: string | string[], htmlLabel: IHTMLContentElement[][]): void {
|
||||
let _labels = (typeof label === 'string' ? [label] : label);
|
||||
let _ariaLabels = (typeof ariaLabel === 'string' ? [ariaLabel] : ariaLabel);
|
||||
_assertAllLabels(keybinding, _labels, _ariaLabels, htmlLabel);
|
||||
}
|
||||
|
||||
|
||||
// TODO: ElectronAccelerator, UserSettings
|
||||
assertAllLabels(
|
||||
createKeybinding(KeyMod.CtrlCmd | KeyCode.KEY_Z),
|
||||
'⌘Z',
|
||||
'Command+Z',
|
||||
[[{
|
||||
tagName: 'span',
|
||||
className: 'monaco-kb',
|
||||
children: [
|
||||
{ tagName: 'span', className: 'monaco-kbkey', text: '⌘' },
|
||||
{ tagName: 'span', className: 'monaco-kbkey', text: 'Z' },
|
||||
]
|
||||
}]]
|
||||
);
|
||||
});
|
||||
|
||||
test('resolveKeybinding - aria labels', () => {
|
||||
function assertAriaLabels(keybinding: number, label: string | string[]): void {
|
||||
let _labels = (typeof label === 'string' ? [label] : label);
|
||||
const kb = mapper.resolveKeybinding(createKeybinding(keybinding));
|
||||
let actualLabels = kb.map(k => k.getAriaLabel());
|
||||
assert.deepEqual(actualLabels, _labels);
|
||||
}
|
||||
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyCode.KEY_1, 'Command+1');
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyCode.KEY_B, 'Command+B');
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_B, 'Shift+Command+B');
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_B, 'Control+Shift+Alt+Command+B');
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyCode.KEY_Z, 'Command+Z');
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyCode.KEY_Y, 'Command+Y');
|
||||
|
||||
// ;
|
||||
assertAriaLabels(KeyCode.US_SEMICOLON, 'Shift+,');
|
||||
// :
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_SEMICOLON, 'Shift+.');
|
||||
// =
|
||||
assertAriaLabels(KeyCode.US_EQUAL, 'Shift+0');
|
||||
// +
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_EQUAL, 'Shift+1');
|
||||
// ,
|
||||
assertAriaLabels(KeyCode.US_COMMA, ',');
|
||||
// <
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_COMMA, '<');
|
||||
// -
|
||||
assertAriaLabels(KeyCode.US_MINUS, '-');
|
||||
// _
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_MINUS, 'Shift+-');
|
||||
// .
|
||||
assertAriaLabels(KeyCode.US_DOT, '.');
|
||||
// >
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_DOT, 'Shift+<');
|
||||
// /
|
||||
assertAriaLabels(KeyCode.US_SLASH, 'Shift+7');
|
||||
// ?
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_SLASH, 'Shift+\'');
|
||||
// `
|
||||
assertAriaLabels(KeyCode.US_BACKTICK, 'Shift+^');
|
||||
// ~
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_BACKTICK, 'Control+Alt+N');
|
||||
// [
|
||||
assertAriaLabels(KeyCode.US_OPEN_SQUARE_BRACKET, 'Control+Alt+5');
|
||||
// {
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_OPEN_SQUARE_BRACKET, 'Control+Alt+8');
|
||||
// \
|
||||
assertAriaLabels(KeyCode.US_BACKSLASH, 'Control+Shift+Alt+7');
|
||||
// |
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_BACKSLASH, 'Control+Alt+7');
|
||||
// ]
|
||||
assertAriaLabels(KeyCode.US_CLOSE_SQUARE_BRACKET, 'Control+Alt+6');
|
||||
// }
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_CLOSE_SQUARE_BRACKET, 'Control+Alt+9');
|
||||
// '
|
||||
assertAriaLabels(KeyCode.US_QUOTE, '\'');
|
||||
// "
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_QUOTE, 'Shift+2');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -626,4 +725,66 @@ suite('keyboardMapper - LINUX de_ch', () => {
|
||||
// OEM_8
|
||||
// OEM_102
|
||||
});
|
||||
|
||||
|
||||
test('resolveKeybinding - aria labels', () => {
|
||||
function assertAriaLabels(keybinding: number, label: string | string[]): void {
|
||||
let _labels = (typeof label === 'string' ? [label] : label);
|
||||
const kb = mapper.resolveKeybinding(createKeybinding(keybinding));
|
||||
let actualLabels = kb.map(k => k.getAriaLabel());
|
||||
assert.deepEqual(actualLabels, _labels);
|
||||
}
|
||||
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyCode.KEY_1, 'Control+1');
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyCode.KEY_B, 'Control+B');
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_B, 'Control+Shift+B');
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyMod.Shift | KeyMod.Alt | KeyMod.WinCtrl | KeyCode.KEY_B, 'Control+Shift+Alt+Windows+B');
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyCode.KEY_Z, 'Control+Z');
|
||||
assertAriaLabels(KeyMod.CtrlCmd | KeyCode.KEY_Y, 'Control+Y');
|
||||
|
||||
// ;
|
||||
assertAriaLabels(KeyCode.US_SEMICOLON, 'Shift+,');
|
||||
// :
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_SEMICOLON, 'Shift+.');
|
||||
// =
|
||||
assertAriaLabels(KeyCode.US_EQUAL, 'Shift+0');
|
||||
// +
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_EQUAL, 'Shift+1');
|
||||
// ,
|
||||
assertAriaLabels(KeyCode.US_COMMA, ',');
|
||||
// <
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_COMMA, ['<', 'Control+Shift+Alt+Y']);
|
||||
// -
|
||||
assertAriaLabels(KeyCode.US_MINUS, '-');
|
||||
// _
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_MINUS, 'Shift+-');
|
||||
// .
|
||||
assertAriaLabels(KeyCode.US_DOT, '.');
|
||||
// >
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_DOT, ['Shift+<', 'Control+Shift+Alt+X']);
|
||||
// /
|
||||
assertAriaLabels(KeyCode.US_SLASH, 'Shift+7');
|
||||
// ?
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_SLASH, 'Shift+\'');
|
||||
// `
|
||||
assertAriaLabels(KeyCode.US_BACKTICK, 'Shift+^');
|
||||
// ~
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_BACKTICK, []);
|
||||
// [
|
||||
assertAriaLabels(KeyCode.US_OPEN_SQUARE_BRACKET, 'Control+Alt+ü');
|
||||
// {
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_OPEN_SQUARE_BRACKET, 'Control+Alt+ä');
|
||||
// \
|
||||
assertAriaLabels(KeyCode.US_BACKSLASH, 'Control+Alt+<');
|
||||
// |
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_BACKSLASH, ['Control+Alt+1', 'Control+Alt+7']);
|
||||
// ]
|
||||
assertAriaLabels(KeyCode.US_CLOSE_SQUARE_BRACKET, ['Control+Alt+9', 'Control+Alt+¨']);
|
||||
// }
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_CLOSE_SQUARE_BRACKET, ['Control+Alt+0', 'Control+Alt+$']);
|
||||
// '
|
||||
assertAriaLabels(KeyCode.US_QUOTE, '\'');
|
||||
// "
|
||||
assertAriaLabels(KeyMod.Shift | KeyCode.US_QUOTE, 'Shift+2');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user