Skip to content

Commit c2671e2

Browse files
pfaffeDevtools-frontend LUCI CQ
authored andcommitted
[css] Store the match type on renderers
This will allow decoupling matchers from renderers more, which is a prerequisite for storing match results on CSSProperty. Bug: 373554278 Change-Id: Ie969e3cba087b04ec007139c5baca065c345afda Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6219312 Commit-Queue: Philip Pfaffe <[email protected]> Reviewed-by: Eric Leese <[email protected]>
1 parent de5d1aa commit c2671e2

File tree

5 files changed

+162
-78
lines changed

5 files changed

+162
-78
lines changed

front_end/core/sdk/CSSPropertyParser.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export type Constructor<T = any> = (abstract new (...args: any[]) => T)|(new (..
185185
export interface Matcher<MatchT extends Match> {
186186
readonly matchType: Constructor<MatchT>;
187187
accepts(propertyName: string): boolean;
188-
matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null;
188+
matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): MatchT|null;
189189
}
190190

191191
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
@@ -196,7 +196,7 @@ export function matcherBase<MatchT extends Match>(matchT: Constructor<MatchT>) {
196196
return true;
197197
}
198198

199-
matches(_node: CodeMirror.SyntaxNode, _matching: BottomUpTreeMatching): Match|null {
199+
matches(_node: CodeMirror.SyntaxNode, _matching: BottomUpTreeMatching): MatchT|null {
200200
return null;
201201
}
202202
}
@@ -520,7 +520,7 @@ export class VariableMatcher extends matcherBase(VariableMatch) {
520520
this.#computedTextCallback = computedTextCallback;
521521
}
522522

523-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
523+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): VariableMatch|null {
524524
const callee = node.getChild('Callee');
525525
const args = node.getChild('ArgList');
526526
if (node.name !== 'CallExpression' || !callee || (matching.ast.text(callee) !== 'var') || !args) {
@@ -581,7 +581,7 @@ class TextMatcher extends matcherBase(TextMatch) {
581581
override accepts(): boolean {
582582
return true;
583583
}
584-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
584+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): TextMatch|null {
585585
if (!node.firstChild || node.name === 'NumberLiteral' /* may have a Unit child */) {
586586
// Leaf node, just emit text
587587
const text = matching.ast.text(node);

front_end/core/sdk/CSSPropertyParserMatchers.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class AngleMatcher extends matcherBase(AngleMatch) {
4141
override accepts(propertyName: string): boolean {
4242
return cssMetadata().isAngleAwareProperty(propertyName);
4343
}
44-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
44+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): AngleMatch|null {
4545
if (node.name !== 'NumberLiteral') {
4646
return null;
4747
}
@@ -77,7 +77,7 @@ export class ColorMixMatcher extends matcherBase(ColorMixMatch) {
7777
override accepts(propertyName: string): boolean {
7878
return cssMetadata().isColorAwareProperty(propertyName);
7979
}
80-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
80+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): ColorMixMatch|null {
8181
if (node.name !== 'CallExpression' || matching.ast.text(node.getChild('Callee')) !== 'color-mix') {
8282
return null;
8383
}
@@ -136,7 +136,7 @@ export class URLMatch implements Match {
136136
// clang-format off
137137
export class URLMatcher extends matcherBase(URLMatch) {
138138
// clang-format on
139-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
139+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): URLMatch|null {
140140
if (node.name !== 'CallLiteral') {
141141
return null;
142142
}
@@ -197,7 +197,7 @@ export class ColorMatcher extends matcherBase(ColorMatch) {
197197
return cssMetadata().isColorAwareProperty(propertyName);
198198
}
199199

200-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
200+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): ColorMatch|null {
201201
const text = matching.ast.text(node);
202202
if (node.name === 'ColorLiteral') {
203203
return new ColorMatch(text, node);
@@ -235,7 +235,7 @@ export class LightDarkColorMatcher extends matcherBase(LightDarkColorMatch) {
235235
return cssMetadata().isColorAwareProperty(propertyName);
236236
}
237237

238-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
238+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): LightDarkColorMatch|null {
239239
if (node.name !== 'CallExpression' || matching.ast.text(node.getChild('Callee')) !== 'light-dark') {
240240
return null;
241241
}
@@ -257,7 +257,7 @@ export class AutoBaseMatch implements Match {
257257
// clang-format off
258258
export class AutoBaseMatcher extends matcherBase(AutoBaseMatch) {
259259
// clang-format on
260-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
260+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): AutoBaseMatch|null {
261261
if (node.name !== 'CallExpression' || matching.ast.text(node.getChild('Callee')) !== '-internal-auto-base') {
262262
return null;
263263
}
@@ -331,7 +331,8 @@ export class LinkableNameMatcher extends matcherBase(LinkableNameMatch) {
331331
}),
332332
);
333333

334-
private matchAnimationNameInShorthand(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
334+
private matchAnimationNameInShorthand(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): LinkableNameMatch|
335+
null {
335336
// Order is important within each animation definition for distinguishing <keyframes-name> values from other keywords.
336337
// When parsing, keywords that are valid for properties other than animation-name
337338
// whose values were not found earlier in the shorthand must be accepted for those properties rather than for animation-name.
@@ -381,7 +382,7 @@ export class LinkableNameMatcher extends matcherBase(LinkableNameMatch) {
381382
return LinkableNameMatcher.isLinkableNameProperty(propertyName);
382383
}
383384

384-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
385+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): LinkableNameMatch|null {
385386
const {propertyName} = matching.ast;
386387
const text = matching.ast.text(node);
387388
const parentNode = node.parent;
@@ -466,7 +467,7 @@ export class ShadowMatcher extends matcherBase(ShadowMatch) {
466467
override accepts(propertyName: string): boolean {
467468
return cssMetadata().isShadowProperty(propertyName);
468469
}
469-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
470+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): ShadowMatch|null {
470471
if (node.name !== 'Declaration') {
471472
return null;
472473
}
@@ -519,7 +520,7 @@ export class LengthMatcher extends matcherBase(LengthMatch) {
519520
'dvb', 'dvmin', 'dvmax', 'svw', 'svh', 'svi', 'svb', 'svmin', 'svmax', 'lvw', 'lvh', 'lvi', 'lvb', 'lvmin',
520521
'lvmax', 'cqw', 'cqh', 'cqi', 'cqb', 'cqmin', 'cqmax', 'cqem', 'cqlh', 'cqex', 'cqch',
521522
]);
522-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
523+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): LengthMatch|null {
523524
if (node.name !== 'NumberLiteral') {
524525
return null;
525526
}
@@ -542,7 +543,7 @@ export class SelectFunctionMatch implements Match {
542543
// clang-format off
543544
export class SelectFunctionMatcher extends matcherBase(SelectFunctionMatch) {
544545
// clang-format on
545-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
546+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): SelectFunctionMatch|null {
546547
if (node.name !== 'CallExpression') {
547548
return null;
548549
}
@@ -573,7 +574,7 @@ export class FlexGridMatcher extends matcherBase(FlexGridMatch) {
573574
return propertyName === 'display';
574575
}
575576

576-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
577+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): FlexGridMatch|null {
577578
if (node.name !== 'Declaration') {
578579
return null;
579580
}
@@ -606,7 +607,7 @@ export class GridTemplateMatcher extends matcherBase(GridTemplateMatch) {
606607
override accepts(propertyName: string): boolean {
607608
return cssMetadata().isGridAreaDefiningProperty(propertyName);
608609
}
609-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
610+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): GridTemplateMatch|null {
610611
if (node.name !== 'Declaration' || matching.hasUnresolvedVars(node)) {
611612
return null;
612613
}
@@ -705,7 +706,7 @@ export class AnchorFunctionMatcher extends matcherBase(AnchorFunctionMatch) {
705706
return null;
706707
}
707708

708-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
709+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): AnchorFunctionMatch|null {
709710
if (node.name === 'VariableName') {
710711
// Double-dashed anchor reference to be rendered with a link to its matching anchor.
711712
let parent = node.parent;
@@ -748,7 +749,7 @@ export class PositionAnchorMatcher extends matcherBase(PositionAnchorMatch) {
748749
return propertyName === 'position-anchor';
749750
}
750751

751-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
752+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): PositionAnchorMatch|null {
752753
if (node.name !== 'VariableName') {
753754
return null;
754755
}
@@ -778,7 +779,7 @@ export class CSSWideKeywordMatcher extends matcherBase(CSSWideKeywordMatch) {
778779
super();
779780
}
780781

781-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
782+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): CSSWideKeywordMatch|null {
782783
const parentNode = node.parent;
783784
if (node.name !== 'ValueName' || parentNode?.name !== 'Declaration') {
784785
return null;
@@ -813,7 +814,7 @@ export class PositionTryMatcher extends matcherBase(PositionTryMatch) {
813814
propertyName === LinkableNameProperties.POSITION_TRY_FALLBACKS;
814815
}
815816

816-
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): Match|null {
817+
override matches(node: CodeMirror.SyntaxNode, matching: BottomUpTreeMatching): PositionTryMatch|null {
817818
if (node.name !== 'Declaration') {
818819
return null;
819820
}

front_end/panels/elements/ComputedStyleWidget.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import computedStyleSidebarPaneStyles from './computedStyleSidebarPane.css.js';
4949
import {ImagePreviewPopover} from './ImagePreviewPopover.js';
5050
import {PlatformFontsWidget} from './PlatformFontsWidget.js';
5151
import {categorizePropertyName, type Category, DefaultCategoryOrder} from './PropertyNameCategories.js';
52-
import {type MatchRenderer, Renderer, type RenderingContext, StringRenderer, URLRenderer} from './PropertyRenderer.js';
52+
import {Renderer, rendererBase, type RenderingContext, StringRenderer, URLRenderer} from './PropertyRenderer.js';
5353
import {StylePropertiesSection} from './StylePropertiesSection.js';
5454

5555
const {html} = Lit;
@@ -178,8 +178,10 @@ const createTraceElement =
178178
return trace;
179179
};
180180

181-
class ColorRenderer implements MatchRenderer<SDK.CSSPropertyParserMatchers.ColorMatch> {
182-
render(match: SDK.CSSPropertyParserMatchers.ColorMatch, context: RenderingContext): Node[] {
181+
// clang-format off
182+
class ColorRenderer extends rendererBase(SDK.CSSPropertyParserMatchers.ColorMatch) {
183+
// clang-format on
184+
override render(match: SDK.CSSPropertyParserMatchers.ColorMatch, context: RenderingContext): Node[] {
183185
const color = Common.Color.parse(match.text);
184186
if (!color) {
185187
return [document.createTextNode(match.text)];

front_end/panels/elements/PropertyRenderer.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,23 @@ function mergeWithSpacing(nodes: Node[], merge: Node[]): Node[] {
3939
}
4040

4141
export interface MatchRenderer<MatchT extends SDK.CSSPropertyParser.Match> {
42-
matcher(): SDK.CSSPropertyParser.Matcher<MatchT>;
42+
readonly matchType: SDK.CSSPropertyParser.Constructor<MatchT>;
4343
render(match: MatchT, context: RenderingContext): Node[];
44+
matcher(): SDK.CSSPropertyParser.Matcher<MatchT>;
45+
}
46+
47+
// A mixin to automatically expose the match type on specific renrerers
48+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
49+
export function rendererBase<MatchT extends SDK.CSSPropertyParser.Match>(
50+
matchT: SDK.CSSPropertyParser.Constructor<MatchT>) {
51+
abstract class RendererBase implements MatchRenderer<MatchT> {
52+
abstract matcher(): SDK.CSSPropertyParser.Matcher<MatchT>;
53+
readonly matchType = matchT;
54+
render(_match: MatchT, _context: RenderingContext): Node[] {
55+
return [];
56+
}
57+
}
58+
return RendererBase;
4459
}
4560

4661
export class RenderingContext {
@@ -172,7 +187,7 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
172187
for (const renderer of renderers) {
173188
const matcher = renderer.matcher();
174189
matchers.push(matcher);
175-
rendererMap.set(matcher.matchType, renderer);
190+
rendererMap.set(renderer.matchType, renderer);
176191
}
177192
const matchedResult = SDK.CSSPropertyParser.BottomUpTreeMatching.walk(ast, matchers);
178193
ast.trailingNodes.forEach(n => matchedResult.matchText(n));
@@ -182,10 +197,14 @@ export class Renderer extends SDK.CSSPropertyParser.TreeWalker {
182197
return valueElement;
183198
}
184199
}
185-
export class URLRenderer implements MatchRenderer<SDK.CSSPropertyParserMatchers.URLMatch> {
200+
201+
// clang-format off
202+
export class URLRenderer extends rendererBase(SDK.CSSPropertyParserMatchers.URLMatch) {
203+
// clang-format on
186204
constructor(private readonly rule: SDK.CSSRule.CSSRule|null, private readonly node: SDK.DOMModel.DOMNode|null) {
205+
super();
187206
}
188-
render(match: SDK.CSSPropertyParserMatchers.URLMatch): Node[] {
207+
override render(match: SDK.CSSPropertyParserMatchers.URLMatch): Node[] {
189208
const url = unescapeCssString(match.url) as Platform.DevToolsPath.UrlString;
190209
const container = document.createDocumentFragment();
191210
UI.UIUtils.createTextChild(container, 'url(');
@@ -218,8 +237,10 @@ export class URLRenderer implements MatchRenderer<SDK.CSSPropertyParserMatchers.
218237
}
219238
}
220239

221-
export class StringRenderer implements MatchRenderer<SDK.CSSPropertyParserMatchers.StringMatch> {
222-
render(match: SDK.CSSPropertyParserMatchers.StringMatch): Node[] {
240+
// clang-format off
241+
export class StringRenderer extends rendererBase(SDK.CSSPropertyParserMatchers.StringMatch) {
242+
// clang-format on
243+
override render(match: SDK.CSSPropertyParserMatchers.StringMatch): Node[] {
223244
const element = document.createElement('span');
224245
element.innerText = match.text;
225246
UI.Tooltip.Tooltip.install(element, unescapeCssString(match.text));

0 commit comments

Comments
 (0)