// Copyright 2024 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 '../../../../core/i18n/i18n.js'; import type * as Platform from '../../../../core/platform/platform.js'; import type {CLSCulpritsInsightModel} from '../../../../models/trace/insights/CLSCulprits.js'; import * as Trace from '../../../../models/trace/trace.js'; import * as Lit from '../../../../ui/lit/lit.js'; import {BaseInsightComponent} from './BaseInsightComponent.js'; import {EventReferenceClick} from './EventRef.js'; import {nodeLink} from './NodeLink.js'; const {UIStrings, i18nString} = Trace.Insights.Models.CLSCulprits; const {html} = Lit; export class CLSCulprits extends BaseInsightComponent { override internalName = 'cls-culprits'; protected override hasAskAiSupport(): boolean { return true; } override createOverlays(): Trace.Types.Overlays.Overlay[] { if (!this.model) { return []; } return this.model.createOverlays?.() ?? []; } #clickEvent(event: Trace.Types.Events.Event): void { this.element.dispatchEvent(new EventReferenceClick(event)); } #renderCulpritsSection(culprits: Trace.Insights.Models.CLSCulprits.LayoutShiftItem[]): Lit.LitTemplate { if (culprits.length === 0) { return html`
${i18nString(UIStrings.noCulprits)}
`; } // clang-format off return html`

${i18nString(UIStrings.topCulprits)}:

`; // clang-format on } override renderContent(): Lit.LitTemplate { if (!this.model || !this.bounds) { return Lit.nothing; } if (!this.model.clusters.length || !this.model.worstCluster) { return html`
${i18nString(UIStrings.noLayoutShifts)}
`; } const worstCluster = this.model.worstCluster; const culprits = this.model.topCulpritsByCluster.get(worstCluster) ?? []; const ts = Trace.Types.Timing.Micro(worstCluster.ts - this.bounds.min); const clusterTs = i18n.TimeUtilities.formatMicroSecondsTime(ts); // clang-format off return html`
${i18nString(UIStrings.worstCluster)}:
${this.#renderCulpritsSection(culprits)} `; // clang-format on } }