Skip to content
Permalink
Browse files
Web Inspector: Elements: rework CSS pseudo class toggles
https://bugs.webkit.org/show_bug.cgi?id=241655

Reviewed by Patrick Angle.

Move the forced pseudo class checkboxes to the bottom of the sidebar next to the class list
checkboxes (though only one of them can be enabled at a time) since more space is needed to support
new (and future) pseudo classes and using space at the bottom of the sidebar is better than at the
top (since there's already precedent with the class list checkboxes).

Test: inspector/css/forcePseudoState.html

* Source/WebInspectorUI/UserInterface/Views/GeneralStyleDetailsSidebarPanel.js:
(WI.GeneralStyleDetailsSidebarPanel):
(WI.GeneralStyleDetailsSidebarPanel.prototype.get minimumWidth):
(WI.GeneralStyleDetailsSidebarPanel.prototype.attached):
(WI.GeneralStyleDetailsSidebarPanel.prototype.layout):
(WI.GeneralStyleDetailsSidebarPanel.prototype.addEventListeners):
(WI.GeneralStyleDetailsSidebarPanel.prototype.removeEventListeners):
(WI.GeneralStyleDetailsSidebarPanel.prototype.initialLayout):
(WI.GeneralStyleDetailsSidebarPanel.prototype.sizeDidChange):
(WI.GeneralStyleDetailsSidebarPanel.prototype._updateClassListContainer): Added.
(WI.GeneralStyleDetailsSidebarPanel.prototype._updateForcedPseudoClassContainer): Added.
(WI.GeneralStyleDetailsSidebarPanel.prototype._handleNodeChanged):
(WI.GeneralStyleDetailsSidebarPanel.prototype._forcedPseudoClassCheckboxChanged): Added.
(WI.GeneralStyleDetailsSidebarPanel.prototype._updatePseudoClasasCheckboxes): Added.
(WI.GeneralStyleDetailsSidebarPanel.prototype._classListToggleButtonClicked): Renamed from `_classToggleButtonClicked`.
(WI.GeneralStyleDetailsSidebarPanel.prototype._forcedPseudoClassToggleButtonClicked): Added.
(WI.GeneralStyleDetailsSidebarPanel.prototype.styleDetailsPanelFocusLastPseudoClassCheckbox): Deleted.
(WI.GeneralStyleDetailsSidebarPanel.prototype.get _initialScrollOffset): Deleted.
(WI.GeneralStyleDetailsSidebarPanel.prototype._updateNoForcedPseudoClassesScrollOffset): Deleted.
(WI.GeneralStyleDetailsSidebarPanel.prototype._handleForcedPseudoClassCheckboxKeydown): Deleted.
* Source/WebInspectorUI/UserInterface/Views/GeneralStyleDetailsSidebarPanel.css:
(.sidebar > .panel.details.css-style > .content ~ :is(.options-container, .class-list-container, .forced-pseudo-class-container)): ADded.
(.sidebar > .panel.details.css-style > .content ~ :is(.options-container, .class-list-container)):
(.sidebar > .panel.details.css-style > .content:not(.supports-new-rule, .has-filter-bar) ~ :is(.options-container, .class-list-container, .forced-pseudo-class-container)): Renamed from `.sidebar > .panel.details.css-style > .content:not(.supports-new-rule, .has-filter-bar) ~ :is(.options-container, .class-list-container)`.
(.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle): Renamed from `.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle`.
(.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle:focus): Renamed from `.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle:focus`.
(.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle::before): Renamed from `.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle::before`.
(.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle:is(.selected, :hover)): Renamed from `.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle:is(.selected, :hover)`.
(.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle:is(.selected, :hover)::before): Renamed from `.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle:is(.selected, :hover)::before`.
(.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle:not(.selected):hover::before): Renamed from `.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle:not(.selected):hover::before`.
(.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle.selected:active::before): Renamed from `.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle.selected:active::before`.
(.sidebar > .panel.details.css-style > .content:not(.supports-new-rule) ~ .options-container > .new-rule, .sidebar > .panel.details.css-style > .content:not(.supports-toggle-class-list) ~ .options-container > .toggle.class-list, .sidebar > .panel.details.css-style > .content:not(.supports-toggle-forced-pseudo-class) ~ .options-container > .toggle.forced-pseudo-class, .sidebar > .panel.details.css-style > .content:not(.has-filter-bar) ~ .options-container > .filter-bar, .sidebar > .panel.details.css-style > .content:not(.supports-new-rule):not(.supports-toggle-class-list):not(.supports-toggle-forced-pseudo-class):not(.has-filter-bar) ~ .options-container): Renamed from `.sidebar > .panel.details.css-style > .content:not(.supports-new-rule) ~ .options-container > .new-rule, .sidebar > .panel.details.css-style > .content:not(.supports-toggle-css-class) ~ .options-container > .toggle-class-toggle, .sidebar > .panel.details.css-style > .content:not(.has-filter-bar) ~ .options-container > .filter-bar, .sidebar > .panel.details.css-style > .content:not(.supports-new-rule):not(.supports-toggle-class):not(.has-filter-bar) ~ .options-container`.
(.sidebar > .panel.details.css-style > .content ~ :is(.class-list-container, .forced-pseudo-class-container)): Added.
(.sidebar > .panel.details.css-style > .content ~ :is(.class-list-container, .forced-pseudo-class-container)[hidden]): Added.
(.sidebar > .panel.details.css-style > .content ~ .class-list-container):
(.sidebar > .panel.details.css-style > .content ~ .forced-pseudo-class-container): Added.
(.sidebar > .panel.details.css-style > .content ~ .forced-pseudo-class-container > label): Added.

* Source/WebInspectorUI/UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js:
(WI.SpreadsheetRulesStyleDetailsPanel.prototype.get supportsToggleCSSClassList): Added.
(WI.SpreadsheetRulesStyleDetailsPanel.prototype.get supportsToggleCSSForcedPseudoClass): Added.
(WI.SpreadsheetRulesStyleDetailsPanel.prototype.get initialToggleCSSForcedPseudoClassState): Added.
(WI.SpreadsheetRulesStyleDetailsPanel.prototype.spreadsheetCSSStyleDeclarationSectionStartEditingAdjacentRule):
Remove `styleDetailsPanelFocusLastPseudoClassCheckbox` as the forced pseudo class checkboxes are no
longer at the top, and therefore should not be focused when shift-tabbing from the first property.

* Source/WebInspectorUI/UserInterface/Views/StyleDetailsPanel.js:
(WI.StyleDetailsPanel.prototype.get supportsToggleCSSClassList): Renamed from `get supportsToggleCSSClass`.
(WI.StyleDetailsPanel.prototype.get supportsToggleCSSForcedPseudoClass):
(WI.StyleDetailsPanel.prototype.get _initialScrollOffset): Deleted.
No need to adjust the initial `scrollTop` for the forced pseudo class checkboxes since they are no
longer at the top.

* Source/WebInspectorUI/UserInterface/Views/ComputedStyleDetailsPanel.js:
(WI.ComputedStyleDetailsPanel.prototype.get supportsToggleCSSClassList): Added.
(WI.ComputedStyleDetailsPanel.prototype.get supportsToggleCSSForcedPseudoClass): Added.
(WI.ComputedStyleDetailsPanel.prototype.get initialToggleCSSForcedPseudoClassState): Added.
* Source/WebInspectorUI/UserInterface/Views/FontDetailsPanel.js:
(WI.FontDetailsPanel.prototype.get supportsToggleCSSClass): Deleted.
Allow `WI.StyleDetailsPanel` subclasses to control whether they support forcing pseudo classes (and
if so whether the container should initially be shown).

* Source/JavaScriptCore/inspector/protocol/CSS.json:
* Source/WebCore/inspector/agents/InspectorCSSAgent.h:
* Source/WebCore/inspector/agents/InspectorCSSAgent.cpp:
(WebCore::computePseudoClassMask): Deleted.
(WebCore::InspectorCSSAgent::forcePseudoState):
* Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js:
(WI.CSSManager.displayNameForForceablePseudoClass): Added.
(WI.CSSManager.prototype.canForcePseudoClass): Renamed from `canForcePseudoClasses`.
Add enum values for `:focus-visible` and `:focus-within`.
Drive-by: Make `CSS.ForceablePseudoClass` enum instead of having it be an inline/anonymous enum for
          only `CSS.forcePseudoState`.

* Source/WebInspectorUI/UserInterface/Views/ContextMenuUtilities.js:
(WI.appendContextMenuItemsForDOMNode):
* Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:
(WI.SpreadsheetCSSStyleDeclarationSection.prototype._populateIconElementContextMenu):
Handle `WI.CSSManager.ForceablePseudoClass` now being an object instead of an array.

* Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js:

* LayoutTests/inspector/css/forcePseudoState.html: Added.
* LayoutTests/inspector/css/forcePseudoState-expected.txt: Added.

Canonical link: https://commits.webkit.org/251628@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295623 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
dcrousso committed Jun 17, 2022
1 parent 6d63a8a commit ba34692437739f66a852b5bb86737cd9c90ded61
Show file tree
Hide file tree
Showing 15 changed files with 448 additions and 271 deletions.
@@ -0,0 +1,52 @@
Testing CSS.forcePseudoState.


== Running test suite: CSS.forcePseudoState
-- Running test case: CSS.forcePseudoState.active
Forcing pseudo class...
PASS: Should have one enabled pseudo class.
PASS: Should change styles.
Removing forced pseudo class...
PASS: Should not have any enabled pseudo classes.
PASS: Should change back to initial style.

-- Running test case: CSS.forcePseudoState.focus
Forcing pseudo class...
PASS: Should have one enabled pseudo class.
PASS: Should change styles.
Removing forced pseudo class...
PASS: Should not have any enabled pseudo classes.
PASS: Should change back to initial style.

-- Running test case: CSS.forcePseudoState.focus-visible
Forcing pseudo class...
PASS: Should have one enabled pseudo class.
PASS: Should change styles.
Removing forced pseudo class...
PASS: Should not have any enabled pseudo classes.
PASS: Should change back to initial style.

-- Running test case: CSS.forcePseudoState.focus-within
Forcing pseudo class...
PASS: Should have one enabled pseudo class.
PASS: Should change styles.
Removing forced pseudo class...
PASS: Should not have any enabled pseudo classes.
PASS: Should change back to initial style.

-- Running test case: CSS.forcePseudoState.hover
Forcing pseudo class...
PASS: Should have one enabled pseudo class.
PASS: Should change styles.
Removing forced pseudo class...
PASS: Should not have any enabled pseudo classes.
PASS: Should change back to initial style.

-- Running test case: CSS.forcePseudoState.visited
Forcing pseudo class...
PASS: Should have one enabled pseudo class.
PASS: Should change styles.
Removing forced pseudo class...
PASS: Should not have any enabled pseudo classes.
PASS: Should change back to initial style.

@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function test() {
let testElement = null;
let nodeStyles = null;

let suite = InspectorTest.createAsyncSuite("CSS.forcePseudoState");

[
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.Active, expectedBackgroundColor: "rgb(0, 0, 10)"},
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.Focus, expectedBackgroundColor: "rgb(0, 0, 20)"},
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.FocusVisible, expectedBackgroundColor: "rgb(0, 0, 30)"},
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.FocusWithin, expectedBackgroundColor: "rgb(0, 0, 40)"},
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.Hover, expectedBackgroundColor: "rgb(0, 0, 50)"},
{forceablePseudoClass: WI.CSSManager.ForceablePseudoClass.Visited, expectedBackgroundColor: "rgb(0, 0, 60)"},
].forEach(({forceablePseudoClass, expectedBackgroundColor}) => {
suite.addTestCase({
name: "CSS.forcePseudoState." + forceablePseudoClass,
async test() {
await nodeStyles.refreshIfNeeded();

InspectorTest.assert(Object.shallowEqual(testElement.enabledPseudoClasses, []), "Should not have any enabled pseudo classes.");
InspectorTest.assert(nodeStyles.computedStyle.propertyForName("background-color").value === "rgb(0, 0, 0)", "Should have expected initial style.");

InspectorTest.log("Forcing pseudo class...");
await Promise.all([
testElement.awaitEvent(WI.DOMNode.Event.EnabledPseudoClassesChanged),
testElement.setPseudoClassEnabled(forceablePseudoClass, true),
]);
await nodeStyles.refreshIfNeeded();
InspectorTest.expectShallowEqual(testElement.enabledPseudoClasses, [forceablePseudoClass], "Should have one enabled pseudo class.");
InspectorTest.expectEqual(nodeStyles.computedStyle.propertyForName("background-color").value, expectedBackgroundColor, "Should change styles.");

InspectorTest.log("Removing forced pseudo class...");
await Promise.all([
testElement.awaitEvent(WI.DOMNode.Event.EnabledPseudoClassesChanged),
testElement.setPseudoClassEnabled(forceablePseudoClass, false),
]);
await nodeStyles.refreshIfNeeded();
InspectorTest.expectShallowEqual(testElement.enabledPseudoClasses, [], "Should not have any enabled pseudo classes.");
InspectorTest.expectEqual(nodeStyles.computedStyle.propertyForName("background-color").value, "rgb(0, 0, 0)", "Should change back to initial style.");
},
});
});

WI.domManager.requestDocument((documentNode) => {
documentNode.querySelector("#test-element", (contentNodeId) => {
if (contentNodeId) {
testElement = WI.domManager.nodeForId(contentNodeId);
nodeStyles = WI.cssManager.stylesForNode(testElement);
suite.runTestCasesAndFinish();
} else {
InspectorTest.fail("DOM node not found.");
InspectorTest.completeTest();
}
});
});
}
</script>
</head>
<body onload="runTest()">
<p>Testing CSS.forcePseudoState.</p>

<style>
#test-element {
background-color: rgb(0, 0, 0);
}
#test-element:active {
background-color: rgb(0, 0, 10);
}
#test-element:focus {
background-color: rgb(0, 0, 20);
}
#test-element:focus-visible {
background-color: rgb(0, 0, 30);
}
#test-element:focus-within {
background-color: rgb(0, 0, 40);
}
#test-element:hover {
background-color: rgb(0, 0, 50);
}
#test-element:visited {
background-color: rgb(0, 0, 60);
}
</style>
<a href="#" id="test-element"></a>
</body>
</html>
@@ -54,6 +54,19 @@
],
"description": "Pseudo-style identifier (see <code>enum PseudoId</code> in <code>RenderStyleConstants.h</code>)."
},
{
"id": "ForceablePseudoClass",
"type": "string",
"enum": [
"active",
"focus",
"focus-visible",
"focus-within",
"hover",
"visited"
],
"description": "Pseudo-style identifier (see <code>enum PseudoId</code> in <code>RenderStyleConstants.h</code>)."
},
{
"id": "PseudoIdMatches",
"type": "object",
@@ -424,7 +437,7 @@
"targetTypes": ["page"],
"parameters": [
{ "name": "nodeId", "$ref": "DOM.NodeId", "description": "The element id for which to force the pseudo state." },
{ "name": "forcedPseudoClasses", "type": "array", "items": { "type": "string", "enum": ["active", "focus", "hover", "visited"] }, "description": "Element pseudo classes to force when computing the element's style." }
{ "name": "forcedPseudoClasses", "type": "array", "items": { "$ref": "ForceablePseudoClass" }, "description": "Element pseudo classes to force when computing the element's style." }
]
},
{
@@ -81,39 +81,6 @@ namespace WebCore {

using namespace Inspector;

enum ForcePseudoClassFlags {
PseudoClassNone = 0,
PseudoClassHover = 1 << 0,
PseudoClassFocus = 1 << 1,
PseudoClassActive = 1 << 2,
PseudoClassVisited = 1 << 3
};

static unsigned computePseudoClassMask(const JSON::Array& pseudoClassArray)
{
static NeverDestroyed<String> active(MAKE_STATIC_STRING_IMPL("active"));
static NeverDestroyed<String> hover(MAKE_STATIC_STRING_IMPL("hover"));
static NeverDestroyed<String> focus(MAKE_STATIC_STRING_IMPL("focus"));
static NeverDestroyed<String> visited(MAKE_STATIC_STRING_IMPL("visited"));
if (!pseudoClassArray.length())
return PseudoClassNone;

unsigned result = PseudoClassNone;
for (auto& pseudoClassValue : pseudoClassArray) {
auto pseudoClass = pseudoClassValue->asString();
if (pseudoClass == active)
result |= PseudoClassActive;
else if (pseudoClass == hover)
result |= PseudoClassHover;
else if (pseudoClass == focus)
result |= PseudoClassFocus;
else if (pseudoClass == visited)
result |= PseudoClassVisited;
}

return result;
}

class InspectorCSSAgent::StyleSheetAction : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(StyleSheetAction);
public:
@@ -428,19 +395,7 @@ bool InspectorCSSAgent::forcePseudoState(const Element& element, CSSSelector::Ps
if (!nodeId)
return false;

unsigned forcedPseudoState = m_nodeIdToForcedPseudoState.get(nodeId);
switch (pseudoClassType) {
case CSSSelector::PseudoClassActive:
return forcedPseudoState & PseudoClassActive;
case CSSSelector::PseudoClassFocus:
return forcedPseudoState & PseudoClassFocus;
case CSSSelector::PseudoClassHover:
return forcedPseudoState & PseudoClassHover;
case CSSSelector::PseudoClassVisited:
return forcedPseudoState & PseudoClassVisited;
default:
return false;
}
return m_nodeIdToForcedPseudoState.get(nodeId).contains(pseudoClassType);
}

std::optional<Protocol::CSS::PseudoId> InspectorCSSAgent::protocolValueForPseudoId(PseudoId pseudoId)
@@ -924,13 +879,45 @@ Protocol::ErrorStringOr<void> InspectorCSSAgent::forcePseudoState(Protocol::DOM:
if (!element)
return makeUnexpected(errorString);

// Return early if the forced pseudo state was already set correctly.
unsigned forcedPseudoState = computePseudoClassMask(forcedPseudoClasses);
if (forcedPseudoState) {
auto iterator = m_nodeIdToForcedPseudoState.add(nodeId, 0).iterator;
if (forcedPseudoState == iterator->value)
return { };
iterator->value = forcedPseudoState;
PseudoClassHashSet forcedPseudoClassesToSet;
for (const auto& pseudoClassValue : forcedPseudoClasses.get()) {
auto pseudoClassString = pseudoClassValue->asString();
if (!pseudoClassString)
return makeUnexpected("Unexpected non-string value in given forcedPseudoClasses"_s);

auto pseudoClass = Protocol::Helpers::parseEnumValueFromString<Protocol::CSS::ForceablePseudoClass>(pseudoClassString);
if (!pseudoClass)
return makeUnexpected(makeString("Unknown forcedPseudoClass: ", pseudoClassString));

switch (*pseudoClass) {
case Protocol::CSS::ForceablePseudoClass::Active:
forcedPseudoClassesToSet.add(CSSSelector::PseudoClassActive);
break;

case Protocol::CSS::ForceablePseudoClass::Hover:
forcedPseudoClassesToSet.add(CSSSelector::PseudoClassHover);
break;

case Protocol::CSS::ForceablePseudoClass::Focus:
forcedPseudoClassesToSet.add(CSSSelector::PseudoClassFocus);
break;

case Protocol::CSS::ForceablePseudoClass::FocusVisible:
forcedPseudoClassesToSet.add(CSSSelector::PseudoClassFocusVisible);
break;

case Protocol::CSS::ForceablePseudoClass::FocusWithin:
forcedPseudoClassesToSet.add(CSSSelector::PseudoClassFocusWithin);
break;

case Protocol::CSS::ForceablePseudoClass::Visited:
forcedPseudoClassesToSet.add(CSSSelector::PseudoClassVisited);
break;
}
}

if (!forcedPseudoClassesToSet.isEmpty()) {
m_nodeIdToForcedPseudoState.set(nodeId, WTFMove(forcedPseudoClassesToSet));
m_documentsWithForcedPseudoStates.add(&element->document());
} else {
if (!m_nodeIdToForcedPseudoState.remove(nodeId))
@@ -137,7 +137,7 @@ class InspectorCSSAgent final : public InspectorAgentBase , public Inspector::CS
typedef HashMap<Inspector::Protocol::CSS::StyleSheetId, RefPtr<InspectorStyleSheet>> IdToInspectorStyleSheet;
typedef HashMap<CSSStyleSheet*, RefPtr<InspectorStyleSheet>> CSSStyleSheetToInspectorStyleSheet;
typedef HashMap<RefPtr<Document>, Vector<RefPtr<InspectorStyleSheet>>> DocumentToViaInspectorStyleSheet; // "via inspector" stylesheets
typedef HashMap<Inspector::Protocol::DOM::NodeId, unsigned> NodeIdToForcedPseudoState;
typedef HashSet<CSSSelector::PseudoClassType, IntHash<CSSSelector::PseudoClassType>, WTF::StrongEnumHashTraits<CSSSelector::PseudoClassType>> PseudoClassHashSet;

InspectorStyleSheetForInlineStyle& asInspectorStyleSheet(StyledElement&);
Element* elementForId(Inspector::Protocol::ErrorString&, Inspector::Protocol::DOM::NodeId);
@@ -171,7 +171,7 @@ class InspectorCSSAgent final : public InspectorAgentBase , public Inspector::CS
HashMap<Node*, Ref<InspectorStyleSheetForInlineStyle>> m_nodeToInspectorStyleSheet; // bogus "stylesheets" with elements' inline styles
DocumentToViaInspectorStyleSheet m_documentToInspectorStyleSheet;
HashMap<Document*, HashSet<CSSStyleSheet*>> m_documentToKnownCSSStyleSheets;
NodeIdToForcedPseudoState m_nodeIdToForcedPseudoState;
HashMap<Inspector::Protocol::DOM::NodeId, PseudoClassHashSet> m_nodeIdToForcedPseudoState;
HashSet<Document*> m_documentsWithForcedPseudoStates;

int m_lastStyleSheetId { 1 };
@@ -1179,6 +1179,8 @@ localizedStrings["Proportional Numerals @ Font Details Sidebar Property Value"]
/* Property value for `font-variant-alternates: proportional-width`. */
localizedStrings["Proportional-Width Variants @ Font Details Sidebar Property Value"] = "Proportional-Width Variants";
localizedStrings["Protocol"] = "Protocol";
/* Label for button that shows controls for toggling CSS pseudo-classes on the selected element. */
localizedStrings["Pseudo @ Styles details sidebar panel"] = "Pseudo";
localizedStrings["Pseudo-Element"] = "Pseudo-Element";
localizedStrings["Query Parameters"] = "Query Parameters";
localizedStrings["Query String"] = "Query String";
@@ -1615,6 +1617,7 @@ localizedStrings["Timing"] = "Timing";
localizedStrings["Titling Capitals @ Font Details Sidebar Property Value"] = "Titling Capitals";
localizedStrings["To improve CPU utilization reduce or batch workloads when the page is not visible or during times when the page is not being interacted with."] = "To improve CPU utilization reduce or batch workloads when the page is not visible or during times when the page is not being interacted with.";
localizedStrings["Toggle Classes"] = "Toggle Classes";
localizedStrings["Toggle Pseudo Classes"] = "Toggle Pseudo Classes";
localizedStrings["Toggle Visibility"] = "Toggle Visibility";
localizedStrings["Top Functions"] = "Top Functions";
localizedStrings["Total"] = "Total";
@@ -264,6 +264,27 @@ WI.CSSManager = class CSSManager extends WI.Object
}
}

static displayNameForForceablePseudoClass(pseudoClass)
{
switch (pseudoClass) {
case WI.CSSManager.ForceablePseudoClass.Active:
return WI.unlocalizedString(":active");
case WI.CSSManager.ForceablePseudoClass.Focus:
return WI.unlocalizedString(":focus");
case WI.CSSManager.ForceablePseudoClass.FocusVisible:
return WI.unlocalizedString(":focus-visible");
case WI.CSSManager.ForceablePseudoClass.FocusWithin:
return WI.unlocalizedString(":focus-within");
case WI.CSSManager.ForceablePseudoClass.Hover:
return WI.unlocalizedString(":hover");
case WI.CSSManager.ForceablePseudoClass.Visited:
return WI.unlocalizedString(":visited");
}

console.assert(false, "Unknown pseudo class", pseudoClass);
return "";
}

// Public

get propertyNameCompletions() { return this._propertyNameCompletions; }
@@ -340,9 +361,29 @@ WI.CSSManager = class CSSManager extends WI.Object
return InspectorBackend.hasCommand("Page.setForcedAppearance") && this._defaultAppearance;
}

canForcePseudoClasses()
canForcePseudoClass(pseudoClass)
{
return InspectorBackend.hasCommand("CSS.forcePseudoState");
if (!InspectorBackend.hasCommand("CSS.forcePseudoState"))
return false;

if (!pseudoClass)
return true;

switch (pseudoClass) {
case WI.CSSManager.ForceablePseudoClass.Active:
case WI.CSSManager.ForceablePseudoClass.Focus:
case WI.CSSManager.ForceablePseudoClass.Hover:
case WI.CSSManager.ForceablePseudoClass.Visited:
return true;

case WI.CSSManager.ForceablePseudoClass.FocusVisible:
case WI.CSSManager.ForceablePseudoClass.FocusWithin:
// COMPATIBILITY (iOS 15.4): CSS.ForceablePseudoClass did not exist yet.
return !!InspectorBackend.Enum.CSS.ForceablePseudoClass;
}

console.assert(false, "Unknown pseudo class", pseudoClass);
return false;
}

propertyNameHasOtherVendorPrefix(name)
@@ -801,5 +842,14 @@ WI.CSSManager.LayoutContextTypeChangedMode = {
};

WI.CSSManager.PseudoElementNames = ["before", "after"];
WI.CSSManager.ForceablePseudoClasses = ["active", "focus", "hover", "visited"];

WI.CSSManager.ForceablePseudoClass = {
Active: "active",
Focus: "focus",
FocusVisible: "focus-visible",
FocusWithin: "focus-within",
Hover: "hover",
Visited: "visited",
};

WI.CSSManager.PreferredInspectorStyleSheetSymbol = Symbol("css-manager-preferred-inspector-style-sheet");

0 comments on commit ba34692

Please sign in to comment.