nsISMILAttr* nsSVGElement::GetAnimatedAttr(const nsIAtom* aName) { // Transforms: if (aName == nsGkAtoms::transform) { nsCOMPtr<nsIDOMSVGTransformable> transformable( do_QueryInterface(static_cast<nsIContent*>(this))); if (!transformable) return nsnull; nsCOMPtr<nsIDOMSVGAnimatedTransformList> transformList; nsresult rv = transformable->GetTransform(getter_AddRefs(transformList)); NS_ENSURE_SUCCESS(rv, nsnull); nsSVGAnimatedTransformList* list = static_cast<nsSVGAnimatedTransformList*>(transformList.get()); NS_ENSURE_TRUE(list, nsnull); return new nsSVGTransformSMILAttr(list, this); } // Lengths: LengthAttributesInfo info = GetLengthInfo(); for (PRUint32 i = 0; i < info.mLengthCount; i++) { if (aName == *info.mLengthInfo[i].mName) { return info.mLengths[i].ToSMILAttr(this); } } return nsnull; }
void nsSVGElement::DidAnimateLength(PRUint8 aAttrEnum) { nsIFrame* frame = GetPrimaryFrame(); if (frame) { LengthAttributesInfo info = GetLengthInfo(); frame->AttributeChanged(kNameSpaceID_None, *info.mLengthInfo[aAttrEnum].mName, nsIDOMMutationEvent::MODIFICATION); } }
bool nsSVGPathGeometryElement::AttributeDefinesGeometry(const nsIAtom *aName) { // Check for nsSVGLength2 attribute LengthAttributesInfo info = GetLengthInfo(); for (uint32_t i = 0; i < info.mLengthCount; i++) { if (aName == *info.mLengthInfo[i].mName) { return true; } } return false; }
PRBool nsSVGPathGeometryElement::AttributeDefinesGeometry(const nsIAtom *aName) { // Check for nsSVGLength2 attribute LengthAttributesInfo info = GetLengthInfo(); for (PRUint32 i = 0; i < info.mLengthCount; i++) { if (aName == *info.mLengthInfo[i].mName) { return PR_TRUE; } } return PR_FALSE; }
void nsSVGElement::DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr) { if (!aDoSetAttr) return; LengthAttributesInfo info = GetLengthInfo(); NS_ASSERTION(info.mLengthCount > 0, "DidChangeLength on element with no length attribs"); NS_ASSERTION(aAttrEnum < info.mLengthCount, "aAttrEnum out of range"); nsAutoString newStr; info.mLengths[aAttrEnum].GetBaseValueString(newStr); SetAttr(kNameSpaceID_None, *info.mLengthInfo[aAttrEnum].mName, newStr, PR_TRUE); }
void nsSVGElement::GetAnimatedLengthValues(float *aFirst, ...) { #ifdef MOZ_SMIL FlushAnimations(); #endif LengthAttributesInfo info = GetLengthInfo(); NS_ASSERTION(info.mLengthCount > 0, "GetAnimatedLengthValues on element with no length attribs"); nsSVGSVGElement *ctx = nsnull; float *f = aFirst; PRUint32 i = 0; va_list args; va_start(args, aFirst); while (f && i < info.mLengthCount) { PRUint8 type = info.mLengths[i].GetSpecifiedUnitType(); if (!ctx) { if (type != nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER && type != nsIDOMSVGLength::SVG_LENGTHTYPE_PX) ctx = GetCtx(); } if (type == nsIDOMSVGLength::SVG_LENGTHTYPE_EMS || type == nsIDOMSVGLength::SVG_LENGTHTYPE_EXS) *f = info.mLengths[i++].GetAnimValue(this); else *f = info.mLengths[i++].GetAnimValue(ctx); f = va_arg(args, float*); } va_end(args); }
nsresult nsSVGElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName, PRBool aNotify) { PRBool foundMatch = PR_FALSE; if (aNamespaceID == kNameSpaceID_None) { // If this is an svg presentation attribute, remove rule to force an update if (IsAttributeMapped(aName)) mContentStyleRule = nsnull; if (IsEventName(aName)) { nsIEventListenerManager* manager = GetListenerManager(PR_FALSE); if (manager) { nsIAtom* eventName = GetEventNameForAttr(aName); manager->RemoveScriptEventListener(eventName); } foundMatch = PR_TRUE; } if (!foundMatch) { // Check if this is a length attribute going away LengthAttributesInfo lenInfo = GetLengthInfo(); for (PRUint32 i = 0; i < lenInfo.mLengthCount; i++) { if (aName == *lenInfo.mLengthInfo[i].mName) { lenInfo.Reset(i); DidChangeLength(i, PR_FALSE); foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Check if this is a number attribute going away NumberAttributesInfo numInfo = GetNumberInfo(); for (PRUint32 i = 0; i < numInfo.mNumberCount; i++) { if (aName == *numInfo.mNumberInfo[i].mName) { if (i + 1 < numInfo.mNumberCount && aName == *numInfo.mNumberInfo[i + 1].mName) { // found a number-optional-number numInfo.Reset(i + 1); DidChangeNumber(i + 1, PR_FALSE); } numInfo.Reset(i); DidChangeNumber(i, PR_FALSE); foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Check if this is an integer attribute going away IntegerAttributesInfo intInfo = GetIntegerInfo(); for (PRUint32 i = 0; i < intInfo.mIntegerCount; i++) { if (aName == *intInfo.mIntegerInfo[i].mName) { if (i + 1 < intInfo.mIntegerCount && aName == *intInfo.mIntegerInfo[i + 1].mName) { // found a number-optional-number intInfo.Reset(i + 1); DidChangeNumber(i + 1, PR_FALSE); } intInfo.Reset(i); DidChangeInteger(i, PR_FALSE); foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Check if this is an angle attribute going away AngleAttributesInfo angleInfo = GetAngleInfo(); for (PRUint32 i = 0; i < angleInfo.mAngleCount; i++) { if (aName == *angleInfo.mAngleInfo[i].mName) { angleInfo.Reset(i); DidChangeAngle(i, PR_FALSE); foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Check if this is a boolean attribute going away BooleanAttributesInfo boolInfo = GetBooleanInfo(); for (PRUint32 i = 0; i < boolInfo.mBooleanCount; i++) { if (aName == *boolInfo.mBooleanInfo[i].mName) { boolInfo.Reset(i); DidChangeBoolean(i, PR_FALSE); foundMatch = PR_TRUE; } } } if (!foundMatch) { // Check if this is an enum attribute going away EnumAttributesInfo enumInfo = GetEnumInfo(); for (PRUint32 i = 0; i < enumInfo.mEnumCount; i++) { if (aName == *enumInfo.mEnumInfo[i].mName) { enumInfo.Reset(i); DidChangeEnum(i, PR_FALSE); foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Check if this is a nsViewBox attribute going away if (aName == nsGkAtoms::viewBox) { nsSVGViewBox* viewBox = GetViewBox(); if (viewBox) { viewBox->Init(); DidChangeViewBox(PR_FALSE); foundMatch = PR_TRUE; } // Check if this is a preserveAspectRatio attribute going away } else if (aName == nsGkAtoms::preserveAspectRatio) { nsSVGPreserveAspectRatio *preserveAspectRatio = GetPreserveAspectRatio(); if (preserveAspectRatio) { preserveAspectRatio->Init(); DidChangePreserveAspectRatio(PR_FALSE); foundMatch = PR_TRUE; } } } } if (!foundMatch) { // Check if this is a string attribute going away StringAttributesInfo stringInfo = GetStringInfo(); for (PRUint32 i = 0; i < stringInfo.mStringCount; i++) { if (aNamespaceID == stringInfo.mStringInfo[i].mNamespaceID && aName == *stringInfo.mStringInfo[i].mName) { stringInfo.Reset(i); DidChangeString(i); foundMatch = PR_TRUE; break; } } } if (!foundMatch) { // Now check for one of the old style basetypes going away nsCOMPtr<nsISVGValue> svg_value = GetMappedAttribute(aNamespaceID, aName); if (svg_value) { mSuppressNotification = PR_TRUE; ResetOldStyleBaseType(svg_value); mSuppressNotification = PR_FALSE; } } return nsSVGElementBase::UnsetAttr(aNamespaceID, aName, aNotify); }
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); }
nsresult nsSVGElement::Init() { // Set up length attributes - can't do this in the constructor // because we can't do a virtual call at that point LengthAttributesInfo lengthInfo = GetLengthInfo(); PRUint32 i; for (i = 0; i < lengthInfo.mLengthCount; i++) { lengthInfo.Reset(i); } NumberAttributesInfo numberInfo = GetNumberInfo(); for (i = 0; i < numberInfo.mNumberCount; i++) { numberInfo.Reset(i); } IntegerAttributesInfo integerInfo = GetIntegerInfo(); for (i = 0; i < integerInfo.mIntegerCount; i++) { integerInfo.Reset(i); } AngleAttributesInfo angleInfo = GetAngleInfo(); for (i = 0; i < angleInfo.mAngleCount; i++) { angleInfo.Reset(i); } BooleanAttributesInfo booleanInfo = GetBooleanInfo(); for (i = 0; i < booleanInfo.mBooleanCount; i++) { booleanInfo.Reset(i); } EnumAttributesInfo enumInfo = GetEnumInfo(); for (i = 0; i < enumInfo.mEnumCount; i++) { enumInfo.Reset(i); } nsSVGViewBox *viewBox = GetViewBox(); if (viewBox) { viewBox->Init(); } nsSVGPreserveAspectRatio *preserveAspectRatio = GetPreserveAspectRatio(); if (preserveAspectRatio) { preserveAspectRatio->Init(); } StringAttributesInfo stringInfo = GetStringInfo(); for (i = 0; i < stringInfo.mStringCount; i++) { stringInfo.Reset(i); } return NS_OK; }