[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9

zimmermann at webkit.org zimmermann at webkit.org
Thu Feb 4 21:22:03 UTC 2010


The following commit has been merged in the webkit-1.1 branch:
commit f9178b1fd1d31de6e3ab9afd9202eee2f520e5e2
Author: zimmermann at webkit.org <zimmermann at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jan 20 22:01:05 2010 +0000

    2010-01-19  Nikolas Zimmermann  <nzimmermann at rim.com>
    
            Reviewed by Alexey Proskuryakov.
    
            svg/custom/use-instanceRoot-event-bubbling.xhtml is flakey
            https://bugs.webkit.org/show_bug.cgi?id=33835
    
            mouseEvent fires mutiple times in svg/custom/use-instanceRoot-as-event-target.xhtml
            https://bugs.webkit.org/show_bug.cgi?id=32519
    
            Test: svg/custom/use-instanceRoot-event-listener-liveness.xhtml
    
            Stabilize <use> scripting support - use tests are reliable now (tested using --repeach-each 50 --random -p)
    
            Do not reclone trees anymore because of event listener changes, instead keep correspondingElement & shadowTreeElement
            synchronized for each SVGElementInstance - any mutations on any event listeners are live, and take immediate effect,
            w/o having to rely on a reclone - this was the root of several race conditions making the <use> tests flakey.
    
            Fix SVGUseElement::instanceRoot() to force shadow tree creation, even if it was not attached so far - we can't wait
            for finishedParsing() to be called which would recalculate the document style and attach the shadow tree as result.
            This is now matching Operas behaviour.
    
            Optimize createAttributeEventListener() to not create event listeners if the supplied Attribute isNull() - otherwhise
            DOM calls like removeAttribute("onclick") cause a temporary JSEventListener to be created, added to the event listener
            cache and removed afterwards.
    
            * bindings/js/ScriptEventListener.cpp:
            (WebCore::createAttributeEventListener): Return early if the supplied attribute is null as discussed with Geoffrey.
            * bindings/v8/ScriptEventListener.cpp:
            (WebCore::createAttributeEventListener): Ditto.
            * dom/Node.cpp: Synchronize event listeners with all element instances, instead of marking the use elements to reclone.
            (WebCore::instancesForSVGElement):
            (WebCore::tryAddEventListener):
            (WebCore::Node::addEventListener): When adding a listener, get a list of element instances and add it their as well.
            (WebCore::tryRemoveEventListener):
            (WebCore::Node::removeEventListener): Ditto for removals, but with special logic for listeners created from markup (see comments)
            * svg/SVGElementInstance.cpp: Cleaned up, removing unncessary checks of correspondingElement() - there is an ASSERT in the ctor.
            (WebCore::SVGElementInstance::invalidateAllInstancesOfElement):
            (WebCore::SVGElementInstance::scriptExecutionContext):
            (WebCore::SVGElementInstance::addEventListener):
            (WebCore::SVGElementInstance::removeEventListener):
            (WebCore::SVGElementInstance::removeAllEventListeners):
            (WebCore::SVGElementInstance::eventTargetData):
            (WebCore::SVGElementInstance::ensureEventTargetData):
            * svg/SVGUseElement.cpp: Call document()->updateLayoutIgnorePendingStylesheets() to force shadow tree creation, just like CSSStyleDecl works.
            (WebCore::SVGUseElement::instanceRoot):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53564 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 3bf6150..24577be 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,28 @@
+2010-01-19  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Alexey Proskuryakov. 
+
+        svg/custom/use-instanceRoot-event-bubbling.xhtml is flakey
+        https://bugs.webkit.org/show_bug.cgi?id=33835
+
+        mouseEvent fires mutiple times in svg/custom/use-instanceRoot-as-event-target.xhtml
+        https://bugs.webkit.org/show_bug.cgi?id=32519
+
+        Stabilize <use> scripting support - use tests are reliable now (tested using --repeach-each 50 --random -p)
+        Reenable the tests in question on gtk / qt / win. mac was only affected from time to time (always reproducable using --repeat-each 50 though.)
+
+        * platform/gtk/Skipped: Unskip use-instanceRoot-event-listeners.xhtml / use-instanceRoot-event-bubbling.xhtml / use-instanceRoot-as-event-target.xhtml
+        * platform/qt/Skipped: Unskip use-instanceRoot-as-event-target.xhtml
+        * platform/win/Skipped: Ditto.
+        * svg/custom/resources/use-instanceRoot-event-bubbling.js:
+        (eventHandler): No need anymore to rely on a 100ms timeout.
+        * svg/custom/resources/use-instanceRoot-event-listeners.js:
+        (eventHandler): Ditto.
+        * svg/custom/use-instanceRoot-as-event-target-expected.txt:
+        * svg/custom/use-instanceRoot-as-event-target.xhtml: Rewrote test - we don't need to work around shadow tree reclone issues anymore.
+        * svg/custom/use-instanceRoot-event-listener-liveness-expected.txt: Added.
+        * svg/custom/use-instanceRoot-event-listener-liveness.xhtml: Added.
+
 2010-01-20  David Levin  <levin at chromium.org>
 
         No review, rolling out r53552.
diff --git a/LayoutTests/platform/gtk/Skipped b/LayoutTests/platform/gtk/Skipped
index 6c03a6b..ac8248b 100644
--- a/LayoutTests/platform/gtk/Skipped
+++ b/LayoutTests/platform/gtk/Skipped
@@ -3699,7 +3699,6 @@ svg/custom/svg-disallowed-in-dashboard-object.html
 svg/custom/svg-fonts-in-text-controls.html
 svg/custom/use-elementInstance-event-target.svg
 svg/custom/use-elementInstance-methods.svg
-svg/custom/use-instanceRoot-event-listeners.xhtml
 svg/custom/use-on-symbol-inside-pattern.svg
 svg/custom/use-setAttribute-crash.svg
 #   Tests generating new results
@@ -5717,11 +5716,6 @@ fast/events/touch
 # See https://bugs.webkit.org/show_bug.cgi?id=32441
 fast/parser/xhtml-close-while-parsing.xhtml
 
-# Bug 32519 -  mouseEvent fires mutiple times in
-#              LayoutTests/svg/custom/use-instanceRoot-as-event-target.xhtml
-# https://bugs.webkit.org/show_bug.cgi?id=32519
-svg/custom/use-instanceRoot-as-event-target.xhtml
-
 # https://bugs.webkit.org/show_bug.cgi?id=32604
 # Fails on the release bot because of, apparently, rouding errors
 svg/custom/path-getTotalLength.svg
@@ -5778,8 +5772,3 @@ svg/custom/relative-sized-deep-shadow-tree-content.xhtml
 svg/custom/relative-sized-shadow-tree-content.xhtml
 svg/custom/text-xy-updates-SVGList.xhtml
 svg/text/selection-background-color.xhtml
-
-# Flakey SVG test, uses 'setTimeout(100)'
-# https://bugs.webkit.org/show_bug.cgi?id=33835
-svg/custom/use-instanceRoot-event-bubbling.xhtml
-
diff --git a/LayoutTests/platform/qt/Skipped b/LayoutTests/platform/qt/Skipped
index 985601d..ffc59de 100644
--- a/LayoutTests/platform/qt/Skipped
+++ b/LayoutTests/platform/qt/Skipped
@@ -5072,11 +5072,6 @@ http/tests/navigation/parsed-iframe-dynamic-form-back-entry.html
 # The bug with this test is tracked under https://bugs.webkit.org/show_bug.cgi?id=32521
 http/tests/xmlhttprequest/access-control-basic-denied-preflight-cache.html
 
-# Bug 32519 -  mouseEvent fires mutiple times in 
-#              LayoutTests/svg/custom/use-instanceRoot-as-event-target.xhtml
-# https://bugs.webkit.org/show_bug.cgi?id=32519
-svg/custom/use-instanceRoot-as-event-target.xhtml
-
 # Missing variables:
 # SVGAltGlyphElement, SVGAnimateElement, SVGAnimateColorElement, SVGAnimateTransformElement
 # SVGFontElement, SVGGlyphElement, SVGMissingGlyphElement, SVGFontFaceElement, SVGFontFaceSrcElement
diff --git a/LayoutTests/platform/win/Skipped b/LayoutTests/platform/win/Skipped
index 9c7c186..9637806 100644
--- a/LayoutTests/platform/win/Skipped
+++ b/LayoutTests/platform/win/Skipped
@@ -721,11 +721,6 @@ fast/events/touch
 http/tests/security/xss-DENIED-getSVGDocument-iframe.html
 http/tests/security/xss-DENIED-getSVGDocument-object.html
 
-# Bug 32519 -  mouseEvent fires mutiple times in
-#              LayoutTests/svg/custom/use-instanceRoot-as-event-target.xhtml
-# https://bugs.webkit.org/show_bug.cgi?id=32519
-svg/custom/use-instanceRoot-as-event-target.xhtml
-
 # http://webkit.org/b/32532 - Time out
 http/tests/navigation/dynamic-iframe-dynamic-form-back-entry.html
 http/tests/navigation/parsed-iframe-dynamic-form-back-entry.html
diff --git a/LayoutTests/svg/custom/resources/use-instanceRoot-event-bubbling.js b/LayoutTests/svg/custom/resources/use-instanceRoot-event-bubbling.js
index c992ef6..9dfeb7d 100644
--- a/LayoutTests/svg/custom/resources/use-instanceRoot-event-bubbling.js
+++ b/LayoutTests/svg/custom/resources/use-instanceRoot-event-bubbling.js
@@ -35,12 +35,8 @@ function eventHandler(evt, label) {
     shouldBeEqualToString("msg", expected[eventCounter]);
     ++eventCounter;
 
-    if (label == counter) {
-        if (label == tests)
-            setTimeout("finishTest()", 100);
-        else
-            setTimeout("nextTest()", 100);
-    }
+    if (label == counter)
+        setTimeout(label == tests ? finishTest : nextTest, 0);
 }
 
 function finishTest()
diff --git a/LayoutTests/svg/custom/resources/use-instanceRoot-event-listeners.js b/LayoutTests/svg/custom/resources/use-instanceRoot-event-listeners.js
index 88653da..9dc1cc1 100644
--- a/LayoutTests/svg/custom/resources/use-instanceRoot-event-listeners.js
+++ b/LayoutTests/svg/custom/resources/use-instanceRoot-event-listeners.js
@@ -18,7 +18,7 @@ function eventHandler(evt)
             debug("Test " + counter + " / " + tests + " FAILED (expected: '" + expected + "' actual: '" + evt.type + "')");
     }
 
-    setTimeout(counter < tests ? driveTests : finishTest, 100);
+    setTimeout(counter < tests ? driveTests : finishTest, 0);
 }
 
 function finishTest()
diff --git a/LayoutTests/svg/custom/use-instanceRoot-as-event-target-expected.txt b/LayoutTests/svg/custom/use-instanceRoot-as-event-target-expected.txt
index 164a7c7..c82ae6c 100644
--- a/LayoutTests/svg/custom/use-instanceRoot-as-event-target-expected.txt
+++ b/LayoutTests/svg/custom/use-instanceRoot-as-event-target-expected.txt
@@ -32,7 +32,7 @@ PASS currentEvent.target == currentEvent.currentTarget is true
 PASS currentEvent.target.correspondingElement == currentEvent.currentTarget.correspondingElement is true
 PASS currentEvent.target.correspondingUseElement == currentEvent.currentTarget.correspondingUseElement is true
 
-Test #3: Verify that event listeners attached to the shadow tree elements are copied when use reclones the internal shadow tree
+Test #3: Verify that events dispatched by the user end up on the SVGElementInstance objects
 
 PASS currentEvent.toString() is "[object MouseEvent]"
 PASS currentEvent.type.toString() is "mouseover"
@@ -46,35 +46,7 @@ PASS currentEvent.target == currentEvent.currentTarget is true
 PASS currentEvent.target.correspondingElement == currentEvent.currentTarget.correspondingElement is true
 PASS currentEvent.target.correspondingUseElement == currentEvent.currentTarget.correspondingUseElement is true
 
-Test #4: Verify that events dispatched to the referenced element end up on the SVElementInstance objects
-
-PASS currentEvent.toString() is "[object MouseEvent]"
-PASS currentEvent.type.toString() is "mouseover"
-PASS currentEvent.target.toString() is "[object SVGElementInstance]"
-PASS currentEvent.currentTarget.toString() is "[object SVGElementInstance]"
-PASS currentEvent.target.correspondingElement == rectElement is true
-PASS currentEvent.target.correspondingUseElement == useElement is true
-PASS currentEvent.currentTarget.correspondingElement == rectElement is true
-PASS currentEvent.currentTarget.correspondingUseElement == useElement is true
-PASS currentEvent.target == currentEvent.currentTarget is true
-PASS currentEvent.target.correspondingElement == currentEvent.currentTarget.correspondingElement is true
-PASS currentEvent.target.correspondingUseElement == currentEvent.currentTarget.correspondingUseElement is true
-
-Test #5: Verify that event listeners attached to the referenced elements are copied when use reclones the internal shadow tree
-
-PASS currentEvent.toString() is "[object MouseEvent]"
-PASS currentEvent.type.toString() is "mouseover"
-PASS currentEvent.target.toString() is "[object SVGElementInstance]"
-PASS currentEvent.currentTarget.toString() is "[object SVGElementInstance]"
-PASS currentEvent.target.correspondingElement == rectElement is true
-PASS currentEvent.target.correspondingUseElement == useElement is true
-PASS currentEvent.currentTarget.correspondingElement == rectElement is true
-PASS currentEvent.currentTarget.correspondingUseElement == useElement is true
-PASS currentEvent.target == currentEvent.currentTarget is true
-PASS currentEvent.target.correspondingElement == currentEvent.currentTarget.correspondingElement is true
-PASS currentEvent.target.correspondingUseElement == currentEvent.currentTarget.correspondingUseElement is true
-
-Test #6: Verify that a click event got dispatched to the original tree as defined in the markup, when sent to the 'rectElement'
+Test #4: Verify that a click event got dispatched to the original tree as defined in the markup, when sent to the 'rectElement'
 
 PASS currentEvent.toString() is "[object MouseEvent]"
 PASS currentEvent.type.toString() is "click"
@@ -84,21 +56,7 @@ PASS currentEvent.target == rectElement is true
 PASS currentEvent.currentTarget == rectElement is true
 PASS currentEvent.target == currentEvent.currentTarget is true
 
-Test #7: Verify that a click event got dispatched to the instance tree when sent to the 'useElement.instanceRoot' with an event listener attached to 'rectElement'
-
-PASS currentEvent.toString() is "[object MouseEvent]"
-PASS currentEvent.type.toString() is "click"
-PASS currentEvent.target.toString() is "[object SVGElementInstance]"
-PASS currentEvent.currentTarget.toString() is "[object SVGElementInstance]"
-PASS currentEvent.target.correspondingElement == rectElement is true
-PASS currentEvent.target.correspondingUseElement == useElement is true
-PASS currentEvent.currentTarget.correspondingElement == rectElement is true
-PASS currentEvent.currentTarget.correspondingUseElement == useElement is true
-PASS currentEvent.target == currentEvent.currentTarget is true
-PASS currentEvent.target.correspondingElement == currentEvent.currentTarget.correspondingElement is true
-PASS currentEvent.target.correspondingUseElement == currentEvent.currentTarget.correspondingUseElement is true
-
-Test #8: Verify that the original click event listener defined in markup is still working properly
+Test #5: Verify that a click event got dispatched to the instance tree when sent to the 'useElement.instanceRoot' with an event listener attached to 'rectElement'
 
 PASS currentEvent.toString() is "[object MouseEvent]"
 PASS currentEvent.type.toString() is "click"
@@ -112,7 +70,7 @@ PASS currentEvent.target == currentEvent.currentTarget is true
 PASS currentEvent.target.correspondingElement == currentEvent.currentTarget.correspondingElement is true
 PASS currentEvent.target.correspondingUseElement == currentEvent.currentTarget.correspondingUseElement is true
 
-Test #9: Verify that the original click event listener got removed and a new one attached to the use root SVGElementInstance
+Test #6: Verify that the original click event listener got removed and a new one attached is attached to the use root SVGElementInstance
 
 PASS currentEvent.toString() is "[object MouseEvent]"
 PASS currentEvent.type.toString() is "click"
@@ -126,7 +84,7 @@ PASS currentEvent.target == currentEvent.currentTarget is true
 PASS currentEvent.target.correspondingElement == currentEvent.currentTarget.correspondingElement is true
 PASS currentEvent.target.correspondingUseElement == currentEvent.currentTarget.correspondingUseElement is true
 
-Test #10: Verify that the simulated click event got dispatched to the right target
+Test #8: Verify that the simulated click event got dispatched to the right target
 
 PASS currentEvent.toString() is "[object MouseEvent]"
 PASS currentEvent.type.toString() is "click"
diff --git a/LayoutTests/svg/custom/use-instanceRoot-as-event-target.xhtml b/LayoutTests/svg/custom/use-instanceRoot-as-event-target.xhtml
index 967be54..ca63bb2 100644
--- a/LayoutTests/svg/custom/use-instanceRoot-as-event-target.xhtml
+++ b/LayoutTests/svg/custom/use-instanceRoot-as-event-target.xhtml
@@ -9,23 +9,36 @@
   <defs>
       <rect id="target" fill="red" width="100" height="100" onclick="eventHandler(evt)"/>
   </defs>
-  <use id="test" xlink:href="url(#target)"/>
+  <use id="test" xlink:href="#target"/>
 </svg>
 
 <p id="description"/>
 <div id="console"/>
 
 <script>
-var currentEvent;
-var nextEventType;
-var eventNotification;
+// Setting up the testcase
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+var useElement = document.getElementById("test");
+var rectElement = document.getElementById("target");
 
+// Start test immediately, to see wheter instanceRoot is already available, as expected.
+description("Test SVG use element specific event handling using SVGElementInstance: ");
+debug("'useElement' is the original use element");
+debug("'rectElement' is the original element which gets cloned by the use element");
+eventTestOne();
+
+// Helper functions
 function eventHandler(evt)
 {
-    if (evt.type != nextEventType)
+    if (evt.type != nextEventType) {
+        debug("RECEIVED UNEXPECTED EVENT! shouldBe='" + nextEventType + "' was='" + evt.type + "'");
         return;
+    }
 
     currentEvent = evt;
+    nextEventType = "not yet set";
     eval(eventNotification);
 }
 
@@ -35,8 +48,12 @@ function fireMouseOverEvent(newEventNotification)
     nextEventType = "mouseover";
     eventNotification = newEventNotification;
 
-    if (window.eventSender)
-        eventSender.mouseMoveTo(50, 50);
+    if (window.eventSender) {
+        setTimeout(function() {
+            eventSender.mouseMoveTo(200, 200);
+            eventSender.mouseMoveTo(50, 50);
+        }, 0);
+    }
 }
 
 function fireMouseClickEvent(newEventNotification)
@@ -46,16 +63,18 @@ function fireMouseClickEvent(newEventNotification)
     eventNotification = newEventNotification;
 
     if (window.eventSender) {
-        eventSender.mouseMoveTo(50, 50);
-        eventSender.mouseDown();
-        eventSender.mouseUp();
+        setTimeout(function() {
+            eventSender.mouseMoveTo(50, 50);
+            eventSender.mouseDown();
+            eventSender.mouseUp();
+        }, 0);
     }
 }
 
-function fireSimulatedMouseClickEvent(newEventNotification, eventTarget)
+function fireSimulatedMouseOverEvent(newEventNotification, eventTarget)
 {
     currentEvent = undefined;
-    nextEventType = "click";
+    nextEventType = "mouseover";
     eventNotification = newEventNotification;
 
     var event = document.createEvent("MouseEvents");
@@ -64,11 +83,17 @@ function fireSimulatedMouseClickEvent(newEventNotification, eventTarget)
     eventTarget.dispatchEvent(event);
 }
 
-if (window.layoutTestController)
-    layoutTestController.waitUntilDone();
+function fireSimulatedMouseClickEvent(newEventNotification, eventTarget)
+{
+    currentEvent = undefined;
+    nextEventType = "click";
+    eventNotification = newEventNotification;
 
-var useElement = document.getElementById("test");
-var rectElement = document.getElementById("target");
+    var event = document.createEvent("MouseEvents");
+    event.initMouseEvent(nextEventType, true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
+
+    eventTarget.dispatchEvent(event);
+}
 
 function verifyEvent(evtString, targetString, currentTargetString)
 {
@@ -113,33 +138,41 @@ function verifyClickEventOnReferenced()
     shouldBeTrue("currentEvent.target == currentEvent.currentTarget");
 }
 
-description("Test SVG use element specific event handling using SVGElementInstance: ");
-debug("'useElement' is the original use element");
-debug("'rectElement' is the original element which gets cloned by the use element");
+function checkEventListenerNotReachable()
+{
+    debug("");
+    debug("YOU SHOULD NOT SEE THIS TEXT. OTHERWHISE REMOVING EVENT LISTENERS FAILED!");
+    debug("");
+}
 
-debug("");
-debug("Test #1: Verify that the use element and the contained SVGElementInstance objects are valid");
-debug("");
+// Event test sections
+function eventTestOne()
+{
+    debug("");
+    debug("Test #1: Verify that the use element and the contained SVGElementInstance objects are valid");
+    debug("");
 
-shouldBeEqualToString("useElement.toString()", "[object SVGUseElement]");
-shouldBeEqualToString("useElement.instanceRoot.toString()", "[object SVGElementInstance]");
+    shouldBeEqualToString("useElement.toString()", "[object SVGUseElement]");
+    shouldBeEqualToString("useElement.instanceRoot.toString()", "[object SVGElementInstance]");
 
-shouldBeEqualToString("useElement.instanceRoot.correspondingElement.toString()", "[object SVGRectElement]");
-shouldBeTrue("useElement.instanceRoot.correspondingElement == rectElement");
+    shouldBeEqualToString("useElement.instanceRoot.correspondingElement.toString()", "[object SVGRectElement]");
+    shouldBeTrue("useElement.instanceRoot.correspondingElement == rectElement");
 
-shouldBeEqualToString("useElement.instanceRoot.correspondingUseElement.toString()", "[object SVGUseElement]");
-shouldBeTrue("useElement.instanceRoot.correspondingUseElement == useElement");
+    shouldBeEqualToString("useElement.instanceRoot.correspondingUseElement.toString()", "[object SVGUseElement]");
+    shouldBeTrue("useElement.instanceRoot.correspondingUseElement == useElement");
 
-shouldBeEqualToString("typeof useElement.addEventListener", "function");
-shouldBeEqualToString("typeof useElement.removeEventListener", "function");
-shouldBeEqualToString("typeof useElement.dispatchEvent", "function");
+    shouldBeEqualToString("typeof useElement.addEventListener", "function");
+    shouldBeEqualToString("typeof useElement.removeEventListener", "function");
+    shouldBeEqualToString("typeof useElement.dispatchEvent", "function");
 
-// Spec: An element and all its corresponding SVGElementInstance objects share an event
-// listener list. The currentTarget attribute of the event can be used to determine through
-// which object an event listener was invoked.
-useElement.instanceRoot.addEventListener("mouseover", eventHandler, false);
+    // Spec: An element and all its corresponding SVGElementInstance objects share an event
+    // listener list. The currentTarget attribute of the event can be used to determine through
+    // which object an event listener was invoked.
+    useElement.instanceRoot.addEventListener("mouseover", eventHandler, false);
+    fireMouseOverEvent("eventTestTwo()");
+}
 
-function startEventTests()
+function eventTestTwo()
 {
     debug("");
     debug("Test #2: Verify that events dispatched to the SVGElementInstance objects have correct target property values");
@@ -155,102 +188,70 @@ function startEventTests()
     // regular tree to the root element in bubbling phase.
     verifyMouseOverEvent();
 
-    // Prepare for next test
-    useElement.instanceRoot.removeEventListener("mouseover", eventHandler, false);
-    useElement.instanceRoot.addEventListener("mouseover", eventHandler, false);
-
-    // Causes svgAttributeChanged() logic to reclone the shadow tree
-    // If 'Test #3' is not executed, then it didn't properly reclone the event listeners.
-    useElement.instanceRoot.correspondingElement.setAttribute("x", useElement.instanceRoot.correspondingElement.getAttribute("x"));
-
-    fireMouseOverEvent("eventTestOne()");
-}
-
-function eventTestOne()
-{
-    debug("");
-    debug("Test #3: Verify that event listeners attached to the shadow tree elements are copied when use reclones the internal shadow tree");
-    debug("");
-
-    // Spec: If event attributes are assigned to referenced elements, then the actual target for the event will be the
-    // SVGElementInstance object within the "instance tree" corresponding to the given referenced element.
-    verifyMouseOverEvent();
-
-    // Prepare for next test
     useElement.instanceRoot.removeEventListener("mouseover", eventHandler, false);
+    fireSimulatedMouseOverEvent("checkEventListenerNotReachable()", useElement.instanceRoot);
+    fireSimulatedMouseOverEvent("checkEventListenerNotReachable()", rectElement);
     rectElement.addEventListener("mouseover", eventHandler, false);
 
-    fireMouseOverEvent("eventTestTwo()");
-}
-
-function eventTestTwo()
-{
-    debug("");
-    debug("Test #4: Verify that events dispatched to the referenced element end up on the SVElementInstance objects");
-    debug("");
-
-    verifyMouseOverEvent();
-
-    // Prepare for next test
-    rectElement.removeEventListener("mouseover", eventHandler, false);
-    rectElement.addEventListener("mouseover", eventHandler, false);
-
-    // Causes svgAttributeChanged() logic to reclone the shadow tree
-    // If 'Test #5' is not executed, then it didn't properly reclone the event listeners.
-    rectElement.setAttribute("x", rectElement.getAttribute("x"));
-
     fireMouseOverEvent("eventTestThree()");
 }
 
 function eventTestThree()
 {
     debug("");
-    debug("Test #5: Verify that event listeners attached to the referenced elements are copied when use reclones the internal shadow tree");
+    debug("Test #3: Verify that events dispatched by the user end up on the SVGElementInstance objects");
     debug("");
 
     verifyMouseOverEvent();
 
-    // Prepare for next test
-    rectElement.removeEventListener("mouseover", eventHandler, false);
-
+    useElement.instanceRoot.removeEventListener("mouseover", eventHandler, false);
+    fireSimulatedMouseOverEvent("checkEventListenerNotReachable()", useElement.instanceRoot);
+    fireSimulatedMouseOverEvent("checkEventListenerNotReachable()", rectElement);
     fireSimulatedMouseClickEvent("eventTestFour()", rectElement);
 }
 
 function eventTestFour()
 {
     debug("");
-    debug("Test #6: Verify that a click event got dispatched to the original tree as defined in the markup, when sent to the 'rectElement'"); 
+    debug("Test #4: Verify that a click event got dispatched to the original tree as defined in the markup, when sent to the 'rectElement'"); 
     debug("");
 
     verifyClickEventOnReferenced();
 
-    // Prepare for next test
     fireSimulatedMouseClickEvent("eventTestFive()", useElement.instanceRoot);
 }
 
 function eventTestFive()
 {
     debug("");
-    debug("Test #7: Verify that a click event got dispatched to the instance tree when sent to the 'useElement.instanceRoot' with an event listener attached to 'rectElement'"); 
+    debug("Test #5: Verify that a click event got dispatched to the instance tree when sent to the 'useElement.instanceRoot' with an event listener attached to 'rectElement'"); 
     debug("");
 
     verifyClickEvent();
 
-    // Prepare for next test
+    // This tests a webkit specific quirk: removeAttribute() on the target element, causes us to reclone the shadow tree.
+    // All event listener mutations are synchronized with the shadow tree and do not cause reclones. So if we add the
+    // click event listener to the current instanceRoot, remove the existing click listener from markup and then fire
+    // a click event, we're sure that the shadow tree is recloned before the eventTestSix() function is executed.
+    // If eventTestSix() is reached, we've properly preserved the dynamically created click event listener after recloning.
+    useElement.instanceRoot.addEventListener("click", eventHandler, false);
+    rectElement.removeAttribute("onclick");
+
     fireMouseClickEvent("eventTestSix()");
 }
 
 function eventTestSix()
 {
     debug("");
-    debug("Test #8: Verify that the original click event listener defined in markup is still working properly");
+    debug("Test #6: Verify that the original click event listener got removed and a new one attached is attached to the use root SVGElementInstance");
     debug("");
 
     verifyClickEvent();
 
-    // Prepare for next test
-    rectElement.removeEventListener("click", eventHandler, false);
-    useElement.instanceRoot.addEventListener("click", eventHandler, false);
+    useElement.instanceRoot.removeEventListener("click", eventHandler, false);
+    fireSimulatedMouseClickEvent("checkEventListenerNotReachable()", useElement.instanceRoot);
+    fireSimulatedMouseClickEvent("checkEventListenerNotReachable()", rectElement);
+    rectElement.addEventListener("click", eventHandler, false);
 
     fireMouseClickEvent("eventTestSeven()");
 }
@@ -258,30 +259,32 @@ function eventTestSix()
 function eventTestSeven()
 {
     debug("");
-    debug("Test #9: Verify that the original click event listener got removed and a new one attached to the use root SVGElementInstance");
+    debug("Test #7: Verify that the recreating the original click event listener dynamically worked and the event is now dispatched to the regular DOM");
     debug("");
 
-    verifyClickEvent();
+    verifyClickEventOnReferenced();
 
     // Prepare for next tests
     fireSimulatedMouseClickEvent("eventTestEight()", useElement.instanceRoot);
 }
 
-function eventTestEight()
+function eventTestSeven()
 {
     debug("");
-    debug("Test #10: Verify that the simulated click event got dispatched to the right target");
+    debug("Test #8: Verify that the simulated click event got dispatched to the right target");
     debug("");
 
     verifyClickEvent();
 
     // Cleanup
     useElement.instanceRoot.removeEventListener("click", eventHandler, false);
+    fireSimulatedMouseClickEvent("checkEventListenerNotReachable()", useElement.instanceRoot);
+    fireSimulatedMouseClickEvent("checkEventListenerNotReachable()", rectElement);
 
-    stopEventTests();
+    finishTests();
 }
 
-function stopEventTests()
+function finishTests()
 {
     successfullyParsed = true;
 
@@ -292,8 +295,6 @@ function stopEventTests()
     if (window.layoutTestController)
         layoutTestController.notifyDone();
 }
-
-fireMouseOverEvent("startEventTests()");
 </script>
 
 </body>
diff --git a/LayoutTests/svg/custom/use-instanceRoot-event-listener-liveness-expected.txt b/LayoutTests/svg/custom/use-instanceRoot-event-listener-liveness-expected.txt
new file mode 100644
index 0000000..386f3d2
--- /dev/null
+++ b/LayoutTests/svg/custom/use-instanceRoot-event-listener-liveness-expected.txt
@@ -0,0 +1 @@
+Test passed
diff --git a/LayoutTests/svg/custom/use-instanceRoot-event-listener-liveness.xhtml b/LayoutTests/svg/custom/use-instanceRoot-event-listener-liveness.xhtml
new file mode 100644
index 0000000..ee042aa
--- /dev/null
+++ b/LayoutTests/svg/custom/use-instanceRoot-event-listener-liveness.xhtml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+</head>
+<body onload="startTest()">
+
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px">
+  <defs>
+      <rect id="target" fill="green" width="100" height="100"/>
+  </defs>
+  <use id="test" xlink:href="#target"/>
+</svg>
+
+<div id="console">Test failed</div>
+
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+function eventHandler()
+{
+    var divElement = document.getElementById("console");
+    divElement.textContent = "Test passed";
+
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function fireSimulatedMouseClickEvent(eventTarget)
+{
+    var event = document.createEvent("MouseEvents");
+    event.initMouseEvent("click", true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
+    eventTarget.dispatchEvent(event);
+}
+
+function startTest() {
+    var useElement = document.getElementById("test");
+
+    // No-op, as no listener is not yet registered
+    fireSimulatedMouseClickEvent(useElement.instanceRoot);
+
+    // Add listener
+    useElement.instanceRoot.addEventListener("click", eventHandler, false);
+
+    // Should fire immediately and finish the test
+    fireSimulatedMouseClickEvent(useElement.instanceRoot);
+}
+</script>
+
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index b9574cf..162f9a8 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,50 @@
+2010-01-19  Nikolas Zimmermann  <nzimmermann at rim.com>
+
+        Reviewed by Alexey Proskuryakov. 
+
+        svg/custom/use-instanceRoot-event-bubbling.xhtml is flakey
+        https://bugs.webkit.org/show_bug.cgi?id=33835
+
+        mouseEvent fires mutiple times in svg/custom/use-instanceRoot-as-event-target.xhtml
+        https://bugs.webkit.org/show_bug.cgi?id=32519
+
+        Test: svg/custom/use-instanceRoot-event-listener-liveness.xhtml
+
+        Stabilize <use> scripting support - use tests are reliable now (tested using --repeach-each 50 --random -p)
+
+        Do not reclone trees anymore because of event listener changes, instead keep correspondingElement & shadowTreeElement
+        synchronized for each SVGElementInstance - any mutations on any event listeners are live, and take immediate effect,
+        w/o having to rely on a reclone - this was the root of several race conditions making the <use> tests flakey.
+
+        Fix SVGUseElement::instanceRoot() to force shadow tree creation, even if it was not attached so far - we can't wait
+        for finishedParsing() to be called which would recalculate the document style and attach the shadow tree as result.
+        This is now matching Operas behaviour.
+
+        Optimize createAttributeEventListener() to not create event listeners if the supplied Attribute isNull() - otherwhise
+        DOM calls like removeAttribute("onclick") cause a temporary JSEventListener to be created, added to the event listener
+        cache and removed afterwards.
+
+        * bindings/js/ScriptEventListener.cpp:
+        (WebCore::createAttributeEventListener): Return early if the supplied attribute is null as discussed with Geoffrey.
+        * bindings/v8/ScriptEventListener.cpp:
+        (WebCore::createAttributeEventListener): Ditto.
+        * dom/Node.cpp: Synchronize event listeners with all element instances, instead of marking the use elements to reclone.
+        (WebCore::instancesForSVGElement):
+        (WebCore::tryAddEventListener):
+        (WebCore::Node::addEventListener): When adding a listener, get a list of element instances and add it their as well.
+        (WebCore::tryRemoveEventListener):
+        (WebCore::Node::removeEventListener): Ditto for removals, but with special logic for listeners created from markup (see comments)
+        * svg/SVGElementInstance.cpp: Cleaned up, removing unncessary checks of correspondingElement() - there is an ASSERT in the ctor.
+        (WebCore::SVGElementInstance::invalidateAllInstancesOfElement):
+        (WebCore::SVGElementInstance::scriptExecutionContext):
+        (WebCore::SVGElementInstance::addEventListener):
+        (WebCore::SVGElementInstance::removeEventListener):
+        (WebCore::SVGElementInstance::removeAllEventListeners):
+        (WebCore::SVGElementInstance::eventTargetData):
+        (WebCore::SVGElementInstance::ensureEventTargetData):
+        * svg/SVGUseElement.cpp: Call document()->updateLayoutIgnorePendingStylesheets() to force shadow tree creation, just like CSSStyleDecl works.
+        (WebCore::SVGUseElement::instanceRoot):
+
 2010-01-20  Dmitry Titov  <dimich at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/bindings/js/ScriptEventListener.cpp b/WebCore/bindings/js/ScriptEventListener.cpp
index b9dc00e..4325dc3 100644
--- a/WebCore/bindings/js/ScriptEventListener.cpp
+++ b/WebCore/bindings/js/ScriptEventListener.cpp
@@ -52,6 +52,9 @@ static const String& eventParameterName(bool isSVGEvent)
 PassRefPtr<JSLazyEventListener> createAttributeEventListener(Node* node, Attribute* attr)
 {
     ASSERT(node);
+    ASSERT(attr);
+    if (attr->isNull())
+        return 0;
 
     int lineNumber = 1;
     String sourceURL;
@@ -79,6 +82,10 @@ PassRefPtr<JSLazyEventListener> createAttributeEventListener(Frame* frame, Attri
     if (!frame)
         return 0;
 
+    ASSERT(attr);
+    if (attr->isNull())
+        return 0;
+
     int lineNumber = 1;
     String sourceURL;
     
diff --git a/WebCore/bindings/v8/ScriptEventListener.cpp b/WebCore/bindings/v8/ScriptEventListener.cpp
index cf2a1ee..1b54f12 100644
--- a/WebCore/bindings/v8/ScriptEventListener.cpp
+++ b/WebCore/bindings/v8/ScriptEventListener.cpp
@@ -46,6 +46,10 @@ namespace WebCore {
 PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribute* attr)
 {
     ASSERT(node);
+    ASSERT(attr);
+    if (attr->isNull())
+        return 0;
+
     int lineNumber = 1;
     int columnNumber = 0;
     String sourceURL;
@@ -76,6 +80,11 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri
     if (!frame)
         return 0;
 
+    ASSERT(node);
+    ASSERT(attr);
+    if (attr->isNull())
+        return 0;
+
     int lineNumber = 1;
     int columnNumber = 0;
     String sourceURL;
diff --git a/WebCore/dom/Node.cpp b/WebCore/dom/Node.cpp
index 8fb752d..160889f 100644
--- a/WebCore/dom/Node.cpp
+++ b/WebCore/dom/Node.cpp
@@ -2332,49 +2332,159 @@ void Node::didMoveToNewOwnerDocument()
     setDidMoveToNewOwnerDocumentWasCalled(true);
 }
 
-static inline void updateSVGElementInstancesAfterEventListenerChange(Node* referenceNode)
+#if ENABLE(SVG)
+static inline HashSet<SVGElementInstance*> instancesForSVGElement(Node* node)
+{
+    HashSet<SVGElementInstance*> instances;
+ 
+    ASSERT(node);
+    if (!node->isSVGElement() || node->shadowTreeRootNode())
+        return HashSet<SVGElementInstance*>();
+
+    SVGElement* element = static_cast<SVGElement*>(node);
+    if (!element->isStyled())
+        return HashSet<SVGElementInstance*>();
+
+    SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(element);
+    ASSERT(!styledElement->instanceUpdatesBlocked());
+
+    return styledElement->instancesForElement();
+}
+#endif
+
+static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+{
+    if (!targetNode->EventTarget::addEventListener(eventType, listener, useCapture))
+        return false;
+
+    if (Document* document = targetNode->document())
+        document->addListenerTypeIfNeeded(eventType);
+
+    return true;
+}
+
+bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
 {
 #if !ENABLE(SVG)
-    UNUSED_PARAM(referenceNode);
+    return tryAddEventListener(this, eventType, listener, useCapture);
 #else
-    ASSERT(referenceNode);
-    if (!referenceNode->isSVGElement())
-        return;
+    if (!isSVGElement())
+        return tryAddEventListener(this, eventType, listener, useCapture);
 
-    // Elements living inside a <use> shadow tree, never cause any updates!
-    if (referenceNode->shadowTreeRootNode())
-        return;
+    HashSet<SVGElementInstance*> instances = instancesForSVGElement(this);
+    if (instances.isEmpty())
+        return tryAddEventListener(this, eventType, listener, useCapture);
 
-    // We're possibly (a child of) an element that is referenced by a <use> client
-    // If an event listeners changes on a referenced element, update all instances.
-    for (Node* node = referenceNode; node; node = node->parentNode()) {
-        if (!node->hasID() || !node->isSVGElement())
-            continue;
+    RefPtr<EventListener> listenerForRegularTree = listener;
+    RefPtr<EventListener> listenerForShadowTree = listenerForRegularTree;
+
+    // Add event listener to regular DOM element
+    if (!tryAddEventListener(this, eventType, listenerForRegularTree.release(), useCapture))
+        return false;
+
+    // Add event listener to all shadow tree DOM element instances
+    const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
+    for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
+        ASSERT((*it)->shadowTreeElement());
+        ASSERT((*it)->correspondingElement() == this);
 
-        SVGElementInstance::invalidateAllInstancesOfElement(static_cast<SVGElement*>(node));
-        break;
+        RefPtr<EventListener> listenerForCurrentShadowTreeElement = listenerForShadowTree;
+        bool result = tryAddEventListener((*it)->shadowTreeElement(), eventType, listenerForCurrentShadowTreeElement.release(), useCapture);
+        ASSERT_UNUSED(result, result);
     }
+
+    return true;
 #endif
 }
 
-bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener* listener, bool useCapture)
 {
-    if (!EventTarget::addEventListener(eventType, listener, useCapture))
+    if (!targetNode->EventTarget::removeEventListener(eventType, listener, useCapture))
         return false;
 
-    if (Document* document = this->document())
-        document->addListenerTypeIfNeeded(eventType);
-    updateSVGElementInstancesAfterEventListenerChange(this);
+    // FIXME: Notify Document that the listener has vanished. We need to keep track of a number of
+    // listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861
+
     return true;
 }
 
 bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
 {
-    if (!EventTarget::removeEventListener(eventType, listener, useCapture))
+#if !ENABLE(SVG)
+    return tryRemoveEventListener(this, eventType, listener, useCapture);
+#else
+    if (!isSVGElement())
+        return tryRemoveEventListener(this, eventType, listener, useCapture);
+
+    HashSet<SVGElementInstance*> instances = instancesForSVGElement(this);
+    if (instances.isEmpty())
+        return tryRemoveEventListener(this, eventType, listener, useCapture);
+
+    // EventTarget::removeEventListener creates a PassRefPtr around the given EventListener
+    // object when creating a temporary RegisteredEventListener object used to look up the
+    // event listener in a cache. If we want to be able to call removeEventListener() multiple
+    // times on different nodes, we have to delay its immediate destruction, which would happen
+    // after the first call below.
+    RefPtr<EventListener> protector(listener);
+
+    // Remove event listener from regular DOM element
+    if (!tryRemoveEventListener(this, eventType, listener, useCapture))
         return false;
 
-    updateSVGElementInstancesAfterEventListenerChange(this);
+    // Remove event listener from all shadow tree DOM element instances
+    const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
+    for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
+        ASSERT((*it)->correspondingElement() == this);
+
+        SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
+        ASSERT(shadowTreeElement);
+
+        if (tryRemoveEventListener(shadowTreeElement, eventType, listener, useCapture))
+            continue;
+
+        // This case can only be hit for event listeners created from markup
+        ASSERT(listener->wasCreatedFromMarkup());
+
+        // If the event listener 'listener' has been created from markup and has been fired before
+        // then JSLazyEventListener::parseCode() has been called and m_jsFunction of that listener
+        // has been created (read: it's not 0 anymore). During shadow tree creation, the event
+        // listener DOM attribute has been cloned, and another event listener has been setup in
+        // the shadow tree. If that event listener has not been used yet, m_jsFunction is still 0,
+        // and tryRemoveEventListener() above will fail. Work around that very seldom problem.
+        EventTargetData* data = shadowTreeElement->eventTargetData();
+        ASSERT(data);
+
+        EventListenerMap::iterator result = data->eventListenerMap.find(eventType);
+        ASSERT(result != data->eventListenerMap.end());
+
+        EventListenerVector* entry = result->second;
+        ASSERT(entry);
+
+        unsigned int index = 0;
+        bool foundListener = false;
+
+        EventListenerVector::iterator end = entry->end();
+        for (EventListenerVector::iterator it = entry->begin(); it != end; ++it) {
+            if (!(*it).listener->wasCreatedFromMarkup()) {
+                ++index;
+                continue;
+            }
+
+            foundListener = true;
+            entry->remove(index);
+            break;
+        }
+
+        ASSERT(foundListener);
+
+        if (entry->isEmpty()) {                
+            delete entry;
+            data->eventListenerMap.remove(result);
+        }
+    }
+
     return true;
+#endif
 }
 
 EventTargetData* Node::eventTargetData()
diff --git a/WebCore/svg/SVGElementInstance.cpp b/WebCore/svg/SVGElementInstance.cpp
index 54ee1c4..d348b0b 100644
--- a/WebCore/svg/SVGElementInstance.cpp
+++ b/WebCore/svg/SVGElementInstance.cpp
@@ -1,5 +1,6 @@
 /*
     Copyright (C) 2007, 2008 Nikolas Zimmermann <zimmermann at kde.org>
+    Copyright (C) Research In Motion Limited 2010. All rights reserved.
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
@@ -39,13 +40,6 @@ namespace WebCore {
 static WTF::RefCountedLeakCounter instanceCounter("WebCoreSVGElementInstance");
 #endif
 
-static EventTargetData& dummyEventTargetData()
-{
-    DEFINE_STATIC_LOCAL(EventTargetData, dummyEventTargetData, ());
-    dummyEventTargetData.eventListenerMap.clear();
-    return dummyEventTargetData;
-}
-
 SVGElementInstance::SVGElementInstance(SVGUseElement* useElement, PassRefPtr<SVGElement> originalElement)
     : m_useElement(useElement)
     , m_element(originalElement)
@@ -95,10 +89,10 @@ void SVGElementInstance::appendChild(PassRefPtr<SVGElementInstance> child)
 
 void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element)
 {
-    if (!element || !element->isStyled())
+    if (!element)
         return;
 
-    if (static_cast<SVGStyledElement*>(element)->instanceUpdatesBlocked())
+    if (element->isStyled() && static_cast<SVGStyledElement*>(element)->instanceUpdatesBlocked())
         return;
 
     HashSet<SVGElementInstance*> set = element->instancesForElement();
@@ -117,30 +111,22 @@ void SVGElementInstance::invalidateAllInstancesOfElement(SVGElement* element)
 
 ScriptExecutionContext* SVGElementInstance::scriptExecutionContext() const
 {
-    if (SVGElement* element = correspondingElement())
-        return element->document();
-    return 0;
+    return m_element->document();
 }
 
 bool SVGElementInstance::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
 {
-    if (!correspondingElement())
-        return false;
-    return correspondingElement()->addEventListener(eventType, listener, useCapture);
+    return m_element->addEventListener(eventType, listener, useCapture);
 }
 
 bool SVGElementInstance::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
 {
-    if (!correspondingElement())
-        return false;
-    return correspondingElement()->removeEventListener(eventType, listener, useCapture);
+    return m_element->removeEventListener(eventType, listener, useCapture);
 }
 
 void SVGElementInstance::removeAllEventListeners()
 {
-    if (!correspondingElement())
-        return;
-    correspondingElement()->removeAllEventListeners();
+    m_element->removeAllEventListeners();
 }
 
 bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> prpEvent)
@@ -160,14 +146,17 @@ bool SVGElementInstance::dispatchEvent(PassRefPtr<Event> prpEvent)
 
 EventTargetData* SVGElementInstance::eventTargetData()
 {
-    return correspondingElement() ? correspondingElement()->eventTargetData() : 0;
+    return m_element->eventTargetData();
 }
 
 EventTargetData* SVGElementInstance::ensureEventTargetData()
 {
-    return &dummyEventTargetData(); // return something, so we don't crash
+    // Avoid crashing - return a default dummy value
+    DEFINE_STATIC_LOCAL(EventTargetData, dummyEventTargetData, ());
+    dummyEventTargetData.eventListenerMap.clear();
+    return &dummyEventTargetData;
 }
 
-} // namespace WebCore
+}
 
-#endif // ENABLE(SVG)
+#endif
diff --git a/WebCore/svg/SVGUseElement.cpp b/WebCore/svg/SVGUseElement.cpp
index 1011b88..6d371dc 100644
--- a/WebCore/svg/SVGUseElement.cpp
+++ b/WebCore/svg/SVGUseElement.cpp
@@ -78,14 +78,11 @@ SVGUseElement::~SVGUseElement()
 SVGElementInstance* SVGUseElement::instanceRoot() const
 {
     // If there is no element instance tree, force immediate SVGElementInstance tree
-    // creation, as we can't wait for the lazy creation to happen if ie. JS wants to
-    // access the instanceRoot object right after creating the element on-the-fly
-    if (!m_targetElementInstance) {
-        if (RenderSVGShadowTreeRootContainer* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer())) {
-            shadowRoot->markShadowTreeForRecreation();
-            shadowRoot->updateFromElement();
-        }
-    }
+    // creation by asking the document to invoke our recalcStyle function - as we can't
+    // wait for the lazy creation to happen if e.g. JS wants to access the instanceRoot
+    // object right after creating the element on-the-fly
+    if (!m_targetElementInstance)
+        document()->updateLayoutIgnorePendingStylesheets();
 
     return m_targetElementInstance.get();
 }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list