Skip to content

Commit be6723f

Browse files
committed
fix(pat scroll-marker): Do not break if no scroll-marker observables have been found.
1 parent ccc3ddc commit be6723f

File tree

2 files changed

+69
-8
lines changed

2 files changed

+69
-8
lines changed

src/pat/scroll-marker/scroll-marker.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,16 @@ class Pattern extends BasePattern {
5353
// Find a possible scroll container based on the first target/content
5454
// element in the observables map.
5555
// Note, a Map's values method returns an iterator.
56-
const first_target = this.observables.values().next()?.value.target;
57-
this.scroll_container = dom.find_scroll_container(first_target, "y", window);
56+
const first_observable = this.observables.values().next();
57+
if (!first_observable.value) {
58+
// No targets found.
59+
return;
60+
}
61+
this.scroll_container = dom.find_scroll_container(
62+
first_observable.value.target,
63+
"y",
64+
window
65+
);
5866
// window.innerHeight or el.clientHeight
5967
const scroll_container_height =
6068
typeof this.scroll_container.innerHeight !== "undefined"

src/pat/scroll-marker/scroll-marker.test.js

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ async function create_scroll_marker({
7070
});
7171

7272
const instance = new Pattern(el, options);
73+
jest.spyOn(instance, "scroll_marker_callback");
74+
jest.spyOn(instance, "scroll_marker_current_callback");
75+
7376
await events.await_pattern_init(instance);
7477

7578
instance.scroll_marker_callback([
@@ -99,6 +102,24 @@ describe("pat-scroll-marker", () => {
99102
document.body.innerHTML = "";
100103
});
101104

105+
it("0: Inexistent targets do not break the runtime", async () => {
106+
document.body.innerHTML = `
107+
<nav class="pat-scroll-marker">
108+
<a href="#id1">link 1</a>
109+
<a href="#id2">link 2</a>
110+
<a href="#id3">link 3</a>
111+
</nav>
112+
`;
113+
const el = document.querySelector(".pat-scroll-marker");
114+
const instance = new Pattern(el);
115+
jest.spyOn(instance, "scroll_marker_callback");
116+
jest.spyOn(instance, "scroll_marker_current_callback");
117+
await events.await_pattern_init(instance);
118+
119+
expect(instance.scroll_marker_callback).not.toHaveBeenCalled();
120+
expect(instance.scroll_marker_current_callback).not.toHaveBeenCalled();
121+
});
122+
102123
describe("1: Test on window as scroll container", () => {
103124
it("1.1: default values, id3 is current", async () => {
104125
// With the default values the baseline is in the middle and the
@@ -113,6 +134,10 @@ describe("pat-scroll-marker", () => {
113134
// container is the window object.
114135
expect(instance.scroll_container).toBe(window);
115136

137+
// Callbacks have been called.
138+
expect(instance.scroll_marker_callback).toHaveBeenCalled();
139+
expect(instance.scroll_marker_current_callback).toHaveBeenCalled();
140+
116141
expect(nav_id1.classList.contains("in-view")).toBe(false);
117142
expect(nav_id2.classList.contains("in-view")).toBe(true);
118143
expect(nav_id3.classList.contains("in-view")).toBe(true);
@@ -127,13 +152,17 @@ describe("pat-scroll-marker", () => {
127152
});
128153

129154
it("1.2: distance 0, id2 is current", async () => {
130-
const { nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
155+
const { instance, nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
131156
await create_scroll_marker({
132157
options: {
133158
distance: 0,
134159
},
135160
});
136161

162+
// Callbacks have been called.
163+
expect(instance.scroll_marker_callback).toHaveBeenCalled();
164+
expect(instance.scroll_marker_current_callback).toHaveBeenCalled();
165+
137166
expect(nav_id1.classList.contains("in-view")).toBe(false);
138167
expect(nav_id2.classList.contains("in-view")).toBe(true);
139168
expect(nav_id3.classList.contains("in-view")).toBe(true);
@@ -148,14 +177,18 @@ describe("pat-scroll-marker", () => {
148177
});
149178

150179
it("1.3: distance 50, side bottom, id2 is current", async () => {
151-
const { nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
180+
const { instance, nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
152181
await create_scroll_marker({
153182
options: {
154183
distance: "50%",
155184
side: "bottom",
156185
},
157186
});
158187

188+
// Callbacks have been called.
189+
expect(instance.scroll_marker_callback).toHaveBeenCalled();
190+
expect(instance.scroll_marker_current_callback).toHaveBeenCalled();
191+
159192
expect(nav_id1.classList.contains("in-view")).toBe(false);
160193
expect(nav_id2.classList.contains("in-view")).toBe(true);
161194
expect(nav_id3.classList.contains("in-view")).toBe(true);
@@ -174,7 +207,7 @@ describe("pat-scroll-marker", () => {
174207
// Only the visibility is set to most-visible, which means that id2 is
175208
// the current one,
176209
//
177-
const { nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
210+
const { instance, nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
178211
await create_scroll_marker({
179212
options: {
180213
distance: "50%",
@@ -183,6 +216,10 @@ describe("pat-scroll-marker", () => {
183216
},
184217
});
185218

219+
// Callbacks have been called.
220+
expect(instance.scroll_marker_callback).toHaveBeenCalled();
221+
expect(instance.scroll_marker_current_callback).toHaveBeenCalled();
222+
186223
expect(nav_id1.classList.contains("in-view")).toBe(false);
187224
expect(nav_id2.classList.contains("in-view")).toBe(true);
188225
expect(nav_id3.classList.contains("in-view")).toBe(true);
@@ -211,6 +248,10 @@ describe("pat-scroll-marker", () => {
211248
// container is the window object.
212249
expect(instance.scroll_container).toBe(main);
213250

251+
// Callbacks have been called.
252+
expect(instance.scroll_marker_callback).toHaveBeenCalled();
253+
expect(instance.scroll_marker_current_callback).toHaveBeenCalled();
254+
214255
expect(nav_id1.classList.contains("in-view")).toBe(false);
215256
expect(nav_id2.classList.contains("in-view")).toBe(true);
216257
expect(nav_id3.classList.contains("in-view")).toBe(true);
@@ -225,14 +266,18 @@ describe("pat-scroll-marker", () => {
225266
});
226267

227268
it("2.2: distance 0, id2 is current", async () => {
228-
const { nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
269+
const { instance, nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
229270
await create_scroll_marker({
230271
options: {
231272
distance: 0,
232273
},
233274
scroll_container_main: true,
234275
});
235276

277+
// Callbacks have been called.
278+
expect(instance.scroll_marker_callback).toHaveBeenCalled();
279+
expect(instance.scroll_marker_current_callback).toHaveBeenCalled();
280+
236281
expect(nav_id1.classList.contains("in-view")).toBe(false);
237282
expect(nav_id2.classList.contains("in-view")).toBe(true);
238283
expect(nav_id3.classList.contains("in-view")).toBe(true);
@@ -247,7 +292,7 @@ describe("pat-scroll-marker", () => {
247292
});
248293

249294
it("2.3: distance 50, side bottom, id2 is current", async () => {
250-
const { nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
295+
const { instance, nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
251296
await create_scroll_marker({
252297
options: {
253298
distance: "50%",
@@ -256,6 +301,10 @@ describe("pat-scroll-marker", () => {
256301
scroll_container_main: true,
257302
});
258303

304+
// Callbacks have been called.
305+
expect(instance.scroll_marker_callback).toHaveBeenCalled();
306+
expect(instance.scroll_marker_current_callback).toHaveBeenCalled();
307+
259308
expect(nav_id1.classList.contains("in-view")).toBe(false);
260309
expect(nav_id2.classList.contains("in-view")).toBe(true);
261310
expect(nav_id3.classList.contains("in-view")).toBe(true);
@@ -274,7 +323,7 @@ describe("pat-scroll-marker", () => {
274323
// Only the visibility is set to most-visible, which means that id2 is
275324
// the current one,
276325
//
277-
const { nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
326+
const { instance, nav_id1, nav_id2, nav_id3, id1, id2, id3 } =
278327
await create_scroll_marker({
279328
options: {
280329
distance: "50%",
@@ -284,6 +333,10 @@ describe("pat-scroll-marker", () => {
284333
scroll_container_main: true,
285334
});
286335

336+
// Callbacks have been called.
337+
expect(instance.scroll_marker_callback).toHaveBeenCalled();
338+
expect(instance.scroll_marker_current_callback).toHaveBeenCalled();
339+
287340
expect(nav_id1.classList.contains("in-view")).toBe(false);
288341
expect(nav_id2.classList.contains("in-view")).toBe(true);
289342
expect(nav_id3.classList.contains("in-view")).toBe(true);

0 commit comments

Comments
 (0)