@mochabug/adapt-sdk 0.1.8 → 0.1.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/frontend.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var u=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var v=(e,t)=>{for(var n in t)u(e,n,{get:t[n],enumerable:!0})},R=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of y(t))!k.call(e,i)&&i!==n&&u(e,i,{get:()=>t[i],enumerable:!(o=M(t,i))||o.enumerable});return e};var z=e=>R(u({},"__esModule",{value:!0}),e);var I={};v(I,{getDarkMode:()=>T,getToken:()=>E,listenDarkMode:()=>A});module.exports=z(I);var s=null;function E(e=!1){if(e)return"dev-token";if(s!==null)return s;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 s=decodeURIComponent(n),s}var d=null,f=new Set;function T(){return d}function A(e){if(f.add(e),d!==null)try{e(d)}catch{}return()=>{f.delete(e)}}function g(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function L(e){return g(e)&&e.type==="adapt-darkMode"&&typeof e.darkMode=="boolean"}function D(e){return g(e)&&e.type==="adapt-autoResizing"&&typeof e.autoResizing=="boolean"}function p(e){return Number.isFinite(e)&&e>=1}function O(e){return g(e)&&typeof e.postMessage=="function"}function a(){return typeof window<"u"&&typeof document<"u"&&typeof window.postMessage=="function"}function b(){if(!a())return!1;try{return window.self!==window.top}catch{return!0}}var h=-1,m=-1,l=null,H=16;function S(){let{body:e,documentElement:t}=document;if(!e||!t)return null;let n=Math.max(e.scrollHeight,e.offsetHeight,t.clientHeight,t.scrollHeight,t.offsetHeight),o=Math.max(e.scrollWidth,e.offsetWidth,t.clientWidth,t.scrollWidth,t.offsetWidth);return!p(o)||!p(n)?null:{width:o,height:n}}function r(){if(!a()||!b())return;let e=window.parent;if(!O(e))return;let t=S();if(!t)return;let{width:n,height:o}=t;if(!(n===h&&o===m)){h=n,m=o;try{e.postMessage({type:"adapt-resize",width:n,height:o},"*")}catch{}}}function c(){l===null&&(l=setTimeout(()=>{l=null,r()},H))}function W(){h=-1,m=-1,r()}function x(e){let t;try{t=e.data}catch{return}if(L(t)){d=t.darkMode;for(let n of f)try{n(t.darkMode)}catch{}}D(t)&&t.autoResizing&&W()}function w(){if(!a()||!b())return;window.addEventListener("message",x);let e=new ResizeObserver(c);document.body&&e.observe(document.body),document.documentElement&&e.observe(document.documentElement),document.body&&new MutationObserver(c).observe(document.body,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),document.addEventListener("load",c,!0),document.fonts?.ready?.then(()=>{r()}),document.readyState==="complete"?r():window.addEventListener("load",()=>{r()})}a()&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",w):w());0&&(module.exports={getDarkMode,getToken,listenDarkMode});
|
|
1
|
+
"use strict";var u=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var v=(e,t)=>{for(var n in t)u(e,n,{get:t[n],enumerable:!0})},R=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of y(t))!k.call(e,i)&&i!==n&&u(e,i,{get:()=>t[i],enumerable:!(o=M(t,i))||o.enumerable});return e};var z=e=>R(u({},"__esModule",{value:!0}),e);var I={};v(I,{getDarkMode:()=>T,getToken:()=>E,listenDarkMode:()=>A});module.exports=z(I);var s=null;function E(e=!1){if(e)return"dev-token";if(s!==null)return s;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 s=decodeURIComponent(n),s}var d=null,f=new Set;function T(){return d}function A(e){if(f.add(e),d!==null)try{e(d)}catch{}return()=>{f.delete(e)}}function g(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function L(e){return g(e)&&e.type==="adapt-darkMode"&&typeof e.darkMode=="boolean"}function D(e){return g(e)&&e.type==="adapt-autoResizing"&&typeof e.autoResizing=="boolean"}function p(e){return Number.isFinite(e)&&e>=1}function O(e){return g(e)&&typeof e.postMessage=="function"}function a(){return typeof window<"u"&&typeof document<"u"&&typeof window.postMessage=="function"}function b(){if(!a())return!1;try{return window.self!==window.top}catch{return!0}}var h=-1,m=-1,l=null,H=16;function S(){let{body:e,documentElement:t}=document;if(!e||!t)return null;let n=Math.max(e.scrollHeight,e.offsetHeight,t.clientHeight,t.scrollHeight,t.offsetHeight),o=Math.max(e.scrollWidth,e.offsetWidth,t.clientWidth,t.scrollWidth,t.offsetWidth);return!p(o)||!p(n)?null:{width:o,height:n+2}}function r(){if(!a()||!b())return;let e=window.parent;if(!O(e))return;let t=S();if(!t)return;let{width:n,height:o}=t;if(!(n===h&&o===m)){h=n,m=o;try{e.postMessage({type:"adapt-resize",width:n,height:o},"*")}catch{}}}function c(){l===null&&(l=setTimeout(()=>{l=null,r()},H))}function W(){h=-1,m=-1,r()}function x(e){let t;try{t=e.data}catch{return}if(L(t)){d=t.darkMode;for(let n of f)try{n(t.darkMode)}catch{}}D(t)&&t.autoResizing&&W()}function w(){if(!a()||!b())return;window.addEventListener("message",x);let e=new ResizeObserver(c);document.body&&e.observe(document.body),document.documentElement&&e.observe(document.documentElement),document.body&&new MutationObserver(c).observe(document.body,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),document.addEventListener("load",c,!0),document.fonts?.ready?.then(()=>{r()}),document.readyState==="complete"?r():window.addEventListener("load",()=>{r()})}a()&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",w):w());0&&(module.exports={getDarkMode,getToken,listenDarkMode});
|
|
2
2
|
//# sourceMappingURL=frontend.cjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/frontend.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Frontend utilities for Adapt plugins running in browser/iframe contexts\n *\n * Iframe resizing is handled automatically - no initialization required.\n * Just import the functions you need and the resize communication starts automatically.\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// Dark Mode\n// =============================================================================\n\nlet currentDarkMode: boolean | null = null;\nconst darkModeListeners = new Set<(darkMode: boolean) => void>();\n\n/**\n * Get the current dark mode state.\n * Returns null if dark mode state hasn't been received from parent yet.\n */\nexport function getDarkMode(): boolean | null {\n return currentDarkMode;\n}\n\n/**\n * Listen for dark mode changes from the parent window.\n * Returns an unsubscribe function.\n * @param callback Called immediately with current state (if known) and on every change\n */\nexport function listenDarkMode(\n callback: (darkMode: boolean) => void\n): () => void {\n darkModeListeners.add(callback);\n\n // Call immediately with current value if we have one\n if (currentDarkMode !== null) {\n try {\n callback(currentDarkMode);\n } catch {}\n }\n\n return () => {\n darkModeListeners.delete(callback);\n };\n}\n\n// =============================================================================\n// Internal: Message Types and Type Guards\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\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 throttleTimer: ReturnType<typeof setTimeout> | null = null;\nconst THROTTLE_MS = 16;\n\nfunction getContentDimensions(): { width: number; height: number } | null {\n const { body, documentElement: html } = document;\n if (!body || !html) return null;\n\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n const width = Math.max(\n body.scrollWidth,\n body.offsetWidth,\n html.clientWidth,\n html.scrollWidth,\n html.offsetWidth\n );\n\n if (!isValidDimension(width) || !isValidDimension(height)) return null;\n\n return { width, height };\n}\n\nfunction sendResizeImmediate(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n const parent = window.parent;\n if (!hasPostMessage(parent)) return;\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\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 // Reset last sent values to force sending even if dimensions haven't changed\n lastSentWidth = -1;\n lastSentHeight = -1;\n sendResizeImmediate();\n}\n\n// =============================================================================\n// Internal: Message Handling\n// =============================================================================\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 currentDarkMode = data.darkMode;\n for (const listener of darkModeListeners) {\n try {\n listener(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// Internal: Auto-initialization\n// =============================================================================\n\nfunction autoInit(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n // Listen for messages from parent\n window.addEventListener('message', handleMessage);\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 // Already loaded, send immediately\n sendResizeImmediate();\n } else {\n // Wait for full load\n window.addEventListener('load', () => {\n sendResizeImmediate();\n });\n }\n}\n\n// Run initialization when DOM is ready\nif (isBrowser()) {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', autoInit);\n } else {\n // DOM already ready, init now\n autoInit();\n }\n}\n"],
|
|
5
|
-
"mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,EAAA,aAAAC,EAAA,mBAAAC,IAAA,eAAAC,EAAAL,GAWA,IAAIM,EAA6B,KAM1B,SAASH,EAASI,EAAgB,GAAe,CACtD,GAAIA,EAAe,MAAO,YAC1B,GAAID,IAAgB,KAAM,OAAOA,EAEjC,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IACvD,MAAM,IAAI,MAAM,sDAAsD,EAGxE,IAAME,EAAO,SAAS,KAAK,MAAM,CAAC,EAClC,GAAI,CAACA,EAAM,MAAM,IAAI,MAAM,4BAA4B,EAEvD,IAAMC,EAAQ,IAAI,gBAAgBD,CAAI,EAAE,IAAI,UAAU,EACtD,GAAI,CAACC,EAAO,MAAM,IAAI,MAAM,wCAAwC,EAEpE,OAAAH,EAAc,mBAAmBG,CAAK,EAC/BH,CACT,CAMA,IAAII,EAAkC,KAChCC,EAAoB,IAAI,IAMvB,SAAST,GAA8B,CAC5C,OAAOQ,CACT,CAOO,SAASN,EACdQ,EACY,CAIZ,GAHAD,EAAkB,IAAIC,CAAQ,EAG1BF,IAAoB,KACtB,GAAI,CACFE,EAASF,CAAe,CAC1B,MAAQ,CAAC,CAGX,MAAO,IAAM,CACXC,EAAkB,OAAOC,CAAQ,CACnC,CACF,CAsBA,SAASC,EAASC,EAAkD,CAClE,OAAOA,IAAU,MAAQ,OAAOA,GAAU,UAAY,CAAC,MAAM,QAAQA,CAAK,CAC5E,CAEA,SAASC,EAAkBC,EAA6C,CACtE,OACEH,EAASG,CAAI,GACbA,EAAK,OAAS,kBACd,OAAOA,EAAK,UAAa,SAE7B,CAEA,SAASC,EACPD,EACkC,CAClC,OACEH,EAASG,CAAI,GACbA,EAAK,OAAS,sBACd,OAAOA,EAAK,cAAiB,SAEjC,CAEA,SAASE,EAAiBJ,EAAwB,CAChD,OAAO,OAAO,SAASA,CAAK,GAAKA,GAAS,CAC5C,CAEA,SAASK,EACPC,EAC4C,CAC5C,OAAOP,EAASO,CAAG,GAAK,OAAOA,EAAI,aAAgB,UACrD,CAMA,SAASC,GAAqB,CAC5B,OACE,OAAO,OAAW,KAClB,OAAO,SAAa,KACpB,OAAO,OAAO,aAAgB,UAElC,CAEA,SAASC,GAAsB,CAC7B,GAAI,CAACD,EAAU,EAAG,MAAO,GACzB,GAAI,CACF,OAAO,OAAO,OAAS,OAAO,GAChC,MAAQ,CACN,MAAO,EACT,CACF,CAMA,IAAIE,EAAgB,GAChBC,EAAiB,GACjBC,EAAsD,KACpDC,EAAc,GAEpB,SAASC,GAAiE,CACxE,GAAM,CAAE,KAAAC,EAAM,gBAAiBC,CAAK,EAAI,SACxC,GAAI,CAACD,GAAQ,CAACC,EAAM,OAAO,KAE3B,IAAMC,EAAS,KAAK,IAClBF,EAAK,aACLA,EAAK,aACLC,EAAK,aACLA,EAAK,aACLA,EAAK,YACP,EAEME,EAAQ,KAAK,IACjBH,EAAK,YACLA,EAAK,YACLC,EAAK,YACLA,EAAK,YACLA,EAAK,WACP,EAEA,MAAI,CAACX,EAAiBa,CAAK,GAAK,CAACb,EAAiBY,CAAM,EAAU,KAE3D,CAAE,MAAAC,EAAO,
|
|
4
|
+
"sourcesContent": ["/**\n * Frontend utilities for Adapt plugins running in browser/iframe contexts\n *\n * Iframe resizing is handled automatically - no initialization required.\n * Just import the functions you need and the resize communication starts automatically.\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// Dark Mode\n// =============================================================================\n\nlet currentDarkMode: boolean | null = null;\nconst darkModeListeners = new Set<(darkMode: boolean) => void>();\n\n/**\n * Get the current dark mode state.\n * Returns null if dark mode state hasn't been received from parent yet.\n */\nexport function getDarkMode(): boolean | null {\n return currentDarkMode;\n}\n\n/**\n * Listen for dark mode changes from the parent window.\n * Returns an unsubscribe function.\n * @param callback Called immediately with current state (if known) and on every change\n */\nexport function listenDarkMode(\n callback: (darkMode: boolean) => void\n): () => void {\n darkModeListeners.add(callback);\n\n // Call immediately with current value if we have one\n if (currentDarkMode !== null) {\n try {\n callback(currentDarkMode);\n } catch {}\n }\n\n return () => {\n darkModeListeners.delete(callback);\n };\n}\n\n// =============================================================================\n// Internal: Message Types and Type Guards\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\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 throttleTimer: ReturnType<typeof setTimeout> | null = null;\nconst THROTTLE_MS = 16;\n\nfunction getContentDimensions(): { width: number; height: number } | null {\n const { body, documentElement: html } = document;\n if (!body || !html) return null;\n\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n const width = Math.max(\n body.scrollWidth,\n body.offsetWidth,\n html.clientWidth,\n html.scrollWidth,\n html.offsetWidth\n );\n\n if (!isValidDimension(width) || !isValidDimension(height)) return null;\n\n return { width, height: height + 2 };\n}\n\nfunction sendResizeImmediate(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n const parent = window.parent;\n if (!hasPostMessage(parent)) return;\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\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 // Reset last sent values to force sending even if dimensions haven't changed\n lastSentWidth = -1;\n lastSentHeight = -1;\n sendResizeImmediate();\n}\n\n// =============================================================================\n// Internal: Message Handling\n// =============================================================================\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 currentDarkMode = data.darkMode;\n for (const listener of darkModeListeners) {\n try {\n listener(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// Internal: Auto-initialization\n// =============================================================================\n\nfunction autoInit(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n // Listen for messages from parent\n window.addEventListener('message', handleMessage);\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 // Already loaded, send immediately\n sendResizeImmediate();\n } else {\n // Wait for full load\n window.addEventListener('load', () => {\n sendResizeImmediate();\n });\n }\n}\n\n// Run initialization when DOM is ready\nif (isBrowser()) {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', autoInit);\n } else {\n // DOM already ready, init now\n autoInit();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["frontend_exports", "__export", "getDarkMode", "getToken", "listenDarkMode", "__toCommonJS", "cachedToken", "isDevelopment", "hash", "token", "currentDarkMode", "darkModeListeners", "callback", "isObject", "value", "isDarkModeMessage", "data", "isAutoResizingMessage", "isValidDimension", "hasPostMessage", "obj", "isBrowser", "isInIframe", "lastSentWidth", "lastSentHeight", "throttleTimer", "THROTTLE_MS", "getContentDimensions", "body", "html", "height", "width", "sendResizeImmediate", "parent", "dims", "sendResizeThrottled", "sendResizeForced", "handleMessage", "event", "listener", "autoInit", "resizeObserver"]
|
|
7
7
|
}
|
package/dist/esm/frontend.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var r=null;function z(e=!1){if(e)return"dev-token";if(r!==null)return r;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 r=decodeURIComponent(n),r}var s=null,l=new Set;function E(){return s}function T(e){if(l.add(e),s!==null)try{e(s)}catch{}return()=>{l.delete(e)}}function h(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function w(e){return h(e)&&e.type==="adapt-darkMode"&&typeof e.darkMode=="boolean"}function b(e){return h(e)&&e.type==="adapt-autoResizing"&&typeof e.autoResizing=="boolean"}function m(e){return Number.isFinite(e)&&e>=1}function M(e){return h(e)&&typeof e.postMessage=="function"}function d(){return typeof window<"u"&&typeof document<"u"&&typeof window.postMessage=="function"}function p(){if(!d())return!1;try{return window.self!==window.top}catch{return!0}}var c=-1,f=-1,a=null,y=16;function k(){let{body:e,documentElement:t}=document;if(!e||!t)return null;let n=Math.max(e.scrollHeight,e.offsetHeight,t.clientHeight,t.scrollHeight,t.offsetHeight),o=Math.max(e.scrollWidth,e.offsetWidth,t.clientWidth,t.scrollWidth,t.offsetWidth);return!m(o)||!m(n)?null:{width:o,height:n}}function i(){if(!d()||!p())return;let e=window.parent;if(!M(e))return;let t=k();if(!t)return;let{width:n,height:o}=t;if(!(n===c&&o===f)){c=n,f=o;try{e.postMessage({type:"adapt-resize",width:n,height:o},"*")}catch{}}}function u(){a===null&&(a=setTimeout(()=>{a=null,i()},y))}function v(){c=-1,f=-1,i()}function R(e){let t;try{t=e.data}catch{return}if(w(t)){s=t.darkMode;for(let n of l)try{n(t.darkMode)}catch{}}b(t)&&t.autoResizing&&v()}function g(){if(!d()||!p())return;window.addEventListener("message",R);let e=new ResizeObserver(u);document.body&&e.observe(document.body),document.documentElement&&e.observe(document.documentElement),document.body&&new MutationObserver(u).observe(document.body,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),document.addEventListener("load",u,!0),document.fonts?.ready?.then(()=>{i()}),document.readyState==="complete"?i():window.addEventListener("load",()=>{i()})}d()&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",g):g());export{E as getDarkMode,z as getToken,T as listenDarkMode};
|
|
1
|
+
var r=null;function z(e=!1){if(e)return"dev-token";if(r!==null)return r;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 r=decodeURIComponent(n),r}var s=null,l=new Set;function E(){return s}function T(e){if(l.add(e),s!==null)try{e(s)}catch{}return()=>{l.delete(e)}}function h(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function w(e){return h(e)&&e.type==="adapt-darkMode"&&typeof e.darkMode=="boolean"}function b(e){return h(e)&&e.type==="adapt-autoResizing"&&typeof e.autoResizing=="boolean"}function m(e){return Number.isFinite(e)&&e>=1}function M(e){return h(e)&&typeof e.postMessage=="function"}function d(){return typeof window<"u"&&typeof document<"u"&&typeof window.postMessage=="function"}function p(){if(!d())return!1;try{return window.self!==window.top}catch{return!0}}var c=-1,f=-1,a=null,y=16;function k(){let{body:e,documentElement:t}=document;if(!e||!t)return null;let n=Math.max(e.scrollHeight,e.offsetHeight,t.clientHeight,t.scrollHeight,t.offsetHeight),o=Math.max(e.scrollWidth,e.offsetWidth,t.clientWidth,t.scrollWidth,t.offsetWidth);return!m(o)||!m(n)?null:{width:o,height:n+2}}function i(){if(!d()||!p())return;let e=window.parent;if(!M(e))return;let t=k();if(!t)return;let{width:n,height:o}=t;if(!(n===c&&o===f)){c=n,f=o;try{e.postMessage({type:"adapt-resize",width:n,height:o},"*")}catch{}}}function u(){a===null&&(a=setTimeout(()=>{a=null,i()},y))}function v(){c=-1,f=-1,i()}function R(e){let t;try{t=e.data}catch{return}if(w(t)){s=t.darkMode;for(let n of l)try{n(t.darkMode)}catch{}}b(t)&&t.autoResizing&&v()}function g(){if(!d()||!p())return;window.addEventListener("message",R);let e=new ResizeObserver(u);document.body&&e.observe(document.body),document.documentElement&&e.observe(document.documentElement),document.body&&new MutationObserver(u).observe(document.body,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),document.addEventListener("load",u,!0),document.fonts?.ready?.then(()=>{i()}),document.readyState==="complete"?i():window.addEventListener("load",()=>{i()})}d()&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",g):g());export{E as getDarkMode,z as getToken,T as listenDarkMode};
|
|
2
2
|
//# sourceMappingURL=frontend.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/frontend.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Frontend utilities for Adapt plugins running in browser/iframe contexts\n *\n * Iframe resizing is handled automatically - no initialization required.\n * Just import the functions you need and the resize communication starts automatically.\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// Dark Mode\n// =============================================================================\n\nlet currentDarkMode: boolean | null = null;\nconst darkModeListeners = new Set<(darkMode: boolean) => void>();\n\n/**\n * Get the current dark mode state.\n * Returns null if dark mode state hasn't been received from parent yet.\n */\nexport function getDarkMode(): boolean | null {\n return currentDarkMode;\n}\n\n/**\n * Listen for dark mode changes from the parent window.\n * Returns an unsubscribe function.\n * @param callback Called immediately with current state (if known) and on every change\n */\nexport function listenDarkMode(\n callback: (darkMode: boolean) => void\n): () => void {\n darkModeListeners.add(callback);\n\n // Call immediately with current value if we have one\n if (currentDarkMode !== null) {\n try {\n callback(currentDarkMode);\n } catch {}\n }\n\n return () => {\n darkModeListeners.delete(callback);\n };\n}\n\n// =============================================================================\n// Internal: Message Types and Type Guards\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\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 throttleTimer: ReturnType<typeof setTimeout> | null = null;\nconst THROTTLE_MS = 16;\n\nfunction getContentDimensions(): { width: number; height: number } | null {\n const { body, documentElement: html } = document;\n if (!body || !html) return null;\n\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n const width = Math.max(\n body.scrollWidth,\n body.offsetWidth,\n html.clientWidth,\n html.scrollWidth,\n html.offsetWidth\n );\n\n if (!isValidDimension(width) || !isValidDimension(height)) return null;\n\n return { width, height };\n}\n\nfunction sendResizeImmediate(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n const parent = window.parent;\n if (!hasPostMessage(parent)) return;\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\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 // Reset last sent values to force sending even if dimensions haven't changed\n lastSentWidth = -1;\n lastSentHeight = -1;\n sendResizeImmediate();\n}\n\n// =============================================================================\n// Internal: Message Handling\n// =============================================================================\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 currentDarkMode = data.darkMode;\n for (const listener of darkModeListeners) {\n try {\n listener(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// Internal: Auto-initialization\n// =============================================================================\n\nfunction autoInit(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n // Listen for messages from parent\n window.addEventListener('message', handleMessage);\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 // Already loaded, send immediately\n sendResizeImmediate();\n } else {\n // Wait for full load\n window.addEventListener('load', () => {\n sendResizeImmediate();\n });\n }\n}\n\n// Run initialization when DOM is ready\nif (isBrowser()) {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', autoInit);\n } else {\n // DOM already ready, init now\n autoInit();\n }\n}\n"],
|
|
5
|
-
"mappings": "AAWA,IAAIA,EAA6B,KAM1B,SAASC,EAASC,EAAgB,GAAe,CACtD,GAAIA,EAAe,MAAO,YAC1B,GAAIF,IAAgB,KAAM,OAAOA,EAEjC,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IACvD,MAAM,IAAI,MAAM,sDAAsD,EAGxE,IAAMG,EAAO,SAAS,KAAK,MAAM,CAAC,EAClC,GAAI,CAACA,EAAM,MAAM,IAAI,MAAM,4BAA4B,EAEvD,IAAMC,EAAQ,IAAI,gBAAgBD,CAAI,EAAE,IAAI,UAAU,EACtD,GAAI,CAACC,EAAO,MAAM,IAAI,MAAM,wCAAwC,EAEpE,OAAAJ,EAAc,mBAAmBI,CAAK,EAC/BJ,CACT,CAMA,IAAIK,EAAkC,KAChCC,EAAoB,IAAI,IAMvB,SAASC,GAA8B,CAC5C,OAAOF,CACT,CAOO,SAASG,EACdC,EACY,CAIZ,GAHAH,EAAkB,IAAIG,CAAQ,EAG1BJ,IAAoB,KACtB,GAAI,CACFI,EAASJ,CAAe,CAC1B,MAAQ,CAAC,CAGX,MAAO,IAAM,CACXC,EAAkB,OAAOG,CAAQ,CACnC,CACF,CAsBA,SAASC,EAASC,EAAkD,CAClE,OAAOA,IAAU,MAAQ,OAAOA,GAAU,UAAY,CAAC,MAAM,QAAQA,CAAK,CAC5E,CAEA,SAASC,EAAkBC,EAA6C,CACtE,OACEH,EAASG,CAAI,GACbA,EAAK,OAAS,kBACd,OAAOA,EAAK,UAAa,SAE7B,CAEA,SAASC,EACPD,EACkC,CAClC,OACEH,EAASG,CAAI,GACbA,EAAK,OAAS,sBACd,OAAOA,EAAK,cAAiB,SAEjC,CAEA,SAASE,EAAiBJ,EAAwB,CAChD,OAAO,OAAO,SAASA,CAAK,GAAKA,GAAS,CAC5C,CAEA,SAASK,EACPC,EAC4C,CAC5C,OAAOP,EAASO,CAAG,GAAK,OAAOA,EAAI,aAAgB,UACrD,CAMA,SAASC,GAAqB,CAC5B,OACE,OAAO,OAAW,KAClB,OAAO,SAAa,KACpB,OAAO,OAAO,aAAgB,UAElC,CAEA,SAASC,GAAsB,CAC7B,GAAI,CAACD,EAAU,EAAG,MAAO,GACzB,GAAI,CACF,OAAO,OAAO,OAAS,OAAO,GAChC,MAAQ,CACN,MAAO,EACT,CACF,CAMA,IAAIE,EAAgB,GAChBC,EAAiB,GACjBC,EAAsD,KACpDC,EAAc,GAEpB,SAASC,GAAiE,CACxE,GAAM,CAAE,KAAAC,EAAM,gBAAiBC,CAAK,EAAI,SACxC,GAAI,CAACD,GAAQ,CAACC,EAAM,OAAO,KAE3B,IAAMC,EAAS,KAAK,IAClBF,EAAK,aACLA,EAAK,aACLC,EAAK,aACLA,EAAK,aACLA,EAAK,YACP,EAEME,EAAQ,KAAK,IACjBH,EAAK,YACLA,EAAK,YACLC,EAAK,YACLA,EAAK,YACLA,EAAK,WACP,EAEA,MAAI,CAACX,EAAiBa,CAAK,GAAK,CAACb,EAAiBY,CAAM,EAAU,KAE3D,CAAE,MAAAC,EAAO,
|
|
4
|
+
"sourcesContent": ["/**\n * Frontend utilities for Adapt plugins running in browser/iframe contexts\n *\n * Iframe resizing is handled automatically - no initialization required.\n * Just import the functions you need and the resize communication starts automatically.\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// Dark Mode\n// =============================================================================\n\nlet currentDarkMode: boolean | null = null;\nconst darkModeListeners = new Set<(darkMode: boolean) => void>();\n\n/**\n * Get the current dark mode state.\n * Returns null if dark mode state hasn't been received from parent yet.\n */\nexport function getDarkMode(): boolean | null {\n return currentDarkMode;\n}\n\n/**\n * Listen for dark mode changes from the parent window.\n * Returns an unsubscribe function.\n * @param callback Called immediately with current state (if known) and on every change\n */\nexport function listenDarkMode(\n callback: (darkMode: boolean) => void\n): () => void {\n darkModeListeners.add(callback);\n\n // Call immediately with current value if we have one\n if (currentDarkMode !== null) {\n try {\n callback(currentDarkMode);\n } catch {}\n }\n\n return () => {\n darkModeListeners.delete(callback);\n };\n}\n\n// =============================================================================\n// Internal: Message Types and Type Guards\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\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 throttleTimer: ReturnType<typeof setTimeout> | null = null;\nconst THROTTLE_MS = 16;\n\nfunction getContentDimensions(): { width: number; height: number } | null {\n const { body, documentElement: html } = document;\n if (!body || !html) return null;\n\n const height = Math.max(\n body.scrollHeight,\n body.offsetHeight,\n html.clientHeight,\n html.scrollHeight,\n html.offsetHeight\n );\n\n const width = Math.max(\n body.scrollWidth,\n body.offsetWidth,\n html.clientWidth,\n html.scrollWidth,\n html.offsetWidth\n );\n\n if (!isValidDimension(width) || !isValidDimension(height)) return null;\n\n return { width, height: height + 2 };\n}\n\nfunction sendResizeImmediate(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n const parent = window.parent;\n if (!hasPostMessage(parent)) return;\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\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 // Reset last sent values to force sending even if dimensions haven't changed\n lastSentWidth = -1;\n lastSentHeight = -1;\n sendResizeImmediate();\n}\n\n// =============================================================================\n// Internal: Message Handling\n// =============================================================================\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 currentDarkMode = data.darkMode;\n for (const listener of darkModeListeners) {\n try {\n listener(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// Internal: Auto-initialization\n// =============================================================================\n\nfunction autoInit(): void {\n if (!isBrowser() || !isInIframe()) return;\n\n // Listen for messages from parent\n window.addEventListener('message', handleMessage);\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 // Already loaded, send immediately\n sendResizeImmediate();\n } else {\n // Wait for full load\n window.addEventListener('load', () => {\n sendResizeImmediate();\n });\n }\n}\n\n// Run initialization when DOM is ready\nif (isBrowser()) {\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', autoInit);\n } else {\n // DOM already ready, init now\n autoInit();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["cachedToken", "getToken", "isDevelopment", "hash", "token", "currentDarkMode", "darkModeListeners", "getDarkMode", "listenDarkMode", "callback", "isObject", "value", "isDarkModeMessage", "data", "isAutoResizingMessage", "isValidDimension", "hasPostMessage", "obj", "isBrowser", "isInIframe", "lastSentWidth", "lastSentHeight", "throttleTimer", "THROTTLE_MS", "getContentDimensions", "body", "html", "height", "width", "sendResizeImmediate", "parent", "dims", "sendResizeThrottled", "sendResizeForced", "handleMessage", "event", "listener", "autoInit", "resizeObserver"]
|
|
7
7
|
}
|