tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit f37ae3280a88a8e819b8279c029a69bfd373e787
parent 4ae6e5e2086abb0d68e2c0f1b9d4b85bad794e6e
Author: Nicolas Chevobbe <nchevobbe@mozilla.com>
Date:   Tue, 21 Oct 2025 13:20:16 +0000

Bug 1994758 - [devtools] Retrieve stylesheet indentation directly from the server. r=devtools-reviewers,devtools-backward-compat-reviewers,ochameau.

To detect the indentation of a given stylesheet when adding a property to an
empty rule, we would retrieve the whole stylesheet text on the client and then
run some heuristics.
This is quite costly, stylesheet can be quite large and sending all that text
from the server to the client isn't ideal.
This patch  adds a `getStyleSheetIndentation` RDP method to the `StyleSheetsActor`,
so we're only getting what we want.
We also fix the backward compat case when adding property to an empty rule in
a large stylesheet, by taking the initial text from the long string front we
get in such case.

Differential Revision: https://phabricator.services.mozilla.com/D269349

Diffstat:
Mdevtools/client/fronts/inspector/rule-rewriter.js | 21++++++++++++++++-----
Mdevtools/client/inspector/rules/test/browser_part1.toml | 2++
Adevtools/client/inspector/rules/test/browser_rules_add-property-large-stylesheet.js | 42++++++++++++++++++++++++++++++++++++++++++
Mdevtools/server/actors/style-sheets.js | 19++++++++++++++++++-
Mdevtools/shared/specs/style-sheets.js | 4++++
5 files changed, 82 insertions(+), 6 deletions(-)

diff --git a/devtools/client/fronts/inspector/rule-rewriter.js b/devtools/client/fronts/inspector/rule-rewriter.js @@ -510,11 +510,22 @@ class RuleRewriter { ); return " "; } - const { str: source } = await styleSheetsFront.getText( - this.rule.parentStyleSheet.resourceId - ); - const { indentUnit, indentWithTabs } = getIndentationFromString(source); - return indentWithTabs ? "\t" : " ".repeat(indentUnit); + + const styleSheetResourceId = this.rule.parentStyleSheet.resourceId; + + // @backward-compat { version 146 } getStyleSheetIndent was added in 146. The whole + // if block can be removed once 146 is in release. + const { hasGetStyleSheetIndentation } = await styleSheetsFront.getTraits(); + if (!hasGetStyleSheetIndentation) { + const { str: source, initial } = + await styleSheetsFront.getText(styleSheetResourceId); + const { indentUnit, indentWithTabs } = getIndentationFromString( + source ?? initial ?? "" + ); + return indentWithTabs ? "\t" : " ".repeat(indentUnit); + } + + return styleSheetsFront.getStyleSheetIndentation(styleSheetResourceId); } /** diff --git a/devtools/client/inspector/rules/test/browser_part1.toml b/devtools/client/inspector/rules/test/browser_part1.toml @@ -38,6 +38,8 @@ support-files = [ ["browser_rules_add-property-invalid-identifier.js"] +["browser_rules_add-property-large-stylesheet.js"] + ["browser_rules_add-property-svg.js"] ["browser_rules_add-property_01.js"] diff --git a/devtools/client/inspector/rules/test/browser_rules_add-property-large-stylesheet.js b/devtools/client/inspector/rules/test/browser_rules_add-property-large-stylesheet.js @@ -0,0 +1,42 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test adding a property to a large stylesheet (whose text would be sent in a longstring +// actor, see Bug 1994758). + +const TEST_URI = ` + <style> + ${Array.from({ length: 10000 }, (_, i) => `/* ${i} */`).join("\n")} + /* it's important to have this empty rule with a line break to trigger the issue we hit in Bug 1994758 */ + #testid { + } + </style> + <div id="testid">Styled Node</div> +`; + +add_task(async function () { + await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + const { inspector, view } = await openRuleView(); + await selectNode("#testid", inspector); + + await addProperty(view, 1, "color", "blue"); + + await checkRuleViewContent(view, [ + { + selector: "element", + declarations: [], + }, + { + selector: "#testid", + declarations: [{ name: "color", value: "blue", dirty: true }], + }, + ]); + + is( + await getComputedStyleProperty("#testid", null, "color"), + `rgb(0, 0, 255)`, + "color: blue was properly applied on the element" + ); +}); diff --git a/devtools/server/actors/style-sheets.js b/devtools/server/actors/style-sheets.js @@ -19,6 +19,12 @@ loader.lazyRequireGetter( "resource://devtools/server/actors/utils/stylesheets-manager.js", true ); +loader.lazyRequireGetter( + this, + "getIndentationFromString", + "resource://devtools/shared/indentation.js", + true +); /** * Creates a StyleSheetsActor. StyleSheetsActor provides remote access to the @@ -47,7 +53,10 @@ class StyleSheetsActor extends Actor { getTraits() { return { - traits: {}, + traits: { + // @backward-compat { version 146 } getStyleSheetIndentation was added in 146 + hasGetStyleSheetIndentation: true, + }, }; } @@ -92,6 +101,14 @@ class StyleSheetsActor extends Actor { return new LongStringActor(this.conn, text || ""); } + async getStyleSheetIndentation(resourceId) { + const styleSheetsManager = this._getStyleSheetsManager(); + const text = await styleSheetsManager.getText(resourceId); + + const { indentUnit, indentWithTabs } = getIndentationFromString(text); + return indentWithTabs ? "\t" : " ".repeat(indentUnit); + } + update(resourceId, text, transition, cause = "") { const styleSheetsManager = this._getStyleSheetsManager(); return styleSheetsManager.setStyleSheetText(resourceId, text, { diff --git a/devtools/shared/specs/style-sheets.js b/devtools/shared/specs/style-sheets.js @@ -34,6 +34,10 @@ const styleSheetsSpec = generateActorSpec({ request: { resourceId: Arg(0, "string") }, response: { text: RetVal("longstring") }, }, + getStyleSheetIndentation: { + request: { resourceId: Arg(0, "string") }, + response: { indentation: RetVal("string") }, + }, update: { request: { resourceId: Arg(0, "string"),