@open-iframe-resizer/vue
Version:
Open-source modern iframe resizer component
2 lines (1 loc) • 7.26 kB
JavaScript
(function(d,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],a):(d=typeof globalThis<"u"?globalThis:d||self,a(d["open-iframe-resizer-vue"]={},d.Vue))})(this,(function(d,a){"use strict";const z=()=>typeof window<"u",D=()=>{try{return window.self!==window.top}catch{return!0}},v=e=>e instanceof HTMLIFrameElement,S=e=>{window.document.readyState==="complete"?e():window.addEventListener("load",e,{once:!0})},T=(e,t)=>{t(),e.addEventListener("load",t,{once:!0})},A=(e,t)=>{const n=e.contentWindow?.document.readyState==="complete";e.src!=="about:blank"&&e.contentWindow?.location.href!=="about:blank"&&n&&t()},H=()=>({offsetSize:0,checkOrigin:!0,enableLegacyLibSupport:!1});async function _(e){try{return e.contentDocument?.URL==="about:blank"?new Promise(t=>{e.addEventListener("load",()=>t(e.contentDocument!==null),{once:!0})}):e.contentDocument!==null}catch{return!1}}const W=e=>{try{const t=new URL(e.src).origin;if(t!=="about:blank")return t}catch{}return null},x=e=>(Object.keys(e).forEach(t=>{e[t]===void 0&&delete e[t]}),e),E=e=>{const{height:t,width:n}=e.getBoundingClientRect();return{height:Math.ceil(t),width:Math.ceil(n)}},m=(e,t)=>e?t?e.querySelector(t):e.documentElement:null,R=(e,t)=>{e&&(t.bodyPadding&&(e.body.style.padding=t.bodyPadding),t.bodyMargin&&(e.body.style.margin=t.bodyMargin))},y=e=>e<=100?100:e<=120?1e3:1e4,C=()=>"[iFrameSizer]ID:0:false:false:32:true:true::auto:::0:false:child:auto:true:::true:::false";function F(e){if(typeof e.data!="string"||!e.data.startsWith("[iFrameSizer]"))return null;const t=e.data.endsWith("mutationObserver")||e.data.endsWith("resizeObserver"),n=e.data.search(/:init(:[\d.]+)?/g)>=0;if(!t&&!n)return null;const[r,i]=e.data.split(":"),o=+i;return o>0?o:null}const L=J();let b=[];const $=async(e,t)=>{if(!z())return[];const n={...H(),...x(e??{})},r=j(t),i=N(n,r);return Promise.all(r.map(async o=>{const s={iframe:o,settings:n,interactionState:{isHovered:!1},initContext:{isInitialized:!1,retryAttempts:0}},{unsubscribe:c,resize:f}=await U(s,i);return b.push(s),{unsubscribe:()=>{c(),b=b.filter(u=>u.iframe!==o)},resize:f}}))};function j(e){return typeof e=="string"?Array.from(document.querySelectorAll(e)).filter(v):e?v(e)?[e]:[]:Array.from(document.getElementsByTagName("iframe"))}function N(e,t){if(Array.isArray(e.checkOrigin))return e.checkOrigin;if(!e.checkOrigin)return[];const n=[];for(const r of t){const i=W(r);i&&n.push(i)}return n}async function U(e,t){const n=await _(e.iframe),{unsubscribe:r,resize:i}=n?V(e):q(e,t),o=G(e);return{unsubscribe:()=>{r(),o()},resize:i}}function q(e,t){const{iframe:n,initContext:r,settings:{checkOrigin:i,enableLegacyLibSupport:o,targetElementSelector:s,bodyPadding:c,bodyMargin:f}}=e,u=l=>{const ie=l.origin==="null",oe=!i||ie||t.includes(l.origin);if(!(n.contentWindow!==l.source||!oe)){if(l.data?.type==="iframe-resized"){const{height:g}=l.data;g&&h({newHeight:g,registeredElement:e});return}if(o){const g=F(l);g!==null&&h({newHeight:g,registeredElement:e});return}}};window.addEventListener("message",u);const re=o?C():{type:"iframe-child-init",targetElementSelector:s,bodyPadding:c,bodyMargin:f},w=()=>{T(n,()=>n.contentWindow?.postMessage(re,"*")),r.retryAttempts++,r.retryTimeoutId=window.setTimeout(w,y(r.retryAttempts))},B=()=>{r.isInitialized&&(r.isInitialized=!1,r.retryAttempts=0,w())};return n.addEventListener("load",B),w(),{unsubscribe:()=>{window.removeEventListener("message",u),n.removeEventListener("load",B)},resize:()=>{const l={type:"iframe-get-child-dimensions"};n.contentWindow?.postMessage(l,"*")}}}function V(e){const{iframe:t,settings:n}=e,{targetElementSelector:r}=n;let i=0;const o=()=>{const s=m(t.contentDocument,r);if(!t.contentDocument||!s)return i++,setTimeout(o,y(i));R(t.contentDocument,n),L().observe(s)};return A(t,o),t.addEventListener("load",o),{unsubscribe:()=>{const s=m(t.contentDocument,r);s&&L().unobserve(s),t.removeEventListener("load",o)},resize:()=>I(e)}}function G({iframe:e,interactionState:t,settings:n}){if(!n.onBeforeIframeResize&&!n.onIframeResize)return()=>{};const r=()=>{t.isHovered=!0},i=()=>{t.isHovered=!1};return e.addEventListener("mouseenter",r),e.addEventListener("mouseleave",i),()=>{e.removeEventListener("mouseenter",r),e.removeEventListener("mouseleave",i)}}function J(){let e=null;return()=>{if(!e){const t=({target:n})=>{const r=b.find(({iframe:i})=>i.contentDocument===n.ownerDocument);r&&I(r)};e=new ResizeObserver(n=>n.forEach(t))}return e}}function I(e){const{iframe:t,settings:n}=e,r=m(t.contentDocument,n.targetElementSelector);if(!r)return;const{height:i}=E(r);i&&h({newHeight:i,registeredElement:e})}function h({registeredElement:e,newHeight:t}){const{iframe:n,settings:r,interactionState:i,initContext:o}=e;if(o.isInitialized||(o.isInitialized=!0,clearTimeout(o.retryTimeoutId)),r.onBeforeIframeResize?.({iframe:n,interactionState:{...i},settings:{...r},observedHeight:t})===!1)return;const s=n.getBoundingClientRect(),c=t+r.offsetSize;if(n.style.height=`${c}px`,!r.onIframeResize)return;const f={iframe:n,settings:{...r},interactionState:{...i},previousRenderState:{rect:s},nextRenderState:{rect:n.getBoundingClientRect()}};r.onIframeResize(f)}const K=Y();let p=!1,M;Q();function Q(){!z()||!D()||window.addEventListener("message",e=>{if(e.data?.type==="iframe-child-init")return S(()=>O(e));if(e.data?.type==="iframe-get-child-dimensions")return S(()=>X(e))})}function O(e,t=0){const{targetElementSelector:n,bodyPadding:r,bodyMargin:i}=e.data,o=m(document,n);if(p||window.parent!==e.source)return;if(!o)return setTimeout(()=>O(e,t+1),y(t));R(document,{bodyMargin:i,bodyPadding:r}),M=n;const s=K();s.disconnect(),s.observe(o),p=!0}function X(e){const t=m(document,M);!p||window.parent!==e.source||!t||k(t)}function Y(){let e=null;return()=>(e||(e=new ResizeObserver(t=>{t[0].target&&k(t[0].target)})),e)}const k=e=>{const{width:t,height:n}=E(e),r={type:"iframe-resized",width:t,height:n};window.parent.postMessage(r,"*")},Z=a.defineComponent({name:"ResizableIframe",props:{offsetSize:[String,Number,Object],checkOrigin:[Boolean,Array],onIframeResize:Function,onBeforeIframeResize:Function,targetElementSelector:String,bodyMargin:[String,Number],bodyPadding:[String,Number],enableLegacyLibSupport:Boolean},setup(e,{attrs:t}){const n=a.ref(null);let r=[],i=!1;const o=async s=>{const c={offsetSize:e.offsetSize,enableLegacyLibSupport:e.enableLegacyLibSupport,checkOrigin:e.checkOrigin,onIframeResize:e.onIframeResize,onBeforeIframeResize:e.onBeforeIframeResize,targetElementSelector:e.targetElementSelector,bodyMargin:e.bodyMargin,bodyPadding:e.bodyPadding};Object.keys(c).forEach(u=>{c[u]===void 0&&delete c[u]});const f=await $(c,s);i?f.forEach(u=>{u.unsubscribe()}):r=f};return a.onMounted(()=>{n.value&&o(n.value)}),a.onBeforeUnmount(()=>{i=!0,r.forEach(s=>{s.unsubscribe()}),r=[]}),{iframeRef:n,attrs:t}}}),ee=(e,t)=>{const n=e.__vccOpts||e;for(const[r,i]of t)n[r]=i;return n};function te(e,t,n,r,i,o){return a.openBlock(),a.createElementBlock("iframe",a.mergeProps({ref:"iframeRef"},e.$attrs),null,16)}const P=ee(Z,[["render",te]]),ne={install(e){e.component("IframeResizer",P)}};d.IframeResizer=P,d.IframeResizerPlugin=ne,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})}));