tor-browser

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

SVGSVGElement.h (9563B)


      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_SVGSVGELEMENT_H_
      8 #define DOM_SVG_SVGSVGELEMENT_H_
      9 
     10 #include "SVGAnimatedEnumeration.h"
     11 #include "SVGViewportElement.h"
     12 #include "mozilla/SVGImageContext.h"
     13 
     14 nsresult NS_NewSVGSVGElement(
     15    nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
     16    mozilla::dom::FromParser aFromParser);
     17 
     18 // {4b83982c-e5e9-4ca1-abd4-14d27e8b3531}
     19 #define MOZILLA_SVGSVGELEMENT_IID \
     20  {0x4b83982c, 0xe5e9, 0x4ca1, {0xab, 0xd4, 0x14, 0xd2, 0x7e, 0x8b, 0x35, 0x31}}
     21 
     22 namespace mozilla {
     23 class AutoSVGViewHandler;
     24 class SMILTimeContainer;
     25 class SVGFragmentIdentifier;
     26 class EventChainPreVisitor;
     27 
     28 namespace dom {
     29 struct DOMMatrix2DInit;
     30 class DOMSVGAngle;
     31 class DOMSVGLength;
     32 class DOMSVGNumber;
     33 class DOMSVGPoint;
     34 class SVGMatrix;
     35 class SVGRect;
     36 class SVGSVGElement;
     37 
     38 // Stores svgView arguments of SVG fragment identifiers.
     39 class SVGView {
     40 public:
     41  SVGView();
     42 
     43  SVGAnimatedEnumeration mZoomAndPan;
     44  SVGAnimatedViewBox mViewBox;
     45  SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
     46  UniquePtr<SVGAnimatedTransformList> mTransforms;
     47 };
     48 
     49 using SVGSVGElementBase = SVGViewportElement;
     50 
     51 class SVGSVGElement final : public SVGSVGElementBase {
     52  friend class mozilla::SVGFragmentIdentifier;
     53  friend class mozilla::SVGOuterSVGFrame;
     54  friend class mozilla::AutoSVGViewHandler;
     55  friend class mozilla::AutoPreserveAspectRatioOverride;
     56  friend class mozilla::dom::SVGView;
     57 
     58 protected:
     59  SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
     60                FromParser aFromParser);
     61  JSObject* WrapNode(JSContext* aCx,
     62                     JS::Handle<JSObject*> aGivenProto) override;
     63 
     64  friend nsresult(::NS_NewSVGSVGElement(
     65      nsIContent** aResult,
     66      already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
     67      mozilla::dom::FromParser aFromParser));
     68 
     69  ~SVGSVGElement() = default;
     70 
     71 public:
     72  NS_IMPL_FROMNODE_WITH_TAG(SVGSVGElement, kNameSpaceID_SVG, svg)
     73 
     74  // interfaces:
     75  NS_INLINE_DECL_STATIC_IID(MOZILLA_SVGSVGELEMENT_IID)
     76  NS_DECL_ISUPPORTS_INHERITED
     77  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGSVGElement, SVGSVGElementBase)
     78 
     79  /*
     80   * Send appropriate events and updates if our root translate
     81   * has changed.
     82   */
     83  MOZ_CAN_RUN_SCRIPT
     84  void DidChangeTranslate();
     85 
     86  // nsIContent interface
     87  void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
     88  bool IsEventAttributeNameInternal(nsAtom* aName) override;
     89 
     90  // nsINode methods:
     91  nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
     92 
     93  // WebIDL
     94  already_AddRefed<DOMSVGAnimatedLength> X();
     95  already_AddRefed<DOMSVGAnimatedLength> Y();
     96  already_AddRefed<DOMSVGAnimatedLength> Width();
     97  already_AddRefed<DOMSVGAnimatedLength> Height();
     98  bool UseCurrentView() const;
     99  float CurrentScale() const;
    100  void SetCurrentScale(float aCurrentScale);
    101  already_AddRefed<DOMSVGPoint> CurrentTranslate();
    102  uint32_t SuspendRedraw(uint32_t max_wait_milliseconds);
    103  void UnsuspendRedraw(uint32_t suspend_handle_id);
    104  void UnsuspendRedrawAll();
    105  void ForceRedraw();
    106  void PauseAnimations();
    107  void PauseAnimationsAt(float seconds);
    108  void UnpauseAnimations();
    109  bool AnimationsPaused();
    110  float GetCurrentTimeAsFloat();
    111  void SetCurrentTime(float seconds);
    112  MOZ_CAN_RUN_SCRIPT void DeselectAll();
    113  already_AddRefed<DOMSVGNumber> CreateSVGNumber();
    114  already_AddRefed<DOMSVGLength> CreateSVGLength();
    115  already_AddRefed<DOMSVGAngle> CreateSVGAngle();
    116  already_AddRefed<DOMSVGPoint> CreateSVGPoint();
    117  already_AddRefed<SVGMatrix> CreateSVGMatrix();
    118  already_AddRefed<SVGRect> CreateSVGRect();
    119  already_AddRefed<DOMSVGTransform> CreateSVGTransform();
    120  already_AddRefed<DOMSVGTransform> CreateSVGTransformFromMatrix(
    121      const DOMMatrix2DInit& matrix, ErrorResult& rv);
    122  using nsINode::GetElementById;  // This does what we want
    123  uint16_t ZoomAndPan() const;
    124  void SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv);
    125 
    126  // SVGElement overrides
    127 
    128  nsresult BindToTree(BindContext&, nsINode& aParent) override;
    129  void UnbindFromTree(UnbindContext&) override;
    130  SVGAnimatedTransformList* GetAnimatedTransformList(
    131      uint32_t aFlags = 0) override;
    132 
    133  // SVGSVGElement methods:
    134 
    135  // Returns true IFF our attributes are currently overridden by a <view>
    136  // element and that element's ID matches the passed-in string.
    137  bool IsOverriddenBy(const nsAString& aViewID) const {
    138    return mCurrentViewID && mCurrentViewID->Equals(aViewID);
    139  }
    140 
    141  SMILTimeContainer* GetTimedDocumentRoot();
    142 
    143  // public helpers:
    144 
    145  const SVGPoint& GetCurrentTranslate() const { return mCurrentTranslate; }
    146  bool IsScaledOrTranslated() const {
    147    return mCurrentTranslate != SVGPoint() || mCurrentScale != 1.0f;
    148  }
    149 
    150  LengthPercentage GetIntrinsicWidth();
    151  LengthPercentage GetIntrinsicHeight();
    152 
    153  // This services any pending notifications for the transform on on this root
    154  // <svg> node needing to be recalculated.  (Only applicable in
    155  // SVG-as-an-image documents.)
    156  virtual void FlushImageTransformInvalidation();
    157 
    158 private:
    159  // SVGViewportElement methods:
    160 
    161  virtual SVGViewElement* GetCurrentViewElement() const;
    162  SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const override;
    163 
    164  // implementation helpers:
    165 
    166  /*
    167   * While binding to the tree we need to determine if we will be the outermost
    168   * <svg> element _before_ the children are bound (as they want to know what
    169   * timed document root to register with) and therefore _before_ our parent is
    170   * set (both actions are performed by Element::BindToTree) so we
    171   * can't use GetOwnerSVGElement() as it relies on GetParent(). This code is
    172   * basically a simplified version of GetOwnerSVGElement that uses the parent
    173   * parameters passed in instead.
    174   *
    175   * FIXME(bug 1596690): GetOwnerSVGElement() uses the flattened tree parent
    176   * rather than the DOM tree parent nowadays.
    177   */
    178  bool WillBeOutermostSVG(nsINode& aParent) const;
    179 
    180  LengthPercentage GetIntrinsicWidthOrHeight(int aAttr);
    181 
    182  // invalidate viewbox -> viewport xform & inform frames
    183  void InvalidateTransformNotifyFrame();
    184  void DidChangeSVGView();
    185 
    186  // Methods for <image> elements to override my "PreserveAspectRatio" value.
    187  // These are private so that only our friends
    188  // (AutoPreserveAspectRatioOverride in particular) have access.
    189  void SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio& aPAR);
    190  void ClearImageOverridePreserveAspectRatio();
    191 
    192  // Set/Clear properties to hold old version of preserveAspectRatio
    193  // when it's being overridden by an <image> element that we are inside of.
    194  bool SetPreserveAspectRatioProperty(const SVGPreserveAspectRatio& aPAR);
    195  const SVGPreserveAspectRatio* GetPreserveAspectRatioProperty() const;
    196  bool ClearPreserveAspectRatioProperty();
    197 
    198  const SVGAnimatedViewBox& GetViewBoxInternal() const override;
    199 
    200  EnumAttributesInfo GetEnumInfo() override;
    201 
    202  enum { ZOOMANDPAN };
    203  SVGAnimatedEnumeration mEnumAttributes[1];
    204  static SVGEnumMapping sZoomAndPanMap[];
    205  static EnumInfo sEnumInfo[1];
    206 
    207  // The time container for animations within this SVG document fragment. Set
    208  // for all outermost <svg> elements (not nested <svg> elements).
    209  UniquePtr<SMILTimeContainer> mTimedDocumentRoot;
    210 
    211  SVGPoint mCurrentTranslate;
    212  float mCurrentScale;
    213 
    214  // For outermost <svg> elements created from parsing, animation is started by
    215  // the onload event in accordance with the SVG spec, but for <svg> elements
    216  // created by script or promoted from inner <svg> to outermost <svg> we need
    217  // to manually kick off animation when they are bound to the tree.
    218  bool mStartAnimationOnBindToTree;
    219 
    220  bool mImageNeedsTransformInvalidation;
    221 
    222  // mCurrentViewID and mSVGView are mutually exclusive; we can have
    223  // at most one non-null.
    224  UniquePtr<nsString> mCurrentViewID;
    225  UniquePtr<SVGView> mSVGView;
    226 };
    227 
    228 }  // namespace dom
    229 
    230 class MOZ_RAII AutoSVGTimeSetRestore {
    231 public:
    232  AutoSVGTimeSetRestore(dom::SVGSVGElement* aRootElem, float aFrameTime)
    233      : mRootElem(aRootElem),
    234        mOriginalTime(mRootElem->GetCurrentTimeAsFloat()) {
    235    mRootElem->SetCurrentTime(
    236        aFrameTime);  // Does nothing if there's no change.
    237  }
    238 
    239  ~AutoSVGTimeSetRestore() { mRootElem->SetCurrentTime(mOriginalTime); }
    240 
    241 private:
    242  const RefPtr<dom::SVGSVGElement> mRootElem;
    243  const float mOriginalTime;
    244 };
    245 
    246 class MOZ_RAII AutoPreserveAspectRatioOverride {
    247 public:
    248  AutoPreserveAspectRatioOverride(const SVGImageContext& aSVGContext,
    249                                  dom::SVGSVGElement* aRootElem)
    250      : mRootElem(aRootElem), mDidOverride(false) {
    251    MOZ_ASSERT(mRootElem, "No SVG/Symbol node to manage?");
    252 
    253    if (aSVGContext.GetPreserveAspectRatio().isSome()) {
    254      // Override preserveAspectRatio in our helper document.
    255      // XXXdholbert We should technically be overriding the helper doc's clip
    256      // and overflow properties here, too. See bug 272288 comment 36.
    257      mRootElem->SetImageOverridePreserveAspectRatio(
    258          *aSVGContext.GetPreserveAspectRatio());
    259      mDidOverride = true;
    260    }
    261  }
    262 
    263  ~AutoPreserveAspectRatioOverride() {
    264    if (mDidOverride) {
    265      mRootElem->ClearImageOverridePreserveAspectRatio();
    266    }
    267  }
    268 
    269 private:
    270  const RefPtr<dom::SVGSVGElement> mRootElem;
    271  bool mDidOverride;
    272 };
    273 
    274 }  // namespace mozilla
    275 
    276 #endif  // DOM_SVG_SVGSVGELEMENT_H_