Add caret position offset when using rtl option. Fixes #1788

This commit is contained in:
Francisco Hodge 2022-11-25 04:01:16 -05:00
parent 56d8fa6c58
commit 11c67de90a
3 changed files with 73 additions and 4 deletions

View File

@ -1190,10 +1190,15 @@ class SimpleKeyboard {
* Tracks current cursor position
* As keys are pressed, text will be added/removed at that position within the input.
*/
instance.setCaretPosition(
event.target.selectionStart,
event.target.selectionEnd
);
let selectionStart = event.target.selectionStart;
let selectionEnd = event.target.selectionEnd;
if(instance.options.rtl){
selectionStart = instance.utilities.getRtlOffset(selectionStart, instance.getInput());
selectionEnd = instance.utilities.getRtlOffset(selectionEnd, instance.getInput());
}
instance.setCaretPosition(selectionStart, selectionEnd);
/**
* Tracking current input in order to handle caret positioning edge cases

View File

@ -1351,4 +1351,54 @@ it('Keyboard will handle selected input with unchanged updatedInput edge case',
expect(keyboard.getInput()).toBe("33");
expect(keyboard.getCaretPosition()).toBe(2);
expect(keyboard.getCaretPositionEnd()).toBe(2);
});
it('Ensure caret position is offset when rtl option is enabled', () => {
const keyboard = new Keyboard({
useMouseEvents: true,
rtl: true,
layout: {
default: ["{bksp} ש ל ו ם"]
}
});
const caretEventHandler = jest.spyOn(keyboard, 'caretEventHandler');
keyboard.getButtonElement("ש").onclick();
keyboard.getButtonElement("ו").onclick();
keyboard.getButtonElement("ם").onclick();
expect(keyboard.getInput()).toBe("‫שום‬");
const input = document.createElement("input");
input.value = keyboard.getInput();
input.type = "text";
input.selectionStart = 2;
input.selectionEnd = 2;
keyboard.caretEventHandler({
type: "selectionchange",
target: input
});
expect(caretEventHandler).toHaveBeenCalled();
expect(keyboard.getCaretPosition()).toBe(1);
keyboard.getButtonElement("ל").onclick();
expect(keyboard.getInput()).toBe('‫שלום‬');
input.value = keyboard.getInput();
input.type = "text";
input.selectionStart = 4;
input.selectionEnd = 4;
keyboard.caretEventHandler({
type: "selectionchange",
target: input
});
keyboard.getButtonElement("{bksp}").onclick();
expect(keyboard.getInput()).toBe('‫שלם‬');
});

View File

@ -539,6 +539,20 @@ class Utilities {
return str.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&");
}
/**
* Calculate caret position offset when using rtl option
*/
getRtlOffset(index: number, input: string) {
let newIndex = index;
const startMarkerIndex = input.indexOf("\u202B");
const endMarkerIndex = input.indexOf("\u202C");
if(startMarkerIndex < index && startMarkerIndex != -1){ newIndex--; }
if(endMarkerIndex < index && startMarkerIndex != -1){ newIndex--; }
return newIndex < 0 ? 0 : newIndex;
}
/**
* Reusable empty function
*/