tor-browser

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

DOMSVGAnimatedNumberList.cpp (4643B)


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