mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 07:19:52 +00:00
fix(cli): skip contrast for intentionally covered text (#2366)
This commit is contained in:
@@ -131,6 +131,12 @@ window.__contrastAuditPrepare = function () {
|
||||
return !paintsAnyProbePoint(el, rect);
|
||||
}
|
||||
|
||||
function isIntentionallyOccluded(el, rect) {
|
||||
if (typeof document.elementFromPoint !== "function") return false;
|
||||
if (!el.closest || !el.closest("[data-layout-allow-occlusion]")) return false;
|
||||
return !paintsAnyProbePoint(el, rect);
|
||||
}
|
||||
|
||||
var out = [];
|
||||
var restores = [];
|
||||
// Registered BEFORE the walk starts (not after it finishes) and pushed to
|
||||
@@ -200,6 +206,10 @@ window.__contrastAuditPrepare = function () {
|
||||
if (rect.width < 8 || rect.height < 8) continue;
|
||||
if (rect.right <= 0 || rect.bottom <= 0) continue;
|
||||
if (isClippedAway(el, rect)) continue;
|
||||
// The layout audit's explicit occlusion opt-out means this text is allowed
|
||||
// to sit behind another scene. Skip contrast only while every probe point
|
||||
// is actually covered; the same copy is audited normally when visible.
|
||||
if (isIntentionallyOccluded(el, rect)) continue;
|
||||
|
||||
// For SVG text, `fill` is the paint that's actually rendered; `color` is
|
||||
// frequently just the inherited/initial value and unrelated to what's on
|
||||
|
||||
@@ -635,6 +635,68 @@ describe("contrast-audit.browser clip-path visibility", () => {
|
||||
expect(selectors).not.toContain("#rail-label");
|
||||
});
|
||||
|
||||
it("excludes intentionally occluded text from contrast reports", async () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="root" data-composition-id="main" data-width="640" data-height="360">
|
||||
<div id="headline" data-layout-allow-occlusion>Covered copy</div>
|
||||
<div id="cover"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
vi.spyOn(window, "getComputedStyle").mockImplementation(
|
||||
() =>
|
||||
({
|
||||
display: "block",
|
||||
visibility: "visible",
|
||||
opacity: "1",
|
||||
color: "rgb(255, 255, 255)",
|
||||
fontSize: "32px",
|
||||
fontWeight: "400",
|
||||
clipPath: "none",
|
||||
}) as unknown as CSSStyleDeclaration,
|
||||
);
|
||||
vi.spyOn(document.getElementById("headline")!, "getBoundingClientRect").mockReturnValue(
|
||||
rect({ left: 100, top: 100, width: 400, height: 40 }),
|
||||
);
|
||||
(document as unknown as { elementFromPoint: () => Element | null }).elementFromPoint = () =>
|
||||
document.getElementById("cover");
|
||||
|
||||
installContrastScript();
|
||||
|
||||
expect(await runContrastAudit()).toEqual([]);
|
||||
});
|
||||
|
||||
it("still audits visible text that allows occlusion", async () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="root" data-composition-id="main" data-width="640" data-height="360">
|
||||
<div id="headline" data-layout-allow-occlusion>Visible copy</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
vi.spyOn(window, "getComputedStyle").mockImplementation(
|
||||
() =>
|
||||
({
|
||||
display: "block",
|
||||
visibility: "visible",
|
||||
opacity: "1",
|
||||
color: "rgb(255, 255, 255)",
|
||||
fontSize: "32px",
|
||||
fontWeight: "400",
|
||||
clipPath: "none",
|
||||
}) as unknown as CSSStyleDeclaration,
|
||||
);
|
||||
vi.spyOn(document.getElementById("headline")!, "getBoundingClientRect").mockReturnValue(
|
||||
rect({ left: 100, top: 100, width: 400, height: 40 }),
|
||||
);
|
||||
(document as unknown as { elementFromPoint: () => Element | null }).elementFromPoint = () =>
|
||||
document.getElementById("headline");
|
||||
|
||||
installContrastScript();
|
||||
|
||||
const entries = await runContrastAudit();
|
||||
expect(entries.map((entry) => entry.selector)).toContain("#headline");
|
||||
});
|
||||
|
||||
it("excludes text that has left the canvas from contrast reports", async () => {
|
||||
document.body.innerHTML = `
|
||||
<div id="root" data-composition-id="main" data-width="640" data-height="360">
|
||||
|
||||
Reference in New Issue
Block a user