From 0ca279acd8e5b7bd7afdbadf658988bd959ee159 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 5 Jan 2009 14:13:56 +1300 Subject: [PATCH] Bug 471165. Make SVG animated class storage an nsAutoPtr and make the DOM 'className' object a tear-off. r=longsonr,sr=roc --HG-- extra : rebase_source : 8ba937100e482ea0dab88a310ad378afd76c8953 --- content/base/src/nsStyledElement.cpp | 4 - content/svg/content/src/Makefile.in | 1 - content/svg/content/src/nsSVGClassValue.cpp | 105 ---------------- content/svg/content/src/nsSVGClassValue.h | 69 ----------- .../svg/content/src/nsSVGStylableElement.cpp | 114 +++++++++++++----- .../svg/content/src/nsSVGStylableElement.h | 39 +++++- .../svg/content/test/test_valueLeaks.xhtml | 12 +- 7 files changed, 131 insertions(+), 213 deletions(-) delete mode 100644 content/svg/content/src/nsSVGClassValue.cpp delete mode 100644 content/svg/content/src/nsSVGClassValue.h diff --git a/content/base/src/nsStyledElement.cpp b/content/base/src/nsStyledElement.cpp index e3217b68113..1fe8fea92b6 100644 --- a/content/base/src/nsStyledElement.cpp +++ b/content/base/src/nsStyledElement.cpp @@ -89,10 +89,6 @@ nsStyledElement::ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute, } if (aAttribute == nsGkAtoms::_class) { SetFlags(NODE_MAY_HAVE_CLASS); -#ifdef MOZ_SVG - NS_ASSERTION(!nsCOMPtr(do_QueryInterface(this)), - "SVG code should have handled this 'class' attribute!"); -#endif aResult.ParseAtomArray(aValue); return PR_TRUE; } diff --git a/content/svg/content/src/Makefile.in b/content/svg/content/src/Makefile.in index cb7bafb361c..05538c66880 100644 --- a/content/svg/content/src/Makefile.in +++ b/content/svg/content/src/Makefile.in @@ -76,7 +76,6 @@ CPPSRCS = \ nsSVGAnimatedTransformList.cpp \ nsSVGBoolean.cpp \ nsSVGCircleElement.cpp \ - nsSVGClassValue.cpp \ nsSVGClipPathElement.cpp \ nsSVGDataParser.cpp \ nsSVGDefsElement.cpp \ diff --git a/content/svg/content/src/nsSVGClassValue.cpp b/content/svg/content/src/nsSVGClassValue.cpp deleted file mode 100644 index 6e5d26db62b..00000000000 --- a/content/svg/content/src/nsSVGClassValue.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mozilla SVG project. - * - * The Initial Developer of the Original Code is - * Crocodile Clips Ltd.. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Fritze (original author) - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsSVGClassValue.h" -#include "nsContentUtils.h" - -//////////////////////////////////////////////////////////////////////// -// nsSVGClassValue - -//---------------------------------------------------------------------- -// nsISupports methods: - -NS_IMPL_ADDREF(nsSVGClassValue) -NS_IMPL_RELEASE(nsSVGClassValue) - -NS_INTERFACE_MAP_BEGIN(nsSVGClassValue) - NS_INTERFACE_MAP_ENTRY(nsISVGValue) - NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedString) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISVGValue) - NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAnimatedString) -NS_INTERFACE_MAP_END - -//---------------------------------------------------------------------- -// nsISVGValue methods: - -NS_IMETHODIMP -nsSVGClassValue::SetValueString(const nsAString& aValue) -{ - WillModify(); - mBaseVal.ParseAtomArray(aValue); - DidModify(); - - return NS_OK; -} - -NS_IMETHODIMP -nsSVGClassValue::GetValueString(nsAString& aValue) -{ - mBaseVal.ToString(aValue); - - return NS_OK; -} - -//---------------------------------------------------------------------- -// nsIDOMSVGAnimatedString methods: - -/* attribute DOMString baseVal; */ -NS_IMETHODIMP -nsSVGClassValue::GetBaseVal(nsAString & aBaseVal) -{ - mBaseVal.ToString(aBaseVal); - - return NS_OK; -} -NS_IMETHODIMP -nsSVGClassValue::SetBaseVal(const nsAString & aBaseVal) -{ - SetValueString(aBaseVal); - - return NS_OK; -} - -/* readonly attribute DOMString animVal; */ -NS_IMETHODIMP -nsSVGClassValue::GetAnimVal(nsAString & aAnimVal) -{ - mBaseVal.ToString(aAnimVal); - - return NS_OK; -} diff --git a/content/svg/content/src/nsSVGClassValue.h b/content/svg/content/src/nsSVGClassValue.h deleted file mode 100644 index 55d3b6d0b50..00000000000 --- a/content/svg/content/src/nsSVGClassValue.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Mozilla SVG project. - * - * The Initial Developer of the Original Code is - * Crocodile Clips Ltd.. - * Portions created by the Initial Developer are Copyright (C) 2003 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Alex Fritze (original author) - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __NS_SVGCLASSVALUE_H__ -#define __NS_SVGCLASSVALUE_H__ - -#include "nsIDOMSVGAnimatedString.h" -#include "nsSVGValue.h" -#include "nsAttrValue.h" - -class nsSVGClassValue : public nsIDOMSVGAnimatedString, - public nsSVGValue -{ -public: - // nsISupports interface: - NS_DECL_ISUPPORTS - - // nsIDOMSVGAnimatedString interface: - NS_DECL_NSIDOMSVGANIMATEDSTRING - - // remainder of nsISVGValue interface: - NS_IMETHOD SetValueString(const nsAString& aValue); - NS_IMETHOD GetValueString(nsAString& aValue); - - const nsAttrValue* GetAttrValue() - { - return &mBaseVal; - } - -protected: - nsAttrValue mBaseVal; -}; - -#endif //__NS_SVGCLASSVALUE_H__ diff --git a/content/svg/content/src/nsSVGStylableElement.cpp b/content/svg/content/src/nsSVGStylableElement.cpp index 5f4a5af9305..9d741fafe25 100644 --- a/content/svg/content/src/nsSVGStylableElement.cpp +++ b/content/svg/content/src/nsSVGStylableElement.cpp @@ -37,16 +37,24 @@ * ***** END LICENSE BLOCK ***** */ #include "nsSVGStylableElement.h" -#include "nsICSSOMFactory.h" #include "nsGkAtoms.h" #include "nsDOMCSSDeclaration.h" -#include "nsIDOMClassInfo.h" - -static NS_DEFINE_CID(kCSSOMFactoryCID, NS_CSSOMFACTORY_CID); +#include "nsContentUtils.h" //---------------------------------------------------------------------- // nsISupports methods +NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGStylableElement::DOMAnimatedClassString, mSVGElement) + +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGStylableElement::DOMAnimatedClassString) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGStylableElement::DOMAnimatedClassString) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGStylableElement::DOMAnimatedClassString) + NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedString) + NS_INTERFACE_MAP_ENTRY(nsISupports) + NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGAnimatedString) +NS_INTERFACE_MAP_END + NS_IMPL_ADDREF_INHERITED(nsSVGStylableElement, nsSVGStylableElementBase) NS_IMPL_RELEASE_INHERITED(nsSVGStylableElement, nsSVGStylableElementBase) @@ -60,29 +68,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsSVGStylableElementBase) nsSVGStylableElement::nsSVGStylableElement(nsINodeInfo *aNodeInfo) : nsSVGStylableElementBase(aNodeInfo) { - // We never know when we might have a class - SetFlags(NODE_MAY_HAVE_CLASS); -} - -nsresult -nsSVGStylableElement::Init() -{ - nsresult rv = nsSVGStylableElementBase::Init(); - NS_ENSURE_SUCCESS(rv, rv); - - // Create mapped properties: - - // DOM property: className, #IMPLIED attrib: class - { - mClassName = new nsSVGClassValue; - NS_ENSURE_TRUE(mClassName, NS_ERROR_OUT_OF_MEMORY); - rv = AddMappedSVGValue(nsGkAtoms::_class, - static_cast(mClassName), - kNameSpaceID_None); - NS_ENSURE_SUCCESS(rv, rv); - } - - return rv; } //---------------------------------------------------------------------- @@ -91,7 +76,7 @@ nsSVGStylableElement::Init() const nsAttrValue* nsSVGStylableElement::DoGetClasses() const { - return mClassName->GetAttrValue(); + return GetClassAnimAttr(); } //---------------------------------------------------------------------- @@ -101,8 +86,10 @@ nsSVGStylableElement::DoGetClasses() const NS_IMETHODIMP nsSVGStylableElement::GetClassName(nsIDOMSVGAnimatedString** aClassName) { - NS_ADDREF(*aClassName = mClassName); + *aClassName = new DOMAnimatedClassString(this); + NS_ENSURE_TRUE(*aClassName, NS_ERROR_OUT_OF_MEMORY); + NS_ADDREF(*aClassName); return NS_OK; } @@ -116,7 +103,7 @@ nsSVGStylableElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle) /* nsIDOMCSSValue getPresentationAttribute (in DOMString name); */ NS_IMETHODIMP nsSVGStylableElement::GetPresentationAttribute(const nsAString& aName, - nsIDOMCSSValue** aReturn) + nsIDOMCSSValue** aReturn) { // Let's not implement this just yet. The CSSValue interface has been // deprecated by the CSS WG. @@ -124,3 +111,70 @@ nsSVGStylableElement::GetPresentationAttribute(const nsAString& aName, return NS_ERROR_NOT_IMPLEMENTED; } + +//---------------------------------------------------------------------- +// nsSVGElement methods + +PRBool +nsSVGStylableElement::ParseAttribute(PRInt32 aNamespaceID, + nsIAtom* aAttribute, + const nsAString& aValue, + nsAttrValue& aResult) +{ + if (aNamespaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::_class) { + mClassAnimAttr = nsnull; + // let the rest be handled in nsStyledElement + } + + return nsSVGStylableElementBase::ParseAttribute(aNamespaceID, aAttribute, + aValue, aResult); +} + +nsresult +nsSVGStylableElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName, + PRBool aNotify) +{ + if (aNamespaceID == kNameSpaceID_None && aName == nsGkAtoms::_class) { + mClassAnimAttr = nsnull; + } + + return nsSVGStylableElementBase::UnsetAttr(aNamespaceID, aName, aNotify); +} + +//---------------------------------------------------------------------- +// Methods for managing the class attribute + +const nsAttrValue* +nsSVGStylableElement::GetClassAnimAttr() const +{ + if (mClassAnimAttr) + return mClassAnimAttr; + + return mAttrsAndChildren.GetAttr(nsGkAtoms::_class, kNameSpaceID_None); +} + +void +nsSVGStylableElement::GetClassBaseValString(nsAString& aResult) const +{ + GetAttr(kNameSpaceID_None, nsGkAtoms::_class, aResult); +} + +void +nsSVGStylableElement::SetClassBaseValString(const nsAString& aValue) +{ + mClassAnimAttr = nsnull; + SetAttr(kNameSpaceID_None, nsGkAtoms::_class, aValue, PR_TRUE); +} + +void +nsSVGStylableElement::GetClassAnimValString(nsAString& aResult) const +{ + const nsAttrValue* attr = GetClassAnimAttr(); + + if (!attr) { + aResult.Truncate(); + return; + } + + attr->ToString(aResult); +} diff --git a/content/svg/content/src/nsSVGStylableElement.h b/content/svg/content/src/nsSVGStylableElement.h index cc82f5f87b5..6bcdda0d163 100644 --- a/content/svg/content/src/nsSVGStylableElement.h +++ b/content/svg/content/src/nsSVGStylableElement.h @@ -43,7 +43,6 @@ #include "nsIDOMSVGStylable.h" #include "nsIDOMSVGAnimatedString.h" #include "nsAutoPtr.h" -#include "nsSVGClassValue.h" typedef nsSVGElement nsSVGStylableElementBase; @@ -52,7 +51,6 @@ class nsSVGStylableElement : public nsSVGStylableElementBase, { protected: nsSVGStylableElement(nsINodeInfo *aNodeInfo); - nsresult Init(); public: // interfaces: @@ -62,8 +60,43 @@ public: // nsIContent virtual const nsAttrValue* DoGetClasses() const; + // nsSVGElement + virtual nsresult UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aAttribute, + PRBool aNotify); + protected: - nsRefPtr mClassName; + + // nsSVGElement + virtual PRBool ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aName, + const nsAString& aValue, + nsAttrValue& aResult); + +private: + nsAutoPtr mClassAnimAttr; + + const nsAttrValue* GetClassAnimAttr() const; + + void GetClassBaseValString(nsAString &aResult) const; + void SetClassBaseValString(const nsAString& aValue); + void GetClassAnimValString(nsAString& aResult) const; + + struct DOMAnimatedClassString : public nsIDOMSVGAnimatedString + { + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS(DOMAnimatedClassString) + + DOMAnimatedClassString(nsSVGStylableElement *aSVGElement) + : mSVGElement(aSVGElement) {} + + nsRefPtr mSVGElement; + + NS_IMETHOD GetBaseVal(nsAString& aResult) + { mSVGElement->GetClassBaseValString(aResult); return NS_OK; } + NS_IMETHOD SetBaseVal(const nsAString& aValue) + { mSVGElement->SetClassBaseValString(aValue); return NS_OK; } + NS_IMETHOD GetAnimVal(nsAString& aResult) + { mSVGElement->GetClassAnimValString(aResult); return NS_OK; } + }; }; diff --git a/content/svg/content/test/test_valueLeaks.xhtml b/content/svg/content/test/test_valueLeaks.xhtml index eeca6001068..eb3c763d945 100644 --- a/content/svg/content/test/test_valueLeaks.xhtml +++ b/content/svg/content/test/test_valueLeaks.xhtml @@ -28,15 +28,25 @@ function storeSVGPropertyAsExpando(localName, prop) var propVal = elem[prop]; Object.prototype.toSource[prop + "_expando"] = propVal; - if (propVal instanceof SVGAnimatedAngle || propVal instanceof SVGAnimatedLength) { + if (propVal instanceof SVGAnimatedAngle || propVal instanceof SVGAnimatedLength || + propVal instanceof SVGAnimatedRect || propVal instanceof SVGAnimatedPreserveAspectRatio) { Object.prototype.toSource[prop + "_baseVal_expando"] = propVal.baseVal; Object.prototype.toSource[prop + "_animVal_expando"] = propVal.animVal; } } +// class +storeSVGPropertyAsExpando("marker", "class"); + // angle storeSVGPropertyAsExpando("marker", "orientAngle"); +// viewBox +storeSVGPropertyAsExpando("marker", "viewBox"); + +// preserveAspectRatio +storeSVGPropertyAsExpando("marker", "preserveAspectRatio"); + // boolean storeSVGPropertyAsExpando("feConvolveMatrix", "preserveAlpha");