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

LCOV - code coverage report
| Current view: | directory - content/svg/content/src - nsSVGAnimationElement.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 190 | 2 | 1.1 %
| Date: | 2012-06-02 | Functions: | 38 | 2 | 5.3 %

           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 the Mozilla SVG project.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is Brian Birtles.
          18                 :  * Portions created by the Initial Developer are Copyright (C) 2005
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *   Brian Birtles <birtles@gmail.com>
          23                 :  *   Chris Double  <chris.double@double.co.nz>
          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 "nsSVGAnimationElement.h"
          40                 : #include "nsSVGSVGElement.h"
          41                 : #include "nsSMILTimeContainer.h"
          42                 : #include "nsSMILAnimationController.h"
          43                 : #include "nsSMILAnimationFunction.h"
          44                 : #include "nsISMILAttr.h"
          45                 : #include "nsContentUtils.h"
          46                 :
          47                 : using namespace mozilla::dom;
          48                 :
          49                 : //----------------------------------------------------------------------
          50                 : // nsISupports methods
          51                 :
          52               0 : NS_IMPL_ADDREF_INHERITED(nsSVGAnimationElement, nsSVGAnimationElementBase)
          53               0 : NS_IMPL_RELEASE_INHERITED(nsSVGAnimationElement, nsSVGAnimationElementBase)
          54                 :
          55               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGAnimationElement)
          56               0 :   NS_INTERFACE_MAP_ENTRY(nsISMILAnimationElement)
          57               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMElementTimeControl)
          58               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTests)
          59               0 : NS_INTERFACE_MAP_END_INHERITING(nsSVGAnimationElementBase)
          60                 :
          61                 : // Cycle collection magic -- based on nsSVGUseElement
          62            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsSVGAnimationElement)
          63               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsSVGAnimationElement,
          64                 :                                                 nsSVGAnimationElementBase)
          65               0 :   tmp->mHrefTarget.Unlink();
          66               0 :   tmp->mTimedElement.Unlink();
          67               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
          68                 :
          69               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsSVGAnimationElement,
          70                 :                                                   nsSVGAnimationElementBase)
          71               0 :   tmp->mHrefTarget.Traverse(&cb);
          72               0 :   tmp->mTimedElement.Traverse(&cb);
          73               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
          74                 :
          75                 : //----------------------------------------------------------------------
          76                 : // Implementation
          77                 :
          78                 : #ifdef _MSC_VER
          79                 : // Disable "warning C4355: 'this' : used in base member initializer list".
          80                 : // We can ignore that warning because we know that mHrefTarget's constructor
          81                 : // doesn't dereference the pointer passed to it.
          82                 : #pragma warning(push)
          83                 : #pragma warning(disable:4355)
          84                 : #endif
          85               0 : nsSVGAnimationElement::nsSVGAnimationElement(already_AddRefed<nsINodeInfo> aNodeInfo)
          86                 :   : nsSVGAnimationElementBase(aNodeInfo),
          87               0 :     mHrefTarget(this)
          88                 : #ifdef _MSC_VER
          89                 : #pragma warning(pop)
          90                 : #endif
          91                 : {
          92               0 : }
          93                 :
          94                 : nsresult
          95               0 : nsSVGAnimationElement::Init()
          96                 : {
          97               0 :   nsresult rv = nsSVGAnimationElementBase::Init();
          98               0 :   NS_ENSURE_SUCCESS(rv, rv);
          99                 :
         100               0 :   mTimedElement.SetAnimationElement(this);
         101               0 :   AnimationFunction().SetAnimationElement(this);
         102               0 :   mTimedElement.SetTimeClient(&AnimationFunction());
         103                 :
         104               0 :   return NS_OK;
         105                 : }
         106                 :
         107                 : //----------------------------------------------------------------------
         108                 : // nsISMILAnimationElement methods
         109                 :
         110                 : const Element&
         111               0 : nsSVGAnimationElement::AsElement() const
         112                 : {
         113               0 :   return *this;
         114                 : }
         115                 :
         116                 : Element&
         117               0 : nsSVGAnimationElement::AsElement()
         118                 : {
         119               0 :   return *this;
         120                 : }
         121                 :
         122                 : bool
         123               0 : nsSVGAnimationElement::PassesConditionalProcessingTests()
         124                 : {
         125                 :   nsCOMPtr<DOMSVGTests> tests(do_QueryInterface(
         126               0 :     static_cast<nsSVGElement*>(this)));
         127               0 :   return tests->PassesConditionalProcessingTests();
         128                 : }
         129                 :
         130                 : const nsAttrValue*
         131               0 : nsSVGAnimationElement::GetAnimAttr(nsIAtom* aName) const
         132                 : {
         133               0 :   return mAttrsAndChildren.GetAttr(aName, kNameSpaceID_None);
         134                 : }
         135                 :
         136                 : bool
         137               0 : nsSVGAnimationElement::GetAnimAttr(nsIAtom* aAttName,
         138                 :                                    nsAString& aResult) const
         139                 : {
         140               0 :   return GetAttr(kNameSpaceID_None, aAttName, aResult);
         141                 : }
         142                 :
         143                 : bool
         144               0 : nsSVGAnimationElement::HasAnimAttr(nsIAtom* aAttName) const
         145                 : {
         146               0 :   return HasAttr(kNameSpaceID_None, aAttName);
         147                 : }
         148                 :
         149                 : Element*
         150               0 : nsSVGAnimationElement::GetTargetElementContent()
         151                 : {
         152               0 :   if (HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)) {
         153               0 :     return mHrefTarget.get();
         154                 :   }
         155               0 :   NS_ABORT_IF_FALSE(!mHrefTarget.get(),
         156                 :                     "We shouldn't have an xlink:href target "
         157                 :                     "if we don't have an xlink:href attribute");
         158                 :
         159                 :   // No "xlink:href" attribute --> I should target my parent.
         160               0 :   nsIContent* parent = GetFlattenedTreeParent();
         161               0 :   return parent && parent->IsElement() ? parent->AsElement() : nsnull;
         162                 : }
         163                 :
         164                 : bool
         165               0 : nsSVGAnimationElement::GetTargetAttributeName(PRInt32 *aNamespaceID,
         166                 :                                               nsIAtom **aLocalName) const
         167                 : {
         168                 :   const nsAttrValue* nameAttr
         169               0 :     = mAttrsAndChildren.GetAttr(nsGkAtoms::attributeName);
         170                 :
         171               0 :   if (!nameAttr)
         172               0 :     return false;
         173                 :
         174               0 :   NS_ASSERTION(nameAttr->Type() == nsAttrValue::eAtom,
         175                 :     "attributeName should have been parsed as an atom");
         176                 :
         177               0 :   return NS_SUCCEEDED(nsContentUtils::SplitQName(
         178                 :                         this, nsDependentAtomString(nameAttr->GetAtomValue()),
         179                 :                         aNamespaceID, aLocalName));
         180                 : }
         181                 :
         182                 : nsSMILTargetAttrType
         183               0 : nsSVGAnimationElement::GetTargetAttributeType() const
         184                 : {
         185                 :   nsIContent::AttrValuesArray typeValues[] = { &nsGkAtoms::css,
         186                 :                                                &nsGkAtoms::XML,
         187               0 :                                                nsnull};
         188                 :   nsSMILTargetAttrType smilTypes[] = { eSMILTargetAttrType_CSS,
         189               0 :                                        eSMILTargetAttrType_XML };
         190                 :   PRInt32 index = FindAttrValueIn(kNameSpaceID_None,
         191                 :                                   nsGkAtoms::attributeType,
         192                 :                                   typeValues,
         193               0 :                                   eCaseMatters);
         194               0 :   return (index >= 0) ? smilTypes[index] : eSMILTargetAttrType_auto;
         195                 : }
         196                 :
         197                 : nsSMILTimedElement&
         198               0 : nsSVGAnimationElement::TimedElement()
         199                 : {
         200               0 :   return mTimedElement;
         201                 : }
         202                 :
         203                 : //----------------------------------------------------------------------
         204                 : // nsIDOMSVGAnimationElement methods
         205                 :
         206                 : /* readonly attribute SVGElement targetElement; */
         207                 : NS_IMETHODIMP
         208               0 : nsSVGAnimationElement::GetTargetElement(nsIDOMSVGElement** aTarget)
         209                 : {
         210               0 :   FlushAnimations();
         211                 :
         212                 :   // We'll just call the other GetTargetElement method, and QI to the right type
         213               0 :   nsIContent* targetContent = GetTargetElementContent();
         214                 :
         215               0 :   nsCOMPtr<nsIDOMSVGElement> targetSVG = do_QueryInterface(targetContent);
         216               0 :   NS_IF_ADDREF(*aTarget = targetSVG);
         217                 :
         218               0 :   return NS_OK;
         219                 : }
         220                 :
         221                 : /* float getStartTime() raises( DOMException ); */
         222                 : NS_IMETHODIMP
         223               0 : nsSVGAnimationElement::GetStartTime(float* retval)
         224                 : {
         225               0 :   FlushAnimations();
         226                 :
         227               0 :   nsSMILTimeValue startTime = mTimedElement.GetStartTime();
         228               0 :   if (!startTime.IsDefinite())
         229               0 :     return NS_ERROR_DOM_INVALID_STATE_ERR;
         230                 :
         231               0 :   *retval = float(double(startTime.GetMillis()) / PR_MSEC_PER_SEC);
         232                 :
         233               0 :   return NS_OK;
         234                 : }
         235                 :
         236                 : /* float getCurrentTime(); */
         237                 : NS_IMETHODIMP
         238               0 : nsSVGAnimationElement::GetCurrentTime(float* retval)
         239                 : {
         240                 :   // Not necessary to call FlushAnimations() for this
         241                 :
         242               0 :   nsSMILTimeContainer* root = GetTimeContainer();
         243               0 :   if (root) {
         244               0 :     *retval = float(double(root->GetCurrentTime()) / PR_MSEC_PER_SEC);
         245                 :   } else {
         246               0 :     *retval = 0.f;
         247                 :   }
         248               0 :   return NS_OK;
         249                 : }
         250                 :
         251                 : /* float getSimpleDuration() raises( DOMException ); */
         252                 : NS_IMETHODIMP
         253               0 : nsSVGAnimationElement::GetSimpleDuration(float* retval)
         254                 : {
         255                 :   // Not necessary to call FlushAnimations() for this
         256                 :
         257               0 :   nsSMILTimeValue simpleDur = mTimedElement.GetSimpleDuration();
         258               0 :   if (!simpleDur.IsDefinite()) {
         259               0 :     *retval = 0.f;
         260               0 :     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
         261                 :   }
         262                 :
         263               0 :   *retval = float(double(simpleDur.GetMillis()) / PR_MSEC_PER_SEC);
         264               0 :   return NS_OK;
         265                 : }
         266                 :
         267                 : //----------------------------------------------------------------------
         268                 : // nsIContent methods
         269                 :
         270                 : nsresult
         271               0 : nsSVGAnimationElement::BindToTree(nsIDocument* aDocument,
         272                 :                                   nsIContent* aParent,
         273                 :                                   nsIContent* aBindingParent,
         274                 :                                   bool aCompileEventHandlers)
         275                 : {
         276               0 :   NS_ABORT_IF_FALSE(!mHrefTarget.get(),
         277                 :                     "Shouldn't have href-target yet "
         278                 :                     "(or it should've been cleared)");
         279                 :   nsresult rv = nsSVGAnimationElementBase::BindToTree(aDocument, aParent,
         280                 :                                                       aBindingParent,
         281               0 :                                                       aCompileEventHandlers);
         282               0 :   NS_ENSURE_SUCCESS(rv,rv);
         283                 :
         284                 :   // XXXdholbert is GetCtx (as a check for SVG parent) still needed here?
         285               0 :   if (!GetCtx()) {
         286                 :     // No use proceeding. We don't have an SVG parent (yet) so we won't be able
         287                 :     // to register ourselves etc. Maybe next time we'll have more luck.
         288                 :     // (This sort of situation will arise a lot when trees are being constructed
         289                 :     // piece by piece via script)
         290               0 :     return NS_OK;
         291                 :   }
         292                 :
         293                 :   // Add myself to the animation controller's master set of animation elements.
         294               0 :   if (aDocument) {
         295               0 :     nsSMILAnimationController *controller = aDocument->GetAnimationController();
         296               0 :     if (controller) {
         297               0 :       controller->RegisterAnimationElement(this);
         298                 :     }
         299                 :     const nsAttrValue* href = mAttrsAndChildren.GetAttr(nsGkAtoms::href,
         300               0 :                                                         kNameSpaceID_XLink);
         301               0 :     if (href) {
         302               0 :       nsAutoString hrefStr;
         303               0 :       href->ToString(hrefStr);
         304                 :
         305                 :       // Pass in |aParent| instead of |this| -- first argument is only used
         306                 :       // for a call to GetCurrentDoc(), and |this| might not have a current
         307                 :       // document yet.
         308               0 :       UpdateHrefTarget(aParent, hrefStr);
         309                 :     }
         310                 :
         311               0 :     mTimedElement.BindToTree(aParent);
         312                 :   }
         313                 :
         314               0 :   AnimationNeedsResample();
         315                 :
         316               0 :   return NS_OK;
         317                 : }
         318                 :
         319                 : void
         320               0 : nsSVGAnimationElement::UnbindFromTree(bool aDeep, bool aNullParent)
         321                 : {
         322               0 :   nsSMILAnimationController *controller = OwnerDoc()->GetAnimationController();
         323               0 :   if (controller) {
         324               0 :     controller->UnregisterAnimationElement(this);
         325                 :   }
         326                 :
         327               0 :   mHrefTarget.Unlink();
         328               0 :   mTimedElement.DissolveReferences();
         329                 :
         330               0 :   AnimationNeedsResample();
         331                 :
         332               0 :   nsSVGAnimationElementBase::UnbindFromTree(aDeep, aNullParent);
         333               0 : }
         334                 :
         335                 : bool
         336               0 : nsSVGAnimationElement::ParseAttribute(PRInt32 aNamespaceID,
         337                 :                                       nsIAtom* aAttribute,
         338                 :                                       const nsAString& aValue,
         339                 :                                       nsAttrValue& aResult)
         340                 : {
         341               0 :   if (aNamespaceID == kNameSpaceID_None) {
         342                 :     // Deal with target-related attributes here
         343               0 :     if (aAttribute == nsGkAtoms::attributeName ||
         344                 :         aAttribute == nsGkAtoms::attributeType) {
         345               0 :       aResult.ParseAtom(aValue);
         346               0 :       AnimationNeedsResample();
         347               0 :       return true;
         348                 :     }
         349                 :
         350               0 :     nsresult rv = NS_ERROR_FAILURE;
         351                 :
         352                 :     // First let the animation function try to parse it...
         353                 :     bool foundMatch =
         354               0 :       AnimationFunction().SetAttr(aAttribute, aValue, aResult, &rv);
         355                 :
         356                 :     // ... and if that didn't recognize the attribute, let the timed element
         357                 :     // try to parse it.
         358               0 :     if (!foundMatch) {
         359                 :       foundMatch =
         360               0 :         mTimedElement.SetAttr(aAttribute, aValue, aResult, this, &rv);
         361                 :     }
         362                 :
         363               0 :     if (foundMatch) {
         364               0 :       AnimationNeedsResample();
         365               0 :       if (NS_FAILED(rv)) {
         366               0 :         ReportAttributeParseFailure(OwnerDoc(), aAttribute, aValue);
         367               0 :         return false;
         368                 :       }
         369               0 :       return true;
         370                 :     }
         371                 :   }
         372                 :
         373                 :   return nsSVGAnimationElementBase::ParseAttribute(aNamespaceID, aAttribute,
         374               0 :                                                    aValue, aResult);
         375                 : }
         376                 :
         377                 : nsresult
         378               0 : nsSVGAnimationElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
         379                 :                                     const nsAttrValue* aValue, bool aNotify)
         380                 : {
         381                 :   nsresult rv =
         382                 :     nsSVGAnimationElementBase::AfterSetAttr(aNamespaceID, aName, aValue,
         383               0 :                                             aNotify);
         384                 :
         385               0 :   if (aNamespaceID != kNameSpaceID_XLink || aName != nsGkAtoms::href)
         386               0 :     return rv;
         387                 :
         388               0 :   if (!aValue) {
         389               0 :     mHrefTarget.Unlink();
         390               0 :     AnimationTargetChanged();
         391               0 :   } else if (IsInDoc()) {
         392               0 :     NS_ABORT_IF_FALSE(aValue->Type() == nsAttrValue::eString,
         393                 :                       "Expected href attribute to be string type");
         394               0 :     UpdateHrefTarget(this, aValue->GetStringValue());
         395                 :   } // else: we're not yet in a document -- we'll update the target on
         396                 :     // next BindToTree call.
         397                 :
         398               0 :   return rv;
         399                 : }
         400                 :
         401                 : nsresult
         402               0 : nsSVGAnimationElement::UnsetAttr(PRInt32 aNamespaceID,
         403                 :                                  nsIAtom* aAttribute, bool aNotify)
         404                 : {
         405                 :   nsresult rv = nsSVGAnimationElementBase::UnsetAttr(aNamespaceID, aAttribute,
         406               0 :                                                      aNotify);
         407               0 :   NS_ENSURE_SUCCESS(rv,rv);
         408                 :
         409               0 :   if (aNamespaceID == kNameSpaceID_None) {
         410               0 :     if (AnimationFunction().UnsetAttr(aAttribute) ||
         411               0 :         mTimedElement.UnsetAttr(aAttribute)) {
         412               0 :       AnimationNeedsResample();
         413                 :     }
         414                 :   }
         415                 :
         416               0 :   return NS_OK;
         417                 : }
         418                 :
         419                 : bool
         420               0 : nsSVGAnimationElement::IsNodeOfType(PRUint32 aFlags) const
         421                 : {
         422               0 :   return !(aFlags & ~(eCONTENT | eANIMATION));
         423                 : }
         424                 :
         425                 : //----------------------------------------------------------------------
         426                 : // Implementation helpers
         427                 :
         428                 : nsSMILTimeContainer*
         429               0 : nsSVGAnimationElement::GetTimeContainer()
         430                 : {
         431               0 :   nsSVGSVGElement *element = nsSVGUtils::GetOuterSVGElement(this);
         432                 :
         433               0 :   if (element) {
         434               0 :     return element->GetTimedDocumentRoot();
         435                 :   }
         436                 :
         437               0 :   return nsnull;
         438                 : }
         439                 :
         440                 : // nsIDOMElementTimeControl
         441                 : /* void beginElement (); */
         442                 : NS_IMETHODIMP
         443               0 : nsSVGAnimationElement::BeginElement(void)
         444                 : {
         445               0 :   return BeginElementAt(0.f);
         446                 : }
         447                 :
         448                 : /* void beginElementAt (in float offset); */
         449                 : NS_IMETHODIMP
         450               0 : nsSVGAnimationElement::BeginElementAt(float offset)
         451                 : {
         452               0 :   NS_ENSURE_FINITE(offset, NS_ERROR_ILLEGAL_VALUE);
         453                 :
         454                 :   // Make sure the timegraph is up-to-date
         455               0 :   FlushAnimations();
         456                 :
         457                 :   // This will fail if we're not attached to a time container (SVG document
         458                 :   // fragment).
         459               0 :   nsresult rv = mTimedElement.BeginElementAt(offset);
         460               0 :   if (NS_FAILED(rv))
         461               0 :     return rv;
         462                 :
         463               0 :   AnimationNeedsResample();
         464                 :   // Force synchronous sample so that events resulting from this call arrive in
         465                 :   // the expected order and we get an up-to-date paint.
         466               0 :   FlushAnimations();
         467                 :
         468               0 :   return NS_OK;
         469                 : }
         470                 :
         471                 : /* void endElement (); */
         472                 : NS_IMETHODIMP
         473               0 : nsSVGAnimationElement::EndElement(void)
         474                 : {
         475               0 :   return EndElementAt(0.f);
         476                 : }
         477                 :
         478                 : /* void endElementAt (in float offset); */
         479                 : NS_IMETHODIMP
         480               0 : nsSVGAnimationElement::EndElementAt(float offset)
         481                 : {
         482               0 :   NS_ENSURE_FINITE(offset, NS_ERROR_ILLEGAL_VALUE);
         483                 :
         484                 :   // Make sure the timegraph is up-to-date
         485               0 :   FlushAnimations();
         486                 :
         487               0 :   nsresult rv = mTimedElement.EndElementAt(offset);
         488               0 :   if (NS_FAILED(rv))
         489               0 :     return rv;
         490                 :
         491               0 :   AnimationNeedsResample();
         492                 :   // Force synchronous sample
         493               0 :   FlushAnimations();
         494                 :
         495               0 :   return NS_OK;
         496                 : }
         497                 :
         498                 : bool
         499               0 : nsSVGAnimationElement::IsEventName(nsIAtom* aName)
         500                 : {
         501               0 :   return nsContentUtils::IsEventAttributeName(aName, EventNameType_SMIL);
         502                 : }
         503                 :
         504                 : void
         505               0 : nsSVGAnimationElement::UpdateHrefTarget(nsIContent* aNodeForContext,
         506                 :                                         const nsAString& aHrefStr)
         507                 : {
         508               0 :   nsCOMPtr<nsIURI> targetURI;
         509               0 :   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
         510               0 :   nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI),
         511               0 :                                             aHrefStr, OwnerDoc(), baseURI);
         512               0 :   mHrefTarget.Reset(aNodeForContext, targetURI);
         513               0 :   AnimationTargetChanged();
         514               0 : }
         515                 :
         516                 : void
         517               0 : nsSVGAnimationElement::AnimationTargetChanged()
         518                 : {
         519               0 :   mTimedElement.HandleTargetElementChange(GetTargetElementContent());
         520               0 :   AnimationNeedsResample();
         521            4392 : }

Generated by: LCOV version 1.7