| 243 | 243 | } |
| 244 | 244 | |
| 245 | 245 | /** |
| 246 | + * getTextBeforeClickedWord retrieves the portion of text within a span |
| 247 | + * that appears before the word clicked by the user. Using the x and y |
| 248 | + * coordinates from a PointerEvent, this function identifies the exact |
| 249 | + * word clicked and returns the text preceding it within the span. |
| 250 | + * |
| 251 | + * If the clicked position does not resolve to a valid word or text node, |
| 252 | + * the entire span text is returned as a fallback. |
| 253 | + * |
| 254 | + * @param {PointerEvent} event - The click event containing the x and y coordinates. |
| 255 | + * @param {string} spanText - The full text content of the span element. |
| 256 | + * @returns {string} The text before the clicked word, or the entire span text as fallback. |
| 257 | + */ |
| 258 | +function getTextBeforeClickedWord(event, spanText) { |
| 259 | + const x = event.clientX; |
| 260 | + const y = event.clientY; |
| 261 | + const range = document.caretRangeFromPoint(x, y); |
| 262 | + |
| 263 | + if (range && range.startContainer.nodeType === Node.TEXT_NODE) { |
| 264 | + const textNode = range.startContainer; |
| 265 | + const offset = range.startOffset; |
| 266 | + |
| 267 | + // Get the full text content of the text node |
| 268 | + const text = textNode.nodeValue; |
| 269 | + |
| 270 | + // Find the boundaries of the clicked word |
| 271 | + const start = text.lastIndexOf(" ", offset - 1) + 1; |
| 272 | + |
| 273 | + // Return the text before the clicked word |
| 274 | + return text.slice(0, start); |
| 275 | + } |
| 276 | + |
| 277 | + // If we can't determine the exact word, return the full span text as a fallback |
| 278 | + return spanText; |
| 279 | +} |
| 280 | + |
| 281 | + |
| 282 | +/** |
| 246 | 283 | * onPrefixClicked is called when the user clicks on the carried-over prefix |
| 247 | 284 | * in the token output view. It allows them to reroll the last 'continue' |
| 248 | 285 | * completion with none of the output generated from it, in case they don't |
| 249 | 286 | * like the results. |
| 287 | + * |
| 288 | + * If the user holds the Ctrl key while clicking, only the portion of text |
| 289 | + * before the clicked word is retained as the prefix for rerolling |
| 250 | 290 | */ |
| 251 | 291 | function onPrefixClicked() { |
| 252 | 292 | if (!checkGenerateReady()) { |