clone

a desktop tv and program guide for over-the-air broadcasts: what's on air, what your tuner gets, live tv, recordings

main
airwaves / frontend / dist / vendor / pretext / line-text.js
line-text.js 1.9K
1import { getSharedGraphemeSegmenter } from './analysis.js';2import { isDiscretionaryLineEnd } from './line-break.js';3let sharedLineTextCaches = new WeakMap();4function getSegmentGraphemeOffsets(segmentIndex, segments, cache) {5 let offsets = cache.get(segmentIndex);6 if (offsets !== undefined)7 return offsets;8 offsets = [0];9 const graphemeSegmenter = getSharedGraphemeSegmenter();10 for (const gs of graphemeSegmenter.segment(segments[segmentIndex])) {11 offsets.push(gs.index + gs.segment.length);12 }13 cache.set(segmentIndex, offsets);14 return offsets;15}16export function getLineTextCache(prepared) {17 let cache = sharedLineTextCaches.get(prepared);18 if (cache !== undefined)19 return cache;20 cache = new Map();21 sharedLineTextCaches.set(prepared, cache);22 return cache;23}24export function buildLineTextFromRange(prepared, cache, startSegmentIndex, startGraphemeIndex, endSegmentIndex, endGraphemeIndex) {25 let text = '';26 for (let i = startSegmentIndex; i < endSegmentIndex; i++) {27 if (prepared.kinds[i] === 'soft-hyphen' || prepared.kinds[i] === 'hard-break')28 continue;29 if (i === startSegmentIndex && startGraphemeIndex > 0) {30 const offsets = getSegmentGraphemeOffsets(i, prepared.segments, cache);31 text += prepared.segments[i].slice(offsets[startGraphemeIndex]);32 }33 else {34 text += prepared.segments[i];35 }36 }37 if (endGraphemeIndex > 0) {38 const offsets = getSegmentGraphemeOffsets(endSegmentIndex, prepared.segments, cache);39 text += prepared.segments[endSegmentIndex].slice(offsets[startSegmentIndex === endSegmentIndex ? startGraphemeIndex : 0], offsets[endGraphemeIndex]);40 }41 return isDiscretionaryLineEnd(prepared.kinds, endSegmentIndex, endGraphemeIndex) ? text + '-' : text;42}43export function clearLineTextCaches() {44 sharedLineTextCaches = new WeakMap();45}