User:Lionel.rowe/sort-by-heading.js

{

// headings

const groupOnSplitCondition = condition => arr => { const groups = [] for (const el of arr) { if (!groups.length || condition(el)) { groups.push([el]) } else { groups[groups.length - 1].push(el) }	}

return groups }

const pipe = (init, ...fns) => { return fns.reduce((val, fn) => fn(val), init) }

const groups = pipe(	document.querySelectorAll('.mw-parser-output > *'),	Array.from,	groupOnSplitCondition(x => x.nodeName === 'H2') )

const main = document.querySelector('.mw-parser-output')

if (main) main.innerText = ''

const priority = ['English', 'Chinese', 'Spanish']

const sortGroups = (sortFn, ascOrDesc = 1) => groups => groups.sort((a, b) => ascOrDesc === -1	? sortFn(b) - sortFn(a)	: sortFn(a) - sortFn(b))

const sorter = group => { const el = group[0]

const idx = priority.indexOf(el?.querySelector('[id]')?.textContent.trim)

return el?.nodeName !== 'H2' ? -Infinity // front-matter : idx === -1 ? Infinity : idx }

for (const group of sortGroups(sorter)(groups)) { for (const el of group) { document.querySelector('.mw-parser-output') .appendChild(el) } }

// TOC

const tocSorter = li => { const el = li.querySelector('.toctext')

const idx = priority.indexOf(el?.textContent.trim)

return idx === -1 ? Infinity : idx }

const toc = document.querySelector('#toc > ul')

const tocGroups = pipe(	toc?.children ?? [],	Array.from, )

if (toc) toc.textContent = ''

for (const el of sortGroups(tocSorter)(tocGroups)) { toc.appendChild(el) }

// scroll back into view if hash

const scrollHashIntoView = (el) => { if (window.location.hash) { const matchedEl = pipe(			window.location.hash.slice(1),			decodeURIComponent,			CSS.escape,			(id) => el.querySelector(`#${id}`),		)

matchedEl?.scrollIntoView(true) } }

scrollHashIntoView(document.body)

}