chrome-devtools-frontend
Version:
Chrome DevTools UI
110 lines (95 loc) • 3.63 kB
text/typescript
// Copyright 2016 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.
import * as i18n from '../../../../core/i18n/i18n.js';
import type * as UI from '../../legacy.js';
import {FilteredListWidget, getRegisteredProviders, type Provider} from './FilteredListWidget.js';
const UIStrings = {
/**
* @description Text of the hint shows under Quick Open input box
*/
typeToSeeAvailableCommands: 'Type ? to see available commands',
} as const;
const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/quick_open/QuickOpen.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
export const history: string[] = [];
export class QuickOpenImpl {
private prefix: string|null = null;
private readonly prefixes: string[] = [];
private providers = new Map<string, {
provider: () => Promise<Provider>,
titlePrefix: (() => string),
titleSuggestion?: (() => string),
}>();
private filteredListWidget: FilteredListWidget|null = null;
constructor() {
getRegisteredProviders().forEach(this.addProvider.bind(this));
this.prefixes.sort((a, b) => b.length - a.length);
}
static show(query: string): void {
const quickOpen = new this();
const filteredListWidget = new FilteredListWidget(null, history, quickOpen.queryChanged.bind(quickOpen));
quickOpen.filteredListWidget = filteredListWidget;
filteredListWidget.setHintElement(i18nString(UIStrings.typeToSeeAvailableCommands));
filteredListWidget.showAsDialog();
filteredListWidget.setQuery(query);
}
private addProvider(extension: {
prefix: string,
provider: () => Promise<Provider>,
titlePrefix: () => string,
titleSuggestion?: (() => string),
}): void {
const prefix = extension.prefix;
if (prefix === null) {
return;
}
this.prefixes.push(prefix);
this.providers.set(prefix, {
provider: extension.provider,
titlePrefix: extension.titlePrefix,
titleSuggestion: extension.titleSuggestion,
});
}
private async queryChanged(query: string): Promise<void> {
const prefix = this.prefixes.find(prefix => query.startsWith(prefix));
if (typeof prefix !== 'string') {
return;
}
if (!this.filteredListWidget) {
return;
}
this.filteredListWidget.setPrefix(prefix);
const titlePrefixFunction = this.providers.get(prefix)?.titlePrefix;
this.filteredListWidget.setCommandPrefix(titlePrefixFunction ? titlePrefixFunction() : '');
const titleSuggestionFunction = (query === prefix) && this.providers.get(prefix)?.titleSuggestion;
this.filteredListWidget.setCommandSuggestion(titleSuggestionFunction ? prefix + titleSuggestionFunction() : '');
if (this.prefix === prefix) {
return;
}
this.prefix = prefix;
this.filteredListWidget.setProvider(null);
const providerFunction = this.providers.get(prefix)?.provider;
if (!providerFunction) {
return;
}
const provider = await providerFunction();
if (this.prefix !== prefix || !this.filteredListWidget) {
return;
}
this.filteredListWidget.setProvider(provider);
this.providerLoadedForTest(provider);
}
private providerLoadedForTest(_provider: Provider): void {
}
}
export class ShowActionDelegate implements UI.ActionRegistration.ActionDelegate {
handleAction(_context: UI.Context.Context, actionId: string): boolean {
switch (actionId) {
case 'quick-open.show':
QuickOpenImpl.show('');
return true;
}
return false;
}
}