Title: [248202] trunk
Revision
248202
Author
[email protected]
Date
2019-08-03 12:36:32 -0700 (Sat, 03 Aug 2019)

Log Message

Web Inspector: Elements: Styles: add icons for various CSS rule types
https://bugs.webkit.org/show_bug.cgi?id=199946

Reviewed by Joseph Pecoraro.

Source/WebInspectorUI:

* UserInterface/Controllers/CSSManager.js:
(WI.CSSManager.displayNameForPseudoId):
Add hardcoded pseudo-selector identifiers for older backends.

* UserInterface/Models/CSSSelector.js:
(WI.CSSSelector.prototype.isPseudoSelector): Added.
(WI.CSSSelector.prototype.isPseudoElementSelector): Deleted.
There are more types of pseudo-selectors than just `:{before|after}`.

* UserInterface/Models/CSSStyleDeclaration.js:
(WI.CSSStyleDeclaration.prototype.generateCSSRuleString): Added.

* UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js:
(WI.SpreadsheetRulesStyleDetailsPanel.prototype.spreadsheetCSSStyleDeclarationSectionAddNewRule): Added.
(WI.SpreadsheetRulesStyleDetailsPanel.prototype.layout):
Provide a delegate method for adding a new rule, so the `WI.SpreadsheetRulesStyleDetailsPanel`
can know what selector to focus once the new rule gets added.

* UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:
(WI.SpreadsheetCSSStyleDeclarationSection.prototype.initialLayout):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype._renderSelector):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype._populateIconElementContextMenu): Added.
* UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css:
(.spreadsheet-css-declaration .header.editing-selector .selector): Added.
(.spreadsheet-css-declaration .selector > .icon): Added.
(.spreadsheet-css-declaration .selector > .icon + *): Added.
(.spreadsheet-css-declaration .selector.style-attribute > span): Added.
When "mousedown" (or "contextmenu") on the icon, show a context menu with helpful actions:
 - Copy Rule
 - {Disable|Enable} Rule
 - Duplicate Selector
 - Add :{active|focus|hover|visited} Rule
 - Create ::{before|after} Rule
 - Reveal in {Resources Tab|Sources Tab|Stylesheet}
Drive-by: add an extra 0.5px of initial margin before the Style Attribute selector (which is
sans-serif) so it properly aligns with the other selectors (which are monospaced).

* UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js:
(WI.SpreadsheetCSSStyleDeclarationEditor.prototype.layout):
* UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.css:
(.spreadsheet-style-declaration-editor:empty): Added.
(.spreadsheet-style-declaration-editor.no-properties): Deleted.
Add some extra space when there's no inline style so it looks a bit less cramped.

* UserInterface/Main.html:
* UserInterface/Views/StyleRuleIcons.css: Added.
(.author-style-rule-icon .icon):
(.author-style-rule-icon.pseudo-selector .icon):
(.user-style-rule-icon .icon):
(.user-style-rule-icon.pseudo-selector .icon):
(.user-agent-style-rule-icon .icon):
(.user-agent-style-rule-icon.pseudo-selector .icon):
(.inspector-style-rule-icon .icon):
(.inspector-style-rule-icon.pseudo-selector .icon):
(.inherited-style-rule-icon .icon):
(.inherited-element-style-rule-icon .icon):
* UserInterface/Images/StyleRule.svg: Added.
* UserInterface/Images/StyleRuleInheritedElement.svg: Added.
* UserInterface/Images/StyleRulePseudo.svg: Added.
Add generic icon classes for style rule icons.

* UserInterface/Base/Setting.js:
* UserInterface/Views/SettingsTabContentView.js:
(WI.SettingsTabContentView.prototype._createExperimentalSettingsView):
Add experimental setting.

* Localizations/en.lproj/localizedStrings.js:

LayoutTests:

* inspector/css/generateCSSRuleString.html: Added.
* inspector/css/generateCSSRuleString-expected.txt: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (248201 => 248202)


--- trunk/LayoutTests/ChangeLog	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/LayoutTests/ChangeLog	2019-08-03 19:36:32 UTC (rev 248202)
@@ -1,5 +1,15 @@
 2019-08-03  Devin Rousso  <[email protected]>
 
+        Web Inspector: Elements: Styles: add icons for various CSS rule types
+        https://bugs.webkit.org/show_bug.cgi?id=199946
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/css/generateCSSRuleString.html: Added.
+        * inspector/css/generateCSSRuleString-expected.txt: Added.
+
+2019-08-03  Devin Rousso  <[email protected]>
+
         Web Inspector: DOM: add a special breakpoint for "All Events"
         https://bugs.webkit.org/show_bug.cgi?id=200285
 

Added: trunk/LayoutTests/inspector/css/generateCSSRuleString-expected.txt (0 => 248202)


--- trunk/LayoutTests/inspector/css/generateCSSRuleString-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/css/generateCSSRuleString-expected.txt	2019-08-03 19:36:32 UTC (rev 248202)
@@ -0,0 +1,41 @@
+Testing that generated CSS rule strings have proper formatting.
+
+
+== Running test suite: CSS.generateCSSRuleString
+-- Running test case: CSS.generateCSSRuleString.InlineStyle
+#test-node {
+    a-b: 1;
+    c-d: 2;
+}
+
+-- Running test case: CSS.generateCSSRuleString.MatchedRules
+@media only screen and (min-width: 0px) {
+    @media only screen and (min-height: 0px) {
+        body > div#test-node {
+            a-b: 1;
+            c-d: 2;
+        }
+    }
+}
+@media only screen and (min-width: 0px) {
+    body > #test-node {
+        a-b: 1;
+        c-d: 2;
+    }
+}
+body > div {
+    a-b: 1;
+    c-d: 2;
+}
+body > * {
+    a-b: 1;
+    c-d: 2;
+}
+* {
+    a-b: 1;
+    c-d: 2;
+}
+address, article, aside, div, footer, header, hgroup, layer, main, nav, section {
+    display: block;
+}
+

Added: trunk/LayoutTests/inspector/css/generateCSSRuleString.html (0 => 248202)


--- trunk/LayoutTests/inspector/css/generateCSSRuleString.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/css/generateCSSRuleString.html	2019-08-03 19:36:32 UTC (rev 248202)
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+*{a-b:1;c-d:2}
+body>*{a-b:1;c-d:2}
+@media all {body>div{a-b:1;c-d:2}}
+@media only screen and (min-width:0px) {body>#test-node{a-b:1;c-d:2}}
+@media only screen and (min-width:0px) {@media only screen and (min-height:0px) {body>div#test-node{a-b:1;c-d:2}}}
+</style>
+<script src=""
+<script>
+function test() {
+    let nodeStyles = null;
+
+    let suite = InspectorTest.createSyncSuite("CSS.generateCSSRuleString");
+
+    suite.addTestCase({
+        name: "CSS.generateCSSRuleString.InlineStyle",
+        description: "Check the formatting of the generated inline style string.",
+        test() {
+            InspectorTest.log(nodeStyles.inlineStyle.generateCSSRuleString());
+        }
+    });
+
+    suite.addTestCase({
+        name: "CSS.generateCSSRuleString.MatchedRules",
+        description: "Check the formatting of the generated string for all matched CSS rules.",
+        test() {
+            for (let rule of nodeStyles.matchedRules)
+                InspectorTest.log(rule.style.generateCSSRuleString());
+        }
+    });
+
+    WI.domManager.requestDocument((documentNode) => {
+        WI.domManager.querySelector(documentNode.id, "#test-node", async (contentNodeId) => {
+            if (!contentNodeId) {
+                InspectorTest.log("DOM node not found.");
+                InspectorTest.completeTest();
+                return;
+            }
+
+            let domNode = WI.domManager.nodeForId(contentNodeId);
+            nodeStyles = WI.cssManager.stylesForNode(domNode);
+            if (nodeStyles.needsRefresh)
+                await nodeStyles.awaitEvent(WI.DOMNodeStyles.Event.Refreshed);
+
+            suite.runTestCasesAndFinish();
+        });
+    });
+}
+</script>
+</head>
+<body _onload_="runTest()">
+    <p>Testing that generated CSS rule strings have proper formatting.</p>
+    <div id="test-node" style="a-b:1;c-d:2"></div>
+</body>
+</html>

Modified: trunk/Source/WebInspectorUI/ChangeLog (248201 => 248202)


--- trunk/Source/WebInspectorUI/ChangeLog	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/ChangeLog	2019-08-03 19:36:32 UTC (rev 248202)
@@ -1,5 +1,80 @@
 2019-08-03  Devin Rousso  <[email protected]>
 
+        Web Inspector: Elements: Styles: add icons for various CSS rule types
+        https://bugs.webkit.org/show_bug.cgi?id=199946
+
+        Reviewed by Joseph Pecoraro.
+
+        * UserInterface/Controllers/CSSManager.js:
+        (WI.CSSManager.displayNameForPseudoId):
+        Add hardcoded pseudo-selector identifiers for older backends.
+
+        * UserInterface/Models/CSSSelector.js:
+        (WI.CSSSelector.prototype.isPseudoSelector): Added.
+        (WI.CSSSelector.prototype.isPseudoElementSelector): Deleted.
+        There are more types of pseudo-selectors than just `:{before|after}`.
+
+        * UserInterface/Models/CSSStyleDeclaration.js:
+        (WI.CSSStyleDeclaration.prototype.generateCSSRuleString): Added.
+
+        * UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js:
+        (WI.SpreadsheetRulesStyleDetailsPanel.prototype.spreadsheetCSSStyleDeclarationSectionAddNewRule): Added.
+        (WI.SpreadsheetRulesStyleDetailsPanel.prototype.layout):
+        Provide a delegate method for adding a new rule, so the `WI.SpreadsheetRulesStyleDetailsPanel`
+        can know what selector to focus once the new rule gets added.
+
+        * UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:
+        (WI.SpreadsheetCSSStyleDeclarationSection.prototype.initialLayout):
+        (WI.SpreadsheetCSSStyleDeclarationSection.prototype._renderSelector):
+        (WI.SpreadsheetCSSStyleDeclarationSection.prototype._populateIconElementContextMenu): Added.
+        * UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css:
+        (.spreadsheet-css-declaration .header.editing-selector .selector): Added.
+        (.spreadsheet-css-declaration .selector > .icon): Added.
+        (.spreadsheet-css-declaration .selector > .icon + *): Added.
+        (.spreadsheet-css-declaration .selector.style-attribute > span): Added.
+        When "mousedown" (or "contextmenu") on the icon, show a context menu with helpful actions:
+         - Copy Rule
+         - {Disable|Enable} Rule
+         - Duplicate Selector
+         - Add :{active|focus|hover|visited} Rule
+         - Create ::{before|after} Rule
+         - Reveal in {Resources Tab|Sources Tab|Stylesheet}
+        Drive-by: add an extra 0.5px of initial margin before the Style Attribute selector (which is
+        sans-serif) so it properly aligns with the other selectors (which are monospaced).
+
+        * UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js:
+        (WI.SpreadsheetCSSStyleDeclarationEditor.prototype.layout):
+        * UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.css:
+        (.spreadsheet-style-declaration-editor:empty): Added.
+        (.spreadsheet-style-declaration-editor.no-properties): Deleted.
+        Add some extra space when there's no inline style so it looks a bit less cramped.
+
+        * UserInterface/Main.html:
+        * UserInterface/Views/StyleRuleIcons.css: Added.
+        (.author-style-rule-icon .icon):
+        (.author-style-rule-icon.pseudo-selector .icon):
+        (.user-style-rule-icon .icon):
+        (.user-style-rule-icon.pseudo-selector .icon):
+        (.user-agent-style-rule-icon .icon):
+        (.user-agent-style-rule-icon.pseudo-selector .icon):
+        (.inspector-style-rule-icon .icon):
+        (.inspector-style-rule-icon.pseudo-selector .icon):
+        (.inherited-style-rule-icon .icon):
+        (.inherited-element-style-rule-icon .icon):
+        * UserInterface/Images/StyleRule.svg: Added.
+        * UserInterface/Images/StyleRuleInheritedElement.svg: Added.
+        * UserInterface/Images/StyleRulePseudo.svg: Added.
+        Add generic icon classes for style rule icons.
+
+        * UserInterface/Base/Setting.js:
+        * UserInterface/Views/SettingsTabContentView.js:
+        (WI.SettingsTabContentView.prototype._createExperimentalSettingsView):
+        Add experimental setting.
+
+        * Localizations/en.lproj/localizedStrings.js:
+
+2019-08-03  Devin Rousso  <[email protected]>
+
         Web Inspector: DOM: add a special breakpoint for "All Events"
         https://bugs.webkit.org/show_bug.cgi?id=200285
 

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (248201 => 248202)


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2019-08-03 19:36:32 UTC (rev 248202)
@@ -82,6 +82,7 @@
 localizedStrings["Action"] = "Action";
 localizedStrings["Activity Viewer"] = "Activity Viewer";
 localizedStrings["Add"] = "Add";
+localizedStrings["Add %s Rule"] = "Add %s Rule";
 localizedStrings["Add Action"] = "Add Action";
 localizedStrings["Add Breakpoint"] = "Add Breakpoint";
 localizedStrings["Add Breakpoints"] = "Add Breakpoints";
@@ -291,11 +292,13 @@
 localizedStrings["Copy Link"] = "Copy Link";
 localizedStrings["Copy Path to Property"] = "Copy Path to Property";
 localizedStrings["Copy Row"] = "Copy Row";
+localizedStrings["Copy Rule"] = "Copy Rule";
 localizedStrings["Copy Selected"] = "Copy Selected";
 localizedStrings["Copy Table"] = "Copy Table";
 localizedStrings["Copy as cURL"] = "Copy as cURL";
 localizedStrings["Could not fetch properties. Object may no longer exist."] = "Could not fetch properties. Object may no longer exist.";
 localizedStrings["Count"] = "Count";
+localizedStrings["Create %s Rule"] = "Create %s Rule";
 localizedStrings["Create Breakpoint"] = "Create Breakpoint";
 localizedStrings["Create a new tab"] = "Create a new tab";
 localizedStrings["Cross-Origin Restrictions"] = "Cross-Origin Restrictions";
@@ -344,6 +347,7 @@
 localizedStrings["Disable Event Listeners"] = "Disable Event Listeners";
 localizedStrings["Disable ICE Candidate Restrictions"] = "Disable ICE Candidate Restrictions";
 localizedStrings["Disable Program"] = "Disable Program";
+localizedStrings["Disable Rule"] = "Disable Rule";
 localizedStrings["Disable all breakpoints (%s)"] = "Disable all breakpoints (%s)";
 localizedStrings["Disable paint flashing"] = "Disable paint flashing";
 localizedStrings["Disable:"] = "Disable:";
@@ -365,6 +369,7 @@
 localizedStrings["Download Web Archive"] = "Download Web Archive";
 localizedStrings["Dropped Element"] = "Dropped Element";
 localizedStrings["Dropped Node"] = "Dropped Node";
+localizedStrings["Duplicate Selector"] = "Duplicate Selector";
 localizedStrings["Duplicate property"] = "Duplicate property";
 localizedStrings["Duration"] = "Duration";
 /* The duration of the Timeline recording in seconds (s). */
@@ -420,6 +425,7 @@
 localizedStrings["Enable Layers Tab"] = "Enable Layers Tab";
 localizedStrings["Enable New Tab Bar"] = "Enable New Tab Bar";
 localizedStrings["Enable Program"] = "Enable Program";
+localizedStrings["Enable Rule"] = "Enable Rule";
 localizedStrings["Enable Sources Tab"] = "Enable Sources Tab";
 localizedStrings["Enable all breakpoints (%s)"] = "Enable all breakpoints (%s)";
 localizedStrings["Enable breakpoints"] = "Enable breakpoints";
@@ -905,6 +911,7 @@
 localizedStrings["Reveal in Original Resource"] = "Reveal in Original Resource";
 localizedStrings["Reveal in Resources Tab"] = "Reveal in Resources Tab";
 localizedStrings["Reveal in Sources Tab"] = "Reveal in Sources Tab";
+localizedStrings["Reveal in Stylesheet"] = "Reveal in Stylesheet";
 localizedStrings["Role"] = "Role";
 localizedStrings["Run %d"] = "Run %d";
 localizedStrings["Run console commands as if inside a user gesture"] = "Run console commands as if inside a user gesture";
@@ -979,6 +986,7 @@
 localizedStrings["Show Console tab"] = "Show Console tab";
 localizedStrings["Show Elements"] = "Show Elements";
 localizedStrings["Show Grid"] = "Show Grid";
+localizedStrings["Show Icons"] = "Show Icons";
 localizedStrings["Show Jump to Effective Property Button"] = "Show Jump to Effective Property Button";
 localizedStrings["Show Path"] = "Show Path";
 localizedStrings["Show Remaining (%d)"] = "Show Remaining (%d)";

Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js	2019-08-03 19:36:32 UTC (rev 248202)
@@ -183,6 +183,7 @@
     experimentalEnableLayersTab: new WI.Setting("experimental-enable-layers-tab", false),
     experimentalEnableNewTabBar: new WI.Setting("experimental-enable-new-tab-bar", false),
     experimentalEnableSourcesTab: new WI.Setting("experimental-enable-sources-tab", false),
+    experimentalEnableStylesIcons: new WI.Setting("experimental-styles-icons", false),
     experimentalEnableStylesJumpToEffective: new WI.Setting("experimental-styles-jump-to-effective", false),
 
     // DebugUI

Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js	2019-08-03 19:36:32 UTC (rev 248202)
@@ -137,31 +137,31 @@
         }
 
         switch (pseudoId) {
-        case InspectorBackend.domains.CSS.PseudoId.FirstLine:
+        case CSSManager.PseudoSelectorNames.FirstLine:
             return WI.unlocalizedString("::first-line");
-        case InspectorBackend.domains.CSS.PseudoId.FirstLetter:
+        case CSSManager.PseudoSelectorNames.FirstLetter:
             return WI.unlocalizedString("::first-letter");
-        case InspectorBackend.domains.CSS.PseudoId.Marker:
+        case CSSManager.PseudoSelectorNames.Marker:
             return WI.unlocalizedString("::marker");
-        case InspectorBackend.domains.CSS.PseudoId.Before:
+        case CSSManager.PseudoSelectorNames.Before:
             return WI.unlocalizedString("::before");
-        case InspectorBackend.domains.CSS.PseudoId.After:
+        case CSSManager.PseudoSelectorNames.After:
             return WI.unlocalizedString("::after");
-        case InspectorBackend.domains.CSS.PseudoId.Selection:
+        case CSSManager.PseudoSelectorNames.Selection:
             return WI.unlocalizedString("::selection");
-        case InspectorBackend.domains.CSS.PseudoId.Scrollbar:
+        case CSSManager.PseudoSelectorNames.Scrollbar:
             return WI.unlocalizedString("::scrollbar");
-        case InspectorBackend.domains.CSS.PseudoId.ScrollbarThumb:
+        case CSSManager.PseudoSelectorNames.ScrollbarThumb:
             return WI.unlocalizedString("::scrollbar-thumb");
-        case InspectorBackend.domains.CSS.PseudoId.ScrollbarButton:
+        case CSSManager.PseudoSelectorNames.ScrollbarButton:
             return WI.unlocalizedString("::scrollbar-button");
-        case InspectorBackend.domains.CSS.PseudoId.ScrollbarTrack:
+        case CSSManager.PseudoSelectorNames.ScrollbarTrack:
             return WI.unlocalizedString("::scrollbar-track");
-        case InspectorBackend.domains.CSS.PseudoId.ScrollbarTrackPiece:
+        case CSSManager.PseudoSelectorNames.ScrollbarTrackPiece:
             return WI.unlocalizedString("::scrollbar-track-piece");
-        case InspectorBackend.domains.CSS.PseudoId.ScrollbarCorner:
+        case CSSManager.PseudoSelectorNames.ScrollbarCorner:
             return WI.unlocalizedString("::scrollbar-corner");
-        case InspectorBackend.domains.CSS.PseudoId.Resizer:
+        case CSSManager.PseudoSelectorNames.Resizer:
             return WI.unlocalizedString("::resizer");
 
         default:
@@ -740,6 +740,22 @@
     Dark: Symbol("dark"),
 };
 
+WI.CSSManager.PseudoSelectorNames = {
+    After: "after",
+    Before: "before",
+    FirstLetter: "first-letter",
+    FirstLine: "first-line",
+    Marker: "marker",
+    Resizer: "resizer",
+    Scrollbar: "scrollbar",
+    ScrollbarButton: "scrollbar-button",
+    ScrollbarCorner: "scrollbar-corner",
+    ScrollbarThumb: "scrollbar-thumb",
+    ScrollbarTrack: "scrollbar-track",
+    ScrollbarTrackPiece: "scrollbar-track-piece",
+    Selection: "selection",
+};
+
 WI.CSSManager.PseudoElementNames = ["before", "after"];
 WI.CSSManager.ForceablePseudoClasses = ["active", "focus", "hover", "visited"];
 WI.CSSManager.PreferredInspectorStyleSheetSymbol = Symbol("css-manager-preferred-inspector-stylesheet");

Added: trunk/Source/WebInspectorUI/UserInterface/Images/StyleRule.svg (0 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Images/StyleRule.svg	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/StyleRule.svg	2019-08-03 19:36:32 UTC (rev 248202)
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2019 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 16 16">
+    <style>
+        svg {
+            display: none;
+        }
+
+        svg:target {
+            display: initial;
+        }
+
+        #author {
+            --background: rgb(148, 183, 219);
+            --border: rgb(106, 136, 170);
+            --outline: rgb(113, 146, 184);
+        }
+
+        #user {
+            --background: rgb(246, 222, 146);
+            --border: rgb(204, 181, 108);
+            --outline: rgb(216, 193, 115);
+        }
+
+        #useragent {
+            --background: rgb(236, 151, 153);
+            --border: rgb(191, 109, 113);
+            --outline: rgb(204, 116, 121);
+        }
+
+        #inspector {
+            --background: rgb(165, 202, 164);
+            --border: rgb(118, 153, 116);
+            --outline: rgb(128, 166, 126);
+        }
+
+        #inherited {
+            --background: rgb(224, 224, 224);
+            --border: rgb(178, 178, 178);
+            --outline: rgb(191, 191, 191);
+        }
+    </style>
+
+    <svg>
+        <symbol id="style-rule">
+            <path fill="var(--background)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 Z"/>
+            <path fill="var(--border)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 M 13 2 C 13.550781 2 14 2.449219 14 3 L 14 13 C 14 13.550781 13.550781 14 13 14 L 3 14 C 2.449219 14 2 13.550781 2 13 L 2 3 C 2 2.449219 2.449219 2 3 2 L 13 2"/>
+            <path fill="white" d="M 6.585938 12.023438 C 6.152344 12.023438 5.820312 11.96875 5.574219 11.863281 C 5.308594 11.746094 5.113281 11.550781 4.992188 11.285156 C 4.882812 11.035156 4.828125 10.660156 4.828125 10.136719 C 4.828125 9.453125 4.796875 9.226562 4.78125 9.152344 C 4.753906 9.03125 4.699219 8.925781 4.617188 8.824219 C 4.558594 8.75 4.40625 8.703125 4.191406 8.695312 L 4 8.6875 L 4 7.328125 L 4.199219 7.328125 C 4.414062 7.324219 4.566406 7.265625 4.667969 7.144531 C 4.714844 7.085938 4.828125 6.875 4.828125 6.152344 C 4.828125 5.691406 4.84375 5.355469 4.878906 5.128906 C 4.914062 4.875 5.007812 4.660156 5.152344 4.484375 C 5.296875 4.308594 5.484375 4.183594 5.710938 4.109375 C 5.925781 4.035156 6.210938 4 6.585938 4 L 6.984375 4 L 6.984375 5.367188 L 6.785156 5.367188 C 6.363281 5.367188 6.273438 5.417969 6.265625 5.425781 C 6.265625 5.425781 6.21875 5.488281 6.214844 5.742188 C 6.199219 6.386719 6.175781 6.804688 6.152344 7 C 6.125 7.21093
 8 6.0625 7.417969 5.964844 7.613281 C 5.894531 7.753906 5.789062 7.882812 5.644531 8.011719 C 5.78125 8.132812 5.890625 8.273438 5.96875 8.421875 C 6.085938 8.648438 6.152344 8.957031 6.171875 9.367188 L 6.226562 10.515625 C 6.234375 10.539062 6.257812 10.574219 6.300781 10.601562 C 6.308594 10.605469 6.394531 10.65625 6.78125 10.65625 L 6.980469 10.65625 L 6.980469 12.023438 Z"/>
+            <path fill="var(--outline)" d="M 7.984375 3 L 6.585938 3 C 6.101562 3 5.714844 3.050781 5.394531 3.160156 C 4.984375 3.296875 4.648438 3.527344 4.382812 3.84375 C 4.121094 4.160156 3.953125 4.546875 3.886719 4.984375 C 3.847656 5.265625 3.828125 5.636719 3.828125 6.152344 C 3.828125 6.21875 3.828125 6.277344 3.824219 6.332031 L 3 6.339844 L 3 9.652344 L 3.820312 9.683594 C 3.824219 9.796875 3.828125 9.941406 3.828125 10.136719 C 3.828125 10.8125 3.90625 11.308594 4.082031 11.691406 C 4.300781 12.1875 4.679688 12.558594 5.171875 12.777344 C 5.546875 12.941406 6.011719 13.023438 6.585938 13.023438 L 7.980469 13.023438 L 7.980469 9.652344 L 7.1875 9.652344 L 7.171875 9.316406 C 7.144531 8.789062 7.050781 8.363281 6.882812 8.015625 C 7.015625 7.730469 7.105469 7.433594 7.144531 7.121094 C 7.160156 7.015625 7.175781 6.820312 7.195312 6.363281 L 7.984375 6.363281 Z M 6.984375 4 L 6.984375 5.363281 L 6.785156 5.363281 C 6.367188 5.363281 6.277344 5.417969 6.26
 5625 5.425781 C 6.265625 5.425781 6.21875 5.488281 6.214844 5.742188 C 6.199219 6.386719 6.175781 6.804688 6.152344 7 C 6.125 7.210938 6.0625 7.417969 5.964844 7.613281 C 5.894531 7.753906 5.789062 7.886719 5.644531 8.011719 C 5.78125 8.132812 5.890625 8.269531 5.96875 8.421875 C 6.085938 8.648438 6.152344 8.957031 6.171875 9.363281 L 6.226562 10.515625 C 6.234375 10.539062 6.257812 10.574219 6.296875 10.601562 C 6.308594 10.605469 6.394531 10.652344 6.78125 10.652344 L 6.980469 10.652344 L 6.980469 12.023438 L 6.585938 12.023438 C 6.152344 12.023438 5.820312 11.96875 5.574219 11.859375 C 5.308594 11.742188 5.113281 11.550781 4.992188 11.285156 C 4.882812 11.035156 4.828125 10.660156 4.828125 10.136719 C 4.828125 9.453125 4.796875 9.230469 4.78125 9.152344 C 4.753906 9.03125 4.699219 8.925781 4.617188 8.824219 C 4.554688 8.75 4.40625 8.703125 4.195312 8.695312 L 4 8.6875 L 4 7.328125 L 4.199219 7.328125 C 4.414062 7.324219 4.570312 7.265625 4.667969 7.144531 C 4.714844 7.085938 4.82
 8125 6.875 4.828125 6.152344 C 4.828125 5.691406 4.84375 5.355469 4.878906 5.128906 C 4.914062 4.875 5.007812 4.65625 5.152344 4.484375 C 5.296875 4.3125 5.484375 4.183594 5.710938 4.105469 C 5.925781 4.035156 6.210938 4 6.585938 4 L 6.984375 4"/>
+            <path fill="var(--outline)" d="M 9.414062 3 L 8.015625 3 L 8.015625 6.363281 L 8.808594 6.363281 C 8.824219 6.804688 8.851562 7.113281 8.890625 7.328125 C 8.933594 7.570312 9.011719 7.804688 9.117188 8.019531 C 9 8.261719 8.921875 8.519531 8.878906 8.785156 C 8.851562 8.921875 8.828125 9.136719 8.808594 9.652344 L 8.019531 9.652344 L 8.019531 13.023438 L 9.421875 13.023438 C 9.90625 13.023438 10.296875 12.96875 10.617188 12.859375 C 11.003906 12.730469 11.355469 12.496094 11.617188 12.179688 C 11.886719 11.855469 12.054688 11.472656 12.117188 11.035156 C 12.15625 10.753906 12.171875 10.382812 12.171875 9.863281 C 12.171875 9.800781 12.175781 9.742188 12.175781 9.691406 L 13 9.683594 L 13 6.371094 L 12.179688 6.339844 C 12.175781 6.230469 12.171875 6.078125 12.171875 5.886719 C 12.171875 5.210938 12.09375 4.714844 11.921875 4.328125 C 11.699219 3.839844 11.324219 3.464844 10.828125 3.246094 C 10.453125 3.078125 9.988281 3 9.414062 3 M 9.414062 4 C 9.8476
 56 4 10.179688 4.054688 10.425781 4.160156 C 10.691406 4.277344 10.886719 4.472656 11.007812 4.738281 C 11.117188 4.988281 11.171875 5.363281 11.171875 5.886719 C 11.171875 6.59375 11.203125 6.816406 11.222656 6.886719 C 11.253906 7.003906 11.308594 7.105469 11.390625 7.203125 C 11.425781 7.246094 11.523438 7.316406 11.808594 7.328125 L 12 7.335938 L 12 8.695312 L 11.800781 8.695312 C 11.585938 8.699219 11.433594 8.757812 11.332031 8.878906 C 11.273438 8.953125 11.171875 9.175781 11.171875 9.863281 C 11.171875 10.332031 11.15625 10.667969 11.125 10.894531 C 11.089844 11.144531 10.996094 11.363281 10.851562 11.539062 C 10.707031 11.714844 10.519531 11.839844 10.292969 11.914062 C 10.082031 11.984375 9.796875 12.023438 9.421875 12.023438 L 9.019531 12.023438 L 9.019531 10.652344 L 9.21875 10.652344 C 9.636719 10.652344 9.726562 10.59375 9.730469 10.59375 C 9.730469 10.59375 9.785156 10.53125 9.789062 10.277344 C 9.808594 9.582031 9.828125 9.148438 9.863281 8.945312 C 9.898438 8.730469
  9.972656 8.527344 10.078125 8.339844 C 10.144531 8.21875 10.238281 8.109375 10.355469 8.007812 C 10.230469 7.902344 10.140625 7.796875 10.074219 7.6875 C 9.976562 7.523438 9.910156 7.34375 9.875 7.148438 C 9.839844 6.96875 9.816406 6.644531 9.800781 6.183594 C 9.78125 5.597656 9.761719 5.480469 9.757812 5.457031 C 9.695312 5.402344 9.609375 5.363281 9.214844 5.363281 L 9.015625 5.363281 L 9.015625 4 L 9.414062 4"/>
+            <path fill="white" d="M 9.019531 12.023438 L 9.019531 10.65625 L 9.21875 10.65625 C 9.636719 10.65625 9.726562 10.59375 9.734375 10.589844 C 9.734375 10.589844 9.785156 10.53125 9.789062 10.277344 C 9.804688 9.582031 9.832031 9.148438 9.863281 8.945312 C 9.898438 8.730469 9.96875 8.527344 10.078125 8.339844 C 10.144531 8.21875 10.238281 8.109375 10.351562 8.007812 C 10.230469 7.902344 10.140625 7.796875 10.074219 7.6875 C 9.976562 7.523438 9.910156 7.34375 9.875 7.152344 C 9.839844 6.96875 9.816406 6.644531 9.800781 6.183594 C 9.78125 5.597656 9.761719 5.476562 9.757812 5.457031 C 9.695312 5.402344 9.609375 5.367188 9.214844 5.367188 L 9.015625 5.367188 L 9.015625 4 L 9.414062 4 C 9.847656 4 10.179688 4.050781 10.425781 4.160156 C 10.691406 4.277344 10.886719 4.472656 11.007812 4.738281 C 11.117188 4.988281 11.171875 5.363281 11.171875 5.886719 C 11.171875 6.589844 11.207031 6.816406 11.222656 6.886719 C 11.253906 7.003906 11.308594 7.105469 11.390625 7
 .203125 C 11.425781 7.246094 11.527344 7.316406 11.804688 7.328125 L 12 7.335938 L 12 8.695312 L 11.800781 8.695312 C 11.585938 8.699219 11.433594 8.757812 11.332031 8.878906 C 11.273438 8.953125 11.171875 9.175781 11.171875 9.867188 C 11.171875 10.332031 11.15625 10.667969 11.125 10.890625 C 11.089844 11.144531 11 11.363281 10.851562 11.539062 C 10.707031 11.710938 10.519531 11.839844 10.292969 11.914062 C 10.082031 11.988281 9.792969 12.023438 9.417969 12.023438 Z"/>
+        </symbol>
+    </svg>
+
+    <svg id="author"><use xlink:href=""
+    <svg id="user"><use xlink:href=""
+    <svg id="useragent"><use xlink:href=""
+    <svg id="inspector"><use xlink:href=""
+    <svg id="inherited"><use xlink:href=""
+</svg>

Added: trunk/Source/WebInspectorUI/UserInterface/Images/StyleRuleInheritedElement.svg (0 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Images/StyleRuleInheritedElement.svg	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/StyleRuleInheritedElement.svg	2019-08-03 19:36:32 UTC (rev 248202)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2019 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" id="root" version="1.1" viewBox="0 0 16 16">
+    <path fill="rgb(224, 224, 224)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 Z"/>
+    <path fill="rgb(178, 178, 178)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 M 13 2 C 13.550781 2 14 2.449219 14 3 L 14 13 C 14 13.550781 13.550781 14 13 14 L 3 14 C 2.449219 14 2 13.550781 2 13 L 2 3 C 2 2.449219 2.449219 2 3 2 L 13 2"/>
+    <path fill="rgb(191, 191, 191)" d="M 5.503906 12.742188 C 4.949219 12.742188 4.503906 12.292969 4.503906 11.742188 L 4.503906 3.792969 C 4.503906 3.242188 4.949219 2.792969 5.503906 2.792969 L 10.472656 2.792969 C 11.023438 2.792969 11.472656 3.242188 11.472656 3.792969 L 11.472656 4.882812 C 11.472656 5.4375 11.023438 5.882812 10.472656 5.882812 C 10.472656 5.882812 9.132812 5.882812 8.15625 5.882812 C 8.15625 5.992188 8.15625 5.996094 8.15625 6.101562 C 8.957031 6.101562 9.875 6.101562 9.875 6.101562 C 10.425781 6.101562 10.875 6.550781 10.875 7.101562 L 10.875 8.164062 C 10.875 8.71875 10.425781 9.164062 9.875 9.164062 C 9.875 9.164062 8.957031 9.164062 8.15625 9.164062 C 8.15625 9.382812 8.15625 9.398438 8.15625 9.613281 C 9.191406 9.613281 10.722656 9.613281 10.722656 9.613281 C 11.277344 9.613281 11.722656 10.0625 11.722656 10.613281 L 11.722656 11.742188 C 11.722656 12.292969 11.277344 12.742188 10.722656 12.742188 L 5.503906 12.742188"/>
+    <path fill="white" d="M 5.503906 11.742188 L 5.503906 3.792969 L 10.46875 3.792969 L 10.46875 4.882812 L 7.15625 4.882812 L 7.15625 7.101562 L 9.875 7.101562 L 9.875 8.164062 L 7.15625 8.164062 L 7.15625 10.613281 L 10.722656 10.613281 L 10.722656 11.742188 Z"/>
+</svg>

Added: trunk/Source/WebInspectorUI/UserInterface/Images/StyleRulePseudo.svg (0 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Images/StyleRulePseudo.svg	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/StyleRulePseudo.svg	2019-08-03 19:36:32 UTC (rev 248202)
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright © 2019 Apple Inc. All rights reserved. -->
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 16 16">
+    <style>
+        svg {
+            display: none;
+        }
+
+        svg:target {
+            display: initial;
+        }
+
+        #author {
+            --background: rgb(148, 183, 219);
+            --border: rgb(106, 136, 170);
+            --outline: rgb(113, 146, 184);
+        }
+
+        #user {
+            --background: rgb(246, 222, 146);
+            --border: rgb(204, 181, 108);
+            --outline: rgb(216, 193, 115);
+        }
+
+        #useragent {
+            --background: rgb(236, 151, 153);
+            --border: rgb(191, 109, 113);
+            --outline: rgb(204, 116, 121);
+        }
+
+        #inspector {
+            --background: rgb(165, 202, 164);
+            --border: rgb(118, 153, 116);
+            --outline: rgb(128, 166, 126);
+        }
+    </style>
+
+    <svg>
+        <symbol id="style-rule">
+            <path fill="var(--background)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 Z"/>
+            <path fill="var(--border)" d="M 13 1 L 3 1 C 1.898438 1 1 1.898438 1 3 L 1 13 C 1 14.101562 1.898438 15 3 15 L 13 15 C 14.101562 15 15 14.101562 15 13 L 15 3 C 15 1.898438 14.101562 1 13 1 M 13 2 C 13.550781 2 14 2.449219 14 3 L 14 13 C 14 13.550781 13.550781 14 13 14 L 3 14 C 2.449219 14 2 13.550781 2 13 L 2 3 C 2 2.449219 2.449219 2 3 2 L 13 2"/>
+            <path fill="white" d="M 6.78125 7.769531 L 7.136719 7.769531 C 7.757812 7.769531 8.246094 7.636719 8.605469 7.371094 C 8.96875 7.105469 9.148438 6.746094 9.148438 6.292969 C 9.148438 5.496094 8.59375 5.097656 7.488281 5.097656 L 6.78125 5.097656 Z M 5 12 L 5 4 L 8.042969 4 C 9.105469 4 9.863281 4.164062 10.316406 4.488281 C 10.773438 4.816406 11 5.359375 11 6.125 C 11 6.988281 10.695312 7.660156 10.085938 8.144531 C 9.480469 8.625 8.628906 8.863281 7.535156 8.863281 L 6.78125 8.863281 L 6.78125 12 Z"/>
+            <path fill="var(--outline)" d="M 7.78125 6.679688 L 7.78125 6.113281 C 8.019531 6.136719 8.117188 6.1875 8.144531 6.203125 C 8.140625 6.210938 8.148438 6.242188 8.148438 6.292969 C 8.148438 6.441406 8.105469 6.496094 8.015625 6.566406 C 7.953125 6.613281 7.875 6.648438 7.78125 6.679688 M 8.042969 3 L 4 3 L 4 13 L 7.78125 13 L 7.78125 9.863281 C 8.988281 9.824219 9.96875 9.507812 10.707031 8.925781 C 11.550781 8.257812 12 7.289062 12 6.125 C 12 4.753906 11.402344 4.035156 10.902344 3.675781 C 10.265625 3.222656 9.332031 3 8.042969 3 M 6.78125 7.769531 L 7.136719 7.769531 C 7.757812 7.769531 8.246094 7.636719 8.605469 7.371094 C 8.96875 7.105469 9.148438 6.746094 9.148438 6.292969 C 9.148438 5.496094 8.59375 5.097656 7.488281 5.097656 L 6.78125 5.097656 L 6.78125 7.769531 M 8.042969 4 C 9.105469 4 9.863281 4.164062 10.316406 4.488281 C 10.773438 4.816406 11 5.359375 11 6.125 C 11 6.988281 10.695312 7.660156 10.085938 8.144531 C 9.480469 8.625 8.628906 8.8
 63281 7.535156 8.863281 L 6.78125 8.863281 L 6.78125 12 L 5 12 L 5 4 L 8.042969 4"/>
+        </symbol>
+    </svg>
+
+    <svg id="author"><use xlink:href=""
+    <svg id="user"><use xlink:href=""
+    <svg id="useragent"><use xlink:href=""
+    <svg id="inspector"><use xlink:href=""
+</svg>

Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Main.html	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html	2019-08-03 19:36:32 UTC (rev 248202)
@@ -206,6 +206,7 @@
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
+    <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSSelector.js (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSSelector.js	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSSelector.js	2019-08-03 19:36:32 UTC (rev 248202)
@@ -40,8 +40,8 @@
     get specificity() { return this._specificity; }
     get dynamic() { return this._dynamic; }
 
-    isPseudoElementSelector()
+    isPseudoSelector()
     {
-        return WI.CSSManager.PseudoElementNames.some((name) => this._text.includes(`:${name}`));
+        return Object.values(WI.CSSManager.PseudoSelectorNames).some((pseudoId) => (new RegExp("(?:\\b|^):{1,2}(?:-webkit-)?" + pseudoId + "(?:\\b|$)")).test(this._text));
     }
 };

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js	2019-08-03 19:36:32 UTC (rev 248202)
@@ -451,6 +451,28 @@
             WI.cssManager.removeModifiedStyle(this);
     }
 
+    generateCSSRuleString()
+    {
+        let indentString = WI.indentString();
+        let styleText = "";
+        let mediaList = this.mediaList.filter((media) => media.text !== "all");
+        let mediaQueriesCount = mediaList.length;
+        for (let i = mediaQueriesCount - 1; i >= 0; --i)
+            styleText += indentString.repeat(mediaQueriesCount - i - 1) + "@media " + mediaList[i].text + " {\n";
+
+        styleText += indentString.repeat(mediaQueriesCount) + this.selectorText + " {\n";
+
+        for (let property of (this._styleSheetTextRange ? this.visibleProperties : this._properties))
+            styleText += indentString.repeat(mediaQueriesCount + 1) + property.formattedText + "\n";
+
+        for (let i = mediaQueriesCount; i > 0; --i)
+            styleText += indentString.repeat(i) + "}\n";
+
+        styleText += "}";
+
+        return styleText;
+    }
+
     // Protected
 
     get nodeStyles()

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js	2019-08-03 19:36:32 UTC (rev 248202)
@@ -307,8 +307,12 @@
         experimentalSettingsView.addSetting(WI.UIString("User Interface:"), WI.settings.experimentalEnableNewTabBar, WI.UIString("Enable New Tab Bar"));
         experimentalSettingsView.addSeparator();
 
-        experimentalSettingsView.addSetting(WI.UIString("Styles:"), WI.settings.experimentalEnableStylesJumpToEffective, WI.UIString("Show Jump to Effective Property Button"));
-        experimentalSettingsView.addSeparator();
+        if (InspectorBackend.domains.CSS) {
+            let stylesGroup = experimentalSettingsView.addGroup(WI.UIString("Styles:"));
+            stylesGroup.addSetting(WI.settings.experimentalEnableStylesIcons, WI.UIString("Show Icons"));
+            stylesGroup.addSetting(WI.settings.experimentalEnableStylesJumpToEffective, WI.UIString("Show Jump to Effective Property Button"));
+            experimentalSettingsView.addSeparator();
+        }
 
         let reloadInspectorButton = document.createElement("button");
         reloadInspectorButton.textContent = WI.UIString("Reload Web Inspector");
@@ -337,8 +341,12 @@
         listenForChange(WI.settings.experimentalEnableSourcesTab);
         listenForChange(WI.settings.experimentalEnableLayersTab);
         listenForChange(WI.settings.experimentalEnableNewTabBar);
-        listenForChange(WI.settings.experimentalEnableStylesJumpToEffective);
 
+        if (InspectorBackend.domains.CSS) {
+            listenForChange(WI.settings.experimentalEnableStylesIcons);
+            listenForChange(WI.settings.experimentalEnableStylesJumpToEffective);
+        }
+
         this.addSettingsView(experimentalSettingsView);
     }
 

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.css (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.css	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.css	2019-08-03 19:36:32 UTC (rev 248202)
@@ -35,6 +35,10 @@
     --border-color-selected: var(--selected-background-color);
 }
 
+.spreadsheet-style-declaration-editor:empty {
+    height: 2px;
+}
+
 .spreadsheet-style-declaration-editor .property {
     padding-right: var(--css-declaration-horizontal-padding);
     padding-left: calc(var(--css-declaration-horizontal-padding) + 17px);
@@ -69,10 +73,6 @@
     max-width: 100%;
 }
 
-.spreadsheet-style-declaration-editor.no-properties {
-    display: none;
-}
-
 .spreadsheet-style-declaration-editor .property-toggle {
     visibility: hidden;
     position: absolute;

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationEditor.js	2019-08-03 19:36:32 UTC (rev 248202)
@@ -88,7 +88,6 @@
             this._style.updatePropertiesModifiedState();
 
         let properties = this.propertiesToRender;
-        this.element.classList.toggle("no-properties", !properties.length);
 
         // FIXME: Only re-layout properties that have been modified and preserve focus whenever possible.
         this._propertyViews = [];

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css	2019-08-03 19:36:32 UTC (rev 248202)
@@ -47,6 +47,10 @@
     padding-top: var(--css-declaration-vertical-padding);
 }
 
+.spreadsheet-css-declaration .header.editing-selector .selector {
+    margin-top: 1px;
+}
+
 .spreadsheet-css-declaration .header.editing-selector .origin {
     position: absolute;
     right: var(--css-declaration-horizontal-padding);
@@ -99,10 +103,27 @@
     -webkit-user-modify: read-only;
 }
 
+.spreadsheet-css-declaration .selector > .icon {
+    width: 16px;
+    height: 16px;
+    margin-top: -1px;
+    -webkit-margin-start: -2px;
+    vertical-align: -3.5px;
+    -webkit-user-select: none;
+}
+
+.spreadsheet-css-declaration .selector > .icon + * {
+    -webkit-padding-start: 2px;
+}
+
 .spreadsheet-css-declaration .selector > span {
     color: var(--text-color-secondary);
 }
 
+.spreadsheet-css-declaration .selector.style-attribute > span {
+    -webkit-margin-start: 0.5px;
+}
+
 .spreadsheet-css-declaration .selector.editing:focus,
 .spreadsheet-css-declaration .selector > .matched {
     color: var(--text-color);

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js	2019-08-03 19:36:32 UTC (rev 248202)
@@ -62,6 +62,43 @@
     {
         super.initialLayout();
 
+        if (WI.settings.experimentalEnableStylesIcons.value) {
+            let iconClassName = null;
+            switch (this._style.type) {
+            case WI.CSSStyleDeclaration.Type.Rule:
+                console.assert(this._style.ownerRule);
+                if (this._style.inherited) {
+                    iconClassName = "inherited-style-rule-icon";
+                    break;
+                }
+
+                switch (this._style.ownerRule.type) {
+                case WI.CSSStyleSheet.Type.Author:
+                    iconClassName = "author-style-rule-icon";
+                    break;
+                case WI.CSSStyleSheet.Type.User:
+                    iconClassName = "user-style-rule-icon";
+                    break;
+                case WI.CSSStyleSheet.Type.UserAgent:
+                    iconClassName = "user-agent-style-rule-icon";
+                    break;
+                case WI.CSSStyleSheet.Type.Inspector:
+                    iconClassName = "inspector-style-rule-icon";
+                    break;
+                }
+                break;
+            case WI.CSSStyleDeclaration.Type.Inline:
+            case WI.CSSStyleDeclaration.Type.Attribute:
+                if (this._style.inherited)
+                    iconClassName = "inherited-element-style-rule-icon";
+                else
+                    iconClassName = WI.DOMTreeElementPathComponent.DOMElementIconStyleClassName;
+                break;
+            }
+            console.assert(iconClassName);
+            this._element.classList.add(iconClassName);
+        }
+
         this._headerElement = document.createElement("div");
         this._headerElement.classList.add("header");
 
@@ -297,15 +334,29 @@
             selectorElement.classList.add(WI.SpreadsheetCSSStyleDeclarationSection.MatchedSelectorElementStyleClassName);
         };
 
+        if (WI.settings.experimentalEnableStylesIcons.value) {
+            if (!this._iconElement) {
+                this._iconElement = document.createElement("img");
+                this._iconElement.classList.add("icon");
+                WI.addMouseDownContextMenuHandlers(this._iconElement, this._populateIconElementContextMenu.bind(this));
+            }
+            this._selectorElement.appendChild(this._iconElement);
+        }
+
         switch (this._style.type) {
         case WI.CSSStyleDeclaration.Type.Rule:
             console.assert(this._style.ownerRule);
 
+            var hasMatchingPseudoSelector = false;
+
             var selectors = this._style.ownerRule.selectors;
-            var matchedSelectorIndices = this._style.ownerRule.matchedSelectorIndices;
             if (selectors.length) {
                 for (let i = 0; i < selectors.length; ++i) {
-                    appendSelector(selectors[i], matchedSelectorIndices.includes(i));
+                    let matched = this._style.ownerRule.matchedSelectorIndices.includes(i);
+                    if (matched && selectors[i].isPseudoSelector())
+                        hasMatchingPseudoSelector = true;
+
+                    appendSelector(selectors[i], matched);
                     if (i < selectors.length - 1)
                         this._selectorElement.append(", ");
                 }
@@ -312,12 +363,15 @@
             } else
                 appendSelectorTextKnownToMatch(this._style.ownerRule.selectorText);
 
+            this._element.classList.toggle("pseudo-selector", hasMatchingPseudoSelector);
             break;
 
-        case WI.CSSStyleDeclaration.Type.Inline:
-            this._selectorElement.textContent = WI.UIString("Style Attribute", "CSS properties defined via HTML style attribute");
+        case WI.CSSStyleDeclaration.Type.Inline: {
             this._selectorElement.classList.add("style-attribute");
+            let wrapper = this._selectorElement.appendChild(document.createElement("span"));
+            wrapper.textContent = WI.UIString("Style Attribute", "CSS properties defined via HTML style attribute");
             break;
+        }
 
         case WI.CSSStyleDeclaration.Type.Attribute:
             appendSelectorTextKnownToMatch(this._style.node.displayName);
@@ -430,6 +484,99 @@
             this._stopSelection();
     }
 
+    _populateIconElementContextMenu(contextMenu)
+    {
+        contextMenu.appendItem(WI.UIString("Copy Rule"), () => {
+            InspectorFrontendHost.copyText(this._style.generateCSSRuleString());
+        });
+
+        if (this._style.editable && this._style.properties.length) {
+            let shouldDisable = this._style.properties.some((property) => property.enabled);
+            contextMenu.appendItem(shouldDisable ? WI.UIString("Disable Rule") : WI.UIString("Enable Rule"), () => {
+                for (let property of this._style.properties)
+                    property.commentOut(shouldDisable);
+            });
+        }
+
+        if (!this._style.inherited) {
+            let generateSelector = () => {
+                if (this._style.type === WI.CSSStyleDeclaration.Type.Attribute)
+                    return this._style.node.displayName;
+                return this._style.selectorText;
+            };
+
+            let createNewRule = (selector, text) => {
+                if (this._delegate && this._delegate.spreadsheetCSSStyleDeclarationSectionAddNewRule)
+                    this._delegate.spreadsheetCSSStyleDeclarationSectionAddNewRule(this, selector, text);
+                else
+                    this._style.nodeStyles.addRule(selector, text);
+            };
+
+            contextMenu.appendSeparator();
+
+            contextMenu.appendItem(WI.UIString("Duplicate Selector"), () => {
+                createNewRule(generateSelector());
+            });
+
+            if (!WI.CSSManager.PseudoElementNames.some((className) => this._style.selectorText.includes(":" + className))) {
+                let addPseudoRule = (pseudoSelector, text) => {
+                    let selector = null;
+                    if (this._style.ownerRule)
+                        selector = this._style.ownerRule.selectors.map((selector) => selector.text + pseudoSelector).join(", ");
+                    else
+                        selector = generateSelector() + pseudoSelector;
+                    createNewRule(selector, text);
+                };
+
+                if (WI.CSSManager.ForceablePseudoClasses.every((className) => !this._style.selectorText.includes(":" + className))) {
+                    contextMenu.appendSeparator();
+
+                     for (let pseudoClass of WI.CSSManager.ForceablePseudoClasses) {
+                        if (pseudoClass === "visited" && this._style.node.nodeName() !== "A")
+                            continue;
+
+                        let pseudoClassSelector = ":" + pseudoClass;
+                        contextMenu.appendItem(WI.UIString("Add %s Rule").format(pseudoClassSelector), () => {
+                            this._style.node.setPseudoClassEnabled(pseudoClass, true);
+                            addPseudoRule(pseudoClassSelector);
+                        });
+                    }
+                }
+
+                if (this._style.type === WI.CSSStyleDeclaration.Type.Rule) {
+                    contextMenu.appendSeparator();
+
+                    for (let pseudoElement of WI.CSSManager.PseudoElementNames) {
+                        let pseudoElementSelector = "::" + pseudoElement;
+                        contextMenu.appendItem(WI.UIString("Create %s Rule").format(pseudoElementSelector), () => {
+                            addPseudoRule(pseudoElementSelector, "content: \"\";");
+                        });
+                    }
+                }
+            }
+        }
+
+        if (this._style.ownerRule && this._style.ownerRule.sourceCodeLocation) {
+            contextMenu.appendSeparator();
+
+            let label = null;
+            let sourceCode = this._style.ownerRule.sourceCodeLocation.displaySourceCode;
+            if (sourceCode instanceof WI.CSSStyleSheet || (sourceCode instanceof WI.Resource && sourceCode.type === WI.Resource.Type.Stylesheet))
+                label = WI.UIString("Reveal in Stylesheet");
+            else if (WI.settings.experimentalEnableSourcesTab.value)
+                label = WI.UIString("Reveal in Sources Tab");
+            else
+                label = WI.UIString("Reveal in Resources Tab");
+
+            contextMenu.appendItem(label, () => {
+                WI.showSourceCodeLocation(this._style.ownerRule.sourceCodeLocation, {
+                    ignoreNetworkTab: true,
+                    ignoreSearchTab: true,
+                });
+            });
+        }
+    }
+
     _handleWindowClick(event)
     {
         if (this._propertiesEditor.hasSelectedProperties()) {

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js (248201 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js	2019-08-03 19:00:01 UTC (rev 248201)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetRulesStyleDetailsPanel.js	2019-08-03 19:36:32 UTC (rev 248202)
@@ -205,6 +205,12 @@
         }
     }
 
+    spreadsheetCSSStyleDeclarationSectionAddNewRule(section, selector, text)
+    {
+        this._newRuleSelector = selector;
+        this.nodeStyles.addRule(this._newRuleSelector, text);
+    }
+
     // Protected
 
     layout()
@@ -300,8 +306,8 @@
         let beforePseudoId = null;
         let afterPseudoId = null;
         if (InspectorBackend.domains.CSS.PseudoId) {
-            beforePseudoId = InspectorBackend.domains.CSS.PseudoId.Before;
-            afterPseudoId = InspectorBackend.domains.CSS.PseudoId.After;
+            beforePseudoId = WI.CSSManager.PseudoSelectorNames.Before;
+            afterPseudoId = WI.CSSManager.PseudoSelectorNames.After;
         } else {
             // Compatibility (iOS 12.2): CSS.PseudoId did not exist.
             beforePseudoId = 4;

Copied: trunk/Source/WebInspectorUI/UserInterface/Views/StyleRuleIcons.css (from rev 248201, trunk/Source/WebInspectorUI/UserInterface/Models/CSSSelector.js) (0 => 248202)


--- trunk/Source/WebInspectorUI/UserInterface/Views/StyleRuleIcons.css	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/StyleRuleIcons.css	2019-08-03 19:36:32 UTC (rev 248202)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.author-style-rule-icon .icon {
+    content: url(../Images/StyleRule.svg#author);
+}
+
+.author-style-rule-icon.pseudo-selector .icon {
+    content: url(../Images/StyleRulePseudo.svg#author);
+}
+
+.user-style-rule-icon .icon {
+    content: url(../Images/StyleRule.svg#user);
+}
+
+.user-style-rule-icon.pseudo-selector .icon {
+    content: url(../Images/StyleRulePseudo.svg#user);
+}
+
+.user-agent-style-rule-icon .icon {
+    content: url(../Images/StyleRule.svg#useragent);
+}
+
+.user-agent-style-rule-icon.pseudo-selector .icon {
+    content: url(../Images/StyleRulePseudo.svg#useragent);
+}
+
+.inspector-style-rule-icon .icon {
+    content: url(../Images/StyleRule.svg#inspector);
+}
+
+.inspector-style-rule-icon.pseudo-selector .icon {
+    content: url(../Images/StyleRulePseudo.svg#inspector);
+}
+
+.inherited-style-rule-icon .icon {
+    content: url(../Images/StyleRule.svg#inherited);
+}
+
+.inherited-element-style-rule-icon .icon {
+    content: url(../Images/StyleRuleInheritedElement.svg);
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to