зеркало из https://github.com/mozilla/gecko-dev.git
Bug 870022 - Part 1 - Split nsAttrValue::StringToInteger out to nsContentUtils, update usage. r=jst
This commit is contained in:
Родитель
eb0149fd3f
Коммит
02eb0d8e6f
|
@ -367,6 +367,19 @@ public:
|
||||||
*/
|
*/
|
||||||
static bool IsHTMLVoid(nsIAtom* aLocalName);
|
static bool IsHTMLVoid(nsIAtom* aLocalName);
|
||||||
|
|
||||||
|
enum ParseHTMLIntegerResultFlags {
|
||||||
|
eParseHTMLInteger_NoFlags = 0,
|
||||||
|
eParseHTMLInteger_IsPercent = 1 << 0,
|
||||||
|
eParseHTMLInteger_NonStandard = 1 << 1,
|
||||||
|
eParseHTMLInteger_DidNotConsumeAllInput = 1 << 2,
|
||||||
|
// Set if one or more error flags were set.
|
||||||
|
eParseHTMLInteger_Error = 1 << 3,
|
||||||
|
eParseHTMLInteger_ErrorNoValue = 1 << 4,
|
||||||
|
eParseHTMLInteger_ErrorOverflow = 1 << 5
|
||||||
|
};
|
||||||
|
static int32_t ParseHTMLInteger(const nsAString& aValue,
|
||||||
|
ParseHTMLIntegerResultFlags *aResult);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a margin string of format 'top, right, bottom, left' into
|
* Parse a margin string of format 'top, right, bottom, left' into
|
||||||
* an nsIntMargin.
|
* an nsIntMargin.
|
||||||
|
|
|
@ -1443,28 +1443,27 @@ nsAttrValue::ParseSpecialIntValue(const nsAString& aString)
|
||||||
{
|
{
|
||||||
ResetIfSet();
|
ResetIfSet();
|
||||||
|
|
||||||
nsresult ec;
|
|
||||||
bool strict;
|
|
||||||
bool isPercent = false;
|
|
||||||
nsAutoString tmp(aString);
|
nsAutoString tmp(aString);
|
||||||
int32_t originalVal = StringToInteger(aString, &strict, &ec, true, &isPercent);
|
nsContentUtils::ParseHTMLIntegerResultFlags result;
|
||||||
|
int32_t originalVal = nsContentUtils::ParseHTMLInteger(aString, &result);
|
||||||
|
|
||||||
if (NS_FAILED(ec)) {
|
if (result & nsContentUtils::eParseHTMLInteger_Error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isPercent = result & nsContentUtils::eParseHTMLInteger_IsPercent;
|
||||||
int32_t val = std::max(originalVal, 0);
|
int32_t val = std::max(originalVal, 0);
|
||||||
|
bool nonStrict = val != originalVal ||
|
||||||
|
(result & nsContentUtils::eParseHTMLInteger_NonStandard) ||
|
||||||
|
(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput);
|
||||||
|
|
||||||
// % (percent)
|
// % (percent)
|
||||||
if (isPercent || tmp.RFindChar('%') >= 0) {
|
if (isPercent || tmp.RFindChar('%') >= 0) {
|
||||||
isPercent = true;
|
isPercent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
strict = strict && (originalVal == val);
|
SetIntValueAndType(val, isPercent ? ePercent : eInteger,
|
||||||
|
nonStrict ? &aString : nullptr);
|
||||||
SetIntValueAndType(val,
|
|
||||||
isPercent ? ePercent : eInteger,
|
|
||||||
strict ? nullptr : &aString);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1476,17 +1475,20 @@ nsAttrValue::ParseIntWithBounds(const nsAString& aString,
|
||||||
|
|
||||||
ResetIfSet();
|
ResetIfSet();
|
||||||
|
|
||||||
nsresult ec;
|
nsContentUtils::ParseHTMLIntegerResultFlags result;
|
||||||
bool strict;
|
int32_t originalVal = nsContentUtils::ParseHTMLInteger(aString, &result);
|
||||||
int32_t originalVal = StringToInteger(aString, &strict, &ec);
|
if (result & nsContentUtils::eParseHTMLInteger_Error) {
|
||||||
if (NS_FAILED(ec)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t val = std::max(originalVal, aMin);
|
int32_t val = std::max(originalVal, aMin);
|
||||||
val = std::min(val, aMax);
|
val = std::min(val, aMax);
|
||||||
strict = strict && (originalVal == val);
|
bool nonStrict = (val != originalVal) ||
|
||||||
SetIntValueAndType(val, eInteger, strict ? nullptr : &aString);
|
(result & nsContentUtils::eParseHTMLInteger_IsPercent) ||
|
||||||
|
(result & nsContentUtils::eParseHTMLInteger_NonStandard) ||
|
||||||
|
(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput);
|
||||||
|
|
||||||
|
SetIntValueAndType(val, eInteger, nonStrict ? &aString : nullptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1496,14 +1498,17 @@ nsAttrValue::ParseNonNegativeIntValue(const nsAString& aString)
|
||||||
{
|
{
|
||||||
ResetIfSet();
|
ResetIfSet();
|
||||||
|
|
||||||
nsresult ec;
|
nsContentUtils::ParseHTMLIntegerResultFlags result;
|
||||||
bool strict;
|
int32_t originalVal = nsContentUtils::ParseHTMLInteger(aString, &result);
|
||||||
int32_t originalVal = StringToInteger(aString, &strict, &ec);
|
if ((result & nsContentUtils::eParseHTMLInteger_Error) || originalVal < 0) {
|
||||||
if (NS_FAILED(ec) || originalVal < 0) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetIntValueAndType(originalVal, eInteger, strict ? nullptr : &aString);
|
bool nonStrict = (result & nsContentUtils::eParseHTMLInteger_IsPercent) ||
|
||||||
|
(result & nsContentUtils::eParseHTMLInteger_NonStandard) ||
|
||||||
|
(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput);
|
||||||
|
|
||||||
|
SetIntValueAndType(originalVal, eInteger, nonStrict ? &aString : nullptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1513,14 +1518,17 @@ nsAttrValue::ParsePositiveIntValue(const nsAString& aString)
|
||||||
{
|
{
|
||||||
ResetIfSet();
|
ResetIfSet();
|
||||||
|
|
||||||
nsresult ec;
|
nsContentUtils::ParseHTMLIntegerResultFlags result;
|
||||||
bool strict;
|
int32_t originalVal = nsContentUtils::ParseHTMLInteger(aString, &result);
|
||||||
int32_t originalVal = StringToInteger(aString, &strict, &ec);
|
if ((result & nsContentUtils::eParseHTMLInteger_Error) || originalVal <= 0) {
|
||||||
if (NS_FAILED(ec) || originalVal <= 0) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetIntValueAndType(originalVal, eInteger, strict ? nullptr : &aString);
|
bool nonStrict = (result & nsContentUtils::eParseHTMLInteger_IsPercent) ||
|
||||||
|
(result & nsContentUtils::eParseHTMLInteger_NonStandard) ||
|
||||||
|
(result & nsContentUtils::eParseHTMLInteger_DidNotConsumeAllInput);
|
||||||
|
|
||||||
|
SetIntValueAndType(originalVal, eInteger, nonStrict ? &aString : nullptr);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1878,78 +1886,6 @@ nsAttrValue::GetStringBuffer(const nsAString& aValue) const
|
||||||
return buf.forget();
|
return buf.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
|
||||||
nsAttrValue::StringToInteger(const nsAString& aValue, bool* aStrict,
|
|
||||||
nsresult* aErrorCode,
|
|
||||||
bool aCanBePercent,
|
|
||||||
bool* aIsPercent) const
|
|
||||||
{
|
|
||||||
*aStrict = true;
|
|
||||||
*aErrorCode = NS_ERROR_ILLEGAL_VALUE;
|
|
||||||
if (aCanBePercent) {
|
|
||||||
*aIsPercent = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAString::const_iterator iter, end;
|
|
||||||
aValue.BeginReading(iter);
|
|
||||||
aValue.EndReading(end);
|
|
||||||
|
|
||||||
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
|
|
||||||
*aStrict = false;
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iter == end) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool negate = false;
|
|
||||||
if (*iter == char16_t('-')) {
|
|
||||||
negate = true;
|
|
||||||
++iter;
|
|
||||||
} else if (*iter == char16_t('+')) {
|
|
||||||
*aStrict = false;
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t value = 0;
|
|
||||||
int32_t pValue = 0; // Previous value, used to check integer overflow
|
|
||||||
while (iter != end) {
|
|
||||||
if (*iter >= char16_t('0') && *iter <= char16_t('9')) {
|
|
||||||
value = (value * 10) + (*iter - char16_t('0'));
|
|
||||||
++iter;
|
|
||||||
// Checking for integer overflow.
|
|
||||||
if (pValue > value) {
|
|
||||||
*aStrict = false;
|
|
||||||
*aErrorCode = NS_ERROR_ILLEGAL_VALUE;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
pValue = value;
|
|
||||||
*aErrorCode = NS_OK;
|
|
||||||
}
|
|
||||||
} else if (aCanBePercent && *iter == char16_t('%')) {
|
|
||||||
++iter;
|
|
||||||
*aIsPercent = true;
|
|
||||||
if (iter != end) {
|
|
||||||
*aStrict = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*aStrict = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (negate) {
|
|
||||||
value = -value;
|
|
||||||
// Checking the special case of -0.
|
|
||||||
if (!value) {
|
|
||||||
*aStrict = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -425,13 +425,6 @@ private:
|
||||||
bool EnsureEmptyAtomArray();
|
bool EnsureEmptyAtomArray();
|
||||||
already_AddRefed<nsStringBuffer>
|
already_AddRefed<nsStringBuffer>
|
||||||
GetStringBuffer(const nsAString& aValue) const;
|
GetStringBuffer(const nsAString& aValue) const;
|
||||||
// aStrict is set true if stringifying the return value equals with
|
|
||||||
// aValue.
|
|
||||||
int32_t StringToInteger(const nsAString& aValue,
|
|
||||||
bool* aStrict,
|
|
||||||
nsresult* aErrorCode,
|
|
||||||
bool aCanBePercent = false,
|
|
||||||
bool* aIsPercent = nullptr) const;
|
|
||||||
// Given an enum table and a particular entry in that table, return
|
// Given an enum table and a particular entry in that table, return
|
||||||
// the actual integer value we should store.
|
// the actual integer value we should store.
|
||||||
int32_t EnumTableEntryToValue(const EnumTable* aEnumTable,
|
int32_t EnumTableEntryToValue(const EnumTable* aEnumTable,
|
||||||
|
|
|
@ -878,6 +878,81 @@ nsContentUtils::InternalSerializeAutocompleteAttribute(const nsAttrValue* aAttrV
|
||||||
return eAutocompleteAttrState_Invalid;
|
return eAutocompleteAttrState_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse an integer according to HTML spec
|
||||||
|
int32_t
|
||||||
|
nsContentUtils::ParseHTMLInteger(const nsAString& aValue,
|
||||||
|
ParseHTMLIntegerResultFlags *aResult)
|
||||||
|
{
|
||||||
|
int result = eParseHTMLInteger_NoFlags;
|
||||||
|
|
||||||
|
nsAString::const_iterator iter, end;
|
||||||
|
aValue.BeginReading(iter);
|
||||||
|
aValue.EndReading(end);
|
||||||
|
|
||||||
|
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
|
||||||
|
result |= eParseHTMLInteger_NonStandard;
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter == end) {
|
||||||
|
result |= eParseHTMLInteger_Error | eParseHTMLInteger_ErrorNoValue;
|
||||||
|
*aResult = (ParseHTMLIntegerResultFlags)result;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool negate = false;
|
||||||
|
if (*iter == char16_t('-')) {
|
||||||
|
negate = true;
|
||||||
|
++iter;
|
||||||
|
} else if (*iter == char16_t('+')) {
|
||||||
|
result |= eParseHTMLInteger_NonStandard;
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool foundValue = false;
|
||||||
|
int32_t value = 0;
|
||||||
|
int32_t pValue = 0; // Previous value, used to check integer overflow
|
||||||
|
while (iter != end) {
|
||||||
|
if (*iter >= char16_t('0') && *iter <= char16_t('9')) {
|
||||||
|
value = (value * 10) + (*iter - char16_t('0'));
|
||||||
|
++iter;
|
||||||
|
// Checking for integer overflow.
|
||||||
|
if (pValue > value) {
|
||||||
|
result |= eParseHTMLInteger_Error | eParseHTMLInteger_ErrorOverflow;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
foundValue = true;
|
||||||
|
pValue = value;
|
||||||
|
}
|
||||||
|
} else if (*iter == char16_t('%')) {
|
||||||
|
++iter;
|
||||||
|
result |= eParseHTMLInteger_IsPercent;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundValue) {
|
||||||
|
result |= eParseHTMLInteger_Error | eParseHTMLInteger_ErrorNoValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (negate) {
|
||||||
|
value = -value;
|
||||||
|
// Checking the special case of -0.
|
||||||
|
if (!value) {
|
||||||
|
result |= eParseHTMLInteger_NonStandard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter != end) {
|
||||||
|
result |= eParseHTMLInteger_DidNotConsumeAllInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResult = (ParseHTMLIntegerResultFlags)result;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
#define SKIP_WHITESPACE(iter, end_iter, end_res) \
|
#define SKIP_WHITESPACE(iter, end_iter, end_res) \
|
||||||
while ((iter) != (end_iter) && nsCRT::IsAsciiSpace(*(iter))) { \
|
while ((iter) != (end_iter) && nsCRT::IsAsciiSpace(*(iter))) { \
|
||||||
++(iter); \
|
++(iter); \
|
||||||
|
|
Загрузка…
Ссылка в новой задаче