making some good progress

This commit is contained in:
Joeri Exelmans 2025-05-11 13:22:12 +02:00
parent 5f3d697866
commit e901fc3f76
15 changed files with 546 additions and 165 deletions

49
src/util/dom_trickery.ts Normal file
View file

@ -0,0 +1,49 @@
// If there is a caret anywhere in the document (user entering text), returns the position of the caret in the focused element
export function getCaretPosition(): number | undefined {
const selection = window.getSelection();
if (selection) {
const range = selection.getRangeAt(0);
const clonedRange = range.cloneRange();
return clonedRange.startOffset;
}
}
// export function setCursorPosition(elem, pos) {
// const range = document.createRange();
// range.selectNode(elem);
// range.setStart(elem, pos);
// range.setEnd(elem, pos);
// const selection = window.getSelection();
// selection?.removeAllRanges();
// selection?.addRange(range);
// }
// Move caret all the way to the right in the currently focused element
export function setRightMostCaretPosition(elem) {
const range = document.createRange();
range.selectNode(elem);
if (elem.lastChild) { // if no text is entered, there is no lastChild
range.setStart(elem.lastChild, elem.textContent.length);
range.setEnd(elem.lastChild, elem.textContent.length);
const selection = window.getSelection();
selection?.removeAllRanges();
selection?.addRange(range);
}
}
export function focusNextElement() {
const editable = Array.from<any>(document.querySelectorAll('[contenteditable]'));
const index = editable.indexOf(document.activeElement);
editable[index+1]?.focus();
}
export function focusPrevElement() {
const editable = Array.from<any>(document.querySelectorAll('[contenteditable]'));
const index = editable.indexOf(document.activeElement);
const prevElem = editable[index-1]
if (prevElem) {
prevElem.focus();
setRightMostCaretPosition(prevElem);
}
}

10
src/util/extra.ts Normal file
View file

@ -0,0 +1,10 @@
export interface Dynamic {
i: any;
t: any;
}
export interface State2Props<T> {
state: T;
// setState: (callback: (state: T) => T) => void;
setState: (state: T) => void;
}

View file

@ -0,0 +1,6 @@
// In the browser, we don't use the inspect.custom symbol,
// but it still needs to exist.
export const inspect = {
custom: Symbol(),
};

21
src/util/parse.ts Normal file
View file

@ -0,0 +1,21 @@
// Helpers...
export function parseDouble(text: string): number | undefined {
if (text === '') {
return;
}
const num = Number(text);
if (Number.isNaN(num)) {
return;
}
return num;
}
export function parseInt(text: string): bigint | undefined {
if (text === '') {
return;
}
try {
return BigInt(text);
}
catch (e) { };
}