@@ -78,11 +78,13 @@ var cartesianScatterPoints = {
7878// The actual rendering is done by private function _hover.
7979exports . hover = function hover ( gd , evt , subplot , noHoverEvent ) {
8080 gd = Lib . getGraphDiv ( gd ) ;
81-
81+ // The 'target' property changes when bubbling out of Shadow DOM.
82+ // Throttling can delay reading the target, so we save the current value.
83+ var eventTarget = evt . target ;
8284 Lib . throttle (
8385 gd . _fullLayout . _uid + constants . HOVERID ,
8486 constants . HOVERMINTIME ,
85- function ( ) { _hover ( gd , evt , subplot , noHoverEvent ) ; }
87+ function ( ) { _hover ( gd , evt , subplot , noHoverEvent , eventTarget ) ; }
8688 ) ;
8789} ;
8890
@@ -247,7 +249,7 @@ exports.loneHover = function loneHover(hoverItems, opts) {
247249} ;
248250
249251// The actual implementation is here:
250- function _hover ( gd , evt , subplot , noHoverEvent ) {
252+ function _hover ( gd , evt , subplot , noHoverEvent , eventTarget ) {
251253 if ( ! subplot ) subplot = 'xy' ;
252254
253255 // if the user passed in an array of subplots,
@@ -366,7 +368,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
366368 // [x|y]px: the pixels (from top left) of the mouse location
367369 // on the currently selected plot area
368370 // add pointerX|Y property for drawing the spikes in spikesnap 'cursor' situation
369- var hasUserCalledHover = ! evt . target ;
371+ var hasUserCalledHover = ! eventTarget ;
370372 var xpx , ypx ;
371373
372374 if ( hasUserCalledHover ) {
@@ -383,13 +385,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
383385 return ;
384386 }
385387
386- // Discover event target, traversing open shadow roots.
387- var target = evt . composedPath && evt . composedPath ( ) [ 0 ] ;
388- if ( ! target ) {
389- // Fallback for browsers not supporting composedPath
390- target = evt . target ;
391- }
392- var dbb = target . getBoundingClientRect ( ) ;
388+ var dbb = eventTarget . getBoundingClientRect ( ) ;
393389
394390 xpx = evt . clientX - dbb . left ;
395391 ypx = evt . clientY - dbb . top ;
@@ -837,15 +833,15 @@ function _hover(gd, evt, subplot, noHoverEvent) {
837833 if ( ! helpers . isUnifiedHover ( hovermode ) ) {
838834 hoverAvoidOverlaps ( hoverLabels , rotateLabels ? 'xa' : 'ya' , fullLayout ) ;
839835 alignHoverText ( hoverLabels , rotateLabels , fullLayout . _invScaleX , fullLayout . _invScaleY ) ;
840- } // TODO: tagName hack is needed to appease geo.js's hack of using evt.target =true
836+ } // TODO: tagName hack is needed to appease geo.js's hack of using eventTarget =true
841837 // we should improve the "fx" API so other plots can use it without these hack.
842- if ( evt . target && evt . target . tagName ) {
838+ if ( eventTarget && eventTarget . tagName ) {
843839 var hasClickToShow = Registry . getComponentMethod ( 'annotations' , 'hasClickToShow' ) ( gd , newhoverdata ) ;
844- overrideCursor ( d3 . select ( evt . target ) , hasClickToShow ? 'pointer' : '' ) ;
840+ overrideCursor ( d3 . select ( eventTarget ) , hasClickToShow ? 'pointer' : '' ) ;
845841 }
846842
847843 // don't emit events if called manually
848- if ( ! evt . target || noHoverEvent || ! hoverChanged ( gd , evt , oldhoverdata ) ) return ;
844+ if ( ! eventTarget || noHoverEvent || ! hoverChanged ( gd , evt , oldhoverdata ) ) return ;
849845
850846 if ( oldhoverdata ) {
851847 gd . emit ( 'plotly_unhover' , {
0 commit comments