@data-fair/frame 0.6.0 → 0.8.0

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.
@@ -1,2 +1,2 @@
1
- var DFrameContent=function(){"use strict";var g=Object.defineProperty;var l=(a,i,s)=>i in a?g(a,i,{enumerable:!0,configurable:!0,writable:!0,value:s}):a[i]=s;var n=(a,i,s)=>l(a,typeof i!="symbol"?i+"":i,s);function a(r){return r[0]==="df-parent"&&r[1]==="init"}function i(r){return r[0]==="df-parent"&&r[1]==="updateSrc"}const s=["animationstart","webkitAnimationStart","animationiteration","webkitAnimationIteration","animationend","webkitAnimationEnd","input","mouseup","mousedown","orientationchange","afterprint","beforeprint","readystatechange","touchstart","touchend","touchcancel","transitionstart","webkitTransitionStart","MSTransitionStart","oTransitionStart","otransitionstart","transitioniteration","webkitTransitionIteration","MSTransitionIteration","oTransitionIteration","otransitioniteration","transitionend","webkitTransitionEnd","MSTransitionEnd","oTransitionEnd","otransitionend","resize"];class c{constructor(e){n(this,"initialized",!1);n(this,"options");n(this,"pendingCheckHeight",!1);n(this,"debug",!1);n(this,"id");n(this,"throttledCheckHeight");n(this,"lastHeight",0);this.options=e??{};const t=()=>{this.checkHeight(),this.pendingCheckHeight=!1};this.throttledCheckHeight=()=>{this.pendingCheckHeight||(this.pendingCheckHeight=!0,requestAnimationFrame(t))},!(typeof window>"u")&&(window.addEventListener("message",o=>this.onMessage(o)),this.postMessageToParent(["df-child","init"]))}log(e,...t){e==="debug"&&!this.debug||(e==="debug"&&console.timeLog(`${this.id}:d-frame-content`,...t),e==="info"&&console.info(`${this.id}:d-frame-content`,...t))}onMessage(e){if(e.source===window.parent&&Array.isArray(e.data)){const t=e.data;a(t)&&(this.id=t[2].id,this.debug=!!t[2].debug,this.debug&&console.time(`${this.id}:d-frame-content`),t[2].resize!=="no"&&this.initResize(),(t[2].syncParams||t[2].syncPath||t[2].stateChangeEvents)&&this.initStateChangeWatcher(),this.initialized=!0),i(t)&&(this.options.updateSrc?this.options.updateSrc(t[2].startsWith("/")?window.location.origin+t[2]:t[2]):window.location.href=t[2])}}postMessageToParent(e){window.parent.postMessage(e)}sendNotif(e){this.postMessageToParent(["df-child","notif",e])}sendMessage(e){this.postMessageToParent(["df-child","custom",e])}initResize(){this.log("debug","initResize"),this.checkHeight(),this.createMutationObserver(),this.createWindowEventListeners()}initStateChangeWatcher(){this.log("debug","initStateChangeWatcher");const e=window.history.replaceState,t=(...h)=>{const d=e.apply(window.history,h);return this.postMessageToParent(["df-child","stateChange","push",window.location.href]),d};window.history.pushState=t;const o=(...h)=>{const d=e.apply(window.history,h);return this.postMessageToParent(["df-child","stateChange","replace",window.location.href]),d};window.history.replaceState=o}createMutationObserver(){const e=document.querySelector("body");if(!e)throw new Error("DFrameContentManager was initialized before the HTML body");new window.MutationObserver(this.throttledCheckHeight).observe(e,{attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1,childList:!0,subtree:!0})}createWindowEventListeners(){for(const e of s)window.addEventListener(e,this.throttledCheckHeight,{passive:!0})}checkHeight(){const e=document.querySelectorAll("[data-iframe-height]");let t=0;for(const o of e){const h=o.getAttribute("data-iframe-height"),d=o.getBoundingClientRect().bottom+parseFloat(getComputedStyle(o).getPropertyValue("margin-bottom"))+(h?parseFloat(h):0);d>t&&(t=d)}t=Math.ceil(t),t!==this.lastHeight&&(this.postMessageToParent(["df-child","height",t]),this.lastHeight=t)}}return new c}();
1
+ var DFrameContent=function(){"use strict";var u=Object.defineProperty;var f=(o,n,r)=>n in o?u(o,n,{enumerable:!0,configurable:!0,writable:!0,value:r}):o[n]=r;var a=(o,n,r)=>f(o,typeof n!="symbol"?n+"":n,r);function o(h){return h[0]==="df-parent"&&h[1]==="init"}function n(h){return h[0]==="df-parent"&&h[1]==="updateSrc"}const r=["animationstart","webkitAnimationStart","animationiteration","webkitAnimationIteration","animationend","webkitAnimationEnd","input","mouseup","mousedown","orientationchange","afterprint","beforeprint","readystatechange","touchstart","touchend","touchcancel","transitionstart","webkitTransitionStart","MSTransitionStart","oTransitionStart","otransitionstart","transitioniteration","webkitTransitionIteration","MSTransitionIteration","oTransitionIteration","otransitioniteration","transitionend","webkitTransitionEnd","MSTransitionEnd","oTransitionEnd","otransitionend","resize"];class l{constructor(t){a(this,"initialized",!1);a(this,"options");a(this,"pendingCheckHeight",!1);a(this,"debug",!1);a(this,"id");a(this,"throttledCheckHeight");a(this,"lastHeight",0);this.options=t??{};const e=()=>{this.checkHeight(),this.pendingCheckHeight=!1};this.throttledCheckHeight=()=>{this.pendingCheckHeight||(this.pendingCheckHeight=!0,requestAnimationFrame(e))},!(typeof window>"u")&&(window.addEventListener("message",i=>this.onMessage(i)),this.postMessageToParent(["df-child","init"]))}log(t,...e){t==="debug"&&!this.debug||(t==="debug"&&console.timeLog(`d-frame:${this.id}:content`,...e),t==="info"&&console.info(`d-frame:${this.id}:content`,...e))}onMessage(t){if(t.source===window.parent&&Array.isArray(t.data)){const e=t.data;o(e)&&(this.id=e[2].id,this.debug=!!e[2].debug,this.debug&&console.time(`d-frame:${this.id}:content`),e[2].resize!=="no"&&this.initResize(),(e[2].syncParams||e[2].syncPath||e[2].stateChangeEvents)&&this.initStateChangeWatcher(),this.initialized=!0),n(e)&&(this.options.updateSrc?this.options.updateSrc(e[2].startsWith("/")?window.location.origin+e[2]:e[2]):window.location.href=e[2])}}postMessageToParent(t){window.parent.postMessage(t)}sendNotif(t){this.postMessageToParent(["df-child","notif",t])}sendMessage(t){this.postMessageToParent(["df-child","custom",t])}ready(){this.postMessageToParent(["df-child","ready"])}initResize(){this.log("debug","initResize"),this.checkHeight(),this.createMutationObserver(),this.createWindowEventListeners()}initStateChangeWatcher(){this.log("debug","initStateChangeWatcher");const t=window.history.replaceState,e=(...s)=>{const d=t.apply(window.history,s);return this.postMessageToParent(["df-child","stateChange","push",window.location.href]),d};window.history.pushState=e;const i=(...s)=>{const d=t.apply(window.history,s);return this.postMessageToParent(["df-child","stateChange","replace",window.location.href]),d};window.history.replaceState=i}createMutationObserver(){const t=document.querySelector("body");if(!t)throw new Error("DFrameContentManager was initialized before the HTML body");new window.MutationObserver(this.throttledCheckHeight).observe(t,{attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1,childList:!0,subtree:!0})}createWindowEventListeners(){for(const t of r)window.addEventListener(t,this.throttledCheckHeight,{passive:!0})}checkHeight(){const t=document.querySelectorAll("[data-iframe-height]");let e=0,i=0;for(const s of t){const d=s.getAttribute("data-iframe-height"),c=s.getBoundingClientRect().bottom+parseFloat(getComputedStyle(s).getPropertyValue("margin-bottom")),g=d?c+parseFloat(d):c;c>e&&(e=c),g>i&&(i=g)}i=Math.ceil(i),e>0&&i!==this.lastHeight&&(this.postMessageToParent(["df-child","height",i]),this.lastHeight=i)}}return new l}();
2
2
  //# sourceMappingURL=d-frame-content.min.js.map
@@ -1,12 +1,15 @@
1
- var H=Object.defineProperty;var M=(u,c,g)=>c in u?H(u,c,{enumerable:!0,configurable:!0,writable:!0,value:g}):u[c]=g;var o=(u,c,g)=>M(u,typeof c!="symbol"?c+"":c,g);(function(){"use strict";function u(e){return e[0]==="df-child"&&e[1]==="init"}function c(e){return e[0]==="df-child"&&e[1]==="height"}function g(e){return e[0]==="df-child"&&e[1]==="stateChange"}function m(e){return e[0]==="df-child"&&e[1]==="custom"}function b(e){return e[0]==="df-child"&&e[1]==="notif"}function y(e){return e.endsWith("/")?e:e===""?"/":e.slice(0,e.lastIndexOf("/")+1)}function w(e,a){if(a.origin!==e.origin)return a.href;if(a.pathname===e.pathname)return"";const t=y(e.pathname);return a.pathname.startsWith(t)?a.pathname.replace(t,"./"):a.pathname}const A=e=>e.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&");function E(e){const a=[];for(const t of e.split(",")){const[s="*",i]=t.split(":"),r="^"+A(s).replace(/\\\*/g,"(.*)")+"$";a.push({regexp:new RegExp(r),append:i})}return a}function z(e,a,t,s){if(!t&&!s)return e.href;const i=new URL(a);if(t&&i.searchParams.forEach((r,l)=>{for(const n of t){if(n.append&&!l.startsWith(n.append)||l===s)continue;const h=n.append?l.replace(n.append,""):l;if(h.match(n.regexp)){e.searchParams.set(h,r);break}}}),s!==null){const r=i.searchParams.get(s);r&&(e.pathname=new URL(r,e).pathname)}return e.href}function R(e,a,t,s,i){const r=new URL(t),l=new URL(a);if(s&&(r.searchParams.forEach((n,h)=>{for(const d of s){if(d.append&&!h.startsWith(d.append))continue;const f=d.append?h.replace(d.append,""):h;if(f.match(d.regexp)){l.searchParams.get(f)===null&&r.searchParams.delete(h);break}}}),l.searchParams.forEach((n,h)=>{for(const d of s){if(!h.match(d.regexp)||(e==null?void 0:e.searchParams.get(h))===n)continue;const f=d.append?d.append+h:h;r.searchParams.set(f,n);break}})),i!==null&&e){const n=w(e,l);n?r.searchParams.set(i,n):r.searchParams.delete(i)}return r}function S(e){return e.vIframe===!0&&e.uiNotification!==void 0}function v(e){if(typeof e=="string")return{type:"default",title:e};if(e.error&&!e.errorMsg){const a=e.error.response&&(e.error.response.data||e.error.response.status)||e.error.message||e.error;return e.msg?{type:"error",title:e.msg,detail:a}:{type:"error",title:a}}return e.type==="error"?{type:e.clientError?"warning":"error",title:e.msg,detail:e.errorMsg}:{type:e.type??"default",title:e.msg}}class P{stateChange(a,t){a==="replace"&&window.history.replaceState(null,"",t),a==="push"&&window.history.pushState(null,"",t)}}const p=document.createElement("template");p.innerHTML=`<style>
1
+ var H=Object.defineProperty;var x=(l,c,f)=>c in l?H(l,c,{enumerable:!0,configurable:!0,writable:!0,value:f}):l[c]=f;var n=(l,c,f)=>x(l,typeof c!="symbol"?c+"":c,f);(function(){"use strict";function l(e){return e[0]==="df-child"&&e[1]==="init"}function c(e){return e[0]==="df-child"&&e[1]==="height"}function f(e){return e[0]==="df-child"&&e[1]==="stateChange"}function m(e){return e[0]==="df-child"&&e[1]==="custom"}function b(e){return e[0]==="df-child"&&e[1]==="notif"}function y(e){return e[0]==="df-child"&&e[1]==="ready"}function E(e){return e.endsWith("/")?e:e===""?"/":e.slice(0,e.lastIndexOf("/")+1)}function w(e,a){if(a.origin!==e.origin)return a.href;if(a.pathname===e.pathname)return"";const t=E(e.pathname);return a.pathname.startsWith(t)?a.pathname.replace(t,"./"):a.pathname}const A=e=>e.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&");function v(e){const a=[];for(const t of e.split(",")){const[s="*",i]=t.split(":"),r="^"+A(s).replace(/\\\*/g,"(.*)")+"$";a.push({regexp:new RegExp(r),append:i})}return a}function S(e,a,t,s){if(!t&&!s)return e.href;const i=new URL(a);if(t&&i.searchParams.forEach((r,d)=>{for(const h of t){if(h.append&&!d.startsWith(h.append)||d===s)continue;const o=h.append?d.replace(h.append,""):d;if(o.match(h.regexp)){e.searchParams.set(o,r);break}}}),s!==null){const r=i.searchParams.get(s);r&&(e.pathname=new URL(r,e).pathname)}return e.href}function C(e,a,t,s,i){const r=new URL(t),d=new URL(a);if(s&&(r.searchParams.forEach((h,o)=>{for(const u of s){if(u.append&&!o.startsWith(u.append))continue;const g=u.append?o.replace(u.append,""):o;if(g.match(u.regexp)){d.searchParams.get(g)===null&&r.searchParams.delete(o);break}}}),d.searchParams.forEach((h,o)=>{for(const u of s){if(!o.match(u.regexp)||(e==null?void 0:e.searchParams.get(o))===h)continue;const g=u.append?u.append+o:o;r.searchParams.set(g,h);break}})),i!==null&&e){const h=w(e,d);h?r.searchParams.set(i,h):r.searchParams.delete(i)}return r}function P(e){return e.vIframe===!0&&e.uiNotification!==void 0}function z(e){if(typeof e=="string")return{type:"default",title:e};if(e.error&&!e.errorMsg){const a=e.error.response&&(e.error.response.data||e.error.response.status)||e.error.message||e.error;return e.msg?{type:"error",title:e.msg,detail:a}:{type:"error",title:a}}return e.type==="error"?{type:e.clientError?"warning":"error",title:e.msg,detail:e.errorMsg}:{type:e.type??"default",title:e.msg}}class R{stateChange(a,t){a==="replace"&&window.history.replaceState(null,"",t),a==="push"&&window.history.pushState(null,"",t)}}const p=document.createElement("template");p.innerHTML=`<style>
2
2
  :host {
3
3
  display: block;
4
4
  }
5
+ .d-frame-wrapper {
6
+ height: 100%;
7
+ }
5
8
  iframe.d-frame-iframe {
6
9
  display: block;
7
10
  width: 100%;
8
11
  height: 100%;
9
12
  border: none;
10
13
  }
11
- </style><slot name="loader"></slot><iframe class="d-frame-iframe" frameborder="0">`;class C extends HTMLElement{constructor(){super();o(this,"adapter");o(this,"connected",!1);o(this,"initialSrc");o(this,"srcUrl");o(this,"parsedSyncParams");o(this,"iframeElement");o(this,"slotElement");o(this,"width");o(this,"aspectRatioHeight");o(this,"resizedHeight");o(this,"randomId");this.randomId=Math.random().toString(36).slice(-6);const t=p.content.cloneNode(!0);this.slotElement=t.childNodes[1],this.resize!=="yes"&&(this.slotElement.style.display="none"),this.iframeElement=t.childNodes[2],this.iframeElement.setAttribute("scrolling",this.resize==="yes"?"no":"auto"),this.iframeElement.setAttribute("loading",this.lazy?"lazy":"eager"),this.attachShadow({mode:"open"}).appendChild(t),new ResizeObserver(r=>{(this.width===void 0||Math.abs(this.width-r[0].contentRect.width)>2)&&(this.width=r[0].contentRect.width,this.updateAspectRatioHeight())}).observe(this),this.adapter=new P,window.addEventListener("message",r=>this.onMessage(r))}get id(){return this.getAttribute("id")??this.randomId}set id(t){this.setAttribute("id",t)}get debug(){return this.hasAttribute("debug")}set debug(t){t?this.setAttribute("debug",""):this.removeAttribute("debug")}get lazy(){return this.hasAttribute("lazy")}set lazy(t){t?this.setAttribute("lazy",""):this.removeAttribute("lazy")}get src(){return this.getAttribute("src")}set src(t){this.setAttribute("src",t)}get aspectRatio(){const t=this.getAttribute("aspect-ratio");return t===""?"auto":t}set aspectRatio(t){t!==null?this.setAttribute("aspect-ratio",t):this.removeAttribute("aspect-ratio")}get height(){return this.getAttribute("height")}set height(t){t?this.setAttribute("height",t):this.removeAttribute("height")}set resize(t){this.setAttribute("resize",t)}get resize(){const t=this.getAttribute("resize");return t===null?"auto":t===""?"yes":t}get syncParams(){return this.getAttribute("sync-params")}set syncParams(t){t!==null?this.setAttribute("sync-params",t):this.removeAttribute("sync-params")}get syncPath(){const t=this.getAttribute("sync-path");return t===null?null:t||"p"}set syncPath(t){t!==null?this.setAttribute("sync-params",t):this.removeAttribute("sync-params")}get stateChangeEvents(){return this.hasAttribute("state-change-events")}set stateChangeEvents(t){t?this.setAttribute("state-change-events",""):this.removeAttribute("state-change-events")}get actualAspectRatio(){return this.aspectRatio!=="auto"?Number(this.aspectRatio):!this.width||this.width<500?1:this.width<800?4/3:this.width<1200?16/9:21/9}onMessage(t){var s;if(t.source===((s=this.iframeElement)==null?void 0:s.contentWindow)){const i=t.data;if(this.log("debug","received message from child",i),Array.isArray(t.data)){if(u(i)&&(this.postMessageToChild(["df-parent","init",{id:this.id,debug:this.debug,resize:this.resize,syncParams:this.syncParams!==null,syncPath:this.syncPath!==null,stateChangeEvents:this.stateChangeEvents}]),this.init()),c(i)&&(this.resizedHeight=i[2],this.updateStyle()),g(i)){if(this.parsedSyncParams||this.syncPath){const r=R(this.srcUrl,i[3],window.location.href,this.parsedSyncParams,this.syncPath);r.href!==window.location.href&&this.adapter.stateChange(i[2],r)}this.stateChangeEvents&&this.dispatchEvent(new CustomEvent("state-change",{detail:[i[2],i[3]]}))}m(i)&&this.dispatchEvent(new CustomEvent("message",{detail:i[2]})),b(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:i[2]}))}else S(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:v(i.uiNotification)}))}}init(){this.initialSrc=this.src}postMessageToChild(t){var s,i;this.log("debug","send message to child",t),(i=(s=this.iframeElement)==null?void 0:s.contentWindow)==null||i.postMessage(t)}updateSrc(){if(!this.connected)return;this.srcUrl=new URL(this.src.startsWith("/")?window.location.origin+this.src:this.src);const t=z(this.srcUrl,window.location.href,this.parsedSyncParams,this.syncPath);this.initialSrc?this.postMessageToChild(["df-parent","updateSrc",t]):(this.log("debug","set src attribute of iframe: "+t),this.iframeElement.setAttribute("src",t))}updateStyle(){if(!this.connected)return;let t="";(this.resize==="yes"||this.resize==="auto"&&this.resizedHeight)&&(this.iframeElement.getAttribute("scrolling")!=="no"&&(this.log("debug","set scrolling attribute of iframe: no"),this.iframeElement.setAttribute("scrolling","no")),this.resizedHeight?(this.log("debug","height of iframe based on resize message: "+this.resizedHeight),this.slotElement.style.display="none",t+=`height:${this.resizedHeight}px;`):this.height?(this.log("debug","height of iframe based on direct attribute: "+this.height),this.slotElement.style.display="none",t+=`height:${this.height};`):this.aspectRatio!=="auto"&&this.aspectRatio!==null?(this.log("debug","height of iframe based on aspect ratio: "+this.aspectRatioHeight),this.slotElement.style.display="none",t+=`height:${this.aspectRatioHeight}px;`):(this.log("debug","use slot element while waiting for resize message"),this.slotElement.style.display="block",t+="height:0;")),(this.resize==="no"||this.resize==="auto"&&!this.resizedHeight)&&(this.iframeElement.getAttribute("scrolling")!=="auto"&&(this.log("debug","set scrolling attribute of iframe: auto"),this.iframeElement.setAttribute("scrolling","auto")),this.height?(this.log("debug","height of iframe based on direct attribute: "+this.height),t+=`height:${this.height};`):this.aspectRatio!==null&&(this.log("debug","height of iframe based on aspect ratio: "+this.aspectRatioHeight),t+=`height:${this.aspectRatioHeight}px;`)),this.log("debug","set style attribute of iframe: "+t),this.iframeElement.setAttribute("style",t)}updateAspectRatioHeight(){this.width&&this.aspectRatio!==null&&(this.resizedHeight||this.height||(this.aspectRatioHeight=Math.ceil(this.width/this.actualAspectRatio),this.updateStyle()))}log(t,...s){t==="debug"&&!this.debug||(t==="debug"&&console.timeLog(`${this.id}:d-frame`,...s),t==="info"&&console.info(`${this.id}:d-frame`,...s))}connectedCallback(){if(this.debug&&console.time(`${this.id}:d-frame`),!this.hasAttribute("src"))throw new Error("src is a required attribute");this.log("debug","connected"),this.connected=!0,this.adapter.onStateChange&&this.adapter.onStateChange(()=>{this.updateSrc()}),this.syncParams!==null&&(this.parsedSyncParams=E(this.syncParams||"*")),this.updateStyle(),this.updateSrc()}disconnectedCallback(){this.log("debug","disconnected"),this.debug&&console.timeEnd(`[${this.id}:d-frame]`)}static get observedAttributes(){return["src","aspect-ratio","height","sync-params","sync-path"]}attributeChangedCallback(t,s,i){t==="aspect-ratio"&&this.updateAspectRatioHeight(),this.connected&&(this.log("debug","attribute change",t,s,i),t==="src"&&this.updateSrc(),t==="height"&&this.updateStyle(),t==="sync-params"&&this.updateSrc(),t==="sync-path"&&this.updateSrc())}}customElements.define("d-frame",C)})();
14
+ </style><div class="d-frame-wrapper"><slot name="loading"><div style="min-height:150px;"></div></slot><iframe class="d-frame-iframe" style="visibility:hidden;position:absolute;height:0px;"></iframe></div>`;class M extends HTMLElement{constructor(){super();n(this,"adapter");n(this,"connected",!1);n(this,"initialSrc");n(this,"srcUrl");n(this,"parsedSyncParams");n(this,"wrapperElement");n(this,"slotElement");n(this,"iframeElement");n(this,"width");n(this,"aspectRatioHeight");n(this,"resizedHeight");n(this,"randomId");n(this,"iframeLoaded",!1);n(this,"ready",!1);n(this,"iframeExtraAttrs",{});this.randomId=Math.random().toString(36).slice(-6);const t=p.content.cloneNode(!0);this.wrapperElement=t.childNodes[1],this.slotElement=this.wrapperElement.childNodes[0],this.iframeElement=this.wrapperElement.childNodes[1],this.iframeElement.setAttribute("scrolling",this.resize==="yes"?"no":"auto"),this.iframeElement.setAttribute("loading",this.lazy?"lazy":"eager"),this.iframeElement.addEventListener("load",()=>{this.iframeElement.getAttribute("src")&&(this.log("debug","iframe loaded"),this.iframeLoaded=!0,this.dispatchEvent(new CustomEvent("iframe-load")),this.resize!=="yes"&&!this.readyMessage&&(this.ready=!0,this.dispatchEvent(new CustomEvent("ready")),this.updateStyle()))}),this.attachShadow({mode:"open"}).appendChild(t),new ResizeObserver(r=>{(this.width===void 0||Math.abs(this.width-r[0].contentRect.width)>2)&&(this.width=r[0].contentRect.width,this.updateAspectRatioHeight())}).observe(this),this.adapter=new R,window.addEventListener("message",r=>this.onMessage(r))}get id(){return this.getAttribute("id")??this.randomId}set id(t){this.setAttribute("id",t)}get debug(){return this.hasAttribute("debug")}set debug(t){t?this.setAttribute("debug",""):this.removeAttribute("debug")}get lazy(){return this.hasAttribute("lazy")}set lazy(t){t?this.setAttribute("lazy",""):this.removeAttribute("lazy")}get src(){return this.getAttribute("src")}set src(t){this.setAttribute("src",t)}get aspectRatio(){const t=this.getAttribute("aspect-ratio");return t===""?"auto":t}set aspectRatio(t){t!==null?this.setAttribute("aspect-ratio",t):this.removeAttribute("aspect-ratio")}get height(){return this.getAttribute("height")}set height(t){t?this.setAttribute("height",t):this.removeAttribute("height")}set resize(t){this.setAttribute("resize",t)}get resize(){const t=this.getAttribute("resize");return t===null?"auto":t===""?"yes":t}get syncParams(){return this.getAttribute("sync-params")}set syncParams(t){t!==null?this.setAttribute("sync-params",t):this.removeAttribute("sync-params")}get syncPath(){const t=this.getAttribute("sync-path");return t===null?null:t||"p"}set syncPath(t){t!==null?this.setAttribute("sync-params",t):this.removeAttribute("sync-params")}get stateChangeEvents(){return this.hasAttribute("state-change-events")}set stateChangeEvents(t){t?this.setAttribute("state-change-events",""):this.removeAttribute("state-change-events")}get readyMessage(){return this.hasAttribute("ready-message")}set readyMessage(t){t?this.setAttribute("ready-message",""):this.removeAttribute("ready-message")}get actualAspectRatio(){return this.aspectRatio!=="auto"?Number(this.aspectRatio):!this.width||this.width<500?1:this.width<800?4/3:this.width<1200?16/9:21/9}onMessage(t){var s;if(t.source===((s=this.iframeElement)==null?void 0:s.contentWindow)){const i=t.data;if(this.log("debug","received message from child",i),Array.isArray(t.data)){if(l(i)&&(this.postMessageToChild(["df-parent","init",{id:this.id,debug:this.debug,resize:this.resize,syncParams:this.syncParams!==null,syncPath:this.syncPath!==null,stateChangeEvents:this.stateChangeEvents}]),this.init()),c(i)&&(this.resizedHeight=i[2],this.resize==="yes"&&!this.ready&&!this.readyMessage&&(this.ready=!0,this.dispatchEvent(new CustomEvent("ready"))),this.updateStyle()),f(i)){if(this.parsedSyncParams||this.syncPath){const r=C(this.srcUrl,i[3],window.location.href,this.parsedSyncParams,this.syncPath);r.href!==window.location.href&&this.adapter.stateChange(i[2],r)}this.stateChangeEvents&&this.dispatchEvent(new CustomEvent("state-change",{detail:[i[2],i[3]]}))}m(i)&&this.dispatchEvent(new CustomEvent("message",{detail:i[2]})),b(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:i[2]})),y(i)&&(this.ready=!0,this.dispatchEvent(new CustomEvent("ready")),this.updateStyle())}else P(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:z(i.uiNotification)}))}}init(){this.initialSrc=this.src}postMessageToChild(t){var s,i;this.log("debug","send message to child",t),(i=(s=this.iframeElement)==null?void 0:s.contentWindow)==null||i.postMessage(t)}updateSrc(){if(!this.connected)return;this.srcUrl=new URL(this.src.startsWith("/")?window.location.origin+this.src:this.src);const t=S(this.srcUrl,window.location.href,this.parsedSyncParams,this.syncPath);this.initialSrc?this.postMessageToChild(["df-parent","updateSrc",t]):(this.log("debug","set src attribute of iframe: "+t),this.iframeElement.setAttribute("src",t))}updateStyle(){if(!this.connected)return;let t;this.resizedHeight?(this.log("debug","height of iframe based on resize message: "+this.resizedHeight),t=this.resizedHeight+"px"):this.height?(this.log("debug","height of iframe based on direct attribute: "+this.height),t=this.height):this.aspectRatio!==null&&(this.log("debug","height of iframe based on aspect ratio: "+this.aspectRatioHeight),t=this.aspectRatioHeight+"px"),t!==void 0?(this.log("debug","set height iframe wrapper: "+t),this.wrapperElement.setAttribute("style",`height:${t};min-height:0;`)):this.wrapperElement.setAttribute("style",""),this.resize==="yes"||this.resize==="auto"&&this.resizedHeight?this.iframeElement.getAttribute("scrolling")!=="no"&&(this.log("debug","set scrolling attribute of iframe: no"),this.iframeElement.setAttribute("scrolling","no")):this.iframeElement.getAttribute("scrolling")!=="auto"&&(this.log("debug","set scrolling attribute of iframe: auto"),this.iframeElement.setAttribute("scrolling","auto")),this.ready&&this.iframeElement.getAttribute("style")!==""&&(this.log("debug","toggle loading slot and iframe visibility"),this.iframeElement.setAttribute("style",""),this.slotElement.setAttribute("style","display:none;"))}updateAspectRatioHeight(){this.width&&this.aspectRatio!==null&&(this.resizedHeight||this.height||(this.aspectRatioHeight=Math.ceil(this.width/this.actualAspectRatio),this.updateStyle()))}updateIframeExtraAttrs(){const t=this.iframeExtraAttrs,s={};for(const i of this.getAttributeNames())if(i.startsWith("iframe-")){const r=this.getAttribute(i);if(r!==null){const d=i.slice(7);s[d]=r}}for(const i of Object.keys(t))i in s||this.iframeElement.removeAttribute(i);for(const i of Object.keys(s))s[i]!==t[i]&&this.iframeElement.setAttribute(i,s[i])}log(t,...s){t==="debug"&&!this.debug||(t==="debug"&&console.timeLog(`d-frame:${this.id}`,...s),t==="info"&&console.info(`d-frame:${this.id}`,...s))}connectedCallback(){if(!this.debug){const t=window.localStorage.getItem("debug");if(t){const s=t.split(",");(s.includes("d-frame")||s.includes("d-frame:"+this.id))&&(this.debug=!0)}}if(this.debug&&console.time(`d-frame:${this.id}`),!this.hasAttribute("src"))throw new Error("src is a required attribute");this.log("debug","connected"),this.connected=!0,this.adapter.onStateChange&&this.adapter.onStateChange(()=>{this.updateSrc()}),this.syncParams!==null&&(this.parsedSyncParams=v(this.syncParams||"*")),this.updateStyle(),this.updateSrc(),this.updateIframeExtraAttrs()}disconnectedCallback(){this.log("debug","disconnected"),this.debug&&console.timeEnd(`d-frame:${this.id}`)}static get observedAttributes(){return["src","aspect-ratio","height","sync-params","sync-path"]}attributeChangedCallback(t,s,i){t==="aspect-ratio"&&this.updateAspectRatioHeight(),t.startsWith("iframe-")&&this.updateIframeExtraAttrs(),this.connected&&(this.log("debug","attribute change",t,s,i),t==="src"&&this.updateSrc(),t==="height"&&this.updateStyle(),t==="sync-params"&&this.updateSrc(),t==="sync-path"&&this.updateSrc())}}customElements.get("d-frame")||customElements.define("d-frame",M)})();
12
15
  //# sourceMappingURL=d-frame.min.js.map
@@ -1,2 +1,2 @@
1
- var VIframeCompatDFrameContent=function(){"use strict";var g=Object.defineProperty;var f=(r,o,h)=>o in r?g(r,o,{enumerable:!0,configurable:!0,writable:!0,value:h}):r[o]=h;var s=(r,o,h)=>f(r,typeof o!="symbol"?o+"":o,h);function r(n){return n[0]==="df-parent"&&n[1]==="init"}function o(n){return n[0]==="df-parent"&&n[1]==="updateSrc"}const h=["animationstart","webkitAnimationStart","animationiteration","webkitAnimationIteration","animationend","webkitAnimationEnd","input","mouseup","mousedown","orientationchange","afterprint","beforeprint","readystatechange","touchstart","touchend","touchcancel","transitionstart","webkitTransitionStart","MSTransitionStart","oTransitionStart","otransitionstart","transitioniteration","webkitTransitionIteration","MSTransitionIteration","oTransitionIteration","otransitioniteration","transitionend","webkitTransitionEnd","MSTransitionEnd","oTransitionEnd","otransitionend","resize"];class l{constructor(t){s(this,"initialized",!1);s(this,"options");s(this,"pendingCheckHeight",!1);s(this,"debug",!1);s(this,"id");s(this,"throttledCheckHeight");s(this,"lastHeight",0);this.options=t??{};const e=()=>{this.checkHeight(),this.pendingCheckHeight=!1};this.throttledCheckHeight=()=>{this.pendingCheckHeight||(this.pendingCheckHeight=!0,requestAnimationFrame(e))},!(typeof window>"u")&&(window.addEventListener("message",i=>this.onMessage(i)),this.postMessageToParent(["df-child","init"]))}log(t,...e){t==="debug"&&!this.debug||(t==="debug"&&console.timeLog(`${this.id}:d-frame-content`,...e),t==="info"&&console.info(`${this.id}:d-frame-content`,...e))}onMessage(t){if(t.source===window.parent&&Array.isArray(t.data)){const e=t.data;r(e)&&(this.id=e[2].id,this.debug=!!e[2].debug,this.debug&&console.time(`${this.id}:d-frame-content`),e[2].resize!=="no"&&this.initResize(),(e[2].syncParams||e[2].syncPath||e[2].stateChangeEvents)&&this.initStateChangeWatcher(),this.initialized=!0),o(e)&&(this.options.updateSrc?this.options.updateSrc(e[2].startsWith("/")?window.location.origin+e[2]:e[2]):window.location.href=e[2])}}postMessageToParent(t){window.parent.postMessage(t)}sendNotif(t){this.postMessageToParent(["df-child","notif",t])}sendMessage(t){this.postMessageToParent(["df-child","custom",t])}initResize(){this.log("debug","initResize"),this.checkHeight(),this.createMutationObserver(),this.createWindowEventListeners()}initStateChangeWatcher(){this.log("debug","initStateChangeWatcher");const t=window.history.replaceState,e=(...a)=>{const d=t.apply(window.history,a);return this.postMessageToParent(["df-child","stateChange","push",window.location.href]),d};window.history.pushState=e;const i=(...a)=>{const d=t.apply(window.history,a);return this.postMessageToParent(["df-child","stateChange","replace",window.location.href]),d};window.history.replaceState=i}createMutationObserver(){const t=document.querySelector("body");if(!t)throw new Error("DFrameContentManager was initialized before the HTML body");new window.MutationObserver(this.throttledCheckHeight).observe(t,{attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1,childList:!0,subtree:!0})}createWindowEventListeners(){for(const t of h)window.addEventListener(t,this.throttledCheckHeight,{passive:!0})}checkHeight(){const t=document.querySelectorAll("[data-iframe-height]");let e=0;for(const i of t){const a=i.getAttribute("data-iframe-height"),d=i.getBoundingClientRect().bottom+parseFloat(getComputedStyle(i).getPropertyValue("margin-bottom"))+(a?parseFloat(a):0);d>e&&(e=d)}e=Math.ceil(e),e!==this.lastHeight&&(this.postMessageToParent(["df-child","height",e]),this.lastHeight=e)}}const u=(n,t)=>{const e=Object.keys(n);t.forEach((i,a)=>{n[a]=i,e.splice(e.indexOf(a),1)}),e.forEach(i=>{delete n[i]})},c=new l({updateSrc:n=>{const t=window.vIframeOptions,e=t==null?void 0:t.reactiveParams;if(e){const i=new URL(n);if(i.origin===window.location.origin&&i.pathname===window.location.pathname){u(e,i.searchParams);return}}if(t!=null&&t.router){const i=window.location.origin+t.router.options.history.base;if(n.startsWith(i)){t.router.replace(n.replace(i,""));return}}window.location.href=n}});return window.dFrameContent=c,c}();
1
+ var VIframeCompatDFrameContent=function(){"use strict";var w=Object.defineProperty;var p=(r,a,h)=>a in r?w(r,a,{enumerable:!0,configurable:!0,writable:!0,value:h}):r[a]=h;var s=(r,a,h)=>p(r,typeof a!="symbol"?a+"":a,h);function r(n){return n[0]==="df-parent"&&n[1]==="init"}function a(n){return n[0]==="df-parent"&&n[1]==="updateSrc"}const h=["animationstart","webkitAnimationStart","animationiteration","webkitAnimationIteration","animationend","webkitAnimationEnd","input","mouseup","mousedown","orientationchange","afterprint","beforeprint","readystatechange","touchstart","touchend","touchcancel","transitionstart","webkitTransitionStart","MSTransitionStart","oTransitionStart","otransitionstart","transitioniteration","webkitTransitionIteration","MSTransitionIteration","oTransitionIteration","otransitioniteration","transitionend","webkitTransitionEnd","MSTransitionEnd","oTransitionEnd","otransitionend","resize"];class u{constructor(t){s(this,"initialized",!1);s(this,"options");s(this,"pendingCheckHeight",!1);s(this,"debug",!1);s(this,"id");s(this,"throttledCheckHeight");s(this,"lastHeight",0);this.options=t??{};const e=()=>{this.checkHeight(),this.pendingCheckHeight=!1};this.throttledCheckHeight=()=>{this.pendingCheckHeight||(this.pendingCheckHeight=!0,requestAnimationFrame(e))},!(typeof window>"u")&&(window.addEventListener("message",i=>this.onMessage(i)),this.postMessageToParent(["df-child","init"]))}log(t,...e){t==="debug"&&!this.debug||(t==="debug"&&console.timeLog(`d-frame:${this.id}:content`,...e),t==="info"&&console.info(`d-frame:${this.id}:content`,...e))}onMessage(t){if(t.source===window.parent&&Array.isArray(t.data)){const e=t.data;r(e)&&(this.id=e[2].id,this.debug=!!e[2].debug,this.debug&&console.time(`d-frame:${this.id}:content`),e[2].resize!=="no"&&this.initResize(),(e[2].syncParams||e[2].syncPath||e[2].stateChangeEvents)&&this.initStateChangeWatcher(),this.initialized=!0),a(e)&&(this.options.updateSrc?this.options.updateSrc(e[2].startsWith("/")?window.location.origin+e[2]:e[2]):window.location.href=e[2])}}postMessageToParent(t){window.parent.postMessage(t)}sendNotif(t){this.postMessageToParent(["df-child","notif",t])}sendMessage(t){this.postMessageToParent(["df-child","custom",t])}ready(){this.postMessageToParent(["df-child","ready"])}initResize(){this.log("debug","initResize"),this.checkHeight(),this.createMutationObserver(),this.createWindowEventListeners()}initStateChangeWatcher(){this.log("debug","initStateChangeWatcher");const t=window.history.replaceState,e=(...o)=>{const d=t.apply(window.history,o);return this.postMessageToParent(["df-child","stateChange","push",window.location.href]),d};window.history.pushState=e;const i=(...o)=>{const d=t.apply(window.history,o);return this.postMessageToParent(["df-child","stateChange","replace",window.location.href]),d};window.history.replaceState=i}createMutationObserver(){const t=document.querySelector("body");if(!t)throw new Error("DFrameContentManager was initialized before the HTML body");new window.MutationObserver(this.throttledCheckHeight).observe(t,{attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1,childList:!0,subtree:!0})}createWindowEventListeners(){for(const t of h)window.addEventListener(t,this.throttledCheckHeight,{passive:!0})}checkHeight(){const t=document.querySelectorAll("[data-iframe-height]");let e=0,i=0;for(const o of t){const d=o.getAttribute("data-iframe-height"),c=o.getBoundingClientRect().bottom+parseFloat(getComputedStyle(o).getPropertyValue("margin-bottom")),f=d?c+parseFloat(d):c;c>e&&(e=c),f>i&&(i=f)}i=Math.ceil(i),e>0&&i!==this.lastHeight&&(this.postMessageToParent(["df-child","height",i]),this.lastHeight=i)}}const g=(n,t)=>{const e=Object.keys(n);t.forEach((i,o)=>{n[o]=i,e.splice(e.indexOf(o),1)}),e.forEach(i=>{delete n[i]})},l=new u({updateSrc:n=>{const t=window.vIframeOptions,e=t==null?void 0:t.reactiveParams;if(e&&typeof e=="object"){const i=new URL(n);if(i.origin===window.location.origin&&i.pathname===window.location.pathname){g(e,i.searchParams);return}}if(t!=null&&t.router){const i=window.location.origin+t.router.options.history.base;if(n.startsWith(i)){t.router.replace(n.replace(i,""));return}}window.location.href=n}});return window.dFrameContent=l,l}();
2
2
  //# sourceMappingURL=d-frame-content.min.js.map
@@ -16,6 +16,7 @@ export default class DFrameContent {
16
16
  private postMessageToParent;
17
17
  sendNotif(notif: Notif): void;
18
18
  sendMessage(msg: any): void;
19
+ ready(): void;
19
20
  private initResize;
20
21
  private initStateChangeWatcher;
21
22
  private createMutationObserver;
@@ -60,9 +60,9 @@ export default class DFrameContent {
60
60
  if (level === 'debug' && !this.debug)
61
61
  return;
62
62
  if (level === 'debug')
63
- console.timeLog(`${this.id}:d-frame-content`, ...args);
63
+ console.timeLog(`d-frame:${this.id}:content`, ...args);
64
64
  if (level === 'info')
65
- console.info(`${this.id}:d-frame-content`, ...args);
65
+ console.info(`d-frame:${this.id}:content`, ...args);
66
66
  }
67
67
  onMessage(e) {
68
68
  if (e.source === window.parent && Array.isArray(e.data)) {
@@ -71,7 +71,7 @@ export default class DFrameContent {
71
71
  this.id = message[2].id;
72
72
  this.debug = !!message[2].debug;
73
73
  if (this.debug)
74
- console.time(`${this.id}:d-frame-content`);
74
+ console.time(`d-frame:${this.id}:content`);
75
75
  if (message[2].resize !== 'no')
76
76
  this.initResize();
77
77
  if (message[2].syncParams || message[2].syncPath || message[2].stateChangeEvents)
@@ -97,6 +97,9 @@ export default class DFrameContent {
97
97
  sendMessage(msg) {
98
98
  this.postMessageToParent(['df-child', 'custom', msg]);
99
99
  }
100
+ ready() {
101
+ this.postMessageToParent(['df-child', 'ready']);
102
+ }
100
103
  initResize() {
101
104
  this.log('debug', 'initResize');
102
105
  this.checkHeight();
@@ -143,17 +146,20 @@ export default class DFrameContent {
143
146
  }
144
147
  checkHeight() {
145
148
  const elements = document.querySelectorAll('[data-iframe-height]');
149
+ let maxWithoutOffset = 0;
146
150
  let max = 0;
147
151
  for (const element of elements) {
148
152
  const dataAttribute = element.getAttribute('data-iframe-height');
149
- const bottom = element.getBoundingClientRect().bottom +
150
- parseFloat(getComputedStyle(element).getPropertyValue('margin-bottom')) +
151
- (dataAttribute ? parseFloat(dataAttribute) : 0);
153
+ const bottomWithoutOffset = element.getBoundingClientRect().bottom +
154
+ parseFloat(getComputedStyle(element).getPropertyValue('margin-bottom'));
155
+ const bottom = dataAttribute ? (bottomWithoutOffset + parseFloat(dataAttribute)) : bottomWithoutOffset;
156
+ if (bottomWithoutOffset > maxWithoutOffset)
157
+ maxWithoutOffset = bottomWithoutOffset;
152
158
  if (bottom > max)
153
159
  max = bottom;
154
160
  }
155
161
  max = Math.ceil(max);
156
- if (max !== this.lastHeight) {
162
+ if (maxWithoutOffset > 0 && max !== this.lastHeight) {
157
163
  this.postMessageToParent(['df-child', 'height', max]);
158
164
  this.lastHeight = max;
159
165
  }
@@ -24,17 +24,23 @@ export default class DFrameElement extends HTMLElement {
24
24
  set syncPath(value: string | null);
25
25
  get stateChangeEvents(): boolean;
26
26
  set stateChangeEvents(value: boolean);
27
+ get readyMessage(): boolean;
28
+ set readyMessage(value: boolean);
27
29
  adapter: StateChangeAdapter;
28
30
  private connected;
29
31
  private initialSrc;
30
32
  private srcUrl;
31
33
  private parsedSyncParams;
32
- private iframeElement;
34
+ private wrapperElement;
33
35
  private slotElement;
36
+ private iframeElement;
34
37
  private width;
35
38
  private aspectRatioHeight;
36
39
  private resizedHeight;
37
40
  private randomId;
41
+ private iframeLoaded;
42
+ private ready;
43
+ private iframeExtraAttrs;
38
44
  get actualAspectRatio(): number;
39
45
  constructor();
40
46
  onMessage(e: MessageEvent): void;
@@ -43,6 +49,7 @@ export default class DFrameElement extends HTMLElement {
43
49
  updateSrc(): void;
44
50
  updateStyle(): void;
45
51
  updateAspectRatioHeight(): void;
52
+ updateIframeExtraAttrs(): void;
46
53
  log(level: 'debug' | 'info', ...args: any[]): void;
47
54
  connectedCallback(): void;
48
55
  disconnectedCallback(): void;
@@ -1,5 +1,5 @@
1
1
  // this is a good doc about writing web components https://web.dev/articles/custom-elements-best-practices
2
- import { isCustomMessage, isHeightMessage, isInitChildMessage, isNotifMessage, isStateChangeMessage } from './messages.js';
2
+ import { isCustomMessage, isHeightMessage, isInitChildMessage, isNotifMessage, isReadyMessage, isStateChangeMessage } from './messages.js';
3
3
  import { parseSyncParams, getChildSrc, getParentUrl } from './utils/sync-params.js';
4
4
  import { isVIframeUiNotif, convertVIframeUiNotif } from './v-iframe-compat/ui-notif.js';
5
5
  class WindowStateChangeAdapter {
@@ -15,13 +15,16 @@ template.innerHTML = `<style>
15
15
  :host {
16
16
  display: block;
17
17
  }
18
+ .d-frame-wrapper {
19
+ height: 100%;
20
+ }
18
21
  iframe.d-frame-iframe {
19
22
  display: block;
20
23
  width: 100%;
21
24
  height: 100%;
22
25
  border: none;
23
26
  }
24
- </style><slot name="loader"></slot><iframe class="d-frame-iframe" frameborder="0">`;
27
+ </style><div class="d-frame-wrapper"><slot name="loading"><div style="min-height:150px;"></div></slot><iframe class="d-frame-iframe" style="visibility:hidden;position:absolute;height:0px;"></iframe></div>`;
25
28
  export default class DFrameElement extends HTMLElement {
26
29
  get id() { return this.getAttribute('id') ?? this.randomId; }
27
30
  set id(value) {
@@ -97,18 +100,29 @@ export default class DFrameElement extends HTMLElement {
97
100
  else
98
101
  this.removeAttribute('state-change-events');
99
102
  }
103
+ get readyMessage() { return this.hasAttribute('ready-message'); }
104
+ set readyMessage(value) {
105
+ if (value)
106
+ this.setAttribute('ready-message', '');
107
+ else
108
+ this.removeAttribute('ready-message');
109
+ }
100
110
  adapter;
101
111
  /* internal state */
102
112
  connected = false;
103
113
  initialSrc;
104
114
  srcUrl;
105
115
  parsedSyncParams;
106
- iframeElement;
116
+ wrapperElement;
107
117
  slotElement;
118
+ iframeElement;
108
119
  width;
109
120
  aspectRatioHeight;
110
121
  resizedHeight;
111
122
  randomId;
123
+ iframeLoaded = false;
124
+ ready = false;
125
+ iframeExtraAttrs = {};
112
126
  get actualAspectRatio() {
113
127
  if (this.aspectRatio !== 'auto')
114
128
  return Number(this.aspectRatio);
@@ -124,12 +138,23 @@ export default class DFrameElement extends HTMLElement {
124
138
  super();
125
139
  this.randomId = Math.random().toString(36).slice(-6);
126
140
  const root = template.content.cloneNode(true);
127
- this.slotElement = root.childNodes[1];
128
- if (this.resize !== 'yes')
129
- this.slotElement.style.display = 'none';
130
- this.iframeElement = root.childNodes[2];
141
+ this.wrapperElement = root.childNodes[1];
142
+ this.slotElement = this.wrapperElement.childNodes[0];
143
+ this.iframeElement = this.wrapperElement.childNodes[1];
131
144
  this.iframeElement.setAttribute('scrolling', this.resize === 'yes' ? 'no' : 'auto');
132
145
  this.iframeElement.setAttribute('loading', this.lazy ? 'lazy' : 'eager');
146
+ this.iframeElement.addEventListener('load', () => {
147
+ if (this.iframeElement.getAttribute('src')) {
148
+ this.log('debug', 'iframe loaded');
149
+ this.iframeLoaded = true;
150
+ this.dispatchEvent(new CustomEvent('iframe-load'));
151
+ if (this.resize !== 'yes' && !this.readyMessage) {
152
+ this.ready = true;
153
+ this.dispatchEvent(new CustomEvent('ready'));
154
+ this.updateStyle();
155
+ }
156
+ }
157
+ });
133
158
  const shadowRoot = this.attachShadow({ mode: 'open' });
134
159
  shadowRoot.appendChild(root);
135
160
  const resizeObserver = new ResizeObserver((entries) => {
@@ -162,6 +187,10 @@ export default class DFrameElement extends HTMLElement {
162
187
  }
163
188
  if (isHeightMessage(message)) {
164
189
  this.resizedHeight = message[2];
190
+ if (this.resize === 'yes' && !this.ready && !this.readyMessage) {
191
+ this.ready = true;
192
+ this.dispatchEvent(new CustomEvent('ready'));
193
+ }
165
194
  this.updateStyle();
166
195
  }
167
196
  if (isStateChangeMessage(message)) {
@@ -181,6 +210,11 @@ export default class DFrameElement extends HTMLElement {
181
210
  if (isNotifMessage(message)) {
182
211
  this.dispatchEvent(new CustomEvent('notif', { detail: message[2] }));
183
212
  }
213
+ if (isReadyMessage(message)) {
214
+ this.ready = true;
215
+ this.dispatchEvent(new CustomEvent('ready'));
216
+ this.updateStyle();
217
+ }
184
218
  }
185
219
  else if (isVIframeUiNotif(message)) {
186
220
  // maintain compatibility with v-iframe notifications sent through postMessage
@@ -212,51 +246,48 @@ export default class DFrameElement extends HTMLElement {
212
246
  updateStyle() {
213
247
  if (!this.connected)
214
248
  return;
215
- let style = '';
249
+ // manage height of iframe wrapper
250
+ let wrapperHeight;
251
+ if (this.resizedHeight) {
252
+ this.log('debug', 'height of iframe based on resize message: ' + this.resizedHeight);
253
+ wrapperHeight = this.resizedHeight + 'px';
254
+ }
255
+ else {
256
+ if (this.height) {
257
+ this.log('debug', 'height of iframe based on direct attribute: ' + this.height);
258
+ wrapperHeight = this.height;
259
+ }
260
+ else if (this.aspectRatio !== null) {
261
+ this.log('debug', 'height of iframe based on aspect ratio: ' + this.aspectRatioHeight);
262
+ wrapperHeight = this.aspectRatioHeight + 'px';
263
+ }
264
+ }
265
+ if (wrapperHeight !== undefined) {
266
+ this.log('debug', 'set height iframe wrapper: ' + wrapperHeight);
267
+ this.wrapperElement.setAttribute('style', `height:${wrapperHeight};min-height:0;`);
268
+ }
269
+ else {
270
+ this.wrapperElement.setAttribute('style', '');
271
+ }
272
+ // set scrolling attribute of iframe
216
273
  if (this.resize === 'yes' || (this.resize === 'auto' && this.resizedHeight)) {
217
274
  if (this.iframeElement.getAttribute('scrolling') !== 'no') {
218
275
  this.log('debug', 'set scrolling attribute of iframe: no');
219
276
  this.iframeElement.setAttribute('scrolling', 'no');
220
277
  }
221
- if (this.resizedHeight) {
222
- this.log('debug', 'height of iframe based on resize message: ' + this.resizedHeight);
223
- this.slotElement.style.display = 'none';
224
- style += `height:${this.resizedHeight}px;`;
225
- }
226
- else {
227
- if (this.height) {
228
- this.log('debug', 'height of iframe based on direct attribute: ' + this.height);
229
- this.slotElement.style.display = 'none';
230
- style += `height:${this.height};`;
231
- }
232
- else if (this.aspectRatio !== 'auto' && this.aspectRatio !== null) {
233
- this.log('debug', 'height of iframe based on aspect ratio: ' + this.aspectRatioHeight);
234
- this.slotElement.style.display = 'none';
235
- style += `height:${this.aspectRatioHeight}px;`;
236
- }
237
- else {
238
- this.log('debug', 'use slot element while waiting for resize message');
239
- this.slotElement.style.display = 'block';
240
- style += 'height:0;';
241
- }
242
- }
243
278
  }
244
- if (this.resize === 'no' || (this.resize === 'auto' && !this.resizedHeight)) {
279
+ else {
245
280
  if (this.iframeElement.getAttribute('scrolling') !== 'auto') {
246
281
  this.log('debug', 'set scrolling attribute of iframe: auto');
247
282
  this.iframeElement.setAttribute('scrolling', 'auto');
248
283
  }
249
- if (this.height) {
250
- this.log('debug', 'height of iframe based on direct attribute: ' + this.height);
251
- style += `height:${this.height};`;
252
- }
253
- else if (this.aspectRatio !== null) {
254
- this.log('debug', 'height of iframe based on aspect ratio: ' + this.aspectRatioHeight);
255
- style += `height:${this.aspectRatioHeight}px;`;
256
- }
257
284
  }
258
- this.log('debug', 'set style attribute of iframe: ' + style);
259
- this.iframeElement.setAttribute('style', style);
285
+ // toggle loading slot vs iframe visibility
286
+ if (this.ready && this.iframeElement.getAttribute('style') !== '') {
287
+ this.log('debug', 'toggle loading slot and iframe visibility');
288
+ this.iframeElement.setAttribute('style', '');
289
+ this.slotElement.setAttribute('style', 'display:none;');
290
+ }
260
291
  }
261
292
  updateAspectRatioHeight() {
262
293
  if (!this.width)
@@ -270,19 +301,49 @@ export default class DFrameElement extends HTMLElement {
270
301
  this.aspectRatioHeight = Math.ceil(this.width / this.actualAspectRatio);
271
302
  this.updateStyle();
272
303
  }
304
+ updateIframeExtraAttrs() {
305
+ const previousAttrs = this.iframeExtraAttrs;
306
+ const newAttrs = {};
307
+ for (const name of this.getAttributeNames()) {
308
+ if (name.startsWith('iframe-')) {
309
+ const value = this.getAttribute(name);
310
+ if (value !== null) {
311
+ const attrName = name.slice(7);
312
+ newAttrs[attrName] = value;
313
+ }
314
+ }
315
+ }
316
+ for (const key of Object.keys(previousAttrs)) {
317
+ if (!(key in newAttrs)) {
318
+ this.iframeElement.removeAttribute(key);
319
+ }
320
+ }
321
+ for (const key of Object.keys(newAttrs)) {
322
+ if (newAttrs[key] !== previousAttrs[key]) {
323
+ this.iframeElement.setAttribute(key, newAttrs[key]);
324
+ }
325
+ }
326
+ }
273
327
  log(level, ...args) {
274
328
  if (level === 'debug' && !this.debug)
275
329
  return;
276
330
  if (level === 'debug')
277
- console.timeLog(`${this.id}:d-frame`, ...args);
278
- // if (level === 'debug') console.debug(`${this.id}:d-frame`, ...args)
331
+ console.timeLog(`d-frame:${this.id}`, ...args);
279
332
  if (level === 'info')
280
- console.info(`${this.id}:d-frame`, ...args);
333
+ console.info(`d-frame:${this.id}`, ...args);
281
334
  }
282
335
  /* standard custom element callbacks */
283
336
  connectedCallback() {
337
+ if (!this.debug) {
338
+ const globalDebug = window.localStorage.getItem('debug');
339
+ if (globalDebug) {
340
+ const debugParts = globalDebug.split(',');
341
+ if (debugParts.includes('d-frame') || debugParts.includes('d-frame:' + this.id))
342
+ this.debug = true;
343
+ }
344
+ }
284
345
  if (this.debug)
285
- console.time(`${this.id}:d-frame`);
346
+ console.time(`d-frame:${this.id}`);
286
347
  if (!this.hasAttribute('src'))
287
348
  throw new Error('src is a required attribute');
288
349
  this.log('debug', 'connected');
@@ -294,11 +355,12 @@ export default class DFrameElement extends HTMLElement {
294
355
  this.parsedSyncParams = parseSyncParams(this.syncParams || '*');
295
356
  this.updateStyle();
296
357
  this.updateSrc();
358
+ this.updateIframeExtraAttrs();
297
359
  }
298
360
  disconnectedCallback() {
299
361
  this.log('debug', 'disconnected');
300
362
  if (this.debug)
301
- console.timeEnd(`[${this.id}:d-frame]`);
363
+ console.timeEnd(`d-frame:${this.id}`);
302
364
  // TODO: more cleanup (resize observer, etc)
303
365
  }
304
366
  /* reflected attributes */
@@ -306,6 +368,8 @@ export default class DFrameElement extends HTMLElement {
306
368
  attributeChangedCallback(name, oldValue, newValue) {
307
369
  if (name === 'aspect-ratio')
308
370
  this.updateAspectRatioHeight();
371
+ if (name.startsWith('iframe-'))
372
+ this.updateIframeExtraAttrs();
309
373
  if (!this.connected)
310
374
  return;
311
375
  this.log('debug', 'attribute change', name, oldValue, newValue);
package/lib/d-frame.js CHANGED
@@ -1,2 +1,4 @@
1
1
  import DFrameElement from './DFrameElement.js';
2
- customElements.define('d-frame', DFrameElement);
2
+ if (!customElements.get('d-frame')) {
3
+ customElements.define('d-frame', DFrameElement);
4
+ }
package/lib/messages.d.ts CHANGED
@@ -3,7 +3,8 @@ export type HeightMessage = ['df-child', 'height', number];
3
3
  export type StateChangeMessage = ['df-child', 'stateChange', 'replace' | 'push', string];
4
4
  export type CustomMessage = ['df-child', 'custom', any];
5
5
  export type NotifMessage = ['df-child', 'notif', Notif];
6
- export type ChildMessage = InitChildMessage | HeightMessage | StateChangeMessage | CustomMessage | NotifMessage;
6
+ export type ReadyMessage = ['df-child', 'ready'];
7
+ export type ChildMessage = InitChildMessage | HeightMessage | StateChangeMessage | CustomMessage | NotifMessage | ReadyMessage;
7
8
  export type Notif = {
8
9
  type: 'default' | 'info' | 'success' | 'warning' | 'error';
9
10
  title: string;
@@ -14,14 +15,19 @@ export declare function isHeightMessage(message: any): message is HeightMessage;
14
15
  export declare function isStateChangeMessage(message: any): message is StateChangeMessage;
15
16
  export declare function isCustomMessage(message: any): message is CustomMessage;
16
17
  export declare function isNotifMessage(message: any): message is NotifMessage;
17
- export type InitParentMessage = ['df-parent', 'init', {
18
- id: string;
19
- debug?: boolean;
20
- resize: 'yes' | 'no' | 'auto';
21
- syncParams: boolean;
22
- syncPath: boolean;
23
- stateChangeEvents: boolean;
24
- }];
18
+ export declare function isReadyMessage(message: any): message is ReadyMessage;
19
+ export type InitParentMessage = [
20
+ 'df-parent',
21
+ 'init',
22
+ {
23
+ id: string;
24
+ debug?: boolean;
25
+ resize: 'yes' | 'no' | 'auto';
26
+ syncParams: boolean;
27
+ syncPath: boolean;
28
+ stateChangeEvents: boolean;
29
+ }
30
+ ];
25
31
  export type UpdateSrcMessage = ['df-parent', 'updateSrc', string];
26
32
  export type ParentMessage = InitParentMessage | UpdateSrcMessage;
27
33
  export declare function isInitParentMessage(message: any[]): message is InitParentMessage;
package/lib/messages.js CHANGED
@@ -13,6 +13,9 @@ export function isCustomMessage(message) {
13
13
  export function isNotifMessage(message) {
14
14
  return message[0] === 'df-child' && message[1] === 'notif';
15
15
  }
16
+ export function isReadyMessage(message) {
17
+ return message[0] === 'df-child' && message[1] === 'ready';
18
+ }
16
19
  export function isInitParentMessage(message) {
17
20
  return message[0] === 'df-parent' && message[1] === 'init';
18
21
  }
@@ -2,7 +2,7 @@ import DFrameContent from '../DFrameContent.js';
2
2
  import type { Router } from 'vue-router';
3
3
  export type VIframeOptions = {
4
4
  router?: Router;
5
- reactiveParams?: Record<string, string>;
5
+ reactiveParams?: Record<string, string> | boolean;
6
6
  };
7
7
  declare const dFrameContent: DFrameContent;
8
8
  export default dFrameContent;
@@ -4,7 +4,7 @@ const dFrameContent = new DFrameContent({
4
4
  updateSrc: (src) => {
5
5
  const vIframeOptions = window.vIframeOptions;
6
6
  const reactiveParams = vIframeOptions?.reactiveParams;
7
- if (reactiveParams) {
7
+ if (reactiveParams && typeof reactiveParams === 'object') {
8
8
  const srcUrl = new URL(src);
9
9
  if (srcUrl.origin === window.location.origin && srcUrl.pathname === window.location.pathname) {
10
10
  applySearchParams(reactiveParams, srcUrl.searchParams);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-fair/frame",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "An iframe wrapper for powerful web app integrations.",
5
5
  "main": "dist/frame.min.js",
6
6
  "directories": {