@data-fair/frame 0.13.1 → 0.13.3
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/dist/d-frame.min.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var k=Object.defineProperty;var N=(u,c,f)=>c in u?k(u,c,{enumerable:!0,configurable:!0,writable:!0,value:f}):u[c]=f;var a=(u,c,f)=>N(u,typeof c!="symbol"?c+"":c,f);(function(){"use strict";var v,A;function u(t){return t[0]==="df-global"&&t[1]==="mouse"}function c(t){return t[0]==="df-child"&&t[1]==="init"}function f(t){return t[0]==="df-child"&&t[1]==="height"}function S(t){return t[0]==="df-child"&&t[1]==="stateChange"}function
|
|
1
|
+
var k=Object.defineProperty;var N=(u,c,f)=>c in u?k(u,c,{enumerable:!0,configurable:!0,writable:!0,value:f}):u[c]=f;var a=(u,c,f)=>N(u,typeof c!="symbol"?c+"":c,f);(function(){"use strict";var v,A;function u(t){return t[0]==="df-global"&&t[1]==="mouse"}function c(t){return t[0]==="df-child"&&t[1]==="init"}function f(t){return t[0]==="df-child"&&t[1]==="height"}function S(t){return t[0]==="df-child"&&t[1]==="stateChange"}function M(t){return t[0]==="df-child"&&t[1]==="custom"}function C(t){return t[0]==="df-child"&&t[1]==="notif"}function L(t){return t[0]==="df-child"&&t[1]==="addParentUrlListener"}function R(t){return t[0]==="df-child"&&t[1]==="removeParentUrlListener"}function P(t){return t[0]==="df-child"&&t[1]==="ready"}function z(t){return t.endsWith("/")?t:t===""?"/":t.slice(0,t.lastIndexOf("/")+1)}function b(t){return t.endsWith("/")?t:t+"/"}function y(t,n){if(n.origin!==t.origin)return n.href;if(b(n.pathname)===b(t.pathname))return"";const e=z(t.pathname);return n.pathname.startsWith(e)?n.pathname.replace(e,""):n.pathname}const x=t=>t.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&");function U(t){const n=[];for(const e of t.split(",")){const[s="*",i]=e.split(":"),r="^"+x(s).replace(/\\\*/g,"(.*)")+"$";n.push({regexp:new RegExp(r),append:i})}return n}function I(t,n,e,s){if(!e&&!s)return t;const i=new URL(t),r=new URL(n);if(e&&r.searchParams.forEach((h,l)=>{for(const o of e){if(o.append&&!l.startsWith(o.append)||l===s)continue;const d=o.append?l.replace(o.append,""):l;if(d.match(o.regexp)){i.searchParams.set(d,h);break}}}),s!==null){let h;if(s==="#")h=r.hash.slice(1);else if(s.startsWith("/"))if(r.pathname.startsWith(s)||r.pathname+"/"===s)h=y(new URL(s,n),r);else return null;else h=r.searchParams.get(s);h&&(i.pathname=new URL(h,t).pathname)}return i.href}function p(t,n,e,s,i){const r=new URL(t),h=new URL(e),l=new URL(n);if(s){for(const o of h.searchParams.keys().toArray())for(const d of s){if(d.append&&!o.startsWith(d.append))continue;const m=d.append?o.replace(d.append,""):o;if(m.match(d.regexp)){l.searchParams.get(m)===null&&h.searchParams.delete(o);break}}l.searchParams.forEach((o,d)=>{for(const m of s){if(!d.match(m.regexp)||(r==null?void 0:r.searchParams.get(d))===o)continue;const K=m.append?m.append+d:d;h.searchParams.set(K,o);break}})}if(i!==null&&r){const o=y(r,l);if(i==="#")h.hash=o;else if(i.startsWith("/")){if(o.startsWith("/"))return null;o===""?h.pathname=i:h.pathname=new URL(o,new URL(i,e)).pathname}else o?h.searchParams.set(i,o):h.searchParams.delete(i)}return h}function W(t){return t.vIframe===!0&&t.uiNotification!==void 0}function H(t){if(typeof t=="string")return{type:"default",title:t};if(t.error&&!t.errorMsg){const n=t.error.response&&(t.error.response.data||t.error.response.status)||t.error.message||t.error;return t.msg?{type:"error",title:t.msg,detail:n}:{type:"error",title:n}}return t.type==="error"?{type:t.clientError?"warning":"error",title:t.msg,detail:t.errorMsg}:{type:t.type??"default",title:t.msg}}class T{stateChange(n,e,s){s.log("debug","apply state change on window.history",n,e.href),n==="replace"&&window.history.replaceState(window.history.state,"",e),n==="push"&&window.history.pushState(window.history.state,"",e)}onStateChange(n){window.addEventListener("popstate",n)}}const g=((v=document.head)==null?void 0:v.querySelector("meta[property=csp-nonce]"))??((A=document.head)==null?void 0:A.querySelector("meta[name=csp-nonce]")),w=(g==null?void 0:g.nonce)??(g==null?void 0:g.content),E=document.createElement("template");E.innerHTML=`<style${w?` nonce="${w}"`:""}>
|
|
2
2
|
:host {
|
|
3
3
|
display: block;
|
|
4
4
|
}
|
|
@@ -15,5 +15,5 @@ var k=Object.defineProperty;var N=(u,c,f)=>c in u?k(u,c,{enumerable:!0,configura
|
|
|
15
15
|
border: none;
|
|
16
16
|
user-select: none;
|
|
17
17
|
}
|
|
18
|
-
</style><div class="d-frame-wrapper"><slot name="loading"><div class="loading-placeholder"></div></slot><iframe class="d-frame-iframe"></iframe></div>`;class O extends HTMLElement{constructor(){super();a(this,"adapter");a(this,"windowAdapter");a(this,"connected",!1);a(this,"childInitialized",!1);a(this,"currentChildSrc",null);a(this,"parsedSyncParams");a(this,"wrapperElement");a(this,"slotElement");a(this,"iframeElement");a(this,"width");a(this,"aspectRatioHeight");a(this,"resizedHeight");a(this,"randomId");a(this,"iframeLoaded",!1);a(this,"ready",!1);a(this,"iframeExtraAttrs",{});a(this,"resizeObserver");a(this,"boundOnMessage",e=>this.onMessage(e));a(this,"mouseEventListeners",{});a(this,"parentUrlListeners",{});a(this,"currentSyncedMouseEvents",new Set);this.randomId=Math.random().toString(36).slice(-6);const e=E.content.cloneNode(!0);this.wrapperElement=e.childNodes[1],this.slotElement=this.wrapperElement.childNodes[0],this.iframeElement=this.wrapperElement.childNodes[1],this.iframeElement.style.cssText="visibility:hidden;position:absolute;height:0px;",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(e),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 I}get id(){return this.getAttribute("id")??this.randomId}set id(e){this.setAttribute("id",e)}get debug(){return this.hasAttribute("debug")}set debug(e){e?this.setAttribute("debug",""):this.removeAttribute("debug")}get src(){return this.getAttribute("src")}set src(e){this.setAttribute("src",e)}get fullSrc(){return this.src.startsWith("/")?window.location.origin+this.src:this.src}get aspectRatio(){const e=this.getAttribute("aspect-ratio");return e===""?"auto":e}set aspectRatio(e){e!==null?this.setAttribute("aspect-ratio",e):this.removeAttribute("aspect-ratio")}get height(){return this.getAttribute("height")}set height(e){e?this.setAttribute("height",e):this.removeAttribute("height")}set resize(e){this.setAttribute("resize",e)}get resize(){const e=this.getAttribute("resize");return e===null?"auto":e===""?"yes":e}get syncParams(){return this.getAttribute("sync-params")}set syncParams(e){e!==null?this.setAttribute("sync-params",e):this.removeAttribute("sync-params")}get syncPath(){const e=this.getAttribute("sync-path");return e===null?null:e||"p"}set syncPath(e){e!==null?this.setAttribute("sync-params",e):this.removeAttribute("sync-params")}get stateChangeEvents(){return this.hasAttribute("state-change-events")}set stateChangeEvents(e){e?this.setAttribute("state-change-events",""):this.removeAttribute("state-change-events")}get readyMessage(){return this.hasAttribute("ready-message")}set readyMessage(e){e?this.setAttribute("ready-message",""):this.removeAttribute("ready-message")}get mouseEvents(){const e=this.getAttribute("mouse-events");return e===null?null:e===""?["click","dblclick","mousedown","mouseup"]:e.split(",")}set mouseEvents(e){e===null?this.removeAttribute("mouse-events"):this.setAttribute("mouse-events",e.join(","))}get reload(){return this.getAttribute("reload")}set reload(e){this.setAttribute("reload",e)}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(e){var s;if(e.source===((s=this.iframeElement)==null?void 0:s.contentWindow)){const i=e.data;if(this.log("debug","received message from child",i),Array.isArray(e.data)){if(c(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()),S(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,this)}catch(h){this.log("error","failed to apply state change to parent using custom adapter",h),this.windowAdapter.stateChange(i[2],r,this)}}}this.stateChangeEvents&&this.dispatchEvent(new CustomEvent("state-change",{detail:[i[2],i[3]]}))}if(C(i)&&this.dispatchEvent(new CustomEvent("message",{detail:i[2]})),M(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:i[2]})),P(i)&&(this.ready=!0,this.dispatchEvent(new CustomEvent("ready")),this.updateStyle()),u(i)&&this.applySyncedMouseEvent(i),L(i)){const r=m(this.fullSrc,i[2],window.location.href,this.parsedSyncParams,this.syncPath).href;this.parentUrlListeners[i[2]]=r,this.postMessageToChild(["df-parent","parentUrl",i[2],r])}R(i)&&delete this.parentUrlListeners[i[2]]}else H(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:T(i.uiNotification)}))}}postMessageToChild(e){var s,i;this.log("debug","send message to child",e),(i=(s=this.iframeElement)==null?void 0:s.contentWindow)==null||i.postMessage(e)}updateSrc(){if(!this.connected)return;for(const[s,i]of Object.entries(this.parentUrlListeners)){const r=m(this.fullSrc,s,window.location.href,this.parsedSyncParams,this.syncPath).href;r!==i&&(this.parentUrlListeners[s]=r,this.postMessageToChild(["df-parent","parentUrl",s,r]))}const e=W(this.fullSrc,window.location.href,this.parsedSyncParams,this.syncPath);e!==this.currentChildSrc&&(this.currentChildSrc=e,this.childInitialized?this.postMessageToChild(["df-parent","updateSrc",e]):(this.log("debug","set src attribute of iframe: "+e),this.iframeElement.setAttribute("src",e)))}updateStyle(){if(!this.connected)return;let e;this.resizedHeight?(this.log("debug","height of iframe based on resize message: "+this.resizedHeight),e=this.resizedHeight+"px"):this.height?(this.log("debug","height of iframe based on direct attribute: "+this.height),e=this.height):this.aspectRatio!==null&&(this.log("debug","height of iframe based on aspect ratio: "+this.aspectRatioHeight),e=this.aspectRatioHeight+"px"),e!==void 0?(this.log("debug","set height iframe wrapper: "+e),this.wrapperElement.style.cssText=`height:${e};min-height:0;`):this.wrapperElement.style.cssText="",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.style.cssText="",this.slotElement.style.cssText="display:none;")}updateAspectRatioHeight(){this.width&&this.aspectRatio!==null&&(this.resizedHeight||this.height||(this.aspectRatioHeight=Math.ceil(this.width/this.actualAspectRatio),this.updateStyle()))}updateIframeExtraAttrs(){const e=this.iframeExtraAttrs,s={};for(const i of this.getAttributeNames())if(i.startsWith("iframe-")){const r=this.getAttribute(i);if(r!==null){const h=i.slice(7);s[h]=r}}this.log("debug","update iframe extra attributes",e,s);for(const i of Object.keys(e))i in s||this.iframeElement.removeAttribute(i);for(const i of Object.keys(s))s[i]!==e[i]&&this.iframeElement.setAttribute(i,s[i])}initMouseEvents(e){this.log("debug","initMouseEvents");for(const s of e)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(e){this.currentSyncedMouseEvents.has(e[2])?this.currentSyncedMouseEvents.delete(e[2]):this.postMessageToChild(e)}applySyncedMouseEvent(e){this.currentSyncedMouseEvents.add(e[2]);const s=new MouseEvent(e[2],{bubbles:!0,cancelable:!0,view:window,...e[3]});this.dispatchEvent(s)}log(e,...s){e==="debug"&&!this.debug||(e==="debug"&&console.timeLog(`d-frame:${this.id}`,...s),e==="info"&&console.info(`d-frame:${this.id}`,...s),e==="error"&&console.error(`d-frame:${this.id}`,...s))}connectedCallback(){if(!this.debug){const e=window.localStorage.getItem("debug");if(e){const s=e.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=U(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[e,s]of Object.entries(this.mouseEventListeners))document.removeEventListener(e,s,!0),delete this.mouseEventListeners[e]}static get observedAttributes(){return["src","aspect-ratio","height","sync-params","sync-path","reload"]}attributeChangedCallback(e,s,i){var r;if(e==="aspect-ratio"&&this.updateAspectRatioHeight(),!!this.connected&&(this.log("debug","attribute change",e,s,i),e==="src"&&this.updateSrc(),e==="height"&&this.updateStyle(),e==="sync-params"&&this.updateSrc(),e==="sync-path"&&this.updateSrc(),e==="reload")){if(!this.currentChildSrc){this.log("debug","reload attribute changed but the iframe has no current 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}if(!this.iframeLoaded){this.log("debug","reload attribute changed before initial loading was complete, ignore it");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",O)})();
|
|
18
|
+
</style><div class="d-frame-wrapper"><slot name="loading"><div class="loading-placeholder"></div></slot><iframe class="d-frame-iframe"></iframe></div>`;class O extends HTMLElement{constructor(){super();a(this,"adapter");a(this,"windowAdapter");a(this,"connected",!1);a(this,"childInitialized",!1);a(this,"currentChildSrc",null);a(this,"parsedSyncParams");a(this,"wrapperElement");a(this,"slotElement");a(this,"iframeElement");a(this,"width");a(this,"aspectRatioHeight");a(this,"resizedHeight");a(this,"randomId");a(this,"iframeLoaded",!1);a(this,"ready",!1);a(this,"iframeExtraAttrs",{});a(this,"resizeObserver");a(this,"boundOnMessage",e=>this.onMessage(e));a(this,"mouseEventListeners",{});a(this,"parentUrlListeners",{});a(this,"currentSyncedMouseEvents",new Set);this.randomId=Math.random().toString(36).slice(-6);const e=E.content.cloneNode(!0);this.wrapperElement=e.childNodes[1],this.slotElement=this.wrapperElement.childNodes[0],this.iframeElement=this.wrapperElement.childNodes[1],this.iframeElement.style.cssText="visibility:hidden;position:absolute;height:0px;",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(e),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 T}get id(){return this.getAttribute("id")??this.randomId}set id(e){this.setAttribute("id",e)}get debug(){return this.hasAttribute("debug")}set debug(e){e?this.setAttribute("debug",""):this.removeAttribute("debug")}get src(){return this.getAttribute("src")}set src(e){this.setAttribute("src",e)}get fullSrc(){return this.src.startsWith("/")?window.location.origin+this.src:this.src}get aspectRatio(){const e=this.getAttribute("aspect-ratio");return e===""?"auto":e}set aspectRatio(e){e!==null?this.setAttribute("aspect-ratio",e):this.removeAttribute("aspect-ratio")}get height(){return this.getAttribute("height")}set height(e){e?this.setAttribute("height",e):this.removeAttribute("height")}set resize(e){this.setAttribute("resize",e)}get resize(){const e=this.getAttribute("resize");return e===null?"auto":e===""?"yes":e}get syncParams(){return this.getAttribute("sync-params")}set syncParams(e){e!==null?this.setAttribute("sync-params",e):this.removeAttribute("sync-params")}get syncPath(){const e=this.getAttribute("sync-path");return e===null?null:e||"p"}set syncPath(e){e!==null?this.setAttribute("sync-params",e):this.removeAttribute("sync-params")}get stateChangeEvents(){return this.hasAttribute("state-change-events")}set stateChangeEvents(e){e?this.setAttribute("state-change-events",""):this.removeAttribute("state-change-events")}get readyMessage(){return this.hasAttribute("ready-message")}set readyMessage(e){e?this.setAttribute("ready-message",""):this.removeAttribute("ready-message")}get mouseEvents(){const e=this.getAttribute("mouse-events");return e===null?null:e===""?["click","dblclick","mousedown","mouseup"]:e.split(",")}set mouseEvents(e){e===null?this.removeAttribute("mouse-events"):this.setAttribute("mouse-events",e.join(","))}get reload(){return this.getAttribute("reload")}set reload(e){this.setAttribute("reload",e)}get emitIFrameMessages(){return this.hasAttribute("emit-iframe-messages")}set emitIFrameMessages(e){e?this.setAttribute("emit-iframe-messages",""):this.removeAttribute("emit-iframe-messages")}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(e){var s;if(this.emitIFrameMessages&&this.dispatchEvent(new CustomEvent("iframe-message",{detail:e.data})),e.source===((s=this.iframeElement)==null?void 0:s.contentWindow)){const i=e.data;if(this.log("debug","received message from child",i),Array.isArray(e.data)){if(c(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()),S(i)){if(this.currentChildSrc=i[3],this.parsedSyncParams||this.syncPath){const r=p(this.fullSrc,i[3],window.location.href,this.parsedSyncParams,this.syncPath);if(r===null)this.log("debug","failed to process newParentUrl, ignore state change");else if(r.href!==window.location.href){this.log("debug","apply state change to parent",i[2],r.href);try{this.adapter.stateChange(i[2],r,this)}catch(h){this.log("error","failed to apply state change to parent using custom adapter",h),this.windowAdapter.stateChange(i[2],r,this)}}}this.stateChangeEvents&&this.dispatchEvent(new CustomEvent("state-change",{detail:[i[2],i[3]]}))}if(M(i)&&this.dispatchEvent(new CustomEvent("message",{detail:i[2]})),C(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:i[2]})),P(i)&&(this.ready=!0,this.dispatchEvent(new CustomEvent("ready")),this.updateStyle()),u(i)&&this.applySyncedMouseEvent(i),L(i)){const r=p(this.fullSrc,i[2],window.location.href,this.parsedSyncParams,this.syncPath);r&&(this.parentUrlListeners[i[2]]=r.href,this.postMessageToChild(["df-parent","parentUrl",i[2],r.href]))}R(i)&&delete this.parentUrlListeners[i[2]]}else W(i)&&this.dispatchEvent(new CustomEvent("notif",{detail:H(i.uiNotification)}))}}postMessageToChild(e){var s,i;this.log("debug","send message to child",e),(i=(s=this.iframeElement)==null?void 0:s.contentWindow)==null||i.postMessage(e)}updateSrc(){if(!this.connected)return;for(const[s,i]of Object.entries(this.parentUrlListeners)){const r=p(this.fullSrc,s,window.location.href,this.parsedSyncParams,this.syncPath);r&&r.href!==i&&(this.parentUrlListeners[s]=r.href,this.postMessageToChild(["df-parent","parentUrl",s,r.href]))}const e=I(this.fullSrc,window.location.href,this.parsedSyncParams,this.syncPath);e&&e!==this.currentChildSrc&&(this.currentChildSrc=e,this.childInitialized?this.postMessageToChild(["df-parent","updateSrc",e]):(this.log("debug","set src attribute of iframe: "+e),this.iframeElement.setAttribute("src",e)))}updateStyle(){if(!this.connected)return;let e;this.resizedHeight?(this.log("debug","height of iframe based on resize message: "+this.resizedHeight),e=this.resizedHeight+"px"):this.height?(this.log("debug","height of iframe based on direct attribute: "+this.height),e=this.height):this.aspectRatio!==null&&(this.log("debug","height of iframe based on aspect ratio: "+this.aspectRatioHeight),e=this.aspectRatioHeight+"px"),e!==void 0?(this.log("debug","set height iframe wrapper: "+e),this.wrapperElement.style.cssText=`height:${e};min-height:0;`):this.wrapperElement.style.cssText="",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.style.cssText="",this.slotElement.style.cssText="display:none;")}updateAspectRatioHeight(){this.width&&this.aspectRatio!==null&&(this.resizedHeight||this.height||(this.aspectRatioHeight=Math.ceil(this.width/this.actualAspectRatio),this.updateStyle()))}updateIframeExtraAttrs(){const e=this.iframeExtraAttrs,s={};for(const i of this.getAttributeNames())if(i.startsWith("iframe-")){const r=this.getAttribute(i);if(r!==null){const h=i.slice(7);s[h]=r}}this.log("debug","update iframe extra attributes",e,s);for(const i of Object.keys(e))i in s||this.iframeElement.removeAttribute(i);for(const i of Object.keys(s))s[i]!==e[i]&&this.iframeElement.setAttribute(i,s[i])}initMouseEvents(e){this.log("debug","initMouseEvents");for(const s of e)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(e){this.currentSyncedMouseEvents.has(e[2])?this.currentSyncedMouseEvents.delete(e[2]):this.postMessageToChild(e)}applySyncedMouseEvent(e){this.currentSyncedMouseEvents.add(e[2]);const s=new MouseEvent(e[2],{bubbles:!0,cancelable:!0,view:window,...e[3]});this.dispatchEvent(s)}log(e,...s){e==="debug"&&!this.debug||(e==="debug"&&console.timeLog(`d-frame:${this.id}`,...s),e==="info"&&console.info(`d-frame:${this.id}`,...s),e==="error"&&console.error(`d-frame:${this.id}`,...s))}connectedCallback(){if(!this.debug){const e=window.localStorage.getItem("debug");if(e){const s=e.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=U(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[e,s]of Object.entries(this.mouseEventListeners))document.removeEventListener(e,s,!0),delete this.mouseEventListeners[e]}static get observedAttributes(){return["src","aspect-ratio","height","sync-params","sync-path","reload"]}attributeChangedCallback(e,s,i){var r;if(e==="aspect-ratio"&&this.updateAspectRatioHeight(),!!this.connected&&(this.log("debug","attribute change",e,s,i),e==="src"&&this.updateSrc(),e==="height"&&this.updateStyle(),e==="sync-params"&&this.updateSrc(),e==="sync-path"&&this.updateSrc(),e==="reload")){if(!this.currentChildSrc){this.log("debug","reload attribute changed but the iframe has no current 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}if(!this.iframeLoaded){this.log("debug","reload attribute changed before initial loading was complete, ignore it");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",O)})();
|
|
19
19
|
//# sourceMappingURL=d-frame.min.js.map
|
package/lib/DFrameElement.d.ts
CHANGED
|
@@ -29,6 +29,8 @@ export declare class DFrameElement extends HTMLElement {
|
|
|
29
29
|
set mouseEvents(value: string[] | null);
|
|
30
30
|
get reload(): string;
|
|
31
31
|
set reload(value: string);
|
|
32
|
+
get emitIFrameMessages(): boolean;
|
|
33
|
+
set emitIFrameMessages(value: boolean);
|
|
32
34
|
adapter: StateChangeAdapter;
|
|
33
35
|
windowAdapter: StateChangeAdapter;
|
|
34
36
|
private connected;
|
package/lib/DFrameElement.js
CHANGED
|
@@ -133,6 +133,13 @@ export class DFrameElement extends HTMLElement {
|
|
|
133
133
|
}
|
|
134
134
|
get reload() { return this.getAttribute('reload'); }
|
|
135
135
|
set reload(value) { this.setAttribute('reload', value); }
|
|
136
|
+
get emitIFrameMessages() { return this.hasAttribute('emit-iframe-messages'); }
|
|
137
|
+
set emitIFrameMessages(value) {
|
|
138
|
+
if (value)
|
|
139
|
+
this.setAttribute('emit-iframe-messages', '');
|
|
140
|
+
else
|
|
141
|
+
this.removeAttribute('emit-iframe-messages');
|
|
142
|
+
}
|
|
136
143
|
adapter;
|
|
137
144
|
windowAdapter;
|
|
138
145
|
/* internal state */
|
|
@@ -197,6 +204,9 @@ export class DFrameElement extends HTMLElement {
|
|
|
197
204
|
this.adapter = this.windowAdapter = new WindowStateChangeAdapter();
|
|
198
205
|
}
|
|
199
206
|
onMessage(e) {
|
|
207
|
+
if (this.emitIFrameMessages) {
|
|
208
|
+
this.dispatchEvent(new CustomEvent('iframe-message', { detail: e.data }));
|
|
209
|
+
}
|
|
200
210
|
if (e.source === this.iframeElement?.contentWindow) {
|
|
201
211
|
const message = e.data;
|
|
202
212
|
this.log('debug', 'received message from child', message);
|
|
@@ -227,14 +237,19 @@ export class DFrameElement extends HTMLElement {
|
|
|
227
237
|
this.currentChildSrc = message[3];
|
|
228
238
|
if ((this.parsedSyncParams || this.syncPath)) {
|
|
229
239
|
const newParentUrl = getParentUrl(this.fullSrc, message[3], window.location.href, this.parsedSyncParams, this.syncPath);
|
|
230
|
-
if (newParentUrl
|
|
231
|
-
this.log('debug', '
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
240
|
+
if (newParentUrl === null) {
|
|
241
|
+
this.log('debug', 'failed to process newParentUrl, ignore state change');
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
if (newParentUrl.href !== window.location.href) {
|
|
245
|
+
this.log('debug', 'apply state change to parent', message[2], newParentUrl.href);
|
|
246
|
+
try {
|
|
247
|
+
this.adapter.stateChange(message[2], newParentUrl, this);
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
this.log('error', 'failed to apply state change to parent using custom adapter', err);
|
|
251
|
+
this.windowAdapter.stateChange(message[2], newParentUrl, this);
|
|
252
|
+
}
|
|
238
253
|
}
|
|
239
254
|
}
|
|
240
255
|
}
|
|
@@ -257,9 +272,11 @@ export class DFrameElement extends HTMLElement {
|
|
|
257
272
|
this.applySyncedMouseEvent(message);
|
|
258
273
|
}
|
|
259
274
|
if (isAddParentUrlListenerMessage(message)) {
|
|
260
|
-
const parentUrl = getParentUrl(this.fullSrc, message[2], window.location.href, this.parsedSyncParams, this.syncPath)
|
|
261
|
-
|
|
262
|
-
|
|
275
|
+
const parentUrl = getParentUrl(this.fullSrc, message[2], window.location.href, this.parsedSyncParams, this.syncPath);
|
|
276
|
+
if (parentUrl) {
|
|
277
|
+
this.parentUrlListeners[message[2]] = parentUrl.href;
|
|
278
|
+
this.postMessageToChild(['df-parent', 'parentUrl', message[2], parentUrl.href]);
|
|
279
|
+
}
|
|
263
280
|
}
|
|
264
281
|
if (isRemoveParentUrlListenerMessage(message)) {
|
|
265
282
|
delete this.parentUrlListeners[message[2]];
|
|
@@ -279,13 +296,17 @@ export class DFrameElement extends HTMLElement {
|
|
|
279
296
|
if (!this.connected)
|
|
280
297
|
return;
|
|
281
298
|
for (const [childHref, existingParentUrl] of Object.entries(this.parentUrlListeners)) {
|
|
282
|
-
const parentUrl = getParentUrl(this.fullSrc, childHref, window.location.href, this.parsedSyncParams, this.syncPath)
|
|
283
|
-
if (parentUrl
|
|
284
|
-
|
|
285
|
-
|
|
299
|
+
const parentUrl = getParentUrl(this.fullSrc, childHref, window.location.href, this.parsedSyncParams, this.syncPath);
|
|
300
|
+
if (parentUrl) {
|
|
301
|
+
if (parentUrl.href !== existingParentUrl) {
|
|
302
|
+
this.parentUrlListeners[childHref] = parentUrl.href;
|
|
303
|
+
this.postMessageToChild(['df-parent', 'parentUrl', childHref, parentUrl.href]);
|
|
304
|
+
}
|
|
286
305
|
}
|
|
287
306
|
}
|
|
288
307
|
const iframeSrc = getChildSrc(this.fullSrc, window.location.href, this.parsedSyncParams, this.syncPath);
|
|
308
|
+
if (!iframeSrc)
|
|
309
|
+
return;
|
|
289
310
|
if (iframeSrc === this.currentChildSrc)
|
|
290
311
|
return;
|
|
291
312
|
this.currentChildSrc = iframeSrc;
|
|
@@ -3,5 +3,5 @@ export type ParsedSyncParams = {
|
|
|
3
3
|
append?: string;
|
|
4
4
|
}[];
|
|
5
5
|
export declare function parseSyncParams(syncParamsStr: string): ParsedSyncParams;
|
|
6
|
-
export declare function getChildSrc(fullSrc: string, parentHref: string, syncParams: ParsedSyncParams | undefined, syncPath: null | string): string;
|
|
7
|
-
export declare function getParentUrl(fullSrc: string, childHref: string, currentParentHref: string, syncParams: ParsedSyncParams | undefined, syncPath: null | string): URL;
|
|
6
|
+
export declare function getChildSrc(fullSrc: string, parentHref: string, syncParams: ParsedSyncParams | undefined, syncPath: null | string): string | null;
|
|
7
|
+
export declare function getParentUrl(fullSrc: string, childHref: string, currentParentHref: string, syncParams: ParsedSyncParams | undefined, syncPath: null | string): URL | null;
|
package/lib/utils/sync-params.js
CHANGED
|
@@ -38,9 +38,12 @@ export function getChildSrc(fullSrc, parentHref, syncParams, syncPath) {
|
|
|
38
38
|
path = parentUrl.hash.slice(1);
|
|
39
39
|
}
|
|
40
40
|
else if (syncPath.startsWith('/')) {
|
|
41
|
-
if (parentUrl.pathname.startsWith(syncPath)) {
|
|
41
|
+
if (parentUrl.pathname.startsWith(syncPath) || (parentUrl.pathname + '/') === syncPath) {
|
|
42
42
|
path = getUrlRelativePath(new URL(syncPath, parentHref), parentUrl);
|
|
43
43
|
}
|
|
44
|
+
else {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
44
47
|
}
|
|
45
48
|
else {
|
|
46
49
|
path = parentUrl.searchParams.get(syncPath);
|
|
@@ -90,7 +93,9 @@ export function getParentUrl(fullSrc, childHref, currentParentHref, syncParams,
|
|
|
90
93
|
}
|
|
91
94
|
else if (syncPath.startsWith('/')) {
|
|
92
95
|
// a full path is not accepted, only a path child of the base
|
|
93
|
-
if (path
|
|
96
|
+
if (path.startsWith('/'))
|
|
97
|
+
return null;
|
|
98
|
+
if (path === '')
|
|
94
99
|
parentUrl.pathname = syncPath;
|
|
95
100
|
else
|
|
96
101
|
parentUrl.pathname = new URL(path, new URL(syncPath, currentParentHref)).pathname;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@data-fair/frame",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.3",
|
|
4
4
|
"description": "An iframe wrapper for powerful web app integrations.",
|
|
5
5
|
"main": "dist/frame.min.js",
|
|
6
6
|
"directories": {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"dev-zellij": "zellij --layout .zellij.kdl",
|
|
25
25
|
"prepare": "husky",
|
|
26
26
|
"test": "node --test tests/*.js",
|
|
27
|
+
"test:only": "node --test --test-only tests/*.js",
|
|
27
28
|
"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 && vite -c vite.config.v-iframe-compat-d-frame-content.js build",
|
|
28
29
|
"prepublishOnly": "npm run lint && npm run test && npm run build",
|
|
29
30
|
"publish:main": "cd doc && npm run build:main && cd .. && gh-pages-multi deploy -v -s doc/.output/public -t main",
|