clicking buttons can cause document activeElement and selection to go out of sync
In userland code, using the onclick of a button to make programmatic changes to an editor can lead to the window's selection and the document's activeElement to go out of sync: the selection is inside the editor (and is visible as a blinking cursor), but the activeElement is still the button. When this is the case, on the next keystroke the browser will typically insert text into the editor's element (since it has a selection), but because the editor's element is not the activeElement, the key* handlers that the editor has installed on its element will not fire. This usually results in dom mutations that the editor has to attempt to handle using its Mutation Observer code, and sometimes can lead to errors.
There are other ways for the selection and activeElement to go out of sync, but via a button click seems like a common case.
The editor already has some code to handle this case when triggering markup changes. Two things need to happen:
- The selection manager needs to be updated to be aware of when the document's activeElement changes (and especially when it goes out of sync w/ the window's selection)
- The editor's
_ensureFocusmethod needs to get called when the editor has selection but not focus
To workaround this problem, the editor's element can be explicitly refocused (editor.element.focus()) in button onclick handlers if the editor is blank. If the editor is not blank, explicitly setting the editor's range (e.g. editor.selectRange(editor.post.tailPosition())) will suffice.
cc @rlivsey
This might be some strange combination of mobiledoc, ember-basic-dropdown and, bizzarely, ember-composable-helpers.
When I changed the button from:
<button {{action (pipe (action on-insert type.type) dd.actions.close)}}>
to
<button {{action "selectType" type.type dd}}>
and call dd.actions.close inside the standard action in the component, the issue goes away and I can remove the runloop hack we played with.
It's very strange and I'm digging in some more to try and get a reproduction of exactly what's going on that gets it into the state where mobiledoc has to deal with split focus.
@rlivsey I'm going to add some more guard code to keep the editor's element focused and in sync w/ the selection. But did you were you able to create a reproduction when looking into ember-basic-dropdown and ember-composable-helpers?
I wasn't unfortunately, no.
Might be able to spend some more time figuring it out, but if you add the guard clause I can go back to that version of our app and see if that fixes it.
Agree it'd be nice to have a repro though!