bool SVGAnimationElement::ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute, const nsAString& aValue, nsAttrValue& aResult) { if (aNamespaceID == kNameSpaceID_None) { // Deal with target-related attributes here if (aAttribute == nsGkAtoms::attributeName || aAttribute == nsGkAtoms::attributeType) { aResult.ParseAtom(aValue); AnimationNeedsResample(); return true; } nsresult rv = NS_ERROR_FAILURE; // First let the animation function try to parse it... bool foundMatch = AnimationFunction().SetAttr(aAttribute, aValue, aResult, &rv); // ... and if that didn't recognize the attribute, let the timed element // try to parse it. if (!foundMatch) { foundMatch = mTimedElement.SetAttr(aAttribute, aValue, aResult, this, &rv); } if (foundMatch) { AnimationNeedsResample(); if (NS_FAILED(rv)) { ReportAttributeParseFailure(OwnerDoc(), aAttribute, aValue); return false; } return true; } } return SVGAnimationElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue, aResult); }
PRBool nsSVGElement::ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute, const nsAString& aValue, nsAttrValue& aResult) { // Parse value nsCOMPtr<nsISVGValue> svg_value; const nsAttrValue* val = mAttrsAndChildren.GetAttr(aAttribute, aNamespaceID); if (val) { // Found the attr in the list. if (val->Type() == nsAttrValue::eSVGValue) { svg_value = val->GetSVGValue(); } } else { // Could be a mapped attribute. svg_value = GetMappedAttribute(aNamespaceID, aAttribute); } if (svg_value) { // We want to prevent DidModifySVGObservable from running if we // come in this route, otherwise AttributeChanged() gets called // twice (once through DidMOdifySVGObservable, once through SetAttr). mSuppressNotification = PR_TRUE; if (NS_FAILED(svg_value->SetValueString(aValue))) { // The value was rejected. This happens e.g. in a XUL template // when trying to set a value like "?x" on a value object that // expects a length. // To accommodate this "erroneous" value, we'll insert a proxy // object between ourselves and the actual value object: ReportAttributeParseFailure(GetOwnerDoc(), aAttribute, aValue); nsCOMPtr<nsISVGValue> proxy; nsresult rv = NS_CreateSVGStringProxyValue(svg_value, getter_AddRefs(proxy)); // Failure means we'll store this attr as a string, not an SVGValue, but // that's the best we can do short of throwing outright. NS_ENSURE_SUCCESS(rv, PR_FALSE); svg_value->RemoveObserver(this); ResetOldStyleBaseType(svg_value); proxy->SetValueString(aValue); proxy->AddObserver(this); aResult.SetTo(proxy); } else { aResult.SetTo(svg_value); } mSuppressNotification = PR_FALSE; return PR_TRUE; } nsresult rv = NS_OK; PRBool foundMatch = PR_FALSE; if (aNamespaceID == kNameSpaceID_None) { // Check for nsSVGLength2 attribute LengthAttributesInfo lengthInfo = GetLengthInfo(); PRUint32 i; for (i = 0; i < lengthInfo.mLengthCount; i++) { if (aAttribute == *lengthInfo.mLengthInfo[i].mName) { rv = lengthInfo.mLengths[i].SetBaseValueString(aValue, this, PR_FALSE); if (NS_FAILED(rv)) { lengthInfo.Reset(i); } foundMatch = PR_TRUE; break; } } if (!foundMatch) { // Check for nsSVGNumber2 attribute NumberAttributesInfo numberInfo = GetNumberInfo(); for (i = 0; i < numberInfo.mNumberCount; i++) { if (aAttribute == *numberInfo.mNumberInfo[i].mName) { if (i + 1 < numberInfo.mNumberCount && aAttribute == *numberInfo.mNumberInfo[i + 1].mName) { rv = ParseNumberOptionalNumber(aValue, i, i + 1); if (NS_FAILED(rv)) { numberInfo.Reset(i + 1); } } else { rv = numberInfo.mNumbers[i].SetBaseValueString(aValue, this, PR_FALSE); } if (NS_FAILED(rv)) { numberInfo.Reset(i); } foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Check for nsSVGInteger attribute IntegerAttributesInfo integerInfo = GetIntegerInfo(); for (i = 0; i < integerInfo.mIntegerCount; i++) { if (aAttribute == *integerInfo.mIntegerInfo[i].mName) { if (i + 1 < integerInfo.mIntegerCount && aAttribute == *integerInfo.mIntegerInfo[i + 1].mName) { rv = ParseIntegerOptionalInteger(aValue, i, i + 1); if (NS_FAILED(rv)) { integerInfo.Reset(i + 1); } } else { rv = integerInfo.mIntegers[i].SetBaseValueString(aValue, this, PR_FALSE); } if (NS_FAILED(rv)) { integerInfo.Reset(i); } foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Check for nsSVGAngle attribute AngleAttributesInfo angleInfo = GetAngleInfo(); for (i = 0; i < angleInfo.mAngleCount; i++) { if (aAttribute == *angleInfo.mAngleInfo[i].mName) { rv = angleInfo.mAngles[i].SetBaseValueString(aValue, this, PR_FALSE); if (NS_FAILED(rv)) { angleInfo.Reset(i); } foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Check for nsSVGBoolean attribute BooleanAttributesInfo booleanInfo = GetBooleanInfo(); for (i = 0; i < booleanInfo.mBooleanCount; i++) { if (aAttribute == *booleanInfo.mBooleanInfo[i].mName) { rv = booleanInfo.mBooleans[i].SetBaseValueString(aValue, this, PR_FALSE); if (NS_FAILED(rv)) { booleanInfo.Reset(i); } foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Check for nsSVGEnum attribute EnumAttributesInfo enumInfo = GetEnumInfo(); for (i = 0; i < enumInfo.mEnumCount; i++) { if (aAttribute == *enumInfo.mEnumInfo[i].mName) { rv = enumInfo.mEnums[i].SetBaseValueString(aValue, this, PR_FALSE); if (NS_FAILED(rv)) { enumInfo.Reset(i); } foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Check for nsSVGViewBox attribute if (aAttribute == nsGkAtoms::viewBox) { nsSVGViewBox* viewBox = GetViewBox(); if (viewBox) { rv = viewBox->SetBaseValueString(aValue, this, PR_FALSE); if (NS_FAILED(rv)) { viewBox->Init(); } foundMatch = PR_TRUE; } // Check for nsSVGPreserveAspectRatio attribute } else if (aAttribute == nsGkAtoms::preserveAspectRatio) { nsSVGPreserveAspectRatio *preserveAspectRatio = GetPreserveAspectRatio(); if (preserveAspectRatio) { rv = preserveAspectRatio->SetBaseValueString(aValue, this, PR_FALSE); if (NS_FAILED(rv)) { preserveAspectRatio->Init(); } foundMatch = PR_TRUE; } } } } if (!foundMatch) { // Check for nsSVGString attribute StringAttributesInfo stringInfo = GetStringInfo(); for (PRUint32 i = 0; i < stringInfo.mStringCount; i++) { if (aNamespaceID == stringInfo.mStringInfo[i].mNamespaceID && aAttribute == *stringInfo.mStringInfo[i].mName) { stringInfo.mStrings[i].SetBaseValue(aValue, this, PR_FALSE); foundMatch = PR_TRUE; break; } } } if (foundMatch) { if (NS_FAILED(rv)) { ReportAttributeParseFailure(GetOwnerDoc(), aAttribute, aValue); return PR_FALSE; } aResult.SetTo(aValue); return PR_TRUE; } return nsSVGElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue, aResult); }