PageSourceSearch

https://www.malmesburysingers.co.uk/brostools/applications/singing/special/anchor.js?ver=3438

js malmesburysingers.co.uk collected 2026-10-03 01:29:36 UTC 3,438 bytes, 91 lines download raw bytes

1/*
2 *	This script does the following:
3 *		- Converts anchor links href="#foo" to the proper URL href="https://www.site.org/dbpage...#foo"
4 *		- Listens for the "click" event on these links, then corrects the scroll position.
5 *	Why use requestAnimationFrame()?
6 *		1) setTimeout() is less reliable.
7 *		2) Listening for 'hashchange' on window won't trigger if you click the same section twice in a row.
8 *
9 *	Also aded:  Code for improving "Visually impaired" mode
10 */
11document.addEventListener('DOMContentLoaded', function ()
12{
13	const pageURLWithoutHash	= window.location.href.replace(/#[^#]*$/, '')
14	const html					= document.querySelector('html')
15	const pageLinks				= document.querySelectorAll('a[href^="#"]:not([href^="#tab-"])')
16	const header				= document.querySelector('header')
17	const themeIsStockholm		= Boolean(document.querySelector('head link[rel="stylesheet"][href*="themes/Stockholm"]'))
18	const themeIsMercury		= Boolean(document.querySelector('head link[rel="stylesheet"][href*="themes/Mercury"]'))
19
20	for (const pageLink of pageLinks)
21	{
22		// This ignores tab links, e.g. on https://www.barbershop.org.au/Contact
23		if (pageLink.parentElement.parentElement.classList.contains('tabList'))
24			continue
25
26		pageLink.href = pageLink.href.replace(window.location.origin + '/', pageURLWithoutHash)
27		pageLink.addEventListener('click', function ()
28		{
29			const originalScrollTop = html.scrollTop
30
31			function tryUpdateScroll()
32			{
33				const scrollTop = html.scrollTop
34
35				if (scrollTop === originalScrollTop)
36				{
37					window.requestAnimationFrame(tryUpdateScroll)
38				}
39				else
40				{
41					const stockholmHeaderIsSticky = themeIsStockholm && window.matchMedia('(min-width: 1001px)').matches
42					const mercuryHeaderIsSticky = themeIsMercury && window.matchMedia('(min-width: 641px)').matches
43
44					if (stockholmHeaderIsSticky || mercuryHeaderIsSticky)
45					{
46						html.scrollTop -= header.getBoundingClientRect().height
47					}
48					html.scrollTop -= 15
49				}
50			}
51
52			tryUpdateScroll()
53		})
54	}
55})
56
57/* Accessibility improvements */
58
59document.addEventListener('DOMContentLoaded', () => {
60    document.body.insertAdjacentHTML('beforeend', `
61        <span id="search-announcement" aria-live="assertive" class="ui-helper-hidden-accessible"></span>
62    `)
63    const searchAnnouncement = document.getElementById('search-announcement')
64    const searchBox = document.getElementById('_searchq')
65    searchBox.addEventListener('keydown', (ev) => {
66        if (ev.key === 'ArrowDown' || ev.key === 'ArrowUp') {
67            const focusedResult = document.querySelector('#ui-id-1 .ui-state-focus')
68            if (!focusedResult) return
69            focusedResult.innerHTML = focusedResult.innerHTML.replace(/<br>/g, '<br>\n')
70            searchAnnouncement.textContent = focusedResult.textContent.replace(/\n/g, ', ')
71        }
72    })
73})
74
75$(document).ready(() => {
76  let previousFocus
77  jQuery('body').on('dialogopen', (ev) => {
78    previousFocus = document.activeElement
79    ev.target.parentElement.focus()
80  })
81  jQuery('body').on('dialogclose', (ev) => {
82    if (window.location.href.includes('dbpage.php?pg=newmemwiz')) {
83      const selectedStep = document.querySelector('.selectedstep')
84      selectedStep.setAttribute('tabindex', '-1')
85      selectedStep.focus()
86    } else {
87      previousFocus.focus()
88    }
89    previousFocus = null
90  })
91})

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.