feat: accurately get cursor index value for input field

This commit is contained in:
Rohit
2025-02-12 22:00:51 +05:30
parent 2199149827
commit 206d760dd1

View File

@@ -431,27 +431,95 @@ export class WorkflowGenerator {
// Calculate the exact position within the element // Calculate the exact position within the element
const positionAndCursor = await page.evaluate( const positionAndCursor = await page.evaluate(
({ selector, coords }) => { ({ selector, coords }) => {
const element = document.querySelector(selector); const getCursorPosition = (element: any, clickX: any) => {
if (!element) return null; // Get the input's text content
const text = element.value;
const getCursorPosition = (inputElement: HTMLInputElement | HTMLTextAreaElement, clickCoords: Coordinates) => { // Create a temporary hidden div to measure text
const position = inputElement.selectionStart || 0; const mirror = document.createElement('div');
return position;
}; // Copy ALL relevant styles that could affect text measurement
const style = window.getComputedStyle(element);
mirror.style.cssText = `
font: ${style.font};
line-height: ${style.lineHeight};
padding: ${style.padding};
border: ${style.border};
box-sizing: ${style.boxSizing};
white-space: ${style.whiteSpace};
overflow-wrap: ${style.overflowWrap};
position: absolute;
top: -9999px;
left: -9999px;
width: ${element.offsetWidth}px;
`;
document.body.appendChild(mirror);
// Get the element's padding and border widths
const paddingLeft = parseFloat(style.paddingLeft);
const borderLeft = parseFloat(style.borderLeftWidth);
// Adjust clickX to account for padding and border
const adjustedClickX = clickX - (paddingLeft + borderLeft);
let bestIndex = 0;
let bestDiff = Infinity;
// Try each possible cursor position
for (let i = 0; i <= text.length; i++) {
// Create a span for the text before cursor
const textBeforeCursor = text.substring(0, i);
const span = document.createElement('span');
span.textContent = textBeforeCursor;
mirror.innerHTML = '';
mirror.appendChild(span);
// Get the x-position where this character would end
const textWidth = span.getBoundingClientRect().width;
// Calculate distance from adjusted click to this position
const diff = Math.abs(adjustedClickX - textWidth);
// If this position is closer to the click, update bestIndex
if (diff < bestDiff) {
bestIndex = i;
bestDiff = diff;
}
}
// Clean up
document.body.removeChild(mirror);
// Add debug logging
console.log({
text,
clickX,
adjustedClickX,
bestIndex,
value: text.substring(0, bestIndex),
nextChar: text[bestIndex] || 'EOL'
});
return bestIndex;
};
const element = document.querySelector(selector) as HTMLInputElement | HTMLTextAreaElement;
if (!element) return null;
const rect = element.getBoundingClientRect(); const rect = element.getBoundingClientRect();
const cursorIndex = getCursorPosition(element as HTMLInputElement | HTMLTextAreaElement, coords); const relativeX = coords.x - rect.left;
return { return {
rect: { rect: {
x: rect.left, x: rect.left,
y: rect.top y: rect.top
}, },
cursorIndex cursorIndex: getCursorPosition(element, relativeX)
}; };
}, },
{ selector, coords: coordinates } { selector, coords: coordinates }
); );
if (positionAndCursor) { if (positionAndCursor) {
const relativeX = coordinates.x - positionAndCursor.rect.x; const relativeX = coordinates.x - positionAndCursor.rect.x;