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 MOZILLA_SVGANIMATEDPRESERVEASPECTRATIO_H__
8 #define MOZILLA_SVGANIMATEDPRESERVEASPECTRATIO_H__
9 
10 #include "nsCycleCollectionParticipant.h"
11 #include "nsError.h"
12 #include "nsISMILAttr.h"
13 #include "nsSVGElement.h"
14 #include "SVGPreserveAspectRatio.h"
15 #include "mozilla/Attributes.h"
16 #include "mozilla/UniquePtr.h"
17 
18 class nsSMILValue;
19 
20 namespace mozilla {
21 namespace dom {
22 class DOMSVGAnimatedPreserveAspectRatio;
23 class SVGAnimationElement;
24 }  // namespace dom
25 
26 class SVGAnimatedPreserveAspectRatio final {
27  public:
Init()28   void Init() {
29     mBaseVal.mAlign =
30         dom::SVGPreserveAspectRatioBinding::SVG_PRESERVEASPECTRATIO_XMIDYMID;
31     mBaseVal.mMeetOrSlice =
32         dom::SVGPreserveAspectRatioBinding::SVG_MEETORSLICE_MEET;
33     mAnimVal = mBaseVal;
34     mIsAnimated = false;
35     mIsBaseSet = false;
36   }
37 
38   nsresult SetBaseValueString(const nsAString& aValue,
39                               nsSVGElement* aSVGElement, bool aDoSetAttr);
40   void GetBaseValueString(nsAString& aValue) const;
41 
42   void SetBaseValue(const SVGPreserveAspectRatio& aValue,
43                     nsSVGElement* aSVGElement);
SetBaseAlign(uint16_t aAlign,nsSVGElement * aSVGElement)44   nsresult SetBaseAlign(uint16_t aAlign, nsSVGElement* aSVGElement) {
45     if (aAlign < SVG_ALIGN_MIN_VALID || aAlign > SVG_ALIGN_MAX_VALID) {
46       return NS_ERROR_FAILURE;
47     }
48     SetBaseValue(SVGPreserveAspectRatio(aAlign, mBaseVal.GetMeetOrSlice()),
49                  aSVGElement);
50     return NS_OK;
51   }
SetBaseMeetOrSlice(uint16_t aMeetOrSlice,nsSVGElement * aSVGElement)52   nsresult SetBaseMeetOrSlice(uint16_t aMeetOrSlice,
53                               nsSVGElement* aSVGElement) {
54     if (aMeetOrSlice < SVG_MEETORSLICE_MIN_VALID ||
55         aMeetOrSlice > SVG_MEETORSLICE_MAX_VALID) {
56       return NS_ERROR_FAILURE;
57     }
58     SetBaseValue(SVGPreserveAspectRatio(mBaseVal.GetAlign(), aMeetOrSlice),
59                  aSVGElement);
60     return NS_OK;
61   }
62   void SetAnimValue(uint64_t aPackedValue, nsSVGElement* aSVGElement);
63 
GetBaseValue()64   const SVGPreserveAspectRatio& GetBaseValue() const { return mBaseVal; }
GetAnimValue()65   const SVGPreserveAspectRatio& GetAnimValue() const { return mAnimVal; }
IsAnimated()66   bool IsAnimated() const { return mIsAnimated; }
IsExplicitlySet()67   bool IsExplicitlySet() const { return mIsAnimated || mIsBaseSet; }
68 
69   already_AddRefed<mozilla::dom::DOMSVGAnimatedPreserveAspectRatio>
70   ToDOMAnimatedPreserveAspectRatio(nsSVGElement* aSVGElement);
71   UniquePtr<nsISMILAttr> ToSMILAttr(nsSVGElement* aSVGElement);
72 
73  private:
74   SVGPreserveAspectRatio mAnimVal;
75   SVGPreserveAspectRatio mBaseVal;
76   bool mIsAnimated;
77   bool mIsBaseSet;
78 
79  public:
80   struct SMILPreserveAspectRatio final : public nsISMILAttr {
81    public:
SMILPreserveAspectRatiofinal82     SMILPreserveAspectRatio(SVGAnimatedPreserveAspectRatio* aVal,
83                             nsSVGElement* aSVGElement)
84         : mVal(aVal), mSVGElement(aSVGElement) {}
85 
86     // These will stay alive because a nsISMILAttr only lives as long
87     // as the Compositing step, and DOM elements don't get a chance to
88     // die during that.
89     SVGAnimatedPreserveAspectRatio* mVal;
90     nsSVGElement* mSVGElement;
91 
92     // nsISMILAttr methods
93     virtual nsresult ValueFromString(
94         const nsAString& aStr, const dom::SVGAnimationElement* aSrcElement,
95         nsSMILValue& aValue, bool& aPreventCachingOfSandwich) const override;
96     virtual nsSMILValue GetBaseValue() const override;
97     virtual void ClearAnimValue() override;
98     virtual nsresult SetAnimValue(const nsSMILValue& aValue) override;
99   };
100 };
101 
102 namespace dom {
103 class DOMSVGAnimatedPreserveAspectRatio final : public nsISupports,
104                                                 public nsWrapperCache {
105   ~DOMSVGAnimatedPreserveAspectRatio();
106 
107   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGAnimatedPreserveAspectRatio)108   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(
109       DOMSVGAnimatedPreserveAspectRatio)
110 
111   DOMSVGAnimatedPreserveAspectRatio(SVGAnimatedPreserveAspectRatio* aVal,
112                                     nsSVGElement* aSVGElement)
113       : mVal(aVal), mSVGElement(aSVGElement) {}
114 
115   // WebIDL
GetParentObject()116   nsSVGElement* GetParentObject() const { return mSVGElement; }
117   virtual JSObject* WrapObject(JSContext* aCx,
118                                JS::Handle<JSObject*> aGivenProto) override;
119 
120   // These aren't weak refs because new objects are returned each time
121   already_AddRefed<DOMSVGPreserveAspectRatio> BaseVal();
122   already_AddRefed<DOMSVGPreserveAspectRatio> AnimVal();
123 
124  protected:
125   // kept alive because it belongs to content:
126   SVGAnimatedPreserveAspectRatio* mVal;
127   RefPtr<nsSVGElement> mSVGElement;
128 };
129 
130 }  // namespace dom
131 }  // namespace mozilla
132 
133 #endif  // MOZILLA_SVGANIMATEDPRESERVEASPECTRATIO_H__
134