tor-browser

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

DOMSVGLength.h (8442B)


      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 #ifndef DOM_SVG_DOMSVGLENGTH_H_
      8 #define DOM_SVG_DOMSVGLENGTH_H_
      9 
     10 #include "DOMSVGLengthList.h"
     11 #include "SVGLength.h"
     12 #include "nsCycleCollectionParticipant.h"
     13 #include "nsDebug.h"
     14 #include "nsTArray.h"
     15 #include "nsWrapperCache.h"
     16 
     17 #define MOZ_SVG_LIST_INDEX_BIT_COUNT 21  // supports > 2 million list items
     18 
     19 namespace mozilla {
     20 
     21 class ErrorResult;
     22 
     23 namespace dom {
     24 class SVGElement;
     25 
     26 /**
     27 * Class DOMSVGLength
     28 *
     29 * This class creates the DOM objects that wrap internal SVGLength objects that
     30 * are in an SVGLengthList. It is also used to create the objects returned by
     31 * SVGSVGElement.createSVGLength().
     32 *
     33 * For the DOM wrapper classes for non-list SVGLength, see SVGAnimatedLength.h.
     34 *
     35 * See the architecture comment in DOMSVGAnimatedLengthList.h.
     36 *
     37 * This class is strongly intertwined with DOMSVGAnimatedLengthList and
     38 * DOMSVGLengthList. We are a friend of DOMSVGLengthList, and are responsible
     39 * for nulling out our DOMSVGLengthList's pointer to us when we die, making it
     40 * a real weak pointer.
     41 *
     42 * When objects of this type are in a DOMSVGLengthList they belong to an
     43 * attribute. While they belong to an attribute, the objects' values come from
     44 * their corresponding internal SVGLength objects in the internal SVGLengthList
     45 * objects for the attribute. Getting and setting values of a DOMSVGLength
     46 * requires reading and writing to its internal SVGLength. However, if the
     47 * DOMSVGLength is detached from its DOMSVGLengthList then it first makes a
     48 * copy of its internal SVGLength's value and unit so that it doesn't appear to
     49 * "lose" its value from script's perspective on being removed from the list.
     50 * This means that these DOM tearoffs have space to store these values, even
     51 * though they're not used in the common case.
     52 *
     53 * Objects of this type are also used to reflect the baseVal and animVal of
     54 * a single, non-list SVGLength attribute. Getting and settings values of the
     55 * DOMSVGLength in this case requires reading and writing to the corresponding
     56 * SVGAnimatedLength object.
     57 *
     58 * This class also stores its current list index, attribute enum, and whether
     59 * it belongs to a baseVal or animVal list. This is so that objects of this
     60 * type can find their corresponding internal SVGLength.
     61 *
     62 * To use these classes for <length> attributes as well as <list-of-length>
     63 * attributes, we would need to take a bit from mListIndex and use that to
     64 * indicate whether the object belongs to a list or non-list attribute, then
     65 * if-else as appropriate. The bug for doing that work is:
     66 * https://bugzilla.mozilla.org/show_bug.cgi?id=571734
     67 */
     68 class DOMSVGLength final : public nsWrapperCache {
     69  template <class T>
     70  friend class AutoChangeLengthListNotifier;
     71 
     72  /**
     73   * Ctor for creating the object returned by
     74   * SVGAnimatedLength::ToDOMBaseVal/ToDOMAnimVal
     75   */
     76  DOMSVGLength(SVGAnimatedLength* aVal, dom::SVGElement* aSVGElement,
     77               bool aAnimVal);
     78 
     79  ~DOMSVGLength() { CleanupWeakRefs(); }
     80 
     81 public:
     82  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMSVGLength)
     83  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMSVGLength)
     84 
     85  /**
     86   * Generic ctor for DOMSVGLength objects that are created for an attribute.
     87   */
     88  DOMSVGLength(DOMSVGLengthList* aList, uint8_t aAttrEnum, uint32_t aListIndex,
     89               bool aIsAnimValItem);
     90 
     91  /**
     92   * Ctor for creating the objects returned by SVGSVGElement.createSVGLength(),
     93   * which do not initially belong to an attribute.
     94   */
     95  DOMSVGLength();
     96 
     97  static already_AddRefed<DOMSVGLength> GetTearOff(SVGAnimatedLength* aVal,
     98                                                   dom::SVGElement* aSVGElement,
     99                                                   bool aAnimVal);
    100 
    101  /**
    102   * Create an unowned copy of a length that is owned or is reflecting a single
    103   * attribute. The caller is responsible for the first AddRef().
    104   */
    105  DOMSVGLength* Copy();
    106 
    107  /**
    108   * Returns true if our attribute is animating.
    109   */
    110  bool IsAnimating() const;
    111 
    112  /**
    113   * In future, if this class is used for non-list lengths, this will be
    114   * different to IsInList().
    115   */
    116  bool HasOwner() const { return !!mOwner; }
    117 
    118  /**
    119   * This method is called to notify this DOM object that it is being inserted
    120   * into a list, and give it the information it needs as a result.
    121   *
    122   * This object MUST NOT already belong to a list when this method is called.
    123   * That's not to say that script can't move these DOM objects between
    124   * lists - it can - it's just that the logic to handle that (and send out
    125   * the necessary notifications) is located elsewhere (in DOMSVGLengthList).)
    126   */
    127  void InsertingIntoList(DOMSVGLengthList* aList, uint8_t aAttrEnum,
    128                         uint32_t aListIndex, bool aIsAnimValItem);
    129 
    130  static uint32_t MaxListIndex() {
    131    return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT) - 1;
    132  }
    133 
    134  /// This method is called to notify this object that its list index changed.
    135  void UpdateListIndex(uint32_t aListIndex) { mListIndex = aListIndex; }
    136 
    137  /**
    138   * This method is called to notify this DOM object that it is about to be
    139   * removed from its current DOM list so that it can first make a copy of its
    140   * internal counterpart's values. (If it didn't do this, then it would
    141   * "lose" its value on being removed.)
    142   */
    143  void RemovingFromList();
    144 
    145  SVGLength ToSVGLength();
    146 
    147  // WebIDL
    148  uint16_t UnitType();
    149  float GetValue(ErrorResult& aRv);
    150  void SetValue(float aUserUnitValue, ErrorResult& aRv);
    151  float ValueInSpecifiedUnits();
    152  void SetValueInSpecifiedUnits(float aValue, ErrorResult& aRv);
    153  void GetValueAsString(nsAString& aValue);
    154  void SetValueAsString(const nsAString& aValue, ErrorResult& aRv);
    155  void NewValueSpecifiedUnits(uint16_t aUnit, float aValue, ErrorResult& aRv);
    156  void ConvertToSpecifiedUnits(uint16_t aUnit, ErrorResult& aRv);
    157 
    158  nsISupports* GetParentObject() { return mOwner; }
    159 
    160  JSObject* WrapObject(JSContext* aCx,
    161                       JS::Handle<JSObject*> aGivenProto) override;
    162 
    163 private:
    164  dom::SVGElement* Element();
    165 
    166  uint8_t AttrEnum() const { return mAttrEnum; }
    167 
    168  /**
    169   * Get a reference to the internal SVGLength list item that this DOM wrapper
    170   * object currently wraps.
    171   *
    172   * To simplify the code we just have this one method for obtaining both
    173   * baseVal and animVal internal items. This means that animVal items don't
    174   * get const protection, but then our setter methods guard against changing
    175   * animVal items.
    176   */
    177  SVGLength& InternalItem();
    178 
    179  /**
    180   * Some values have units that depend on style or layout so we may need to
    181   * flush to ensure we get or set the right value in pixels.
    182   */
    183  void FlushIfNeeded();
    184 
    185 #ifdef DEBUG
    186  bool IndexIsValid();
    187 #endif
    188 
    189  /**
    190   * Clears soon-to-be-invalid weak references in external objects that were
    191   * set up during the creation of this object. This should be called during
    192   * destruction and during cycle collection.
    193   */
    194  void CleanupWeakRefs();
    195 
    196  RefPtr<nsISupports> mOwner;  // Either a DOMSVGLengthList if we're in a list,
    197                               // an SVGElement if we're an attribute or null
    198 
    199  // Bounds for the following are checked in the ctor, so be sure to update
    200  // that if you change the capacity of any of the following.
    201 
    202  uint32_t mListIndex : MOZ_SVG_LIST_INDEX_BIT_COUNT;
    203  uint32_t mAttrEnum : 4;  // supports up to 16 attributes
    204  uint32_t mIsAnimValItem : 1;
    205 
    206  // Tracks whether we're in the tearoff table. Initialized to false in the
    207  // ctor, but then immediately set to true after we're added to the table
    208  // (unless we're an instance created via 'Copy()'; those never get added to
    209  // the table).  Updated to false when we're removed from the table (at which
    210  // point we're being destructed or soon-to-be destructed).
    211  uint32_t mIsInTearoffTable : 1;
    212 
    213  // The following members are only used when we're not in a list:
    214  uint32_t mUnit : 5;  // can handle 31 units (the 10 SVG 1.1 units + rem, vw,
    215                       // vh, wm, calc + future additions)
    216  float mValue = 0.0f;
    217 };
    218 
    219 }  // namespace dom
    220 }  // namespace mozilla
    221 
    222 #undef MOZ_SVG_LIST_INDEX_BIT_COUNT
    223 
    224 #endif  // DOM_SVG_DOMSVGLENGTH_H_