DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (b6d82b1a6b02)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef MOZILLA_DOMSVGANIMATEDNUMBERLIST_H__
#define MOZILLA_DOMSVGANIMATEDNUMBERLIST_H__

#include "nsCycleCollectionParticipant.h"
#include "SVGElement.h"
#include "nsWrapperCache.h"
#include "mozilla/Attributes.h"
#include "mozilla/RefPtr.h"

namespace mozilla {

class SVGAnimatedNumberList;
class SVGNumberList;

namespace dom {

class DOMSVGNumberList;

/**
 * Class DOMSVGAnimatedNumberList
 *
 * This class is used to create the DOM tearoff objects that wrap internal
 * SVGAnimatedNumberList objects.
 *
 * See the architecture comment in DOMSVGAnimatedLengthList.h (that's
 * LENGTH list). The comment for that class largly applies to this one too
 * and will go a long way to helping you understand the architecture here.
 *
 * This class is strongly intertwined with DOMSVGNumberList and DOMSVGNumber.
 * Our DOMSVGNumberList base and anim vals are friends and take care of nulling
 * out our pointers to them when they die (making our pointers to them true
 * weak refs).
 */
class DOMSVGAnimatedNumberList final : public nsISupports,
                                       public nsWrapperCache {
  friend class DOMSVGNumberList;

 public:
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGAnimatedNumberList)

  /**
   * Factory method to create and return a DOMSVGAnimatedNumberList wrapper
   * for a given internal SVGAnimatedNumberList object. The factory takes care
   * of caching the object that it returns so that the same object can be
   * returned for the given SVGAnimatedNumberList each time it is requested.
   * The cached object is only removed from the cache when it is destroyed due
   * to there being no more references to it or to any of its descendant
   * objects. If that happens, any subsequent call requesting the DOM wrapper
   * for the SVGAnimatedNumberList will naturally result in a new
   * DOMSVGAnimatedNumberList being returned.
   */
  static already_AddRefed<DOMSVGAnimatedNumberList> GetDOMWrapper(
      SVGAnimatedNumberList* aList, dom::SVGElement* aElement,
      uint8_t aAttrEnum);

  /**
   * This method returns the DOMSVGAnimatedNumberList wrapper for an internal
   * SVGAnimatedNumberList object if it currently has a wrapper. If it does
   * not, then nullptr is returned.
   */
  static DOMSVGAnimatedNumberList* GetDOMWrapperIfExists(
      SVGAnimatedNumberList* aList);

  /**
   * Called by internal code to notify us when we need to sync the length of
   * our baseVal DOM list with its internal list. This is called just prior to
   * the length of the internal baseVal list being changed so that any DOM list
   * items that need to be removed from the DOM list can first get their values
   * from their internal counterpart.
   *
   * The only time this method could fail is on OOM when trying to increase the
   * length of the DOM list. If that happens then this method simply clears the
   * list and returns. Callers just proceed as normal, and we simply accept
   * that the DOM list will be empty (until successfully set to a new value).
   */
  void InternalBaseValListWillChangeTo(const SVGNumberList& aNewValue);
  void InternalAnimValListWillChangeTo(const SVGNumberList& aNewValue);

  /**
   * Returns true if our attribute is animating (in which case our animVal is
   * not simply a mirror of our baseVal).
   */
  bool IsAnimating() const;

  // WebIDL
  dom::SVGElement* GetParentObject() const { return mElement; }
  virtual JSObject* WrapObject(JSContext* aCx,
                               JS::Handle<JSObject*> aGivenProto) override;
  // These aren't weak refs because mBaseVal and mAnimVal are weak
  already_AddRefed<DOMSVGNumberList> BaseVal();
  already_AddRefed<DOMSVGNumberList> AnimVal();

 private:
  /**
   * Only our static GetDOMWrapper() factory method may create objects of our
   * type.
   */
  DOMSVGAnimatedNumberList(dom::SVGElement* aElement, uint8_t aAttrEnum)
      : mBaseVal(nullptr),
        mAnimVal(nullptr),
        mElement(aElement),
        mAttrEnum(aAttrEnum) {}

  ~DOMSVGAnimatedNumberList();

  /// Get a reference to this DOM wrapper object's internal counterpart.
  SVGAnimatedNumberList& InternalAList();
  const SVGAnimatedNumberList& InternalAList() const;

  // Weak refs to our DOMSVGNumberList baseVal/animVal objects. These objects
  // are friends and take care of clearing these pointers when they die, making
  // these true weak references.
  DOMSVGNumberList* mBaseVal;
  DOMSVGNumberList* mAnimVal;

  // Strong ref to our element to keep it alive. We hold this not only for
  // ourself, but also for our base/animVal and all of their items.
  RefPtr<dom::SVGElement> mElement;

  uint8_t mAttrEnum;
};

}  // namespace dom
}  // namespace mozilla

#endif  // MOZILLA_DOMSVGANIMATEDNUMBERLIST_H__