From fdf80d6185883ac49eb4e5254f523289fe2656ea Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Tue, 28 Jan 2014 15:40:25 -0800 Subject: [PATCH] Workaround element event path The SVG element has a horrifying "instance tree" related to ShadowDOM, but does not retarget. The SVGElementInstance (the instanceRoot type) has parts of a Node's API, but not all (like .contains). For native events the SVGElementInstance will bubble events up to the element, even non-bubbling events like enter and leave, but it will not do so when dispatchEvent is called on it with a non-bubbling event. Only Safari, IE, and Chrome implement this monstrosity, and working group seems to agree it should be removed: http://lists.w3.org/Archives/Public/www-svg/2014Jan/0014.html This workaround rewites event.target and relatedTarget to refer to elements and not their "instance trees". Fixes #124 --- src/dispatcher.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/dispatcher.js b/src/dispatcher.js index 6ad9ea91..93e050a6 100644 --- a/src/dispatcher.js +++ b/src/dispatcher.js @@ -75,6 +75,8 @@ 0 ]; + var HAS_SVG_INSTANCE = (typeof SVGElementInstance !== 'undefined'); + /** * This module is for normalizing events. Mouse and Touch events will be * collected here, and fire PointerEvents that have the same semantics, no @@ -246,6 +248,14 @@ for (var i = 0; i < CLONE_PROPS.length; i++) { p = CLONE_PROPS[i]; eventCopy[p] = inEvent[p] || CLONE_DEFAULTS[i]; + // Work around SVGInstanceElement shadow tree + // Return the element that is represented by the instance for Safari, Chrome, IE. + // This is the behavior implemented by Firefox. + if (HAS_SVG_INSTANCE && (p === 'target' || p === 'relatedTarget')) { + if (eventCopy[p] instanceof SVGElementInstance) { + eventCopy[p] = eventCopy[p].correspondingUseElement; + } + } } // keep the semantics of preventDefault if (inEvent.preventDefault) {