{"version":3,"sources":["sticky-popup.js"],"names":["_container$dataset$de","container","document","querySelector","cookie","dataset","indexOf","observer","_container$querySelec","_container$querySelec2","sentinel","delay","successfulSubmission","toggleActiveClasses","arguments","length","undefined","match","classList","add","setTimeout","contains","Soho","GTM","trackExperiment","newsletterOptimizeExperimentId","ContentSquare","window","stickyPopupViewSentToCs","trackArtificialPageview","csqPageUrl","remove","setupObserver","userSetScrollPosition","parseInt","triggerHeight","showAfterScroll","innerHeight","style","top","IntersectionObserver","entries","forEach","entry","isIntersecting","root","rootMargin","threshold","initObserver","observe","close","unobserve","setCookie","trackEvent","gtmCategory","gtmLabel","onFormSubmit","e","preventDefault","form","errorElem","$","ajax","url","method","data","target","serialize","success","payload","successful","innerHTML","message","createElement","appendChild","addEventListener","event"],"mappings":"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","file":"../../javascript/sticky-popup.js","sourcesContent":["/**\n * Immediately Invoked Function Expression (IIFE) to encapsulate the sticky popup functionality.\n * This function will display a sticky popup element when certain conditions are met (scroll position or delay).\n */\n(() => {\n    const container = document.querySelector('.js-sticky-popup');\n\n    if (!container) {\n        return;\n    }\n\n    const cookie = container.dataset.cookie;\n\n    /**\n     * The soho_npopup cookie (relating to the newsletter type popup) will be set if user is logged in and opted in, closed the popup in last 14 days, or submitted within the last year.\n     * For promo cookie will only be set once user has closed.\n     */\n    if (document.cookie.indexOf(cookie + \"=\") >= 0) {\n        return;\n    }\n\n    const sentinel = document.querySelector('.js-sentinel');\n\n    /**\n     * Get the delay from the data-delay attribute, if set.\n     */\n    const delay = container.dataset.delay ?? 0;\n\n    /**\n     * The IntersectionObserver instance.\n     */\n    let observer;\n\n    /**\n     * Flag to indicate whether the form was successfully submitted, used to stop close tracking event firing when form is closed.\n     *\n     * @type {boolean}\n     */\n    let successfulSubmission = false;\n\n    /**\n     * Adds the active classes to the sticky popup.\n     * There are two classes added to achieve a fade in effect.\n     */\n    const toggleActiveClasses = (isAdding = true) => {\n        if (isAdding) {\n            if (!document.cookie.match('OptanonAlertBoxClosed')) {\n                return;\n            }\n\n            container.classList.add('sticky-popup--active-a');\n            setTimeout(() => {\n                container.classList.add('sticky-popup--active-b');\n            }, 200);\n\n            if (container.classList.contains('sticky-popup--newsletter-signup')) {\n                Soho.GTM.trackExperiment(Soho.newsletterOptimizeExperimentId, 1);\n            }\n\n            if (Soho.ContentSquare && !window.stickyPopupViewSentToCs) {\n                Soho.ContentSquare.trackArtificialPageview(container.dataset.csqPageUrl);\n                window.stickyPopupViewSentToCs = true;\n            }\n        } else {\n            container.classList.remove('sticky-popup--active-b');\n            setTimeout(() => {\n                container.classList.remove(\n                    'sticky-popup--active-a'\n                );\n            }, 200);\n        }\n    };\n\n    /**\n     * Initializes and returns a new instance of IntersectionObserver, if not already initialized.\n     * The observer watches for element intersection with the viewport and toggles active classes.\n     *\n     * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API}\n     * @returns {IntersectionObserver} The instance of IntersectionObserver.\n     */\n    const initObserver = () => {\n        if (observer) {\n            return;\n        }\n\n        observer = new IntersectionObserver(\n            function (entries) {\n                entries.forEach((entry) => {\n                    if (entry.isIntersecting) {\n                        toggleActiveClasses();\n                    }\n                });\n            },\n            {\n                root: null,\n                rootMargin: '0px',\n                threshold: 0,\n            }\n        );\n\n        return observer;\n    };\n\n    /**\n     * Sets up an Intersection Observer to detect when a sentinel element intersects with the viewport.\n     * When the intersection occurs, the sticky popup will be displayed.\n     * Set a default scroll trigger position of the window height plus 400px.\n     */\n    const setupObserver = () => {\n        const userSetScrollPosition =\n            parseInt(container.dataset.triggerHeight ? container.dataset.triggerHeight : 400);\n        const showAfterScroll = window.innerHeight + userSetScrollPosition;\n\n        // Update sentinel position\n        sentinel.style.top = showAfterScroll + 'px';\n\n        initObserver();\n        observer.observe(sentinel);\n    };\n\n    /**\n     * Sets up a delay before displaying the sticky popup.\n     */\n    const setUpDelay = () => {\n        setTimeout(() => {\n            toggleActiveClasses();\n        }, parseInt(delay) * 1000);\n    };\n\n    /**\n     * Closes the sticky popup and removes the Intersection Observer.\n     */\n    const close = () => {\n        toggleActiveClasses(false);\n\n        if (observer) {\n            observer.unobserve(sentinel);\n        }\n\n        if (!successfulSubmission) {\n            setCookie(cookie, '1', 14);\n            Soho.GTM.trackEvent(container.dataset.gtmCategory, 'Closed', container.dataset.gtmLabel);\n        }\n    };\n\n    const onFormSubmit = (e) => {\n        e.preventDefault();\n\n        const form = container.querySelector('form');\n\n        form.classList.remove('sticky-popup__controls--error');\n\n        const errorElem =  container.querySelector('.sticky-popup__error');\n        if (errorElem) {\n            errorElem.remove();\n        }\n\n        $.ajax({\n            url: '/newsletter',\n            method: 'POST',\n            data: $(e.target).serialize(),\n            success: function(data) {\n                if (!data.payload.successful) {\n                    form.classList.add('sticky-popup__controls--error');\n\n                    const errorElem = document.createElement('p');\n                    errorElem.classList.add('sticky-popup__error');\n                    errorElem.innerHTML = data.payload.message;\n                    form.appendChild(errorElem);\n                } else {\n                    successfulSubmission = true;\n\n                    container.querySelector('.sticky-popup__label').remove();\n                    container.querySelector('.sticky-popup__title').innerHTML = data.payload.message;\n\n                    // Don't show the popup again for a year\n                    setCookie(cookie, '1', 365);\n\n                    Soho.GTM.trackEvent(container.dataset.gtmCategory, 'Subscribe', container.dataset.gtmLabel);\n                }\n            }\n        });\n    };\n\n    /**\n     * Binds events to the close button for the sticky popup & form.\n     */\n    const bindEvents = () => {\n        const closeBtn = container.querySelector('[data-close]');\n        closeBtn.addEventListener('click', close);\n\n        container.querySelector('form')?.addEventListener('submit', onFormSubmit);\n\n        container.querySelector('.sticky-popup__button')?.addEventListener('click', (event) => {\n            setCookie(cookie, '1', 14);\n            Soho.GTM.trackEvent(container.dataset.gtmCategory, 'Clicked', container.dataset.gtmLabel);\n        });\n    };\n\n    /**\n     * Initializes the sticky popup functionality.\n     * Depending on whether a delay is set, it will either set up a delay or set up an observer.\n     * Then binds events to the close button.\n     */\n    const init = () => {\n        if (delay) {\n            setUpDelay();\n        } else {\n            setupObserver();\n        }\n        bindEvents();\n    };\n\n    // Fire!\n    init();\n})();\n"],"sourceRoot":"../../../../resources/javascript"}