hyperframes 0.7.11 → 0.7.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -88,6 +88,25 @@ window.__contrastAudit = async function (imgBase64, time) {
88
88
  var cs = getComputedStyle(el);
89
89
  if (cs.visibility === "hidden" || cs.display === "none") continue;
90
90
  if (parseFloat(cs.opacity) <= 0.01) continue;
91
+ // Also skip when an ANCESTOR is effectively invisible (opacity≈0 / hidden / display:none).
92
+ // Karaoke captions keep every word at opacity 1 but toggle the GROUP's opacity per beat,
93
+ // so an inactive word's OWN opacity is 1 — only an ancestor reveals it's hidden. Without
94
+ // this, the hidden caption words flood the audit with false ~1:1 contrast warnings.
95
+ var anc = el.parentElement,
96
+ ancHidden = false;
97
+ while (anc && anc !== document.body) {
98
+ var acs = getComputedStyle(anc);
99
+ if (
100
+ acs.visibility === "hidden" ||
101
+ acs.display === "none" ||
102
+ parseFloat(acs.opacity) <= 0.01
103
+ ) {
104
+ ancHidden = true;
105
+ break;
106
+ }
107
+ anc = anc.parentElement;
108
+ }
109
+ if (ancHidden) continue;
91
110
  var rect = el.getBoundingClientRect();
92
111
  if (rect.width < 8 || rect.height < 8) continue;
93
112
  if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= w || rect.top >= h) continue;
@@ -27,14 +27,18 @@
27
27
  return Math.round(value * 100) / 100;
28
28
  }
29
29
 
30
- function overflowFor(subject, container, tolerance) {
30
+ function overflowFor(subject, container, tolerance, vTolerance) {
31
+ // Horizontal axis uses `tolerance`; vertical axis uses `vTolerance` (defaults to the same).
32
+ // A separate vertical tolerance lets text overflow checks absorb glyph ink that exceeds a
33
+ // snug line-height — see textOverflowIssues.
34
+ if (vTolerance == null) vTolerance = tolerance;
31
35
  const overflow = {};
32
36
  if (subject.left < container.left - tolerance)
33
37
  overflow.left = round(container.left - subject.left);
34
38
  if (subject.right > container.right + tolerance)
35
39
  overflow.right = round(subject.right - container.right);
36
- if (subject.top < container.top - tolerance) overflow.top = round(container.top - subject.top);
37
- if (subject.bottom > container.bottom + tolerance)
40
+ if (subject.top < container.top - vTolerance) overflow.top = round(container.top - subject.top);
41
+ if (subject.bottom > container.bottom + vTolerance)
38
42
  overflow.bottom = round(subject.bottom - container.bottom);
39
43
  return Object.keys(overflow).length > 0 ? overflow : null;
40
44
  }
@@ -319,9 +323,22 @@
319
323
 
320
324
  const container = nearestConstraint(element, root, rootRect);
321
325
  const containerRect = container === root ? rootRect : toRect(container.getBoundingClientRect());
322
- const containerOverflow = overflowFor(textRect, containerRect, tolerance);
326
+ // Glyph ink (ascenders / descenders / accents / heavy display faces) routinely exceeds a
327
+ // snug line-height box by a few px, proportional to font size. When the constraining box
328
+ // does NOT clip, that vertical spill is normal typography — it shows in the padding, nothing
329
+ // is hidden — not a layout defect (it false-flagged caption words). Allow a font-metric
330
+ // vertical tolerance there; keep it tight when the box actually clips (a real cut-off) and
331
+ // always tight horizontally (too-wide text is a real wrap/legibility issue).
332
+ const elementStyle = getComputedStyle(element);
333
+ const containerClips = clipsOverflow(
334
+ container === root ? getComputedStyle(root) : getComputedStyle(container),
335
+ );
336
+ const verticalTolerance = containerClips
337
+ ? tolerance
338
+ : Math.max(tolerance, parsePx(elementStyle.fontSize) * 0.2);
339
+ const containerOverflow = overflowFor(textRect, containerRect, tolerance, verticalTolerance);
323
340
  if (containerOverflow && !hasAllowOverflowFlag(element)) {
324
- const style = getComputedStyle(element);
341
+ const style = elementStyle;
325
342
  issues.push({
326
343
  code: "text_box_overflow",
327
344
  severity: "error",