tor-browser

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

SVGUseElement.h (6228B)


      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_SVGUSEELEMENT_H_
      8 #define DOM_SVG_SVGUSEELEMENT_H_
      9 
     10 #include "SVGAnimatedLength.h"
     11 #include "SVGAnimatedString.h"
     12 #include "mozilla/RefPtr.h"
     13 #include "mozilla/dom/FromParser.h"
     14 #include "mozilla/dom/IDTracker.h"
     15 #include "mozilla/dom/SVGGraphicsElement.h"
     16 #include "nsCOMPtr.h"
     17 #include "nsStubMutationObserver.h"
     18 #include "nsTArray.h"
     19 
     20 class nsIContent;
     21 
     22 nsresult NS_NewSVGSVGElement(
     23    nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
     24    mozilla::dom::FromParser aFromParser);
     25 nsresult NS_NewSVGUseElement(
     26    nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
     27 
     28 namespace mozilla {
     29 class Encoding;
     30 class SVGUseFrame;
     31 struct URLExtraData;
     32 
     33 namespace dom {
     34 
     35 using SVGUseElementBase = SVGGraphicsElement;
     36 
     37 class SVGUseElement final : public SVGUseElementBase,
     38                            public nsStubMutationObserver {
     39  friend class mozilla::SVGUseFrame;
     40 
     41 protected:
     42  friend nsresult(::NS_NewSVGUseElement(
     43      nsIContent** aResult,
     44      already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
     45  explicit SVGUseElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
     46  virtual ~SVGUseElement();
     47  JSObject* WrapNode(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
     48 
     49 public:
     50  NS_IMPL_FROMNODE_WITH_TAG(SVGUseElement, kNameSpaceID_SVG, use)
     51 
     52  nsresult BindToTree(BindContext&, nsINode& aParent) override;
     53  void UnbindFromTree(UnbindContext&) override;
     54 
     55  // interfaces:
     56  NS_DECL_ISUPPORTS_INHERITED
     57  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGUseElement, SVGUseElementBase)
     58 
     59  NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
     60  NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
     61  NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
     62  NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
     63  NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
     64  NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
     65 
     66  // SVGElement specializations:
     67  gfxMatrix ChildToUserSpaceTransform() const override;
     68  bool HasValidDimensions() const override;
     69 
     70  // nsIContent interface
     71  nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
     72  NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
     73 
     74  static NonCustomCSSPropertyId GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum);
     75 
     76  // WebIDL
     77  already_AddRefed<DOMSVGAnimatedString> Href();
     78  already_AddRefed<DOMSVGAnimatedLength> X();
     79  already_AddRefed<DOMSVGAnimatedLength> Y();
     80  already_AddRefed<DOMSVGAnimatedLength> Width();
     81  already_AddRefed<DOMSVGAnimatedLength> Height();
     82 
     83  Document* GetSourceDocument() const;
     84  nsIURI* GetSourceDocURI() const;
     85  const Encoding* GetSourceDocCharacterSet() const;
     86  URLExtraData* GetContentURLData() const { return mContentURLData; }
     87 
     88  // Updates the internal shadow tree to be an up-to-date clone of the
     89  // referenced element.
     90  void UpdateShadowTree();
     91 
     92  // Shared code between AfterSetAttr and SVGUseFrame::AttributeChanged.
     93  //
     94  // This is needed because SMIL doesn't go through AfterSetAttr unfortunately.
     95  void ProcessAttributeChange(int32_t aNamespaceID, nsAtom* aAttribute);
     96 
     97  void AfterSetAttr(int32_t aNamespaceID, nsAtom* aAttribute,
     98                    const nsAttrValue* aValue, const nsAttrValue* aOldValue,
     99                    nsIPrincipal* aSubjectPrincipal, bool aNotify) final;
    100 
    101 protected:
    102  // Information from walking our ancestors and a given target.
    103  enum class ScanResult {
    104    // Nothing that should stop us from rendering the shadow tree.
    105    Ok,
    106    // We're never going to be displayed, so no point in updating the shadow
    107    // tree.
    108    //
    109    // However if we're referenced from another tree that tree may need to be
    110    // rendered.
    111    Invisible,
    112    // We're a cyclic reference to either an ancestor or another shadow tree. We
    113    // shouldn't render this <use> element.
    114    CyclicReference,
    115    // We're too deep in our clone chain, we shouldn't be rendered.
    116    TooDeep,
    117  };
    118  ScanResult ScanAncestors(const Element& aTarget) const;
    119  ScanResult ScanAncestorsInternal(const Element& aTarget,
    120                                   uint32_t& aCount) const;
    121 
    122  /**
    123   * Helper that provides a reference to the element with the ID that is
    124   * referenced by the 'use' element's 'href' attribute, and that will update
    125   * the 'use' element if the element that that ID identifies changes to a
    126   * different element (or none).
    127   */
    128  class ElementTracker final : public IDTracker {
    129   public:
    130    explicit ElementTracker(SVGUseElement* aOwningUseElement)
    131        : mOwningUseElement(aOwningUseElement) {}
    132 
    133   private:
    134    void ElementChanged(Element* aFrom, Element* aTo) override {
    135      IDTracker::ElementChanged(aFrom, aTo);
    136      if (aFrom) {
    137        aFrom->RemoveMutationObserver(mOwningUseElement);
    138      }
    139      mOwningUseElement->TriggerReclone();
    140    }
    141 
    142    SVGUseElement* mOwningUseElement;
    143  };
    144 
    145  void DidAnimateAttribute(int32_t aNameSpaceID, nsAtom* aAttribute) override;
    146  SVGUseFrame* GetFrame() const;
    147 
    148  LengthAttributesInfo GetLengthInfo() override;
    149  StringAttributesInfo GetStringInfo() override;
    150 
    151  /**
    152   * Returns true if our width and height should be used, or false if they
    153   * should be ignored. As per the spec, this depends on the type of the
    154   * element that we're referencing.
    155   */
    156  bool OurWidthAndHeightAreUsed() const;
    157  void SyncWidthOrHeight(nsAtom* aName);
    158  void LookupHref();
    159  void TriggerReclone();
    160  void UnlinkSource();
    161 
    162  enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
    163  SVGAnimatedLength mLengthAttributes[4];
    164  static LengthInfo sLengthInfo[4];
    165 
    166  enum { HREF, XLINK_HREF };
    167  SVGAnimatedString mStringAttributes[2];
    168  static StringInfo sStringInfo[2];
    169 
    170  RefPtr<SVGUseElement> mOriginal;  // if we've been cloned, our "real" copy
    171  ElementTracker mReferencedElementTracker;
    172  RefPtr<URLExtraData> mContentURLData;  // URL data for its anonymous content
    173 };
    174 
    175 }  // namespace dom
    176 }  // namespace mozilla
    177 
    178 #endif  // DOM_SVG_SVGUSEELEMENT_H_