Skip to content

Commit 9b4d93e

Browse files
pfaffeDevtools-frontend LUCI CQ
authored andcommitted
CSS Value tracing for substitutions
Bug: 396080529 Change-Id: Icd3de860e343180836d1a31c68daaaa11cf44e64 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6284853 Commit-Queue: Philip Pfaffe <[email protected]> Reviewed-by: Eric Leese <[email protected]> Reviewed-by: Changhao Han <[email protected]>
1 parent 7ea9140 commit 9b4d93e

File tree

4 files changed

+69
-6
lines changed

4 files changed

+69
-6
lines changed

front_end/panels/elements/CSSValueTraceView.test.ts

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,55 @@ describeWithMockConnection('CSSValueTraceView', () => {
120120
}
121121
});
122122

123-
it('does not have substitutions yet', async () => {
123+
it('applies substitutions', async () => {
124124
const {matchedStyles, stylesPane} = await setUpStyles();
125125
const {property, treeElement} =
126-
await getTreeElement(matchedStyles, stylesPane, 'width', 'var(--w)', {'--w': {value: '40em'}});
126+
await getTreeElement(matchedStyles, stylesPane, 'width', 'var(--w)', {'--w': {value: '40px'}});
127+
const input = await showTrace(property, matchedStyles, treeElement);
128+
const substitutions = input.substitutions.map(nodes => nodes.map(node => node.textContent ?? '').join());
129+
const evaluations = input.evaluations.map(nodes => nodes.map(node => node.textContent ?? '').join());
130+
const result = input.finalResult?.map(node => node.textContent ?? '').join();
131+
assert.deepEqual(substitutions, []);
132+
assert.deepEqual(evaluations, []);
133+
assert.deepEqual(result, '40px');
134+
});
135+
136+
it('substitutes the variable declaration if the variable is found (with fallback)', async () => {
137+
const {matchedStyles, stylesPane} = await setUpStyles();
138+
const {property, treeElement} =
139+
await getTreeElement(matchedStyles, stylesPane, 'width', 'var(--w, 10px)', {'--w': {value: '40px'}});
140+
const input = await showTrace(property, matchedStyles, treeElement);
141+
const substitutions = input.substitutions.map(nodes => nodes.map(node => node.textContent ?? '').join());
142+
const evaluations = input.evaluations.map(nodes => nodes.map(node => node.textContent ?? '').join());
143+
const result = input.finalResult?.map(node => node.textContent ?? '').join();
144+
assert.deepEqual(substitutions, []);
145+
assert.deepEqual(evaluations, []);
146+
assert.deepEqual(result, '40px');
147+
});
148+
149+
it('substitutes the fallback if the variable is found', async () => {
150+
const {matchedStyles, stylesPane} = await setUpStyles();
151+
const {property, treeElement} = await getTreeElement(matchedStyles, stylesPane, 'width', 'var(--w, 10px)');
152+
const input = await showTrace(property, matchedStyles, treeElement);
153+
const substitutions = input.substitutions.map(nodes => nodes.map(node => node.textContent ?? '').join());
154+
const evaluations = input.evaluations.map(nodes => nodes.map(node => node.textContent ?? '').join());
155+
const result = input.finalResult?.map(node => node.textContent ?? '').join();
156+
assert.deepEqual(substitutions, []);
157+
assert.deepEqual(evaluations, []);
158+
assert.deepEqual(result, '10px');
159+
});
160+
161+
it('shows chains of substitutions', async () => {
162+
const {matchedStyles, stylesPane} = await setUpStyles();
163+
const {property, treeElement} = await getTreeElement(
164+
matchedStyles, stylesPane, 'width', 'var(--v)', {'--w': {value: '40px'}, '--v': {value: 'var(--w)'}});
127165
const input = await showTrace(property, matchedStyles, treeElement);
128166
const substitutions = input.substitutions.map(nodes => nodes.map(node => node.textContent ?? '').join());
129167
const evaluations = input.evaluations.map(nodes => nodes.map(node => node.textContent ?? '').join());
130168
const result = input.finalResult?.map(node => node.textContent ?? '').join();
131-
// TODO(pfaffe) once vars actually substitute this needs to show the first line
132169
assert.deepEqual(substitutions, ['var(--w)']);
133170
assert.deepEqual(evaluations, []);
134-
assert.deepEqual(result, 'var(--w)');
171+
assert.deepEqual(result, '40px');
135172
});
136173

137174
it('shows intermediate evaluation steps', async () => {

front_end/panels/elements/CSSValueTraceView.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ export class CSSValueTraceView extends UI.Widget.VBox {
124124
this.#substitutions = substitutions;
125125
this.#finalResult = evaluations.pop();
126126
this.#evaluations = evaluations;
127+
if (evaluations.length === 0 && !tracing.didApplyEvaluations()) {
128+
this.#substitutions.pop();
129+
}
127130
this.requestUpdate();
128131
}
129132

front_end/panels/elements/PropertyRenderer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ export class TracingContext {
111111
return true;
112112
}
113113

114+
didApplyEvaluations(): boolean {
115+
return this.#appliedEvaluations > 0;
116+
}
117+
114118
#setHasMoreEvaluations(value: boolean): void {
115119
if (this.#parent) {
116120
this.#parent.#setHasMoreEvaluations(value);

front_end/panels/elements/StylePropertyTreeElement.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,20 +213,39 @@ export class VariableRenderer extends rendererBase(SDK.CSSPropertyParserMatchers
213213
readonly #stylesPane: StylesSidebarPane;
214214
readonly #treeElement: StylePropertyTreeElement|null;
215215
readonly #matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles;
216+
readonly #computedStyles: Map<string, string>;
216217
constructor(
217218
stylesPane: StylesSidebarPane, treeElement: StylePropertyTreeElement|null,
218-
matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles) {
219+
matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, computedStyles: Map<string, string>) {
219220
super();
220221
this.#treeElement = treeElement;
221222
this.#stylesPane = stylesPane;
222223
this.#matchedStyles = matchedStyles;
224+
this.#computedStyles = computedStyles;
223225
}
224226

225227
override render(match: SDK.CSSPropertyParserMatchers.VariableMatch, context: RenderingContext): Node[] {
226228
const {declaration, value: variableValue} = match.resolveVariable() ?? {};
227229
const fromFallback = variableValue === undefined;
228230
const computedValue = variableValue ?? match.fallbackValue();
229231

232+
const substitution = context.tracing?.substitution();
233+
if (substitution) {
234+
if (declaration?.declaration instanceof SDK.CSSProperty.CSSProperty) {
235+
const valueElement = Renderer.renderValueElement(
236+
declaration.declaration.name, declaration.declaration.value,
237+
declaration.declaration.parseValue(this.#matchedStyles, this.#computedStyles),
238+
getPropertyRenderers(
239+
declaration.declaration.ownerStyle, this.#stylesPane, this.#matchedStyles, this.#treeElement,
240+
this.#computedStyles),
241+
substitution);
242+
return [valueElement];
243+
}
244+
if (!declaration && match.fallback.length > 0) {
245+
return Renderer.render(match.fallback, substitution.renderingContext(context)).nodes;
246+
}
247+
}
248+
230249
const renderedFallback = match.fallback.length > 0 ? Renderer.render(match.fallback, context) : undefined;
231250

232251
const varSwatch = new InlineEditor.LinkSwatch.CSSVarSwatch();
@@ -1418,7 +1437,7 @@ export function getPropertyRenderers(
14181437
matchedStyles: SDK.CSSMatchedStyles.CSSMatchedStyles, treeElement: StylePropertyTreeElement|null,
14191438
computedStyles: Map<string, string>): Array<MatchRenderer<SDK.CSSPropertyParser.Match>> {
14201439
return [
1421-
new VariableRenderer(stylesPane, treeElement, matchedStyles),
1440+
new VariableRenderer(stylesPane, treeElement, matchedStyles, computedStyles),
14221441
new ColorRenderer(stylesPane, treeElement),
14231442
new ColorMixRenderer(stylesPane),
14241443
new URLRenderer(style.parentRule, stylesPane.node()),

0 commit comments

Comments
 (0)