Jump to content

User:Habst/getWikiWinners.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Habst (talk | contribs) at 19:08, 1 September 2024 (remove rowspans). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// <nowiki>
window.meets ??= {};
window.redirs ??= {};
(async () => {
  const getRedir = async pg => {
    redirs[pg] ??= new DOMParser().parseFromString(await (await fetch(`/wiki/${pg}`)).text(), 'text/html').querySelector('title').innerText.slice(0, -12);
    return redirs[pg];
  }
  const addPipe = name => `${name}${name.includes('(') ? '|' : ''}`;
  const bullet = (yr) => winners[yr] ? `* [[${yr} USA Indoor Track and Field Championships|${yr}]]: ${winners[yr].map(w => w.ctry ? `{{fla|[[${addPipe(w.name)}]]|${w.ctry}}}` : `[[${addPipe(w.name)}]]${w.pl > 1 ? ` (${ord(w.pl)})` : ''}`).join(', ') ?? ''}` : '';
  const range = (start, end) => [...Array(end - start + 1)].map((_, i) => i + start);
  const getRed = href => new URLSearchParams(href.split('?').at(-1)).get('title').replaceAll('_', ' ');
  const ord = n => n + ['st', 'nd', 'rd'][(((n < 0 ? -n : n) + 90) % 100 - 10) % 10 - 1] || 'th';
  const removeRowspans = table => {
    const rows = Array.from(table.rows);
    for (let i = 0; i < rows.length; i++) {
      const cells = Array.from(rows[i].cells);
      for (let cell of cells) {
        const rowspan = cell.getAttribute('rowspan');
        if (rowspan && rowspan > 1) {
          const rowSpanValue = parseInt(rowspan);
          cell.removeAttribute('rowspan');
          for (let j = 1; j < rowSpanValue; j++) {
            const targetRow = rows[i + j];
            if (targetRow) {
              const newCell = cell.cloneNode(true);
              targetRow.insertBefore(newCell, targetRow.cells[cell.cellIndex]);
            }
          }
        }
      }
    }
  }

  const GEN = 'Women';
  const START = 1927;
  const END = new Date().getFullYear();
  const matchEvts = {
    '60m': ['60 metres', '40-yard dash', '40 yards', '50 m', '50 metres', '55 m', '55 metres', '50 yards', '50-yard dash', '60 yards', '60-yard dash'],
    '60mH': ['60 metres hurdles', '60 yards hurdles', '60-yard hurdles', '55 metres hurdles', '50 metres hurdles', '50 yards hurdles', '50-yard hurdles', '80 metres hurdles', '70 yards hurdles', '70-yard hurdles'],
    HJ: ['High jump'],
  }['60m'];
  const trackOrField = 'track';
  const winners = {};
  for (const y of range(START, END)) {
    meets[y] ??= await (await fetch(`/wiki/${y}_USA_Indoor_Track_and_Field_Championships`)).text();
    const doc = new DOMParser().parseFromString(meets[y], 'text/html');
    const tables = [GEN, `${GEN}\\'s_${trackOrField}`].map(id => doc.querySelector(`#${id}`)?.parentElement.nextSibling.nextSibling).filter(x => x?.tagName === 'TABLE');
    for (const table of tables) removeRowspans(table);
    const trs = tables.flatMap(table => [...table?.querySelectorAll('tr') ?? []]);
    const evtRows = [];
    for (const tr of trs) {
      const tds = tr.querySelectorAll('td');
      const rowEvtA = tds[0]?.querySelector('a');
      const rowEvt = rowEvtA?.href.split('/').at(-1).split('#')[0];
      if (!rowEvt) continue;
      const evt = rowEvtA.classList.contains('new') ? getRed(rowEvt) : await getRedir(rowEvt);
      if (matchEvts.includes(evt)) evtRows.push(tds);
    }
    for (const tds of evtRows) {
      const getWinner = async (idx) => {
        const winnerA = tds[idx].querySelector('a');
        const winnerHref = winnerA?.href.split('/').at(-1);
        if (!winnerHref) return;
        const name = winnerA.classList.contains('new') ? getRed(winnerHref) : await getRedir(winnerHref);
        const ctry = tds[idx].querySelector('.flagicon') ? tds[idx].querySelector('abbr').innerText : undefined;
        return { name, ctry, pl: (idx + 1) / 2 };
      }
      winners[y] ??= [];
      for (let i = 1; i <= 5; i += 2) {
        const winner = await getWinner(i);
        if (!winner) continue;
        winners[y].push(winner);
        //if (!winner.ctry) break;
      }
    }
    if (!winners[y]) continue;
    winners[y].sort((a, b) => a.pl - b.pl);
    const topNativeFinish = [...Array(3)].map((_, i) => i + 1).find(num => winners[y].find(ath => ath.pl === num && !ath.ctry));
    if (!topNativeFinish) console.log('no native finish', y);
    winners[y] = winners[y].filter(ath => {
      if (ath.pl > topNativeFinish) return false;
      if (ath.pl > 1 && ath.ctry) return false;
      return true;
    });
  }
  const abbrEvt = matchEvts[0].replace('metres', 'm').toLowerCase();
  const out = `
{{Navbox
 | name = USA Indoor Track and Field Championships winners in women's ${abbrEvt}
 | title = [[USA Indoor Track and Field Championships]] winners in women's [[${abbrEvt}]]
 | state = {{{state<includeonly>|collapsed</includeonly>}}}
 | listclass = hlist
 | nowrapitems = yes

 | titlestyle = background: #F0DC82
 | groupstyle = text-align: center; background: #F0DC82

 | group1 = 1927–1979<br />{{small|[[Amateur Athletic Union]]}}
 | list1 =

${range(1927, 1979).map(bullet).filter(x => x).join('\n')}

 | group2 = 1980–1992<br />{{small|[[The Athletics Congress]]}}
 | list2 =

${range(1980, 1992).map(bullet).filter(x => x).join('\n')}

 | group3 = 1993–present<br />{{small|[[USA Track & Field]]}}
 | list3 =

${range(1993, END).map(bullet).filter(x => x).join('\n')}

|group4 = Notes
|list4 =
{{allow wrap|* Distances have varied as follows: 440 yards (1959–1986), 400 meters (1987–date) alternating with 300 meters in odd numbered years starting 2015}}

}}<noinclude>
{{collapsible option}}
[[Category:United States indoor track and field champions navigational boxes|${abbrEvt}, women]]
</noinclude>`
  console.log(out);
})();
// </nowiki>