An interface font and a reading font in Settings (#359)
The font chosen before is the interface's, under the same cookie, so a choice already made stays as it was. The reading font, ipx_rfont, sets an item's title and text and is the interface's until chosen. Text read in a serif gets a line height of 1.75 for 1.65, whichever setting put it there. Each face's stack is a custom property, used by both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -82,7 +82,7 @@ if (PAGE === 'index.html') {
|
||||
|
||||
// theme.ts keeps the Settings theme controls in step when Settings is open, and looks before it
|
||||
// touches them. The admin page has no Settings, so those are the ones it may ask for and not find.
|
||||
const OPTIONAL = new Set(['#stheme', '#smode', '#smodefield', '#sfont']);
|
||||
const OPTIONAL = new Set(['#stheme', '#smode', '#smodefield', '#sfont', '#srfont']);
|
||||
missing.splice(0, missing.length, ...missing.filter(sel => !OPTIONAL.has(sel)));
|
||||
if (missing.length) {
|
||||
console.error('FAIL: handlers wired to elements that do not exist: ' + [...new Set(missing)].join(', '));
|
||||
|
||||
@@ -171,6 +171,31 @@ test('a font chosen in Settings is kept in this browser, over any theme\'s own',
|
||||
expect(await face()).toMatch(/^Inter/);
|
||||
});
|
||||
|
||||
test('the reading font is an item\'s title and text, and the interface keeps its own', async ({ page }) => {
|
||||
const fam = (sel) => page.locator(sel).first().evaluate(el => getComputedStyle(el).fontFamily);
|
||||
await page.locator('.feed', { hasText: 'Picture Blog' }).click();
|
||||
await page.locator('.ep', { hasText: 'An Article' }).click();
|
||||
await expect(page.locator('#detail .dt')).toHaveText('An Article');
|
||||
await page.locator('#prefs').click();
|
||||
await page.locator('#sfont').selectOption('atkinson');
|
||||
await expect(page.locator('#srfont'), 'the same as the interface until chosen').toHaveValue('same');
|
||||
expect(await fam('#detail .dbody')).toMatch(/^"Atkinson/);
|
||||
|
||||
await page.locator('#srfont').selectOption('literata');
|
||||
expect((await page.context().cookies()).find(c => c.name === 'ipx_rfont')?.value).toBe('literata');
|
||||
expect(await fam('#detail .dt')).toMatch(/^Literata/);
|
||||
expect(await fam('#detail .dbody')).toMatch(/^Literata/);
|
||||
expect(await fam('#feedlist')).toMatch(/^"Atkinson/);
|
||||
// A serif gets more room between its lines (1.75 of the text's size, against 1.65).
|
||||
const lh = await page.locator('#detail .dbody').evaluate(el => { const c = getComputedStyle(el); return parseFloat(c.lineHeight) / parseFloat(c.fontSize); });
|
||||
expect(lh).toBeCloseTo(1.75, 2);
|
||||
|
||||
await page.locator('#srfont').selectOption('same');
|
||||
await page.locator('#sfont').selectOption('theme');
|
||||
expect(await fam('#detail .dbody')).toMatch(/^Inter/);
|
||||
await page.locator('#modal .cardx').click();
|
||||
});
|
||||
|
||||
test('a theme this browser kept in localStorage becomes its cookie once', async ({ browser }) => {
|
||||
const who = `theme-${Date.now()}@example.com`;
|
||||
const ctx = await browser.newContext({ extraHTTPHeaders: { 'X-Test-User': who } });
|
||||
|
||||
Reference in New Issue
Block a user