+2007-10-10 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ Test for:
+ http://bugs.webkit.org/show_bug.cgi?id=14150
+
+ * svg/dom/animated-tearoff-equality-expected.txt: Added.
+ * svg/dom/animated-tearoff-equality.xhtml: Added.
+ * svg/dom/animated-tearoff-lifespan-expected.txt: Added.
+ * svg/dom/animated-tearoff-lifespan.xhtml: Added.
+
2007-10-10 Oliver Hunt <oliver@apple.com>
RS = Eric
* svg/batik/text/textOnPathSpaces-expected.txt:
+
2007-10-10 Eric Seidel <eric@webkit.org>
Reviewed by Oliver.
--- /dev/null
+x1: [object SVGAnimatedLength]
+x2: [object SVGAnimatedLength]
+x1.baseVal : [object SVGLength]
+x2.baseVal : [object SVGLength]
+x1.baseVal.value : 0
+x2.baseVal.value : 0
+x1 == x2: true
+x1 === x2: true
+x1.baseVal == x2.baseVal: true
+x1.baseVal === x2.baseVal: true
+x1: [object SVGAnimatedLength]
+x2: [object SVGAnimatedLength]
+x1.baseVal : [object SVGLength]
+x2.baseVal : [object SVGLength]
+x1.baseVal.value : 100
+x2.baseVal.value : 100
+x1 == x2: true
+x1 === x2: true
+x1.baseVal == x2.baseVal: true
+x1.baseVal === x2.baseVal: true
+
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
+xmlns="http://www.w3.org/1999/xhtml"
+xmlns:xlink="http://www.w3.org/1999/xlink"
+>
+<body>
+ <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
+ <rect width="100" height="100" fill="blue" />
+ <rect id="rect" width="100" height="100" fill="red" />
+ </svg>
+
+<div id="log"></div>
+<script type="text/javascript"><![CDATA[
+
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+ function debugLog(s) {
+ var logDiv = document.getElementById("log");
+ logDiv.appendChild(document.createTextNode(s));
+ logDiv.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "br"));
+ }
+
+ var rect = document.getElementById("rect");
+ var x1 = rect.x;
+ var x2 = rect.x;
+
+ debugLog("x1: " + x1);
+ debugLog("x2: " + x2);
+ debugLog("x1.baseVal : " + x1.baseVal);
+ debugLog("x2.baseVal : " + x2.baseVal);
+ debugLog("x1.baseVal.value : " + x1.baseVal.value);
+ debugLog("x2.baseVal.value : " + x2.baseVal.value);
+ debugLog("x1 == x2: " + (x1 == x2));
+ debugLog("x1 === x2: " + (x1 === x2));
+ debugLog("x1.baseVal == x2.baseVal: " + (x1.baseVal == x2.baseVal));
+ debugLog("x1.baseVal === x2.baseVal: " + (x1.baseVal === x2.baseVal));
+
+ x1.baseVal.value = 100;
+
+ debugLog("x1: " + x1);
+ debugLog("x2: " + x2);
+ debugLog("x1.baseVal : " + x1.baseVal);
+ debugLog("x2.baseVal : " + x2.baseVal);
+ debugLog("x1.baseVal.value : " + x1.baseVal.value);
+ debugLog("x2.baseVal.value : " + x2.baseVal.value);
+ debugLog("x1 == x2: " + (x1 == x2));
+ debugLog("x1 === x2: " + (x1 === x2));
+ debugLog("x1.baseVal == x2.baseVal: " + (x1.baseVal == x2.baseVal));
+ debugLog("x1.baseVal === x2.baseVal: " + (x1.baseVal === x2.baseVal));
+
+]]></script>
+</body>
+</html>
--- /dev/null
+x1: [object SVGAnimatedLength]
+x2: [object SVGAnimatedLength]
+x1.baseVal : [object SVGLength]
+x2.baseVal : [object SVGLength]
+x1.baseVal.value : 10
+x2.baseVal.value : 10
+x1 == x2: true
+x1 === x2: true
+x1.baseVal == x2.baseVal: true
+x1.baseVal === x2.baseVal: true
+removing rect from document
+x1: [object SVGAnimatedLength]
+x2: [object SVGAnimatedLength]
+x1.baseVal : [object SVGLength]
+x2.baseVal : [object SVGLength]
+x1.baseVal.value : 10
+x2.baseVal.value : 10
+x1 == x2: true
+x1 === x2: true
+x1.baseVal == x2.baseVal: true
+x1.baseVal === x2.baseVal: true
+modifying, x1.baseVal = 100
+x1: [object SVGAnimatedLength]
+x2: [object SVGAnimatedLength]
+x1.baseVal : [object SVGLength]
+x2.baseVal : [object SVGLength]
+x1.baseVal.value : 100
+x2.baseVal.value : 100
+x1 == x2: true
+x1 === x2: true
+x1.baseVal == x2.baseVal: true
+x1.baseVal === x2.baseVal: true
+
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html
+xmlns="http://www.w3.org/1999/xhtml"
+xmlns:xlink="http://www.w3.org/1999/xlink"
+>
+<body>
+ <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
+ <rect width="100" height="100" fill="blue" />
+ <rect id="rect" x="10" y="10" width="100" height="100" fill="red" />
+ </svg>
+
+<div id="log"></div>
+<script type="text/javascript"><![CDATA[
+
+ if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+ function debugLog(s) {
+ var logDiv = document.getElementById("log");
+ logDiv.appendChild(document.createTextNode(s));
+ logDiv.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "br"));
+ }
+
+ var x1;
+ var x2;
+
+ {
+ var rect = document.getElementById("rect");
+ x1 = rect.x;
+ x2 = rect.x;
+ debugLog("x1: " + x1);
+ debugLog("x2: " + x2);
+ debugLog("x1.baseVal : " + x1.baseVal);
+ debugLog("x2.baseVal : " + x2.baseVal);
+ debugLog("x1.baseVal.value : " + x1.baseVal.value);
+ debugLog("x2.baseVal.value : " + x2.baseVal.value);
+ debugLog("x1 == x2: " + (x1 == x2));
+ debugLog("x1 === x2: " + (x1 === x2));
+ debugLog("x1.baseVal == x2.baseVal: " + (x1.baseVal == x2.baseVal));
+ debugLog("x1.baseVal === x2.baseVal: " + (x1.baseVal === x2.baseVal));
+
+ debugLog("removing rect from document");
+ rect.parentNode.removeChild(rect);
+ }
+
+ debugLog("x1: " + x1);
+ debugLog("x2: " + x2);
+ debugLog("x1.baseVal : " + x1.baseVal);
+ debugLog("x2.baseVal : " + x2.baseVal);
+ debugLog("x1.baseVal.value : " + x1.baseVal.value);
+ debugLog("x2.baseVal.value : " + x2.baseVal.value);
+ debugLog("x1 == x2: " + (x1 == x2));
+ debugLog("x1 === x2: " + (x1 === x2));
+ debugLog("x1.baseVal == x2.baseVal: " + (x1.baseVal == x2.baseVal));
+ debugLog("x1.baseVal === x2.baseVal: " + (x1.baseVal === x2.baseVal));
+
+ debugLog("modifying, x1.baseVal = 100");
+ try {
+ x1.baseVal.value = 100;
+ } catch(e) {
+ debugLog("x1.baseVal = 100 threw exception: " + e);
+ }
+
+ debugLog("x1: " + x1);
+ debugLog("x2: " + x2);
+ debugLog("x1.baseVal : " + x1.baseVal);
+ debugLog("x2.baseVal : " + x2.baseVal);
+ debugLog("x1.baseVal.value : " + x1.baseVal.value);
+ debugLog("x2.baseVal.value : " + x2.baseVal.value);
+ debugLog("x1 == x2: " + (x1 == x2));
+ debugLog("x1 === x2: " + (x1 === x2));
+ debugLog("x1.baseVal == x2.baseVal: " + (x1.baseVal == x2.baseVal));
+ debugLog("x1.baseVal === x2.baseVal: " + (x1.baseVal === x2.baseVal));
+
+]]></script>
+</body>
+</html>
+2007-10-10 Eric Seidel <eric@webkit.org>
+
+ Reviewed by Nikolas Zimmermann.
+
+ Fix the SVG dom so that rect.x.baseVal = rect.x.baseVal like it should.
+ http://bugs.webkit.org/show_bug.cgi?id=14150
+
+ Test: svg/dom/animated-tearoff-equlity.xhtml
+
+ * ksvg2/svg/SVGAnimatedTemplate.h:
+ (WebCore::SVGAnimatedTypeWrapperKey::SVGAnimatedTypeWrapperKey):
+ (WebCore::SVGAnimatedTypeWrapperKey::operator==):
+ (WebCore::SVGAnimatedTypeWrapperKeyHash::hash):
+ (WebCore::SVGAnimatedTypeWrapperKeyHash::equal):
+ (WebCore::SVGAnimatedTypeWrapperKeyHashTraits::deletedValue):
+ (WebCore::SVGAnimatedTypeWrapperKeyHashTraits::emptyValue):
+ (WebCore::SVGAnimatedTemplate::~SVGAnimatedTemplate):
+ (WebCore::SVGAnimatedTemplate::wrapperCache):
+ (WebCore::SVGAnimatedTemplate::forgetWrapper):
+ (WebCore::lookupOrCreateWrapper):
+ * ksvg2/svg/SVGElement.h:
+
2007-10-10 Oliver Hunt <oliver@apple.com>
Reviewed by Maciej.
* ksvg2/svg/SVGDocument.idl:
-
-
2007-10-10 Eric Seidel <eric@webkit.org>
Reviewed by Oliver.
#if ENABLE(SVG)
#include "Shared.h"
+#include "AtomicString.h"
namespace WebCore {
class SVGAngle;
+ class SVGElement;
class SVGLength;
class SVGLengthList;
class SVGNumberList;
class String;
class FloatRect;
+ struct SVGAnimatedTypeWrapperKey {
+ // Empty value
+ SVGAnimatedTypeWrapperKey()
+ : element(0)
+ , attributeName(0)
+ { }
+
+ // Deleted value
+ explicit SVGAnimatedTypeWrapperKey(bool)
+ : element(reinterpret_cast<SVGElement*>(-1))
+ , attributeName(0)
+ { }
+
+ SVGAnimatedTypeWrapperKey(const SVGElement* _element, const AtomicString& _attributeName)
+ : element(_element)
+ , attributeName(_attributeName.impl())
+ {
+ ASSERT(element);
+ ASSERT(attributeName);
+ }
+
+ bool operator==(const SVGAnimatedTypeWrapperKey& other) const
+ {
+ return element == other.element && attributeName == other.attributeName;
+ }
+
+ const SVGElement* element;
+ AtomicStringImpl* attributeName;
+ };
+
+ struct SVGAnimatedTypeWrapperKeyHash {
+ static unsigned hash(const SVGAnimatedTypeWrapperKey& key)
+ {
+ return StringImpl::computeHash((::UChar*) &key, sizeof(SVGAnimatedTypeWrapperKey) / sizeof(::UChar));
+ }
+
+ static bool equal(const SVGAnimatedTypeWrapperKey& a, const SVGAnimatedTypeWrapperKey& b)
+ {
+ return a == b;
+ }
+ };
+
+ struct SVGAnimatedTypeWrapperKeyHashTraits : WTF::GenericHashTraits<SVGAnimatedTypeWrapperKey> {
+ static const bool emptyValueIsZero = true;
+ static const bool needsDestruction = false;
+
+ static const SVGAnimatedTypeWrapperKey& deletedValue()
+ {
+ static SVGAnimatedTypeWrapperKey deletedKey(true);
+ return deletedKey;
+ }
+
+ static const SVGAnimatedTypeWrapperKey& emptyValue()
+ {
+ static SVGAnimatedTypeWrapperKey emptyKey;
+ return emptyKey;
+ }
+ };
+
template<typename BareType>
class SVGAnimatedTemplate : public Shared<SVGAnimatedTemplate<BareType> >
{
- public:
- virtual ~SVGAnimatedTemplate() { }
+ public:
+ virtual ~SVGAnimatedTemplate() { forgetWrapper(this); }
virtual BareType baseVal() const = 0;
virtual void setBaseVal(BareType newBaseVal) = 0;
virtual BareType animVal() const = 0;
virtual void setAnimVal(BareType newAnimVal) = 0;
+
+ typedef HashMap<SVGAnimatedTypeWrapperKey, SVGAnimatedTemplate<BareType>*, SVGAnimatedTypeWrapperKeyHash, SVGAnimatedTypeWrapperKeyHashTraits > ElementToWrapperMap;
+ typedef typename ElementToWrapperMap::const_iterator ElementToWrapperMapIterator;
+
+ static ElementToWrapperMap* wrapperCache() {
+ static ElementToWrapperMap* sWrapperCache = new ElementToWrapperMap;
+ return sWrapperCache;
+ }
+
+ static void forgetWrapper(SVGAnimatedTemplate<BareType>* wrapper)
+ {
+ ElementToWrapperMap* cache = wrapperCache();
+ ElementToWrapperMapIterator itr = cache->begin();
+ ElementToWrapperMapIterator end = cache->end();
+ for (; itr != end; ++itr) {
+ if (itr->second == wrapper) {
+ cache->remove(itr->first);
+ break;
+ }
+ }
+ }
};
+
+ template <class Type, class SVGElementSubClass>
+ Type* lookupOrCreateWrapper(const SVGElementSubClass* element, const AtomicString& attrName) {
+ SVGAnimatedTypeWrapperKey key(element, attrName);
+ Type* wrapper = static_cast<Type*>(Type::wrapperCache()->get(key));
+ if (!wrapper) {
+ wrapper = new Type(element);
+ Type::wrapperCache()->set(key, wrapper);
+ }
+ return wrapper;
+ }
// Common type definitions, to ease IDL generation...
typedef SVGAnimatedTemplate<SVGAngle*> SVGAnimatedAngle;
typedef SVGAnimatedTemplate<SVGPreserveAspectRatio*> SVGAnimatedPreserveAspectRatio;
typedef SVGAnimatedTemplate<FloatRect> SVGAnimatedRect;
typedef SVGAnimatedTemplate<String> SVGAnimatedString;
- typedef SVGAnimatedTemplate<SVGTransformList*> SVGAnimatedTransformList;
+ typedef SVGAnimatedTemplate<SVGTransformList*> SVGAnimatedTransformList;
}
#endif // ENABLE(SVG)
virtual void setBaseVal(BareType newBaseVal); \
virtual BareType animVal() const; \
virtual void setAnimVal(BareType newAnimVal); \
-\
+ \
protected: \
ClassStorageType m_element; \
}; \
{ \
const SVGElement* context = contextElement(); \
ASSERT(context); \
- return new ClassName::SVGAnimatedTemplate##UpperProperty(context); \
+ return lookupOrCreateWrapper<ClassName::SVGAnimatedTemplate##UpperProperty, SVGElement>(context, AttrName); \
}
#define ANIMATED_PROPERTY_DEFINITIONS(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter) \
ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter, this) \
PassRefPtr<ClassName::SVGAnimatedTemplate##UpperProperty> ClassName::LowerProperty##Animated() const \
{ \
- return new ClassName::SVGAnimatedTemplate##UpperProperty(this); \
+ return lookupOrCreateWrapper<ClassName::SVGAnimatedTemplate##UpperProperty, ClassName>(this, AttrName); \
}
namespace WebCore {