I tried two other strategies (unsuccesfully):
Instead of putting a marked range around the footnote marker
Main text<mR><span class="footnote" data-contents="The footnote">¹</span></mR>
which lead to the marked range becoming empty when using tr.replaceWith to exchange the footnote (in order to exchange the contents attribute of it):
Main text<span class="footnote" data-contents="The changed footnote">¹</span><mR></mR>
I set removeWhenEmpty: false and put an empty marked range in front of it, like this:
Main text<mR></mR><span class="footnote" data-contents="The footnote">¹</span>
The good thing was that now the marked range was no longer being emptied when the footnote was updated. Unfortunately, tr.replaceWith now caused the marked range to be moved after the footnote when it was exchanged:
Main text<span class="footnote" data-contents="The changed footnote">¹</span><mR></mR>
So then I tried putting the empty marked range behind the footnote marker:
Main text<span class="footnote" data-contents="The footnote">¹</span><mR></mR>
The good thing was that now the marked range would not be touched when updating the footnote:
Main text<span class="footnote" data-contents="The changed footnote">¹</span><mR></mR>
But unfortunately it was now no longer possible to remove the marked range by any conventional means. For example, selecting this part (seleciton = [])
Main t[ext<span class="footnote" data-contents="The changed footnote">¹</span><mR></mR> main text contin]uation
And hitting backspace resulted in:
Main t<mR></mR>uation