Skip to content

Commit f2ad2f1

Browse files
authored
platform: fix spaces & callers (#266)
- move leading spaces when inserting inline nodes - ensure default note callers are set
1 parent d56cd7c commit f2ad2f1

File tree

2 files changed

+50
-28
lines changed

2 files changed

+50
-28
lines changed

packages/platform/src/editor/adaptors/usj-editor.adaptor.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ import {
115115
ImmutableVerseNode,
116116
} from "shared-react/nodes/scripture/usj/ImmutableVerseNode";
117117
import { CallerData, generateNoteCaller } from "shared-react/nodes/scripture/usj/node-react.utils";
118+
import { defaultNoteCallers } from "shared-react/nodes/scripture/usj/use-default-node-options.hook";
118119
import {
119120
AddMissingComments,
120121
MarkNodeName,
@@ -144,7 +145,7 @@ let _viewOptions: ViewOptions | undefined;
144145
/** Options for each node. */
145146
let _nodeOptions: UsjNodeOptions | undefined;
146147
/** List of possible note callers. */
147-
let noteCallers: string[] | undefined;
148+
let noteCallers: string[] = defaultNoteCallers;
148149
/** Method to add missing comments. */
149150
let addMissingComments: AddMissingComments;
150151
/** Logger instance. */

packages/platform/src/editor/adaptors/usj-marker-action.utils.ts

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
} from "lexical";
1414
import { $createNodeFromSerializedNode } from "shared/converters/usfm/emptyUsfmNodes";
1515
import { $isTypedMarkNode } from "shared/nodes/features/TypedMarkNode";
16-
import { $isCharNode, CharNode } from "shared/nodes/scripture/usj/CharNode";
16+
import { CharNode } from "shared/nodes/scripture/usj/CharNode";
1717
import { $isNoteNode, GENERATOR_NOTE_CALLER } from "shared/nodes/scripture/usj/NoteNode";
1818
import { getNextVerse } from "shared/nodes/scripture/usj/node.utils";
1919
import { ParaNode } from "shared/nodes/scripture/usj/ParaNode";
@@ -130,8 +130,9 @@ export function getUsjMarkerAction(
130130
nodeToInsert.selectStart();
131131
}
132132
} else {
133-
const nodes = $addVerseLeadingSpaceIfNeeded(selection, nodeToInsert);
134-
selection.insertNodes(nodes);
133+
selection.insertNodes([nodeToInsert]);
134+
$moveTextLeadingSpaceToPreviousNode(nodeToInsert);
135+
$moveVerseFollowingSpaceToPreviousNode(nodeToInsert);
135136
}
136137
} else {
137138
// Insert the node directly
@@ -282,10 +283,16 @@ function handleTextNode(
282283
function $wrapNode(node: LexicalNode, wrapper: LexicalNode): void {
283284
if ($isTextNode(wrapper)) {
284285
let text = node.getTextContent();
285-
// CharNodes can't start with a space.
286-
if ($isTextNode(node) && $isCharNode(wrapper) && text.startsWith(" ")) {
287-
wrapper.insertBefore($createTextNode(" "));
286+
// Inline nodes can't start with a space.
287+
if ($isTextNode(node) && wrapper.isInline() && text.startsWith(" ")) {
288288
text = text.trimStart();
289+
const previousNode = wrapper.getPreviousSibling();
290+
if ($isTextNode(previousNode)) {
291+
const previousText = previousNode.getTextContent();
292+
if (!previousText.endsWith(" ")) previousNode.setTextContent(`${previousText} `);
293+
} else {
294+
wrapper.insertBefore($createTextNode(" "));
295+
}
289296
}
290297
wrapper.setTextContent(text);
291298
node.remove();
@@ -298,31 +305,45 @@ function $wrapNode(node: LexicalNode, wrapper: LexicalNode): void {
298305
// #endregion
299306

300307
/**
301-
* Adds a leading space before a verse node if needed.
308+
* Moves the leading space of a text node to the previous node.
302309
*
303-
* This function checks if the given selection is collapsed and if the node to be inserted is a
304-
* verse node or an immutable verse node. If both conditions are met, it further checks if the
305-
* anchor node of the selection is a text node and if there is no leading space before the insertion
306-
* point. If there is no leading space, it prepends a space to the node to be inserted.
310+
* This function checks if the given node is a text node and if it starts with a space. If both
311+
* conditions are met, it trims the leading space from the text node and appends a space to the
312+
* previous node if it is a text node and doesn't end in a space already.
307313
*
308-
* @param selection - The current selection range in the editor.
309-
* @param nodeToInsert - The node that is to be inserted into the editor.
310-
* @returns An array containing the nodes to be inserted, potentially with a leading space node.
314+
* @param node - The node to check for leading space.
311315
*/
312-
function $addVerseLeadingSpaceIfNeeded(
313-
selection: RangeSelection,
314-
nodeToInsert: LexicalNode,
315-
): LexicalNode[] {
316-
if (!selection.isCollapsed()) return [nodeToInsert];
317-
if (!$isSomeVerseNode(nodeToInsert)) return [nodeToInsert];
316+
function $moveTextLeadingSpaceToPreviousNode(node: LexicalNode): void {
317+
if (!$isTextNode(node) || !node.getTextContent().startsWith(" ")) return;
318+
319+
node.setTextContent(node.getTextContent().trimStart());
320+
const previousNode = node.getPreviousSibling();
321+
if ($isTextNode(previousNode)) {
322+
const previousText = previousNode.getTextContent();
323+
if (!previousText.endsWith(" ")) previousNode.setTextContent(`${previousText} `);
324+
}
325+
}
318326

319-
const anchorNode = selection.anchor.getNode();
320-
if (!$isTextNode(anchorNode)) return [nodeToInsert];
327+
/**
328+
* Moves the leading space of a node following a verse node to the previous node.
329+
*
330+
* This function checks if the previous node ends in a space and adds one if needed. It then checks
331+
* if the following node starts with a space and removes it.
332+
*
333+
* @param node - The node to check for leading space.
334+
*/
335+
function $moveVerseFollowingSpaceToPreviousNode(node: LexicalNode) {
336+
if (!$isSomeVerseNode(node)) return;
321337

322-
const offset = selection.anchor.offset;
323-
const textContent = anchorNode.getTextContent();
324-
const hasLeadingSpace = textContent[offset - 1] === " ";
325-
if (hasLeadingSpace) return [nodeToInsert];
338+
const previousNode = node.getPreviousSibling();
339+
if ($isTextNode(previousNode)) {
340+
const previousText = previousNode.getTextContent();
341+
if (!previousText.endsWith(" ")) previousNode.setTextContent(`${previousText} `);
342+
}
326343

327-
return [$createTextNode(" "), nodeToInsert];
344+
const nextNode = node.getNextSibling();
345+
if ($isTextNode(nextNode)) {
346+
const nextText = nextNode.getTextContent();
347+
if (nextText.startsWith(" ")) nextNode.setTextContent(nextText.trimStart());
348+
}
328349
}

0 commit comments

Comments
 (0)