|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 // Keep in (case-insensitive) order: |
|
7 #include "nsFrame.h" |
|
8 #include "nsGkAtoms.h" |
|
9 #include "nsSVGOuterSVGFrame.h" |
|
10 #include "mozilla/dom/SVGSVGElement.h" |
|
11 #include "mozilla/dom/SVGViewElement.h" |
|
12 |
|
13 typedef nsFrame SVGViewFrameBase; |
|
14 |
|
15 using namespace mozilla::dom; |
|
16 |
|
17 /** |
|
18 * While views are not directly rendered in SVG they can be linked to |
|
19 * and thereby override attributes of an <svg> element via a fragment |
|
20 * identifier. The SVGViewFrame class passes on any attribute changes |
|
21 * the view receives to the overridden <svg> element (if there is one). |
|
22 **/ |
|
23 class SVGViewFrame : public SVGViewFrameBase |
|
24 { |
|
25 friend nsIFrame* |
|
26 NS_NewSVGViewFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); |
|
27 protected: |
|
28 SVGViewFrame(nsStyleContext* aContext) |
|
29 : SVGViewFrameBase(aContext) |
|
30 { |
|
31 AddStateBits(NS_FRAME_IS_NONDISPLAY); |
|
32 } |
|
33 |
|
34 public: |
|
35 NS_DECL_FRAMEARENA_HELPERS |
|
36 |
|
37 #ifdef DEBUG |
|
38 virtual void Init(nsIContent* aContent, |
|
39 nsIFrame* aParent, |
|
40 nsIFrame* aPrevInFlow) MOZ_OVERRIDE; |
|
41 #endif |
|
42 |
|
43 virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE |
|
44 { |
|
45 return SVGViewFrameBase::IsFrameOfType(aFlags & ~(nsIFrame::eSVG)); |
|
46 } |
|
47 |
|
48 #ifdef DEBUG_FRAME_DUMP |
|
49 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE |
|
50 { |
|
51 return MakeFrameName(NS_LITERAL_STRING("SVGView"), aResult); |
|
52 } |
|
53 #endif |
|
54 |
|
55 /** |
|
56 * Get the "type" of the frame |
|
57 * |
|
58 * @see nsGkAtoms::svgFELeafFrame |
|
59 */ |
|
60 virtual nsIAtom* GetType() const MOZ_OVERRIDE; |
|
61 |
|
62 virtual nsresult AttributeChanged(int32_t aNameSpaceID, |
|
63 nsIAtom* aAttribute, |
|
64 int32_t aModType) MOZ_OVERRIDE; |
|
65 |
|
66 virtual bool UpdateOverflow() MOZ_OVERRIDE { |
|
67 // We don't maintain a visual overflow rect |
|
68 return false; |
|
69 } |
|
70 }; |
|
71 |
|
72 nsIFrame* |
|
73 NS_NewSVGViewFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) |
|
74 { |
|
75 return new (aPresShell) SVGViewFrame(aContext); |
|
76 } |
|
77 |
|
78 NS_IMPL_FRAMEARENA_HELPERS(SVGViewFrame) |
|
79 |
|
80 #ifdef DEBUG |
|
81 void |
|
82 SVGViewFrame::Init(nsIContent* aContent, |
|
83 nsIFrame* aParent, |
|
84 nsIFrame* aPrevInFlow) |
|
85 { |
|
86 NS_ASSERTION(aContent->IsSVG(nsGkAtoms::view), |
|
87 "Content is not an SVG view"); |
|
88 |
|
89 SVGViewFrameBase::Init(aContent, aParent, aPrevInFlow); |
|
90 } |
|
91 #endif /* DEBUG */ |
|
92 |
|
93 nsIAtom * |
|
94 SVGViewFrame::GetType() const |
|
95 { |
|
96 return nsGkAtoms::svgViewFrame; |
|
97 } |
|
98 |
|
99 nsresult |
|
100 SVGViewFrame::AttributeChanged(int32_t aNameSpaceID, |
|
101 nsIAtom* aAttribute, |
|
102 int32_t aModType) |
|
103 { |
|
104 // Ignore zoomAndPan as it does not cause the <svg> element to re-render |
|
105 |
|
106 if (aNameSpaceID == kNameSpaceID_None && |
|
107 (aAttribute == nsGkAtoms::preserveAspectRatio || |
|
108 aAttribute == nsGkAtoms::viewBox || |
|
109 aAttribute == nsGkAtoms::viewTarget)) { |
|
110 |
|
111 nsSVGOuterSVGFrame *outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(this); |
|
112 NS_ASSERTION(outerSVGFrame->GetContent()->IsSVG(nsGkAtoms::svg), |
|
113 "Expecting an <svg> element"); |
|
114 |
|
115 SVGSVGElement* svgElement = |
|
116 static_cast<SVGSVGElement*>(outerSVGFrame->GetContent()); |
|
117 |
|
118 nsAutoString viewID; |
|
119 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, viewID); |
|
120 |
|
121 if (svgElement->IsOverriddenBy(viewID)) { |
|
122 // We're the view that's providing overrides, so pretend that the frame |
|
123 // we're overriding was updated. |
|
124 outerSVGFrame->AttributeChanged(aNameSpaceID, aAttribute, aModType); |
|
125 } |
|
126 } |
|
127 |
|
128 return SVGViewFrameBase::AttributeChanged(aNameSpaceID, |
|
129 aAttribute, aModType); |
|
130 } |