| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| function escapeHtml(text) { |
| const map = { |
| '&': '&', |
| '<': '<', |
| '>': '>', |
| '"': '"', |
| "'": ''', |
| }; |
| return text.replace(/[&<>"']/g, (c) => map[c]); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| function sortSuggestions(suggestions) { |
| return [...suggestions].sort((a, b) => a.start - b.start); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| function getErrorClass(type) { |
| const classes = { |
| spelling: 'bayan-spelling-error', |
| grammar: 'bayan-grammar-error', |
| punctuation: 'bayan-punctuation-suggestion', |
| }; |
| return classes[type] || 'bayan-spelling-error'; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| function createSegments(text, suggestions) { |
| const sorted = sortSuggestions(suggestions); |
| const finalSegments = []; |
| let segStart = 0; |
|
|
| sorted.forEach((suggestion) => { |
| const { start, end } = suggestion; |
|
|
| |
| if (segStart < start) { |
| finalSegments.push({ |
| type: 'text', |
| text: text.slice(segStart, start), |
| suggestions: [], |
| }); |
| } |
|
|
| |
| finalSegments.push({ |
| type: 'suggestion', |
| text: text.slice(start, end), |
| suggestion: suggestion, |
| }); |
|
|
| segStart = end; |
| }); |
|
|
| |
| if (segStart < text.length) { |
| finalSegments.push({ |
| type: 'text', |
| text: text.slice(segStart), |
| suggestions: [], |
| }); |
| } |
|
|
| return finalSegments; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| function renderHighlightedText(text, suggestions) { |
| if (!text || text.length === 0) return ''; |
| if (!suggestions || suggestions.length === 0) return escapeHtml(text); |
|
|
| const segments = createSegments(text, suggestions); |
| let html = ''; |
|
|
| segments.forEach((segment) => { |
| if (segment.type === 'text') { |
| html += escapeHtml(segment.text); |
| } else if (segment.type === 'suggestion') { |
| const { suggestion } = segment; |
| const errorClass = getErrorClass(suggestion.type); |
| const escapedText = escapeHtml(segment.text); |
| const sid = suggestion.id || ''; |
|
|
| html += `<span class="${errorClass}" data-suggestion-id="${sid}" data-original="${escapeHtml( |
| suggestion.original |
| )}" data-correction="${escapeHtml( |
| suggestion.correction |
| )}" data-type="${suggestion.type}" title="${suggestion.type}: ${escapeHtml( |
| suggestion.correction |
| )}">${escapedText}</span>`; |
| } |
| }); |
|
|
| return html; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| function bayanRender(input) { |
| const { text = '', suggestions = [] } = input; |
| return renderHighlightedText(text, suggestions); |
| } |
|
|