UNPKG

chrome-devtools-frontend

Version:
669 lines (629 loc) • 21.8 kB
// 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. import * as Common from '../../core/common/common.js'; import * as Root from '../../core/root/root.js'; import * as SDK from '../../core/sdk/sdk.js'; import * as UI from '../../ui/legacy/legacy.js'; import type * as Elements from './elements.js'; import type * as ElementsComponents from './components/components.js'; import * as i18n from '../../core/i18n/i18n.js'; const UIStrings = { /** * @description Command for showing the 'Elements' panel. Elements refers to HTML elements. */ showElements: 'Show Elements', /** * @description Title of the Elements Panel. Elements refers to HTML elements. */ elements: 'Elements', /** * @description Command for showing the 'Event Listeners' tool. Refers to DOM Event listeners. */ showEventListeners: 'Show Event Listeners', /** * @description Title of the 'Event Listeners' tool in the sidebar of the elements panel. Refers to * DOM Event listeners. */ eventListeners: 'Event Listeners', /** * @description Command for showing the 'Properties' tool. Refers to HTML properties. */ showProperties: 'Show Properties', /** * @description Title of the 'Properties' tool in the sidebar of the elements tool. Refers to HTML * properties. */ properties: 'Properties', /** * @description Command for showing the 'Stack Trace' tool. Stack trace refers to the location in * the code where the program was at a point in time. */ showStackTrace: 'Show Stack Trace', /** * @description Text for the execution stack trace tool, which shows the stack trace from when this * HTML element was created. Stack trace refers to the location in the code where the program was * at a point in time. */ stackTrace: 'Stack Trace', /** * @description Command for showing the 'Layout' tool */ showLayout: 'Show Layout', /** * @description The title of the 'Layout' tool in the sidebar of the elements panel. */ layout: 'Layout', /** * @description Command to hide a HTML element in the Elements tree. */ hideElement: 'Hide element', /** * @description A context menu item (command) in the Elements panel that allows the user to edit the * currently selected node as raw HTML text. */ editAsHtml: 'Edit as HTML', /** * @description A context menu item (command) in the Elements panel that creates an exact copy of * this HTML element. */ duplicateElement: 'Duplicate element', /** * @description A command in the Elements panel to undo the last action the user took. */ undo: 'Undo', /** * @description A command in the Elements panel to redo the last action the user took (undo an * undo). */ redo: 'Redo', /** * @description A command in the Elements panel to capture a screenshot of the selected area. */ captureAreaScreenshot: 'Capture area screenshot', /** * @description Title/tooltip of an action in the elements panel to toggle element search on/off. */ selectAnElementInThePageTo: 'Select an element in the page to inspect it', /** * @description Title of a setting under the Elements category in Settings. Whether words should be * wrapped around at the end of lines or not. */ wordWrap: 'Word wrap', /** * @description Title of a setting under the Elements category. Whether words should be wrapped * around at the end of lines or not when showing DOM elements. */ enableDomWordWrap: 'Enable `DOM` word wrap', /** * @description Title of a setting under the Elements category. Whether words should be wrapped * around at the end of lines or not when showing DOM elements. */ disableDomWordWrap: 'Disable `DOM` word wrap', /** * @description Title of a setting under the Elements category. Whether to show/hide code comments in HTML. */ showHtmlComments: 'Show `HTML` comments', /** * @description Title of a setting under the Elements category. Whether to show/hide code comments in HTML. */ hideHtmlComments: 'Hide `HTML` comments', /** * @description Title of a setting under the Elements category in Settings. Whether the position of * the DOM node on the actual website should be highlighted/revealed to the user when they hover * over the corresponding node in the DOM tree in DevTools. */ revealDomNodeOnHover: 'Reveal `DOM` node on hover', /** * @description Title of a setting under the Elements category in Settings. Turns on a mode where * the inspect tooltip (an information pane that hovers next to selected DOM elements) has extra * detail. */ showDetailedInspectTooltip: 'Show detailed inspect tooltip', /** * @description Title of a setting under the Elements category in Settings. Turns on a mode where * hovering over CSS properties in the Styles pane will display a popover with documentation. */ showCSSDocumentationTooltip: 'Show CSS documentation tooltip', /** *@description A context menu item (command) in the Elements panel that copy the styles of * the HTML element. */ copyStyles: 'Copy styles', /** * @description Title of a setting under the Elements category. Whether to show/hide hide * the shadow DOM nodes of HTML elements that are built into the browser (e.g. the <input> element). */ showUserAgentShadowDOM: 'Show user agent shadow `DOM`', /** * @description Command for showing the 'Computed' tool. Displays computed CSS styles in Elements sidebar. */ showComputedStyles: 'Show Computed Styles', /** * @description Command for showing the 'Styles' tool. Displays CSS styles in Elements sidebar. */ showStyles: 'Show Styles', /** * @description Command for toggling the eye dropper when the color picker is open */ toggleEyeDropper: 'Toggle eye dropper', }; const str_ = i18n.i18n.registerUIStrings('panels/elements/elements-meta.ts', UIStrings); const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_); let loadedElementsModule: (typeof Elements|undefined); let loadedElementsComponentsModule: (typeof ElementsComponents|undefined); async function loadElementsModule(): Promise<typeof Elements> { if (!loadedElementsModule) { loadedElementsModule = await import('./elements.js'); } return loadedElementsModule; } async function loadElementsComponentsModule(): Promise<typeof ElementsComponents> { if (!loadedElementsComponentsModule) { loadedElementsComponentsModule = await import('./components/components.js'); } return loadedElementsComponentsModule; } function maybeRetrieveContextTypes<T = unknown>(getClassCallBack: (elementsModule: typeof Elements) => T[]): T[] { if (loadedElementsModule === undefined) { return []; } return getClassCallBack(loadedElementsModule); } UI.ViewManager.registerViewExtension({ location: UI.ViewManager.ViewLocationValues.PANEL, id: 'elements', commandPrompt: i18nLazyString(UIStrings.showElements), title: i18nLazyString(UIStrings.elements), order: 10, persistence: UI.ViewManager.ViewPersistence.PERMANENT, hasToolbar: false, async loadView() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsPanel.instance(); }, }); UI.ActionRegistration.registerActionExtension({ actionId: 'elements.show-styles', category: UI.ActionRegistration.ActionCategory.ELEMENTS, title: i18nLazyString(UIStrings.showStyles), async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsActionDelegate.instance(); }, }); UI.ActionRegistration.registerActionExtension({ actionId: 'elements.show-computed', category: UI.ActionRegistration.ActionCategory.ELEMENTS, title: i18nLazyString(UIStrings.showComputedStyles), async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsActionDelegate.instance(); }, }); UI.ViewManager.registerViewExtension({ location: UI.ViewManager.ViewLocationValues.ELEMENTS_SIDEBAR, id: 'elements.eventListeners', commandPrompt: i18nLazyString(UIStrings.showEventListeners), title: i18nLazyString(UIStrings.eventListeners), order: 5, hasToolbar: true, persistence: UI.ViewManager.ViewPersistence.PERMANENT, async loadView() { const Elements = await loadElementsModule(); return Elements.EventListenersWidget.EventListenersWidget.instance(); }, }); UI.ViewManager.registerViewExtension({ location: UI.ViewManager.ViewLocationValues.ELEMENTS_SIDEBAR, id: 'elements.domProperties', commandPrompt: i18nLazyString(UIStrings.showProperties), title: i18nLazyString(UIStrings.properties), order: 7, persistence: UI.ViewManager.ViewPersistence.PERMANENT, async loadView() { const Elements = await loadElementsModule(); return Elements.PropertiesWidget.PropertiesWidget.instance(); }, }); UI.ViewManager.registerViewExtension({ experiment: Root.Runtime.ExperimentName.CAPTURE_NODE_CREATION_STACKS, location: UI.ViewManager.ViewLocationValues.ELEMENTS_SIDEBAR, id: 'elements.domCreation', commandPrompt: i18nLazyString(UIStrings.showStackTrace), title: i18nLazyString(UIStrings.stackTrace), order: 10, persistence: UI.ViewManager.ViewPersistence.PERMANENT, async loadView() { const Elements = await loadElementsModule(); return Elements.NodeStackTraceWidget.NodeStackTraceWidget.instance(); }, }); UI.ViewManager.registerViewExtension({ location: UI.ViewManager.ViewLocationValues.ELEMENTS_SIDEBAR, id: 'elements.layout', commandPrompt: i18nLazyString(UIStrings.showLayout), title: i18nLazyString(UIStrings.layout), order: 4, persistence: UI.ViewManager.ViewPersistence.PERMANENT, async loadView() { const ElementsComponents = await loadElementsComponentsModule(); return ElementsComponents.LayoutPane.LayoutPane.instance().wrapper as UI.Widget.Widget; }, }); UI.ActionRegistration.registerActionExtension({ actionId: 'elements.hide-element', category: UI.ActionRegistration.ActionCategory.ELEMENTS, title: i18nLazyString(UIStrings.hideElement), async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsActionDelegate.instance(); }, contextTypes() { return maybeRetrieveContextTypes(Elements => [Elements.ElementsPanel.ElementsPanel]); }, bindings: [ { shortcut: 'H', }, ], }); UI.ActionRegistration.registerActionExtension({ actionId: 'elements.toggle-eye-dropper', category: UI.ActionRegistration.ActionCategory.ELEMENTS, title: i18nLazyString(UIStrings.toggleEyeDropper), async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsActionDelegate.instance(); }, contextTypes() { return maybeRetrieveContextTypes(Elements => [Elements.ColorSwatchPopoverIcon.ColorSwatchPopoverIcon]); }, bindings: [ { shortcut: 'c', }, ], }); UI.ActionRegistration.registerActionExtension({ actionId: 'elements.edit-as-html', category: UI.ActionRegistration.ActionCategory.ELEMENTS, title: i18nLazyString(UIStrings.editAsHtml), async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsActionDelegate.instance(); }, contextTypes() { return maybeRetrieveContextTypes(Elements => [Elements.ElementsPanel.ElementsPanel]); }, bindings: [ { shortcut: 'F2', }, ], }); UI.ActionRegistration.registerActionExtension({ actionId: 'elements.duplicate-element', category: UI.ActionRegistration.ActionCategory.ELEMENTS, title: i18nLazyString(UIStrings.duplicateElement), async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsActionDelegate.instance(); }, contextTypes() { return maybeRetrieveContextTypes(Elements => [Elements.ElementsPanel.ElementsPanel]); }, bindings: [ { shortcut: 'Shift+Alt+Down', }, ], }); UI.ActionRegistration.registerActionExtension({ actionId: 'elements.copy-styles', category: UI.ActionRegistration.ActionCategory.ELEMENTS, title: i18nLazyString(UIStrings.copyStyles), async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsActionDelegate.instance(); }, contextTypes() { return maybeRetrieveContextTypes(Elements => [Elements.ElementsPanel.ElementsPanel]); }, bindings: [ { shortcut: 'Ctrl+Alt+C', platform: UI.ActionRegistration.Platforms.WindowsLinux, }, { shortcut: 'Meta+Alt+C', platform: UI.ActionRegistration.Platforms.Mac, }, ], }); UI.ActionRegistration.registerActionExtension({ actionId: 'elements.undo', category: UI.ActionRegistration.ActionCategory.ELEMENTS, title: i18nLazyString(UIStrings.undo), async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsActionDelegate.instance(); }, contextTypes() { return maybeRetrieveContextTypes(Elements => [Elements.ElementsPanel.ElementsPanel]); }, bindings: [ { shortcut: 'Ctrl+Z', platform: UI.ActionRegistration.Platforms.WindowsLinux, }, { shortcut: 'Meta+Z', platform: UI.ActionRegistration.Platforms.Mac, }, ], }); UI.ActionRegistration.registerActionExtension({ actionId: 'elements.redo', category: UI.ActionRegistration.ActionCategory.ELEMENTS, title: i18nLazyString(UIStrings.redo), async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsActionDelegate.instance(); }, contextTypes() { return maybeRetrieveContextTypes(Elements => [Elements.ElementsPanel.ElementsPanel]); }, bindings: [ { shortcut: 'Ctrl+Y', platform: UI.ActionRegistration.Platforms.WindowsLinux, }, { shortcut: 'Meta+Shift+Z', platform: UI.ActionRegistration.Platforms.Mac, }, ], }); UI.ActionRegistration.registerActionExtension({ actionId: 'elements.capture-area-screenshot', async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.InspectElementModeController.ToggleSearchActionDelegate.instance(); }, condition: Root.Runtime.ConditionName.CAN_DOCK, title: i18nLazyString(UIStrings.captureAreaScreenshot), category: UI.ActionRegistration.ActionCategory.SCREENSHOT, }); UI.ActionRegistration.registerActionExtension({ category: UI.ActionRegistration.ActionCategory.ELEMENTS, actionId: 'elements.toggle-element-search', toggleable: true, async loadActionDelegate() { const Elements = await loadElementsModule(); return Elements.InspectElementModeController.ToggleSearchActionDelegate.instance(); }, title: i18nLazyString(UIStrings.selectAnElementInThePageTo), iconClass: UI.ActionRegistration.IconClass.LARGEICON_NODE_SEARCH, bindings: [ { shortcut: 'Ctrl+Shift+C', platform: UI.ActionRegistration.Platforms.WindowsLinux, }, { shortcut: 'Meta+Shift+C', platform: UI.ActionRegistration.Platforms.Mac, }, ], }); Common.Settings.registerSettingExtension({ category: Common.Settings.SettingCategory.ELEMENTS, storageType: Common.Settings.SettingStorageType.Synced, order: 1, title: i18nLazyString(UIStrings.showUserAgentShadowDOM), settingName: 'showUAShadowDOM', settingType: Common.Settings.SettingType.BOOLEAN, defaultValue: false, }); Common.Settings.registerSettingExtension({ category: Common.Settings.SettingCategory.ELEMENTS, storageType: Common.Settings.SettingStorageType.Synced, order: 2, title: i18nLazyString(UIStrings.wordWrap), settingName: 'domWordWrap', settingType: Common.Settings.SettingType.BOOLEAN, options: [ { value: true, title: i18nLazyString(UIStrings.enableDomWordWrap), }, { value: false, title: i18nLazyString(UIStrings.disableDomWordWrap), }, ], defaultValue: true, }); Common.Settings.registerSettingExtension({ category: Common.Settings.SettingCategory.ELEMENTS, storageType: Common.Settings.SettingStorageType.Synced, order: 3, title: i18nLazyString(UIStrings.showHtmlComments), settingName: 'showHTMLComments', settingType: Common.Settings.SettingType.BOOLEAN, defaultValue: true, options: [ { value: true, title: i18nLazyString(UIStrings.showHtmlComments), }, { value: false, title: i18nLazyString(UIStrings.hideHtmlComments), }, ], }); Common.Settings.registerSettingExtension({ category: Common.Settings.SettingCategory.ELEMENTS, storageType: Common.Settings.SettingStorageType.Synced, order: 4, title: i18nLazyString(UIStrings.revealDomNodeOnHover), settingName: 'highlightNodeOnHoverInOverlay', settingType: Common.Settings.SettingType.BOOLEAN, defaultValue: true, }); Common.Settings.registerSettingExtension({ category: Common.Settings.SettingCategory.ELEMENTS, storageType: Common.Settings.SettingStorageType.Synced, order: 5, title: i18nLazyString(UIStrings.showDetailedInspectTooltip), settingName: 'showDetailedInspectTooltip', settingType: Common.Settings.SettingType.BOOLEAN, defaultValue: true, }); Common.Settings.registerSettingExtension({ settingName: 'showEventListenersForAncestors', settingType: Common.Settings.SettingType.BOOLEAN, defaultValue: true, }); Common.Settings.registerSettingExtension({ category: Common.Settings.SettingCategory.ADORNER, storageType: Common.Settings.SettingStorageType.Synced, settingName: 'adornerSettings', settingType: Common.Settings.SettingType.ARRAY, defaultValue: [], }); Common.Settings.registerSettingExtension({ category: Common.Settings.SettingCategory.ELEMENTS, storageType: Common.Settings.SettingStorageType.Synced, title: i18nLazyString(UIStrings.showCSSDocumentationTooltip), settingName: 'showCSSPropertyDocumentationOnHover', settingType: Common.Settings.SettingType.BOOLEAN, defaultValue: true, }); UI.ContextMenu.registerProvider({ contextTypes() { return [ SDK.RemoteObject.RemoteObject, SDK.DOMModel.DOMNode, SDK.DOMModel.DeferredDOMNode, ]; }, async loadProvider() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ContextMenuProvider.instance(); }, experiment: undefined, }); UI.ViewManager.registerLocationResolver({ name: UI.ViewManager.ViewLocationValues.ELEMENTS_SIDEBAR, category: UI.ViewManager.ViewLocationCategory.ELEMENTS, async loadResolver() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.ElementsPanel.instance(); }, }); Common.Revealer.registerRevealer({ contextTypes() { return [ SDK.DOMModel.DOMNode, SDK.DOMModel.DeferredDOMNode, SDK.RemoteObject.RemoteObject, ]; }, destination: Common.Revealer.RevealerDestination.ELEMENTS_PANEL, async loadRevealer() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.DOMNodeRevealer.instance(); }, }); Common.Revealer.registerRevealer({ contextTypes() { return [ SDK.CSSProperty.CSSProperty, ]; }, destination: Common.Revealer.RevealerDestination.STYLES_SIDEBAR, async loadRevealer() { const Elements = await loadElementsModule(); return Elements.ElementsPanel.CSSPropertyRevealer.instance(); }, }); UI.Toolbar.registerToolbarItem({ async loadItem() { const Elements = await loadElementsModule(); return Elements.LayersWidget.ButtonProvider.instance(); }, order: 1, location: UI.Toolbar.ToolbarItemLocation.STYLES_SIDEBARPANE_TOOLBAR, showLabel: undefined, condition: undefined, separator: undefined, actionId: undefined, }); UI.Toolbar.registerToolbarItem({ async loadItem() { const Elements = await loadElementsModule(); return Elements.ElementStatePaneWidget.ButtonProvider.instance(); }, order: 2, location: UI.Toolbar.ToolbarItemLocation.STYLES_SIDEBARPANE_TOOLBAR, showLabel: undefined, condition: undefined, separator: undefined, actionId: undefined, }); UI.Toolbar.registerToolbarItem({ async loadItem() { const Elements = await loadElementsModule(); return Elements.ClassesPaneWidget.ButtonProvider.instance(); }, order: 3, location: UI.Toolbar.ToolbarItemLocation.STYLES_SIDEBARPANE_TOOLBAR, showLabel: undefined, condition: undefined, separator: undefined, actionId: undefined, }); UI.Toolbar.registerToolbarItem({ async loadItem() { const Elements = await loadElementsModule(); return Elements.StylesSidebarPane.ButtonProvider.instance(); }, order: 100, location: UI.Toolbar.ToolbarItemLocation.STYLES_SIDEBARPANE_TOOLBAR, showLabel: undefined, condition: undefined, separator: undefined, actionId: undefined, }); UI.Toolbar.registerToolbarItem({ actionId: 'elements.toggle-element-search', location: UI.Toolbar.ToolbarItemLocation.MAIN_TOOLBAR_LEFT, order: 0, showLabel: undefined, condition: undefined, separator: undefined, loadItem: undefined, }); UI.UIUtils.registerRenderer({ contextTypes() { return [SDK.DOMModel.DOMNode, SDK.DOMModel.DeferredDOMNode]; }, async loadRenderer() { const Elements = await loadElementsModule(); return Elements.ElementsTreeOutline.Renderer.instance(); }, }); Common.Linkifier.registerLinkifier({ contextTypes() { return [ SDK.DOMModel.DOMNode, SDK.DOMModel.DeferredDOMNode, ]; }, async loadLinkifier() { const Elements = await loadElementsModule(); return Elements.DOMLinkifier.Linkifier.instance(); }, });