Web Inspector: Styles: show @supports CSS groupings
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Aug 2019 18:28:15 +0000 (18:28 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Aug 2019 18:28:15 +0000 (18:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200419
<rdar://problem/53971948>

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

* inspector/protocol/CSS.json:
Rename `CSSMedia` to `Grouping` and remove the `sourceLine` value, as it was never populated
and wasn't used by Web Inspector.

* inspector/scripts/codegen/objc_generator_templates.py:
* inspector/scripts/codegen/generate_objc_header.py:
(ObjCHeaderGenerator.generate_output):
Add support for including files at the end of <WebInspector/RWIProtocol.h> for compatibility
statements so that changes to the Web Inspector protocol don't break other clients.

Source/WebCore:

Test: inspector/css/getMatchedStylesForNode.html

* inspector/InspectorStyleSheet.cpp:
(WebCore::buildArrayForGroupings): Added.
(WebCore::InspectorStyleSheet::buildObjectForRule):
(WebCore::buildMediaObject): Deleted.
(WebCore::fillMediaListChain): Deleted.

* css/MediaList.h:
* css/MediaList.cpp:
(WebCore::MediaQuerySet::MediaQuerySet):
Remove the `lastLine` as it was never set by anyone and wasn't used by Web Inspector.

Source/WebInspectorUI:

* UserInterface/Models/CSSGrouping.js: Renamed from Source/WebInspectorUI/UserInterface/Models/CSSMedia.js.
(WI.CSSGrouping):
(WI.CSSGrouping.prototype.get type):
(WI.CSSGrouping.prototype.get text):
(WI.CSSGrouping.prototype.get sourceCodeLocation):
(WI.CSSGrouping.prototype.get isMedia): Added.
(WI.CSSGrouping.prototype.get isSupports): Added.
(WI.CSSGrouping.prototype.get prefix): Added.

* UserInterface/Models/CSSStyleDeclaration.js:
(WI.CSSStyleDeclaration.prototype.get groupings): Added.
(WI.CSSStyleDeclaration.prototype.generateCSSRuleString):
(WI.CSSStyleDeclaration.prototype.get mediaList): Deleted.

* UserInterface/Models/CSSRule.js:
(WI.CSSRule):
(WI.CSSRule.prototype.get groupings): Added.
(WI.CSSRule.prototype.update):
(WI.CSSRule.prototype._selectorResolved):
(WI.CSSRule.prototype.get mediaList): Deleted.

* UserInterface/Models/DOMNodeStyles.js:
(WI.DOMNodeStyles.prototype._parseRulePayload):
(WI.DOMNodeStyles.prototype.rulesForSelector): Deleted.

* UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:
(WI.SpreadsheetCSSStyleDeclarationSection):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype.initialLayout):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype._handleEditorFilterApplied):
(WI.SpreadsheetCSSStyleDeclarationSection.prototype._createMediaHeader): Deleted.
* UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css:
(.spreadsheet-css-declaration :matches(.header, .header-groupings)): Added.
(.spreadsheet-css-declaration :matches(.header, .header-groupings):first-child): Added.
(.spreadsheet-css-declaration .header-groupings > .grouping): Added.
(.spreadsheet-css-declaration :matches(.header, .header-media)): Deleted.
(.spreadsheet-css-declaration :matches(.header, .header-media):first-child): Deleted.
(.spreadsheet-css-declaration .media-label): Deleted.

* UserInterface/Controllers/CSSManager.js:
(WI.CSSManager.protocolGroupingTypeToEnum): Added.
(WI.CSSManager.protocolMediaSourceToEnum): Deleted.

* UserInterface/Main.html:
* UserInterface/Test.html:

LayoutTests:

* inspector/css/getMatchedStylesForNode.html:
* inspector/css/getMatchedStylesForNode-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248602 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/css/getMatchedStylesForNode-expected.txt
LayoutTests/inspector/css/getMatchedStylesForNode.html
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/protocol/CSS.json
Source/JavaScriptCore/inspector/scripts/codegen/generate_objc_header.py
Source/JavaScriptCore/inspector/scripts/codegen/objc_generator_templates.py
Source/WebCore/ChangeLog
Source/WebCore/css/MediaList.cpp
Source/WebCore/css/MediaList.h
Source/WebCore/inspector/InspectorStyleSheet.cpp
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Controllers/CSSManager.js
Source/WebInspectorUI/UserInterface/Main.html
Source/WebInspectorUI/UserInterface/Models/CSSGrouping.js [moved from Source/WebInspectorUI/UserInterface/Models/CSSMedia.js with 62% similarity]
Source/WebInspectorUI/UserInterface/Models/CSSRule.js
Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js
Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js
Source/WebInspectorUI/UserInterface/Test.html
Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css
Source/WebInspectorUI/UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js

index 013d2c9..3610634 100644 (file)
@@ -1,3 +1,14 @@
+2019-08-13  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Styles: show @supports CSS groupings
+        https://bugs.webkit.org/show_bug.cgi?id=200419
+        <rdar://problem/53971948>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/css/getMatchedStylesForNode.html:
+        * inspector/css/getMatchedStylesForNode-expected.txt:
+
 2019-08-13  Russell Epstein  <repstein@apple.com>
 
         Reverting change in r248379
index f8fd63a..35c566f 100644 (file)
@@ -790,9 +790,59 @@ Inherited:
           "style": {
             "cssProperties": [
               {
-                "name": "z-index",
-                "value": "0",
-                "text": "z-index: 0;",
+                "name": "color",
+                "value": "red",
+                "text": "color: red;",
+                "range": "<filtered>",
+                "implicit": false,
+                "status": "active"
+              }
+            ],
+            "shorthandEntries": [],
+            "styleId": "<filtered>",
+            "width": "",
+            "height": "",
+            "range": "<filtered>",
+            "cssText": " color: red; "
+          },
+          "sourceURL": "<filtered>",
+          "ruleId": "<filtered>",
+          "groupings": [
+            {
+              "text": "(min-width: 0px)",
+              "type": "media-import-rule",
+              "sourceURL": "<filtered>"
+            }
+          ]
+        },
+        "matchingSelectors": [
+          0
+        ]
+      },
+      {
+        "rule": {
+          "selectorList": {
+            "selectors": [
+              {
+                "text": "body",
+                "specificity": [
+                  0,
+                  0,
+                  1
+                ]
+              }
+            ],
+            "text": "body",
+            "range": "<filtered>"
+          },
+          "sourceLine": "<filtered>",
+          "origin": "regular",
+          "style": {
+            "cssProperties": [
+              {
+                "name": "color",
+                "value": "red",
+                "text": "color: red;",
                 "range": "<filtered>",
                 "implicit": false,
                 "status": "active"
@@ -803,7 +853,7 @@ Inherited:
             "width": "",
             "height": "",
             "range": "<filtered>",
-            "cssText": " z-index: 0; "
+            "cssText": " color: red; "
           },
           "sourceURL": "<filtered>",
           "ruleId": "<filtered>"
@@ -811,6 +861,211 @@ Inherited:
         "matchingSelectors": [
           0
         ]
+      },
+      {
+        "rule": {
+          "selectorList": {
+            "selectors": [
+              {
+                "text": "body",
+                "specificity": [
+                  0,
+                  0,
+                  1
+                ]
+              }
+            ],
+            "text": "body",
+            "range": "<filtered>"
+          },
+          "sourceLine": "<filtered>",
+          "origin": "regular",
+          "style": {
+            "cssProperties": [
+              {
+                "name": "color",
+                "value": "red",
+                "text": "color: red;",
+                "range": "<filtered>",
+                "implicit": false,
+                "status": "active"
+              }
+            ],
+            "shorthandEntries": [],
+            "styleId": "<filtered>",
+            "width": "",
+            "height": "",
+            "range": "<filtered>",
+            "cssText": " color: red; "
+          },
+          "sourceURL": "<filtered>",
+          "ruleId": "<filtered>",
+          "groupings": [
+            {
+              "text": "(min-width: 1px)",
+              "type": "media-rule",
+              "sourceURL": "<filtered>"
+            }
+          ]
+        },
+        "matchingSelectors": [
+          0
+        ]
+      },
+      {
+        "rule": {
+          "selectorList": {
+            "selectors": [
+              {
+                "text": "body",
+                "specificity": [
+                  0,
+                  0,
+                  1
+                ]
+              }
+            ],
+            "text": "body",
+            "range": "<filtered>"
+          },
+          "sourceLine": "<filtered>",
+          "origin": "regular",
+          "style": {
+            "cssProperties": [
+              {
+                "name": "color",
+                "value": "red",
+                "text": "color: red;",
+                "range": "<filtered>",
+                "implicit": false,
+                "status": "active"
+              }
+            ],
+            "shorthandEntries": [],
+            "styleId": "<filtered>",
+            "width": "",
+            "height": "",
+            "range": "<filtered>",
+            "cssText": " color: red; "
+          },
+          "sourceURL": "<filtered>",
+          "ruleId": "<filtered>",
+          "groupings": [
+            {
+              "text": "(display: block)",
+              "type": "supports-rule",
+              "sourceURL": "<filtered>"
+            },
+            {
+              "text": "(min-width: 2px)",
+              "type": "media-rule",
+              "sourceURL": "<filtered>"
+            }
+          ]
+        },
+        "matchingSelectors": [
+          0
+        ]
+      },
+      {
+        "rule": {
+          "selectorList": {
+            "selectors": [
+              {
+                "text": "body",
+                "specificity": [
+                  0,
+                  0,
+                  1
+                ]
+              }
+            ],
+            "text": "body",
+            "range": "<filtered>"
+          },
+          "sourceLine": "<filtered>",
+          "origin": "regular",
+          "style": {
+            "cssProperties": [
+              {
+                "name": "color",
+                "value": "red",
+                "text": "color: red;",
+                "range": "<filtered>",
+                "implicit": false,
+                "status": "active"
+              }
+            ],
+            "shorthandEntries": [],
+            "styleId": "<filtered>",
+            "width": "",
+            "height": "",
+            "range": "<filtered>",
+            "cssText": " color: red;"
+          },
+          "sourceURL": "<filtered>",
+          "ruleId": "<filtered>",
+          "groupings": [
+            {
+              "text": "(min-width: 3px)",
+              "type": "media-style-node",
+              "sourceURL": "<filtered>"
+            }
+          ]
+        },
+        "matchingSelectors": [
+          0
+        ]
+      },
+      {
+        "rule": {
+          "selectorList": {
+            "selectors": [
+              {
+                "text": "body",
+                "specificity": [
+                  0,
+                  0,
+                  1
+                ]
+              }
+            ],
+            "text": "body",
+            "range": "<filtered>"
+          },
+          "sourceLine": "<filtered>",
+          "origin": "regular",
+          "style": {
+            "cssProperties": [
+              {
+                "name": "color",
+                "value": "red",
+                "text": "color: red;",
+                "range": "<filtered>",
+                "implicit": false,
+                "status": "active"
+              }
+            ],
+            "shorthandEntries": [],
+            "styleId": "<filtered>",
+            "width": "",
+            "height": "",
+            "range": "<filtered>",
+            "cssText": " color: red; "
+          },
+          "sourceURL": "<filtered>",
+          "ruleId": "<filtered>",
+          "groupings": [
+            {
+              "text": "(min-width: 4px)",
+              "type": "media-link-node",
+              "sourceURL": "<filtered>"
+            }
+          ]
+        },
+        "matchingSelectors": [
+          0
+        ]
       }
     ]
   }
index 61c80b1..6dbbf2e 100644 (file)
@@ -1,6 +1,36 @@
 <html>
 <head>
 <script src="../../http/tests/inspector/resources/protocol-test.js"></script>
+<style>
+    @import url(resources/external.css?1) (min-width: 0px);
+
+    body { color: red; }
+    @media (min-width: 1px) { body { color: red; } }
+    @media (min-width: 2px) { @supports(display: block) { body { color: red; } } }
+</style>
+<style media="(min-width: 3px)">
+    body { color: red;}
+</style>
+<link rel="stylesheet" href="resources/external.css?2" media="(min-width: 4px)">
+<style>
+    div#x { z-index: 100; }
+    #x { z-index: 200; }
+    div { z-index: 300; }
+
+    div::first-line { z-index: 1; }
+    div::first-letter { z-index: 2; }
+    div::marker { z-index: 3; }
+    div::before { z-index: 4; }
+    div::after { z-index: 5; }
+    div::selection { z-index: 6; }
+    div::-webkit-scrollbar { z-index: 7; }
+    div::-webkit-scrollbar-thumb { z-index: 8; }
+    div::-webkit-scrollbar-button { z-index: 9; }
+    div::-webkit-scrollbar-track { z-index: 10; }
+    div::-webkit-scrollbar-track-piece { z-index: 11; }
+    div::-webkit-scrollbar-corner { z-index: 12; }
+    div::-webkit-resizer { z-index: 13; }
+</style>
 <script>
 function test()
 {
@@ -75,29 +105,7 @@ function test()
 </script>
 </head>
 <body onLoad="runTest()">
-    <p>Testing CSS.getMatchedStylesForNode.</p>
-
-    <style>
-    body { z-index: 0; }
-
-    div#x { z-index: 100; }
-    #x { z-index: 200; }
-    div { z-index: 300; }
-
-    div::first-line { z-index: 1; }
-    div::first-letter { z-index: 2; }
-    div::marker { z-index: 3; }
-    div::before { z-index: 4; }
-    div::after { z-index: 5; }
-    div::selection { z-index: 6; }
-    div::-webkit-scrollbar { z-index: 7; }
-    div::-webkit-scrollbar-thumb { z-index: 8; }
-    div::-webkit-scrollbar-button { z-index: 9; }
-    div::-webkit-scrollbar-track { z-index: 10; }
-    div::-webkit-scrollbar-track-piece { z-index: 11; }
-    div::-webkit-scrollbar-corner { z-index: 12; }
-    div::-webkit-resizer { z-index: 13; }
-    </style>
-    <div id="x"></div>
+<p>Testing CSS.getMatchedStylesForNode.</p>
+<div id="x"></div>
 </body>
 </html>
index a62d1e0..723fb2b 100644 (file)
@@ -1,3 +1,21 @@
+2019-08-13  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Styles: show @supports CSS groupings
+        https://bugs.webkit.org/show_bug.cgi?id=200419
+        <rdar://problem/53971948>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/protocol/CSS.json:
+        Rename `CSSMedia` to `Grouping` and remove the `sourceLine` value, as it was never populated
+        and wasn't used by Web Inspector.
+
+        * inspector/scripts/codegen/objc_generator_templates.py:
+        * inspector/scripts/codegen/generate_objc_header.py:
+        (ObjCHeaderGenerator.generate_output):
+        Add support for including files at the end of <WebInspector/RWIProtocol.h> for compatibility
+        statements so that changes to the Web Inspector protocol don't break other clients.
+
 2019-08-13  Joseph Pecoraro  <pecoraro@apple.com>
 
         JSContext Inspector: Basic CommandLineAPI doesn't work
index e48f3bb..cda3175 100644 (file)
                 { "name": "sourceLine", "type": "integer", "description": "Line ordinal of the rule selector start character in the resource."},
                 { "name": "origin", "$ref": "StyleSheetOrigin", "description": "Parent stylesheet's origin."},
                 { "name": "style", "$ref": "CSSStyle", "description": "Associated style declaration." },
-                { "name": "media", "type": "array", "items": { "$ref": "CSSMedia" }, "optional": true, "description": "Media list array (for rules involving media queries). The array enumerates media queries starting with the innermost one, going outwards." }
+                { "name": "groupings", "type": "array", "items": { "$ref": "Grouping" }, "optional": true, "description": "Grouping list array (for rules involving @media/@supports). The array enumerates CSS groupings starting with the innermost one, going outwards." }
             ]
         },
         {
             ]
         },
         {
-            "id": "CSSMedia",
+            "id": "Grouping",
             "type": "object",
-            "description": "CSS media query descriptor.",
+            "description": "CSS @media (as well as other users of media queries, like @import, <style>, <link>, etc.) and @supports descriptor.",
             "properties": [
                 { "name": "text", "type": "string", "description": "Media query text." },
-                { "name": "source", "type": "string", "enum": ["mediaRule", "importRule", "linkedSheet", "inlineSheet"], "description": "Source of the media query: \"mediaRule\" if specified by a @media rule, \"importRule\" if specified by an @import rule, \"linkedSheet\" if specified by a \"media\" attribute in a linked stylesheet's LINK tag, \"inlineSheet\" if specified by a \"media\" attribute in an inline stylesheet's STYLE tag." },
-                { "name": "sourceURL", "type": "string", "optional": true, "description": "URL of the document containing the media query description." },
-                { "name": "sourceLine", "type": "integer", "optional": true, "description": "Line in the document containing the media query (not defined for the \"stylesheet\" source)." }
+                { "name": "type", "type": "string", "enum": ["media-rule", "media-import-rule", "media-link-node", "media-style-node", "supports-rule"], "description": "Source of the media query: \"media-rule\" if specified by a @media rule, \"media-import-rule\" if specified by an @import rule, \"media-link-node\" if specified by a \"media\" attribute in a linked style sheet's LINK tag, \"media-style-node\" if specified by a \"media\" attribute in an inline style sheet's STYLE tag, \"supports-rule\" if specified by an @supports rule, ." },
+                { "name": "sourceURL", "type": "string", "optional": true, "description": "URL of the document containing the CSS grouping." }
             ]
         }
     ],
index 2532652..fc0cc2a 100755 (executable)
@@ -57,12 +57,20 @@ class ObjCHeaderGenerator(ObjCGenerator):
         return '%s.h' % self.protocol_name()
 
     def generate_output(self):
-        headers = set([
+        headerPreludeHeaders = set([
             '<WebInspector/%sJSONObject.h>' % ObjCGenerator.OBJC_STATIC_PREFIX,
         ])
 
-        header_args = {
-            'includes': '\n'.join(['#import ' + header for header in sorted(headers)]),
+        headerPrelude_args = {
+            'includes': '\n'.join(['#import ' + header for header in sorted(headerPreludeHeaders)]),
+        }
+
+        headerPostludeHeaders = set([
+            '<WebInspector/%sBuildCompatibilityObjects.h>' % ObjCGenerator.OBJC_STATIC_PREFIX,
+        ])
+
+        headerPostlude_args = {
+            'includes': '\n'.join(['#import ' + header for header in sorted(headerPostludeHeaders)]),
         }
 
         domains = self.domains_to_generate()
@@ -77,7 +85,7 @@ class ObjCHeaderGenerator(ObjCGenerator):
 
         sections = []
         sections.append(self.generate_license())
-        sections.append(Template(ObjCTemplates.HeaderPrelude).substitute(None, **header_args))
+        sections.append(Template(ObjCTemplates.HeaderPrelude).substitute(None, **headerPrelude_args))
         sections.append('\n'.join([_f for _f in map(self._generate_forward_declarations, type_domains) if _f]))
         sections.append(self._generate_enum_for_platforms())
         sections.append('\n'.join([_f for _f in map(self._generate_enums, type_domains) if _f]))
@@ -87,7 +95,7 @@ class ObjCHeaderGenerator(ObjCGenerator):
             sections.append('\n\n'.join([_f for _f in map(self._generate_command_protocols, command_domains) if _f]))
             sections.append('\n\n'.join([_f for _f in map(self._generate_event_interfaces, event_domains) if _f]))
 
-        sections.append(Template(ObjCTemplates.HeaderPostlude).substitute(None))
+        sections.append(Template(ObjCTemplates.HeaderPostlude).substitute(None, **headerPostlude_args))
         return '\n\n'.join(sections)
 
     def _generate_forward_declarations(self, domain):
index 50c8f6f..66f9fd2 100755 (executable)
@@ -36,7 +36,9 @@ ${includes}
 """)
 
     HeaderPostlude = (
-    """""")
+    """
+${includes}
+""")
 
     TypeConversionsHeaderPrelude = (
     """${includes}
index b35e878..dc81d0c 100644 (file)
@@ -1,3 +1,24 @@
+2019-08-13  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Styles: show @supports CSS groupings
+        https://bugs.webkit.org/show_bug.cgi?id=200419
+        <rdar://problem/53971948>
+
+        Reviewed by Joseph Pecoraro.
+
+        Test: inspector/css/getMatchedStylesForNode.html
+
+        * inspector/InspectorStyleSheet.cpp:
+        (WebCore::buildArrayForGroupings): Added.
+        (WebCore::InspectorStyleSheet::buildObjectForRule):
+        (WebCore::buildMediaObject): Deleted.
+        (WebCore::fillMediaListChain): Deleted.
+
+        * css/MediaList.h:
+        * css/MediaList.cpp:
+        (WebCore::MediaQuerySet::MediaQuerySet):
+        Remove the `lastLine` as it was never set by anyone and wasn't used by Web Inspector.
+
 2019-08-13  Sihui Liu  <sihui_liu@apple.com>
 
         Make sure UniqueIDBDatabaseConnection unregister itself from IDBServer
index 1ad9644..2112f40 100644 (file)
@@ -73,7 +73,6 @@ MediaQuerySet::MediaQuerySet() = default;
 
 MediaQuerySet::MediaQuerySet(const MediaQuerySet& o)
     : RefCounted()
-    , m_lastLine(o.m_lastLine)
     , m_queries(o.m_queries)
 {
 }
index 4cbd401..2b6d987 100644 (file)
@@ -56,9 +56,6 @@ public:
 
     const Vector<MediaQuery>& queryVector() const { return m_queries; }
 
-    int lastLine() const { return m_lastLine; }
-    void setLastLine(int lastLine) { m_lastLine = lastLine; }
-
     WEBCORE_EXPORT String mediaText() const;
 
     Ref<MediaQuerySet> copy() const { return adoptRef(*new MediaQuerySet(*this)); }
@@ -70,7 +67,6 @@ private:
     WEBCORE_EXPORT MediaQuerySet(const String& mediaQuery);
     MediaQuerySet(const MediaQuerySet&);
 
-    int m_lastLine { 0 };
     Vector<MediaQuery> m_queries;
 };
 
index ca30e1a..1495f39 100644 (file)
@@ -379,13 +379,6 @@ void StyleSheetHandler::observeComment(unsigned startOffset, unsigned endOffset)
     m_currentRuleDataStack.last()->styleSourceData->propertyData.append(CSSPropertySourceData(propertyData.name, propertyData.value, false, true, true, SourceRange(startOffset - topRuleBodyRange.start, endOffset - topRuleBodyRange.start)));
 }
 
-enum MediaListSource {
-    MediaListSourceLinkedSheet,
-    MediaListSourceInlineSheet,
-    MediaListSourceMediaRule,
-    MediaListSourceImportRule
-};
-
 static RefPtr<Inspector::Protocol::CSS::SourceRange> buildSourceRangeObject(const SourceRange& range, const Vector<size_t>& lineEndings, int* endingLine = nullptr)
 {
     if (lineEndings.isEmpty())
@@ -405,37 +398,6 @@ static RefPtr<Inspector::Protocol::CSS::SourceRange> buildSourceRangeObject(cons
         .release();
 }
 
-static Ref<Inspector::Protocol::CSS::CSSMedia> buildMediaObject(const MediaList* media, MediaListSource mediaListSource, const String& sourceURL)
-{
-    // Make certain compilers happy by initializing |source| up-front.
-    Inspector::Protocol::CSS::CSSMedia::Source source = Inspector::Protocol::CSS::CSSMedia::Source::InlineSheet;
-    switch (mediaListSource) {
-    case MediaListSourceMediaRule:
-        source = Inspector::Protocol::CSS::CSSMedia::Source::MediaRule;
-        break;
-    case MediaListSourceImportRule:
-        source = Inspector::Protocol::CSS::CSSMedia::Source::ImportRule;
-        break;
-    case MediaListSourceLinkedSheet:
-        source = Inspector::Protocol::CSS::CSSMedia::Source::LinkedSheet;
-        break;
-    case MediaListSourceInlineSheet:
-        source = Inspector::Protocol::CSS::CSSMedia::Source::InlineSheet;
-        break;
-    }
-
-    auto mediaObject = Inspector::Protocol::CSS::CSSMedia::create()
-        .setText(media->mediaText())
-        .setSource(source)
-        .release();
-
-    if (!sourceURL.isEmpty()) {
-        mediaObject->setSourceURL(sourceURL);
-        mediaObject->setSourceLine(media->queries()->lastLine());
-    }
-    return mediaObject;
-}
-
 static RefPtr<CSSRuleList> asCSSRuleList(CSSStyleSheet* styleSheet)
 {
     if (!styleSheet)
@@ -465,59 +427,85 @@ static RefPtr<CSSRuleList> asCSSRuleList(CSSRule* rule)
     return nullptr;
 }
 
-static void fillMediaListChain(CSSRule* rule, JSON::ArrayOf<Inspector::Protocol::CSS::CSSMedia>& mediaArray)
+static Ref<JSON::ArrayOf<Inspector::Protocol::CSS::Grouping>> buildArrayForGroupings(CSSRule& rule)
 {
-    MediaList* mediaList;
-    CSSRule* parentRule = rule;
-    String sourceURL;
+    auto groupingsPayload = JSON::ArrayOf<Inspector::Protocol::CSS::Grouping>::create();
+
+    auto* parentRule = &rule;
     while (parentRule) {
-        CSSStyleSheet* parentStyleSheet = nullptr;
-        bool isMediaRule = true;
-        if (is<CSSMediaRule>(*parentRule)) {
-            CSSMediaRule& mediaRule = downcast<CSSMediaRule>(*parentRule);
-            mediaList = mediaRule.media();
-            parentStyleSheet = mediaRule.parentStyleSheet();
-        } else if (is<CSSImportRule>(*parentRule)) {
-            CSSImportRule& importRule = downcast<CSSImportRule>(*parentRule);
-            mediaList = &importRule.media();
-            parentStyleSheet = importRule.parentStyleSheet();
-            isMediaRule = false;
-        } else
-            mediaList = nullptr;
-
-        if (parentStyleSheet) {
-            sourceURL = parentStyleSheet->contents().baseURL();
-            if (sourceURL.isEmpty())
-                sourceURL = InspectorDOMAgent::documentURLString(parentStyleSheet->ownerDocument());
-        } else
-            sourceURL = emptyString();
-
-        if (mediaList && mediaList->length())
-            mediaArray.addItem(buildMediaObject(mediaList, isMediaRule ? MediaListSourceMediaRule : MediaListSourceImportRule, sourceURL));
-
-        if (parentRule->parentRule())
-            parentRule = parentRule->parentRule();
-        else {
-            CSSStyleSheet* styleSheet = parentRule->parentStyleSheet();
-            while (styleSheet) {
-                mediaList = styleSheet->media();
-                if (mediaList && mediaList->length()) {
-                    Document* doc = styleSheet->ownerDocument();
-                    if (doc)
-                        sourceURL = doc->url();
-                    else if (!styleSheet->contents().baseURL().isEmpty())
-                        sourceURL = styleSheet->contents().baseURL();
-                    else
-                        sourceURL = emptyString();
-                    mediaArray.addItem(buildMediaObject(mediaList, styleSheet->ownerNode() ? MediaListSourceLinkedSheet : MediaListSourceInlineSheet, sourceURL));
+        RefPtr<Inspector::Protocol::CSS::Grouping> ruleGroupingPayload;
+
+        if (is<CSSMediaRule>(parentRule)) {
+            auto* media = downcast<CSSMediaRule>(parentRule)->media();
+            if (media && media->length() && media->mediaText() != "all") {
+                ruleGroupingPayload = Inspector::Protocol::CSS::Grouping::create()
+                    .setText(media->mediaText())
+                    .setType(Inspector::Protocol::CSS::Grouping::Type::MediaRule)
+                    .release();
+            }
+        } else if (is<CSSImportRule>(parentRule)) {
+            auto& media = downcast<CSSImportRule>(parentRule)->media();
+            if (media.length() && media.mediaText() != "all") {
+                ruleGroupingPayload = Inspector::Protocol::CSS::Grouping::create()
+                    .setText(media.mediaText())
+                    .setType(Inspector::Protocol::CSS::Grouping::Type::MediaImportRule)
+                    .release();
+            }
+        } else if (is<CSSSupportsRule>(parentRule)) {
+            ruleGroupingPayload = Inspector::Protocol::CSS::Grouping::create()
+                .setText(downcast<CSSSupportsRule>(parentRule)->conditionText())
+                .setType(Inspector::Protocol::CSS::Grouping::Type::SupportsRule)
+                .release();
+        }
+
+        if (ruleGroupingPayload) {
+            if (auto* parentStyleSheet = parentRule->parentStyleSheet()) {
+                String sourceURL = parentStyleSheet->contents().baseURL();
+                if (sourceURL.isEmpty()) {
+                    if (auto* ownerDocument = parentStyleSheet->ownerDocument())
+                        sourceURL = InspectorDOMAgent::documentURLString(ownerDocument);
                 }
-                parentRule = styleSheet->ownerRule();
-                if (parentRule)
-                    break;
-                styleSheet = styleSheet->parentStyleSheet();
+                if (!sourceURL.isEmpty())
+                    ruleGroupingPayload->setSourceURL(sourceURL);
+            }
+
+            groupingsPayload->addItem(WTFMove(ruleGroupingPayload));
+        }
+
+        if (parentRule->parentRule()) {
+            parentRule = parentRule->parentRule();
+            continue;
+        }
+
+        auto* styleSheet = parentRule->parentStyleSheet();
+        while (styleSheet) {
+            auto* media = styleSheet->media();
+            if (media && media->length() && media->mediaText() != "all") {
+                auto sheetGroupingPayload = Inspector::Protocol::CSS::Grouping::create()
+                    .setText(media->mediaText())
+                    .setType(is<HTMLStyleElement>(styleSheet->ownerNode()) ? Inspector::Protocol::CSS::Grouping::Type::MediaStyleNode: Inspector::Protocol::CSS::Grouping::Type::MediaLinkNode)
+                    .release();
+
+                String sourceURL;
+                if (auto* ownerDocument = styleSheet->ownerDocument())
+                    sourceURL = ownerDocument->url();
+                else if (!styleSheet->contents().baseURL().isEmpty())
+                    sourceURL = styleSheet->contents().baseURL();
+                if (!sourceURL.isEmpty())
+                    sheetGroupingPayload->setSourceURL(sourceURL);
+
+                groupingsPayload->addItem(WTFMove(sheetGroupingPayload));
             }
+
+            parentRule = styleSheet->ownerRule();
+            if (parentRule)
+                break;
+
+            styleSheet = styleSheet->parentStyleSheet();
         }
     }
+
+    return groupingsPayload;
 }
 
 Ref<InspectorStyle> InspectorStyle::create(const InspectorCSSId& styleId, Ref<CSSStyleDeclaration>&& style, InspectorStyleSheet* parentStyleSheet)
@@ -1173,11 +1161,9 @@ RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorStyleSheet::buildObjectForRul
             result->setRuleId(id.asProtocolValue<Inspector::Protocol::CSS::CSSRuleId>());
     }
 
-    auto mediaArray = ArrayOf<Inspector::Protocol::CSS::CSSMedia>::create();
-
-    fillMediaListChain(rule, mediaArray.get());
-    if (mediaArray->length())
-        result->setMedia(WTFMove(mediaArray));
+    auto groupingsPayload = buildArrayForGroupings(*rule);
+    if (groupingsPayload->length())
+        result->setGroupings(WTFMove(groupingsPayload));
 
     return result;
 }
index 88f3340..fa9d4b7 100644 (file)
@@ -1,3 +1,56 @@
+2019-08-13  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Styles: show @supports CSS groupings
+        https://bugs.webkit.org/show_bug.cgi?id=200419
+        <rdar://problem/53971948>
+
+        Reviewed by Joseph Pecoraro.
+
+        * UserInterface/Models/CSSGrouping.js: Renamed from Source/WebInspectorUI/UserInterface/Models/CSSMedia.js.
+        (WI.CSSGrouping):
+        (WI.CSSGrouping.prototype.get type):
+        (WI.CSSGrouping.prototype.get text):
+        (WI.CSSGrouping.prototype.get sourceCodeLocation):
+        (WI.CSSGrouping.prototype.get isMedia): Added.
+        (WI.CSSGrouping.prototype.get isSupports): Added.
+        (WI.CSSGrouping.prototype.get prefix): Added.
+
+        * UserInterface/Models/CSSStyleDeclaration.js:
+        (WI.CSSStyleDeclaration.prototype.get groupings): Added.
+        (WI.CSSStyleDeclaration.prototype.generateCSSRuleString):
+        (WI.CSSStyleDeclaration.prototype.get mediaList): Deleted.
+
+        * UserInterface/Models/CSSRule.js:
+        (WI.CSSRule):
+        (WI.CSSRule.prototype.get groupings): Added.
+        (WI.CSSRule.prototype.update):
+        (WI.CSSRule.prototype._selectorResolved):
+        (WI.CSSRule.prototype.get mediaList): Deleted.
+
+        * UserInterface/Models/DOMNodeStyles.js:
+        (WI.DOMNodeStyles.prototype._parseRulePayload):
+        (WI.DOMNodeStyles.prototype.rulesForSelector): Deleted.
+
+        * UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.js:
+        (WI.SpreadsheetCSSStyleDeclarationSection):
+        (WI.SpreadsheetCSSStyleDeclarationSection.prototype.initialLayout):
+        (WI.SpreadsheetCSSStyleDeclarationSection.prototype._handleEditorFilterApplied):
+        (WI.SpreadsheetCSSStyleDeclarationSection.prototype._createMediaHeader): Deleted.
+        * UserInterface/Views/SpreadsheetCSSStyleDeclarationSection.css:
+        (.spreadsheet-css-declaration :matches(.header, .header-groupings)): Added.
+        (.spreadsheet-css-declaration :matches(.header, .header-groupings):first-child): Added.
+        (.spreadsheet-css-declaration .header-groupings > .grouping): Added.
+        (.spreadsheet-css-declaration :matches(.header, .header-media)): Deleted.
+        (.spreadsheet-css-declaration :matches(.header, .header-media):first-child): Deleted.
+        (.spreadsheet-css-declaration .media-label): Deleted.
+
+        * UserInterface/Controllers/CSSManager.js:
+        (WI.CSSManager.protocolGroupingTypeToEnum): Added.
+        (WI.CSSManager.protocolMediaSourceToEnum): Deleted.
+
+        * UserInterface/Main.html:
+        * UserInterface/Test.html:
+
 2019-08-12  Devin Rousso  <drousso@apple.com>
 
         REGRESSION(r248391): Web Inspector: changing Layout Direction Debug setting no longer adds dir="ltr" to body element
index d8f3ddf..dd1218e 100644 (file)
@@ -81,21 +81,22 @@ WI.CSSManager = class CSSManager extends WI.Object
         }
     }
 
-    static protocolMediaSourceToEnum(source)
-    {
-        switch (source) {
-        case CSSAgent.CSSMediaSource.MediaRule:
-            return WI.CSSMedia.Type.MediaRule;
-        case CSSAgent.CSSMediaSource.ImportRule:
-            return WI.CSSMedia.Type.ImportRule;
-        case CSSAgent.CSSMediaSource.LinkedSheet:
-            return WI.CSSMedia.Type.LinkedStyleSheet;
-        case CSSAgent.CSSMediaSource.InlineSheet:
-            return WI.CSSMedia.Type.InlineStyleSheet;
-        default:
-            console.assert(false, "Unknown CSS.CSSMediaSource", source);
-            return WI.CSSMedia.Type.MediaRule;
+    static protocolGroupingTypeToEnum(type)
+    {
+        // COMPATIBILITY (iOS 13): CSS.Grouping did not exist yet.
+        if (!InspectorBackend.domains.CSS.Grouping) {
+            switch (type) {
+            case "mediaRule":
+                return WI.CSSGrouping.Type.MediaRule;
+            case "importRule":
+                return WI.CSSGrouping.Type.MediaImportRule;
+            case "linkedSheet":
+                return WI.CSSGrouping.Type.MediaLinkNode;
+            case "inlineSheet":
+                return WI.CSSGrouping.Type.MediaStyleNode;
+            }
         }
+        return type;
     }
 
     static displayNameForPseudoId(pseudoId)
index 5b0b064..9a766f7 100644 (file)
     <script src="Models/CPUTimeline.js"></script>
     <script src="Models/CPUTimelineRecord.js"></script>
     <script src="Models/CSSCompletions.js"></script>
+    <script src="Models/CSSGrouping.js"></script>
     <script src="Models/CSSKeywordCompletions.js"></script>
-    <script src="Models/CSSMedia.js"></script>
     <script src="Models/CSSProperty.js"></script>
     <script src="Models/CSSRule.js"></script>
     <script src="Models/CSSSelector.js"></script>
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * 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
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-WI.CSSMedia = class CSSMedia
+WI.CSSGrouping = class CSSGrouping
 {
     constructor(type, text, sourceCodeLocation)
     {
+        console.assert(Object.values(CSSGrouping.Type).includes(type));
+        console.assert(typeof text === "string" && text.length);
         console.assert(!sourceCodeLocation || sourceCodeLocation instanceof WI.SourceCodeLocation);
 
-        this._type = type || null;
-        this._text = text || "";
+        this._type = type;
+        this._text = text;
         this._sourceCodeLocation = sourceCodeLocation || null;
     }
 
@@ -39,11 +41,34 @@ WI.CSSMedia = class CSSMedia
     get type() { return this._type; }
     get text() { return this._text; }
     get sourceCodeLocation() { return this._sourceCodeLocation; }
+
+    get isMedia()
+    {
+        return this._type === WI.CSSGrouping.Type.MediaRule
+            || this._type === WI.CSSGrouping.Type.MediaImportRule
+            || this._type === WI.CSSGrouping.Type.MediaLinkNode
+            || this._type === WI.CSSGrouping.Type.MediaStyleNode;
+    }
+
+    get isSupports()
+    {
+        return this._type === WI.CSSGrouping.Type.SupportsRule;
+    }
+
+    get prefix()
+    {
+        if (this.isSupports)
+            return "@supports";
+
+        console.assert(this.isMedia);
+        return "@media";
+    }
 };
 
-WI.CSSMedia.Type = {
-    MediaRule: "css-media-type-media-rule",
-    ImportRule: "css-media-type-import-rule",
-    LinkedStyleSheet: "css-media-type-linked-stylesheet",
-    InlineStyleSheet: "css-media-type-inline-stylesheet"
+WI.CSSGrouping.Type = {
+    MediaRule: "media-rule",
+    MediaImportRule: "media-import-rule",
+    MediaLinkNode: "media-link-node",
+    MediaStyleNode: "media-style-node",
+    SupportsRule: "supports-rule",
 };
index 8d8e259..5c21079 100644 (file)
@@ -25,7 +25,7 @@
 
 WI.CSSRule = class CSSRule extends WI.Object
 {
-    constructor(nodeStyles, ownerStyleSheet, id, type, sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList)
+    constructor(nodeStyles, ownerStyleSheet, id, type, sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, groupings)
     {
         super();
 
@@ -37,57 +37,26 @@ WI.CSSRule = class CSSRule extends WI.Object
         this._type = type || null;
         this._initialState = null;
 
-        this.update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList, true);
+        this.update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, groupings, true);
     }
 
     // Public
 
+    get ownerStyleSheet() { return this._ownerStyleSheet; }
     get id() { return this._id; }
+    get type() { return this._type; }
     get initialState() { return this._initialState; }
-
-    get ownerStyleSheet()
-    {
-        return this._ownerStyleSheet;
-    }
+    get sourceCodeLocation() { return this._sourceCodeLocation; }
+    get selectors() { return this._selectors; }
+    get matchedSelectorIndices() { return this._matchedSelectorIndices; }
+    get style() { return this._style; }
+    get groupings() { return this._groupings; }
 
     get editable()
     {
         return !!this._id && (this._type === WI.CSSStyleSheet.Type.Author || this._type === WI.CSSStyleSheet.Type.Inspector);
     }
 
-    update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList)
-    {
-        sourceCodeLocation = sourceCodeLocation || null;
-        selectorText = selectorText || "";
-        selectors = selectors || [];
-        matchedSelectorIndices = matchedSelectorIndices || [];
-        style = style || null;
-        mediaList = mediaList || [];
-
-        if (this._style)
-            this._style.ownerRule = null;
-
-        this._sourceCodeLocation = sourceCodeLocation;
-        this._selectorText = selectorText;
-        this._selectors = selectors;
-        this._matchedSelectorIndices = matchedSelectorIndices;
-        this._style = style;
-        this._mediaList = mediaList;
-
-        if (this._style)
-            this._style.ownerRule = this;
-    }
-
-    get type()
-    {
-        return this._type;
-    }
-
-    get sourceCodeLocation()
-    {
-        return this._sourceCodeLocation;
-    }
-
     get selectorText()
     {
         return this._selectorText;
@@ -107,24 +76,27 @@ WI.CSSRule = class CSSRule extends WI.Object
         this._nodeStyles.changeRuleSelector(this, selectorText).then(this._selectorResolved.bind(this), this._selectorRejected.bind(this));
     }
 
-    get selectors()
+    update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, groupings)
     {
-        return this._selectors;
-    }
+        sourceCodeLocation = sourceCodeLocation || null;
+        selectorText = selectorText || "";
+        selectors = selectors || [];
+        matchedSelectorIndices = matchedSelectorIndices || [];
+        style = style || null;
+        groupings = groupings || [];
 
-    get matchedSelectorIndices()
-    {
-        return this._matchedSelectorIndices;
-    }
+        if (this._style)
+            this._style.ownerRule = null;
 
-    get style()
-    {
-        return this._style;
-    }
+        this._sourceCodeLocation = sourceCodeLocation;
+        this._selectorText = selectorText;
+        this._selectors = selectors;
+        this._matchedSelectorIndices = matchedSelectorIndices;
+        this._style = style;
+        this._groupings = groupings;
 
-    get mediaList()
-    {
-        return this._mediaList;
+        if (this._style)
+            this._style.ownerRule = this;
     }
 
     isEqualTo(rule)
@@ -173,7 +145,7 @@ WI.CSSRule = class CSSRule extends WI.Object
                     sourceCodeLocation = this._ownerStyleSheet.offsetSourceCodeLocation(sourceCodeLocation);
                 }
 
-                this.update(sourceCodeLocation, selectorText, selectors, [], this._style, this._mediaList);
+                this.update(sourceCodeLocation, selectorText, selectors, [], this._style, this._groupings);
             }
         }
 
index c3bf44d..0e97884 100644 (file)
@@ -287,10 +287,10 @@ WI.CSSStyleDeclaration = class CSSStyleDeclaration extends WI.Object
         return this._styleSheetTextRange;
     }
 
-    get mediaList()
+    get groupings()
     {
         if (this._ownerRule)
-            return this._ownerRule.mediaList;
+            return this._ownerRule.groupings;
         return [];
     }
 
@@ -511,17 +511,17 @@ WI.CSSStyleDeclaration = class CSSStyleDeclaration extends WI.Object
     {
         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";
+        let groupings = this.groupings.filter((grouping) => grouping.text !== "all");
+        let groupingsCount = groupings.length;
+        for (let i = groupingsCount - 1; i >= 0; --i)
+            styleText += indentString.repeat(groupingsCount - i - 1) + groupings[i].prefix + " " + groupings[i].text + " {\n";
 
-        styleText += indentString.repeat(mediaQueriesCount) + this.selectorText + " {\n";
+        styleText += indentString.repeat(groupingsCount) + this.selectorText + " {\n";
 
         for (let property of (this._styleSheetTextRange ? this.visibleProperties : this._properties))
-            styleText += indentString.repeat(mediaQueriesCount + 1) + property.formattedText + "\n";
+            styleText += indentString.repeat(groupingsCount + 1) + property.formattedText + "\n";
 
-        for (let i = mediaQueriesCount; i > 0; --i)
+        for (let i = groupingsCount; i > 0; --i)
             styleText += indentString.repeat(i) + "}\n";
 
         styleText += "}";
index 807b1f6..4309b6a 100644 (file)
@@ -123,16 +123,25 @@ WI.DOMNodeStyles = class DOMNodeStyles extends WI.Object
 
     // Public
 
-    get node()
-    {
-        return this._node;
-    }
+    get node() { return this._node; }
+    get matchedRules() { return this._matchedRules; }
+    get inheritedRules() { return this._inheritedRules; }
+    get inlineStyle() { return this._inlineStyle; }
+    get attributesStyle() { return this._attributesStyle; }
+    get pseudoElements() { return this._pseudoElements; }
+    get computedStyle() { return this._computedStyle; }
+    get orderedStyles() { return this._orderedStyles; }
 
     get needsRefresh()
     {
         return this._pendingRefreshTask || this._needsRefresh;
     }
 
+    get uniqueOrderedStyles()
+    {
+        return WI.DOMNodeStyles.uniqueOrderedStyles(this._orderedStyles);
+    }
+
     refreshIfNeeded()
     {
         if (this._pendingRefreshTask)
@@ -375,62 +384,6 @@ WI.DOMNodeStyles = class DOMNodeStyles extends WI.Object
             WI.cssManager.preferredInspectorStyleSheetForFrame(this._node.frame, inspectorStyleSheetAvailable.bind(this));
     }
 
-    rulesForSelector(selector)
-    {
-        selector = selector || this._node.appropriateSelectorFor(true);
-
-        function ruleHasSelector(rule) {
-            return !rule.mediaList.length && rule.selectorText === selector;
-        }
-
-        let rules = this._matchedRules.filter(ruleHasSelector);
-
-        for (let pseudoElementInfo of this._pseudoElements.values())
-            rules = rules.concat(pseudoElementInfo.matchedRules.filter(ruleHasSelector));
-
-        return rules;
-    }
-
-    get matchedRules()
-    {
-        return this._matchedRules;
-    }
-
-    get inheritedRules()
-    {
-        return this._inheritedRules;
-    }
-
-    get inlineStyle()
-    {
-        return this._inlineStyle;
-    }
-
-    get attributesStyle()
-    {
-        return this._attributesStyle;
-    }
-
-    get pseudoElements()
-    {
-        return this._pseudoElements;
-    }
-
-    get computedStyle()
-    {
-        return this._computedStyle;
-    }
-
-    get orderedStyles()
-    {
-        return this._orderedStyles;
-    }
-
-    get uniqueOrderedStyles()
-    {
-        return WI.DOMNodeStyles.uniqueOrderedStyles(this._orderedStyles);
-    }
-
     effectivePropertyForName(name)
     {
         let property = this._propertyNameToEffectivePropertyMap[name];
@@ -731,27 +684,24 @@ WI.DOMNodeStyles = class DOMNodeStyles extends WI.Object
             sourceCodeLocation = styleSheet.offsetSourceCodeLocation(sourceCodeLocation);
         }
 
-        var mediaList = [];
-        for (var i = 0; payload.media && i < payload.media.length; ++i) {
-            var mediaItem = payload.media[i];
-            var mediaType = WI.CSSManager.protocolMediaSourceToEnum(mediaItem.source);
-            var mediaText = mediaItem.text;
-            let mediaSourceCodeLocation = DOMNodeStyles.createSourceCodeLocation(mediaItem.sourceURL, {line: mediaItem.sourceLine});
+        // COMPATIBILITY (iOS 13): CSS.CSSRule.groupings did not exist yet.
+        let groupings = (payload.groupings || payload.media || []).map((grouping) => {
+            let groupingType = WI.CSSManager.protocolGroupingTypeToEnum(grouping.type || grouping.source);
+            let groupingSourceCodeLocation = DOMNodeStyles.createSourceCodeLocation(grouping.sourceURL);
             if (styleSheet)
-                mediaSourceCodeLocation = styleSheet.offsetSourceCodeLocation(mediaSourceCodeLocation);
-
-            mediaList.push(new WI.CSSMedia(mediaType, mediaText, mediaSourceCodeLocation));
-        }
+                groupingSourceCodeLocation = styleSheet.offsetSourceCodeLocation(groupingSourceCodeLocation);
+            return new WI.CSSGrouping(groupingType, grouping.text, groupingSourceCodeLocation);
+        });
 
         if (rule) {
-            rule.update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList);
+            rule.update(sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, groupings);
             return rule;
         }
 
         if (styleSheet)
             styleSheet.addEventListener(WI.CSSStyleSheet.Event.ContentDidChange, this._styleSheetContentDidChange, this);
 
-        rule = new WI.CSSRule(this, styleSheet, id, type, sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, mediaList);
+        rule = new WI.CSSRule(this, styleSheet, id, type, sourceCodeLocation, selectorText, selectors, matchedSelectorIndices, style, groupings);
 
         if (mapKey)
             this._rulesMap.set(mapKey, rule);
index c002183..92c7e98 100644 (file)
     <script src="Models/CPUTimeline.js"></script>
     <script src="Models/CPUTimelineRecord.js"></script>
     <script src="Models/CSSCompletions.js"></script>
+    <script src="Models/CSSGrouping.js"></script>
     <script src="Models/CSSKeywordCompletions.js"></script>
-    <script src="Models/CSSMedia.js"></script>
     <script src="Models/CSSProperty.js"></script>
     <script src="Models/CSSRule.js"></script>
     <script src="Models/CSSSelector.js"></script>
index 177603f..200e82c 100644 (file)
     -webkit-user-select: none;
 }
 
-.spreadsheet-css-declaration :matches(.header, .header-media) {
+.spreadsheet-css-declaration :matches(.header, .header-groupings) {
     padding: 0 var(--css-declaration-horizontal-padding);
 }
 
-.spreadsheet-css-declaration :matches(.header, .header-media):first-child {
+.spreadsheet-css-declaration :matches(.header, .header-groupings):first-child {
     padding-top: var(--css-declaration-vertical-padding);
 }
 
@@ -58,7 +58,7 @@
     right: var(--css-declaration-horizontal-padding);
 }
 
-.spreadsheet-css-declaration .media-label {
+.spreadsheet-css-declaration .header-groupings > .grouping {
     color: var(--text-color);
 }
 
index 90ab754..b417c38 100644 (file)
@@ -38,7 +38,7 @@ WI.SpreadsheetCSSStyleDeclarationSection = class SpreadsheetCSSStyleDeclarationS
         this._style = style;
         this._propertiesEditor = null;
         this._selectorElements = [];
-        this._mediaElements = [];
+        this._groupingElements = [];
         this._filterText = null;
         this._shouldFocusSelectorElement = false;
         this._wasEditing = false;
@@ -99,7 +99,29 @@ WI.SpreadsheetCSSStyleDeclarationSection = class SpreadsheetCSSStyleDeclarationS
             this._element.classList.add("has-icon", iconClassName);
         }
 
-        this._headerElement = document.createElement("div");
+        let groupings = this._style.groupings.filter((grouping) => grouping.text !== "all");
+        if (groupings.length) {
+            let groupingsElement = this.element.appendChild(document.createElement("div"));
+            groupingsElement.classList.add("header-groupings");
+
+            let currentGroupingType = null;
+            let groupingTypeElement = null;
+            this._groupingElements = groupings.map((grouping) => {
+                if (grouping.type !== currentGroupingType) {
+                    groupingTypeElement = groupingsElement.appendChild(document.createElement("div"));
+                    groupingTypeElement.classList.add("grouping");
+                    groupingTypeElement.textContent = grouping.prefix + " ";
+                    currentGroupingType = grouping.type;
+                } else
+                    groupingTypeElement.append(", ");
+
+                let span = groupingTypeElement.appendChild(document.createElement("span"));
+                span.textContent = grouping.text;
+                return span;
+            });
+        }
+
+        this._headerElement = this._element.appendChild(document.createElement("div"));
         this._headerElement.classList.add("header");
 
         this._styleOriginView = new WI.StyleOriginView();
@@ -136,7 +158,7 @@ WI.SpreadsheetCSSStyleDeclarationSection = class SpreadsheetCSSStyleDeclarationS
         this._closeBrace.classList.add("close-brace");
         this._closeBrace.textContent = "}";
 
-        this._element.append(this._createMediaHeader(), this._headerElement);
+
         this.addSubview(this._propertiesEditor);
         this._propertiesEditor.needsLayout();
         this._element.append(this._closeBrace);
@@ -382,31 +404,6 @@ WI.SpreadsheetCSSStyleDeclarationSection = class SpreadsheetCSSStyleDeclarationS
             this.applyFilter(this._filterText);
     }
 
-    _createMediaHeader()
-    {
-        let mediaList = this._style.mediaList;
-        if (!mediaList.length || (mediaList.length === 1 && (mediaList[0].text === "all" || mediaList[0].text === "screen")))
-            return "";
-
-        let mediaElement = document.createElement("div");
-        mediaElement.classList.add("header-media");
-
-        let mediaLabel = mediaElement.appendChild(document.createElement("div"));
-        mediaLabel.className = "media-label";
-        mediaLabel.append("@media ");
-
-        this._mediaElements = mediaList.map((media, i) => {
-            if (i)
-                mediaLabel.append(", ");
-
-            let span = mediaLabel.appendChild(document.createElement("span"));
-            span.textContent = media.text;
-            return span;
-        });
-
-        return mediaElement;
-    }
-
     _save(event)
     {
         event.stop();
@@ -668,13 +665,13 @@ WI.SpreadsheetCSSStyleDeclarationSection = class SpreadsheetCSSStyleDeclarationS
 
     _handleEditorFilterApplied(event)
     {
-        let matchesMedia = false;
-        for (let mediaElement of this._mediaElements) {
-            mediaElement.classList.remove(WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName);
+        let matchesGrouping = false;
+        for (let groupingElement of this._groupingElements) {
+            groupingElement.classList.remove(WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName);
 
-            if (mediaElement.textContent.includes(this._filterText)) {
-                mediaElement.classList.add(WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName);
-                matchesMedia = true;
+            if (groupingElement.textContent.includes(this._filterText)) {
+                groupingElement.classList.add(WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName);
+                matchesGrouping = true;
             }
         }
 
@@ -688,7 +685,7 @@ WI.SpreadsheetCSSStyleDeclarationSection = class SpreadsheetCSSStyleDeclarationS
             }
         }
 
-        let matches = event.data.matches || matchesMedia || matchesSelector;
+        let matches = event.data.matches || matchesGrouping || matchesSelector;
         if (!matches)
             this._element.classList.add(WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName);