MediaWiki:Common.js: Difference between revisions
No edit summary |
No edit summary |
||
| Line 343: | Line 343: | ||
toc.querySelectorAll('.gr-toc-in-path').forEach(function (el) { el.classList.remove('gr-toc-in-path'); }); | toc.querySelectorAll('.gr-toc-in-path').forEach(function (el) { el.classList.remove('gr-toc-in-path'); }); | ||
} | } | ||
function setActiveToc(id) { | function ownLink(li) { | ||
return li.querySelector(':scope > .vector-toc-link') || li.querySelector('.vector-toc-link'); | |||
} | |||
function isShown(el) { | |||
return !!(el && (el.offsetParent || (el.getClientRects && el.getClientRects().length))); | |||
} | |||
// Open a collapsed section so a given entry can be seen. Vector marks a | |||
// top-level item open with vector-toc-list-item-expanded plus | |||
// aria-expanded on its toggle, so this matches what its own button does. | |||
function expandTocFor(li) { | |||
var top = li.closest ? li.closest('.vector-toc-level-1') : null; | |||
if (!top) return; | |||
if (!top.classList.contains('vector-toc-list-item-expanded')) { | |||
top.classList.add('vector-toc-list-item-expanded'); | |||
var tg = top.querySelector('.vector-toc-toggle'); | |||
if (tg) tg.setAttribute('aria-expanded', 'true'); | |||
} | |||
var anc = li.parentNode; | |||
while (anc && anc.classList) { | |||
anc.classList.remove('vector-toc-list-item-collapsed'); | |||
if (anc.classList.contains('vector-toc')) break; | |||
anc = anc.parentNode; | |||
} | |||
} | |||
// expand=true when the reader picked the entry (TOC click, search | |||
// result, #hash): open its section so the exact entry is shown. | |||
// expand=false while scrolling: never open or close anything — if the | |||
// entry is hidden inside a collapsed section, the section itself is | |||
// highlighted instead, so the reader still sees where they are. | |||
function setActiveToc(id, expand) { | |||
var toc = document.querySelector('.vector-toc'); | var toc = document.querySelector('.vector-toc'); | ||
if (!toc) return; | if (!toc) return; | ||
if (_tocActiveId === id) return; | var shownNow = toc.querySelector('.gr-toc-current'); | ||
if (_tocActiveId === id && !expand && shownNow && isShown(shownNow)) return; | |||
_tocActiveId = id; | _tocActiveId = id; | ||
clearActiveToc(); | clearActiveToc(); | ||
| Line 352: | Line 383: | ||
var li = getTocLi(id); | var li = getTocLi(id); | ||
if (!li) return; | if (!li) return; | ||
// | if (expand) expandTocFor(li); | ||
var lnk = ownLink(li); | |||
var hostLi = li; | |||
if (lnk && !isShown(lnk)) { // hidden in a collapsed section | |||
var p = li.parentNode; | |||
while (p && p !== toc) { | |||
if (p.classList && p.classList.contains('vector-toc-list-item')) { | |||
var pl = ownLink(p); | |||
if (pl && isShown(pl)) { lnk = pl; hostLi = p; break; } | |||
} | |||
p = p.parentNode; | |||
} | |||
} | |||
if (lnk) lnk.classList.add('gr-toc-current'); | if (lnk) lnk.classList.add('gr-toc-current'); | ||
// | // Sections above it get the quieter "you are in here" treatment. | ||
var anc = hostLi.parentNode; | |||
var anc = | |||
while (anc && anc !== toc) { | while (anc && anc !== toc) { | ||
if (anc.classList | if (anc.classList && anc.classList.contains('vector-toc-list-item')) anc.classList.add('gr-toc-in-path'); | ||
anc = anc.parentNode; | anc = anc.parentNode; | ||
} | } | ||
keepTocEntryVisible(lnk || | keepTocEntryVisible(lnk || hostLi); | ||
} | } | ||
| Line 507: | Line 545: | ||
if (!id) return; | if (!id) return; | ||
_pin = { id: id, y: scrollY(), until: Date.now() + 900 }; | _pin = { id: id, y: scrollY(), until: Date.now() + 900 }; | ||
setActiveToc(id); | setActiveToc(id, true); // open its section if collapsed | ||
scheduleRecheck(950); | scheduleRecheck(950); | ||
} | } | ||
| Line 521: | Line 559: | ||
if (Date.now() < _pin.until) { // still settling after the jump | if (Date.now() < _pin.until) { // still settling after the jump | ||
_pin.y = y; | _pin.y = y; | ||
setActiveToc(_pin.id); | setActiveToc(_pin.id, true); | ||
scheduleRecheck(_pin.until - Date.now() + 30); | scheduleRecheck(_pin.until - Date.now() + 30); | ||
return; | return; | ||