@data-fair/frame 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -4,8 +4,8 @@ An iframe wrapper for powerful web app integrations.
4
4
  Lightweight, vanilla JS, no dependency.
5
5
 
6
6
  Supports:
7
+ - dynamic resizing
7
8
  - navigation syncing
8
- - aspect ratio management
9
- - dynamic resize
9
+ - notification passing
10
10
 
11
11
  See [the documentation](https://data-fair.github.io/frame/latest/).
@@ -1,2 +1,2 @@
1
- var DFrameContent=function(){"use strict";var u=Object.defineProperty;var g=(n,i,a)=>i in n?u(n,i,{enumerable:!0,configurable:!0,writable:!0,value:a}):n[i]=a;var c=(n,i,a)=>g(n,typeof i!="symbol"?i+"":i,a);function n(s){return s[0]==="df-parent"&&s[1]==="init"}function i(s){return s[0]==="df-parent"&&s[1]==="updateSrc"}const a=["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 d{constructor(e){c(this,"options");c(this,"pendingCheckHeight",!1);c(this,"debug",!1);c(this,"throttledCheckHeight");c(this,"lastHeight",0);this.options=e??{};const t=()=>{this.checkHeight(),this.pendingCheckHeight=!1};this.throttledCheckHeight=()=>{this.pendingCheckHeight||(this.pendingCheckHeight=!0,requestAnimationFrame(t))},!(typeof window>"u")&&(window.addEventListener("message",o=>this.onMessage(o)),this.postMessageToParent(["df-child","init"]))}log(e,...t){e==="debug"&&!this.debug||(e==="debug"&&console.debug("d-frame-content",...t),e==="info"&&console.info("d-frame-content",...t))}onMessage(e){if(e.source===window.parent&&Array.isArray(e.data)){const t=e.data;n(t)&&(this.debug=!!t[2].debug,t[2].resize!=="no"&&this.initResize(),(t[2].syncParams||t[2].syncPath)&&this.initSyncParams()),i(t)&&(this.options.updateSrc?this.options.updateSrc(t[2].startsWith("/")?window.location.origin+t[2]:t[2]):window.location.href=t[2])}}postMessageToParent(e){window.parent.postMessage(e)}initResize(){this.log("debug","initResize"),this.checkHeight(),this.createMutationObserver(),this.createWindowEventListeners()}initSyncParams(){this.log("debug","initSyncParams");const e=window.history.replaceState,t=(...r)=>{const h=e.apply(window.history,r);return this.postMessageToParent(["df-child","stateChange","push",window.location.href]),h};window.history.pushState=t;const o=(...r)=>{const h=e.apply(window.history,r);return this.postMessageToParent(["df-child","stateChange","replace",window.location.href]),h};window.history.replaceState=o}createMutationObserver(){const e=document.querySelector("body");if(!e)throw new Error("DFrameContentManager was initialized before the HTML body");new window.MutationObserver(this.throttledCheckHeight).observe(e,{attributes:!1,attributeOldValue:!1,characterData:!1,characterDataOldValue:!1,childList:!0,subtree:!0})}createWindowEventListeners(){for(const e of a)window.addEventListener(e,this.throttledCheckHeight,{passive:!0})}checkHeight(){const e=document.querySelectorAll("[data-iframe-height]");let t=0;for(const o of e){const r=o.getAttribute("data-iframe-height"),h=o.getBoundingClientRect().bottom+parseFloat(getComputedStyle(o).getPropertyValue("margin-bottom"))+(r?parseFloat(r):0);h>t&&(t=h)}t!==this.lastHeight&&(this.postMessageToParent(["df-child","height",t]),this.lastHeight=t)}}return new d}();
1
+ var DFrameContent=function(){"use strict";var u=Object.defineProperty;var l=(n,i,s)=>i in n?u(n,i,{enumerable:!0,configurable:!0,writable:!0,value:s}):n[i]=s;var a=(n,i,s)=>l(n,typeof i!="symbol"?i+"":i,s);function n(r){return r[0]==="df-parent"&&r[1]==="init"}function i(r){return r[0]==="df-parent"&&r[1]==="updateSrc"}const s=["animationstart","webkitAnimationStart","animationiteration","webkitAnimationIteration","animationend","webkitAnimationEnd","input","mouseup","mousedown","orientationchange","afterprint","beforeprint","readystatechange","touchstart","touchend","touchcancel","transitionstart","webkitTransitionStart","MSTransitionStart","oTransitionStart","otransitionstart","transitioniteration","webkitTransitionIteration","MSTransitionIteration","oTransitionIteration","otransitioniteration","transitionend","webkitTransitionEnd","MSTransitionEnd","oTransitionEnd","otransitionend","resize"];class c{constructor(t){a(this,"initialized",!1);a(this,"options");a(this,"pendingCheckHeight",!1);a(this,"debug",!1);a(this,"throttledCheckHeight");a(this,"lastHeight",0);this.options=t??{};const e=()=>{this.checkHeight(),this.pendingCheckHeight=!1};this.throttledCheckHeight=()=>{this.pendingCheckHeight||(this.pendingCheckHeight=!0,requestAnimationFrame(e))},!(typeof window>"u")&&(window.addEventListener("message",o=>this.onMessage(o)),this.postMessageToParent(["df-child","init"]))}log(t,...e){t==="debug"&&!this.debug||(t==="debug"&&console.debug("d-frame-content",...e),t==="info"&&console.info("d-frame-content",...e))}onMessage(t){if(t.source===window.parent&&Array.isArray(t.data)){const e=t.data;n(e)&&(this.debug=!!e[2].debug,e[2].resize!=="no"&&this.initResize(),(e[2].syncParams||e[2].syncPath)&&this.initSyncParams(),this.initialized=!0),i(e)&&(this.options.updateSrc?this.options.updateSrc(e[2].startsWith("/")?window.location.origin+e[2]:e[2]):window.location.href=e[2])}}postMessageToParent(t){window.parent.postMessage(t)}sendNotif(t){this.postMessageToParent(["df-child","notif",t])}sendMessage(t){this.postMessageToParent(["df-child","custom",t])}initResize(){this.log("debug","initResize"),this.checkHeight(),this.createMutationObserver(),this.createWindowEventListeners()}initSyncParams(){this.log("debug","initSyncParams");const t=window.history.replaceState,e=(...h)=>{const d=t.apply(window.history,h);return this.postMessageToParent(["df-child","stateChange","push",window.location.href]),d};window.history.pushState=e;const o=(...h)=>{const d=t.apply(window.history,h);return this.postMessageToParent(["df-child","stateChange","replace",window.location.href]),d};window.history.replaceState=o}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 s)window.addEventListener(t,this.throttledCheckHeight,{passive:!0})}checkHeight(){const t=document.querySelectorAll("[data-iframe-height]");let e=0;for(const o of t){const h=o.getAttribute("data-iframe-height"),d=o.getBoundingClientRect().bottom+parseFloat(getComputedStyle(o).getPropertyValue("margin-bottom"))+(h?parseFloat(h):0);d>e&&(e=d)}e!==this.lastHeight&&(this.postMessageToParent(["df-child","height",e]),this.lastHeight=e)}}return new c}();
2
2
  //# sourceMappingURL=d-frame-content.min.js.map
@@ -1,4 +1,4 @@
1
- var E=Object.defineProperty;var R=(u,c,p)=>c in u?E(u,c,{enumerable:!0,configurable:!0,writable:!0,value:p}):u[c]=p;var o=(u,c,p)=>R(u,typeof c!="symbol"?c+"":c,p);(function(){"use strict";function u(e){return e[0]==="df-child"&&e[1]==="init"}function c(e){return e[0]==="df-child"&&e[1]==="height"}function p(e){return e[0]==="df-child"&&e[1]==="stateChange"}function m(e){return e.endsWith("/")?e:e===""?"/":e.slice(0,e.lastIndexOf("/")+1)}function b(e,r){if(r.origin!==e.origin)return r.href;if(r.pathname===e.pathname)return"";const t=m(e.pathname);return r.pathname.startsWith(t)?r.pathname.replace(t,"./"):r.pathname}const y=e=>e.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&");function w(e){const r=[];for(const t of e.split(",")){const[i="*",s]=t.split(":"),a="^"+y(i).replace(/\\\*/g,"(.*)")+"$";r.push({regexp:new RegExp(a),append:s})}return r}function A(e,r,t,i){if(!t&&!i)return e.href;const s=new URL(r);if(t&&s.searchParams.forEach((a,d)=>{for(const n of t){if(n.append&&!d.startsWith(n.append)||d===i)continue;const h=n.append?d.replace(n.append,""):d;if(h.match(n.regexp)){e.searchParams.set(h,a);break}}}),i!==null){const a=s.searchParams.get(i);a&&(e.pathname=new URL(a,e).pathname)}return e.href}function S(e,r,t,i,s){const a=new URL(t),d=new URL(r);if(i&&(a.searchParams.forEach((n,h)=>{for(const l of i){if(l.append&&!h.startsWith(l.append))continue;const f=l.append?h.replace(l.append,""):h;if(f.match(l.regexp)){d.searchParams.get(f)===null&&a.searchParams.delete(h);break}}}),d.searchParams.forEach((n,h)=>{for(const l of i){if(!h.match(l.regexp)||(e==null?void 0:e.searchParams.get(h))===n)continue;const f=l.append?l.append+h:h;a.searchParams.set(f,n);break}})),s!==null&&e){const n=b(e,d);n?a.searchParams.set(s,n):a.searchParams.delete(s)}return a}class P{stateChange(r,t){r==="replace"&&window.history.replaceState(null,"",t),r==="push"&&window.history.pushState(null,"",t)}}const g=document.createElement("template");g.innerHTML=`<style>
1
+ var C=Object.defineProperty;var H=(u,c,p)=>c in u?C(u,c,{enumerable:!0,configurable:!0,writable:!0,value:p}):u[c]=p;var o=(u,c,p)=>H(u,typeof c!="symbol"?c+"":c,p);(function(){"use strict";function u(e){return e[0]==="df-child"&&e[1]==="init"}function c(e){return e[0]==="df-child"&&e[1]==="height"}function p(e){return e[0]==="df-child"&&e[1]==="stateChange"}function m(e){return e[0]==="df-child"&&e[1]==="custom"}function b(e){return e[0]==="df-child"&&e[1]==="notif"}function y(e){return e.endsWith("/")?e:e===""?"/":e.slice(0,e.lastIndexOf("/")+1)}function w(e,r){if(r.origin!==e.origin)return r.href;if(r.pathname===e.pathname)return"";const t=y(e.pathname);return r.pathname.startsWith(t)?r.pathname.replace(t,"./"):r.pathname}const A=e=>e.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&");function E(e){const r=[];for(const t of e.split(",")){const[s="*",i]=t.split(":"),a="^"+A(s).replace(/\\\*/g,"(.*)")+"$";r.push({regexp:new RegExp(a),append:i})}return r}function S(e,r,t,s){if(!t&&!s)return e.href;const i=new URL(r);if(t&&i.searchParams.forEach((a,d)=>{for(const n of t){if(n.append&&!d.startsWith(n.append)||d===s)continue;const h=n.append?d.replace(n.append,""):d;if(h.match(n.regexp)){e.searchParams.set(h,a);break}}}),s!==null){const a=i.searchParams.get(s);a&&(e.pathname=new URL(a,e).pathname)}return e.href}function P(e,r,t,s,i){const a=new URL(t),d=new URL(r);if(s&&(a.searchParams.forEach((n,h)=>{for(const l of s){if(l.append&&!h.startsWith(l.append))continue;const f=l.append?h.replace(l.append,""):h;if(f.match(l.regexp)){d.searchParams.get(f)===null&&a.searchParams.delete(h);break}}}),d.searchParams.forEach((n,h)=>{for(const l of s){if(!h.match(l.regexp)||(e==null?void 0:e.searchParams.get(h))===n)continue;const f=l.append?l.append+h:h;a.searchParams.set(f,n);break}})),i!==null&&e){const n=w(e,d);n?a.searchParams.set(i,n):a.searchParams.delete(i)}return a}class z{stateChange(r,t){r==="replace"&&window.history.replaceState(null,"",t),r==="push"&&window.history.pushState(null,"",t)}}const g=document.createElement("template");g.innerHTML=`<style>
2
2
  :host {
3
3
  display: block;
4
4
  }
@@ -8,5 +8,5 @@ var E=Object.defineProperty;var R=(u,c,p)=>c in u?E(u,c,{enumerable:!0,configura
8
8
  border: none;
9
9
  max-height: 100%;
10
10
  }
11
- </style><slot name="loader"></slot><iframe class="d-frame-iframe" frameborder="0">`;class z extends HTMLElement{constructor(){super();o(this,"adapter");o(this,"connected",!1);o(this,"initialSrc");o(this,"srcUrl");o(this,"parsedSyncParams");o(this,"iframeElement");o(this,"slotElement");o(this,"width");o(this,"aspectRatioHeight");o(this,"resizedHeight");const t=g.content.cloneNode(!0);this.slotElement=t.childNodes[1],this.resize!=="yes"&&(this.slotElement.style.display="none"),this.iframeElement=t.childNodes[2],this.iframeElement.setAttribute("scrolling",this.resize==="yes"?"no":"auto"),this.iframeElement.setAttribute("loading",this.lazy?"lazy":"eager"),this.attachShadow({mode:"open"}).appendChild(t),new ResizeObserver(a=>{this.width!==a[0].contentRect.width&&(this.width=a[0].contentRect.width,this.updateAspectRatioHeight())}).observe(this),this.adapter=new P,window.addEventListener("message",a=>this.onMessage(a))}get debug(){return this.hasAttribute("debug")}set debug(t){t?this.setAttribute("debug",""):this.removeAttribute("debug")}get lazy(){return this.hasAttribute("lazy")}set lazy(t){t?this.setAttribute("lazy",""):this.removeAttribute("lazy")}get src(){return this.getAttribute("src")}set src(t){this.setAttribute("src",t)}get aspectRatio(){return this.getAttribute("aspect-ratio")??"auto"}set aspectRatio(t){this.setAttribute("aspect-ratio",t)}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 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 i;if(t.source===((i=this.iframeElement)==null?void 0:i.contentWindow)&&Array.isArray(t.data)){const s=t.data;if(this.log("debug","received message from child",s),u(s)&&(this.postMessageToChild(["df-parent","init",{debug:this.debug,resize:this.resize,syncParams:this.syncParams!==null,syncPath:this.syncPath!==null}]),this.init()),c(s)&&(this.resizedHeight=s[2],this.updateStyle()),p(s)&&(this.parsedSyncParams||this.syncPath)){const a=S(this.srcUrl,s[3],window.location.href,this.parsedSyncParams,this.syncPath);a.href!==window.location.href&&this.adapter.stateChange(s[2],a)}}}init(){this.initialSrc=this.src}postMessageToChild(t){var i,s;this.log("debug","send message to child",t),(s=(i=this.iframeElement)==null?void 0:i.contentWindow)==null||s.postMessage(t)}updateSrc(){if(!this.connected)return;this.srcUrl=new URL(this.src.startsWith("/")?window.location.origin+this.src:this.src);const t=A(this.srcUrl,window.location.href,this.parsedSyncParams,this.syncPath);this.initialSrc?this.postMessageToChild(["df-parent","updateSrc",t]):this.iframeElement.setAttribute("src",t)}updateStyle(){let t="";(this.resize==="yes"||this.resize==="auto"&&this.resizedHeight)&&(this.iframeElement.setAttribute("scrolling","no"),this.resizedHeight?(this.slotElement.style.display="none",t+=`height:${this.resizedHeight}px;`):this.height?(this.slotElement.style.display="none",t+=`height:${this.height};`):this.aspectRatio!=="auto"?(this.slotElement.style.display="none",t+=`height:${this.aspectRatioHeight}px;`):(this.slotElement.style.display="block",t+="height:0;")),(this.resize==="no"||this.resize==="auto"&&!this.resizedHeight)&&(this.iframeElement.setAttribute("scrolling","auto"),this.height?t+=`height:${this.height};`:t+=`height:${this.aspectRatioHeight}px;`),this.iframeElement.setAttribute("style",t)}updateAspectRatioHeight(){this.width&&(this.resizedHeight||this.height||(this.aspectRatioHeight=this.width/this.actualAspectRatio,this.updateStyle()))}log(t,...i){t==="debug"&&!this.debug||(t==="debug"&&console.debug("d-frame",...i),t==="info"&&console.info("d-frame",...i))}connectedCallback(){if(!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=w(this.syncParams||"*")),this.updateStyle(),this.updateSrc()}static get observedAttributes(){return["src","aspect-ratio","height","sync-params","sync-path"]}attributeChangedCallback(t,i,s){this.log("debug","attribute change",t,i,s),t==="aspect-ratio"&&this.updateAspectRatioHeight(),t==="src"&&this.updateSrc(),t==="height"&&this.updateStyle(),t==="sync-params"&&this.updateSrc(),t==="sync-path"&&this.updateSrc()}}customElements.define("d-frame",z)})();
11
+ </style><slot name="loader"></slot><iframe class="d-frame-iframe" frameborder="0">`;class R extends HTMLElement{constructor(){super();o(this,"adapter");o(this,"connected",!1);o(this,"initialSrc");o(this,"srcUrl");o(this,"parsedSyncParams");o(this,"iframeElement");o(this,"slotElement");o(this,"width");o(this,"aspectRatioHeight");o(this,"resizedHeight");const t=g.content.cloneNode(!0);this.slotElement=t.childNodes[1],this.resize!=="yes"&&(this.slotElement.style.display="none"),this.iframeElement=t.childNodes[2],this.iframeElement.setAttribute("scrolling",this.resize==="yes"?"no":"auto"),this.iframeElement.setAttribute("loading",this.lazy?"lazy":"eager"),this.attachShadow({mode:"open"}).appendChild(t),new ResizeObserver(a=>{this.width!==a[0].contentRect.width&&(this.width=a[0].contentRect.width,this.updateAspectRatioHeight())}).observe(this),this.adapter=new z,window.addEventListener("message",a=>this.onMessage(a))}get debug(){return this.hasAttribute("debug")}set debug(t){t?this.setAttribute("debug",""):this.removeAttribute("debug")}get lazy(){return this.hasAttribute("lazy")}set lazy(t){t?this.setAttribute("lazy",""):this.removeAttribute("lazy")}get src(){return this.getAttribute("src")}set src(t){this.setAttribute("src",t)}get aspectRatio(){return this.getAttribute("aspect-ratio")??"auto"}set aspectRatio(t){this.setAttribute("aspect-ratio",t)}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 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)&&Array.isArray(t.data)){const i=t.data;if(this.log("debug","received message from child",i),u(i)&&(this.postMessageToChild(["df-parent","init",{debug:this.debug,resize:this.resize,syncParams:this.syncParams!==null,syncPath:this.syncPath!==null}]),this.init()),c(i)&&(this.resizedHeight=i[2],this.updateStyle()),p(i)&&(this.parsedSyncParams||this.syncPath)){const a=P(this.srcUrl,i[3],window.location.href,this.parsedSyncParams,this.syncPath);a.href!==window.location.href&&this.adapter.stateChange(i[2],a)}m(i)&&this.dispatchEvent(new CustomEvent("message",{detail:i[2]})),b(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:i[2]}))}}init(){this.initialSrc=this.src}postMessageToChild(t){var s,i;this.log("debug","send message to child",t),(i=(s=this.iframeElement)==null?void 0:s.contentWindow)==null||i.postMessage(t)}updateSrc(){if(!this.connected)return;this.srcUrl=new URL(this.src.startsWith("/")?window.location.origin+this.src:this.src);const t=S(this.srcUrl,window.location.href,this.parsedSyncParams,this.syncPath);this.initialSrc?this.postMessageToChild(["df-parent","updateSrc",t]):this.iframeElement.setAttribute("src",t)}updateStyle(){let t="";(this.resize==="yes"||this.resize==="auto"&&this.resizedHeight)&&(this.iframeElement.setAttribute("scrolling","no"),this.resizedHeight?(this.slotElement.style.display="none",t+=`height:${this.resizedHeight}px;`):this.height?(this.slotElement.style.display="none",t+=`height:${this.height};`):this.aspectRatio!=="auto"?(this.slotElement.style.display="none",t+=`height:${this.aspectRatioHeight}px;`):(this.slotElement.style.display="block",t+="height:0;")),(this.resize==="no"||this.resize==="auto"&&!this.resizedHeight)&&(this.iframeElement.setAttribute("scrolling","auto"),this.height?t+=`height:${this.height};`:t+=`height:${this.aspectRatioHeight}px;`),this.iframeElement.setAttribute("style",t)}updateAspectRatioHeight(){this.width&&(this.resizedHeight||this.height||(this.aspectRatioHeight=this.width/this.actualAspectRatio,this.updateStyle()))}log(t,...s){t==="debug"&&!this.debug||(t==="debug"&&console.debug("d-frame",...s),t==="info"&&console.info("d-frame",...s))}connectedCallback(){if(!this.hasAttribute("src"))throw new Error("src is a required attribute");this.log("debug","connected"),this.connected=!0,this.adapter.onStateChange&&this.adapter.onStateChange(()=>{this.updateSrc()}),this.syncParams!==null&&(this.parsedSyncParams=E(this.syncParams||"*")),this.updateStyle(),this.updateSrc()}static get observedAttributes(){return["src","aspect-ratio","height","sync-params","sync-path"]}attributeChangedCallback(t,s,i){this.log("debug","attribute change",t,s,i),t==="aspect-ratio"&&this.updateAspectRatioHeight(),t==="src"&&this.updateSrc(),t==="height"&&this.updateStyle(),t==="sync-params"&&this.updateSrc(),t==="sync-path"&&this.updateSrc()}}customElements.define("d-frame",R)})();
12
12
  //# sourceMappingURL=d-frame.min.js.map
@@ -0,0 +1,23 @@
1
+ import { type Notif } from './messages.js';
2
+ export type DFrameContentOptions = {
3
+ updateSrc?: (src: string) => void;
4
+ };
5
+ export default class DFrameContent {
6
+ initialized: boolean;
7
+ options: DFrameContentOptions;
8
+ private pendingCheckHeight;
9
+ debug: boolean;
10
+ private throttledCheckHeight;
11
+ private lastHeight;
12
+ constructor(options?: DFrameContentOptions);
13
+ private log;
14
+ private onMessage;
15
+ private postMessageToParent;
16
+ sendNotif(notif: Notif): void;
17
+ sendMessage(msg: any): void;
18
+ private initResize;
19
+ private initSyncParams;
20
+ private createMutationObserver;
21
+ private createWindowEventListeners;
22
+ private checkHeight;
23
+ }
@@ -31,6 +31,7 @@ const windowEventTypes = [
31
31
  'otransitionend', 'resize'
32
32
  ];
33
33
  export default class DFrameContent {
34
+ initialized = false;
34
35
  options;
35
36
  pendingCheckHeight = false;
36
37
  debug = false;
@@ -71,6 +72,7 @@ export default class DFrameContent {
71
72
  this.initResize();
72
73
  if (message[2].syncParams || message[2].syncPath)
73
74
  this.initSyncParams();
75
+ this.initialized = true;
74
76
  }
75
77
  if (isUpdateSrcMessage(message)) {
76
78
  if (this.options.updateSrc) {
@@ -85,6 +87,12 @@ export default class DFrameContent {
85
87
  postMessageToParent(message) {
86
88
  window.parent.postMessage(message);
87
89
  }
90
+ sendNotif(notif) {
91
+ this.postMessageToParent(['df-child', 'notif', notif]);
92
+ }
93
+ sendMessage(msg) {
94
+ this.postMessageToParent(['df-child', 'custom', msg]);
95
+ }
88
96
  initResize() {
89
97
  this.log('debug', 'initResize');
90
98
  this.checkHeight();
@@ -1,5 +1,5 @@
1
1
  // this is a good doc about writing web components https://web.dev/articles/custom-elements-best-practices
2
- import { isHeightMessage, isInitChildMessage, isStateChangeMessage } from './messages.js';
2
+ import { isCustomMessage, isHeightMessage, isInitChildMessage, isNotifMessage, isStateChangeMessage } from './messages.js';
3
3
  import { parseSyncParams, getChildSrc, getParentUrl } from './utils/sync-params.js';
4
4
  class WindowStateChangeAdapter {
5
5
  stateChange(action, newUrl) {
@@ -143,6 +143,12 @@ export default class DFrameElement extends HTMLElement {
143
143
  this.adapter.stateChange(message[2], newParentHUrl);
144
144
  }
145
145
  }
146
+ if (isCustomMessage(message)) {
147
+ this.dispatchEvent(new CustomEvent('message', { detail: message[2] }));
148
+ }
149
+ if (isNotifMessage(message)) {
150
+ this.dispatchEvent(new CustomEvent('notif', { detail: message[2] }));
151
+ }
146
152
  }
147
153
  }
148
154
  init() {
@@ -1,10 +1,19 @@
1
1
  export type InitChildMessage = ['df-child', 'init'];
2
2
  export type HeightMessage = ['df-child', 'height', number];
3
3
  export type StateChangeMessage = ['df-child', 'stateChange', 'replace' | 'push', string];
4
- export type ChildMessage = InitChildMessage | HeightMessage | StateChangeMessage;
5
- export declare function isInitChildMessage(message: any[]): message is InitChildMessage;
6
- export declare function isHeightMessage(message: any[]): message is HeightMessage;
7
- export declare function isStateChangeMessage(message: any[]): message is StateChangeMessage;
4
+ export type CustomMessage = ['df-child', 'custom', any];
5
+ export type NotifMessage = ['df-child', 'notif', Notif];
6
+ export type ChildMessage = InitChildMessage | HeightMessage | StateChangeMessage | CustomMessage | NotifMessage;
7
+ export type Notif = {
8
+ type: 'default' | 'info' | 'success' | 'warning' | 'error';
9
+ title: string;
10
+ detail?: string;
11
+ };
12
+ export declare function isInitChildMessage(message: any): message is InitChildMessage;
13
+ export declare function isHeightMessage(message: any): message is HeightMessage;
14
+ export declare function isStateChangeMessage(message: any): message is StateChangeMessage;
15
+ export declare function isCustomMessage(message: any): message is CustomMessage;
16
+ export declare function isNotifMessage(message: any): message is NotifMessage;
8
17
  export type InitParentMessage = ['df-parent', 'init', {
9
18
  debug?: boolean;
10
19
  resize: 'yes' | 'no' | 'auto';
@@ -7,6 +7,12 @@ export function isHeightMessage(message) {
7
7
  export function isStateChangeMessage(message) {
8
8
  return message[0] === 'df-child' && message[1] === 'stateChange';
9
9
  }
10
+ export function isCustomMessage(message) {
11
+ return message[0] === 'df-child' && message[1] === 'custom';
12
+ }
13
+ export function isNotifMessage(message) {
14
+ return message[0] === 'df-child' && message[1] === 'notif';
15
+ }
10
16
  export function isInitParentMessage(message) {
11
17
  return message[0] === 'df-parent' && message[1] === 'init';
12
18
  }
@@ -0,0 +1,7 @@
1
+ export type ParsedSyncParams = {
2
+ regexp: RegExp;
3
+ append?: string;
4
+ }[];
5
+ export declare function parseSyncParams(syncParamsStr: string): ParsedSyncParams;
6
+ export declare function getChildSrc(srcUrl: URL, parentHref: string, syncParams: ParsedSyncParams | undefined, syncPath: null | string): string;
7
+ export declare function getParentUrl(srcUrl: URL | undefined, childHref: string, currentParentHref: string, syncParams: ParsedSyncParams | undefined, syncPath: null | string): URL;
@@ -0,0 +1,80 @@
1
+ import { getUrlRelativePath } from './url.js';
2
+ const escapeRegExp = (str) => str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
3
+ export function parseSyncParams(syncParamsStr) {
4
+ const syncParams = [];
5
+ for (const syncParam of syncParamsStr.split(',')) {
6
+ const [pattern = '*', append] = syncParam.split(':');
7
+ const regexpStr = '^' + escapeRegExp(pattern).replace(/\\\*/g, '(.*)') + '$';
8
+ syncParams.push({
9
+ regexp: new RegExp(regexpStr),
10
+ append
11
+ });
12
+ }
13
+ return syncParams;
14
+ }
15
+ export function getChildSrc(srcUrl, parentHref, syncParams, syncPath) {
16
+ if (!syncParams && !syncPath)
17
+ return srcUrl.href;
18
+ const parentUrl = new URL(parentHref);
19
+ if (syncParams) {
20
+ parentUrl.searchParams.forEach((value, key) => {
21
+ for (const syncParam of syncParams) {
22
+ if (syncParam.append && !key.startsWith(syncParam.append))
23
+ continue;
24
+ if (key === syncPath)
25
+ continue;
26
+ const childKey = syncParam.append ? key.replace(syncParam.append, '') : key;
27
+ if (!childKey.match(syncParam.regexp))
28
+ continue;
29
+ srcUrl.searchParams.set(childKey, value);
30
+ break;
31
+ }
32
+ });
33
+ }
34
+ if (syncPath !== null) {
35
+ const path = parentUrl.searchParams.get(syncPath);
36
+ if (path) {
37
+ srcUrl.pathname = new URL(path, srcUrl).pathname;
38
+ }
39
+ }
40
+ return srcUrl.href;
41
+ }
42
+ export function getParentUrl(srcUrl, childHref, currentParentHref, syncParams, syncPath) {
43
+ const parentUrl = new URL(currentParentHref);
44
+ const childUrl = new URL(childHref);
45
+ if (syncParams) {
46
+ // remove existing keys that were deleted from the child
47
+ parentUrl.searchParams.forEach((value, key) => {
48
+ for (const syncParam of syncParams) {
49
+ if (syncParam.append && !key.startsWith(syncParam.append))
50
+ continue;
51
+ const childKey = syncParam.append ? key.replace(syncParam.append, '') : key;
52
+ if (!childKey.match(syncParam.regexp))
53
+ continue;
54
+ if (childUrl.searchParams.get(childKey) === null)
55
+ parentUrl.searchParams.delete(key);
56
+ break;
57
+ }
58
+ });
59
+ // apply params from child to parent
60
+ childUrl.searchParams.forEach((value, key) => {
61
+ for (const syncParam of syncParams) {
62
+ if (!key.match(syncParam.regexp))
63
+ continue;
64
+ if (srcUrl?.searchParams.get(key) === value)
65
+ continue;
66
+ const parentKey = syncParam.append ? (syncParam.append + key) : key;
67
+ parentUrl.searchParams.set(parentKey, value);
68
+ break;
69
+ }
70
+ });
71
+ }
72
+ if (syncPath !== null && srcUrl) {
73
+ const path = getUrlRelativePath(srcUrl, childUrl);
74
+ if (path)
75
+ parentUrl.searchParams.set(syncPath, path);
76
+ else
77
+ parentUrl.searchParams.delete(syncPath);
78
+ }
79
+ return parentUrl;
80
+ }
@@ -0,0 +1,2 @@
1
+ export declare function getPathDirectory(path: string): string;
2
+ export declare function getUrlRelativePath(srcUrl: URL, currentUrl: URL): string;
@@ -0,0 +1,17 @@
1
+ export function getPathDirectory(path) {
2
+ if (path.endsWith('/'))
3
+ return path;
4
+ if (path === '')
5
+ return '/';
6
+ return path.slice(0, path.lastIndexOf('/') + 1);
7
+ }
8
+ export function getUrlRelativePath(srcUrl, currentUrl) {
9
+ if (currentUrl.origin !== srcUrl.origin)
10
+ return currentUrl.href;
11
+ if (currentUrl.pathname === srcUrl.pathname)
12
+ return '';
13
+ const srcDirectory = getPathDirectory(srcUrl.pathname);
14
+ if (!currentUrl.pathname.startsWith(srcDirectory))
15
+ return currentUrl.pathname;
16
+ return currentUrl.pathname.replace(srcDirectory, './');
17
+ }
@@ -0,0 +1,5 @@
1
+ import DFrameContent, { type DFrameContentOptions } from '../DFrameContent.js';
2
+ import type { Router } from 'vue-router';
3
+ type VueRouterDFrameContentOptions = Omit<DFrameContentOptions, 'updateSrc'>;
4
+ export declare function vueRouterDFrameContent(router: Router, options?: VueRouterDFrameContentOptions): DFrameContent;
5
+ export default vueRouterDFrameContent;
@@ -0,0 +1,15 @@
1
+ import DFrameContent from '../DFrameContent.js';
2
+ export function vueRouterDFrameContent(router, options) {
3
+ return new DFrameContent({
4
+ updateSrc: (src) => {
5
+ const urlPrefix = window.location.origin + router.options.history.base;
6
+ if (src.startsWith(urlPrefix)) {
7
+ router.replace(src.replace(urlPrefix, ''));
8
+ }
9
+ else {
10
+ window.location.href = src;
11
+ }
12
+ }
13
+ });
14
+ }
15
+ export default vueRouterDFrameContent;
@@ -0,0 +1,10 @@
1
+ import { type StateChangeAdapter } from '../DFrameElement.js';
2
+ import type { Router } from 'vue-router';
3
+ declare class VueRouterDFrameStateChangeAdapter implements StateChangeAdapter {
4
+ router: Router;
5
+ constructor(router: Router);
6
+ stateChange(action: 'push' | 'replace', newUrl: URL): void;
7
+ onStateChange(callback: () => void): void;
8
+ }
9
+ declare const _default: (router: Router) => VueRouterDFrameStateChangeAdapter;
10
+ export default _default;
@@ -0,0 +1,16 @@
1
+ class VueRouterDFrameStateChangeAdapter {
2
+ router;
3
+ constructor(router) {
4
+ this.router = router;
5
+ }
6
+ stateChange(action, newUrl) {
7
+ if (action === 'push')
8
+ this.router.push({ query: Object.fromEntries(newUrl.searchParams) });
9
+ if (action === 'replace')
10
+ this.router.replace({ query: Object.fromEntries(newUrl.searchParams) });
11
+ }
12
+ onStateChange(callback) {
13
+ this.router.afterEach(callback);
14
+ }
15
+ }
16
+ export default (router) => new VueRouterDFrameStateChangeAdapter(router);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@data-fair/frame",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "An iframe wrapper for powerful web app integrations.",
5
5
  "main": "dist/frame.min.js",
6
6
  "directories": {
@@ -23,7 +23,7 @@
23
23
  "dev-zellij": "zellij --layout .zellij.kdl",
24
24
  "prepare": "husky",
25
25
  "test": "node --test tests/*.js",
26
- "build": "rm -f src/*.d.ts && rm -f src/*.js && tsc -p tsconfig.json && rm -rf dist && vite -c vite.config.d-frame.js build && vite -c vite.config.d-frame-content.js build",
26
+ "build": "rm -f lib/*.d.ts && rm -f lib/*.js && tsc -p tsconfig.json && rm -rf dist && vite -c vite.config.d-frame.js build && vite -c vite.config.d-frame-content.js build",
27
27
  "prepublishOnly": "npm run lint && npm run test && npm run build",
28
28
  "publish:main": "cd doc && npm run build:main && cd .. && gh-pages-multi deploy -v -s doc/.output/public -t main",
29
29
  "publish:latest": "cd doc && npm run build:latest && cd .. && gh-pages-multi deploy -v -s doc/.output/public -t latest"
@@ -37,8 +37,8 @@
37
37
  "license": "MIT",
38
38
  "type": "module",
39
39
  "files": [
40
- "src/*.js",
41
- "src/*.d.ts",
40
+ "lib/**/*.js",
41
+ "lib/**/*.d.ts",
42
42
  "dist/*.js"
43
43
  ]
44
44
  }
@@ -1,20 +0,0 @@
1
- import { ChildMessage } from './messages.js';
2
- export type DFrameContentOptions = {
3
- updateSrc?: (src: string) => void;
4
- };
5
- export default class DFrameContent {
6
- private options;
7
- private pendingCheckHeight;
8
- private debug;
9
- private throttledCheckHeight;
10
- private lastHeight;
11
- constructor(options?: DFrameContentOptions);
12
- log(level: 'debug' | 'info', ...args: any[]): void;
13
- onMessage(e: MessageEvent): void;
14
- postMessageToParent(message: ChildMessage): void;
15
- initResize(): void;
16
- initSyncParams(): void;
17
- createMutationObserver(): void;
18
- createWindowEventListeners(): void;
19
- checkHeight(): void;
20
- }
File without changes
File without changes
File without changes
File without changes
File without changes