mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-13 07:40:06 +00:00
fix(fonts): cover rendered case variants in subsets
This commit is contained in:
@@ -39,4 +39,47 @@ describe("Google Fonts text subsetting", () => {
|
|||||||
|
|
||||||
expect(new URL(requestedUrl).searchParams.get("text")).toContain("旅行");
|
expect(new URL(requestedUrl).searchParams.get("text")).toContain("旅行");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("includes case variants for transformed supplemental alias weights", async () => {
|
||||||
|
let requestedUrl = "";
|
||||||
|
const fetchImpl = (async (input: unknown) => {
|
||||||
|
requestedUrl = String(input);
|
||||||
|
return new Response("", { status: 400 });
|
||||||
|
}) as unknown as typeof fetch;
|
||||||
|
|
||||||
|
await injectDeterministicFontFaces(
|
||||||
|
`<!doctype html><html><head><style>
|
||||||
|
h1 { font-family: "Inter", sans-serif; font-weight: 800; text-transform: uppercase; }
|
||||||
|
</style></head><body><h1>Your Kidney Transplant:<br/>What Happens Next</h1></body></html>`,
|
||||||
|
{ fetchImpl, allowSystemFontCapture: false },
|
||||||
|
);
|
||||||
|
|
||||||
|
const text = new URL(requestedUrl).searchParams.get("text") ?? "";
|
||||||
|
for (const character of new Set("YOUR KIDNEY TRANSPLANT:WHAT HAPPENS NEXT")) {
|
||||||
|
expect(text).toContain(character);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("falls back to the full font when case closure exceeds the text URL budget", async () => {
|
||||||
|
let requestedUrl = "";
|
||||||
|
const fetchImpl = (async (input: unknown) => {
|
||||||
|
requestedUrl = String(input);
|
||||||
|
return new Response("", { status: 400 });
|
||||||
|
}) as unknown as typeof fetch;
|
||||||
|
const caseChangingCharacters = Array.from({ length: 0x500 }, (_, index) =>
|
||||||
|
String.fromCodePoint(index),
|
||||||
|
)
|
||||||
|
.filter((character) => character.toUpperCase() !== character.toLowerCase())
|
||||||
|
.slice(0, 300)
|
||||||
|
.join("");
|
||||||
|
|
||||||
|
await injectDeterministicFontFaces(
|
||||||
|
`<!doctype html><html><head><style>
|
||||||
|
p { font-family: "Inter", sans-serif; font-weight: 800; text-transform: uppercase; }
|
||||||
|
</style></head><body><p>${caseChangingCharacters}</p></body></html>`,
|
||||||
|
{ fetchImpl, allowSystemFontCapture: false },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(new URL(requestedUrl).searchParams.has("text")).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1193,18 +1193,26 @@ export interface InjectDeterministicFontFacesOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Keep the complete CSS request under the broadly supported ~2 KB URL limit.
|
// Keep the complete CSS request under the broadly supported ~2 KB URL limit.
|
||||||
// Using unique source characters covers static text plus strings authored in
|
// Using unique source/decoded characters plus deterministic case variants covers
|
||||||
// scripts, while collapsing repeated prose and base64 assets to a tiny set.
|
// static text, strings authored in scripts, and CSS case transforms while
|
||||||
|
// collapsing repeated prose and base64 assets to a tiny set.
|
||||||
const GOOGLE_FONTS_TEXT_MAX_ENCODED_LENGTH = 1_700;
|
const GOOGLE_FONTS_TEXT_MAX_ENCODED_LENGTH = 1_700;
|
||||||
|
|
||||||
function extractGoogleFontsText(html: string): string | undefined {
|
function extractGoogleFontsText(html: string): string | undefined {
|
||||||
const { document } = parseHTML(html);
|
const { document } = parseHTML(html);
|
||||||
const decodedBodyText = document.body?.textContent ?? "";
|
const decodedBodyText = document.body?.textContent ?? "";
|
||||||
const uniqueCharacters = [...new Set([...Array.from(html), ...Array.from(decodedBodyText)])].join(
|
const characters = [...Array.from(html), ...Array.from(decodedBodyText)];
|
||||||
"",
|
const uniqueCharacters = new Set<string>();
|
||||||
);
|
for (const character of characters) {
|
||||||
return encodeURIComponent(uniqueCharacters).length <= GOOGLE_FONTS_TEXT_MAX_ENCODED_LENGTH
|
uniqueCharacters.add(character);
|
||||||
? uniqueCharacters
|
// CSS text-transform can render glyphs absent from the authored source.
|
||||||
|
for (const variant of `${character.toUpperCase()}${character.toLowerCase()}`) {
|
||||||
|
uniqueCharacters.add(variant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const fontText = [...uniqueCharacters].join("");
|
||||||
|
return encodeURIComponent(fontText).length <= GOOGLE_FONTS_TEXT_MAX_ENCODED_LENGTH
|
||||||
|
? fontText
|
||||||
: undefined;
|
: undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user