diff --git a/src/components/Personalization/in-app-message-actions/actions/displayIframeContent.js b/src/components/Personalization/in-app-message-actions/actions/displayIframeContent.js index d15701050..f06693d49 100644 --- a/src/components/Personalization/in-app-message-actions/actions/displayIframeContent.js +++ b/src/components/Personalization/in-app-message-actions/actions/displayIframeContent.js @@ -87,35 +87,27 @@ export const createIframe = (htmlContent, clickHandler) => { return element; }; -const renderElement = (iframe, webParameters, container, overlay) => { - const { style: iframeStyle = {} } = webParameters[ALLOY_IFRAME_ID]; - const { - style: messagingStyle = {}, - params: messagingParams = {} - } = webParameters[ALLOY_MESSAGING_CONTAINER_ID]; - - const { - style: overlayStyle = {}, - params: overlayParams = {} - } = webParameters[ALLOY_OVERLAY_CONTAINER_ID]; - - assign(iframe.style, iframeStyle); - assign(container.style, messagingStyle); - - const { enabled = true } = overlayParams; - if (enabled) { - assign(overlay.style, overlayStyle); - document.body.appendChild(overlay); - document.body.style.overflow = "hidden"; - } - - const { - paramElement = "body", - insertionMethod = "appendChild" - } = messagingParams; - - const element = document.querySelector(paramElement); - element[insertionMethod](container); +const renderMessage = (iframe, webParameters, container, overlay) => { + [ + { id: ALLOY_OVERLAY_CONTAINER_ID, element: overlay }, + { id: ALLOY_MESSAGING_CONTAINER_ID, element: container }, + { id: ALLOY_IFRAME_ID, element: iframe } + ].forEach(({ id, element }) => { + const { style = {}, params = {} } = webParameters[id]; + + assign(element.style, style); + + const { + parentElement = "body", + insertionMethod = "appendChild", + enabled = true + } = params; + + const parent = document.querySelector(parentElement); + if (enabled && parent && typeof parent[insertionMethod] === "function") { + parent[insertionMethod](element); + } + }); }; export const buildStyleFromMobileParameters = mobileParameters => { @@ -188,41 +180,85 @@ export const mobileOverlay = mobileParameters => { return style; }; +const isValidWebParameters = webParameters => { + if (!webParameters) { + return false; + } + + const ids = Object.keys(webParameters); + + if (!ids.includes(ALLOY_MESSAGING_CONTAINER_ID)) { + return false; + } + + if (!ids.includes(ALLOY_OVERLAY_CONTAINER_ID)) { + return false; + } + + const values = Object.values(webParameters); + + for (let i = 0; i < values.length; i += 1) { + if (!Object.prototype.hasOwnProperty.call(values[i], "style")) { + return false; + } + } + + return true; +}; + +const generateWebParameters = mobileParameters => { + const { uiTakeover = false } = mobileParameters; + + return { + [ALLOY_IFRAME_ID]: { + style: { + border: "none", + width: "100%", + height: "100%" + }, + params: { + enabled: true, + parentElement: "#alloy-messaging-container", + insertionMethod: "appendChild" + } + }, + [ALLOY_MESSAGING_CONTAINER_ID]: { + style: buildStyleFromMobileParameters(mobileParameters), + params: { + enabled: true, + parentElement: "body", + insertionMethod: "appendChild" + } + }, + [ALLOY_OVERLAY_CONTAINER_ID]: { + style: mobileOverlay(mobileParameters), + params: { + enabled: uiTakeover === true, + parentElement: "body", + insertionMethod: "appendChild" + } + } + }; +}; + export const displayHTMLContentInIframe = (settings, interact) => { dismissMessage(); - const { content, contentType, mobileParameters, webParameters } = settings; + const { content, contentType, mobileParameters } = settings; + let { webParameters } = settings; if (contentType !== TEXT_HTML) { return; } const container = createElement(ALLOY_MESSAGING_CONTAINER_ID); - const iframe = createIframe(content, createIframeClickHandler(interact)); - const overlay = createElement(ALLOY_OVERLAY_CONTAINER_ID); - container.appendChild(iframe); - if (webParameters && webParameters.info !== "this is a placeholder") { - renderElement(iframe, webParameters, container, overlay); - } else { - assign(webParameters, { - "alloy-content-iframe": { - style: { - border: "none", - width: "100%", - height: "100%" - } - }, - "alloy-messaging-container": { - style: buildStyleFromMobileParameters(mobileParameters) - }, - "alloy-overlay-container": { - style: mobileOverlay(mobileParameters) - } - }); - renderElement(iframe, webParameters, container, overlay); + if (!isValidWebParameters(webParameters)) { + webParameters = generateWebParameters(mobileParameters); } + + renderMessage(iframe, webParameters, container, overlay); }; export default (settings, collect) => { diff --git a/test/unit/specs/components/Personalization/in-app-message-actions/actions/displayIframeContent.spec.js b/test/unit/specs/components/Personalization/in-app-message-actions/actions/displayIframeContent.spec.js index dc94f48c9..92e4fa42c 100644 --- a/test/unit/specs/components/Personalization/in-app-message-actions/actions/displayIframeContent.spec.js +++ b/test/unit/specs/components/Personalization/in-app-message-actions/actions/displayIframeContent.spec.js @@ -326,7 +326,6 @@ describe("DOM Actions on Iframe", () => { displayHTMLContentInIframe(settings, mockCollect); expect(document.body.appendChild).toHaveBeenCalledTimes(2); - expect(document.body.style.overflow).toBe("hidden"); }); it("should display HTML content in iframe with overlay using web parameters", () => { @@ -373,6 +372,11 @@ describe("DOM Actions on Iframe", () => { style: { width: "100%", height: "100%" + }, + params: { + enabled: true, + parentElement: "#alloy-messaging-container", + insertionMethod: "appendChild" } } }, @@ -384,11 +388,9 @@ describe("DOM Actions on Iframe", () => { displayHTMLContentInIframe(settings, mockCollect); expect(document.body.appendChild).toHaveBeenCalledTimes(2); - expect(document.body.style.overflow).toBe("hidden"); }); it("should display HTML content in iframe with no overlay using web parameters", () => { const settings = { - type: "custom", webParameters: { "alloy-overlay-container": { style: { @@ -430,6 +432,11 @@ describe("DOM Actions on Iframe", () => { style: { width: "100%", height: "100%" + }, + params: { + enabled: true, + parentElement: "#alloy-messaging-container", + insertionMethod: "appendChild" } } },