more fixes for pad editor, mainly for mobile

This commit is contained in:
2025-04-06 18:14:59 -04:00
parent 5d55c6de4a
commit bee420feb3
4 changed files with 120 additions and 6 deletions

View File

@@ -8,6 +8,19 @@ export function calculateCursorPosition(editor: TipexEditor | undefined) {
const rect = range.getBoundingClientRect();
const editorRect = editor?.view.dom.getBoundingClientRect() || { left: 0, top: 0 };
// Check if on mobile
const isMobile = window.innerWidth < 768;
if (isMobile) {
// For mobile, position suggestions at the bottom center of the screen
// to avoid issues with virtual keyboard and to make them more accessible
return {
x: window.innerWidth / 2,
y: Math.min(rect.bottom - editorRect.top + window.scrollY, window.innerHeight - 250)
};
}
// Desktop positioning
const x = Math.min(
Math.max(rect.left - editorRect.left + window.scrollX, 100),
window.innerWidth - 300

View File

@@ -9,16 +9,44 @@ function extractLastWord(text: string): string {
/**
* Extracts the current word at cursor position from the document
* Improved to handle different selection scenarios on mobile
*/
export function extractCurrentWord(doc: any, pos: number): string {
const textBefore = doc.textBetween(Math.max(0, pos - 100), pos);
return extractLastWord(textBefore);
// For mobile, we might need to look further back to find words
// since touch selection can be less precise
const lookbackDistance = window.innerWidth < 768 ? 200 : 100;
const textBefore = doc.textBetween(Math.max(0, pos - lookbackDistance), pos);
// First try with standard pattern
const word = extractLastWord(textBefore);
// If standard pattern fails, try a more lenient pattern for mobile
if (!word && window.innerWidth < 768) {
const lenientMatches = textBefore.match(/[a-zA-Z]+(?:\s+[a-zA-Z]+)*\s*$/);
return lenientMatches ? lenientMatches[0].trim().split(/\s+/).pop() || '' : '';
}
return word;
}
/**
* Extracts the last word from a selected text range
* Improved to handle imprecise selections on mobile
*/
export function extractSelectedWord(doc: any, from: number, to: number): string {
// On mobile, selections might include extra spaces
const isMobile = window.innerWidth < 768;
const selectedText = doc.textBetween(from, to, ' ');
if (isMobile && selectedText.trim()) {
// For mobile, take the largest word in the selection
const words = selectedText.trim().split(/\s+/);
if (words.length > 0) {
// Find the longest word in selection (mobile users often select multiple words)
return words.reduce((longest: string, current: string) =>
current.length > longest.length ? current : longest, '');
}
}
return extractLastWord(selectedText);
}