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,44 @@
|
||||
import { test, expect } from 'vitest';
|
||||
import { findWords, isWholeVerse, placeHighlights } from './highlightSpans.js';
|
||||
|
||||
const BSB = 'In the beginning God created the heavens and the earth.';
|
||||
const KJV = 'In the beginning God created the heaven and the earth.';
|
||||
const hl = (extra) => ({ id: 'h', color: '#fef08a', startOffset: 3, endOffset: 16, text: 'the beginning', translation: 'BSB', ...extra });
|
||||
|
||||
test('in the same translation the saved positions are used', () => {
|
||||
expect(placeHighlights([hl()], BSB, 'BSB').spans).toEqual([{ start: 3, end: 16, id: 'h', color: '#fef08a' }]);
|
||||
});
|
||||
|
||||
test('in another translation the same words are found where they are, even if they sit elsewhere', () => {
|
||||
const other = `And so, ${KJV}`;
|
||||
const placed = placeHighlights([hl()], other, 'KJV');
|
||||
expect(placed.ghosts).toEqual([]);
|
||||
expect(other.slice(placed.spans[0].start, placed.spans[0].end)).toBe('the beginning');
|
||||
});
|
||||
|
||||
test('matching ignores case, punctuation and spacing', () => {
|
||||
expect(findWords('And God said, “Let there be light,” and there was light.', 'God said Let there be light')).toEqual({ start: 4, end: 'And God said, “Let there be light'.length });
|
||||
expect(findWords('Grace and peace', 'GRACE and PEACE')).toEqual({ start: 0, end: 15 });
|
||||
expect(findWords('Grace and peace', 'of')).toBeNull(); // too short to trust
|
||||
expect(findWords('Grace and peace', 'mercy')).toBeNull();
|
||||
});
|
||||
|
||||
test('words the other translation puts differently leave a dot, not a wrong mark', () => {
|
||||
const placed = placeHighlights([hl({ startOffset: 22, endOffset: 40, text: 'created the heavens', translation: 'BSB' })], 'In the beginning God made heaven and earth.', 'KJV');
|
||||
expect(placed.spans).toEqual([]);
|
||||
expect(placed.ghosts).toEqual([{ id: 'h', color: '#fef08a', translation: 'BSB', text: 'created the heavens' }]);
|
||||
});
|
||||
|
||||
test('a whole-verse highlight covers the whole verse in every translation', () => {
|
||||
const whole = hl({ startOffset: 0, endOffset: BSB.length, text: BSB, whole: true });
|
||||
expect(placeHighlights([whole], 'A much longer verse in another Bible than the first one was.', 'NET').spans).toEqual([{ start: 0, end: 'A much longer verse in another Bible than the first one was.'.length, id: 'h', color: '#fef08a' }]);
|
||||
expect(isWholeVerse({ startOffset: 0, endOffset: 500 }, BSB)).toBe(true); // made before the flag existed
|
||||
expect(isWholeVerse(hl(), BSB)).toBe(false);
|
||||
});
|
||||
|
||||
test('older highlights with no translation are checked against their words, not trusted blindly', () => {
|
||||
const old = { id: 'o', color: '#bbf7d0', startOffset: 3, endOffset: 16, text: 'the beginning' }; // no translation saved
|
||||
expect(placeHighlights([old], BSB, 'BSB').spans).toHaveLength(1);
|
||||
expect(placeHighlights([old], 'Before time began, God began.', 'NET').ghosts).toHaveLength(1); // the offsets would mark the wrong words here
|
||||
expect(placeHighlights([{ ...old, text: undefined }], BSB, 'BSB').spans).toHaveLength(1);
|
||||
});
|
||||
Reference in new issue
Block a user