Bug 1346256 Part 3: Modify GetCSSStyleRules to collect ServoStyleRules. draft
authorBrad Werth <bwerth@mozilla.com>
Fri, 07 Apr 2017 15:21:36 -0700
changeset 559518 b54ea57f2786c953bbcf1cab41aa823ef6f44adf
parent 559517 1e1145bb4ee21a6d4564ace4930eb97bba86a291
child 623417 9ab6545407d6a2788c5f357406fd55ce452cacc7
push id53118
push userbwerth@mozilla.com
push dateMon, 10 Apr 2017 08:18:55 +0000
bugs1346256
milestone55.0a1
Bug 1346256 Part 3: Modify GetCSSStyleRules to collect ServoStyleRules. MozReview-Commit-ID: IMQLykuXjfL
layout/inspector/inDOMUtils.cpp
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -47,16 +47,19 @@
 #include "nsCSSParser.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 #include "nsColor.h"
 #include "mozilla/StyleSetHandle.h"
 #include "mozilla/StyleSetHandleInlines.h"
 #include "nsStyleUtil.h"
 #include "nsQueryObject.h"
+#include "mozilla/ServoBindings.h"
+#include "mozilla/ServoCSSRuleList.h"
+#include "mozilla/ServoStyleRule.h"
 
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
 
 ///////////////////////////////////////////////////////////////////////////////
 
 inDOMUtils::inDOMUtils()
@@ -238,39 +241,79 @@ inDOMUtils::GetCSSStyleRules(nsIDOMEleme
     GetCleanStyleContextForElement(element, pseudoElt);
   if (!styleContext) {
     // This can fail for elements that are not in the document or
     // if the document they're in doesn't have a presshell.  Bail out.
     return NS_OK;
   }
 
   NonOwningStyleContextSource source = styleContext->StyleSource();
-  if (!source.IsNull() && source.IsGeckoRuleNodeOrNull()) {
+  if (source.IsNull()) {
+    return NS_OK;
+  }
+
+  nsCOMPtr<nsIMutableArray> rules = nsArray::Create();
+  if (source.IsGeckoRuleNodeOrNull()) {
     nsRuleNode* ruleNode = source.AsGeckoRuleNode();
 
     AutoTArray<nsRuleNode*, 16> ruleNodes;
     while (!ruleNode->IsRoot()) {
       ruleNodes.AppendElement(ruleNode);
       ruleNode = ruleNode->GetParent();
     }
 
-    nsCOMPtr<nsIMutableArray> rules = nsArray::Create();
     for (nsRuleNode* ruleNode : Reversed(ruleNodes)) {
       RefPtr<Declaration> decl = do_QueryObject(ruleNode->GetRule());
       if (decl) {
         css::Rule* owningRule = decl->GetOwningRule();
         if (owningRule) {
           rules->AppendElement(owningRule, /*weak =*/ false);
         }
       }
     }
+  } else {
+    // It's a Servo source, so use some servo methods on the element to get
+    // the rule list.
+    nsTArray<const RawServoStyleRule*> rawRuleList;
+    Servo_Element_GetStyleRuleList(element, &rawRuleList);
+    size_t rawRuleCount = rawRuleList.Length();
 
-    rules.forget(_retval);
+    // We have RawServoStyleRules, and now we'll map them to ServoStyleRules
+    // by looking them up in the ServoStyleSheets owned by this document.
+    ServoCSSRuleList::StyleRuleHashtable rawRulesToRules;
+
+    nsIDocument* document = element->GetOwnerDocument();
+    int32_t sheetCount = document->GetNumberOfStyleSheets();
+
+    for (int32_t i = 0; i < sheetCount; i++) {
+      StyleSheet* sheet = document->GetStyleSheetAt(i);
+      MOZ_ASSERT(sheet->IsServo());
+
+      ErrorResult ignored;
+      ServoCSSRuleList* ruleList = static_cast<ServoCSSRuleList*>(
+        sheet->GetCssRules(*nsContentUtils::SubjectPrincipal(), ignored));
+      if (ruleList) {
+        // Generate the map from raw rules to rules.
+        ruleList->FillStyleRuleHashtable(rawRulesToRules);
+      }
+    }
+
+    // Find matching rules in the table.
+    for (size_t j = 0; j < rawRuleCount; j++) {
+      const RawServoStyleRule* rawRule = rawRuleList.ElementAt(j);
+      ServoStyleRule* rule;
+      rawRulesToRules.Get(rawRule, &rule);
+      MOZ_ASSERT(rule, "We should always be able to map a raw rule to a rule.");
+      RefPtr<css::Rule> ruleObj(rule);
+      rules->AppendElement(ruleObj, false);
+    }
   }
 
+  rules.forget(_retval);
+
   return NS_OK;
 }
 
 static already_AddRefed<StyleRule>
 GetRuleFromDOMRule(nsIDOMCSSStyleRule *aRule, ErrorResult& rv)
 {
   nsCOMPtr<nsICSSStyleRuleDOMWrapper> rule = do_QueryInterface(aRule);
   if (!rule) {