mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-10 13:44:39 +08:00
R=jacktfranklin@chromium.org Bug: 1058320 Change-Id: I86fdc670c6667f37bfced2d9068106ec553d2210 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2364370 Commit-Queue: Tim van der Lippe <tvanderlippe@chromium.org> Reviewed-by: Jack Franklin <jacktfranklin@chromium.org> Auto-Submit: Tim van der Lippe <tvanderlippe@chromium.org>
174 lines
5.3 KiB
JavaScript
174 lines
5.3 KiB
JavaScript
// Copyright 2020 The Chromium Authors. All rights reserved.
|
||
// Use of this source code is governed by a BSD-style license that can be
|
||
// found in the LICENSE file.
|
||
|
||
// @ts-nocheck
|
||
// TODO(crbug.com/1011811): Enable TypeScript compiler checks
|
||
|
||
import * as UI from '../ui/ui.js';
|
||
|
||
/**
|
||
* @implements {UI.ListControl.ListDelegate<!KeybindsItem>}
|
||
*/
|
||
export class KeybindsSettingsTab extends UI.Widget.VBox {
|
||
constructor() {
|
||
super(true);
|
||
this.registerRequiredCSS('settings/keybindsSettingsTab.css');
|
||
|
||
const header = this.contentElement.createChild('header');
|
||
header.createChild('h1').textContent = ls`Shortcuts`;
|
||
const keybindsSetSetting = self.Common.settings.moduleSetting('activeKeybindSet');
|
||
keybindsSetSetting.addChangeListener(this.update, this);
|
||
const keybindsSetSelect =
|
||
UI.SettingsUI.createControlForSetting(keybindsSetSetting, ls`Match shortcuts from preset`);
|
||
keybindsSetSelect.classList.add('keybinds-set-select');
|
||
this.contentElement.appendChild(keybindsSetSelect);
|
||
|
||
/** @type {!UI.ListModel.ListModel<!KeybindsItem>} */
|
||
this._items = new UI.ListModel.ListModel();
|
||
this._list = new UI.ListControl.ListControl(this._items, this, UI.ListControl.ListMode.NonViewport);
|
||
this._items.replaceAll(this._createListItems());
|
||
UI.ARIAUtils.markAsList(this._list.element);
|
||
this.registerRequiredCSS('settings/keybindsSettingsTab.css');
|
||
this.contentElement.appendChild(this._list.element);
|
||
UI.ARIAUtils.setAccessibleName(this._list.element, ls`Keyboard shortcuts list`);
|
||
this.update();
|
||
}
|
||
|
||
/**
|
||
* @override
|
||
* @param {!KeybindsItem} item
|
||
* @return {!Element}
|
||
*/
|
||
createElementForItem(item) {
|
||
const itemElement = document.createElement('div');
|
||
itemElement.classList.add('keybinds-list-item');
|
||
UI.ARIAUtils.markAsListitem(itemElement);
|
||
itemElement.tabIndex = item === this._list.selectedItem() ? 0 : -1;
|
||
|
||
if (typeof item === 'string') {
|
||
UI.ARIAUtils.setLevel(itemElement, 1);
|
||
itemElement.classList.add('keybinds-category-header');
|
||
itemElement.textContent = item;
|
||
} else {
|
||
UI.ARIAUtils.setLevel(itemElement, 2);
|
||
itemElement.createChild('div', 'keybinds-action-name keybinds-list-text').textContent = item.title();
|
||
const shortcuts = self.UI.shortcutRegistry.shortcutsForAction(item.id());
|
||
shortcuts.forEach((shortcut, index) => {
|
||
if (!shortcut.isDefault()) {
|
||
const icon = UI.Icon.Icon.create('largeicon-shortcut-changed', 'keybinds-modified');
|
||
UI.ARIAUtils.setAccessibleName(icon, ls`Shortcut provided by preset`);
|
||
itemElement.appendChild(icon);
|
||
}
|
||
const shortcutElement = itemElement.createChild('div', 'keybinds-shortcut keybinds-list-text');
|
||
const keys = shortcut.descriptors.flatMap(descriptor => descriptor.name.split(' + '));
|
||
keys.forEach(key => {
|
||
shortcutElement.createChild('span', 'keybinds-key').textContent = key;
|
||
});
|
||
});
|
||
if (shortcuts.length === 0) {
|
||
if (self.UI.shortcutRegistry.actionHasDefaultShortcut(item.id())) {
|
||
const icon = UI.Icon.Icon.create('largeicon-shortcut-changed', 'keybinds-modified');
|
||
UI.ARIAUtils.setAccessibleName(icon, ls`Shortcut provided by preset`);
|
||
itemElement.appendChild(icon);
|
||
}
|
||
const emptyElement = itemElement.createChild('div', 'keybinds-shortcut keybinds-list-text');
|
||
UI.ARIAUtils.setAccessibleName(emptyElement, ls`No shortcut for action`);
|
||
}
|
||
}
|
||
|
||
return itemElement;
|
||
}
|
||
|
||
/**
|
||
* This method will never be called.
|
||
* @override
|
||
* @param {!KeybindsItem} item
|
||
* @return {number}
|
||
*/
|
||
heightForItem(item) {
|
||
return 0;
|
||
}
|
||
|
||
|
||
/**
|
||
* @override
|
||
* @param {!KeybindsItem} item
|
||
* @returns {boolean}
|
||
*/
|
||
isItemSelectable(item) {
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* @override
|
||
* @param {?KeybindsItem} from
|
||
* @param {?KeybindsItem} to
|
||
* @param {?Element} fromElement
|
||
* @param {?Element} toElement
|
||
*/
|
||
selectedItemChanged(from, to, fromElement, toElement) {
|
||
if (fromElement) {
|
||
fromElement.tabIndex = -1;
|
||
}
|
||
if (toElement) {
|
||
toElement.tabIndex = 0;
|
||
if (this._list.element.hasFocus()) {
|
||
toElement.focus();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @override
|
||
* @param {?Element} fromElement
|
||
* @param {?Element} toElement
|
||
* @return {boolean}
|
||
*/
|
||
updateSelectedItemARIA(fromElement, toElement) {
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* @returns {!Array.<!KeybindsItem>}
|
||
*/
|
||
_createListItems() {
|
||
const actions = UI.ActionRegistry.ActionRegistry.instance().actions().sort((actionA, actionB) => {
|
||
if (actionA.category() < actionB.category()) {
|
||
return -1;
|
||
}
|
||
if (actionA.category() > actionB.category()) {
|
||
return 1;
|
||
}
|
||
if (actionA.id() < actionB.id()) {
|
||
return -1;
|
||
}
|
||
if (actionA.id() > actionB.id()) {
|
||
return 1;
|
||
}
|
||
return 0;
|
||
});
|
||
|
||
const items = [];
|
||
let currentCategory;
|
||
actions.forEach(action => {
|
||
if (currentCategory !== action.category()) {
|
||
items.push(action.category());
|
||
}
|
||
items.push(action);
|
||
currentCategory = action.category();
|
||
});
|
||
return items;
|
||
}
|
||
|
||
update() {
|
||
this._list.refreshAllItems();
|
||
if (!this._list.selectedItem()) {
|
||
this._list.selectItem(this._items.at(0));
|
||
}
|
||
}
|
||
}
|
||
|
||
/** @typedef {string|!UI.Action.Action} */
|
||
export let KeybindsItem;
|