LCOV - code coverage report
Current view: directory - content/svg/content/src - nsSVGElement.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 1124 0 0.0 %
Date: 2012-06-02 Functions: 121 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla Communicator client code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Alex Fritze <alex.fritze@crocodile-clips.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "nsSVGElement.h"
      40                 : 
      41                 : #include "mozilla/Util.h"
      42                 : 
      43                 : #include "nsSVGSVGElement.h"
      44                 : #include "nsIDocument.h"
      45                 : #include "nsRange.h"
      46                 : #include "nsIDOMAttr.h"
      47                 : #include "nsIDOMEventTarget.h"
      48                 : #include "nsIDOMMutationEvent.h"
      49                 : #include "nsMutationEvent.h"
      50                 : #include "nsXBLPrototypeBinding.h"
      51                 : #include "nsBindingManager.h"
      52                 : #include "nsXBLBinding.h"
      53                 : #include "nsStyleConsts.h"
      54                 : #include "nsDOMError.h"
      55                 : #include "nsIPresShell.h"
      56                 : #include "nsIServiceManager.h"
      57                 : #include "nsIXBLService.h"
      58                 : #include "nsGkAtoms.h"
      59                 : #include "mozilla/css/StyleRule.h"
      60                 : #include "nsRuleWalker.h"
      61                 : #include "mozilla/css/Declaration.h"
      62                 : #include "nsCSSProps.h"
      63                 : #include "nsCSSParser.h"
      64                 : #include "nsGenericHTMLElement.h"
      65                 : #include "nsNodeInfoManager.h"
      66                 : #include "nsIScriptGlobalObject.h"
      67                 : #include "nsEventListenerManager.h"
      68                 : #include "nsSVGUtils.h"
      69                 : #include "nsSVGLength2.h"
      70                 : #include "nsSVGNumber2.h"
      71                 : #include "nsSVGNumberPair.h"
      72                 : #include "nsSVGInteger.h"
      73                 : #include "nsSVGIntegerPair.h"
      74                 : #include "nsSVGAngle.h"
      75                 : #include "nsSVGBoolean.h"
      76                 : #include "nsSVGEnum.h"
      77                 : #include "nsSVGViewBox.h"
      78                 : #include "nsSVGString.h"
      79                 : #include "SVGAnimatedNumberList.h"
      80                 : #include "SVGAnimatedLengthList.h"
      81                 : #include "SVGAnimatedPointList.h"
      82                 : #include "SVGAnimatedPathSegList.h"
      83                 : #include "SVGAnimatedTransformList.h"
      84                 : #include "DOMSVGTests.h"
      85                 : #include "nsIDOMSVGUnitTypes.h"
      86                 : #include "nsSVGRect.h"
      87                 : #include "nsIFrame.h"
      88                 : #include "prdtoa.h"
      89                 : #include <stdarg.h>
      90                 : #include "nsSMILMappedAttribute.h"
      91                 : #include "SVGMotionSMILAttr.h"
      92                 : #include "nsAttrValueOrString.h"
      93                 : 
      94                 : using namespace mozilla;
      95                 : 
      96                 : // This is needed to ensure correct handling of calls to the
      97                 : // vararg-list methods in this file:
      98                 : //   nsSVGElement::GetAnimated{Length,Number,Integer}Values
      99                 : // See bug 547964 for details:
     100                 : PR_STATIC_ASSERT(sizeof(void*) == sizeof(nsnull));
     101                 : 
     102                 : 
     103                 : nsSVGEnumMapping nsSVGElement::sSVGUnitTypesMap[] = {
     104                 :   {&nsGkAtoms::userSpaceOnUse, nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE},
     105                 :   {&nsGkAtoms::objectBoundingBox, nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX},
     106                 :   {nsnull, 0}
     107                 : };
     108                 : 
     109               0 : nsSVGElement::nsSVGElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     110               0 :   : nsSVGElementBase(aNodeInfo)
     111                 : {
     112               0 : }
     113                 : 
     114                 : nsresult
     115               0 : nsSVGElement::Init()
     116                 : {
     117                 :   // Set up length attributes - can't do this in the constructor
     118                 :   // because we can't do a virtual call at that point
     119                 : 
     120               0 :   LengthAttributesInfo lengthInfo = GetLengthInfo();
     121                 : 
     122                 :   PRUint32 i;
     123               0 :   for (i = 0; i < lengthInfo.mLengthCount; i++) {
     124               0 :     lengthInfo.Reset(i);
     125                 :   }
     126                 : 
     127               0 :   NumberAttributesInfo numberInfo = GetNumberInfo();
     128                 : 
     129               0 :   for (i = 0; i < numberInfo.mNumberCount; i++) {
     130               0 :     numberInfo.Reset(i);
     131                 :   }
     132                 : 
     133               0 :   NumberPairAttributesInfo numberPairInfo = GetNumberPairInfo();
     134                 : 
     135               0 :   for (i = 0; i < numberPairInfo.mNumberPairCount; i++) {
     136               0 :     numberPairInfo.Reset(i);
     137                 :   }
     138                 : 
     139               0 :   IntegerAttributesInfo integerInfo = GetIntegerInfo();
     140                 : 
     141               0 :   for (i = 0; i < integerInfo.mIntegerCount; i++) {
     142               0 :     integerInfo.Reset(i);
     143                 :   }
     144                 : 
     145               0 :   IntegerPairAttributesInfo integerPairInfo = GetIntegerPairInfo();
     146                 : 
     147               0 :   for (i = 0; i < integerPairInfo.mIntegerPairCount; i++) {
     148               0 :     integerPairInfo.Reset(i);
     149                 :   }
     150                 : 
     151               0 :   AngleAttributesInfo angleInfo = GetAngleInfo();
     152                 : 
     153               0 :   for (i = 0; i < angleInfo.mAngleCount; i++) {
     154               0 :     angleInfo.Reset(i);
     155                 :   }
     156                 : 
     157               0 :   BooleanAttributesInfo booleanInfo = GetBooleanInfo();
     158                 : 
     159               0 :   for (i = 0; i < booleanInfo.mBooleanCount; i++) {
     160               0 :     booleanInfo.Reset(i);
     161                 :   }
     162                 : 
     163               0 :   EnumAttributesInfo enumInfo = GetEnumInfo();
     164                 : 
     165               0 :   for (i = 0; i < enumInfo.mEnumCount; i++) {
     166               0 :     enumInfo.Reset(i);
     167                 :   }
     168                 : 
     169               0 :   nsSVGViewBox *viewBox = GetViewBox();
     170                 : 
     171               0 :   if (viewBox) {
     172               0 :     viewBox->Init();
     173                 :   }
     174                 : 
     175                 :   SVGAnimatedPreserveAspectRatio *preserveAspectRatio =
     176               0 :     GetPreserveAspectRatio();
     177                 : 
     178               0 :   if (preserveAspectRatio) {
     179               0 :     preserveAspectRatio->Init();
     180                 :   }
     181                 : 
     182               0 :   LengthListAttributesInfo lengthListInfo = GetLengthListInfo();
     183                 : 
     184               0 :   for (i = 0; i < lengthListInfo.mLengthListCount; i++) {
     185               0 :     lengthListInfo.Reset(i);
     186                 :   }
     187                 : 
     188               0 :   NumberListAttributesInfo numberListInfo = GetNumberListInfo();
     189                 : 
     190               0 :   for (i = 0; i < numberListInfo.mNumberListCount; i++) {
     191               0 :     numberListInfo.Reset(i);
     192                 :   }
     193                 : 
     194                 :   // No need to reset SVGPointList since the default value is always the same
     195                 :   // (an empty list).
     196                 : 
     197                 :   // No need to reset SVGPathData since the default value is always the same
     198                 :   // (an empty list).
     199                 : 
     200               0 :   StringAttributesInfo stringInfo = GetStringInfo();
     201                 : 
     202               0 :   for (i = 0; i < stringInfo.mStringCount; i++) {
     203               0 :     stringInfo.Reset(i);
     204                 :   }
     205                 : 
     206               0 :   return NS_OK;
     207                 : }
     208                 : 
     209                 : //----------------------------------------------------------------------
     210                 : // nsISupports methods
     211                 : 
     212               0 : NS_IMPL_ADDREF_INHERITED(nsSVGElement, nsSVGElementBase)
     213               0 : NS_IMPL_RELEASE_INHERITED(nsSVGElement, nsSVGElementBase)
     214                 : 
     215               0 : NS_INTERFACE_MAP_BEGIN(nsSVGElement)
     216                 : // provided by nsGenericElement:
     217                 : //  NS_INTERFACE_MAP_ENTRY(nsIContent)
     218               0 : NS_INTERFACE_MAP_END_INHERITING(nsSVGElementBase)
     219                 : 
     220                 : //----------------------------------------------------------------------
     221                 : // Implementation
     222                 :   
     223                 : //----------------------------------------------------------------------
     224                 : // nsIContent methods
     225                 : 
     226                 : nsresult
     227               0 : nsSVGElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
     228                 :                          nsIContent* aBindingParent,
     229                 :                          bool aCompileEventHandlers)
     230                 : {
     231                 :   nsresult rv = nsSVGElementBase::BindToTree(aDocument, aParent,
     232                 :                                              aBindingParent,
     233               0 :                                              aCompileEventHandlers);
     234               0 :   NS_ENSURE_SUCCESS(rv, rv);
     235                 : 
     236               0 :   if (!MayHaveStyle()) {
     237               0 :     return NS_OK;
     238                 :   }
     239               0 :   const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
     240                 : 
     241               0 :   if (oldVal && oldVal->Type() == nsAttrValue::eCSSStyleRule) {
     242                 :     // we need to force a reparse because the baseURI of the document
     243                 :     // may have changed, and in particular because we may be clones of
     244                 :     // XBL anonymous content now being bound to the document we should
     245                 :     // render in and due to the hacky way in which we implement the
     246                 :     // interaction of XBL and SVG resources.  Once we have a sane
     247                 :     // ownerDocument on XBL anonymous content, this can all go away.
     248               0 :     nsAttrValue attrValue;
     249               0 :     nsAutoString stringValue;
     250               0 :     oldVal->ToString(stringValue);
     251                 :     // Force in data doc, since we already have a style rule
     252               0 :     ParseStyleAttribute(stringValue, attrValue, true);
     253                 :     // Don't bother going through SetInlineStyleRule, we don't want to fire off
     254                 :     // mutation events or document notifications anyway
     255               0 :     rv = mAttrsAndChildren.SetAndTakeAttr(nsGkAtoms::style, attrValue);
     256               0 :     NS_ENSURE_SUCCESS(rv, rv);
     257                 :   }
     258                 : 
     259               0 :   return NS_OK;
     260                 : }
     261                 : 
     262                 : nsresult
     263               0 : nsSVGElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
     264                 :                            const nsAttrValue* aValue, bool aNotify)
     265                 : {
     266                 :   // We don't currently use nsMappedAttributes within SVG. If this changes, we
     267                 :   // need to be very careful because some nsAttrValues used by SVG point to
     268                 :   // member data of SVG elements and if an nsAttrValue outlives the SVG element
     269                 :   // whose data it points to (by virtue of being stored in
     270                 :   // mAttrsAndChildren->mMappedAttributes, meaning it's shared between
     271                 :   // elements), the pointer will dangle. See bug 724680.
     272               0 :   NS_ABORT_IF_FALSE(!mAttrsAndChildren.HasMappedAttrs(),
     273                 :     "Unexpected use of nsMappedAttributes within SVG");
     274                 : 
     275                 :   // If this is an svg presentation attribute we need to map it into
     276                 :   // the content stylerule.
     277                 :   // XXX For some reason incremental mapping doesn't work, so for now
     278                 :   // just delete the style rule and lazily reconstruct it in
     279                 :   // GetContentStyleRule()
     280               0 :   if (aNamespaceID == kNameSpaceID_None && IsAttributeMapped(aName)) {
     281               0 :     mContentStyleRule = nsnull;
     282                 :   }
     283                 : 
     284               0 :   if (IsEventName(aName) && aValue) {
     285               0 :     NS_ABORT_IF_FALSE(aValue->Type() == nsAttrValue::eString,
     286                 :       "Expected string value for script body");
     287                 :     nsresult rv = AddScriptEventListener(GetEventNameForAttr(aName),
     288               0 :                                          aValue->GetStringValue());
     289               0 :     NS_ENSURE_SUCCESS(rv, rv);
     290                 :   }
     291                 : 
     292               0 :   return nsSVGElementBase::AfterSetAttr(aNamespaceID, aName, aValue, aNotify);
     293                 : }
     294                 : 
     295                 : bool
     296               0 : nsSVGElement::ParseAttribute(PRInt32 aNamespaceID,
     297                 :                              nsIAtom* aAttribute,
     298                 :                              const nsAString& aValue,
     299                 :                              nsAttrValue& aResult)
     300                 : {
     301               0 :   nsresult rv = NS_OK;
     302               0 :   bool foundMatch = false;
     303               0 :   bool didSetResult = false;
     304                 : 
     305               0 :   if (aNamespaceID == kNameSpaceID_None) {
     306                 : 
     307                 :     // Check for nsSVGLength2 attribute
     308               0 :     LengthAttributesInfo lengthInfo = GetLengthInfo();
     309                 : 
     310                 :     PRUint32 i;
     311               0 :     for (i = 0; i < lengthInfo.mLengthCount; i++) {
     312               0 :       if (aAttribute == *lengthInfo.mLengthInfo[i].mName) {
     313               0 :         rv = lengthInfo.mLengths[i].SetBaseValueString(aValue, this, false);
     314               0 :         if (NS_FAILED(rv)) {
     315               0 :           lengthInfo.Reset(i);
     316                 :         } else {
     317               0 :           aResult.SetTo(lengthInfo.mLengths[i], &aValue);
     318               0 :           didSetResult = true;
     319                 :         }
     320               0 :         foundMatch = true;
     321               0 :         break;
     322                 :       }
     323                 :     }
     324                 : 
     325               0 :     if (!foundMatch) {
     326                 :       // Check for SVGAnimatedLengthList attribute
     327               0 :       LengthListAttributesInfo lengthListInfo = GetLengthListInfo();
     328               0 :       for (i = 0; i < lengthListInfo.mLengthListCount; i++) {
     329               0 :         if (aAttribute == *lengthListInfo.mLengthListInfo[i].mName) {
     330               0 :           rv = lengthListInfo.mLengthLists[i].SetBaseValueString(aValue);
     331               0 :           if (NS_FAILED(rv)) {
     332               0 :             lengthListInfo.Reset(i);
     333                 :           } else {
     334               0 :             aResult.SetTo(lengthListInfo.mLengthLists[i].GetBaseValue(),
     335               0 :                           &aValue);
     336               0 :             didSetResult = true;
     337                 :           }
     338               0 :           foundMatch = true;
     339               0 :           break;
     340                 :         }
     341                 :       }
     342                 :     }
     343                 : 
     344               0 :     if (!foundMatch) {
     345                 :       // Check for SVGAnimatedNumberList attribute
     346               0 :       NumberListAttributesInfo numberListInfo = GetNumberListInfo();
     347               0 :       for (i = 0; i < numberListInfo.mNumberListCount; i++) {
     348               0 :         if (aAttribute == *numberListInfo.mNumberListInfo[i].mName) {
     349               0 :           rv = numberListInfo.mNumberLists[i].SetBaseValueString(aValue);
     350               0 :           if (NS_FAILED(rv)) {
     351               0 :             numberListInfo.Reset(i);
     352                 :           } else {
     353               0 :             aResult.SetTo(numberListInfo.mNumberLists[i].GetBaseValue(),
     354               0 :                           &aValue);
     355               0 :             didSetResult = true;
     356                 :           }
     357               0 :           foundMatch = true;
     358               0 :           break;
     359                 :         }
     360                 :       }
     361                 :     }
     362                 : 
     363               0 :     if (!foundMatch) {
     364                 :       // Check for SVGAnimatedPointList attribute
     365               0 :       if (GetPointListAttrName() == aAttribute) {
     366               0 :         SVGAnimatedPointList* pointList = GetAnimatedPointList();
     367               0 :         if (pointList) {
     368               0 :           pointList->SetBaseValueString(aValue);
     369                 :           // The spec says we parse everything up to the failure, so we DON'T
     370                 :           // need to check the result of SetBaseValueString or call
     371                 :           // pointList->ClearBaseValue() if it fails
     372               0 :           aResult.SetTo(pointList->GetBaseValue(), &aValue);
     373               0 :           didSetResult = true;
     374               0 :           foundMatch = true;
     375                 :         }
     376                 :       }
     377                 :     }
     378                 : 
     379               0 :     if (!foundMatch) {
     380                 :       // Check for SVGAnimatedPathSegList attribute
     381               0 :       if (GetPathDataAttrName() == aAttribute) {
     382               0 :         SVGAnimatedPathSegList* segList = GetAnimPathSegList();
     383               0 :         if (segList) {
     384               0 :           segList->SetBaseValueString(aValue);
     385                 :           // The spec says we parse everything up to the failure, so we DON'T
     386                 :           // need to check the result of SetBaseValueString or call
     387                 :           // segList->ClearBaseValue() if it fails
     388               0 :           aResult.SetTo(segList->GetBaseValue(), &aValue);
     389               0 :           didSetResult = true;
     390               0 :           foundMatch = true;
     391                 :         }
     392                 :       }
     393                 :     }
     394                 : 
     395               0 :     if (!foundMatch) {
     396                 :       // Check for nsSVGNumber2 attribute
     397               0 :       NumberAttributesInfo numberInfo = GetNumberInfo();
     398               0 :       for (i = 0; i < numberInfo.mNumberCount; i++) {
     399               0 :         if (aAttribute == *numberInfo.mNumberInfo[i].mName) {
     400               0 :           rv = numberInfo.mNumbers[i].SetBaseValueString(aValue, this);
     401               0 :           if (NS_FAILED(rv)) {
     402               0 :             numberInfo.Reset(i);
     403                 :           } else {
     404               0 :             aResult.SetTo(numberInfo.mNumbers[i].GetBaseValue(), &aValue);
     405               0 :             didSetResult = true;
     406                 :           }
     407               0 :           foundMatch = true;
     408               0 :           break;
     409                 :         }
     410                 :       }
     411                 :     }
     412                 : 
     413               0 :     if (!foundMatch) {
     414                 :       // Check for nsSVGNumberPair attribute
     415               0 :       NumberPairAttributesInfo numberPairInfo = GetNumberPairInfo();
     416               0 :       for (i = 0; i < numberPairInfo.mNumberPairCount; i++) {
     417               0 :         if (aAttribute == *numberPairInfo.mNumberPairInfo[i].mName) {
     418               0 :           rv = numberPairInfo.mNumberPairs[i].SetBaseValueString(aValue, this);
     419               0 :           if (NS_FAILED(rv)) {
     420               0 :             numberPairInfo.Reset(i);
     421                 :           } else {
     422               0 :             aResult.SetTo(numberPairInfo.mNumberPairs[i], &aValue);
     423               0 :             didSetResult = true;
     424                 :           }
     425               0 :           foundMatch = true;
     426               0 :           break;
     427                 :         }
     428                 :       }
     429                 :     }
     430                 : 
     431               0 :     if (!foundMatch) {
     432                 :       // Check for nsSVGInteger attribute
     433               0 :       IntegerAttributesInfo integerInfo = GetIntegerInfo();
     434               0 :       for (i = 0; i < integerInfo.mIntegerCount; i++) {
     435               0 :         if (aAttribute == *integerInfo.mIntegerInfo[i].mName) {
     436               0 :           rv = integerInfo.mIntegers[i].SetBaseValueString(aValue, this);
     437               0 :           if (NS_FAILED(rv)) {
     438               0 :             integerInfo.Reset(i);
     439                 :           } else {
     440               0 :             aResult.SetTo(integerInfo.mIntegers[i].GetBaseValue(), &aValue);
     441               0 :             didSetResult = true;
     442                 :           }
     443               0 :           foundMatch = true;
     444               0 :           break;
     445                 :         }
     446                 :       }
     447                 :     }
     448                 : 
     449               0 :     if (!foundMatch) {
     450                 :       // Check for nsSVGIntegerPair attribute
     451               0 :       IntegerPairAttributesInfo integerPairInfo = GetIntegerPairInfo();
     452               0 :       for (i = 0; i < integerPairInfo.mIntegerPairCount; i++) {
     453               0 :         if (aAttribute == *integerPairInfo.mIntegerPairInfo[i].mName) {
     454                 :           rv =
     455               0 :             integerPairInfo.mIntegerPairs[i].SetBaseValueString(aValue, this);
     456               0 :           if (NS_FAILED(rv)) {
     457               0 :             integerPairInfo.Reset(i);
     458                 :           } else {
     459               0 :             aResult.SetTo(integerPairInfo.mIntegerPairs[i], &aValue);
     460               0 :             didSetResult = true;
     461                 :           }
     462               0 :           foundMatch = true;
     463               0 :           break;
     464                 :         }
     465                 :       }
     466                 :     }
     467                 : 
     468               0 :     if (!foundMatch) {
     469                 :       // Check for nsSVGAngle attribute
     470               0 :       AngleAttributesInfo angleInfo = GetAngleInfo();
     471               0 :       for (i = 0; i < angleInfo.mAngleCount; i++) {
     472               0 :         if (aAttribute == *angleInfo.mAngleInfo[i].mName) {
     473               0 :           rv = angleInfo.mAngles[i].SetBaseValueString(aValue, this, false);
     474               0 :           if (NS_FAILED(rv)) {
     475               0 :             angleInfo.Reset(i);
     476                 :           } else {
     477               0 :             aResult.SetTo(angleInfo.mAngles[i], &aValue);
     478               0 :             didSetResult = true;
     479                 :           }
     480               0 :           foundMatch = true;
     481               0 :           break;
     482                 :         }
     483                 :       }
     484                 :     }
     485                 : 
     486               0 :     if (!foundMatch) {
     487                 :       // Check for nsSVGBoolean attribute
     488               0 :       BooleanAttributesInfo booleanInfo = GetBooleanInfo();
     489               0 :       for (i = 0; i < booleanInfo.mBooleanCount; i++) {
     490               0 :         if (aAttribute == *booleanInfo.mBooleanInfo[i].mName) {
     491               0 :           nsCOMPtr<nsIAtom> valAtom = do_GetAtom(aValue);
     492               0 :           rv = booleanInfo.mBooleans[i].SetBaseValueAtom(valAtom, this);
     493               0 :           if (NS_FAILED(rv)) {
     494               0 :             booleanInfo.Reset(i);
     495                 :           } else {
     496               0 :             aResult.SetTo(valAtom);
     497               0 :             didSetResult = true;
     498                 :           }
     499               0 :           foundMatch = true;
     500                 :           break;
     501                 :         }
     502                 :       }
     503                 :     }
     504                 : 
     505               0 :     if (!foundMatch) {
     506                 :       // Check for nsSVGEnum attribute
     507               0 :       EnumAttributesInfo enumInfo = GetEnumInfo();
     508               0 :       for (i = 0; i < enumInfo.mEnumCount; i++) {
     509               0 :         if (aAttribute == *enumInfo.mEnumInfo[i].mName) {
     510               0 :           nsCOMPtr<nsIAtom> valAtom = do_GetAtom(aValue);
     511               0 :           rv = enumInfo.mEnums[i].SetBaseValueAtom(valAtom, this);
     512               0 :           if (NS_FAILED(rv)) {
     513               0 :             enumInfo.Reset(i);
     514                 :           } else {
     515               0 :             aResult.SetTo(valAtom);
     516               0 :             didSetResult = true;
     517                 :           }
     518               0 :           foundMatch = true;
     519                 :           break;
     520                 :         }
     521                 :       }
     522                 :     }
     523                 : 
     524               0 :     if (!foundMatch) {
     525                 :       // Check for conditional processing attributes
     526               0 :       nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(this));
     527               0 :       if (tests && tests->ParseConditionalProcessingAttribute(
     528               0 :                             aAttribute, aValue, aResult)) {
     529               0 :         foundMatch = true;
     530                 :       }
     531                 :     }
     532                 : 
     533               0 :     if (!foundMatch) {
     534                 :       // Check for StringList attribute
     535               0 :       StringListAttributesInfo stringListInfo = GetStringListInfo();
     536               0 :       for (i = 0; i < stringListInfo.mStringListCount; i++) {
     537               0 :         if (aAttribute == *stringListInfo.mStringListInfo[i].mName) {
     538               0 :           rv = stringListInfo.mStringLists[i].SetValue(aValue);
     539               0 :           if (NS_FAILED(rv)) {
     540               0 :             stringListInfo.Reset(i);
     541                 :           } else {
     542               0 :             aResult.SetTo(stringListInfo.mStringLists[i], &aValue);
     543               0 :             didSetResult = true;
     544                 :           }
     545               0 :           foundMatch = true;
     546               0 :           break;
     547                 :         }
     548                 :       }
     549                 :     }
     550                 : 
     551               0 :     if (!foundMatch) {
     552                 :       // Check for nsSVGViewBox attribute
     553               0 :       if (aAttribute == nsGkAtoms::viewBox) {
     554               0 :         nsSVGViewBox* viewBox = GetViewBox();
     555               0 :         if (viewBox) {
     556               0 :           rv = viewBox->SetBaseValueString(aValue, this);
     557               0 :           if (NS_FAILED(rv)) {
     558               0 :             viewBox->Init();
     559                 :           } else {
     560               0 :             aResult.SetTo(*viewBox, &aValue);
     561               0 :             didSetResult = true;
     562                 :           }
     563               0 :           foundMatch = true;
     564                 :         }
     565                 :       // Check for SVGAnimatedPreserveAspectRatio attribute
     566               0 :       } else if (aAttribute == nsGkAtoms::preserveAspectRatio) {
     567                 :         SVGAnimatedPreserveAspectRatio *preserveAspectRatio =
     568               0 :           GetPreserveAspectRatio();
     569               0 :         if (preserveAspectRatio) {
     570               0 :           rv = preserveAspectRatio->SetBaseValueString(aValue, this);
     571               0 :           if (NS_FAILED(rv)) {
     572               0 :             preserveAspectRatio->Init();
     573                 :           } else {
     574               0 :             aResult.SetTo(*preserveAspectRatio, &aValue);
     575               0 :             didSetResult = true;
     576                 :           }
     577               0 :           foundMatch = true;
     578                 :         }
     579                 :       // Check for SVGAnimatedTransformList attribute
     580               0 :       } else if (GetTransformListAttrName() == aAttribute) {
     581               0 :         SVGAnimatedTransformList *transformList = GetAnimatedTransformList();
     582               0 :         if (transformList) {
     583               0 :           rv = transformList->SetBaseValueString(aValue);
     584               0 :           if (NS_FAILED(rv)) {
     585               0 :             transformList->ClearBaseValue();
     586                 :           } else {
     587               0 :             aResult.SetTo(transformList->GetBaseValue(), &aValue);
     588               0 :             didSetResult = true;
     589                 :           }
     590               0 :           foundMatch = true;
     591                 :         }
     592                 :       }
     593                 :     }
     594                 :   }
     595                 : 
     596               0 :   if (!foundMatch) {
     597                 :     // Check for nsSVGString attribute
     598               0 :     StringAttributesInfo stringInfo = GetStringInfo();
     599               0 :     for (PRUint32 i = 0; i < stringInfo.mStringCount; i++) {
     600               0 :       if (aNamespaceID == stringInfo.mStringInfo[i].mNamespaceID &&
     601               0 :           aAttribute == *stringInfo.mStringInfo[i].mName) {
     602               0 :         stringInfo.mStrings[i].SetBaseValue(aValue, this, false);
     603               0 :         foundMatch = true;
     604               0 :         break;
     605                 :       }
     606                 :     }
     607                 :   }
     608                 : 
     609               0 :   if (foundMatch) {
     610               0 :     if (NS_FAILED(rv)) {
     611               0 :       ReportAttributeParseFailure(OwnerDoc(), aAttribute, aValue);
     612               0 :       return false;
     613                 :     }
     614               0 :     if (!didSetResult) {
     615               0 :       aResult.SetTo(aValue);
     616                 :     }
     617               0 :     return true;
     618                 :   }
     619                 : 
     620                 :   return nsSVGElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
     621               0 :                                           aResult);
     622                 : }
     623                 : 
     624                 : void
     625               0 : nsSVGElement::UnsetAttrInternal(PRInt32 aNamespaceID, nsIAtom* aName,
     626                 :                                 bool aNotify)
     627                 : {
     628                 :   // XXXbz there's a bunch of redundancy here with AfterSetAttr.
     629                 :   // Maybe consolidate?
     630                 : 
     631               0 :   if (aNamespaceID == kNameSpaceID_None) {
     632                 :     // If this is an svg presentation attribute, remove rule to force an update
     633               0 :     if (IsAttributeMapped(aName))
     634               0 :       mContentStyleRule = nsnull;
     635                 : 
     636               0 :     if (IsEventName(aName)) {
     637               0 :       nsEventListenerManager* manager = GetListenerManager(false);
     638               0 :       if (manager) {
     639               0 :         nsIAtom* eventName = GetEventNameForAttr(aName);
     640               0 :         manager->RemoveScriptEventListener(eventName);
     641                 :       }
     642               0 :       return;
     643                 :     }
     644                 :     
     645                 :     // Check if this is a length attribute going away
     646               0 :     LengthAttributesInfo lenInfo = GetLengthInfo();
     647                 : 
     648               0 :     for (PRUint32 i = 0; i < lenInfo.mLengthCount; i++) {
     649               0 :       if (aName == *lenInfo.mLengthInfo[i].mName) {
     650               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     651               0 :         lenInfo.Reset(i);
     652               0 :         return;
     653                 :       }
     654                 :     }
     655                 : 
     656                 :     // Check if this is a length list attribute going away
     657               0 :     LengthListAttributesInfo lengthListInfo = GetLengthListInfo();
     658                 : 
     659               0 :     for (PRUint32 i = 0; i < lengthListInfo.mLengthListCount; i++) {
     660               0 :       if (aName == *lengthListInfo.mLengthListInfo[i].mName) {
     661               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     662               0 :         lengthListInfo.Reset(i);
     663               0 :         return;
     664                 :       }
     665                 :     }
     666                 : 
     667                 :     // Check if this is a number list attribute going away
     668               0 :     NumberListAttributesInfo numberListInfo = GetNumberListInfo();
     669                 : 
     670               0 :     for (PRUint32 i = 0; i < numberListInfo.mNumberListCount; i++) {
     671               0 :       if (aName == *numberListInfo.mNumberListInfo[i].mName) {
     672               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     673               0 :         numberListInfo.Reset(i);
     674               0 :         return;
     675                 :       }
     676                 :     }
     677                 : 
     678                 :     // Check if this is a point list attribute going away
     679               0 :     if (GetPointListAttrName() == aName) {
     680               0 :       SVGAnimatedPointList *pointList = GetAnimatedPointList();
     681               0 :       if (pointList) {
     682               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     683               0 :         pointList->ClearBaseValue();
     684               0 :         return;
     685                 :       }
     686                 :     }
     687                 : 
     688                 :     // Check if this is a path segment list attribute going away
     689               0 :     if (GetPathDataAttrName() == aName) {
     690               0 :       SVGAnimatedPathSegList *segList = GetAnimPathSegList();
     691               0 :       if (segList) {
     692               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     693               0 :         segList->ClearBaseValue();
     694               0 :         return;
     695                 :       }
     696                 :     }
     697                 : 
     698                 :     // Check if this is a number attribute going away
     699               0 :     NumberAttributesInfo numInfo = GetNumberInfo();
     700                 : 
     701               0 :     for (PRUint32 i = 0; i < numInfo.mNumberCount; i++) {
     702               0 :       if (aName == *numInfo.mNumberInfo[i].mName) {
     703               0 :         numInfo.Reset(i);
     704               0 :         return;
     705                 :       }
     706                 :     }
     707                 : 
     708                 :     // Check if this is a number pair attribute going away
     709               0 :     NumberPairAttributesInfo numPairInfo = GetNumberPairInfo();
     710                 : 
     711               0 :     for (PRUint32 i = 0; i < numPairInfo.mNumberPairCount; i++) {
     712               0 :       if (aName == *numPairInfo.mNumberPairInfo[i].mName) {
     713               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     714               0 :         numPairInfo.Reset(i);
     715               0 :         return;
     716                 :       }
     717                 :     }
     718                 : 
     719                 :     // Check if this is an integer attribute going away
     720               0 :     IntegerAttributesInfo intInfo = GetIntegerInfo();
     721                 : 
     722               0 :     for (PRUint32 i = 0; i < intInfo.mIntegerCount; i++) {
     723               0 :       if (aName == *intInfo.mIntegerInfo[i].mName) {
     724               0 :         intInfo.Reset(i);
     725               0 :         return;
     726                 :       }
     727                 :     }
     728                 : 
     729                 :     // Check if this is an integer pair attribute going away
     730               0 :     IntegerPairAttributesInfo intPairInfo = GetIntegerPairInfo();
     731                 : 
     732               0 :     for (PRUint32 i = 0; i < intPairInfo.mIntegerPairCount; i++) {
     733               0 :       if (aName == *intPairInfo.mIntegerPairInfo[i].mName) {
     734               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     735               0 :         intPairInfo.Reset(i);
     736               0 :         return;
     737                 :       }
     738                 :     }
     739                 : 
     740                 :     // Check if this is an angle attribute going away
     741               0 :     AngleAttributesInfo angleInfo = GetAngleInfo();
     742                 : 
     743               0 :     for (PRUint32 i = 0; i < angleInfo.mAngleCount; i++) {
     744               0 :       if (aName == *angleInfo.mAngleInfo[i].mName) {
     745               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     746               0 :         angleInfo.Reset(i);
     747               0 :         return;
     748                 :       }
     749                 :     }
     750                 : 
     751                 :     // Check if this is a boolean attribute going away
     752               0 :     BooleanAttributesInfo boolInfo = GetBooleanInfo();
     753                 : 
     754               0 :     for (PRUint32 i = 0; i < boolInfo.mBooleanCount; i++) {
     755               0 :       if (aName == *boolInfo.mBooleanInfo[i].mName) {
     756               0 :         boolInfo.Reset(i);
     757               0 :         return;
     758                 :       }
     759                 :     }
     760                 : 
     761                 :     // Check if this is an enum attribute going away
     762               0 :     EnumAttributesInfo enumInfo = GetEnumInfo();
     763                 : 
     764               0 :     for (PRUint32 i = 0; i < enumInfo.mEnumCount; i++) {
     765               0 :       if (aName == *enumInfo.mEnumInfo[i].mName) {
     766               0 :         enumInfo.Reset(i);
     767               0 :         return;
     768                 :       }
     769                 :     }
     770                 : 
     771                 :     // Check if this is a nsViewBox attribute going away
     772               0 :     if (aName == nsGkAtoms::viewBox) {
     773               0 :       nsSVGViewBox* viewBox = GetViewBox();
     774               0 :       if (viewBox) {
     775               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     776               0 :         viewBox->Init();
     777               0 :         return;
     778                 :       }
     779                 :     }
     780                 : 
     781                 :     // Check if this is a preserveAspectRatio attribute going away
     782               0 :     if (aName == nsGkAtoms::preserveAspectRatio) {
     783                 :       SVGAnimatedPreserveAspectRatio *preserveAspectRatio =
     784               0 :         GetPreserveAspectRatio();
     785               0 :       if (preserveAspectRatio) {
     786               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     787               0 :         preserveAspectRatio->Init();
     788               0 :         return;
     789                 :       }
     790                 :     }
     791                 : 
     792                 :     // Check if this is a transform list attribute going away
     793               0 :     if (GetTransformListAttrName() == aName) {
     794               0 :       SVGAnimatedTransformList *transformList = GetAnimatedTransformList();
     795               0 :       if (transformList) {
     796               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     797               0 :         transformList->ClearBaseValue();
     798               0 :         return;
     799                 :       }
     800                 :     }
     801                 : 
     802                 :     // Check for conditional processing attributes
     803               0 :     nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(this));
     804               0 :     if (tests && tests->IsConditionalProcessingAttribute(aName)) {
     805               0 :       MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     806               0 :       tests->UnsetAttr(aName);
     807                 :       return;
     808                 :     }
     809                 : 
     810                 :     // Check if this is a string list attribute going away
     811               0 :     StringListAttributesInfo stringListInfo = GetStringListInfo();
     812                 : 
     813               0 :     for (PRUint32 i = 0; i < stringListInfo.mStringListCount; i++) {
     814               0 :       if (aName == *stringListInfo.mStringListInfo[i].mName) {
     815               0 :         MaybeSerializeAttrBeforeRemoval(aName, aNotify);
     816               0 :         stringListInfo.Reset(i);
     817                 :         return;
     818                 :       }
     819                 :     }
     820                 :   }
     821                 : 
     822                 :   // Check if this is a string attribute going away
     823               0 :   StringAttributesInfo stringInfo = GetStringInfo();
     824                 : 
     825               0 :   for (PRUint32 i = 0; i < stringInfo.mStringCount; i++) {
     826               0 :     if (aNamespaceID == stringInfo.mStringInfo[i].mNamespaceID &&
     827               0 :         aName == *stringInfo.mStringInfo[i].mName) {
     828               0 :       stringInfo.Reset(i);
     829               0 :       return;
     830                 :     }
     831                 :   }
     832                 : }
     833                 : 
     834                 : nsresult
     835               0 : nsSVGElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
     836                 :                         bool aNotify)
     837                 : {
     838               0 :   UnsetAttrInternal(aNamespaceID, aName, aNotify);
     839               0 :   return nsSVGElementBase::UnsetAttr(aNamespaceID, aName, aNotify);
     840                 : }
     841                 : 
     842                 : nsChangeHint
     843               0 : nsSVGElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
     844                 :                                      PRInt32 aModType) const
     845                 : {
     846                 :   nsChangeHint retval =
     847               0 :     nsSVGElementBase::GetAttributeChangeHint(aAttribute, aModType);
     848                 : 
     849               0 :   nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(const_cast<nsSVGElement*>(this)));
     850               0 :   if (tests && tests->IsConditionalProcessingAttribute(aAttribute)) {
     851                 :     // It would be nice to only reconstruct the frame if the value returned by
     852                 :     // DOMSVGTests::PassesConditionalProcessingTests has changed, but we don't
     853                 :     // know that
     854               0 :     NS_UpdateHint(retval, nsChangeHint_ReconstructFrame);
     855                 :   }
     856               0 :   return retval;
     857                 : }
     858                 : 
     859                 : bool
     860               0 : nsSVGElement::IsNodeOfType(PRUint32 aFlags) const
     861                 : {
     862               0 :   return !(aFlags & ~eCONTENT);
     863                 : }
     864                 : 
     865                 : NS_IMETHODIMP
     866               0 : nsSVGElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
     867                 : {
     868                 : #ifdef DEBUG
     869                 : //  printf("nsSVGElement(%p)::WalkContentStyleRules()\n", this);
     870                 : #endif
     871               0 :   if (!mContentStyleRule)
     872               0 :     UpdateContentStyleRule();
     873                 : 
     874               0 :   if (mContentStyleRule) {
     875               0 :     mContentStyleRule->RuleMatched();
     876               0 :     aRuleWalker->Forward(mContentStyleRule);
     877                 :   }
     878                 : 
     879                 :   // Update & walk the animated content style rule, to include style from
     880                 :   // animated mapped attributes.  But first, get nsPresContext to check
     881                 :   // whether this is a "no-animation restyle". (This should match the check
     882                 :   // in nsHTMLCSSStyleSheet::RulesMatching(), where we determine whether to
     883                 :   // apply the SMILOverrideStyle.)
     884               0 :   nsIDocument* doc = OwnerDoc();
     885               0 :   nsIPresShell* shell = doc->GetShell();
     886               0 :   nsPresContext* context = shell ? shell->GetPresContext() : nsnull;
     887               0 :   if (context && context->IsProcessingRestyles() &&
     888               0 :       !context->IsProcessingAnimationStyleChange()) {
     889                 :     // Any style changes right now could trigger CSS Transitions. We don't
     890                 :     // want that to happen from SMIL-animated value of mapped attrs, so
     891                 :     // ignore animated value for now, and request an animation restyle to
     892                 :     // get our animated value noticed.
     893               0 :     shell->RestyleForAnimation(this, eRestyle_Self);
     894                 :   } else {
     895                 :     // Ok, this is an animation restyle -- go ahead and update/walk the
     896                 :     // animated content style rule.
     897               0 :     css::StyleRule* animContentStyleRule = GetAnimatedContentStyleRule();
     898               0 :     if (!animContentStyleRule) {
     899               0 :       UpdateAnimatedContentStyleRule();
     900               0 :       animContentStyleRule = GetAnimatedContentStyleRule();
     901                 :     }
     902               0 :     if (animContentStyleRule) {
     903               0 :       animContentStyleRule->RuleMatched();
     904               0 :       aRuleWalker->Forward(animContentStyleRule);
     905                 :     }
     906                 :   }
     907                 : 
     908               0 :   return NS_OK;
     909                 : }
     910                 : 
     911                 : NS_IMETHODIMP_(bool)
     912               0 : nsSVGElement::IsAttributeMapped(const nsIAtom* name) const
     913                 : {
     914               0 :   if (name == nsGkAtoms::lang) {
     915               0 :     return true;
     916                 :   }
     917               0 :   return nsSVGElementBase::IsAttributeMapped(name);
     918                 : }
     919                 : 
     920                 : // PresentationAttributes-FillStroke
     921                 : /* static */ const nsGenericElement::MappedAttributeEntry
     922                 : nsSVGElement::sFillStrokeMap[] = {
     923                 :   { &nsGkAtoms::fill },
     924                 :   { &nsGkAtoms::fill_opacity },
     925                 :   { &nsGkAtoms::fill_rule },
     926                 :   { &nsGkAtoms::stroke },
     927                 :   { &nsGkAtoms::stroke_dasharray },
     928                 :   { &nsGkAtoms::stroke_dashoffset },
     929                 :   { &nsGkAtoms::stroke_linecap },
     930                 :   { &nsGkAtoms::stroke_linejoin },
     931                 :   { &nsGkAtoms::stroke_miterlimit },
     932                 :   { &nsGkAtoms::stroke_opacity },
     933                 :   { &nsGkAtoms::stroke_width },
     934                 :   { nsnull }
     935                 : };
     936                 : 
     937                 : // PresentationAttributes-Graphics
     938                 : /* static */ const nsGenericElement::MappedAttributeEntry
     939                 : nsSVGElement::sGraphicsMap[] = {
     940                 :   { &nsGkAtoms::clip_path },
     941                 :   { &nsGkAtoms::clip_rule },
     942                 :   { &nsGkAtoms::colorInterpolation },
     943                 :   { &nsGkAtoms::cursor },
     944                 :   { &nsGkAtoms::display },
     945                 :   { &nsGkAtoms::filter },
     946                 :   { &nsGkAtoms::image_rendering },
     947                 :   { &nsGkAtoms::mask },
     948                 :   { &nsGkAtoms::opacity },
     949                 :   { &nsGkAtoms::pointer_events },
     950                 :   { &nsGkAtoms::shape_rendering },
     951                 :   { &nsGkAtoms::text_rendering },
     952                 :   { &nsGkAtoms::visibility },
     953                 :   { nsnull }
     954                 : };
     955                 : 
     956                 : // PresentationAttributes-TextContentElements
     957                 : /* static */ const nsGenericElement::MappedAttributeEntry
     958                 : nsSVGElement::sTextContentElementsMap[] = {
     959                 :   { &nsGkAtoms::alignment_baseline },
     960                 :   { &nsGkAtoms::baseline_shift },
     961                 :   { &nsGkAtoms::direction },
     962                 :   { &nsGkAtoms::dominant_baseline },
     963                 :   { &nsGkAtoms::glyph_orientation_horizontal },
     964                 :   { &nsGkAtoms::glyph_orientation_vertical },
     965                 :   { &nsGkAtoms::kerning },
     966                 :   { &nsGkAtoms::letter_spacing },
     967                 :   { &nsGkAtoms::text_anchor },
     968                 :   { &nsGkAtoms::text_decoration },
     969                 :   { &nsGkAtoms::unicode_bidi },
     970                 :   { &nsGkAtoms::word_spacing },
     971                 :   { nsnull }
     972                 : };
     973                 : 
     974                 : // PresentationAttributes-FontSpecification
     975                 : /* static */ const nsGenericElement::MappedAttributeEntry
     976                 : nsSVGElement::sFontSpecificationMap[] = {
     977                 :   { &nsGkAtoms::font_family },
     978                 :   { &nsGkAtoms::font_size },
     979                 :   { &nsGkAtoms::font_size_adjust },
     980                 :   { &nsGkAtoms::font_stretch },
     981                 :   { &nsGkAtoms::font_style },
     982                 :   { &nsGkAtoms::font_variant },
     983                 :   { &nsGkAtoms::fontWeight },  
     984                 :   { nsnull }
     985                 : };
     986                 : 
     987                 : // PresentationAttributes-GradientStop
     988                 : /* static */ const nsGenericElement::MappedAttributeEntry
     989                 : nsSVGElement::sGradientStopMap[] = {
     990                 :   { &nsGkAtoms::stop_color },
     991                 :   { &nsGkAtoms::stop_opacity },
     992                 :   { nsnull }
     993                 : };
     994                 : 
     995                 : // PresentationAttributes-Viewports
     996                 : /* static */ const nsGenericElement::MappedAttributeEntry
     997                 : nsSVGElement::sViewportsMap[] = {
     998                 :   { &nsGkAtoms::overflow },
     999                 :   { &nsGkAtoms::clip },
    1000                 :   { nsnull }
    1001                 : };
    1002                 : 
    1003                 : // PresentationAttributes-Makers
    1004                 : /* static */ const nsGenericElement::MappedAttributeEntry
    1005                 : nsSVGElement::sMarkersMap[] = {
    1006                 :   { &nsGkAtoms::marker_end },
    1007                 :   { &nsGkAtoms::marker_mid },
    1008                 :   { &nsGkAtoms::marker_start },
    1009                 :   { nsnull }
    1010                 : };
    1011                 : 
    1012                 : // PresentationAttributes-Color
    1013                 : /* static */ const nsGenericElement::MappedAttributeEntry
    1014                 : nsSVGElement::sColorMap[] = {
    1015                 :   { &nsGkAtoms::color },
    1016                 :   { nsnull }
    1017                 : };
    1018                 : 
    1019                 : // PresentationAttributes-Filters
    1020                 : /* static */ const nsGenericElement::MappedAttributeEntry
    1021                 : nsSVGElement::sFiltersMap[] = {
    1022                 :   { &nsGkAtoms::colorInterpolationFilters },
    1023                 :   { nsnull }
    1024                 : };
    1025                 : 
    1026                 : // PresentationAttributes-feFlood
    1027                 : /* static */ const nsGenericElement::MappedAttributeEntry
    1028                 : nsSVGElement::sFEFloodMap[] = {
    1029                 :   { &nsGkAtoms::flood_color },
    1030                 :   { &nsGkAtoms::flood_opacity },
    1031                 :   { nsnull }
    1032                 : };
    1033                 : 
    1034                 : // PresentationAttributes-LightingEffects
    1035                 : /* static */ const nsGenericElement::MappedAttributeEntry
    1036                 : nsSVGElement::sLightingEffectsMap[] = {
    1037                 :   { &nsGkAtoms::lighting_color },
    1038                 :   { nsnull }
    1039                 : };
    1040                 : 
    1041                 : //----------------------------------------------------------------------
    1042                 : // nsIDOMNode methods
    1043                 : 
    1044                 : NS_IMETHODIMP
    1045               0 : nsSVGElement::IsSupported(const nsAString& aFeature, const nsAString& aVersion, bool* aReturn)
    1046                 : {
    1047               0 :   return nsGenericElement::IsSupported(aFeature, aVersion, aReturn); 
    1048                 : }
    1049                 : 
    1050                 : //----------------------------------------------------------------------
    1051                 : // nsIDOMElement methods
    1052                 : 
    1053                 : // forwarded to nsGenericElement implementations
    1054                 : 
    1055                 : 
    1056                 : //----------------------------------------------------------------------
    1057                 : // nsIDOMSVGElement methods
    1058                 : 
    1059                 : /* attribute DOMString id; */
    1060               0 : NS_IMETHODIMP nsSVGElement::GetId(nsAString & aId)
    1061                 : {
    1062               0 :   GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
    1063                 : 
    1064               0 :   return NS_OK;
    1065                 : }
    1066                 : 
    1067               0 : NS_IMETHODIMP nsSVGElement::SetId(const nsAString & aId)
    1068                 : {
    1069               0 :   return SetAttr(kNameSpaceID_None, nsGkAtoms::id, aId, true);
    1070                 : }
    1071                 : 
    1072                 : /* readonly attribute nsIDOMSVGSVGElement ownerSVGElement; */
    1073                 : NS_IMETHODIMP
    1074               0 : nsSVGElement::GetOwnerSVGElement(nsIDOMSVGSVGElement * *aOwnerSVGElement)
    1075                 : {
    1076               0 :   NS_IF_ADDREF(*aOwnerSVGElement = GetCtx());
    1077                 : 
    1078               0 :   if (*aOwnerSVGElement || Tag() == nsGkAtoms::svg) {
    1079                 :     // If we found something or we're the outermost SVG element, that's OK.
    1080               0 :     return NS_OK;
    1081                 :   }
    1082                 :   // Otherwise, we've got an invalid structure
    1083               0 :   return NS_ERROR_FAILURE;
    1084                 : }
    1085                 : 
    1086                 : /* readonly attribute nsIDOMSVGElement viewportElement; */
    1087                 : NS_IMETHODIMP
    1088               0 : nsSVGElement::GetViewportElement(nsIDOMSVGElement * *aViewportElement)
    1089                 : {
    1090               0 :   *aViewportElement = nsSVGUtils::GetNearestViewportElement(this).get();
    1091               0 :   return NS_OK;
    1092                 : }
    1093                 : 
    1094                 : //------------------------------------------------------------------------
    1095                 : // Helper class: MappedAttrParser, for parsing values of mapped attributes
    1096                 : 
    1097                 : namespace {
    1098                 : 
    1099                 : class MappedAttrParser {
    1100                 : public:
    1101                 :   MappedAttrParser(css::Loader* aLoader,
    1102                 :                    nsIURI* aDocURI,
    1103                 :                    already_AddRefed<nsIURI> aBaseURI,
    1104                 :                    nsIPrincipal* aNodePrincipal);
    1105                 :   ~MappedAttrParser();
    1106                 : 
    1107                 :   // Parses a mapped attribute value.
    1108                 :   void ParseMappedAttrValue(nsIAtom* aMappedAttrName,
    1109                 :                             nsAString& aMappedAttrValue);
    1110                 : 
    1111                 :   // If we've parsed any values for mapped attributes, this method returns
    1112                 :   // a new already_AddRefed css::StyleRule that incorporates the parsed
    1113                 :   // values. Otherwise, this method returns null.
    1114                 :   already_AddRefed<css::StyleRule> CreateStyleRule();
    1115                 : 
    1116                 : private:
    1117                 :   // MEMBER DATA
    1118                 :   // -----------
    1119                 :   nsCSSParser       mParser;
    1120                 : 
    1121                 :   // Arguments for nsCSSParser::ParseProperty
    1122                 :   nsIURI*           mDocURI;
    1123                 :   nsCOMPtr<nsIURI>  mBaseURI;
    1124                 :   nsIPrincipal*     mNodePrincipal;
    1125                 : 
    1126                 :   // Declaration for storing parsed values (lazily initialized)
    1127                 :   css::Declaration* mDecl;
    1128                 : };
    1129                 : 
    1130               0 : MappedAttrParser::MappedAttrParser(css::Loader* aLoader,
    1131                 :                                    nsIURI* aDocURI,
    1132                 :                                    already_AddRefed<nsIURI> aBaseURI,
    1133                 :                                    nsIPrincipal* aNodePrincipal)
    1134                 :   : mParser(aLoader), mDocURI(aDocURI), mBaseURI(aBaseURI),
    1135               0 :     mNodePrincipal(aNodePrincipal), mDecl(nsnull)
    1136                 : {
    1137                 :   // SVG and CSS differ slightly in their interpretation of some of
    1138                 :   // the attributes.  SVG allows attributes of the form: font-size="5"
    1139                 :   // (style="font-size: 5" if using a style attribute)
    1140                 :   // where CSS requires units: font-size="5pt" (style="font-size: 5pt")
    1141                 :   // Set a flag to pass information to the parser so that we can use
    1142                 :   // the CSS parser to parse the font-size attribute.  Note that this
    1143                 :   // does *not* affect the use of CSS stylesheets, which will still
    1144                 :   // require units.
    1145               0 :   mParser.SetSVGMode(true);
    1146               0 : }
    1147                 : 
    1148               0 : MappedAttrParser::~MappedAttrParser()
    1149                 : {
    1150               0 :   NS_ABORT_IF_FALSE(!mDecl,
    1151                 :                     "If mDecl was initialized, it should have been converted "
    1152                 :                     "into a style rule (and had its pointer cleared)");
    1153               0 : }
    1154                 : 
    1155                 : void
    1156               0 : MappedAttrParser::ParseMappedAttrValue(nsIAtom* aMappedAttrName,
    1157                 :                                        nsAString& aMappedAttrValue)
    1158                 : {
    1159               0 :   if (!mDecl) {
    1160               0 :     mDecl = new css::Declaration();
    1161               0 :     mDecl->InitializeEmpty();
    1162                 :   }
    1163                 : 
    1164                 :   // Get the nsCSSProperty ID for our mapped attribute.
    1165                 :   nsCSSProperty propertyID =
    1166               0 :     nsCSSProps::LookupProperty(nsDependentAtomString(aMappedAttrName));
    1167               0 :   if (propertyID != eCSSProperty_UNKNOWN) {
    1168                 :     bool changed; // outparam for ParseProperty. (ignored)
    1169                 :     mParser.ParseProperty(propertyID, aMappedAttrValue, mDocURI, mBaseURI,
    1170               0 :                           mNodePrincipal, mDecl, &changed, false);
    1171               0 :     return;
    1172                 :   }
    1173               0 :   NS_ABORT_IF_FALSE(aMappedAttrName == nsGkAtoms::lang,
    1174                 :                     "Only 'lang' should be unrecognized!");
    1175                 :   // nsCSSParser doesn't know about 'lang', so we need to handle it specially.
    1176               0 :   if (aMappedAttrName == nsGkAtoms::lang) {
    1177               0 :     propertyID = eCSSProperty__x_lang;
    1178               0 :     nsCSSExpandedDataBlock block;
    1179               0 :     mDecl->ExpandTo(&block);
    1180               0 :     nsCSSValue cssValue(PromiseFlatString(aMappedAttrValue), eCSSUnit_Ident);
    1181               0 :     block.AddLonghandProperty(propertyID, cssValue);
    1182               0 :     mDecl->ValueAppended(propertyID);
    1183               0 :     mDecl->CompressFrom(&block);
    1184                 :   }
    1185                 : }
    1186                 : 
    1187                 : already_AddRefed<css::StyleRule>
    1188               0 : MappedAttrParser::CreateStyleRule()
    1189                 : {
    1190               0 :   if (!mDecl) {
    1191               0 :     return nsnull; // No mapped attributes were parsed
    1192                 :   }
    1193                 : 
    1194               0 :   nsRefPtr<css::StyleRule> rule = new css::StyleRule(nsnull, mDecl);
    1195               0 :   mDecl = nsnull; // We no longer own the declaration -- drop our pointer to it
    1196               0 :   return rule.forget();
    1197                 : }
    1198                 : 
    1199                 : } // anonymous namespace
    1200                 : 
    1201                 : //----------------------------------------------------------------------
    1202                 : // Implementation Helpers:
    1203                 : 
    1204                 : bool
    1205               0 : nsSVGElement::IsEventName(nsIAtom* aName)
    1206                 : {
    1207               0 :   return false;
    1208                 : }
    1209                 : 
    1210                 : void
    1211               0 : nsSVGElement::UpdateContentStyleRule()
    1212                 : {
    1213               0 :   NS_ASSERTION(!mContentStyleRule, "we already have a content style rule");
    1214                 : 
    1215               0 :   PRUint32 attrCount = mAttrsAndChildren.AttrCount();
    1216               0 :   if (!attrCount) {
    1217                 :     // nothing to do
    1218               0 :     return;
    1219                 :   }
    1220                 : 
    1221               0 :   nsIDocument* doc = OwnerDoc();
    1222                 :   MappedAttrParser mappedAttrParser(doc->CSSLoader(), doc->GetDocumentURI(),
    1223               0 :                                     GetBaseURI(), NodePrincipal());
    1224                 : 
    1225               0 :   for (PRUint32 i = 0; i < attrCount; ++i) {
    1226               0 :     const nsAttrName* attrName = mAttrsAndChildren.AttrNameAt(i);
    1227               0 :     if (!attrName->IsAtom() || !IsAttributeMapped(attrName->Atom()))
    1228               0 :       continue;
    1229                 : 
    1230               0 :     if (attrName->NamespaceID() != kNameSpaceID_None &&
    1231               0 :         !attrName->Equals(nsGkAtoms::lang, kNameSpaceID_XML)) {
    1232               0 :       continue;
    1233                 :     }
    1234                 : 
    1235               0 :     if (attrName->Equals(nsGkAtoms::lang, kNameSpaceID_None) &&
    1236               0 :         HasAttr(kNameSpaceID_XML, nsGkAtoms::lang)) {
    1237               0 :       continue; // xml:lang has precedence
    1238                 :     }
    1239                 : 
    1240               0 :     if (Tag() == nsGkAtoms::svg) {
    1241                 :       // Special case: we don't want <svg> 'width'/'height' mapped into style
    1242                 :       // if the attribute value isn't a valid <length> according to SVG (which
    1243                 :       // only supports a subset of the CSS <length> values). We don't enforce
    1244                 :       // this by checking the attribute value in nsSVGSVGElement::
    1245                 :       // IsAttributeMapped since we don't want that method to depend on the
    1246                 :       // value of the attribute that is being checked. Rather we just prevent
    1247                 :       // the actual mapping here, as necessary.
    1248               0 :       if (attrName->Atom() == nsGkAtoms::width &&
    1249               0 :           !GetAnimatedLength(nsGkAtoms::width)->HasBaseVal()) {
    1250               0 :         continue;
    1251                 :       }
    1252               0 :       if (attrName->Atom() == nsGkAtoms::height &&
    1253               0 :           !GetAnimatedLength(nsGkAtoms::height)->HasBaseVal()) {
    1254               0 :         continue;
    1255                 :       }
    1256                 :     }
    1257                 : 
    1258               0 :     nsAutoString value;
    1259               0 :     mAttrsAndChildren.AttrAt(i)->ToString(value);
    1260               0 :     mappedAttrParser.ParseMappedAttrValue(attrName->Atom(), value);
    1261                 :   }
    1262               0 :   mContentStyleRule = mappedAttrParser.CreateStyleRule();
    1263                 : }
    1264                 : 
    1265                 : static void
    1266               0 : ParseMappedAttrAnimValueCallback(void*    aObject,
    1267                 :                                  nsIAtom* aPropertyName,
    1268                 :                                  void*    aPropertyValue,
    1269                 :                                  void*    aData)
    1270                 : {
    1271               0 :   NS_ABORT_IF_FALSE(aPropertyName != SMIL_MAPPED_ATTR_STYLERULE_ATOM,
    1272                 :                     "animated content style rule should have been removed "
    1273                 :                     "from properties table already (we're rebuilding it now)");
    1274                 : 
    1275                 :   MappedAttrParser* mappedAttrParser =
    1276               0 :     static_cast<MappedAttrParser*>(aData);
    1277                 : 
    1278               0 :   nsStringBuffer* valueBuf = static_cast<nsStringBuffer*>(aPropertyValue);
    1279               0 :   nsAutoString value;
    1280               0 :   PRUint32 len = NS_strlen(static_cast<PRUnichar*>(valueBuf->Data()));
    1281               0 :   valueBuf->ToString(len, value);
    1282                 : 
    1283               0 :   mappedAttrParser->ParseMappedAttrValue(aPropertyName, value);
    1284               0 : }
    1285                 : 
    1286                 : // Callback for freeing animated content style rule, in property table.
    1287                 : static void
    1288               0 : ReleaseStyleRule(void*    aObject,       /* unused */
    1289                 :                  nsIAtom* aPropertyName,
    1290                 :                  void*    aPropertyValue,
    1291                 :                  void*    aData          /* unused */)
    1292                 : {
    1293               0 :   NS_ABORT_IF_FALSE(aPropertyName == SMIL_MAPPED_ATTR_STYLERULE_ATOM,
    1294                 :                     "unexpected property name, for "
    1295                 :                     "animated content style rule");
    1296               0 :   css::StyleRule* styleRule = static_cast<css::StyleRule*>(aPropertyValue);
    1297               0 :   NS_ABORT_IF_FALSE(styleRule, "unexpected null style rule");
    1298               0 :   styleRule->Release();
    1299               0 : }
    1300                 : 
    1301                 : void
    1302               0 : nsSVGElement::UpdateAnimatedContentStyleRule()
    1303                 : {
    1304               0 :   NS_ABORT_IF_FALSE(!GetAnimatedContentStyleRule(),
    1305                 :                     "Animated content style rule already set");
    1306                 : 
    1307               0 :   nsIDocument* doc = OwnerDoc();
    1308               0 :   if (!doc) {
    1309               0 :     NS_ERROR("SVG element without owner document");
    1310               0 :     return;
    1311                 :   }
    1312                 : 
    1313                 :   MappedAttrParser mappedAttrParser(doc->CSSLoader(), doc->GetDocumentURI(),
    1314               0 :                                     GetBaseURI(), NodePrincipal());
    1315                 :   doc->PropertyTable(SMIL_MAPPED_ATTR_ANIMVAL)->
    1316               0 :     Enumerate(this, ParseMappedAttrAnimValueCallback, &mappedAttrParser);
    1317                 :  
    1318                 :   nsRefPtr<css::StyleRule>
    1319               0 :     animContentStyleRule(mappedAttrParser.CreateStyleRule());
    1320                 : 
    1321               0 :   if (animContentStyleRule) {
    1322                 : #ifdef DEBUG
    1323                 :     nsresult rv =
    1324                 : #endif
    1325                 :       SetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
    1326                 :                   SMIL_MAPPED_ATTR_STYLERULE_ATOM,
    1327               0 :                   animContentStyleRule.get(),
    1328               0 :                   ReleaseStyleRule);
    1329               0 :     animContentStyleRule.forget();
    1330               0 :     NS_ABORT_IF_FALSE(rv == NS_OK,
    1331                 :                       "SetProperty failed (or overwrote something)");
    1332                 :   }
    1333                 : }
    1334                 : 
    1335                 : css::StyleRule*
    1336               0 : nsSVGElement::GetAnimatedContentStyleRule()
    1337                 : {
    1338                 :   return
    1339                 :     static_cast<css::StyleRule*>(GetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
    1340                 :                                              SMIL_MAPPED_ATTR_STYLERULE_ATOM,
    1341               0 :                                              nsnull));
    1342                 : }
    1343                 : 
    1344                 : /**
    1345                 :  * Helper methods for the type-specific WillChangeXXX methods.
    1346                 :  *
    1347                 :  * This method sends out appropriate pre-change notifications so that selector
    1348                 :  * restyles (e.g. due to changes that cause |elem[attr="val"]| to start/stop
    1349                 :  * matching) work, and it returns an nsAttrValue that _may_ contain the
    1350                 :  * attribute's pre-change value.
    1351                 :  *
    1352                 :  * The nsAttrValue returned by this method depends on whether there are
    1353                 :  * mutation event listeners listening for changes to this element's attributes.
    1354                 :  * If not, then the object returned is empty. If there are, then the
    1355                 :  * nsAttrValue returned contains a serialized copy of the attribute's value
    1356                 :  * prior to the change, and this object should be passed to the corresponding
    1357                 :  * DidChangeXXX method call (assuming a WillChangeXXX call is required for the
    1358                 :  * SVG type - see comment below). This is necessary so that the 'prevValue'
    1359                 :  * property of the mutation event that is dispatched will correctly contain the
    1360                 :  * old value.
    1361                 :  *
    1362                 :  * The reason we need to serialize the old value if there are mutation
    1363                 :  * event listeners is because the underlying nsAttrValue for the attribute
    1364                 :  * points directly to a parsed representation of the attribute (e.g. an
    1365                 :  * SVGAnimatedLengthList*) that is a member of the SVG element. That object
    1366                 :  * will have changed by the time DidChangeXXX has been called, so without the
    1367                 :  * serialization of the old attribute value that we provide, DidChangeXXX
    1368                 :  * would have no way to get the old value to pass to SetAttrAndNotify.
    1369                 :  *
    1370                 :  * We only return the old value when there are mutation event listeners because
    1371                 :  * it's not needed otherwise, and because it's expensive to serialize the old
    1372                 :  * value. This is especially true for list type attributes, which may be built
    1373                 :  * up via the SVG DOM resulting in a large number of Will/DidModifyXXX calls
    1374                 :  * before the script finally finishes setting the attribute.
    1375                 :  *
    1376                 :  * Note that unlike using SetParsedAttr, using Will/DidChangeXXX does NOT check
    1377                 :  * and filter out redundant changes. Before calling WillChangeXXX, the caller
    1378                 :  * should check whether the new and old values are actually the same, and skip
    1379                 :  * calling Will/DidChangeXXX if they are.
    1380                 :  *
    1381                 :  * Also note that not all SVG types use this scheme. For types that can be
    1382                 :  * represented by an nsAttrValue without pointing back to an SVG object (e.g.
    1383                 :  * enums, booleans, integers) we can simply use SetParsedAttr which will do all
    1384                 :  * of the above for us. For such types there is no matching WillChangeXXX
    1385                 :  * method, only DidChangeXXX which calls SetParsedAttr.
    1386                 :  */
    1387                 : nsAttrValue
    1388               0 : nsSVGElement::WillChangeValue(nsIAtom* aName)
    1389                 : {
    1390                 :   // We need an empty attr value:
    1391                 :   //   a) to pass to BeforeSetAttr when GetParsedAttr returns nsnull
    1392                 :   //   b) to store the old value in the case we have mutation listeners
    1393                 :   // We can use the same value for both purposes since (a) happens before (b).
    1394                 :   // Also, we should be careful to always return this value to benefit from
    1395                 :   // return value optimization.
    1396               0 :   nsAttrValue emptyOrOldAttrValue;
    1397               0 :   const nsAttrValue* attrValue = GetParsedAttr(aName);
    1398                 : 
    1399                 :   // This is not strictly correct--the attribute value parameter for
    1400                 :   // BeforeSetAttr should reflect the value that *will* be set but that implies
    1401                 :   // allocating, e.g. an extra nsSVGLength2, and isn't necessary at the moment
    1402                 :   // since no SVG elements overload BeforeSetAttr. For now we just pass the
    1403                 :   // current value.
    1404                 :   nsAttrValueOrString attrStringOrValue(attrValue ? *attrValue
    1405               0 :                                                   : emptyOrOldAttrValue);
    1406                 :   DebugOnly<nsresult> rv =
    1407                 :     BeforeSetAttr(kNameSpaceID_None, aName, &attrStringOrValue,
    1408               0 :                   kNotifyDocumentObservers);
    1409                 :   // SVG elements aren't expected to overload BeforeSetAttr in such a way that
    1410                 :   // it may fail. So long as this is the case we don't need to check and pass on
    1411                 :   // the return value which simplifies the calling code significantly.
    1412               0 :   NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "Unexpected failure from BeforeSetAttr");
    1413                 : 
    1414                 :   // We only need to set the old value if we have listeners since otherwise it
    1415                 :   // isn't used.
    1416               0 :   if (attrValue &&
    1417                 :       nsContentUtils::HasMutationListeners(this,
    1418                 :                                            NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
    1419               0 :                                            this)) {
    1420               0 :     emptyOrOldAttrValue.SetToSerialized(*attrValue);
    1421                 :   }
    1422                 : 
    1423                 :   PRUint8 modType = attrValue
    1424                 :                   ? static_cast<PRUint8>(nsIDOMMutationEvent::MODIFICATION)
    1425               0 :                   : static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION);
    1426               0 :   nsNodeUtils::AttributeWillChange(this, kNameSpaceID_None, aName, modType);
    1427                 : 
    1428                 :   return emptyOrOldAttrValue;
    1429                 : }
    1430                 : 
    1431                 : /**
    1432                 :  * Helper methods for the type-specific DidChangeXXX methods.
    1433                 :  *
    1434                 :  * aEmptyOrOldValue will normally be the object returned from the corresponding
    1435                 :  * WillChangeXXX call. This is because:
    1436                 :  * a) WillChangeXXX will ensure the object is set when we have mutation
    1437                 :  *    listeners, and
    1438                 :  * b) WillChangeXXX will ensure the object represents a serialized version of
    1439                 :  *    the old attribute value so that the value doesn't change when the
    1440                 :  *    underlying SVG type is updated.
    1441                 :  */
    1442                 : void
    1443               0 : nsSVGElement::DidChangeValue(nsIAtom* aName,
    1444                 :                              const nsAttrValue& aEmptyOrOldValue,
    1445                 :                              nsAttrValue& aNewValue)
    1446                 : {
    1447                 :   bool hasListeners =
    1448                 :     nsContentUtils::HasMutationListeners(this,
    1449                 :                                          NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
    1450               0 :                                          this);
    1451               0 :   PRUint8 modType = HasAttr(kNameSpaceID_None, aName)
    1452                 :                   ? static_cast<PRUint8>(nsIDOMMutationEvent::MODIFICATION)
    1453               0 :                   : static_cast<PRUint8>(nsIDOMMutationEvent::ADDITION);
    1454                 :   SetAttrAndNotify(kNameSpaceID_None, aName, nsnull, aEmptyOrOldValue,
    1455                 :                    aNewValue, modType, hasListeners, kNotifyDocumentObservers,
    1456               0 :                    kCallAfterSetAttr);
    1457               0 : }
    1458                 : 
    1459                 : void
    1460               0 : nsSVGElement::MaybeSerializeAttrBeforeRemoval(nsIAtom* aName, bool aNotify)
    1461                 : {
    1462               0 :   if (!aNotify ||
    1463                 :       !nsContentUtils::HasMutationListeners(this,
    1464                 :                                             NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
    1465               0 :                                             this)) {
    1466               0 :     return;
    1467                 :   }
    1468                 : 
    1469               0 :   const nsAttrValue* attrValue = mAttrsAndChildren.GetAttr(aName);
    1470               0 :   if (!attrValue)
    1471               0 :     return;
    1472                 : 
    1473               0 :   nsAutoString serializedValue;
    1474               0 :   attrValue->ToString(serializedValue);
    1475               0 :   nsAttrValue oldAttrValue(serializedValue);
    1476               0 :   mAttrsAndChildren.SetAndTakeAttr(aName, oldAttrValue);
    1477                 : }
    1478                 : 
    1479                 : /* static */
    1480               0 : nsIAtom* nsSVGElement::GetEventNameForAttr(nsIAtom* aAttr)
    1481                 : {
    1482               0 :   if (aAttr == nsGkAtoms::onload)
    1483               0 :     return nsGkAtoms::onSVGLoad;
    1484               0 :   if (aAttr == nsGkAtoms::onunload)
    1485               0 :     return nsGkAtoms::onSVGUnload;
    1486               0 :   if (aAttr == nsGkAtoms::onabort)
    1487               0 :     return nsGkAtoms::onSVGAbort;
    1488               0 :   if (aAttr == nsGkAtoms::onerror)
    1489               0 :     return nsGkAtoms::onSVGError;
    1490               0 :   if (aAttr == nsGkAtoms::onresize)
    1491               0 :     return nsGkAtoms::onSVGResize;
    1492               0 :   if (aAttr == nsGkAtoms::onscroll)
    1493               0 :     return nsGkAtoms::onSVGScroll;
    1494               0 :   if (aAttr == nsGkAtoms::onzoom)
    1495               0 :     return nsGkAtoms::onSVGZoom;
    1496               0 :   if (aAttr == nsGkAtoms::onbegin)
    1497               0 :     return nsGkAtoms::onbeginEvent;
    1498               0 :   if (aAttr == nsGkAtoms::onrepeat)
    1499               0 :     return nsGkAtoms::onrepeatEvent;
    1500               0 :   if (aAttr == nsGkAtoms::onend)
    1501               0 :     return nsGkAtoms::onendEvent;
    1502                 : 
    1503               0 :   return aAttr;
    1504                 : }
    1505                 : 
    1506                 : nsSVGSVGElement *
    1507               0 : nsSVGElement::GetCtx() const
    1508                 : {
    1509               0 :   nsIContent* ancestor = GetFlattenedTreeParent();
    1510                 : 
    1511               0 :   while (ancestor && ancestor->IsSVG()) {
    1512               0 :     nsIAtom* tag = ancestor->Tag();
    1513               0 :     if (tag == nsGkAtoms::foreignObject) {
    1514               0 :       return nsnull;
    1515                 :     }
    1516               0 :     if (tag == nsGkAtoms::svg) {
    1517               0 :       return static_cast<nsSVGSVGElement*>(ancestor);
    1518                 :     }
    1519               0 :     ancestor = ancestor->GetFlattenedTreeParent();
    1520                 :   }
    1521                 : 
    1522                 :   // we don't have an ancestor <svg> element...
    1523               0 :   return nsnull;
    1524                 : }
    1525                 : 
    1526                 : /* virtual */ gfxMatrix
    1527               0 : nsSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
    1528                 :                                        TransformTypes aWhich) const
    1529                 : {
    1530               0 :   return aMatrix;
    1531                 : }
    1532                 : 
    1533                 : nsSVGElement::LengthAttributesInfo
    1534               0 : nsSVGElement::GetLengthInfo()
    1535                 : {
    1536               0 :   return LengthAttributesInfo(nsnull, nsnull, 0);
    1537                 : }
    1538                 : 
    1539               0 : void nsSVGElement::LengthAttributesInfo::Reset(PRUint8 aAttrEnum)
    1540                 : {
    1541               0 :   mLengths[aAttrEnum].Init(mLengthInfo[aAttrEnum].mCtxType,
    1542                 :                            aAttrEnum,
    1543               0 :                            mLengthInfo[aAttrEnum].mDefaultValue,
    1544               0 :                            mLengthInfo[aAttrEnum].mDefaultUnitType);
    1545               0 : }
    1546                 : 
    1547                 : void
    1548               0 : nsSVGElement::SetLength(nsIAtom* aName, const nsSVGLength2 &aLength)
    1549                 : {
    1550               0 :   LengthAttributesInfo lengthInfo = GetLengthInfo();
    1551                 : 
    1552               0 :   for (PRUint32 i = 0; i < lengthInfo.mLengthCount; i++) {
    1553               0 :     if (aName == *lengthInfo.mLengthInfo[i].mName) {
    1554               0 :       lengthInfo.mLengths[i] = aLength;
    1555               0 :       DidAnimateLength(i);
    1556               0 :       return;
    1557                 :     }
    1558                 :   }
    1559               0 :   NS_ABORT_IF_FALSE(false, "no length found to set");
    1560                 : }
    1561                 : 
    1562                 : nsAttrValue
    1563               0 : nsSVGElement::WillChangeLength(PRUint8 aAttrEnum)
    1564                 : {
    1565               0 :   return WillChangeValue(*GetLengthInfo().mLengthInfo[aAttrEnum].mName);
    1566                 : }
    1567                 : 
    1568                 : void
    1569               0 : nsSVGElement::DidChangeLength(PRUint8 aAttrEnum,
    1570                 :                               const nsAttrValue& aEmptyOrOldValue)
    1571                 : {
    1572               0 :   LengthAttributesInfo info = GetLengthInfo();
    1573                 : 
    1574               0 :   NS_ASSERTION(info.mLengthCount > 0,
    1575                 :                "DidChangeLength on element with no length attribs");
    1576               0 :   NS_ASSERTION(aAttrEnum < info.mLengthCount, "aAttrEnum out of range");
    1577                 : 
    1578               0 :   nsAttrValue newValue;
    1579               0 :   newValue.SetTo(info.mLengths[aAttrEnum], nsnull);
    1580                 : 
    1581               0 :   DidChangeValue(*info.mLengthInfo[aAttrEnum].mName, aEmptyOrOldValue,
    1582               0 :                  newValue);
    1583               0 : }
    1584                 : 
    1585                 : void
    1586               0 : nsSVGElement::DidAnimateLength(PRUint8 aAttrEnum)
    1587                 : {
    1588               0 :   nsIFrame* frame = GetPrimaryFrame();
    1589                 : 
    1590               0 :   if (frame) {
    1591               0 :     LengthAttributesInfo info = GetLengthInfo();
    1592                 :     frame->AttributeChanged(kNameSpaceID_None,
    1593               0 :                             *info.mLengthInfo[aAttrEnum].mName,
    1594               0 :                             nsIDOMMutationEvent::MODIFICATION);
    1595                 :   }
    1596               0 : }
    1597                 : 
    1598                 : nsSVGLength2*
    1599               0 : nsSVGElement::GetAnimatedLength(const nsIAtom *aAttrName)
    1600                 : {
    1601               0 :   LengthAttributesInfo lengthInfo = GetLengthInfo();
    1602                 : 
    1603               0 :   for (PRUint32 i = 0; i < lengthInfo.mLengthCount; i++) {
    1604               0 :     if (aAttrName == *lengthInfo.mLengthInfo[i].mName) {
    1605               0 :       return &lengthInfo.mLengths[i];
    1606                 :     }
    1607                 :   }
    1608               0 :   NS_ABORT_IF_FALSE(false, "no matching length found");
    1609               0 :   return nsnull;
    1610                 : }
    1611                 : 
    1612                 : void
    1613               0 : nsSVGElement::GetAnimatedLengthValues(float *aFirst, ...)
    1614                 : {
    1615               0 :   LengthAttributesInfo info = GetLengthInfo();
    1616                 : 
    1617               0 :   NS_ASSERTION(info.mLengthCount > 0,
    1618                 :                "GetAnimatedLengthValues on element with no length attribs");
    1619                 : 
    1620               0 :   nsSVGSVGElement *ctx = nsnull;
    1621                 : 
    1622               0 :   float *f = aFirst;
    1623               0 :   PRUint32 i = 0;
    1624                 : 
    1625                 :   va_list args;
    1626               0 :   va_start(args, aFirst);
    1627                 : 
    1628               0 :   while (f && i < info.mLengthCount) {
    1629               0 :     PRUint8 type = info.mLengths[i].GetSpecifiedUnitType();
    1630               0 :     if (!ctx) {
    1631               0 :       if (type != nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER &&
    1632                 :           type != nsIDOMSVGLength::SVG_LENGTHTYPE_PX)
    1633               0 :         ctx = GetCtx();
    1634                 :     }
    1635               0 :     if (type == nsIDOMSVGLength::SVG_LENGTHTYPE_EMS ||
    1636                 :         type == nsIDOMSVGLength::SVG_LENGTHTYPE_EXS)
    1637               0 :       *f = info.mLengths[i++].GetAnimValue(this);
    1638                 :     else
    1639               0 :       *f = info.mLengths[i++].GetAnimValue(ctx);
    1640               0 :     f = va_arg(args, float*);
    1641                 :   }
    1642                 : 
    1643               0 :   va_end(args);
    1644               0 : }
    1645                 : 
    1646                 : nsSVGElement::LengthListAttributesInfo
    1647               0 : nsSVGElement::GetLengthListInfo()
    1648                 : {
    1649               0 :   return LengthListAttributesInfo(nsnull, nsnull, 0);
    1650                 : }
    1651                 : 
    1652                 : void
    1653               0 : nsSVGElement::LengthListAttributesInfo::Reset(PRUint8 aAttrEnum)
    1654                 : {
    1655               0 :   mLengthLists[aAttrEnum].ClearBaseValue(aAttrEnum);
    1656                 :   // caller notifies
    1657               0 : }
    1658                 : 
    1659                 : nsAttrValue
    1660               0 : nsSVGElement::WillChangeLengthList(PRUint8 aAttrEnum)
    1661                 : {
    1662               0 :   return WillChangeValue(*GetLengthListInfo().mLengthListInfo[aAttrEnum].mName);
    1663                 : }
    1664                 : 
    1665                 : void
    1666               0 : nsSVGElement::DidChangeLengthList(PRUint8 aAttrEnum,
    1667                 :                                   const nsAttrValue& aEmptyOrOldValue)
    1668                 : {
    1669               0 :   LengthListAttributesInfo info = GetLengthListInfo();
    1670                 : 
    1671               0 :   NS_ASSERTION(info.mLengthListCount > 0,
    1672                 :                "DidChangeLengthList on element with no length list attribs");
    1673               0 :   NS_ASSERTION(aAttrEnum < info.mLengthListCount, "aAttrEnum out of range");
    1674                 : 
    1675               0 :   nsAttrValue newValue;
    1676               0 :   newValue.SetTo(info.mLengthLists[aAttrEnum].GetBaseValue(), nsnull);
    1677                 : 
    1678               0 :   DidChangeValue(*info.mLengthListInfo[aAttrEnum].mName, aEmptyOrOldValue,
    1679               0 :                  newValue);
    1680               0 : }
    1681                 : 
    1682                 : void
    1683               0 : nsSVGElement::DidAnimateLengthList(PRUint8 aAttrEnum)
    1684                 : {
    1685               0 :   nsIFrame* frame = GetPrimaryFrame();
    1686                 : 
    1687               0 :   if (frame) {
    1688               0 :     LengthListAttributesInfo info = GetLengthListInfo();
    1689                 :     frame->AttributeChanged(kNameSpaceID_None,
    1690               0 :                             *info.mLengthListInfo[aAttrEnum].mName,
    1691               0 :                             nsIDOMMutationEvent::MODIFICATION);
    1692                 :   }
    1693               0 : }
    1694                 : 
    1695                 : void
    1696               0 : nsSVGElement::GetAnimatedLengthListValues(SVGUserUnitList *aFirst, ...)
    1697                 : {
    1698               0 :   LengthListAttributesInfo info = GetLengthListInfo();
    1699                 : 
    1700               0 :   NS_ASSERTION(info.mLengthListCount > 0,
    1701                 :                "GetAnimatedLengthListValues on element with no length list attribs");
    1702                 : 
    1703               0 :   SVGUserUnitList *list = aFirst;
    1704               0 :   PRUint32 i = 0;
    1705                 : 
    1706                 :   va_list args;
    1707               0 :   va_start(args, aFirst);
    1708                 : 
    1709               0 :   while (list && i < info.mLengthListCount) {
    1710               0 :     list->Init(&(info.mLengthLists[i].GetAnimValue()), this, info.mLengthListInfo[i].mAxis);
    1711               0 :     ++i;
    1712               0 :     list = va_arg(args, SVGUserUnitList*);
    1713                 :   }
    1714                 : 
    1715               0 :   va_end(args);
    1716               0 : }
    1717                 : 
    1718                 : SVGAnimatedLengthList*
    1719               0 : nsSVGElement::GetAnimatedLengthList(PRUint8 aAttrEnum)
    1720                 : {
    1721               0 :   LengthListAttributesInfo info = GetLengthListInfo();
    1722               0 :   if (aAttrEnum < info.mLengthListCount) {
    1723               0 :     return &(info.mLengthLists[aAttrEnum]);
    1724                 :   }
    1725               0 :   NS_NOTREACHED("Bad attrEnum");
    1726               0 :   return nsnull;
    1727                 : }
    1728                 : 
    1729                 : 
    1730                 : nsSVGElement::NumberListAttributesInfo
    1731               0 : nsSVGElement::GetNumberListInfo()
    1732                 : {
    1733               0 :   return NumberListAttributesInfo(nsnull, nsnull, 0);
    1734                 : }
    1735                 : 
    1736                 : void
    1737               0 : nsSVGElement::NumberListAttributesInfo::Reset(PRUint8 aAttrEnum)
    1738                 : {
    1739               0 :   NS_ABORT_IF_FALSE(aAttrEnum < mNumberListCount, "Bad attr enum");
    1740               0 :   mNumberLists[aAttrEnum].ClearBaseValue(aAttrEnum);
    1741                 :   // caller notifies
    1742               0 : }
    1743                 : 
    1744                 : nsAttrValue
    1745               0 : nsSVGElement::WillChangeNumberList(PRUint8 aAttrEnum)
    1746                 : {
    1747               0 :   return WillChangeValue(*GetNumberListInfo().mNumberListInfo[aAttrEnum].mName);
    1748                 : }
    1749                 : 
    1750                 : void
    1751               0 : nsSVGElement::DidChangeNumberList(PRUint8 aAttrEnum,
    1752                 :                                   const nsAttrValue& aEmptyOrOldValue)
    1753                 : {
    1754               0 :   NumberListAttributesInfo info = GetNumberListInfo();
    1755                 : 
    1756               0 :   NS_ABORT_IF_FALSE(info.mNumberListCount > 0,
    1757                 :     "DidChangeNumberList on element with no number list attribs");
    1758               0 :   NS_ABORT_IF_FALSE(aAttrEnum < info.mNumberListCount,
    1759                 :     "aAttrEnum out of range");
    1760                 : 
    1761               0 :   nsAttrValue newValue;
    1762               0 :   newValue.SetTo(info.mNumberLists[aAttrEnum].GetBaseValue(), nsnull);
    1763                 : 
    1764               0 :   DidChangeValue(*info.mNumberListInfo[aAttrEnum].mName, aEmptyOrOldValue,
    1765               0 :                  newValue);
    1766               0 : }
    1767                 : 
    1768                 : void
    1769               0 : nsSVGElement::DidAnimateNumberList(PRUint8 aAttrEnum)
    1770                 : {
    1771               0 :   nsIFrame* frame = GetPrimaryFrame();
    1772                 : 
    1773               0 :   if (frame) {
    1774               0 :     NumberListAttributesInfo info = GetNumberListInfo();
    1775               0 :     NS_ABORT_IF_FALSE(aAttrEnum < info.mNumberListCount, "aAttrEnum out of range");
    1776                 : 
    1777                 :     frame->AttributeChanged(kNameSpaceID_None,
    1778               0 :                             *info.mNumberListInfo[aAttrEnum].mName,
    1779               0 :                             nsIDOMMutationEvent::MODIFICATION);
    1780                 :   }
    1781               0 : }
    1782                 : 
    1783                 : SVGAnimatedNumberList*
    1784               0 : nsSVGElement::GetAnimatedNumberList(PRUint8 aAttrEnum)
    1785                 : {
    1786               0 :   NumberListAttributesInfo info = GetNumberListInfo();
    1787               0 :   if (aAttrEnum < info.mNumberListCount) {
    1788               0 :     return &(info.mNumberLists[aAttrEnum]);
    1789                 :   }
    1790               0 :   NS_ABORT_IF_FALSE(false, "Bad attrEnum");
    1791               0 :   return nsnull;
    1792                 : }
    1793                 : 
    1794                 : SVGAnimatedNumberList*
    1795               0 : nsSVGElement::GetAnimatedNumberList(nsIAtom *aAttrName)
    1796                 : {
    1797               0 :   NumberListAttributesInfo info = GetNumberListInfo();
    1798               0 :   for (PRUint32 i = 0; i < info.mNumberListCount; i++) {
    1799               0 :     if (aAttrName == *info.mNumberListInfo[i].mName) {
    1800               0 :       return &info.mNumberLists[i];
    1801                 :     }
    1802                 :   }
    1803               0 :   NS_ABORT_IF_FALSE(false, "Bad caller");
    1804               0 :   return nsnull;
    1805                 : }
    1806                 : 
    1807                 : nsAttrValue
    1808               0 : nsSVGElement::WillChangePointList()
    1809                 : {
    1810               0 :   NS_ABORT_IF_FALSE(GetPointListAttrName(),
    1811                 :                     "Changing non-existent point list?");
    1812               0 :   return WillChangeValue(GetPointListAttrName());
    1813                 : }
    1814                 : 
    1815                 : void
    1816               0 : nsSVGElement::DidChangePointList(const nsAttrValue& aEmptyOrOldValue)
    1817                 : {
    1818               0 :   NS_ABORT_IF_FALSE(GetPointListAttrName(),
    1819                 :                     "Changing non-existent point list?");
    1820                 : 
    1821               0 :   nsAttrValue newValue;
    1822               0 :   newValue.SetTo(GetAnimatedPointList()->GetBaseValue(), nsnull);
    1823                 : 
    1824               0 :   DidChangeValue(GetPointListAttrName(), aEmptyOrOldValue, newValue);
    1825               0 : }
    1826                 : 
    1827                 : void
    1828               0 : nsSVGElement::DidAnimatePointList()
    1829                 : {
    1830               0 :   NS_ABORT_IF_FALSE(GetPointListAttrName(),
    1831                 :                     "Animating non-existent path data?");
    1832                 : 
    1833               0 :   nsIFrame* frame = GetPrimaryFrame();
    1834                 : 
    1835               0 :   if (frame) {
    1836                 :     frame->AttributeChanged(kNameSpaceID_None,
    1837               0 :                             GetPointListAttrName(),
    1838               0 :                             nsIDOMMutationEvent::MODIFICATION);
    1839                 :   }
    1840               0 : }
    1841                 : 
    1842                 : nsAttrValue
    1843               0 : nsSVGElement::WillChangePathSegList()
    1844                 : {
    1845               0 :   NS_ABORT_IF_FALSE(GetPathDataAttrName(),
    1846                 :                     "Changing non-existent path seg list?");
    1847               0 :   return WillChangeValue(GetPathDataAttrName());
    1848                 : }
    1849                 : 
    1850                 : void
    1851               0 : nsSVGElement::DidChangePathSegList(const nsAttrValue& aEmptyOrOldValue)
    1852                 : {
    1853               0 :   NS_ABORT_IF_FALSE(GetPathDataAttrName(),
    1854                 :                     "Changing non-existent path seg list?");
    1855                 : 
    1856               0 :   nsAttrValue newValue;
    1857               0 :   newValue.SetTo(GetAnimPathSegList()->GetBaseValue(), nsnull);
    1858                 : 
    1859               0 :   DidChangeValue(GetPathDataAttrName(), aEmptyOrOldValue, newValue);
    1860               0 : }
    1861                 : 
    1862                 : void
    1863               0 : nsSVGElement::DidAnimatePathSegList()
    1864                 : {
    1865               0 :   NS_ABORT_IF_FALSE(GetPathDataAttrName(),
    1866                 :                     "Animating non-existent path data?");
    1867                 : 
    1868               0 :   nsIFrame* frame = GetPrimaryFrame();
    1869                 : 
    1870               0 :   if (frame) {
    1871                 :     frame->AttributeChanged(kNameSpaceID_None,
    1872               0 :                             GetPathDataAttrName(),
    1873               0 :                             nsIDOMMutationEvent::MODIFICATION);
    1874                 :   }
    1875               0 : }
    1876                 : 
    1877                 : nsSVGElement::NumberAttributesInfo
    1878               0 : nsSVGElement::GetNumberInfo()
    1879                 : {
    1880               0 :   return NumberAttributesInfo(nsnull, nsnull, 0);
    1881                 : }
    1882                 : 
    1883               0 : void nsSVGElement::NumberAttributesInfo::Reset(PRUint8 aAttrEnum)
    1884                 : {
    1885                 :   mNumbers[aAttrEnum].Init(aAttrEnum,
    1886               0 :                            mNumberInfo[aAttrEnum].mDefaultValue);
    1887               0 : }
    1888                 : 
    1889                 : void
    1890               0 : nsSVGElement::DidChangeNumber(PRUint8 aAttrEnum)
    1891                 : {
    1892               0 :   NumberAttributesInfo info = GetNumberInfo();
    1893                 : 
    1894               0 :   NS_ASSERTION(info.mNumberCount > 0,
    1895                 :                "DidChangeNumber on element with no number attribs");
    1896               0 :   NS_ASSERTION(aAttrEnum < info.mNumberCount, "aAttrEnum out of range");
    1897                 : 
    1898               0 :   nsAttrValue attrValue;
    1899               0 :   attrValue.SetTo(info.mNumbers[aAttrEnum].GetBaseValue(), nsnull);
    1900                 : 
    1901               0 :   SetParsedAttr(kNameSpaceID_None, *info.mNumberInfo[aAttrEnum].mName, nsnull,
    1902               0 :                 attrValue, true);
    1903               0 : }
    1904                 : 
    1905                 : void
    1906               0 : nsSVGElement::DidAnimateNumber(PRUint8 aAttrEnum)
    1907                 : {
    1908               0 :   nsIFrame* frame = GetPrimaryFrame();
    1909                 : 
    1910               0 :   if (frame) {
    1911               0 :     NumberAttributesInfo info = GetNumberInfo();
    1912                 :     frame->AttributeChanged(kNameSpaceID_None,
    1913               0 :                             *info.mNumberInfo[aAttrEnum].mName,
    1914               0 :                             nsIDOMMutationEvent::MODIFICATION);
    1915                 :   }
    1916               0 : }
    1917                 : 
    1918                 : void
    1919               0 : nsSVGElement::GetAnimatedNumberValues(float *aFirst, ...)
    1920                 : {
    1921               0 :   NumberAttributesInfo info = GetNumberInfo();
    1922                 : 
    1923               0 :   NS_ASSERTION(info.mNumberCount > 0,
    1924                 :                "GetAnimatedNumberValues on element with no number attribs");
    1925                 : 
    1926               0 :   float *f = aFirst;
    1927               0 :   PRUint32 i = 0;
    1928                 : 
    1929                 :   va_list args;
    1930               0 :   va_start(args, aFirst);
    1931                 : 
    1932               0 :   while (f && i < info.mNumberCount) {
    1933               0 :     *f = info.mNumbers[i++].GetAnimValue();
    1934               0 :     f = va_arg(args, float*);
    1935                 :   }
    1936               0 :   va_end(args);
    1937               0 : }
    1938                 : 
    1939                 : nsSVGElement::NumberPairAttributesInfo
    1940               0 : nsSVGElement::GetNumberPairInfo()
    1941                 : {
    1942               0 :   return NumberPairAttributesInfo(nsnull, nsnull, 0);
    1943                 : }
    1944                 : 
    1945               0 : void nsSVGElement::NumberPairAttributesInfo::Reset(PRUint8 aAttrEnum)
    1946                 : {
    1947                 :   mNumberPairs[aAttrEnum].Init(aAttrEnum,
    1948               0 :                                mNumberPairInfo[aAttrEnum].mDefaultValue1,
    1949               0 :                                mNumberPairInfo[aAttrEnum].mDefaultValue2);
    1950               0 : }
    1951                 : 
    1952                 : nsAttrValue
    1953               0 : nsSVGElement::WillChangeNumberPair(PRUint8 aAttrEnum)
    1954                 : {
    1955               0 :   return WillChangeValue(*GetNumberPairInfo().mNumberPairInfo[aAttrEnum].mName);
    1956                 : }
    1957                 : 
    1958                 : void
    1959               0 : nsSVGElement::DidChangeNumberPair(PRUint8 aAttrEnum,
    1960                 :                                   const nsAttrValue& aEmptyOrOldValue)
    1961                 : {
    1962               0 :   NumberPairAttributesInfo info = GetNumberPairInfo();
    1963                 : 
    1964               0 :   NS_ASSERTION(info.mNumberPairCount > 0,
    1965                 :                "DidChangePairNumber on element with no number pair attribs");
    1966               0 :   NS_ASSERTION(aAttrEnum < info.mNumberPairCount, "aAttrEnum out of range");
    1967                 : 
    1968               0 :   nsAttrValue newValue;
    1969               0 :   newValue.SetTo(info.mNumberPairs[aAttrEnum], nsnull);
    1970                 : 
    1971               0 :   DidChangeValue(*info.mNumberPairInfo[aAttrEnum].mName, aEmptyOrOldValue,
    1972               0 :                  newValue);
    1973               0 : }
    1974                 : 
    1975                 : void
    1976               0 : nsSVGElement::DidAnimateNumberPair(PRUint8 aAttrEnum)
    1977                 : {
    1978               0 :   nsIFrame* frame = GetPrimaryFrame();
    1979                 : 
    1980               0 :   if (frame) {
    1981               0 :     NumberPairAttributesInfo info = GetNumberPairInfo();
    1982                 :     frame->AttributeChanged(kNameSpaceID_None,
    1983               0 :                             *info.mNumberPairInfo[aAttrEnum].mName,
    1984               0 :                             nsIDOMMutationEvent::MODIFICATION);
    1985                 :   }
    1986               0 : }
    1987                 : 
    1988                 : nsSVGElement::IntegerAttributesInfo
    1989               0 : nsSVGElement::GetIntegerInfo()
    1990                 : {
    1991               0 :   return IntegerAttributesInfo(nsnull, nsnull, 0);
    1992                 : }
    1993                 : 
    1994               0 : void nsSVGElement::IntegerAttributesInfo::Reset(PRUint8 aAttrEnum)
    1995                 : {
    1996                 :   mIntegers[aAttrEnum].Init(aAttrEnum,
    1997               0 :                             mIntegerInfo[aAttrEnum].mDefaultValue);
    1998               0 : }
    1999                 : 
    2000                 : void
    2001               0 : nsSVGElement::DidChangeInteger(PRUint8 aAttrEnum)
    2002                 : {
    2003               0 :   IntegerAttributesInfo info = GetIntegerInfo();
    2004                 : 
    2005               0 :   NS_ASSERTION(info.mIntegerCount > 0,
    2006                 :                "DidChangeInteger on element with no integer attribs");
    2007               0 :   NS_ASSERTION(aAttrEnum < info.mIntegerCount, "aAttrEnum out of range");
    2008                 : 
    2009               0 :   nsAttrValue attrValue;
    2010               0 :   attrValue.SetTo(info.mIntegers[aAttrEnum].GetBaseValue(), nsnull);
    2011                 : 
    2012               0 :   SetParsedAttr(kNameSpaceID_None, *info.mIntegerInfo[aAttrEnum].mName, nsnull,
    2013               0 :                 attrValue, true);
    2014               0 : }
    2015                 : 
    2016                 : void
    2017               0 : nsSVGElement::DidAnimateInteger(PRUint8 aAttrEnum)
    2018                 : {
    2019               0 :   nsIFrame* frame = GetPrimaryFrame();
    2020                 :   
    2021               0 :   if (frame) {
    2022               0 :     IntegerAttributesInfo info = GetIntegerInfo();
    2023                 :     frame->AttributeChanged(kNameSpaceID_None,
    2024               0 :                             *info.mIntegerInfo[aAttrEnum].mName,
    2025               0 :                             nsIDOMMutationEvent::MODIFICATION);
    2026                 :   }
    2027               0 : }
    2028                 : 
    2029                 : void
    2030               0 : nsSVGElement::GetAnimatedIntegerValues(PRInt32 *aFirst, ...)
    2031                 : {
    2032               0 :   IntegerAttributesInfo info = GetIntegerInfo();
    2033                 : 
    2034               0 :   NS_ASSERTION(info.mIntegerCount > 0,
    2035                 :                "GetAnimatedIntegerValues on element with no integer attribs");
    2036                 : 
    2037               0 :   PRInt32 *n = aFirst;
    2038               0 :   PRUint32 i = 0;
    2039                 : 
    2040                 :   va_list args;
    2041               0 :   va_start(args, aFirst);
    2042                 : 
    2043               0 :   while (n && i < info.mIntegerCount) {
    2044               0 :     *n = info.mIntegers[i++].GetAnimValue();
    2045               0 :     n = va_arg(args, PRInt32*);
    2046                 :   }
    2047               0 :   va_end(args);
    2048               0 : }
    2049                 : 
    2050                 : nsSVGElement::IntegerPairAttributesInfo
    2051               0 : nsSVGElement::GetIntegerPairInfo()
    2052                 : {
    2053               0 :   return IntegerPairAttributesInfo(nsnull, nsnull, 0);
    2054                 : }
    2055                 : 
    2056               0 : void nsSVGElement::IntegerPairAttributesInfo::Reset(PRUint8 aAttrEnum)
    2057                 : {
    2058                 :   mIntegerPairs[aAttrEnum].Init(aAttrEnum,
    2059               0 :                                 mIntegerPairInfo[aAttrEnum].mDefaultValue1,
    2060               0 :                                 mIntegerPairInfo[aAttrEnum].mDefaultValue2);
    2061               0 : }
    2062                 : 
    2063                 : nsAttrValue
    2064               0 : nsSVGElement::WillChangeIntegerPair(PRUint8 aAttrEnum)
    2065                 : {
    2066                 :   return WillChangeValue(
    2067               0 :     *GetIntegerPairInfo().mIntegerPairInfo[aAttrEnum].mName);
    2068                 : }
    2069                 : 
    2070                 : void
    2071               0 : nsSVGElement::DidChangeIntegerPair(PRUint8 aAttrEnum,
    2072                 :                                    const nsAttrValue& aEmptyOrOldValue)
    2073                 : {
    2074               0 :   IntegerPairAttributesInfo info = GetIntegerPairInfo();
    2075                 : 
    2076               0 :   NS_ASSERTION(info.mIntegerPairCount > 0,
    2077                 :                "DidChangeIntegerPair on element with no integer pair attribs");
    2078               0 :   NS_ASSERTION(aAttrEnum < info.mIntegerPairCount, "aAttrEnum out of range");
    2079                 : 
    2080               0 :   nsAttrValue newValue;
    2081               0 :   newValue.SetTo(info.mIntegerPairs[aAttrEnum], nsnull);
    2082                 : 
    2083               0 :   DidChangeValue(*info.mIntegerPairInfo[aAttrEnum].mName, aEmptyOrOldValue,
    2084               0 :                  newValue);
    2085               0 : }
    2086                 : 
    2087                 : void
    2088               0 : nsSVGElement::DidAnimateIntegerPair(PRUint8 aAttrEnum)
    2089                 : {
    2090               0 :   nsIFrame* frame = GetPrimaryFrame();
    2091                 :   
    2092               0 :   if (frame) {
    2093               0 :     IntegerPairAttributesInfo info = GetIntegerPairInfo();
    2094                 :     frame->AttributeChanged(kNameSpaceID_None,
    2095               0 :                             *info.mIntegerPairInfo[aAttrEnum].mName,
    2096               0 :                             nsIDOMMutationEvent::MODIFICATION);
    2097                 :   }
    2098               0 : }
    2099                 : 
    2100                 : nsSVGElement::AngleAttributesInfo
    2101               0 : nsSVGElement::GetAngleInfo()
    2102                 : {
    2103               0 :   return AngleAttributesInfo(nsnull, nsnull, 0);
    2104                 : }
    2105                 : 
    2106               0 : void nsSVGElement::AngleAttributesInfo::Reset(PRUint8 aAttrEnum)
    2107                 : {
    2108                 :   mAngles[aAttrEnum].Init(aAttrEnum, 
    2109               0 :                           mAngleInfo[aAttrEnum].mDefaultValue,
    2110               0 :                           mAngleInfo[aAttrEnum].mDefaultUnitType);
    2111               0 : }
    2112                 : 
    2113                 : nsAttrValue
    2114               0 : nsSVGElement::WillChangeAngle(PRUint8 aAttrEnum)
    2115                 : {
    2116               0 :   return WillChangeValue(*GetAngleInfo().mAngleInfo[aAttrEnum].mName);
    2117                 : }
    2118                 : 
    2119                 : void
    2120               0 : nsSVGElement::DidChangeAngle(PRUint8 aAttrEnum,
    2121                 :                              const nsAttrValue& aEmptyOrOldValue)
    2122                 : {
    2123               0 :   AngleAttributesInfo info = GetAngleInfo();
    2124                 : 
    2125               0 :   NS_ASSERTION(info.mAngleCount > 0,
    2126                 :                "DidChangeAngle on element with no angle attribs");
    2127               0 :   NS_ASSERTION(aAttrEnum < info.mAngleCount, "aAttrEnum out of range");
    2128                 : 
    2129               0 :   nsAttrValue newValue;
    2130               0 :   newValue.SetTo(info.mAngles[aAttrEnum], nsnull);
    2131                 : 
    2132               0 :   DidChangeValue(*info.mAngleInfo[aAttrEnum].mName, aEmptyOrOldValue, newValue);
    2133               0 : }
    2134                 : 
    2135                 : void
    2136               0 : nsSVGElement::DidAnimateAngle(PRUint8 aAttrEnum)
    2137                 : {
    2138               0 :   nsIFrame* frame = GetPrimaryFrame();
    2139                 : 
    2140               0 :   if (frame) {
    2141               0 :     AngleAttributesInfo info = GetAngleInfo();
    2142                 :     frame->AttributeChanged(kNameSpaceID_None,
    2143               0 :                             *info.mAngleInfo[aAttrEnum].mName,
    2144               0 :                             nsIDOMMutationEvent::MODIFICATION);
    2145                 :   }
    2146               0 : }
    2147                 : 
    2148                 : nsSVGElement::BooleanAttributesInfo
    2149               0 : nsSVGElement::GetBooleanInfo()
    2150                 : {
    2151               0 :   return BooleanAttributesInfo(nsnull, nsnull, 0);
    2152                 : }
    2153                 : 
    2154               0 : void nsSVGElement::BooleanAttributesInfo::Reset(PRUint8 aAttrEnum)
    2155                 : {
    2156                 :   mBooleans[aAttrEnum].Init(aAttrEnum,
    2157               0 :                             mBooleanInfo[aAttrEnum].mDefaultValue);
    2158               0 : }
    2159                 : 
    2160                 : void
    2161               0 : nsSVGElement::DidChangeBoolean(PRUint8 aAttrEnum)
    2162                 : {
    2163               0 :   BooleanAttributesInfo info = GetBooleanInfo();
    2164                 : 
    2165               0 :   NS_ASSERTION(info.mBooleanCount > 0,
    2166                 :                "DidChangeBoolean on element with no boolean attribs");
    2167               0 :   NS_ASSERTION(aAttrEnum < info.mBooleanCount, "aAttrEnum out of range");
    2168                 : 
    2169               0 :   nsAttrValue attrValue(info.mBooleans[aAttrEnum].GetBaseValueAtom());
    2170               0 :   SetParsedAttr(kNameSpaceID_None, *info.mBooleanInfo[aAttrEnum].mName, nsnull,
    2171               0 :                 attrValue, true);
    2172               0 : }
    2173                 : 
    2174                 : void
    2175               0 : nsSVGElement::DidAnimateBoolean(PRUint8 aAttrEnum)
    2176                 : {
    2177               0 :   nsIFrame* frame = GetPrimaryFrame();
    2178                 :   
    2179               0 :   if (frame) {
    2180               0 :     BooleanAttributesInfo info = GetBooleanInfo();
    2181                 :     frame->AttributeChanged(kNameSpaceID_None,
    2182               0 :                             *info.mBooleanInfo[aAttrEnum].mName,
    2183               0 :                             nsIDOMMutationEvent::MODIFICATION);
    2184                 :   }
    2185               0 : }
    2186                 : 
    2187                 : nsSVGElement::EnumAttributesInfo
    2188               0 : nsSVGElement::GetEnumInfo()
    2189                 : {
    2190               0 :   return EnumAttributesInfo(nsnull, nsnull, 0);
    2191                 : }
    2192                 : 
    2193               0 : void nsSVGElement::EnumAttributesInfo::Reset(PRUint8 aAttrEnum)
    2194                 : {
    2195                 :   mEnums[aAttrEnum].Init(aAttrEnum,
    2196               0 :                          mEnumInfo[aAttrEnum].mDefaultValue);
    2197               0 : }
    2198                 : 
    2199                 : void
    2200               0 : nsSVGElement::DidChangeEnum(PRUint8 aAttrEnum)
    2201                 : {
    2202               0 :   EnumAttributesInfo info = GetEnumInfo();
    2203                 : 
    2204               0 :   NS_ASSERTION(info.mEnumCount > 0,
    2205                 :                "DidChangeEnum on element with no enum attribs");
    2206               0 :   NS_ASSERTION(aAttrEnum < info.mEnumCount, "aAttrEnum out of range");
    2207                 : 
    2208               0 :   nsAttrValue attrValue(info.mEnums[aAttrEnum].GetBaseValueAtom(this));
    2209               0 :   SetParsedAttr(kNameSpaceID_None, *info.mEnumInfo[aAttrEnum].mName, nsnull,
    2210               0 :                 attrValue, true);
    2211               0 : }
    2212                 : 
    2213                 : void
    2214               0 : nsSVGElement::DidAnimateEnum(PRUint8 aAttrEnum)
    2215                 : {
    2216               0 :   nsIFrame* frame = GetPrimaryFrame();
    2217                 : 
    2218               0 :   if (frame) {
    2219               0 :     EnumAttributesInfo info = GetEnumInfo();
    2220                 :     frame->AttributeChanged(kNameSpaceID_None,
    2221               0 :                             *info.mEnumInfo[aAttrEnum].mName,
    2222               0 :                             nsIDOMMutationEvent::MODIFICATION);
    2223                 :   }
    2224               0 : }
    2225                 : 
    2226                 : nsSVGViewBox *
    2227               0 : nsSVGElement::GetViewBox()
    2228                 : {
    2229               0 :   return nsnull;
    2230                 : }
    2231                 : 
    2232                 : nsAttrValue
    2233               0 : nsSVGElement::WillChangeViewBox()
    2234                 : {
    2235               0 :   return WillChangeValue(nsGkAtoms::viewBox);
    2236                 : }
    2237                 : 
    2238                 : void
    2239               0 : nsSVGElement::DidChangeViewBox(const nsAttrValue& aEmptyOrOldValue)
    2240                 : {
    2241               0 :   nsSVGViewBox *viewBox = GetViewBox();
    2242                 : 
    2243               0 :   NS_ASSERTION(viewBox, "DidChangeViewBox on element with no viewBox attrib");
    2244                 : 
    2245               0 :   nsAttrValue newValue;
    2246               0 :   newValue.SetTo(*viewBox, nsnull);
    2247                 : 
    2248               0 :   DidChangeValue(nsGkAtoms::viewBox, aEmptyOrOldValue, newValue);
    2249               0 : }
    2250                 : 
    2251                 : void
    2252               0 : nsSVGElement::DidAnimateViewBox()
    2253                 : {
    2254               0 :   nsIFrame* frame = GetPrimaryFrame();
    2255                 :   
    2256               0 :   if (frame) {
    2257                 :     frame->AttributeChanged(kNameSpaceID_None,
    2258                 :                             nsGkAtoms::viewBox,
    2259               0 :                             nsIDOMMutationEvent::MODIFICATION);
    2260                 :   }
    2261               0 : }
    2262                 : 
    2263                 : SVGAnimatedPreserveAspectRatio *
    2264               0 : nsSVGElement::GetPreserveAspectRatio()
    2265                 : {
    2266               0 :   return nsnull;
    2267                 : }
    2268                 : 
    2269                 : nsAttrValue
    2270               0 : nsSVGElement::WillChangePreserveAspectRatio()
    2271                 : {
    2272               0 :   return WillChangeValue(nsGkAtoms::preserveAspectRatio);
    2273                 : }
    2274                 : 
    2275                 : void
    2276               0 : nsSVGElement::DidChangePreserveAspectRatio(const nsAttrValue& aEmptyOrOldValue)
    2277                 : {
    2278                 :   SVGAnimatedPreserveAspectRatio *preserveAspectRatio =
    2279               0 :     GetPreserveAspectRatio();
    2280                 : 
    2281               0 :   NS_ASSERTION(preserveAspectRatio,
    2282                 :                "DidChangePreserveAspectRatio on element with no "
    2283                 :                "preserveAspectRatio attrib");
    2284                 : 
    2285               0 :   nsAttrValue newValue;
    2286               0 :   newValue.SetTo(*preserveAspectRatio, nsnull);
    2287                 : 
    2288               0 :   DidChangeValue(nsGkAtoms::preserveAspectRatio, aEmptyOrOldValue, newValue);
    2289               0 : }
    2290                 : 
    2291                 : void
    2292               0 : nsSVGElement::DidAnimatePreserveAspectRatio()
    2293                 : {
    2294               0 :   nsIFrame* frame = GetPrimaryFrame();
    2295                 :   
    2296               0 :   if (frame) {
    2297                 :     frame->AttributeChanged(kNameSpaceID_None,
    2298                 :                             nsGkAtoms::preserveAspectRatio,
    2299               0 :                             nsIDOMMutationEvent::MODIFICATION);
    2300                 :   }
    2301               0 : }
    2302                 : 
    2303                 : nsAttrValue
    2304               0 : nsSVGElement::WillChangeTransformList()
    2305                 : {
    2306               0 :   return WillChangeValue(GetTransformListAttrName());
    2307                 : }
    2308                 : 
    2309                 : void
    2310               0 : nsSVGElement::DidChangeTransformList(const nsAttrValue& aEmptyOrOldValue)
    2311                 : {
    2312               0 :   NS_ABORT_IF_FALSE(GetTransformListAttrName(),
    2313                 :                     "Changing non-existent transform list?");
    2314                 : 
    2315               0 :   nsAttrValue newValue;
    2316               0 :   newValue.SetTo(GetAnimatedTransformList()->GetBaseValue(), nsnull);
    2317                 : 
    2318               0 :   DidChangeValue(GetTransformListAttrName(), aEmptyOrOldValue, newValue);
    2319               0 : }
    2320                 : 
    2321                 : void
    2322               0 : nsSVGElement::DidAnimateTransformList()
    2323                 : {
    2324               0 :   NS_ABORT_IF_FALSE(GetTransformListAttrName(),
    2325                 :                     "Animating non-existent transform data?");
    2326                 : 
    2327               0 :   nsIFrame* frame = GetPrimaryFrame();
    2328                 : 
    2329               0 :   if (frame) {
    2330                 :     frame->AttributeChanged(kNameSpaceID_None,
    2331               0 :                             GetTransformListAttrName(),
    2332               0 :                             nsIDOMMutationEvent::MODIFICATION);
    2333                 :   }
    2334               0 : }
    2335                 : 
    2336                 : nsSVGElement::StringAttributesInfo
    2337               0 : nsSVGElement::GetStringInfo()
    2338                 : {
    2339               0 :   return StringAttributesInfo(nsnull, nsnull, 0);
    2340                 : }
    2341                 : 
    2342               0 : void nsSVGElement::StringAttributesInfo::Reset(PRUint8 aAttrEnum)
    2343                 : {
    2344               0 :   mStrings[aAttrEnum].Init(aAttrEnum);
    2345               0 : }
    2346                 : 
    2347               0 : void nsSVGElement::GetStringBaseValue(PRUint8 aAttrEnum, nsAString& aResult) const
    2348                 : {
    2349               0 :   nsSVGElement::StringAttributesInfo info = const_cast<nsSVGElement*>(this)->GetStringInfo();
    2350                 : 
    2351               0 :   NS_ASSERTION(info.mStringCount > 0,
    2352                 :                "GetBaseValue on element with no string attribs");
    2353                 : 
    2354               0 :   NS_ASSERTION(aAttrEnum < info.mStringCount, "aAttrEnum out of range");
    2355                 : 
    2356               0 :   GetAttr(info.mStringInfo[aAttrEnum].mNamespaceID,
    2357               0 :           *info.mStringInfo[aAttrEnum].mName, aResult);
    2358               0 : }
    2359                 : 
    2360               0 : void nsSVGElement::SetStringBaseValue(PRUint8 aAttrEnum, const nsAString& aValue)
    2361                 : {
    2362               0 :   nsSVGElement::StringAttributesInfo info = GetStringInfo();
    2363                 : 
    2364               0 :   NS_ASSERTION(info.mStringCount > 0,
    2365                 :                "SetBaseValue on element with no string attribs");
    2366                 : 
    2367               0 :   NS_ASSERTION(aAttrEnum < info.mStringCount, "aAttrEnum out of range");
    2368                 : 
    2369               0 :   SetAttr(info.mStringInfo[aAttrEnum].mNamespaceID,
    2370               0 :           *info.mStringInfo[aAttrEnum].mName, aValue, true);
    2371               0 : }
    2372                 : 
    2373                 : void
    2374               0 : nsSVGElement::DidAnimateString(PRUint8 aAttrEnum)
    2375                 : {
    2376               0 :   nsIFrame* frame = GetPrimaryFrame();
    2377                 : 
    2378               0 :   if (frame) {
    2379               0 :     StringAttributesInfo info = GetStringInfo();
    2380               0 :     frame->AttributeChanged(info.mStringInfo[aAttrEnum].mNamespaceID,
    2381               0 :                             *info.mStringInfo[aAttrEnum].mName,
    2382               0 :                             nsIDOMMutationEvent::MODIFICATION);
    2383                 :   }
    2384               0 : }
    2385                 : 
    2386                 : nsSVGElement::StringListAttributesInfo
    2387               0 : nsSVGElement::GetStringListInfo()
    2388                 : {
    2389               0 :   return StringListAttributesInfo(nsnull, nsnull, 0);
    2390                 : }
    2391                 : 
    2392                 : nsAttrValue
    2393               0 : nsSVGElement::WillChangeStringList(bool aIsConditionalProcessingAttribute,
    2394                 :                                    PRUint8 aAttrEnum)
    2395                 : {
    2396                 :   nsIAtom* name;
    2397               0 :   if (aIsConditionalProcessingAttribute) {
    2398               0 :     nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(this));
    2399               0 :     name = tests->GetAttrName(aAttrEnum);
    2400                 :   } else {
    2401               0 :     name = *GetStringListInfo().mStringListInfo[aAttrEnum].mName;
    2402                 :   }
    2403               0 :   return WillChangeValue(name);
    2404                 : }
    2405                 : 
    2406                 : void
    2407               0 : nsSVGElement::DidChangeStringList(bool aIsConditionalProcessingAttribute,
    2408                 :                                   PRUint8 aAttrEnum,
    2409                 :                                   const nsAttrValue& aEmptyOrOldValue)
    2410                 : {
    2411                 :   nsIAtom* name;
    2412               0 :   nsAttrValue newValue;
    2413               0 :   nsCOMPtr<DOMSVGTests> tests;
    2414                 : 
    2415               0 :   if (aIsConditionalProcessingAttribute) {
    2416               0 :     tests = do_QueryInterface(this);
    2417               0 :     name = tests->GetAttrName(aAttrEnum);
    2418               0 :     tests->GetAttrValue(aAttrEnum, newValue);
    2419                 :   } else {
    2420               0 :     StringListAttributesInfo info = GetStringListInfo();
    2421                 : 
    2422               0 :     NS_ASSERTION(info.mStringListCount > 0,
    2423                 :                  "DidChangeStringList on element with no string list attribs");
    2424               0 :     NS_ASSERTION(aAttrEnum < info.mStringListCount, "aAttrEnum out of range");
    2425                 : 
    2426               0 :     name = *info.mStringListInfo[aAttrEnum].mName;
    2427               0 :     newValue.SetTo(info.mStringLists[aAttrEnum], nsnull);
    2428                 :   }
    2429                 : 
    2430               0 :   DidChangeValue(name, aEmptyOrOldValue, newValue);
    2431                 : 
    2432               0 :   if (aIsConditionalProcessingAttribute) {
    2433               0 :     tests->MaybeInvalidate();
    2434                 :   }
    2435               0 : }
    2436                 : 
    2437                 : void
    2438               0 : nsSVGElement::StringListAttributesInfo::Reset(PRUint8 aAttrEnum)
    2439                 : {
    2440               0 :   mStringLists[aAttrEnum].Clear();
    2441                 :   // caller notifies
    2442               0 : }
    2443                 : 
    2444                 : nsresult
    2445               0 : nsSVGElement::ReportAttributeParseFailure(nsIDocument* aDocument,
    2446                 :                                           nsIAtom* aAttribute,
    2447                 :                                           const nsAString& aValue)
    2448                 : {
    2449               0 :   const nsAFlatString& attributeValue = PromiseFlatString(aValue);
    2450               0 :   const PRUnichar *strings[] = { aAttribute->GetUTF16String(),
    2451               0 :                                  attributeValue.get() };
    2452                 :   return nsSVGUtils::ReportToConsole(aDocument,
    2453                 :                                      "AttributeParseWarning",
    2454               0 :                                      strings, ArrayLength(strings));
    2455                 : }
    2456                 : 
    2457                 : void
    2458               0 : nsSVGElement::RecompileScriptEventListeners()
    2459                 : {
    2460               0 :   PRInt32 i, count = mAttrsAndChildren.AttrCount();
    2461               0 :   for (i = 0; i < count; ++i) {
    2462               0 :     const nsAttrName *name = mAttrsAndChildren.AttrNameAt(i);
    2463                 : 
    2464                 :     // Eventlistenener-attributes are always in the null namespace
    2465               0 :     if (!name->IsAtom()) {
    2466               0 :         continue;
    2467                 :     }
    2468                 : 
    2469               0 :     nsIAtom *attr = name->Atom();
    2470               0 :     if (!IsEventName(attr)) {
    2471               0 :       continue;
    2472                 :     }
    2473                 : 
    2474               0 :     nsAutoString value;
    2475               0 :     GetAttr(kNameSpaceID_None, attr, value);
    2476               0 :     AddScriptEventListener(GetEventNameForAttr(attr), value, true);
    2477                 :   }
    2478               0 : }
    2479                 : 
    2480                 : nsISMILAttr*
    2481               0 : nsSVGElement::GetAnimatedAttr(PRInt32 aNamespaceID, nsIAtom* aName)
    2482                 : {
    2483               0 :   if (aNamespaceID == kNameSpaceID_None) {
    2484                 :     // Transforms:
    2485               0 :     if (GetTransformListAttrName() == aName) {
    2486               0 :       SVGAnimatedTransformList* transformList = GetAnimatedTransformList();
    2487               0 :       return transformList ?  transformList->ToSMILAttr(this) : nsnull;
    2488                 :     }
    2489                 : 
    2490                 :     // Motion (fake 'attribute' for animateMotion)
    2491               0 :     if (aName == nsGkAtoms::mozAnimateMotionDummyAttr) {
    2492               0 :       return new SVGMotionSMILAttr(this);
    2493                 :     }
    2494                 : 
    2495                 :     // Lengths:
    2496               0 :     LengthAttributesInfo info = GetLengthInfo();
    2497               0 :     for (PRUint32 i = 0; i < info.mLengthCount; i++) {
    2498               0 :       if (aName == *info.mLengthInfo[i].mName) {
    2499               0 :         return info.mLengths[i].ToSMILAttr(this);
    2500                 :       }
    2501                 :     }
    2502                 : 
    2503                 :     // Numbers:
    2504                 :     {
    2505               0 :       NumberAttributesInfo info = GetNumberInfo();
    2506               0 :       for (PRUint32 i = 0; i < info.mNumberCount; i++) {
    2507               0 :         if (aName == *info.mNumberInfo[i].mName) {
    2508               0 :           return info.mNumbers[i].ToSMILAttr(this);
    2509                 :         }
    2510                 :       }
    2511                 :     }
    2512                 : 
    2513                 :     // Number Pairs:
    2514                 :     {
    2515               0 :       NumberPairAttributesInfo info = GetNumberPairInfo();
    2516               0 :       for (PRUint32 i = 0; i < info.mNumberPairCount; i++) {
    2517               0 :         if (aName == *info.mNumberPairInfo[i].mName) {
    2518               0 :           return info.mNumberPairs[i].ToSMILAttr(this);
    2519                 :         }
    2520                 :       }
    2521                 :     }
    2522                 : 
    2523                 :     // Integers:
    2524                 :     {
    2525               0 :       IntegerAttributesInfo info = GetIntegerInfo();
    2526               0 :       for (PRUint32 i = 0; i < info.mIntegerCount; i++) {
    2527               0 :         if (aName == *info.mIntegerInfo[i].mName) {
    2528               0 :           return info.mIntegers[i].ToSMILAttr(this);
    2529                 :         }
    2530                 :       }
    2531                 :     }
    2532                 : 
    2533                 :     // Integer Pairs:
    2534                 :     {
    2535               0 :       IntegerPairAttributesInfo info = GetIntegerPairInfo();
    2536               0 :       for (PRUint32 i = 0; i < info.mIntegerPairCount; i++) {
    2537               0 :         if (aName == *info.mIntegerPairInfo[i].mName) {
    2538               0 :           return info.mIntegerPairs[i].ToSMILAttr(this);
    2539                 :         }
    2540                 :       }
    2541                 :     }
    2542                 : 
    2543                 :     // Enumerations:
    2544                 :     {
    2545               0 :       EnumAttributesInfo info = GetEnumInfo();
    2546               0 :       for (PRUint32 i = 0; i < info.mEnumCount; i++) {
    2547               0 :         if (aName == *info.mEnumInfo[i].mName) {
    2548               0 :           return info.mEnums[i].ToSMILAttr(this);
    2549                 :         }
    2550                 :       }
    2551                 :     }
    2552                 : 
    2553                 :     // Booleans:
    2554                 :     {
    2555               0 :       BooleanAttributesInfo info = GetBooleanInfo();
    2556               0 :       for (PRUint32 i = 0; i < info.mBooleanCount; i++) {
    2557               0 :         if (aName == *info.mBooleanInfo[i].mName) {
    2558               0 :           return info.mBooleans[i].ToSMILAttr(this);
    2559                 :         }
    2560                 :       }
    2561                 :     }
    2562                 : 
    2563                 :     // Angles:
    2564                 :     {
    2565               0 :       AngleAttributesInfo info = GetAngleInfo();
    2566               0 :       for (PRUint32 i = 0; i < info.mAngleCount; i++) {
    2567               0 :         if (aName == *info.mAngleInfo[i].mName) {
    2568               0 :           return info.mAngles[i].ToSMILAttr(this);
    2569                 :         }
    2570                 :       }
    2571                 :     }
    2572                 : 
    2573                 :     // viewBox:
    2574               0 :     if (aName == nsGkAtoms::viewBox) {
    2575               0 :       nsSVGViewBox *viewBox = GetViewBox();
    2576               0 :       return viewBox ? viewBox->ToSMILAttr(this) : nsnull;
    2577                 :     }
    2578                 : 
    2579                 :     // preserveAspectRatio:
    2580               0 :     if (aName == nsGkAtoms::preserveAspectRatio) {
    2581                 :       SVGAnimatedPreserveAspectRatio *preserveAspectRatio =
    2582               0 :         GetPreserveAspectRatio();
    2583                 :       return preserveAspectRatio ?
    2584               0 :         preserveAspectRatio->ToSMILAttr(this) : nsnull;
    2585                 :     }
    2586                 : 
    2587                 :     // NumberLists:
    2588                 :     {
    2589               0 :       NumberListAttributesInfo info = GetNumberListInfo();
    2590               0 :       for (PRUint32 i = 0; i < info.mNumberListCount; i++) {
    2591               0 :         if (aName == *info.mNumberListInfo[i].mName) {
    2592               0 :           NS_ABORT_IF_FALSE(i <= UCHAR_MAX, "Too many attributes");
    2593               0 :           return info.mNumberLists[i].ToSMILAttr(this, PRUint8(i));
    2594                 :         }
    2595                 :       }
    2596                 :     }
    2597                 : 
    2598                 :     // LengthLists:
    2599                 :     {
    2600               0 :       LengthListAttributesInfo info = GetLengthListInfo();
    2601               0 :       for (PRUint32 i = 0; i < info.mLengthListCount; i++) {
    2602               0 :         if (aName == *info.mLengthListInfo[i].mName) {
    2603               0 :           NS_ABORT_IF_FALSE(i <= UCHAR_MAX, "Too many attributes");
    2604                 :           return info.mLengthLists[i].ToSMILAttr(this,
    2605                 :                                                  PRUint8(i),
    2606               0 :                                                  info.mLengthListInfo[i].mAxis,
    2607               0 :                                                  info.mLengthListInfo[i].mCouldZeroPadList);
    2608                 :         }
    2609                 :       }
    2610                 :     }
    2611                 : 
    2612                 :     // PointLists:
    2613                 :     {
    2614               0 :       if (GetPointListAttrName() == aName) {
    2615               0 :         SVGAnimatedPointList *pointList = GetAnimatedPointList();
    2616               0 :         if (pointList) {
    2617               0 :           return pointList->ToSMILAttr(this);
    2618                 :         }
    2619                 :       }
    2620                 :     }
    2621                 : 
    2622                 :     // PathSegLists:
    2623                 :     {
    2624               0 :       if (GetPathDataAttrName() == aName) {
    2625               0 :         SVGAnimatedPathSegList *segList = GetAnimPathSegList();
    2626               0 :         if (segList) {
    2627               0 :           return segList->ToSMILAttr(this);
    2628                 :         }
    2629                 :       }
    2630                 :     }
    2631                 : 
    2632                 :     // Mapped attributes:
    2633               0 :     if (IsAttributeMapped(aName)) {
    2634                 :       nsCSSProperty prop =
    2635               0 :         nsCSSProps::LookupProperty(nsDependentAtomString(aName));
    2636                 :       // Check IsPropertyAnimatable to avoid attributes that...
    2637                 :       //  - map to explicitly unanimatable properties (e.g. 'direction')
    2638                 :       //  - map to unsupported attributes (e.g. 'glyph-orientation-horizontal')
    2639               0 :       if (nsSMILCSSProperty::IsPropertyAnimatable(prop)) {
    2640               0 :         return new nsSMILMappedAttribute(prop, this);
    2641                 :       }
    2642                 :     }
    2643                 :   }
    2644                 : 
    2645                 :   // Strings
    2646                 :   {
    2647               0 :     StringAttributesInfo info = GetStringInfo();
    2648               0 :     for (PRUint32 i = 0; i < info.mStringCount; i++) {
    2649               0 :       if (aNamespaceID == info.mStringInfo[i].mNamespaceID &&
    2650               0 :           aName == *info.mStringInfo[i].mName) {
    2651               0 :         return info.mStrings[i].ToSMILAttr(this);
    2652                 :       }
    2653                 :     }
    2654                 :   }
    2655                 : 
    2656               0 :   return nsnull;
    2657                 : }
    2658                 : 
    2659                 : void
    2660               0 : nsSVGElement::AnimationNeedsResample()
    2661                 : {
    2662               0 :   nsIDocument* doc = GetCurrentDoc();
    2663               0 :   if (doc && doc->HasAnimationController()) {
    2664               0 :     doc->GetAnimationController()->SetResampleNeeded();
    2665                 :   }
    2666               0 : }
    2667                 : 
    2668                 : void
    2669               0 : nsSVGElement::FlushAnimations()
    2670                 : {
    2671               0 :   nsIDocument* doc = GetCurrentDoc();
    2672               0 :   if (doc && doc->HasAnimationController()) {
    2673               0 :     doc->GetAnimationController()->FlushResampleRequests();
    2674                 :   }
    2675               0 : }

Generated by: LCOV version 1.7