PageSourceSearch

https://legalservicesboard.org.uk/wp-content/themes/lsb/js/newsletter-popup.js

js legalservicesboard.org.uk collected 2026-09-24 19:27:49 UTC 4,102 bytes, 131 lines download raw bytes

1// Will hold previously focused element
2document.addEventListener('DOMContentLoaded', () => {
3
4    if (getCookie('newsletter-popup-shown') !== '')
5    {
6        return;
7    }
8    let newsletterOpen = false;
9    const scrollThreshold = 2200;
10   
11    //get elements
12    const newsletterPopup = document.querySelector('#newsletter_popup');
13    const overlay= document.querySelector('#popup_overlay');
14    let focusedElementBeforeModal = document.activeElement;
15    const closeButton = document.querySelector('#newsletter_popup a.close');
16
17    //add event to close button
18    closeButton.addEventListener('click', e => {
19        e.preventDefault();
20        closeNewsletterPopup();
21    });
22    
23    // scroll event throttling
24    let lastScrollPosition = 0,
25    tick = false;  // Track whether call is currently in process
26
27    function checkScrollPos(scrollPos) {
28        if (scrollPos > scrollThreshold && !newsletterOpen && window.innerWidth > 780)
29        {
30            openNewsletterPopup();
31        }
32    }
33
34    window.addEventListener('scroll', function(e) {
35        lastScrollPosition = window.scrollY;
36        if (!tick) {
37            setTimeout(function () {
38            checkScrollPos(lastScrollPosition);
39            tick = false;
40            }, 16)
41        }
42        tick = true;
43    });
44
45
46    function openNewsletterPopup() {
47
48        newsletterOpen = true;
49
50        newsletterPopup.style.display = 'grid';
51        overlay.style.display = 'block';
52
53        // Save current focus
54        focusedElementBeforeModal = document.activeElement;
55        // Listen for and trap the keyboard
56        newsletterPopup.addEventListener('keydown', trapTabKey);
57        // Find all focusable children
58        let focusableElementsString = 'a[href], area[href], input:not([disabled]), input:not([tabindex="-1"]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"], [contenteditable]';
59        let focusableElements = newsletterPopup.querySelectorAll(focusableElementsString);
60        focusableElements = Array.from(focusableElements);
61        let firstTabStop = focusableElements[0];
62        let lastTabStop = focusableElements[focusableElements.length - 1];
63
64        // Focus first child
65        firstTabStop.focus();
66      
67        function trapTabKey(e) {
68          // Check for TAB key press
69          if (e.keyCode === 9) {
70      
71            // SHIFT + TAB
72            if (e.shiftKey) {
73              if (document.activeElement === firstTabStop) {
74                e.preventDefault();
75                lastTabStop.focus();
76              }
77      
78            // TAB
79            } else {
80              if (document.activeElement === lastTabStop) {
81                e.preventDefault();
82                firstTabStop.focus();
83              }
84            }
85          }
86      
87          // ESCAPE
88          if (e.keyCode === 27) {
89            closeNewsletterPopup();
90          }
91        }
92      }
93      
94      function closeNewsletterPopup() {
95    
96        newsletterPopup.style.display = 'none';
97        overlay.style.display = 'none';
98      
99        // Set focus back to element that had it before the modal was opened
100        focusedElementBeforeModal.focus();
101    
102        //store a cookie so that the user isn't bothered again
103        setCookie('newsletter-popup-shown', 'true', 28);
104      }
105
106
107      function setCookie(cname, cvalue, exdays) {
108        const d = new Date();
109        d.setTime(d.getTime() + (exdays*24*60*60*1000));
110        let expires = "expires="+ d.toUTCString();
111        document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
112      }
113      
114      function getCookie(cname) {
115        let name = cname + "=";
116        let decodedCookie = decodeURIComponent(document.cookie);
117        let ca = decodedCookie.split(';');
118        for(let i = 0; i <ca.length; i++) {
119          let c = ca[i];
120          while (c.charAt(0) == ' ') {
121            c = c.substring(1);
122          }
123          if (c.indexOf(name) == 0) {
124            return c.substring(name.length, c.length);
125          }
126        }
127        return "";
128      }
129
130})
131

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.