tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SVGAnimatedInteger.cpp (5058B)


      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 "SVGAnimatedInteger.h"
      8 
      9 #include "SMILIntegerType.h"
     10 #include "SVGAttrTearoffTable.h"
     11 #include "mozilla/SMILValue.h"
     12 #include "mozilla/SVGContentUtils.h"
     13 #include "nsError.h"
     14 
     15 using namespace mozilla::dom;
     16 
     17 namespace mozilla {
     18 
     19 /* Implementation */
     20 
     21 //----------------------------------------------------------------------
     22 // Helper class: AutoChangeIntegerNotifier
     23 // Stack-based helper class ensure DidChangeInteger is called.
     24 class MOZ_RAII AutoChangeIntegerNotifier {
     25 public:
     26  AutoChangeIntegerNotifier(SVGAnimatedInteger* aInteger,
     27                            SVGElement* aSVGElement, bool aDoSetAttr = true)
     28      : mInteger(aInteger), mSVGElement(aSVGElement), mDoSetAttr(aDoSetAttr) {
     29    MOZ_ASSERT(mInteger, "Expecting non-null integer");
     30    MOZ_ASSERT(mSVGElement, "Expecting non-null element");
     31  }
     32 
     33  ~AutoChangeIntegerNotifier() {
     34    if (mDoSetAttr) {
     35      mSVGElement->DidChangeInteger(mInteger->mAttrEnum);
     36    }
     37    if (mInteger->mIsAnimated) {
     38      mSVGElement->AnimationNeedsResample();
     39    }
     40  }
     41 
     42 private:
     43  SVGAnimatedInteger* const mInteger;
     44  SVGElement* const mSVGElement;
     45  bool mDoSetAttr;
     46 };
     47 
     48 constinit static SVGAttrTearoffTable<SVGAnimatedInteger,
     49                                     SVGAnimatedInteger::DOMAnimatedInteger>
     50    sSVGAnimatedIntegerTearoffTable;
     51 
     52 nsresult SVGAnimatedInteger::SetBaseValueString(const nsAString& aValueAsString,
     53                                                SVGElement* aSVGElement) {
     54  bool success;
     55  auto token = SVGContentUtils::GetAndEnsureOneToken(aValueAsString, success);
     56 
     57  if (!success) {
     58    return NS_ERROR_DOM_SYNTAX_ERR;
     59  }
     60 
     61  int32_t value;
     62 
     63  if (!SVGContentUtils::ParseInteger(token, value)) {
     64    return NS_ERROR_DOM_SYNTAX_ERR;
     65  }
     66 
     67  AutoChangeIntegerNotifier notifier(this, aSVGElement, false);
     68 
     69  mIsBaseSet = true;
     70  mBaseVal = value;
     71  if (!mIsAnimated) {
     72    mAnimVal = mBaseVal;
     73  }
     74  return NS_OK;
     75 }
     76 
     77 void SVGAnimatedInteger::GetBaseValueString(nsAString& aValueAsString) {
     78  aValueAsString.Truncate();
     79  aValueAsString.AppendInt(mBaseVal);
     80 }
     81 
     82 void SVGAnimatedInteger::SetBaseValue(int aValue, SVGElement* aSVGElement) {
     83  // We can't just rely on SetParsedAttrValue (as called by DidChangeInteger)
     84  // detecting redundant changes since it will compare false if the existing
     85  // attribute value has an associated serialized version (a string value) even
     86  // if the integers match due to the way integers are stored in nsAttrValue.
     87  if (aValue == mBaseVal && mIsBaseSet) {
     88    return;
     89  }
     90 
     91  AutoChangeIntegerNotifier notifier(this, aSVGElement);
     92 
     93  mBaseVal = aValue;
     94  mIsBaseSet = true;
     95  if (!mIsAnimated) {
     96    mAnimVal = mBaseVal;
     97  }
     98 }
     99 
    100 void SVGAnimatedInteger::SetAnimValue(int aValue, SVGElement* aSVGElement) {
    101  if (mIsAnimated && aValue == mAnimVal) {
    102    return;
    103  }
    104  mAnimVal = aValue;
    105  mIsAnimated = true;
    106  aSVGElement->DidAnimateInteger(mAttrEnum);
    107 }
    108 
    109 already_AddRefed<DOMSVGAnimatedInteger>
    110 SVGAnimatedInteger::ToDOMAnimatedInteger(SVGElement* aSVGElement) {
    111  RefPtr<DOMAnimatedInteger> domAnimatedInteger =
    112      sSVGAnimatedIntegerTearoffTable.GetTearoff(this);
    113  if (!domAnimatedInteger) {
    114    domAnimatedInteger = new DOMAnimatedInteger(this, aSVGElement);
    115    sSVGAnimatedIntegerTearoffTable.AddTearoff(this, domAnimatedInteger);
    116  }
    117 
    118  return domAnimatedInteger.forget();
    119 }
    120 
    121 SVGAnimatedInteger::DOMAnimatedInteger::~DOMAnimatedInteger() {
    122  sSVGAnimatedIntegerTearoffTable.RemoveTearoff(mVal);
    123 }
    124 
    125 UniquePtr<SMILAttr> SVGAnimatedInteger::ToSMILAttr(SVGElement* aSVGElement) {
    126  return MakeUnique<SMILInteger>(this, aSVGElement);
    127 }
    128 
    129 nsresult SVGAnimatedInteger::SMILInteger::ValueFromString(
    130    const nsAString& aStr, const dom::SVGAnimationElement* /*aSrcElement*/,
    131    SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
    132  int32_t val;
    133 
    134  if (!SVGContentUtils::ParseInteger(aStr, val)) {
    135    return NS_ERROR_DOM_SYNTAX_ERR;
    136  }
    137 
    138  SMILValue smilVal(SMILIntegerType::Singleton());
    139  smilVal.mU.mInt = val;
    140  aValue = smilVal;
    141  return NS_OK;
    142 }
    143 
    144 SMILValue SVGAnimatedInteger::SMILInteger::GetBaseValue() const {
    145  SMILValue val(SMILIntegerType::Singleton());
    146  val.mU.mInt = mVal->mBaseVal;
    147  return val;
    148 }
    149 
    150 void SVGAnimatedInteger::SMILInteger::ClearAnimValue() {
    151  if (mVal->mIsAnimated) {
    152    mVal->mIsAnimated = false;
    153    mVal->mAnimVal = mVal->mBaseVal;
    154    mSVGElement->DidAnimateInteger(mVal->mAttrEnum);
    155  }
    156 }
    157 
    158 nsresult SVGAnimatedInteger::SMILInteger::SetAnimValue(
    159    const SMILValue& aValue) {
    160  NS_ASSERTION(aValue.mType == SMILIntegerType::Singleton(),
    161               "Unexpected type to assign animated value");
    162  if (aValue.mType == SMILIntegerType::Singleton()) {
    163    mVal->SetAnimValue(int(aValue.mU.mInt), mSVGElement);
    164  }
    165  return NS_OK;
    166 }
    167 
    168 }  // namespace mozilla