chrome-devtools-frontend
Version:
Chrome DevTools UI
147 lines (124 loc) • 5.02 kB
text/typescript
// Copyright (c) 2021 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 SDK from '../../../core/sdk/sdk.js';
import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
import * as IconButton from '../../../ui/components/icon_button/icon_button.js';
import * as LitHtml from '../../../ui/lit-html/lit-html.js';
import type {DOMNode} from './Helper.js';
import {NodeText} from './NodeText.js';
import type {NodeTextData} from './NodeText.js';
import queryContainerStyles from './queryContainer.css.js';
const {render, html} = LitHtml;
const {PhysicalAxis, QueryAxis} = SDK.CSSContainerQuery;
export class QueriedSizeRequestedEvent extends Event {
static readonly eventName = 'queriedsizerequested';
constructor() {
super(QueriedSizeRequestedEvent.eventName, {});
}
}
export interface QueryContainerData {
container: DOMNode;
queryName?: string;
onContainerLinkClick: (event: Event) => void;
}
export class QueryContainer extends HTMLElement {
static readonly litTagName = LitHtml.literal`devtools-query-container`;
private readonly shadow = this.attachShadow({mode: 'open'});
private queryName?: string;
private container?: DOMNode;
private onContainerLinkClick?: (event: Event) => void;
private isContainerLinkHovered = false;
private queriedSizeDetails?: SDK.CSSContainerQuery.ContainerQueriedSizeDetails;
set data(data: QueryContainerData) {
this.queryName = data.queryName;
this.container = data.container;
this.onContainerLinkClick = data.onContainerLinkClick;
this.render();
}
connectedCallback(): void {
this.shadow.adoptedStyleSheets = [queryContainerStyles];
}
updateContainerQueriedSizeDetails(details: SDK.CSSContainerQuery.ContainerQueriedSizeDetails): void {
this.queriedSizeDetails = details;
this.render();
}
private async onContainerLinkMouseEnter(): Promise<void> {
this.container?.highlightNode('container-outline');
this.isContainerLinkHovered = true;
this.dispatchEvent(new QueriedSizeRequestedEvent());
}
private onContainerLinkMouseLeave(): void {
this.container?.clearHighlight();
this.isContainerLinkHovered = false;
this.render();
}
private render(): void {
if (!this.container) {
return;
}
let idToDisplay, classesToDisplay;
if (!this.queryName) {
idToDisplay = this.container.getAttribute('id');
classesToDisplay = this.container.getAttribute('class')?.split(/\s+/).filter(Boolean);
}
const nodeTitle = this.queryName || this.container.nodeNameNicelyCased;
// Disabled until https://crbug.com/1079231 is fixed.
// clang-format off
// eslint-disable-next-line rulesdir/ban_a_tags_in_lit_html
render(html`
→
<a href="#"
draggable=false
class="container-link"
=${this.onContainerLinkClick}
=${this.onContainerLinkMouseEnter}
=${this.onContainerLinkMouseLeave}
><${NodeText.litTagName}
data-node-title=${nodeTitle}
.data=${{
nodeTitle,
nodeId: idToDisplay,
nodeClasses: classesToDisplay,
} as NodeTextData}></${NodeText.litTagName}></a>
${this.isContainerLinkHovered ? this.renderQueriedSizeDetails() : LitHtml.nothing}
`, this.shadow, {
host: this,
});
// clang-format on
}
private renderQueriedSizeDetails(): LitHtml.TemplateResult|{} {
if (!this.queriedSizeDetails || this.queriedSizeDetails.queryAxis === QueryAxis.None) {
return LitHtml.nothing;
}
const areBothAxesQueried = this.queriedSizeDetails.queryAxis === QueryAxis.Both;
const axisIconClasses = LitHtml.Directives.classMap({
'axis-icon': true,
'hidden': areBothAxesQueried,
'vertical': this.queriedSizeDetails.physicalAxis === PhysicalAxis.Vertical,
});
// Disabled until https://crbug.com/1079231 is fixed.
// clang-format off
return html`
<span class="queried-size-details">
(${this.queriedSizeDetails.queryAxis}<${IconButton.Icon.Icon.litTagName}
class=${axisIconClasses} .data=${{
iconName: 'ic_dimension_single',
color: 'var(--color-text-primary)',
} as IconButton.Icon.IconData}></${IconButton.Icon.Icon.litTagName}>)
${areBothAxesQueried && this.queriedSizeDetails.width ? 'width:' : LitHtml.nothing}
${this.queriedSizeDetails.width || LitHtml.nothing}
${areBothAxesQueried && this.queriedSizeDetails.height ? 'height:' : LitHtml.nothing}
${this.queriedSizeDetails.height || LitHtml.nothing}
</span>
`;
// clang-format on
}
}
ComponentHelpers.CustomElements.defineComponent('devtools-query-container', QueryContainer);
declare global {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface HTMLElementTagNameMap {
'devtools-query-container': QueryContainer;
}
}