PageSourceSearch

https://www.cwresources.org/wp-content/themes/wpcode-v2/js/pageLoad.js?ver=1775495167

js cwresources.org collected 2026-10-04 12:43:33 UTC 10,489 bytes, 324 lines download raw bytes

1var mq = matchMedia("(min-width: 750px)");
2
3document.addEventListener("DOMContentLoaded", () => {
4
5  // Accessible dropdowns - Event listener for buttons
6  document.querySelectorAll( '#mainnav>ul>li>button' ).forEach( el => {
7    el.addEventListener( 'click', (e) => {
8      e.preventDefault();
9      let parent = el.parentNode;
10      parent.classList.toggle( 'expand' );
11      parent.querySelector( 'button' ).setAttribute( 'aria-expanded', parent.classList.contains( 'expand' ) ? true : false );
12    });
13  });
14
15
16  if (window.mq.matches) {
17    // do desktop stuff //
18 // Accessible dropdowns - Focus event listeners for megamenus
19    // Only needed if the megamenu is not a <ul> (#mainnav>ul>li>ul.megamenu) i.e. it's a div (#mainnav>ul>li>div.megamenu)
20    document.querySelectorAll( '#mainnav>ul>li.has-megamenu' ).forEach( el => {
21      let megamenu = el.querySelector( '.megamenu' );
22
23      el.querySelector( 'a' ).addEventListener( 'focus', e => {
24        ws_close_element( el );
25      });
26
27      megamenu.addEventListener( 'focusout', e => {
28        if ( !megamenu.contains( e.relatedTarget ) ) {
29          ws_close_element( el );
30        }
31      });
32    });
33
34
35    // Accessible dropdowns - Focus event listeners for normal dropdowns
36    document.querySelectorAll( '#mainnav>ul>li.menu-item-has-children' ).forEach( el => {
37      el.querySelector( 'a' ).addEventListener( 'focus', e => {
38        ws_close_element( el );
39      });
40
41      el.querySelector( 'ul' ).addEventListener( 'focusout', function (e) {
42        if ( !this.contains( e.relatedTarget ) ) {
43          ws_close_element( el );
44        }
45      });
46    });
47
48
49    // Accessible dropdowns - Helper class to close expanded elements
50    function ws_close_element( el ) {
51      el.classList.remove( 'expand' );
52      el.querySelector( 'button' ).setAttribute( 'aria-expanded', false );
53    }
54
55
56    // Toggle aria-expanded on hover (desktop only)
57    document.querySelectorAll( '#mainnav>ul>li:is(.menu-item-has-children, .has-megamenu)' ).forEach( el => {
58      let button = el.querySelector( 'button' );
59      if ( button.classList.contains( 'expand' ) ) {
60        return;
61      }
62
63      el.addEventListener( 'mouseover', (e) => {
64        el.querySelector( 'button' ).setAttribute( 'aria-expanded', true );
65      });
66
67      el.addEventListener( 'mouseout', (e) => {
68        el.querySelector( 'button' ).setAttribute( 'aria-expanded', false );
69      });
70    });
71
72
73
74    // Add class to header when page scrolled to toggle alternate styles
75    var header = document.querySelector('body>header');
76    window.addEventListener( 'scroll', () => {
77      if(window.pageYOffset > 0) {
78        header.classList.add('scrolled');
79      } else {
80        header.classList.remove('scrolled');
81      }
82    }, { passive: true } );
83
84
85
86
87    function is_touch_device() {
88      var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
89      var mq = function (query) {
90        return window.matchMedia(query).matches;
91      }
92      if(('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints > 0) || window.DocumentTouch && document instanceof DocumentTouch) {
93        return true;
94      }
95      var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
96      return mq(query);
97    }
98
99    // On touch devices, expand dropdowns on first tap
100    if( is_touch_device() ) {
101      document.querySelectorAll("#mainnav>div>ul>li>a").forEach(elem => {
102        elem.addEventListener('touchstart', () => {
103          var parent = elem.parentElement;
104          if( parent.contains( parent.querySelector('ul') ) ) {
105            if( !parent.classList.contains('tapped') ) {
106              event.preventDefault();
107              document.querySelector("#mainnav>ul>li.tapped")?.classList.remove('tapped');
108              parent.classList.add('tapped');
109            }
110          }
111        });
112      });
113    }
114
115
116  } else {
117    // do mobile stuff //
118
119      // Set Initial states on pageLoad:
120    navContainer.setAttribute( 'role', 'dialog' );
121    navContainer.inert = true;
122    navContainer.querySelectorAll( 'li.menu-item-has-children>ul' ).forEach( item => {
123      item.inert = true;
124    });
125
126    // Handle toggleNav button clicks (#mobilenav Menu and navContainer "Close menu")
127    document.querySelectorAll( '.toggleNav' ).forEach( toggleNav => {
128      toggleNav.addEventListener( 'click', ws_toggleNav );
129    });
130
131    // Close slidenav with ESC key
132    navContainer.addEventListener( 'keydown', function(event) {
133      if (event.key === 'Escape' || event.key === 'Esc') {
134        ws_toggleNav();
135      }
136    });
137
138
139    // Close slideNav when clicked outside navContainer
140    document.addEventListener( 'click', checkTarget, false );
141    document.addEventListener( 'touchstart', checkTarget, { passive: true, capture: false } );
142
143    function checkTarget( event ) {
144      const mobile_toggle = document.querySelector( '#mobilenav .toggleNav') ;
145
146      if (
147        document.body.classList.contains('slideNav') &&
148        !navContainer.contains(event.target) &&
149        !mobile_toggle.contains(event.target)
150      ) {
151        ws_toggleNav();
152      }
153    }
154
155
156    // Toggle the slideNav open/close and update aria attributes
157    function ws_toggleNav() {
158
159      document.body.classList.toggle( 'slideNav' );
160      let expanded = document.body.classList.contains( 'slideNav' );
161      let main     = document.querySelector( 'main' );
162      let footer   = document.querySelector( 'body>footer' );
163      let skipnav  = document.getElementById( 'skipNavigation' );
164
165      // Update ARIA states:
166      if ( expanded ) {
167        main.inert = true;
168        footer.inert = true;
169        skipnav.inert = true;
170        navContainer.inert = false;
171        navContainer.setAttribute( 'aria-modal', true );
172      } else {
173        main.inert = false;
174        footer.inert = false;
175        skipnav.inert = false;
176        navContainer.inert = true;
177        navContainer.setAttribute( 'aria-modal', false );
178      }
179
180      document.querySelectorAll( '.toggleNav').forEach( button => {
181        button.setAttribute( 'aria-expanded', expanded ? 'true' : 'false' );
182      });
183
184      // Focus management with 250ms delay
185      setTimeout( () => {
186        if ( expanded ) {
187          navContainer.querySelector( 'button.toggleNav' ).focus();
188        } else {
189          document.querySelector( '#mobilenav button.toggleNav' ).focus();
190        }
191      }, 250);
192
193    }
194
195
196    // Trap focus within navContainer
197    navContainer.addEventListener( 'focusout', e => {
198      if ( !navContainer.contains( e.relatedTarget ) ) {
199        navContainer.querySelector( 'button.toggleNav' ).focus();
200      }
201    });
202
203
204    // Expand T1 dropdowns when + clicked
205    document.querySelectorAll( '#navContainer #mainnav>ul>li>button' ).forEach( button => {
206      button.addEventListener( 'click', () => {
207
208        let dropdown = button.nextElementSibling;
209
210        if ( !button.parentElement.classList.contains( 'expand') ) {
211          let scroll_height = button.nextElementSibling.scrollHeight;
212          dropdown.inert = true;
213        } else {
214          let scroll_height = button.nextElementSibling.scrollHeight;
215          dropdown.inert = false;
216        }
217
218      });
219    });
220
221
222
223    // Expand current page / current page ancestor T1 items in mobile nav
224    document.querySelectorAll('#mainnav li.current_page_item, #mainnav li.current_page_parent, #mainnav li.current_page_ancestor, #mainnav li.current-page-ancestor').forEach(nav_item => {
225      nav_item.classList.add( 'expand' );
226      var dropdown = nav_item.querySelector( ':scope>ul' );
227      if ( dropdown ) {
228        dropdown.inert = false;
229        dropdown.previousElementSibling.setAttribute( 'aria-expanded', true );
230      }
231    });
232
233
234
235  } // end of mobile stuff //
236
237  // do desktop and mobile stuff //
238  mq.addListener( () => {
239    location.reload();
240  });
241
242
243  // Smooth scroll to anchor tag
244  document.querySelectorAll('a[href^="#"]:not([href="#"])').forEach(anchor => {
245    anchor.addEventListener('click', (e) => {
246      e.preventDefault();
247      document.querySelector(anchor.getAttribute('href')).scrollIntoView({
248        behavior: 'smooth'
249      });
250      anchor.blur();
251    });
252  });
253
254
255  //
256  // Skip Link Focus
257  //
258  var is_webkit = navigator.userAgent.toLowerCase().indexOf( 'webkit' ) > -1,
259  is_opera      = navigator.userAgent.toLowerCase().indexOf( 'opera' )  > -1,
260  is_ie         = navigator.userAgent.toLowerCase().indexOf( 'msie' )   > -1;
261
262  if ( ( is_webkit || is_opera || is_ie ) && document.getElementById && window.addEventListener ) {
263    window.addEventListener( 'hashchange', function() {
264      var id = location.hash.substring( 1 ),
265      element;
266      if ( ! ( /^[A-z0-9_-]+$/.test( id ) ) ) {
267        return;
268      }
269      element = document.getElementById( id );
270      if ( element ) {
271        if ( ! ( /^(?:a|select|input|button|textarea)$/i.test( element.tagName ) ) ) {
272          element.tabIndex = -1;
273        }
274        element.focus();
275      }
276    }, false );
277  }
278
279
280  // Animations
281  const elements = document.querySelectorAll('.circle-section, .translate-up li'); // define animated elements
282  var offset     = window.mq.matches ? 150 : 50; // desktop offset / mobile offset
283
284  function intersectionObserver() {
285    var theRootMargin =  '-' + offset + 'px 0px -' + offset + 'px 0px';
286    const config = { rootMargin: theRootMargin, threshold: 0 };
287    let observer = new IntersectionObserver(entries => {
288      entries.forEach(entry => {
289        if (entry.intersectionRatio > 0) {
290          entry.target.classList.add("animated");
291          observer.unobserve(entry.target);
292        }
293      });
294    }, config);
295    elements.forEach(element => {
296      observer.observe(element);
297    });
298  }
299  intersectionObserver();
300
301
302  // Stop animations during window resize event
303  var timer;
304  window.addEventListener('resize', () => {
305    document.body.classList.add( 'stop-transitions' );
306    clearTimeout(timer);
307    timer = setTimeout( () => {
308      document.body.classList.remove( 'stop-transitions' );
309    }, 500);
310  }, true);
311
312
313   // Add <span class="sr-only">(Opens in new window)</span> to any link with target="_blank"
314  const links = document.querySelectorAll( 'a[target="_blank"]' );
315  links.forEach( link => {
316    if ( !link.querySelector( '.sr-only' ) ) {
317      const sr_span = document.createElement( 'span' );
318      sr_span.className   = 'sr-only';
319      sr_span.textContent = ' (Opens in new window)';
320      link.appendChild( sr_span );
321    }
322  });
323
324});

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.