LCOV - code coverage report
Current view: top level - dom/svg - SVGAnimatedPointList.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 12 78 15.4 %
Date: 2017-07-14 16:53:18 Functions: 1 9 11.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "SVGAnimatedPointList.h"
       8             : 
       9             : #include "DOMSVGPointList.h"
      10             : #include "mozilla/Move.h"
      11             : #include "nsSVGElement.h"
      12             : #include "nsSVGAttrTearoffTable.h"
      13             : #include "nsSMILValue.h"
      14             : #include "SVGPointListSMILType.h"
      15             : 
      16             : // See the comments in this file's header!
      17             : 
      18             : namespace mozilla {
      19             : 
      20             : nsresult
      21          14 : SVGAnimatedPointList::SetBaseValueString(const nsAString& aValue)
      22             : {
      23          28 :   SVGPointList newBaseValue;
      24             : 
      25             :   // The spec says that the point data is parsed and accepted up to the first
      26             :   // error encountered, so we don't return early if an error occurs. However,
      27             :   // we do want to throw any error code from setAttribute if there's a problem.
      28             : 
      29          14 :   nsresult rv = newBaseValue.SetValueFromString(aValue);
      30             : 
      31             :   // We must send these notifications *before* changing mBaseVal! Our baseVal's
      32             :   // DOM wrapper list may have to remove DOM items from itself, and any removed
      33             :   // DOM items need to copy their internal counterpart's values *before* we
      34             :   // change them. See the comments in
      35             :   // DOMSVGPointList::InternalListWillChangeTo().
      36             : 
      37             :   DOMSVGPointList *baseValWrapper =
      38          14 :     DOMSVGPointList::GetDOMWrapperIfExists(GetBaseValKey());
      39          14 :   if (baseValWrapper) {
      40           0 :     baseValWrapper->InternalListWillChangeTo(newBaseValue);
      41             :   }
      42             : 
      43          14 :   DOMSVGPointList* animValWrapper = nullptr;
      44          14 :   if (!IsAnimating()) {  // DOM anim val wraps our base val too!
      45          14 :     animValWrapper = DOMSVGPointList::GetDOMWrapperIfExists(GetAnimValKey());
      46          14 :     if (animValWrapper) {
      47           0 :       animValWrapper->InternalListWillChangeTo(newBaseValue);
      48             :     }
      49             :   }
      50             : 
      51             :   // Only now may we modify mBaseVal!
      52             : 
      53             :   // We don't need to call DidChange* here - we're only called by
      54             :   // nsSVGElement::ParseAttribute under Element::SetAttr,
      55             :   // which takes care of notifying.
      56             : 
      57          14 :   nsresult rv2 = mBaseVal.CopyFrom(newBaseValue);
      58          14 :   if (NS_FAILED(rv2)) {
      59             :     // Attempting to increase mBaseVal's length failed (mBaseVal is left
      60             :     // unmodified). We MUST keep any DOM wrappers in sync:
      61           0 :     if (baseValWrapper) {
      62           0 :       baseValWrapper->InternalListWillChangeTo(mBaseVal);
      63             :     }
      64           0 :     if (animValWrapper) {
      65           0 :       animValWrapper->InternalListWillChangeTo(mBaseVal);
      66             :     }
      67           0 :     return rv2;
      68             :   }
      69          14 :   return rv;
      70             : }
      71             : 
      72             : void
      73           0 : SVGAnimatedPointList::ClearBaseValue()
      74             : {
      75             :   // We must send these notifications *before* changing mBaseVal! (See above.)
      76             : 
      77             :   DOMSVGPointList *baseValWrapper =
      78           0 :     DOMSVGPointList::GetDOMWrapperIfExists(GetBaseValKey());
      79           0 :   if (baseValWrapper) {
      80           0 :     baseValWrapper->InternalListWillChangeTo(SVGPointList());
      81             :   }
      82             : 
      83           0 :   if (!IsAnimating()) { // DOM anim val wraps our base val too!
      84             :     DOMSVGPointList *animValWrapper =
      85           0 :       DOMSVGPointList::GetDOMWrapperIfExists(GetAnimValKey());
      86           0 :     if (animValWrapper) {
      87           0 :       animValWrapper->InternalListWillChangeTo(SVGPointList());
      88             :     }
      89             :   }
      90             : 
      91           0 :   mBaseVal.Clear();
      92             :   // Caller notifies
      93           0 : }
      94             : 
      95             : nsresult
      96           0 : SVGAnimatedPointList::SetAnimValue(const SVGPointList& aNewAnimValue,
      97             :                                    nsSVGElement *aElement)
      98             : {
      99             :   // Note that a new animation may totally change the number of items in the
     100             :   // animVal list, either replacing what was essentially a mirror of the
     101             :   // baseVal list, or else replacing and overriding an existing animation.
     102             :   // It is not possible for us to reliably distinguish between calls to this
     103             :   // method that are setting a new sample for an existing animation (in which
     104             :   // case our list length isn't changing and we wouldn't need to notify our DOM
     105             :   // wrapper to keep its length in sync), and calls to this method that are
     106             :   // setting the first sample of a new animation that will override the base
     107             :   // value/an existing animation (in which case our length may be changing and
     108             :   // our DOM wrapper may need to be notified). Happily though, it's cheap to
     109             :   // just blindly notify our animVal's DOM wrapper of our new value each time
     110             :   // this method is called, so that's what we do.
     111             : 
     112             :   // We must send this notification *before* changing mAnimVal! (See above.)
     113             : 
     114             :   DOMSVGPointList *domWrapper =
     115           0 :     DOMSVGPointList::GetDOMWrapperIfExists(GetAnimValKey());
     116           0 :   if (domWrapper) {
     117           0 :     domWrapper->InternalListWillChangeTo(aNewAnimValue);
     118             :   }
     119           0 :   if (!mAnimVal) {
     120           0 :     mAnimVal = new SVGPointList();
     121             :   }
     122           0 :   nsresult rv = mAnimVal->CopyFrom(aNewAnimValue);
     123           0 :   if (NS_FAILED(rv)) {
     124             :     // OOM. We clear the animation and, importantly, ClearAnimValue() ensures
     125             :     // that mAnimVal's DOM wrapper (if any) is kept in sync!
     126           0 :     ClearAnimValue(aElement);
     127           0 :     return rv;
     128             :   }
     129           0 :   aElement->DidAnimatePointList();
     130           0 :   return NS_OK;
     131             : }
     132             : 
     133             : void
     134           0 : SVGAnimatedPointList::ClearAnimValue(nsSVGElement *aElement)
     135             : {
     136             :   // We must send these notifications *before* changing mAnimVal! (See above.)
     137             : 
     138             :   DOMSVGPointList *domWrapper =
     139           0 :     DOMSVGPointList::GetDOMWrapperIfExists(GetAnimValKey());
     140           0 :   if (domWrapper) {
     141             :     // When all animation ends, animVal simply mirrors baseVal, which may have
     142             :     // a different number of items to the last active animated value.
     143             :     //
     144           0 :     domWrapper->InternalListWillChangeTo(mBaseVal);
     145             :   }
     146           0 :   mAnimVal = nullptr;
     147           0 :   aElement->DidAnimatePointList();
     148           0 : }
     149             : 
     150             : UniquePtr<nsISMILAttr>
     151           0 : SVGAnimatedPointList::ToSMILAttr(nsSVGElement *aElement)
     152             : {
     153           0 :   return MakeUnique<SMILAnimatedPointList>(this, aElement);
     154             : }
     155             : 
     156             : nsresult
     157           0 : SVGAnimatedPointList::
     158             :   SMILAnimatedPointList::ValueFromString(const nsAString& aStr,
     159             :                                const dom::SVGAnimationElement* /*aSrcElement*/,
     160             :                                nsSMILValue& aValue,
     161             :                                bool& aPreventCachingOfSandwich) const
     162             : {
     163           0 :   nsSMILValue val(&SVGPointListSMILType::sSingleton);
     164           0 :   SVGPointListAndInfo *list = static_cast<SVGPointListAndInfo*>(val.mU.mPtr);
     165           0 :   nsresult rv = list->SetValueFromString(aStr);
     166           0 :   if (NS_SUCCEEDED(rv)) {
     167           0 :     list->SetInfo(mElement);
     168           0 :     aValue = Move(val);
     169             :   }
     170           0 :   aPreventCachingOfSandwich = false;
     171           0 :   return rv;
     172             : }
     173             : 
     174             : nsSMILValue
     175           0 : SVGAnimatedPointList::SMILAnimatedPointList::GetBaseValue() const
     176             : {
     177             :   // To benefit from Return Value Optimization and avoid copy constructor calls
     178             :   // due to our use of return-by-value, we must return the exact same object
     179             :   // from ALL return points. This function must only return THIS variable:
     180           0 :   nsSMILValue val;
     181             : 
     182           0 :   nsSMILValue tmp(&SVGPointListSMILType::sSingleton);
     183           0 :   SVGPointListAndInfo *list = static_cast<SVGPointListAndInfo*>(tmp.mU.mPtr);
     184           0 :   nsresult rv = list->CopyFrom(mVal->mBaseVal);
     185           0 :   if (NS_SUCCEEDED(rv)) {
     186           0 :     list->SetInfo(mElement);
     187           0 :     Swap(val, tmp);
     188             :   }
     189           0 :   return val;
     190             : }
     191             : 
     192             : nsresult
     193           0 : SVGAnimatedPointList::SMILAnimatedPointList::SetAnimValue(const nsSMILValue& aValue)
     194             : {
     195           0 :   NS_ASSERTION(aValue.mType == &SVGPointListSMILType::sSingleton,
     196             :                "Unexpected type to assign animated value");
     197           0 :   if (aValue.mType == &SVGPointListSMILType::sSingleton) {
     198           0 :     mVal->SetAnimValue(*static_cast<SVGPointListAndInfo*>(aValue.mU.mPtr),
     199           0 :                        mElement);
     200             :   }
     201           0 :   return NS_OK;
     202             : }
     203             : 
     204             : void
     205           0 : SVGAnimatedPointList::SMILAnimatedPointList::ClearAnimValue()
     206             : {
     207           0 :   if (mVal->mAnimVal) {
     208           0 :     mVal->ClearAnimValue(mElement);
     209             :   }
     210           0 : }
     211             : 
     212             : } // namespace mozilla

Generated by: LCOV version 1.13