Skip to content

Commit

Permalink
feat(YfmNote): move cursor to end of note's title when press backspac…
Browse files Browse the repository at this point in the history
…e in the beginning of its content
  • Loading branch information
d3m1d0v committed Sep 28, 2022
1 parent c1865ed commit a485fc9
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
18 changes: 16 additions & 2 deletions src/extensions/yfm/YfmNote/commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {builders} from 'prosemirror-test-builder';

import {NoteNode} from './const';
import {getSpec} from './spec';
import {removeNote} from './commands';
import {backToNoteTitle, removeNote} from './commands';

const schema = new Schema({
nodes: {
Expand All @@ -14,7 +14,6 @@ const schema = new Schema({
paragraph: {
group: 'block',
content: 'inline*',
parseDOM: [{tag: 'p'}],
toDOM: () => ['p', 0],
},
...getSpec(),
Expand Down Expand Up @@ -45,4 +44,19 @@ describe('YfmNote commands', () => {
expect(view.state.doc).toMatchNode(doc(p('note title'), p('note content in paragraph')));
expect((view.state.selection as TextSelection).$cursor?.pos).toBe(1);
});

it("backToNoteTitle: should move cursor to the end of note's title", () => {
const pmDoc = doc(note(noteTitle('note title'), p('note content in paragraph')));
const view = new EditorView(null, {
state: EditorState.create({
schema,
doc: pmDoc,
selection: TextSelection.create(pmDoc, 14),
}),
});
const res = backToNoteTitle(view.state, view.dispatch, view);
expect(res).toBe(true);
expect(view.state.doc).toMatchNode(pmDoc);
expect((view.state.selection as TextSelection).$cursor?.pos).toBe(12);
});
});
31 changes: 31 additions & 0 deletions src/extensions/yfm/YfmNote/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,34 @@ export const removeNote: Command = (state, dispatch, view) => {
}
return false;
};

/**
* If the cursor is at the beginning of the first paragraph in note's content,
* moves the cursor to the end of the note's title.
*/
export const backToNoteTitle: Command = (state, dispatch, view) => {
const {selection, schema} = state;
if (!isTextSelection(selection)) return false;
const {$cursor} = selection;
if (!$cursor) return false;
if (
!isSameNodeType($cursor.parent, pType(schema)) ||
!isSameNodeType($cursor.node(-1), noteType(schema))
) {
return false;
}
const noteNode = $cursor.node(-1);
if ($cursor.parent !== noteNode.maybeChild(1)) return false;
if (view?.endOfTextblock('backward', state)) {
if (dispatch) {
const noteTitleNode = noteNode.firstChild!;
dispatch(
state.tr.setSelection(
TextSelection.create(state.doc, $cursor.before(-1) + noteTitleNode.nodeSize),
),
);
}
return true;
}
return false;
};
4 changes: 2 additions & 2 deletions src/extensions/yfm/YfmNote/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {fromYfm} from './fromYfm';
import {getSpec, YfmNoteSpecOptions} from './spec';
import {createYfmNote, toYfmNote} from './actions/toYfmNote';
import {nodeInputRule} from '../../../utils/inputrules';
import {exitFromNoteTitle, removeNote} from './commands';
import {backToNoteTitle, exitFromNoteTitle, removeNote} from './commands';
import {noteType} from './utils';

import './index.scss';
Expand Down Expand Up @@ -42,7 +42,7 @@ export const YfmNote: ExtensionAuto<YfmNoteOptions> = (builder, opts) => {
}))
.addKeymap(() => ({
Enter: exitFromNoteTitle,
Backspace: chainCommands(removeNote),
Backspace: chainCommands(backToNoteTitle, removeNote),
}))
.addAction(noteAction, () => toYfmNote)
.addInputRules(({schema}) => ({
Expand Down

0 comments on commit a485fc9

Please sign in to comment.