From dd7daa7d7afd043960f910895f16d224d3b14c34 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Wed, 27 May 2026 17:47:33 +0300 Subject: [PATCH] =?UTF-8?q?fix(tracker):=204-=D0=B9=20=D1=85=D1=83=D0=BA?= =?UTF-8?q?=20=E2=80=94=20polling=20=D0=BF=D0=BE=20.para-pill.active?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Если ни bubble, ни capture, ни setParaTab-patch не сработали (например, страница использует другой механизм навигации), наблюдаем DOM раз в 500мс на изменение класса .active у пилюли. Когда активная пилюля меняется — фиксируем визит. Это самый robust способ: работает независимо от событий, функций и библиотек страницы. Стоит копейки — один querySelector в 500мс. --- frontend/js/textbook-tracker.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/frontend/js/textbook-tracker.js b/frontend/js/textbook-tracker.js index 5148c5d..9f3e21a 100644 --- a/frontend/js/textbook-tracker.js +++ b/frontend/js/textbook-tracker.js @@ -283,6 +283,21 @@ if (typeof window.setParaTab === 'function' && window.setParaTab.__tbPatched) clearInterval(ivl); if (++tries > 20) clearInterval(ivl); }, 100); + // Hook 4: polling — наблюдаем за классом .active на пилюлях. + // Если кто-то поменял активный параграф (через клик, через JS вызов + // setParaTab, через любой механизм) — мы это поймаем за 500мс и зафиксируем. + // Самый robust способ; не зависит ни от событий, ни от наличия функций. + let lastActivePara = null; + setInterval(() => { + const active = document.querySelector('.para-pill.active[data-para]'); + if (!active) return; + const para = active.dataset.para; + if (para && para !== lastActivePara) { + if (lastActivePara !== null) console.log('[tracker] активный параграф изменился на', para); + lastActivePara = para; + recordParaVisit(para); + } + }, 500); } /* ── 8. Inject styling for read-pills (subtle green dot) ─────── */