tor-browser

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

DOMSVGNumber.cpp (4583B)


      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 "DOMSVGNumber.h"
      8 
      9 #include "DOMSVGAnimatedNumberList.h"
     10 #include "DOMSVGNumberList.h"
     11 #include "SVGAnimatedNumberList.h"
     12 #include "SVGElement.h"
     13 #include "mozilla/dom/SVGNumberBinding.h"
     14 #include "mozilla/dom/SVGSVGElement.h"
     15 #include "nsContentUtils.h"  // for NS_ENSURE_FINITE
     16 #include "nsError.h"
     17 
     18 // See the architecture comment in DOMSVGAnimatedNumberList.h.
     19 
     20 namespace mozilla::dom {
     21 
     22 // We could use NS_IMPL_CYCLE_COLLECTION(, except that in Unlink() we need to
     23 // clear our list's weak ref to us to be safe. (The other option would be to
     24 // not unlink and rely on the breaking of the other edges in the cycle, as
     25 // NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.)
     26 NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGNumber)
     27 
     28 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGNumber)
     29  // We may not belong to a list, so we must null check tmp->mList.
     30  if (tmp->mList) {
     31    tmp->mList->mItems[tmp->mListIndex] = nullptr;
     32  }
     33  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
     34  NS_IMPL_CYCLE_COLLECTION_UNLINK(mList)
     35  NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
     36 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     37 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGNumber)
     38  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList)
     39  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
     40 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     41 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGNumber)
     42  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
     43 NS_IMPL_CYCLE_COLLECTION_TRACE_END
     44 
     45 DOMSVGNumber::DOMSVGNumber(DOMSVGNumberList* aList, uint8_t aAttrEnum,
     46                           uint32_t aListIndex, bool aIsAnimValItem)
     47    : mList(aList),
     48      mParent(aList),
     49      mListIndex(aListIndex),
     50      mAttrEnum(aAttrEnum),
     51      mIsAnimValItem(aIsAnimValItem),
     52      mValue(0.0f) {
     53  // These shifts are in sync with the members in the header.
     54  MOZ_ASSERT(aList && aAttrEnum < (1 << 4) && aListIndex <= MaxListIndex(),
     55             "bad arg");
     56 
     57  MOZ_ASSERT(IndexIsValid(), "Bad index for DOMSVGNumber!");
     58 }
     59 
     60 DOMSVGNumber::DOMSVGNumber(nsISupports* aParent)
     61    : mList(nullptr),
     62      mParent(aParent),
     63      mListIndex(0),
     64      mAttrEnum(0),
     65      mIsAnimValItem(false),
     66      mValue(0.0f) {}
     67 
     68 DOMSVGNumber::DOMSVGNumber(SVGSVGElement* aParent)
     69    : mList(nullptr),
     70      mParent(ToSupports(aParent)),
     71      mListIndex(0),
     72      mAttrEnum(0),
     73      mIsAnimValItem(false),
     74      mValue(0.0f) {}
     75 
     76 float DOMSVGNumber::Value() {
     77  if (mIsAnimValItem && HasOwner()) {
     78    Element()->FlushAnimations();  // May make HasOwner() == false
     79  }
     80  return HasOwner() ? InternalItem() : mValue;
     81 }
     82 
     83 void DOMSVGNumber::SetValue(float aValue, ErrorResult& aRv) {
     84  if (mIsAnimValItem) {
     85    aRv.ThrowNoModificationAllowedError("Animated values cannot be set");
     86    return;
     87  }
     88 
     89  if (HasOwner()) {
     90    if (InternalItem() == aValue) {
     91      return;
     92    }
     93    AutoChangeNumberListNotifier notifier(this);
     94    InternalItem() = aValue;
     95    return;
     96  }
     97 
     98  mValue = aValue;
     99 }
    100 
    101 void DOMSVGNumber::InsertingIntoList(DOMSVGNumberList* aList, uint8_t aAttrEnum,
    102                                     uint32_t aListIndex, bool aIsAnimValItem) {
    103  NS_ASSERTION(!HasOwner(), "Inserting item that is already in a list");
    104 
    105  mList = aList;
    106  mAttrEnum = aAttrEnum;
    107  mListIndex = aListIndex;
    108  mIsAnimValItem = aIsAnimValItem;
    109 
    110  MOZ_ASSERT(IndexIsValid(), "Bad index for DOMSVGNumber!");
    111 }
    112 
    113 void DOMSVGNumber::RemovingFromList() {
    114  mValue = InternalItem();
    115  mList = nullptr;
    116  mIsAnimValItem = false;
    117 }
    118 
    119 float DOMSVGNumber::ToSVGNumber() {
    120  return HasOwner() ? InternalItem() : mValue;
    121 }
    122 
    123 float& DOMSVGNumber::InternalItem() {
    124  SVGAnimatedNumberList* alist = Element()->GetAnimatedNumberList(mAttrEnum);
    125  return mIsAnimValItem && alist->mAnimVal ? (*alist->mAnimVal)[mListIndex]
    126                                           : alist->mBaseVal[mListIndex];
    127 }
    128 
    129 #ifdef DEBUG
    130 bool DOMSVGNumber::IndexIsValid() {
    131  SVGAnimatedNumberList* alist = Element()->GetAnimatedNumberList(mAttrEnum);
    132  return (mIsAnimValItem && mListIndex < alist->GetAnimValue().Length()) ||
    133         (!mIsAnimValItem && mListIndex < alist->GetBaseValue().Length());
    134 }
    135 #endif
    136 
    137 JSObject* DOMSVGNumber::WrapObject(JSContext* aCx,
    138                                   JS::Handle<JSObject*> aGivenProto) {
    139  return SVGNumber_Binding::Wrap(aCx, this, aGivenProto);
    140 }
    141 
    142 }  // namespace mozilla::dom