Bug 771594. Allow preference control over what CSS properties we parse. r=dbaron,dholbert
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 13 Jul 2012 19:59:05 -0400
changeset 99255 2bc62d5247fe16ca3ab43bb895de24da11d70224
parent 99254 ddfa6d5ad10a91444bf67904c0463994c8a34f7f
child 99257 31342850f91f2a0622b6402004ecd4191787c698
push id23116
push userryanvm@gmail.com
push dateSat, 14 Jul 2012 16:58:48 +0000
treeherdermozilla-central@9046ecf4db8f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron, dholbert
bugs771594
milestone16.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 771594. Allow preference control over what CSS properties we parse. r=dbaron,dholbert
content/smil/nsSMILAnimationController.cpp
content/smil/nsSMILCompositor.cpp
content/svg/content/src/nsSVGElement.cpp
dom/base/nsDOMWindowUtils.cpp
layout/inspector/src/inCSSValueSearch.cpp
layout/inspector/src/inDOMUtils.cpp
layout/style/Declaration.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSProps.cpp
layout/style/nsCSSProps.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsDOMCSSDeclaration.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/test/TestCSSPropertyLookup.cpp
--- a/content/smil/nsSMILAnimationController.cpp
+++ b/content/smil/nsSMILAnimationController.cpp
@@ -765,17 +765,18 @@ nsSMILAnimationController::GetTargetIden
     if (attributeNamespaceID == kNameSpaceID_None) {
       // width/height are special as they may be attributes or for
       // outer-<svg> elements, mapped into style.
       if (attributeName == nsGkAtoms::width ||
           attributeName == nsGkAtoms::height) {
         isCSS = targetElem->GetNameSpaceID() != kNameSpaceID_SVG;
       } else {
         nsCSSProperty prop =
-          nsCSSProps::LookupProperty(nsDependentAtomString(attributeName));
+          nsCSSProps::LookupProperty(nsDependentAtomString(attributeName),
+                                     nsCSSProps::eEnabled);
         isCSS = nsSMILCSSProperty::IsPropertyAnimatable(prop);
       }
     }
   } else {
     isCSS = (attributeType == eSMILTargetAttrType_CSS);
   }
 
   // Construct the key
--- a/content/smil/nsSMILCompositor.cpp
+++ b/content/smil/nsSMILCompositor.cpp
@@ -119,17 +119,18 @@ nsSMILCompositor::ClearAnimationEffects(
 
 // Protected Helper Functions
 // --------------------------
 nsISMILAttr*
 nsSMILCompositor::CreateSMILAttr()
 {
   if (mKey.mIsCSS) {
     nsCSSProperty propId =
-      nsCSSProps::LookupProperty(nsDependentAtomString(mKey.mAttributeName));
+      nsCSSProps::LookupProperty(nsDependentAtomString(mKey.mAttributeName),
+                                 nsCSSProps::eEnabled);
     if (nsSMILCSSProperty::IsPropertyAnimatable(propId)) {
       return new nsSMILCSSProperty(propId, mKey.mElement.get());
     }
   } else {
     return mKey.mElement->GetAnimatedAttr(mKey.mAttributeNamespaceID,
                                           mKey.mAttributeName);
   }
   return nsnull;
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1126,17 +1126,18 @@ MappedAttrParser::ParseMappedAttrValue(n
 {
   if (!mDecl) {
     mDecl = new css::Declaration();
     mDecl->InitializeEmpty();
   }
 
   // Get the nsCSSProperty ID for our mapped attribute.
   nsCSSProperty propertyID =
-    nsCSSProps::LookupProperty(nsDependentAtomString(aMappedAttrName));
+    nsCSSProps::LookupProperty(nsDependentAtomString(aMappedAttrName),
+                               nsCSSProps::eEnabled);
   if (propertyID != eCSSProperty_UNKNOWN) {
     bool changed; // outparam for ParseProperty. (ignored)
     mParser.ParseProperty(propertyID, aMappedAttrValue, mDocURI, mBaseURI,
                           mNodePrincipal, mDecl, &changed, false);
     return;
   }
   NS_ABORT_IF_FALSE(aMappedAttrName == nsGkAtoms::lang,
                     "Only 'lang' should be unrecognized!");
@@ -2448,17 +2449,18 @@ nsSVGElement::GetAnimatedAttr(PRInt32 aN
     // We check mapped-into-style attributes first so that animations
     // targeting width/height on outer-<svg> don't appear to be ignored
     // because we returned a nsISMILAttr for the corresponding
     // SVGAnimatedLength.
 
     // Mapped attributes:
     if (IsAttributeMapped(aName)) {
       nsCSSProperty prop =
-        nsCSSProps::LookupProperty(nsDependentAtomString(aName));
+        nsCSSProps::LookupProperty(nsDependentAtomString(aName),
+                                   nsCSSProps::eEnabled);
       // Check IsPropertyAnimatable to avoid attributes that...
       //  - map to explicitly unanimatable properties (e.g. 'direction')
       //  - map to unsupported attributes (e.g. 'glyph-orientation-horizontal')
       if (nsSMILCSSProperty::IsPropertyAnimatable(prop)) {
         return new nsSMILMappedAttribute(prop, this);
       }
     }
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2021,17 +2021,18 @@ nsDOMWindowUtils::ComputeAnimationDistan
   }
 
   nsresult rv;
   nsCOMPtr<nsIContent> content = do_QueryInterface(aElement, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Convert direction-dependent properties as appropriate, e.g.,
   // border-left to border-left-value.
-  nsCSSProperty property = nsCSSProps::LookupProperty(aProperty);
+  nsCSSProperty property = nsCSSProps::LookupProperty(aProperty,
+                                                      nsCSSProps::eAny);
   if (property != eCSSProperty_UNKNOWN && nsCSSProps::IsShorthand(property)) {
     nsCSSProperty subprop0 = *nsCSSProps::SubpropertyEntryFor(property);
     if (nsCSSProps::PropHasFlags(subprop0, CSS_PROPERTY_REPORT_OTHER_NAME) &&
         nsCSSProps::OtherNameFor(subprop0) == property) {
       property = subprop0;
     } else {
       property = eCSSProperty_UNKNOWN;
     }
--- a/layout/inspector/src/inCSSValueSearch.cpp
+++ b/layout/inspector/src/inCSSValueSearch.cpp
@@ -219,17 +219,18 @@ inCSSValueSearch::SetNormalizeChromeURLs
   mNormalizeChromeURLs = aNormalizeChromeURLs;
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 inCSSValueSearch::AddPropertyCriteria(const PRUnichar *aPropName)
 {
   nsCSSProperty prop =
-    nsCSSProps::LookupProperty(nsDependentString(aPropName));
+    nsCSSProps::LookupProperty(nsDependentString(aPropName),
+                               nsCSSProps::eAny);
   mProperties[mPropertyCount] = prop;
   mPropertyCount++;
   return NS_OK;
 }
 
 NS_IMETHODIMP 
 inCSSValueSearch::GetTextCriteria(PRUnichar** aTextCriteria)
 {
--- a/layout/inspector/src/inDOMUtils.cpp
+++ b/layout/inspector/src/inDOMUtils.cpp
@@ -210,17 +210,18 @@ inDOMUtils::GetRuleLine(nsIDOMCSSStyleRu
   NS_ENSURE_TRUE(cssrule != nsnull, NS_ERROR_FAILURE);
   *_retval = cssrule->GetLineNumber();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 inDOMUtils::IsInheritedProperty(const nsAString &aPropertyName, bool *_retval)
 {
-  nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName);
+  nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName,
+                                                  nsCSSProps::eAny);
   if (prop == eCSSProperty_UNKNOWN) {
     *_retval = false;
     return NS_OK;
   }
 
   if (nsCSSProps::IsShorthand(prop)) {
     prop = nsCSSProps::SubpropertyEntryFor(prop)[0];
   }
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -818,17 +818,17 @@ Declaration::GetValue(nsCSSProperty aPro
       NS_ABORT_IF_FALSE(false, "no other shorthands");
       break;
   }
 }
 
 bool
 Declaration::GetValueIsImportant(const nsAString& aProperty) const
 {
-  nsCSSProperty propID = nsCSSProps::LookupProperty(aProperty);
+  nsCSSProperty propID = nsCSSProps::LookupProperty(aProperty, nsCSSProps::eAny);
   if (propID == eCSSProperty_UNKNOWN) {
     return false;
   }
   return GetValueIsImportant(propID);
 }
 
 bool
 Declaration::GetValueIsImportant(nsCSSProperty aProperty) const
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -1075,17 +1075,18 @@ CSSParserImpl::ParseProperty(const nsCSS
   mTempData.AssertInitialState();
   aDeclaration->AssertMutable();
 
   InitScanner(aPropValue, aSheetURI, 0, aBaseURI, aSheetPrincipal);
   mSection = eCSSSection_General;
 
   *aChanged = false;
 
-  if (eCSSProperty_UNKNOWN == aPropID) { // unknown property
+  // Check for unknown or preffed off properties
+  if (eCSSProperty_UNKNOWN == aPropID || !nsCSSProps::IsEnabled(aPropID)) {
     NS_ConvertASCIItoUTF16 propName(nsCSSProps::GetStringValue(aPropID));
     const PRUnichar *params[] = {
       propName.get()
     };
     REPORT_UNEXPECTED_P(PEUnknownProperty, params);
     REPORT_UNEXPECTED(PEDeclDropped);
     OUTPUT_ERROR();
     ReleaseScanner();
@@ -4058,17 +4059,18 @@ CSSParserImpl::ParseDeclaration(css::Dec
       OUTPUT_ERROR();
     }
     // Not a declaration...
     UngetToken();
     return false;
   }
 
   // Map property name to its ID and then parse the property
-  nsCSSProperty propID = nsCSSProps::LookupProperty(propertyName);
+  nsCSSProperty propID = nsCSSProps::LookupProperty(propertyName,
+                                                    nsCSSProps::eEnabled);
   if (eCSSProperty_UNKNOWN == propID) { // unknown property
     if (!NonMozillaVendorIdentifier(propertyName)) {
       const PRUnichar *params[] = {
         propertyName.get()
       };
       REPORT_UNEXPECTED_P(PEUnknownProperty, params);
       REPORT_UNEXPECTED(PEDeclDropped);
       OUTPUT_ERROR();
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -17,16 +17,18 @@
 #include "nsThemeConstants.h"  // For system widget appearance types
 
 #include "mozilla/LookAndFeel.h" // for system colors
 
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsStaticNameTable.h"
 
+#include "mozilla/Preferences.h"
+
 using namespace mozilla;
 
 // required to make the symbol external, so that TestCSSPropertyLookup.cpp can link with it
 extern const char* const kCSSRawProperties[];
 
 // define an array of all CSS properties
 const char* const kCSSRawProperties[] = {
 #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, kwtable_, \
@@ -67,16 +69,60 @@ SortPropertyAndCount(const void* s1, con
   const PropertyAndCount *pc2 = static_cast<const PropertyAndCount*>(s2);
   // Primary sort by count (lowest to highest)
   if (pc1->count != pc2->count)
     return pc1->count - pc2->count;
   // Secondary sort by property index (highest to lowest)
   return pc2->property - pc1->property;
 }
 
+// We need eCSSAliasCount so we can make gAliases nonzero size when there
+// are no aliases.
+enum {
+#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)              \
+  eCSSAliasCountBefore_##aliasmethod_,
+#include "nsCSSPropAliasList.h"
+#undef CSS_PROP_ALIAS
+
+  eCSSAliasCount
+};
+
+enum {
+  // We want the largest sizeof(#aliasname_).  To find that, we use the
+  // auto-incrementing behavior of C++ enums (a value without an
+  // initializer is one larger than the previous value, or 0 at the
+  // start of the enum), and for each alias we define two values:
+  //   eMaxCSSAliasNameSizeBefore_##aliasmethod_ is the largest
+  //     sizeof(#aliasname_) before that alias.  The first one is
+  //     conveniently zero.
+  //   eMaxCSSAliasNameSizeWith_##aliasmethod_ is **one less than** the
+  //     largest sizeof(#aliasname_) before or including that alias.
+#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)              \
+  eMaxCSSAliasNameSizeBefore_##aliasmethod_,                                  \
+  eMaxCSSAliasNameSizeWith_##aliasmethod_ =                                   \
+    PR_MAX(sizeof(#aliasname_), eMaxCSSAliasNameSizeBefore_##aliasmethod_) - 1,
+#include "nsCSSPropAliasList.h"
+#undef CSS_PROP_ALIAS
+
+  eMaxCSSAliasNameSize
+};
+
+struct CSSPropertyAlias {
+  const char name[PR_MAX(eMaxCSSAliasNameSize, 1)];
+  const nsCSSProperty id;
+  bool enabled;
+};
+
+static CSSPropertyAlias gAliases[PR_MAX(eCSSAliasCount, 1)] = {
+#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)  \
+  { #aliasname_, eCSSProperty_##propid_, true },
+#include "nsCSSPropAliasList.h"
+#undef CSS_PROP_ALIAS
+};
+
 void
 nsCSSProps::AddRefTable(void)
 {
   if (0 == gTableRefCount++) {
     NS_ABORT_IF_FALSE(!gPropertyTable, "pre existing array!");
     NS_ABORT_IF_FALSE(!gFontDescTable, "pre existing array!");
 
     gPropertyTable = new nsStaticCaseInsensitiveNameTable();
@@ -111,16 +157,50 @@ nsCSSProps::AddRefTable(void)
                           "underscore char in desc table");
       }
     }
 #endif
       gFontDescTable->Init(kCSSRawFontDescs, eCSSFontDesc_COUNT);
     }
 
     BuildShorthandsContainingTable();
+
+    static bool prefObserversInited = false;
+    if (!prefObserversInited) {
+      prefObserversInited = true;
+      
+      #define OBSERVE_PROP(pref_, id_)                                        \
+        if (pref_[0]) {                                                       \
+          Preferences::AddBoolVarCache(&gPropertyEnabled[eCSSProperty_##id_], \
+                                       pref_);                                \
+        }
+
+      #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
+                       kwtable_, stylestruct_, stylestructoffset_, animtype_) \
+        OBSERVE_PROP(pref_, id_)
+      #include "nsCSSPropList.h"
+      #undef CSS_PROP
+
+      #define  CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \
+        OBSERVE_PROP(pref_, id_)
+      #include "nsCSSPropList.h"
+      #undef CSS_PROP_SHORTHAND
+
+      #undef OBSERVE_PROP
+
+      size_t aliasIndex = 0;
+      #define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)    \
+        if (pref_[0]) {                                                   \
+          Preferences::AddBoolVarCache(&gAliases[aliasIndex].enabled,     \
+                                       pref_);                            \
+        }                                                                 \
+        ++aliasIndex;
+      #include "nsCSSPropAliasList.h"
+      #undef CSS_PROP_ALIAS
+    }
   }
 }
 
 #undef  DEBUG_SHORTHANDS_CONTAINING
 
 bool
 nsCSSProps::BuildShorthandsContainingTable()
 {
@@ -277,100 +357,66 @@ nsCSSProps::ReleaseTable(void)
     delete gFontDescTable;
     gFontDescTable = nsnull;
 
     delete [] gShorthandsContainingPool;
     gShorthandsContainingPool = nsnull;
   }
 }
 
-// We need eCSSAliasCount so we can make gAliases nonzero size when there
-// are no aliases.
-enum {
-#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)              \
-  eCSSAliasCountBefore_##aliasmethod_,
-#include "nsCSSPropAliasList.h"
-#undef CSS_PROP_ALIAS
-
-  eCSSAliasCount
-};
-
-enum {
-  // We want the largest sizeof(#aliasname_).  To find that, we use the
-  // auto-incrementing behavior of C++ enums (a value without an
-  // initializer is one larger than the previous value, or 0 at the
-  // start of the enum), and for each alias we define two values:
-  //   eMaxCSSAliasNameSizeBefore_##aliasmethod_ is the largest
-  //     sizeof(#aliasname_) before that alias.  The first one is
-  //     conveniently zero.
-  //   eMaxCSSAliasNameSizeWith_##aliasmethod_ is **one less than** the
-  //     largest sizeof(#aliasname_) before or including that alias.
-#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)              \
-  eMaxCSSAliasNameSizeBefore_##aliasmethod_,                                  \
-  eMaxCSSAliasNameSizeWith_##aliasmethod_ =                                   \
-    PR_MAX(sizeof(#aliasname_), eMaxCSSAliasNameSizeBefore_##aliasmethod_) - 1,
-#include "nsCSSPropAliasList.h"
-#undef CSS_PROP_ALIAS
-
-  eMaxCSSAliasNameSize
-};
-
-struct CSSPropertyAlias {
-  char name[PR_MAX(eMaxCSSAliasNameSize, 1)];
-  nsCSSProperty id;
-};
-
-static const CSSPropertyAlias gAliases[PR_MAX(eCSSAliasCount, 1)] = {
-#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)  \
-  { #aliasname_, eCSSProperty_##propid_ },
-#include "nsCSSPropAliasList.h"
-#undef CSS_PROP_ALIAS
-};
-
 nsCSSProperty
-nsCSSProps::LookupProperty(const nsACString& aProperty)
+nsCSSProps::LookupProperty(const nsACString& aProperty,
+                           EnabledState aEnabled)
 {
   NS_ABORT_IF_FALSE(gPropertyTable, "no lookup table, needs addref");
 
   nsCSSProperty res = nsCSSProperty(gPropertyTable->Lookup(aProperty));
   // Check eCSSAliasCount against 0 to make it easy for the
   // compiler to optimize away the 0-aliases case.
   if (eCSSAliasCount != 0 && res == eCSSProperty_UNKNOWN) {
     for (const CSSPropertyAlias *alias = gAliases,
                             *alias_end = ArrayEnd(gAliases);
          alias < alias_end; ++alias) {
-      if (aProperty.LowerCaseEqualsASCII(alias->name)) {
+      if (aProperty.LowerCaseEqualsASCII(alias->name) &&
+          (alias->enabled || aEnabled == eAny)) {
         res = alias->id;
         break;
       }
     }
   }
+  if (res != eCSSProperty_UNKNOWN && aEnabled == eEnabled && !IsEnabled(res)) {
+    res = eCSSProperty_UNKNOWN;
+  }
   return res;
 }
 
 nsCSSProperty
-nsCSSProps::LookupProperty(const nsAString& aProperty)
+nsCSSProps::LookupProperty(const nsAString& aProperty, EnabledState aEnabled)
 {
   // This is faster than converting and calling
   // LookupProperty(nsACString&).  The table will do its own
   // converting and avoid a PromiseFlatCString() call.
   NS_ABORT_IF_FALSE(gPropertyTable, "no lookup table, needs addref");
   nsCSSProperty res = nsCSSProperty(gPropertyTable->Lookup(aProperty));
   // Check eCSSAliasCount against 0 to make it easy for the
   // compiler to optimize away the 0-aliases case.
   if (eCSSAliasCount != 0 && res == eCSSProperty_UNKNOWN) {
     for (const CSSPropertyAlias *alias = gAliases,
                             *alias_end = ArrayEnd(gAliases);
          alias < alias_end; ++alias) {
-      if (aProperty.LowerCaseEqualsASCII(alias->name)) {
+      if (aProperty.LowerCaseEqualsASCII(alias->name) &&
+          (alias->enabled || aEnabled == eAny)) {
         res = alias->id;
         break;
       }
     }
   }
+  if (res != eCSSProperty_UNKNOWN && aEnabled == eEnabled && !IsEnabled(res)) {
+    res = eCSSProperty_UNKNOWN;
+  }
   return res;
 }
 
 nsCSSFontDesc
 nsCSSProps::LookupFontDesc(const nsACString& aFontDesc)
 {
   NS_ABORT_IF_FALSE(gFontDescTable, "no lookup table, needs addref");
   return nsCSSFontDesc(gFontDescTable->Lookup(aFontDesc));
@@ -2371,8 +2417,22 @@ nsCSSProps::gPropertyIndexInStruct[eCSSP
   #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
                    kwtable_, stylestruct_, stylestructoffset_, animtype_) \
     ePropertyIndex_for_##id_,
   #include "nsCSSPropList.h"
   #undef CSS_PROP
   #undef CSS_PROP_BACKENDONLY
 
 };
+
+/* static */ bool
+nsCSSProps::gPropertyEnabled[eCSSProperty_COUNT] = {
+  #define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,     \
+                   kwtable_, stylestruct_, stylestructoffset_, animtype_) \
+    true,
+  #include "nsCSSPropList.h"
+  #undef CSS_PROP
+
+  #define  CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \
+    true,
+  #include "nsCSSPropList.h"
+  #undef CSS_PROP_SHORTHAND
+};
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -145,18 +145,24 @@ enum nsStyleAnimType {
 };
 
 class nsCSSProps {
 public:
   static void AddRefTable(void);
   static void ReleaseTable(void);
 
   // Given a property string, return the enum value
-  static nsCSSProperty LookupProperty(const nsAString& aProperty);
-  static nsCSSProperty LookupProperty(const nsACString& aProperty);
+  enum EnabledState {
+    eEnabled,
+    eAny
+  };
+  static nsCSSProperty LookupProperty(const nsAString& aProperty,
+                                      EnabledState aEnabled);
+  static nsCSSProperty LookupProperty(const nsACString& aProperty,
+                                      EnabledState aEnabled);
 
   static inline bool IsShorthand(nsCSSProperty aProperty) {
     NS_ABORT_IF_FALSE(0 <= aProperty && aProperty < eCSSProperty_COUNT,
                  "out of range");
     return (aProperty >= eCSSProperty_COUNT_no_shorthands);
   }
 
   // Same but for @font-face descriptors
@@ -290,16 +296,27 @@ public:
    */
   static size_t PropertyIndexInStruct(nsCSSProperty aProperty) {
     NS_ABORT_IF_FALSE(0 <= aProperty &&
                          aProperty < eCSSProperty_COUNT_no_shorthands,
                       "out of range");
     return gPropertyIndexInStruct[aProperty];
   }
 
+private:
+  static bool gPropertyEnabled[eCSSProperty_COUNT];
+
+public:
+
+  static bool IsEnabled(nsCSSProperty aProperty) {
+    NS_ABORT_IF_FALSE(0 <= aProperty && aProperty < eCSSProperty_COUNT,
+                      "out of range");
+    return gPropertyEnabled[aProperty];
+  }
+
 public:
 
 #define CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(iter_, prop_)                    \
   for (const nsCSSProperty* iter_ = nsCSSProps::SubpropertyEntryFor(prop_);   \
        *iter_ != eCSSProperty_UNKNOWN; ++iter_)
 
   // Keyword/Enum value tables
   static const PRInt32 kAnimationDirectionKTable[];
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -424,17 +424,18 @@ nsComputedDOMStyle::GetPropertyCSSValue(
   NS_ASSERTION(!mStyleContextHolder, "bad state");
 
   *aReturn = nsnull;
 
   nsCOMPtr<nsIDocument> document = do_QueryReferent(mDocumentWeak);
   NS_ENSURE_TRUE(document, NS_ERROR_NOT_AVAILABLE);
   document->FlushPendingLinkUpdates();
 
-  nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName);
+  nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName,
+                                                  nsCSSProps::eEnabled);
 
   const ComputedStyleMapEntry* propEntry = nsnull;
   {
     PRUint32 length = 0;
     const ComputedStyleMapEntry* propMap = GetQueryablePropertyMap(&length);
     for (PRUint32 i = 0; i < length; ++i) {
       if (prop == propMap[i].mProperty) {
         propEntry = &propMap[i];
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -156,17 +156,18 @@ nsDOMCSSDeclaration::Item(PRUint32 aInde
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMCSSDeclaration::GetPropertyValue(const nsAString& aPropertyName,
                                       nsAString& aReturn)
 {
-  const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
+  const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName,
+                                                          nsCSSProps::eEnabled);
   if (propID == eCSSProperty_UNKNOWN) {
     aReturn.Truncate();
     return NS_OK;
   }
 
   return GetPropertyValue(propID, aReturn);
 }
 
@@ -185,17 +186,18 @@ nsDOMCSSDeclaration::GetPropertyPriority
 }
 
 NS_IMETHODIMP
 nsDOMCSSDeclaration::SetProperty(const nsAString& aPropertyName,
                                  const nsAString& aValue,
                                  const nsAString& aPriority)
 {
   // In the common (and fast) cases we can use the property id
-  nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
+  nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName,
+                                                    nsCSSProps::eEnabled);
   if (propID == eCSSProperty_UNKNOWN) {
     return NS_OK;
   }
 
   if (aValue.IsEmpty()) {
     // If the new value of the property is an empty string we remove the
     // property.
     // XXX this ignores the priority string, should it?
@@ -213,17 +215,18 @@ nsDOMCSSDeclaration::SetProperty(const n
   // XXX silent failure?
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMCSSDeclaration::RemoveProperty(const nsAString& aPropertyName,
                                     nsAString& aReturn)
 {
-  const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
+  const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName,
+                                                          nsCSSProps::eEnabled);
   if (propID == eCSSProperty_UNKNOWN) {
     aReturn.Truncate();
     return NS_OK;
   }
 
   nsresult rv = GetPropertyValue(propID, aReturn);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -4342,17 +4342,18 @@ nsRuleNode::ComputeDisplayData(void* aSt
       transition->SetProperty(eCSSPropertyExtra_no_properties);
     } else if (property.list) {
       NS_ABORT_IF_FALSE(property.list->mValue.GetUnit() == eCSSUnit_Ident,
                         nsPrintfCString("Invalid transition property unit %d",
                                         property.list->mValue.GetUnit()).get());
 
       nsDependentString
         propertyStr(property.list->mValue.GetStringBufferValue());
-      nsCSSProperty prop = nsCSSProps::LookupProperty(propertyStr);
+      nsCSSProperty prop = nsCSSProps::LookupProperty(propertyStr,
+                                                      nsCSSProps::eEnabled);
       if (prop == eCSSProperty_UNKNOWN) {
         transition->SetUnknownProperty(propertyStr);
       } else {
         transition->SetProperty(prop);
       }
     }
 
     if (i >= timingFunction.num) {
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2096,17 +2096,18 @@ void nsTransition::SetInitialValues()
   mTimingFunction = nsTimingFunction(NS_STYLE_TRANSITION_TIMING_FUNCTION_EASE);
   mDuration = 0.0;
   mDelay = 0.0;
   mProperty = eCSSPropertyExtra_all_properties;
 }
 
 void nsTransition::SetUnknownProperty(const nsAString& aUnknownProperty)
 {
-  NS_ASSERTION(nsCSSProps::LookupProperty(aUnknownProperty) ==
+  NS_ASSERTION(nsCSSProps::LookupProperty(aUnknownProperty,
+                                          nsCSSProps::eEnabled) ==
                  eCSSProperty_UNKNOWN,
                "should be unknown property");
   mProperty = eCSSProperty_UNKNOWN;
   mUnknownProperty = do_GetAtom(aUnknownProperty);
 }
 
 nsAnimation::nsAnimation(const nsAnimation& aCopy)
   : mTimingFunction(aCopy.mTimingFunction)
--- a/layout/style/test/TestCSSPropertyLookup.cpp
+++ b/layout/style/test/TestCSSPropertyLookup.cpp
@@ -35,46 +35,47 @@ TestProps()
   const char*const* et = &kCSSRawProperties[0];
   const char*const* end = &kCSSRawProperties[eCSSProperty_COUNT];
   index = eCSSProperty_UNKNOWN;
   while (et < end) {
     char tagName[100];
     PL_strcpy(tagName, *et);
     index = nsCSSProperty(PRInt32(index) + 1);
 
-    id = nsCSSProps::LookupProperty(nsCString(tagName));
+    id = nsCSSProps::LookupProperty(nsCString(tagName), nsCSSProps::eAny);
     if (id == eCSSProperty_UNKNOWN) {
       printf("bug: can't find '%s'\n", tagName);
       success = false;
     }
     if (id != index) {
       printf("bug: name='%s' id=%d index=%d\n", tagName, id, index);
       success = false;
     }
 
     // fiddle with the case to make sure we can still find it
     if (('a' <= tagName[0]) && (tagName[0] <= 'z')) {
       tagName[0] = tagName[0] - 32;
     }
-    id = nsCSSProps::LookupProperty(NS_ConvertASCIItoUTF16(tagName));
+    id = nsCSSProps::LookupProperty(NS_ConvertASCIItoUTF16(tagName),
+                                    nsCSSProps::eAny);
     if (id < 0) {
       printf("bug: can't find '%s'\n", tagName);
       success = false;
     }
     if (index != id) {
       printf("bug: name='%s' id=%d index=%d\n", tagName, id, index);
       success = false;
     }
     et++;
   }
 
   // Now make sure we don't find some garbage
   for (int i = 0; i < (int) (sizeof(kJunkNames) / sizeof(const char*)); i++) {
     const char* const tag = kJunkNames[i];
-    id = nsCSSProps::LookupProperty(nsCAutoString(tag));
+    id = nsCSSProps::LookupProperty(nsCAutoString(tag), nsCSSProps::eAny);
     if (id >= 0) {
       printf("bug: found '%s'\n", tag ? tag : "(null)");
       success = false;
     }
   }
 
   nsCSSProps::ReleaseTable();
   return success;