Diff
Modified: trunk/LayoutTests/ChangeLog (278606 => 278607)
--- trunk/LayoutTests/ChangeLog 2021-06-08 14:16:21 UTC (rev 278606)
+++ trunk/LayoutTests/ChangeLog 2021-06-08 15:57:00 UTC (rev 278607)
@@ -1,3 +1,18 @@
+2021-06-08 Razvan Caliman <[email protected]>
+
+ Web Inspector: Styles panel slow to render when inspecting node with many inherited CSS variables
+ https://bugs.webkit.org/show_bug.cgi?id=225972
+ <rdar://problem/78211185>
+
+ Reviewed by Devin Rousso.
+
+ Add tests for logic to aggregate used CSS variables in Web Inspector.
+
+ * inspector/css/findVariableNames-expected.txt: Added.
+ * inspector/css/findVariableNames.html: Added.
+ * inspector/css/usedCSSVariables-expected.txt: Added.
+ * inspector/css/usedCSSVariables.html: Added.
+
2021-06-08 Alan Bujtas <[email protected]>
[LFC][TFC] Add initial percent value support for columns
Added: trunk/LayoutTests/inspector/css/findVariableNames-expected.txt (0 => 278607)
--- trunk/LayoutTests/inspector/css/findVariableNames-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/css/findVariableNames-expected.txt 2021-06-08 15:57:00 UTC (rev 278607)
@@ -0,0 +1,51 @@
+Test naive parsing of CSS variable names with CSSProperty.findVariableNames
+
+
+== Running test suite: CSSProperty.findVariableNames
+-- Running test case: CSSProperty.findVariableNames.Empty
+PASS: "" should contain these CSS variable names: [].
+
+-- Running test case: CSSProperty.findVariableNames.EmptyFunction
+PASS: "var()" should contain these CSS variable names: [].
+
+-- Running test case: CSSProperty.findVariableNames.EmptyNoFunction
+PASS: "--one" should contain these CSS variable names: [].
+
+-- Running test case: CSSProperty.findVariableNames.Basic
+PASS: "var(--one)" should contain these CSS variable names: ["--one"].
+
+-- Running test case: CSSProperty.findVariableNames.BasicWithFallback
+PASS: "var(--one, red)" should contain these CSS variable names: ["--one"].
+
+-- Running test case: CSSProperty.findVariableNames.BasicWithVariableFallback
+PASS: "var(--one, var(--two, red))" should contain these CSS variable names: ["--one","--two"].
+
+-- Running test case: CSSProperty.findVariableNames.Whitespace
+PASS: "var( --one )" should contain these CSS variable names: ["--one"].
+
+-- Running test case: CSSProperty.findVariableNames.Newline
+PASS: "var(
+--one
+)" should contain these CSS variable names: ["--one"].
+
+-- Running test case: CSSProperty.findVariableNames.Tab
+PASS: "var( --one )" should contain these CSS variable names: ["--one"].
+
+-- Running test case: CSSProperty.findVariableNames.Nested
+PASS: "var(--one, var(--two, var(--three)))" should contain these CSS variable names: ["--one","--two","--three"].
+
+-- Running test case: CSSProperty.findVariableNames.Content
+PASS: "content: "var(--one)"" should contain these CSS variable names: ["--one"].
+
+-- Running test case: CSSProperty.findVariableNames.Dashed
+PASS: "var(----o--n--e)" should contain these CSS variable names: ["----o--n--e"].
+
+-- Running test case: CSSProperty.findVariableNames.NaiveWhitespace
+PASS: "var(--one --two --three)" should contain these CSS variable names: ["--one"].
+
+-- Running test case: CSSProperty.findVariableNames.NaiveDataURI
+PASS: "data:text/plain;base64,xxxvar(--one)xxx" should contain these CSS variable names: ["--one"].
+
+-- Running test case: CSSProperty.findVariableNames.NaiveMalformed
+PASS: "var(--var(one))" should contain these CSS variable names: ["--var(one"].
+
Added: trunk/LayoutTests/inspector/css/findVariableNames.html (0 => 278607)
--- trunk/LayoutTests/inspector/css/findVariableNames.html (rev 0)
+++ trunk/LayoutTests/inspector/css/findVariableNames.html 2021-06-08 15:57:00 UTC (rev 278607)
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+
+function test()
+{
+ let suite = InspectorTest.createSyncSuite("CSSProperty.findVariableNames");
+
+ function addTestCase({name, _expression_, expected, checkUsedCSSVariableNames})
+ {
+ suite.addTestCase({
+ name,
+ test() {
+ let variables = WI.CSSProperty.findVariableNames(_expression_);
+ InspectorTest.expectShallowEqual(variables, expected, `"${_expression_}" should contain these CSS variable names: ${JSON.stringify(expected)}.`);
+ },
+ });
+ }
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.Empty",
+ _expression_: "",
+ expected: [],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.EmptyFunction",
+ _expression_: "var()",
+ expected: [],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.EmptyNoFunction",
+ _expression_: "--one",
+ expected: [],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.Basic",
+ _expression_: "var(--one)",
+ expected: ["--one"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.BasicWithFallback",
+ _expression_: "var(--one, red)",
+ expected: ["--one"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.BasicWithVariableFallback",
+ _expression_: "var(--one, var(--two, red))",
+ expected: ["--one", "--two"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.Whitespace",
+ _expression_: "var( --one )",
+ expected: ["--one"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.Newline",
+ _expression_: "var(\n--one\n)",
+ expected: ["--one"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.Tab",
+ _expression_: "var(\t--one\t)",
+ expected: ["--one"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.Nested",
+ _expression_: "var(--one, var(--two, var(--three)))",
+ expected: ["--one", "--two", "--three"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.Content",
+ _expression_: "content: \"var(--one)\"",
+ expected: ["--one"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.Dashed",
+ _expression_: "var(----o--n--e)",
+ expected: ["----o--n--e"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.NaiveWhitespace",
+ _expression_: "var(--one --two --three)",
+ expected: ["--one"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.NaiveDataURI",
+ _expression_: "data:text/plain;base64,xxxvar(--one)xxx",
+ expected: ["--one"],
+ });
+
+ addTestCase({
+ name: "CSSProperty.findVariableNames.NaiveMalformed",
+ _expression_: "var(--var(one))",
+ expected: ["--var(one"],
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest();">
+<p>Test naive parsing of CSS variable names with CSSProperty.findVariableNames</p>
+</body>
+</html>
\ No newline at end of file
Added: trunk/LayoutTests/inspector/css/usedCSSVariables-expected.txt (0 => 278607)
--- trunk/LayoutTests/inspector/css/usedCSSVariables-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/css/usedCSSVariables-expected.txt 2021-06-08 15:57:00 UTC (rev 278607)
@@ -0,0 +1,32 @@
+Test for DOMNodeStyles.usedCSSVariables
+
+
+== Running test suite: DOMNodeStyles.usedCSSVariables
+-- Running test case: DOMNodeStyles.usedCSSVariables.InheritedUsed
+PASS: Set should contain one used variable
+PASS: --inherited-color should be used
+
+-- Running test case: DOMNodeStyles.usedCSSVariables.InheritedUsedReferenced
+PASS: Set should contain two used variables
+PASS: --inherited-color should be used
+PASS: --color should be used
+
+-- Running test case: DOMNodeStyles.usedCSSVariables.InheritedNotUsed
+PASS: Set should contain one used variable
+PASS: --color should be used
+PASS: --inherited-color should not be used
+
+-- Running test case: DOMNodeStyles.usedCSSVariables.InheritedUsedFunction
+PASS: Set should contain one used variable
+PASS: --inherited-color should be used
+
+-- Running test case: DOMNodeStyles.usedCSSVariables.HighSpecificityUsed
+PASS: --color should be used
+
+-- Running test case: DOMNodeStyles.usedCSSVariables.InheritedHighSpecificityUsed
+PASS: Set should contain one used variable
+PASS: --color should be used
+
+-- Running test case: DOMNodeStyles.usedCSSVariables.InheritedHighSpecificityNotUsed
+PASS: --color should not be used
+
Added: trunk/LayoutTests/inspector/css/usedCSSVariables.html (0 => 278607)
--- trunk/LayoutTests/inspector/css/usedCSSVariables.html (rev 0)
+++ trunk/LayoutTests/inspector/css/usedCSSVariables.html 2021-06-08 15:57:00 UTC (rev 278607)
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("DOMNodeStyles.usedCSSVariables");
+
+ function addTestCase({name, description, selector, checkUsedCSSVariables})
+ {
+ suite.addTestCase({
+ name,
+ description,
+ async test() {
+ let documentNode = await WI.domManager.requestDocument();
+ let nodeId = await documentNode.querySelector(selector);
+ let domNode = await WI.domManager.nodeForId(nodeId);
+ InspectorTest.assert(domNode, `Should find DOM Node for selector '${selector}'.`);
+
+ let cssStyles = WI.cssManager.stylesForNode(domNode);
+ InspectorTest.assert(cssStyles, `Should find CSS Styles for DOM Node.`);
+
+ await cssStyles.refreshIfNeeded();
+
+ checkUsedCSSVariables(cssStyles.usedCSSVariables);
+ },
+ });
+ }
+
+ addTestCase({
+ name: "DOMNodeStyles.usedCSSVariables.InheritedUsed",
+ description: "A used inherited variable is found in the set of used variables",
+ selector: "#used-inherited-variable",
+ checkUsedCSSVariables(usedCSSVariables) {
+ InspectorTest.expectEqual(usedCSSVariables.size, 1, "Set should contain one used variable");
+ InspectorTest.expectTrue(usedCSSVariables.has("--inherited-color"), "--inherited-color should be used");
+ },
+ });
+
+ addTestCase({
+ name: "DOMNodeStyles.usedCSSVariables.InheritedUsedReferenced",
+ description: "An inherited variable referenced by another used variable is found in the set of used variables",
+ selector: "#used-referenced-inherited-variable",
+ checkUsedCSSVariables(usedCSSVariables) {
+ InspectorTest.expectEqual(usedCSSVariables.size, 2, "Set should contain two used variables");
+ InspectorTest.expectTrue(usedCSSVariables.has("--inherited-color"), "--inherited-color should be used");
+ InspectorTest.expectTrue(usedCSSVariables.has("--color"), "--color should be used");
+ },
+ });
+
+ addTestCase({
+ name: "DOMNodeStyles.usedCSSVariables.InheritedNotUsed",
+ description: "Unused inherited variables are not found in the set of used variables",
+ selector: "#unused-inherited-variable",
+ checkUsedCSSVariables(usedCSSVariables) {
+ InspectorTest.expectEqual(usedCSSVariables.size, 1, "Set should contain one used variable");
+ InspectorTest.expectTrue(usedCSSVariables.has("--color"), "--color should be used");
+ InspectorTest.expectFalse(usedCSSVariables.has("--inherited-color"), "--inherited-color should not be used");
+ },
+ });
+
+ addTestCase({
+ name: "DOMNodeStyles.usedCSSVariables.InheritedUsedFunction",
+ description: "An inherited variable used in a function value is found in the set of used variables",
+ selector: "#used-inherited-variable-function",
+ checkUsedCSSVariables(usedCSSVariables) {
+ InspectorTest.expectEqual(usedCSSVariables.size, 1, "Set should contain one used variable");
+ InspectorTest.expectTrue(usedCSSVariables.has("--inherited-color"), "--inherited-color should be used");
+ },
+ });
+
+ addTestCase({
+ name: "DOMNodeStyles.usedCSSVariables.HighSpecificityUsed",
+ description: "A variable declared in a higher specificity rule but used in a lower specificity rule is found in the set of used variables",
+ selector: "#used-higher-specificity",
+ checkUsedCSSVariables(usedCSSVariables) {
+ InspectorTest.expectTrue(usedCSSVariables.has("--color"), "--color should be used");
+ },
+ });
+
+ addTestCase({
+ name: "DOMNodeStyles.usedCSSVariables.InheritedHighSpecificityUsed",
+ description: "An inherited variable declared in a higher specificity rule but used in a lower specificity rule on an inheritable property (`color`) is found in the set of used variables",
+ selector: "#used-higher-specificity-inheritable > p",
+ checkUsedCSSVariables(usedCSSVariables) {
+ InspectorTest.expectEqual(usedCSSVariables.size, 1, "Set should contain one used variable");
+ InspectorTest.expectTrue(usedCSSVariables.has("--color"), "--color should be used");
+ },
+ });
+
+ addTestCase({
+ name: "DOMNodeStyles.usedCSSVariables.InheritedHighSpecificityNotUsed",
+ description: "An inherited variable declared in a higher specificity rule but used in a lower specificity rule on a non-inheritable property (`background-color`) is not found in the set of used variables",
+ selector: "#unused-higher-specificity-non-inheritable > p",
+ checkUsedCSSVariables(usedCSSVariables) {
+ InspectorTest.expectFalse(usedCSSVariables.has("--color"), "--color should not be used");
+ },
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+<style>
+
+html {
+ --inherited-color: green;
+}
+
+div#used-inherited-variable {
+ color: var(--inherited-color, red);
+}
+
+div#used-referenced-inherited-variable {
+ --color: var(--inherited-color);
+ color: var(--color, red);
+}
+
+div#unused-inherited-variable {
+ --color: green;
+ color: var(--color, red);
+}
+
+div#used-inherited-variable-function {
+ background: linear-gradient(90deg, var(--inherited-color, red), white);
+}
+
+div.used-lower-specificity {
+ background-color: var(--color, red);
+}
+
+div#used-higher-specificity {
+ --color: green;
+}
+
+div.used-lower-specificity-inheritable {
+ color: var(--color, red);
+}
+
+div#used-higher-specificity-inheritable {
+ --color: green;
+}
+
+div.unused-lower-specificity-non-inheritable {
+ background-color: var(--color, red);
+}
+
+div#unused-higher-specificity-non-inheritable {
+ --color: green;
+}
+
+</style>
+</head>
+<body _onload_="runTest();">
+<p>Test for DOMNodeStyles.usedCSSVariables</p>
+<div>
+ <div id="used-inherited-variable"></div>
+ <div id="used-referenced-inherited-variable"></div>
+ <div id="unused-inherited-variable"></div>
+ <div id="used-inherited-variable-function"></div>
+ <div id="used-higher-specificity" class="used-lower-specificity"></div>
+ <div id="used-higher-specificity-inheritable" class="used-lower-specificity-inheritable">
+ <p></p>
+ </div>
+ <div id="unused-higher-specificity-non-inheritable" class="unused-lower-specificity-non-inheritable">
+ <p></p>
+ </div>
+</div>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/Source/WebInspectorUI/ChangeLog (278606 => 278607)
--- trunk/Source/WebInspectorUI/ChangeLog 2021-06-08 14:16:21 UTC (rev 278606)
+++ trunk/Source/WebInspectorUI/ChangeLog 2021-06-08 15:57:00 UTC (rev 278607)
@@ -1,3 +1,46 @@
+2021-06-08 Razvan Caliman <[email protected]>
+
+ Web Inspector: Styles panel slow to render when inspecting node with many inherited CSS variables
+ https://bugs.webkit.org/show_bug.cgi?id=225972
+ <rdar://problem/78211185>
+
+ Reviewed by Devin Rousso.
+
+ Do not show unused inherited CSS variables in the Styles details sidebar.
+
+ When aggregating styles for the selected node in `WI.DOMNodeStyles`, collect a list of names of CSS variables used in CSS property values.
+ In the Styles details sidebar, skip rendering declarations of inherited CSS variables that are not found in this list.
+
+ Always show inherited variables that are used, either directly inherited or via reference (variables using other variables in their value).
+ Always show inherited variables used as values of inheritable properties like color, font-size, etc.
+
+ When a CSS rule contains hidden inherited variables, offer a button to request disclosing them for that rule.
+ Option-click to show unused inherited variables in all matching rules.
+
+ Clicking the "Go to variable" button automatically renders all the unused variables in the CSS rule where the target variable is declared.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ * UserInterface/Models/CSSProperty.js:
+ (WI.CSSProperty.findVariableNames):
+ * UserInterface/Models/DOMNodeStyles.js:
+ (WI.DOMNodeStyles):
+ (WI.DOMNodeStyles.prototype.get usedCSSVariables):
+ (WI.DOMNodeStyles.prototype._updateStyleCascade):
+ (WI.DOMNodeStyles.prototype._collectUsedCSSVariables):
+ * UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.css:
+ (.spreadsheet-style-declaration-editor .property):
+ (.spreadsheet-style-declaration-editor > .hidden-variables-button):
+ * UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js:
+ (WI.SpreadsheetCSSStyleDeclarationEditor):
+ (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.layout):
+ (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.get propertiesToRender):
+ (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.highlightProperty):
+ * UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype.set propertyVisibilityMode):
+ (WI.SpreadsheetCSSStyleDeclarationSection.prototype.spreadsheetCSSStyleDeclarationEditorSetAllPropertyVisibilityMode):
+ * UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js:
+ (WI.SpreadsheetRulesStyleDetailsPanel.prototype.spreadsheetCSSStyleDeclarationSectionSetAllPropertyVisibilityMode):
+
2021-06-04 Devin Rousso <[email protected]>
Web Inspector: cannot see experimental settings when inspecting `ServiceWorker`
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (278606 => 278607)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2021-06-08 14:16:21 UTC (rev 278606)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2021-06-08 15:57:00 UTC (rev 278607)
@@ -1028,6 +1028,8 @@
/* Context menu item for opening the target item in a new window. */
localizedStrings["Open in New Window @ Context Menu Item"] = "Open in New Window";
localizedStrings["Option-click to show source"] = "Option-click to show source";
+/* Tooltip with instructions on how to show all hidden CSS variables */
+localizedStrings["Option-click to show unused CSS variables from all rules @ Styles Sidebar Panel Tooltip"] = "Option-click to show unused CSS variables from all rules";
localizedStrings["Options"] = "Options";
/* Property value for `font-variant-numeric: ordinal`. */
localizedStrings["Ordinal Letter Forms @ Font Details Sidebar Property Value"] = "Ordinal Letter Forms";
@@ -1319,6 +1321,10 @@
localizedStrings["Shared Focus"] = "Shared Focus";
localizedStrings["Shortest property path to %s"] = "Shortest property path to %s";
localizedStrings["Show %d More"] = "Show %d More";
+/* Text label for button to reveal multiple unused CSS variables */
+localizedStrings["Show %d unused CSS variable (singular) @ Styles Sidebar Panel"] = "Show %d unused CSS variable";
+/* Text label for button to reveal one unused CSS variable */
+localizedStrings["Show %d unused CSS variables (plural) @ Styles Sidebar Panel"] = "Show %d unused CSS variables";
localizedStrings["Show All"] = "Show All";
localizedStrings["Show All (%d More)"] = "Show All (%d More)";
localizedStrings["Show All Nodes (%d More)"] = "Show All Nodes (%d More)";
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSProperty.js (278606 => 278607)
--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSProperty.js 2021-06-08 14:16:21 UTC (rev 278606)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSProperty.js 2021-06-08 15:57:00 UTC (rev 278607)
@@ -49,6 +49,39 @@
return name.startsWith("--");
}
+ // FIXME: <https://webkit.org/b/226647> This naively collects variable-like names used in values. It should be hardened.
+ static findVariableNames(string)
+ {
+ const prefix = "var(--";
+ let prefixCursor = 0;
+ let cursor = 0;
+ let nameStartIndex = 0;
+ let names = [];
+
+ function isTerminatingChar(char) {
+ return char === ")" || char === "," || char === " " || char === "\n" || char === "\t";
+ }
+
+ while (cursor < string.length) {
+ if (nameStartIndex && isTerminatingChar(string.charAt(cursor))) {
+ names.push("--" + string.substring(nameStartIndex, cursor));
+ nameStartIndex = 0;
+ }
+
+ if (prefixCursor === prefix.length) {
+ prefixCursor = 0;
+ nameStartIndex = cursor;
+ }
+
+ if (string.charAt(cursor) === prefix.charAt(prefixCursor))
+ prefixCursor++;
+
+ cursor++;
+ }
+
+ return names;
+ }
+
// Public
get ownerStyle()
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js (278606 => 278607)
--- trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js 2021-06-08 14:16:21 UTC (rev 278606)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js 2021-06-08 15:57:00 UTC (rev 278607)
@@ -46,6 +46,7 @@
this._computedPrimaryFont = null;
this._propertyNameToEffectivePropertyMap = {};
+ this._usedCSSVariables = new Set;
this._pendingRefreshTask = null;
this.refresh();
@@ -129,6 +130,7 @@
get computedStyle() { return this._computedStyle; }
get orderedStyles() { return this._orderedStyles; }
get computedPrimaryFont() { return this._computedPrimaryFont; }
+ get usedCSSVariables() { return this._usedCSSVariables; }
get needsRefresh()
{
@@ -767,6 +769,7 @@
this._associateRelatedProperties(cascadeOrderedStyleDeclarations, this._propertyNameToEffectivePropertyMap);
this._markOverriddenProperties(cascadeOrderedStyleDeclarations, this._propertyNameToEffectivePropertyMap);
+ this._collectUsedCSSVariables(cascadeOrderedStyleDeclarations);
for (let pseudoElementInfo of this._pseudoElements.values()) {
pseudoElementInfo.orderedStyles = this._collectStylesInCascadeOrder(pseudoElementInfo.matchedRules, null, null);
@@ -942,6 +945,35 @@
}
}
+ _collectUsedCSSVariables(styles)
+ {
+ this._usedCSSVariables = new Set;
+
+ for (let style of styles) {
+ for (let property of style.enabledProperties) {
+ let variables = WI.CSSProperty.findVariableNames(property.value);
+
+ if (!style.inherited) {
+ // FIXME: <https://webkit.org/b/226648> Support the case of variables declared on matching styles but not used anywhere.
+ this._usedCSSVariables.addAll(variables);
+ continue;
+ }
+
+ // Always collect variables used in values of inheritable properties.
+ if (WI.CSSKeywordCompletions.InheritedProperties.has(property.name)) {
+ this._usedCSSVariables.addAll(variables);
+ continue;
+ }
+
+ // For variables from inherited styles, leverage the fact that styles are already sorted in cascade order to support inherited variables referencing other variables.
+ // If the variable was found to be used before, collect any variables used in its declaration value
+ // (if any variables are found, this isn't the end of the variable reference chain in the inheritance stack).
+ if (property.isVariable && this._usedCSSVariables.has(property.name))
+ this._usedCSSVariables.addAll(variables);
+ }
+ }
+ }
+
_isPropertyFoundInMatchingRules(propertyName)
{
return this._orderedStyles.some((style) => {
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.css (278606 => 278607)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.css 2021-06-08 14:16:21 UTC (rev 278606)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.css 2021-06-08 15:57:00 UTC (rev 278607)
@@ -33,6 +33,8 @@
--background-color-selected: var(--selected-text-background-color);
--border-color-selected: var(--selected-background-color);
+ --property-checkbox-width: 17px;
+ --property-indentation: calc(var(--css-declaration-horizontal-padding) + var(--property-checkbox-width));
}
.spreadsheet-style-declaration-editor:empty {
@@ -41,7 +43,7 @@
.spreadsheet-style-declaration-editor .property {
padding-right: var(--css-declaration-horizontal-padding);
- padding-left: calc(var(--css-declaration-horizontal-padding) + 17px);
+ padding-left: var(--property-indentation);
border-right: 2px solid transparent;
border-left: 1px solid transparent;
outline: none;
@@ -233,6 +235,10 @@
white-space: nowrap;
}
+.spreadsheet-style-declaration-editor > .hidden-variables-button {
+ margin-left: var(--property-indentation);
+}
+
body.meta-key-pressed .spreadsheet-css-declaration:not(.locked) > .spreadsheet-style-declaration-editor > .property > .content :matches(.name, .value):not(.editing):hover {
color: var(--syntax-highlight-link-color) !important;
text-decoration: underline !important;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js (278606 => 278607)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js 2021-06-08 14:16:21 UTC (rev 278606)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js 2021-06-08 15:57:00 UTC (rev 278607)
@@ -40,7 +40,8 @@
this._showsImplicitProperties = false;
this._alwaysShowPropertyNames = new Set;
- this._propertyVisibilityMode = WI.SpreadsheetCSSStyleDeclarationEditor.PropertyVisibilityMode.ShowAll;
+ this._propertyVisibilityMode = WI.SpreadsheetCSSStyleDeclarationEditor.PropertyVisibilityMode.HideUnusedInheritedVariables;
+ this._hiddenUnusedVariables = new Set;
this._hideFilterNonMatchingProperties = false;
this._sortPropertiesByName = false;
@@ -104,6 +105,26 @@
propertyViewPendingStartEditing = propertyView;
}
+ if (this._hiddenUnusedVariables.size) {
+ let showHiddenVariablesButtonElement = this.element.appendChild(document.createElement("button"));
+ showHiddenVariablesButtonElement.classList.add("hidden-variables-button");
+ showHiddenVariablesButtonElement.title = WI.UIString("Option-click to show unused CSS variables from all rules", "Option-click to show unused CSS variables from all rules @ Styles Sidebar Panel Tooltip", "Tooltip with instructions on how to show all hidden CSS variables");
+
+ const labelSingular = WI.UIString("Show %d unused CSS variable", "Show %d unused CSS variable (singular) @ Styles Sidebar Panel", "Text label for button to reveal one unused CSS variable");
+ const labelPlural = WI.UIString("Show %d unused CSS variables", "Show %d unused CSS variables (plural) @ Styles Sidebar Panel", "Text label for button to reveal multiple unused CSS variables");
+ let label = this._hiddenUnusedVariables.size > 1 ? labelPlural : labelSingular;
+
+ showHiddenVariablesButtonElement.textContent = label.format(this._hiddenUnusedVariables.size);
+ showHiddenVariablesButtonElement.addEventListener("click", (event) => {
+ if (event.altKey) {
+ this._setAllPropertyVisibilityMode(WI.SpreadsheetCSSStyleDeclarationEditor.PropertyVisibilityMode.ShowAll);
+ return;
+ }
+
+ this.propertyVisibilityMode = WI.SpreadsheetCSSStyleDeclarationEditor.PropertyVisibilityMode.ShowAll;
+ });
+ }
+
if (propertyViewPendingStartEditing) {
propertyViewPendingStartEditing.startEditingName();
this._propertyPendingStartEditing = null;
@@ -117,6 +138,11 @@
else if (this.hasSelectedProperties())
this.selectProperties(this._anchorIndex, this._focusIndex);
+ if (this._pendingPropertyToHighlight) {
+ this.highlightProperty(this._pendingPropertyToHighlight);
+ this._pendingPropertyToHighlight = null;
+ }
+
this._updateDebugLockStatus();
}
@@ -234,7 +260,10 @@
let hideVariables = this._propertyVisibilityMode === SpreadsheetCSSStyleDeclarationEditor.PropertyVisibilityMode.HideVariables;
let hideNonVariables = this._propertyVisibilityMode === SpreadsheetCSSStyleDeclarationEditor.PropertyVisibilityMode.HideNonVariables;
+ let hideUnusedInheritedVariables = this._propertyVisibilityMode === SpreadsheetCSSStyleDeclarationEditor.PropertyVisibilityMode.HideUnusedInheritedVariables;
+ this._hiddenUnusedVariables = new Set;
+
return properties.filter((property) => {
if (!property.isVariable && hideNonVariables)
return false;
@@ -242,6 +271,11 @@
if (property.isVariable && hideVariables)
return false;
+ if (property.isVariable && hideUnusedInheritedVariables && this._style.inherited && !this._style.nodeStyles.usedCSSVariables.has(property.name)) {
+ this._hiddenUnusedVariables.add(property);
+ return false;
+ }
+
return !property.implicit || this._showsImplicitProperties || this._alwaysShowPropertyNames.has(property.canonicalName);
});
}
@@ -277,6 +311,12 @@
highlightProperty(property)
{
+ if (!property.overridden && this._hiddenUnusedVariables.has(property)) {
+ this._pendingPropertyToHighlight = property;
+ this.propertyVisibilityMode = WI.SpreadsheetCSSStyleDeclarationEditor.PropertyVisibilityMode.ShowAll;
+ return true;
+ }
+
let propertiesMatch = (cssProperty) => {
if (cssProperty.attached && !cssProperty.overridden) {
if (cssProperty.canonicalName === property.canonicalName || hasMatchingLonghandProperty(cssProperty))
@@ -683,6 +723,11 @@
this.element.classList.toggle("debug-style-locked", this._style.locked);
}
+
+ _setAllPropertyVisibilityMode(propertyVisibilityMode)
+ {
+ this._delegate?.spreadsheetCSSStyleDeclarationEditorSetAllPropertyVisibilityMode?.(this, propertyVisibilityMode);
+ }
};
WI.SpreadsheetCSSStyleDeclarationEditor.Event = {
@@ -695,4 +740,5 @@
ShowAll: Symbol("variable-visibility-show-all"),
HideVariables: Symbol("variable-visibility-hide-variables"),
HideNonVariables: Symbol("variable-visibility-hide-non-variables"),
+ HideUnusedInheritedVariables: Symbol("variable-visibility-hide-unused-inherited-variables"),
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js (278606 => 278607)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js 2021-06-08 14:16:21 UTC (rev 278606)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js 2021-06-08 15:57:00 UTC (rev 278607)
@@ -58,6 +58,11 @@
return this._style.editable;
}
+ set propertyVisibilityMode(propertyVisibilityMode)
+ {
+ this._propertiesEditor.propertyVisibilityMode = propertyVisibilityMode;
+ }
+
initialLayout()
{
super.initialLayout();
@@ -284,6 +289,11 @@
this._delegate.spreadsheetCSSStyleDeclarationSectionSelectProperty(property);
}
+ spreadsheetCSSStyleDeclarationEditorSetAllPropertyVisibilityMode(editor, propertyVisibilityMode)
+ {
+ this._delegate?.spreadsheetCSSStyleDeclarationSectionSetAllPropertyVisibilityMode?.(this, propertyVisibilityMode);
+ }
+
applyFilter(filterText)
{
this._filterText = filterText;
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js (278606 => 278607)
--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js 2021-06-08 14:16:21 UTC (rev 278606)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js 2021-06-08 15:57:00 UTC (rev 278607)
@@ -203,6 +203,12 @@
this.nodeStyles.addRule(this._newRuleSelector, text);
}
+ spreadsheetCSSStyleDeclarationSectionSetAllPropertyVisibilityMode(section, propertyVisibilityMode)
+ {
+ for (let section of this._sections)
+ section.propertyVisibilityMode = propertyVisibilityMode;
+ }
+
// Protected
layout()