1/** 2 * @name QuickButtons 3 * @author Bartosz Adamski 4 * @editor Sami El-Younsi 5 * @version 1.0.0 6 * @date 23.07.2024 7 * @param {string} selector - A CSS selector string to identify the CTA container element. 8 * @param {Object} [options={}] - Optional settings to customize the component behavior. 9*/ 10class QuickButtons{constructor(t,e={}){this.ctaContainer=document.querySelector(t),this.ctaItems=this.ctaContainer.querySelectorAll(".cta-item"),this.lang=document.documentElement.lang.split(/[-_]/)[0].toLowerCase(),this.options={resizeDelay:275,scrollUpdate:!0,resizeUpdate:!0,observeBodyClassChanges:!0,dayConversion:{de:{"Mo:":"Montag","Di:":"Dienstag","Mi:":"Mittwoch","Do:":"Donnerstag","Fr:":"Freitag","Sa:":"Samstag","So:":"Sonntag"},en:{"Mon:":"Monday","Tue:":"Tuesday","Wed:":"Wednesday","Thu:":"Thursday","Fri:":"Friday","Sat:":"Saturday","Sun:":"Sunday"}},heightsToMonitor:[],translation:{de:{locationAnnouncement:"Adresse",times:{openTimesAnnouncement:"Ãffnungszeiten",untilText:"bis"},contact:{phoneNumber:"Telefonnummer",emailAdress:"E-Mail Adresse"}},en:{locationAnnouncement:"Address",times:{openTimesAnnouncement:"Open times",untilText:"to"},contact:{phoneNumber:"Phonenumber",emailAdress:"Mailadress"}}}},this.defaultHeightsToMonitor=[{selectors:["#navigation"],cssVar:"--nav-height"},{selectors:[".widgetFlex"],cssVar:"--yourrate-mobile"}],this.settings=this.merge(this.options,e),this.settings.heightsToMonitor=this.settings.heightsToMonitor.concat(this.defaultHeightsToMonitor),this.init()}init(){this.applyAccessibilityEnhancements(),this.startMonitoring()}startMonitoring(){let t;const e=()=>{this.settings.heightsToMonitor.forEach((t=>{let e=0;t.selectors.forEach((t=>{document.querySelectorAll(t).forEach((t=>{t&&(e+=t.offsetHeight)}))})),document.documentElement.style.setProperty(t.cssVar,`${e}px`)}))},s=(s=this.settings.resizeDelay)=>{clearTimeout(t),t=setTimeout(e,s)};e();const n={attributes:!0,childList:!0,subtree:!0};if((()=>{this.settings.heightsToMonitor.forEach((t=>{t.selectors.forEach((t=>{document.querySelectorAll(t).forEach((t=>{if(t){new MutationObserver((()=>s())).observe(t,n)}}))}))}))})(),this.settings.resizeUpdate&&window.addEventListener("resize",s),this.settings.scrollUpdate&&window.addEventListener("scroll",e),this.settings.observeBodyClassChanges){(()=>{new MutationObserver((t=>{t.forEach((t=>{"attributes"===t.type&&"class"===t.attributeName&&s()}))})).observe(document.body,{attributes:!0})})(),document.body.classList.contains("scrolled")&&s()}}applyAccessibilityEnhancements(){this.ctaItems.forEach((t=>{t.setAttribute("tabindex","0");const e=t.querySelector(".cta-icon");e&&e.setAttribute("aria-hidden","true"),t.addEventListener("focusin",(()=>{t.classList.add("hover","focused")})),t.addEventListener("focusout",(e=>{t.contains(e.relatedTarget)||t.classList.remove("hover","focused")})),t.addEventListener("mouseover",(()=>{t.classList.add("hover")})),t.addEventListener("mouseout",(()=>{t.contains(document.activeElement)||t.classList.remove("hover")})),t.addEventListener("blur",(()=>{t.classList.remove("focused")}));t.querySelectorAll("a.phone, a[href^='tel:'], a.email, a[href^='mailto:']").forEach((t=>{t.classList.contains("phone")||t.href.startsWith("tel:")?t.setAttribute("aria-label",`${this.getTranslation("contact.phoneNumber")}: ${t.textContent}`):t.classList.contains("email")||t.href.startsWith("mailto:")?t.setAttribute("aria-label",`${this.getTranslation("contact.emailAdress")}: ${t.textContent}`):t.title?t.setAttribute("aria-label",t.title):t.setAttribute("aria-label",t.textContent)}));if(t.querySelectorAll("dl dt").forEach((t=>{t.setAttribute("role","definition")})),t.classList.contains("opening-hours-suffix")||t.classList.contains("cta-times")){let e=`${this.getTranslation("times.openTimesAnnouncement")}. `;t.querySelectorAll("dt").forEach((t=>{const s=t.textContent.trim(),n=this.convertDays(s);n&&(t.setAttribute("aria-label",n),e+=`${n} `);const i=t.nextElementSibling;if(i&&"dd"===i.tagName.toLowerCase()){const t=i.textContent.trim(),s=this.translateHours(t);i.setAttribute("aria-label",s),e+=`${s} `}})),t.setAttribute("aria-label",e.trim())}}));this.ctaContainer.querySelectorAll(".cta-list").forEach((t=>{t.setAttribute("tabindex","0")}))}translateHours(t){return t.replace("-",this.getTranslation("times.untilText"))}convertDays(t){const e=t.replace(":","").split(/[,\-]/).map((t=>t.trim()));return 1===e.length?this.settings.dayConversion[this.lang][e[0]+":"]||e[0]:2===e.length&&t.includes("-")?`${this.settings.dayConversion[this.lang][e[0]+":"]} ${this.getTranslation("times.untilText")} ${this.settings.dayConversion[this.lang][e[1]+":"]}`:e.map((t=>this.settings.dayConversion[this.lang][t+":"])).join(", ")}getTranslation(t,e={}){let s=this.settings.translation;if(this.lang in s){const n=t.split(".");let i=s[this.lang];for(let t of n)if(i=i[t],!i)break;for(let t in e)i=i.replace(`{{${t}}}`,e[t]);return i}return void 0!==s.en&&s.en.hasOwnProperty(t)?s.en[t]:t}merge(...t){let e={};const s=t=>{for(let s in t)t.hasOwnProperty(s)&&("[object Object]"===Object.prototype.toString.call(t[s])?e[s]=this.merge
10(e[s],t[s]):e[s]=t[s])};for(let e=0;e<t.length;e++)s(t[e]);return e}}
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.