Fix race condition that could cause the editor to not scroll the cursor(s) into the viewport upon loading

This commit is contained in:
Jonatan Heyman 2024-07-15 20:23:17 +02:00
parent 9ca0fabb71
commit 1f9be701b3
4 changed files with 39 additions and 33 deletions

View File

@ -136,35 +136,41 @@ export class HeynoteEditor {
} }
setContent(content) { setContent(content) {
this.note = NoteFormat.load(content) return new Promise((resolve) => {
this.note = NoteFormat.load(content)
// set buffer content
this.view.dispatch({ // set buffer content
changes: { this.view.dispatch({
from: 0, changes: {
to: this.view.state.doc.length, from: 0,
insert: this.note.content, to: this.view.state.doc.length,
}, insert: this.note.content,
annotations: [heynoteEvent.of(SET_CONTENT)], },
annotations: [heynoteEvent.of(SET_CONTENT)],
})
// Ensure we have a parsed syntax tree when buffer is loaded. This prevents errors for large buffers
// when moving the cursor to the end of the buffer when the program starts
ensureSyntaxTree(this.view.state, this.view.state.doc.length, 5000)
// Set cursor positions
// We use requestAnimationFrame to avoid a race condition causing the scrollIntoView to sometimes not work
requestAnimationFrame(() => {
if (this.note.cursors) {
this.view.dispatch({
selection: EditorSelection.fromJSON(this.note.cursors),
scrollIntoView: true,
})
} else {
// if metadata doesn't contain cursor position, we set the cursor to the end of the buffer
this.view.dispatch({
selection: {anchor: this.view.state.doc.length, head: this.view.state.doc.length},
scrollIntoView: true,
})
}
resolve()
})
}) })
// Ensure we have a parsed syntax tree when buffer is loaded. This prevents errors for large buffers
// when moving the cursor to the end of the buffer when the program starts
ensureSyntaxTree(this.view.state, this.view.state.doc.length, 5000)
// set cursor positions
if (this.note.cursors) {
this.view.dispatch({
selection: EditorSelection.fromJSON(this.note.cursors),
scrollIntoView: true,
})
} else {
// if metadata doesn't contain cursor position, we set the cursor to the end of the buffer
this.view.dispatch({
selection: {anchor: this.view.state.doc.length, head: this.view.state.doc.length},
scrollIntoView: true,
})
}
} }
getBlocks() { getBlocks() {

View File

@ -8,7 +8,7 @@ test.beforeEach(async ({page}) => {
await heynotePage.goto() await heynotePage.goto()
expect((await heynotePage.getBlocks()).length).toBe(1) expect((await heynotePage.getBlocks()).length).toBe(1)
heynotePage.setContent(` await heynotePage.setContent(`
text text
Block A Block A
text text

View File

@ -10,7 +10,7 @@ test.beforeEach(async ({ page }) => {
test("JSON formatting", async ({ page }) => { test("JSON formatting", async ({ page }) => {
heynotePage.setContent(` await heynotePage.setContent(`
json json
{"test": 1, "key2": "hey!"} {"test": 1, "key2": "hey!"}
`) `)
@ -25,7 +25,7 @@ test("JSON formatting", async ({ page }) => {
}) })
test("JSON formatting (cursor at start)", async ({ page }) => { test("JSON formatting (cursor at start)", async ({ page }) => {
heynotePage.setContent(` await heynotePage.setContent(`
json json
{"test": 1, "key2": "hey!"} {"test": 1, "key2": "hey!"}
`) `)

View File

@ -11,7 +11,7 @@ test.beforeEach(async ({ page }) => {
test("test restore cursor position", async ({ page, browserName }) => { test("test restore cursor position", async ({ page, browserName }) => {
heynotePage.setContent(`{"formatVersion":"1.0", "cursors":{"ranges":[{"anchor":13,"head":13}],"main":0}} await heynotePage.setContent(`{"formatVersion":"1.0", "cursors":{"ranges":[{"anchor":13,"head":13}],"main":0}}
text text
Textblock`) Textblock`)
await page.locator("body").press((heynotePage.isMac ? "Meta" : "Control") + "+Alt+Enter") await page.locator("body").press((heynotePage.isMac ? "Meta" : "Control") + "+Alt+Enter")
@ -24,7 +24,7 @@ block`)
test("test save cursor positions", async ({ page, browserName }) => { test("test save cursor positions", async ({ page, browserName }) => {
heynotePage.setContent(`{"formatVersion":"1.0", "cursors":{"ranges":[{"anchor":9,"head":9}],"main":0}} await heynotePage.setContent(`{"formatVersion":"1.0", "cursors":{"ranges":[{"anchor":9,"head":9}],"main":0}}
text text
this this
is is