From 0174161f5777139eec4bcbbabdfc5160766f9afc Mon Sep 17 00:00:00 2001 From: Alex Warren Date: Wed, 26 Feb 2025 14:42:06 +0000 Subject: [PATCH 1/5] Update key-bindings.ts --- src/rich-text/key-bindings.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/rich-text/key-bindings.ts b/src/rich-text/key-bindings.ts index eda9c81a..ce00c026 100644 --- a/src/rich-text/key-bindings.ts +++ b/src/rich-text/key-bindings.ts @@ -2,7 +2,6 @@ import { toggleMark, wrapIn, setBlockType, - exitCode, baseKeymap, } from "prosemirror-commands"; import { redo, undo } from "prosemirror-history"; @@ -26,7 +25,6 @@ import { moveToPreviousCellCommand, moveSelectionAfterTableCommand, insertRichTextTableCommand, - exitInclusiveMarkCommand, indentCodeBlockLinesCommand, unindentCodeBlockLinesCommand, toggleHeadingLevel, @@ -86,9 +84,6 @@ export function allKeymaps( "Mod-,": toggleMark(schema.marks.sub), "Mod-.": toggleMark(schema.marks.sup), "Mod-'": toggleMark(schema.marks.kbd), - // users expect to be able to leave certain blocks/marks using the arrow keys - "ArrowRight": exitInclusiveMarkCommand, - "ArrowDown": exitCode, }); const keymaps = [ From 1da064655a34a7f13c47f935aa43c140acdff125 Mon Sep 17 00:00:00 2001 From: Alex Warren Date: Thu, 27 Feb 2025 11:02:44 +0000 Subject: [PATCH 2/5] fix(blah): reinstate exitInclusiveMarkCommand --- src/rich-text/commands/index.ts | 4 ++-- src/rich-text/key-bindings.ts | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/rich-text/commands/index.ts b/src/rich-text/commands/index.ts index 0c66224b..d0597549 100644 --- a/src/rich-text/commands/index.ts +++ b/src/rich-text/commands/index.ts @@ -532,7 +532,7 @@ export function exitInclusiveMarkCommand( dispatch: (tr: Transaction) => void ) { const $cursor = (state.selection).$cursor; - const marks = state.storedMarks || $cursor.marks(); + const marks = state.storedMarks || $cursor?.marks(); if (!marks?.length) { return false; @@ -546,7 +546,7 @@ export function exitInclusiveMarkCommand( } // check if we're at the end of the exitable mark - const nextNode = $cursor.nodeAfter; + const nextNode = $cursor?.nodeAfter; let endExitables: Mark[]; let tr = state.tr; diff --git a/src/rich-text/key-bindings.ts b/src/rich-text/key-bindings.ts index ce00c026..962b4f41 100644 --- a/src/rich-text/key-bindings.ts +++ b/src/rich-text/key-bindings.ts @@ -30,6 +30,7 @@ import { toggleHeadingLevel, toggleTagLinkCommand, toggleList, + exitInclusiveMarkCommand, } from "./commands"; export function allKeymaps( @@ -84,6 +85,8 @@ export function allKeymaps( "Mod-,": toggleMark(schema.marks.sub), "Mod-.": toggleMark(schema.marks.sup), "Mod-'": toggleMark(schema.marks.kbd), + // exit inline code block using the right arrow key + "ArrowRight": exitInclusiveMarkCommand, }); const keymaps = [ From 42ae429ead589c4f8ae1d66c74372b59e2de72a3 Mon Sep 17 00:00:00 2001 From: Alex Warren Date: Thu, 27 Feb 2025 12:53:08 +0000 Subject: [PATCH 3/5] fix(blah): add test for when $cursor is null --- test/rich-text/commands/index.test.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/rich-text/commands/index.test.ts b/test/rich-text/commands/index.test.ts index e22c3177..07ddf81a 100644 --- a/test/rich-text/commands/index.test.ts +++ b/test/rich-text/commands/index.test.ts @@ -1,4 +1,4 @@ -import { EditorState, Transaction } from "prosemirror-state"; +import { EditorState, TextSelection, Transaction } from "prosemirror-state"; import { exitInclusiveMarkCommand, insertRichTextHorizontalRuleCommand, @@ -733,7 +733,7 @@ describe("commands", () => { ); }); - describe("exitMarkCommand", () => { + describe("exitInclusiveMarkCommand", () => { it("all exitable marks should also be inclusive: true", () => { Object.keys(testRichTextSchema.marks).forEach((markName) => { const mark = testRichTextSchema.marks[markName]; @@ -783,6 +783,14 @@ describe("commands", () => { expect(exitInclusiveMarkCommand(state, null)).toBe(true); } ); + + it("should handle the case when $cursor is null", () => { + let state = createState("this is my state", []); + state = state.apply(state.tr.setSelection(TextSelection.create(state.doc, 0, null))); + expect((state.selection).$cursor).toBeNull(); + expect(() => exitInclusiveMarkCommand(state, null)).not.toThrow(); + } + ); }); describe("indentCodeBlockLinesCommand", () => { From a2f063b52d57ef7e4dc122181ecae9c0a09d759c Mon Sep 17 00:00:00 2001 From: Alex Warren Date: Thu, 27 Feb 2025 12:58:32 +0000 Subject: [PATCH 4/5] fix(blah): format --- test/rich-text/commands/index.test.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/rich-text/commands/index.test.ts b/test/rich-text/commands/index.test.ts index 07ddf81a..6d04893a 100644 --- a/test/rich-text/commands/index.test.ts +++ b/test/rich-text/commands/index.test.ts @@ -785,12 +785,13 @@ describe("commands", () => { ); it("should handle the case when $cursor is null", () => { - let state = createState("this is my state", []); - state = state.apply(state.tr.setSelection(TextSelection.create(state.doc, 0, null))); - expect((state.selection).$cursor).toBeNull(); - expect(() => exitInclusiveMarkCommand(state, null)).not.toThrow(); - } - ); + let state = createState("this is my state", []); + state = state.apply( + state.tr.setSelection(TextSelection.create(state.doc, 0, null)) + ); + expect((state.selection).$cursor).toBeNull(); + expect(() => exitInclusiveMarkCommand(state, null)).not.toThrow(); + }); }); describe("indentCodeBlockLinesCommand", () => { From 820eff463dc23aa8a4cd07e0ebf0419a1115fd6a Mon Sep 17 00:00:00 2001 From: Alex Warren Date: Fri, 28 Feb 2025 09:06:08 +0000 Subject: [PATCH 5/5] fix(blah): suppress console.warn in test --- test/rich-text/commands/index.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/rich-text/commands/index.test.ts b/test/rich-text/commands/index.test.ts index 6d04893a..bf31c10b 100644 --- a/test/rich-text/commands/index.test.ts +++ b/test/rich-text/commands/index.test.ts @@ -785,12 +785,20 @@ describe("commands", () => { ); it("should handle the case when $cursor is null", () => { + // suppress console.warn + const consoleWarnSpy = jest + .spyOn(console, "warn") + .mockImplementation(() => {}); + let state = createState("this is my state", []); state = state.apply( state.tr.setSelection(TextSelection.create(state.doc, 0, null)) ); expect((state.selection).$cursor).toBeNull(); expect(() => exitInclusiveMarkCommand(state, null)).not.toThrow(); + + // restore console.warn + consoleWarnSpy.mockRestore(); }); });