1var MiniMasonry=function(t){return this._sizes=[],this._columns=[],this._container=null,this._count=null,this._width=0,this._resizeTimeout=null,this.conf={baseWidth:255,gutterX:null,gutterY:null,gutter:10,container:null,minify:!0,ultimateGutter:5,surroundingGutter:!0},this.init(t),this};MiniMasonry.prototype.init=function(t){for(var i in this.conf)null!=t[i]&&(this.conf[i]=t[i]);if(null!=this.conf.gutterX&&null!=this.conf.gutterY||(this.conf.gutterX=this.conf.gutterY=this.conf.gutter),this._gutterX=this.conf.gutterX,this._container=document.querySelector(this.conf.container),!this._container)throw new Error("Container not found or missing");window.addEventListener("resize",this.resizeThrottler.bind(this)),this.layout()},MiniMasonry.prototype.reset=function(){this._sizes=[],this._columns=[],this._count=null,this._width=this._container.clientWidth;var t=this.conf.baseWidth;this._width<t&&(this._width=t,this._container.style.minWidth=t+"px"),1==this.getCount()?(this.conf._gutterX=this.conf.gutterX,this.conf.gutterX=this.conf.ultimateGutter,this._count=1):this.conf.gutterX=this._gutterX},MiniMasonry.prototype.getCount=function(){return this.conf.surroundingGutter?Math.floor((this._width-this.conf.gutterX)/(this.conf.baseWidth+this.conf.gutterX)):Math.floor((this._width+this.conf.gutterX)/(this.conf.baseWidth+this.conf.gutterX))},MiniMasonry.prototype.computeWidth=function(){var t;return t=this.conf.surroundingGutter?(this._width-this.conf.gutterX)/this._count-this.conf.gutterX:(this._width+this.conf.gutterX)/this._count-this.conf.gutterX,t=Number.parseInt(t.toFixed(2))},MiniMasonry.prototype.layout=function(){if(this._container){this.reset(),null==this._count&&(this._count=this.getCount());for(var t=this.computeWidth(),i=0;i<this._count;i++)this._columns[i]=0;for(var n=this._container.querySelectorAll(this.conf.container+" > *"),s=0;s<n.length;s++)n[s].style.width=t+"px",this._sizes[s]=n[s].clientHeight;var o=this.conf.surroundingGutter?this.conf.gutterX:0;if(this._count>this._sizes.length){var e=this._sizes.length*(t+this.conf.gutterX)-this.conf.gutterX;o=(this._width-e)/2}for(var r=0;r<n.length;r++){var h=this.conf.minify?this.getShortest():this.getNextColumn(r),u=0;(this.conf.surroundingGutter||h!=this._columns.length)&&(u=this.conf.gutterX);var c=o+(t+u)*h,l=this._columns[h];n[r].style.transform="translate3d("+Math.round(c)+"px,"+Math.round(l)+"px,0)",this._columns[h]+=this._sizes[r]+this.conf.gutterY}this._container.style.height=this._columns[this.getLongest()]-this.conf.gutterY+"px"}else console.error("Container not found")},MiniMasonry.prototype.getNextColumn=function(t){return t%this._columns.length},MiniMasonry.prototype.getShortest=function(){for(var t=0,i=0;i<this._count;i++)this._columns[i]<this._columns[t]&&(t=i);return t},MiniMasonry.prototype.getLongest=function(){for(var t=0,i=0;i<this._count;i++)this._columns[i]>this._columns[t]&&(t=i);return t},MiniMasonry.prototype.resizeThrottler=function(){this._resizeTimeout||(this._resizeTimeout=setTimeout(function(){this._resizeTimeout=null,this._container.clientWidth!=this._width&&this.layout()}.bind(this),33))}; 2 3var journoPortfolio = (function () { 4 5 const loaded = []; 6 const inProgress = {}; 7 const blocks = []; 8 var DOMContentLoaded = false 9 var animateInElements = []; 10 var animateInterval; 11 12 var animateObserver = new IntersectionObserver(function(entries, observer) { 13 entries.forEach(function(entry) { 14 if (entry.isIntersecting) { 15 animateInElements.push(entry.target) 16 }else{ 17 if(animateInElements.indexOf(entry.target) !== -1){ 18 animateInElements.splice(animateInElements.indexOf(entry.target), 1); 19 } 20 } 21 }); 22 }, {root: document, rootMargin: "0px 0px 0px 0px"}); 23 24 var imageObserver = new IntersectionObserver(function(entries, observer) { 25 entries.forEach(function(entry) { 26 if (entry.isIntersecting) { 27 var image = entry.target; 28 if(image.dataset.src){ 29 image.src = image.dataset.src; 30 delete image.dataset.src 31 }else if (image.dataset.layout === "slideshow"){ 32 image.querySelectorAll('[data-src]').forEach(($el) => { 33 if($el.dataset.src){ 34 $el.src = $el.dataset.src; 35 delete $el.dataset.src 36 } 37 imageObserver.unobserve($el); 38 }) 39 image.querySelectorAll('[data-background-src]').forEach(($el) => { 40 if($el.dataset.backgroundSrc){ 41 $el.style.backgroundImage = 'url('+$el.dataset.backgroundSrc+')'; 42 delete $el.dataset.backgroundSrc 43 } 44 imageBGObserver.unobserve($el); 45 }) 46 } 47 imageObserver.unobserve(entry.target); 48 } 49 }); 50 }, {root: document, rootMargin: "0px 0px 300px 0px"}); 51 52 53 var imageBGObserver = new IntersectionObserver(function(entries, observer) {
54 entries.forEach(function(entry) { 55 if (entry.isIntersecting) { 56 var image = entry.target; 57 if(image.dataset.backgroundSrc){ 58 image.style.backgroundImage = 'url('+image.dataset.backgroundSrc+')'; 59 delete image.dataset.backgroundSrc 60 } 61 imageBGObserver.unobserve(image); 62 } 63 }); 64 }, {root: document, rootMargin: "0px 0px 300px 0px"}); 65 66 function libName2URL(libName){ 67 switch(libName){ 68 case 'mapbox': 69 return 'https://api.mapbox.com/mapbox-gl-js/v2.1.1/mapbox-gl.js' 70 case 'mux-player': 71 return 'https://unpkg.com/@mux/[email protected]/dist/mux-player.js' 72 case 'grecaptcha': 73 return `https://www.google.com/recaptcha/api.js?render=${window.PORTFOLIO_CAPTCHA_PUBLIC_KEY}` 74 case 'reframe': 75 return 'https://static.journoportfolio.com/public/js/reframe-2.min.js' 76 case 'pdfobject': 77 return 'https://static.journoportfolio.com/public/js/pdfobject-201604172.min.js' 78 case 'macy': 79 return 'https://static.journoportfolio.com/public/js/macy-1.0.0.js' 80 case 'swiper': 81 return 'https://static.journoportfolio.com/public/js/swiper-6.4.11.min.js' 82 case 'axios': 83 return 'https://static.journoportfolio.com/public/js/axios-0.21.1.min.js' 84 } 85 } 86 87 function articleClick(id){ 88 return new Promise((resolve, reject) => { 89 if(window.IS_OWNER){ 90 resolve() 91 return 92 } 93 try { 94 fetch('/_analytics/articles/'+id+'/').then(function(){ 95 resolve() 96 }).catch(function(){ 97 resolve() 98 }) 99 } catch { 100 resolve() 101 } 102 }) 103 } 104 105 function requireLibrary(libName){ 106 var promise = new Promise((resolve, reject) => { 107 108 let url = libName2URL(libName); 109 110 if(url){ 111 loadScript(libName, url, resolve) 112 } 113 }) 114 return promise; 115 } 116 117 function loadScript(libName, url, resolve){ 118 if(loaded.indexOf(libName) !== -1){ 119 return resolve(); 120 } 121 if(libName in inProgress){ 122 inProgress[libName].push(resolve); 123 return 124 }else{ 125 inProgress[libName] = [resolve] 126 } 127 var script = document.createElement('script'); 128 script.onload = function(){ 129 loaded.push(libName) 130 for(var i=0;i<inProgress[libName].length;i++){ 131 inProgress[libName][i]() 132 } 133 delete inProgress[libName]; 134 } 135 script.src = url; 136 document.head.appendChild(script); 137 } 138 139 function newContent($elParent) { 140 $elParent.querySelectorAll('.animate-in').forEach(($el) => { 141 animateObserver.observe($el) 142 }) 143 144 $elParent.querySelectorAll('[data-src]').forEach(($el) => { 145 if($el.dataset.src){ 146 imageObserver.observe($el) 147 } 148 }) 149 150 $elParent.querySelectorAll('[data-layout=slideshow]').forEach(($el) => { 151 imageObserver.observe($el) 152 }) 153 154 $elParent.querySelectorAll('[data-background-src]').forEach(($el) => { 155 if($el.dataset.backgroundSrc){ 156 imageBGObserver.observe($el) 157 } 158 }); 159 160 if(!window.IS_OWNER){ 161 if($elParent.matches && $elParent.matches('.section')){ 162 initializeSectionSlideshow($elParent) 163 } 164 $elParent.querySelectorAll('.section').forEach(($section) => { 165 initializeSectionSlideshow($section) 166 }) 167 } 168 } 169 170 function initializeSectionSlideshow($section){ 171 var $slider = $section.querySelector('.section__content[data-layout-mode="slideshow"] .section-slideshow') 172 var $viewport = $slider && $slider.querySelector('.section-slideshow__viewport') 173 if(!$viewport || $viewport.swiper){ 174 return 175 } 176 177 requireLibrary('swiper').then(function(){ 178 if(!$viewport.isConnected || $viewport.swiper){ 179 return 180 } 181
182 var $wrapper = $viewport.querySelector('.section-slideshow__wrapper') 183 var hasMultipleSlides = Boolean($wrapper && $wrapper.children.length > 1) 184 var useClonedLoop = hasMultipleSlides && !window.IS_OWNER 185 var options = { 186 autoHeight: false, 187 loop: useClonedLoop, 188 noSwiping: true, 189 noSwipingSelector: '.jp-block-mount, .jp-column-mount, .jp-divider-add, .jp-toolbar, [contenteditable="true"]', 190 observer: true, 191 observeParents: true, 192 observeSlideChildren: true, 193 preventClicks: !window.IS_OWNER, 194 preventClicksPropagation: !window.IS_OWNER, 195 touchStartPreventDefault: !window.IS_OWNER, 196 } 197 var $pagination = $slider.querySelector('.section-slideshow__pagination') 198 if($pagination){ 199 options.pagination = { 200 el: $pagination, 201 clickable: true, 202 } 203 } 204 var $next = $slider.querySelector('.section-slideshow__button--next') 205 var $previous = $slider.querySelector('.section-slideshow__button--previous') 206 if($next && $previous && useClonedLoop){ 207 options.navigation = { 208 nextEl: $next, 209 prevEl: $previous, 210 } 211 } 212 213 var swiper = new Swiper($viewport, options) 214 if($next && $previous && $wrapper && hasMultipleSlides && !useClonedLoop){ 215 var wrapping = false 216 217 function prepareClone($slide){ 218 var $clone = $slide.cloneNode(true) 219 $clone.classList.remove('swiper-slide-active', 'swiper-slide-next', 'swiper-slide-prev') 220 $clone.classList.add('section-slideshow__transition-clone') 221 $clone.setAttribute('aria-hidden', 'true') 222 return $clone 223 } 224 225 function wrapNext(){ 226 if(wrapping || swiper.animating){ 227 return 228 } 229 wrapping = true 230 var $clone = prepareClone(swiper.slides[0]) 231 $wrapper.appendChild($clone) 232 swiper.update() 233 swiper.once('transitionEnd', function(){ 234 swiper.slideTo(0, 0, false) 235 $clone.remove() 236 swiper.update() 237 wrapping = false 238 }) 239 swiper.slideTo(swiper.slides.length - 1) 240 } 241 242 function wrapPrevious(){ 243 if(wrapping || swiper.animating){ 244 return 245 } 246 wrapping = true 247 var $clone = prepareClone(swiper.slides[swiper.slides.length - 1]) 248 $wrapper.insertBefore($clone, $wrapper.firstChild) 249 swiper.update() 250 swiper.slideTo(1, 0, false) 251 swiper.once('transitionEnd', function(){ 252 $clone.remove() 253 swiper.update() 254 swiper.slideTo(swiper.slides.length - 1, 0, false) 255 wrapping = false 256 }) 257 requestAnimationFrame(function(){ 258 swiper.slideTo(0) 259 }) 260 } 261 262 $next.addEventListener('click', function(){ 263 if(swiper.isEnd){ 264 wrapNext() 265 }else{ 266 swiper.slideNext() 267 } 268 }) 269 $previous.addEventListener('click', function(){ 270 if(swiper.isBeginning){ 271 wrapPrevious() 272 }else{ 273 swiper.slidePrev() 274 } 275 }) 276 277 var gestureStartedAtBeginning = false 278 var gestureStartedAtEnd = false 279 swiper.on('touchStart', function(){ 280 gestureStartedAtBeginning = swiper.isBeginning 281 gestureStartedAtEnd = swiper.isEnd 282 }) 283 swiper.on('touchEnd', function(){ 284 if(gestureStartedAtEnd && swiper.swipeDirection === 'next'){ 285 wrapNext() 286 }else if(gestureStartedAtBeginning && swiper.swipeDirection === 'prev'){ 287 wrapPrevious() 288 } 289 gestureStartedAtBeginning = false 290 gestureStartedAtEnd = false 291 }) 292 } 293 }) 294 } 295 296 function redoExpand($block) { 297 var $el = $block.firstElementChild 298 if($el.dataset.collapsed && $block.nextElementSibling){ 299 $block.nextElementSibling.classList.add('collapsed') 300 } 301 302 $el.onclick = function(e){ 303 if($el.dataset.collapsed){ 304 $el.removeAttribute('data-collapsed') 305 if($block.nextElementSibling){ 306 $block.nextElementSibling.classList.remove('collapsed') 307 } 308 }else{ 309 $el.dataset.collapsed = "true" 310 if($block.nextElementSibling){ 311 $block.nextElementSibling.classList.add('collapsed') 312 } 313 } 314 } 315 } 316
317 function init(){ 318 document.addEventListener('DOMContentLoaded', function(){ 319 DOMContentLoaded = true 320 321 document.querySelectorAll('.block').forEach(($block) => { 322 if($block.dataset.definitionName in blocks){ 323 blocks[$block.dataset.definitionName].initialize($block); 324 } 325 }) 326 327 if(!window.IS_OWNER){ 328 document.querySelectorAll('.section').forEach(($section) => { 329 initializeSectionSlideshow($section) 330 }) 331 } 332 333 document.querySelectorAll('.animate-in').forEach(($el) => { 334 animateObserver.observe($el) 335 }) 336 337 if(document.querySelector('[data-language-picker]')){ 338 document.querySelectorAll('[data-language-picker]').forEach(($el) => { 339 $el.onchange = function(){ 340 window.location = "/" + $el.value + $el.dataset.path; 341 } 342 }) 343 } 344 345 document.querySelectorAll('[data-layout=slideshow]').forEach(($el) => { 346 imageObserver.observe($el) 347 }) 348 349 document.querySelectorAll('[data-src]').forEach(($el) => { 350 if($el.dataset.src){ 351 imageObserver.observe($el) 352 } 353 }) 354 355 document.querySelectorAll('[data-background-src]').forEach(($el) => { 356 if($el.dataset.backgroundSrc){ 357 imageBGObserver.observe($el) 358 } 359 }); 360 361 var delay = parseFloat(getComputedStyle(document.querySelector('html')).getPropertyValue('--jp-animation-delay')); 362 363 animateInterval = setInterval(function() { 364 if(animateInElements.length > 0){ 365 var $el = animateInElements.shift() 366 $el.classList.add("animate-in-go") 367 } 368 }, delay) 369 }); 370 } 371 372 function resetAnimation(){ 373 374 clearInterval(animateInterval) 375 376 animateInElements = [] 377 378 document.querySelectorAll('.animate-in').forEach(($el) => { 379 animateInElements.push($el) 380 }) 381 382 var delay = parseFloat(getComputedStyle(document.querySelector('html')).getPropertyValue('--jp-animation-delay')); 383 384 animateInterval = setInterval(function() { 385 if(animateInElements.length > 0){ 386 var $el = animateInElements.shift() 387 $el.classList.add("animate-in-go") 388 } 389 }, delay) 390 } 391 392 function reInitializeBlock($block){ 393 if($block.dataset.definitionName in blocks){ 394 blocks[$block.dataset.definitionName].initialize($block); 395 } 396 397 $block.querySelectorAll('.animate-in').forEach(($el) => { 398 animateInElements.push($el) 399 }) 400 401 $block.querySelectorAll('[data-src]').forEach(($el) => { 402 if($el.dataset.src){ 403 $el.src = $el.dataset.src; 404 delete $el.dataset.src 405 } 406 }) 407 408 $block.querySelectorAll('[data-background-src]').forEach(($el) => { 409 if($el.dataset.backgroundSrc){ 410 $el.style.backgroundImage = 'url('+$el.dataset.backgroundSrc+')'; 411 delete $el.dataset.backgroundSrc 412 } 413 }); 414 } 415 416 function registerBlock(typeID, func){ 417 blocks[typeID] = func 418 } 419 420 return { 421 reInitializeBlock: reInitializeBlock, 422 resetAnimation: resetAnimation, 423 requireLibrary: requireLibrary, 424 articleClick: articleClick, 425 registerBlock: registerBlock, 426 initializeSectionSlideshow: initializeSectionSlideshow, 427 newContent: newContent, 428 redoExpand: redoExpand, 429 init: init, 430 cart: null, 431 } 432})(); 433journoPortfolio.registerBlock("PDF", (function () { 434 const type = "generic"; 435 436 function initialize (block) { 437 executeBlockCode(block); 438 } 439 440 function executeBlockCode (block) { 441 var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); 442 443function performSwitch(){ 444 if(!('PDF Viewer' in navigator.plugins)){ 445 var $e = block.querySelector("object") 446 if($e){ 447 var height = $e.height 448 if(height < 400){ 449 height = 400 450 } 451 $e.parentNode.insertAdjacentElement('beforebegin', $e.children[0]) 452 453 setTimeout(function(){ // required for weird safari bug 454 $e.parentNode.removeChild($e) 455 block.querySelector('iframe').style.width = '100%' 456 block.querySelector('iframe').style.height = height+'px' 457 }, 1000) 458 } 459 } 460} 461 462if(isSafari){ 463 setTimeout(function(){ 464 performSwitch() 465 }, 500) 466}else{ 467 performSwitch() 468} 469 470 471 } 472 473 return { 474 initialize: initialize, 475 } 476})()); 477 478journoPortfolio.registerBlock("Subscribe Form", (function () { 479 const type = "generic"; 480 481 function initialize (block) { 482 executeBlockCode(block); 483 } 484 485 function executeBlockCode (block) { 486 var $modal = block.querySelector('.content-modal') 487if($modal){ 488 var $form = $modal; 489}else{ 490 var $form = block; 491} 492 493function escPress (e) { 494 if (e.key === "Escape") { 495 closeModal() 496 } 497} 498 499function closePress (e) { 500 closeModal(); 501} 502 503function clickBg (e) { 504 if (e.target === this){ 505 closeModal() 506 } 507} 508 509function closeModal () { 510 $modal.classList.remove('open') 511 document.removeEventListener('keyup', escPress); 512} 513 514function openModal () { 515 document.body.appendChild($modal) 516 517 // force render so animations work 518 var x = $modal.clientHeight; 519 520 $modal.classList.add('open') 521 $modal.removeAttribute('hidden') 522 523 $modal.onclick = clickBg 524 $modal.querySelector('.close').onclick = closePress 525 document.addEventListener('keyup', escPress); 526} 527 528if(block.querySelector('.open-subscribe-form')){ 529 block.querySelector('.open-subscribe-form').onclick = function(){ 530 openModal() 531 } 532} 533 534Promise.all([ 535 journoPortfolio.requireLibrary("grecaptcha"), 536 journoPortfolio.requireLibrary("axios"), 537]).then(function(){ 538 539 var loading = false 540 if(!block.querySelector('form')){ 541 return 542 } 543 block.querySelector('form').onsubmit = function(e){ 544 e.preventDefault(); 545 546 if(loading){ 547 return 548 } 549 550 loading = true 551 $form.querySelector('button[data-save-button]').classList.add('saving') 552 $form.querySelectorAll('input,textarea').forEach(function($el){ 553 $el.parentElement.classList.remove('error') 554 }) 555 556 grecaptcha.ready(function() { 557 grecaptcha.execute(window.PORTFOLIO_CAPTCHA_PUBLIC_KEY, {action: 'submit'}).then(function(token) { 558 559 var data = { 560 email: $form.querySelector('input[name=email]').value, 561 block: Number(block.dataset.id), 562 captcha_token: token 563 } 564 565 if($form.querySelector('input[name=name]')){ 566 data.name = $form.querySelector('input[name=name]').value 567 } 568 569 axios.post('/api/v1/subscribe/', data) 570 .then(function(data) { 571 var $form1 = $form.querySelector('form') 572 var $success = $form.querySelector('.success-message') 573 $success.style.height = $form1.offsetHeight + 'px' 574 $success.style.width = $form1.offsetWidth + 'px' 575 $success.style.display = 'block' 576 $form1.remove() 577 578 if(typeof journoPortfolio.onSubscribeFormSuccess === 'function') { 579 journoPortfolio.onSubscribeFormSuccess(Number(block.dataset.id)) 580 } 581 }) 582 .catch(function(error){ 583 if (error.response) { 584 if(error.response.status === 400){ 585 errors = error.response.data; 586 for(name in errors){ 587 $form.querySelector('input[name='+name+']').parentElement.classList.add('error') 588 $form.querySelector('input[name='+name+']').parentElement.querySelector('.field__error').innerHTML = errors[name][0] 589 } 590 console.log(error.response.data) 591 } 592 } else if (error.request) { 593 console.log(error.request); 594 } else { 595 console.log('Error', error.message); 596 } 597 }) 598 .finally(function(){ 599 loading = false 600 if($form.querySelector('button[data-save-button]')){ 601 $form.querySelector('button[data-save-button]').classList.remove('saving') 602 } 603 }) 604 }) 605 606 }); 607 } 608}); 609 610 } 611 612 return { 613 initialize: initialize, 614 } 615})()); 616 617journoPortfolio.registerBlock("Blog Post Footer", (function () { 618 const type = "blog-post"; 619 620 function initialize (block) { 621 executeBlockCode(block); 622 } 623 624 function executeBlockCode (block) { 625 var loading = false;
626 627Promise.all([ 628 journoPortfolio.requireLibrary("grecaptcha"), 629 journoPortfolio.requireLibrary("axios"), 630]).then(function(){ 631 632 var $modal = block.querySelector('.content-modal') 633 634 if(block.querySelector('#add-comment')){ 635 block.querySelector('#add-comment').onclick = function(){ 636 openModal() 637 } 638 } 639 640 function closeModal () { 641 $modal.classList.remove('open') 642 document.removeEventListener('keyup', escPress); 643 } 644 645 function escPress (e) { 646 if (e.key === "Escape") { 647 closeModal() 648 } 649 } 650 651 function closePress (e) { 652 closeModal(); 653 } 654 655 function clickBg (e) { 656 if (e.target === this){ 657 closeModal() 658 } 659 } 660 661 function showGlobalError(errorMsg){ 662 $modal.querySelector('.error-global').innerText = errorMsg 663 $modal.querySelector('.error-global').style.display = 'block' 664 } 665 666 function applyErrorToField(fieldName, errorMsg){ 667 var $field = block.querySelector('#field_'+fieldName) 668 $field.classList.add('error') 669 if($field.querySelector('.error-msg')){ 670 $field.querySelector('.error-msg').remove() 671 } 672 $field.children[1].insertAdjacentHTML( 'afterend', "<div class='error-msg'>"+errorMsg+"</div>"); 673 } 674 675 function openModal () { 676 document.body.appendChild($modal) 677 678 // force render so animations work 679 var x = $modal.clientHeight; 680 $modal.classList.add('open') 681 $modal.removeAttribute('hidden') 682 683 $modal.onclick = clickBg 684 $modal.querySelector('.close').onclick = closePress 685 document.addEventListener('keyup', escPress); 686 687 $modal.querySelector('#comment-form').onsubmit = function(e){ 688 e.preventDefault() 689 690 loading = true 691 $modal.querySelectorAll('input,textarea').forEach(function($el){ 692 $el.parentElement.classList.remove('error') 693 }) 694 $modal.querySelector('button').classList.add('saving') 695 696 grecaptcha.ready(function() { 697 grecaptcha.execute(window.PORTFOLIO_CAPTCHA_PUBLIC_KEY, {action: 'submit'}).then(function(token) { 698 699 var data = { 700 name: $modal.querySelector('#comment_name').value, 701 email: $modal.querySelector('#comment_email').value, 702 content: $modal.querySelector('#comment_content').value, 703 article: window.ARTICLE_ID, 704 captcha_token: token 705 } 706 axios.post("/api/v1/comments/", data) 707 .then(data => { 708 closeModal() 709 $modal.querySelector('#comment_name').value = '' 710 $modal.querySelector('#comment_email').value = '' 711 $modal.querySelector('#comment_content').value = '' 712 var comment = data.data 713 document.querySelector('.comments').insertAdjacentHTML('beforeend', `<div class="comment new" id="comment-${comment.id}"><small class="meta">Posted on ${comment.datetime} <a class="comment__permalink" href="${window.location.pathname}#comment-${comment.id}">Permalink</a></small><h3>${comment.name}</h3>${comment.content_display}</div>`) 714 715 document.querySelector(`#comment-${comment.id}`).scrollIntoView({ 716 behavior: 'smooth' 717 }); 718 }) 719 .catch(error =>{ 720 loading = false 721 if (error.response) { 722 if(error.response.status === 400){ 723 errors = error.response.data; 724 for(name in errors){ 725 $modal.querySelector('[name='+name+']').parentElement.classList.add('error') 726 $modal.querySelector('[name='+name+']').parentElement.querySelector('.field__error').innerHTML = errors[name][0] 727 } 728 console.log(error.response.data) 729 } 730 } else if (error.request) { 731 console.log(error.request); 732 } else { 733 console.log('Error', error.message); 734 } 735 736 }) 737 }) 738 }) 739 } 740 } 741 742}) 743 744 } 745 746 return { 747 initialize: initialize, 748 } 749})()); 750 751journoPortfolio.registerBlock("Navigation", (function () { 752 const type = "navigation"; 753 754 function initialize (block) { 755 executeBlockCode(block); 756 } 757 758 function executeBlockCode (block) { 759 function isOverflown(element) { 760 return element.scrollWidth > element.clientWidth; 761} 762 763block.querySelectorAll('.navicon').forEach(function(item){ 764 item.onclick = function (){ 765 block.querySelector('.sidebar').classList.toggle("open"); 766 block.querySelector('.navicon').classList.toggle("open"); 767 }; 768}) 769 770block.querySelectorAll('.menu ul li a, .sidebar__inner a').forEach(function(item){ 771 item.onclick = function (e){ 772 var href = item.getAttribute("href") 773 if(href.startsWith('/#') && window.location.pathname === '/'){ 774 e.preventDefault() 775 var el = document.getElementById(href.replace('/#', '')) 776 var y = el.getBoundingClientRect().top + window.pageYOffset - document.querySelector('.header').offsetHeight; 777 778 window.scrollTo({top: y, behavior: 'smooth'}); 779 block.querySelector('.sidebar').classList.remove("open"); 780 block.querySelector('.navicon').classList.remove("open"); 781 } 782 }; 783}) 784 785function setupMenu() { 786 var menu = block.querySelector('.menu') 787 if(menu){ 788 var social = menu.querySelector('.social-icons') 789 if(social){ 790 if(social.offsetWidth > (menu.offsetWidth-40)){ 791 social.classList.add('hidden') 792 }else{ 793 social.classList.remove('hidden') 794 } 795 } 796 } 797 block.querySelector('.menu').classList.remove('force-navicon') 798 block.querySelectorAll('.menu ul > li.hidden').forEach((item)=>{ 799 item.classList.remove('hidden') 800 }) 801 if(block.querySelector('.menu > ul')){ 802 if(isOverflown(block.querySelector('.menu > ul'))){ 803 block.querySelector('.menu').classList.add('force-navicon') 804 while(isOverflown(block.querySelector('.menu > ul')) && block.querySelectorAll('.menu ul > li:not(.hidden)').length > 0){ 805 var links = block.querySelectorAll('.menu ul > li:not(.hidden)') 806 links[links.length-1].classList.add('hidden') 807 } 808 } 809 } 810} 811 812function setupTransparency () { 813 if(window.scrollY > 50){ 814 document.body.classList.add('scrolled') 815 }else{ 816 document.body.classList.remove('scrolled') 817 } 818} 819 820window.onresize = setupMenu 821setupMenu() 822 823window.onscroll = setupTransparency 824setupTransparency() 825 826journoPortfolio.cart.init() 827 828 829 } 830 831 return { 832 initialize: initialize, 833 } 834})()); 835 836journoPortfolio.registerBlock("Media Embed", (function () { 837 const type = "generic"; 838 839 function initialize (block) { 840 executeBlockCode(block); 841 } 842 843 function executeBlockCode (block) { 844 845if(window.FB){ 846 FB.XFBML.parse() 847} 848if(window.instgrm){ 849 window.instgrm.Embeds.process() 850} 851if(window.twttr){ 852 window.twttr.widgets.load() 853} 854 855if(block.querySelector('iframe') && block.querySelector('iframe').src.indexOf("www.linkedin.com") === -1 && block.querySelector('iframe').src.indexOf("pinterest.com") === -1){ 856 857journoPortfolio.requireLibrary("reframe").then(function(){ 858 if(block.querySelector('iframe')){ 859 if(block.querySelector('iframe').height){ 860 var newHeight = block.offsetWidth * (block.querySelector('iframe').height/block.querySelector('iframe').width) 861 block.querySelector('iframe').style.width = '100%' 862 block.querySelector('iframe').style.height = newHeight + 'px' 863 } 864 reframe(block.querySelector('iframe')) 865 } 866}) 867 868} 869 870 871 } 872 873 return { 874 initialize: initialize, 875 } 876})()); 877 878journoPortfolio.registerBlock("Slideshow", (function () { 879 const type = "generic"; 880 881 function initialize (block) { 882 executeBlockCode(block); 883 } 884 885 function executeBlockCode (block) { 886 journoPortfolio.requireLibrary('swiper').then(function(){ 887 var $slider = block.querySelector('.block-slider') 888 if(block.querySelectorAll('.swiper-container').length){ 889 var autoplay = false;
890 if($slider.hasAttribute('autoplay')){ 891 autoplay = { 892 delay: Number($slider.dataset.autoplayDelay), 893 disableOnInteraction: true, 894 } 895 } 896 var spaceBetween = 30 897 if($slider.dataset.spaceBetween === "none"){ 898 spaceBetween = 0 899 } 900 if($slider.dataset.spaceBetween === "small"){ 901 spaceBetween = 15 902 } 903 if($slider.dataset.spaceBetween === "medium"){ 904 spaceBetween = 30 905 } 906 if($slider.dataset.spaceBetween === "large"){ 907 spaceBetween = 50 908 } 909 var mySwiper = new Swiper('#block-'+block.dataset.id+' .swiper-container', { 910 direction: 'horizontal', 911 loop: $slider.hasAttribute('loop'), 912 autoHeight: true, 913 autoplay: autoplay, 914 spaceBetween: spaceBetween, 915 slidesPerView: Number($slider.dataset.slidesPerView), 916 paginationClickable: true, 917 navigation: { 918 nextEl: '.swiper-button-next', 919 prevEl: '.swiper-button-prev', 920 }, 921 }); 922 } 923}) 924 925 } 926 927 return { 928 initialize: initialize, 929 } 930})()); 931 932journoPortfolio.registerBlock("Expand", (function () { 933 const type = "generic"; 934 935 function initialize (block) { 936 executeBlockCode(block); 937 } 938 939 function executeBlockCode (block) { 940 journoPortfolio.redoExpand(block) 941 } 942 943 return { 944 initialize: initialize, 945 } 946})()); 947 948journoPortfolio.registerBlock("Gallery", (function () { 949 const type = "generic"; 950 951 function initialize (block) { 952 executeBlockCode(block); 953 } 954 955 function executeBlockCode (block) { 956 957 958var $modal = block.querySelector('.content-modal'); 959 960function reloadMacy(){ 961 if(document.querySelector(`#block-${block.dataset.id} .gallery-item__wrapper--nocrop`)){ 962 var width = document.querySelector(`#block-${block.dataset.id} .gallery-item__wrapper--nocrop`).offsetWidth / Number(block.children[0].dataset.columns); 963 width = Math.max(width-30, 180) 964 if(window.ONE_COLUMN_ON_MOBILE){ 965 if(window.innerWidth < 600){ 966 width = block.offsetWidth -100 967 } 968 } 969 new MiniMasonry({ 970 baseWidth: width, 971 gutter: 0, 972 container: `#block-${block.dataset.id} .gallery-item__wrapper--nocrop`, 973 surroundingGutter: false, 974 }) 975 } 976 977} 978 979if(block.querySelector('.gallery-item__wrapper--nocrop')){ 980 reloadMacy() 981 setTimeout(function(){ 982 reloadMacy() 983 }, 1000) 984} 985 986block.querySelectorAll('.gallery-item__img').forEach(function(item){ 987 988 item.onclick = function () { 989 var $root = item.parentElement; 990 var $current = item.parentElement; 991 992 if(!$modal){ 993 return 994 } 995 996 document.body.style.overflow = 'hidden' 997 document.documentElement.style.overflow = 'hidden' 998 999 1000 function sliderSlideLeft(){ 1001 var $prev = $current.previousElementSibling; 1002 if(!$prev){ 1003 $prev = $root.parentElement.children[$root.parentElement.children.length-1] 1004 } 1005 1006 $modal.querySelector('img').classList.add("transition") 1007 setTimeout(() => { 1008 $modal.querySelector('img').onload = function() { 1009 $modal.querySelector('img').classList.remove("transition") 1010 } 1011 $modal.querySelector('img').setAttribute('src', $prev.dataset.imgSrc) 1012 }, 300); 1013 1014 $modal.querySelector('.caption').innerText = $prev.dataset.caption 1015 $current = $prev; 1016 } 1017 1018 function sliderSlideRight(){ 1019 var $next = $current.nextElementSibling; 1020 if(!$next){ 1021 $next = $root.parentElement.children[0] 1022 } 1023 $modal.querySelector('img').classList.add("transition") 1024 setTimeout(() => { 1025 $modal.querySelector('img').onload = function() { 1026 $modal.querySelector('img').classList.remove("transition") 1027 } 1028 $modal.querySelector('img').setAttribute('src', $next.dataset.imgSrc) 1029 }, 300); 1030 1031 $modal.querySelector('.caption').innerText = $next.dataset.caption 1032 $current = $next; 1033 } 1034 1035 if($modal.querySelectorAll('.gallery-modal__leftarrow').length===0){ 1036 $modal.insertAdjacentHTML('beforeend', '<a class="gallery-modal__leftarrow">←</a>') 1037 $modal.insertAdjacentHTML('beforeend', '<a class="gallery-modal__rightarrow">→</a>') 1038 $modal.insertAdjacentHTML('beforeend', '<div class="gallery-modal__close">Close <span>✕</span></div>') 1039 } 1040 1041 document.body.appendChild($modal); 1042 1043 // force render so animations work 1044 var x = $modal.clientHeight; 1045 1046 $modal.classList.add('open') 1047 $modal.removeAttribute('hidden') 1048 1049 $modal.querySelector('img').setAttribute('src', $root.dataset.imgSrc); 1050 $modal.querySelector('.caption').innerText = $root.dataset.caption 1051 $modal.querySelector('.gallery-modal__close').onclick = sliderClose 1052 $modal.querySelector('.gallery-modal__leftarrow').onclick = sliderSlideLeft 1053 $modal.querySelector('.gallery-modal__rightarrow').onclick = sliderSlideRight 1054 1055 function sliderClose(){ 1056 $modal.querySelector('.gallery-modal__close').onclick = null 1057 $modal.classList.remove('open'); 1058 document.onkeyup = null 1059 document.body.style.overflow = 'initial' 1060 document.documentElement.style.overflow = 'initial' 1061 } 1062 1063 document.onkeyup = function(event) { 1064 switch (event.key) { 1065 case "Left": 1066 case "ArrowLeft": 1067 sliderSlideLeft() 1068 break; 1069 case "Right": 1070 case "ArrowRight": 1071 sliderSlideRight() 1072 break; 1073 case "Esc": 1074 case "Escape": 1075 sliderClose() 1076 break; 1077 } 1078 } 1079 1080 } 1081 1082}) 1083 1084 } 1085 1086 return { 1087 initialize: initialize, 1088 } 1089})()); 1090 1091journoPortfolio.registerBlock("Products", (function () { 1092 const type = "product"; 1093 1094 function initialize (block) { 1095 executeBlockCode(block); 1096 } 1097 1098 function executeBlockCode (block) { 1099 1100var $block = block; 1101var $articleBlock = $block.children[0]; 1102var $autoloader = $block.querySelector('.autoloader') 1103var $inputSearch = $block.querySelector('input.search') 1104var $selectOrder = $block.querySelector('.order-select') 1105var loading = false 1106 1107var $masonry = $block.querySelector('.masonry') 1108var $modal = $block.querySelector('.text-modal') 1109var $galleryModal = block.querySelector('.gallery-modal'); 1110 1111var loadingMacy = false 1112var mySwiper; 1113 1114if($block.querySelector('[data-layout=slideshow]')){ 1115 journoPortfolio.requireLibrary('swiper').then(function(){ 1116 if(block.querySelectorAll('.swiper-container').length){ 1117 var autoplay = false;
1118 if($articleBlock.hasAttribute('autoplay')){ 1119 autoplay = { 1120 delay: Number($articleBlock.dataset.autoplayDelay), 1121 disableOnInteraction: true, 1122 } 1123 } 1124 var spaceBetween = 30 1125 if($articleBlock.dataset.gutter === "none"){ 1126 spaceBetween = 0 1127 } 1128 if($articleBlock.dataset.gutter === "small"){ 1129 spaceBetween = 15 1130 } 1131 if($articleBlock.dataset.gutter === "medium"){ 1132 spaceBetween = 30 1133 } 1134 if($articleBlock.dataset.gutter === "large"){ 1135 spaceBetween = 50 1136 } 1137 1138 var loop = $articleBlock.hasAttribute('loop') 1139 if($articleBlock.querySelectorAll('article').length < Number($articleBlock.dataset.slidesPerView)){ 1140 loop = false 1141 } 1142 1143 var slidesPerView = Number($articleBlock.dataset.slidesPerView) 1144 1145 if(window.innerWidth < 700){ 1146 slidesPerView = 1 1147 } 1148 1149 mySwiper = new Swiper('#block-'+block.dataset.id+' .swiper-container', { 1150 direction: 'horizontal', 1151 loop: loop, 1152 autoHeight: false, 1153 autoplay: autoplay, 1154 spaceBetween: spaceBetween, 1155 slidesPerView: slidesPerView, 1156 paginationClickable: true, 1157 navigation: { 1158 nextEl: '.swiper-button-next', 1159 prevEl: '.swiper-button-prev', 1160 }, 1161 }); 1162 } 1163 }) 1164} 1165 1166 1167if($block.querySelector('.filters-show')){ 1168 $block.querySelector('.filters-show').onclick = function(){ 1169 $block.querySelector('.filters-show').nextElementSibling.classList.toggle('open') 1170 } 1171} 1172 1173var GUTTERS = { 1174 "none": 0, 1175 "small": 15, 1176 "medium": 30, 1177 "large": 50, 1178} 1179 1180function COLUMNS_TARGET(cols){ 1181 if(window.innerWidth < 600){ 1182 return $articleBlock.offsetWidth -100 1183 } 1184 var width = $articleBlock.offsetWidth -((Number(cols)-1)*GUTTERS[$articleBlock.dataset.gutter]) 1185 return Math.max((width / Number(cols)), 200) 1186} 1187 1188function bindProducts(){ 1189 $articleBlock.querySelectorAll('article').forEach(function ($article) { 1190 1191 if($article.querySelector('.product__select')){ 1192 $article.querySelector('.product__select').addEventListener('change', function(event){ 1193 var value = $article.querySelector('.product__select').value 1194 var price = $article.querySelector('.product__select').selectedOptions[0].dataset.price 1195 $article.querySelector('[data-cart-add]').dataset.variant = value 1196 $article.querySelector(['[data-price-display]']).innerText = price 1197 }) 1198 } 1199 1200 if($article.querySelector('[data-cart-checkout]')){ 1201 var $button = $article.querySelector('[data-cart-checkout]') 1202 $button.onclick = function(event){ 1203 event.preventDefault() 1204 1205 if(!$button.dataset || !$button.dataset.disabled){ 1206 $button.dataset.disabled = true 1207 $button.style.position = "relative" 1208 $button.innerHTML = '<span style="opacity: 0;">'+$article.querySelector('[data-cart-checkout]').innerText +'</span><span style="position: absolute;display: flex;justify-content: center;left: 0;top: 0;bottom: 0; right: 0;width: 100%;text-align: center;"><svg style="align-self: center;display: inline-block; fill: white; -webkit-animation: v-clipDelay 0.75s 0s infinite linear; animation: v-clipDelay 0.75s 0s infinite linear; -webkit-animation-fill-mode: both; animation-fill-mode: both;" xmlns="http://www.w3.org/2000/svg" height="24" width="24"><path d="M4 20v-2h2.75l-.4-.35q-1.3-1.15-1.825-2.625Q4 13.55 4 12.05q0-2.775 1.662-4.938Q7.325 4.95 10 4.25v2.1Q8.2 7 7.1 8.562 6 10.125 6 12.05q0 1.125.425 2.187Q6.85 15.3 7.75 16.2l.25.25V14h2v6Zm10-.25v-2.1q1.8-.65 2.9-2.212Q18 13.875 18 11.95q0-1.125-.425-2.188Q17.15 8.7 16.25 7.8L16 7.55V10h-2V4h6v2h-2.75l.4.35q1.225 1.225 1.788 2.662Q20 10.45 20 11.95q0 2.775-1.663 4.937Q16.675 19.05 14 19.75Z"/></svg></span>' 1209 1210 journoPortfolio.cart.checkoutProduct($article.querySelector('[data-cart-checkout]').dataset.variant) 1211 } 1212 } 1213 } 1214 1215 if($article.querySelector('[data-cart-add]')){ 1216 $article.querySelector('[data-cart-add]').onclick = function(event){ 1217 event.preventDefault() 1218 journoPortfolio.cart.addToCart($article.querySelector('[data-cart-add]').dataset.variant) 1219 } 1220 } 1221 1222 // if($article.querySelector('.product__inner')){ 1223 // $article.querySelector('.product__inner').onclick = function (event) { 1224 1225 // if(event.target.classList.contains('product__select')){ 1226 // event.preventDefault() 1227 // return 1228 // } 1229 1230 // // journoPortfolio.articleClick($article.dataset.id).then(function(){ 1231 1232 // // // do nothing 1233 // // }) 1234 // } 1235 // } 1236 }) 1237} 1238 1239function reloadMacy(){ 1240 if(!$masonry){ 1241 bindProducts() 1242 return 1243 } 1244 $masonry.classList.remove('animate') 1245 if(!window.MASONRY){ 1246 window.MASONRY = {} 1247 } 1248 1249 if(document.querySelector(`#block-${block.dataset.id} .masonry`)){ 1250 window.MASONRY[Number(block.dataset.id)] = new MiniMasonry({ 1251 baseWidth: COLUMNS_TARGET($articleBlock.dataset.columns), 1252 container: `#block-${block.dataset.id} .masonry`, 1253 surroundingGutter: false, 1254 gutter: GUTTERS[$articleBlock.dataset.gutter], 1255 }) 1256 1257 if(block.querySelectorAll('.dragging').length > 0){ 1258 $masonry.classList.add('animate') 1259 }else{ 1260 setTimeout(function(){ 1261 $masonry.classList.add('animate') 1262 }, 500) 1263 } 1264 } 1265 bindProducts() 1266} 1267 1268function autoLoaderClick(e){ 1269 loadNextPage(); 1270} 1271 1272function loadNextPage(){ 1273 $autoloader.innerText = 'Loading more...' 1274 1275 loadArticles($articleBlock.querySelectorAll('article').length) 1276} 1277 1278 1279function loadArticles(start_from) { 1280 if(loading){ 1281 return 1282 } 1283 loading = true; 1284 1285 var searchVal = '' 1286 var publicationVal = 'all' 1287 var tagsVal = 'all' 1288 var orderVal = $articleBlock.dataset.defaultOrder 1289 1290 if(typeof start_from !== "number"){ 1291 start_from = 0 1292 } 1293 1294 if($inputSearch){ 1295 searchVal = $inputSearch.value 1296 } 1297 if($selectOrder){ 1298 orderVal = $selectOrder.value 1299 } 1300 fetch("/api/v1/articles/?block="+block.dataset.id+"&order="+orderVal+"&start="+start_from+"&search="+searchVal) 1301 .then(response => response.text()) 1302 .then(data => { 1303 // this.$el.removeClass('loading') 1304 loading = false;
1305 1306 var countBefore = block.querySelectorAll('.products__wrapper article').length 1307 1308 if(start_from === 0){ 1309 countBefore = 0 1310 block.querySelector('.products__wrapper').innerHTML = data; 1311 }else{ 1312 block.querySelector('.products__wrapper').insertAdjacentHTML('beforeend', data) 1313 } 1314 1315 journoPortfolio.newContent(block.querySelector('.products__wrapper')) 1316 1317 var countAfter = block.querySelectorAll('.products__wrapper article').length 1318 1319 if($autoloader){ 1320 if(data == '' || (countAfter-countBefore) < 12 ){ 1321 $autoloader.style.display = 'none'; 1322 }else{ 1323 $autoloader.style.display = 'block'; 1324 $autoloader.innerText = 'Load More' 1325 } 1326 } 1327 1328 reloadMacy(); 1329 1330 block.dispatchEvent(new Event('ArticleAPILoad')) 1331 1332 }); 1333} 1334 1335if ("IntersectionObserver" in window) { 1336 if(!window.loadMoreObserver){ 1337 window.loadMoreObserver = {} 1338 }else{ 1339 if($block.dataset.id in window.loadMoreObserver){ 1340 window.loadMoreObserver[$block.dataset.id].disconnect() 1341 } 1342 } 1343 1344 window.loadMoreObserver[$block.dataset.id] = new IntersectionObserver(function(entries, observer) { 1345 entries.forEach(function(entry) { 1346 if (entry.isIntersecting) { 1347 autoLoaderClick() 1348 } 1349 }); 1350 }, {rootMargin: "0px 0px 300px 0px"}); 1351} 1352 1353if($autoloader){ 1354 $autoloader.onclick = autoLoaderClick 1355 1356 // If the last block in the last section load on page scroll 1357 if ($block.nextElementSibling === null){ 1358 1359 if ($block.parentNode.parentNode.parentNode.nextElementSibling === null){ 1360 if (!$block.parentNode.parentNode.parentNode.parentNode.classList.contains('widget-render')){ 1361 1362 1363 if ("IntersectionObserver" in window) { 1364 window.loadMoreObserver[$block.dataset.id].unobserve($autoloader); 1365 window.loadMoreObserver[$block.dataset.id].observe($autoloader); 1366 } 1367 } 1368 } 1369 } 1370} 1371 1372if($inputSearch){ 1373 $inputSearch.onblur = loadArticles 1374 $inputSearch.onkeyup = function(event) { 1375 if (event.keyCode === 13) { 1376 event.preventDefault(); 1377 loadArticles() 1378 } 1379 } 1380} 1381 1382if($selectOrder){ 1383 $selectOrder.onchange = loadArticles 1384} 1385 1386 1387loadingMacy = true 1388reloadMacy(); 1389setTimeout(function(){ 1390 reloadMacy(); 1391 loadingMacy = false 1392}, 500) 1393 1394 } 1395 1396 return { 1397 initialize: initialize, 1398 } 1399})()); 1400 1401journoPortfolio.registerBlock("Blog Post", (function () { 1402 const type = "blog-post"; 1403 1404 function initialize (block) { 1405 executeBlockCode(block); 1406 } 1407 1408 function executeBlockCode (block) { 1409 var loading = false; 1410 1411Promise.all([ 1412 journoPortfolio.requireLibrary("grecaptcha"), 1413 journoPortfolio.requireLibrary("axios"), 1414]).then(function(){ 1415 1416 var $modal = block.querySelector('.content-modal') 1417 1418 if(block.querySelector('#add-comment')){ 1419 block.querySelector('#add-comment').onclick = function(){ 1420 openModal() 1421 } 1422 } 1423 1424 function closeModal () { 1425 $modal.classList.remove('open') 1426 document.removeEventListener('keyup', escPress); 1427 } 1428 1429 function escPress (e) { 1430 if (e.key === "Escape") { 1431 closeModal() 1432 } 1433 } 1434 1435 function closePress (e) { 1436 closeModal(); 1437 } 1438 1439 function clickBg (e) { 1440 if (e.target === this){ 1441 closeModal() 1442 } 1443 } 1444 1445 function showGlobalError(errorMsg){ 1446 $modal.querySelector('.error-global').innerText = errorMsg 1447 $modal.querySelector('.error-global').style.display = 'block' 1448 } 1449 1450 function applyErrorToField(fieldName, errorMsg){ 1451 var $field = block.querySelector('#field_'+fieldName) 1452 $field.classList.add('error') 1453 if($field.querySelector('.error-msg')){ 1454 $field.querySelector('.error-msg').remove() 1455 } 1456 $field.children[1].insertAdjacentHTML( 'afterend', "<div class='error-msg'>"+errorMsg+"</div>"); 1457 } 1458 1459 function openModal () { 1460 document.body.appendChild($modal) 1461 1462 // force render so animations work 1463 var x = $modal.clientHeight; 1464 1465 $modal.classList.add('open') 1466 $modal.removeAttribute('hidden') 1467 1468 $modal.onclick = clickBg 1469 $modal.querySelector('.close').onclick = closePress 1470 document.addEventListener('keyup', escPress); 1471 1472 $modal.querySelector('#comment-form').onsubmit = function(e){ 1473 e.preventDefault() 1474 1475 loading = true 1476 $modal.querySelectorAll('input,textarea').forEach(function($el){ 1477 $el.parentElement.classList.remove('error') 1478 }) 1479 $modal.querySelector('button').classList.add('saving') 1480 1481 grecaptcha.ready(function() { 1482 grecaptcha.execute(window.PORTFOLIO_CAPTCHA_PUBLIC_KEY, {action: 'submit'}).then(function(token) { 1483 1484 var data = { 1485 name: $modal.querySelector('#comment_name').value, 1486 email: $modal.querySelector('#comment_email').value, 1487 content: $modal.querySelector('#comment_content').value, 1488 article: window.ARTICLE_ID, 1489 captcha_token: token 1490 } 1491 axios.post("/api/v1/comments/", data) 1492 .then(data => { 1493 closeModal() 1494 $modal.querySelector('#comment_name').value = '' 1495 $modal.querySelector('#comment_email').value = '' 1496 $modal.querySelector('#comment_content').value = '' 1497 var comment = data.data 1498 document.querySelector('.comments').insertAdjacentHTML('beforeend', `<div class="comment new" id="comment-${comment.id}"><small class="meta">Posted on ${comment.datetime} <a class="comment__permalink" href="${window.location.pathname}#comment-${comment.id}">Permalink</a></small><h3>
1498${comment.name}</h3>${comment.content_display}</div>`) 1499 1500 document.querySelector(`#comment-${comment.id}`).scrollIntoView({ 1501 behavior: 'smooth' 1502 }); 1503 }) 1504 .catch(error =>{ 1505 loading = false 1506 if (error.response) { 1507 if(error.response.status === 400){ 1508 errors = error.response.data; 1509 for(name in errors){ 1510 $modal.querySelector('[name='+name+']').parentElement.classList.add('error') 1511 $modal.querySelector('[name='+name+']').parentElement.querySelector('.field__error').innerHTML = errors[name][0] 1512 } 1513 console.log(error.response.data) 1514 } 1515 } else if (error.request) { 1516 console.log(error.request); 1517 } else { 1518 console.log('Error', error.message); 1519 } 1520 1521 }) 1522 }) 1523 }) 1524 } 1525 } 1526 1527}) 1528 1529 } 1530 1531 return { 1532 initialize: initialize, 1533 } 1534})()); 1535 1536journoPortfolio.registerBlock("Map", (function () { 1537 const type = "generic"; 1538 1539 function initialize (block) { 1540 executeBlockCode(block); 1541 } 1542 1543 function executeBlockCode (block) { 1544 journoPortfolio.requireLibrary("mapbox").then(function(){ 1545 var map_wrapper = block.querySelector('.map-wrapper'); 1546 1547 mapboxgl.accessToken = 'pk.eyJ1Ijoiam9zaGNhcmxsZXdpcyIsImEiOiJja2w4Y3Mxcm4wb2tlMnBucDQwZWVtNWY3In0.a-z6wpUPJ-tvhwZWREoLuQ'; 1548 var map = new mapboxgl.Map({ 1549 container: map_wrapper.querySelector('.map'), 1550 center: [parseFloat(map_wrapper.dataset.lng), parseFloat(map_wrapper.dataset.lat)], 1551 style: 'mapbox://styles/mapbox/'+map_wrapper.dataset.style, 1552 zoom: Number(map_wrapper.dataset.zoom), 1553 }); 1554 1555 if(map_wrapper.dataset.marker && map_wrapper.dataset.marker === "true"){ 1556 const marker = new mapboxgl.Marker() 1557 marker.setLngLat([parseFloat(map_wrapper.dataset.lng), parseFloat(map_wrapper.dataset.lat)]) 1558 marker.addTo(map); 1559 } 1560}) 1561 } 1562 1563 return { 1564 initialize: initialize, 1565 } 1566})()); 1567 1568journoPortfolio.registerBlock("Instagram", (function () { 1569 const type = "generic"; 1570 1571 function initialize (block) { 1572 executeBlockCode(block); 1573 } 1574 1575 function executeBlockCode (block) { 1576 1577 1578var $modal = block.querySelector('.content-modal'); 1579 1580function reloadMacy(){ 1581 if(document.querySelector(`#block-${block.dataset.id} .gallery-item__wrapper--nocrop`)){ 1582 var width = document.querySelector(`#block-${block.dataset.id} .gallery-item__wrapper--nocrop`).offsetWidth / Number(block.children[0].dataset.columns); 1583 width = Math.max(width-30, 180) 1584 new MiniMasonry({ 1585 baseWidth: width, 1586 gutter: 0, 1587 container: `#block-${block.dataset.id} .gallery-item__wrapper--nocrop`, 1588 surroundingGutter: false, 1589 }) 1590 } 1591 1592} 1593 1594if(block.querySelector('[data-layout=slideshow]')){ 1595 journoPortfolio.requireLibrary('swiper').then(function(){ 1596 var $slider = block.querySelector('.block-slideshow') 1597 if(block.querySelectorAll('.swiper-container').length){ 1598 var autoplay = false; 1599 if($slider.hasAttribute('autoplay')){ 1600 autoplay = { 1601 delay: Number($slider.dataset.autoplayDelay), 1602 disableOnInteraction: true, 1603 } 1604 } 1605 var spaceBetween = 30 1606 if($slider.dataset.spaceBetween === "none"){ 1607 spaceBetween = 0 1608 } 1609 if($slider.dataset.spaceBetween === "small"){ 1610 spaceBetween = 15 1611 } 1612 if($slider.dataset.spaceBetween === "medium"){ 1613 spaceBetween = 30 1614 } 1615 if($slider.dataset.spaceBetween === "large"){ 1616 spaceBetween = 50 1617 } 1618 var loop = $slider.hasAttribute('loop') 1619 if($slider.querySelectorAll('.swiper-slide').length < Number($slider.dataset.slidesPerView)){ 1620 loop = false 1621 } 1622 var mySwiper = new Swiper('#block-'+block.dataset.id+' .swiper-container', { 1623 direction: 'horizontal', 1624 loop: loop, 1625 autoHeight: true, 1626 autoplay: autoplay, 1627 spaceBetween: spaceBetween, 1628 slidesPerView: Number($slider.dataset.slidesPerView), 1629 paginationClickable: true, 1630 navigation: { 1631 nextEl: '.swiper-button-next', 1632 prevEl: '.swiper-button-prev', 1633 }, 1634 }); 1635 } 1636 }) 1637} 1638 1639block.querySelectorAll('.gallery-item__img').forEach(function(item){ 1640 1641 item.addEventListener('click', function() { 1642 var $root = item.parentElement; 1643 var $current = item.parentElement; 1644 1645 if(!$modal){ 1646 return 1647 } 1648 1649 document.body.style.overflow = 'hidden' 1650 document.documentElement.style.overflow = 'hidden' 1651 1652 1653 function sliderSlideLeft(){ 1654 var $prev = $current.previousElementSibling; 1655 if(!$prev){ 1656 $prev = $root.parentElement.children[$root.parentElement.children.length-1] 1657 } 1658 1659 $modal.querySelector('img').classList.add("transition") 1660 setTimeout(() => { 1661 $modal.querySelector('img').onload = function() { 1662 $modal.querySelector('img').classList.remove("transition") 1663 } 1664 $modal.querySelector('img').setAttribute('src', $prev.dataset.imgSrc) 1665 }, 300); 1666 1667 $modal.querySelector('.caption').innerText = $prev.dataset.caption 1668 $current = $prev; 1669 } 1670 1671 function sliderSlideRight(){ 1672 var $next = $current.nextElementSibling; 1673 if(!$next){ 1674 $next = $root.parentElement.children[0] 1675 } 1676 $modal.querySelector('img').classList.add("transition") 1677 setTimeout(() => { 1678 $modal.querySelector('img').onload = function() { 1679 $modal.querySelector('img').classList.remove("transition") 1680 } 1681 $modal.querySelector('img').setAttribute('src', $next.dataset.imgSrc) 1682 }, 300); 1683 1684 $modal.querySelector('.caption').innerText = $next.dataset.caption 1685 $current = $next; 1686 } 1687 1688 if($modal.querySelectorAll('.gallery-modal__leftarrow').length===0){ 1689 $modal.insertAdjacentHTML('beforeend', '<a class="gallery-modal__leftarrow">←</a>') 1690 $modal.insertAdjacentHTML('beforeend', '<a class="gallery-modal__rightarrow">→</a>') 1691 $modal.insertAdjacentHTML('beforeend', '<div class="gallery-modal__close">Close <span>✕</span></div>') 1692 } 1693 1694 document.body.appendChild($modal); 1695 1696 // force render so animations work 1697 var x = $modal.clientHeight; 1698 1699 $modal.classList.add('open') 1700 $modal.removeAttribute('hidden') 1701 1702 $modal.querySelector('img').setAttribute('src', $root.dataset.imgSrc); 1703 $modal.querySelector('.caption').innerText = $root.dataset.caption 1704 $modal.querySelector('.gallery-modal__close').onclick = sliderClose 1705 $modal.querySelector('.gallery-modal__leftarrow').onclick = sliderSlideLeft 1706 $modal.querySelector('.gallery-modal__rightarrow').onclick = sliderSlideRight 1707 1708 function sliderClose(){ 1709 $modal.querySelector('.gallery-modal__close').onclick = null 1710 $modal.classList.remove('open'); 1711 document.onkeyup = null 1712 document.body.style.overflow = 'initial' 1713 document.documentElement.style.overflow = 'initial' 1714 } 1715 1716 document.onkeyup = function(event) { 1717 switch (event.key) { 1718 case "Left": 1719 case "ArrowLeft": 1720 sliderSlideLeft() 1721 break; 1722 case "Right": 1723 case "ArrowRight": 1724 sliderSlideRight() 1725 break; 1726 case "Esc": 1727 case "Escape": 1728 sliderClose() 1729 break; 1730 } 1731 } 1732 1733 }) 1734 1735}) 1736 1737 } 1738 1739 return { 1740 initialize: initialize, 1741 } 1742})()); 1743 1744journoPortfolio.registerBlock("Video", (function () { 1745 const type = "generic"; 1746 1747 function initialize (block) { 1748 executeBlockCode(block); 1749 } 1750 1751 function executeBlockCode (block) { 1752 journoPortfolio.requireLibrary("mux-player").then(function(){ 1753 1754}) 1755 } 1756 1757 return { 1758 initialize: initialize, 1759 } 1760})()); 1761 1762journoPortfolio.registerBlock("Video Legacy", (function () { 1763 const type = "generic"; 1764 1765 function initialize (block) { 1766 executeBlockCode(block); 1767 } 1768 1769 function executeBlockCode (block) { 1770 journoPortfolio.requireLibrary("reframe").then(function(){ 1771 if(block.querySelector('iframe')){ 1772 reframe(block.querySelector('iframe')) 1773 } 1774}); 1775 1776 } 1777 1778 return { 1779 initialize: initialize, 1780 } 1781})()); 1782 1783journoPortfolio.registerBlock("Product Page", (function () { 1784 const type = "product-page"; 1785 1786 function initialize (block) { 1787 executeBlockCode(block); 1788 } 1789 1790 function executeBlockCode (block) { 1791 1792if(block.querySelector('.product__select')){ 1793 block.querySelector('.product__select').addEventListener('change', function(event){ 1794 var value = block.querySelector('.product__select').value 1795 var price = block.querySelector('.product__select').selectedOptions[0].dataset.price 1796 document.querySelector('[data-cart-add]').dataset.variant = value
1797 document.querySelector(['[data-price-display]']).innerText = price 1798 }) 1799} 1800 1801if(block.querySelector('[data-cart-add]')){ 1802 block.querySelector('[data-cart-add]').onclick = function(event){ 1803 event.preventDefault() 1804 journoPortfolio.cart.addToCart(block.querySelector('[data-cart-add]').dataset.variant) 1805 } 1806} 1807 1808journoPortfolio.requireLibrary('swiper').then(function(){ 1809 var $slider = block.querySelector('.block-slider') 1810 if(block.querySelectorAll('.swiper-container').length){ 1811 var mySwiper = new Swiper('#block-'+block.dataset.id+' .swiper-container', { 1812 direction: 'horizontal', 1813 loop: true, 1814 autoHeight: true, 1815 autoplay: false, 1816 spaceBetween: 30, 1817 slidesPerView: Number(1), 1818 paginationClickable: true, 1819 navigation: { 1820 nextEl: '.swiper-button-next', 1821 prevEl: '.swiper-button-prev', 1822 }, 1823 }); 1824 } 1825}) 1826 1827 } 1828 1829 return { 1830 initialize: initialize, 1831 } 1832})()); 1833 1834journoPortfolio.registerBlock("Audio", (function () { 1835 const type = "generic"; 1836 1837 function initialize (block) { 1838 executeBlockCode(block); 1839 } 1840 1841 function executeBlockCode (block) { 1842 journoPortfolio.requireLibrary("mux-player").then(function(){ 1843 1844}) 1845 } 1846 1847 return { 1848 initialize: initialize, 1849 } 1850})()); 1851 1852journoPortfolio.registerBlock("Articles", (function () { 1853 const type = "article"; 1854 1855 function initialize (block) { 1856 executeBlockCode(block); 1857 } 1858 1859 function executeBlockCode (block) { 1860 var $block = block; 1861var $articleBlock = $block.children[0]; 1862var $autoloader = $block.querySelector(".autoloader"); 1863var $inputSearch = $block.querySelector("input.search"); 1864var $selectPublication = $block.querySelector(".publication-select"); 1865var $selectTags = $block.querySelector(".tags-select"); 1866var $selectOrder = $block.querySelector(".order-select"); 1867var loading = false; 1868 1869var $masonry = $block.querySelector(".masonry"); 1870var $modal = $block.querySelector(".text-modal"); 1871var $galleryModal = $block.querySelector(".gallery-modal"); 1872 1873var loadingMacy = false; 1874var mySwiper; 1875 1876function addUrlParameter(name, value) { 1877 const currentUrl = new URL(window.location); 1878 currentUrl.searchParams.set(name, value); 1879 history.pushState({}, "", currentUrl); 1880} 1881 1882function removeUrlParameter(name) { 1883 let urlObject = new URL(window.location.href); 1884 urlObject.searchParams.delete(name); 1885 history.pushState({}, "", urlObject); 1886} 1887 1888if ($block.querySelector("[data-layout=slideshow]")) { 1889 journoPortfolio.requireLibrary("swiper").then(function () { 1890 if (block.querySelectorAll(".swiper-container").length) { 1891 var autoplay = false; 1892 if ($articleBlock.hasAttribute("autoplay")) { 1893 autoplay = { 1894 delay: Number($articleBlock.dataset.autoplayDelay), 1895 disableOnInteraction: true, 1896 }; 1897 } 1898 var spaceBetween = 30; 1899 if ($articleBlock.dataset.gutter === "none") { 1900 spaceBetween = 0; 1901 } 1902 if ($articleBlock.dataset.gutter === "small") { 1903 spaceBetween = 15; 1904 } 1905 if ($articleBlock.dataset.gutter === "medium") { 1906 spaceBetween = 30; 1907 } 1908 if ($articleBlock.dataset.gutter === "large") { 1909 spaceBetween = 50; 1910 } 1911 1912 var loop = $articleBlock.hasAttribute("loop"); 1913 if ( 1914 $articleBlock.querySelectorAll("article").length < 1915 Number($articleBlock.dataset.slidesPerView) 1916 ) { 1917 loop = false; 1918 } 1919 1920 var slidesPerView = Number($articleBlock.dataset.slidesPerView); 1921 1922 if (window.innerWidth < 700) { 1923 slidesPerView = 1; 1924 } 1925 1926 mySwiper = new Swiper( 1927 "#block-" + block.dataset.id + " .swiper-container", 1928 { 1929 direction: "horizontal", 1930 loop: loop, 1931 autoHeight: false, 1932 autoplay: autoplay, 1933 spaceBetween: spaceBetween, 1934 slidesPerView: slidesPerView, 1935 paginationClickable: true, 1936 navigation: { 1937 nextEl: ".swiper-button-next", 1938 prevEl: ".swiper-button-prev", 1939 }, 1940 }, 1941 ); 1942 } 1943 }); 1944} 1945 1946if ($block.querySelector(".filters-show")) { 1947 $block.querySelector(".filters-show").onclick = function () { 1948 $block 1949 .querySelector(".filters-show") 1950 .nextElementSibling.classList.toggle("open"); 1951 }; 1952} 1953 1954var GUTTERS = { 1955 none: 0, 1956 small: 15, 1957 medium: 30, 1958 large: 50, 1959}; 1960 1961function COLUMNS_TARGET(cols) { 1962 if (window.innerWidth < 600) { 1963 return $articleBlock.offsetWidth - 100; 1964 } 1965 var width = 1966 $articleBlock.offsetWidth - 1967 (Number(cols) - 1) * GUTTERS[$articleBlock.dataset.gutter]; 1968 return Math.max(width / Number(cols), 200); 1969} 1970 1971function openGallery(article) { 1972 var $root = article.parentElement; 1973 var $current = article; 1974 1975 if (mySwiper) { 1976 mySwiper.autoplay.pause(); 1977 console.log(mySwiper.autoplay.paused); 1978 } 1979 1980 if (!$galleryModal) { 1981 return; 1982 } 1983 1984 addParam(article.dataset.id); 1985 1986 document.body.style.overflow = "hidden"; 1987 document.documentElement.style.overflow = "hidden"; 1988 1989 function sliderSlideLeft() { 1990 if ($block.querySelector("[data-layout=slideshow]")) { 1991 if (!$current.parentElement.previousElementSibling) { 1992 var $sliderRoot = $current.parentElement.parentElement; 1993 var $prev = 1994 $sliderRoot.children[$sliderRoot.children.length - 1] 1995 .firstElementChild; 1996 } else { 1997 var $prev = 1998 $current.parentElement.previousElementSibling.firstElementChild; 1999 } 2000 } else { 2001 var $prev = $current.previousElementSibling; 2002 if (!$prev) { 2003 $prev = $root.children[$root.children.length - 1]; 2004 } 2005 } 2006 2007 $galleryModal.querySelector("img").classList.add("transition"); 2008 setTimeout(() => { 2009 $galleryModal.querySelector("img").onload = function () { 2010 $galleryModal.querySelector("img").classList.remove("transition"); 2011 }; 2012 $galleryModal 2013 .querySelector("img") 2014 .setAttribute("src", $prev.dataset.imgSrc); 2015 }, 300); 2016 2017 if ($galleryModal.querySelector(".caption")) { 2018 if ($prev.querySelector("[data-caption]")) { 2019 $galleryModal.querySelector(".caption").innerHTML = 2020 $prev.querySelector("[data-caption]").innerHTML; 2021 } else { 2022 $galleryModal.querySelector(".caption").innerHTML = ""; 2023 } 2024 } 2025 2026 $current = $prev; 2027 addParam($prev.dataset.id) 2028 } 2029 2030 function sliderSlideRight() { 2031 if ($block.querySelector("[data-layout=slideshow]")) { 2032 if (!$current.parentElement.nextElementSibling) { 2033 var $sliderRoot = $current.parentElement.parentElement; 2034 var $next = $sliderRoot.children[0].firstElementChild; 2035 } else { 2036 var $next = $current.parentElement.nextElementSibling.firstElementChild; 2037 } 2038 } else { 2039 var $next = $current.nextElementSibling; 2040 if (!$next) { 2041 $next = $root.children[0]; 2042 } 2043 } 2044 2045 $galleryModal.querySelector("img").classList.add("transition"); 2046 setTimeout(() => { 2047 $galleryModal.querySelector("img").onload = function () { 2048 $galleryModal.querySelector("img").classList.remove("transition"); 2049 }; 2050 $galleryModal 2051 .querySelector("img") 2052 .setAttribute("src", $next.dataset.imgSrc); 2053 }, 300); 2054 2055 if ($galleryModal.querySelector(".caption")) { 2056 if ($next.querySelector("[data-caption]")) { 2057 $galleryModal.querySelector(".caption").innerHTML = 2058 $next.querySelector("[data-caption]").innerHTML; 2059 } else { 2060 $galleryModal.querySelector(".caption").innerHTML = ""; 2061 } 2062 } 2063 2064 $current = $next; 2065 addParam($next.dataset.id) 2066 } 2067 2068 function sliderClose() { 2069 $galleryModal.querySelector(".gallery-modal__close").onclick = null; 2070 $galleryModal.classList.remove("open"); 2071 document.onkeyup = null; 2072 document.body.style.overflow = "initial"; 2073 document.documentElement.style.overflow = "initial"; 2074 addParam(null) 2075 } 2076 2077 let closeText = 'Close';
2078 if(document.querySelector('.content-modal .close')){ 2079 closeText = document.querySelector('.content-modal .close').innerHTML.split(' <')[0] 2080 } 2081 if ( 2082 $galleryModal.querySelectorAll(".gallery-modal__leftarrow").length === 0 2083 ) { 2084 $galleryModal.insertAdjacentHTML( 2085 "beforeend", 2086 '<a class="gallery-modal__leftarrow">←</a>', 2087 ); 2088 $galleryModal.insertAdjacentHTML( 2089 "beforeend", 2090 '<a class="gallery-modal__rightarrow">→</a>', 2091 ); 2092 $galleryModal.insertAdjacentHTML( 2093 "beforeend", 2094 '<div class="gallery-modal__close">'+closeText+' <span>✕</span></div>', 2095 ); 2096 } 2097 2098 document.body.appendChild($galleryModal); 2099 2100 // force render so animations work 2101 var x = $galleryModal.clientHeight; 2102 2103 $galleryModal.classList.add("open"); 2104 $galleryModal.removeAttribute("hidden"); 2105 2106 $galleryModal 2107 .querySelector("img") 2108 .setAttribute("src", article.dataset.imgSrc); 2109 2110 if ($galleryModal.querySelector(".caption")) { 2111 if (article.querySelector("[data-caption]")) { 2112 $galleryModal.querySelector(".caption").innerHTML = 2113 article.querySelector("[data-caption]").innerHTML; 2114 } else { 2115 $galleryModal.querySelector(".caption").innerHTML = ""; 2116 } 2117 } 2118 $galleryModal.querySelector(".gallery-modal__close").onclick = sliderClose; 2119 $galleryModal.querySelector(".gallery-modal__leftarrow").onclick = 2120 sliderSlideLeft; 2121 $galleryModal.querySelector(".gallery-modal__rightarrow").onclick = 2122 sliderSlideRight; 2123 2124 document.onkeyup = function (event) { 2125 switch (event.key) { 2126 case "Left": 2127 case "ArrowLeft": 2128 sliderSlideLeft(); 2129 break; 2130 case "Right": 2131 case "ArrowRight": 2132 sliderSlideRight(); 2133 break; 2134 case "Esc": 2135 case "Escape": 2136 sliderClose(); 2137 break; 2138 } 2139 }; 2140} 2141 2142function bindArticles() { 2143 $articleBlock.querySelectorAll("article").forEach(function ($article) { 2144 if ($article.querySelector(".article__inner")) { 2145 $article.querySelector(".article__inner").onclick = function (event) { 2146 console.log('click') 2147 journoPortfolio.articleClick($article.dataset.id).then(function () { 2148 // do nothing 2149 }); 2150 2151 if ( 2152 $article.classList.contains("article--modal") && 2153 !$article.querySelector("[data-caption]") 2154 ) { 2155 event.preventDefault(); 2156 openModal($article.dataset.id); 2157 return false; 2158 } else if ($article.dataset.type === "image") { 2159 event.preventDefault(); 2160 openGallery($article); 2161 return false; 2162 } 2163 }; 2164 } 2165 }); 2166} 2167 2168function reloadMacy() { 2169 if (!$masonry) { 2170 bindArticles(); 2171 return; 2172 } 2173 $masonry.classList.remove("animate"); 2174 if (!window.MASONRY) { 2175 window.MASONRY = {}; 2176 } 2177 2178 if (document.querySelector(`#block-${block.dataset.id} .masonry`)) { 2179 window.MASONRY[Number(block.dataset.id)] = new MiniMasonry({ 2180 baseWidth: COLUMNS_TARGET($articleBlock.dataset.columns), 2181 container: `#block-${block.dataset.id} .masonry`, 2182 surroundingGutter: false, 2183 gutter: GUTTERS[$articleBlock.dataset.gutter], 2184 }); 2185 2186 if (block.querySelectorAll(".dragging").length > 0) { 2187 $masonry.classList.add("animate"); 2188 } else { 2189 setTimeout(function () { 2190 $masonry.classList.add("animate"); 2191 }, 500); 2192 } 2193 } 2194 bindArticles(); 2195} 2196 2197function autoLoaderClick(e) { 2198 loadNextPage(); 2199} 2200 2201function loadNextPage() { 2202 $autoloader.innerText = "Loading more..."; 2203 2204 loadArticles($articleBlock.querySelectorAll("article").length); 2205} 2206 2207function escPress(e) { 2208 if (e.key === "Escape") { 2209 closeModal(); 2210 } 2211} 2212 2213function closePress(e) { 2214 closeModal(); 2215} 2216 2217function clickBg(e) { 2218 if (e.target === this) { 2219 closeModal(); 2220 } 2221} 2222 2223function closeModal() { 2224 document.documentElement.classList.remove("modal-open"); 2225 $modal.querySelector(".content-modal__content").innerHTML = ""; 2226 $modal.classList.remove("open"); 2227 document.removeEventListener("keyup", escPress); 2228 2229 addParam(null); 2230} 2231 2232function openModal(article_id) { 2233 if(document.documentElement.classList.contains("modal-open")){ 2234 return 2235 } 2236 console.log('openModal '+article_id) 2237 $modal = $modal.cloneNode(true); 2238 document.body.appendChild($modal); 2239 2240 addParam(article_id); 2241 2242 document.documentElement.classList.add("modal-open"); 2243 $modal.querySelector(".loading").style.display = "block"; 2244 2245 // force render so animations work 2246 var x = $modal.clientHeight; 2247 2248 $modal.classList.add("open"); 2249 $modal.removeAttribute("hidden"); 2250 2251 fetch( 2252 "/api/v1/articles/" + 2253 article_id + 2254 "/?template&language=" + 2255 document.documentElement.getAttribute("lang"), 2256 ) 2257 .then((response) => response.text()) 2258 .then((data) => { 2259 $modal.querySelector(".content-modal__content").innerHTML = data; 2260 if ($modal.querySelectorAll("mux-player").length > 0) { 2261 journoPortfolio.requireLibrary("mux-player").then(function () { 2262 // do nothing 2263 }); 2264 } 2265 2266 $modal.querySelector(".loading").style.display = "none"; 2267 2268 if ($modal.querySelector("script")) { 2269 var script = document.createElement("script"); 2270 script.onload = function () {}; 2271 script.src = $modal.querySelector("script").src; 2272 document.head.appendChild(script); 2273 } 2274 2275 if (window.instgrm && window.instgrm.Embeds) { 2276 window.instgrm.Embeds.process(); 2277 } 2278 2279 if ( 2280 $modal.querySelector("iframe") && 2281 !$modal.querySelector("iframe[data-nofitvids]") && 2282 $modal.querySelector("iframe").src.indexOf(".soundcloud.com") === -1 && 2283 $modal.querySelector("iframe").src.indexOf(".reverbnation.com") === 2284 -1 && 2285 $modal.querySelector("iframe").src.indexOf(".instagram.com") === -1 && 2286 $modal.querySelector("iframe").src.indexOf(".facebook.com") === -1 && 2287 $modal.querySelector("iframe").src.indexOf(".twitter.com") === -1 2288 ) { 2289 journoPortfolio.requireLibrary("reframe").then(function () { 2290 reframe($modal.querySelector("iframe"), 80); 2291 }); 2292 } 2293 }); 2294 2295 $modal.onclick = clickBg; 2296 $modal.querySelector(".close").onclick = closePress; 2297 document.addEventListener("keyup", escPress); 2298} 2299 2300function loadArticles(start_from) { 2301 if (loading) { 2302 return; 2303 } 2304 loading = true; 2305 2306 var searchVal = ""; 2307 var publicationVal = "all"; 2308 var tagsVal = "all"; 2309 var orderVal = $articleBlock.dataset.defaultOrder; 2310 2311 if (typeof start_from !== "number") { 2312 start_from = 0; 2313 } 2314 2315 if ($inputSearch) { 2316 searchVal = $inputSearch.value; 2317 if (searchVal && document.querySelectorAll(".search").length === 1) { 2318 addUrlParameter("q", searchVal); 2319 } else { 2320 removeUrlParameter("q"); 2321 } 2322 } 2323 if ($selectOrder) { 2324 orderVal = $selectOrder.value; 2325 if ( 2326 orderVal && 2327 document.querySelectorAll(".order-select").length === 1 && 2328 !$selectOrder.options[$selectOrder.selectedIndex].dataset.default 2329 ) { 2330 addUrlParameter("order", orderVal); 2331 } else { 2332 removeUrlParameter("order"); 2333 } 2334 } 2335 if ($selectPublication) { 2336 publicationVal = $selectPublication.value; 2337 if ( 2338 publicationVal && 2339 publicationVal != "all" && 2340 document.querySelectorAll(".publication-select").length === 1 2341 ) { 2342 var selectedOptionText = 2343 $selectPublication.options[$selectPublication.selectedIndex].text; 2344 addUrlParameter("publication", selectedOptionText); 2345 } else { 2346 removeUrlParameter("publication"); 2347 } 2348 } 2349 if ($selectTags) { 2350 tagsVal = $selectTags.value; 2351 if ( 2352 tagsVal && 2353 tagsVal != "all" && 2354 document.querySelectorAll(".tags-select").length === 1 2355 ) { 2356 addUrlParameter("tag", tagsVal); 2357 } else { 2358 removeUrlParameter("tag"); 2359 } 2360 } 2361 2362 fetch( 2363 "/api/v1/articles/?block=" + 2364 block.dataset.id + 2365 "&order=" + 2366 orderVal + 2367 "&publication=" + 2368 publicationVal + 2369 "&tag=" + 2370 encodeURIComponent(tagsVal) + 2371 "&start=" + 2372 start_from + 2373 "&search=" + 2374 encodeURIComponent(searchVal) + 2375 "&language=" + 2376 document.documentElement.getAttribute("lang"), 2377 ) 2378 .then((response) => response.text()) 2379 .then((data) => { 2380 // this.$el.removeClass('loading') 2381 loading = false;
2382 2383 var countBefore = block.querySelectorAll( 2384 ".articles__wrapper article", 2385 ).length; 2386 2387 if (start_from === 0) { 2388 countBefore = 0; 2389 block.querySelector(".articles__wrapper").innerHTML = data; 2390 } else { 2391 block 2392 .querySelector(".articles__wrapper") 2393 .insertAdjacentHTML("beforeend", data); 2394 } 2395 2396 journoPortfolio.newContent(block.querySelector(".articles__wrapper")); 2397 2398 var countAfter = block.querySelectorAll( 2399 ".articles__wrapper article", 2400 ).length; 2401 2402 if ($autoloader) { 2403 if (data == "" || countAfter - countBefore < 12) { 2404 $autoloader.style.display = "none"; 2405 } else { 2406 $autoloader.style.display = "block"; 2407 $autoloader.innerText = "Load More"; 2408 } 2409 } 2410 2411 reloadMacy(); 2412 2413 block.dispatchEvent(new Event("ArticleAPILoad")); 2414 }); 2415} 2416 2417if ("IntersectionObserver" in window && window.top == window.self) { 2418 if (!window.loadMoreObserver) { 2419 window.loadMoreObserver = {}; 2420 } else { 2421 if ($block.dataset.id in window.loadMoreObserver) { 2422 window.loadMoreObserver[$block.dataset.id].disconnect(); 2423 } 2424 } 2425 2426 window.loadMoreObserver[$block.dataset.id] = new IntersectionObserver( 2427 function (entries, observer) { 2428 entries.forEach(function (entry) { 2429 if (entry.isIntersecting) { 2430 autoLoaderClick(); 2431 } 2432 }); 2433 }, 2434 { rootMargin: "0px 0px 300px 0px" }, 2435 ); 2436} 2437 2438function addParam(param){ 2439 let url = new URL(window.location.href); 2440 url.searchParams.set('item', param); 2441 if(param == null){ 2442 url.searchParams.delete('item'); 2443 } 2444 window.history.pushState({}, '', url); 2445} 2446 2447setTimeout(()=>{ 2448 let url = new URL(window.location.href); 2449 let paramExists = url.searchParams.has('item'); 2450 2451 if (paramExists) { 2452 let articleID = url.searchParams.get('item'); 2453 let $article = $articleBlock.querySelector("#article_"+articleID) 2454 2455 console.log('trigger click') 2456 $article.querySelector(".article__inner").click(); 2457 2458 } 2459}, 1000) 2460 2461function onceFieldsLoaded() { 2462 if ( 2463 ($selectTags !== null && !$selectTags.dataset.loaded) || 2464 ($selectPublication !== null && !$selectPublication.dataset.loaded) 2465 ) { 2466 return; 2467 } 2468 const queryString = window.location.search; 2469 const urlParams = new URLSearchParams(queryString); 2470 2471 let changed = false; 2472 2473 if ($selectPublication) { 2474 if (document.querySelectorAll(".publication-select").length === 1) { 2475 const pubValue = urlParams.get("publication"); 2476 if (pubValue) { 2477 for (var i = 0; i < $selectPublication.options.length; i++) { 2478 if ($selectPublication.options[i].text === pubValue) { 2479 $selectPublication.value = $selectPublication.options[i].value; 2480 changed = true; 2481 break; 2482 } 2483 } 2484 } 2485 } 2486 } 2487 2488 if ($selectTags) { 2489 if (document.querySelectorAll(".tags-select").length === 1) { 2490 const tagValue = urlParams.get("tag"); 2491 if (tagValue) { 2492 for (var i = 0; i < $selectTags.options.length; i++) { 2493 if ($selectTags.options[i].value === tagValue) { 2494 $selectTags.value = tagValue; 2495 changed = true; 2496 break; 2497 } 2498 } 2499 } 2500 } 2501 } 2502 2503 if ($selectOrder) { 2504 if (document.querySelectorAll(".order-select").length === 1) { 2505 const orderVal = urlParams.get("order"); 2506 if (orderVal) { 2507 for (var i = 0; i < $selectOrder.options.length; i++) { 2508 if ($selectOrder.options[i].value === orderVal) { 2509 $selectOrder.value = orderVal; 2510 changed = true; 2511 break; 2512 } 2513 } 2514 } 2515 } 2516 } 2517 2518 if ($inputSearch) { 2519 if (document.querySelectorAll(".search").length === 1) { 2520 const searchVal = urlParams.get("q"); 2521 if (searchVal) { 2522 $inputSearch.value = searchVal; 2523 changed = true 2524 } 2525 } 2526 } 2527 2528 if (changed && !$block.dataset.loaded){ 2529 $block.dataset.loaded = true 2530 loadArticles(); 2531 } 2532} 2533 2534if ($autoloader) { 2535 $autoloader.onclick = autoLoaderClick; 2536 2537 // If the last block in the last section load on page scroll 2538 if ($block.nextElementSibling === null) { 2539 if ($block.parentNode.parentNode.parentNode.nextElementSibling === null) { 2540 if ( 2541 !$block.parentNode.parentNode.parentNode.parentNode.classList.contains( 2542 "widget-render", 2543 ) 2544 ) { 2545 if ("IntersectionObserver" in window && window.top == window.self) { 2546 window.loadMoreObserver[$block.dataset.id].unobserve($autoloader); 2547 window.loadMoreObserver[$block.dataset.id].observe($autoloader); 2548 } 2549 } 2550 } 2551 } 2552} 2553 2554if ($inputSearch) { 2555 $inputSearch.onblur = loadArticles; 2556 $inputSearch.onkeyup = function (event) { 2557 if (event.keyCode === 13) { 2558 event.preventDefault(); 2559 loadArticles(); 2560 } 2561 }; 2562} 2563 2564if ($selectOrder) { 2565 $selectOrder.onchange = loadArticles; 2566} 2567 2568if ($selectTags) { 2569 $selectTags.onchange = loadArticles; 2570 2571 if (!isNaN($block.dataset.id)) { 2572 fetch("/api/v1/tags/?block=" + $block.dataset.id) 2573 .then((response) => response.json()) 2574 .then((data) => { 2575 $selectTags.innerHTML = 2576 '<option value="all" selected>All Tags</option>'; 2577 for (var i = 0; i < data.length; i++) { 2578 var tag = data[i]; 2579 var option = document.createElement("option"); 2580 option.text = tag; 2581 option.value = tag; 2582 $selectTags.appendChild(option); 2583 } 2584 $selectTags.dataset.loaded = true; 2585 onceFieldsLoaded(); 2586 }); 2587 } 2588} else { 2589 onceFieldsLoaded(); 2590} 2591 2592if ($selectPublication) { 2593 $selectPublication.onchange = loadArticles; 2594 2595 if (!isNaN($block.dataset.id)) { 2596 var $emptyOption = $selectPublication.querySelectorAll("option")[0]; 2597 2598 fetch("/api/v1/publications/?block=" + $block.dataset.id) 2599 .then((response) => response.json()) 2600 .then((data) => { 2601 $selectPublication.innerHTML = ""; 2602 $selectPublication.appendChild($emptyOption); 2603 for (var i = 0; i < data.length; i++) { 2604 var pub = data[i]; 2605 var option = document.createElement("option"); 2606 option.text = pub.name; 2607 option.value = pub.id; 2608 $selectPublication.appendChild(option); 2609 } 2610 2611 $selectPublication.dataset.loaded = true; 2612 2613 onceFieldsLoaded(); 2614 }); 2615 } 2616} else { 2617 onceFieldsLoaded(); 2618} 2619 2620loadingMacy = true; 2621reloadMacy(); 2622setTimeout(function () { 2623 reloadMacy(); 2624 loadingMacy = false;
2625}, 500); 2626 2627 } 2628 2629 return { 2630 initialize: initialize, 2631 } 2632})()); 2633 2634journoPortfolio.registerBlock("Navigation Sidebar", (function () { 2635 const type = "navigation"; 2636 2637 function initialize (block) { 2638 executeBlockCode(block); 2639 } 2640 2641 function executeBlockCode (block) { 2642 2643block.querySelectorAll('.menu ul li a').forEach(function(item){ 2644 item.onclick = function (e){ 2645 var href = item.getAttribute("href") 2646 if(href.startsWith('/#') && window.location.pathname === '/'){ 2647 e.preventDefault() 2648 var el = document.getElementById(href.replace('/#', '')) 2649 var y = el.getBoundingClientRect().top + window.pageYOffset 2650 2651 window.scrollTo({top: y, behavior: 'smooth'}); 2652 } 2653 }; 2654}) 2655 2656journoPortfolio.cart.init() 2657 } 2658 2659 return { 2660 initialize: initialize, 2661 } 2662})()); 2663 2664journoPortfolio.registerBlock("Contact Form", (function () { 2665 const type = "generic"; 2666 2667 function initialize (block) { 2668 executeBlockCode(block); 2669 } 2670 2671 function executeBlockCode (block) { 2672 var $modal = block.querySelector('.content-modal') 2673if($modal){ 2674 var $form = $modal; 2675}else{ 2676 var $form = block; 2677} 2678 2679function escPress (e) { 2680 if (e.key === "Escape") { 2681 closeModal() 2682 } 2683} 2684 2685function closePress (e) { 2686 closeModal(); 2687} 2688 2689function clickBg (e) { 2690 if (e.target === this){ 2691 closeModal() 2692 } 2693} 2694 2695function closeModal () { 2696 $modal.classList.remove('open') 2697 document.removeEventListener('keyup', escPress); 2698} 2699 2700function openModal () { 2701 document.body.appendChild($modal) 2702 2703 // force render so animations work 2704 var x = $modal.clientHeight; 2705 2706 $modal.classList.add('open') 2707 $modal.removeAttribute('hidden') 2708 2709 $modal.onclick = clickBg 2710 $modal.querySelector('.close').onclick = closePress 2711 document.addEventListener('keyup', escPress); 2712} 2713 2714if(block.querySelector('.open-contact-form')){ 2715 block.querySelector('.open-contact-form').onclick = function(){ 2716 openModal() 2717 } 2718} 2719 2720Promise.all([ 2721 journoPortfolio.requireLibrary("grecaptcha"), 2722 journoPortfolio.requireLibrary("axios"), 2723]).then(function(){ 2724 2725 var loading = false 2726 if(!block.querySelector('form')){ 2727 return 2728 } 2729 block.querySelector('form').onsubmit = function(e){ 2730 e.preventDefault(); 2731 2732 if(loading){ 2733 return 2734 } 2735 2736 loading = true 2737 $form.querySelectorAll('input,textarea').forEach(function($el){ 2738 $el.parentElement.classList.remove('error') 2739 }) 2740 $form.querySelector('button[data-save-button]').classList.add('saving') 2741 2742 grecaptcha.ready(function() { 2743 grecaptcha.execute(window.PORTFOLIO_CAPTCHA_PUBLIC_KEY, {action: 'submit'}).then(function(token) { 2744 2745 var data = { 2746 email: $form.querySelector('input[name=email]').value, 2747 block: Number(block.dataset.id), 2748 message: $form.querySelector('textarea[name=message]').value, 2749 captcha_token: token 2750 } 2751 if($form.querySelector('input[name=name]')){ 2752 data.name = $form.querySelector('input[name=name]').value; 2753 } 2754 if($form.querySelector('input[name=phone]')){ 2755 data.phone = $form.querySelector('input[name=phone]').value; 2756 } 2757 axios.post('/api/v1/message/', data) 2758 .then(function(data){ 2759 var $form1 = $form.querySelector('form') 2760 var $success = $form.querySelector('.success-message') 2761 $success.style.height = $form1.offsetHeight + 'px' 2762 $success.style.width = $form1.offsetWidth + 'px' 2763 $success.style.display = 'block' 2764 $form1.remove() 2765 2766 2767 if(typeof journoPortfolio.onContactFormSuccess === 'function') { 2768 journoPortfolio.onContactFormSuccess(Number(block.dataset.id)) 2769 } 2770 }) 2771 .catch(function(error){ 2772 if (error.response) { 2773 if(error.response.status === 400){ 2774 errors = error.response.data; 2775 for(name in errors){ 2776 $form.querySelector('[name='+name+']').parentElement.classList.add('error') 2777 $form.querySelector('[name='+name+']').parentElement.querySelector('.field__error').innerHTML = errors[name][0] 2778 } 2779 console.log(error.response.data) 2780 } 2781 } else if (error.request) { 2782 console.log(error.request); 2783 } else { 2784 console.log('Error', error.message); 2785 } 2786 }) 2787 .finally(function(){ 2788 loading = false 2789 if($form.querySelector('button[data-save-button]')){ 2790 $form.querySelector('button[data-save-button]').classList.remove('saving') 2791 } 2792 }) 2793 }) 2794 2795 }); 2796 } 2797}); 2798 2799 } 2800 2801 return { 2802 initialize: initialize, 2803 } 2804})()); 2805journoPortfolio.init(); 2806 2807 2808journoPortfolio.cart = (function () { 2809 var cartData = null; 2810 var hasStore = false 2811 2812 var $cart = document.querySelector('#cart') 2813 var $modal = document.querySelector('.cart-modal') 2814 2815 function escPress (e) { 2816 if (e.key === "Escape") { 2817 closeModal() 2818 } 2819 } 2820 2821 function closePress (e) { 2822 closeModal(); 2823 } 2824 2825 function clickBg (e) { 2826 if (e.target === this){ 2827 closeModal() 2828 } 2829 } 2830 2831 function closeModal () { 2832 $modal.style.display = 'none' 2833 document.removeEventListener('keyup', escPress); 2834 } 2835 2836 function updateShippingAddressState(){ 2837 if(document.getElementById('requires-shipping-country').value in cartData.countries_needing_states){ 2838 2839 var currentValue = document.getElementById('requires-shipping-state').value 2840 document.getElementById('requires-shipping-state-field').style.display = 'block' 2841 document.getElementById('requires-shipping-state').innerHTML = "" 2842 2843 var options = cartData.countries_needing_states[document.getElementById('requires-shipping-country').value] 2844 for(var i=0;i<options.length;i++){ 2845 var option = document.createElement("option"); 2846 option.text = options[i].name; 2847 option.value = options[i].value; 2848 document.getElementById('requires-shipping-state').appendChild(option); 2849 } 2850 2851 if(currentValue){ 2852 document.getElementById('requires-shipping-state').value = currentValue 2853 } 2854 }else{ 2855 document.getElementById('requires-shipping-state-field').style.display = 'none' 2856 document.getElementById('requires-shipping-state').innerHTML = "" 2857 document.getElementById('requires-shipping-state').value = null 2858 } 2859 } 2860 2861 function renableCheckoutButtons() { 2862 document.querySelector('.cart-modal__inner .button').classList.remove('saving') 2863 document.querySelector('#cart .button').classList.remove('saving') 2864 } 2865 2866 function disableCheckoutButtons() { 2867 if(document.querySelector('.cart-modal__inner .button')){ 2868 document.querySelector('.cart-modal__inner .button').classList.add('saving') 2869 } 2870 if(document.querySelector('#cart .button')){ 2871 document.querySelector('#cart .button').classList.add('saving') 2872 } 2873 } 2874 2875 function doCheckout(){ 2876 disableCheckoutButtons() 2877 2878 var countryValue = document.getElementById('requires-shipping-country').value 2879 var stateValue = document.getElementById('requires-shipping-state').value 2880 2881 axios.post('/api/v1/cart/checkout/', {url: window.location.pathname, country: countryValue, state: stateValue}).then(function(result){ 2882 if(result.data && result.data.url){ 2883 window.location = result.data.url 2884 }else{ 2885 renableCheckoutButtons() 2886 } 2887 }).catch(function(error){ 2888 2889 closeModal() 2890 renableCheckoutButtons() 2891 2892 if(error.response && error.response.status==400){ 2893 if(error.response.data && error.response.data.error){ 2894 return loadCart(error.response.data.error) 2895 } 2896 } 2897 return loadCart("other") 2898 }) 2899 } 2900 2901 function cartCheckoutClick(){ 2902 if(document.querySelector('.cart-modal__inner .button').classList.contains('saving')){ 2903 return 2904 } 2905 doCheckout() 2906 } 2907 2908 function openModal () { 2909 $modal.style.display = 'flex' 2910 2911 document.getElementById('requires-shipping-country').innerHTML = '' 2912 2913 for(var i=0;i<cartData.countries.length;i++){ 2914 var option = document.createElement("option"); 2915 option.text = cartData.countries[i].name; 2916 option.value = cartData.countries[i].value; 2917 if(cartData.countries[i].value === cartData.shipping_address_country){ 2918 option.selected = true 2919 } 2920 document.getElementById('requires-shipping-country').appendChild(option); 2921 } 2922 2923 updateShippingAddressState() 2924 2925 $modal.onclick = clickBg 2926 document.querySelector('.cart-modal__inner .button').onclick = cartCheckoutClick 2927 document.getElementById('requires-shipping-country').onchange = updateShippingAddressState 2928 document.querySelector('.cart-modal .close').onclick = closePress 2929 document.addEventListener('keyup', escPress); 2930 } 2931 2932 function _addToCart(variant_id){ 2933 disableCheckoutButtons() 2934 2935 axios.post('/api/v1/cart/add/', {variant: variant_id}).then(function(result){ 2936 cartData = result.data 2937 renderCart(false) 2938 renableCheckoutButtons() 2939 }).catch(function(error){ 2940 console.log(error) 2941 renableCheckoutButtons() 2942 if(error.response && error.response.status==400){ 2943 if(error.response.data && error.response.data.error){ 2944 return loadCart(error.response.data.error) 2945 } 2946 } 2947 return loadCart("other") 2948 }) 2949 } 2950 2951 function addToCart(variant_id){ 2952 if(!hasStore){ 2953 alert("This site does not have checkout enabled. If you are the site owner you can enable the cart and checkout under 'Settings' -> 'Store'") 2954 } 2955 2956 _addToCart(variant_id) 2957 openCart() 2958 } 2959 2960 function checkoutProduct(variant_id){ 2961 if(!hasStore){ 2962 alert("This site does not have checkout enabled. If you are the site owner you can enable the cart and checkout under 'Settings' -> 'Store'") 2963 } 2964 2965 axios.post('/api/v1/cart/add/', {variant: variant_id}).then(function(result){ 2966 cartData = result.data 2967 renderCart(false) 2968 doCheckout() 2969 }).catch(function(error){ 2970 console.log(error) 2971 openCart() 2972 renableCheckoutButtons() 2973 if(error.response && error.response.status==400){ 2974 if(error.response.data && error.response.data.error){ 2975 return loadCart(error.response.data.error) 2976 } 2977 } 2978 return loadCart("other") 2979 }) 2980 } 2981 2982 function _removeFromCart(variant_id){ 2983 disableCheckoutButtons() 2984 axios.post('/api/v1/cart/remove/', {variant: variant_id}).then(function(result){ 2985 cartData = result.data 2986 renderCart(false) 2987 renableCheckoutButtons() 2988 }).catch(function(error){ 2989 console.log(error) 2990 renableCheckoutButtons() 2991 if(error.response && error.response.status==400){ 2992 if(error.response.data && error.response.data.error){ 2993 return loadCart(error.response.data.error) 2994 } 2995 } 2996 return loadCart("other") 2997 }) 2998 } 2999 3000 function bindCartEvents() { 3001 3002 document.querySelectorAll('#cart .minus-btn').forEach(($el) => { 3003 $el.onclick = function(e){ 3004 var input = $el.parentElement.querySelector('input') 3005 if(Number(input.value) > 0){ 3006 input.value = Number(input.value) - 1 3007 } 3008 _removeFromCart($el.parentElement.parentElement.parentElement.dataset.variant) 3009 } 3010 }) 3011 3012 document.querySelectorAll('#cart .plus-btn').forEach(($el) => { 3013 $el.onclick = function(e){ 3014 var input = $el.parentElement.querySelector('input') 3015 input.value = Number(input.value) + 1 3016 3017 _addToCart($el.parentElement.parentElement.parentElement.dataset.variant) 3018 } 3019 }) 3020 3021 } 3022 3023 function getCartCount(argument) { 3024 var qty = 0; 3025 for(var i=0;i<cartData.line_items.length;i++){ 3026 qty += cartData.line_items[i].quantity 3027 } 3028 return qty 3029 } 3030 3031 function renderLineItem(line_item){ 3032 var $product = document.getElementById('cart-line-item-template').cloneNode(true) 3033 $product.removeAttribute('id') 3034 $product.dataset.variant = line_item.variant.id 3035 if(line_item.variant.name === "Default"){ 3036 $product.querySelector('.variant').style.display = 'none' 3037 }else{ 3038 $product.querySelector('.variant').style.display = 'inline-block' 3039 $product.querySelector('[data-variant-name]').innerText = line_item.variant.name 3040 } 3041 3042 if(line_item.variant.product.primary_image){ 3043 var img = document.createElement("img"); 3044 img.setAttribute("src", line_item.variant.product.primary_image.small) 3045 $product.querySelector('.img-placeholder').parentNode.insertBefore(img, $product.querySelector('.img-placeholder').nextSibling); 3046 $product.querySelector('.img-placeholder').remove() 3047 }else{ 3048 $product.querySelector('img').remove() 3049 } 3050 3051 $product.querySelector('h3').innerText = line_item.variant.product.name 3052 $product.querySelector('.price').innerText = cartData.currency_symbol + line_item.variant.price + ' each' 3053 $product.querySelector('.total').innerText = cartData.currency_symbol + line_item.total 3054 $product.querySelector('.quantity input').value = line_item.quantity 3055 3056 return $product 3057 } 3058
3059 function renderShippingMessage(){ 3060 document.querySelector('.shipping-taxes').style.display = "none" 3061 document.querySelector('.shipping').style.display = "none" 3062 document.querySelector('.taxes').style.display = "none" 3063 3064 if(cartData.taxes_enabled && cartData.requires_shipping){ 3065 document.querySelector('.shipping-taxes').style.display = "block" 3066 }else if(cartData.requires_shipping){ 3067 document.querySelector('.shipping').style.display = "block" 3068 }else if(cartData.taxes_enabled){ 3069 document.querySelector('.taxes').style.display = "block" 3070 } 3071 } 3072 3073 3074 function renderCart(error){ 3075 document.querySelector('#cart .v-spinner').style.display = 'none' 3076 3077 document.querySelectorAll('[data-cart-count]').forEach(($el) => { 3078 $el.innerText = getCartCount() 3079 }) 3080 3081 if(cartData.line_items.length == 0){ 3082 document.querySelector('.cart__empty').style.display = 'block' 3083 }else{ 3084 document.querySelector('.cart__empty').style.display = 'none' 3085 } 3086 3087 var cart_items = document.querySelector('#cart .cart__items'); 3088 cart_items.innerHTML = '' 3089 3090 for(var i=0; i<cartData.line_items.length; i++){ 3091 var product = renderLineItem(cartData.line_items[i]) 3092 cart_items.appendChild(product) 3093 } 3094 3095 document.querySelector('.cart__bottom .price').innerText = cartData.currency_symbol + cartData.total 3096 3097 renderShippingMessage() 3098 3099 renderCartError(error || cartData.error) 3100 bindCartEvents() 3101 } 3102 3103 function renderCartError(error){ 3104 document.querySelectorAll('.cart__error').forEach(function($el){ 3105 $el.style.display = 'none' 3106 }) 3107 3108 if(error){ 3109 try{ 3110 if(document.querySelector('.cart__error-'+error)){ 3111 document.querySelector('.cart__error-'+error).style.display = 'block' 3112 }else{ 3113 document.querySelector('.cart__error-custom').style.display = 'block' 3114 document.querySelector('.cart__error-custom span').innerText = error 3115 } 3116 }catch(error1){ 3117 document.querySelector('.cart__error-custom').style.display = 'block' 3118 document.querySelector('.cart__error-custom span').innerText = error 3119 } 3120 } 3121 } 3122 3123 function loadCart(error) { 3124 axios.get('/api/v1/cart/').then(function(result){ 3125 cartData = result.data 3126 renderCart(error) 3127 }) 3128 } 3129 3130 function outsideClickListener (event) { 3131 if (!$modal.contains(event.target) && !("cartAdd" in event.target.dataset) && !$cart.contains(event.target) && $cart.classList.contains("open")) { 3132 closeCart() 3133 } 3134 } 3135 3136 function openCart(){ 3137 if(!$cart.classList.contains("open")){ 3138 $cart.classList.add("open"); 3139 3140 setTimeout(function(){ 3141 document.querySelector('#cart #close').addEventListener('click', closeCart) 3142 document.addEventListener('click', outsideClickListener); 3143 }, 50) 3144 } 3145 } 3146 3147 function closeCart(){ 3148 $cart.classList.remove("open"); 3149 document.querySelector('#cart #close').removeEventListener('click', closeCart) 3150 document.removeEventListener('click', outsideClickListener) 3151 } 3152 3153 function init() { 3154 $cart = document.querySelector('#cart') 3155 $modal = document.querySelector('.cart-modal') 3156 3157 if($cart){ 3158 hasStore = true 3159 journoPortfolio.requireLibrary("axios").then(function(){ 3160 loadCart(null) 3161 3162 document.querySelectorAll('[data-cart-open]').forEach(function($el){ 3163 $el.onclick = function (){ 3164 openCart() 3165 }; 3166 }) 3167 3168 document.querySelectorAll('[data-checkout]').forEach(($el)=>{ 3169 $el.onclick = function (e) { 3170 e.preventDefault() 3171 3172 if($el.classList.contains('saving')){ 3173 return 3174 } 3175 3176 if(!cartData){ 3177 return 3178 } 3179 3180 if(cartData.requires_country){ 3181 openModal() 3182 return 3183 } 3184 3185 doCheckout() 3186 } 3187 }) 3188 }) 3189 } 3190 } 3191 3192 return { 3193 checkoutProduct: checkoutProduct, 3194 addToCart: addToCart, 3195 init: init, 3196 } 3197})();
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.