-
-
Notifications
You must be signed in to change notification settings - Fork 459
Closed
Description
CodeMirror view jumps when programatically inserting text when the following conditions are met:
- Document is long enough for vertical scrollbar to appear
- lineWrapping is enabled
- Document is scrolled to the very bottom / last line of the document is visible
- Text is programatically inserted using replaceSelection or a similar method
- The inserted text contains fragments that get replaced with replace decorations
Code to reproduce this:
import { basicSetup, EditorView } from "codemirror"
import { drawSelection, highlightActiveLine, keymap, lineNumbers, MatchDecorator, WidgetType } from "@codemirror/view"
import { Decoration, ViewPlugin, ViewUpdate } from "@codemirror/view"
import { standardKeymap } from "@codemirror/commands"
const placeholderMatcher = new MatchDecorator({
regexp: /\[\[(\w+)\]\]/g,
decoration: match => Decoration.replace({
widget: new PlaceholderWidget(match[1]),
//inclusive: true,
})
})
const placeholders = ViewPlugin.fromClass(class {
constructor(view) {
this.placeholders = placeholderMatcher.createDeco(view)
}
update(update) {
this.placeholders = placeholderMatcher.updateDeco(update, this.placeholders)
}
}, {
decorations: instance => instance.placeholders,
provide: plugin => EditorView.atomicRanges.of(view => {
return view.plugin(plugin)?.placeholders || Decoration.none
})
})
class PlaceholderWidget extends WidgetType {
constructor(repr) {
super()
this.repr = repr
}
eq(other) {
return this.repr === other.repr
}
toDOM() {
const dom = document.createElement("span")
this.updateDOMInner(dom)
return dom
}
ignoreEvent() { return false }
updateDOM(dom, view) {
this.updateDOMInner(dom)
return true
}
updateDOMInner(dom) {
dom.textContent = this.repr
}
}
const KB_TEST = {
key: "Ctrl-.",
run: (view) => {
const text = '[[boopbooopbooop]]'
const spec = view.state.replaceSelection(text)
const tr = view.state.update(spec)
view.update([tr])
return true
},
};
const start = "foo\n".repeat(200)
const middle = "z = [[boopbooopbooop]] + [[boopbooopbooop]] + \n"
const end = "\n".repeat(10)
const doc = [start, middle, end].join('')
new EditorView({
doc,
parent: document.body,
extensions: [
drawSelection(),
highlightActiveLine(),
lineNumbers(),
keymap.of([KB_TEST, ...standardKeymap]),
placeholders,
EditorView.lineWrapping,
],
})
Steps to reproduce the problem using the code provided:
- Run the code in CodeMirror sandbox
- Scroll to the very bottom so the last line of the document (line 212) is visible.
- Go to the end of line 201
- Press Ctrl+. to activate KB_TEST keybinding, which will insert '[[boopbooopbooop]]' at the cursor position
- The document scrolls up on its own and the last line (212) is no longer visible.
The issue happens both on Firefox and Chromium-based browsers.
Metadata
Metadata
Assignees
Labels
No labels