Skip to content

Commit 9f09780

Browse files
platform: PT-3799 Remove extra space before inline markers and annotations (#454)
* Fix typo, skip adding trailing space when sibling is char or typed mark node * Fix same typo in scribe package * Add tests for not adding space when next sibling is char or typed mark node * Remove uneeded editor.update() step from test cases * Update function description, add test for preserving space-only TextNodes when next sibling is CharNode
1 parent 54ddb4c commit 9f09780

File tree

7 files changed

+83
-10
lines changed

7 files changed

+83
-10
lines changed

libs/shared-react/src/plugins/PerfNodesItems/useUsfmMarkersForMenu.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { getMarker, GetMarkerAction, ScriptureReference } from "shared";
44

55
// getMarker() takes a marker string and gets its data from a usfm markers map object that is merged with overwrites that fit the PERF editor context.
66
// getMarkerAction() returns a function to generate a LexicalNode and insert it in the editor, this lexical node is a custom node made for the PERF editor
7-
//NOTE: You can create your own typeahead plugin by creating your own getMarker() and getMarkerAction() functions adapted to your editor needs.
8-
export default function useUsfmMakersForMenu({
7+
// NOTE: You can create your own typeahead plugin by creating your own getMarker() and getMarkerAction() functions adapted to your editor needs.
8+
export default function useUsfmMarkersForMenu({
99
scriptureReference,
1010
contextMarker,
1111
getMarkerAction,

libs/shared-react/src/plugins/PerfTypeahead/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { getUsfmMarkerAction, ScriptureReference } from "shared";
2-
import useUsfmMakersForMenu from "../PerfNodesItems/useUsfmMarkersForMenu";
2+
import useUsfmMarkersForMenu from "../PerfNodesItems/useUsfmMarkersForMenu";
33
import TypeaheadPlugin from "../Typeahead/TypeaheadPlugin";
44

55
export default function PerfTypeaheadPlugin({
@@ -11,7 +11,7 @@ export default function PerfTypeaheadPlugin({
1111
scriptureReference: ScriptureReference;
1212
contextMarker: string;
1313
}) {
14-
const { markersMenuItems } = useUsfmMakersForMenu({
14+
const { markersMenuItems } = useUsfmMarkersForMenu({
1515
scriptureReference,
1616
contextMarker,
1717
getMarkerAction: getUsfmMarkerAction,

libs/shared-react/src/plugins/UsfmNodesMenuPlugin.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { GetMarkerAction, ScriptureReference } from "shared";
2-
import useUsfmMakersForMenu from "./PerfNodesItems/useUsfmMarkersForMenu";
2+
import useUsfmMarkersForMenu from "./PerfNodesItems/useUsfmMarkersForMenu";
33
import NodesMenu from "./NodesMenu";
44

55
export default function UsfmNodesMenuPlugin({
@@ -13,7 +13,7 @@ export default function UsfmNodesMenuPlugin({
1313
contextMarker: string | undefined;
1414
getMarkerAction: GetMarkerAction;
1515
}) {
16-
const { markersMenuItems } = useUsfmMakersForMenu({
16+
const { markersMenuItems } = useUsfmMarkersForMenu({
1717
scriptureReference,
1818
contextMarker,
1919
getMarkerAction,

libs/shared-react/src/plugins/usj/TextSpacingPlugin.test.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,72 @@ describe("TextSpacingPlugin", () => {
147147
});
148148
});
149149

150+
it("should not add trailing space when next sibling is a CharNode", async () => {
151+
const { editor } = await testEnvironment(() => {
152+
$getRoot().append(
153+
$createParaNode().append(
154+
$createTextNode("abc"),
155+
$createCharNode("nd").append($createTextNode("xyz")),
156+
),
157+
);
158+
});
159+
160+
editor.getEditorState().read(() => {
161+
const para = $getRoot().getFirstChild();
162+
if (!$isParaNode(para)) throw new Error("Expected a ParaNode");
163+
expect(para.getChildren()).toHaveLength(2);
164+
const textNode = para.getChildAtIndex(0);
165+
if (!$isTextNode(textNode)) throw new Error("Expected a TextNode");
166+
expect(textNode.getTextContent()).toBe("abc");
167+
const charNode = para.getChildAtIndex(1);
168+
if (!$isCharNode(charNode)) throw new Error("Expected a CharNode");
169+
expect(charNode.getTextContent()).toBe("xyz");
170+
});
171+
});
172+
173+
it("should not add trailing space when next sibling is a TypedMarkNode", async () => {
174+
const { editor } = await testEnvironment(() => {
175+
$getRoot().append(
176+
$createParaNode().append(
177+
$createTextNode("abc"),
178+
$createTypedMarkNode({ testType1: ["testID1"] }).append($createTextNode("marked")),
179+
),
180+
);
181+
});
182+
183+
editor.getEditorState().read(() => {
184+
const para = $getRoot().getFirstChild();
185+
if (!$isParaNode(para)) throw new Error("Expected a ParaNode");
186+
expect(para.getChildren()).toHaveLength(2);
187+
const textNode = para.getChildAtIndex(0);
188+
if (!$isTextNode(textNode)) throw new Error("Expected a TextNode");
189+
expect(textNode.getTextContent()).toBe("abc");
190+
const markNode = para.getChildAtIndex(1);
191+
if (!$isTypedMarkNode(markNode)) throw new Error("Expected a TypedMarkNode");
192+
expect(markNode.getTextContent()).toBe("marked");
193+
});
194+
});
195+
196+
it("should preserve space-only TextNode when next sibling is a CharNode", async () => {
197+
const { editor } = await testEnvironment(() => {
198+
$getRoot().append(
199+
$createParaNode().append(
200+
$createTextNode(" "),
201+
$createCharNode("nd").append($createTextNode("xyz")),
202+
),
203+
);
204+
});
205+
206+
editor.getEditorState().read(() => {
207+
const para = $getRoot().getFirstChild();
208+
if (!$isParaNode(para)) throw new Error("Expected a ParaNode");
209+
expect(para.getChildren()).toHaveLength(2);
210+
const spaceNode = para.getChildAtIndex(0);
211+
if (!$isTextNode(spaceNode)) throw new Error("Expected a TextNode");
212+
expect(spaceNode.getTextContent()).toBe(" ");
213+
});
214+
});
215+
150216
it("should add a space if typing before an initial verse in a para", async () => {
151217
const { editor } = await testEnvironment();
152218

libs/shared-react/src/plugins/usj/TextSpacingPlugin.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ function useTextSpacing(editor: LexicalEditor) {
5252
* Adds a space to the end of a TextNode if it doesn't precede a note or isn't inside a CharNode,
5353
* TypedMarkNode, or UnknownNode. It doesn't add a space if the text node is not editable. It
5454
* removes a TextNode with only a space if it is not followed by a verse node.
55+
*
56+
* When the next sibling is a CharNode or TypedMarkNode (inline marker or annotation), we skip
57+
* both adding trailing space and the space-only cleanup below, so spacing before inline content
58+
* is left unchanged.
59+
*
5560
* @param node - TextNode that might need updating.
5661
*/
5762
function $textNodeTrailingSpaceTransform(node: TextNode): void {
@@ -65,7 +70,9 @@ function $textNodeTrailingSpaceTransform(node: TextNode): void {
6570
(text.endsWith(" ") && text.length > 1) ||
6671
$isNoteNode(nextSibling) ||
6772
$isCharNode(parent) ||
73+
$isCharNode(nextSibling) ||
6874
$isTypedMarkNode(parent) ||
75+
$isTypedMarkNode(nextSibling) ||
6976
$isUnknownNode(parent)
7077
)
7178
return;

packages/scribe/src/editor/plugins/UsfmNodesMenuPlugin.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { GetMarkerAction, ScriptureReference } from "shared";
2-
import useUsfmMakersForMenu from "@/hooks/useUsfmMarkersForMenu";
2+
import useUsfmMarkersForMenu from "@/hooks/useUsfmMarkersForMenu";
33
import NodesMenu from "@/components/NodesMenu/NodesMenu";
44

55
export default function UsfmNodesMenuPlugin({
@@ -15,7 +15,7 @@ export default function UsfmNodesMenuPlugin({
1515
getMarkerAction: GetMarkerAction;
1616
autoNumbering?: boolean;
1717
}) {
18-
const { markersMenuItems } = useUsfmMakersForMenu({
18+
const { markersMenuItems } = useUsfmMarkersForMenu({
1919
scriptureReference,
2020
contextMarker,
2121
getMarkerAction,

packages/scribe/src/hooks/useUsfmMarkersForMenu.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { getMarker, GetMarkerAction, ScriptureReference } from "shared";
44

55
// getMarker() takes a marker string and gets its data from a usfm markers map object that is merged with overwrites that fit the PERF editor context.
66
// getMarkerAction() returns a function to generate a LexicalNode and insert it in the editor, this lexical node is a custom node made for the PERF editor
7-
//NOTE: You can create your own typeahead plugin by creating your own getMarker() and getMarkerAction() functions adapted to your editor needs.
8-
export default function useUsfmMakersForMenu({
7+
// NOTE: You can create your own typeahead plugin by creating your own getMarker() and getMarkerAction() functions adapted to your editor needs.
8+
export default function useUsfmMarkersForMenu({
99
scriptureReference,
1010
contextMarker,
1111
getMarkerAction,

0 commit comments

Comments
 (0)