{"version":3,"file":"creative-side.cjs","sources":["../../src/utils/messaging.ts","../../src/types/index.ts","../../src/utils/logging.ts","../../src/advantage/messaging/creative-side.ts"],"sourcesContent":["import { AdvantageMessage, ADVANTAGE_MESSAGE } from \"../types\";\n\nexport const ADVANTAGE = \"ADVANTAGE\" as ADVANTAGE_MESSAGE;\n\n/**\n * Sends a message and opens a message channel to receive the reply.\n * @param message - The message to send.\n * @param retryInterval - The interval (in milliseconds) between retry attempts. Default is 100ms.\n * @param maxAttempts - The maximum number of retry attempts. Default is 25.\n * @returns A promise that resolves with the reply and the message channel.\n */\nexport function sendMessageAndOpenChannel(\n    message: Partial<AdvantageMessage>,\n    retryInterval: number = 200,\n    maxAttempts: number = 25\n): Promise<{ reply: AdvantageMessage; messageChannel: MessageChannel }> {\n    let attempts = 0;\n    let replyReceived = false;\n\n    const getTargetWindow = (currentWindow: Window = window) => {\n        let targetWindow: Window = currentWindow;\n        try {\n            while (currentWindow !== window.top && currentWindow.document) {\n                targetWindow = currentWindow;\n                currentWindow = currentWindow.parent;\n            }\n        } catch (error) {\n            return targetWindow;\n        }\n        return targetWindow;\n    };\n\n    const createMessageContext = (\n        targetWindow: Window,\n        message: Partial<AdvantageMessage>\n    ) => {\n        const avic = targetWindow.document\n            .querySelector(\"[id^=avic_]\")\n            ?.id.replace(\"avic_\", \"\");\n        const qemid =\n            targetWindow.document.querySelector<HTMLElement>(\n                \"[data-jcp-qem-id]\"\n            )?.dataset.jcpQemId;\n        const targetingMap = targetWindow.ucTagData?.targetingMap;\n        const origins = Array.from([\n            ...(targetWindow.location.ancestorOrigins || []),\n            targetWindow.location.origin\n        ]);\n        const backgroundAdURL = location.href;\n\n        return {\n            ...message,\n            gqid: avic || qemid,\n            targetingMap: targetingMap,\n            origins: origins,\n            backgroundAdURL: backgroundAdURL\n        };\n    };\n\n    return new Promise((resolve, reject) => {\n        // Define a function that we'll call to send the message\n        const sendMessage = (messageWithContext: Partial<AdvantageMessage>) => {\n            attempts++;\n            // Create a new MessageChannel for each attempt\n            const channel = new MessageChannel();\n\n            // Define the response listener\n            channel.port1.onmessage = (event: MessageEvent) => {\n                // Check if this is the response we're waiting for\n                if (\n                    event.data.type === ADVANTAGE &&\n                    event.data.sessionID === message.sessionID\n                ) {\n                    replyReceived = true;\n\n                    resolve({\n                        reply: event.data as AdvantageMessage,\n                        messageChannel: channel\n                    });\n                }\n            };\n\n            window.top?.postMessage(messageWithContext, \"*\", [channel.port2]);\n        };\n\n        // try to find direct child window under top window\n        const targetWindow = getTargetWindow();\n        const messageWithContext = createMessageContext(targetWindow, message);\n\n        // Send the first message\n        sendMessage(messageWithContext);\n\n        // Set up the retry interval\n        const retryIntervalRef = setInterval(() => {\n            if (attempts < maxAttempts && !replyReceived) {\n                sendMessage(messageWithContext);\n            } else {\n                // Clean up and reject promise\n                clearInterval(retryIntervalRef);\n                if (!replyReceived) {\n                    reject(new Error(\"Max attempts reached without response\"));\n                }\n            }\n        }, retryInterval);\n    });\n}\n\n/**\n * Sends a message and awaits a response.\n *\n * @param message - The message to send.\n * @param messageChannel - The message channel to use for communication.\n * @param timeout - The timeout in milliseconds.\n * @returns A promise that resolves with the response message.\n */\nexport function sendMessageAndAwaitResponse(\n    message: Partial<AdvantageMessage>,\n    messageChannel: MessageChannel,\n    timeout: number\n): Promise<AdvantageMessage> {\n    return new Promise((resolve, reject) => {\n        const timeoutID = setTimeout(() => {\n            reject(new Error(\"Timeout reached without response\"));\n        }, timeout);\n\n        const responseListener = (event: MessageEvent) => {\n            if (\n                event.data.type === ADVANTAGE &&\n                event.data.sessionID === message.sessionID\n            ) {\n                clearTimeout(timeoutID);\n                messageChannel.port1.removeEventListener(\n                    \"message\",\n                    responseListener\n                );\n                resolve(event.data as AdvantageMessage);\n            }\n        };\n\n        messageChannel.port1.onmessage = responseListener;\n        messageChannel.port1.postMessage(message);\n    });\n}\n","export type ADVANTAGE_MESSAGE = \"ADVANTAGE\";\n\nexport enum AdvantageMessageAction {\n    START_SESSION = \"START_SESSION\",\n    CONFIRM_SESSION = \"CONFIRM_SESSION\",\n    REQUEST_FORMAT = \"REQUEST_FORMAT\",\n    FORMAT_CONFIRMED = \"FORMAT_CONFIRMED\",\n    FORMAT_REJECTED = \"FORMAT_REJECTED\",\n    SCROLL_PROGRESS = \"SCROLL_PROGRESS\"\n}\n\nexport enum AdvantageFormatName {\n    TopScroll = \"TOPSCROLL\",\n    DoubleMidscroll = \"DOUBLE_MIDSCROLL\",\n    DoubleMidscrollSingleCreative = \"DOUBLE_MIDSCROLL_SINGLE_CREATIVE\",\n    Midscroll = \"MIDSCROLL\",\n    TripleMidscroll = \"TRIPLE_MIDSCROLL\",\n    WelcomePage = \"WELCOME_PAGE\"\n}\n\nexport interface AdvantageAd {\n    eventSource: MessageEventSource;\n    port: MessagePort;\n    iframe?: HTMLElement;\n}\n\nexport interface AdvantageConfig {\n    configUrlResolver?: () => string;\n    formats?: AdvantageFormat[];\n    formatIntegrations?: AdvantageFormatIntegration[];\n    messageValidator?: (\n        parentElement: HTMLElement | IAdvantageWrapper,\n        message: MessageEvent<any>\n    ) => boolean;\n}\n\nexport interface IAdvantageWrapper extends HTMLElement {\n    container: HTMLElement;\n    content: HTMLElement;\n    currentFormat?: AdvantageFormatName | string;\n    uiLayer: IAdvantageUILayer;\n    contentNodes: Node[];\n    allowedFormats: string[] | null;\n    morphIntoFormat: (\n        format: AdvantageFormatName | string,\n        message?: AdvantageMessage\n    ) => Promise<void>;\n    forceFormat: (\n        format: AdvantageFormatName | string,\n        iframe?: HTMLIFrameElement,\n        options?: any\n    ) => Promise<void>;\n    applyStylesToAllChildElements: (styles: string) => void;\n    insertCSS: (CSS: string) => void;\n    resetCSS: () => void;\n    reset: () => void;\n    close: () => void;\n    changeContent: (content: string | HTMLElement) => void;\n    simulateFormat: (format: AdvantageFormatName | string) => Promise<void>;\n    animateClose: (callback?: () => void) => void;\n    setAllowedFormats: (formats: string[]) => void;\n    clearAllowedFormats: () => void;\n}\n\nexport interface IAdvantageUILayer extends HTMLElement {\n    changeContent: (content: string | HTMLElement) => void;\n    insertCSS: (CSS: string) => void;\n    getSlottedElement: (selector: string) => HTMLElement | null;\n    getAllSlottedElements: (selector: string) => HTMLElement[];\n    querySlottedElements: (selector: string) => HTMLElement[];\n}\n\nexport interface AdvantageFormat {\n    name: AdvantageFormatName | string;\n    description: string;\n    setup: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLElement,\n        options?: AdvantageFormatOptions\n    ) => Promise<void>;\n    reset: (wrapper: IAdvantageWrapper, adIframe?: HTMLElement) => void;\n    close?: (wrapper: IAdvantageWrapper, adIframe?: HTMLElement) => void;\n    simulate?: (wrapper: IAdvantageWrapper) => void;\n}\n\nexport interface AdvantageFormatOptions {\n    closeButton?: boolean;\n    closeButtonText?: string;\n    closeButtonAnimationDuration?: number;\n    downArrow?: boolean;\n    height?: number;\n    sessionID?: string;\n    /**\n     * The duration in seconds before the format closes automatically.\n     * If set to 0, the format will not close automatically.\n     *\n     * @type {number}\n     * @defult 12\n     */\n    autoCloseDuration?: number;\n    /**\n     * You can customize this item to replace the default site title.\n     * When set to `false`, title will be hidden. Useful when you have customize `continueToLabel`.\n     *\n     * @type {(string | boolean)}\n     * @default window.location.hostname\n     */\n    siteTitle?: string | boolean;\n    /**\n     * Logo file to display in Welcome page header bar, right before the `continueToLabel`. Accepts a path string to the image.\n     * If not set, current sites favicon will be displayed.\n     * If set to `false`, logo will be hidden.\n     *\n     * @type {string | boolean}\n     * @default https://icons.duckduckgo.com/ip3/[hostname].ico\n     */\n    logo?: string;\n    scrollBackToTop?: boolean;\n    adLabel?: string;\n    /**\n     * Can be used to customize the label of the continue to site\n     * @defaul Continue to */\n    continueToLabel?: string;\n    /**\n     * URL to the background ad. Only used in the Double Midscroll format.\n     * This is set from the foreground ad.\n     */\n    backgroundAdURL?: string;\n    allowedOrigins?: string[];\n    dangerouslyAllowAllOrigins?: boolean;\n}\n\nexport interface AdvantageFormatIntegration {\n    format: AdvantageFormatName | string;\n    options?: AdvantageFormatOptions;\n    setup: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => Promise<void>;\n    teardown?: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => void;\n    close?: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => void;\n    reset?: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => void;\n    /** @deprecated use close */\n    onClose?: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => void;\n    /** @deprecated use reset */\n    onReset?: (\n        wrapper: IAdvantageWrapper,\n        adIframe?: HTMLIFrameElement | HTMLElement\n    ) => void;\n}\n\nexport interface AdvantageMessage {\n    sessionID: string;\n    type: ADVANTAGE_MESSAGE;\n    action: AdvantageMessageAction;\n    format?: AdvantageFormatName;\n    origins?: string[];\n    gqid?: string;\n    targetingMap?: { [key: string]: string[] };\n    backgroundAdURL?: string;\n}\n","type LogLevel = \"log\" | \"info\" | \"error\";\n\nclass Logger {\n    private debugMode: boolean;\n    private style: string =\n        \"color: #f3f1ff; font-weight: bold; background-color: #6b04fd; padding: 2px; border-radius: 2px;\";\n\n    constructor() {\n        this.debugMode = new URLSearchParams(window.location.search).has(\n            \"adv_debug\"\n        );\n    }\n\n    private formatMessage(level: LogLevel): string {\n        const timestamp = new Date().toISOString();\n        return `${timestamp} [${level.toUpperCase()}] %cADVANTAGE`;\n    }\n\n    private log(level: LogLevel, message: any, ...optionalParams: any) {\n        if (this.debugMode) {\n            console[level](\n                this.formatMessage(level),\n                this.style,\n                `- ${message}`,\n                ...optionalParams\n            );\n            if (level === \"error\") {\n                console.trace();\n            }\n        }\n    }\n\n    debug(message: any, ...optionalParams: any) {\n        this.log(\"log\", message, ...optionalParams);\n    }\n\n    info(message: any, ...optionalParams: any) {\n        this.log(\"info\", message, ...optionalParams);\n    }\n\n    error(message: any, ...optionalParams: any) {\n        this.log(\"error\", message, ...optionalParams);\n    }\n\n    /**\n     * Enables debug mode for logging.\n     */\n    enableDebugMode() {\n        this.debugMode = true;\n    }\n}\n\nconst logger = new Logger();\nexport default logger;\n","import {\n    sendMessageAndOpenChannel,\n    sendMessageAndAwaitResponse\n} from \"../../utils/messaging\";\nimport {\n    AdvantageMessage,\n    AdvantageMessageAction,\n    AdvantageFormatName\n} from \"../../types\";\nexport { AdvantageMessageAction, AdvantageFormatName };\nimport logger from \"../../utils/logging\";\n\n/**\n * AdvantageCreativeMessenger is the class that should be used in creative ads to communicate with Advantage on the publisher side. This class is used to request formats and other information from the parent website.\n * @public\n *\n * @example\n * Here's an example on how to request a format from the parent website and then start the ad when the format is confirmed:\n *\n * ::: code-group\n * ```typescript\n * const advantageMessenger = new AdvantageCreativeMessenger();\n * const session = await advantageMessenger.startSession();\n *\n * if (session) {\n *  // Request the midscroll format\n *  const response = await advantageMessenger.sendMessage({\n *      action: AdvantageMessageAction.REQUEST_FORMAT,\n *      format: AdvantageFormatName.Midscroll\n *  });\n *  // The format is confirmed, start the ad\n *  if (response?.action === AdvantageMessageAction.FORMAT_CONFIRMED) {\n *      document.body.classList.add(\"midscroll\");\n *  }\n * } else {\n *      console.log(\"Session failed to start\");\n * }\n * ```\n * ```javascript\n * const advantageMessenger = new AdvantageCreativeMessenger();\n * advantageMessenger.startSession().then((confirmed) => {\n *  if (confirmed) {\n *      advantageMessenger.sendMessage({\n *          action: \"REQUEST_FORMAT\",\n *          format: \"MIDSCROLL\"\n *      }).then((response) => {\n *          if (response.action === \"FORMAT_CONFIRMED\") {\n *              // The format is confirmed, start the ad\n *              document.body.classList.add(\"midscroll\");\n *          }\n *      });\n *  } else {\n *     console.log(\"Session failed to start\");\n *  }\n * });\n * ```\n */\nexport class AdvantageCreativeMessenger {\n    #messageChannel: MessageChannel | null = null;\n    #sessionID: string;\n    #validSession = false;\n    #broadcastChannel: BroadcastChannel | null = null;\n\n    constructor() {\n        // check if its a sessionId in the URL, if not create a new one\n        const urlParams = new URLSearchParams(window.location.search);\n        const sessionId = urlParams.get(\"sessionId\");\n        if (sessionId) {\n            this.#sessionID = sessionId;\n            this.#validSession = true;\n        } else {\n            // Create a new session ID\n            // This is a random string that will be used to identify the session\n            this.#sessionID = Math.random().toString(36).substring(2, 15);\n        }\n    }\n\n    async startSession(): Promise<boolean> {\n        try {\n            const { messageChannel, reply } = await sendMessageAndOpenChannel({\n                type: \"ADVANTAGE\",\n                action: AdvantageMessageAction.START_SESSION,\n                sessionID: this.#sessionID\n            });\n            this.#messageChannel = messageChannel;\n            this.#validSession =\n                reply.action === AdvantageMessageAction.CONFIRM_SESSION;\n            return this.#validSession;\n        } catch (e) {\n            this.#validSession = false;\n            return false;\n        }\n    }\n\n    async sendMessage(message: Partial<AdvantageMessage>) {\n        if (!this.#validSession || !this.#messageChannel) {\n            throw new Error(\"There is no valid session to send messages to.\");\n        }\n        try {\n            const response = await sendMessageAndAwaitResponse(\n                {\n                    ...message,\n                    sessionID: this.#sessionID,\n                    type: \"ADVANTAGE\"\n                },\n                this.#messageChannel,\n                1000\n            );\n\n            return response;\n        } catch (e) {\n            logger.error(\"Error sending message\", e);\n        }\n    }\n\n    onMessage(callback: (message: AdvantageMessage) => void) {\n        if (!this.#messageChannel) {\n            throw new Error(\"No message port available\");\n        }\n        this.#messageChannel.port1.addEventListener(\n            \"message\",\n            (event: MessageEvent) => {\n                callback(event.data as AdvantageMessage);\n            }\n        );\n    }\n\n    setupWaypoints(waypoints: HTMLElement[]): { disconnect: () => void } {\n        if (!this.#validSession) {\n            throw new Error(\"There is no valid session to send messages to.\");\n        }\n\n        this.#broadcastChannel = new BroadcastChannel(this.#sessionID);\n\n        // Setup Intersection Observer\n        const observer = new IntersectionObserver((entries) => {\n            entries.forEach((entry) => {\n                const waypointId = (entry.target as HTMLElement).dataset.id;\n                const isIntersecting = entry.isIntersecting;\n\n                // Broadcast waypoint status\n                this.#broadcastChannel!.postMessage({\n                    type: \"waypoint\",\n                    waypointId,\n                    isIntersecting\n                });\n            });\n        });\n\n        // Observe each waypoint\n        waypoints.forEach((waypoint) => observer.observe(waypoint));\n\n        return {\n            disconnect: () => {\n                observer.disconnect();\n                this.#broadcastChannel!.close();\n            }\n        };\n    }\n\n    listenToWaypoints(\n        onWaypointTrigger: (waypointId: string, isIntersecting: boolean) => void\n    ): { disconnect: () => void } {\n        if (!this.#validSession) {\n            throw new Error(\"No valid session available.\");\n        }\n\n        // Create a new BroadcastChannel for this context\n        this.#broadcastChannel = new BroadcastChannel(this.#sessionID);\n\n        const listener = (event: MessageEvent) => {\n            const { waypointId, isIntersecting } = event.data;\n            if (waypointId !== undefined && isIntersecting !== undefined) {\n                onWaypointTrigger(waypointId, isIntersecting);\n            }\n        };\n\n        //this.#broadcastChannel.onmessage = listener;\n        this.#broadcastChannel.addEventListener(\"message\", (event) => {\n            listener(event);\n        });\n\n        return {\n            disconnect: () => this.#broadcastChannel!.close()\n        };\n    }\n}\n"],"names":["ADVANTAGE","sendMessageAndOpenChannel","message","retryInterval","maxAttempts","attempts","replyReceived","getTargetWindow","currentWindow","targetWindow","createMessageContext","avic","_a","qemid","_b","targetingMap","_c","origins","backgroundAdURL","resolve","reject","sendMessage","messageWithContext","channel","event","retryIntervalRef","sendMessageAndAwaitResponse","messageChannel","timeout","timeoutID","responseListener","AdvantageMessageAction","AdvantageFormatName","Logger","__publicField","level","optionalParams","logger","AdvantageCreativeMessenger","__privateAdd","_messageChannel","_sessionID","_validSession","_broadcastChannel","sessionId","__privateSet","reply","__privateGet","e","callback","waypoints","observer","entries","entry","waypointId","isIntersecting","waypoint","onWaypointTrigger","listener"],"mappings":"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"}