Title: [286890] trunk/Source/WebInspectorUI
Revision
286890
Author
rcali...@apple.com
Date
2021-12-10 17:08:04 -0800 (Fri, 10 Dec 2021)

Log Message

Web Inspector: Add CSS variable names to property name completion list
https://bugs.webkit.org/show_bug.cgi?id=233372
<rdar://83205968>

Reviewed by Devin Rousso.

Add the list of applicable CSS variables to the list of CSS property name completions.

`WI.CSSPropertyNameCompletions` is a long-lived object that holds all supported property names.
It doesn't need to change over time in a Web Inspector session. But the list of applicable
CSS variables depends on the selected node.

To avoid thrashing the long list of values in `WI.CSSPropertyNameCompletions` we don't proactively collect
CSS variables. Instead, we introduce a flag to indicate that the list of CSS variables may
be stale whenever the inspected node changes. Only when completions are requested do we check
this flag and augment the list of CSS property names with the latest list of CSS variables.

* UserInterface/Models/CSSCompletions.js:
(WI.CSSCompletions.prototype.replaceValues):
Allow a sub-class to replace the list of values in one go.
If a `WI.CSSQueryController` was used, reset it and provide it the new list of values.

* UserInterface/Models/CSSPropertyNameCompletions.js:
(WI.CSSPropertyNameCompletions):
(WI.CSSPropertyNameCompletions.prototype.executeQuery):
(WI.CSSPropertyNameCompletions.prototype.startsWith):
(WI.CSSPropertyNameCompletions.prototype._updateValuesWithLatestCSSVariablesIfNeeded):
Holding a copy of the original list of CSS property names in order to create a new list
agumented with variables on demand.

(WI.CSSPropertyNameCompletions.prototype.addValues):
Warn when trying to add new property values which would overwrite the cached and sorted list of CSS property names.

(WI.CSSPropertyNameCompletions.prototype._handleInspectedNodeChanged):
Consider changing of the inspected node as an indicator that the list of variables is stale.
That may not necessarily be true for web pages with all CSS variables declared on :root or <html>,
but iterating over them to verify is needlessly expensive especially if completions were not even requested.

(WI.CSSPropertyNameCompletions.prototype._handleNodesStylesNeedsRefresh):
Consider any change to the styles of the inspected node as a potential change to the list of applicable variables.

(WI.CSSPropertyNameCompletions):

Modified Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (286889 => 286890)


--- trunk/Source/WebInspectorUI/ChangeLog	2021-12-11 00:53:37 UTC (rev 286889)
+++ trunk/Source/WebInspectorUI/ChangeLog	2021-12-11 01:08:04 UTC (rev 286890)
@@ -1,3 +1,48 @@
+2021-12-10  Razvan Caliman  <rcali...@apple.com>
+
+        Web Inspector: Add CSS variable names to property name completion list
+        https://bugs.webkit.org/show_bug.cgi?id=233372
+        <rdar://83205968>
+
+        Reviewed by Devin Rousso.
+
+        Add the list of applicable CSS variables to the list of CSS property name completions.
+
+        `WI.CSSPropertyNameCompletions` is a long-lived object that holds all supported property names.
+        It doesn't need to change over time in a Web Inspector session. But the list of applicable
+        CSS variables depends on the selected node.
+
+        To avoid thrashing the long list of values in `WI.CSSPropertyNameCompletions` we don't proactively collect
+        CSS variables. Instead, we introduce a flag to indicate that the list of CSS variables may
+        be stale whenever the inspected node changes. Only when completions are requested do we check
+        this flag and augment the list of CSS property names with the latest list of CSS variables.
+
+        * UserInterface/Models/CSSCompletions.js:
+        (WI.CSSCompletions.prototype.replaceValues):
+        Allow a sub-class to replace the list of values in one go.
+        If a `WI.CSSQueryController` was used, reset it and provide it the new list of values.
+
+        * UserInterface/Models/CSSPropertyNameCompletions.js:
+        (WI.CSSPropertyNameCompletions):
+        (WI.CSSPropertyNameCompletions.prototype.executeQuery):
+        (WI.CSSPropertyNameCompletions.prototype.startsWith):
+        (WI.CSSPropertyNameCompletions.prototype._updateValuesWithLatestCSSVariablesIfNeeded):
+        Holding a copy of the original list of CSS property names in order to create a new list
+        agumented with variables on demand.
+
+        (WI.CSSPropertyNameCompletions.prototype.addValues):
+        Warn when trying to add new property values which would overwrite the cached and sorted list of CSS property names.
+
+        (WI.CSSPropertyNameCompletions.prototype._handleInspectedNodeChanged):
+        Consider changing of the inspected node as an indicator that the list of variables is stale.
+        That may not necessarily be true for web pages with all CSS variables declared on :root or <html>,
+        but iterating over them to verify is needlessly expensive especially if completions were not even requested.
+
+        (WI.CSSPropertyNameCompletions.prototype._handleNodesStylesNeedsRefresh):
+        Consider any change to the styles of the inspected node as a potential change to the list of applicable variables.
+
+        (WI.CSSPropertyNameCompletions):
+
 2021-12-10  BJ Burg  <bb...@apple.com>
 
         Web Inspector: save and restore extension tab positions

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSCompletions.js (286889 => 286890)


--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSCompletions.js	2021-12-11 00:53:37 UTC (rev 286889)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSCompletions.js	2021-12-11 01:08:04 UTC (rev 286890)
@@ -172,6 +172,22 @@
         return results;
     }
 
+    // Protected
+
+    replaceValues(values)
+    {
+        console.assert(Array.isArray(values), values);
+        console.assert(typeof values[0] === "string", "Expect an array of string values", values);
+
+        this._values = values;
+        this._values.sort();
+
+        this._queryController?.reset();
+        this._queryController?.addValues(values);
+    }
+
+    // Private
+
     _firstIndexOfPrefix(prefix)
     {
         if (!this._values.length)

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSPropertyNameCompletions.js (286889 => 286890)


--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSPropertyNameCompletions.js	2021-12-11 00:53:37 UTC (rev 286889)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSPropertyNameCompletions.js	2021-12-11 01:08:04 UTC (rev 286890)
@@ -40,6 +40,11 @@
         }
 
         super(values, options);
+
+        this._cachedSortedPropertyNames = this.values.slice();
+        this._needsVariablesFromInspectedNode = true;
+
+        WI.domManager.addEventListener(WI.DOMManager.Event.InspectedNodeChanged, this._handleInspectedNodeChanged, this);
     }
 
     // Public
@@ -48,4 +53,62 @@
     {
         return this.values.includes(name);
     }
+
+    executeQuery(query)
+    {
+        this._updateValuesWithLatestCSSVariablesIfNeeded();
+
+        return super.executeQuery(query);
+    }
+
+    startsWith(prefix)
+    {
+        this._updateValuesWithLatestCSSVariablesIfNeeded();
+
+        return super.startsWith(prefix);
+    }
+
+    addValues()
+    {
+        console.assert(false, "Adding values will overwrite the list of supported CSS property names.");
+    }
+
+    // Private
+
+    _updateValuesWithLatestCSSVariablesIfNeeded()
+    {
+        if (!this._needsVariablesFromInspectedNode)
+            return;
+
+        // An inspected node is not guaranteed to exist when unit testing.
+        if (!WI.domManager.inspectedNode) {
+            this._needsVariablesFromInspectedNode = false;
+            return;
+        }
+
+        let nodeStyles = WI.cssManager.stylesForNode(WI.domManager.inspectedNode);
+        nodeStyles.addEventListener(WI.DOMNodeStyles.Event.NeedsRefresh, this._handleNodesStylesNeedsRefresh, this);
+
+        let values = Array.from(nodeStyles.allCSSVariables);
+        values.pushAll(this._cachedSortedPropertyNames);
+        this.replaceValues(values);
+
+        this._needsVariablesFromInspectedNode = false;
+    }
+
+    _handleInspectedNodeChanged(event)
+    {
+        if (this._needsVariablesFromInspectedNode || !event.data.lastInspectedNode)
+            return;
+
+        this._needsVariablesFromInspectedNode = true;
+
+        let nodeStyles = WI.cssManager.stylesForNode(event.data.lastInspectedNode);
+        nodeStyles.removeEventListener(WI.DOMNodeStyles.Event.NeedsRefresh, this._handleNodesStylesNeedsRefresh, this);
+    }
+
+    _handleNodesStylesNeedsRefresh(event)
+    {
+        this._needsVariablesFromInspectedNode = true;
+    }
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to