blob: 75683459209360720c024077e567d134f55edf4e [file] [log] [blame]
// Copyright 2025 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 SDK from '../core/sdk/sdk.js';
import * as Protocol from '../generated/protocol.js';
import {
clearMockConnectionResponseHandler,
type ProtocolCommandHandler,
setMockConnectionResponseHandler
} from './MockConnection.js';
export function getMatchedStylesWithStylesheet(payload: {
cssModel: SDK.CSSModel.CSSModel,
origin: Protocol.CSS.StyleSheetOrigin,
styleSheetId: Protocol.DOM.StyleSheetId,
getEnvironmentVariablesCallback?: ProtocolCommandHandler<'CSS.getEnvironmentVariables'>,
}&Partial<Protocol.CSS.CSSStyleSheetHeader>&Partial<SDK.CSSMatchedStyles.CSSMatchedStylesPayload>):
Promise<SDK.CSSMatchedStyles.CSSMatchedStyles> {
payload.cssModel.styleSheetAdded({
frameId: '' as Protocol.Page.FrameId,
sourceURL: '',
title: '',
disabled: false,
isInline: false,
isMutable: false,
isConstructed: false,
startLine: 0,
startColumn: 0,
length: 0,
endLine: 0,
endColumn: 0,
...payload,
});
return getMatchedStyles(payload, payload.getEnvironmentVariablesCallback);
}
export function getMatchedStylesWithBlankRule(payload: {
cssModel: SDK.CSSModel.CSSModel,
selector?: string,
range?: Protocol.CSS.SourceRange,
origin?: Protocol.CSS.StyleSheetOrigin,
styleSheetId?: Protocol.DOM.StyleSheetId,
getEnvironmentVariablesCallback?: ProtocolCommandHandler<'CSS.getEnvironmentVariables'>,
}&Partial<SDK.CSSMatchedStyles.CSSMatchedStylesPayload>) {
return getMatchedStylesWithProperties({properties: {}, ...payload});
}
export function createCSSStyle(
cssProperties: Protocol.CSS.CSSProperty[],
range?: Protocol.CSS.SourceRange,
styleSheetId = '0' as Protocol.DOM.StyleSheetId,
): Protocol.CSS.CSSStyle {
return {
cssProperties,
styleSheetId,
range,
shorthandEntries: [],
};
}
function getSimpleList(selector: string): Protocol.CSS.SelectorList {
return {
selectors: [{text: selector}],
text: selector,
};
}
export function ruleMatch(
selectorOrList: string|Protocol.CSS.SelectorList,
properties: Protocol.CSS.CSSProperty[]|Record<string, string>,
options: {
range?: Protocol.CSS.SourceRange,
origin?: Protocol.CSS.StyleSheetOrigin,
styleSheetId?: Protocol.DOM.StyleSheetId,
/** Matches all selectors if undefined */
matchingSelectorsIndexes?: number[],
nestingSelectors?: string[],
} = {},
): Protocol.CSS.RuleMatch {
const {
range,
origin = Protocol.CSS.StyleSheetOrigin.Regular,
styleSheetId,
matchingSelectorsIndexes,
nestingSelectors,
} = options;
const cssProperties =
Array.isArray(properties) ? properties : Object.keys(properties).map(name => ({name, value: properties[name]}));
const selectorList = typeof selectorOrList === 'string' ? getSimpleList(selectorOrList) : selectorOrList;
const matchingSelectors = matchingSelectorsIndexes ?? selectorList.selectors.map((_, index) => index);
return {
rule: {
nestingSelectors,
selectorList,
origin,
style: createCSSStyle(cssProperties, range, styleSheetId),
styleSheetId,
},
matchingSelectors,
};
}
export function getMatchedStylesWithProperties(payload: {
cssModel: SDK.CSSModel.CSSModel,
properties: Protocol.CSS.CSSProperty[]|Record<string, string>,
selector?: string,
range?: Protocol.CSS.SourceRange,
origin?: Protocol.CSS.StyleSheetOrigin,
styleSheetId?: Protocol.DOM.StyleSheetId,
getEnvironmentVariablesCallback?: ProtocolCommandHandler<'CSS.getEnvironmentVariables'>,
}&Partial<SDK.CSSMatchedStyles.CSSMatchedStylesPayload>) {
const styleSheetId = payload.styleSheetId ?? '0' as Protocol.DOM.StyleSheetId;
const range = payload.range;
const origin = payload.origin ?? Protocol.CSS.StyleSheetOrigin.Regular;
const matchedPayload = [ruleMatch(payload.selector ?? 'div', payload.properties, {range, origin, styleSheetId})];
return getMatchedStylesWithStylesheet({styleSheetId, origin, matchedPayload, ...payload});
}
export function getMatchedStyles(
payload: Partial<SDK.CSSMatchedStyles.CSSMatchedStylesPayload> = {},
getEnvironmentVariablesCallback: ProtocolCommandHandler<'CSS.getEnvironmentVariables'> = () =>
({environmentVariables: {}})) {
clearMockConnectionResponseHandler('CSS.getEnvironmentVariables');
setMockConnectionResponseHandler('CSS.getEnvironmentVariables', getEnvironmentVariablesCallback);
let node = payload.node;
if (!node) {
node = sinon.createStubInstance(SDK.DOMModel.DOMNode);
node.id = 1 as Protocol.DOM.NodeId;
}
let cssModel = payload.cssModel;
if (!cssModel) {
cssModel = sinon.createStubInstance(SDK.CSSModel.CSSModel);
}
return SDK.CSSMatchedStyles.CSSMatchedStyles.create({
cssModel,
node,
inlinePayload: null,
attributesPayload: null,
matchedPayload: [],
pseudoPayload: [],
inheritedPayload: [],
inheritedPseudoPayload: [],
animationsPayload: [],
parentLayoutNodeId: undefined,
positionTryRules: [],
propertyRules: [],
cssPropertyRegistrations: [],
atRules: [],
activePositionFallbackIndex: -1,
animationStylesPayload: [],
transitionsStylePayload: null,
inheritedAnimatedPayload: [],
functionRules: [],
...payload,
});
}