// TODO this whole code can be improved more (function () { const MAX_RETRIES = 50; const DELAY = 100; function warn(message) { // eslint-disable-next-line no-console console && console.warn && console.warn(`[WARNING] ${message}`); } function createModal(appName) { // TODO: Replace the styles with the CDN link to the neetomolecules/PageLoader stylesheet once https://github.com/bigbinary/neeto-engineering-web/issues/779 is resolved. return `
`; } function createLoader(appName) { return ` `; } function createCloseIcon(appName) { return ` `; } function embedButtonStyles(appName) { return ` `; } function createButton(values, appName) { const style = values; const content = `${style.btnText}`; let btn = document.getElementById(`${appName}-floating-popup-btn`); if (!btn) { btn = document.createElement("button"); } btn.innerHTML = content; btn.id = `${appName}-floating-popup-btn`; btn.style.backgroundColor = style.btnColor; btn.style.color = style.btnTextColor; style.btnPosition === "bottomRight" ? (btn.style.right = 0) : (btn.style.left = 0); document.body.appendChild(btn); } function displayWarnings(popupButton, embedLink) { if (!popupButton) warn(`The element was not found in the DOM tree`); if (!embedLink) warn(`Invalid 'embedLink'`); } function iframeStyles(appName) { return ` `; } function addIframe(embedLink, appName) { const iframe = document.createElement("iframe"); iframe.src = embedLink; iframe.id = `${appName}-iframe`; iframe.allow = "clipboard-write *"; // Check if isSidebarAndCoverImgHidden is in the URL and set width accordingly let isSidebarAndCoverImgHidden = false; try { const url = typeof embedLink === "string" ? new URL(embedLink) : embedLink; isSidebarAndCoverImgHidden = url.searchParams?.get("isSidebarAndCoverImgHidden") === "true"; } catch (_) { // If URL parsing fails, check if the string contains the parameter isSidebarAndCoverImgHidden = typeof embedLink === "string" && embedLink.includes("isSidebarAndCoverImgHidden=true"); } iframe.style.width = isSidebarAndCoverImgHidden ? "780px" : "1080px"; iframe.onload = () => { document.getElementById(`${appName}-loader`).style.display = "none"; }; const embedAppContainer = document.getElementById( `${appName}-embed-container` ); embedAppContainer.appendChild(iframe); } function openModal(iframeLink, appName) { document.getElementById(`${appName}-loader`).style.display = "block"; const embedAppModal = document.getElementById(`${appName}-modal`); embedAppModal.style.display = "block"; document.body.setAttribute("data-neetocal-modal-open", "true"); const iframe = document.getElementById(`${appName}-iframe`); if (!iframe) addIframe(iframeLink, appName); } function closeModal(appName) { const embedAppModal = document.getElementById(`${appName}-modal`); embedAppModal.style.display = "none"; document.body.removeAttribute("data-neetocal-modal-open"); const embedAppContainer = document.getElementById( `${appName}-embed-container` ); embedAppContainer.innerHTML = ""; } function embedContent(popupButton, iframeLink, appName = "NeetoCal") { displayWarnings(popupButton, iframeLink); const modal = document.getElementById(`${appName}-modal`); if (!modal) { const ncWrapper = document.createElement("div"); ncWrapper.id = `${appName}-modal`; ncWrapper.innerHTML += createModal(appName); ncWrapper.innerHTML += createLoader(appName); ncWrapper.innerHTML += createCloseIcon(appName); ncWrapper.innerHTML += embedButtonStyles(appName); ncWrapper.innerHTML += iframeStyles(appName); document.body.appendChild(ncWrapper); } popupButton.addEventListener("click", () => { openModal(iframeLink, appName); }); document .getElementById(`${appName}-modal`) .addEventListener("click", () => closeModal(appName)); document .getElementById(`close-${appName}`) .addEventListener("click", () => closeModal(appName)); } function embedFloatingPopupButton(iframeLink, styles, appName) { createButton(styles, appName); const btn = document.querySelector(`#${appName}-floating-popup-btn`); embedContent(btn, iframeLink); } const appendEmbedUrlToElement = (iframeLink, styles, elementSelector) => element => { const iframeId = `iframe-${btoa(elementSelector)}`; const iframe = document.getElementById(iframeId) || document.createElement("iframe"); iframe.id = iframeId; iframe.src = iframeLink; if (styles.height || styles.width) { // Backwards compatibility for old format iframe.height = styles.height; iframe.width = styles.width; } else { iframe.style = styles; } iframe.style.border = "none"; iframe.allow = "clipboard-write *"; element.append(iframe); }; function getElementsAfterDomInsert(elementSelector, callback) { let attempts = 0; const intervalId = setInterval(() => { const element = document.querySelector(elementSelector); if (element) { clearInterval(intervalId); callback(element); } else if (attempts >= MAX_RETRIES) { clearInterval(intervalId); console.error( "Couldn't find the specified elements in the DOM. Please verify the elementSelector." ); } attempts++; }, DELAY); } function inlineEmbed({ iframeLink, styles, elementSelector }) { const embedHandler = () => getElementsAfterDomInsert( elementSelector, appendEmbedUrlToElement(iframeLink, styles, elementSelector) ); if (document.readyState === "loading") window.addEventListener("load", embedHandler); else embedHandler(); } function embedContentOnElements(elementSelector, iframeLink, appName) { const embedHandler = () => getElementsAfterDomInsert(elementSelector, element => embedContent(element, iframeLink, appName) ); if (document.readyState === "loading") window.addEventListener("DOMContentLoaded", embedHandler); else embedHandler(); } function embedNeetoCal(...args) { const firstArgument = args[0]; if (firstArgument instanceof Element) { embedContent(...args); return; } const { type, meetingSlug, id, organization, styles, elementSelector, env = "production", kind = "meeting", isSidebarAndCoverImgHidden = "false", isSidebarHidden = "false", isImageAndTitleHidden = "false", shouldForwardQueryParams = "false", extraParams = {}, // Deprecated on 2025 May 8 queryParams = {}, } = firstArgument; const baseUrl = { production: `https://${organization}.neetocal.com`, staging: `https://${organization}.neetocal.net`, development: `http://${organization}.lvh.me:9026`, }; const getApiPath = () => { if (kind === "routingForm") { return `embed/routing-forms/${id}`; } else if (kind === "introPage") { return `embed/intro-pages/${id}`; } else { return !!id ? `embed/${id}` : meetingSlug; } }; const appendQueryParamsToUrl = url => { const params = new URLSearchParams(); if (isSidebarAndCoverImgHidden === "true" || isSidebarHidden === "true") { params.set("isSidebarAndCoverImgHidden", "true"); } if (isImageAndTitleHidden === "true") { params.set("isImageAndTitleHidden", "true"); } // Automatically enable dynamicHeight for popup types if (type === "floatingPopup" || type === "elementClick") { params.set("dynamicHeight", "true"); } const mergedParams = { ...queryParams, ...extraParams }; if (shouldForwardQueryParams === "true") { const parentQueryParams = window.parent.location.search; const parentParams = new URLSearchParams(parentQueryParams); for (const [key, value] of parentParams) { params.set(key, value); } } Object.keys(mergedParams).forEach(key => { params.set(key, mergedParams[key]); }); url.search = params.toString(); return url; }; const getIframeLink = () => { const apiPath = new URL(getApiPath(), baseUrl[env]); return appendQueryParamsToUrl(apiPath); }; const iframeLink = getIframeLink(); const appName = "NeetoCal"; if (type === "inline") inlineEmbed({ iframeLink, styles, elementSelector }); if (type === "floatingPopup") { if ( document.readyState === "interactive" || document.readyState === "complete" ) { embedFloatingPopupButton(iframeLink, styles, appName); } document.addEventListener("DOMContentLoaded", function () { embedFloatingPopupButton(iframeLink, styles, appName); }); } if (type === "elementClick") { embedContentOnElements(elementSelector, iframeLink, appName); } } if (!window.__neetoCalGlobalHeightListenerAdded) { const onNeetoCalHeightMessage = event => { try { const isHeightChangeEvent = event?.data?.type === "neeto-cal-height-change-event"; if (!isHeightChangeEvent) return; const newHeight = Number(event.data.height); const iframes = document.getElementsByTagName("iframe"); for (let i = 0; i < iframes.length; i++) { const frame = iframes[i]; if (frame.contentWindow === event.source) { frame.style.height = `${Math.ceil(newHeight)}px`; break; } } } catch (_) { // Silently ignore errors } }; window.addEventListener("message", onNeetoCalHeightMessage); window.__neetoCalGlobalHeightListenerAdded = true; } window.neetoCal = { q: window.neetoCal?.q || [], embed: embedNeetoCal, embedFloatingPopupButton, }; neetoCal.q = neetoCal.q?.filter( args => embedNeetoCal.apply(null, args) && false ); })();