@data-fair/frame 0.6.0 → 0.7.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 +6 -1
- package/lib/DFrameElement.js +83 -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,d,f)=>d in l?H(l,d,{enumerable:!0,configurable:!0,writable:!0,value:f}):l[d]=f;var n=(l,d,f)=>x(l,typeof d!="symbol"?d+"":d,f);(function(){"use strict";function l(e){return e[0]==="df-child"&&e[1]==="init"}function d(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 w(e){return e.endsWith("/")?e:e===""?"/":e.slice(0,e.lastIndexOf("/")+1)}function E(e,a){if(a.origin!==e.origin)return a.href;if(a.pathname===e.pathname)return"";const t=w(e.pathname);return a.pathname.startsWith(t)?a.pathname.replace(t,"./"):a.pathname}const A=e=>e.replace(/[-[\]/{}()*+?.\\^$|]/g,"\\$&");function 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,u)=>{for(const h of t){if(h.append&&!u.startsWith(h.append)||u===s)continue;const o=h.append?u.replace(h.append,""):u;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),u=new URL(a);if(s&&(r.searchParams.forEach((h,o)=>{for(const c of s){if(c.append&&!o.startsWith(c.append))continue;const g=c.append?o.replace(c.append,""):o;if(g.match(c.regexp)){u.searchParams.get(g)===null&&r.searchParams.delete(o);break}}}),u.searchParams.forEach((h,o)=>{for(const c of s){if(!o.match(c.regexp)||(e==null?void 0:e.searchParams.get(o))===h)continue;const g=c.append?c.append+o:o;r.searchParams.set(g,h);break}})),i!==null&&e){const h=E(e,u);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" frameborder="0" 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);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()),d(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()))}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()}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(),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,22 @@ 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;
|
|
38
43
|
get actualAspectRatio(): number;
|
|
39
44
|
constructor();
|
|
40
45
|
onMessage(e: MessageEvent): 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" frameborder="0" 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,28 @@ 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;
|
|
112
125
|
get actualAspectRatio() {
|
|
113
126
|
if (this.aspectRatio !== 'auto')
|
|
114
127
|
return Number(this.aspectRatio);
|
|
@@ -124,12 +137,23 @@ export default class DFrameElement extends HTMLElement {
|
|
|
124
137
|
super();
|
|
125
138
|
this.randomId = Math.random().toString(36).slice(-6);
|
|
126
139
|
const root = template.content.cloneNode(true);
|
|
127
|
-
this.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
this.iframeElement = root.childNodes[2];
|
|
140
|
+
this.wrapperElement = root.childNodes[1];
|
|
141
|
+
this.slotElement = this.wrapperElement.childNodes[0];
|
|
142
|
+
this.iframeElement = this.wrapperElement.childNodes[1];
|
|
131
143
|
this.iframeElement.setAttribute('scrolling', this.resize === 'yes' ? 'no' : 'auto');
|
|
132
144
|
this.iframeElement.setAttribute('loading', this.lazy ? 'lazy' : 'eager');
|
|
145
|
+
this.iframeElement.addEventListener('load', () => {
|
|
146
|
+
if (this.iframeElement.getAttribute('src')) {
|
|
147
|
+
this.log('debug', 'iframe loaded');
|
|
148
|
+
this.iframeLoaded = true;
|
|
149
|
+
this.dispatchEvent(new CustomEvent('iframe-load'));
|
|
150
|
+
if (this.resize !== 'yes' && !this.readyMessage) {
|
|
151
|
+
this.ready = true;
|
|
152
|
+
this.dispatchEvent(new CustomEvent('ready'));
|
|
153
|
+
this.updateStyle();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
});
|
|
133
157
|
const shadowRoot = this.attachShadow({ mode: 'open' });
|
|
134
158
|
shadowRoot.appendChild(root);
|
|
135
159
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
@@ -162,6 +186,10 @@ export default class DFrameElement extends HTMLElement {
|
|
|
162
186
|
}
|
|
163
187
|
if (isHeightMessage(message)) {
|
|
164
188
|
this.resizedHeight = message[2];
|
|
189
|
+
if (this.resize === 'yes' && !this.ready && !this.readyMessage) {
|
|
190
|
+
this.ready = true;
|
|
191
|
+
this.dispatchEvent(new CustomEvent('ready'));
|
|
192
|
+
}
|
|
165
193
|
this.updateStyle();
|
|
166
194
|
}
|
|
167
195
|
if (isStateChangeMessage(message)) {
|
|
@@ -181,6 +209,11 @@ export default class DFrameElement extends HTMLElement {
|
|
|
181
209
|
if (isNotifMessage(message)) {
|
|
182
210
|
this.dispatchEvent(new CustomEvent('notif', { detail: message[2] }));
|
|
183
211
|
}
|
|
212
|
+
if (isReadyMessage(message)) {
|
|
213
|
+
this.ready = true;
|
|
214
|
+
this.dispatchEvent(new CustomEvent('ready'));
|
|
215
|
+
this.updateStyle();
|
|
216
|
+
}
|
|
184
217
|
}
|
|
185
218
|
else if (isVIframeUiNotif(message)) {
|
|
186
219
|
// maintain compatibility with v-iframe notifications sent through postMessage
|
|
@@ -212,51 +245,48 @@ export default class DFrameElement extends HTMLElement {
|
|
|
212
245
|
updateStyle() {
|
|
213
246
|
if (!this.connected)
|
|
214
247
|
return;
|
|
215
|
-
|
|
248
|
+
// manage height of iframe wrapper
|
|
249
|
+
let wrapperHeight;
|
|
250
|
+
if (this.resizedHeight) {
|
|
251
|
+
this.log('debug', 'height of iframe based on resize message: ' + this.resizedHeight);
|
|
252
|
+
wrapperHeight = this.resizedHeight + 'px';
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
if (this.height) {
|
|
256
|
+
this.log('debug', 'height of iframe based on direct attribute: ' + this.height);
|
|
257
|
+
wrapperHeight = this.height;
|
|
258
|
+
}
|
|
259
|
+
else if (this.aspectRatio !== null) {
|
|
260
|
+
this.log('debug', 'height of iframe based on aspect ratio: ' + this.aspectRatioHeight);
|
|
261
|
+
wrapperHeight = this.aspectRatioHeight + 'px';
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (wrapperHeight !== undefined) {
|
|
265
|
+
this.log('debug', 'set height iframe wrapper: ' + wrapperHeight);
|
|
266
|
+
this.wrapperElement.setAttribute('style', `height:${wrapperHeight};min-height:0;`);
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
this.wrapperElement.setAttribute('style', '');
|
|
270
|
+
}
|
|
271
|
+
// set scrolling attribute of iframe
|
|
216
272
|
if (this.resize === 'yes' || (this.resize === 'auto' && this.resizedHeight)) {
|
|
217
273
|
if (this.iframeElement.getAttribute('scrolling') !== 'no') {
|
|
218
274
|
this.log('debug', 'set scrolling attribute of iframe: no');
|
|
219
275
|
this.iframeElement.setAttribute('scrolling', 'no');
|
|
220
276
|
}
|
|
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
277
|
}
|
|
244
|
-
|
|
278
|
+
else {
|
|
245
279
|
if (this.iframeElement.getAttribute('scrolling') !== 'auto') {
|
|
246
280
|
this.log('debug', 'set scrolling attribute of iframe: auto');
|
|
247
281
|
this.iframeElement.setAttribute('scrolling', 'auto');
|
|
248
282
|
}
|
|
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
283
|
}
|
|
258
|
-
|
|
259
|
-
this.iframeElement.
|
|
284
|
+
// toggle loading slot vs iframe visibility
|
|
285
|
+
if (this.ready && this.iframeElement.getAttribute('style') !== '') {
|
|
286
|
+
this.log('debug', 'toggle loading slot and iframe visibility');
|
|
287
|
+
this.iframeElement.setAttribute('style', '');
|
|
288
|
+
this.slotElement.setAttribute('style', 'display:none;');
|
|
289
|
+
}
|
|
260
290
|
}
|
|
261
291
|
updateAspectRatioHeight() {
|
|
262
292
|
if (!this.width)
|
|
@@ -274,15 +304,22 @@ export default class DFrameElement extends HTMLElement {
|
|
|
274
304
|
if (level === 'debug' && !this.debug)
|
|
275
305
|
return;
|
|
276
306
|
if (level === 'debug')
|
|
277
|
-
console.timeLog(
|
|
278
|
-
// if (level === 'debug') console.debug(`${this.id}:d-frame`, ...args)
|
|
307
|
+
console.timeLog(`d-frame:${this.id}`, ...args);
|
|
279
308
|
if (level === 'info')
|
|
280
|
-
console.info(
|
|
309
|
+
console.info(`d-frame:${this.id}`, ...args);
|
|
281
310
|
}
|
|
282
311
|
/* standard custom element callbacks */
|
|
283
312
|
connectedCallback() {
|
|
313
|
+
if (!this.debug) {
|
|
314
|
+
const globalDebug = window.localStorage.getItem('debug');
|
|
315
|
+
if (globalDebug) {
|
|
316
|
+
const debugParts = globalDebug.split(',');
|
|
317
|
+
if (debugParts.includes('d-frame') || debugParts.includes('d-frame:' + this.id))
|
|
318
|
+
this.debug = true;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
284
321
|
if (this.debug)
|
|
285
|
-
console.time(
|
|
322
|
+
console.time(`d-frame:${this.id}`);
|
|
286
323
|
if (!this.hasAttribute('src'))
|
|
287
324
|
throw new Error('src is a required attribute');
|
|
288
325
|
this.log('debug', 'connected');
|
|
@@ -298,7 +335,7 @@ export default class DFrameElement extends HTMLElement {
|
|
|
298
335
|
disconnectedCallback() {
|
|
299
336
|
this.log('debug', 'disconnected');
|
|
300
337
|
if (this.debug)
|
|
301
|
-
console.timeEnd(`
|
|
338
|
+
console.timeEnd(`d-frame:${this.id}`);
|
|
302
339
|
// TODO: more cleanup (resize observer, etc)
|
|
303
340
|
}
|
|
304
341
|
/* reflected attributes */
|
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);
|