diff --git a/index.html b/index.html index 8b347e5..5ee3749 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - + Hive Commons @@ -1146,14 +1146,17 @@

Thanks to the organizations that power Hive Commons< } function stop() { clearInterval(timer); timer = null; } function restart() { stop(); start(); } - root.addEventListener('mouseenter', function () { pointerPaused = true; stop(); }); - root.addEventListener('mouseleave', function () { pointerPaused = false; start(); }); - root.addEventListener('focusin', function () { focusPaused = true; stop(); }); - root.addEventListener('focusout', function (e) { - if (!root.contains(e.relatedTarget)) { - focusPaused = false; - start(); - } + [root, controls].forEach(function (el) { + if (!el) return; + el.addEventListener('mouseenter', function () { pointerPaused = true; stop(); }); + el.addEventListener('mouseleave', function () { pointerPaused = false; start(); }); + el.addEventListener('focusin', function () { focusPaused = true; stop(); }); + el.addEventListener('focusout', function (e) { + if (!root.contains(e.relatedTarget) && !(controls && controls.contains(e.relatedTarget))) { + focusPaused = false; + start(); + } + }); }); document.addEventListener('visibilitychange', function () { document.hidden ? stop() : start(); }); if (reduceMotion.addEventListener) { diff --git a/scripts/carousels.test.mjs b/scripts/carousels.test.mjs index 1e9f678..f33f909 100644 --- a/scripts/carousels.test.mjs +++ b/scripts/carousels.test.mjs @@ -789,6 +789,22 @@ test("projects pause: pointer hovering then external focusout stays paused until assert.deepEqual(t.timers.intervals(), [PROJECT_ADVANCE_MS], "resumes once neither is inside"); }); +test("projects pause: hovering or focusing the external Prev/Next controls pauses auto-advance", () => { + const t = bootProjects(); + t.controls.dispatch("mouseenter"); + assert.deepEqual(t.timers.intervals(), [], "hover on controls pauses"); + t.controls.dispatch("mouseleave"); + assert.deepEqual(t.timers.intervals(), [PROJECT_ADVANCE_MS], "leaving controls resumes"); + t.controls.dispatch("focusin"); + assert.deepEqual(t.timers.intervals(), [], "focus on controls pauses"); + t.controls.dispatch("focusout", { relatedTarget: t.root }); + assert.deepEqual(t.timers.intervals(), [], "focus moving into the carousel stays paused"); + t.root.dispatch("focusout", { relatedTarget: t.next }); + assert.deepEqual(t.timers.intervals(), [], "focus moving back to the controls stays paused"); + t.controls.dispatch("focusout", { relatedTarget: null }); + assert.deepEqual(t.timers.intervals(), [PROJECT_ADVANCE_MS], "resumes once focus leaves both"); +}); + test("projects reduced-motion toggle: stops and resumes auto-advance", () => { const t = bootProjects(); t.mq.set(true);