Skip to content

Commit

Permalink
Fix issue incorrectly positioning selection on chip add at start of d…
Browse files Browse the repository at this point in the history
…ocument
  • Loading branch information
jonathonherbert committed Nov 12, 2024
1 parent d8f6850 commit 72f1316
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 16 deletions.
11 changes: 9 additions & 2 deletions prosemirror-client/src/cqlInput/editor/plugin.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, it, beforeEach } from "bun:test";
import { describe, it, beforeEach, expect } from "bun:test";
import { errorMsgTestId, errorTestId, typeaheadTestId } from "../CqlInput";
import { findByTestId, findByText, fireEvent } from "@testing-library/dom";
import { CqlClientService } from "../../services/CqlService";
Expand All @@ -11,6 +11,7 @@ import { keymap } from "prosemirror-keymap";
import {
createProseMirrorTokenToDocumentMap,
docToQueryStr,
getNodeTypeAtSelection,
mapResult,
tokensToDoc,
toProseMirrorTokens,
Expand Down Expand Up @@ -165,11 +166,14 @@ describe("plugin", () => {
await findByText(popoverContainer, "Section");
});

it("displays a popover after search text", async () => {
it("displays a popover after search text, moving the caret to key position", async () => {
const { editor, container } = createCqlEditor();

await editor.insertText("+");

const nodeAtCaret = getNodeTypeAtSelection(editor.view);
expect(nodeAtCaret.name).toBe("chipKey");

const popoverContainer = await findByTestId(container, typeaheadTestId);

await findByText(popoverContainer, "Tag");
Expand All @@ -181,6 +185,9 @@ describe("plugin", () => {

editor.insertText("+");

const nodeAtCaret = getNodeTypeAtSelection(editor.view);
expect(nodeAtCaret.name).toBe("chipKey");

const popoverContainer = await findByTestId(container, typeaheadTestId);

await findByText(popoverContainer, "Tag");
Expand Down
12 changes: 7 additions & 5 deletions prosemirror-client/src/cqlInput/editor/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
} from "prosemirror-state";
import {
getNewSelection,
isBeginningKeyValPair,
docToQueryStr,
tokensToDecorations,
tokensToDoc,
Expand Down Expand Up @@ -106,8 +105,6 @@ export const createCqlPlugin = ({
prevQuery?: string
) => {
const currentQuery = docToQueryStr(tr.doc);
const shouldWrapSelectionInKey =
!!prevQuery && isBeginningKeyValPair(prevQuery, currentQuery);

const result = cqlService.parseCqlQueryStr(currentQuery);
const {
Expand Down Expand Up @@ -157,7 +154,12 @@ export const createCqlPlugin = ({

if (!newDoc.eq(tr.doc)) {
tr.replaceWith(docSelection.from, docSelection.to, newDoc).setSelection(
getNewSelection(userSelection, shouldWrapSelectionInKey, tr.doc)
getNewSelection({
selection: userSelection,
doc: tr.doc,
currentQuery,
prevQuery,
})
);
}

Expand Down Expand Up @@ -432,7 +434,7 @@ export const createCqlPlugin = ({
}

view.dispatch(tr);
}
};

typeaheadPopover = new TypeaheadPopover(
view,
Expand Down
46 changes: 37 additions & 9 deletions prosemirror-client/src/cqlInput/editor/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,12 @@ export const docToQueryStr = (doc: Node) => {
const keyValPairChars = ["+"];

export const isBeginningKeyValPair = (
first: string,
first: string | undefined,
second: string
): boolean => {
if (!first) {
return keyValPairChars.includes(second[0]);
}
const firstDiffChar = getFirstDiff(first, second);
return firstDiffChar ? keyValPairChars.includes(firstDiffChar) : false;
};
Expand Down Expand Up @@ -334,13 +337,24 @@ export const findNodeAt = (pos: number, doc: Node, type: NodeType): number => {
return found;
};

export const getNewSelection = (
currentSelection: Selection,
shouldWrapSelectionInKey: boolean,
doc: Node
): Selection => {
export const getNewSelection = ({
selection,
doc,
prevQuery,
currentQuery,
}: {
selection: Selection;
doc: Node;
prevQuery?: string;
currentQuery: string;
}): Selection => {
const shouldWrapSelectionInKey = isBeginningKeyValPair(
prevQuery,
currentQuery
);

if (shouldWrapSelectionInKey) {
const nodePos = findNodeAt(currentSelection.from, doc, chipKey);
const nodePos = findNodeAt(selection.from, doc, chipKey);

if (nodePos !== -1) {
const $pos = doc.resolve(nodePos);
Expand All @@ -353,8 +367,8 @@ export const getNewSelection = (

return TextSelection.create(
doc,
Math.min(currentSelection.from, doc.nodeSize - 2),
Math.min(currentSelection.to, doc.nodeSize - 2)
Math.min(selection.from, doc.nodeSize - 2),
Math.min(selection.to, doc.nodeSize - 2)
);
};

Expand Down Expand Up @@ -538,3 +552,17 @@ export const queryHasChanged = (

return prevQuery !== currentQuery ? { prevQuery, currentQuery } : undefined;
};

export const getNodeTypeAtSelection = (view: EditorView) => {
const {
doc,
selection: { from, to },
} = view.state;
if (from !== to) {
throw new Error(
`[getNodeTypeAtPos]: Selection is not collapsed (${from}-${to})`
);
}

return doc.resolve(from).node().type;
};

0 comments on commit 72f1316

Please sign in to comment.