React: Bug: DevTools DOM highlighting gets stuck after a prolonged hover

Created on 16 Jan 2020  ·  6Comments  ·  Source: facebook/react

Steps To Reproduce

  1. Hover a component in DevTools
  2. Keep hovering it for a second or so
  3. Quickly move the cursor out of the DevTools without hovering anything else

Expected: DOM highlighting goes away.
Actual: DOM highlighting gets stuck.

Developer Tools Bug

Most helpful comment

I mentioned this on Twitter, but I dug through devtools source to figure out how they were handling mouse movement & highlighting DOM elements.

It looks like the main place devtools updates the hover state is in their _onmousemove handler. This function in turn calls _highlightTreeElement which, interestingly, isn't referenced by any other event handler.

A few other methods (_onfocusout, _onmouseleave, _ondragstart, and _reset) call SDK.OverlayModel.hideDOMNodeHighlight() which, as the name implies, removes the highlight from the main page.

EDIT: Forgot to mention that I wanted to call out the different set of event handlers as the current implementation of itemData appears to bind to onMouseMove and onMouseLeave at the moment. The extra events devtools observes may also make things a bit more robust should dragging or more focus change handling be a concern for you.

All 6 comments

An easier way to trigger this:

  1. Click to select an element in the Components tree
  2. Move your mouse outside of the DevTools
  3. Click up or down arrow

The highlight will now "stick" until you focus on something else in DevTools.

TBH this is expected behavior in my mind, because it matches what the browser's Elements panel does so long as a native element is either hovered or focused. 1

If we wanted to, we could enable auto-hiding after a couple of seconds by updating Tree...
https://github.com/facebook/react/blob/95bd7aad7daa80c381faa3215c80b0906ab5ead5/packages/react-devtools-shared/src/devtools/views/Components/Tree.js#L207-L223

...to also pass hideAfterTimeout: true like SelectedElement does...
https://github.com/facebook/react/blob/95bd7aad7daa80c381faa3215c80b0906ab5ead5/packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.js#L75-L89

1 One small but maybe important difference between the two is that the native elements panel doesn't seem to leave the "stuck" highlight on mouse out. Maybe it's more reliably detecting mouse leaving the entire developer tools bounds? Maybe we could do that better somehow?

Whether its expected behavior or not the behavior between Firefox and Chrome is inconsistent since the highlighting doesn't get stuck on Firefox.

One small but maybe important difference between the two is that the native elements panel doesn't seem to leave the "stuck" highlight on mouse out.

I'm not sure I understand — this is exactly what I filed the issue about. :-) So yes, I think it is an important difference. I'm hitting this issue every day.

...to also pass hideAfterTimeout: true like SelectedElement does...

That sounds like it would always remove the highlighting after a few seconds. So it would solve this issue, but by making the other case worse. That doesn't seem like an acceptable solution to me.

Ideally, all I want is for highlighting to reliably be removed the very moment I put my cursor outside the DevTools. Just like the native one does.

I understand there are edge cases like "what if I keep using the keyboard" but I'm not hitting them all the time. By contrast, I am hitting this particular bug (inconsistently reset highlighting on mouseout) every day many times.

I spent half an hour here and I don't have even a remote idea for why the event doesn't fire. Let's ask twitter. https://twitter.com/dan_abramov/status/1222178476817633282

I mentioned this on Twitter, but I dug through devtools source to figure out how they were handling mouse movement & highlighting DOM elements.

It looks like the main place devtools updates the hover state is in their _onmousemove handler. This function in turn calls _highlightTreeElement which, interestingly, isn't referenced by any other event handler.

A few other methods (_onfocusout, _onmouseleave, _ondragstart, and _reset) call SDK.OverlayModel.hideDOMNodeHighlight() which, as the name implies, removes the highlight from the main page.

EDIT: Forgot to mention that I wanted to call out the different set of event handlers as the current implementation of itemData appears to bind to onMouseMove and onMouseLeave at the moment. The extra events devtools observes may also make things a bit more robust should dragging or more focus change handling be a concern for you.

Was this page helpful?
0 / 5 - 0 ratings