import type { EditorState } from '../richTextTypes' export function insertLink(_openLinkModal: unknown, state: EditorState) { const { doc } = state if (!doc) { console.log('No doc found') return } // Get current selection const selection = doc.getSelection() if (!selection || !selection.rangeCount) { console.log('No selection found') return } let range = selection.getRangeAt(0) // If no text is selected, try to select word at cursor if (range.collapsed) { const success = selectWordAtCursor(doc, range) if (!success) { console.log('Failed to select word at cursor') // Show a helpful tooltip to the user const { showTooltipMessage } = state as any if (showTooltipMessage) { showTooltipMessage('To add a link, please select text first or place cursor within a word') } else { // Fallback to alert if tooltip system is not available alert('To add a link, please select text first or place the cursor within a word you want to turn into a link.') } return } // Get the updated range after word selection range = selection.getRangeAt(0) } // Check if we're editing an existing link const commonAncestor = range.commonAncestorContainer const parentElement = commonAncestor.nodeType === Node.TEXT_NODE ? commonAncestor.parentElement : commonAncestor as Element const existingLink = parentElement?.closest('a') // Use the new modal function if available if ((state as any).openLinkModal) { (state as any).openLinkModal(selection, range, existingLink) return } // Fallback - just show an alert if modal is not available console.warn('Link modal not available - openLinkModal function not found') alert('Link functionality requires proper modal setup') } // Helper function to select word at cursor function selectWordAtCursor(doc: Document, range: Range): boolean { if (!range.collapsed) { return true } // Already has selection let textNode = range.startContainer let offset = range.startOffset // If we're in an element node, try to find a text node if (textNode.nodeType !== Node.TEXT_NODE) { const element = textNode as Element if (element.childNodes.length > 0 && offset < element.childNodes.length) { const childNode = element.childNodes[offset] if (childNode.nodeType === Node.TEXT_NODE) { textNode = childNode offset = 0 } else { return false } } else { return false } } const text = textNode.textContent || '' if (!text) { return false } // Find word boundaries - support Hebrew, English, and numbers let start = offset let end = offset // Define word characters (Hebrew, English, numbers) const wordRegex = /[\u0590-\u05FF\u0600-\u06FF\w]/ // Move start backwards to find beginning of word while (start > 0 && wordRegex.test(text[start - 1])) { start-- } // Move end forwards to find end of word while (end < text.length && wordRegex.test(text[end])) { end++ } // If we found a word if (start < end) { range.setStart(textNode, start) range.setEnd(textNode, end) const selection = doc.getSelection() if (selection) { selection.removeAllRanges() selection.addRange(range) } return true } return false }