Reader: visible text selection in every theme; highlights follow across translations
Build and Push Docker Image / build-and-push (push) Failing after 19s
Build and Push Docker Image / build-and-push (push) Failing after 19s
Selection - Selected text uses a per-theme colour (it was nearly invisible on Dark) - The colour picker also appears on touch screens after dragging the selection handles, and sits below the selection there so the system menu doesn't cover it Highlights - Each highlight remembers its translation and whether it covers the whole verse - In another translation the same words are found again (ignoring case and punctuation); whole-verse highlights cover the whole verse; when the wording differs, the verse gets a small colour dot instead of marking the wrong words - Older highlights are checked against their saved words instead of trusted - Server keeps the new fields Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aabd4267b8
commit
a0971eab29
9 files changed
+189
-38
No files matched your search
@@ -0,0 +1,23 @@
|
||||
import { test, expect } from 'vitest';
|
||||
import { READER_THEMES } from './readerThemes.js';
|
||||
|
||||
// Contrast of two #rrggbb colours (WCAG ratio), used to make sure selected text can be seen on every theme.
|
||||
const lum = (hex) => {
|
||||
const [r, g, b] = [1, 3, 5].map((i) => parseInt(hex.slice(i, i + 2), 16) / 255).map((c) => (c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4));
|
||||
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
};
|
||||
const mix = (bg, rgba) => {
|
||||
const [r, g, b, a] = rgba.match(/[\d.]+/g).map(Number);
|
||||
return `#${[r, g, b].map((c, i) => Math.round(c * a + parseInt(bg.slice(1 + i * 2, 3 + i * 2), 16) * (1 - a)).toString(16).padStart(2, '0')).join('')}`;
|
||||
};
|
||||
const ratio = (a, b) => { const [x, y] = [lum(a), lum(b)].sort((p, q) => q - p); return (x + 0.05) / (y + 0.05); };
|
||||
|
||||
test('every theme sets a selection colour that is different from the page and keeps text readable', () => {
|
||||
for (const [id, theme] of Object.entries(READER_THEMES)) {
|
||||
const v = theme.vars;
|
||||
expect(v['--r-sel'], id).toBeTruthy();
|
||||
const selected = mix(v['--r-bg'], v['--r-sel']);
|
||||
expect(ratio(selected, v['--r-bg']), `${id}: selection stands out from the page`).toBeGreaterThan(1.25);
|
||||
expect(ratio(selected, v['--r-text']), `${id}: text stays readable on the selection`).toBeGreaterThan(4);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user