UNPKG

chrome-devtools-frontend

Version:
133 lines (115 loc) 4.87 kB
// Copyright (c) 2024 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 '../../../ui/components/icon_button/icon_button.js'; import '../../../ui/legacy/components/inline_editor/inline_editor.js'; import * as i18n from '../../../core/i18n/i18n.js'; import type * as SDK from '../../../core/sdk/sdk.js'; import type * as InlineEditor from '../../../ui/legacy/components/inline_editor/inline_editor.js'; import * as Lit from '../../../ui/lit/lit.js'; import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js'; import anchorFunctionLinkSwatchStylesRaw from './anchorFunctionLinkSwatch.css.js'; // TODO(crbug.com/391381439): Fully migrate off of constructed style sheets. const anchorFunctionLinkSwatchStyles = new CSSStyleSheet(); anchorFunctionLinkSwatchStyles.replaceSync(anchorFunctionLinkSwatchStylesRaw.cssContent); const UIStrings = { /** *@description Title in the styles tab for the icon button for jumping to the anchor node. */ jumpToAnchorNode: 'Jump to anchor node', }; const str_ = i18n.i18n.registerUIStrings('panels/elements/components/AnchorFunctionLinkSwatch.ts', UIStrings); const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); const {render, html} = Lit; // Clang format is messing up the formatting of the functions below. It's best // to leave formatting off for this type declaration. // clang-format off export interface AnchorFunctionLinkSwatchData { onLinkActivate: () => void; onMouseEnter: () => void; onMouseLeave: () => void; // The dashed identifier for the anchor function. // It is undefined when we're rendering for implicit or default anchor cases. identifier?: string; // The anchor node, it is undefined when it is not resolved correctly. anchorNode?: SDK.DOMModel.DOMNode; // Whether to add a space after the link or not. This is needed because for some cases, // even though the link swatch is created; there might not be any links rendered for it. // So adding the space from the outside causes an unnecessary space to be rendered for these cases. // That's the reason we're controlling space behavior from the inside. // However for `position-anchor: --dashed-ident` case, there is no space needed at all. // That's why we need the parameter so that we don't render a space for that case. needsSpace?: boolean; } // clang-format on export class AnchorFunctionLinkSwatch extends HTMLElement { readonly #shadow = this.attachShadow({mode: 'open'}); #data: AnchorFunctionLinkSwatchData; constructor(data: AnchorFunctionLinkSwatchData) { super(); this.#data = data; } dataForTest(): AnchorFunctionLinkSwatchData { return this.#data; } connectedCallback(): void { this.#shadow.adoptedStyleSheets = [anchorFunctionLinkSwatchStyles]; this.render(); } set data(data: AnchorFunctionLinkSwatchData) { this.#data = data; this.render(); } #handleIconClick(ev: MouseEvent): void { ev.stopPropagation(); this.#data.onLinkActivate(); } #renderIdentifierLink(): Lit.LitTemplate { // clang-format off return html`<devtools-link-swatch @mouseenter=${this.#data.onMouseEnter} @mouseleave=${this.#data.onMouseLeave} .data=${{ text: this.#data.identifier, isDefined: Boolean(this.#data.anchorNode), jslogContext: 'anchor-link', onLinkActivate: this.#data.onLinkActivate, } as InlineEditor.LinkSwatch.LinkSwatchRenderData}></devtools-link-swatch>`; // clang-format on } #renderIconLink(): Lit.LitTemplate { // clang-format off return html`<devtools-icon role='button' title=${i18nString(UIStrings.jumpToAnchorNode)} class='icon-link' name='open-externally' jslog=${VisualLogging.action('jump-to-anchor-node').track({click: true})} @mouseenter=${this.#data.onMouseEnter} @mouseleave=${this.#data.onMouseLeave} @mousedown=${(ev: MouseEvent) => ev.stopPropagation()} @click=${this.#handleIconClick} ></devtools-icon>`; // clang-format on } protected render(): void { if (!this.#data.identifier && !this.#data.anchorNode) { return; } if (this.#data.identifier) { // clang-format off render(html`${this.#renderIdentifierLink()}${this.#data.needsSpace ? ' ' : ''}`, this.#shadow, {host: this}); // clang-format on } else { // clang-format off render(html`${this.#renderIconLink()}${this.#data.needsSpace ? ' ' : ''}`, this.#shadow, {host: this}); // clang-format on } } } customElements.define('devtools-anchor-function-link-swatch', AnchorFunctionLinkSwatch); declare global { interface HTMLElementTagNameMap { 'devtools-anchor-function-link-swatch': AnchorFunctionLinkSwatch; } }