Bug 784466 - [css3-animations] Drop declarations in keyframe rules that have !important. r=dbaron

This commit is contained in:
Emmanuele Bassi 2012-10-16 09:21:35 -07:00
parent 5554aa327e
commit c8c63750f6
3 changed files with 77 additions and 25 deletions

View File

@ -396,11 +396,16 @@ protected:
bool ParseSelectorGroup(nsCSSSelectorList*& aListHead);
bool ParseSelector(nsCSSSelectorList* aList, PRUnichar aPrevCombinator);
css::Declaration* ParseDeclarationBlock(bool aCheckForBraces);
enum {
eParseDeclaration_InBraces = 1 << 0,
eParseDeclaration_AllowImportant = 1 << 1
};
css::Declaration* ParseDeclarationBlock(uint32_t aFlags);
bool ParseDeclaration(css::Declaration* aDeclaration,
bool aCheckForBraces,
bool aMustCallValueAppended,
bool* aChanged);
uint32_t aFlags,
bool aMustCallValueAppended,
bool* aChanged);
bool ParseProperty(nsCSSProperty aPropID);
bool ParsePropertyByFunction(nsCSSProperty aPropID);
@ -987,7 +992,12 @@ CSSParserImpl::ParseStyleAttribute(const nsAString& aAttributeValue,
haveBraces = false;
}
css::Declaration* declaration = ParseDeclarationBlock(haveBraces);
uint32_t parseFlags = eParseDeclaration_AllowImportant;
if (haveBraces) {
parseFlags |= eParseDeclaration_InBraces;
}
css::Declaration* declaration = ParseDeclarationBlock(parseFlags);
if (declaration) {
// Create a style rule for the declaration
NS_ADDREF(*aResult = new css::StyleRule(nullptr, declaration));
@ -1026,7 +1036,8 @@ CSSParserImpl::ParseDeclarations(const nsAString& aBuffer,
for (;;) {
// If we cleared the old decl, then we want to be calling
// ValueAppended as we parse.
if (!ParseDeclaration(aDeclaration, false, true, aChanged)) {
if (!ParseDeclaration(aDeclaration, eParseDeclaration_AllowImportant,
true, aChanged)) {
if (!SkipDeclaration(false)) {
break;
}
@ -2301,7 +2312,9 @@ CSSParserImpl::ParseKeyframeRule()
return nullptr;
}
nsAutoPtr<css::Declaration> declaration(ParseDeclarationBlock(true));
// Ignore !important in keyframe rules
uint32_t parseFlags = eParseDeclaration_InBraces;
nsAutoPtr<css::Declaration> declaration(ParseDeclarationBlock(parseFlags));
if (!declaration) {
REPORT_UNEXPECTED(PEBadSelectorKeyframeRuleIgnored);
return nullptr;
@ -2757,7 +2770,9 @@ CSSParserImpl::ParseRuleSet(RuleAppendFunc aAppendFunc, void* aData,
CLEAR_ERROR();
// Next parse the declaration block
css::Declaration* declaration = ParseDeclarationBlock(true);
uint32_t parseFlags = eParseDeclaration_InBraces |
eParseDeclaration_AllowImportant;
css::Declaration* declaration = ParseDeclarationBlock(parseFlags);
if (nullptr == declaration) {
delete slist;
return false;
@ -3877,9 +3892,11 @@ CSSParserImpl::ParseSelector(nsCSSSelectorList* aList,
}
css::Declaration*
CSSParserImpl::ParseDeclarationBlock(bool aCheckForBraces)
CSSParserImpl::ParseDeclarationBlock(uint32_t aFlags)
{
if (aCheckForBraces) {
bool checkForBraces = (aFlags & eParseDeclaration_InBraces) != 0;
if (checkForBraces) {
if (!ExpectSymbol('{', true)) {
REPORT_UNEXPECTED_TOKEN(PEBadDeclBlockStart);
OUTPUT_ERROR();
@ -3891,12 +3908,11 @@ CSSParserImpl::ParseDeclarationBlock(bool aCheckForBraces)
if (declaration) {
for (;;) {
bool changed;
if (!ParseDeclaration(declaration, aCheckForBraces,
true, &changed)) {
if (!SkipDeclaration(aCheckForBraces)) {
if (!ParseDeclaration(declaration, aFlags, true, &changed)) {
if (!SkipDeclaration(checkForBraces)) {
break;
}
if (aCheckForBraces) {
if (checkForBraces) {
if (ExpectSymbol('}', true)) {
break;
}
@ -4281,10 +4297,12 @@ CSSParserImpl::ParseTreePseudoElement(nsAtomList **aPseudoElementArgs)
bool
CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
bool aCheckForBraces,
uint32_t aFlags,
bool aMustCallValueAppended,
bool* aChanged)
{
bool checkForBraces = (aFlags & eParseDeclaration_InBraces) != 0;
mTempData.AssertInitialState();
// Get property name
@ -4292,7 +4310,7 @@ CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
nsAutoString propertyName;
for (;;) {
if (!GetToken(true)) {
if (aCheckForBraces) {
if (checkForBraces) {
REPORT_UNEXPECTED_EOF(PEDeclEndEOF);
}
return false;
@ -4353,7 +4371,13 @@ CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
CLEAR_ERROR();
// Look for "!important".
PriorityParsingStatus status = ParsePriority();
PriorityParsingStatus status;
if ((aFlags & eParseDeclaration_AllowImportant) != 0) {
status = ParsePriority();
}
else {
status = ePriority_None;
}
// Look for a semicolon or close brace.
if (status != ePriority_Error) {
@ -4362,9 +4386,9 @@ CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
} else if (mToken.IsSymbol(';')) {
// semicolon is always ok
} else if (mToken.IsSymbol('}')) {
// brace is ok if aCheckForBraces, but don't eat it
// brace is ok if checkForBraces, but don't eat it
UngetToken();
if (!aCheckForBraces) {
if (!checkForBraces) {
status = ePriority_Error;
}
} else {
@ -4374,7 +4398,7 @@ CSSParserImpl::ParseDeclaration(css::Declaration* aDeclaration,
}
if (status == ePriority_Error) {
if (aCheckForBraces) {
if (checkForBraces) {
REPORT_UNEXPECTED_TOKEN(PEBadDeclOrRuleEnd2);
} else {
REPORT_UNEXPECTED_TOKEN(PEBadDeclEnd);

View File

@ -1982,11 +1982,10 @@ nsCSSKeyframeRule::MapRuleInfoInto(nsRuleData* aRuleData)
// constructs a rule node pointing to us in order to compute the
// styles it needs to animate.
// FIXME (spec): The spec doesn't say what to do with !important.
// We'll just map them.
if (mDeclaration->HasImportantData()) {
mDeclaration->MapImportantRuleInfoInto(aRuleData);
}
// The spec says that !important declarations should just be ignored
NS_ASSERTION(!mDeclaration->HasImportantData(),
"Keyframe rules has !important data");
mDeclaration->MapNormalRuleInfoInto(aRuleData);
}

View File

@ -112,6 +112,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=435442
to { -moz-transform: rotate(270deg) translate3d(0px, 0px, 0px) scale(1)
translateY(0px) scaleY(1); }
}
@keyframes important1 {
from { margin-top: 50px; }
50% { margin-top: 150px !important; } /* ignored */
to { margin-top: 100px; }
}
@keyframes important2 {
from { margin-top: 50px;
margin-bottom: 100px; }
to { margin-top: 150px !important; /* ignored */
margin-bottom: 50px; }
}
</style>
</head>
<body>
@ -1422,6 +1435,22 @@ is(cs.getPropertyValue("-moz-transform"), "matrix(0, -1, 1, 0, 0, 0)",
"primitives1 at 0s");
done_div();
new_div("animation: important1 1s linear forwards");
is(cs.marginTop, "50px", "important1 test at 0s");
advance_clock(500);
is(cs.marginTop, "75px", "important1 test at 0.5s");
advance_clock(500);
is(cs.marginTop, "100px", "important1 test at 1s");
done_div();
new_div("animation: important2 1s linear forwards");
is(cs.marginTop, "50px", "important2 (margin-top) test at 0s");
is(cs.marginBottom, "100px", "important2 (margin-bottom) test at 0s");
advance_clock(1000);
is(cs.marginTop, "0px", "important2 (margin-top) test at 1s");
is(cs.marginBottom, "50px", "important2 (margin-bottom) test at 1s");
done_div();
SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
</script>