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