Bug 265894 - Part 5. Move svg-view back to SVGSVGElement.
MozReview-Commit-ID: ESHLDHxsqps
--- a/dom/svg/SVGSVGElement.cpp
+++ b/dom/svg/SVGSVGElement.cpp
@@ -123,16 +123,24 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(SVGSVGElement,SVGSVGElementBase)
NS_IMPL_RELEASE_INHERITED(SVGSVGElement,SVGSVGElementBase)
NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGSVGElement)
NS_INTERFACE_TABLE_INHERITED(SVGSVGElement, nsIDOMNode, nsIDOMElement,
nsIDOMSVGElement)
NS_INTERFACE_TABLE_TAIL_INHERITING(SVGSVGElementBase)
+SVGView::SVGView()
+{
+ mZoomAndPan.Init(SVGSVGElement::ZOOMANDPAN,
+ SVG_ZOOMANDPAN_MAGNIFY);
+ mViewBox.Init();
+ mPreserveAspectRatio.Init();
+}
+
//----------------------------------------------------------------------
// Implementation
SVGSVGElement::SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
FromParser aFromParser)
: SVGSVGElementBase(aNodeInfo),
mCurrentTranslate(0.0f, 0.0f),
mCurrentScale(1.0f),
@@ -536,16 +544,25 @@ SVGSVGElement::UnbindFromTree(bool aDeep
{
if (mTimedDocumentRoot) {
mTimedDocumentRoot->SetParent(nullptr);
}
SVGGraphicsElement::UnbindFromTree(aDeep, aNullParent);
}
+nsSVGAnimatedTransformList*
+SVGSVGElement::GetAnimatedTransformList(uint32_t aFlags)
+{
+ if (!(aFlags & DO_ALLOCATE) && mSVGView && mSVGView->mTransforms) {
+ return mSVGView->mTransforms;
+ }
+ return SVGGraphicsElement::GetAnimatedTransformList(aFlags);
+}
+
nsresult
SVGSVGElement::GetEventTargetParent(EventChainPreVisitor& aVisitor)
{
if (aVisitor.mEvent->mMessage == eSVGLoad) {
if (mTimedDocumentRoot) {
mTimedDocumentRoot->Begin();
// Set 'resample needed' flag, so that if any script calls a DOM method
// that requires up-to-date animations before our first sample callback,
@@ -760,10 +777,47 @@ SVGSVGElement::GetPreserveAspectRatioWit
return viewElement->mPreserveAspectRatio.GetAnimValue();
}
if (mSVGView && mSVGView->mPreserveAspectRatio.IsExplicitlySet()) {
return mSVGView->mPreserveAspectRatio.GetAnimValue();
}
return mPreserveAspectRatio.GetAnimValue();
}
+SVGViewElement*
+SVGSVGElement::GetCurrentViewElement() const
+{
+ if (mCurrentViewID) {
+ //XXXsmaug It is unclear how this should work in case we're in Shadow DOM.
+ nsIDocument* doc = GetUncomposedDoc();
+ if (doc) {
+ Element *element = doc->GetElementById(*mCurrentViewID);
+ if (element && element->IsSVGElement(nsGkAtoms::view)) {
+ return static_cast<SVGViewElement*>(element);
+ }
+ }
+ }
+ return nullptr;
+}
+
+const nsSVGViewBox&
+SVGSVGElement::GetViewBoxInternal() const
+{
+ SVGViewElement* viewElement = GetCurrentViewElement();
+
+ if (viewElement && viewElement->mViewBox.HasRect()) {
+ return viewElement->mViewBox;
+ } else if (mSVGView && mSVGView->mViewBox.HasRect()) {
+ return mSVGView->mViewBox;
+ }
+
+ return mViewBox;
+}
+
+nsSVGAnimatedTransformList*
+SVGSVGElement::GetTransformInternal() const
+{
+ return (mSVGView && mSVGView->mTransforms)
+ ? mSVGView->mTransforms: mTransforms;
+}
+
} // namespace dom
} // namespace mozilla
--- a/dom/svg/SVGSVGElement.h
+++ b/dom/svg/SVGSVGElement.h
@@ -23,16 +23,27 @@ class DOMSVGLength;
class DOMSVGNumber;
namespace dom {
class SVGAngle;
class SVGMatrix;
class SVGIRect;
class SVGSVGElement;
+// Stores svgView arguments of SVG fragment identifiers.
+class SVGView {
+public:
+ SVGView();
+
+ nsSVGEnum mZoomAndPan;
+ nsSVGViewBox mViewBox;
+ SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
+ nsAutoPtr<nsSVGAnimatedTransformList> mTransforms;
+};
+
class DOMSVGTranslatePoint final : public nsISVGPoint {
public:
DOMSVGTranslatePoint(SVGPoint* aPt, SVGSVGElement* aElement)
: nsISVGPoint(aPt, true), mElement(aElement) {}
explicit DOMSVGTranslatePoint(DOMSVGTranslatePoint* aPt)
: nsISVGPoint(&aPt->mPt, true), mElement(aPt->mElement) {}
@@ -59,16 +70,17 @@ private:
typedef SVGViewportElement SVGSVGElementBase;
class SVGSVGElement final : public SVGSVGElementBase
{
friend class ::nsSVGOuterSVGFrame;
friend class mozilla::SVGFragmentIdentifier;
friend class mozilla::AutoSVGViewHandler;
friend class mozilla::AutoPreserveAspectRatioOverride;
+ friend class mozilla::dom::SVGView;
protected:
SVGSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo,
FromParser aFromParser);
virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
friend nsresult (::NS_NewSVGSVGElement(nsIContent **aResult,
already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
@@ -135,16 +147,18 @@ public:
void SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv);
// nsSVGElement overrides
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers) override;
virtual void UnbindFromTree(bool aDeep, bool aNullParent) override;
+ virtual nsSVGAnimatedTransformList*
+ GetAnimatedTransformList(uint32_t aFlags = 0) override;
// SVGSVGElement methods:
// Returns true IFF our attributes are currently overridden by a <view>
// element and that element's ID matches the passed-in string.
bool IsOverriddenBy(const nsAString &aViewID) const {
return mCurrentViewID && mCurrentViewID->Equals(aViewID);
}
@@ -174,16 +188,17 @@ public:
void SetViewportSize(const svgFloatSize& aSize) {
mViewportWidth = aSize.width;
mViewportHeight = aSize.height;
}
private:
// SVGViewportElement methods:
+ virtual SVGViewElement* GetCurrentViewElement() const;
virtual SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const override;
// implementation helpers:
/*
* While binding to the tree we need to determine if we will be the outermost
* <svg> element _before_ the children are bound (as they want to know what
* timed document root to register with) and therefore _before_ our parent is
@@ -215,18 +230,23 @@ private:
const SVGPreserveAspectRatio* GetPreserveAspectRatioProperty() const;
bool ClearPreserveAspectRatioProperty();
virtual SVGPoint GetCurrentTranslate() const override
{ return mCurrentTranslate; }
virtual float GetCurrentScale() const override
{ return mCurrentScale; }
+ virtual const nsSVGViewBox& GetViewBoxInternal() const override;
+ virtual nsSVGAnimatedTransformList* GetTransformInternal() const override;
+
+
virtual EnumAttributesInfo GetEnumInfo() override;
+ enum { ZOOMANDPAN };
nsSVGEnum mEnumAttributes[1];
static nsSVGEnumMapping sZoomAndPanMap[];
static EnumInfo sEnumInfo[1];
// The time container for animations within this SVG document fragment. Set
// for all outermost <svg> elements (not nested <svg> elements).
nsAutoPtr<nsSMILTimeContainer> mTimedDocumentRoot;
@@ -240,16 +260,21 @@ private:
// For outermost <svg> elements created from parsing, animation is started by
// the onload event in accordance with the SVG spec, but for <svg> elements
// created by script or promoted from inner <svg> to outermost <svg> we need
// to manually kick off animation when they are bound to the tree.
bool mStartAnimationOnBindToTree;
bool mImageNeedsTransformInvalidation;
+
+ // mCurrentViewID and mSVGView are mutually exclusive; we can have
+ // at most one non-null.
+ nsAutoPtr<nsString> mCurrentViewID;
+ nsAutoPtr<SVGView> mSVGView;
};
} // namespace dom
class MOZ_RAII AutoSVGTimeSetRestore
{
public:
AutoSVGTimeSetRestore(dom::SVGSVGElement* aRootElem,
--- a/dom/svg/SVGViewportElement.cpp
+++ b/dom/svg/SVGViewportElement.cpp
@@ -40,24 +40,16 @@ namespace dom {
nsSVGElement::LengthInfo SVGViewportElement::sLengthInfo[4] =
{
{ &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X },
{ &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y },
{ &nsGkAtoms::width, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X },
{ &nsGkAtoms::height, 100, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y },
};
-SVGView::SVGView()
-{
- mZoomAndPan.Init(SVGViewportElement::ZOOMANDPAN,
- SVG_ZOOMANDPAN_MAGNIFY);
- mViewBox.Init();
- mPreserveAspectRatio.Init();
-}
-
//----------------------------------------------------------------------
// Implementation
SVGViewportElement::SVGViewportElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
: SVGGraphicsElement(aNodeInfo),
mViewportWidth(0),
mViewportHeight(0),
mHasChildrenOnlyTransform(false)
@@ -232,30 +224,21 @@ SVGViewportElement::GetViewBoxTransform(
GetPreserveAspectRatioWithOverride());
}
//----------------------------------------------------------------------
// SVGViewportElement
float
SVGViewportElement::GetLength(uint8_t aCtxType)
{
- float h, w;
-
- SVGViewElement* viewElement = GetCurrentViewElement();
- const nsSVGViewBoxRect* viewbox = nullptr;
+ const nsSVGViewBoxRect* viewbox =
+ GetViewBoxInternal().HasRect() ? &GetViewBoxInternal().GetAnimValue()
+ : nullptr;
- // The logic here should match HasViewBoxRect().
- if (viewElement && viewElement->mViewBox.HasRect()) {
- viewbox = &viewElement->mViewBox.GetAnimValue();
- } else if (mSVGView && mSVGView->mViewBox.HasRect()) {
- viewbox = &mSVGView->mViewBox.GetAnimValue();
- } else if (mViewBox.HasRect()) {
- viewbox = &mViewBox.GetAnimValue();
- }
-
+ float h, w;
if (viewbox) {
w = viewbox->width;
h = viewbox->height;
} else if (IsInner()) {
SVGViewportElement *ctx = GetCtx();
w = mLengthAttributes[ATTR_WIDTH].GetAnimValue(ctx);
h = mLengthAttributes[ATTR_HEIGHT].GetAnimValue(ctx);
} else if (ShouldSynthesizeViewBox()) {
@@ -289,19 +272,17 @@ SVGViewportElement::GetLength(uint8_t aC
SVGViewportElement::PrependLocalTransformsTo(const gfxMatrix& aMatrix,
SVGTransformTypes aWhich) const
{
// 'transform' attribute (or an override from a fragment identifier):
gfxMatrix userToParent;
if (aWhich == eUserSpaceToParent || aWhich == eAllTransforms) {
userToParent = GetUserToParentTransform(mAnimateMotionTransform,
- mSVGView && mSVGView->mTransforms
- ? mSVGView->mTransforms
- : mTransforms);
+ GetTransformInternal());
if (aWhich == eUserSpaceToParent) {
return userToParent * aMatrix;
}
}
gfxMatrix childToUser;
if (IsInner()) {
@@ -331,25 +312,16 @@ SVGViewportElement::PrependLocalTransfor
// transform between the two wouldn't make sense. We don't expect that to
// ever happen though. We get here either when the identity matrix has been
// passed because our caller just wants our eChildToUserSpace transform, or
// when our eUserSpaceToParent transform has already been multiplied into the
// matrix that our caller passes (such as when we're called from PaintSVG).
return childToUser * aMatrix;
}
-nsSVGAnimatedTransformList*
-SVGViewportElement::GetAnimatedTransformList(uint32_t aFlags)
-{
- if (!(aFlags & DO_ALLOCATE) && mSVGView && mSVGView->mTransforms) {
- return mSVGView->mTransforms;
- }
- return SVGGraphicsElement::GetAnimatedTransformList(aFlags);
-}
-
/* virtual */ bool
SVGViewportElement::HasValidDimensions() const
{
return !IsInner() ||
((!mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() ||
mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0) &&
(!mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() ||
mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0));
@@ -365,67 +337,32 @@ SVGViewportElement::GetViewBox()
SVGAnimatedPreserveAspectRatio *
SVGViewportElement::GetPreserveAspectRatio()
{
return &mPreserveAspectRatio;
}
bool
-SVGViewportElement::HasViewBoxRect() const
-{
- SVGViewElement* viewElement = GetCurrentViewElement();
- if ((viewElement && viewElement->mViewBox.HasRect()) ||
- (mSVGView && mSVGView->mViewBox.HasRect())) {
- return true;
- }
- return mViewBox.HasRect();
-}
-
-bool
SVGViewportElement::ShouldSynthesizeViewBox() const
{
MOZ_ASSERT(!HasViewBoxRect(), "Should only be called if we lack a viewBox");
return IsRoot() && OwnerDoc()->IsBeingUsedAsImage();
}
//----------------------------------------------------------------------
// implementation helpers
-SVGViewElement*
-SVGViewportElement::GetCurrentViewElement() const
-{
- if (mCurrentViewID) {
- //XXXsmaug It is unclear how this should work in case we're in Shadow DOM.
- nsIDocument* doc = GetUncomposedDoc();
- if (doc) {
- Element *element = doc->GetElementById(*mCurrentViewID);
- if (element && element->IsSVGElement(nsGkAtoms::view)) {
- return static_cast<SVGViewElement*>(element);
- }
- }
- }
- return nullptr;
-}
-
nsSVGViewBoxRect
SVGViewportElement::GetViewBoxWithSynthesis(
float aViewportWidth, float aViewportHeight) const
{
- // The logic here should match HasViewBoxRect().
- SVGViewElement* viewElement = GetCurrentViewElement();
- if (viewElement && viewElement->mViewBox.HasRect()) {
- return viewElement->mViewBox.GetAnimValue();
- }
- if (mSVGView && mSVGView->mViewBox.HasRect()) {
- return mSVGView->mViewBox.GetAnimValue();
- }
- if (mViewBox.HasRect()) {
- return mViewBox.GetAnimValue();
+ if (GetViewBoxInternal().HasRect()) {
+ return GetViewBoxInternal().GetAnimValue();
}
if (ShouldSynthesizeViewBox()) {
// Special case -- fake a viewBox, using height & width attrs.
// (Use |this| as context, since if we get here, we're outermost <svg>.)
return nsSVGViewBoxRect(0, 0,
ComputeSynthesizedViewBoxDimension(mLengthAttributes[ATTR_WIDTH],
mViewportWidth, this),
--- a/dom/svg/SVGViewportElement.h
+++ b/dom/svg/SVGViewportElement.h
@@ -41,50 +41,37 @@ public:
{}
bool operator!=(const svgFloatSize& rhs) {
return width != rhs.width || height != rhs.height;
}
float width;
float height;
};
-// Stores svgView arguments of SVG fragment identifiers.
-class SVGView {
-public:
- SVGView();
-
- nsSVGEnum mZoomAndPan;
- nsSVGViewBox mViewBox;
- SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
- nsAutoPtr<nsSVGAnimatedTransformList> mTransforms;
-};
-
class SVGViewportElement : public SVGGraphicsElement
{
friend class ::nsSVGOuterSVGFrame;
friend class ::nsSVGInnerSVGFrame;
- friend class mozilla::dom::SVGView;
protected:
SVGViewportElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
~SVGViewportElement();
public:
// nsIContent interface
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
virtual bool IsEventAttributeName(nsIAtom* aName) override;
// nsSVGElement specializations:
virtual gfxMatrix PrependLocalTransformsTo(
const gfxMatrix &aMatrix,
SVGTransformTypes aWhich = eAllTransforms) const override;
- virtual nsSVGAnimatedTransformList*
- GetAnimatedTransformList(uint32_t aFlags = 0) override;
+
virtual bool HasValidDimensions() const override;
// SVGViewportElement methods:
float GetLength(uint8_t mCtxType);
// public helpers:
/**
@@ -94,17 +81,19 @@ public:
* has a valid viewBox.
*
* Note that this does not check whether we need to synthesize a viewBox,
* so you must call ShouldSynthesizeViewBox() if you need to chck that too.
*
* Note also that this method does not pay attention to whether the width or
* height values of the viewBox rect are positive!
*/
- bool HasViewBoxRect() const;
+ bool HasViewBoxRect() const {
+ return GetViewBoxInternal().HasRect();
+ }
/**
* Returns true if we should synthesize a viewBox for ourselves (that is, if
* we're the root element in an image document, and we're not currently being
* painted for an <svg:image> element).
*
* Only call this method if HasViewBoxRect() returns false.
*/
@@ -160,18 +149,16 @@ protected:
* this is the root of a use-element shadow tree.
*/
bool IsInner() const {
const nsIContent *parent = GetFlattenedTreeParent();
return parent && parent->IsSVGElement() &&
!parent->IsSVGElement(nsGkAtoms::foreignObject);
}
- SVGViewElement* GetCurrentViewElement() const;
-
/**
* Returns the explicit or default preserveAspectRatio, unless we're
* synthesizing a viewBox, in which case it returns the "none" value.
*/
virtual SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const {
return mPreserveAspectRatio.GetAnimValue();
}
@@ -191,28 +178,25 @@ protected:
virtual float GetCurrentScale() const
{ return 1.0f; }
enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
nsSVGLength2 mLengthAttributes[4];
static LengthInfo sLengthInfo[4];
virtual LengthAttributesInfo GetLengthInfo() override;
- enum { ZOOMANDPAN };
-
virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() override;
+ virtual const nsSVGViewBox& GetViewBoxInternal() const { return mViewBox; }
+ virtual nsSVGAnimatedTransformList* GetTransformInternal() const {
+ return mTransforms;
+ }
nsSVGViewBox mViewBox;
SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
- // mCurrentViewID and mSVGView are mutually exclusive; we can have
- // at most one non-null.
- nsAutoPtr<nsString> mCurrentViewID;
- nsAutoPtr<SVGView> mSVGView;
-
// The size of the rectangular SVG viewport into which we render. This is
// not (necessarily) the same as the content area. See:
//
// http://www.w3.org/TR/SVG11/coords.html#ViewportSpace
//
// XXXjwatt Currently only used for outer <svg>, but maybe we could use -1 to
// flag this as an inner <svg> to save the overhead of GetCtx calls?
// XXXjwatt our frame should probably reset these when it's destroyed.