Bug 771594. Allow preference control over what CSS properties we parse. r=dbaron,dholbert

This commit is contained in:
Boris Zbarsky 2012-07-13 19:59:05 -04:00
parent 43d3bd71ac
commit 43d45b95b9
15 changed files with 161 additions and 68 deletions

View File

@ -770,7 +770,8 @@ nsSMILAnimationController::GetTargetIdentifierForAnimation(
isCSS = targetElem->GetNameSpaceID() != kNameSpaceID_SVG;
} else {
nsCSSProperty prop =
nsCSSProps::LookupProperty(nsDependentAtomString(attributeName));
nsCSSProps::LookupProperty(nsDependentAtomString(attributeName),
nsCSSProps::eEnabled);
isCSS = nsSMILCSSProperty::IsPropertyAnimatable(prop);
}
}

View File

@ -124,7 +124,8 @@ 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());
}

View File

@ -1131,7 +1131,8 @@ MappedAttrParser::ParseMappedAttrValue(nsIAtom* aMappedAttrName,
// 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,
@ -2453,7 +2454,8 @@ nsSVGElement::GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName)
// 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')

View File

@ -2026,7 +2026,8 @@ nsDOMWindowUtils::ComputeAnimationDistance(nsIDOMElement* aElement,
// 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) &&

View File

@ -224,7 +224,8 @@ 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;

View File

@ -215,7 +215,8 @@ inDOMUtils::GetRuleLine(nsIDOMCSSStyleRule *aRule, PRUint32 *_retval)
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;

View File

@ -823,7 +823,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue) const
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;
}

View File

@ -1080,7 +1080,8 @@ CSSParserImpl::ParseProperty(const nsCSSProperty aPropID,
*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()
@ -4063,7 +4064,8 @@ CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
}
// 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[] = {

View File

@ -22,6 +22,8 @@
#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
@ -72,6 +74,50 @@ SortPropertyAndCount(const void* s1, const void* s2, void *closure)
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)
{
@ -116,6 +162,40 @@ nsCSSProps::AddRefTable(void)
}
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
}
}
}
@ -282,51 +362,9 @@ nsCSSProps::ReleaseTable(void)
}
}
// 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");
@ -337,17 +375,21 @@ nsCSSProps::LookupProperty(const nsACString& aProperty)
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
@ -360,12 +402,16 @@ nsCSSProps::LookupProperty(const nsAString& aProperty)
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;
}
@ -2376,3 +2422,17 @@ nsCSSProps::gPropertyIndexInStruct[eCSSProperty_COUNT_no_shorthands] = {
#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
};

View File

@ -150,8 +150,14 @@ public:
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,
@ -295,6 +301,17 @@ public:
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_) \

View File

@ -429,7 +429,8 @@ nsComputedDOMStyle::GetPropertyCSSValue(const nsAString& aPropertyName,
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;
{

View File

@ -161,7 +161,8 @@ 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;
@ -190,7 +191,8 @@ nsDOMCSSDeclaration::SetProperty(const nsAString& aPropertyName,
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;
}
@ -218,7 +220,8 @@ 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;

View File

@ -4347,7 +4347,8 @@ nsRuleNode::ComputeDisplayData(void* aStartStruct,
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 {

View File

@ -2101,7 +2101,8 @@ void nsTransition::SetInitialValues()
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;

View File

@ -40,7 +40,7 @@ TestProps()
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;
@ -54,7 +54,8 @@ TestProps()
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;
@ -69,7 +70,7 @@ TestProps()
// 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;