https://bugs.webkit.org/show_bug.cgi?id=200083
Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2019-07-25
Reviewed by Ryosuke Niwa.
Source/WebCore:
When adding an event listener to an SVGElement, the same event listener
has to be add to all the instances of SVGElement in the shadow tree. See
SVGElement::addEventListener().
In r244995, an assertion was added to ensure if the event listener is
attached to an event target, the new event target has be the same as the
attached one. This assertion isn't correct for the event targets which
were copied from the targetElement sub tree of an SVGUseElement to the
shadow tree.
Test: svg/custom/add-event-listener-shadow-tree-element.html
* bindings/js/JSLazyEventListener.cpp:
(WebCore::isCloneInShadowTreeOfSVGUseElement):
(WebCore::JSLazyEventListener::checkValidityForEventTarget):
LayoutTests:
* svg/custom/add-event-listener-shadow-tree-element-expected.txt: Added.
* svg/custom/add-event-listener-shadow-tree-element.html: Added.
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@247826
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2019-07-25 Said Abou-Hallawa <sabouhallawa@apple.com>
+
+ REGRESSION (r244995): Assertion failure when addEventListener to an SVGElement which has an. instance in shadow tree
+ https://bugs.webkit.org/show_bug.cgi?id=200083
+
+ Reviewed by Ryosuke Niwa.
+
+ * svg/custom/add-event-listener-shadow-tree-element-expected.txt: Added.
+ * svg/custom/add-event-listener-shadow-tree-element.html: Added.
+
2019-07-25 Truitt Savell <tsavell@apple.com>
Unreviewed, rolling out r247821.
--- /dev/null
+PASS if it doesn't assert in debug builds.
+
--- /dev/null
+<html>
+<body onload=test()>
+ <svg>
+ <def>
+ <rect id="rect" width="100" height="100" fill="red"/>
+ </def>
+ <use id="use1" href="#rect"/>
+ <use id="use2" href="#use1"/>
+ <text y="120">PASS if it doesn't assert in debug builds.</text>
+ </svg>
+ <script>
+ function eventhandler() {
+ rect.setAttribute("fill", "green");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }
+ function test() {
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+ use1.setAttribute("onfocusin", "eventhandler()");
+ use1.focus();
+ }
+ </script>
+</body>
+</html>
+2019-07-25 Said Abou-Hallawa <sabouhallawa@apple.com>
+
+ REGRESSION (r244995): Assertion failure when addEventListener to an SVGElement which has an. instance in shadow tree
+ https://bugs.webkit.org/show_bug.cgi?id=200083
+
+ Reviewed by Ryosuke Niwa.
+
+ When adding an event listener to an SVGElement, the same event listener
+ has to be add to all the instances of SVGElement in the shadow tree. See
+ SVGElement::addEventListener().
+
+ In r244995, an assertion was added to ensure if the event listener is
+ attached to an event target, the new event target has be the same as the
+ attached one. This assertion isn't correct for the event targets which
+ were copied from the targetElement sub tree of an SVGUseElement to the
+ shadow tree.
+
+ Test: svg/custom/add-event-listener-shadow-tree-element.html
+
+ * bindings/js/JSLazyEventListener.cpp:
+ (WebCore::isCloneInShadowTreeOfSVGUseElement):
+ (WebCore::JSLazyEventListener::checkValidityForEventTarget):
+
2019-07-25 Truitt Savell <tsavell@apple.com>
Unreviewed, rolling out r247821.
#include "Frame.h"
#include "JSNode.h"
#include "QualifiedName.h"
+#include "SVGElement.h"
#include "ScriptController.h"
#include <JavaScriptCore/CatchScope.h>
#include <JavaScriptCore/FunctionConstructor.h>
}
#if !ASSERT_DISABLED
+static inline bool isCloneInShadowTreeOfSVGUseElement(Node& originalNode, EventTarget& eventTarget)
+{
+ if (!eventTarget.isNode())
+ return false;
+
+ auto& node = downcast<Node>(eventTarget);
+ if (!is<SVGElement>(node))
+ return false;
+
+ auto& element = downcast<SVGElement>(node);
+ if (!element.correspondingElement())
+ return false;
+
+ ASSERT(element.isInShadowTree());
+ return &originalNode == element.correspondingElement();
+}
+
// This is to help find the underlying cause of <rdar://problem/24314027>.
void JSLazyEventListener::checkValidityForEventTarget(EventTarget& eventTarget)
{
if (eventTarget.isNode()) {
ASSERT(m_originalNode);
- ASSERT(static_cast<EventTarget*>(m_originalNode.get()) == &eventTarget);
+ ASSERT(static_cast<EventTarget*>(m_originalNode.get()) == &eventTarget || isCloneInShadowTreeOfSVGUseElement(*m_originalNode, eventTarget));
} else
ASSERT(!m_originalNode);
}