SVGViewFrame.cpp 3.7 KB

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