I hope you kept the part using beforeinput events instead of mutation observers in a branch somewhere. The solution you describe should currently work most places, except IME/Android. Once EditContext ships in Chrome (supposedly later this year) the approach should even work on IME/Android (on Chromium). So unless browser makers change directions in the last minute, as they have done in the past, this approach should be the way all editor apps work in the near future.