Files
jobtrackingapp/job-tracker-ui/e2e/helpers/nameInkClearance.ts
T

28 lines
1.4 KiB
TypeScript

// Run in the preview frame after fonts/pagination settle, rather than using text-cell tops.
export function minimumNameInkClearance(selector: string): number {
const name = document.querySelector(selector);
const flow = document.querySelector('[data-cv-preview-flow]');
const context = document.createElement('canvas').getContext('2d');
if (!name || !flow || !context) throw new Error('Missing name or settled print fragment');
const clipTop = flow.getBoundingClientRect().top;
const clearance: number[] = [];
const walker = document.createTreeWalker(name, NodeFilter.SHOW_TEXT);
let node;
while ((node = walker.nextNode())) {
const style = getComputedStyle(node.parentElement!);
context.font = `${style.fontStyle} ${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;
let offset = 0;
for (const character of node.textContent || '') {
const range = document.createRange();
range.setStart(node, offset); range.setEnd(node, offset + character.length);
offset += character.length;
if (!character.trim()) continue;
const rect = range.getClientRects()[0], glyph = context.measureText(character);
if (!rect) throw new Error('Name glyph has no rendered position');
clearance.push(rect.top + glyph.fontBoundingBoxAscent - glyph.actualBoundingBoxAscent - clipTop);
}
}
if (!clearance.length) throw new Error('Empty name cannot qualify glyph clearance');
return Math.min(...clearance);
}