1document.addEventListener( 2 "DOMContentLoaded", () => { 3 4 let mobileCtaButton = document.querySelector('.mobile-cta-button'); 5 console.log(mobileCtaButton); 6 const mmenu = new Mmenu("#mmenu", { 7 navbars: [ 8 { 9 position: "bottom", 10 content: [ 11 mobileCtaButton?.outerHTML 12 ] 13 } 14 ], 15 // options 16 offCanvas: { 17 position: "right" 18 } 19 }, { 20 // configuration 21 offCanvas: { 22 page: { 23 nodetype: "section", 24 selector: ".page-wrapper" 25 } 26 } 27 }); 28 29 const menuButton = document.querySelector('.menu-button'); 30 const menuAPI = mmenu.API; 31 32 // instead of using click event and having to track whether the menu is open or not to change click behaviour simply change the href of the menu button to the ID of the page wrapper 33 menuAPI.bind('open:after', function () { 34 menuButton.setAttribute('href', '#pageTop'); 35 }); 36 37 menuAPI.bind('close:after', function () { 38 menuButton.setAttribute('href', '#mmenu'); 39 }); 40 41 // Header Code 42 var lastScrollTop = 0; 43 // element should be replaced with the actual target element on which you have applied scroll, use window in case of no target element. 44 window.addEventListener("scroll", function () { // or window.addEventListener("scroll".... 45 46 // Code to deal with scrolling near the top 47 if (scrollY > 100) { 48 document.body.classList.add('lost-head'); 49 } else { 50 document.body.classList.remove('lost-head'); 51 } 52 53 // Code to deal with scrolling up/down for the header 54 var st = window.pageYOffset || document.documentElement.scrollTop; // Credits: "https://github.com/qeremy/so/blob/master/so.dom.js#L426" 55 if (st > lastScrollTop) { 56 // downscroll code 57 if (scrollY > 200) { 58 document.body.classList.add('force-hide'); 59 } 60 } else if (st < lastScrollTop) { 61 // upscroll code 62 document.body.classList.remove('force-hide'); 63 } // else was horizontal scroll 64 lastScrollTop = st <= 0 ? 0 : st; // For Mobile or negative scrolling 65 }, false); 66 67 let anchorlinks = document.querySelectorAll('.page-content a[href^="#"]'); 68 anchorlinks.forEach(el => el.addEventListener('click', event => { 69 event.preventDefault(); 70 71 var elementValue = el.getAttribute('href'); 72 if (elementValue != '#') { 73 elementValue = elementValue.replace('#', ''); 74 var scrollElement = document.getElementById(elementValue); 75 scrollElement.scrollIntoView({ behavior: "smooth", block: "start" }); 76 } 77 })); 78 79 let videoPlayButtons = document.querySelectorAll(".video-play-trigger"); 80 videoPlayButtons.forEach(videoPlayButton => { 81 videoPlayButton.addEventListener('click', (event) => { 82 event.preventDefault(); 83 84 // Stops it scrolling back to the top 85 /*const popupScroll = window.scrollY; 86 document.body.style.top = '-' + popupScroll + 'px'; 87 document.body.style.position = 'fixed';*/ 88 89 // Get the popup content 90 var videoContent = videoPlayButton.querySelector('.video-popup-content code'); 91 92 // Copy the content to the popup 93 document.querySelector('.site-popup-content').innerHTML = unescapeHTML(videoContent.textContent); // We use text because html brings back the non-html version 94 95 // Activate the popup 96 document.querySelector('.site-popup').classList.add('active'); 97 document.querySelector('.site-popup').classList.add('video-only'); 98 document.querySelector('body').classList.add('popup-active'); 99 }); 100 }); 101 102 let popupCloseButtons = document.querySelectorAll(".site-popup-overlay, .site-popup-close"); 103 popupCloseButtons.forEach(popupCloseButton => { 104 popupCloseButton.addEventListener('click', () => { 105 106 // Remove the active state 107 document.querySelector('.site-popup').classList.remove('active'); 108 document.querySelector('body').classList.remove('popup-active'); 109 110 // Make sure it doesnt scroll back to the top 111 /*const scrollY = document.body.style.top; 112 document.body.style.position = ''; 113 document.body.style.top = ''; 114 window.scrollTo(0, parseInt(scrollY || '0') * -1);*/ 115 116 // Wait for the popup to disappear first then remove additional attributes 117 setTimeout(function () { 118 document.querySelector('.site-popup').classList.remove('video-only'); 119 document.querySelector('.site-popup-container').classList.remove('content-height'); 120 document.querySelector('.site-popup-content').innerHTML = ''; 121 }, 500); 122 }); 123 }); 124 } 125); 126 127function unescapeHTML(str) { 128 var htmlEntities = { 129 nbsp: ' ', 130 cent: '¢', 131 pound: '£', 132 yen: '¥', 133 euro: '', 134 copy: '©', 135 reg: '®', 136 lt: '<', 137 gt: '>', 138 quot: '"', 139 amp: '&', 140 apos: '\'' 141 }; 142 143 return str.replace(/\&([^;]+);/g, function (entity, entityCode) { 144 var match; 145 146 if (entityCode in htmlEntities) { 147 return htmlEntities[entityCode]; 148 /*eslint no-cond-assign: 0*/ 149 } else if (match = entityCode.match(/^#x([\da-fA-F]+)$/)) { 150 return String.fromCharCode(parseInt(match[1], 16)); 151 /*eslint no-cond-assign: 0*/ 152 } else if (match = entityCode.match(/^#(\d+)$/)) { 153 return String.fromCharCode(~~match[1]); 154 } else { 155 return entity; 156 } 157 });
158};
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.