Bug 1346256 Part 3: Modify GetCSSStyleRules to collect ServoStyleRules. draft
authorBrad Werth <bwerth@mozilla.com>
Wed, 05 Apr 2017 15:45:06 -0700
changeset 556477 f780f05dc4489db79d7dfb2062163136f8748fb9
parent 556476 0f8b7b1a6534ea66ce85de57dfa1c7e29c752d7b
child 622899 55ce6fe083b81bdf2cd0de186570245fb451f8c1
push id52559
push userbwerth@mozilla.com
push dateWed, 05 Apr 2017 22:55:45 +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
@@ -238,39 +238,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.
+    StyleRuleHashtable rawRulesToRules;
+
+    nsIDocument* document = element->GetOwnerDocument();
+    int32_t sheetCount = document->GetNumberOfStyleSheets();
+
+    for (int32_t i = 0; i < sheetCount; i++) {
+      StyleSheet* sheet = document->GetStyleSheetAt(i);
+      if (sheet->IsServo()) {
+        ErrorResult ignored;
+        ServoCSSRuleList* ruleList = (ServoCSSRuleList*)(
+          sheet->AsServo()->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.GetWeak(rawRule);
+      if (rule) {
+        rules->AppendElement(rule, false);
+      }
+    }
   }
 
+  rules.forget(_retval);
+
   return NS_OK;
 }
 
 static already_AddRefed<StyleRule>
 GetRuleFromDOMRule(nsIDOMCSSStyleRule *aRule, ErrorResult& rv)
 {
   nsCOMPtr<nsICSSStyleRuleDOMWrapper> rule = do_QueryInterface(aRule);
   if (!rule) {