Bug 591303 - Part 3: Set line and column number for all rules in nsCSSParser. r=bz
authorGabriel Luong <gabriel.luong@gmail.com>
Mon, 14 Jul 2014 15:57:54 -0700
changeset 215867 8acc3d0aa7108642b0d1230072acc68f8221c673
parent 215866 785257a95e363df9238b4ffc7fdc78eabe1b2369
child 215868 6b8e30b71a4ec220b8678fd61bfd8467b2d61eb4
push idunknown
push userunknown
push dateunknown
reviewersbz
bugs591303
milestone33.0a1
Bug 591303 - Part 3: Set line and column number for all rules in nsCSSParser. r=bz
content/svg/content/src/nsSVGElement.cpp
layout/style/GroupRule.h
layout/style/ImportRule.h
layout/style/NameSpaceRule.h
layout/style/Rule.h
layout/style/StyleAnimationValue.cpp
layout/style/StyleRule.h
layout/style/nsCSSParser.cpp
layout/style/nsCSSRules.cpp
layout/style/nsCSSRules.h
layout/style/nsDOMCSSAttrDeclaration.cpp
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1208,17 +1208,17 @@ MappedAttrParser::ParseMappedAttrValue(n
 
 already_AddRefed<css::StyleRule>
 MappedAttrParser::CreateStyleRule()
 {
   if (!mDecl) {
     return nullptr; // No mapped attributes were parsed
   }
 
-  nsRefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, mDecl);
+  nsRefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, mDecl, 0, 0);
   mDecl = nullptr; // We no longer own the declaration -- drop our pointer to it
   return rule.forget();
 }
 
 } // anonymous namespace
 
 //----------------------------------------------------------------------
 // Implementation Helpers:
--- a/layout/style/GroupRule.h
+++ b/layout/style/GroupRule.h
@@ -29,17 +29,17 @@ namespace css {
 
 class GroupRuleRuleList;
 
 // inherits from Rule so it can be shared between
 // MediaRule and DocumentRule
 class GroupRule : public Rule
 {
 protected:
-  GroupRule();
+  GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber);
   GroupRule(const GroupRule& aCopy);
   virtual ~GroupRule();
 public:
 
   NS_DECL_CYCLE_COLLECTION_CLASS(GroupRule)
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   // implement part of nsIStyleRule and Rule
--- a/layout/style/ImportRule.h
+++ b/layout/style/ImportRule.h
@@ -22,17 +22,18 @@ namespace mozilla {
 class CSSStyleSheet;
 
 namespace css {
 
 class ImportRule MOZ_FINAL : public Rule,
                              public nsIDOMCSSImportRule
 {
 public:
-  ImportRule(nsMediaList* aMedia, const nsString& aURLSpec);
+  ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
+             uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // for |Clone|
   ImportRule(const ImportRule& aCopy);
   ~ImportRule();
 public:
   NS_DECL_ISUPPORTS
 
   DECL_STYLE_RULE_INHERIT
--- a/layout/style/NameSpaceRule.h
+++ b/layout/style/NameSpaceRule.h
@@ -23,17 +23,18 @@ class nsIAtom;
 
 namespace mozilla {
 namespace css {
 
 class NameSpaceRule MOZ_FINAL : public Rule,
                                 public nsIDOMCSSRule
 {
 public:
-  NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec);
+  NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec,
+                uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // for |Clone|
   NameSpaceRule(const NameSpaceRule& aCopy);
   ~NameSpaceRule();
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_NAMESPACE_RULE_IMPL_CID)
 
   NS_DECL_ISUPPORTS
--- a/layout/style/Rule.h
+++ b/layout/style/Rule.h
@@ -28,17 +28,17 @@ virtual void MapRuleInfoInto(nsRuleData*
 
 #define DECL_STYLE_RULE_INHERIT                   \
   DECL_STYLE_RULE_INHERIT_NO_DOMRULE              \
   virtual nsIDOMCSSRule* GetDOMRule();            \
   virtual nsIDOMCSSRule* GetExistingDOMRule();
 
 class Rule : public nsIStyleRule {
 protected:
-  Rule(uint32_t aLineNumber = 0, uint32_t aColumnNumber = 0)
+  Rule(uint32_t aLineNumber, uint32_t aColumnNumber)
     : mSheet(0),
       mParentRule(nullptr),
       mLineNumber(aLineNumber),
       mColumnNumber(aColumnNumber),
       mWasMatched(false)
   {
   }
 
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -2457,17 +2457,19 @@ BuildStyleRule(nsCSSProperty aProperty,
                                      declaration, &changed, false,
                                      aUseSVGMode)) ||
       // check whether property parsed without CSS parsing errors
       !declaration->HasNonImportantValueFor(propertyToCheck)) {
     NS_WARNING("failure in BuildStyleRule");
     return nullptr;
   }
 
-  nsRefPtr<css::StyleRule> rule = new css::StyleRule(nullptr, declaration.forget());
+  nsRefPtr<css::StyleRule> rule = new css::StyleRule(nullptr,
+                                                     declaration.forget(),
+                                                     0, 0);
   return rule.forget();
 }
 
 inline
 already_AddRefed<nsStyleContext>
 LookupStyleContext(dom::Element* aElement)
 {
   nsIDocument* doc = aElement->GetCurrentDoc();
--- a/layout/style/StyleRule.h
+++ b/layout/style/StyleRule.h
@@ -298,17 +298,17 @@ protected:
   friend class StyleRule;
 };
 
 class StyleRule MOZ_FINAL : public Rule
 {
  public:
   StyleRule(nsCSSSelectorList* aSelector,
             Declaration *aDeclaration,
-            uint32_t aLineNumber = 0, uint32_t aColumnNumber = 0);
+            uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // for |Clone|
   StyleRule(const StyleRule& aCopy);
   // for |DeclarationChanged|
   StyleRule(StyleRule& aCopy,
             Declaration *aDeclaration);
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_CSS_STYLE_RULE_IMPL_CID)
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -459,25 +459,28 @@ protected:
                          // expression" as two.
                          eMediaQuerySingleCondition };
   bool ParseMediaQuery(eMediaQueryType aMode, nsMediaQuery **aQuery,
                        bool *aHitStop);
   bool ParseMediaQueryExpression(nsMediaQuery* aQuery);
   void ProcessImport(const nsString& aURLSpec,
                      nsMediaList* aMedia,
                      RuleAppendFunc aAppendFunc,
-                     void* aProcessData);
+                     void* aProcessData,
+                     uint32_t aLineNumber,
+                     uint32_t aColumnNumber);
   bool ParseGroupRule(css::GroupRule* aRule, RuleAppendFunc aAppendFunc,
                       void* aProcessData);
   bool ParseMediaRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   bool ParseMozDocumentRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   bool ParseNameSpaceRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   void ProcessNameSpace(const nsString& aPrefix,
                         const nsString& aURLSpec, RuleAppendFunc aAppendFunc,
-                        void* aProcessData);
+                        void* aProcessData,
+                        uint32_t aLineNumber, uint32_t aColumnNumber);
 
   bool ParseFontFaceRule(RuleAppendFunc aAppendFunc, void* aProcessData);
   bool ParseFontFeatureValuesRule(RuleAppendFunc aAppendFunc,
                                   void* aProcessData);
   bool ParseFontFeatureValueSet(nsCSSFontFeatureValuesRule *aRule);
   bool ParseFontDescriptor(nsCSSFontFaceRule* aRule);
   bool ParseFontDescriptorValue(nsCSSFontDesc aDescID,
                                 nsCSSValue& aValue);
@@ -1324,17 +1327,17 @@ CSSParserImpl::ParseStyleAttribute(const
 
   mSection = eCSSSection_General;
 
   uint32_t parseFlags = eParseDeclaration_AllowImportant;
 
   css::Declaration* declaration = ParseDeclarationBlock(parseFlags);
   if (declaration) {
     // Create a style rule for the declaration
-    NS_ADDREF(*aResult = new css::StyleRule(nullptr, declaration));
+    NS_ADDREF(*aResult = new css::StyleRule(nullptr, declaration, 0, 0));
   } else {
     *aResult = nullptr;
   }
 
   ReleaseScanner();
 
   // XXX check for low level errors
   return NS_OK;
@@ -2789,34 +2792,37 @@ CSSParserImpl::ParseAtRule(RuleAppendFun
   
   return true;
 }
 
 bool
 CSSParserImpl::ParseCharsetRule(RuleAppendFunc aAppendFunc,
                                 void* aData)
 {
-  if (!GetToken(true)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !GetToken(true)) {
     REPORT_UNEXPECTED_EOF(PECharsetRuleEOF);
     return false;
   }
 
   if (eCSSToken_String != mToken.mType) {
     UngetToken();
     REPORT_UNEXPECTED_TOKEN(PECharsetRuleNotString);
     return false;
   }
 
   nsAutoString charset = mToken.mIdent;
 
   if (!ExpectSymbol(';', true)) {
     return false;
   }
 
-  nsRefPtr<css::CharsetRule> rule = new css::CharsetRule(charset);
+  nsRefPtr<css::CharsetRule> rule = new css::CharsetRule(charset,
+                                                         linenum, colnum);
   (*aAppendFunc)(rule, aData);
 
   return true;
 }
 
 bool
 CSSParserImpl::ParseURLOrString(nsString& aURL)
 {
@@ -3151,18 +3157,20 @@ CSSParserImpl::ParseMediaQueryExpression
 }
 
 // Parse a CSS2 import rule: "@import STRING | URL [medium [, medium]]"
 bool
 CSSParserImpl::ParseImportRule(RuleAppendFunc aAppendFunc, void* aData)
 {
   nsRefPtr<nsMediaList> media = new nsMediaList();
 
+  uint32_t linenum, colnum;
   nsAutoString url;
-  if (!ParseURLOrString(url)) {
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !ParseURLOrString(url)) {
     REPORT_UNEXPECTED_TOKEN(PEImportNotURI);
     return false;
   }
 
   if (!ExpectSymbol(';', true)) {
     if (!GatherMedia(media, true) ||
         !ExpectSymbol(';', true)) {
       REPORT_UNEXPECTED_TOKEN(PEImportUnexpected);
@@ -3170,28 +3178,31 @@ CSSParserImpl::ParseImportRule(RuleAppen
       return false;
     }
 
     // Safe to assert this, since we ensured that there is something
     // other than the ';' coming after the @import's url() token.
     NS_ASSERTION(media->Length() != 0, "media list must be nonempty");
   }
 
-  ProcessImport(url, media, aAppendFunc, aData);
-  return true;
-}
-
+  ProcessImport(url, media, aAppendFunc, aData, linenum, colnum);
+  return true;
+}
 
 void
 CSSParserImpl::ProcessImport(const nsString& aURLSpec,
                              nsMediaList* aMedia,
                              RuleAppendFunc aAppendFunc,
-                             void* aData)
-{
-  nsRefPtr<css::ImportRule> rule = new css::ImportRule(aMedia, aURLSpec);
+                             void* aData,
+                             uint32_t aLineNumber,
+                             uint32_t aColumnNumber)
+{
+  nsRefPtr<css::ImportRule> rule = new css::ImportRule(aMedia, aURLSpec,
+                                                       aLineNumber,
+                                                       aColumnNumber);
   (*aAppendFunc)(rule, aData);
 
   // Diagnose bad URIs even if we don't have a child loader.
   nsCOMPtr<nsIURI> url;
   // Charset will be deduced from mBaseURI, which is more or less correct.
   nsresult rv = NS_NewURI(getter_AddRefs(url), aURLSpec, nullptr, mBaseURI);
 
   if (NS_FAILED(rv)) {
@@ -3252,20 +3263,21 @@ CSSParserImpl::ParseGroupRule(css::Group
   return true;
 }
 
 // Parse a CSS2 media rule: "@media medium [, medium] { ... }"
 bool
 CSSParserImpl::ParseMediaRule(RuleAppendFunc aAppendFunc, void* aData)
 {
   nsRefPtr<nsMediaList> media = new nsMediaList();
-
-  if (GatherMedia(media, true)) {
+  uint32_t linenum, colnum;
+  if (GetNextTokenLocation(true, &linenum, &colnum) &&
+      GatherMedia(media, true)) {
     // XXXbz this could use better error reporting throughout the method
-    nsRefPtr<css::MediaRule> rule = new css::MediaRule();
+    nsRefPtr<css::MediaRule> rule = new css::MediaRule(linenum, colnum);
     // Append first, so when we do SetMedia() the rule
     // knows what its stylesheet is.
     if (ParseGroupRule(rule, aAppendFunc, aData)) {
       rule->SetMedia(media);
       return true;
     }
   }
 
@@ -3275,16 +3287,22 @@ CSSParserImpl::ParseMediaRule(RuleAppend
 // Parse a @-moz-document rule.  This is like an @media rule, but instead
 // of a medium it has a nonempty list of items where each item is either
 // url(), url-prefix(), or domain().
 bool
 CSSParserImpl::ParseMozDocumentRule(RuleAppendFunc aAppendFunc, void* aData)
 {
   css::DocumentRule::URL *urls = nullptr;
   css::DocumentRule::URL **next = &urls;
+
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum)) {
+    return false;
+  }
+
   do {
     if (!GetToken(true)) {
       REPORT_UNEXPECTED_EOF(PEMozDocRuleEOF);
       delete urls;
       return false;
     }
         
     if (!(eCSSToken_URL == mToken.mType ||
@@ -3334,27 +3352,29 @@ CSSParserImpl::ParseMozDocumentRule(Rule
 
       // We could try to make the URL (as long as it's not domain())
       // canonical and absolute with NS_NewURI and GetSpec, but I'm
       // inclined to think we shouldn't.
       CopyUTF16toUTF8(mToken.mIdent, cur->url);
     }
   } while (ExpectSymbol(',', true));
 
-  nsRefPtr<css::DocumentRule> rule = new css::DocumentRule();
+  nsRefPtr<css::DocumentRule> rule = new css::DocumentRule(linenum, colnum);
   rule->SetURLs(urls);
 
   return ParseGroupRule(rule, aAppendFunc, aData);
 }
 
 // Parse a CSS3 namespace rule: "@namespace [prefix] STRING | URL;"
 bool
 CSSParserImpl::ParseNameSpaceRule(RuleAppendFunc aAppendFunc, void* aData)
 {
-  if (!GetToken(true)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !GetToken(true)) {
     REPORT_UNEXPECTED_EOF(PEAtNSPrefixEOF);
     return false;
   }
 
   nsAutoString  prefix;
   nsAutoString  url;
 
   if (eCSSToken_Ident == mToken.mType) {
@@ -3368,56 +3388,62 @@ CSSParserImpl::ParseNameSpaceRule(RuleAp
     if (mHavePushBack) {
       REPORT_UNEXPECTED_TOKEN(PEAtNSUnexpected);
     } else {
       REPORT_UNEXPECTED_EOF(PEAtNSURIEOF);
     }
     return false;
   }
 
-  ProcessNameSpace(prefix, url, aAppendFunc, aData);
+  ProcessNameSpace(prefix, url, aAppendFunc, aData, linenum, colnum);
   return true;
 }
 
 void
 CSSParserImpl::ProcessNameSpace(const nsString& aPrefix,
                                 const nsString& aURLSpec,
                                 RuleAppendFunc aAppendFunc,
-                                void* aData)
+                                void* aData,
+                                uint32_t aLineNumber,
+                                uint32_t aColumnNumber)
 {
   nsCOMPtr<nsIAtom> prefix;
 
   if (!aPrefix.IsEmpty()) {
     prefix = do_GetAtom(aPrefix);
     if (!prefix) {
       NS_RUNTIMEABORT("do_GetAtom failed - out of memory?");
     }
   }
 
-  nsRefPtr<css::NameSpaceRule> rule = new css::NameSpaceRule(prefix, aURLSpec);
+  nsRefPtr<css::NameSpaceRule> rule = new css::NameSpaceRule(prefix, aURLSpec,
+                                                             aLineNumber,
+                                                             aColumnNumber);
   (*aAppendFunc)(rule, aData);
 
   // If this was the first namespace rule encountered, it will trigger
   // creation of a namespace map.
   if (!mNameSpaceMap) {
     mNameSpaceMap = mSheet->GetNameSpaceMap();
   }
 }
 
 // font-face-rule: '@font-face' '{' font-description '}'
 // font-description: font-descriptor+
 bool
 CSSParserImpl::ParseFontFaceRule(RuleAppendFunc aAppendFunc, void* aData)
 {
-  if (!ExpectSymbol('{', true)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !ExpectSymbol('{', true)) {
     REPORT_UNEXPECTED_TOKEN(PEBadFontBlockStart);
     return false;
   }
 
-  nsRefPtr<nsCSSFontFaceRule> rule(new nsCSSFontFaceRule());
+  nsRefPtr<nsCSSFontFaceRule> rule(new nsCSSFontFaceRule(linenum, colnum));
 
   for (;;) {
     if (!GetToken(true)) {
       REPORT_UNEXPECTED_EOF(PEFontFaceEOF);
       break;
     }
     if (mToken.IsSymbol('}')) { // done!
       UngetToken();
@@ -3504,18 +3530,23 @@ CSSParserImpl::ParseFontDescriptor(nsCSS
 //   }
 //   ...
 // }
 
 bool
 CSSParserImpl::ParseFontFeatureValuesRule(RuleAppendFunc aAppendFunc,
                                           void* aData)
 {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum)) {
+    return false;
+  }
+
   nsRefPtr<nsCSSFontFeatureValuesRule>
-               valuesRule(new nsCSSFontFeatureValuesRule());
+               valuesRule(new nsCSSFontFeatureValuesRule(linenum, colnum));
 
   // parse family list
   nsCSSValue fontlistValue;
 
   if (!ParseFamily(fontlistValue) ||
       fontlistValue.GetUnit() != eCSSUnit_FontFamilyList)
   {
     REPORT_UNEXPECTED_TOKEN(PEFFVNoFamily);
@@ -3721,34 +3752,37 @@ CSSParserImpl::ParseFontFeatureValueSet(
 
   aFeatureValuesRule->AddValueList(whichVariant, values);
   return true;
 }
 
 bool
 CSSParserImpl::ParseKeyframesRule(RuleAppendFunc aAppendFunc, void* aData)
 {
-  if (!GetToken(true)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !GetToken(true)) {
     REPORT_UNEXPECTED_EOF(PEKeyframeNameEOF);
     return false;
   }
 
   if (mToken.mType != eCSSToken_Ident) {
     REPORT_UNEXPECTED_TOKEN(PEKeyframeBadName);
     UngetToken();
     return false;
   }
   nsString name(mToken.mIdent);
 
   if (!ExpectSymbol('{', true)) {
     REPORT_UNEXPECTED_TOKEN(PEKeyframeBrace);
     return false;
   }
 
-  nsRefPtr<nsCSSKeyframesRule> rule = new nsCSSKeyframesRule(name);
+  nsRefPtr<nsCSSKeyframesRule> rule = new nsCSSKeyframesRule(name,
+                                                             linenum, colnum);
 
   while (!ExpectSymbol('}', true)) {
     nsRefPtr<nsCSSKeyframeRule> kid = ParseKeyframeRule();
     if (kid) {
       rule->AppendStyleRule(kid);
     } else {
       OUTPUT_ERROR();
       SkipRuleSet(true);
@@ -3757,16 +3791,21 @@ CSSParserImpl::ParseKeyframesRule(RuleAp
 
   (*aAppendFunc)(rule, aData);
   return true;
 }
 
 bool
 CSSParserImpl::ParsePageRule(RuleAppendFunc aAppendFunc, void* aData)
 {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum)) {
+    return false;
+  }
+
   // TODO: There can be page selectors after @page such as ":first", ":left".
   uint32_t parseFlags = eParseDeclaration_InBraces |
                         eParseDeclaration_AllowImportant;
 
   // Forbid viewport units in @page rules. See bug 811391.
   NS_ABORT_IF_FALSE(mViewportUnitsEnabled,
                     "Viewport units should be enabled outside of @page rules.");
   mViewportUnitsEnabled = false;
@@ -3775,42 +3814,44 @@ CSSParserImpl::ParsePageRule(RuleAppendF
                                                       eCSSContext_Page));
   mViewportUnitsEnabled = true;
 
   if (!declaration) {
     return false;
   }
 
   // Takes ownership of declaration.
-  nsRefPtr<nsCSSPageRule> rule = new nsCSSPageRule(Move(declaration));
+  nsRefPtr<nsCSSPageRule> rule = new nsCSSPageRule(Move(declaration),
+                                                   linenum, colnum);
 
   (*aAppendFunc)(rule, aData);
   return true;
 }
 
 already_AddRefed<nsCSSKeyframeRule>
 CSSParserImpl::ParseKeyframeRule()
 {
   InfallibleTArray<float> selectorList;
-  if (!ParseKeyframeSelectorList(selectorList)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !ParseKeyframeSelectorList(selectorList)) {
     REPORT_UNEXPECTED(PEBadSelectorKeyframeRuleIgnored);
     return nullptr;
   }
 
   // Ignore !important in keyframe rules
   uint32_t parseFlags = eParseDeclaration_InBraces;
   nsAutoPtr<css::Declaration> declaration(ParseDeclarationBlock(parseFlags));
   if (!declaration) {
     return nullptr;
   }
 
   // Takes ownership of declaration, and steals contents of selectorList.
   nsRefPtr<nsCSSKeyframeRule> rule =
-    new nsCSSKeyframeRule(selectorList, Move(declaration));
-
+    new nsCSSKeyframeRule(selectorList, Move(declaration), linenum, colnum);
   return rule.forget();
 }
 
 bool
 CSSParserImpl::ParseKeyframeSelectorList(InfallibleTArray<float>& aSelectorList)
 {
   for (;;) {
     if (!GetToken(true)) {
@@ -3851,16 +3892,22 @@ CSSParserImpl::ParseKeyframeSelectorList
 //   ;
 bool
 CSSParserImpl::ParseSupportsRule(RuleAppendFunc aAppendFunc, void* aProcessData)
 {
   bool conditionMet = false;
   nsString condition;
 
   mScanner->StartRecording();
+
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum)) {
+    return false;
+  }
+
   bool parsed = ParseSupportsCondition(conditionMet);
 
   if (!parsed) {
     mScanner->StopRecording();
     return false;
   }
 
   if (!ExpectSymbol('{', true)) {
@@ -3879,17 +3926,18 @@ CSSParserImpl::ParseSupportsRule(RuleApp
 
   // Remove spaces from the start and end of the recorded supports condition.
   condition.Trim(" ", true, true, false);
 
   // Record whether we are in a failing @supports, so that property parse
   // errors don't get reported.
   nsAutoFailingSupportsRule failing(this, conditionMet);
 
-  nsRefPtr<css::GroupRule> rule = new CSSSupportsRule(conditionMet, condition);
+  nsRefPtr<css::GroupRule> rule = new CSSSupportsRule(conditionMet, condition,
+                                                      linenum, colnum);
   return ParseGroupRule(rule, aAppendFunc, aProcessData);
 }
 
 // supports_condition
 //   : supports_condition_in_parens supports_condition_terms
 //   | supports_condition_negation
 //   ;
 bool
@@ -4141,27 +4189,31 @@ CSSParserImpl::ParseSupportsConditionTer
     }
   }
 }
 
 bool
 CSSParserImpl::ParseCounterStyleRule(RuleAppendFunc aAppendFunc, void* aData)
 {
   nsAutoString name;
-  if (!ParseCounterStyleName(name, true)) {
+  uint32_t linenum, colnum;
+  if (!GetNextTokenLocation(true, &linenum, &colnum) ||
+      !ParseCounterStyleName(name, true)) {
     REPORT_UNEXPECTED_TOKEN(PECounterStyleNotIdent);
     return false;
   }
 
   if (!ExpectSymbol('{', true)) {
     REPORT_UNEXPECTED_TOKEN(PECounterStyleBadBlockStart);
     return false;
   }
 
-  nsRefPtr<nsCSSCounterStyleRule> rule = new nsCSSCounterStyleRule(name);
+  nsRefPtr<nsCSSCounterStyleRule> rule = new nsCSSCounterStyleRule(name,
+                                                                   linenum,
+                                                                   colnum);
   for (;;) {
     if (!GetToken(true)) {
       REPORT_UNEXPECTED_EOF(PECounterStyleEOF);
       break;
     }
     if (mToken.IsSymbol('}')) {
       break;
     }
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -211,18 +211,19 @@ GroupRuleRuleList::IndexedGetter(uint32_
 //
 
 // Must be outside namespace
 DOMCI_DATA(CSSCharsetRule, css::CharsetRule)
 
 namespace mozilla {
 namespace css {
 
-CharsetRule::CharsetRule(const nsAString& aEncoding)
-  : Rule(),
+CharsetRule::CharsetRule(const nsAString& aEncoding,
+                         uint32_t aLineNumber, uint32_t aColumnNumber)
+  : Rule(aLineNumber, aColumnNumber),
     mEncoding(aEncoding)
 {
 }
 
 CharsetRule::CharsetRule(const CharsetRule& aCopy)
   : Rule(aCopy),
     mEncoding(aCopy.mEncoding)
 {
@@ -331,18 +332,19 @@ CharsetRule::SizeOfIncludingThis(MallocS
   // worthwhile:
   // - mEncoding
 }
 
 // -------------------------------------------
 // ImportRule
 //
 
-ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec)
-  : Rule()
+ImportRule::ImportRule(nsMediaList* aMedia, const nsString& aURLSpec,
+                       uint32_t aLineNumber, uint32_t aColumnNumber)
+  : Rule(aLineNumber, aColumnNumber)
   , mURLSpec(aURLSpec)
   , mMedia(aMedia)
 {
   // XXXbz This is really silly.... the mMedia here will be replaced
   // with itself if we manage to load a sheet.  Which should really
   // never fail nowadays, in sane cases.
 }
 
@@ -519,18 +521,18 @@ ImportRule::SizeOfIncludingThis(MallocSi
 } // namespace mozilla
 
 // must be outside the namespace
 DOMCI_DATA(CSSImportRule, css::ImportRule)
 
 namespace mozilla {
 namespace css {
 
-GroupRule::GroupRule()
-  : Rule()
+GroupRule::GroupRule(uint32_t aLineNumber, uint32_t aColumnNumber)
+  : Rule(aLineNumber, aColumnNumber)
 {
 }
 
 static bool
 SetParentRuleReference(Rule* aRule, void* aParentRule)
 {
   GroupRule* parentRule = static_cast<GroupRule*>(aParentRule);
   aRule->SetParentRule(parentRule);
@@ -765,17 +767,18 @@ GroupRule::SizeOfExcludingThis(MallocSiz
   // worthwhile:
   // - mRuleCollection
 }
 
 
 // -------------------------------------------
 // nsICSSMediaRule
 //
-MediaRule::MediaRule()
+MediaRule::MediaRule(uint32_t aLineNumber, uint32_t aColumnNumber)
+  : GroupRule(aLineNumber, aColumnNumber)
 {
 }
 
 MediaRule::MediaRule(const MediaRule& aCopy)
   : GroupRule(aCopy)
 {
   if (aCopy.mMedia) {
     mMedia = aCopy.mMedia->Clone();
@@ -991,17 +994,18 @@ MediaRule::AppendConditionText(nsAString
 } // namespace mozilla
 
 // Must be outside namespace
 DOMCI_DATA(CSSMediaRule, css::MediaRule)
 
 namespace mozilla {
 namespace css {
 
-DocumentRule::DocumentRule()
+DocumentRule::DocumentRule(uint32_t aLineNumber, uint32_t aColumnNumber)
+  : GroupRule(aLineNumber, aColumnNumber)
 {
 }
 
 DocumentRule::DocumentRule(const DocumentRule& aCopy)
   : GroupRule(aCopy)
   , mURLs(new URL(*aCopy.mURLs))
 {
 }
@@ -1247,18 +1251,19 @@ DOMCI_DATA(CSSMozDocumentRule, css::Docu
 
 // -------------------------------------------
 // NameSpaceRule
 //
 
 namespace mozilla {
 namespace css {
 
-NameSpaceRule::NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec)
-  : Rule(),
+NameSpaceRule::NameSpaceRule(nsIAtom* aPrefix, const nsString& aURLSpec,
+                             uint32_t aLineNumber, uint32_t aColumnNumber)
+  : Rule(aLineNumber, aColumnNumber),
     mPrefix(aPrefix),
     mURLSpec(aURLSpec)
 {
 }
 
 NameSpaceRule::NameSpaceRule(const NameSpaceRule& aCopy)
   : Rule(aCopy),
     mPrefix(aCopy.mPrefix),
@@ -2916,19 +2921,21 @@ nsCSSPageRule::ChangeDeclaration(css::De
 nsCSSPageRule::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   return aMallocSizeOf(this);
 }
 
 namespace mozilla {
 
 CSSSupportsRule::CSSSupportsRule(bool aConditionMet,
-                                 const nsString& aCondition)
-  : mUseGroup(aConditionMet),
-    mCondition(aCondition)
+                                 const nsString& aCondition,
+                                 uint32_t aLineNumber, uint32_t aColumnNumber)
+  : css::GroupRule(aLineNumber, aColumnNumber)
+  , mUseGroup(aConditionMet)
+  , mCondition(aCondition)
 {
 }
 
 CSSSupportsRule::~CSSSupportsRule()
 {
 }
 
 CSSSupportsRule::CSSSupportsRule(const CSSSupportsRule& aCopy)
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -42,17 +42,17 @@ namespace mozilla {
 class ErrorResult;
 
 namespace css {
 
 class MediaRule MOZ_FINAL : public GroupRule,
                             public nsIDOMCSSMediaRule
 {
 public:
-  MediaRule();
+  MediaRule(uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   MediaRule(const MediaRule& aCopy);
   ~MediaRule();
 public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIStyleRule methods
@@ -100,17 +100,17 @@ protected:
 
   nsRefPtr<nsMediaList> mMedia;
 };
 
 class DocumentRule MOZ_FINAL : public GroupRule,
                                public nsIDOMCSSMozDocumentRule
 {
 public:
-  DocumentRule();
+  DocumentRule(uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   DocumentRule(const DocumentRule& aCopy);
   ~DocumentRule();
 public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIStyleRule methods
@@ -226,17 +226,18 @@ private:
   // nsCSSFontFaceRule.
   void* operator new(size_t size) CPP_THROW_NEW;
 };
 
 class nsCSSFontFaceRule MOZ_FINAL : public mozilla::css::Rule,
                                     public nsIDOMCSSFontFaceRule
 {
 public:
-  nsCSSFontFaceRule() {}
+  nsCSSFontFaceRule(uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::Rule(aLineNumber, aColumnNumber) {}
 
   nsCSSFontFaceRule(const nsCSSFontFaceRule& aCopy)
     // copy everything except our reference count
     : mozilla::css::Rule(aCopy), mDecl(aCopy.mDecl) {}
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsCSSFontFaceRule,
                                                          mozilla::css::Rule)
@@ -291,17 +292,18 @@ nsCSSFontFaceStyleDecl::ContainingRule()
     (reinterpret_cast<const char*>(this) - offsetof(nsCSSFontFaceRule, mDecl));
 }
 
 class nsCSSFontFeatureValuesRule MOZ_FINAL :
                                        public mozilla::css::Rule,
                                        public nsIDOMCSSFontFeatureValuesRule
 {
 public:
-  nsCSSFontFeatureValuesRule() {}
+  nsCSSFontFeatureValuesRule(uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::Rule(aLineNumber, aColumnNumber) {}
 
   nsCSSFontFeatureValuesRule(const nsCSSFontFeatureValuesRule& aCopy)
     // copy everything except our reference count
     : mozilla::css::Rule(aCopy),
       mFamilyList(aCopy.mFamilyList),
       mFeatureValues(aCopy.mFeatureValues) {}
 
   NS_DECL_ISUPPORTS
@@ -354,17 +356,18 @@ protected:
 
 namespace mozilla {
 namespace css {
 
 class CharsetRule MOZ_FINAL : public Rule,
                               public nsIDOMCSSCharsetRule
 {
 public:
-  CharsetRule(const nsAString& aEncoding);
+  CharsetRule(const nsAString& aEncoding,
+              uint32_t aLineNumber, uint32_t aColumnNumber);
 private:
   // For |Clone|
   CharsetRule(const CharsetRule& aCopy);
   ~CharsetRule() {}
 
 public:
   NS_DECL_ISUPPORTS
 
@@ -424,18 +427,20 @@ protected:
 };
 
 class nsCSSKeyframeRule MOZ_FINAL : public mozilla::css::Rule,
                                     public nsIDOMMozCSSKeyframeRule
 {
 public:
   // WARNING: Steals the contents of aKeys *and* aDeclaration
   nsCSSKeyframeRule(InfallibleTArray<float>& aKeys,
-                    nsAutoPtr<mozilla::css::Declaration>&& aDeclaration)
-    : mDeclaration(mozilla::Move(aDeclaration))
+                    nsAutoPtr<mozilla::css::Declaration>&& aDeclaration,
+                    uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::Rule(aLineNumber, aColumnNumber)
+    , mDeclaration(mozilla::Move(aDeclaration))
   {
     mKeys.SwapElements(aKeys);
   }
 private:
   nsCSSKeyframeRule(const nsCSSKeyframeRule& aCopy);
   ~nsCSSKeyframeRule();
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -472,18 +477,20 @@ private:
   // lazily created when needed:
   nsRefPtr<nsCSSKeyframeStyleDeclaration>    mDOMDeclaration;
 };
 
 class nsCSSKeyframesRule MOZ_FINAL : public mozilla::css::GroupRule,
                                      public nsIDOMMozCSSKeyframesRule
 {
 public:
-  nsCSSKeyframesRule(const nsSubstring& aName)
-    : mName(aName)
+  nsCSSKeyframesRule(const nsSubstring& aName,
+                     uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::GroupRule(aLineNumber, aColumnNumber)
+    , mName(aName)
   {
   }
 private:
   nsCSSKeyframesRule(const nsCSSKeyframesRule& aCopy);
   ~nsCSSKeyframesRule();
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
@@ -552,19 +559,21 @@ protected:
   nsCSSPageRule *mRule;
 };
 
 class nsCSSPageRule MOZ_FINAL : public mozilla::css::Rule,
                                 public nsIDOMCSSPageRule
 {
 public:
   // WARNING: Steals the contents of aDeclaration
-  nsCSSPageRule(nsAutoPtr<mozilla::css::Declaration>&& aDeclaration)
-    : mDeclaration(mozilla::Move(aDeclaration)),
-      mImportantRule(nullptr)
+  nsCSSPageRule(nsAutoPtr<mozilla::css::Declaration>&& aDeclaration,
+                uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::Rule(aLineNumber, aColumnNumber)
+    , mDeclaration(mozilla::Move(aDeclaration))
+    , mImportantRule(nullptr)
   {
   }
 private:
   nsCSSPageRule(const nsCSSPageRule& aCopy);
   ~nsCSSPageRule();
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsCSSPageRule, nsIDOMCSSPageRule)
@@ -600,17 +609,18 @@ private:
 };
 
 namespace mozilla {
 
 class CSSSupportsRule : public css::GroupRule,
                         public nsIDOMCSSSupportsRule
 {
 public:
-  CSSSupportsRule(bool aConditionMet, const nsString& aCondition);
+  CSSSupportsRule(bool aConditionMet, const nsString& aCondition,
+                  uint32_t aLineNumber, uint32_t aColumnNumber);
   CSSSupportsRule(const CSSSupportsRule& aCopy);
 
   // nsIStyleRule methods
 #ifdef DEBUG
   virtual void List(FILE* out = stdout, int32_t aIndent = 0) const MOZ_OVERRIDE;
 #endif
 
   // Rule methods
@@ -651,19 +661,21 @@ protected:
 };
 
 } // namespace mozilla
 
 class nsCSSCounterStyleRule MOZ_FINAL : public mozilla::css::Rule,
                                         public nsIDOMCSSCounterStyleRule
 {
 public:
-  explicit nsCSSCounterStyleRule(const nsAString& aName)
-    : mName(aName),
-      mGeneration(0)
+  explicit nsCSSCounterStyleRule(const nsAString& aName,
+                                 uint32_t aLineNumber, uint32_t aColumnNumber)
+    : mozilla::css::Rule(aLineNumber, aColumnNumber)
+    , mName(aName)
+    , mGeneration(0)
   {
   }
 
 private:
   nsCSSCounterStyleRule(const nsCSSCounterStyleRule& aCopy);
   ~nsCSSCounterStyleRule();
 
 public:
--- a/layout/style/nsDOMCSSAttrDeclaration.cpp
+++ b/layout/style/nsDOMCSSAttrDeclaration.cpp
@@ -123,17 +123,17 @@ nsDOMCSSAttributeDeclaration::GetCSSDecl
   }
   if (!aAllocate) {
     return nullptr;
   }
 
   // cannot fail
   css::Declaration *decl = new css::Declaration();
   decl->InitializeEmpty();
-  nsRefPtr<css::StyleRule> newRule = new css::StyleRule(nullptr, decl);
+  nsRefPtr<css::StyleRule> newRule = new css::StyleRule(nullptr, decl, 0, 0);
 
   // this *can* fail (inside SetAttrAndNotify, at least).
   nsresult rv;
   if (mIsSMILOverride)
     rv = mElement->SetSMILOverrideStyleRule(newRule, false);
   else
     rv = mElement->SetInlineStyleRule(newRule, nullptr, false);