PageSourceSearch

https://woodlandchampions.co.uk/_lib/cms/assets/js/cms.js?v=1790608489

js woodlandchampions.co.uk collected 2026-09-28 15:15:01 UTC 8,395 bytes, 228 lines download raw bytes

1/*jshint esversion: 11 */
2
3function timeSince(timeStamp) {
4    if (typeof timeStamp === "string") {
5        timeStamp = new Date(timeStamp.replace(/-/g, "/"));
6    }
7
8    let now = new Date();
9    let secondsPast = parseInt((now.getTime() - timeStamp.getTime()) / 1000);
10
11    if (secondsPast <= 86400) {
12        let hour = timeStamp.getHours();
13        hour = ("0" + hour).slice(-2);
14        let min = timeStamp.getMinutes();
15        min = ("0" + min).slice(-2);
16        return hour + ':' + min;
17    }
18    if (secondsPast > 86400) {
19        day = timeStamp.getDate();
20        month = timeStamp.toDateString().match(/ [a-zA-Z]*/)[0].replace(" ", "");
21        year = timeStamp.getFullYear() == now.getFullYear() ? "": " "+timeStamp.getFullYear();
22        return day + " " + month + year;
23    }
24}
25
26function initForms() {
27    // validation
28    document.querySelectorAll('form.validate').forEach(function(form) {
29        const fileInputs = form.querySelectorAll('*[type="file"], *[type="files"]');
30        if (fileInputs.length) {
31            form.setAttribute('enctype', 'multipart/form-data');
32        }
33    });
34
35    const validateForms = document.querySelectorAll('form.validate');
36
37    validateForms.forEach(form => {
38        form.addEventListener('submit', function(event) {
39            // Your form validation logic goes here
40            event.preventDefault(); // Prevent default form submission
41
42            let form = this;
43
44            // Disable the buttons
45            const submitButtons = form.querySelectorAll('*[type="submit"], *[type="image"]');
46            submitButtons.forEach(button => button.disabled = true);
47
48            // Remove error messages
49            const errorDivs = form.querySelectorAll('div.error');
50            errorDivs.forEach(div => div.remove());
51
52            let url = form.action ? form.action : location.href;
53            
54            let data = new URLSearchParams();
55            for (const pair of new FormData(form)) {
56                let value = pair[1] instanceof File ? pair[1].name : pair[1];
57                data.append(pair[0], value);
58            }
59            
60            data.append('validate', 1);
61            data.append('nospam', 1);
62            
63            //validate
64            if (form.method.toUpperCase() === 'GET') {
65                url += '?' + data;
66                data = null;
67            }
68
69            //validate
70            fetch(url, {
71                method: form.method,
72                body: data,
73                headers: {
74                    'Content-Type': 'application/x-www-form-urlencoded' // For POST requests
75                }
76            })
77            .then(response => response.json()) // Parse JSON response
78            .then(data => {
79                // Handle successful response (replace with your logic)
80                console.log('Success:', data);
81
82                if (!data.success && data != 1) {
83                    // display errors
84                    let errors = data.errors ? data.errors: data;
85
86                    errors.forEach(function(item) {
87                        let pos = item.indexOf(' ');
88                        let fieldName;
89
90                        if (pos === -1) {
91                            fieldName = item;
92                            error = 'required';
93                        } else {
94                            fieldName = item.substring(0, pos);
95                            error = item.substring(pos + 1);
96                        }
97
98                        let parent = '';
99                        let fieldInput = form[fieldName + '[]'] ? form[fieldName + '[]'] : form[fieldName];
100                        
101                        if (fieldInput) {
102                            if (fieldInput.style) {
103                                parent = fieldInput.parentNode;
104                            } else if (fieldInput[0]) {
105                                parent = fieldInput[0].parentNode.parentNode;
106                            }
107                        } else {
108                            console.log('field not found: ' + fieldName);
109                        }
110
111                        if (parent) {
112                            div = document.createElement("div");
113                            div.innerHTML = error;
114                            div.style.color = 'red';
115                            div.className = 'error';
116                            parent.appendChild(div);
117                        }
118                    })
119                    
120                    // scroll to first error
121                    const elements = document.getElementsByClassName('error');
122                    if (elements && elements.length > 0) {
123                        elements[0].scrollIntoView({ behavior: 'smooth', block: 'center' });
124                    }
125
126                } else {
127                    // Create the hidden input element
128                    const hiddenInput = document.createElement('input');
129                    hiddenInput.type = 'hidden';
130                    hiddenInput.name = 'nospam';
131                    hiddenInput.value = '1';
132
133                    // Append the hidden input to the form
134                    form.appendChild(hiddenInput);
135
136                    const recaptchaSiteKey = document.querySelector('#recaptcha')?.dataset?.key;
137
138                    if (recaptchaSiteKey) {
139                        grecaptcha.ready(() => {
140                            grecaptcha.execute(recaptchaSiteKey, {
141                                action: 'submit'
142                            }).then(token => {
143                                const recaptchaTextarea = form.querySelector('.recaptcha') || document.createElement('textarea');
144
145                                if (!recaptchaTextarea.classList.contains('recaptcha')) {
146                                    recaptchaTextarea.style.display = 'none';
147                                    recaptchaTextarea.classList.add('recaptcha');
148                                    recaptchaTextarea.name = 'g-recaptcha-response';
149                                    form.appendChild(recaptchaTextarea);
150                                }
151
152                                recaptchaTextarea.value = token;
153                                form.submit();
154                            });
155                        });
156                    } else {
157                        form.submit();
158                    }
159                }
160                
161                // re-enable submit
162                const submitButtons = form.querySelectorAll('*[type="submit"], *[type="image"]');
163                submitButtons.forEach(button => button.disabled = false);
164            })
165            .catch(error => {
166                // Handle errors
167                console.error('Error:', error);
168                alert(error.message); // Example error message display
169            });
170
171        });
172    });
173}
174
175function clearFile(field)
176{
177    inputFile = document.createElement("input");
178    inputFile.setAttribute('name', field.getAttribute('name'));
179    inputFile.setAttribute('type', 'file');
180
181    var cell = field.parentNode;
182
183    while ( cell.childNodes.length >= 1 )
184    {
185        cell.removeChild( cell.firstChild );
186    }
187
188    cell.appendChild(inputFile);
189}
190
191function initSortables() {
192    // sortable
193    document.querySelectorAll('ul.files').forEach(list => {
194      let draggedItem = null;
195    
196      list.addEventListener('dragstart', e => {
197        const li = e.target.closest('li');
198        if (li && list.contains(li)) {
199          draggedItem = li;
200          e.dataTransfer.effectAllowed = "move";
201          e.dataTransfer.setData("text/plain", ""); // required in some browsers
202          li.style.opacity = '0.5';
203        }
204      });
205    
206      list.addEventListener('dragend', e => {
207        if (draggedItem) {
208          draggedItem.style.opacity = '';
209          draggedItem = null;
210        }
211      });
212    
213      list.addEventListener('dragover', e => {
214        e.preventDefault(); // allow drop
215        const li = e.target.closest('li');
216        if (li && draggedItem && li.parentNode === list && li !== draggedItem) {
217          const rect = li.getBoundingClientRect();
218          const next = (e.clientY - rect.top) > rect.height / 2;
219          list.insertBefore(draggedItem, next ? li.nextSibling : li);
220        }
221      });
222    });
223}
224
225window.addEventListener('DOMContentLoaded', function() {
226    initForms();
227    initSortables();
228});

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.