PRBool nsAttrValue::ParseSpecialIntValue(const nsAString& aString, PRBool aCanBePercent) { ResetIfSet(); PRInt32 ec; nsAutoString tmp(aString); PRInt32 val = tmp.ToInteger(&ec); if (NS_FAILED(ec)) { return PR_FALSE; } val = PR_MAX(val, 0); val = PR_MIN(val, NS_ATTRVALUE_INTEGERTYPE_MAXVALUE); // % (percent) // XXX RFindChar means that 5%x will be parsed! if (aCanBePercent && tmp.RFindChar('%') >= 0) { if (val > 100) { val = 100; } SetIntValueAndType(val, ePercent); return PR_TRUE; } // Straight number is interpreted as integer SetIntValueAndType(val, eInteger); return PR_TRUE; }
PRBool nsAttrValue::ParseSpecialIntValue(const nsAString& aString) { ResetIfSet(); PRInt32 ec; PRBool strict; PRBool isPercent = PR_FALSE; nsAutoString tmp(aString); PRInt32 originalVal = StringToInteger(aString, &strict, &ec, PR_TRUE, &isPercent); if (NS_FAILED(ec)) { return PR_FALSE; } PRInt32 val = NS_MAX(originalVal, 0); // % (percent) if (isPercent || tmp.RFindChar('%') >= 0) { isPercent = PR_TRUE; } strict = strict && (originalVal == val); SetIntValueAndType(val, isPercent ? ePercent : eInteger, strict ? nsnull : &aString); return PR_TRUE; }
PRBool nsAttrValue::ParseEnumValue(const nsAString& aValue, const EnumTable* aTable, PRBool aCaseSensitive, const EnumTable* aDefaultValue) { ResetIfSet(); const EnumTable* tableEntry = aTable; while (tableEntry->tag) { if (aCaseSensitive ? aValue.EqualsASCII(tableEntry->tag) : aValue.LowerCaseEqualsASCII(tableEntry->tag)) { PRInt32 value = EnumTableEntryToValue(aTable, tableEntry); PRBool equals = aCaseSensitive || aValue.EqualsASCII(tableEntry->tag); if (!equals) { nsAutoString tag; tag.AssignASCII(tableEntry->tag); ToUpperCase(tag); if ((equals = tag.Equals(aValue))) { value |= NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER; } } SetIntValueAndType(value, eEnum, equals ? nsnull : &aValue); NS_ASSERTION(GetEnumValue() == tableEntry->value, "failed to store enum properly"); return PR_TRUE; } tableEntry++; } if (aDefaultValue) { NS_PRECONDITION(aTable <= aDefaultValue && aDefaultValue < tableEntry, "aDefaultValue not inside aTable?"); SetIntValueAndType(EnumTableEntryToValue(aTable, aDefaultValue), eEnum, &aValue); return PR_TRUE; } return PR_FALSE; }
PRBool nsAttrValue::ParseColor(const nsAString& aString, nsIDocument* aDocument) { nsAutoString colorStr(aString); colorStr.CompressWhitespace(PR_TRUE, PR_TRUE); if (colorStr.IsEmpty()) { Reset(); return PR_FALSE; } nscolor color; // No color names begin with a '#', but numerical colors do so // it is a very common first char if ((colorStr.CharAt(0) != '#') && NS_ColorNameToRGB(colorStr, &color)) { SetTo(colorStr); return PR_TRUE; } // Check if we are in compatibility mode if (aDocument->GetCompatibilityMode() == eCompatibility_NavQuirks) { NS_LooseHexToRGB(colorStr, &color); } else { if (colorStr.First() != '#') { Reset(); return PR_FALSE; } colorStr.Cut(0, 1); if (!NS_HexToRGB(colorStr, &color)) { Reset(); return PR_FALSE; } } PRInt32 colAsInt = static_cast<PRInt32>(color); PRInt32 tmp = colAsInt * NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER; if (tmp / NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER == colAsInt) { ResetIfSet(); SetIntValueAndType(colAsInt, eColor); } else if (EnsureEmptyMiscContainer()) { MiscContainer* cont = GetMiscContainer(); cont->mColor = color; cont->mType = eColor; } return PR_TRUE; }
PRBool nsAttrValue::ParsePositiveIntValue(const nsAString& aString) { ResetIfSet(); PRInt32 ec; PRBool strict; PRInt32 originalVal = StringToInteger(aString, &strict, &ec); if (NS_FAILED(ec) || originalVal <= 0) { return PR_FALSE; } SetIntValueAndType(originalVal, eInteger, nsnull); return PR_TRUE; }
PRBool nsAttrValue::ParseIntWithBounds(const nsAString& aString, PRInt32 aMin, PRInt32 aMax) { NS_PRECONDITION(aMin < aMax, "bad boundaries"); ResetIfSet(); PRInt32 ec; PRBool strict; PRInt32 originalVal = StringToInteger(aString, &strict, &ec); if (NS_FAILED(ec)) { return PR_FALSE; } PRInt32 val = NS_MAX(originalVal, aMin); val = NS_MIN(val, aMax); strict = strict && (originalVal == val); SetIntValueAndType(val, eInteger, strict ? nsnull : &aString); return PR_TRUE; }
PRBool nsAttrValue::ParseEnumValue(const nsAString& aValue, const EnumTable* aTable, PRBool aCaseSensitive) { ResetIfSet(); const EnumTable* tableEntry = aTable; while (tableEntry->tag) { if (aCaseSensitive ? aValue.EqualsASCII(tableEntry->tag) : aValue.LowerCaseEqualsASCII(tableEntry->tag)) { PRInt16 index; if (!GetEnumTableIndex(aTable, index)) { return PR_FALSE; } PRInt32 value = (tableEntry->value << NS_ATTRVALUE_ENUMTABLEINDEX_BITS) + index; PRBool equals = aCaseSensitive || aValue.EqualsASCII(tableEntry->tag); if (!equals) { nsAutoString tag; tag.AssignASCII(tableEntry->tag); ToUpperCase(tag); if ((equals = tag.Equals(aValue))) { value |= NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER; } } SetIntValueAndType(value, eEnum, equals ? nsnull : &aValue); NS_ASSERTION(GetEnumValue() == tableEntry->value, "failed to store enum properly"); return PR_TRUE; } tableEntry++; } return PR_FALSE; }
PRBool nsAttrValue::ParseIntWithBounds(const nsAString& aString, PRInt32 aMin, PRInt32 aMax) { NS_PRECONDITION(aMin < aMax && aMin >= NS_ATTRVALUE_INTEGERTYPE_MINVALUE && aMax <= NS_ATTRVALUE_INTEGERTYPE_MAXVALUE, "bad boundaries"); ResetIfSet(); PRInt32 ec; PRInt32 val = PromiseFlatString(aString).ToInteger(&ec); if (NS_FAILED(ec)) { return PR_FALSE; } val = PR_MAX(val, aMin); val = PR_MIN(val, aMax); SetIntValueAndType(val, eInteger); return PR_TRUE; }
PRBool nsAttrValue::ParseEnumValue(const nsAString& aValue, const EnumTable* aTable, PRBool aCaseSensitive) { ResetIfSet(); while (aTable->tag) { if (aCaseSensitive ? aValue.EqualsASCII(aTable->tag) : aValue.LowerCaseEqualsASCII(aTable->tag)) { // Find index of EnumTable PRInt16 index = sEnumTableArray->IndexOf(aTable); if (index < 0) { index = sEnumTableArray->Length(); NS_ASSERTION(index <= NS_ATTRVALUE_ENUMTABLEINDEX_MAXVALUE, "too many enum tables"); if (!sEnumTableArray->AppendElement(aTable)) { return PR_FALSE; } } PRInt32 value = (aTable->value << NS_ATTRVALUE_ENUMTABLEINDEX_BITS) + index; SetIntValueAndType(value, eEnum); NS_ASSERTION(GetEnumValue() == aTable->value, "failed to store enum properly"); return PR_TRUE; } aTable++; } return PR_FALSE; }
void nsAttrValue::SetTo(PRInt16 aInt) { ResetIfSet(); SetIntValueAndType(aInt, eInteger, nsnull); }