Line data Source code
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 : using namespace mozilla::dom;
14 :
15 : /**
16 : * While views are not directly rendered in SVG they can be linked to
17 : * and thereby override attributes of an <svg> element via a fragment
18 : * identifier. The SVGViewFrame class passes on any attribute changes
19 : * the view receives to the overridden <svg> element (if there is one).
20 : **/
21 0 : class SVGViewFrame : public nsFrame
22 : {
23 : friend nsIFrame*
24 : NS_NewSVGViewFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
25 : protected:
26 0 : explicit SVGViewFrame(nsStyleContext* aContext)
27 0 : : nsFrame(aContext, kClassID)
28 : {
29 0 : AddStateBits(NS_FRAME_IS_NONDISPLAY);
30 0 : }
31 :
32 : public:
33 0 : NS_DECL_FRAMEARENA_HELPERS(SVGViewFrame)
34 :
35 : #ifdef DEBUG
36 : virtual void Init(nsIContent* aContent,
37 : nsContainerFrame* aParent,
38 : nsIFrame* aPrevInFlow) override;
39 : #endif
40 :
41 0 : virtual bool IsFrameOfType(uint32_t aFlags) const override
42 : {
43 0 : return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eSVG));
44 : }
45 :
46 : #ifdef DEBUG_FRAME_DUMP
47 0 : virtual nsresult GetFrameName(nsAString& aResult) const override
48 : {
49 0 : return MakeFrameName(NS_LITERAL_STRING("SVGView"), aResult);
50 : }
51 : #endif
52 :
53 : virtual nsresult AttributeChanged(int32_t aNameSpaceID,
54 : nsIAtom* aAttribute,
55 : int32_t aModType) override;
56 :
57 0 : virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override {
58 : // We don't maintain a visual overflow rect
59 0 : return false;
60 : }
61 : };
62 :
63 : nsIFrame*
64 0 : NS_NewSVGViewFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
65 : {
66 0 : return new (aPresShell) SVGViewFrame(aContext);
67 : }
68 :
69 0 : NS_IMPL_FRAMEARENA_HELPERS(SVGViewFrame)
70 :
71 : #ifdef DEBUG
72 : void
73 0 : SVGViewFrame::Init(nsIContent* aContent,
74 : nsContainerFrame* aParent,
75 : nsIFrame* aPrevInFlow)
76 : {
77 0 : NS_ASSERTION(aContent->IsSVGElement(nsGkAtoms::view),
78 : "Content is not an SVG view");
79 :
80 0 : nsFrame::Init(aContent, aParent, aPrevInFlow);
81 0 : }
82 : #endif /* DEBUG */
83 :
84 : nsresult
85 0 : SVGViewFrame::AttributeChanged(int32_t aNameSpaceID,
86 : nsIAtom* aAttribute,
87 : int32_t aModType)
88 : {
89 : // Ignore zoomAndPan as it does not cause the <svg> element to re-render
90 :
91 0 : if (aNameSpaceID == kNameSpaceID_None &&
92 0 : (aAttribute == nsGkAtoms::preserveAspectRatio ||
93 0 : aAttribute == nsGkAtoms::viewBox ||
94 0 : aAttribute == nsGkAtoms::viewTarget)) {
95 :
96 0 : nsSVGOuterSVGFrame *outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(this);
97 0 : NS_ASSERTION(outerSVGFrame->GetContent()->IsSVGElement(nsGkAtoms::svg),
98 : "Expecting an <svg> element");
99 :
100 : SVGSVGElement* svgElement =
101 0 : static_cast<SVGSVGElement*>(outerSVGFrame->GetContent());
102 :
103 0 : nsAutoString viewID;
104 0 : mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, viewID);
105 :
106 0 : if (svgElement->IsOverriddenBy(viewID)) {
107 : // We're the view that's providing overrides, so pretend that the frame
108 : // we're overriding was updated.
109 0 : outerSVGFrame->AttributeChanged(aNameSpaceID, aAttribute, aModType);
110 : }
111 : }
112 :
113 0 : return nsFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
114 : }
|