(function () { function getConfig() { const configs = window.essentialAnnouncementConfigs; return new Promise((resolve) => { resolve(configs); }); } // pages const isHomePage = window.location.pathname === "/"; const isProductPage = window.location && window.location.pathname.includes("/products/"); const isCollectionPage = window.location && window.location.pathname.includes("/collections/"); // utility function that simplifies creation of new html node function create({ tag, appendTo, children = [], attributes = {}, events = {}, }) { const element = document.createElement(tag); Object.entries(attributes).forEach(([key, value]) => { element[key] = value; }); Object.entries(events).forEach(([key, value]) => { element.addEventListener(key, value); }); if (appendTo) { appendTo.appendChild(element); } children.forEach((child) => child && element.appendChild(child)); return element; } // utility function that simplifies editing of new html node function update( createdElement, { appendTo, children = [], attributes = {}, events = {} } ) { const element = createdElement; Object.entries(attributes).forEach(([key, value]) => { element[key] += value; }); Object.entries(events).forEach(([key, value]) => { element.addEventListener(key, value); }); if (appendTo) { appendTo.appendChild(element); } children.forEach((child) => child && element.appendChild(child)); return element; } function createSvgIgon(icon, color, width = 12, height = 12) { const IconSVG = document.createElementNS( "http://www.w3.org/2000/svg", "svg" ); const IconSVGPath = document.createElementNS( "http://www.w3.org/2000/svg", "path" ); IconSVG.setAttribute("width", width); IconSVG.setAttribute("height", height); IconSVG.setAttribute("fill", "none"); IconSVGPath.setAttribute("d", icon); IconSVGPath.setAttribute("fill", color); IconSVG.append(IconSVGPath); return IconSVG; } function closeButtonIconSVG(color) { const closeIcon = "m7.414 6 4.293-4.293A.999.999 0 1 0 10.293.293L6 4.586 1.707.293A.999.999 0 1 0 .293 1.707L4.586 6 .293 10.293a.999.999 0 1 0 1.414 1.414L6 7.414l4.293 4.293a.997.997 0 0 0 1.414 0 .999.999 0 0 0 0-1.414L7.414 6Z"; return createSvgIgon(closeIcon, color); } function nextButtonIconSVG(color) { const nextIcon = "M8.00001 16C7.74401 16 7.48801 15.902 7.29301 15.707C6.90201 15.316 6.90201 14.684 7.29301 14.293L11.586 10L7.29301 5.70701C6.90201 5.31601 6.90201 4.68401 7.29301 4.29301C7.68401 3.90201 8.31601 3.90201 8.70701 4.29301L13.707 9.29301C14.098 9.68401 14.098 10.316 13.707 10.707L8.70701 15.707C8.51201 15.902 8.25601 16 8.00001 16Z"; return createSvgIgon(nextIcon, color, 20, 20); } function prevButtonIconSVG(color) { const prevIcon = "M12 16C11.744 16 11.488 15.902 11.293 15.707L6.29301 10.707C5.90201 10.316 5.90201 9.68401 6.29301 9.29301L11.293 4.29301C11.684 3.90201 12.316 3.90201 12.707 4.29301C13.098 4.68401 13.098 5.31601 12.707 5.70701L8.41401 10L12.707 14.293C13.098 14.684 13.098 15.316 12.707 15.707C12.512 15.902 12.256 16 12 16Z"; return createSvgIgon(prevIcon, color, 20, 20); } function appdedCss(css) { const head = document.getElementsByTagName("head")[0]; const style = document.createElement("style"); style.setAttribute("type", "text/css"); style.setAttribute("id", "essential-apps-announcement-bar-css"); if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } head.appendChild(style); } function fontFamily(styleConfig) { return styleConfig.font !== "" && styleConfig.font ? `font-family: ${styleConfig.font};\n` : ""; } function appendAnnoucementBarCss(config, animationDuration) { const styleConfig = config.style; const smallerOnMobile = (config, styleConfig) => { if ( !config.createdAt || new Date(config.createdAt).getTime() < 1701866300000 ) { return ""; } return ` @media (max-width: 620px) { .essential_annoucement_bar_running_line_title_${config.id} { font-size: ${Math.floor(styleConfig.titleSize * 0.8)}px; } .essential_annoucement_bar_wrapper_${config.id} h2, .essential_annoucement_bar_wrapper_${config.id} h4, .essential_annoucement_bar_title_container_${config.id}, #essential_annoucement_bar_title_${config.id} { font-size: ${Math.floor(styleConfig.titleSize * 0.8)}px; } .essential_annoucement_bar_subheading_${config.id} { font-size: ${Math.floor(styleConfig.subheadingSize * 0.8)}px; } .essential_annoucement_bar_cta_${config.id} { font-size: ${Math.floor(styleConfig.buttonFontSize * 0.9)}px; } }`; }; const wrapperBackground = styleConfig.backgroundType === "gradientBackground" ? `linear-gradient(${styleConfig.gradientTurn}deg, ${styleConfig.gradientStart}, ${styleConfig.gradientEnd})` : styleConfig.singleColor; const css = ` .essential_annoucement_bar_wrapper_${config.id} { overflow: hidden; position: relative; display: flex !important; flex-wrap: nowrap; column-gap: 26px; row-gap: 10px; ${fontFamily(styleConfig)} background: ${wrapperBackground}; padding: 10px; align-items: center; justify-content: center; width: 100%; border-radius: ${styleConfig.borderRadius}px; border: ${styleConfig.borderColor} solid ${styleConfig.borderSize}px; ${ styleConfig.announcementBarStyle === "seperate-centered" ? `flex-flow: column; justify-items: center;` : "" } } .essential_annoucement_bar_wrapper_${config.id}.top_page { z-index: 101; } .essential_annoucement_bar_wrapper_${config.id}.top_page_styles {} .essential_annoucement_bar_wrapper_${config.id}.top_page_sticky { position: sticky; top: 0; } .essential_annoucement_bar_wrapper_${config.id}.bottom_page { z-index: 101; bottom: 0; left: 0; position: fixed; width: 100%; } .essential_annoucement_bar_wrapper_${config.id}.bottom_page_styles {} .essential_annoucement_bar_wrapper_${config.id}.clickable { cursor: pointer; } .essential_annoucement_main_content_wrapper_${config.id} { display: flex; align-items: center; justify-content: center; flex-grow: 1; overflow: hidden; gap: ${config.announcementType !== "rotating" ? "26px" : "0"}; } .essential_annoucement_titles_outside_wrapper_${config.id} { overflow: hidden; position: relative; width: ${config.announcementType === "simple" ? "auto" : "100%"}; padding: ${config.announcementType === "rotating" ? "0 20px" : "0"}; } .essential_annoucement_running_line_wrapper_${config.id} { display: flex; width: 100%; } .essential_annoucement_bar_running_line_title_${config.id} { ${fontFamily(styleConfig)}font-weight: bold; font-size: ${styleConfig.titleSize}px; color: ${styleConfig.titleColor}; margin: 0; padding: 0; line-height: 1.2; letter-spacing: normal; text-transform: none; text-align: left; white-space: nowrap; animation: runningLine ${animationDuration}s linear infinite; animation-delay: -${animationDuration}s; display: flex; gap: 26px; padding-right: 26px; } .essential_annoucement_running_line_wrapper_${ config.id } .essential_annoucement_bar_running_line_title_${ config.id }:nth-child(2) { animation: runningLine2 ${animationDuration}s linear infinite; animation-delay: -${animationDuration / 2}s; } .essential_annoucement_bar_slider_container_${config.id} { margin: 0; align-items: center; } .essential_annoucement_bar_slide_${config.id} { display: flex; justify-content: center; align-items: center; gap: 26px; } .essential_annoucement_bar_slide_${config.id}.glide__slide--active { z-index: 1; } .essential_annoucement_bar_slide_${config.id}.clickable { cursor: pointer; } .essential_annoucement_bar_glide__arrow { cursor: pointer; } .essential_annoucement_bar_glide__arrows_prev_${config.id} { position: absolute; left: -20px; top: 0; bottom: 0; height: 20px; margin: auto; } .essential_annoucement_bar_glide__arrows_next_${config.id} { position: absolute; right: -20px; top: 0; bottom: 0; height: 20px; margin: auto; } .essential_annoucement_titles_wrapper_${config.id}.center { text-align: center; } .essential_annoucement_bar_wrapper_${config.id} h2, .essential_annoucement_bar_wrapper_${config.id} h4, .essential_annoucement_bar_title_container_${config.id}, #essential_annoucement_bar_title_${config.id} { ${fontFamily(styleConfig)}font-weight: bold; font-size: ${styleConfig.titleSize}px; color: ${styleConfig.titleColor}; margin: 0; padding: 0; line-height: 1.2; letter-spacing: normal; text-transform: none; white-space: pre-wrap; } .essential_annoucement_bar_subheading_${config.id} { ${fontFamily(styleConfig)}font-size: ${ styleConfig.subheadingSize }px; color: ${styleConfig.subheadingColor}; line-height: 1.2; letter-spacing: normal; padding: 0; margin: 0; } .essential_annoucement_bar_cta_${config.id} { display: block; cursor: pointer; text-decoration: none; background: ${styleConfig.buttonBackgroundColor}; border: 0; white-space: nowrap; padding: 8px 16px; line-height: 1.5; border-radius: ${styleConfig.buttonBorderRadius}px; font-size: ${styleConfig.buttonFontSize}px; color: ${styleConfig.buttonFontColor}; } .essential_annoucement_bar_close_button_${config.id} { display: block; border: none; background: none; cursor: pointer; margin-left: auto; } .essential_annoucement_bar_close_button_${config.id} svg { width: 12px; height: 12px; display: block; } @media (max-width: 430px) { .essential_annoucement_bar_wrapper_${config.id} { justify-items: center; text-align: center; padding: 10px 15px; } .essential_annoucement_bar_close_button_${config.id} { position: absolute; padding: 0; transform: none; top: 5px; right: 2px; } .essential_annoucement_bar_wrapper_${config.id} h2, .essential_annoucement_bar_wrapper_${config.id} h4, .essential_annoucement_bar_title_container_${config.id}, #essential_annoucement_bar_title_${config.id} { text-align: center; white-space: pre-wrap; } .essential_annoucement_main_content_wrapper_${config.id} { gap: ${config.announcementType !== "rotating" ? "10px" : "0"}; } .essential_annoucement_bar_slide_${config.id} { gap: 10px; } .essential_annoucement_titles_outside_wrapper_${config.id} { padding: 0; } .essential_annoucement_bar_glide__arrows_${config.id} { display: none!important; } } @keyframes runningLine { from { -moz-transform: translateX(100%); -webkit-transform: translateX(100%); transform: translateX(100%); } to { -moz-transform: translateX(-100%); -webkit-transform: translateX(-100%); transform: translateX(-100%); } } @keyframes runningLine2 { from { -moz-transform: translateX(0); -webkit-transform: translateX(0); transform: translateX(0); } to { -moz-transform: translateX(-200%); -webkit-transform: translateX(-200%); transform: translateX(-200%); } } ${smallerOnMobile(config, styleConfig)} `; appdedCss(css); } function initAnnoucmentBar(config, placementNode, appBlockId = "") { const title = config.title; const titleLength = title.length || 20; const titleLengthRatio = Math.ceil(100 / titleLength); const animationSpeed = config.animationSpeed || config.animationSpeed == 0 ? config.animationSpeed : 80; const rotateDuration = isNaN(parseInt(config.rotateDuration)) ? 4 : parseInt(config.rotateDuration); const animationSpeedReversed = 100 - animationSpeed; const slowAnimationDuration = titleLength * animationSpeedReversed; const fastAnimationDuration = slowAnimationDuration / 16; const animationDuration = titleLengthRatio < 10 ? fastAnimationDuration : slowAnimationDuration; const runningLineItems = titleLengthRatio < 10 ? 10 : titleLengthRatio; const announcementBar = document.querySelector( `.essential_annoucement_bar_wrapper_${config.id}_${appBlockId}` ); const titleTagChangeFlag = config.createdAt && new Date(config.createdAt).getTime() > 1704971931000; const titleTag = () => { if (Shopify?.shop === "fd6f42-4.myshopify.com") { return "h4"; } if (titleTagChangeFlag) { return "div"; } return "h2"; }; if (announcementBar && config.announcementPlacement !== "custom") { return; } try { let localStorageData = window.localStorage.getItem( `essentialAnnoucementBarClosed_${config.id}_${appBlockId}` ); localStorageData = JSON.parse(localStorageData); if ( localStorageData && localStorageData.id === config.id && localStorageData.updatedAt === config.updatedAt && localStorageData.value ) { return; } } catch (error) { console.log(error); } if (config.announcementPlacement) { if (config.announcementPlacement === "home-page" && !isHomePage) { return; } if (config.announcementPlacement === "all-products" && !isProductPage) { return; } if ( config.announcementPlacement === "all-collections" && !isCollectionPage ) { return; } } let wrapper = create({ tag: "div", attributes: { className: `essential_annoucement_bar_wrapper essential_annoucement_bar_wrapper_${config.id} essential_annoucement_bar_wrapper_${config.id}_${appBlockId}`, }, }); if ( config.style.position === "top-page" && config.announcementPlacement !== "custom" ) { wrapper = update(wrapper, { attributes: { className: " top_page", }, }); } if (config.style.position === "top-page") { wrapper = update(wrapper, { attributes: { className: " top_page_styles", }, }); } if ( config.style.position === "top-page" && config.style.stickyBar && config.announcementPlacement !== "custom" ) { wrapper = update(wrapper, { attributes: { className: " top_page_sticky", }, }); } if ( config.style.position === "bottom-page" && config.announcementPlacement !== "custom" ) { wrapper = update(wrapper, { attributes: { className: " bottom_page", }, }); } if (config.style.position === "bottom-page") { wrapper = update(wrapper, { attributes: { className: " bottom_page_styles", }, }); } if ( config.CTAType === "clickable" && config.CTALink && config.announcementType !== "rotating" ) { wrapper = update(wrapper, { attributes: { className: " clickable", }, events: { click: (event) => { event.preventDefault(); if (!event.target.closest("button") && config.CTALink) { window.location.href = config.CTALink; } }, }, }); } const mainContentWrapper = create({ tag: "div", attributes: { className: `essential_annoucement_main_content_wrapper_${config.id}`, }, appendTo: wrapper, }); const TitlesOutsideWrapper = create({ tag: "div", attributes: { className: `essential_annoucement_titles_outside_wrapper_${config.id}`, }, appendTo: mainContentWrapper, }); if (config.announcementType === "simple") { create({ tag: "div", attributes: { className: `essential_annoucement_titles_wrapper_${config.id} ${ !config.subheading ? "center" : "" }`, }, children: [ create({ tag: titleTag(), attributes: { id: `essential_annoucement_bar_title_${config.id}`, className: titleTagChangeFlag ? `essential_annoucement_bar_title_container_${config.id} h2` : "", textContent: config.title, }, }), config.subheading && create({ tag: "p", attributes: { className: `essential_annoucement_bar_subheading_${config.id}`, textContent: config.subheading, }, }), ], appendTo: TitlesOutsideWrapper, }); } else if (config.announcementType === "running-line") { const hasEmptySpaces = (inputString) => /\s{2,}/.test(inputString); const replaceSpacesWithHTML = (inputString) => { const safeInputString = inputString .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); const spaceRegex = / +/g; return safeInputString.replace(spaceRegex, (match) => { let spaceCount = match.length; if (spaceCount > 1) { return ``; } else { return match; } }); }; create({ tag: "div", attributes: { className: `essential_annoucement_running_line_wrapper_${config.id}`, }, children: [ create({ tag: "div", attributes: { className: `essential_annoucement_bar_running_line_title_${config.id}`, }, children: Array.from(Array(runningLineItems).keys()).map(() => create({ tag: "span", attributes: hasEmptySpaces(config.title) ? { innerHTML: replaceSpacesWithHTML(config.title) } : { textContent: config.title }, }) ), }), create({ tag: "div", attributes: { className: `essential_annoucement_bar_running_line_title_${config.id}`, }, children: Array.from(Array(runningLineItems).keys()).map(() => create({ tag: "span", attributes: hasEmptySpaces(config.title) ? { innerHTML: replaceSpacesWithHTML(config.title) } : { textContent: config.title }, }) ), }), ], appendTo: TitlesOutsideWrapper, }); } else if (config.announcementType === "rotating") { create({ tag: "div", attributes: { id: `essential_annoucement_bar_slider_${config.id}_${appBlockId}`, className: `essential_annoucement_bar_glide`, }, children: [ create({ tag: "div", attributes: { className: `essential_annoucement_bar_glide__track essential_annoucement_bar_glide__track_${config.id} essential_annoucement_bar_glide__track_${config.id}_${appBlockId}`, }, children: [ create({ tag: "ul", attributes: { className: `essential_annoucement_bar_glide__slides essential_annoucement_bar_slider_container_${config.id}`, }, children: config.announcements.map((announcement) => create({ tag: "li", attributes: { className: `essential_annoucement_bar_glide__slide essential_annoucement_bar_slide_${ config.id } ${ announcement.CTAType === "clickable" && announcement.CTALink ? "clickable" : "" }`, }, ...(announcement.CTAType === "clickable" ? { events: { click: (event) => { event.preventDefault(); if ( !event.target.closest("a") && announcement.CTALink ) { window.location.href = announcement.CTALink; } }, }, } : {}), children: [ create({ tag: "div", attributes: { className: `essential_annoucement_titles_wrapper_${ config.id } ${!announcement.subheading ? "center" : ""}`, }, children: [ create({ tag: titleTag(), attributes: { className: `essential_annoucement_bar_title_${ config.id } ${ titleTagChangeFlag ? `essential_annoucement_bar_title_container_${config.id} h2` : "" }`, textContent: announcement.title, }, }), announcement.subheading && create({ tag: "p", attributes: { className: `essential_annoucement_bar_subheading_${config.id}`, textContent: announcement.subheading, }, }), ], }), announcement.CTAType === "button" && create({ tag: "a", attributes: { className: `essential_annoucement_bar_cta_${config.id}`, href: announcement.CTALink || "", textContent: announcement.buttonText || "", }, }), ], }) ), }), ], }), create({ tag: "div", attributes: { className: `essential_annoucement_bar_glide__arrows_${config.id} essential_annoucement_bar_glide__arrows_${config.id}_${appBlockId}`, }, children: [ create({ tag: "div", attributes: { className: `essential_annoucement_bar_glide__arrow essential_annoucement_bar_glide__arrows_prev_${config.id} essential_annoucement_bar_glide__arrows_prev_${config.id}_${appBlockId}`, }, children: [prevButtonIconSVG(config.style.arrowIconColor)], }), create({ tag: "div", attributes: { className: `essential_annoucement_bar_glide__arrow essential_annoucement_bar_glide__arrows_next_${config.id} essential_annoucement_bar_glide__arrows_next_${config.id}_${appBlockId}`, }, children: [nextButtonIconSVG(config.style.arrowIconColor)], }), ], }), ], appendTo: TitlesOutsideWrapper, }); } if (config.CTAType === "button" && config.announcementType !== "rotating") { create({ tag: "a", attributes: { className: `essential_annoucement_bar_cta_${config.id}`, href: config.CTALink, textContent: config.buttonText, }, appendTo: mainContentWrapper, }); } if (config.closeButton) { create({ tag: "button", attributes: { className: `essential_annoucement_bar_close_button_${config.id}`, }, events: { click: (event) => { event.preventDefault(); const announcementBar = document.querySelector( `.essential_annoucement_bar_wrapper_${config.id}_${appBlockId}` ); if (announcementBar) { announcementBar.parentNode.removeChild(announcementBar); try { window.localStorage.setItem( `essentialAnnoucementBarClosed_${config.id}_${appBlockId}`, JSON.stringify({ value: true, id: config.id, updatedAt: config.updatedAt, }) ); } catch (error) { console.log(error); } } }, }, children: [closeButtonIconSVG(config.style.closeIconColor)], appendTo: wrapper, }); } appendAnnoucementBarCss(config, animationDuration); if (placementNode) { placementNode.prepend(wrapper); } else { const defaultPlacementNode = document.querySelector( ".essential-announcement-bar-placement" ); if (defaultPlacementNode) { defaultPlacementNode.prepend(wrapper); } else { document.querySelector("body").prepend(wrapper); } } if (config.announcementType === "rotating") { const sliderTrack = document.querySelector( `.essential_annoucement_bar_glide__track_${config.id}_${appBlockId}` ); const slideArrows = document.querySelector( `.essential_annoucement_bar_glide__arrows_${config.id}_${appBlockId}` ); const prevArrow = document.querySelector( `.essential_annoucement_bar_glide__arrows_prev_${config.id}_${appBlockId}` ); const newxArrow = document.querySelector( `.essential_annoucement_bar_glide__arrows_next_${config.id}_${appBlockId}` ); sliderTrack.setAttribute("data-glide-el", "track"); slideArrows.setAttribute("data-glide-el", "controls"); prevArrow.setAttribute("data-glide-dir", "<"); newxArrow.setAttribute("data-glide-dir", ">"); // if glide library exists if (typeof Glide === "function") { const glide = new Glide( `#essential_annoucement_bar_slider_${config.id}_${appBlockId}`, { type: "carousel", animationDuration: window.essentialAnimationDuration ? window.essentialAnimationDuration : 400, autoplay: rotateDuration * 1000, } ); window.addEventListener("load", () => { glide.mount(); }); } } } function addAnnouncementBar() { const announcementBlocks = document.querySelectorAll( "div.essential-announcement-block" ); const canShowOnProduct = (config) => { if (config.showOnProducts && config.showOnProducts.length !== 0) { const pathname = decodeURI(window.location.pathname); const showOnProduct = config.showOnProducts.find((product) => { if (typeof pathname.endsWith === "function") { return pathname.endsWith(`products/${product.handle}`); } else { return pathname.includes(`products/${product.handle}`); } }); if (!showOnProduct) { return false; } } return true; }; const canShowOnCollection = (config) => { if (config.showOnCollections && config.showOnCollections.length !== 0) { const pathname = decodeURI(window.location.pathname); const showOnCollection = config.showOnCollections.find((collection) => pathname.includes(`collections/${collection.handle}`) ); if (!showOnCollection) { return false; } } return true; }; const getCleanTranslation = (translation) => { const cleanedTranslation = Object.keys(translation).reduce((acc, key) => { if ( translation[key] !== null && translation[key] !== "" && !["id", "itemId", "itemType", "locale"].includes(key) ) { acc[key] = translation[key]; } return acc; }, {}); return cleanedTranslation; }; getConfig().then((configs) => { if (!configs) { return null; } configs.forEach((config) => { const translationType = config.announcementType === "rotating" ? "list" : "single"; const itemType = config.announcementType; if (config.translations && config.translations.length > 0) { if (translationType === "single") { const translation = config.translations.find( (translation) => translation.locale === Shopify?.locale && translation.itemType === itemType ); if (translation) { Object.assign(config, getCleanTranslation(translation)); } } if (translationType === "list") { const items = config.announcements; items.forEach((item) => { const translation = config.translations.find( (translation) => translation.locale === Shopify?.locale && translation.itemType === itemType && translation.itemId === item.id ); if (translation) { Object.assign(item, getCleanTranslation(translation)); } }); } } }); const appEmbeds = configs.filter( (config) => config.announcementPlacement !== "custom" ); const appBlocks = configs.filter( (config) => config.announcementPlacement === "custom" ); if ((configs && !Array.isArray(configs)) || configs.length === 0) { return null; } appEmbeds.forEach((announcementBarConfig) => { if ( announcementBarConfig && canShowOnProduct(announcementBarConfig) && canShowOnCollection(announcementBarConfig) ) { initAnnoucmentBar(announcementBarConfig); } }); // loop through announcementBlocks and if it's in appBlocks then initAnnoucmentBar announcementBlocks.forEach((announcementBlockNode) => { const config = appBlocks.find( (config) => config.id === announcementBlockNode.getAttribute("id") ); // get parent node id find by class shopify-app-block const appBlockParentNode = announcementBlockNode.closest(".shopify-app-block"); // get parent node id if appBlockParentNode exist const appBlockParentNodeId = appBlockParentNode ? appBlockParentNode.getAttribute("id") : ""; if (config && canShowOnProduct(config) && canShowOnCollection(config)) { initAnnoucmentBar( config, announcementBlockNode, appBlockParentNodeId ); } }); }); } addAnnouncementBar(); })();