main
js 43 lines 1.32 KB
Raw
1 const COLLAPSE_MAX_HEIGHT_EM = 15;
2 const UNMEASURABLE_WIDTH_PX = 1;
3
4 function pixels(value) {
5 const parsed = Number.parseFloat(value || "0");
6 return Number.isFinite(parsed) ? parsed : 0;
7 }
8
9 function hasUsableContentWidth(element, style = getComputedStyle(element)) {
10 const contentWidth =
11 element.clientWidth - pixels(style.paddingLeft) - pixels(style.paddingRight);
12 return contentWidth > UNMEASURABLE_WIDTH_PX;
13 }
14
15 /**
16 * Measure whether a message body exceeds its collapsed preview.
17 *
18 * Returns null while the surrounding chat has no usable layout. Replay can be
19 * rendered in a hidden or zero-width staging tree, where ordinary text wraps
20 * once per character and would otherwise produce a false overflow result.
21 */
22 export function measureMessageCollapseOverflow(
23 content,
24 { expanded = false, lazy = false } = {},
25 ) {
26 if (lazy) return true;
27 if (!content?.isConnected) return null;
28
29 const history = content.closest?.("#chat-history");
30 if (history && !hasUsableContentWidth(history)) {
31 return null;
32 }
33
34 const style = getComputedStyle(content);
35 if (!hasUsableContentWidth(content, style)) return null;
36
37 const fontSize = Number.parseFloat(style.fontSize || "16") || 16;
38 const maxHeight = expanded
39 ? fontSize * COLLAPSE_MAX_HEIGHT_EM
40 : content.clientHeight;
41
42 return content.scrollHeight > maxHeight;
43 }