UNPKG

chrome-devtools-frontend

Version:
322 lines (303 loc) • 9.8 kB
// Copyright 2020 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 '../i18n/i18n.js'; import type * as Platform from '../platform/platform.js'; import type {SettingStorageType} from './Settings.js'; const UIStrings = { /** * @description Title of the Elements panel. */ elements: 'Elements', /** * @description Text for DevTools AI. */ ai: 'AI', /** * @description Text for DevTools appearance. */ appearance: 'Appearance', /** * @description Title of the Sources panel. */ sources: 'Sources', /** * @description Title of the Network panel. */ network: 'Network', /** * @description Title of the Performance panel. */ performance: 'Performance', /** * @description Title of the Console panel. */ console: 'Console', /** * @description Title of the Persistence setting category. */ persistence: 'Persistence', /** * @description Title of the Debugger setting category. */ debugger: 'Debugger', /** * @description Title of the Global setting category for shortcuts and settings available throughout DevTools. */ global: 'Global', /** * @description Title of the Rendering tool. */ rendering: 'Rendering', /** * @description Title of the Grid setting category for CSS Grid tooling. */ grid: 'Grid', /** * @description Title of the Mobile setting category. */ mobile: 'Mobile', /** * @description Title of the Memory panel setting category. */ memory: 'Memory', /** * @description Title of the Extension setting category. */ extension: 'Extension', /** * @description Title of the Adorner setting category. */ adorner: 'Adorner', /** * @description Header for the Account section in the settings UI. The Account * section allows users to see their signed-in account and configure which DevTools data is synced via Chrome Sync. */ account: 'Account', } as const; const str_ = i18n.i18n.registerUIStrings('core/common/SettingRegistration.ts', UIStrings); const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); let registeredSettings: SettingRegistration[] = []; const settingNameSet = new Set<string>(); const orderValuesBySettingCategory = new Map<SettingCategory, Set<number>>(); export function registerCategoryOrder(category?: SettingCategory, order?: number): void { if (category && typeof order === 'number') { let orderValues = orderValuesBySettingCategory.get(category); if (!orderValues) { orderValues = new Set(); orderValuesBySettingCategory.set(category, orderValues); } if (orderValues.has(order)) { throw new Error(`Duplicate order value '${order}' for settings category '${category}'`); } orderValues.add(order); } } export function removeCategoryOrder(category?: SettingCategory, order?: number): void { if (category && typeof order === 'number') { orderValuesBySettingCategory.get(category)?.delete(order); } } export function registerSettingExtension(registration: SettingRegistration): void { const settingName = registration.settingName; if (settingNameSet.has(settingName)) { throw new Error(`Duplicate setting name '${settingName}'`); } registerCategoryOrder(registration.category, registration.order); settingNameSet.add(settingName); registeredSettings.push(registration); } export function getRegisteredSettings(): SettingRegistration[] { return registeredSettings; } export function registerSettingsForTest(settings: SettingRegistration[], forceReset = false): void { if (registeredSettings.length === 0 || forceReset) { resetSettings(); for (const setting of settings) { registerSettingExtension(setting); } } } export function resetSettings(): void { for (const setting of registeredSettings) { removeCategoryOrder(setting.category, setting.order); } registeredSettings = []; settingNameSet.clear(); } export function maybeRemoveSettingExtension(settingName: string): boolean { const settingIndex = registeredSettings.findIndex(setting => setting.settingName === settingName); if (settingIndex < 0 || !settingNameSet.delete(settingName)) { return false; } const [removed] = registeredSettings.splice(settingIndex, 1); removeCategoryOrder(removed.category, removed.order); return true; } export const enum SettingCategory { NONE = '', // `NONE` must be a falsy value. Legacy code uses if-checks for the category. ELEMENTS = 'ELEMENTS', AI = 'AI', APPEARANCE = 'APPEARANCE', SOURCES = 'SOURCES', NETWORK = 'NETWORK', PERFORMANCE = 'PERFORMANCE', CONSOLE = 'CONSOLE', PERSISTENCE = 'PERSISTENCE', DEBUGGER = 'DEBUGGER', GLOBAL = 'GLOBAL', RENDERING = 'RENDERING', GRID = 'GRID', MOBILE = 'MOBILE', EMULATION = 'EMULATION', MEMORY = 'MEMORY', EXTENSIONS = 'EXTENSIONS', ADORNER = 'ADORNER', ACCOUNT = 'ACCOUNT', } export function getLocalizedSettingsCategory(category: SettingCategory): Platform.UIString.LocalizedString { switch (category) { case SettingCategory.ELEMENTS: return i18nString(UIStrings.elements); case SettingCategory.AI: return i18nString(UIStrings.ai); case SettingCategory.APPEARANCE: return i18nString(UIStrings.appearance); case SettingCategory.SOURCES: return i18nString(UIStrings.sources); case SettingCategory.NETWORK: return i18nString(UIStrings.network); case SettingCategory.PERFORMANCE: return i18nString(UIStrings.performance); case SettingCategory.CONSOLE: return i18nString(UIStrings.console); case SettingCategory.PERSISTENCE: return i18nString(UIStrings.persistence); case SettingCategory.DEBUGGER: return i18nString(UIStrings.debugger); case SettingCategory.GLOBAL: return i18nString(UIStrings.global); case SettingCategory.RENDERING: return i18nString(UIStrings.rendering); case SettingCategory.GRID: return i18nString(UIStrings.grid); case SettingCategory.MOBILE: return i18nString(UIStrings.mobile); case SettingCategory.EMULATION: return i18nString(UIStrings.console); case SettingCategory.MEMORY: return i18nString(UIStrings.memory); case SettingCategory.EXTENSIONS: return i18nString(UIStrings.extension); case SettingCategory.ADORNER: return i18nString(UIStrings.adorner); case SettingCategory.NONE: return i18n.i18n.lockedString(''); case SettingCategory.ACCOUNT: return i18nString(UIStrings.account); } } export const enum SettingType { ARRAY = 'array', REGEX = 'regex', ENUM = 'enum', BOOLEAN = 'boolean', } export interface RegExpSettingItem { /** * A regular expression matched against URLs for ignore listing. */ pattern: string; /** * If true, ignore this rule. */ disabled?: boolean; /** * When a rule is disabled due to requesting through a script's context menu * that it no longer be ignore listed, this field is set to the URL of that * script, so that if the user requests through the same context menu to * enable ignore listing, the rule can be reenabled. */ disabledForUrl?: Platform.DevToolsPath.UrlString; } export interface SettingRegistration { /** * The category with which the setting is displayed in the UI. */ category?: 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; /** * The identifier of the setting. */ settingName: string; /** * Determines how the possible values of the setting are expressed. * * - If the setting can only be enabled and disabled use BOOLEAN * - If the setting has a list of possible values use ENUM * - If each setting value is a set of objects use ARRAY * - If the setting value is a regular expression use REGEX */ settingType: SettingType; /** * The value set by default to the setting. */ defaultValue: unknown; /** * 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?: SettingExtensionOption[]; /** * Whether DevTools must be reloaded for a change in the setting to take effect. */ reloadRequired?: boolean; /** * Determines if the setting value is stored in the global, local or session storage. */ storageType?: SettingStorageType; /** * See {@link LearnMore} for more info. */ learnMore?: LearnMore; } /** * Optional information to learn more about the setting. * * If tooltip is provided creates a (i) icon with rich tooltip with said tooltip * * If url is provided creates a (?) icon with a link to said url * * If both tooltip is provided creates a (i) icon with rich tooltip * and a link inside the rich tool tip with text `Learn more` */ export interface LearnMore { tooltip?: () => Platform.UIString.LocalizedString; url?: Platform.DevToolsPath.UrlString; } interface LocalizedSettingExtensionOption { value: boolean|string; title: () => Platform.UIString.LocalizedString; text?: () => Platform.UIString.LocalizedString; raw?: false; } interface RawSettingExtensionOption { value: boolean|string; title: () => Platform.UIString.LocalizedString; /** * Text used to describe the option. Must be localized if 'raw' is false. */ text?: string; raw: true; } export type SettingExtensionOption = LocalizedSettingExtensionOption|RawSettingExtensionOption;