@data-fair/frame 0.10.0 → 0.11.1

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 w=Object.defineProperty;var g=(r,n,h)=>n in r?w(r,n,{enumerable:!0,configurable:!0,writable:!0,value:h}):r[n]=h;var s=(r,n,h)=>g(r,typeof n!="symbol"?n+"":n,h);function r(o){return o[0]==="df-global"&&o[1]==="mouse"}function n(o){return o[0]==="df-parent"&&o[1]==="init"}function h(o){return o[0]==="df-parent"&&o[1]==="updateSrc"}const f=["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);s(this,"currentSyncedMouseEvents",new Set);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),t==="error"&&console.error(`d-frame:${this.id}:content`,...e))}onMessage(t){if(t.source===window.parent&&Array.isArray(t.data)){const e=t.data;if(n(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(),e[2].mouseEvents&&this.initMouseEvents(e[2].mouseEvents),this.initialized=!0),h(e)){const i=e[2].startsWith("/")?window.location.origin+e[2]:e[2];if(i===window.location.href)return;this.options.updateSrc?this.options.updateSrc(i,this):window.location.href=e[2]}r(e)&&this.applySyncedMouseEvent(e)}}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"])}initMouseEvents(t){this.log("debug","initMouseEvents");for(const e of t)document.addEventListener(e,i=>{i instanceof MouseEvent&&this.transmitSyncedMouseEvent(["df-global","mouse",e,{altKey:i.altKey,ctrlKey:i.ctrlKey,shiftKey:i.shiftKey,metaKey:i.metaKey}])},!0)}transmitSyncedMouseEvent(t){this.currentSyncedMouseEvents.has(t[2])?this.currentSyncedMouseEvents.delete(t[2]):this.postMessageToParent(t)}applySyncedMouseEvent(t){this.currentSyncedMouseEvents.add(t[2]);const e=new MouseEvent(t[2],{bubbles:!0,cancelable:!0,view:window,...t[3]});document.body.dispatchEvent(e)}initResize(){this.log("debug","initResize"),this.checkHeight(),this.createMutationObserver(),this.createWindowEventListeners()}initStateChangeWatcher(){this.log("debug","initStateChangeWatcher");const t=window.history.replaceState,e=(...d)=>{const c=window.location.href,a=t.apply(window.history,d);return window.location.href!==c&&this.postMessageToParent(["df-child","stateChange","push",window.location.href]),a};window.history.pushState=e;const i=(...d)=>{const c=window.location.href,a=t.apply(window.history,d);return window.location.href!==c&&this.postMessageToParent(["df-child","stateChange","replace",window.location.href]),a};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 f)window.addEventListener(t,this.throttledCheckHeight,{passive:!0})}checkHeight(){const t=document.querySelectorAll("[data-iframe-height]");let e=0,i=0;for(const d of t){const c=d.getAttribute("data-iframe-height"),a=d.getBoundingClientRect().bottom+parseFloat(getComputedStyle(d).getPropertyValue("margin-bottom")),u=c?a+parseFloat(c):a;a>e&&(e=a),u>i&&(i=u)}i=Math.ceil(i),e>0&&i!==this.lastHeight&&(this.postMessageToParent(["df-child","height",i]),this.lastHeight=i)}}return new l}();
1
+ var DFrameContent=function(){"use strict";var g=Object.defineProperty;var w=(r,n,d)=>n in r?g(r,n,{enumerable:!0,configurable:!0,writable:!0,value:d}):r[n]=d;var s=(r,n,d)=>w(r,typeof n!="symbol"?n+"":n,d);function r(o){return o[0]==="df-global"&&o[1]==="mouse"}function n(o){return o[0]==="df-parent"&&o[1]==="init"}function d(o){return o[0]==="df-parent"&&o[1]==="updateSrc"}const l=["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 f{constructor(e){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);s(this,"currentSyncedMouseEvents",new Set);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",i=>this.onMessage(i)),this.postMessageToParent(["df-child","init"]))}log(e,...t){e==="debug"&&!this.debug||(e==="debug"&&console.timeLog(`d-frame:${this.id}:content`,...t),e==="info"&&console.info(`d-frame:${this.id}:content`,...t),e==="error"&&console.error(`d-frame:${this.id}:content`,...t))}onMessage(e){if(e.source===window.parent&&Array.isArray(e.data)){const t=e.data;if(n(t)&&(this.id=t[2].id,this.debug=!!t[2].debug,this.debug&&console.time(`d-frame:${this.id}:content`),this.log("debug","init handshake is ok",t,this.options),t[2].src&&t[2].src!==window.location.href&&this.log("error",`src mismatch at init, maybe the frame navigated before the initialization handshake: ${window.location.href} !== ${t[2].src}`),t[2].resize!=="no"&&this.initResize(),(t[2].syncParams||t[2].syncPath||t[2].stateChangeEvents)&&this.initStateChangeWatcher(),t[2].mouseEvents&&this.initMouseEvents(t[2].mouseEvents),this.initialized=!0),d(t)){const i=t[2].startsWith("/")?window.location.origin+t[2]:t[2];if(i===window.location.href)return;this.log("debug",`update src ${window.location.href} -> ${i}`),this.options.updateSrc?this.options.updateSrc(i,this):(this.log("debug","no updateSrc method available, falling back to updating window.location.href",i),window.location.href=i)}r(t)&&this.applySyncedMouseEvent(t)}}postMessageToParent(e){window.parent.postMessage(e)}sendNotif(e){this.postMessageToParent(["df-child","notif",e])}sendMessage(e){this.postMessageToParent(["df-child","custom",e])}ready(){this.postMessageToParent(["df-child","ready"])}initMouseEvents(e){this.log("debug","initMouseEvents");for(const t of e)document.addEventListener(t,i=>{i instanceof MouseEvent&&this.transmitSyncedMouseEvent(["df-global","mouse",t,{altKey:i.altKey,ctrlKey:i.ctrlKey,shiftKey:i.shiftKey,metaKey:i.metaKey}])},!0)}transmitSyncedMouseEvent(e){this.currentSyncedMouseEvents.has(e[2])?this.currentSyncedMouseEvents.delete(e[2]):this.postMessageToParent(e)}applySyncedMouseEvent(e){this.currentSyncedMouseEvents.add(e[2]);const t=new MouseEvent(e[2],{bubbles:!0,cancelable:!0,view:window,...e[3]});document.body.dispatchEvent(t)}initResize(){this.log("debug","initResize"),this.checkHeight(),this.createMutationObserver(),this.createWindowEventListeners()}initStateChangeWatcher(){this.log("debug","initStateChangeWatcher");const e=window.history.replaceState,t=(...h)=>{const c=window.location.href,a=e.apply(window.history,h);return window.location.href!==c&&this.postMessageToParent(["df-child","stateChange","push",window.location.href]),a};window.history.pushState=t;const i=(...h)=>{const c=window.location.href,a=e.apply(window.history,h);return window.location.href!==c&&this.postMessageToParent(["df-child","stateChange","replace",window.location.href]),a};window.history.replaceState=i}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 l)window.addEventListener(e,this.throttledCheckHeight,{passive:!0})}checkHeight(){const e=document.querySelectorAll("[data-iframe-height]");let t=0,i=0;for(const h of e){const c=h.getAttribute("data-iframe-height"),a=h.getBoundingClientRect().bottom+parseFloat(getComputedStyle(h).getPropertyValue("margin-bottom")),u=c?a+parseFloat(c):a;a>t&&(t=a),u>i&&(i=u)}i=Math.ceil(i),t>0&&i!==this.lastHeight&&(this.postMessageToParent(["df-child","height",i]),this.lastHeight=i)}}return new f}();
2
2
  //# sourceMappingURL=d-frame-content.min.js.map
@@ -1,4 +1,4 @@
1
- var I=Object.defineProperty;var L=(l,u,f)=>u in l?I(l,u,{enumerable:!0,configurable:!0,writable:!0,value:f}):l[u]=f;var n=(l,u,f)=>L(l,typeof u!="symbol"?u+"":u,f);(function(){"use strict";function l(e){return e[0]==="df-global"&&e[1]==="mouse"}function u(e){return e[0]==="df-child"&&e[1]==="init"}function f(e){return e[0]==="df-child"&&e[1]==="height"}function m(e){return e[0]==="df-child"&&e[1]==="stateChange"}function b(e){return e[0]==="df-child"&&e[1]==="custom"}function y(e){return e[0]==="df-child"&&e[1]==="notif"}function E(e){return e[0]==="df-child"&&e[1]==="ready"}function w(e){return e.endsWith("/")?e:e===""?"/":e.slice(0,e.lastIndexOf("/")+1)}function v(e,a){if(a.origin!==e.origin)return a.href;if(a.pathname===e.pathname)return"";const t=w(e.pathname);return a.pathname.startsWith(t)?a.pathname.replace(t,"./"):a.pathname}const A=e=>e.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&");function S(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 C(e,a,t,s){if(!t&&!s)return e;const i=new URL(e),r=new URL(a);if(t&&r.searchParams.forEach((o,c)=>{for(const h of t){if(h.append&&!c.startsWith(h.append)||c===s)continue;const d=h.append?c.replace(h.append,""):c;if(d.match(h.regexp)){i.searchParams.set(d,o);break}}}),s!==null){const o=r.searchParams.get(s);o&&(i.pathname=new URL(o,e).pathname)}return i.href}function M(e,a,t,s,i){const r=new URL(e),o=new URL(t),c=new URL(a);if(s){for(const h of o.searchParams.keys().toArray())for(const d of s){if(d.append&&!h.startsWith(d.append))continue;const g=d.append?h.replace(d.append,""):h;if(g.match(d.regexp)){c.searchParams.get(g)===null&&o.searchParams.delete(h);break}}c.searchParams.forEach((h,d)=>{for(const g of s){if(!d.match(g.regexp)||(r==null?void 0:r.searchParams.get(d))===h)continue;const x=g.append?g.append+d:d;o.searchParams.set(x,h);break}})}if(i!==null&&r){const h=v(r,c);h?o.searchParams.set(i,h):o.searchParams.delete(i)}return o}function P(e){return e.vIframe===!0&&e.uiNotification!==void 0}function R(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 z{stateChange(a,t){a==="replace"&&window.history.replaceState(window.history.state,"",t),a==="push"&&window.history.pushState(window.history.state,"",t)}onStateChange(a){window.addEventListener("popstate",a)}}const p=document.createElement("template");p.innerHTML=`<style>
1
+ var H=Object.defineProperty;var I=(l,u,f)=>u in l?H(l,u,{enumerable:!0,configurable:!0,writable:!0,value:f}):l[u]=f;var a=(l,u,f)=>I(l,typeof u!="symbol"?u+"":u,f);(function(){"use strict";function l(e){return e[0]==="df-global"&&e[1]==="mouse"}function u(e){return e[0]==="df-child"&&e[1]==="init"}function f(e){return e[0]==="df-child"&&e[1]==="height"}function b(e){return e[0]==="df-child"&&e[1]==="stateChange"}function y(e){return e[0]==="df-child"&&e[1]==="custom"}function E(e){return e[0]==="df-child"&&e[1]==="notif"}function w(e){return e[0]==="df-child"&&e[1]==="ready"}function v(e){return e.endsWith("/")?e:e===""?"/":e.slice(0,e.lastIndexOf("/")+1)}function p(e,n){if(n.origin!==e.origin)return n.href;if(n.pathname===e.pathname)return"";const t=v(e.pathname);return n.pathname.startsWith(t)?n.pathname.replace(t,"./"):n.pathname}const A=e=>e.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&");function S(e){const n=[];for(const t of e.split(",")){const[s="*",i]=t.split(":"),r="^"+A(s).replace(/\\\*/g,"(.*)")+"$";n.push({regexp:new RegExp(r),append:i})}return n}function M(e,n,t,s){if(!t&&!s)return e;const i=new URL(e),r=new URL(n);if(t&&r.searchParams.forEach((h,c)=>{for(const o of t){if(o.append&&!c.startsWith(o.append)||c===s)continue;const d=o.append?c.replace(o.append,""):c;if(d.match(o.regexp)){i.searchParams.set(d,h);break}}}),s!==null){let h;s==="#"?h=r.hash.slice(1):s.startsWith("/")?r.pathname.startsWith(s)&&(h=p(new URL(s,n),r)):h=r.searchParams.get(s),h&&(i.pathname=new URL(h,e).pathname)}return i.href}function C(e,n,t,s,i){const r=new URL(e),h=new URL(t),c=new URL(n);if(s){for(const o of h.searchParams.keys().toArray())for(const d of s){if(d.append&&!o.startsWith(d.append))continue;const g=d.append?o.replace(d.append,""):o;if(g.match(d.regexp)){c.searchParams.get(g)===null&&h.searchParams.delete(o);break}}c.searchParams.forEach((o,d)=>{for(const g of s){if(!d.match(g.regexp)||(r==null?void 0:r.searchParams.get(d))===o)continue;const x=g.append?g.append+d:d;h.searchParams.set(x,o);break}})}if(i!==null&&r){const o=p(r,c);i==="#"?h.hash=o:i.startsWith("/")?h.pathname=new URL(o,new URL(i,t)).pathname:o?h.searchParams.set(i,o):h.searchParams.delete(i)}return h}function R(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 n=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:n}:{type:"error",title:n}}return e.type==="error"?{type:e.clientError?"warning":"error",title:e.msg,detail:e.errorMsg}:{type:e.type??"default",title:e.msg}}class L{stateChange(n,t,s){s.log("debug","apply state change on window.history",n,t.href),n==="replace"&&window.history.replaceState(window.history.state,"",t),n==="push"&&window.history.pushState(window.history.state,"",t)}onStateChange(n){window.addEventListener("popstate",n)}}const m=document.createElement("template");m.innerHTML=`<style>
2
2
  :host {
3
3
  display: block;
4
4
  }
@@ -11,5 +11,5 @@ var I=Object.defineProperty;var L=(l,u,f)=>u in l?I(l,u,{enumerable:!0,configura
11
11
  height: 100%;
12
12
  border: none;
13
13
  }
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 H extends HTMLElement{constructor(){super();n(this,"adapter");n(this,"connected",!1);n(this,"childInitialized",!1);n(this,"currentChildSrc",null);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",{});n(this,"currentSyncedMouseEvents",new Set);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.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 z,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 src(){return this.getAttribute("src")}set src(t){this.setAttribute("src",t)}get fullSrc(){return this.src.startsWith("/")?window.location.origin+this.src:this.src}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 mouseEvents(){const t=this.getAttribute("mouse-events");return t===null?null:t===""?["click","dblclick","mousedown","mouseup"]:t.split(",")}set mouseEvents(t){t===null?this.removeAttribute("mouse-events"):this.setAttribute("mouse-events",t.join(","))}get reload(){return this.getAttribute("reload")}set reload(t){this.setAttribute("reload",t)}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,mouseEvents:this.mouseEvents}]),this.childInitialized=!0),f(i)&&(this.resizedHeight=i[2],this.resize==="yes"&&!this.ready&&!this.readyMessage&&(this.ready=!0,this.dispatchEvent(new CustomEvent("ready"))),this.updateStyle()),m(i)){if(this.currentChildSrc=i[3],this.parsedSyncParams||this.syncPath){const r=M(this.fullSrc,i[3],window.location.href,this.parsedSyncParams,this.syncPath);r.href!==window.location.href&&(this.log("debug","apply state change to parent",i[2],r),this.adapter.stateChange(i[2],r))}this.stateChangeEvents&&this.dispatchEvent(new CustomEvent("state-change",{detail:[i[2],i[3]]}))}b(i)&&this.dispatchEvent(new CustomEvent("message",{detail:i[2]})),y(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:i[2]})),E(i)&&(this.ready=!0,this.dispatchEvent(new CustomEvent("ready")),this.updateStyle()),l(i)&&this.applySyncedMouseEvent(i)}else P(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:R(i.uiNotification)}))}}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;const t=C(this.fullSrc,window.location.href,this.parsedSyncParams,this.syncPath);t!==this.currentChildSrc&&(this.currentChildSrc=t,this.childInitialized?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 o=i.slice(7);s[o]=r}}this.log("debug","update iframe extra attributes",t,s);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])}initMouseEvents(t){this.log("debug","initMouseEvents");for(const s of t)document.addEventListener(s,i=>{i instanceof MouseEvent&&this.transmitSyncedMouseEvent(["df-global","mouse",s,{altKey:i.altKey,ctrlKey:i.ctrlKey,shiftKey:i.shiftKey,metaKey:i.metaKey}])},!0)}transmitSyncedMouseEvent(t){this.currentSyncedMouseEvents.has(t[2])?this.currentSyncedMouseEvents.delete(t[2]):this.postMessageToChild(t)}applySyncedMouseEvent(t){this.currentSyncedMouseEvents.add(t[2]);const s=new MouseEvent(t[2],{bubbles:!0,cancelable:!0,view:window,...t[3]});this.dispatchEvent(s)}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=S(this.syncParams||"*")),this.updateStyle(),this.updateIframeExtraAttrs(),this.updateSrc(),this.mouseEvents&&this.initMouseEvents(this.mouseEvents)}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","reload"]}attributeChangedCallback(t,s,i){var r;if(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(),t==="reload")){if(!this.currentChildSrc){this.log("debug","reload attribute changed but no iframe previously src");return}if(!((r=this.iframeElement.contentWindow)!=null&&r.location)){this.log("debug","reload attribute changed but no iframe contentWindow, is this a cross domain iframe ?");return}this.log("debug","reload iframe with current src",this.currentChildSrc),this.childInitialized=!1,this.iframeElement.setAttribute("src",this.currentChildSrc),this.iframeElement.contentWindow.location.reload()}}}customElements.get("d-frame")||customElements.define("d-frame",H)})();
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 P extends HTMLElement{constructor(){super();a(this,"adapter");a(this,"windowAdapter");a(this,"connected",!1);a(this,"childInitialized",!1);a(this,"currentChildSrc",null);a(this,"parsedSyncParams");a(this,"wrapperElement");a(this,"slotElement");a(this,"iframeElement");a(this,"width");a(this,"aspectRatioHeight");a(this,"resizedHeight");a(this,"randomId");a(this,"iframeLoaded",!1);a(this,"ready",!1);a(this,"iframeExtraAttrs",{});a(this,"resizeObserver");a(this,"boundOnMessage",t=>this.onMessage(t));a(this,"mouseEventListeners",{});a(this,"currentSyncedMouseEvents",new Set);this.randomId=Math.random().toString(36).slice(-6);const t=m.content.cloneNode(!0);this.wrapperElement=t.childNodes[1],this.slotElement=this.wrapperElement.childNodes[0],this.iframeElement=this.wrapperElement.childNodes[1],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),this.resizeObserver=new ResizeObserver(i=>{(this.width===void 0||Math.abs(this.width-i[0].contentRect.width)>2)&&(this.width=i[0].contentRect.width,this.updateAspectRatioHeight())}),this.adapter=this.windowAdapter=new L}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 src(){return this.getAttribute("src")}set src(t){this.setAttribute("src",t)}get fullSrc(){return this.src.startsWith("/")?window.location.origin+this.src:this.src}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 mouseEvents(){const t=this.getAttribute("mouse-events");return t===null?null:t===""?["click","dblclick","mousedown","mouseup"]:t.split(",")}set mouseEvents(t){t===null?this.removeAttribute("mouse-events"):this.setAttribute("mouse-events",t.join(","))}get reload(){return this.getAttribute("reload")}set reload(t){this.setAttribute("reload",t)}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,mouseEvents:this.mouseEvents,src:this.currentChildSrc}]),this.childInitialized=!0),f(i)&&(this.resizedHeight=i[2],this.resize==="yes"&&!this.ready&&!this.readyMessage&&(this.ready=!0,this.dispatchEvent(new CustomEvent("ready"))),this.updateStyle()),b(i)){if(this.currentChildSrc=i[3],this.parsedSyncParams||this.syncPath){const r=C(this.fullSrc,i[3],window.location.href,this.parsedSyncParams,this.syncPath);if(r.href!==window.location.href){this.log("debug","apply state change to parent",i[2],r.href);try{this.adapter.stateChange(i[2],r,this)}catch(h){this.log("error","failed to apply state change to parent using custom adapter",h),this.windowAdapter.stateChange(i[2],r,this)}}}this.stateChangeEvents&&this.dispatchEvent(new CustomEvent("state-change",{detail:[i[2],i[3]]}))}y(i)&&this.dispatchEvent(new CustomEvent("message",{detail:i[2]})),E(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:i[2]})),w(i)&&(this.ready=!0,this.dispatchEvent(new CustomEvent("ready")),this.updateStyle()),l(i)&&this.applySyncedMouseEvent(i)}else R(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:z(i.uiNotification)}))}}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;const t=M(this.fullSrc,window.location.href,this.parsedSyncParams,this.syncPath);t!==this.currentChildSrc&&(this.currentChildSrc=t,this.childInitialized?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 h=i.slice(7);s[h]=r}}this.log("debug","update iframe extra attributes",t,s);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])}initMouseEvents(t){this.log("debug","initMouseEvents");for(const s of t)if(!this.mouseEventListeners[s]){const i=r=>{r instanceof MouseEvent&&this.transmitSyncedMouseEvent(["df-global","mouse",s,{altKey:r.altKey,ctrlKey:r.ctrlKey,shiftKey:r.shiftKey,metaKey:r.metaKey}])};this.mouseEventListeners[s]=i,document.addEventListener(s,i,!0)}}transmitSyncedMouseEvent(t){this.currentSyncedMouseEvents.has(t[2])?this.currentSyncedMouseEvents.delete(t[2]):this.postMessageToChild(t)}applySyncedMouseEvent(t){this.currentSyncedMouseEvents.add(t[2]);const s=new MouseEvent(t[2],{bubbles:!0,cancelable:!0,view:window,...t[3]});this.dispatchEvent(s)}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),t==="error"&&console.error(`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.resizeObserver.observe(this),window.addEventListener("message",this.boundOnMessage),this.syncParams!==null&&(this.parsedSyncParams=S(this.syncParams||"*")),this.updateStyle(),this.updateIframeExtraAttrs(),this.updateSrc(),this.mouseEvents&&this.initMouseEvents(this.mouseEvents)}disconnectedCallback(){this.log("debug","disconnected"),this.resizeObserver.disconnect(),window.removeEventListener("message",this.boundOnMessage);for(const[t,s]of Object.entries(this.mouseEventListeners))document.removeEventListener(t,s,!0),delete this.mouseEventListeners[t]}static get observedAttributes(){return["src","aspect-ratio","height","sync-params","sync-path","reload"]}attributeChangedCallback(t,s,i){var r;if(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(),t==="reload")){if(!this.currentChildSrc){this.log("debug","reload attribute changed but no iframe previously src");return}if(!((r=this.iframeElement.contentWindow)!=null&&r.location)){this.log("debug","reload attribute changed but no iframe contentWindow, is this a cross domain iframe ?");return}this.log("debug","reload iframe with current src",this.currentChildSrc),this.childInitialized=!1,this.iframeElement.setAttribute("src",this.currentChildSrc),this.iframeElement.contentWindow.location.reload()}}}customElements.get("d-frame")||customElements.define("d-frame",P)})();
15
15
  //# sourceMappingURL=d-frame.min.js.map
@@ -1,2 +1,2 @@
1
- var VIframeCompatDFrameContent=function(){"use strict";var y=Object.defineProperty;var m=(h,r,u)=>r in h?y(h,r,{enumerable:!0,configurable:!0,writable:!0,value:u}):h[r]=u;var d=(h,r,u)=>m(h,typeof r!="symbol"?r+"":r,u);function h(n){return n[0]==="df-global"&&n[1]==="mouse"}function r(n){return n[0]==="df-parent"&&n[1]==="init"}function u(n){return n[0]==="df-parent"&&n[1]==="updateSrc"}const g=["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 p{constructor(e){d(this,"initialized",!1);d(this,"options");d(this,"pendingCheckHeight",!1);d(this,"debug",!1);d(this,"id");d(this,"throttledCheckHeight");d(this,"lastHeight",0);d(this,"currentSyncedMouseEvents",new Set);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",i=>this.onMessage(i)),this.postMessageToParent(["df-child","init"]))}log(e,...t){e==="debug"&&!this.debug||(e==="debug"&&console.timeLog(`d-frame:${this.id}:content`,...t),e==="info"&&console.info(`d-frame:${this.id}:content`,...t),e==="error"&&console.error(`d-frame:${this.id}:content`,...t))}onMessage(e){if(e.source===window.parent&&Array.isArray(e.data)){const t=e.data;if(r(t)&&(this.id=t[2].id,this.debug=!!t[2].debug,this.debug&&console.time(`d-frame:${this.id}:content`),t[2].resize!=="no"&&this.initResize(),(t[2].syncParams||t[2].syncPath||t[2].stateChangeEvents)&&this.initStateChangeWatcher(),t[2].mouseEvents&&this.initMouseEvents(t[2].mouseEvents),this.initialized=!0),u(t)){const i=t[2].startsWith("/")?window.location.origin+t[2]:t[2];if(i===window.location.href)return;this.options.updateSrc?this.options.updateSrc(i,this):window.location.href=t[2]}h(t)&&this.applySyncedMouseEvent(t)}}postMessageToParent(e){window.parent.postMessage(e)}sendNotif(e){this.postMessageToParent(["df-child","notif",e])}sendMessage(e){this.postMessageToParent(["df-child","custom",e])}ready(){this.postMessageToParent(["df-child","ready"])}initMouseEvents(e){this.log("debug","initMouseEvents");for(const t of e)document.addEventListener(t,i=>{i instanceof MouseEvent&&this.transmitSyncedMouseEvent(["df-global","mouse",t,{altKey:i.altKey,ctrlKey:i.ctrlKey,shiftKey:i.shiftKey,metaKey:i.metaKey}])},!0)}transmitSyncedMouseEvent(e){this.currentSyncedMouseEvents.has(e[2])?this.currentSyncedMouseEvents.delete(e[2]):this.postMessageToParent(e)}applySyncedMouseEvent(e){this.currentSyncedMouseEvents.add(e[2]);const t=new MouseEvent(e[2],{bubbles:!0,cancelable:!0,view:window,...e[3]});document.body.dispatchEvent(t)}initResize(){this.log("debug","initResize"),this.checkHeight(),this.createMutationObserver(),this.createWindowEventListeners()}initStateChangeWatcher(){this.log("debug","initStateChangeWatcher");const e=window.history.replaceState,t=(...o)=>{const c=window.location.href,s=e.apply(window.history,o);return window.location.href!==c&&this.postMessageToParent(["df-child","stateChange","push",window.location.href]),s};window.history.pushState=t;const i=(...o)=>{const c=window.location.href,s=e.apply(window.history,o);return window.location.href!==c&&this.postMessageToParent(["df-child","stateChange","replace",window.location.href]),s};window.history.replaceState=i}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 g)window.addEventListener(e,this.throttledCheckHeight,{passive:!0})}checkHeight(){const e=document.querySelectorAll("[data-iframe-height]");let t=0,i=0;for(const o of e){const c=o.getAttribute("data-iframe-height"),s=o.getBoundingClientRect().bottom+parseFloat(getComputedStyle(o).getPropertyValue("margin-bottom")),a=c?s+parseFloat(c):s;s>t&&(t=s),a>i&&(i=a)}i=Math.ceil(i),t>0&&i!==this.lastHeight&&(this.postMessageToParent(["df-child","height",i]),this.lastHeight=i)}}const b=(n,e)=>{const t=Object.keys(n);e.forEach((i,o)=>{n[o]=i,t.splice(t.indexOf(o),1)}),t.forEach(i=>{delete n[i]})},w=new p({updateSrc(n,e){var c,s;const t=window.vIframeOptions,i=t==null?void 0:t.reactiveParams;if(i&&typeof i=="object"){const a=new URL(n);if(a.origin===window.location.origin&&a.pathname===window.location.pathname){e.log("debug","applying reactive params",a.searchParams),b(i,a.searchParams);return}}const o=t==null?void 0:t.router;if(o){const a=((c=o.options)==null?void 0:c.base)??((s=o.options.history)==null?void 0:s.base);if(a==null)e.log("error","failed to access base path in router (no router.options.base nor router.options.history.base)",o);else{const f=window.location.origin+a;if(!n.startsWith(f))e.log("info","src does not start with base path",n,f);else{let l=n.replace(f,"");l.startsWith("/")||(l="/"+l),e.log("debug","applying router.replace",l),o.replace(l);return}}}e.log("info","falling back to updating window.location.href",n),window.location.href=n}});return window.dFrameContent=w,w}();
1
+ var VIframeCompatDFrameContent=function(){"use strict";var m=Object.defineProperty;var y=(c,r,l)=>r in c?m(c,r,{enumerable:!0,configurable:!0,writable:!0,value:l}):c[r]=l;var h=(c,r,l)=>y(c,typeof r!="symbol"?r+"":r,l);function c(n){return n[0]==="df-global"&&n[1]==="mouse"}function r(n){return n[0]==="df-parent"&&n[1]==="init"}function l(n){return n[0]==="df-parent"&&n[1]==="updateSrc"}const g=["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 p{constructor(e){h(this,"initialized",!1);h(this,"options");h(this,"pendingCheckHeight",!1);h(this,"debug",!1);h(this,"id");h(this,"throttledCheckHeight");h(this,"lastHeight",0);h(this,"currentSyncedMouseEvents",new Set);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",i=>this.onMessage(i)),this.postMessageToParent(["df-child","init"]))}log(e,...t){e==="debug"&&!this.debug||(e==="debug"&&console.timeLog(`d-frame:${this.id}:content`,...t),e==="info"&&console.info(`d-frame:${this.id}:content`,...t),e==="error"&&console.error(`d-frame:${this.id}:content`,...t))}onMessage(e){if(e.source===window.parent&&Array.isArray(e.data)){const t=e.data;if(r(t)&&(this.id=t[2].id,this.debug=!!t[2].debug,this.debug&&console.time(`d-frame:${this.id}:content`),this.log("debug","init handshake is ok",t,this.options),t[2].src&&t[2].src!==window.location.href&&this.log("error",`src mismatch at init, maybe the frame navigated before the initialization handshake: ${window.location.href} !== ${t[2].src}`),t[2].resize!=="no"&&this.initResize(),(t[2].syncParams||t[2].syncPath||t[2].stateChangeEvents)&&this.initStateChangeWatcher(),t[2].mouseEvents&&this.initMouseEvents(t[2].mouseEvents),this.initialized=!0),l(t)){const i=t[2].startsWith("/")?window.location.origin+t[2]:t[2];if(i===window.location.href)return;this.log("debug",`update src ${window.location.href} -> ${i}`),this.options.updateSrc?this.options.updateSrc(i,this):(this.log("debug","no updateSrc method available, falling back to updating window.location.href",i),window.location.href=i)}c(t)&&this.applySyncedMouseEvent(t)}}postMessageToParent(e){window.parent.postMessage(e)}sendNotif(e){this.postMessageToParent(["df-child","notif",e])}sendMessage(e){this.postMessageToParent(["df-child","custom",e])}ready(){this.postMessageToParent(["df-child","ready"])}initMouseEvents(e){this.log("debug","initMouseEvents");for(const t of e)document.addEventListener(t,i=>{i instanceof MouseEvent&&this.transmitSyncedMouseEvent(["df-global","mouse",t,{altKey:i.altKey,ctrlKey:i.ctrlKey,shiftKey:i.shiftKey,metaKey:i.metaKey}])},!0)}transmitSyncedMouseEvent(e){this.currentSyncedMouseEvents.has(e[2])?this.currentSyncedMouseEvents.delete(e[2]):this.postMessageToParent(e)}applySyncedMouseEvent(e){this.currentSyncedMouseEvents.add(e[2]);const t=new MouseEvent(e[2],{bubbles:!0,cancelable:!0,view:window,...e[3]});document.body.dispatchEvent(t)}initResize(){this.log("debug","initResize"),this.checkHeight(),this.createMutationObserver(),this.createWindowEventListeners()}initStateChangeWatcher(){this.log("debug","initStateChangeWatcher");const e=window.history.replaceState,t=(...o)=>{const d=window.location.href,s=e.apply(window.history,o);return window.location.href!==d&&this.postMessageToParent(["df-child","stateChange","push",window.location.href]),s};window.history.pushState=t;const i=(...o)=>{const d=window.location.href,s=e.apply(window.history,o);return window.location.href!==d&&this.postMessageToParent(["df-child","stateChange","replace",window.location.href]),s};window.history.replaceState=i}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 g)window.addEventListener(e,this.throttledCheckHeight,{passive:!0})}checkHeight(){const e=document.querySelectorAll("[data-iframe-height]");let t=0,i=0;for(const o of e){const d=o.getAttribute("data-iframe-height"),s=o.getBoundingClientRect().bottom+parseFloat(getComputedStyle(o).getPropertyValue("margin-bottom")),a=d?s+parseFloat(d):s;s>t&&(t=s),a>i&&(i=a)}i=Math.ceil(i),t>0&&i!==this.lastHeight&&(this.postMessageToParent(["df-child","height",i]),this.lastHeight=i)}}const b=(n,e)=>{const t=Object.keys(n);e.forEach((i,o)=>{n[o]=i,t.splice(t.indexOf(o),1)}),t.forEach(i=>{delete n[i]})},w=new p({updateSrc(n,e){var d,s;const t=window.vIframeOptions,i=t==null?void 0:t.reactiveParams;if(i&&typeof i=="object"){const a=new URL(n);if(a.origin===window.location.origin&&a.pathname===window.location.pathname){e.log("debug","applying reactive params",a.searchParams),b(i,a.searchParams);return}}const o=t==null?void 0:t.router;if(o){const a=((d=o.options)==null?void 0:d.base)??((s=o.options.history)==null?void 0:s.base);if(a==null)e.log("error","failed to access base path in router (no router.options.base nor router.options.history.base)",o);else{const f=window.location.origin+a;if(!n.startsWith(f))e.log("info","src does not start with base path",n,f);else{let u=n.replace(f,"");u.startsWith("/")||(u="/"+u),e.log("debug","applying router.replace",u),o.replace(u);return}}}e.log("info","falling back to updating window.location.href",n),window.location.href=n}});return window.dFrameContent=w,w}();
2
2
  //# sourceMappingURL=d-frame-content.min.js.map
@@ -74,6 +74,10 @@ export default class DFrameContent {
74
74
  this.debug = !!message[2].debug;
75
75
  if (this.debug)
76
76
  console.time(`d-frame:${this.id}:content`);
77
+ this.log('debug', 'init handshake is ok', message, this.options);
78
+ if (message[2].src && message[2].src !== window.location.href) {
79
+ this.log('error', `src mismatch at init, maybe the frame navigated before the initialization handshake: ${window.location.href} !== ${message[2].src}`);
80
+ }
77
81
  if (message[2].resize !== 'no')
78
82
  this.initResize();
79
83
  if (message[2].syncParams || message[2].syncPath || message[2].stateChangeEvents)
@@ -86,11 +90,13 @@ export default class DFrameContent {
86
90
  const newSrc = message[2].startsWith('/') ? window.location.origin + message[2] : message[2];
87
91
  if (newSrc === window.location.href)
88
92
  return;
93
+ this.log('debug', `update src ${window.location.href} -> ${newSrc}`);
89
94
  if (this.options.updateSrc) {
90
95
  this.options.updateSrc(newSrc, this);
91
96
  }
92
97
  else {
93
- window.location.href = message[2];
98
+ this.log('debug', 'no updateSrc method available, falling back to updating window.location.href', newSrc);
99
+ window.location.href = newSrc;
94
100
  }
95
101
  }
96
102
  if (isMouseEventMessage(message))
@@ -1,9 +1,9 @@
1
1
  import { type ParentMessage } from './messages.js';
2
2
  export interface StateChangeAdapter {
3
- stateChange(action: 'push' | 'replace', newUrl: URL): void;
3
+ stateChange(action: 'push' | 'replace', newUrl: URL, element: DFrameElement): void;
4
4
  onStateChange(callback: () => void): void;
5
5
  }
6
- export default class DFrameElement extends HTMLElement {
6
+ export declare class DFrameElement extends HTMLElement {
7
7
  get id(): string;
8
8
  set id(value: string);
9
9
  get debug(): boolean;
@@ -30,6 +30,7 @@ export default class DFrameElement extends HTMLElement {
30
30
  get reload(): string;
31
31
  set reload(value: string);
32
32
  adapter: StateChangeAdapter;
33
+ windowAdapter: StateChangeAdapter;
33
34
  private connected;
34
35
  private childInitialized;
35
36
  private currentChildSrc;
@@ -44,6 +45,9 @@ export default class DFrameElement extends HTMLElement {
44
45
  private iframeLoaded;
45
46
  private ready;
46
47
  private iframeExtraAttrs;
48
+ private resizeObserver;
49
+ private boundOnMessage;
50
+ private mouseEventListeners;
47
51
  get actualAspectRatio(): number;
48
52
  constructor();
49
53
  onMessage(e: MessageEvent): void;
@@ -56,9 +60,10 @@ export default class DFrameElement extends HTMLElement {
56
60
  private initMouseEvents;
57
61
  private transmitSyncedMouseEvent;
58
62
  private applySyncedMouseEvent;
59
- log(level: 'debug' | 'info', ...args: any[]): void;
63
+ log(level: 'debug' | 'info' | 'error', ...args: any[]): void;
60
64
  connectedCallback(): void;
61
65
  disconnectedCallback(): void;
62
66
  static get observedAttributes(): string[];
63
67
  attributeChangedCallback(name: string, oldValue: any, newValue: any): void;
64
68
  }
69
+ export default DFrameElement;
@@ -3,7 +3,8 @@ import { isCustomMessage, isHeightMessage, isInitChildMessage, isMouseEventMessa
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 {
6
- stateChange(action, newUrl) {
6
+ stateChange(action, newUrl, element) {
7
+ element.log('debug', 'apply state change on window.history', action, newUrl.href);
7
8
  if (action === 'replace')
8
9
  window.history.replaceState(window.history.state, '', newUrl);
9
10
  if (action === 'push')
@@ -33,7 +34,7 @@ template.innerHTML = `<style>
33
34
  border: none;
34
35
  }
35
36
  </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>`;
36
- export default class DFrameElement extends HTMLElement {
37
+ export class DFrameElement extends HTMLElement {
37
38
  get id() { return this.getAttribute('id') ?? this.randomId; }
38
39
  set id(value) {
39
40
  this.setAttribute('id', value);
@@ -126,6 +127,7 @@ export default class DFrameElement extends HTMLElement {
126
127
  get reload() { return this.getAttribute('reload'); }
127
128
  set reload(value) { this.setAttribute('reload', value); }
128
129
  adapter;
130
+ windowAdapter;
129
131
  /* internal state */
130
132
  connected = false;
131
133
  childInitialized = false;
@@ -141,6 +143,9 @@ export default class DFrameElement extends HTMLElement {
141
143
  iframeLoaded = false;
142
144
  ready = false;
143
145
  iframeExtraAttrs = {};
146
+ resizeObserver;
147
+ boundOnMessage = (e) => this.onMessage(e);
148
+ mouseEventListeners = {};
144
149
  get actualAspectRatio() {
145
150
  if (this.aspectRatio !== 'auto')
146
151
  return Number(this.aspectRatio);
@@ -173,16 +178,14 @@ export default class DFrameElement extends HTMLElement {
173
178
  });
174
179
  const shadowRoot = this.attachShadow({ mode: 'open' });
175
180
  shadowRoot.appendChild(root);
176
- const resizeObserver = new ResizeObserver((entries) => {
181
+ this.resizeObserver = new ResizeObserver((entries) => {
177
182
  // make this callback insensitive to micro changes
178
183
  if (this.width === undefined || Math.abs(this.width - entries[0].contentRect.width) > 2) {
179
184
  this.width = entries[0].contentRect.width;
180
185
  this.updateAspectRatioHeight();
181
186
  }
182
187
  });
183
- resizeObserver.observe(this);
184
- this.adapter = new WindowStateChangeAdapter();
185
- window.addEventListener('message', (e) => this.onMessage(e));
188
+ this.adapter = this.windowAdapter = new WindowStateChangeAdapter();
186
189
  }
187
190
  onMessage(e) {
188
191
  if (e.source === this.iframeElement?.contentWindow) {
@@ -198,7 +201,8 @@ export default class DFrameElement extends HTMLElement {
198
201
  syncParams: this.syncParams !== null,
199
202
  syncPath: this.syncPath !== null,
200
203
  stateChangeEvents: this.stateChangeEvents,
201
- mouseEvents: this.mouseEvents
204
+ mouseEvents: this.mouseEvents,
205
+ src: this.currentChildSrc
202
206
  }]);
203
207
  this.childInitialized = true;
204
208
  }
@@ -215,8 +219,14 @@ export default class DFrameElement extends HTMLElement {
215
219
  if ((this.parsedSyncParams || this.syncPath)) {
216
220
  const newParentHUrl = getParentUrl(this.fullSrc, message[3], window.location.href, this.parsedSyncParams, this.syncPath);
217
221
  if (newParentHUrl.href !== window.location.href) {
218
- this.log('debug', 'apply state change to parent', message[2], newParentHUrl);
219
- this.adapter.stateChange(message[2], newParentHUrl);
222
+ this.log('debug', 'apply state change to parent', message[2], newParentHUrl.href);
223
+ try {
224
+ this.adapter.stateChange(message[2], newParentHUrl, this);
225
+ }
226
+ catch (err) {
227
+ this.log('error', 'failed to apply state change to parent using custom adapter', err);
228
+ this.windowAdapter.stateChange(message[2], newParentHUrl, this);
229
+ }
220
230
  }
221
231
  }
222
232
  if (this.stateChangeEvents) {
@@ -348,11 +358,15 @@ export default class DFrameElement extends HTMLElement {
348
358
  initMouseEvents(types) {
349
359
  this.log('debug', 'initMouseEvents');
350
360
  for (const eventType of types) {
351
- document.addEventListener(eventType, (e) => {
352
- if (!(e instanceof MouseEvent))
353
- return;
354
- this.transmitSyncedMouseEvent(['df-global', 'mouse', eventType, { altKey: e.altKey, ctrlKey: e.ctrlKey, shiftKey: e.shiftKey, metaKey: e.metaKey }]);
355
- }, true);
361
+ if (!this.mouseEventListeners[eventType]) {
362
+ const listener = (e) => {
363
+ if (!(e instanceof MouseEvent))
364
+ return;
365
+ this.transmitSyncedMouseEvent(['df-global', 'mouse', eventType, { altKey: e.altKey, ctrlKey: e.ctrlKey, shiftKey: e.shiftKey, metaKey: e.metaKey }]);
366
+ };
367
+ this.mouseEventListeners[eventType] = listener;
368
+ document.addEventListener(eventType, listener, true);
369
+ }
356
370
  }
357
371
  }
358
372
  transmitSyncedMouseEvent(message) {
@@ -375,6 +389,8 @@ export default class DFrameElement extends HTMLElement {
375
389
  console.timeLog(`d-frame:${this.id}`, ...args);
376
390
  if (level === 'info')
377
391
  console.info(`d-frame:${this.id}`, ...args);
392
+ if (level === 'error')
393
+ console.error(`d-frame:${this.id}`, ...args);
378
394
  }
379
395
  /* standard custom element callbacks */
380
396
  connectedCallback() {
@@ -395,6 +411,8 @@ export default class DFrameElement extends HTMLElement {
395
411
  if (this.adapter.onStateChange) {
396
412
  this.adapter.onStateChange(() => { this.updateSrc(); });
397
413
  }
414
+ this.resizeObserver.observe(this);
415
+ window.addEventListener('message', this.boundOnMessage);
398
416
  if (this.syncParams !== null)
399
417
  this.parsedSyncParams = parseSyncParams(this.syncParams || '*');
400
418
  this.updateStyle();
@@ -405,9 +423,12 @@ export default class DFrameElement extends HTMLElement {
405
423
  }
406
424
  disconnectedCallback() {
407
425
  this.log('debug', 'disconnected');
408
- if (this.debug)
409
- console.timeEnd(`d-frame:${this.id}`);
410
- // TODO: more cleanup (resize observer, etc)
426
+ this.resizeObserver.disconnect();
427
+ window.removeEventListener('message', this.boundOnMessage);
428
+ for (const [eventType, listener] of Object.entries(this.mouseEventListeners)) {
429
+ document.removeEventListener(eventType, listener, true);
430
+ delete this.mouseEventListeners[eventType];
431
+ }
411
432
  }
412
433
  /* reflected attributes */
413
434
  static get observedAttributes() { return ['src', 'aspect-ratio', 'height', 'sync-params', 'sync-path', 'reload']; }
@@ -442,3 +463,4 @@ export default class DFrameElement extends HTMLElement {
442
463
  }
443
464
  }
444
465
  }
466
+ export default DFrameElement;
package/lib/messages.d.ts CHANGED
@@ -29,6 +29,7 @@ export type InitParentMessage = [
29
29
  syncPath: boolean;
30
30
  stateChangeEvents: boolean;
31
31
  mouseEvents: null | string[];
32
+ src: string | null;
32
33
  }
33
34
  ];
34
35
  export type UpdateSrcMessage = ['df-parent', 'updateSrc', string];
@@ -33,7 +33,18 @@ export function getChildSrc(fullSrc, parentHref, syncParams, syncPath) {
33
33
  });
34
34
  }
35
35
  if (syncPath !== null) {
36
- const path = parentUrl.searchParams.get(syncPath);
36
+ let path;
37
+ if (syncPath === '#') {
38
+ path = parentUrl.hash.slice(1);
39
+ }
40
+ else if (syncPath.startsWith('/')) {
41
+ if (parentUrl.pathname.startsWith(syncPath)) {
42
+ path = getUrlRelativePath(new URL(syncPath, parentHref), parentUrl);
43
+ }
44
+ }
45
+ else {
46
+ path = parentUrl.searchParams.get(syncPath);
47
+ }
37
48
  if (path) {
38
49
  childUrl.pathname = new URL(path, fullSrc).pathname;
39
50
  }
@@ -74,10 +85,18 @@ export function getParentUrl(fullSrc, childHref, currentParentHref, syncParams,
74
85
  }
75
86
  if (syncPath !== null && srcUrl) {
76
87
  const path = getUrlRelativePath(srcUrl, childUrl);
77
- if (path)
78
- parentUrl.searchParams.set(syncPath, path);
79
- else
80
- parentUrl.searchParams.delete(syncPath);
88
+ if (syncPath === '#') {
89
+ parentUrl.hash = path;
90
+ }
91
+ else if (syncPath.startsWith('/')) {
92
+ parentUrl.pathname = new URL(path, new URL(syncPath, currentParentHref)).pathname;
93
+ }
94
+ else {
95
+ if (path)
96
+ parentUrl.searchParams.set(syncPath, path);
97
+ else
98
+ parentUrl.searchParams.delete(syncPath);
99
+ }
81
100
  }
82
101
  return parentUrl;
83
102
  }
@@ -1,9 +1,9 @@
1
- import { type StateChangeAdapter } from '../DFrameElement.js';
1
+ import { type DFrameElement, type StateChangeAdapter } from '../DFrameElement.js';
2
2
  import type { Router } from 'vue-router';
3
3
  declare class VueRouterDFrameStateChangeAdapter implements StateChangeAdapter {
4
4
  router: Router;
5
5
  constructor(router: Router);
6
- stateChange(action: 'push' | 'replace', newUrl: URL): void;
6
+ stateChange(action: 'push' | 'replace', newUrl: URL, element: DFrameElement): void;
7
7
  onStateChange(callback: () => void): void;
8
8
  }
9
9
  declare const _default: (router: Router) => VueRouterDFrameStateChangeAdapter;
@@ -3,11 +3,24 @@ class VueRouterDFrameStateChangeAdapter {
3
3
  constructor(router) {
4
4
  this.router = router;
5
5
  }
6
- stateChange(action, newUrl) {
6
+ stateChange(action, newUrl, element) {
7
+ // @ts-ignore vue-router v2
8
+ const base = this.router.options?.base ?? this.router.options.history?.base;
9
+ if (base === null || base === undefined) {
10
+ throw new Error('failed to access base path in router (no router.options.base nor router.options.history.base)');
11
+ }
12
+ const urlPrefix = window.location.origin + base;
13
+ if (!newUrl.href.startsWith(urlPrefix)) {
14
+ throw new Error('new URL does not start with base path');
15
+ }
16
+ let newRoute = newUrl.href.replace(urlPrefix, '');
17
+ if (!newRoute.startsWith('/'))
18
+ newRoute = '/' + newRoute;
19
+ element.log('debug', 'apply state change on vue.router', action, newRoute);
7
20
  if (action === 'push')
8
- this.router.push({ query: Object.fromEntries(newUrl.searchParams) });
21
+ this.router.push(newRoute);
9
22
  if (action === 'replace')
10
- this.router.replace({ query: Object.fromEntries(newUrl.searchParams) });
23
+ this.router.replace(newRoute);
11
24
  }
12
25
  onStateChange(callback) {
13
26
  this.router.afterEach(callback);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-fair/frame",
3
- "version": "0.10.0",
3
+ "version": "0.11.1",
4
4
  "description": "An iframe wrapper for powerful web app integrations.",
5
5
  "main": "dist/frame.min.js",
6
6
  "directories": {