(1) I was trying to use like something the following ECMAScript, but I noticed some strange behavior:
========= START CODE ========= <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" id="testSVG"> <script type="text/ecmascript"><![CDATA[ function TestObj() { this.root = document.documentElement; this.abc = 123; this.myFunc = function() { alert(this.abc); } this.root.addEventListener("click", this.myFunc, false); } var obj = new TestObj(); ]]></script> <rect width="100%" height="100%" fill="green"/> <rect x="45%" y="45%" width="10%" height="10%" > </svg> ========= END CODE =========
When addEventListener() is explicitly called to add the TestObj.myFunc method as an event listener, and myFunc gets called as the result of an event, the "instance variable" this.abc is undefined. However, if I add the same function as a listener via an onmouseover attribute, that instance variable is properly defined. This is true with Batik and Adobe's viewer as well.
To see the undefined variable behavior, click anywhere in the SVG window. To see the "proper" behavior, mouse over the black rectangle.
It seems to me the click behavior should be the same as the mouseover behavior.
(2) Also, in looking at the source for addEventListener() in org.apache.batik.dom.events.EventSupport, I noticed a bug due to a possible race condition. I'm not sure if the bug is related to the above-described behavior, but I kind of doubt it. Anyway, the bug is that the method starts out as follows:
========= START CODE ========= public void addEventListener(String type, EventListener listener, boolean useCapture) { HashTable listeners; if (useCapture) { if (capturingListeners == null) { capturingListeners = new HashTable(); } listeners = capturingListeners; } else { if (bubblingListeners == null) { bubblingListeners = new HashTable(); } listeners = bubblingListeners; } . . . ========= END CODE =========
You'll notice that nothing is synchronized, so if multiple threads call addEventListener() at around the same time, it is possible for the capturingListeners and/or bubblingListeners objects to be created multiple times. If that happens, the initially created Hashtable objects are simply thrown away, and any listeners they might have contained are forgotten. It seems the code should at least have a "synchronize(this)" block around the if/else statement.
|
Title: Message