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; }
void nsAttrValue::SetTo(const nsAString& aValue) { ResetIfSet(); nsStringBuffer* buf = GetStringBuffer(aValue); if (buf) { SetPtrValueAndType(buf, eStringBase); } #ifdef TAINTED if(aValue.isTainted()==1){ #ifdef DEBUG printf("This Attribute is tainted! %x \n",this); #endif mTainted=1; mJSStr=aValue.getJSReference(); } #endif }
PRBool nsAttrValue::ParseColor(const nsAString& aString) { ResetIfSet(); // FIXME (partially, at least): HTML5's algorithm says we shouldn't do // the whitespace compression, trimming, or the test for emptiness. // (I'm a little skeptical that we shouldn't do the whitespace // trimming; WebKit also does it.) nsAutoString colorStr(aString); colorStr.CompressWhitespace(PR_TRUE, PR_TRUE); if (colorStr.IsEmpty()) { return PR_FALSE; } nscolor color; // No color names begin with a '#'; in standards mode, all acceptable // numeric colors do. if (colorStr.First() == '#') { nsDependentString withoutHash(colorStr.get() + 1, colorStr.Length() - 1); if (NS_HexToRGB(withoutHash, &color)) { SetColorValue(color, aString); return PR_TRUE; } } else { if (NS_ColorNameToRGB(colorStr, &color)) { SetColorValue(color, aString); return PR_TRUE; } } // FIXME (maybe): HTML5 says we should handle system colors. This // means we probably need another storage type, since we'd need to // handle dynamic changes. However, I think this is a bad idea: // http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2010-May/026449.html // Use NS_LooseHexToRGB as a fallback if nothing above worked. if (NS_LooseHexToRGB(colorStr, &color)) { SetColorValue(color, aString); return PR_TRUE; } return PR_FALSE; }
bool nsAttrValue::EnsureEmptyMiscContainer() { MiscContainer* cont; if (BaseType() == eOtherBase) { ResetMiscAtomOrString(); cont = GetMiscContainer(); switch (cont->mType) { case eCSSStyleRule: { NS_RELEASE(cont->mCSSStyleRule); break; } case eAtomArray: { delete cont->mAtomArray; break; } case eIntMarginValue: { delete cont->mIntMargin; break; } default: { break; } } } else { ResetIfSet(); cont = new MiscContainer; NS_ENSURE_TRUE(cont, PR_FALSE); SetPtrValueAndType(cont, eOtherBase); } cont->mType = eColor; cont->mStringBits = 0; cont->mColor = 0; return PR_TRUE; }
PRBool nsAttrValue::EnsureEmptyMiscContainer() { MiscContainer* cont; if (BaseType() == eOtherBase) { cont = GetMiscContainer(); switch (cont->mType) { case eCSSStyleRule: { NS_RELEASE(cont->mCSSStyleRule); break; } case eAtomArray: { delete cont->mAtomArray; break; } #ifdef MOZ_SVG case eSVGValue: { NS_RELEASE(cont->mSVGValue); break; } #endif default: { break; } } } else { ResetIfSet(); cont = new MiscContainer; NS_ENSURE_TRUE(cont, PR_FALSE); SetPtrValueAndType(cont, eOtherBase); } cont->mType = eColor; cont->mColor = 0; return PR_TRUE; }
PRBool nsAttrValue::ParseIntMarginValue(const nsAString& aString) { ResetIfSet(); nsIntMargin margins; if (!nsContentUtils::ParseIntMarginValue(aString, margins)) return PR_FALSE; if (EnsureEmptyMiscContainer()) { MiscContainer* cont = GetMiscContainer(); cont->mIntMargin = new nsIntMargin(margins); cont->mType = eIntMarginValue; SetMiscAtomOrString(&aString); return PR_TRUE; } return PR_FALSE; }
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::ParseDoubleValue(const nsAString& aString) { ResetIfSet(); PRInt32 ec; double val = PromiseFlatString(aString).ToDouble(&ec); if (NS_FAILED(ec)) { return PR_FALSE; } if (EnsureEmptyMiscContainer()) { MiscContainer* cont = GetMiscContainer(); cont->mDoubleValue = val; cont->mType = eDoubleValue; nsAutoString serializedFloat; serializedFloat.AppendFloat(val); SetMiscAtomOrString(serializedFloat.Equals(aString) ? nsnull : &aString); return PR_TRUE; } return PR_FALSE; }
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::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(); 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(const nsAttrValue& aOther) { switch (aOther.BaseType()) { case eStringBase: { ResetIfSet(); nsStringBuffer* str = static_cast<nsStringBuffer*>(aOther.GetPtr()); if (str) { str->AddRef(); SetPtrValueAndType(str, eStringBase); } #ifdef TAINTED if(aOther.isTainted()==1){ mTainted=1; mJSStr=aOther.mJSStr; } #endif return; } case eOtherBase: { break; } case eAtomBase: { ResetIfSet(); nsIAtom* atom = aOther.GetAtomValue(); NS_ADDREF(atom); SetPtrValueAndType(atom, eAtomBase); return; } case eIntegerBase: { ResetIfSet(); mBits = aOther.mBits; return; } } MiscContainer* otherCont = aOther.GetMiscContainer(); if (!EnsureEmptyMiscContainer()) { return; } MiscContainer* cont = GetMiscContainer(); switch (otherCont->mType) { case eInteger: { cont->mInteger = otherCont->mInteger; break; } case eEnum: { cont->mEnumValue = otherCont->mEnumValue; break; } case ePercent: { cont->mPercent = otherCont->mPercent; break; } case eColor: { cont->mColor = otherCont->mColor; break; } case eCSSStyleRule: { NS_ADDREF(cont->mCSSStyleRule = otherCont->mCSSStyleRule); break; } case eAtomArray: { if (!EnsureEmptyAtomArray() || !GetAtomArrayValue()->AppendElements(*otherCont->mAtomArray)) { Reset(); return; } break; } case eSVGValue: { NS_ADDREF(cont->mSVGValue = otherCont->mSVGValue); break; } case eDoubleValue: { cont->mDoubleValue = otherCont->mDoubleValue; break; } case eIntMarginValue: { if (otherCont->mIntMargin) cont->mIntMargin = new nsIntMargin(*otherCont->mIntMargin); break; } default: { NS_NOTREACHED("unknown type stored in MiscContainer"); break; } } void* otherPtr = MISC_STR_PTR(otherCont); if (otherPtr) { if (static_cast<ValueBaseType>(otherCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) == eStringBase) { static_cast<nsStringBuffer*>(otherPtr)->AddRef(); } else { static_cast<nsIAtom*>(otherPtr)->AddRef(); } cont->mStringBits = otherCont->mStringBits; } // Note, set mType after switch-case, otherwise EnsureEmptyAtomArray doesn't // work correctly. cont->mType = otherCont->mType; }
nsAttrValue::~nsAttrValue() { ResetIfSet(); }
void nsAttrValue::ParseAtomArray(const nsAString& aValue) { nsAString::const_iterator iter, end; aValue.BeginReading(iter); aValue.EndReading(end); // skip initial whitespace while (iter != end && nsCRT::IsAsciiSpace(*iter)) { ++iter; } if (iter == end) { ResetIfSet(); return; } nsAString::const_iterator start(iter); // get first - and often only - atom do { ++iter; } while (iter != end && !nsCRT::IsAsciiSpace(*iter)); nsCOMPtr<nsIAtom> classAtom = do_GetAtom(Substring(start, iter)); if (!classAtom) { Reset(); return; } // skip whitespace while (iter != end && nsCRT::IsAsciiSpace(*iter)) { ++iter; } if (iter == end) { // we only found one classname so don't bother storing a list ResetIfSet(); nsIAtom* atom = nsnull; classAtom.swap(atom); SetPtrValueAndType(atom, eAtomBase); return; } if (!EnsureEmptyAtomArray()) { return; } nsCOMArray<nsIAtom>* array = GetAtomArrayValue(); if (!array->AppendObject(classAtom)) { Reset(); return; } // parse the rest of the classnames do { start = iter; do { ++iter; } while (iter != end && !nsCRT::IsAsciiSpace(*iter)); classAtom = do_GetAtom(Substring(start, iter)); if (!array->AppendObject(classAtom)) { Reset(); return; } // skip whitespace while (iter != end && nsCRT::IsAsciiSpace(*iter)) { ++iter; } } while (iter != end); return; }
void nsAttrValue::SetTo(PRInt16 aInt) { ResetIfSet(); SetIntValueAndType(aInt, eInteger, nsnull); }
void nsAttrValue::ParseAtomArray(const nsAString& aValue) { nsAString::const_iterator iter, end; aValue.BeginReading(iter); aValue.EndReading(end); PRBool hasSpace = PR_FALSE; // skip initial whitespace while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) { hasSpace = PR_TRUE; ++iter; } if (iter == end) { SetTo(aValue); return; } nsAString::const_iterator start(iter); // get first - and often only - atom do { ++iter; } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter)); nsCOMPtr<nsIAtom> classAtom = do_GetAtom(Substring(start, iter)); if (!classAtom) { Reset(); return; } // skip whitespace while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) { hasSpace = PR_TRUE; ++iter; } if (iter == end && !hasSpace) { // we only found one classname and there was no whitespace so // don't bother storing a list ResetIfSet(); nsIAtom* atom = nsnull; classAtom.swap(atom); SetPtrValueAndType(atom, eAtomBase); return; } if (!EnsureEmptyAtomArray()) { return; } AtomArray* array = GetAtomArrayValue(); if (!array->AppendElement(classAtom)) { Reset(); return; } // parse the rest of the classnames while (iter != end) { start = iter; do { ++iter; } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter)); classAtom = do_GetAtom(Substring(start, iter)); if (!array->AppendElement(classAtom)) { Reset(); return; } // skip whitespace while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) { ++iter; } } SetMiscAtomOrString(&aValue); return; }
void nsAttrValue::SetTo(const nsAttrValue& aOther) { switch (aOther.BaseType()) { case eStringBase: { ResetIfSet(); nsStringBuffer* str = static_cast<nsStringBuffer*>(aOther.GetPtr()); if (str) { str->AddRef(); SetPtrValueAndType(str, eStringBase); } return; } case eOtherBase: { break; } case eAtomBase: { ResetIfSet(); nsIAtom* atom = aOther.GetAtomValue(); NS_ADDREF(atom); SetPtrValueAndType(atom, eAtomBase); return; } case eIntegerBase: { ResetIfSet(); mBits = aOther.mBits; return; } } MiscContainer* otherCont = aOther.GetMiscContainer(); switch (otherCont->mType) { case eColor: { if (EnsureEmptyMiscContainer()) { MiscContainer* cont = GetMiscContainer(); cont->mColor = otherCont->mColor; cont->mType = eColor; } break; } case eCSSStyleRule: { SetTo(otherCont->mCSSStyleRule); break; } case eAtomArray: { if (!EnsureEmptyAtomArray() || !GetAtomArrayValue()->AppendObjects(*otherCont->mAtomArray)) { Reset(); } break; } #ifdef MOZ_SVG case eSVGValue: { SetTo(otherCont->mSVGValue); } #endif default: { NS_NOTREACHED("unknown type stored in MiscContainer"); break; } } }