@mochabug/adapt-sdk 0.3.7 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/browser.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var c=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var _=(e,t)=>{for(var n in t)c(e,n,{get:t[n],enumerable:!0})},N=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of P(t))!U.call(e,o)&&o!==n&&c(e,o,{get:()=>t[o],enumerable:!(i=I(t,o))||i.enumerable});return e};var j=e=>N(c({},"__esModule",{value:!0}),e);var $={};_($,{getToken:()=>V,init:()=>Y});module.exports=j($);var d=null;function V(e=!1){if(e)return"dev-token";if(d!==null)return d;if(typeof window>"u"||typeof location>"u")throw new Error("getToken() is only available in browser environments");let t=location.hash.slice(1);if(!t)throw new Error("No token found in URL hash");let n=new URLSearchParams(t).get("mb_token");if(!n)throw new Error('Token "mb_token" not found in URL hash');return d=decodeURIComponent(n),d}function y(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Z(e){return y(e)&&e.type==="adapt-darkMode"&&typeof e.darkMode=="boolean"}function q(e){return y(e)&&e.type==="adapt-autoResizing"&&typeof e.autoResizing=="boolean"}function z(e){return Number.isFinite(e)&&e>=1}function G(e){return y(e)&&typeof e.postMessage=="function"}function w(){return typeof window<"u"&&typeof document<"u"&&typeof window.postMessage=="function"}function v(){if(!w())return!1;try{return window.self!==window.top}catch{return!0}}var l=-1,a=-1,h=-1,g=-1,f=null,J=16,m=0,K=5;function E(){let{body:e,documentElement:t}=document;if(!e)return null;let n=getComputedStyle(e),i=parseFloat(n.marginTop)||0,o=parseFloat(n.marginBottom)||0,L=parseFloat(n.marginLeft)||0,B=parseFloat(n.marginRight)||0,r=getComputedStyle(t),F=parseFloat(r.paddingTop)||0,W=parseFloat(r.paddingBottom)||0,A=parseFloat(r.paddingLeft)||0,S=parseFloat(r.paddingRight)||0,x=parseFloat(r.borderTopWidth)||0,H=parseFloat(r.borderBottomWidth)||0,O=parseFloat(r.borderLeftWidth)||0,C=parseFloat(r.borderRightWidth)||0,u=Math.max(e.scrollHeight,e.offsetHeight),D=Math.max(e.scrollWidth,e.offsetWidth),M=u+i+o+F+W+x+H,k=D+L+B+A+S+O+C,R=t.scrollWidth>t.clientWidth?Math.max(0,window.innerHeight-t.clientHeight):0;return!z(k)||!z(M+R)||m>=K&&g>0&&Math.abs(u-a)<=2?null:(g=u,{width:k,height:M+R+
|
|
1
|
+
"use strict";var c=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var _=(e,t)=>{for(var n in t)c(e,n,{get:t[n],enumerable:!0})},N=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of P(t))!U.call(e,o)&&o!==n&&c(e,o,{get:()=>t[o],enumerable:!(i=I(t,o))||i.enumerable});return e};var j=e=>N(c({},"__esModule",{value:!0}),e);var $={};_($,{getToken:()=>V,init:()=>Y});module.exports=j($);var d=null;function V(e=!1){if(e)return"dev-token";if(d!==null)return d;if(typeof window>"u"||typeof location>"u")throw new Error("getToken() is only available in browser environments");let t=location.hash.slice(1);if(!t)throw new Error("No token found in URL hash");let n=new URLSearchParams(t).get("mb_token");if(!n)throw new Error('Token "mb_token" not found in URL hash');return d=decodeURIComponent(n),d}function y(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Z(e){return y(e)&&e.type==="adapt-darkMode"&&typeof e.darkMode=="boolean"}function q(e){return y(e)&&e.type==="adapt-autoResizing"&&typeof e.autoResizing=="boolean"}function z(e){return Number.isFinite(e)&&e>=1}function G(e){return y(e)&&typeof e.postMessage=="function"}function w(){return typeof window<"u"&&typeof document<"u"&&typeof window.postMessage=="function"}function v(){if(!w())return!1;try{return window.self!==window.top}catch{return!0}}var l=-1,a=-1,h=-1,g=-1,f=null,J=16,m=0,K=5;function E(){let{body:e,documentElement:t}=document;if(!e)return null;let n=getComputedStyle(e),i=parseFloat(n.marginTop)||0,o=parseFloat(n.marginBottom)||0,L=parseFloat(n.marginLeft)||0,B=parseFloat(n.marginRight)||0,r=getComputedStyle(t),F=parseFloat(r.paddingTop)||0,W=parseFloat(r.paddingBottom)||0,A=parseFloat(r.paddingLeft)||0,S=parseFloat(r.paddingRight)||0,x=parseFloat(r.borderTopWidth)||0,H=parseFloat(r.borderBottomWidth)||0,O=parseFloat(r.borderLeftWidth)||0,C=parseFloat(r.borderRightWidth)||0,u=Math.max(e.scrollHeight,e.offsetHeight),D=Math.max(e.scrollWidth,e.offsetWidth),M=u+i+o+F+W+x+H,k=D+L+B+A+S+O+C,R=t.scrollWidth>t.clientWidth?Math.max(0,window.innerHeight-t.clientHeight):0;return!z(k)||!z(M+R)||m>=K&&g>0&&Math.abs(u-a)<=2?null:(g=u,{width:k,height:M+R+2})}function s(){if(!w()||!v())return;let e=window.parent;if(!G(e))return;let t=document.body?Math.max(document.body.scrollWidth,document.body.offsetWidth):0;t!==h&&h!==-1&&(m=0,g=-1),h=t;let n=E();if(!n)return;let{width:i,height:o}=n;if(!(i===l&&o===a)){l=i,a=o,m++;try{e.postMessage({type:"adapt-resize",width:i,height:o},"*")}catch{}}}function p(){f===null&&(f=setTimeout(()=>{f=null,s()},J))}function Q(){let e=E();if(!e){if(a>0)try{window.parent.postMessage({type:"adapt-resize",width:l,height:a},"*")}catch{}return}let{width:t,height:n}=e;l=t,a=n;try{window.parent.postMessage({type:"adapt-resize",width:t,height:n},"*")}catch{}}var b=null;function X(e){let t;try{t=e.data}catch{return}if(Z(t)&&b)try{b(t.darkMode)}catch{}q(t)&&t.autoResizing&&Q()}var T=!1;function Y(e={}){if(T)throw new Error("init() has already been called");if(T=!0,!w()||!v())return;let t=e.resize!==!1;b=e.onDarkMode??null,window.addEventListener("message",X);try{window.parent.postMessage({type:"adapt-init",resize:t},"*")}catch{}if(t){let n=document.createElement("style");n.textContent=`
|
|
2
2
|
html, body {
|
|
3
3
|
box-sizing: border-box;
|
|
4
4
|
}
|
package/dist/cjs/browser.cjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/browser/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Frontend utilities for Adapt plugins running in browser/iframe contexts\n *\n * Plugins must call `init()` to set up iframe communication with the parent.\n * The `init()` function sends an `adapt-init` message to the parent and optionally\n * sets up content-based resizing.\n */\n\n// =============================================================================\n// Token Management\n// =============================================================================\n\nlet cachedToken: string | null = null;\n\n/**\n * Get the authentication token from the URL hash.\n * @param isDevelopment If true, returns a dev token for local development\n */\nexport function getToken(isDevelopment = false): string {\n if (isDevelopment) return 'dev-token';\n if (cachedToken !== null) return cachedToken;\n\n if (typeof window === 'undefined' || typeof location === 'undefined') {\n throw new Error('getToken() is only available in browser environments');\n }\n\n const hash = location.hash.slice(1);\n if (!hash) throw new Error('No token found in URL hash');\n\n const token = new URLSearchParams(hash).get('mb_token');\n if (!token) throw new Error('Token \"mb_token\" not found in URL hash');\n\n cachedToken = decodeURIComponent(token);\n return cachedToken;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AdaptInitMessage {\n type: 'adapt-init';\n resize: boolean;\n}\n\ninterface AdaptResizeMessage {\n type: 'adapt-resize';\n width: number;\n height: number;\n}\n\ninterface AdaptDarkModeMessage {\n type: 'adapt-darkMode';\n darkMode: boolean;\n}\n\ninterface AdaptAutoResizingMessage {\n type: 'adapt-autoResizing';\n autoResizing: boolean;\n}\n\nexport interface InitOptions {\n /** Whether the plugin supports content-based resizing. Default: true */\n resize?: boolean;\n /** Callback invoked when dark mode state changes from parent */\n onDarkMode?: (darkMode: boolean) => void;\n}\n\n// =============================================================================\n// Internal: Type Guards & Helpers\n// =============================================================================\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isDarkModeMessage(data: unknown): data is AdaptDarkModeMessage {\n return (\n isObject(data) &&\n data.type === 'adapt-darkMode' &&\n typeof data.darkMode === 'boolean'\n );\n}\n\nfunction isAutoResizingMessage(\n data: unknown\n): data is AdaptAutoResizingMessage {\n return (\n isObject(data) &&\n data.type === 'adapt-autoResizing' &&\n typeof data.autoResizing === 'boolean'\n );\n}\n\nfunction isValidDimension(value: number): boolean {\n return Number.isFinite(value) && value >= 1;\n}\n\nfunction hasPostMessage(\n obj: unknown\n): obj is { postMessage: typeof postMessage } {\n return isObject(obj) && typeof obj.postMessage === 'function';\n}\n\n// =============================================================================\n// Internal: Environment Detection\n// =============================================================================\n\nfunction isBrowser(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined' &&\n typeof window.postMessage === 'function'\n );\n}\n\nfunction isInIframe(): boolean {\n if (!isBrowser()) return false;\n try {\n return window.self !== window.top;\n } catch {\n return true;\n }\n}\n\n// =============================================================================\n// Internal: Resize Logic\n// =============================================================================\n\nlet lastSentWidth = -1;\nlet lastSentHeight = -1;\nlet lastBodyWidth = -1; // Track body width separately for change detection\nlet lastBodyHeight = -1;\nlet throttleTimer: ReturnType<typeof setTimeout> | null = null;\nconst THROTTLE_MS = 16;\nlet resizeCount = 0;\nconst RESIZE_SETTLE_COUNT = 5;\n\nfunction getContentDimensions(): { width: number; height: number } | null {\n const { body, documentElement: html } = document;\n if (!body) return null;\n\n // Get computed styles for body margin\n // body.scrollHeight/offsetHeight include padding and border but NOT margin\n const bodyStyle = getComputedStyle(body);\n const bodyMarginTop = parseFloat(bodyStyle.marginTop) || 0;\n const bodyMarginBottom = parseFloat(bodyStyle.marginBottom) || 0;\n const bodyMarginLeft = parseFloat(bodyStyle.marginLeft) || 0;\n const bodyMarginRight = parseFloat(bodyStyle.marginRight) || 0;\n\n // Get computed styles for html element padding and border\n // html padding creates space around the body, html border adds to outer edge\n const htmlStyle = getComputedStyle(html);\n const htmlPaddingTop = parseFloat(htmlStyle.paddingTop) || 0;\n const htmlPaddingBottom = parseFloat(htmlStyle.paddingBottom) || 0;\n const htmlPaddingLeft = parseFloat(htmlStyle.paddingLeft) || 0;\n const htmlPaddingRight = parseFloat(htmlStyle.paddingRight) || 0;\n const htmlBorderTop = parseFloat(htmlStyle.borderTopWidth) || 0;\n const htmlBorderBottom = parseFloat(htmlStyle.borderBottomWidth) || 0;\n const htmlBorderLeft = parseFloat(htmlStyle.borderLeftWidth) || 0;\n const htmlBorderRight = parseFloat(htmlStyle.borderRightWidth) || 0;\n\n // Calculate total dimensions:\n // body content (scrollHeight/offsetHeight includes body padding + border)\n // + body margin (space between body and html's inner edge)\n // + html padding (space between html's inner edge and body)\n // + html border (html element's border)\n const bodyHeight = Math.max(body.scrollHeight, body.offsetHeight);\n const bodyWidth = Math.max(body.scrollWidth, body.offsetWidth);\n\n const height =\n bodyHeight +\n bodyMarginTop +\n bodyMarginBottom +\n htmlPaddingTop +\n htmlPaddingBottom +\n htmlBorderTop +\n htmlBorderBottom;\n\n const width =\n bodyWidth +\n bodyMarginLeft +\n bodyMarginRight +\n htmlPaddingLeft +\n htmlPaddingRight +\n htmlBorderLeft +\n htmlBorderRight;\n\n // Account for horizontal scrollbar height \u2014 when content overflows horizontally,\n // the browser adds a scrollbar that eats vertical space. body.scrollHeight\n // doesn't include this, so the reported height would be too short.\n const hasHScrollbar = html.scrollWidth > html.clientWidth;\n const scrollbarHeight = hasHScrollbar\n ? Math.max(0, window.innerHeight - html.clientHeight)\n : 0;\n\n if (!isValidDimension(width) || !isValidDimension(height + scrollbarHeight))\n return null;\n\n // Feedback loop detection: detect when body is tracking the viewport height\n // If bodyHeight \u2248 lastSentHeight, the body expanded to fill the new iframe\n // This happens with min-height: 100vh or similar viewport-relative CSS\n if (\n resizeCount >= RESIZE_SETTLE_COUNT &&\n lastBodyHeight > 0 &&\n Math.abs(bodyHeight - lastSentHeight) <= 2\n ) {\n return null;\n }\n\n lastBodyHeight = bodyHeight;\n\n return { width, height: height + scrollbarHeight + 1 };\n}\n\nfunction sendResizeImmediate(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n const parent = window.parent;\n if (!hasPostMessage(parent)) return;\n\n // Check for width change BEFORE getting dims (to reset counters)\n const currentBodyWidth = document.body\n ? Math.max(document.body.scrollWidth, document.body.offsetWidth)\n : 0;\n if (currentBodyWidth !== lastBodyWidth && lastBodyWidth !== -1) {\n // Width changed (window resize) - reset counters to allow re-settling\n resizeCount = 0;\n lastBodyHeight = -1;\n }\n lastBodyWidth = currentBodyWidth;\n\n const dims = getContentDimensions();\n if (!dims) return;\n\n const { width, height } = dims;\n if (width === lastSentWidth && height === lastSentHeight) return;\n\n lastSentWidth = width;\n lastSentHeight = height;\n resizeCount++;\n\n try {\n parent.postMessage(\n { type: 'adapt-resize', width, height } satisfies AdaptResizeMessage,\n '*'\n );\n } catch {}\n}\n\nfunction sendResizeThrottled(): void {\n if (throttleTimer !== null) return;\n\n throttleTimer = setTimeout(() => {\n throttleTimer = null;\n sendResizeImmediate();\n }, THROTTLE_MS);\n}\n\nfunction sendResizeForced(): void {\n // Force sending current dimensions (don't reset tracking)\n const dims = getContentDimensions();\n if (!dims) {\n // If detection stopped us, send the last known dimensions\n if (lastSentHeight > 0) {\n try {\n window.parent.postMessage(\n {\n type: 'adapt-resize',\n width: lastSentWidth,\n height: lastSentHeight\n },\n '*'\n );\n } catch {}\n }\n return;\n }\n\n const { width, height } = dims;\n lastSentWidth = width;\n lastSentHeight = height;\n\n try {\n window.parent.postMessage({ type: 'adapt-resize', width, height }, '*');\n } catch {}\n}\n\n// =============================================================================\n// Internal: Message Handling\n// =============================================================================\n\nlet onDarkModeCallback: ((darkMode: boolean) => void) | null = null;\n\nfunction handleMessage(event: MessageEvent): void {\n let data: unknown;\n try {\n data = event.data;\n } catch {\n return;\n }\n\n if (isDarkModeMessage(data)) {\n if (onDarkModeCallback) {\n try {\n onDarkModeCallback(data.darkMode);\n } catch {}\n }\n }\n\n if (isAutoResizingMessage(data) && data.autoResizing) {\n // Parent requested auto-resizing - immediately send current dimensions\n sendResizeForced();\n }\n}\n\n// =============================================================================\n// Public API: init()\n// =============================================================================\n\nlet initialized = false;\n\n/**\n * Initialize the plugin's iframe communication with the parent.\n *\n * Must be called exactly once. Sends an `adapt-init` message to the parent\n * indicating whether this plugin supports content-based resizing.\n *\n * @param options.resize - Whether to enable content-based resizing (default: true)\n * @param options.onDarkMode - Callback invoked when dark mode state changes\n */\nexport function init(options: InitOptions = {}): void {\n if (initialized) {\n throw new Error('init() has already been called');\n }\n initialized = true;\n\n if (!isBrowser() || !isInIframe()) return;\n\n const resize = options.resize !== false;\n\n // Store dark mode callback\n onDarkModeCallback = options.onDarkMode ?? null;\n\n // Listen for messages from parent\n window.addEventListener('message', handleMessage);\n\n // Send adapt-init to parent\n try {\n window.parent.postMessage(\n { type: 'adapt-init', resize } satisfies AdaptInitMessage,\n '*'\n );\n } catch {}\n\n if (resize) {\n // Inject baseline CSS for consistent measurements\n const style = document.createElement('style');\n style.textContent = `\n html, body {\n box-sizing: border-box;\n }\n *, *::before, *::after {\n box-sizing: inherit;\n }\n `;\n document.head.appendChild(style);\n\n // Set up resize observation\n const resizeObserver = new ResizeObserver(sendResizeThrottled);\n if (document.body) resizeObserver.observe(document.body);\n if (document.documentElement)\n resizeObserver.observe(document.documentElement);\n\n // Set up mutation observation for DOM changes\n if (document.body) {\n const mutationObserver = new MutationObserver(sendResizeThrottled);\n mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true\n });\n }\n\n // Capture load events on resources (images, iframes, etc.)\n document.addEventListener('load', sendResizeThrottled, true);\n\n // Wait for fonts to load\n document.fonts?.ready?.then(() => {\n sendResizeImmediate();\n });\n\n // Send initial size when fully loaded\n if (document.readyState === 'complete') {\n sendResizeImmediate();\n } else {\n window.addEventListener('load', () => {\n sendResizeImmediate();\n });\n }\n\n // Send again with delays to handle timing issues\n setTimeout(sendResizeImmediate, 50);\n setTimeout(sendResizeImmediate, 150);\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * Frontend utilities for Adapt plugins running in browser/iframe contexts\n *\n * Plugins must call `init()` to set up iframe communication with the parent.\n * The `init()` function sends an `adapt-init` message to the parent and optionally\n * sets up content-based resizing.\n */\n\n// =============================================================================\n// Token Management\n// =============================================================================\n\nlet cachedToken: string | null = null;\n\n/**\n * Get the authentication token from the URL hash.\n * @param isDevelopment If true, returns a dev token for local development\n */\nexport function getToken(isDevelopment = false): string {\n if (isDevelopment) return 'dev-token';\n if (cachedToken !== null) return cachedToken;\n\n if (typeof window === 'undefined' || typeof location === 'undefined') {\n throw new Error('getToken() is only available in browser environments');\n }\n\n const hash = location.hash.slice(1);\n if (!hash) throw new Error('No token found in URL hash');\n\n const token = new URLSearchParams(hash).get('mb_token');\n if (!token) throw new Error('Token \"mb_token\" not found in URL hash');\n\n cachedToken = decodeURIComponent(token);\n return cachedToken;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AdaptInitMessage {\n type: 'adapt-init';\n resize: boolean;\n}\n\ninterface AdaptResizeMessage {\n type: 'adapt-resize';\n width: number;\n height: number;\n}\n\ninterface AdaptDarkModeMessage {\n type: 'adapt-darkMode';\n darkMode: boolean;\n}\n\ninterface AdaptAutoResizingMessage {\n type: 'adapt-autoResizing';\n autoResizing: boolean;\n}\n\nexport interface InitOptions {\n /** Whether the plugin supports content-based resizing. Default: true */\n resize?: boolean;\n /** Callback invoked when dark mode state changes from parent */\n onDarkMode?: (darkMode: boolean) => void;\n}\n\n// =============================================================================\n// Internal: Type Guards & Helpers\n// =============================================================================\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isDarkModeMessage(data: unknown): data is AdaptDarkModeMessage {\n return (\n isObject(data) &&\n data.type === 'adapt-darkMode' &&\n typeof data.darkMode === 'boolean'\n );\n}\n\nfunction isAutoResizingMessage(\n data: unknown\n): data is AdaptAutoResizingMessage {\n return (\n isObject(data) &&\n data.type === 'adapt-autoResizing' &&\n typeof data.autoResizing === 'boolean'\n );\n}\n\nfunction isValidDimension(value: number): boolean {\n return Number.isFinite(value) && value >= 1;\n}\n\nfunction hasPostMessage(\n obj: unknown\n): obj is { postMessage: typeof postMessage } {\n return isObject(obj) && typeof obj.postMessage === 'function';\n}\n\n// =============================================================================\n// Internal: Environment Detection\n// =============================================================================\n\nfunction isBrowser(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined' &&\n typeof window.postMessage === 'function'\n );\n}\n\nfunction isInIframe(): boolean {\n if (!isBrowser()) return false;\n try {\n return window.self !== window.top;\n } catch {\n return true;\n }\n}\n\n// =============================================================================\n// Internal: Resize Logic\n// =============================================================================\n\nlet lastSentWidth = -1;\nlet lastSentHeight = -1;\nlet lastBodyWidth = -1; // Track body width separately for change detection\nlet lastBodyHeight = -1;\nlet throttleTimer: ReturnType<typeof setTimeout> | null = null;\nconst THROTTLE_MS = 16;\nlet resizeCount = 0;\nconst RESIZE_SETTLE_COUNT = 5;\n\nfunction getContentDimensions(): { width: number; height: number } | null {\n const { body, documentElement: html } = document;\n if (!body) return null;\n\n // Get computed styles for body margin\n // body.scrollHeight/offsetHeight include padding and border but NOT margin\n const bodyStyle = getComputedStyle(body);\n const bodyMarginTop = parseFloat(bodyStyle.marginTop) || 0;\n const bodyMarginBottom = parseFloat(bodyStyle.marginBottom) || 0;\n const bodyMarginLeft = parseFloat(bodyStyle.marginLeft) || 0;\n const bodyMarginRight = parseFloat(bodyStyle.marginRight) || 0;\n\n // Get computed styles for html element padding and border\n // html padding creates space around the body, html border adds to outer edge\n const htmlStyle = getComputedStyle(html);\n const htmlPaddingTop = parseFloat(htmlStyle.paddingTop) || 0;\n const htmlPaddingBottom = parseFloat(htmlStyle.paddingBottom) || 0;\n const htmlPaddingLeft = parseFloat(htmlStyle.paddingLeft) || 0;\n const htmlPaddingRight = parseFloat(htmlStyle.paddingRight) || 0;\n const htmlBorderTop = parseFloat(htmlStyle.borderTopWidth) || 0;\n const htmlBorderBottom = parseFloat(htmlStyle.borderBottomWidth) || 0;\n const htmlBorderLeft = parseFloat(htmlStyle.borderLeftWidth) || 0;\n const htmlBorderRight = parseFloat(htmlStyle.borderRightWidth) || 0;\n\n // Calculate total dimensions:\n // body content (scrollHeight/offsetHeight includes body padding + border)\n // + body margin (space between body and html's inner edge)\n // + html padding (space between html's inner edge and body)\n // + html border (html element's border)\n const bodyHeight = Math.max(body.scrollHeight, body.offsetHeight);\n const bodyWidth = Math.max(body.scrollWidth, body.offsetWidth);\n\n const height =\n bodyHeight +\n bodyMarginTop +\n bodyMarginBottom +\n htmlPaddingTop +\n htmlPaddingBottom +\n htmlBorderTop +\n htmlBorderBottom;\n\n const width =\n bodyWidth +\n bodyMarginLeft +\n bodyMarginRight +\n htmlPaddingLeft +\n htmlPaddingRight +\n htmlBorderLeft +\n htmlBorderRight;\n\n // Account for horizontal scrollbar height \u2014 when content overflows horizontally,\n // the browser adds a scrollbar that eats vertical space. body.scrollHeight\n // doesn't include this, so the reported height would be too short.\n const hasHScrollbar = html.scrollWidth > html.clientWidth;\n const scrollbarHeight = hasHScrollbar\n ? Math.max(0, window.innerHeight - html.clientHeight)\n : 0;\n\n if (!isValidDimension(width) || !isValidDimension(height + scrollbarHeight))\n return null;\n\n // Feedback loop detection: detect when body is tracking the viewport height\n // If bodyHeight \u2248 lastSentHeight, the body expanded to fill the new iframe\n // This happens with min-height: 100vh or similar viewport-relative CSS\n if (\n resizeCount >= RESIZE_SETTLE_COUNT &&\n lastBodyHeight > 0 &&\n Math.abs(bodyHeight - lastSentHeight) <= 2\n ) {\n return null;\n }\n\n lastBodyHeight = bodyHeight;\n\n return { width, height: height + scrollbarHeight + 2 };\n}\n\nfunction sendResizeImmediate(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n const parent = window.parent;\n if (!hasPostMessage(parent)) return;\n\n // Check for width change BEFORE getting dims (to reset counters)\n const currentBodyWidth = document.body\n ? Math.max(document.body.scrollWidth, document.body.offsetWidth)\n : 0;\n if (currentBodyWidth !== lastBodyWidth && lastBodyWidth !== -1) {\n // Width changed (window resize) - reset counters to allow re-settling\n resizeCount = 0;\n lastBodyHeight = -1;\n }\n lastBodyWidth = currentBodyWidth;\n\n const dims = getContentDimensions();\n if (!dims) return;\n\n const { width, height } = dims;\n if (width === lastSentWidth && height === lastSentHeight) return;\n\n lastSentWidth = width;\n lastSentHeight = height;\n resizeCount++;\n\n try {\n parent.postMessage(\n { type: 'adapt-resize', width, height } satisfies AdaptResizeMessage,\n '*'\n );\n } catch {}\n}\n\nfunction sendResizeThrottled(): void {\n if (throttleTimer !== null) return;\n\n throttleTimer = setTimeout(() => {\n throttleTimer = null;\n sendResizeImmediate();\n }, THROTTLE_MS);\n}\n\nfunction sendResizeForced(): void {\n // Force sending current dimensions (don't reset tracking)\n const dims = getContentDimensions();\n if (!dims) {\n // If detection stopped us, send the last known dimensions\n if (lastSentHeight > 0) {\n try {\n window.parent.postMessage(\n {\n type: 'adapt-resize',\n width: lastSentWidth,\n height: lastSentHeight\n },\n '*'\n );\n } catch {}\n }\n return;\n }\n\n const { width, height } = dims;\n lastSentWidth = width;\n lastSentHeight = height;\n\n try {\n window.parent.postMessage({ type: 'adapt-resize', width, height }, '*');\n } catch {}\n}\n\n// =============================================================================\n// Internal: Message Handling\n// =============================================================================\n\nlet onDarkModeCallback: ((darkMode: boolean) => void) | null = null;\n\nfunction handleMessage(event: MessageEvent): void {\n let data: unknown;\n try {\n data = event.data;\n } catch {\n return;\n }\n\n if (isDarkModeMessage(data)) {\n if (onDarkModeCallback) {\n try {\n onDarkModeCallback(data.darkMode);\n } catch {}\n }\n }\n\n if (isAutoResizingMessage(data) && data.autoResizing) {\n // Parent requested auto-resizing - immediately send current dimensions\n sendResizeForced();\n }\n}\n\n// =============================================================================\n// Public API: init()\n// =============================================================================\n\nlet initialized = false;\n\n/**\n * Initialize the plugin's iframe communication with the parent.\n *\n * Must be called exactly once. Sends an `adapt-init` message to the parent\n * indicating whether this plugin supports content-based resizing.\n *\n * @param options.resize - Whether to enable content-based resizing (default: true)\n * @param options.onDarkMode - Callback invoked when dark mode state changes\n */\nexport function init(options: InitOptions = {}): void {\n if (initialized) {\n throw new Error('init() has already been called');\n }\n initialized = true;\n\n if (!isBrowser() || !isInIframe()) return;\n\n const resize = options.resize !== false;\n\n // Store dark mode callback\n onDarkModeCallback = options.onDarkMode ?? null;\n\n // Listen for messages from parent\n window.addEventListener('message', handleMessage);\n\n // Send adapt-init to parent\n try {\n window.parent.postMessage(\n { type: 'adapt-init', resize } satisfies AdaptInitMessage,\n '*'\n );\n } catch {}\n\n if (resize) {\n // Inject baseline CSS for consistent measurements\n const style = document.createElement('style');\n style.textContent = `\n html, body {\n box-sizing: border-box;\n }\n *, *::before, *::after {\n box-sizing: inherit;\n }\n `;\n document.head.appendChild(style);\n\n // Set up resize observation\n const resizeObserver = new ResizeObserver(sendResizeThrottled);\n if (document.body) resizeObserver.observe(document.body);\n if (document.documentElement)\n resizeObserver.observe(document.documentElement);\n\n // Set up mutation observation for DOM changes\n if (document.body) {\n const mutationObserver = new MutationObserver(sendResizeThrottled);\n mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true\n });\n }\n\n // Capture load events on resources (images, iframes, etc.)\n document.addEventListener('load', sendResizeThrottled, true);\n\n // Wait for fonts to load\n document.fonts?.ready?.then(() => {\n sendResizeImmediate();\n });\n\n // Send initial size when fully loaded\n if (document.readyState === 'complete') {\n sendResizeImmediate();\n } else {\n window.addEventListener('load', () => {\n sendResizeImmediate();\n });\n }\n\n // Send again with delays to handle timing issues\n setTimeout(sendResizeImmediate, 50);\n setTimeout(sendResizeImmediate, 150);\n }\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["browser_exports", "__export", "getToken", "init", "__toCommonJS", "cachedToken", "isDevelopment", "hash", "token", "isObject", "value", "isDarkModeMessage", "data", "isAutoResizingMessage", "isValidDimension", "hasPostMessage", "obj", "isBrowser", "isInIframe", "lastSentWidth", "lastSentHeight", "lastBodyWidth", "lastBodyHeight", "throttleTimer", "THROTTLE_MS", "resizeCount", "RESIZE_SETTLE_COUNT", "getContentDimensions", "body", "html", "bodyStyle", "bodyMarginTop", "bodyMarginBottom", "bodyMarginLeft", "bodyMarginRight", "htmlStyle", "htmlPaddingTop", "htmlPaddingBottom", "htmlPaddingLeft", "htmlPaddingRight", "htmlBorderTop", "htmlBorderBottom", "htmlBorderLeft", "htmlBorderRight", "bodyHeight", "bodyWidth", "height", "width", "scrollbarHeight", "sendResizeImmediate", "parent", "currentBodyWidth", "dims", "sendResizeThrottled", "sendResizeForced", "onDarkModeCallback", "handleMessage", "event", "initialized", "options", "resize", "style", "resizeObserver"]
|
|
7
7
|
}
|
package/dist/esm/browser.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var d=null;function Z(e=!1){if(e)return"dev-token";if(d!==null)return d;if(typeof window>"u"||typeof location>"u")throw new Error("getToken() is only available in browser environments");let t=location.hash.slice(1);if(!t)throw new Error("No token found in URL hash");let n=new URLSearchParams(t).get("mb_token");if(!n)throw new Error('Token "mb_token" not found in URL hash');return d=decodeURIComponent(n),d}function b(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function D(e){return b(e)&&e.type==="adapt-darkMode"&&typeof e.darkMode=="boolean"}function I(e){return b(e)&&e.type==="adapt-autoResizing"&&typeof e.autoResizing=="boolean"}function R(e){return Number.isFinite(e)&&e>=1}function P(e){return b(e)&&typeof e.postMessage=="function"}function y(){return typeof window<"u"&&typeof document<"u"&&typeof window.postMessage=="function"}function T(){if(!y())return!1;try{return window.self!==window.top}catch{return!0}}var l=-1,a=-1,c=-1,p=-1,h=null,U=16,g=0,_=5;function v(){let{body:e,documentElement:t}=document;if(!e)return null;let n=getComputedStyle(e),o=parseFloat(n.marginTop)||0,r=parseFloat(n.marginBottom)||0,E=parseFloat(n.marginLeft)||0,L=parseFloat(n.marginRight)||0,i=getComputedStyle(t),B=parseFloat(i.paddingTop)||0,F=parseFloat(i.paddingBottom)||0,W=parseFloat(i.paddingLeft)||0,A=parseFloat(i.paddingRight)||0,S=parseFloat(i.borderTopWidth)||0,x=parseFloat(i.borderBottomWidth)||0,H=parseFloat(i.borderLeftWidth)||0,O=parseFloat(i.borderRightWidth)||0,u=Math.max(e.scrollHeight,e.offsetHeight),C=Math.max(e.scrollWidth,e.offsetWidth),w=u+o+r+B+F+S+x,M=C+E+L+W+A+H+O,k=t.scrollWidth>t.clientWidth?Math.max(0,window.innerHeight-t.clientHeight):0;return!R(M)||!R(w+k)||g>=_&&p>0&&Math.abs(u-a)<=2?null:(p=u,{width:M,height:w+k+
|
|
1
|
+
var d=null;function Z(e=!1){if(e)return"dev-token";if(d!==null)return d;if(typeof window>"u"||typeof location>"u")throw new Error("getToken() is only available in browser environments");let t=location.hash.slice(1);if(!t)throw new Error("No token found in URL hash");let n=new URLSearchParams(t).get("mb_token");if(!n)throw new Error('Token "mb_token" not found in URL hash');return d=decodeURIComponent(n),d}function b(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function D(e){return b(e)&&e.type==="adapt-darkMode"&&typeof e.darkMode=="boolean"}function I(e){return b(e)&&e.type==="adapt-autoResizing"&&typeof e.autoResizing=="boolean"}function R(e){return Number.isFinite(e)&&e>=1}function P(e){return b(e)&&typeof e.postMessage=="function"}function y(){return typeof window<"u"&&typeof document<"u"&&typeof window.postMessage=="function"}function T(){if(!y())return!1;try{return window.self!==window.top}catch{return!0}}var l=-1,a=-1,c=-1,p=-1,h=null,U=16,g=0,_=5;function v(){let{body:e,documentElement:t}=document;if(!e)return null;let n=getComputedStyle(e),o=parseFloat(n.marginTop)||0,r=parseFloat(n.marginBottom)||0,E=parseFloat(n.marginLeft)||0,L=parseFloat(n.marginRight)||0,i=getComputedStyle(t),B=parseFloat(i.paddingTop)||0,F=parseFloat(i.paddingBottom)||0,W=parseFloat(i.paddingLeft)||0,A=parseFloat(i.paddingRight)||0,S=parseFloat(i.borderTopWidth)||0,x=parseFloat(i.borderBottomWidth)||0,H=parseFloat(i.borderLeftWidth)||0,O=parseFloat(i.borderRightWidth)||0,u=Math.max(e.scrollHeight,e.offsetHeight),C=Math.max(e.scrollWidth,e.offsetWidth),w=u+o+r+B+F+S+x,M=C+E+L+W+A+H+O,k=t.scrollWidth>t.clientWidth?Math.max(0,window.innerHeight-t.clientHeight):0;return!R(M)||!R(w+k)||g>=_&&p>0&&Math.abs(u-a)<=2?null:(p=u,{width:M,height:w+k+2})}function s(){if(!y()||!T())return;let e=window.parent;if(!P(e))return;let t=document.body?Math.max(document.body.scrollWidth,document.body.offsetWidth):0;t!==c&&c!==-1&&(g=0,p=-1),c=t;let n=v();if(!n)return;let{width:o,height:r}=n;if(!(o===l&&r===a)){l=o,a=r,g++;try{e.postMessage({type:"adapt-resize",width:o,height:r},"*")}catch{}}}function f(){h===null&&(h=setTimeout(()=>{h=null,s()},U))}function N(){let e=v();if(!e){if(a>0)try{window.parent.postMessage({type:"adapt-resize",width:l,height:a},"*")}catch{}return}let{width:t,height:n}=e;l=t,a=n;try{window.parent.postMessage({type:"adapt-resize",width:t,height:n},"*")}catch{}}var m=null;function j(e){let t;try{t=e.data}catch{return}if(D(t)&&m)try{m(t.darkMode)}catch{}I(t)&&t.autoResizing&&N()}var z=!1;function q(e={}){if(z)throw new Error("init() has already been called");if(z=!0,!y()||!T())return;let t=e.resize!==!1;m=e.onDarkMode??null,window.addEventListener("message",j);try{window.parent.postMessage({type:"adapt-init",resize:t},"*")}catch{}if(t){let n=document.createElement("style");n.textContent=`
|
|
2
2
|
html, body {
|
|
3
3
|
box-sizing: border-box;
|
|
4
4
|
}
|
package/dist/esm/browser.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/browser/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Frontend utilities for Adapt plugins running in browser/iframe contexts\n *\n * Plugins must call `init()` to set up iframe communication with the parent.\n * The `init()` function sends an `adapt-init` message to the parent and optionally\n * sets up content-based resizing.\n */\n\n// =============================================================================\n// Token Management\n// =============================================================================\n\nlet cachedToken: string | null = null;\n\n/**\n * Get the authentication token from the URL hash.\n * @param isDevelopment If true, returns a dev token for local development\n */\nexport function getToken(isDevelopment = false): string {\n if (isDevelopment) return 'dev-token';\n if (cachedToken !== null) return cachedToken;\n\n if (typeof window === 'undefined' || typeof location === 'undefined') {\n throw new Error('getToken() is only available in browser environments');\n }\n\n const hash = location.hash.slice(1);\n if (!hash) throw new Error('No token found in URL hash');\n\n const token = new URLSearchParams(hash).get('mb_token');\n if (!token) throw new Error('Token \"mb_token\" not found in URL hash');\n\n cachedToken = decodeURIComponent(token);\n return cachedToken;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AdaptInitMessage {\n type: 'adapt-init';\n resize: boolean;\n}\n\ninterface AdaptResizeMessage {\n type: 'adapt-resize';\n width: number;\n height: number;\n}\n\ninterface AdaptDarkModeMessage {\n type: 'adapt-darkMode';\n darkMode: boolean;\n}\n\ninterface AdaptAutoResizingMessage {\n type: 'adapt-autoResizing';\n autoResizing: boolean;\n}\n\nexport interface InitOptions {\n /** Whether the plugin supports content-based resizing. Default: true */\n resize?: boolean;\n /** Callback invoked when dark mode state changes from parent */\n onDarkMode?: (darkMode: boolean) => void;\n}\n\n// =============================================================================\n// Internal: Type Guards & Helpers\n// =============================================================================\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isDarkModeMessage(data: unknown): data is AdaptDarkModeMessage {\n return (\n isObject(data) &&\n data.type === 'adapt-darkMode' &&\n typeof data.darkMode === 'boolean'\n );\n}\n\nfunction isAutoResizingMessage(\n data: unknown\n): data is AdaptAutoResizingMessage {\n return (\n isObject(data) &&\n data.type === 'adapt-autoResizing' &&\n typeof data.autoResizing === 'boolean'\n );\n}\n\nfunction isValidDimension(value: number): boolean {\n return Number.isFinite(value) && value >= 1;\n}\n\nfunction hasPostMessage(\n obj: unknown\n): obj is { postMessage: typeof postMessage } {\n return isObject(obj) && typeof obj.postMessage === 'function';\n}\n\n// =============================================================================\n// Internal: Environment Detection\n// =============================================================================\n\nfunction isBrowser(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined' &&\n typeof window.postMessage === 'function'\n );\n}\n\nfunction isInIframe(): boolean {\n if (!isBrowser()) return false;\n try {\n return window.self !== window.top;\n } catch {\n return true;\n }\n}\n\n// =============================================================================\n// Internal: Resize Logic\n// =============================================================================\n\nlet lastSentWidth = -1;\nlet lastSentHeight = -1;\nlet lastBodyWidth = -1; // Track body width separately for change detection\nlet lastBodyHeight = -1;\nlet throttleTimer: ReturnType<typeof setTimeout> | null = null;\nconst THROTTLE_MS = 16;\nlet resizeCount = 0;\nconst RESIZE_SETTLE_COUNT = 5;\n\nfunction getContentDimensions(): { width: number; height: number } | null {\n const { body, documentElement: html } = document;\n if (!body) return null;\n\n // Get computed styles for body margin\n // body.scrollHeight/offsetHeight include padding and border but NOT margin\n const bodyStyle = getComputedStyle(body);\n const bodyMarginTop = parseFloat(bodyStyle.marginTop) || 0;\n const bodyMarginBottom = parseFloat(bodyStyle.marginBottom) || 0;\n const bodyMarginLeft = parseFloat(bodyStyle.marginLeft) || 0;\n const bodyMarginRight = parseFloat(bodyStyle.marginRight) || 0;\n\n // Get computed styles for html element padding and border\n // html padding creates space around the body, html border adds to outer edge\n const htmlStyle = getComputedStyle(html);\n const htmlPaddingTop = parseFloat(htmlStyle.paddingTop) || 0;\n const htmlPaddingBottom = parseFloat(htmlStyle.paddingBottom) || 0;\n const htmlPaddingLeft = parseFloat(htmlStyle.paddingLeft) || 0;\n const htmlPaddingRight = parseFloat(htmlStyle.paddingRight) || 0;\n const htmlBorderTop = parseFloat(htmlStyle.borderTopWidth) || 0;\n const htmlBorderBottom = parseFloat(htmlStyle.borderBottomWidth) || 0;\n const htmlBorderLeft = parseFloat(htmlStyle.borderLeftWidth) || 0;\n const htmlBorderRight = parseFloat(htmlStyle.borderRightWidth) || 0;\n\n // Calculate total dimensions:\n // body content (scrollHeight/offsetHeight includes body padding + border)\n // + body margin (space between body and html's inner edge)\n // + html padding (space between html's inner edge and body)\n // + html border (html element's border)\n const bodyHeight = Math.max(body.scrollHeight, body.offsetHeight);\n const bodyWidth = Math.max(body.scrollWidth, body.offsetWidth);\n\n const height =\n bodyHeight +\n bodyMarginTop +\n bodyMarginBottom +\n htmlPaddingTop +\n htmlPaddingBottom +\n htmlBorderTop +\n htmlBorderBottom;\n\n const width =\n bodyWidth +\n bodyMarginLeft +\n bodyMarginRight +\n htmlPaddingLeft +\n htmlPaddingRight +\n htmlBorderLeft +\n htmlBorderRight;\n\n // Account for horizontal scrollbar height \u2014 when content overflows horizontally,\n // the browser adds a scrollbar that eats vertical space. body.scrollHeight\n // doesn't include this, so the reported height would be too short.\n const hasHScrollbar = html.scrollWidth > html.clientWidth;\n const scrollbarHeight = hasHScrollbar\n ? Math.max(0, window.innerHeight - html.clientHeight)\n : 0;\n\n if (!isValidDimension(width) || !isValidDimension(height + scrollbarHeight))\n return null;\n\n // Feedback loop detection: detect when body is tracking the viewport height\n // If bodyHeight \u2248 lastSentHeight, the body expanded to fill the new iframe\n // This happens with min-height: 100vh or similar viewport-relative CSS\n if (\n resizeCount >= RESIZE_SETTLE_COUNT &&\n lastBodyHeight > 0 &&\n Math.abs(bodyHeight - lastSentHeight) <= 2\n ) {\n return null;\n }\n\n lastBodyHeight = bodyHeight;\n\n return { width, height: height + scrollbarHeight + 1 };\n}\n\nfunction sendResizeImmediate(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n const parent = window.parent;\n if (!hasPostMessage(parent)) return;\n\n // Check for width change BEFORE getting dims (to reset counters)\n const currentBodyWidth = document.body\n ? Math.max(document.body.scrollWidth, document.body.offsetWidth)\n : 0;\n if (currentBodyWidth !== lastBodyWidth && lastBodyWidth !== -1) {\n // Width changed (window resize) - reset counters to allow re-settling\n resizeCount = 0;\n lastBodyHeight = -1;\n }\n lastBodyWidth = currentBodyWidth;\n\n const dims = getContentDimensions();\n if (!dims) return;\n\n const { width, height } = dims;\n if (width === lastSentWidth && height === lastSentHeight) return;\n\n lastSentWidth = width;\n lastSentHeight = height;\n resizeCount++;\n\n try {\n parent.postMessage(\n { type: 'adapt-resize', width, height } satisfies AdaptResizeMessage,\n '*'\n );\n } catch {}\n}\n\nfunction sendResizeThrottled(): void {\n if (throttleTimer !== null) return;\n\n throttleTimer = setTimeout(() => {\n throttleTimer = null;\n sendResizeImmediate();\n }, THROTTLE_MS);\n}\n\nfunction sendResizeForced(): void {\n // Force sending current dimensions (don't reset tracking)\n const dims = getContentDimensions();\n if (!dims) {\n // If detection stopped us, send the last known dimensions\n if (lastSentHeight > 0) {\n try {\n window.parent.postMessage(\n {\n type: 'adapt-resize',\n width: lastSentWidth,\n height: lastSentHeight\n },\n '*'\n );\n } catch {}\n }\n return;\n }\n\n const { width, height } = dims;\n lastSentWidth = width;\n lastSentHeight = height;\n\n try {\n window.parent.postMessage({ type: 'adapt-resize', width, height }, '*');\n } catch {}\n}\n\n// =============================================================================\n// Internal: Message Handling\n// =============================================================================\n\nlet onDarkModeCallback: ((darkMode: boolean) => void) | null = null;\n\nfunction handleMessage(event: MessageEvent): void {\n let data: unknown;\n try {\n data = event.data;\n } catch {\n return;\n }\n\n if (isDarkModeMessage(data)) {\n if (onDarkModeCallback) {\n try {\n onDarkModeCallback(data.darkMode);\n } catch {}\n }\n }\n\n if (isAutoResizingMessage(data) && data.autoResizing) {\n // Parent requested auto-resizing - immediately send current dimensions\n sendResizeForced();\n }\n}\n\n// =============================================================================\n// Public API: init()\n// =============================================================================\n\nlet initialized = false;\n\n/**\n * Initialize the plugin's iframe communication with the parent.\n *\n * Must be called exactly once. Sends an `adapt-init` message to the parent\n * indicating whether this plugin supports content-based resizing.\n *\n * @param options.resize - Whether to enable content-based resizing (default: true)\n * @param options.onDarkMode - Callback invoked when dark mode state changes\n */\nexport function init(options: InitOptions = {}): void {\n if (initialized) {\n throw new Error('init() has already been called');\n }\n initialized = true;\n\n if (!isBrowser() || !isInIframe()) return;\n\n const resize = options.resize !== false;\n\n // Store dark mode callback\n onDarkModeCallback = options.onDarkMode ?? null;\n\n // Listen for messages from parent\n window.addEventListener('message', handleMessage);\n\n // Send adapt-init to parent\n try {\n window.parent.postMessage(\n { type: 'adapt-init', resize } satisfies AdaptInitMessage,\n '*'\n );\n } catch {}\n\n if (resize) {\n // Inject baseline CSS for consistent measurements\n const style = document.createElement('style');\n style.textContent = `\n html, body {\n box-sizing: border-box;\n }\n *, *::before, *::after {\n box-sizing: inherit;\n }\n `;\n document.head.appendChild(style);\n\n // Set up resize observation\n const resizeObserver = new ResizeObserver(sendResizeThrottled);\n if (document.body) resizeObserver.observe(document.body);\n if (document.documentElement)\n resizeObserver.observe(document.documentElement);\n\n // Set up mutation observation for DOM changes\n if (document.body) {\n const mutationObserver = new MutationObserver(sendResizeThrottled);\n mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true\n });\n }\n\n // Capture load events on resources (images, iframes, etc.)\n document.addEventListener('load', sendResizeThrottled, true);\n\n // Wait for fonts to load\n document.fonts?.ready?.then(() => {\n sendResizeImmediate();\n });\n\n // Send initial size when fully loaded\n if (document.readyState === 'complete') {\n sendResizeImmediate();\n } else {\n window.addEventListener('load', () => {\n sendResizeImmediate();\n });\n }\n\n // Send again with delays to handle timing issues\n setTimeout(sendResizeImmediate, 50);\n setTimeout(sendResizeImmediate, 150);\n }\n}\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * Frontend utilities for Adapt plugins running in browser/iframe contexts\n *\n * Plugins must call `init()` to set up iframe communication with the parent.\n * The `init()` function sends an `adapt-init` message to the parent and optionally\n * sets up content-based resizing.\n */\n\n// =============================================================================\n// Token Management\n// =============================================================================\n\nlet cachedToken: string | null = null;\n\n/**\n * Get the authentication token from the URL hash.\n * @param isDevelopment If true, returns a dev token for local development\n */\nexport function getToken(isDevelopment = false): string {\n if (isDevelopment) return 'dev-token';\n if (cachedToken !== null) return cachedToken;\n\n if (typeof window === 'undefined' || typeof location === 'undefined') {\n throw new Error('getToken() is only available in browser environments');\n }\n\n const hash = location.hash.slice(1);\n if (!hash) throw new Error('No token found in URL hash');\n\n const token = new URLSearchParams(hash).get('mb_token');\n if (!token) throw new Error('Token \"mb_token\" not found in URL hash');\n\n cachedToken = decodeURIComponent(token);\n return cachedToken;\n}\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AdaptInitMessage {\n type: 'adapt-init';\n resize: boolean;\n}\n\ninterface AdaptResizeMessage {\n type: 'adapt-resize';\n width: number;\n height: number;\n}\n\ninterface AdaptDarkModeMessage {\n type: 'adapt-darkMode';\n darkMode: boolean;\n}\n\ninterface AdaptAutoResizingMessage {\n type: 'adapt-autoResizing';\n autoResizing: boolean;\n}\n\nexport interface InitOptions {\n /** Whether the plugin supports content-based resizing. Default: true */\n resize?: boolean;\n /** Callback invoked when dark mode state changes from parent */\n onDarkMode?: (darkMode: boolean) => void;\n}\n\n// =============================================================================\n// Internal: Type Guards & Helpers\n// =============================================================================\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction isDarkModeMessage(data: unknown): data is AdaptDarkModeMessage {\n return (\n isObject(data) &&\n data.type === 'adapt-darkMode' &&\n typeof data.darkMode === 'boolean'\n );\n}\n\nfunction isAutoResizingMessage(\n data: unknown\n): data is AdaptAutoResizingMessage {\n return (\n isObject(data) &&\n data.type === 'adapt-autoResizing' &&\n typeof data.autoResizing === 'boolean'\n );\n}\n\nfunction isValidDimension(value: number): boolean {\n return Number.isFinite(value) && value >= 1;\n}\n\nfunction hasPostMessage(\n obj: unknown\n): obj is { postMessage: typeof postMessage } {\n return isObject(obj) && typeof obj.postMessage === 'function';\n}\n\n// =============================================================================\n// Internal: Environment Detection\n// =============================================================================\n\nfunction isBrowser(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined' &&\n typeof window.postMessage === 'function'\n );\n}\n\nfunction isInIframe(): boolean {\n if (!isBrowser()) return false;\n try {\n return window.self !== window.top;\n } catch {\n return true;\n }\n}\n\n// =============================================================================\n// Internal: Resize Logic\n// =============================================================================\n\nlet lastSentWidth = -1;\nlet lastSentHeight = -1;\nlet lastBodyWidth = -1; // Track body width separately for change detection\nlet lastBodyHeight = -1;\nlet throttleTimer: ReturnType<typeof setTimeout> | null = null;\nconst THROTTLE_MS = 16;\nlet resizeCount = 0;\nconst RESIZE_SETTLE_COUNT = 5;\n\nfunction getContentDimensions(): { width: number; height: number } | null {\n const { body, documentElement: html } = document;\n if (!body) return null;\n\n // Get computed styles for body margin\n // body.scrollHeight/offsetHeight include padding and border but NOT margin\n const bodyStyle = getComputedStyle(body);\n const bodyMarginTop = parseFloat(bodyStyle.marginTop) || 0;\n const bodyMarginBottom = parseFloat(bodyStyle.marginBottom) || 0;\n const bodyMarginLeft = parseFloat(bodyStyle.marginLeft) || 0;\n const bodyMarginRight = parseFloat(bodyStyle.marginRight) || 0;\n\n // Get computed styles for html element padding and border\n // html padding creates space around the body, html border adds to outer edge\n const htmlStyle = getComputedStyle(html);\n const htmlPaddingTop = parseFloat(htmlStyle.paddingTop) || 0;\n const htmlPaddingBottom = parseFloat(htmlStyle.paddingBottom) || 0;\n const htmlPaddingLeft = parseFloat(htmlStyle.paddingLeft) || 0;\n const htmlPaddingRight = parseFloat(htmlStyle.paddingRight) || 0;\n const htmlBorderTop = parseFloat(htmlStyle.borderTopWidth) || 0;\n const htmlBorderBottom = parseFloat(htmlStyle.borderBottomWidth) || 0;\n const htmlBorderLeft = parseFloat(htmlStyle.borderLeftWidth) || 0;\n const htmlBorderRight = parseFloat(htmlStyle.borderRightWidth) || 0;\n\n // Calculate total dimensions:\n // body content (scrollHeight/offsetHeight includes body padding + border)\n // + body margin (space between body and html's inner edge)\n // + html padding (space between html's inner edge and body)\n // + html border (html element's border)\n const bodyHeight = Math.max(body.scrollHeight, body.offsetHeight);\n const bodyWidth = Math.max(body.scrollWidth, body.offsetWidth);\n\n const height =\n bodyHeight +\n bodyMarginTop +\n bodyMarginBottom +\n htmlPaddingTop +\n htmlPaddingBottom +\n htmlBorderTop +\n htmlBorderBottom;\n\n const width =\n bodyWidth +\n bodyMarginLeft +\n bodyMarginRight +\n htmlPaddingLeft +\n htmlPaddingRight +\n htmlBorderLeft +\n htmlBorderRight;\n\n // Account for horizontal scrollbar height \u2014 when content overflows horizontally,\n // the browser adds a scrollbar that eats vertical space. body.scrollHeight\n // doesn't include this, so the reported height would be too short.\n const hasHScrollbar = html.scrollWidth > html.clientWidth;\n const scrollbarHeight = hasHScrollbar\n ? Math.max(0, window.innerHeight - html.clientHeight)\n : 0;\n\n if (!isValidDimension(width) || !isValidDimension(height + scrollbarHeight))\n return null;\n\n // Feedback loop detection: detect when body is tracking the viewport height\n // If bodyHeight \u2248 lastSentHeight, the body expanded to fill the new iframe\n // This happens with min-height: 100vh or similar viewport-relative CSS\n if (\n resizeCount >= RESIZE_SETTLE_COUNT &&\n lastBodyHeight > 0 &&\n Math.abs(bodyHeight - lastSentHeight) <= 2\n ) {\n return null;\n }\n\n lastBodyHeight = bodyHeight;\n\n return { width, height: height + scrollbarHeight + 2 };\n}\n\nfunction sendResizeImmediate(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n const parent = window.parent;\n if (!hasPostMessage(parent)) return;\n\n // Check for width change BEFORE getting dims (to reset counters)\n const currentBodyWidth = document.body\n ? Math.max(document.body.scrollWidth, document.body.offsetWidth)\n : 0;\n if (currentBodyWidth !== lastBodyWidth && lastBodyWidth !== -1) {\n // Width changed (window resize) - reset counters to allow re-settling\n resizeCount = 0;\n lastBodyHeight = -1;\n }\n lastBodyWidth = currentBodyWidth;\n\n const dims = getContentDimensions();\n if (!dims) return;\n\n const { width, height } = dims;\n if (width === lastSentWidth && height === lastSentHeight) return;\n\n lastSentWidth = width;\n lastSentHeight = height;\n resizeCount++;\n\n try {\n parent.postMessage(\n { type: 'adapt-resize', width, height } satisfies AdaptResizeMessage,\n '*'\n );\n } catch {}\n}\n\nfunction sendResizeThrottled(): void {\n if (throttleTimer !== null) return;\n\n throttleTimer = setTimeout(() => {\n throttleTimer = null;\n sendResizeImmediate();\n }, THROTTLE_MS);\n}\n\nfunction sendResizeForced(): void {\n // Force sending current dimensions (don't reset tracking)\n const dims = getContentDimensions();\n if (!dims) {\n // If detection stopped us, send the last known dimensions\n if (lastSentHeight > 0) {\n try {\n window.parent.postMessage(\n {\n type: 'adapt-resize',\n width: lastSentWidth,\n height: lastSentHeight\n },\n '*'\n );\n } catch {}\n }\n return;\n }\n\n const { width, height } = dims;\n lastSentWidth = width;\n lastSentHeight = height;\n\n try {\n window.parent.postMessage({ type: 'adapt-resize', width, height }, '*');\n } catch {}\n}\n\n// =============================================================================\n// Internal: Message Handling\n// =============================================================================\n\nlet onDarkModeCallback: ((darkMode: boolean) => void) | null = null;\n\nfunction handleMessage(event: MessageEvent): void {\n let data: unknown;\n try {\n data = event.data;\n } catch {\n return;\n }\n\n if (isDarkModeMessage(data)) {\n if (onDarkModeCallback) {\n try {\n onDarkModeCallback(data.darkMode);\n } catch {}\n }\n }\n\n if (isAutoResizingMessage(data) && data.autoResizing) {\n // Parent requested auto-resizing - immediately send current dimensions\n sendResizeForced();\n }\n}\n\n// =============================================================================\n// Public API: init()\n// =============================================================================\n\nlet initialized = false;\n\n/**\n * Initialize the plugin's iframe communication with the parent.\n *\n * Must be called exactly once. Sends an `adapt-init` message to the parent\n * indicating whether this plugin supports content-based resizing.\n *\n * @param options.resize - Whether to enable content-based resizing (default: true)\n * @param options.onDarkMode - Callback invoked when dark mode state changes\n */\nexport function init(options: InitOptions = {}): void {\n if (initialized) {\n throw new Error('init() has already been called');\n }\n initialized = true;\n\n if (!isBrowser() || !isInIframe()) return;\n\n const resize = options.resize !== false;\n\n // Store dark mode callback\n onDarkModeCallback = options.onDarkMode ?? null;\n\n // Listen for messages from parent\n window.addEventListener('message', handleMessage);\n\n // Send adapt-init to parent\n try {\n window.parent.postMessage(\n { type: 'adapt-init', resize } satisfies AdaptInitMessage,\n '*'\n );\n } catch {}\n\n if (resize) {\n // Inject baseline CSS for consistent measurements\n const style = document.createElement('style');\n style.textContent = `\n html, body {\n box-sizing: border-box;\n }\n *, *::before, *::after {\n box-sizing: inherit;\n }\n `;\n document.head.appendChild(style);\n\n // Set up resize observation\n const resizeObserver = new ResizeObserver(sendResizeThrottled);\n if (document.body) resizeObserver.observe(document.body);\n if (document.documentElement)\n resizeObserver.observe(document.documentElement);\n\n // Set up mutation observation for DOM changes\n if (document.body) {\n const mutationObserver = new MutationObserver(sendResizeThrottled);\n mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true\n });\n }\n\n // Capture load events on resources (images, iframes, etc.)\n document.addEventListener('load', sendResizeThrottled, true);\n\n // Wait for fonts to load\n document.fonts?.ready?.then(() => {\n sendResizeImmediate();\n });\n\n // Send initial size when fully loaded\n if (document.readyState === 'complete') {\n sendResizeImmediate();\n } else {\n window.addEventListener('load', () => {\n sendResizeImmediate();\n });\n }\n\n // Send again with delays to handle timing issues\n setTimeout(sendResizeImmediate, 50);\n setTimeout(sendResizeImmediate, 150);\n }\n}\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["cachedToken", "getToken", "isDevelopment", "hash", "token", "isObject", "value", "isDarkModeMessage", "data", "isAutoResizingMessage", "isValidDimension", "hasPostMessage", "obj", "isBrowser", "isInIframe", "lastSentWidth", "lastSentHeight", "lastBodyWidth", "lastBodyHeight", "throttleTimer", "THROTTLE_MS", "resizeCount", "RESIZE_SETTLE_COUNT", "getContentDimensions", "body", "html", "bodyStyle", "bodyMarginTop", "bodyMarginBottom", "bodyMarginLeft", "bodyMarginRight", "htmlStyle", "htmlPaddingTop", "htmlPaddingBottom", "htmlPaddingLeft", "htmlPaddingRight", "htmlBorderTop", "htmlBorderBottom", "htmlBorderLeft", "htmlBorderRight", "bodyHeight", "bodyWidth", "height", "width", "scrollbarHeight", "sendResizeImmediate", "parent", "currentBodyWidth", "dims", "sendResizeThrottled", "sendResizeForced", "onDarkModeCallback", "handleMessage", "event", "initialized", "init", "options", "resize", "style", "resizeObserver"]
|
|
7
7
|
}
|