tor-browser

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

SVGAnimatedBoolean.cpp (5215B)


      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 "SVGAnimatedBoolean.h"
      8 
      9 #include "DOMSVGAnimatedBoolean.h"
     10 #include "SMILBoolType.h"
     11 #include "SVGAttrTearoffTable.h"
     12 #include "mozilla/SMILValue.h"
     13 #include "nsError.h"
     14 
     15 using namespace mozilla::dom;
     16 
     17 namespace mozilla {
     18 
     19 /* Implementation */
     20 
     21 //----------------------------------------------------------------------
     22 // Helper class: AutoChangeBooleanNotifier
     23 // Stack-based helper class to ensure DidChangeBoolean is called.
     24 class MOZ_RAII AutoChangeBooleanNotifier {
     25 public:
     26  AutoChangeBooleanNotifier(SVGAnimatedBoolean* aBoolean,
     27                            SVGElement* aSVGElement, bool aDoSetAttr = true)
     28      : mBoolean(aBoolean), mSVGElement(aSVGElement), mDoSetAttr(aDoSetAttr) {
     29    MOZ_ASSERT(mBoolean, "Expecting non-null boolean");
     30    MOZ_ASSERT(mSVGElement, "Expecting non-null element");
     31  }
     32 
     33  ~AutoChangeBooleanNotifier() {
     34    if (mDoSetAttr) {
     35      mSVGElement->DidChangeBoolean(mBoolean->mAttrEnum);
     36    }
     37    if (mBoolean->mIsAnimated) {
     38      mSVGElement->AnimationNeedsResample();
     39    }
     40  }
     41 
     42 private:
     43  SVGAnimatedBoolean* const mBoolean;
     44  SVGElement* const mSVGElement;
     45  bool mDoSetAttr;
     46 };
     47 
     48 static inline SVGAttrTearoffTable<SVGAnimatedBoolean, DOMSVGAnimatedBoolean>&
     49 SVGAnimatedBooleanTearoffTable() {
     50  static SVGAttrTearoffTable<SVGAnimatedBoolean, DOMSVGAnimatedBoolean>
     51      sSVGAnimatedBooleanTearoffTable;
     52  return sSVGAnimatedBooleanTearoffTable;
     53 }
     54 
     55 static bool GetValueFromString(const nsAString& aValueAsString, bool& aValue) {
     56  if (aValueAsString.EqualsLiteral("true")) {
     57    aValue = true;
     58    return true;
     59  }
     60  if (aValueAsString.EqualsLiteral("false")) {
     61    aValue = false;
     62    return true;
     63  }
     64  return false;
     65 }
     66 
     67 static bool GetValueFromAtom(const nsAtom* aValueAsAtom, bool* aValue) {
     68  if (aValueAsAtom == nsGkAtoms::_true) {
     69    *aValue = true;
     70    return true;
     71  }
     72  if (aValueAsAtom == nsGkAtoms::_false) {
     73    *aValue = false;
     74    return true;
     75  }
     76  return false;
     77 }
     78 
     79 nsresult SVGAnimatedBoolean::SetBaseValueAtom(const nsAtom* aValue,
     80                                              SVGElement* aSVGElement) {
     81  bool val = false;
     82 
     83  if (!GetValueFromAtom(aValue, &val)) {
     84    return NS_ERROR_DOM_SYNTAX_ERR;
     85  }
     86 
     87  // We don't need to call DidChange* here - we're only called by
     88  // SVGElement::ParseAttribute under Element::SetAttr,
     89  // which takes care of notifying.
     90  AutoChangeBooleanNotifier notifier(this, aSVGElement, false);
     91 
     92  mBaseVal = val;
     93  if (!mIsAnimated) {
     94    mAnimVal = mBaseVal;
     95  }
     96 
     97  return NS_OK;
     98 }
     99 
    100 nsAtom* SVGAnimatedBoolean::GetBaseValueAtom() const {
    101  return mBaseVal ? nsGkAtoms::_true : nsGkAtoms::_false;
    102 }
    103 
    104 void SVGAnimatedBoolean::SetBaseValue(bool aValue, SVGElement* aSVGElement) {
    105  if (aValue == mBaseVal) {
    106    return;
    107  }
    108 
    109  AutoChangeBooleanNotifier notifier(this, aSVGElement);
    110 
    111  mBaseVal = aValue;
    112  if (!mIsAnimated) {
    113    mAnimVal = mBaseVal;
    114  }
    115 }
    116 
    117 void SVGAnimatedBoolean::SetAnimValue(bool aValue, SVGElement* aSVGElement) {
    118  if (mIsAnimated && mAnimVal == aValue) {
    119    return;
    120  }
    121  mAnimVal = aValue;
    122  mIsAnimated = true;
    123  aSVGElement->DidAnimateBoolean(mAttrEnum);
    124 }
    125 
    126 already_AddRefed<DOMSVGAnimatedBoolean>
    127 SVGAnimatedBoolean::ToDOMAnimatedBoolean(SVGElement* aSVGElement) {
    128  RefPtr<DOMSVGAnimatedBoolean> domAnimatedBoolean =
    129      SVGAnimatedBooleanTearoffTable().GetTearoff(this);
    130  if (!domAnimatedBoolean) {
    131    domAnimatedBoolean = new DOMSVGAnimatedBoolean(this, aSVGElement);
    132    SVGAnimatedBooleanTearoffTable().AddTearoff(this, domAnimatedBoolean);
    133  }
    134 
    135  return domAnimatedBoolean.forget();
    136 }
    137 
    138 DOMSVGAnimatedBoolean::~DOMSVGAnimatedBoolean() {
    139  SVGAnimatedBooleanTearoffTable().RemoveTearoff(mVal);
    140 }
    141 
    142 UniquePtr<SMILAttr> SVGAnimatedBoolean::ToSMILAttr(SVGElement* aSVGElement) {
    143  return MakeUnique<SMILBool>(this, aSVGElement);
    144 }
    145 
    146 nsresult SVGAnimatedBoolean::SMILBool::ValueFromString(
    147    const nsAString& aStr, const SVGAnimationElement* /*aSrcElement*/,
    148    SMILValue& aValue, bool& aPreventCachingOfSandwich) const {
    149  bool value;
    150  if (!GetValueFromString(aStr, value)) {
    151    return NS_ERROR_DOM_SYNTAX_ERR;
    152  }
    153 
    154  SMILValue val(SMILBoolType::Singleton());
    155  val.mU.mBool = value;
    156  aValue = val;
    157 
    158  return NS_OK;
    159 }
    160 
    161 SMILValue SVGAnimatedBoolean::SMILBool::GetBaseValue() const {
    162  SMILValue val(SMILBoolType::Singleton());
    163  val.mU.mBool = mVal->mBaseVal;
    164  return val;
    165 }
    166 
    167 void SVGAnimatedBoolean::SMILBool::ClearAnimValue() {
    168  if (mVal->mIsAnimated) {
    169    mVal->mIsAnimated = false;
    170    mVal->mAnimVal = mVal->mBaseVal;
    171    mSVGElement->DidAnimateBoolean(mVal->mAttrEnum);
    172  }
    173 }
    174 
    175 nsresult SVGAnimatedBoolean::SMILBool::SetAnimValue(const SMILValue& aValue) {
    176  NS_ASSERTION(aValue.mType == SMILBoolType::Singleton(),
    177               "Unexpected type to assign animated value");
    178  if (aValue.mType == SMILBoolType::Singleton()) {
    179    mVal->SetAnimValue(uint16_t(aValue.mU.mBool), mSVGElement);
    180  }
    181  return NS_OK;
    182 }
    183 
    184 }  // namespace mozilla