UNPKG

chrome-devtools-frontend

Version:
140 lines (121 loc) 4.28 kB
// Copyright 2021 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 Protocol from '../../generated/protocol.js'; import * as TextUtils from '../../models/text_utils/text_utils.js'; import type {CSSModel} from './CSSModel.js'; import {CSSQuery} from './CSSQuery.js'; import type {DOMNode} from './DOMModel.js'; export class CSSContainerQuery extends CSSQuery { name?: string; physicalAxes?: Protocol.DOM.PhysicalAxes; logicalAxes?: Protocol.DOM.LogicalAxes; queriesScrollState?: boolean; queriesAnchored?: boolean; static parseContainerQueriesPayload(cssModel: CSSModel, payload: Protocol.CSS.CSSContainerQuery[]): CSSContainerQuery[] { return payload.map(cq => new CSSContainerQuery(cssModel, cq)); } constructor(cssModel: CSSModel, payload: Protocol.CSS.CSSContainerQuery) { super(cssModel); this.reinitialize(payload); } reinitialize(payload: Protocol.CSS.CSSContainerQuery): void { this.text = payload.text; this.range = payload.range ? TextUtils.TextRange.TextRange.fromObject(payload.range) : null; this.styleSheetId = payload.styleSheetId; this.name = payload.name; this.physicalAxes = payload.physicalAxes; this.logicalAxes = payload.logicalAxes; this.queriesScrollState = payload.queriesScrollState; this.queriesAnchored = payload.queriesAnchored; } active(): boolean { return true; } async getContainerForNode(nodeId: Protocol.DOM.NodeId): Promise<CSSContainerQueryContainer|undefined> { const containerNode = await this.cssModel.domModel().getContainerForNode( nodeId, this.name, this.physicalAxes, this.logicalAxes, this.queriesScrollState, this.queriesAnchored); if (!containerNode) { return; } return new CSSContainerQueryContainer(containerNode); } } export class CSSContainerQueryContainer { readonly containerNode: DOMNode; constructor(containerNode: DOMNode) { this.containerNode = containerNode; } async getContainerSizeDetails(): Promise<ContainerQueriedSizeDetails|undefined> { const styles = await this.containerNode.domModel().cssModel().getComputedStyle(this.containerNode.id); if (!styles) { return; } const containerType = styles.get('container-type'); const writingMode = styles.get('writing-mode'); if (!containerType || !writingMode) { return; } const queryAxis = getQueryAxisFromContainerType(`${containerType}`); const physicalAxis = getPhysicalAxisFromQueryAxis(queryAxis, writingMode); let width, height; if (physicalAxis === PhysicalAxis.BOTH || physicalAxis === PhysicalAxis.HORIZONTAL) { width = styles.get('width'); } if (physicalAxis === PhysicalAxis.BOTH || physicalAxis === PhysicalAxis.VERTICAL) { height = styles.get('height'); } return { queryAxis, physicalAxis, width, height, }; } } export const getQueryAxisFromContainerType = (propertyValue: string): QueryAxis => { const segments = propertyValue.split(' '); let isInline = false; for (const segment of segments) { if (segment === 'size') { return QueryAxis.BOTH; } isInline = isInline || segment === 'inline-size'; } if (isInline) { return QueryAxis.INLINE; } return QueryAxis.NONE; }; export const getPhysicalAxisFromQueryAxis = (queryAxis: QueryAxis, writingMode: string): PhysicalAxis => { const isVerticalWritingMode = writingMode.startsWith('vertical'); switch (queryAxis) { case QueryAxis.NONE: return PhysicalAxis.NONE; case QueryAxis.BOTH: return PhysicalAxis.BOTH; case QueryAxis.INLINE: return isVerticalWritingMode ? PhysicalAxis.VERTICAL : PhysicalAxis.HORIZONTAL; case QueryAxis.BLOCK: return isVerticalWritingMode ? PhysicalAxis.HORIZONTAL : PhysicalAxis.VERTICAL; } }; export interface ContainerQueriedSizeDetails { queryAxis: QueryAxis; physicalAxis: PhysicalAxis; width?: string; height?: string; } export const enum QueryAxis { NONE = '', INLINE = 'inline-size', BLOCK = 'block-size', BOTH = 'size', } export const enum PhysicalAxis { NONE = '', HORIZONTAL = 'Horizontal', VERTICAL = 'Vertical', BOTH = 'Both', }