tor-browser

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

DOMSVGAnimatedLengthList.cpp (4597B)


      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 "DOMSVGAnimatedLengthList.h"
      8 
      9 #include "DOMSVGLengthList.h"
     10 #include "SVGAnimatedLengthList.h"
     11 #include "SVGAttrTearoffTable.h"
     12 #include "mozilla/RefPtr.h"
     13 #include "mozilla/dom/SVGAnimatedLengthListBinding.h"
     14 #include "mozilla/dom/SVGElement.h"
     15 
     16 // See the architecture comment in this file's header.
     17 
     18 namespace mozilla::dom {
     19 
     20 static inline SVGAttrTearoffTable<SVGAnimatedLengthList,
     21                                  DOMSVGAnimatedLengthList>&
     22 SVGAnimatedLengthListTearoffTable() {
     23  static SVGAttrTearoffTable<SVGAnimatedLengthList, DOMSVGAnimatedLengthList>
     24      sSVGAnimatedLengthListTearoffTable;
     25  return sSVGAnimatedLengthListTearoffTable;
     26 }
     27 
     28 NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(DOMSVGAnimatedLengthList,
     29                                               mElement)
     30 
     31 JSObject* DOMSVGAnimatedLengthList::WrapObject(
     32    JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
     33  return dom::SVGAnimatedLengthList_Binding::Wrap(aCx, this, aGivenProto);
     34 }
     35 
     36 already_AddRefed<DOMSVGLengthList> DOMSVGAnimatedLengthList::BaseVal() {
     37  if (!mBaseVal) {
     38    mBaseVal = new DOMSVGLengthList(this, InternalAList().GetBaseValue());
     39  }
     40  RefPtr<DOMSVGLengthList> baseVal = mBaseVal;
     41  return baseVal.forget();
     42 }
     43 
     44 already_AddRefed<DOMSVGLengthList> DOMSVGAnimatedLengthList::AnimVal() {
     45  if (!mAnimVal) {
     46    mAnimVal = new DOMSVGLengthList(this, InternalAList().GetAnimValue());
     47  }
     48  RefPtr<DOMSVGLengthList> animVal = mAnimVal;
     49  return animVal.forget();
     50 }
     51 
     52 /* static */
     53 already_AddRefed<DOMSVGAnimatedLengthList>
     54 DOMSVGAnimatedLengthList::GetDOMWrapper(SVGAnimatedLengthList* aList,
     55                                        dom::SVGElement* aElement,
     56                                        uint8_t aAttrEnum, uint8_t aAxis) {
     57  RefPtr<DOMSVGAnimatedLengthList> wrapper =
     58      SVGAnimatedLengthListTearoffTable().GetTearoff(aList);
     59  if (!wrapper) {
     60    wrapper = new DOMSVGAnimatedLengthList(aElement, aAttrEnum, aAxis);
     61    SVGAnimatedLengthListTearoffTable().AddTearoff(aList, wrapper);
     62  }
     63  return wrapper.forget();
     64 }
     65 
     66 /* static */
     67 DOMSVGAnimatedLengthList* DOMSVGAnimatedLengthList::GetDOMWrapperIfExists(
     68    SVGAnimatedLengthList* aList) {
     69  return SVGAnimatedLengthListTearoffTable().GetTearoff(aList);
     70 }
     71 
     72 DOMSVGAnimatedLengthList::~DOMSVGAnimatedLengthList() {
     73  // Script no longer has any references to us, to our base/animVal objects, or
     74  // to any of their list items.
     75  SVGAnimatedLengthListTearoffTable().RemoveTearoff(&InternalAList());
     76 }
     77 
     78 void DOMSVGAnimatedLengthList::InternalBaseValListWillChangeTo(
     79    const SVGLengthList& aNewValue) {
     80  // When the number of items in our internal counterpart's baseVal changes,
     81  // we MUST keep our baseVal in sync. If we don't, script will either see a
     82  // list that is too short and be unable to access indexes that should be
     83  // valid, or else, MUCH WORSE, script will see a list that is too long and be
     84  // able to access "items" at indexes that are out of bounds (read/write to
     85  // bad memory)!!
     86 
     87  RefPtr<DOMSVGAnimatedLengthList> kungFuDeathGrip;
     88  if (mBaseVal) {
     89    if (aNewValue.Length() < mBaseVal->LengthNoFlush()) {
     90      // InternalListLengthWillChange might clear last reference to |this|.
     91      // Retain a temporary reference to keep from dying before returning.
     92      kungFuDeathGrip = this;
     93    }
     94    mBaseVal->InternalListLengthWillChange(aNewValue.Length());
     95  }
     96 
     97  // If our attribute is not animating, then our animVal mirrors our baseVal
     98  // and we must sync its length too. (If our attribute is animating, then the
     99  // SMIL engine takes care of calling InternalAnimValListWillChangeTo() if
    100  // necessary.)
    101 
    102  if (!IsAnimating()) {
    103    InternalAnimValListWillChangeTo(aNewValue);
    104  }
    105 }
    106 
    107 void DOMSVGAnimatedLengthList::InternalAnimValListWillChangeTo(
    108    const SVGLengthList& aNewValue) {
    109  if (mAnimVal) {
    110    mAnimVal->InternalListLengthWillChange(aNewValue.Length());
    111  }
    112 }
    113 
    114 bool DOMSVGAnimatedLengthList::IsAnimating() const {
    115  return InternalAList().IsAnimating();
    116 }
    117 
    118 SVGAnimatedLengthList& DOMSVGAnimatedLengthList::InternalAList() {
    119  return *mElement->GetAnimatedLengthList(mAttrEnum);
    120 }
    121 
    122 const SVGAnimatedLengthList& DOMSVGAnimatedLengthList::InternalAList() const {
    123  return *mElement->GetAnimatedLengthList(mAttrEnum);
    124 }
    125 
    126 }  // namespace mozilla::dom