Skip to content

search query input: Better handle CodeMirror extensions derived from props

Administrator requested to merge fkling/37721-query-input-freeze into main

Created by: fkling

Fixes #37721 (closed)

Please read this comment from the issue for more information about what causes the problem.

tl;dr: onChange changed after onBlur was called, which caused a group of extensions to be re-created, including the onBlur DOM event handler, which caused it to fire as along as the editor wasn't focused (go back to the beginning).

This PR introduces a couple of changes to prevent unexpected issues with recreating CodeMirror extensions:

  • At the Monaco facade level, all callbacks are "bound" via state fields. That means that extensions are not recreated (and the editor is not reconfigured) when any of the callback functions change. The downside is that extensions cannot be conditionally created depending on whether a callback was provided or not (e.g. there is always an event handler bound for Mod+k even if onHandleFuzzyFinder is not provided), but luckily CodeMirror provides ways to indicate that an event wasn't handled by the extension (e.g. returning false from the keybinding handler).
  • onFocus and onBlur event handlers are now triggered from the state update handler (as it was before) instead of DOM event handlers, to prevent them from being accidentally triggered, which was the cause for the Code Insights creation form freeze up.
  • The "core" CodeMirror query input also switches to using a compartment for the theme setting. With this any extension created by the component itself won't ever be re-created. All extensions derived from props are updated via transactions.

I'm also including a minor CSS fix. Without it the actual input doesn't expand to the whole width of the container and clicking inside what appears to be the input field doesn't focus to actual input.

Test plan

Go to https://sourcegraph.test:3443/insights/create/search?dashboardId=all and create a new code insight. Go to the search query input. Type something, leave the input. The page does not freeze.

App preview:

Check out the client app preview documentation to learn more.

Merge request reports

Loading