Bug 1552098 - Add "Matched CSS Rules" command to the layout debugger. r=emilio
authorCameron McCormack <cam@mcc.id.au>
Thu, 16 May 2019 23:11:50 +0000
changeset 474274 fc0842a0b38f664b96458910cc1a2f7faf2b9858
parent 474273 d62be51ffad3d8a22ad4ebaffff910e9dd7bb6e1
child 474275 243251620b8e60ec461d348ee79a2df307655ba7
push id36027
push usershindli@mozilla.com
push dateFri, 17 May 2019 16:24:38 +0000
treeherdermozilla-central@c94c54aff466 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1552098
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1552098 - Add "Matched CSS Rules" command to the layout debugger. r=emilio Differential Revision: https://phabricator.services.mozilla.com/D31397
layout/generic/nsContainerFrame.cpp
layout/generic/nsContainerFrame.h
layout/generic/nsFrame.cpp
layout/generic/nsIFrame.h
layout/tools/layout-debug/src/nsILayoutDebuggingTools.idl
layout/tools/layout-debug/src/nsLayoutDebuggingTools.cpp
layout/tools/layout-debug/ui/content/layoutdebug.xul
layout/tools/layout-debug/ui/locale/en-US/layoutdebug.dtd
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -2001,9 +2001,32 @@ void nsContainerFrame::List(FILE* out, c
     fprintf_stderr(out, "%s>\n", aPrefix);
     outputOneList = true;
   }
 
   if (!outputOneList) {
     fprintf_stderr(out, "%s<>\n", str.get());
   }
 }
+
+void nsContainerFrame::ListWithMatchedRules(FILE* out,
+                                            const char* aPrefix) const {
+  fprintf_stderr(out, "%s%s\n", aPrefix, ListTag().get());
+
+  nsCString rulePrefix;
+  rulePrefix += aPrefix;
+  rulePrefix += "    ";
+  ListMatchedRules(out, rulePrefix.get());
+
+  nsCString childPrefix;
+  childPrefix += aPrefix;
+  childPrefix += "  ";
+
+  ChildListIterator lists(this);
+  for (; !lists.IsDone(); lists.Next()) {
+    nsFrameList::Enumerator childFrames(lists.CurrentList());
+    for (; !childFrames.AtEnd(); childFrames.Next()) {
+      nsIFrame* kid = childFrames.get();
+      kid->ListWithMatchedRules(out, childPrefix.get());
+    }
+  }
+}
 #endif
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -68,16 +68,18 @@ class nsContainerFrame : public nsSplitt
   virtual FrameSearchResult PeekOffsetCharacter(
       bool aForward, int32_t* aOffset,
       PeekOffsetCharacterOptions aOptions =
           PeekOffsetCharacterOptions()) override;
 
 #ifdef DEBUG_FRAME_DUMP
   void List(FILE* out = stderr, const char* aPrefix = "",
             uint32_t aFlags = 0) const override;
+  void ListWithMatchedRules(FILE* out = stderr,
+                            const char* aPrefix = "") const override;
 #endif
 
   // nsContainerFrame methods
 
   /**
    * Called to set the initial list of frames. This happens after the frame
    * has been initialized.
    *
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -7600,16 +7600,36 @@ void nsIFrame::ListGeneric(nsACString& a
 }
 
 void nsIFrame::List(FILE* out, const char* aPrefix, uint32_t aFlags) const {
   nsCString str;
   ListGeneric(str, aPrefix, aFlags);
   fprintf_stderr(out, "%s\n", str.get());
 }
 
+void nsIFrame::ListMatchedRules(FILE* out, const char* aPrefix) const {
+  nsTArray<const RawServoStyleRule*> rawRuleList;
+  Servo_ComputedValues_GetStyleRuleList(mComputedStyle, &rawRuleList);
+  for (const RawServoStyleRule* rawRule : rawRuleList) {
+    nsString ruleText;
+    Servo_StyleRule_GetCssText(rawRule, &ruleText);
+    fprintf_stderr(out, "%s%s\n", aPrefix,
+                   NS_ConvertUTF16toUTF8(ruleText).get());
+  }
+}
+
+void nsIFrame::ListWithMatchedRules(FILE* out, const char* aPrefix) const {
+  fprintf_stderr(out, "%s%s\n", aPrefix, ListTag().get());
+
+  nsCString rulePrefix;
+  rulePrefix += aPrefix;
+  rulePrefix += "    ";
+  ListMatchedRules(out, rulePrefix.get());
+}
+
 nsresult nsFrame::GetFrameName(nsAString& aResult) const {
   return MakeFrameName(NS_LITERAL_STRING("Frame"), aResult);
 }
 
 nsresult nsFrame::MakeFrameName(const nsAString& aType,
                                 nsAString& aResult) const {
   aResult = aType;
   if (mContent && !mContent->IsText()) {
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -4577,16 +4577,19 @@ class nsIFrame : public nsQueryFrame {
   }
   void ListTag(FILE* out) const { fputs(ListTag().get(), out); }
   nsAutoCString ListTag() const;
   void ListGeneric(nsACString& aTo, const char* aPrefix = "",
                    uint32_t aFlags = 0) const;
   enum {TRAVERSE_SUBDOCUMENT_FRAMES = 0x01};
   virtual void List(FILE* out = stderr, const char* aPrefix = "",
                     uint32_t aFlags = 0) const;
+  virtual void ListWithMatchedRules(FILE* out = stderr,
+                                    const char* aPrefix = "") const;
+  void ListMatchedRules(FILE* out, const char* aPrefix) const;
   /**
    * lists the frames beginning from the root frame
    * - calls root frame's List(...)
    */
   static void RootFrameList(nsPresContext* aPresContext, FILE* out = stderr,
                             const char* aPrefix = "");
   virtual void DumpFrameTree() const;
   void DumpFrameTreeLimited() const;
--- a/layout/tools/layout-debug/src/nsILayoutDebuggingTools.idl
+++ b/layout/tools/layout-debug/src/nsILayoutDebuggingTools.idl
@@ -41,12 +41,13 @@ interface nsILayoutDebuggingTools : nsIS
 
     /* Run various tests. */
     void dumpWebShells();
     void dumpContent();
     void dumpFrames();
     void dumpViews();
 
     void dumpStyleSheets();
+    void dumpMatchedRules();
     void dumpComputedStyles();
 
     void dumpReflowStats();
 };
--- a/layout/tools/layout-debug/src/nsLayoutDebuggingTools.cpp
+++ b/layout/tools/layout-debug/src/nsLayoutDebuggingTools.cpp
@@ -408,16 +408,32 @@ nsLayoutDebuggingTools::DumpStyleSheets(
     presShell->ListStyleSheets(out);
   } else {
     fputs("null pres shell\n", out);
   }
 #endif
   return NS_OK;
 }
 
+NS_IMETHODIMP nsLayoutDebuggingTools::DumpMatchedRules() {
+  NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
+#ifdef DEBUG_FRAME_DUMP
+  FILE* out = stdout;
+  if (PresShell* presShell = GetPresShell(mDocShell)) {
+    nsIFrame* root = presShell->GetRootFrame();
+    if (root) {
+      root->ListWithMatchedRules(out);
+    }
+  } else {
+    fputs("null pres shell\n", out);
+  }
+#endif
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsLayoutDebuggingTools::DumpComputedStyles() {
   NS_ENSURE_TRUE(mDocShell, NS_ERROR_NOT_INITIALIZED);
 #ifdef DEBUG
   FILE* out = stdout;
   if (PresShell* presShell = GetPresShell(mDocShell)) {
     presShell->ListComputedStyles(out);
   } else {
--- a/layout/tools/layout-debug/ui/content/layoutdebug.xul
+++ b/layout/tools/layout-debug/ui/content/layoutdebug.xul
@@ -78,16 +78,17 @@
               accesskey="&ldb.DumpMenu.accesskey;">
           <menupopup>
             <menuitem id="menu_dumpWebShells" label="&ldb.dumpWebShells.label;" accesskey="&ldb.dumpWebShells.accesskey;" oncommand="gDebugger.dumpWebShells();" />
             <menuitem id="menu_dumpContent" label="&ldb.dumpContent.label;" accesskey="&ldb.dumpContent.accesskey;" oncommand="gDebugger.dumpContent();" />
             <menuitem id="menu_dumpFrames" label="&ldb.dumpFrames.label;" accesskey="&ldb.dumpFrames.accesskey;" oncommand="gDebugger.dumpFrames();" />
             <menuitem id="menu_dumpViews" label="&ldb.dumpViews.label;" accesskey="&ldb.dumpViews.accesskey;" oncommand="gDebugger.dumpViews();" />
             <menuseparator />
             <menuitem id="menu_dumpStyleSheets" label="&ldb.dumpStyleSheets.label;" accesskey="&ldb.dumpStyleSheets.accesskey;" oncommand="gDebugger.dumpStyleSheets();" />
+            <menuitem id="menu_dumpMatchedRules" label="&ldb.dumpMatchedRules.label;" accesskey="&ldb.dumpMatchedRules.accesskey;" oncommand="gDebugger.dumpMatchedRules();" />
             <menuitem id="menu_dumpComputedStyles" label="&ldb.dumpComputedStyles.label;" accesskey="&ldb.dumpComputedStyles.accesskey;" oncommand="gDebugger.dumpComputedStyles();" />
             <menuseparator />
             <menuitem id="menu_dumpReflowStats" label="&ldb.dumpReflowStats.label;" accesskey="&ldb.dumpReflowStats.accesskey;" oncommand="gDebugger.dumpReflowStats();" />
           </menupopup>
         </menu>
         <menu id="tasksMenu"/>
         <menu id="windowMenu"/>
         <menu id="menu_Help"/>
--- a/layout/tools/layout-debug/ui/locale/en-US/layoutdebug.dtd
+++ b/layout/tools/layout-debug/ui/locale/en-US/layoutdebug.dtd
@@ -65,12 +65,14 @@
 <!ENTITY ldb.dumpContent.label "Content">
 <!ENTITY ldb.dumpContent.accesskey "C">
 <!ENTITY ldb.dumpFrames.label "Frames">
 <!ENTITY ldb.dumpFrames.accesskey "F">
 <!ENTITY ldb.dumpViews.label "Views and Widgets">
 <!ENTITY ldb.dumpViews.accesskey "V">
 <!ENTITY ldb.dumpStyleSheets.label "Style Sheets">
 <!ENTITY ldb.dumpStyleSheets.accesskey "S">
+<!ENTITY ldb.dumpMatchedRules.label "Matched CSS Rules">
+<!ENTITY ldb.dumpMatchedRules.accesskey "M">
 <!ENTITY ldb.dumpComputedStyles.label "Style Contexts">
 <!ENTITY ldb.dumpComputedStyles.accesskey "x">
 <!ENTITY ldb.dumpReflowStats.label "Reflow Statistics">
 <!ENTITY ldb.dumpReflowStats.accesskey "R">