PageSourceSearch

https://www.wv.gov/sites/default/files/asset_injector/js/google_se…-ad409b15bf6a5577c8f40e6eb212a045.js?tls5ra

js wv.gov collected 2026-09-24 07:14:18 UTC 7,438 bytes, 224 lines download raw bytes

1var searchhelper = {};
2
3// Load Google Custom Search script
4(function() {
5    var gcse = document.createElement('script');
6    gcse.type = 'text/javascript';
7    gcse.async = true;
8    gcse.src = 'https://cse.google.com/cse.js?cx=' + GOOGLE_CSE_CX;
9    var s = document.getElementsByTagName('script')[0];
10    s.parentNode.insertBefore(gcse, s);
11})();
12
13webResultsRenderedCallback = function(name, q, promos, results) {
14    // Remove role="main" from Google search result elements to avoid multiple main landmarks
15    var googleResultsDiv = document.getElementById('google-results');
16    if (googleResultsDiv) {
17        var mainRoleElements = googleResultsDiv.querySelectorAll('[role="main"]');
18        mainRoleElements.forEach(function(element) {
19            element.removeAttribute('role');
20        });
21    }
22};
23
24window.__gcse || (window.__gcse = {});
25window.__gcse.searchCallbacks = {
26    web: {
27        rendered: 'webResultsRenderedCallback',
28    },
29};
30
31// Perform Google search
32searchhelper.perform_google = function(queryText) {
33    if (typeof(google) != 'undefined') {
34        if (SEARCH_SITE_URL) {
35            google.search.cse.element.render({
36                div: "google-results",
37                tag: 'searchresults-only',
38                gname: 'google-results',
39                attributes: { as_sitesearch: SEARCH_SITE_URL }
40            });
41        }
42        else {
43            google.search.cse.element.render({
44                div: "google-results",
45                tag: 'searchresults-only',
46                gname: 'google-results'
47            });
48        }
49        var element = google.search.cse.element.getElement('google-results');
50        element.execute(queryText);
51    }
52};
53
54// Initialize search when DOM is ready
55if (document.readyState === 'loading') {
56    document.addEventListener('DOMContentLoaded', initSearch);
57} else {
58    initSearch();
59}
60
61function initSearch() {
62    var searchInput = document.getElementById('google-search-input');
63    var searchButton = document.getElementById('google-search-button');
64    var googleResults = document.getElementById('google-results');
65    var searchResults = document.getElementById('google-search-panel');
66
67    if (!searchInput || !searchButton || !googleResults) return;
68
69    // Keyword rotation variables
70    var keywordRotation = {
71        active: true,
72        keywords: [],
73        currentIndex: 0,
74        currentText: '',
75        currentChar: 0,
76        typeTimeout: null,
77        waitTimeout: null,
78
79        init: function() {
80            var keywordsAttr = searchInput.getAttribute('data-keywords');
81            if (keywordsAttr) {
82                try {
83                    this.keywords = JSON.parse(keywordsAttr);
84                } catch(e) {
85                    console.error('Invalid keywords JSON:', e);
86                    return;
87                }
88            }
89            if (this.keywords.length > 0) {
90                this.startRotation();
91            }
92        },
93
94        startRotation: function() {
95            var self = this;
96            // Wait 1.5s before starting first keyword
97            setTimeout(function() {
98                self.nextKeyword();
99            }, 1500);
100        },
101
102        shouldStop: function() {
103            // Stop if input has user-entered text or is focused
104            return searchInput.value.length > 0 || document.activeElement === searchInput;
105        },
106
107        nextKeyword: function() {
108            if (this.shouldStop()) {
109                this.scheduleNext();
110                return;
111            }
112
113            this.currentText = this.keywords[this.currentIndex];
114            this.currentChar = 0;
115            searchInput.placeholder = '|';
116            this.typeNextChar();
117        },
118
119        typeNextChar: function() {
120            var self = this;
121
122            if (this.shouldStop()) {
123                this.scheduleNext();
124                return;
125            }
126
127            var humanize = Math.round(Math.random() * 180) + 40;
128
129            this.typeTimeout = setTimeout(function() {
130                if (self.shouldStop()) {
131                    self.scheduleNext();
132                    return;
133                }
134
135                self.currentChar++;
136                var displayText = self.currentText.substring(0, self.currentChar);
137                searchInput.placeholder = displayText + '|';
138
139                if (self.currentChar < self.currentText.length) {
140                    self.typeNextChar();
141                } else {
142                    // Finished typing this keyword, remove cursor and wait 5s
143                    searchInput.placeholder = self.currentText;
144                    self.waitTimeout = setTimeout(function() {
145                        self.currentIndex = (self.currentIndex + 1) % self.keywords.length;
146                        self.nextKeyword();
147                    }, 5000);
148                }
149            }, humanize);
150        },
151
152        scheduleNext: function() {
153            var self = this;
154            // Check again in 4 seconds to see if we can resume
155            clearTimeout(this.typeTimeout);
156            clearTimeout(this.waitTimeout);
157            this.waitTimeout = setTimeout(function() {
158                if (!self.shouldStop()) {
159                    self.nextKeyword();
160                } else {
161                    self.scheduleNext();
162                }
163            }, 4000);
164        },
165
166        stop: function() {
167            clearTimeout(this.typeTimeout);
168            clearTimeout(this.waitTimeout);
169        }
170    };
171
172    // Initialize keyword rotation
173    keywordRotation.init();
174
175    // Handle search button click
176    searchButton.addEventListener('click', function() {
177        var query = searchInput.value.trim();
178
179        // If input is empty but placeholder has a value, use placeholder
180        if (!query && searchInput.placeholder) {
181            query = searchInput.placeholder.replace('|', '').trim();
182            searchInput.value = query;
183        }
184
185        if (query.length > 2) {
186            googleResults.innerHTML = "";
187            googleResults.style.display = "block";
188            if (searchResults) {
189                searchResults.classList.add("google-search-active");
190                searchResults.style.display = "block";
191            }
192            searchhelper.perform_google(query);
193        }
194    });
195
196    // Handle Enter key in search input
197    searchInput.addEventListener('keypress', function(e) {
198        if (e.keyCode === 13) {
199            e.preventDefault();
200            var query = searchInput.value.trim();
201            if (query.length > 2) {
202                searchButton.click();
203            }
204            return false;
205        }
206    });
207
208    // Close search when clicking outside
209    document.addEventListener('click', function(event) {
210        if (searchResults && searchResults.classList.contains("google-search-active")) {
211            var target = event.target;
212            var searchBanner = document.getElementById('google-search-banner');
213
214            // Check if click is outside search area
215            if (searchBanner && !searchBanner.contains(target) && !searchResults.contains(target)) {
216                searchInput.value = "";
217                searchInput.placeholder = DEFAULT_SEARCH_PLACEHOLDER;
218                if (googleResults) googleResults.innerHTML = "";
219                searchResults.classList.remove("google-search-active");
220                searchResults.style.display = "none";
221            }
222        }
223    });
224}

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.