| // Copyright 2016 The Chromium Authors |
| // 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, |
| type ProviderRegistration |
| } 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: ProviderRegistration): void { |
| const prefix = extension.prefix; |
| if (prefix === null) { |
| return; |
| } |
| this.prefixes.push(prefix); |
| this.providers.set(prefix, { |
| provider: () => extension.provider(extension.jslogContext), |
| 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; |
| } |
| } |