LCOV - app.info - content/svg/content/src/nsSVGElement.cpp

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-04-21 | 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