Bug 1207084 - keep sheet level on tokenstream for use in ruledata when resolving variables, to fix hcm issues with CSS variables, r=heycam, a=sylvestre
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Tue, 29 Sep 2015 09:21:12 -0400
changeset 291085 5c4b0ba07c6527114389d792d381e4b8084960df
parent 291084 c3751676de8a9fdf320db1a938998a0becfb0cd1
child 291086 1e432808c08581f5f179c9139f6a884fb25220e5
push id934
push userraliiev@mozilla.com
push dateMon, 26 Oct 2015 12:58:05 +0000
treeherdermozilla-release@05704e35c1d0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam, sylvestre
bugs1207084
milestone42.0
Bug 1207084 - keep sheet level on tokenstream for use in ruledata when resolving variables, to fix hcm issues with CSS variables, r=heycam, a=sylvestre
layout/style/nsCSSDataBlock.cpp
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
layout/style/nsRuleNode.cpp
--- a/layout/style/nsCSSDataBlock.cpp
+++ b/layout/style/nsCSSDataBlock.cpp
@@ -255,16 +255,25 @@ nsCSSCompressedDataBlock::MapRuleInfoInt
                 // the style context, since data cached in the rule tree could be
                 // used with a style context with a different value.
                 uint8_t wm = WritingMode(aRuleData->mStyleContext).GetBits();
                 aRuleData->mConditions.SetWritingModeDependency(wm);
             }
             nsCSSValue* target = aRuleData->ValueFor(iProp);
             if (target->GetUnit() == eCSSUnit_Null) {
                 const nsCSSValue *val = ValueAtIndex(i);
+                // In order for variable resolution to have the right information
+                // about the stylesheet level of a value, that level needs to be
+                // stored on the token stream. We can't do that at creation time
+                // because the CSS parser (which creates the object) has no idea
+                // about the stylesheet level, so we do it here instead, where
+                // the rule walking will have just updated aRuleData.
+                if (val->GetUnit() == eCSSUnit_TokenStream) {
+                  val->GetTokenStreamValue()->mLevel = aRuleData->mLevel;
+                }
                 MapSinglePropertyInto(iProp, val, target, aRuleData);
             }
         }
     }
 }
 
 const nsCSSValue*
 nsCSSCompressedDataBlock::ValueFor(nsCSSProperty aProperty) const
--- a/layout/style/nsCSSValue.cpp
+++ b/layout/style/nsCSSValue.cpp
@@ -18,16 +18,17 @@
 #include "imgRequestProxy.h"
 #include "nsIDocument.h"
 #include "nsIPrincipal.h"
 #include "nsCSSProps.h"
 #include "nsNetUtil.h"
 #include "nsPresContext.h"
 #include "nsStyleUtil.h"
 #include "nsDeviceContext.h"
+#include "nsStyleSet.h"
 
 using namespace mozilla;
 
 nsCSSValue::nsCSSValue(int32_t aValue, nsCSSUnit aUnit)
   : mUnit(aUnit)
 {
   MOZ_ASSERT(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
              aUnit == eCSSUnit_EnumColor,
@@ -2532,16 +2533,17 @@ nsCSSValueGradient::SizeOfIncludingThis(
   return n;
 }
 
 // --- nsCSSValueTokenStream ------------
 
 nsCSSValueTokenStream::nsCSSValueTokenStream()
   : mPropertyID(eCSSProperty_UNKNOWN)
   , mShorthandPropertyID(eCSSProperty_UNKNOWN)
+  , mLevel(nsStyleSet::eSheetTypeCount)
 {
   MOZ_COUNT_CTOR(nsCSSValueTokenStream);
 }
 
 nsCSSValueTokenStream::~nsCSSValueTokenStream()
 {
   MOZ_COUNT_DTOR(nsCSSValueTokenStream);
 }
--- a/layout/style/nsCSSValue.h
+++ b/layout/style/nsCSSValue.h
@@ -1488,16 +1488,17 @@ private:
 
 public:
   bool operator==(const nsCSSValueTokenStream& aOther) const
   {
     bool eq;
     return mPropertyID == aOther.mPropertyID &&
            mShorthandPropertyID == aOther.mShorthandPropertyID &&
            mTokenStream.Equals(aOther.mTokenStream) &&
+           mLevel == aOther.mLevel &&
            (mBaseURI == aOther.mBaseURI ||
             (mBaseURI && aOther.mBaseURI &&
              NS_SUCCEEDED(mBaseURI->Equals(aOther.mBaseURI, &eq)) &&
              eq)) &&
            (mSheetURI == aOther.mSheetURI ||
             (mSheetURI && aOther.mSheetURI &&
              NS_SUCCEEDED(mSheetURI->Equals(aOther.mSheetURI, &eq)) &&
              eq)) &&
@@ -1536,16 +1537,17 @@ public:
 
   nsCOMPtr<nsIURI> mBaseURI;
   nsCOMPtr<nsIURI> mSheetURI;
   nsCOMPtr<nsIPrincipal> mSheetPrincipal;
   // XXX Should store sheet here (see Bug 952338)
   // mozilla::CSSStyleSheet* mSheet;
   uint32_t mLineNumber;
   uint32_t mLineOffset;
+  uint16_t mLevel; // an nsStyleSet::sheetType
 
   // This table is used to hold a reference on to any ImageValue that results
   // from re-parsing this token stream at computed value time.  When properties
   // like background-image contain a normal url(), the Declaration's data block
   // will hold a reference to the ImageValue.  When a token stream is used,
   // the Declaration only holds on to this nsCSSValueTokenStream object, and
   // the ImageValue would only exist for the duration of
   // nsRuleNode::WalkRuleTree, in the AutoCSSValueArray.  So instead when
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -2172,16 +2172,22 @@ nsRuleNode::ResolveVariableReferences(co
     if (value->GetUnit() != eCSSUnit_TokenStream) {
       continue;
     }
 
     const CSSVariableValues* variables =
       &aContext->StyleVariables()->mVariables;
     nsCSSValueTokenStream* tokenStream = value->GetTokenStreamValue();
 
+    MOZ_ASSERT(tokenStream->mLevel != nsStyleSet::eSheetTypeCount,
+               "Token stream should have a defined level");
+
+    AutoRestore<uint16_t> saveLevel(aRuleData->mLevel);
+    aRuleData->mLevel = tokenStream->mLevel;
+
     // Note that ParsePropertyWithVariableReferences relies on the fact
     // that the nsCSSValue in aRuleData for the property we are re-parsing
     // is still the token stream value.  When
     // ParsePropertyWithVariableReferences calls
     // nsCSSExpandedDataBlock::MapRuleInfoInto, that function will add
     // the ImageValue that is created into the token stream object's
     // mImageValues table; see the comment above mImageValues for why.