Bug 1418867 - getUnanimatedComputedStyle throws an exception for non-existent pseudo element. r?birtles draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Wed, 22 Nov 2017 09:57:31 +0900
changeset 701684 c9ad8a02b9e28baf321c3a707a1c9d7479a3914d
parent 701683 c08a7543af12b6420b78a19e58cc197dcf2d7224
child 701685 6661b4e81ec5f7e093c73b6fdd4f34dee92f9eb3
push id90239
push userhikezoe@mozilla.com
push dateWed, 22 Nov 2017 04:18:13 +0000
reviewersbirtles
bugs1418867
milestone59.0a1
Bug 1418867 - getUnanimatedComputedStyle throws an exception for non-existent pseudo element. r?birtles This is a prerequisite change for passing pseudo element to Servo_StyleSet_GetBaseComputedValuesForElement which will be done in the next commit. MozReview-Commit-ID: HEGF2wjBGEP
dom/base/nsDOMWindowUtils.cpp
dom/base/test/file_domwindowutils_animation.html
layout/style/nsComputedDOMStyle.cpp
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3003,16 +3003,19 @@ nsDOMWindowUtils::GetUnanimatedComputedS
   if (!shell) {
     return NS_ERROR_FAILURE;
   }
 
   RefPtr<nsAtom> pseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElement);
   RefPtr<nsStyleContext> styleContext =
     nsComputedDOMStyle::GetUnanimatedStyleContextNoFlush(element,
                                                          pseudo, shell);
+  if (!styleContext) {
+    return NS_ERROR_FAILURE;
+  }
 
   if (styleContext->IsServo()) {
     RefPtr<RawServoAnimationValue> value =
       Servo_ComputedValues_ExtractAnimationValue(styleContext->AsServo(),
                                                  propertyID).Consume();
     if (!value) {
       return NS_ERROR_FAILURE;
     }
--- a/dom/base/test/file_domwindowutils_animation.html
+++ b/dom/base/test/file_domwindowutils_animation.html
@@ -122,16 +122,21 @@ function test_getUnanimatedComputedStyle
     "FLUSH_LAYOUT option should throw");
 
   SimpleTest.doesThrow(
     () => utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_DISPLAY),
     "NS_ERROR_INVALID_ARG",
     "FLUSH_DISPLAY option should throw");
 
   if (utils.isStyledByServo) {
+    SimpleTest.doesThrow(
+      () => utils.getUnanimatedComputedStyle(div, "::before", "opacity", utils.FLUSH_NONE),
+      "NS_ERROR_FAILURE",
+      "Non-existent pseudo should throw");
+
     // Flush styles since getUnanimatedComputedStyle flushes pending styles even
     // with FLUSH_NONE option if the element hasn't yet styled.
     getComputedStyle(div).opacity;
 
     div.style.opacity = "0";
     is(utils.getUnanimatedComputedStyle(div, null, "opacity", utils.FLUSH_NONE),
        "1",
        "getUnanimatedComputedStyle with FLUSH_NONE should not flush pending styles");
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -738,16 +738,21 @@ nsComputedDOMStyle::DoGetStyleContextNoF
           nsPresContext* presContext = presShell->GetPresContext();
           MOZ_ASSERT(presContext, "Should have a prescontext if we have a frame");
           if (presContext && presContext->StyleSet()->IsGecko()) {
             nsStyleSet* styleSet = presContext->StyleSet()->AsGecko();
             return styleSet->ResolveStyleByRemovingAnimation(
                      aElement, result->AsGecko(),
                      eRestyle_AllHintsWithAnimations);
           } else {
+            Element* elementOrPseudoElement =
+              EffectCompositor::GetElementToRestyle(aElement, pseudoType);
+            if (!elementOrPseudoElement) {
+              return nullptr;
+            }
             return presContext->StyleSet()->AsServo()->
               GetBaseContextForElement(aElement, presContext,
                                        pseudoType, result->AsServo());
           }
         }
 
         // this function returns an addrefed style context
         RefPtr<nsStyleContext> ret = result;
@@ -772,16 +777,21 @@ nsComputedDOMStyle::DoGetStyleContextNoF
                                ? StyleRuleInclusion::DefaultOnly
                                : StyleRuleInclusion::All;
     RefPtr<ServoStyleContext> result =
        servoSet->ResolveStyleLazily(aElement, pseudoType, rules);
     if (aAnimationFlag == eWithAnimation) {
       return result.forget();
     }
 
+    Element* elementOrPseudoElement =
+      EffectCompositor::GetElementToRestyle(aElement, pseudoType);
+    if (!elementOrPseudoElement) {
+      return nullptr;
+    }
     return servoSet->GetBaseContextForElement(aElement, presContext,
                                               pseudoType, result);
   }
 
   RefPtr<GeckoStyleContext> parentContext;
   nsIContent* parent = aPseudo ? aElement : aElement->GetParent();
   // Don't resolve parent context for document fragments.
   if (parent && parent->IsElement()) {