| // Copyright 2026 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 Common from '../../core/common/common.js'; |
| import type * as Platform from '../../core/platform/platform.js'; |
| |
| export interface SettingUIDescriptor { |
| /** |
| * The category with which the setting is displayed in the UI. |
| */ |
| category?: Common.SettingRegistration.SettingCategory; |
| /** |
| * Used to sort on screen the settings that belong to the same category. |
| */ |
| order?: number; |
| /** |
| * The title with which the setting is shown on screen. |
| */ |
| title?: () => Platform.UIString.LocalizedString; |
| /** |
| * Words used to find a setting in the Command Menu. |
| */ |
| tags?: Array<() => Platform.UIString.LocalizedString>; |
| /** |
| * The possible values the setting can have, each with a description composed of a title and an optional text. |
| */ |
| options?: Common.SettingRegistration.SettingExtensionOption[]; |
| /** |
| * Whether DevTools must be reloaded for a change in the setting to take effect. |
| */ |
| reloadRequired?: boolean; |
| /** |
| * See {@link LearnMore} for more info. |
| */ |
| learnMore?: Common.SettingRegistration.LearnMore; |
| } |
| |
| export interface RegisteredSettingUI { |
| descriptor: Common.Settings.SettingDescriptor<unknown>; |
| uiDescriptor: SettingUIDescriptor; |
| } |
| |
| const registeredSettings = new Map<string, RegisteredSettingUI>(); |
| |
| export function register( |
| settingDescriptor: Common.Settings.SettingDescriptor<unknown>, |
| settingUIDescriptor: SettingUIDescriptor, |
| ): void { |
| const settingName = settingDescriptor.name; |
| if (registeredSettings.has(settingName)) { |
| throw new Error(`Duplicate setting name '${settingName}'`); |
| } |
| Common.SettingRegistration.registerCategoryOrder(settingUIDescriptor.category, settingUIDescriptor.order); |
| registeredSettings.set(settingName, {descriptor: settingDescriptor, uiDescriptor: settingUIDescriptor}); |
| } |
| |
| export function getRegisteredSettings(): readonly RegisteredSettingUI[] { |
| const combined = new Map<string, RegisteredSettingUI>(); |
| for (const legacy of Common.SettingRegistration.getRegisteredSettings()) { |
| combined.set(legacy.settingName, { |
| descriptor: { |
| name: legacy.settingName, |
| type: legacy.settingType, |
| defaultValue: legacy.defaultValue, |
| storageType: legacy.storageType, |
| }, |
| uiDescriptor: { |
| category: legacy.category, |
| order: legacy.order, |
| title: legacy.title, |
| tags: legacy.tags, |
| options: legacy.options, |
| reloadRequired: legacy.reloadRequired, |
| learnMore: legacy.learnMore, |
| }, |
| }); |
| } |
| |
| for (const [name, registeredUI] of registeredSettings) { |
| combined.set(name, registeredUI); |
| } |
| |
| return Array.from(combined.values()); |
| } |
| |
| export interface SimpleSettingOption { |
| value: string|boolean; |
| title: Platform.UIString.LocalizedString; |
| text?: Platform.UIString.LocalizedString|string; |
| raw?: boolean; |
| } |
| |
| export class SettingUI { |
| readonly #raw: SettingUIDescriptor; |
| |
| constructor(raw: SettingUIDescriptor) { |
| this.#raw = raw; |
| } |
| |
| get title(): Platform.UIString.LocalizedString { |
| return this.#raw.title?.() ?? ('' as Platform.UIString.LocalizedString); |
| } |
| |
| get category(): Common.SettingRegistration.SettingCategory|null { |
| return this.#raw.category ?? null; |
| } |
| |
| get order(): number|null { |
| return this.#raw.order ?? null; |
| } |
| |
| get tags(): string { |
| return this.#raw.tags ? this.#raw.tags.map(tag => tag()).join('\0') : ''; |
| } |
| |
| get options(): SimpleSettingOption[] { |
| return this.#raw.options?.map(opt => ({ |
| value: opt.value, |
| title: opt.title(), |
| text: typeof opt.text === 'function' ? opt.text() : opt.text, |
| raw: opt.raw, |
| })) ?? |
| []; |
| } |
| |
| get reloadRequired(): boolean { |
| return Boolean(this.#raw.reloadRequired); |
| } |
| |
| get learnMore(): Common.SettingRegistration.LearnMore|null { |
| return this.#raw.learnMore ?? null; |
| } |
| } |
| |
| export function maybeResolve(settingDescriptor: Common.Settings.SettingDescriptor<unknown>): SettingUI|null { |
| const settingUI = registeredSettings.get(settingDescriptor.name) ?? |
| getRegisteredSettings().find(registered => registered.descriptor.name === settingDescriptor.name); |
| return settingUI ? new SettingUI(settingUI.uiDescriptor) : null; |
| } |
| |
| export function resolve(settingDescriptor: Common.Settings.SettingDescriptor<unknown>): SettingUI { |
| const ui = maybeResolve(settingDescriptor); |
| if (!ui) { |
| throw new Error(`No UI descriptor registered for setting '${settingDescriptor.name}'`); |
| } |
| return ui; |
| } |
| |
| export function resetSettings(): void { |
| for (const {uiDescriptor} of registeredSettings.values()) { |
| Common.SettingRegistration.removeCategoryOrder(uiDescriptor.category, uiDescriptor.order); |
| } |
| registeredSettings.clear(); |
| } |