Skip to content

Commit

Permalink
Fix wrong cursor position after inserting new blocks at the top of th…
Browse files Browse the repository at this point in the history
…e buffer, when the previous first block's delimiter is long (e.g. Markdown)
  • Loading branch information
heyman committed Jan 1, 2024
1 parent bf1ce2f commit fc31a27
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/editor/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ export const heynoteEvent = Annotation.define()
export const LANGUAGE_CHANGE = "heynote-change"
export const CURRENCIES_LOADED = "heynote-currencies-loaded"
export const SET_CONTENT = "heynote-set-content"

export const ADD_NEW_BLOCK = "heynote-add-new-block"
2 changes: 1 addition & 1 deletion src/editor/block/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ const preventFirstBlockFromBeingDeleted = EditorState.changeFilter.of((tr) => {
* Transaction filter to prevent the selection from being before the first block
*/
const preventSelectionBeforeFirstBlock = EditorState.transactionFilter.of((tr) => {
if (!firstBlockDelimiterSize) {
if (!firstBlockDelimiterSize || tr.annotations.some(a => a.type === heynoteEvent)) {
return tr
}
tr?.selection?.ranges.forEach(range => {
Expand Down
8 changes: 5 additions & 3 deletions src/editor/block/commands.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EditorSelection } from "@codemirror/state"
import { heynoteEvent, LANGUAGE_CHANGE, CURRENCIES_LOADED } from "../annotation.js";
import { heynoteEvent, LANGUAGE_CHANGE, CURRENCIES_LOADED, ADD_NEW_BLOCK } from "../annotation.js";
import {blockState, getActiveNoteBlock, getFirstNoteBlock, getLastNoteBlock, getNoteBlockFromPos} from "./block"
import { moveLineDown, moveLineUp } from "./move-lines.js";
import { selectAll } from "./select-all.js";
Expand Down Expand Up @@ -40,7 +40,8 @@ export const addNewBlockBeforeCurrent = ({ state, dispatch }) => {
from: block.delimiter.from,
insert: delimText,
},
selection: EditorSelection.cursor(block.delimiter.from + delimText.length)
selection: EditorSelection.cursor(block.delimiter.from + delimText.length),
annotations: [heynoteEvent.of(ADD_NEW_BLOCK)],
}, {
scrollIntoView: true,
userEvent: "input",
Expand Down Expand Up @@ -78,7 +79,8 @@ export const addNewBlockBeforeFirst = ({ state, dispatch }) => {
from: block.delimiter.from,
insert: delimText,
},
selection: EditorSelection.cursor(delimText.length) // TODO: fix jump. See first char of file when saving
selection: EditorSelection.cursor(delimText.length),
annotations: [heynoteEvent.of(ADD_NEW_BLOCK)],
}, {
scrollIntoView: true,
userEvent: "input",
Expand Down
4 changes: 4 additions & 0 deletions src/editor/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ export class HeynoteEditor {
return this.view.state.facet(blockState)
}

getCursorPosition() {
return this.view.state.selection.main.head
}

focus() {
this.view.focus()
}
Expand Down
28 changes: 26 additions & 2 deletions tests/block-creation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Block C`)
expect((await heynotePage.getBlocks()).length).toBe(3)

// check that visual block layers are created
expect(await page.locator("css=.heynote-blocks-layer > div")).toHaveCount(3)
await expect(page.locator("css=.heynote-blocks-layer > div")).toHaveCount(3)

// select the second block
await page.locator("body").press("ArrowUp")
Expand All @@ -43,6 +43,30 @@ test("create block after last", async ({ page }) => {
await runTest(page, heynotePage.isMac ? "Meta+Shift+Enter" : "Control+Shift+Enter",['A', 'B', 'C', 'D'])
})

test("create block before Markdown block", async ({ page }) => {
await heynotePage.setContent(`
∞∞∞markdown
# Markdown!
`)
await page.locator("body").press("Alt+Enter")
await page.waitForTimeout(100);
expect(await heynotePage.getCursorPosition()).toBe(11)
})

test("create block before first Markdown block", async ({ page }) => {
await heynotePage.setContent(`
∞∞∞markdown
# Markdown!
∞∞∞text
`)
for (let i=0; i<5; i++) {
await page.locator("body").press("ArrowDown")
}
await page.locator("body").press("Alt+Shift+Enter")
await page.waitForTimeout(100);
expect(await heynotePage.getCursorPosition()).toBe(11)
})

const runTest = async (page, key, expectedBlocks) => {
// create a new block
await page.locator("body").press(key)
Expand All @@ -59,6 +83,6 @@ const runTest = async (page, key, expectedBlocks) => {
}

// check that only one block delimiter widget has the class first
expect(await page.locator("css=.heynote-block-start.first")).toHaveCount(1)
await expect(await page.locator("css=.heynote-block-start.first")).toHaveCount(1)
}

4 changes: 4 additions & 0 deletions tests/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export class HeynotePage {
await this.page.evaluate((content) => window._heynote_editor.setContent(content), content)
}

async getCursorPosition() {
return await this.page.evaluate(() => window._heynote_editor.getCursorPosition())
}

async getBlockContent(blockIndex) {
const blocks = await this.getBlocks()
const content = await this.getContent()
Expand Down

0 comments on commit fc31a27

Please sign in to comment.