1var currentActive = { 2 id: '', 3 obj: {}, 4 reason: '' 5}; 6 7 8class XModal{ 9 constructor(el, config){ 10 this.el = el; 11 this.config = config; 12 } 13 getParams(x){ 14 return this.config 15 } 16 getParam(x){ 17 return this.config[x] 18 } 19 getEl(){ 20 return this.el 21 } 22 23 setParam(x, value){ 24 this.config[x] = value 25 } 26 addToParam(x, value){ 27 if (Array.isArray(this.config[x])){ 28 if (Array.isArray(value)){ 29 value.forEach(function(item){ 30 this.config[x].push(item); 31 }) 32 } else { 33 this.config[x].push(value); 34 } 35 } else { 36 console.log('add to param available only for array type params'); 37 } 38 } 39 removeFromParam(x, value){ 40 if (Array.isArray(this.config[x])){ 41 if (Array.isArray(value)){ 42 value.forEach(function(item){ 43 removeFromArray(this.config[x], item) 44 }) 45 } else { 46 removeFromArray(this.config[x], value); 47 } 48 } else { 49 console.log('remove from param available only for array type params'); 50 } 51 } 52 addClass(value){ 53 if (Array.isArray(value)){ 54 value.forEach(function(item){ 55 addToArray(this.config.classes, item); 56 this.el.classList.add(item); 57 }) 58 } else { 59 addToArray(this.config.classes, value); 60 this.el.classList.add(value); 61 } 62 } 63 removeClass(value){ 64 if (Array.isArray(value)){ 65 value.forEach(function(item){ 66 removeFromArray(this.config.classes, item); 67 if (this.el.classList.contains(item)){ 68 this.el.classList.remove(item); 69 } 70 }) 71 } else { 72 removeFromArray(this.config.classes, value); 73 if (this.el.classList.contains(value)){ 74 this.el.classList.remove(value); 75 } 76 77 } 78 } 79 80 init(){ 81 if(!this.config.isInit){ 82 this.config.isInit = true 83 const event = new CustomEvent('modal-init', { detail: this }); 84 document.dispatchEvent(event); 85 } 86 } 87 activate(reason){ 88 if(!this.config.isActive){ 89 if (currentActive.id != '' && currentActive.id != this.config.id){ 90 if ( currentActive.obj instanceof XModal ){ 91 if (reason != 'btn-trigger'){ 92 return 93 } else { 94 currentActive.obj.deactivate('other'); 95 } 96 } 97 } 98 99 this.config.isActive = true 100 this.config.notTriggered = false 101 102 const event = new CustomEvent('modal-activated', { detail: this }); 103 document.dispatchEvent(event); 104 currentActive.id = this.config.id; 105 currentActive.obj = this; 106 currentActive.reason = reason; 107 } 108 } 109 deactivate(reason){ 110 if(this.config.isActive){ 111 this.config.isActive = false 112 const event = new CustomEvent('modal-deactivated', { detail: this }); 113 if (this.config.useCookies){ 114 setCookie(this.config.cookieName, 'closed', this.config.cookiesPeriod) 115 } 116 document.dispatchEvent(event); 117 currentActive.id = ''; 118 currentActive.obj = {}; 119 } 120 } 121} 122 123 124function xModal(el, givenParams){ 125 if (!el.id) return 126 // Default params 127 var config = { 128 id: '', 129 post_id: '', 130 isActive: false, 131 notTriggered: true, 132 isInit: false, 133 classes: [], 134 triggers: [], 135 customTriggersOnce: true, 136 timerValue: 3000, 137 scrollType: 'page-scroll', 138 scrollValue: 50, 139 scrollOffset: 0, 140 scrollTarget: 'body', 141 useCookies: false, 142 cookieName: '', 143 cookiesPeriod: 21, 144 cookiePass: true, 145 useState: false, 146 useScrollBlock: false, 147 isContentAware: false, 148 hasVideos: false, 149 hasForms: false, 150 hasActiveForms: false, 151 submitList: ['sent'], 152 responsesList: [ 'sent','failed','invalid','mc4wp-form-submitted','mc4wp-form-error'], 153 } 154 155 // Get config from DOM 156 config.id = el.id; 157 config.post_id = el.getAttribute('data-post-id'); 158 config.classes = Array.from(el.classList); 159 (function initParamsFromDOM(){ 160 if (el.hasAttribute('data-custom-triggers')){ 161 config.triggers = el.getAttribute('data-custom-triggers').split(',').map(function(el){ return el.trim() }); 162 } 163 if (el.hasAttribute('data-timer-value')){ 164 config.timerValue = parseInt(el.getAttribute('data-timer-value'), 10); 165 } 166 if (el.hasAttribute('data-scroll-type')){ 167 config.scrollType = el.getAttribute('data-scroll-type'); 168 } 169 if (el.hasAttribute('data-scroll-value')){ 170 config.scrollValue = parseInt(el.getAttribute('data-scroll-value'), 10); 171 } 172 if (el.hasAttribute('data-scroll-offset')){ 173 config.scrollOffset = parseInt(el.getAttribute('data-scroll-offset'), 10); 174 } 175 if (el.hasAttribute('data-scroll-target')){ 176 config.scrollTarget = el.getAttribute('data-scroll-target'); 177 }
178 if (el.hasAttribute('data-use-cookies')){ 179 config.useCookies = true; 180 config.cookieName = 'modal-' + el.id + '-' + config.post_id; 181 if (getCookie(config.cookieName) === 'closed'){ 182 config.cookiePass = false; 183 } 184 } 185 if (el.hasAttribute('data-cookies-storage')){ 186 config.cookiesPeriod = el.getAttribute('data-cookies-storage'); 187 } 188 if (el.hasAttribute('data-use-state')){ 189 config.useState = true; 190 } 191 if (el.hasAttribute('data-scroll-block')){ 192 config.useScrollBlock = true; 193 } 194 if (el.hasAttribute('data-triggers-everytime')){ 195 config.customTriggersOnce = false; 196 } 197 if (el.hasAttribute('data-has-video')){ 198 config.hasVideos = true; 199 } 200 201 if (el.hasAttribute('data-content-aware')){ 202 config.isContentAware = true; 203 var innerForms = getCollection('form', el); 204 var innerVideos = getCollection('video', el); 205 if (innerForms){ 206 config.hasForms = true; 207 innerForms.forEach(function(innerForm){ 208 config.responsesList.forEach(function(term){ 209 if(innerForm.classList.contains(term)){ 210 config.hasActiveForms = true; 211 } 212 }) 213 }) 214 } 215 if (innerVideos){ 216 config.hasVideos = true; 217 } 218 } 219 })(); 220 221 // Get config from prop 222 Object.assign(config, givenParams); 223 224 var modal_obj = new XModal(el, config); 225 return modal_obj; 226 227} 228 229 230 231 232 233 234function noScroll() { 235 const x = getCurrentTop(); 236 window.scrollTo(0, x); 237} 238 239 240 241 242 243 244 245// Modal Init 246document.addEventListener("DOMContentLoaded", function(){ 247 var modals = getCollection('.x-modal'); 248 if (modals){ 249 modals.forEach(function(modal){ 250 var theModal = xModal(modal); 251 if (theModal){ 252 theModal.init(); 253 } 254 }); 255 } 256}) 257 258// Modal Init on Init Event 259document.addEventListener('modal-init', function(e){ 260 var modal = e.detail; 261 modal.addClass('--init'); 262 initButtons(modal, modal.getParam('id')); 263 264 if(modal.getParam('hasActiveForms')){ 265 modal.activate('has-active-form-trigger'); 266 } 267 268 if (checkHash(modal.getParam('id'))) { 269 modal.activate('hash-trigger'); 270 }; 271 272 if(modal.getParam('triggers').length > 0){
273 initCustomTriggers(modal); 274 } 275 if(modal.getParam('useState')){ 276 window.addEventListener('hashchange', function() { 277 if (checkHash(modal.getParam('id'))) { 278 modal.activate('hash-change-trigger'); 279 } 280 }, false); 281 } 282 283 // Close buttons 284 var close_btns = getCollection( '.x-modal__close', modal.getEl() ); 285 if (close_btns) { 286 close_btns.forEach((btn) => { 287 btn.addEventListener('click', e => { 288 modal.deactivate('btn'); 289 }) 290 }) 291 } 292 293 // Backdrop closure 294 var backdrop = getElement( '.x-modal__backdrop', modal.getEl() ); 295 if (backdrop) { 296 backdrop.addEventListener('click', e => { 297 if(e.target == backdrop){ 298 modal.deactivate('backdrop'); 299 } 300 }) 301 } 302 303 // Esc key closure 304 document.addEventListener('keyup', function(e) { 305 if(e.key === "Escape") { 306 modal.deactivate('key'); 307 } 308 }) 309 310 311}) 312 313function checkHash(name){ 314 if(!window.location.hash) return false; 315 var hash = window.location.hash.substring(1); //Puts hash in variable, and removes the # character 316 if (hash == name) return true; 317 return false; 318} 319 320function initButtons(modal, id){ 321 var btns = getCollection( '.modal-trigger[data-modal-name="' + id + '"], .modal-trigger[href="#' + id + '"], .modal-trigger__' + id); 322 if (!btns) return 323 btns.forEach((btn) => { 324 btn.addEventListener('click', e => { 325 e.preventDefault(); 326 modal.activate('btn-trigger'); 327 }) 328 }) 329} 330 331function initCustomTriggers(modal){ 332 333 function initTimerTrigger(givenModal){ 334 setTimeout(function(){ 335 if (givenModal.getParam('notTriggered')){ 336 givenModal.activate('custom-trigger'); 337 } 338 }, givenModal.getParam('timerValue')); 339 } 340 341 function initExitIntentTrigger(givenModal){ 342 if (givenModal.getParam('notTriggered')){ 343 function eventHandler(e){ 344 if (!e.toElement && !e.relatedTarget) { 345 givenModal.activate('custom-trigger'); 346 if(givenModal.getParam('customTriggersOnce')){ 347 document.removeEventListener('mouseout', eventHandler) 348 } 349 } 350 } 351 document.addEventListener('mouseout', eventHandler); 352 } 353 } 354 //Scroll triggers 355 function initPageScroll(givenModal) { 356 function scrollHandler(){ 357 var givenHeight = document.body.scrollHeight; 358 var scrollTop = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop; 359 var calcValue = (givenHeight * givenModal.getParam('scrollValue') / 100) - xClientHeight; 360 if (calcValue < scrollTop) { 361 givenModal.activate('custom-trigger'); 362 if(givenModal.getParam('customTriggersOnce')){ 363 document.removeEventListener('scroll', scrollHandler) 364 } 365 } 366 } 367 document.addEventListener('scroll', scrollHandler); 368 } 369 370 function initElementScroll(givenModal) { 371 var target = document.querySelector(givenModal.getParam('scrollTarget')); 372 if (!target) return 373 var targetHeight = target.getBoundingClientRect().height; 374 function scrollHandler(){ 375 var currentTop = target.getBoundingClientRect().top; 376 377 var percentRemain = (targetHeight + currentTop - xClientHeight / 2) * 100 / targetHeight; 378 379 if (percentRemain < givenModal.getParam('scrollValue')) { 380 givenModal.activate('custom-trigger'); 381 if(givenModal.getParam('customTriggersOnce')){ 382 document.removeEventListener('scroll', scrollHandler) 383 } 384 } 385 } 386 document.addEventListener('scroll', scrollHandler); 387 } 388 389 function initScrollElementStart(givenModal) { 390 var target = document.querySelector(givenModal.getParam('scrollTarget')); 391 if (!target) return 392 function scrollHandler(){ 393 var currentTop = target.getBoundingClientRect().top; 394 395 if (currentTop < -1 * givenModal.getParam('scrollOffset')){ 396 givenModal.activate('custom-trigger'); 397 if(givenModal.getParam('customTriggersOnce')){ 398 document.removeEventListener('scroll', scrollHandler) 399 } 400 } 401 } 402 document.addEventListener('scroll', scrollHandler); 403 } 404 405 function initScrollElementEnd(givenModal) { 406 var target = document.querySelector(givenModal.getParam('scrollTarget')); 407 if (!target) return 408 function scrollHandler(){ 409 var currentBottom = target.getBoundingClientRect().bottom; 410 if (currentBottom > 0){ 411 var fromBottom = xClientHeight - currentBottom 412 413 if (fromBottom < 1 * givenModal.getParam('scrollOffset')){ 414 givenModal.activate('custom-trigger'); 415 if(givenModal.getParam('customTriggersOnce')){ 416 document.removeEventListener('scroll', scrollHandler) 417 } 418 } 419 } 420 } 421 document.addEventListener('scroll', scrollHandler); 422 } 423 424 function initScrollTrigger(givenModal){ 425 if (givenModal.getParam('notTriggered')){ 426 switch (givenModal.getParam('scrollType')){ 427 case 'page-scroll' : 428 initPageScroll(givenModal); 429 break; 430 case 'element-scroll' : 431 initElementScroll(givenModal); 432 break; 433 case 'element-start' : 434 initScrollElementStart(givenModal); 435 break; 436 case 'element-end' : 437 initScrollElementEnd(givenModal); 438 break; 439 } 440 } 441 } 442 443 444 if (!modal.getParam('cookiePass')) return 445 modal.getParam('triggers').forEach(function(customTrigger){
446 switch (customTrigger){ 447 case 'timer' : 448 initTimerTrigger(modal); 449 break; 450 case 'exit-intent' : 451 if (!is_touch_device()){ 452 initExitIntentTrigger(modal); 453 } else { 454 initScrollTrigger(modal); 455 } 456 break; 457 case 'scroll' : 458 initScrollTrigger(modal); 459 break; 460 } 461 }) 462} 463 464document.addEventListener('modal-activated', function(e){ 465 var modal = e.detail; 466 467 modal.addClass('--active'); 468 var holder = modal.getEl().closest('.x-modal_holder'); 469 if (holder){ 470 holder.classList.add('--has-active'); 471 } 472 473 474 if (modal.getParam('hasVideos') && modal.getParam('isContentAware')){ 475 var video = modal.getEl().querySelector('video'); 476 477 if (video){ 478 video.play(); 479 } 480 var video_obj = modal.getEl().querySelector('.video-js'); 481 var id = video_obj.getAttribute('id'); 482 if (video_obj){ 483 var player = videojs(id); 484 player.play(); 485 } 486 } 487 488 if (modal.getParam('useState')){ 489 if (window.location.hash) { 490 window.history.pushState({}, document.title, location.href.substr(0, location.href.length-location.hash.length) + '#' + modal.getParam('id')); 491 } else { 492 window.history.pushState({}, document.title, location.href + '#' + modal.getParam('id') ); 493 } 494 window.addEventListener('hashchange', function() { 495 if (!checkHash(modal.getParam('id'))) { 496 modal.deactivate('hash-change-trigger'); 497 } 498 }, false); 499 } 500 501 if (modal.getParam('hasForms')){ 502 var form = modal.getEl().querySelector('form'); 503 if (form){ 504 form.addEventListener('submit', function(e){ 505 setTimeout(function(){ 506 modal.getParam('submitList').forEach(function(value){ 507 if(e.target.classList.contains(value)){ 508 modal.deactivate('succesful-submit') 509 } 510 }) 511 }, 6000) 512 513 }) 514 } 515 } 516 517 if (modal.getParam('useScrollBlock')){ 518 var givenHeight = document.body.scrollHeight; 519 if (givenHeight > xClientHeight){ 520 var scrollTop = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop; 521 // document.documentElement.style.setProperty('top', (-1 * scrollTop) + 'px'); 522 document.documentElement.style.setProperty('--top', (-1 * scrollTop) + 'px'); 523 document.documentElement.classList.add('--scrolling-disabled'); 524 document.documentElement.classList.add('--scrolling-instant'); 525 document.documentElement.setAttribute('data-scroll-position', scrollTop ); 526 } 527 } 528}) 529 530document.addEventListener('modal-deactivated', function(e){ 531 var modal = e.detail; 532 533 if (modal.getParam('hasVideos') && modal.getParam('isContentAware')){ 534 var video = modal.getEl().querySelector('video'); 535 536 if (video){ 537 video.pause(); 538 } 539 var video_obj = modal.getEl().querySelector('.video-js'); 540 var id = video_obj.getAttribute('id'); 541 if (video_obj){ 542 var player = videojs(id); 543 player.pause(); 544 } 545 } 546 547 modal.removeClass('--active'); 548 var holder = modal.getEl().closest('.x-modal_holder'); 549 if (holder){ 550 removeClass('--has-active', holder); 551 } 552 553 if (modal.getParam('useState')){ 554 if (window.location.hash && window.location.hash == '#' + modal.getParam('id')) { 555 window.history.pushState({}, document.title, location.href.substr(0, location.href.length-location.hash.length)); 556 } 557 } 558 559 if (modal.getParam('useScrollBlock')){ 560 if (document.documentElement.classList.contains('--scrolling-disabled')){ 561 // document.documentElement.style.setProperty('top', ''); 562 document.documentElement.style.setProperty('--top', ''); 563 document.documentElement.classList.remove('--scrolling-disabled'); 564 setTimeout(function(){document.documentElement.classList.remove('--scrolling-instant');}, 50) 565 document.documentElement.scrollTop = document.documentElement.getAttribute('data-scroll-position'); 566 } 567 } 568}) 569
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.