Bug 814907 - Add new CSS GroupingRule and ConditionRule interfaces. r=bz
authorCameron McCormack <cam@mcc.id.au>
Tue, 27 Nov 2012 16:30:30 +1100
changeset 114186 cb43db016af69abe72d0888a45a281406a96759b
parent 114185 0fbfdf387c4c9df5f0eb8786d0ab6ace4e3f2ca9
child 114187 e37de84261fde584cc5c7b9759a968854e6600fd
push id23907
push useremorley@mozilla.com
push dateTue, 27 Nov 2012 14:15:28 +0000
treeherdermozilla-central@532d0832c09d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs814907
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 814907 - Add new CSS GroupingRule and ConditionRule interfaces. r=bz
dom/interfaces/css/Makefile.in
dom/interfaces/css/nsIDOMCSSConditionRule.idl
dom/interfaces/css/nsIDOMCSSGroupingRule.idl
dom/interfaces/css/nsIDOMCSSMediaRule.idl
dom/interfaces/css/nsIDOMCSSMozDocumentRule.idl
dom/interfaces/css/nsIDOMCSSSupportsRule.idl
layout/style/nsCSSRules.cpp
layout/style/nsCSSRules.h
layout/style/test/Makefile.in
layout/style/test/test_condition_text.html
--- a/dom/interfaces/css/Makefile.in
+++ b/dom/interfaces/css/Makefile.in
@@ -22,17 +22,19 @@ SDK_XPIDLSRCS = 				\
 	nsIDOMCSSStyleSheet.idl			\
 	nsIDOMCSSValue.idl			\
 	nsIDOMCSSValueList.idl			\
 	nsIDOMElementCSSInlineStyle.idl		\
 	$(NULL)
 
 XPIDLSRCS =					\
 	nsIDOMCSSCharsetRule.idl		\
+	nsIDOMCSSConditionRule.idl		\
 	nsIDOMCSSFontFaceRule.idl		\
+	nsIDOMCSSGroupingRule.idl		\
 	nsIDOMCSSImportRule.idl			\
 	nsIDOMCSSMediaRule.idl			\
 	nsIDOMCSSMozDocumentRule.idl		\
 	nsIDOMCSSSupportsRule.idl		\
 	nsIDOMMozCSSKeyframeRule.idl		\
 	nsIDOMMozCSSKeyframesRule.idl		\
 	nsIDOMCSSPageRule.idl			\
 	nsIDOMCSSStyleRule.idl			\
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/css/nsIDOMCSSConditionRule.idl
@@ -0,0 +1,16 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIDOMCSSGroupingRule.idl"
+
+/**
+ * Interface in the CSS OM for at-rules that conditionally apply their
+ * child rules.
+ */
+[scriptable, uuid(942754f2-2c0e-461b-9c10-c0e929504fe1)]
+interface nsIDOMCSSConditionRule : nsIDOMCSSGroupingRule
+{
+  attribute DOMString conditionText;
+};
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/css/nsIDOMCSSGroupingRule.idl
@@ -0,0 +1,21 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsIDOMCSSRule.idl"
+
+/**
+ * Interface for at-rules that have child rules in the CSS OM.
+ */
+[scriptable, uuid(ab013eed-fa21-4c6a-bba3-79e8780f583e)]
+interface nsIDOMCSSGroupingRule : nsIDOMCSSRule
+{
+  readonly attribute nsIDOMCSSRuleList cssRules;
+
+  unsigned long      insertRule(in DOMString rule,
+                                in unsigned long index)
+                                        raises(DOMException);
+  void               deleteRule(in unsigned long index)
+                                        raises(DOMException);
+};
--- a/dom/interfaces/css/nsIDOMCSSMediaRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSMediaRule.idl
@@ -1,19 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsIDOMCSSRule.idl"
+#include "nsIDOMCSSConditionRule.idl"
 
-[scriptable, uuid(a6cf90bc-15b3-11d2-932e-00805f8add32)]
-interface nsIDOMCSSMediaRule : nsIDOMCSSRule
+/**
+ * Interface for @media rules in the CSS OM.
+ */
+[scriptable, uuid(1f491b05-932b-4aa1-a1f1-466505d70898)]
+interface nsIDOMCSSMediaRule : nsIDOMCSSConditionRule
 {
   readonly attribute nsIDOMMediaList   media;
-  readonly attribute nsIDOMCSSRuleList cssRules;
-
-  unsigned long      insertRule(in DOMString rule, 
-                                in unsigned long index)
-                                        raises(DOMException);
-  void               deleteRule(in unsigned long index)
-                                        raises(DOMException);
 };
--- a/dom/interfaces/css/nsIDOMCSSMozDocumentRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSMozDocumentRule.idl
@@ -1,23 +1,15 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsIDOMCSSRule.idl"
+#include "nsIDOMCSSConditionRule.idl"
 
 /**
- * Modified version of nsIDOMCSSMediaRule for @-moz-document rules.
+ * Interface for @-moz-document rules in the CSS OM.
  */
-[scriptable, uuid(4eb9adac-afaf-4b8a-8640-7340863c1587)]
-interface nsIDOMCSSMozDocumentRule : nsIDOMCSSRule
+[scriptable, uuid(f118a5a8-ac36-464f-b993-18cf6fe76fda)]
+interface nsIDOMCSSMozDocumentRule : nsIDOMCSSConditionRule
 {
-  readonly attribute nsIDOMCSSRuleList cssRules;
-
-  unsigned long      insertRule(in DOMString rule, 
-                                in unsigned long index)
-                                        raises(DOMException);
-  void               deleteRule(in unsigned long index)
-                                        raises(DOMException);
-
   // XXX Add access to the URL list.
 };
--- a/dom/interfaces/css/nsIDOMCSSSupportsRule.idl
+++ b/dom/interfaces/css/nsIDOMCSSSupportsRule.idl
@@ -1,21 +1,14 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsIDOMCSSRule.idl"
+#include "nsIDOMCSSConditionRule.idl"
 
 /**
  * Interface for @supports rules in the CSS OM.
  */
 [scriptable, uuid(5f409a4d-92f9-4a62-8e8a-cc1c02c32918)]
-interface nsIDOMCSSSupportsRule : nsIDOMCSSRule
+interface nsIDOMCSSSupportsRule : nsIDOMCSSConditionRule
 {
-  readonly attribute nsIDOMCSSRuleList cssRules;
-
-  unsigned long      insertRule(in DOMString rule,
-                                in unsigned long index)
-                                        raises(DOMException);
-  void               deleteRule(in unsigned long index)
-                                        raises(DOMException);
 };
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -809,16 +809,18 @@ MediaRule::~MediaRule()
 
 NS_IMPL_ADDREF_INHERITED(MediaRule, GroupRule)
 NS_IMPL_RELEASE_INHERITED(MediaRule, GroupRule)
 
 // QueryInterface implementation for MediaRule
 NS_INTERFACE_MAP_BEGIN(MediaRule)
   NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMediaRule)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMediaRule)
 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
 
 /* virtual */ void
 MediaRule::SetStyleSheet(nsCSSStyleSheet* aSheet)
 {
@@ -880,23 +882,17 @@ MediaRule::GetType(uint16_t* aType)
   *aType = nsIDOMCSSRule::MEDIA_RULE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MediaRule::GetCssText(nsAString& aCssText)
 {
   aCssText.AssignLiteral("@media ");
-  // get all the media
-  if (mMedia) {
-    nsAutoString mediaText;
-    mMedia->GetText(mediaText);
-    aCssText.Append(mediaText);
-  }
-
+  AppendConditionText(aCssText);
   return GroupRule::AppendRulesToCssText(aCssText);
 }
 
 NS_IMETHODIMP
 MediaRule::SetCssText(const nsAString& aCssText)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
@@ -908,25 +904,17 @@ MediaRule::GetParentStyleSheet(nsIDOMCSS
 }
 
 NS_IMETHODIMP
 MediaRule::GetParentRule(nsIDOMCSSRule** aParentRule)
 {
   return GroupRule::GetParentRule(aParentRule);
 }
 
-// nsIDOMCSSMediaRule methods
-NS_IMETHODIMP
-MediaRule::GetMedia(nsIDOMMediaList* *aMedia)
-{
-  NS_ENSURE_ARG_POINTER(aMedia);
-  NS_IF_ADDREF(*aMedia = mMedia);
-  return NS_OK;
-}
-
+// nsIDOMCSSGroupingRule methods
 NS_IMETHODIMP
 MediaRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
 {
   return GroupRule::GetCssRules(aRuleList);
 }
 
 NS_IMETHODIMP
 MediaRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
@@ -935,16 +923,40 @@ MediaRule::InsertRule(const nsAString & 
 }
 
 NS_IMETHODIMP
 MediaRule::DeleteRule(uint32_t aIndex)
 {
   return GroupRule::DeleteRule(aIndex);
 }
 
+// nsIDOMCSSConditionRule methods
+NS_IMETHODIMP
+MediaRule::GetConditionText(nsAString& aConditionText)
+{
+  aConditionText.Truncate(0);
+  AppendConditionText(aConditionText);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MediaRule::SetConditionText(const nsAString& aConditionText)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+// nsIDOMCSSMediaRule methods
+NS_IMETHODIMP
+MediaRule::GetMedia(nsIDOMMediaList* *aMedia)
+{
+  NS_ENSURE_ARG_POINTER(aMedia);
+  NS_IF_ADDREF(*aMedia = mMedia);
+  return NS_OK;
+}
+
 // GroupRule interface
 /* virtual */ bool
 MediaRule::UseForPresentation(nsPresContext* aPresContext,
                                    nsMediaQueryResultCacheKey& aKey)
 {
   if (mMedia) {
     return mMedia->Matches(aPresContext, &aKey);
   }
@@ -959,16 +971,26 @@ MediaRule::SizeOfIncludingThis(nsMallocS
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mMedia
 
   return n;
 }
 
+void
+MediaRule::AppendConditionText(nsAString& aOutput)
+{
+  if (mMedia) {
+    nsAutoString mediaText;
+    mMedia->GetText(mediaText);
+    aOutput.Append(mediaText);
+  }
+}
+
 } // namespace css
 } // namespace mozilla
 
 // Must be outside namespace
 DOMCI_DATA(CSSMediaRule, css::MediaRule)
 
 namespace mozilla {
 namespace css {
@@ -989,16 +1011,18 @@ DocumentRule::~DocumentRule()
 
 NS_IMPL_ADDREF_INHERITED(DocumentRule, GroupRule)
 NS_IMPL_RELEASE_INHERITED(DocumentRule, GroupRule)
 
 // QueryInterface implementation for DocumentRule
 NS_INTERFACE_MAP_BEGIN(DocumentRule)
   NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSMozDocumentRule)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSMozDocumentRule)
 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
 
 #ifdef DEBUG
 /* virtual */ void
 DocumentRule::List(FILE* out, int32_t aIndent) const
@@ -1055,37 +1079,17 @@ DocumentRule::GetType(uint16_t* aType)
   *aType = nsIDOMCSSRule::UNKNOWN_RULE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 DocumentRule::GetCssText(nsAString& aCssText)
 {
   aCssText.AssignLiteral("@-moz-document ");
-  for (URL *url = mURLs; url; url = url->next) {
-    switch (url->func) {
-      case eURL:
-        aCssText.AppendLiteral("url(");
-        break;
-      case eURLPrefix:
-        aCssText.AppendLiteral("url-prefix(");
-        break;
-      case eDomain:
-        aCssText.AppendLiteral("domain(");
-        break;
-      case eRegExp:
-        aCssText.AppendLiteral("regexp(");
-        break;
-    }
-    nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url->url),
-                                        aCssText);
-    aCssText.AppendLiteral("), ");
-  }
-  aCssText.Cut(aCssText.Length() - 2, 1); // remove last ,
-
+  AppendConditionText(aCssText);
   return GroupRule::AppendRulesToCssText(aCssText);
 }
 
 NS_IMETHODIMP
 DocumentRule::SetCssText(const nsAString& aCssText)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
@@ -1097,16 +1101,17 @@ DocumentRule::GetParentStyleSheet(nsIDOM
 }
 
 NS_IMETHODIMP
 DocumentRule::GetParentRule(nsIDOMCSSRule** aParentRule)
 {
   return GroupRule::GetParentRule(aParentRule);
 }
 
+// nsIDOMCSSGroupingRule methods
 NS_IMETHODIMP
 DocumentRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
 {
   return GroupRule::GetCssRules(aRuleList);
 }
 
 NS_IMETHODIMP
 DocumentRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
@@ -1115,16 +1120,31 @@ DocumentRule::InsertRule(const nsAString
 }
 
 NS_IMETHODIMP
 DocumentRule::DeleteRule(uint32_t aIndex)
 {
   return GroupRule::DeleteRule(aIndex);
 }
 
+// nsIDOMCSSConditionRule methods
+NS_IMETHODIMP
+DocumentRule::GetConditionText(nsAString& aConditionText)
+{
+  aConditionText.Truncate(0);
+  AppendConditionText(aConditionText);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+DocumentRule::SetConditionText(const nsAString& aConditionText)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
 // GroupRule interface
 /* virtual */ bool
 DocumentRule::UseForPresentation(nsPresContext* aPresContext,
                                  nsMediaQueryResultCacheKey& aKey)
 {
   nsIDocument *doc = aPresContext->Document();
   nsIURI *docURI = doc->GetDocumentURI();
   nsAutoCString docURISpec;
@@ -1181,16 +1201,41 @@ DocumentRule::SizeOfIncludingThis(nsMall
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mURLs
 
   return n;
 }
 
+void
+DocumentRule::AppendConditionText(nsAString& aCssText)
+{
+  for (URL *url = mURLs; url; url = url->next) {
+    switch (url->func) {
+      case eURL:
+        aCssText.AppendLiteral("url(");
+        break;
+      case eURLPrefix:
+        aCssText.AppendLiteral("url-prefix(");
+        break;
+      case eDomain:
+        aCssText.AppendLiteral("domain(");
+        break;
+      case eRegExp:
+        aCssText.AppendLiteral("regexp(");
+        break;
+    }
+    nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(url->url),
+                                        aCssText);
+    aCssText.AppendLiteral("), ");
+  }
+  aCssText.Truncate(aCssText.Length() - 2); // remove last ", "
+}
+
 } // namespace css
 } // namespace mozilla
 
 // Must be outside namespace
 DOMCI_DATA(CSSMozDocumentRule, css::DocumentRule)
 
 // -------------------------------------------
 // NameSpaceRule
@@ -2603,16 +2648,18 @@ CSSSupportsRule::UseForPresentation(nsPr
 
 NS_IMPL_ADDREF_INHERITED(CSSSupportsRule, css::GroupRule)
 NS_IMPL_RELEASE_INHERITED(CSSSupportsRule, css::GroupRule)
 
 // QueryInterface implementation for CSSSupportsRule
 NS_INTERFACE_MAP_BEGIN(CSSSupportsRule)
   NS_INTERFACE_MAP_ENTRY(nsIStyleRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSGroupingRule)
+  NS_INTERFACE_MAP_ENTRY(nsIDOMCSSConditionRule)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSSupportsRule)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStyleRule)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSSupportsRule)
 NS_INTERFACE_MAP_END_INHERITING(GroupRule)
 
 // nsIDOMCSSRule methods
 NS_IMETHODIMP
 CSSSupportsRule::GetType(uint16_t* aType)
@@ -2642,25 +2689,17 @@ CSSSupportsRule::GetParentStyleSheet(nsI
 }
 
 NS_IMETHODIMP
 CSSSupportsRule::GetParentRule(nsIDOMCSSRule** aParentRule)
 {
   return css::GroupRule::GetParentRule(aParentRule);
 }
 
-/* virtual */ size_t
-CSSSupportsRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
-{
-  size_t n = aMallocSizeOf(this);
-  n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf);
-  n += mCondition.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
-  return n;
-}
-
+// nsIDOMCSSGroupingRule methods
 NS_IMETHODIMP
 CSSSupportsRule::GetCssRules(nsIDOMCSSRuleList* *aRuleList)
 {
   return css::GroupRule::GetCssRules(aRuleList);
 }
 
 NS_IMETHODIMP
 CSSSupportsRule::InsertRule(const nsAString & aRule, uint32_t aIndex, uint32_t* _retval)
@@ -2669,12 +2708,35 @@ CSSSupportsRule::InsertRule(const nsAStr
 }
 
 NS_IMETHODIMP
 CSSSupportsRule::DeleteRule(uint32_t aIndex)
 {
   return css::GroupRule::DeleteRule(aIndex);
 }
 
+// nsIDOMCSSConditionRule methods
+NS_IMETHODIMP
+CSSSupportsRule::GetConditionText(nsAString& aConditionText)
+{
+  aConditionText.Assign(mCondition);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+CSSSupportsRule::SetConditionText(const nsAString& aConditionText)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+/* virtual */ size_t
+CSSSupportsRule::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
+{
+  size_t n = aMallocSizeOf(this);
+  n += css::GroupRule::SizeOfExcludingThis(aMallocSizeOf);
+  n += mCondition.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
+  return n;
+}
+
 } // namespace mozilla
 
 // Must be outside namespace
 DOMCI_DATA(CSSSupportsRule, mozilla::CSSSupportsRule)
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -8,17 +8,19 @@
 
 #ifndef nsCSSRules_h_
 #define nsCSSRules_h_
 
 #include "mozilla/Attributes.h"
 
 #include "mozilla/css/GroupRule.h"
 #include "mozilla/Preferences.h"
+#include "nsIDOMCSSConditionRule.h"
 #include "nsIDOMCSSFontFaceRule.h"
+#include "nsIDOMCSSGroupingRule.h"
 #include "nsIDOMCSSMediaRule.h"
 #include "nsIDOMCSSMozDocumentRule.h"
 #include "nsIDOMCSSSupportsRule.h"
 #include "nsIDOMMozCSSKeyframeRule.h"
 #include "nsIDOMMozCSSKeyframesRule.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsICSSRuleList.h"
 #include "nsAutoPtr.h"
@@ -64,30 +66,38 @@ public:
   virtual nsIDOMCSSRule* GetExistingDOMRule()
   {
     return this;
   }
 
   // nsIDOMCSSRule interface
   NS_DECL_NSIDOMCSSRULE
 
+  // nsIDOMCSSGroupingRule interface
+  NS_DECL_NSIDOMCSSGROUPINGRULE
+
+  // nsIDOMCSSConditionRule interface
+  NS_DECL_NSIDOMCSSCONDITIONRULE
+
   // nsIDOMCSSMediaRule interface
   NS_DECL_NSIDOMCSSMEDIARULE
 
   // rest of GroupRule
   virtual bool UseForPresentation(nsPresContext* aPresContext,
                                     nsMediaQueryResultCacheKey& aKey);
 
   // @media rule methods
   nsresult SetMedia(nsMediaList* aMedia);
   
   virtual NS_MUST_OVERRIDE size_t
     SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
 
 protected:
+  void AppendConditionText(nsAString& aOutput);
+
   nsRefPtr<nsMediaList> mMedia;
 };
 
 class DocumentRule MOZ_FINAL : public GroupRule,
                                public nsIDOMCSSMozDocumentRule
 {
 public:
   DocumentRule();
@@ -113,16 +123,22 @@ public:
   virtual nsIDOMCSSRule* GetExistingDOMRule()
   {
     return this;
   }
 
   // nsIDOMCSSRule interface
   NS_DECL_NSIDOMCSSRULE
 
+  // nsIDOMCSSGroupingRule interface
+  NS_DECL_NSIDOMCSSGROUPINGRULE
+
+  // nsIDOMCSSConditionRule interface
+  NS_DECL_NSIDOMCSSCONDITIONRULE
+
   // nsIDOMCSSMozDocumentRule interface
   NS_DECL_NSIDOMCSSMOZDOCUMENTRULE
 
   // rest of GroupRule
   virtual bool UseForPresentation(nsPresContext* aPresContext,
                                     nsMediaQueryResultCacheKey& aKey);
 
   enum Function {
@@ -148,16 +164,18 @@ public:
   };
 
   void SetURLs(URL *aURLs) { mURLs = aURLs; }
 
   virtual NS_MUST_OVERRIDE size_t
     SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
 
 protected:
+  void AppendConditionText(nsAString& aOutput);
+
   nsAutoPtr<URL> mURLs; // linked list of |struct URL| above.
 };
 
 } // namespace css
 } // namespace mozilla
 
 // A nsCSSFontFaceStyleDecl is always embedded in a nsCSSFontFaceRule.
 class nsCSSFontFaceRule;
@@ -532,16 +550,22 @@ public:
     return this;
   }
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIDOMCSSRule interface
   NS_DECL_NSIDOMCSSRULE
 
+  // nsIDOMCSSGroupingRule interface
+  NS_DECL_NSIDOMCSSGROUPINGRULE
+
+  // nsIDOMCSSConditionRule interface
+  NS_DECL_NSIDOMCSSCONDITIONRULE
+
   // nsIDOMCSSSupportsRule interface
   NS_DECL_NSIDOMCSSSUPPORTSRULE
 
   virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
 
   static bool PrefEnabled()
   {
     return Preferences::GetBool("layout.css.supports-rule.enabled");
--- a/layout/style/test/Makefile.in
+++ b/layout/style/test/Makefile.in
@@ -87,16 +87,17 @@ MOCHITEST_FILES =	test_acid3_test46.html
 		file_bug645998-2.css \
 		test_bug716226.html \
 		test_bug765590.html \
 		test_cascade.html \
 		test_ch_ex_no_infloops.html \
 		test_compute_data_with_start_struct.html \
 		test_computed_style.html \
 		test_computed_style_no_pseudo.html \
+		test_condition_text.html \
 		test_default_computed_style.html \
 		test_css_cross_domain.html \
 		test_css_eof_handling.html \
 		test_default_bidi_css.html \
 		test_descriptor_storage.html \
 		test_descriptor_syntax_errors.html \
 		test_dont_use_document_colors.html \
 		test_font_face_parser.html \
new file mode 100644
--- /dev/null
+++ b/layout/style/test/test_condition_text.html
@@ -0,0 +1,89 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=814907
+-->
+<head>
+  <title>Test for Bug 814907</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <style id="style">
+    @-moz-document url(http://www.example.com/) {}
+    @-moz-document url('http://www.example.com/') {}
+    @-moz-document url("http://www.example.com/") {}
+    @-moz-document url-prefix('http://www.example.com/') {}
+    @-moz-document url-prefix("http://www.example.com/") {}
+    @-moz-document domain('example.com') {}
+    @-moz-document domain("example.com") {}
+    @-moz-document regexp('http://www.w3.org/TR/\\d{4}/[^/]*-CSS2-\\d{8}/') {}
+    @-moz-document regexp("http://www.w3.org/TR/\\d{4}/[^/]*-CSS2-\\d{8}/") {}
+
+    @media all {}
+    @media only color {}
+    @media (color ) {}
+    @media color \0061ND ( monochrome ) {}
+    @media (max-width: 200px), (color) {}
+
+    @supports(color: green){}
+    @supports (color: green) {}
+    @supports ((color: green)) {}
+    @supports (color: green) and (color: blue) {}
+    @supports ( Font:  20px serif ! Important)  {}
+  </style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=814907">Mozilla Bug 814907</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 814907 **/
+
+function runTest()
+{
+  var sheet = document.getElementById("style").sheet;
+
+  var conditions = [
+    "url(\"http://www.example.com/\")",
+    "url(\"http://www.example.com/\")",
+    "url(\"http://www.example.com/\")",
+    "url-prefix(\"http://www.example.com/\")",
+    "url-prefix(\"http://www.example.com/\")",
+    "domain(\"example.com\")",
+    "domain(\"example.com\")",
+    "regexp(\"http://www.w3.org/TR/\\\\d{4}/[^/]*-CSS2-\\\\d{8}/\")",
+    "regexp(\"http://www.w3.org/TR/\\\\d{4}/[^/]*-CSS2-\\\\d{8}/\")",
+    "all",
+    "only color",
+    "(color)",
+    "color and (monochrome)",
+    "(max-width: 200px), (color)",
+    "(color: green)",
+    "(color: green)",
+    "((color: green))",
+    "(color: green) and (color: blue)",
+    "( Font:  20px serif ! Important)"
+  ];
+
+  is(sheet.cssRules.length, conditions.length);
+
+  for (var i = 0; i < sheet.cssRules.length; i++) {
+    var rule = sheet.cssRules[i];
+    is(rule.conditionText, conditions[i], "rule " + i + " has expected conditionText");
+    if (rule.type == CSSRule.MEDIA_RULE) {
+      is(rule.conditionText, rule.media.mediaText, "rule " + i + " conditionText matches media.mediaText");
+    }
+  }
+
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({ "set": [["layout.css.supports-rule.enabled", true]] }, runTest);
+</script>
+</pre>
+</body>
+</html>