Skip to content

Commit

Permalink
fix: Cursor movement in/out of transclusions
Browse files Browse the repository at this point in the history
* If the transcluded content was not at the end of its document then
errors in findFinalEditable prevented some movements.
* Transclusions did not handle -0 focus offset (start of last line).
  • Loading branch information
dstoc committed Nov 16, 2024
1 parent 1d9cca4 commit 3198617
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 8 deletions.
3 changes: 1 addition & 2 deletions src/copy-paste-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
cloneNode,
compareDocumentOrder,
dfs,
findFinalEditable,
performLogicalInsertion,
removeDescendantNodes,
} from './markdown/view-model-util.js';
Expand All @@ -30,7 +29,7 @@ export function insertMarkdown(markdown: string, node: ViewModelNode) {
const newInlineNodes = newNodes
.flatMap((node) => [...dfs(node, node)])
.filter(isInlineViewModelNode);
const newFocus = findFinalEditable(newNodes[0]);
const newFocus = newInlineNodes.at(-1);
performLogicalInsertion(node, newNodes);
return {newFocus, newInlineNodes};
}
Expand Down
7 changes: 4 additions & 3 deletions src/markdown/transclusion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ export class MarkdownTransclusion extends LitElement implements SigpropHost {
if (!this.hostContext) return;
if (!this.root) return;
if (this.hostContext.focusNode !== this.node) return;
const offset = this.hostContext.focusOffset ?? -1;
const node =
(this.hostContext.focusOffset ?? -1) >= 0
? findNextEditable(this.root, this.root, true)
: findFinalEditable(this.root, true);
offset < 0 || Object.is(offset, -0)
? findFinalEditable(this.root, this.root, true)
: findNextEditable(this.root, this.root, true);
this.markdownRenderer.hostContext.focusNode = node ?? undefined;
this.markdownRenderer.hostContext.focusOffset =
this.hostContext.focusOffset;
Expand Down
12 changes: 9 additions & 3 deletions src/markdown/view-model-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import {
isInlineViewModelNode,
type InlineViewModelNode,
type MaybeViewModelNode,
type ViewModelNode, viewModel} from './view-model-node.js';
type ViewModelNode,
viewModel,
} from './view-model-node.js';
import {MarkdownNode} from './node.js';

export function swapNodes(node1: ViewModelNode, node2: ViewModelNode) {
Expand Down Expand Up @@ -160,11 +162,12 @@ export function findNextEditable(
// TODO: why doesn't this return Editable?
export function findFinalEditable(
node: ViewModelNode,
root: ViewModelNode,
include = false,
): InlineViewModelNode | null {
let result: InlineViewModelNode | null = null;
if (include && isInlineViewModelNode(node)) result = node;
for (const next of dfs(node)) {
for (const next of dfs(node, root)) {
if (isInlineViewModelNode(next)) result = next;
}
return result;
Expand All @@ -175,7 +178,10 @@ export function findNextDfs<T extends ViewModelNode>(
root: ViewModelNode,
predicate: (node: ViewModelNode) => node is T,
) {
for (const next of dfs(node, root[viewModel].parent)) {
for (const next of dfs(
node,
root[viewModel].nextSibling ?? root[viewModel].parent,
)) {
if (next !== node && predicate(next)) return next;
}
return null;
Expand Down
38 changes: 38 additions & 0 deletions tests/edit_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,44 @@ test.describe('editing', () => {
`);
});
test('follow caret movements in and out', async ({page}) => {
await page.keyboard.type('before');
await page.keyboard.press('Enter');
await page.keyboard.type('after');
await page.keyboard.press('Home');
await page.keyboard.press('ArrowUp');
await importFile('transclusion.md', '# transclusion\naaa');
await state.main.runCommand('insert transclusion', 'transclusion');
await state.main.host
.locator('md-transclusion')
.waitFor({state: 'visible'});
await page.keyboard.press('ArrowDown');
await page.keyboard.press('ArrowDown');
await page.keyboard.type('1');
await page.keyboard.press('ArrowDown');
await page.keyboard.type('2');
await page.keyboard.press('ArrowUp');
await page.keyboard.type('3');
await page.keyboard.press('ArrowUp');
await page.keyboard.press('ArrowUp');
await page.keyboard.type('4');
expect(await exportMarkdown('test')).toMatchPretty(`
# test
bef4ore
\`\`\`tc
transclusion
\`\`\`
a2fter
`);
expect(await exportMarkdown('transclusion')).toMatchPretty(`
# transclusion
1a3aa
`);
});
test('can be inserted and deleted', async ({page}) => {
await page.keyboard.type('test');
await importFile('transclusion.md', '# transclusion\n');
Expand Down

0 comments on commit 3198617

Please sign in to comment.