1'use strict'; 2 3export const lib = { 4 ajax: function (method, url, data, cb) { 5 let r = new XMLHttpRequest(); 6 if (typeof cb === 'function') { 7 r.onreadystatechange = function () { 8 if (this.readyState === 4 && this.status !== 0) { 9 try { 10 if (this.status >= 200 && this.status < 400) { 11 cb(this.responseText); 12 // } else { 13 // cb(null); // is dit slim? 14 } 15 } catch (e) { 16 if (url !== '/e') { 17 let data2 = { 18 data: { 19 method: method, url: url, data: data, cb: cb, status: this.status, response: this.responseText 20 }, error: null 21 } 22 try { 23 data2.error = { 24 error: e.error, filename: e.filename, lineno: e.lineno, colno: e.colno, message: e.message 25 }; 26 } catch (e) { 27 } 28 ajax('POST', '/e', data2); 29 } 30 throw e; 31 } 32 } 33 }; 34 } 35 r.open(method, url, true); 36 r.setRequestHeader("Cache-Control", "no-cache, no-store, must-revalidate"); 37 r.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 38 if (data instanceof FormData) { 39 } else { 40 r.setRequestHeader("Content-type", "application/json"); 41 data = JSON.stringify(data); 42 } 43 r.send(data); 44 return r; 45 }, 46 47 getJSON: function (url, cb) { 48 const controller = new AbortController(); 49 fetch(url, {signal: controller.signal, headers: {'X-Requested-With': 'XMLHttpRequest'}}).then((response) => response.json()).then(cb).catch((e) => { 50 console.log(e); 51 }); 52 return controller; 53 }, 54 55 postJSON: function (url, data, cb) { 56 return ajax('POST', url, data, function (result) { 57 if (typeof cb === 'function') { 58 let json = null; 59 try { 60 json = JSON.parse(result); 61 } catch (e) { 62 } 63 cb(json) 64 } 65 }); 66 }, 67 68 delayed: function (fn, delay) { 69 let d = function () { 70 if (d.t) { 71 clearTimeout(d.t); 72 } 73 d.t = setTimeout(fn, delay); 74 } 75 d.t = null; 76 return d; 77 }, cookies: { 78 set: function (key, value, expiry) { // expiry in days 79 let expires = ''; 80 if (expiry) { 81 let d = new Date(); 82 d.setTime(d.getTime() + (expiry * 24 * 60 * 60 * 1000)); 83 expires = ';expires=' + d.toUTCString(); 84 } 85 document.cookie = key + '=' + value + expires + ';SameSite=Strict;secure'; 86 }, get: function (key) { 87 let keyValue = document.cookie.match('(^|;) ?' + key + '=([^;]*)(;|$)'); 88 return keyValue ? keyValue[2] : null; 89 } 90 }, dedupe: function (arr) { 91 return Array.from(new Set(arr)); 92 }, form: { 93 serialize: function (form, complex) { 94 let obj = {}, data = new FormData(form); 95 96 for (let [name, value] of data) { 97 let basename = name.replace(/^(.*)\[.*\]$/, '$1'); 98 let name2 = complex !== true ? name.replace(/^(.*)\[\]$/, '$1') : name; 99 100 let el = form[name]; 101 if (!el) { 102 console.log(el, form, name); 103 } 104 if (el instanceof RadioNodeList) { 105 el = el[0]; 106 if (el.type === 'checkbox') { 107 value = [value]; 108 if (obj[name2]) value = obj[name2].concat(value); 109 } 110 } 111 112 let d = el.closest('[data-type]'); 113 switch (d.getAttribute('data-type')) { 114 case 'slider': 115 if (value === '0') { 116 value = ''; 117 } 118 break; 119 } 120 //if (/*value === '' ||*/ ['lastminutes'].includes(name)) continue; 121 if (/*value === '' ||*/ ['lastminutes'].includes(name)) continue; 122 123 if (name !== basename && form[basename]) { 124 if (form[basename].value === '') { 125 continue; // gasten selectie 126 } 127 } 128 let match = name2.match(/^(.*)(\[.*?\])$/); 129 if (match) { 130 let temp = obj; 131 let matches = match[2].match(/\[([^\]]*)\]/g); 132 matches.unshift('[' + match[1] + ']'); 133 for (let i = 0, j = matches.length; i < j; i++) { 134 let key = matches[i].slice(1, -1); 135 if (typeof temp[key] === 'undefined') { 136 temp[key] = i + 1 < j ? {} : value; 137 } 138 temp = temp[key]; 139 } 140 } else { 141 obj[name2] = value; 142 } 143 } 144 145 return obj; 146 }, clear: function (form) { 147 let data = {}; 148 for (let i = 0; i < form.elements.length; i++) { 149 data[form.elements[i].name] = ''; 150 } 151 Lib.form.fill(form, data); 152 }, fill: function (form, data, complex) { 153 let value, el; 154 return Object.keys(data).map(function (name) {
155 let name2 = (complex !== true && form[name + '[]']) ? name + '[]' : name; 156 if (form[name2] && !form[name2].disabled) { 157 value = data[name].toString(); 158 el = form.elements[name2]; 159 if (!el) return; 160 if (el instanceof RadioNodeList) { 161 for (let i = 0; i < el.length; i++) { 162 if (el[i].type === 'checkbox') { 163 if (value.includes(el[i].value)) el[i].checked = true; 164 } else { 165 if (el[i].value === value) el[i].checked = true; 166 } 167 } 168 } else { 169 if (el = el.closest('[data-type]')) { 170 switch (el.getAttribute('data-type')) { 171 case 'checkbox': 172 if (value) { 173 if (!form[name2].checked) { 174 form[name2].checked = true; 175 form[name2].dispatchEvent(new Event('change', { 176 bubbles: true, cancelable: false 177 })); 178 } 179 } 180 break; 181 default: 182 if (form[name2].value !== value) { 183 form[name2].value = value; 184 form[name2].dispatchEvent(new Event('change', { 185 bubbles: true, cancelable: false 186 })); 187 } 188 break; 189 } 190 } 191 } 192 } 193 }); 194 }, onsubmit: function (e) { 195 console.log(this, e); 196 let form = this; 197 e.preventDefault(); 198 var loader = new moduleLoader(form); 199 loader.show(); 200 let postData = new FormData(form); 201 let request = new XMLHttpRequest(); 202 let alert_danger = form.querySelector('.alert--danger'); 203 let alert_success = form.querySelector('.alert--success'); 204 if (alert_danger) alert_danger.classList.remove('alert--visible'); 205 if (alert_success) alert_success.classList.remove('alert--visible'); 206 207 form.querySelectorAll('[data-name]').forEach(function (node) { 208 node.classList.remove('input-error'); 209 }); 210 211 request.open('POST', '', true); 212 request.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 213 if (form.closest('.popup .popup__content') || form.closest('.popup-dialog .popup-dialog__content')) { 214 request.setRequestHeader('X-Posted-From', 'popup'); 215 } 216 217 request.onreadystatechange = function () { 218 if (this.readyState === 4) { 219 try { 220 if (this.status === 200) { 221 let response = null; 222 try { 223 response = JSON.parse(this.responseText); 224 } catch (e) { 225 if (alert_danger) { 226 alert_danger.querySelector('.alert--inner').innerHTML = 'Er is een onverwachte fout opgetreden.'; 227 alert_danger.classList.add('alert--visible'); 228 } 229 loader.hide(); 230 return; 231 } 232 233 if (response.success) { 234 if (typeof gtag === 'function') { 235 gtag('event', 'mm_form_sent', {mm_id: form.dataset.id}); 236 } 237 if (document.location && response.action === 'redirect') { 238 document.location = response.data.redirect; 239 return; // keep the loader 240 } else if (response.action === 'refresh') { 241 let r = document.createElement('meta'); 242 r.httpEquiv = 'refresh'; 243 r.content = 0; 244 document.documentElement.appendChild(r); 245 return; 246 } else { 247 if (alert_success) { 248 display_messages(alert_success, response); 249 } 250 form.reset(); 251 } 252 } else { 253 if (alert_danger) { 254 if (response.data && response.data.message) { // zie LayerForm:500 255 alert_danger.querySelector('.alert--inner').innerHTML = response.data.message; 256 } 257 display_messages(alert_danger, response); 258 } 259 260 if (response.errors && Object.keys(response.errors).length) { 261 for (let id in response.errors) { 262 let node = form.querySelector('[data-name="' + id + '"]'); 263 if (node) { 264 node.classList.add('input-error'); 265 node.dataset.error = response.errors[id]; 266 } 267 } 268 if (alert_danger) alert_danger.classList.add('alert--visible'); 269 } 270 } 271 272 } 273 } catch (e) { 274 loader.hide(); 275 throw e; 276 } 277 loader.hide(); 278 } 279 }; 280 request.send(postData); 281 282 function display_messages(node, response) { 283 if (response.messages && Array.isArray(response.messages)) { 284 if (response.messages.length > 1) { 285 node.querySelector('.alert--inner').innerHTML = '<ul>' + response.messages.map(s => '<li>' + s + '</li>').join('') + '</ul>'; 286 } else { 287 node.querySelector('.alert--inner').innerHTML = response.messages[0]; 288 } 289 } 290 node.classList.add('alert--visible'); 291 } 292 } 293 }, url: function (base, qs, hash) { 294 if (typeof qs === 'object') qs = Lib.qs.build(qs); 295 if (typeof hash === 'object') hash = Lib.qs.build(hash); 296 return base + (qs ? '?' + qs : '') + (hash ? '#' + hash : ''); 297 }, qs: { 298 parse: function (url) { 299 if (typeof url === 'undefined') url = location.search.slice(1); 300 let pairs = url.split('&'); 301 let result = {}, k;
302 pairs.forEach(function (pair) { 303 pair = pair.split('='); 304 if ((pair.length === 2) && (k = decodeURIComponent(pair[0]))) { 305 result[k] = decodeURIComponent(pair[1].replace(/\+/g, ' ') || ''); 306 } 307 }); 308 return result; 309 }, build: function (obj) { 310 let s = function (o, base) { 311 if (typeof o !== 'object') { 312 return '=' + encodeURIComponent(o); 313 } 314 return Object.keys(o).filter(function (k) { 315 return obj[k] !== '' && obj[k] !== null; 316 }).map(function (k) { 317 return (base || '') + '[' + encodeURIComponent(k) + "]" + s(o[k]); 318 }).join("&"); 319 } 320 321 let m = function (obj) { 322 return Object.keys(obj).filter(function (k) { 323 return obj[k] !== '' && obj[k] !== null; 324 }).map(function (k) { 325 if (typeof obj[k] !== 'object') { 326 if (obj[k] !== '' && obj[k] !== null) { 327 return encodeURIComponent(k) + "=" + encodeURIComponent(obj[k]); 328 } 329 return null; 330 } 331 return s(obj[k], encodeURIComponent(k)); 332 }).join("&"); 333 } 334 return m(obj); 335 }, 336 }, format: { 337 dateToISO: function (date) { 338 if (!date) return null;
339 const year = date.getFullYear(), month = date.getMonth() + 1, day = date.getDate(); 340 return [year, month < 10 ? '0' + month : month, day < 10 ? '0' + day : day].join('-'); 341 }, dateToLocalDateString: function (date) { 342 let day = ('0' + date.getDate()).slice(-2); 343 let monthIndex = ('0' + (date.getMonth() + 1)).slice(-2); 344 let year = date.getFullYear(); 345 return day + '-' + monthIndex + '-' + year; 346 }, dateToShortLocalDateString: function (date) { 347 return date.toLocaleDateString('nl', {day: 'numeric', month: 'short', year: '2-digit'}); 348 }, moneyFormat: function (s, d) { 349 return s ? s.toFixed(isNaN(parseInt(d)) ? 2 : parseInt(d)).replace(/\./g, ',') : ''; 350 }, 351 }, deepMerge: function (obj1, obj2) { 352 const f = (obj1, obj2) => { 353 for (let key in obj2) { 354 if (obj2.hasOwnProperty(key)) { 355 if (obj2[key] instanceof Object && obj1[key] instanceof Object) { 356 obj1[key] = f(obj1[key], obj2[key]); 357 } else { 358 obj1[key] = obj2[key]; 359 } 360 } 361 } 362 return obj1; 363 } 364 return f(obj1, obj2); 365 }, process_queue: function (queue, callback) { 366 if (queue.length) { 367 queue = [...queue]; // make a copy 368 const q = function () { 369 if (queue.length) { 370 let called = false; 371 if (false !== queue.pop()(function () { 372 called = true; 373 q() 374 }) && !called) { 375 q(); 376 } 377 } else if (typeof callback === 'function') { 378 callback(); 379 } 380 }; 381 q(); 382 } else if (typeof callback === 'function') { 383 callback(); 384 } 385 }, 386 hover: function (element, {onHover, onHoverEnd}) { 387 let isTouchUsed = false; // Track real touch interactions 388 389 init(); 390 391 function init() { 392 window.addEventListener("touchstart", () => { 393 isTouchUsed = true; 394 console.log('touchstart'); 395 }, {passive: true}); 396 397 window.addEventListener("mousemove", () => { 398 // console.log('mousemove'); 399 isTouchUsed = false; // If mouse moves, assume it's a real mouse 400 }); 401 402 element.addEventListener("mouseenter", handleHover.bind(this)); 403 element.addEventListener("mouseleave", handleHoverEnd.bind(this)); 404 element.addEventListener("click", handleClick.bind(this)); 405 document.addEventListener("click", handleClickOutside.bind(this)); 406 } 407 408 function handleHover(e) { 409 console.log(isTouchUsed, e); 410 if (!isTouchUsed) onHover(e); // Only trigger hover if it's a real mouse 411 } 412 413 function handleHoverEnd(e) { 414 console.log(isTouchUsed, e); 415 if (!isTouchUsed) onHoverEnd(e); 416 } 417 418 function handleClick(event) { 419 event.stopPropagation(); 420 if (element.classList.contains("active")) { 421 onHoverEnd(event); 422 } else { 423 onHover(event); 424 } 425 } 426 427 function handleClickOutside(event) { 428 if (!element.contains(event.target)) { 429 onHoverEnd(event); 430 } 431 } 432 } 433}
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.