author Emilio Cobos Álvarez <>
Mon, 01 May 2017 19:32:52 +0200
changeset 356045 fbc54f707dc421f8132340e45fa2719dbdc9621b
parent 355830 662df8ef329fd7a38fb2ceb24e305cd31e7bcaa7
child 360754 45bf72e9b3b3b5d45457598865c72536b3027264
permissions -rw-r--r--
Bug 1361051: rename mozilla::FrameType to mozilla::LayoutFrameType. r=xidorn This avoids conflicts with mozilla::dom::FrameType. MozReview-Commit-ID: 7aEMbHRaTFk

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at */

// Keep in (case-insensitive) order:
#include "nsFrame.h"
#include "nsGkAtoms.h"
#include "nsSVGOuterSVGFrame.h"
#include "mozilla/dom/SVGSVGElement.h"
#include "mozilla/dom/SVGViewElement.h"

using namespace mozilla::dom;

 * While views are not directly rendered in SVG they can be linked to
 * and thereby override attributes of an <svg> element via a fragment
 * identifier. The SVGViewFrame class passes on any attribute changes
 * the view receives to the overridden <svg> element (if there is one).
class SVGViewFrame : public nsFrame
  friend nsIFrame*
  NS_NewSVGViewFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
  explicit SVGViewFrame(nsStyleContext* aContext)
    : nsFrame(aContext, LayoutFrameType::SVGView)


#ifdef DEBUG
  virtual void Init(nsIContent*       aContent,
                    nsContainerFrame* aParent,
                    nsIFrame*         aPrevInFlow) override;

  virtual bool IsFrameOfType(uint32_t aFlags) const override
    return nsFrame::IsFrameOfType(aFlags & ~(nsIFrame::eSVG));

  virtual nsresult GetFrameName(nsAString& aResult) const override
    return MakeFrameName(NS_LITERAL_STRING("SVGView"), aResult);

  virtual nsresult AttributeChanged(int32_t  aNameSpaceID,
                                    nsIAtom* aAttribute,
                                    int32_t  aModType) override;

  virtual bool ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) override {
    // We don't maintain a visual overflow rect
    return false;

NS_NewSVGViewFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
  return new (aPresShell) SVGViewFrame(aContext);


#ifdef DEBUG
SVGViewFrame::Init(nsIContent*       aContent,
                   nsContainerFrame* aParent,
                   nsIFrame*         aPrevInFlow)
               "Content is not an SVG view");

  nsFrame::Init(aContent, aParent, aPrevInFlow);
#endif /* DEBUG */

SVGViewFrame::AttributeChanged(int32_t  aNameSpaceID,
                               nsIAtom* aAttribute,
                               int32_t  aModType)
  // Ignore zoomAndPan as it does not cause the <svg> element to re-render
  if (aNameSpaceID == kNameSpaceID_None &&
      (aAttribute == nsGkAtoms::preserveAspectRatio ||
       aAttribute == nsGkAtoms::viewBox ||
       aAttribute == nsGkAtoms::viewTarget)) {

    nsSVGOuterSVGFrame *outerSVGFrame = nsSVGUtils::GetOuterSVGFrame(this);
                 "Expecting an <svg> element");

    SVGSVGElement* svgElement =

    nsAutoString viewID;
    mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, viewID);

    if (svgElement->IsOverriddenBy(viewID)) {
      // We're the view that's providing overrides, so pretend that the frame
      // we're overriding was updated.
      outerSVGFrame->AttributeChanged(aNameSpaceID, aAttribute, aModType);

  return nsFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);