Skip to content

Commit d713396

Browse files
Change segment view to allow for infinite scroll within a book
1 parent eae720d commit d713396

13 files changed

Lines changed: 1201 additions & 108 deletions

cspell.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,16 @@
3838
"morphosyntactic",
3939
"nums",
4040
"okina",
41+
"overscan",
4142
"papi",
4243
"paranext",
4344
"paratext",
4445
"pdpf",
4546
"plusplus",
4647
"punct",
48+
"recentered",
49+
"recentering",
50+
"recenters",
4751
"relayout",
4852
"sandboxed",
4953
"scriptio",
@@ -54,6 +58,7 @@
5458
"Stylesheet",
5559
"typedefs",
5660
"unhover",
61+
"unobserves",
5762
"unphrased",
5863
"unreviewed",
5964
"unsub",

jest.config.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,11 @@ const config: Config = {
108108
modulePathIgnorePatterns: ['<rootDir>/dist'],
109109

110110
/** Load @testing-library/jest-dom matchers and browser API stubs for React component tests. */
111-
setupFilesAfterEnv: ['<rootDir>/jest.setup.resize-observer.js', '<rootDir>/jest.setup.ts'],
111+
setupFilesAfterEnv: [
112+
'<rootDir>/jest.setup.resize-observer.js',
113+
'<rootDir>/jest.setup.intersection-observer.js',
114+
'<rootDir>/jest.setup.ts',
115+
],
112116

113117
/** Use jsdom for React component tests; parser tests run fine in jsdom (no DOM use). */
114118
testEnvironment: 'jsdom',
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* eslint-disable no-underscore-dangle */
2+
// jsdom does not implement IntersectionObserver; stub it so hooks that use it don't throw.
3+
// Plain JS to avoid TypeScript/ESLint restrictions on type assertions and class rules.
4+
//
5+
// The stub records every constructed observer and the elements it observes on `global.ioInstances`
6+
// so tests can drive intersections deterministically. `triggerIntersection(el, isIntersecting)`
7+
// finds the observer watching `el` and invokes its callback with a minimal entry.
8+
global.ioInstances = [];
9+
10+
global.IntersectionObserver = function IntersectionObserver(callback, options) {
11+
const targets = new Set();
12+
const instance = {
13+
callback,
14+
options,
15+
targets,
16+
observe(el) {
17+
targets.add(el);
18+
},
19+
unobserve(el) {
20+
targets.delete(el);
21+
},
22+
disconnect() {
23+
targets.clear();
24+
const i = global.ioInstances.indexOf(instance);
25+
if (i !== -1) global.ioInstances.splice(i, 1);
26+
},
27+
takeRecords() {
28+
return [];
29+
},
30+
};
31+
global.ioInstances.push(instance);
32+
return instance;
33+
};
34+
35+
// Fires an intersection for `el` on whichever observer is watching it.
36+
global.triggerIntersection = function triggerIntersection(el, isIntersecting) {
37+
global.ioInstances.forEach((instance) => {
38+
if (instance.targets.has(el)) {
39+
instance.callback([{ target: el, isIntersecting }], instance);
40+
}
41+
});
42+
};

0 commit comments

Comments
 (0)