kokhlo commented on issue #44371:
URL: https://github.com/apache/superset/issues/44371#issuecomment-5709694881
I dug into this on current master — the mechanism survives the react-ace 10
→ 15 upgrade, in a slightly different flavor.
What happens on master (SQL Lab path):
- `EditorWrapper` renders a fully controlled editor: `value={sql}` +
`onChange` (`src/SqlLab/components/EditorWrapper/index.tsx`), backed by
`EditorHost` → `AceEditorProvider` → react-ace
(`src/core/editors/AceEditorProvider.tsx`).
- With N cursors, Ace applies a keystroke per selection
(`forEachSelection`), so the session `change` event fires N times with N
intermediate document values, and only the last one is the final text. Every
firing goes straight through `onChange` → `setSql` + redux dispatch.
- Whenever React renders with an intermediate value while the editor already
holds the final one, react-ace's `componentDidUpdate` sees `getValue() !==
props.value` and calls `editor.setValue(...)` mid-keystroke. That is the
`setValue(intermediateText, 1)` + `navigateFileEnd()` pair from your trace. On
master (react-ace 15) there is a save/restore around it, but it uses
`selection.toJSON()/fromJSON()`, which is a single-range API — a
multi-selection collapses to its first range. Either way the extra cursors are
destroyed mid-keystroke, and subsequent characters land wherever the surviving
cursor points (document end in your 6.0.0 trace).
Fix plan, in `AceEditorProvider` so every editor surface benefits: coalesce
change emissions per keystroke — buffer the latest editor value and call the
consumer `onChange` once per microtask batch. Intermediate per-selection values
then never reach the controlled `value` prop, `getValue() === props.value`
holds at every render, and react-ace's out-of-band `setValue` never fires while
typing. Programmatic value changes (format SQL etc.) keep the existing
single-range restore path, which is correct for single-cursor restores.
Regression test: simulate multi-cursor typing by firing `onChange` twice
synchronously (intermediate value, then final) and assert the provider emits
exactly once with the final value — that assertion fails on current master.
PR within the hour.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]