author David Keeler <>
Fri, 16 Mar 2018 16:50:19 -0700
changeset 409021 5be07e86738e8993022e1c507b5b09e602872a33
parent 397436 fceda645f5e3f6cb4f429d5c8efcdeb5a6913e40
child 409519 b683bb3f22a1aef672332aa3ee9d2c7a77149913
permissions -rw-r--r--
bug 1439383 - clean up the load loadable roots thread when we're done with it r=froydnj,jcj MozReview-Commit-ID: J5GnpwxYguz

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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, kClassID)


#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,
                                    nsAtom* 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,
                               nsAtom* 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->AsElement()->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);