@data-fair/frame 0.11.0 → 0.12.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 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 w=Object.defineProperty;var g=(r,n,d)=>n in r?w(r,n,{enumerable:!0,configurable:!0,writable:!0,value:d}):r[n]=d;var s=(r,n,d)=>g(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 u=["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);if(this.options=e??{},typeof window>"u")return;if(window.__d_frame__content)throw new Error("DFrameContent was already initialized");window.__d_frame__content=this;const t=()=>{this.checkHeight(),this.pendingCheckHeight=!1};this.throttledCheckHeight=()=>{this.pendingCheckHeight||(this.pendingCheckHeight=!0,requestAnimationFrame(t))},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");if(!this.throttledCheckHeight)throw new Error("throttledCheckHeight is not defined");new window.MutationObserver(this.throttledCheckHeight).observe(e,{attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1,childList:!0,subtree:!0})}createWindowEventListeners(){if(!this.throttledCheckHeight)throw new Error("throttledCheckHeight is not defined");for(const e of u)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")),l=c?a+parseFloat(c):a;a>t&&(t=a),l>i&&(i=l)}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 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 o=(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 w(e){return e[0]==="df-child"&&e[1]==="notif"}function E(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,a){if(a.origin!==e.origin)return a.href;if(a.pathname===e.pathname)return"";const t=v(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((n,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,n);break}}}),s!==null){let n;s==="#"?n=r.hash.slice(1):s.startsWith("/")?r.pathname.startsWith(s)&&(n=p(new URL(s,a),r)):n=r.searchParams.get(s),n&&(i.pathname=new URL(n,e).pathname)}return i.href}function M(e,a,t,s,i){const r=new URL(e),n=new URL(t),c=new URL(a);if(s){for(const h of n.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&&n.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 L=g.append?g.append+d:d;n.searchParams.set(L,h);break}})}if(i!==null&&r){const h=p(r,c);i==="#"?n.hash=h:i.startsWith("/")?n.pathname=new URL(h,new URL(i,t)).pathname:h?n.searchParams.set(i,h):n.searchParams.delete(i)}return n}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 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(window.history.state,"",t),a==="push"&&window.history.pushState(window.history.state,"",t)}onStateChange(a){window.addEventListener("popstate",a)}}const m=document.createElement("template");m.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 h=(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 y(e){return e[0]==="df-child"&&e[1]==="stateChange"}function E(e){return e[0]==="df-child"&&e[1]==="custom"}function w(e){return e[0]==="df-child"&&e[1]==="notif"}function v(e){return e[0]==="df-child"&&e[1]==="ready"}function A(e){return e.endsWith("/")?e:e===""?"/":e.slice(0,e.lastIndexOf("/")+1)}function m(e){return e.endsWith("/")?e:e+"/"}function p(e,n){if(n.origin!==e.origin)return n.href;if(m(n.pathname)===m(e.pathname))return"";const t=A(e.pathname);return n.pathname.startsWith(t)?n.pathname.replace(t,""):n.pathname}const S=e=>e.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&");function M(e){const n=[];for(const t of e.split(",")){const[s="*",i]=t.split(":"),r="^"+S(s).replace(/\\\*/g,"(.*)")+"$";n.push({regexp:new RegExp(r),append:i})}return n}function C(e,n,t,s){if(!t&&!s)return e;const i=new URL(e),r=new URL(n);if(t&&r.searchParams.forEach((a,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,a);break}}}),s!==null){let a;s==="#"?a=r.hash.slice(1):s.startsWith("/")?r.pathname.startsWith(s)&&(a=p(new URL(s,n),r)):a=r.searchParams.get(s),a&&(i.pathname=new URL(a,e).pathname)}return i.href}function R(e,n,t,s,i){const r=new URL(e),a=new URL(t),c=new URL(n);if(s){for(const o of a.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&&a.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 W=g.append?g.append+d:d;a.searchParams.set(W,o);break}})}if(i!==null&&r){const o=p(r,c);i==="#"?a.hash=o:i.startsWith("/")?o===""||o.startsWith("/")?a.pathname=i:a.pathname=new URL(o,new URL(i,t)).pathname:o?a.searchParams.set(i,o):a.searchParams.delete(i)}return a}function z(e){return e.vIframe===!0&&e.uiNotification!==void 0}function L(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 P{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 b=document.createElement("template");b.innerHTML=`<style>
2
2
  :host {
3
3
  display: block;
4
4
  }
@@ -10,6 +10,7 @@ var H=Object.defineProperty;var I=(l,u,f)=>u in l?H(l,u,{enumerable:!0,configura
10
10
  width: 100%;
11
11
  height: 100%;
12
12
  border: none;
13
+ user-select: none;
13
14
  }
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 x extends HTMLElement{constructor(){super();o(this,"adapter");o(this,"windowAdapter");o(this,"connected",!1);o(this,"childInitialized",!1);o(this,"currentChildSrc",null);o(this,"parsedSyncParams");o(this,"wrapperElement");o(this,"slotElement");o(this,"iframeElement");o(this,"width");o(this,"aspectRatioHeight");o(this,"resizedHeight");o(this,"randomId");o(this,"iframeLoaded",!1);o(this,"ready",!1);o(this,"iframeExtraAttrs",{});o(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),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=this.windowAdapter=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 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()),b(i)){if(this.currentChildSrc=i[3],this.parsedSyncParams||this.syncPath){const r=M(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)}catch(n){this.log("error","failed to apply state change to parent using custom adapter",n),this.windowAdapter.stateChange(i[2],r)}}}this.stateChangeEvents&&this.dispatchEvent(new CustomEvent("state-change",{detail:[i[2],i[3]]}))}y(i)&&this.dispatchEvent(new CustomEvent("message",{detail:i[2]})),w(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 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=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 n=i.slice(7);s[n]=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),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.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",x)})();
15
+ </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 x extends HTMLElement{constructor(){super();h(this,"adapter");h(this,"windowAdapter");h(this,"connected",!1);h(this,"childInitialized",!1);h(this,"currentChildSrc",null);h(this,"parsedSyncParams");h(this,"wrapperElement");h(this,"slotElement");h(this,"iframeElement");h(this,"width");h(this,"aspectRatioHeight");h(this,"resizedHeight");h(this,"randomId");h(this,"iframeLoaded",!1);h(this,"ready",!1);h(this,"iframeExtraAttrs",{});h(this,"resizeObserver");h(this,"boundOnMessage",t=>this.onMessage(t));h(this,"mouseEventListeners",{});h(this,"currentSyncedMouseEvents",new Set);this.randomId=Math.random().toString(36).slice(-6);const t=b.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 P}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()),y(i)){if(this.currentChildSrc=i[3],this.parsedSyncParams||this.syncPath){const r=R(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(a){this.log("error","failed to apply state change to parent using custom adapter",a),this.windowAdapter.stateChange(i[2],r,this)}}}this.stateChangeEvents&&this.dispatchEvent(new CustomEvent("state-change",{detail:[i[2],i[3]]}))}E(i)&&this.dispatchEvent(new CustomEvent("message",{detail:i[2]})),w(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:i[2]})),v(i)&&(this.ready=!0,this.dispatchEvent(new CustomEvent("ready")),this.updateStyle()),l(i)&&this.applySyncedMouseEvent(i)}else z(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:L(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 a=i.slice(7);s[a]=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=M(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",x)})();
15
16
  //# 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 d=(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){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);if(this.options=e??{},typeof window>"u")return;if(window.__d_frame__content)throw new Error("DFrameContent was already initialized");window.__d_frame__content=this;const t=()=>{this.checkHeight(),this.pendingCheckHeight=!1};this.throttledCheckHeight=()=>{this.pendingCheckHeight||(this.pendingCheckHeight=!0,requestAnimationFrame(t))},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 h=window.location.href,s=e.apply(window.history,o);return window.location.href!==h&&this.postMessageToParent(["df-child","stateChange","push",window.location.href]),s};window.history.pushState=t;const i=(...o)=>{const h=window.location.href,s=e.apply(window.history,o);return window.location.href!==h&&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");if(!this.throttledCheckHeight)throw new Error("throttledCheckHeight is not defined");new window.MutationObserver(this.throttledCheckHeight).observe(e,{attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1,childList:!0,subtree:!0})}createWindowEventListeners(){if(!this.throttledCheckHeight)throw new Error("throttledCheckHeight is not defined");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 h=o.getAttribute("data-iframe-height"),s=o.getBoundingClientRect().bottom+parseFloat(getComputedStyle(o).getPropertyValue("margin-bottom")),a=h?s+parseFloat(h):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 h,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=((h=o.options)==null?void 0:h.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 u=window.location.origin+a;if(!n.startsWith(u))e.log("info","src does not start with base path",n,u);else{let f=n.replace(u,"");f.startsWith("/")||(f="/"+f),e.log("debug","applying router.replace",f),o.replace(f);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
@@ -2,13 +2,18 @@ import { type Notif } from './messages.js';
2
2
  export type DFrameContentOptions = {
3
3
  updateSrc?: (src: string, instance: DFrameContent) => void;
4
4
  };
5
+ declare global {
6
+ interface Window {
7
+ __d_frame__content: DFrameContent;
8
+ }
9
+ }
5
10
  export default class DFrameContent {
6
11
  initialized: boolean;
7
12
  options: DFrameContentOptions;
8
13
  private pendingCheckHeight;
9
14
  debug: boolean;
10
15
  id?: string;
11
- private throttledCheckHeight;
16
+ private throttledCheckHeight?;
12
17
  private lastHeight;
13
18
  constructor(options?: DFrameContentOptions);
14
19
  log(level: 'debug' | 'info' | 'error', ...args: any[]): void;
@@ -40,6 +40,12 @@ export default class DFrameContent {
40
40
  lastHeight = 0;
41
41
  constructor(options) {
42
42
  this.options = options ?? {};
43
+ if (typeof window === 'undefined')
44
+ return;
45
+ if (window.__d_frame__content) {
46
+ throw new Error('DFrameContent was already initialized');
47
+ }
48
+ window.__d_frame__content = this;
43
49
  const afCallback = () => {
44
50
  this.checkHeight();
45
51
  this.pendingCheckHeight = false;
@@ -50,8 +56,6 @@ export default class DFrameContent {
50
56
  this.pendingCheckHeight = true;
51
57
  requestAnimationFrame(afCallback);
52
58
  };
53
- if (typeof window === 'undefined')
54
- return;
55
59
  window.addEventListener('message', (e) => this.onMessage(e));
56
60
  // simple handshake for initialization
57
61
  this.postMessageToParent(['df-child', 'init']);
@@ -74,6 +78,10 @@ export default class DFrameContent {
74
78
  this.debug = !!message[2].debug;
75
79
  if (this.debug)
76
80
  console.time(`d-frame:${this.id}:content`);
81
+ this.log('debug', 'init handshake is ok', message, this.options);
82
+ if (message[2].src && message[2].src !== window.location.href) {
83
+ this.log('error', `src mismatch at init, maybe the frame navigated before the initialization handshake: ${window.location.href} !== ${message[2].src}`);
84
+ }
77
85
  if (message[2].resize !== 'no')
78
86
  this.initResize();
79
87
  if (message[2].syncParams || message[2].syncPath || message[2].stateChangeEvents)
@@ -86,11 +94,13 @@ export default class DFrameContent {
86
94
  const newSrc = message[2].startsWith('/') ? window.location.origin + message[2] : message[2];
87
95
  if (newSrc === window.location.href)
88
96
  return;
97
+ this.log('debug', `update src ${window.location.href} -> ${newSrc}`);
89
98
  if (this.options.updateSrc) {
90
99
  this.options.updateSrc(newSrc, this);
91
100
  }
92
101
  else {
93
- window.location.href = message[2];
102
+ this.log('debug', 'no updateSrc method available, falling back to updating window.location.href', newSrc);
103
+ window.location.href = newSrc;
94
104
  }
95
105
  }
96
106
  if (isMouseEventMessage(message))
@@ -168,6 +178,8 @@ export default class DFrameContent {
168
178
  const body = document.querySelector('body');
169
179
  if (!body)
170
180
  throw new Error('DFrameContentManager was initialized before the HTML body');
181
+ if (!this.throttledCheckHeight)
182
+ throw new Error('throttledCheckHeight is not defined');
171
183
  const observer = new window.MutationObserver(this.throttledCheckHeight);
172
184
  observer.observe(body, {
173
185
  attributes: false,
@@ -179,6 +191,8 @@ export default class DFrameContent {
179
191
  });
180
192
  }
181
193
  createWindowEventListeners() {
194
+ if (!this.throttledCheckHeight)
195
+ throw new Error('throttledCheckHeight is not defined');
182
196
  for (const eventType of windowEventTypes) {
183
197
  window.addEventListener(eventType, this.throttledCheckHeight, { passive: true });
184
198
  }
@@ -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;
@@ -45,6 +45,9 @@ export default class DFrameElement extends HTMLElement {
45
45
  private iframeLoaded;
46
46
  private ready;
47
47
  private iframeExtraAttrs;
48
+ private resizeObserver;
49
+ private boundOnMessage;
50
+ private mouseEventListeners;
48
51
  get actualAspectRatio(): number;
49
52
  constructor();
50
53
  onMessage(e: MessageEvent): void;
@@ -63,3 +66,4 @@ export default class DFrameElement extends HTMLElement {
63
66
  static get observedAttributes(): string[];
64
67
  attributeChangedCallback(name: string, oldValue: any, newValue: any): void;
65
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')
@@ -31,9 +32,10 @@ template.innerHTML = `<style>
31
32
  width: 100%;
32
33
  height: 100%;
33
34
  border: none;
35
+ user-select: none;
34
36
  }
35
37
  </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 {
38
+ export class DFrameElement extends HTMLElement {
37
39
  get id() { return this.getAttribute('id') ?? this.randomId; }
38
40
  set id(value) {
39
41
  this.setAttribute('id', value);
@@ -142,6 +144,9 @@ export default class DFrameElement extends HTMLElement {
142
144
  iframeLoaded = false;
143
145
  ready = false;
144
146
  iframeExtraAttrs = {};
147
+ resizeObserver;
148
+ boundOnMessage = (e) => this.onMessage(e);
149
+ mouseEventListeners = {};
145
150
  get actualAspectRatio() {
146
151
  if (this.aspectRatio !== 'auto')
147
152
  return Number(this.aspectRatio);
@@ -174,16 +179,14 @@ export default class DFrameElement extends HTMLElement {
174
179
  });
175
180
  const shadowRoot = this.attachShadow({ mode: 'open' });
176
181
  shadowRoot.appendChild(root);
177
- const resizeObserver = new ResizeObserver((entries) => {
182
+ this.resizeObserver = new ResizeObserver((entries) => {
178
183
  // make this callback insensitive to micro changes
179
184
  if (this.width === undefined || Math.abs(this.width - entries[0].contentRect.width) > 2) {
180
185
  this.width = entries[0].contentRect.width;
181
186
  this.updateAspectRatioHeight();
182
187
  }
183
188
  });
184
- resizeObserver.observe(this);
185
189
  this.adapter = this.windowAdapter = new WindowStateChangeAdapter();
186
- window.addEventListener('message', (e) => this.onMessage(e));
187
190
  }
188
191
  onMessage(e) {
189
192
  if (e.source === this.iframeElement?.contentWindow) {
@@ -199,7 +202,8 @@ export default class DFrameElement extends HTMLElement {
199
202
  syncParams: this.syncParams !== null,
200
203
  syncPath: this.syncPath !== null,
201
204
  stateChangeEvents: this.stateChangeEvents,
202
- mouseEvents: this.mouseEvents
205
+ mouseEvents: this.mouseEvents,
206
+ src: this.currentChildSrc
203
207
  }]);
204
208
  this.childInitialized = true;
205
209
  }
@@ -218,11 +222,11 @@ export default class DFrameElement extends HTMLElement {
218
222
  if (newParentHUrl.href !== window.location.href) {
219
223
  this.log('debug', 'apply state change to parent', message[2], newParentHUrl.href);
220
224
  try {
221
- this.adapter.stateChange(message[2], newParentHUrl);
225
+ this.adapter.stateChange(message[2], newParentHUrl, this);
222
226
  }
223
227
  catch (err) {
224
228
  this.log('error', 'failed to apply state change to parent using custom adapter', err);
225
- this.windowAdapter.stateChange(message[2], newParentHUrl);
229
+ this.windowAdapter.stateChange(message[2], newParentHUrl, this);
226
230
  }
227
231
  }
228
232
  }
@@ -355,11 +359,15 @@ export default class DFrameElement extends HTMLElement {
355
359
  initMouseEvents(types) {
356
360
  this.log('debug', 'initMouseEvents');
357
361
  for (const eventType of types) {
358
- document.addEventListener(eventType, (e) => {
359
- if (!(e instanceof MouseEvent))
360
- return;
361
- this.transmitSyncedMouseEvent(['df-global', 'mouse', eventType, { altKey: e.altKey, ctrlKey: e.ctrlKey, shiftKey: e.shiftKey, metaKey: e.metaKey }]);
362
- }, true);
362
+ if (!this.mouseEventListeners[eventType]) {
363
+ const listener = (e) => {
364
+ if (!(e instanceof MouseEvent))
365
+ return;
366
+ this.transmitSyncedMouseEvent(['df-global', 'mouse', eventType, { altKey: e.altKey, ctrlKey: e.ctrlKey, shiftKey: e.shiftKey, metaKey: e.metaKey }]);
367
+ };
368
+ this.mouseEventListeners[eventType] = listener;
369
+ document.addEventListener(eventType, listener, true);
370
+ }
363
371
  }
364
372
  }
365
373
  transmitSyncedMouseEvent(message) {
@@ -404,6 +412,8 @@ export default class DFrameElement extends HTMLElement {
404
412
  if (this.adapter.onStateChange) {
405
413
  this.adapter.onStateChange(() => { this.updateSrc(); });
406
414
  }
415
+ this.resizeObserver.observe(this);
416
+ window.addEventListener('message', this.boundOnMessage);
407
417
  if (this.syncParams !== null)
408
418
  this.parsedSyncParams = parseSyncParams(this.syncParams || '*');
409
419
  this.updateStyle();
@@ -414,9 +424,12 @@ export default class DFrameElement extends HTMLElement {
414
424
  }
415
425
  disconnectedCallback() {
416
426
  this.log('debug', 'disconnected');
417
- if (this.debug)
418
- console.timeEnd(`d-frame:${this.id}`);
419
- // TODO: more cleanup (resize observer, etc)
427
+ this.resizeObserver.disconnect();
428
+ window.removeEventListener('message', this.boundOnMessage);
429
+ for (const [eventType, listener] of Object.entries(this.mouseEventListeners)) {
430
+ document.removeEventListener(eventType, listener, true);
431
+ delete this.mouseEventListeners[eventType];
432
+ }
420
433
  }
421
434
  /* reflected attributes */
422
435
  static get observedAttributes() { return ['src', 'aspect-ratio', 'height', 'sync-params', 'sync-path', 'reload']; }
@@ -451,3 +464,4 @@ export default class DFrameElement extends HTMLElement {
451
464
  }
452
465
  }
453
466
  }
467
+ 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];
@@ -89,7 +89,11 @@ export function getParentUrl(fullSrc, childHref, currentParentHref, syncParams,
89
89
  parentUrl.hash = path;
90
90
  }
91
91
  else if (syncPath.startsWith('/')) {
92
- parentUrl.pathname = new URL(path, new URL(syncPath, currentParentHref)).pathname;
92
+ // a full path is not accepted, only a path child of the base
93
+ if (path === '' || path.startsWith('/'))
94
+ parentUrl.pathname = syncPath;
95
+ else
96
+ parentUrl.pathname = new URL(path, new URL(syncPath, currentParentHref)).pathname;
93
97
  }
94
98
  else {
95
99
  if (path)
@@ -1,2 +1,3 @@
1
1
  export declare function getPathDirectory(path: string): string;
2
+ export declare function getPathWithTrailingSlash(path: string): string;
2
3
  export declare function getUrlRelativePath(srcUrl: URL, currentUrl: URL): string;
package/lib/utils/url.js CHANGED
@@ -5,13 +5,18 @@ export function getPathDirectory(path) {
5
5
  return '/';
6
6
  return path.slice(0, path.lastIndexOf('/') + 1);
7
7
  }
8
+ export function getPathWithTrailingSlash(path) {
9
+ if (path.endsWith('/'))
10
+ return path;
11
+ return path + '/';
12
+ }
8
13
  export function getUrlRelativePath(srcUrl, currentUrl) {
9
14
  if (currentUrl.origin !== srcUrl.origin)
10
15
  return currentUrl.href;
11
- if (currentUrl.pathname === srcUrl.pathname)
16
+ if (getPathWithTrailingSlash(currentUrl.pathname) === getPathWithTrailingSlash(srcUrl.pathname))
12
17
  return '';
13
18
  const srcDirectory = getPathDirectory(srcUrl.pathname);
14
19
  if (!currentUrl.pathname.startsWith(srcDirectory))
15
20
  return currentUrl.pathname;
16
- return currentUrl.pathname.replace(srcDirectory, './');
21
+ return currentUrl.pathname.replace(srcDirectory, '');
17
22
  }
@@ -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,7 +3,7 @@ class VueRouterDFrameStateChangeAdapter {
3
3
  constructor(router) {
4
4
  this.router = router;
5
5
  }
6
- stateChange(action, newUrl) {
6
+ stateChange(action, newUrl, element) {
7
7
  // @ts-ignore vue-router v2
8
8
  const base = this.router.options?.base ?? this.router.options.history?.base;
9
9
  if (base === null || base === undefined) {
@@ -16,6 +16,7 @@ class VueRouterDFrameStateChangeAdapter {
16
16
  let newRoute = newUrl.href.replace(urlPrefix, '');
17
17
  if (!newRoute.startsWith('/'))
18
18
  newRoute = '/' + newRoute;
19
+ element.log('debug', 'apply state change on vue.router', action, newRoute);
19
20
  if (action === 'push')
20
21
  this.router.push(newRoute);
21
22
  if (action === 'replace')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-fair/frame",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "An iframe wrapper for powerful web app integrations.",
5
5
  "main": "dist/frame.min.js",
6
6
  "directories": {