Bug 703992 - Fix parsing of indefinite times; r=dholbert

This commit is contained in:
Brian Birtles 2011-12-01 08:45:28 +09:00
parent cc9cc9085f
commit 7e4679553e
4 changed files with 34 additions and 26 deletions

View File

@ -257,7 +257,8 @@ ParseOptionalOffset(const nsAString& aSpec, nsSMILTimeValueSpecParams& aResult)
if (aSpec.First() != '+' && aSpec.First() != '-')
return NS_ERROR_FAILURE;
return nsSMILParserUtils::ParseClockValue(aSpec, &aResult.mOffset, true);
return nsSMILParserUtils::ParseClockValue(aSpec, &aResult.mOffset,
nsSMILParserUtils::kClockValueAllowSign);
}
nsresult
@ -686,7 +687,8 @@ nsSMILParserUtils::ParseTimeValueSpecParams(const nsAString& aSpec,
// offset type
if (*start == '+' || *start == '-' || NS_IsAsciiDigit(*start)) {
rv = ParseClockValue(spec, &aResult.mOffset, true);
rv = ParseClockValue(spec, &aResult.mOffset,
nsSMILParserUtils::kClockValueAllowSign);
if (NS_SUCCEEDED(rv)) {
aResult.mType = nsSMILTimeValueSpecParams::OFFSET;
}
@ -729,6 +731,8 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
PRInt8 sign = 0;
PRUint8 colonCount = 0;
// Indicates we have started parsing a clock-value (not including the optional
// +/- that precedes the clock-value) or keyword ("media", "indefinite")
bool started = false;
PRInt32 metricMultiplicand = MSEC_PER_SEC;
@ -749,25 +753,17 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
while (start != end) {
if (IsSpace(*start)) {
++start;
if (started) {
++start;
break;
}
// else, we haven't started yet, ignore initial whitespace
++start;
} else if ((aFlags & kClockValueAllowSign)
&& (*start == '+' || *start == '-')) {
// check sign has not already been set
} else if (!started && (aFlags & kClockValueAllowSign) &&
(*start == '+' || *start == '-')) {
// check sign has not already been set (e.g. ++10s)
if (sign != 0) {
return NS_ERROR_FAILURE;
}
// check sign is not in middle of string
if (started) {
return NS_ERROR_FAILURE;
}
sign = (*start == '+') ? 1 : -1;
++start;
// The NS_IS_DIGIT etc. macros are not locale-specific
@ -775,11 +771,11 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
prevNumCouldBeMin = numCouldBeMin;
if (!ParseClockComponent(start, end, component, numIsReal, numCouldBeMin,
numCouldBeSec))
numCouldBeSec)) {
return NS_ERROR_FAILURE;
}
started = true;
} else if (*start == ':') {
} else if (started && *start == ':') {
++colonCount;
// Neither minutes nor hours can be reals
@ -787,11 +783,6 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
return NS_ERROR_FAILURE;
}
// Clock value can't start with a ':'
if (!started) {
return NS_ERROR_FAILURE;
}
// Can't have more than two colons
if (colonCount > 2) {
return NS_ERROR_FAILURE;
@ -807,8 +798,8 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
return NS_ERROR_FAILURE;
}
if ((aFlags & kClockValueAllowIndefinite)
&& ConsumeSubstring(start, end, "indefinite")) {
if (!started && (aFlags & kClockValueAllowIndefinite) &&
ConsumeSubstring(start, end, "indefinite")) {
// We set a separate flag because we don't know what the state of the
// passed in time value is and we shouldn't change it in the case of a
// bad input string (so we can't initialise it to 0ms for example).
@ -816,8 +807,11 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
if (aResult) {
aResult->SetIndefinite();
}
} else if (aIsMedia && ConsumeSubstring(start, end, "media")) {
started = true;
} else if (!started && aIsMedia &&
ConsumeSubstring(start, end, "media")) {
*aIsMedia = true;
started = true;
} else if (!ParseMetricMultiplicand(start, end, metricMultiplicand)) {
return NS_ERROR_FAILURE;
}
@ -829,6 +823,7 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
}
}
// Whitespace/empty string
if (!started) {
return NS_ERROR_FAILURE;
}
@ -855,7 +850,7 @@ nsSMILParserUtils::ParseClockValue(const nsAString& aSpec,
// Tack on the last component
if (colonCount > 0) {
offset = offset * 60 * 1000;
offset *= 60 * 1000;
component *= 1000;
// rounding
component = (component >= 0) ? component + 0.5 : component - 0.5;

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg">
<rect width="100" height="100" fill="green"/>
</svg>

After

Width:  |  Height:  |  Size: 96 B

View File

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="reftest-wait"
onload="setTimeAndSnapshot(5)">
<script xlink:href="../smil-util.js" type="text/javascript"/>
<rect width="100" height="100" fill="red">
<set attributeName="fill" to="green" dur="1s" repeatDur="indefinite"/>
</rect>
</svg>

After

Width:  |  Height:  |  Size: 343 B

View File

@ -1,2 +1,3 @@
# Tests for repeat behaviour
== indefinite-repeat-1.svg green-box-ref.svg
== init-repeat-1.svg init-repeat-1-ref.svg