mirror of
https://github.com/heyman/heynote.git
synced 2025-06-27 21:12:00 +02:00
Merge pull request #204 from wolimst/feat/move-block
Add feature for moving the current block up and down
This commit is contained in:
commit
74558769e0
@ -9,6 +9,7 @@ Here are the most notable changes in each release. For a more detailed list of c
|
|||||||
- Added support for custom key bindings. See [the documentation](https://heynote.com/docs/#user-content-custom-key-bindings) for more info.
|
- Added support for custom key bindings. See [the documentation](https://heynote.com/docs/#user-content-custom-key-bindings) for more info.
|
||||||
- Added a "command palette" that can be accessed by pressing `Ctrl/Cmd+Shift+P`, or just typing `>` in the buffer selector. The command palette allows you to discover all available commands in the app, and to quickly execute them.
|
- Added a "command palette" that can be accessed by pressing `Ctrl/Cmd+Shift+P`, or just typing `>` in the buffer selector. The command palette allows you to discover all available commands in the app, and to quickly execute them.
|
||||||
- Added support for configuring the tab size.
|
- Added support for configuring the tab size.
|
||||||
|
- Added functionality for moving blocks up and down. Default key bindings are `Ctrl/Cmd+Alt+Shift+Up` and `Ctrl/Cmd+Alt+Shift+Down`.
|
||||||
|
|
||||||
### Other changes
|
### Other changes
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ export const LANGUAGE_CHANGE = "heynote-change"
|
|||||||
export const CURRENCIES_LOADED = "heynote-currencies-loaded"
|
export const CURRENCIES_LOADED = "heynote-currencies-loaded"
|
||||||
export const SET_CONTENT = "heynote-set-content"
|
export const SET_CONTENT = "heynote-set-content"
|
||||||
export const ADD_NEW_BLOCK = "heynote-add-new-block"
|
export const ADD_NEW_BLOCK = "heynote-add-new-block"
|
||||||
|
export const MOVE_BLOCK = "heynote-move-block"
|
||||||
export const DELETE_BLOCK = "heynote-delete-block"
|
export const DELETE_BLOCK = "heynote-delete-block"
|
||||||
export const CURSOR_CHANGE = "heynote-cursor-change"
|
export const CURSOR_CHANGE = "heynote-cursor-change"
|
||||||
export const APPEND_BLOCK = "heynote-append-block"
|
export const APPEND_BLOCK = "heynote-append-block"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { EditorSelection, Transaction } from "@codemirror/state"
|
import { EditorSelection, Transaction } from "@codemirror/state"
|
||||||
|
|
||||||
import { heynoteEvent, LANGUAGE_CHANGE, CURRENCIES_LOADED, ADD_NEW_BLOCK, DELETE_BLOCK } from "../annotation.js";
|
import { heynoteEvent, LANGUAGE_CHANGE, CURRENCIES_LOADED, ADD_NEW_BLOCK, MOVE_BLOCK, DELETE_BLOCK } from "../annotation.js";
|
||||||
import { blockState, getActiveNoteBlock, getFirstNoteBlock, getLastNoteBlock, getNoteBlockFromPos } from "./block"
|
import { blockState, getActiveNoteBlock, getFirstNoteBlock, getLastNoteBlock, getNoteBlockFromPos } from "./block"
|
||||||
import { moveLineDown, moveLineUp } from "./move-lines.js";
|
import { moveLineDown, moveLineUp } from "./move-lines.js";
|
||||||
import { selectAll } from "./select-all.js";
|
import { selectAll } from "./select-all.js";
|
||||||
@ -322,6 +322,62 @@ export function triggerCurrenciesLoaded(state, dispatch) {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function moveCurrentBlockUp({state, dispatch}) {
|
||||||
|
return moveCurrentBlock(state, dispatch, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function moveCurrentBlockDown({state, dispatch}) {
|
||||||
|
return moveCurrentBlock(state, dispatch, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveCurrentBlock(state, dispatch, up) {
|
||||||
|
if (state.readOnly) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const blocks = state.facet(blockState)
|
||||||
|
const currentBlock = getActiveNoteBlock(state)
|
||||||
|
const blockIndex = blocks.indexOf(currentBlock)
|
||||||
|
if ((up && blockIndex === 0) || (!up && blockIndex === blocks.length - 1)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const dir = up ? -1 : 1
|
||||||
|
const neighborBlock = blocks[blockIndex + dir]
|
||||||
|
|
||||||
|
const currentBlockContent = state.sliceDoc(currentBlock.delimiter.from, currentBlock.content.to)
|
||||||
|
const neighborBlockContent = state.sliceDoc(neighborBlock.delimiter.from, neighborBlock.content.to)
|
||||||
|
const newContent = up ? currentBlockContent + neighborBlockContent : neighborBlockContent + currentBlockContent
|
||||||
|
|
||||||
|
const selectionRange = state.selection.asSingle().ranges[0]
|
||||||
|
let newSelectionRange
|
||||||
|
if (up) {
|
||||||
|
newSelectionRange = EditorSelection.range(
|
||||||
|
selectionRange.anchor - currentBlock.delimiter.from + neighborBlock.delimiter.from,
|
||||||
|
selectionRange.head - currentBlock.delimiter.from + neighborBlock.delimiter.from,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
newSelectionRange = EditorSelection.range(
|
||||||
|
selectionRange.anchor + neighborBlock.content.to - neighborBlock.delimiter.from,
|
||||||
|
selectionRange.head + neighborBlock.content.to - neighborBlock.delimiter.from,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(state.update({
|
||||||
|
changes: {
|
||||||
|
from: up ? neighborBlock.delimiter.from : currentBlock.delimiter.from,
|
||||||
|
to: up ? currentBlock.content.to : neighborBlock.content.to,
|
||||||
|
insert: newContent,
|
||||||
|
},
|
||||||
|
selection: newSelectionRange,
|
||||||
|
annotations: [heynoteEvent.of(MOVE_BLOCK)],
|
||||||
|
}, {
|
||||||
|
scrollIntoView: true,
|
||||||
|
userEvent: "input",
|
||||||
|
}))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
export const deleteBlock = (editor) => ({state, dispatch}) => {
|
export const deleteBlock = (editor) => ({state, dispatch}) => {
|
||||||
const range = state.selection.asSingle().ranges[0]
|
const range = state.selection.asSingle().ranges[0]
|
||||||
const blocks = state.facet(blockState)
|
const blocks = state.facet(blockState)
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
selectAll,
|
selectAll,
|
||||||
deleteBlock, deleteBlockSetCursorPreviousBlock,
|
deleteBlock, deleteBlockSetCursorPreviousBlock,
|
||||||
newCursorBelow, newCursorAbove,
|
newCursorBelow, newCursorAbove,
|
||||||
|
moveCurrentBlockUp, moveCurrentBlockDown,
|
||||||
} from "./block/commands.js"
|
} from "./block/commands.js"
|
||||||
import { deleteLine } from "./block/delete-line.js"
|
import { deleteLine } from "./block/delete-line.js"
|
||||||
import { formatBlockContent } from "./block/format-code.js"
|
import { formatBlockContent } from "./block/format-code.js"
|
||||||
@ -85,6 +86,8 @@ const HEYNOTE_COMMANDS = {
|
|||||||
insertNewBlockAtCursor: cmd(insertNewBlockAtCursor, "Block", "Insert new block at cursor"),
|
insertNewBlockAtCursor: cmd(insertNewBlockAtCursor, "Block", "Insert new block at cursor"),
|
||||||
deleteBlock: cmd(deleteBlock, "Block", "Delete block"),
|
deleteBlock: cmd(deleteBlock, "Block", "Delete block"),
|
||||||
deleteBlockSetCursorPreviousBlock: cmd(deleteBlockSetCursorPreviousBlock, "Block", "Delete block and set cursor to previous block"),
|
deleteBlockSetCursorPreviousBlock: cmd(deleteBlockSetCursorPreviousBlock, "Block", "Delete block and set cursor to previous block"),
|
||||||
|
moveCurrentBlockUp: cmdLessContext(moveCurrentBlockUp, "Block", "Move current block up"),
|
||||||
|
moveCurrentBlockDown: cmdLessContext(moveCurrentBlockDown, "Block", "Move current block down"),
|
||||||
cursorPreviousBlock: cmd(cursorPreviousBlock, "Cursor", "Move cursor to previous block"),
|
cursorPreviousBlock: cmd(cursorPreviousBlock, "Cursor", "Move cursor to previous block"),
|
||||||
cursorNextBlock: cmd(cursorNextBlock, "Cursor", "Move cursor to next block"),
|
cursorNextBlock: cmd(cursorNextBlock, "Cursor", "Move cursor to next block"),
|
||||||
cursorPreviousParagraph: cmd(cursorPreviousParagraph, "Cursor", "Move cursor to previous paragraph"),
|
cursorPreviousParagraph: cmd(cursorPreviousParagraph, "Cursor", "Move cursor to previous paragraph"),
|
||||||
|
@ -40,6 +40,8 @@ export const DEFAULT_KEYMAP = [
|
|||||||
...cmdShift("PageDown", "cursorPageDown", "selectPageDown"),
|
...cmdShift("PageDown", "cursorPageDown", "selectPageDown"),
|
||||||
...cmdShift("Home", "cursorLineBoundaryBackward", "selectLineBoundaryBackward"),
|
...cmdShift("Home", "cursorLineBoundaryBackward", "selectLineBoundaryBackward"),
|
||||||
...cmdShift("End", "cursorLineBoundaryForward", "selectLineBoundaryForward"),
|
...cmdShift("End", "cursorLineBoundaryForward", "selectLineBoundaryForward"),
|
||||||
|
cmd("Alt-Mod-Shift-ArrowUp", "moveCurrentBlockUp"),
|
||||||
|
cmd("Alt-Mod-Shift-ArrowDown", "moveCurrentBlockDown"),
|
||||||
cmd("Backspace", "deleteCharBackward"),
|
cmd("Backspace", "deleteCharBackward"),
|
||||||
cmd("Delete", "deleteCharForward"),
|
cmd("Delete", "deleteCharForward"),
|
||||||
cmd("Escape", "simplifySelection"),
|
cmd("Escape", "simplifySelection"),
|
||||||
|
125
tests/move-block-between-buffers.spec.js
Normal file
125
tests/move-block-between-buffers.spec.js
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
import {expect, test} from "@playwright/test";
|
||||||
|
import {HeynotePage} from "./test-utils.js";
|
||||||
|
|
||||||
|
import { AUTO_SAVE_INTERVAL } from "../src/common/constants.js"
|
||||||
|
import { NoteFormat } from "../src/common/note-format.js"
|
||||||
|
|
||||||
|
|
||||||
|
let heynotePage
|
||||||
|
|
||||||
|
test.beforeEach(async ({page}) => {
|
||||||
|
heynotePage = new HeynotePage(page)
|
||||||
|
await heynotePage.goto()
|
||||||
|
|
||||||
|
expect((await heynotePage.getBlocks()).length).toBe(1)
|
||||||
|
await heynotePage.setContent(`
|
||||||
|
∞∞∞text
|
||||||
|
Block A
|
||||||
|
∞∞∞text
|
||||||
|
Block B
|
||||||
|
∞∞∞text
|
||||||
|
Block C`)
|
||||||
|
await page.waitForTimeout(100);
|
||||||
|
// check that blocks are created
|
||||||
|
expect((await heynotePage.getBlocks()).length).toBe(3)
|
||||||
|
|
||||||
|
// check that visual block layers are created
|
||||||
|
await expect(page.locator("css=.heynote-blocks-layer > div")).toHaveCount(3)
|
||||||
|
|
||||||
|
// create secondary buffer
|
||||||
|
await heynotePage.saveBuffer("other.txt", `
|
||||||
|
∞∞∞text-a
|
||||||
|
First block
|
||||||
|
∞∞∞math
|
||||||
|
Second block`)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test("move block to other buffer", async ({page}) => {
|
||||||
|
await page.locator("body").press(heynotePage.agnosticKey("Mod+S"))
|
||||||
|
await page.waitForTimeout(50)
|
||||||
|
await page.locator("body").press("Enter")
|
||||||
|
await page.waitForTimeout(AUTO_SAVE_INTERVAL + 50);
|
||||||
|
|
||||||
|
const buffers = Object.keys(await heynotePage.getStoredBufferList())
|
||||||
|
expect(buffers).toContain("other.txt")
|
||||||
|
|
||||||
|
const otherBuffer = NoteFormat.load(await heynotePage.getStoredBuffer("other.txt"))
|
||||||
|
|
||||||
|
expect(await heynotePage.getContent()).toBe(`
|
||||||
|
∞∞∞text
|
||||||
|
Block A
|
||||||
|
∞∞∞text
|
||||||
|
Block B`)
|
||||||
|
|
||||||
|
expect(otherBuffer.content).toBe(`
|
||||||
|
∞∞∞text-a
|
||||||
|
First block
|
||||||
|
∞∞∞math
|
||||||
|
Second block
|
||||||
|
∞∞∞text
|
||||||
|
Block C`)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
test("move block to other open/cached buffer", async ({page}) => {
|
||||||
|
await page.locator("body").press(heynotePage.agnosticKey("Mod+P"))
|
||||||
|
await page.locator("body").press("Enter")
|
||||||
|
await page.waitForTimeout(50)
|
||||||
|
await page.locator("body").press(heynotePage.agnosticKey("Mod+P"))
|
||||||
|
await page.locator("body").press("Enter")
|
||||||
|
await page.waitForTimeout(50)
|
||||||
|
await page.locator("body").press(heynotePage.agnosticKey("Mod+S"))
|
||||||
|
await page.waitForTimeout(50)
|
||||||
|
await page.locator("body").press("Enter")
|
||||||
|
await page.waitForTimeout(AUTO_SAVE_INTERVAL + 50);
|
||||||
|
|
||||||
|
const buffers = Object.keys(await heynotePage.getStoredBufferList())
|
||||||
|
expect(buffers).toContain("other.txt")
|
||||||
|
|
||||||
|
const otherBuffer = NoteFormat.load(await heynotePage.getStoredBuffer("other.txt"))
|
||||||
|
|
||||||
|
expect(await heynotePage.getContent()).toBe(`
|
||||||
|
∞∞∞text
|
||||||
|
Block A
|
||||||
|
∞∞∞text
|
||||||
|
Block B`)
|
||||||
|
|
||||||
|
expect(otherBuffer.content).toBe(`
|
||||||
|
∞∞∞text-a
|
||||||
|
First block
|
||||||
|
∞∞∞math
|
||||||
|
Second block
|
||||||
|
∞∞∞text
|
||||||
|
Block C`)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
test("cursor position after moving first block", async ({page}) => {
|
||||||
|
await heynotePage.setCursorPosition(10)
|
||||||
|
expect(await heynotePage.getCursorPosition()).toBe(10)
|
||||||
|
await page.locator("body").press(heynotePage.agnosticKey("Mod+S"))
|
||||||
|
await page.waitForTimeout(50)
|
||||||
|
await page.locator("body").press("Enter")
|
||||||
|
await page.waitForTimeout(50)
|
||||||
|
expect(await heynotePage.getCursorPosition()).toBe(9)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("cursor position after moving middle block", async ({page}) => {
|
||||||
|
await heynotePage.setCursorPosition(28)
|
||||||
|
await page.locator("body").press(heynotePage.agnosticKey("Mod+S"))
|
||||||
|
await page.waitForTimeout(50)
|
||||||
|
await page.locator("body").press("Enter")
|
||||||
|
await page.waitForTimeout(50)
|
||||||
|
expect(await heynotePage.getCursorPosition()).toBe(25)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("cursor position after moving last block", async ({page}) => {
|
||||||
|
await heynotePage.setCursorPosition(48)
|
||||||
|
await page.locator("body").press(heynotePage.agnosticKey("Mod+S"))
|
||||||
|
await page.waitForTimeout(50)
|
||||||
|
await page.locator("body").press("Enter")
|
||||||
|
await page.waitForTimeout(50)
|
||||||
|
expect(await heynotePage.getCursorPosition()).toBe(32)
|
||||||
|
})
|
@ -1,13 +1,9 @@
|
|||||||
import {expect, test} from "@playwright/test";
|
import { expect, test } from "@playwright/test"
|
||||||
import {HeynotePage} from "./test-utils.js";
|
import { HeynotePage } from "./test-utils.js"
|
||||||
|
|
||||||
import { AUTO_SAVE_INTERVAL } from "../src/common/constants.js"
|
|
||||||
import { NoteFormat } from "../src/common/note-format.js"
|
|
||||||
|
|
||||||
|
|
||||||
let heynotePage
|
let heynotePage
|
||||||
|
|
||||||
test.beforeEach(async ({page}) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
heynotePage = new HeynotePage(page)
|
heynotePage = new HeynotePage(page)
|
||||||
await heynotePage.goto()
|
await heynotePage.goto()
|
||||||
|
|
||||||
@ -19,107 +15,97 @@ Block A
|
|||||||
Block B
|
Block B
|
||||||
∞∞∞text
|
∞∞∞text
|
||||||
Block C`)
|
Block C`)
|
||||||
await page.waitForTimeout(100);
|
|
||||||
// check that blocks are created
|
// check that blocks are created
|
||||||
expect((await heynotePage.getBlocks()).length).toBe(3)
|
expect((await heynotePage.getBlocks()).length).toBe(3)
|
||||||
|
|
||||||
// check that visual block layers are created
|
// check that visual block layers are created
|
||||||
await expect(page.locator("css=.heynote-blocks-layer > div")).toHaveCount(3)
|
await expect(page.locator("css=.heynote-blocks-layer > div")).toHaveCount(3)
|
||||||
|
|
||||||
// create secondary buffer
|
|
||||||
await heynotePage.saveBuffer("other.txt", `
|
|
||||||
∞∞∞text-a
|
|
||||||
First block
|
|
||||||
∞∞∞math
|
|
||||||
Second block`)
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
test("move block to other buffer", async ({page}) => {
|
|
||||||
await page.locator("body").press(heynotePage.agnosticKey("Mod+S"))
|
|
||||||
await page.waitForTimeout(50)
|
|
||||||
await page.locator("body").press("Enter")
|
|
||||||
await page.waitForTimeout(AUTO_SAVE_INTERVAL + 50);
|
|
||||||
|
|
||||||
const buffers = Object.keys(await heynotePage.getStoredBufferList())
|
|
||||||
expect(buffers).toContain("other.txt")
|
|
||||||
|
|
||||||
const otherBuffer = NoteFormat.load(await heynotePage.getStoredBuffer("other.txt"))
|
|
||||||
|
|
||||||
expect(await heynotePage.getContent()).toBe(`
|
|
||||||
∞∞∞text
|
|
||||||
Block A
|
|
||||||
∞∞∞text
|
|
||||||
Block B`)
|
|
||||||
|
|
||||||
expect(otherBuffer.content).toBe(`
|
|
||||||
∞∞∞text-a
|
|
||||||
First block
|
|
||||||
∞∞∞math
|
|
||||||
Second block
|
|
||||||
∞∞∞text
|
|
||||||
Block C`)
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("move the first block up", async ({ page }) => {
|
||||||
|
// select the first block, cursor position: "Block A|"
|
||||||
|
await page.locator("body").press("ArrowUp")
|
||||||
|
await page.locator("body").press("ArrowUp")
|
||||||
|
|
||||||
test("move block to other open/cached buffer", async ({page}) => {
|
await page.locator("body").press(`${heynotePage.isMac ? "Meta" : "Control"}+Shift+Alt+ArrowUp`)
|
||||||
await page.locator("body").press(heynotePage.agnosticKey("Mod+P"))
|
const cursorPosition = await heynotePage.getCursorPosition()
|
||||||
await page.locator("body").press("Enter")
|
const content = await heynotePage.getContent()
|
||||||
await page.waitForTimeout(50)
|
|
||||||
await page.locator("body").press(heynotePage.agnosticKey("Mod+P"))
|
|
||||||
await page.locator("body").press("Enter")
|
|
||||||
await page.waitForTimeout(50)
|
|
||||||
await page.locator("body").press(heynotePage.agnosticKey("Mod+S"))
|
|
||||||
await page.waitForTimeout(50)
|
|
||||||
await page.locator("body").press("Enter")
|
|
||||||
await page.waitForTimeout(AUTO_SAVE_INTERVAL + 50);
|
|
||||||
|
|
||||||
const buffers = Object.keys(await heynotePage.getStoredBufferList())
|
|
||||||
expect(buffers).toContain("other.txt")
|
|
||||||
|
|
||||||
const otherBuffer = NoteFormat.load(await heynotePage.getStoredBuffer("other.txt"))
|
|
||||||
|
|
||||||
expect(await heynotePage.getContent()).toBe(`
|
|
||||||
∞∞∞text
|
|
||||||
Block A
|
|
||||||
∞∞∞text
|
|
||||||
Block B`)
|
|
||||||
|
|
||||||
expect(otherBuffer.content).toBe(`
|
|
||||||
∞∞∞text-a
|
|
||||||
First block
|
|
||||||
∞∞∞math
|
|
||||||
Second block
|
|
||||||
∞∞∞text
|
|
||||||
Block C`)
|
|
||||||
|
|
||||||
|
expect((await heynotePage.getBlocks()).length).toBe(3)
|
||||||
|
expect(await heynotePage.getBlockContent(0)).toBe("Block A")
|
||||||
|
expect(await heynotePage.getBlockContent(1)).toBe("Block B")
|
||||||
|
expect(await heynotePage.getBlockContent(2)).toBe("Block C")
|
||||||
|
expect(content.slice(cursorPosition - 1, cursorPosition)).toBe("A")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("cursor position after moving first block", async ({page}) => {
|
test("move the middle block up", async ({ page }) => {
|
||||||
await heynotePage.setCursorPosition(10)
|
// select the second block, cursor position: "Block B|"
|
||||||
expect(await heynotePage.getCursorPosition()).toBe(10)
|
await page.locator("body").press("ArrowUp")
|
||||||
await page.locator("body").press(heynotePage.agnosticKey("Mod+S"))
|
|
||||||
await page.waitForTimeout(50)
|
await page.locator("body").press(`${heynotePage.isMac ? "Meta" : "Control"}+Shift+Alt+ArrowUp`)
|
||||||
await page.locator("body").press("Enter")
|
const cursorPosition = await heynotePage.getCursorPosition()
|
||||||
await page.waitForTimeout(50)
|
const content = await heynotePage.getContent()
|
||||||
expect(await heynotePage.getCursorPosition()).toBe(9)
|
|
||||||
|
expect((await heynotePage.getBlocks()).length).toBe(3)
|
||||||
|
expect(await heynotePage.getBlockContent(0)).toBe("Block B")
|
||||||
|
expect(await heynotePage.getBlockContent(1)).toBe("Block A")
|
||||||
|
expect(await heynotePage.getBlockContent(2)).toBe("Block C")
|
||||||
|
expect(content.slice(cursorPosition - 1, cursorPosition)).toBe("B")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("cursor position after moving middle block", async ({page}) => {
|
test("move the last block up", async ({ page }) => {
|
||||||
await heynotePage.setCursorPosition(28)
|
// cursor position: "Block C|"
|
||||||
await page.locator("body").press(heynotePage.agnosticKey("Mod+S"))
|
await page.locator("body").press(`${heynotePage.isMac ? "Meta" : "Control"}+Shift+Alt+ArrowUp`)
|
||||||
await page.waitForTimeout(50)
|
const cursorPosition = await heynotePage.getCursorPosition()
|
||||||
await page.locator("body").press("Enter")
|
const content = await heynotePage.getContent()
|
||||||
await page.waitForTimeout(50)
|
|
||||||
expect(await heynotePage.getCursorPosition()).toBe(25)
|
expect((await heynotePage.getBlocks()).length).toBe(3)
|
||||||
|
expect(await heynotePage.getBlockContent(0)).toBe("Block A")
|
||||||
|
expect(await heynotePage.getBlockContent(1)).toBe("Block C")
|
||||||
|
expect(await heynotePage.getBlockContent(2)).toBe("Block B")
|
||||||
|
expect(content.slice(cursorPosition - 1, cursorPosition)).toBe("C")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("cursor position after moving last block", async ({page}) => {
|
test("move the first block down", async ({ page }) => {
|
||||||
await heynotePage.setCursorPosition(48)
|
// select the first block, cursor position: "Block A|"
|
||||||
await page.locator("body").press(heynotePage.agnosticKey("Mod+S"))
|
await page.locator("body").press("ArrowUp")
|
||||||
await page.waitForTimeout(50)
|
await page.locator("body").press("ArrowUp")
|
||||||
await page.locator("body").press("Enter")
|
|
||||||
await page.waitForTimeout(50)
|
await page.locator("body").press(`${heynotePage.isMac ? "Meta" : "Control"}+Shift+Alt+ArrowDown`)
|
||||||
expect(await heynotePage.getCursorPosition()).toBe(32)
|
const cursorPosition = await heynotePage.getCursorPosition()
|
||||||
|
const content = await heynotePage.getContent()
|
||||||
|
|
||||||
|
expect((await heynotePage.getBlocks()).length).toBe(3)
|
||||||
|
expect(await heynotePage.getBlockContent(0)).toBe("Block B")
|
||||||
|
expect(await heynotePage.getBlockContent(1)).toBe("Block A")
|
||||||
|
expect(await heynotePage.getBlockContent(2)).toBe("Block C")
|
||||||
|
expect(content.slice(cursorPosition - 1, cursorPosition)).toBe("A")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("move the middle block down", async ({ page }) => {
|
||||||
|
// select the second block, cursor position: "Block B|"
|
||||||
|
await page.locator("body").press("ArrowUp")
|
||||||
|
|
||||||
|
await page.locator("body").press(`${heynotePage.isMac ? "Meta" : "Control"}+Shift+Alt+ArrowDown`)
|
||||||
|
const cursorPosition = await heynotePage.getCursorPosition()
|
||||||
|
const content = await heynotePage.getContent()
|
||||||
|
|
||||||
|
expect((await heynotePage.getBlocks()).length).toBe(3)
|
||||||
|
expect(await heynotePage.getBlockContent(0)).toBe("Block A")
|
||||||
|
expect(await heynotePage.getBlockContent(1)).toBe("Block C")
|
||||||
|
expect(await heynotePage.getBlockContent(2)).toBe("Block B")
|
||||||
|
expect(content.slice(cursorPosition - 1, cursorPosition)).toBe("B")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("move the last block down", async ({ page }) => {
|
||||||
|
// cursor position: "Block C|"
|
||||||
|
await page.locator("body").press(`${heynotePage.isMac ? "Meta" : "Control"}+Shift+Alt+ArrowDown`)
|
||||||
|
const cursorPosition = await heynotePage.getCursorPosition()
|
||||||
|
const content = await heynotePage.getContent()
|
||||||
|
|
||||||
|
expect((await heynotePage.getBlocks()).length).toBe(3)
|
||||||
|
expect(await heynotePage.getBlockContent(0)).toBe("Block A")
|
||||||
|
expect(await heynotePage.getBlockContent(1)).toBe("Block B")
|
||||||
|
expect(await heynotePage.getBlockContent(2)).toBe("Block C")
|
||||||
|
expect(content.slice(cursorPosition - 1, cursorPosition)).toBe("C")
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user