I would like to add decorations to my editor. I am hitting an issue when doing so shortly after user has switched away from the editor brings the focus back to the editor. I see that view.dispatch({effects});
triggers focus/focusIn event breaking signal cascade in my application:
where index.js
in trace above is CodeMirror’s code (most recent at the top). Based on the trace, it appears related to updating selections.
It is reproducible using Chrome in playground using minimally modified Decoration
example from documentation (link to playground):
import { Decoration, EditorView, keymap } from "@codemirror/view"
import { StateField, StateEffect } from "@codemirror/state"
const addUnderline = StateEffect.define({
map: ({from, to}, change) => ({from: change.mapPos(from), to: change.mapPos(to)})
})
const underlineField = StateField.define({
create() {
return Decoration.none
},
update(underlines, tr) {
underlines = underlines.map(tr.changes)
for (let e of tr.effects) if (e.is(addUnderline)) {
underlines = underlines.update({
add: [underlineMark.range(e.value.from, e.value.to)]
})
}
return underlines
},
provide: f => EditorView.decorations.from(f)
})
const underlineMark = Decoration.mark({class: "cm-underline"})
const underlineTheme = EditorView.baseTheme({
".cm-underline": { textDecoration: "underline 3px red" }
})
export function underlineSelection(view) {
let effects = view.state.selection.ranges
.filter(r => !r.empty)
.map(({from, to}) => addUnderline.of({from, to}))
if (!effects.length) return false
if (!view.state.field(underlineField, false))
effects.push(StateEffect.appendConfig.of([underlineField,
underlineTheme]))
console.log('will blur', document.activeElement)
document.activeElement.blur();
console.log('active element before dispatch:', document.activeElement)
view.dispatch({effects});
console.log('active element after dispatch:', document.activeElement)
return true
}
export const underlineKeymap = keymap.of([{
key: "Mod-h",
preventDefault: true,
run: underlineSelection
}])
new EditorView({
doc: "Select text and press Ctrl-h (Cmd-h) to add an underline\nto it.\n",
extensions: [underlineKeymap],
parent: document.body
})
After underlining a selection it logs:
will blur HTMLDivElement {cmView: DocView {parent: null, …}}
active element before dispatch: HTMLBodyElement {}
active element after dispatch: HTMLDivElement {cmView: DocView {parent: null, …}}
But I expected it to be:
will blur HTMLDivElement {cmView: DocView {parent: null, …}}
active element before dispatch: HTMLBodyElement {}
active element after dispatch: HTMLBodyElement {}
Am I missing something, or is this a buglet?