|
|
import { morphdom } from '../../lib.js'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function isSegmenterSupported() { |
|
|
return typeof Intl.Segmenter === 'function'; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function segmentTextInElement(htmlElement, htmlContent, granularity = 'word') { |
|
|
htmlElement.innerHTML = htmlContent; |
|
|
|
|
|
if (!isSegmenterSupported()) { |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
const segmenter = new Intl.Segmenter('en-US', { granularity }); |
|
|
const textNodes = []; |
|
|
const walker = document.createTreeWalker(htmlElement, NodeFilter.SHOW_TEXT); |
|
|
while (walker.nextNode()) { |
|
|
const textNode = (walker.currentNode); |
|
|
|
|
|
|
|
|
if (textNode.parentElement && textNode.parentElement.closest('pre, code')) { |
|
|
continue; |
|
|
} |
|
|
|
|
|
|
|
|
if (/^\s*$/.test(textNode.data)) { |
|
|
continue; |
|
|
} |
|
|
|
|
|
textNodes.push(textNode); |
|
|
} |
|
|
|
|
|
|
|
|
for (const textNode of textNodes) { |
|
|
const fragment = document.createDocumentFragment(); |
|
|
const segments = segmenter.segment(textNode.data); |
|
|
for (const segment of segments) { |
|
|
|
|
|
|
|
|
const span = document.createElement('span'); |
|
|
span.innerText = segment.segment; |
|
|
span.className = 'text_segment'; |
|
|
fragment.appendChild(span); |
|
|
} |
|
|
textNode.replaceWith(fragment); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function applyStreamFadeIn(messageTextElement, htmlContent) { |
|
|
const targetElement = (messageTextElement.cloneNode()); |
|
|
segmentTextInElement(targetElement, htmlContent); |
|
|
morphdom(messageTextElement, targetElement); |
|
|
} |
|
|
|