| // Copyright 2015 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import type * as SDK from '../../core/sdk/sdk.js'; |
| import {PanelUtils} from '../utils/utils.js'; |
| |
| import type {StylePropertiesSection} from './StylePropertiesSection.js'; |
| import {StylePropertyTreeElement} from './StylePropertyTreeElement.js'; |
| import type {StylesSidebarPane} from './StylesSidebarPane.js'; |
| |
| export class StylePropertyHighlighter { |
| private readonly styleSidebarPane: StylesSidebarPane; |
| constructor(ssp: StylesSidebarPane) { |
| this.styleSidebarPane = ssp; |
| } |
| |
| /** |
| * Expand all shorthands, find the given property, scroll to it and highlight it. |
| */ |
| async highlightProperty(cssProperty: SDK.CSSProperty.CSSProperty): Promise<void> { |
| const section = |
| this.styleSidebarPane.allSections().find(section => section.style().allProperties().includes(cssProperty)); |
| if (!section) { |
| return; |
| } |
| section.showAllItems(); |
| const populatePromises: Array<Promise<void>> = []; |
| for (let treeElement = section.propertiesTreeOutline.firstChild(); treeElement; |
| treeElement = treeElement.nextSibling) { |
| populatePromises.push(treeElement.onpopulate()); |
| } |
| await Promise.all(populatePromises); |
| |
| const treeElement = this.findTreeElementFromSection(treeElement => treeElement.property === cssProperty, section); |
| if (treeElement) { |
| treeElement.parent?.expand(); |
| this.scrollAndHighlightTreeElement(treeElement); |
| section.element.focus(); |
| } |
| } |
| |
| findAndHighlightSectionBlock(sectionBlockName: string): void { |
| const block = this.styleSidebarPane.getSectionBlockByName(sectionBlockName); |
| if (!block || block.sections.length === 0) { |
| return; |
| } |
| const [section] = block.sections; |
| section.showAllItems(); |
| PanelUtils.highlightElement(block.titleElement() as HTMLElement); |
| } |
| |
| findAndHighlightSection(sectionName: string, blockName: string): void { |
| const block = this.styleSidebarPane.getSectionBlockByName(blockName); |
| const section = block?.sections.find(section => section.headerText() === sectionName); |
| if (!section || !block) { |
| return; |
| } |
| block.expand(true); |
| section.showAllItems(); |
| PanelUtils.highlightElement(section.element); |
| } |
| |
| /** |
| * Find the first non-overridden property that matches the provided name, scroll to it and highlight it. |
| */ |
| findAndHighlightPropertyName(propertyName: string, sectionName?: string, blockName?: string): boolean { |
| const block = blockName ? this.styleSidebarPane.getSectionBlockByName(blockName) : undefined; |
| const sections = block?.sections ?? this.styleSidebarPane.allSections(); |
| if (!sections) { |
| return false; |
| } |
| for (const section of sections) { |
| if (sectionName && section.headerText() !== sectionName) { |
| continue; |
| } |
| if (!section.style().hasActiveProperty(propertyName)) { |
| continue; |
| } |
| block?.expand(true); |
| section.showAllItems(); |
| const treeElement = this.findTreeElementFromSection( |
| treeElement => treeElement.property.name === propertyName && !treeElement.overloaded(), section); |
| if (treeElement) { |
| this.scrollAndHighlightTreeElement(treeElement); |
| section.element.focus(); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private findTreeElementFromSection( |
| compareCb: (arg0: StylePropertyTreeElement) => boolean, section: StylePropertiesSection): StylePropertyTreeElement |
| |null { |
| let treeElement = section.propertiesTreeOutline.firstChild(); |
| while (treeElement && (treeElement instanceof StylePropertyTreeElement)) { |
| if (compareCb(treeElement)) { |
| return treeElement; |
| } |
| treeElement = treeElement.traverseNextTreeElement(false, null, true); |
| } |
| return null; |
| } |
| |
| private scrollAndHighlightTreeElement(treeElement: StylePropertyTreeElement): void { |
| PanelUtils.highlightElement(treeElement.listItemElement); |
| } |
| } |