@open-iframe-resizer/core 1.0.0-rc1
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/child.d.ts +2 -0
- package/dist/common.d.ts +12 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +112 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.cjs +2 -0
- package/dist/index.umd.cjs.map +1 -0
- package/dist/parent.d.ts +3 -0
- package/dist/type.d.ts +21 -0
- package/package.json +46 -0
package/dist/child.d.ts
ADDED
package/dist/common.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Settings } from './type';
|
|
2
|
+
declare const isInIframe: () => boolean;
|
|
3
|
+
declare const isSameOriginIframe: (iframe: HTMLIFrameElement) => iframe is HTMLIFrameElement & {
|
|
4
|
+
contentDocument: Document;
|
|
5
|
+
};
|
|
6
|
+
declare const isHtmlIframeElement: (element: Element) => element is HTMLIFrameElement;
|
|
7
|
+
declare const deferWhenDomContentIsLoaded: (document: Document, executable: () => void) => void;
|
|
8
|
+
declare const deferWhenPageIsLoaded: (document: Document, executable: () => void) => void;
|
|
9
|
+
declare const getDefaultSettings: () => Settings;
|
|
10
|
+
declare const isIframeSameOrigin: (iframe: HTMLIFrameElement) => boolean;
|
|
11
|
+
declare function debounce<T extends (...args: any[]) => any>(f: T, delay: number): (...args: unknown[]) => void;
|
|
12
|
+
export { isInIframe, isSameOriginIframe, deferWhenDomContentIsLoaded, isHtmlIframeElement, deferWhenPageIsLoaded, isIframeSameOrigin, debounce, getDefaultSettings, };
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
const w = () => window && window.self !== window.top, l = (e) => e instanceof HTMLIFrameElement, b = () => ({ offsetSize: 0, checkOrigin: !0 }), y = (e) => {
|
|
2
|
+
try {
|
|
3
|
+
return new URL(e.src, window.location.origin).origin === window.location.origin;
|
|
4
|
+
} catch {
|
|
5
|
+
return !1;
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
function m(e, t) {
|
|
9
|
+
let n;
|
|
10
|
+
return (...i) => {
|
|
11
|
+
clearTimeout(n), n = setTimeout(() => e.apply(void 0, i), t);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
const f = I(), d = [], S = (e, t) => {
|
|
15
|
+
const n = { ...b(), ...e }, i = O(t), r = v(n, i);
|
|
16
|
+
return i.map((c) => {
|
|
17
|
+
const o = d.push({ iframe: c, settings: n }), s = p(c, n, r);
|
|
18
|
+
return {
|
|
19
|
+
unsubscribe: () => {
|
|
20
|
+
s(), d.splice(o - 1, 1);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
function O(e) {
|
|
26
|
+
return typeof e == "string" ? Array.from(document.querySelectorAll(e)).filter(l) : e ? l(e) ? [e] : [] : Array.from(document.getElementsByTagName("iframe"));
|
|
27
|
+
}
|
|
28
|
+
function v(e, t) {
|
|
29
|
+
if (Array.isArray(e.checkOrigin))
|
|
30
|
+
return e.checkOrigin;
|
|
31
|
+
if (!e.checkOrigin)
|
|
32
|
+
return [];
|
|
33
|
+
const n = [];
|
|
34
|
+
for (const i of t) {
|
|
35
|
+
const r = z(i);
|
|
36
|
+
r && n.push(r);
|
|
37
|
+
}
|
|
38
|
+
return n;
|
|
39
|
+
}
|
|
40
|
+
function z(e) {
|
|
41
|
+
try {
|
|
42
|
+
const t = new URL(e.src).origin;
|
|
43
|
+
if (t !== "about:blank")
|
|
44
|
+
return t;
|
|
45
|
+
} catch {
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
function p(e, t, n) {
|
|
50
|
+
return y(e) ? E(e) : L(e, t, n);
|
|
51
|
+
}
|
|
52
|
+
function L(e, t, n) {
|
|
53
|
+
const i = (r) => {
|
|
54
|
+
var o;
|
|
55
|
+
if ((!t.checkOrigin || n.includes(r.origin)) && ((o = r.data) == null ? void 0 : o.type) === "iframe-resized" && e.contentWindow === r.source) {
|
|
56
|
+
const { width: s, height: a } = r.data;
|
|
57
|
+
g({ width: s, height: a, iframe: e, settings: t });
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return window.addEventListener("message", i, !1), () => window.removeEventListener("message", i, !1);
|
|
61
|
+
}
|
|
62
|
+
function E(e) {
|
|
63
|
+
const t = () => {
|
|
64
|
+
var i;
|
|
65
|
+
const n = (i = e.contentDocument) == null ? void 0 : i.body;
|
|
66
|
+
if (!n) {
|
|
67
|
+
console.error("Unable to observe the iframe content document body");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
f.observe(n);
|
|
71
|
+
};
|
|
72
|
+
return e.addEventListener("load", t), () => {
|
|
73
|
+
var n;
|
|
74
|
+
(n = e.contentDocument) != null && n.body && f.unobserve(e.contentDocument.body), e.removeEventListener("load", t);
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function I() {
|
|
78
|
+
const e = ({ target: n }) => {
|
|
79
|
+
var a;
|
|
80
|
+
const i = d.find((h) => {
|
|
81
|
+
var u;
|
|
82
|
+
return ((u = h.iframe.contentDocument) == null ? void 0 : u.body) === n;
|
|
83
|
+
});
|
|
84
|
+
if (!i)
|
|
85
|
+
return;
|
|
86
|
+
const { iframe: r, settings: c } = i, { scrollHeight: o, scrollWidth: s } = ((a = r.contentDocument) == null ? void 0 : a.documentElement) ?? {};
|
|
87
|
+
o !== void 0 && s !== void 0 && g({ width: s, height: o, iframe: r, settings: c });
|
|
88
|
+
}, t = m((n) => n.forEach(e), 10);
|
|
89
|
+
return new ResizeObserver(t);
|
|
90
|
+
}
|
|
91
|
+
function g({ width: e, height: t, iframe: n, settings: i }) {
|
|
92
|
+
n.style.width = `${e}px`, n.style.height = `${t + i.offsetSize}px`;
|
|
93
|
+
}
|
|
94
|
+
w() && R();
|
|
95
|
+
function R() {
|
|
96
|
+
window.addEventListener("load", () => {
|
|
97
|
+
const e = m(() => {
|
|
98
|
+
const n = {
|
|
99
|
+
type: "iframe-resized",
|
|
100
|
+
width: document.documentElement.scrollWidth,
|
|
101
|
+
height: document.documentElement.scrollHeight
|
|
102
|
+
};
|
|
103
|
+
window.parent.postMessage(n, "*");
|
|
104
|
+
}, 10);
|
|
105
|
+
new ResizeObserver(e).observe(document.body);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
export {
|
|
109
|
+
S as initialize,
|
|
110
|
+
R as initializeChildListener
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/common.ts","../src/parent.ts","../src/child.ts"],"sourcesContent":["import type { Settings } from \"~/type\";\n\nconst isInIframe = () => window && window.self !== window.top;\n\nconst isSameOriginIframe = (iframe: HTMLIFrameElement): iframe is HTMLIFrameElement & { contentDocument: Document } => !!iframe.contentDocument;\n\nconst isHtmlIframeElement = (element: Element): element is HTMLIFrameElement => element instanceof HTMLIFrameElement;\n\nconst deferWhenDomContentIsLoaded = (document: Document, executable: () => void) => {\n\tdocument.readyState === \"loading\" ? document.addEventListener(\"DOMContentLoaded\", executable) : executable();\n};\n\nconst deferWhenPageIsLoaded = (document: Document, executable: () => void) => {\n\tdocument.readyState !== \"complete\" ? document.addEventListener(\"load\", executable) : executable();\n};\n\nconst getDefaultSettings: () => Settings = () => ({ offsetSize: 0, checkOrigin: true });\n\nconst isIframeSameOrigin = (iframe: HTMLIFrameElement) => {\n\ttry {\n\t\tconst iframeSrc = new URL(iframe.src, window.location.origin);\n\t\treturn iframeSrc.origin === window.location.origin;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\n// biome-ignore lint/suspicious/noExplicitAny:\nfunction debounce<T extends (...args: any[]) => any>(f: T, delay: number) {\n\tlet timer: NodeJS.Timeout;\n\treturn (...args: unknown[]) => {\n\t\tclearTimeout(timer);\n\t\ttimer = setTimeout(() => f.apply(undefined, args), delay);\n\t};\n}\n\nexport {\n\tisInIframe,\n\tisSameOriginIframe,\n\tdeferWhenDomContentIsLoaded,\n\tisHtmlIframeElement,\n\tdeferWhenPageIsLoaded,\n\tisIframeSameOrigin,\n\tdebounce,\n\tgetDefaultSettings,\n};\n","import { debounce, getDefaultSettings, isHtmlIframeElement, isIframeSameOrigin } from \"~/common\";\nimport type { IframeResizeEvent, InitializeFunction, Settings } from \"./type\";\n\nconst resizeObserver = createResizeObserver();\nconst registeredIframes: Array<{ iframe: HTMLIFrameElement; settings: Settings }> = [];\n\nconst initialize: InitializeFunction = (clientSettings, selector) => {\n\tconst finalSettings = { ...getDefaultSettings(), ...clientSettings };\n\tconst iframes = resolveIframesToRegister(selector);\n\tconst allowedOrigins = registerIframesAllowOrigins(finalSettings, iframes);\n\n\treturn iframes.map((iframe) => {\n\t\tconst length = registeredIframes.push({ iframe, settings: finalSettings });\n\t\tconst unsubscribeResizeListener = addChildResizeListener(iframe, finalSettings, allowedOrigins);\n\t\treturn {\n\t\t\tunsubscribe: () => {\n\t\t\t\tunsubscribeResizeListener();\n\t\t\t\tregisteredIframes.splice(length - 1, 1);\n\t\t\t},\n\t\t};\n\t});\n};\n\nfunction resolveIframesToRegister(selector?: string | HTMLIFrameElement): HTMLIFrameElement[] {\n\tif (typeof selector === \"string\") {\n\t\treturn Array.from(document.querySelectorAll<HTMLElement>(selector)).filter(isHtmlIframeElement);\n\t}\n\tif (selector) {\n\t\treturn isHtmlIframeElement(selector) ? [selector] : [];\n\t}\n\treturn Array.from(document.getElementsByTagName(\"iframe\"));\n}\n\nfunction registerIframesAllowOrigins(settings: Settings, iframes: HTMLIFrameElement[]) {\n\tif (Array.isArray(settings.checkOrigin)) {\n\t\treturn settings.checkOrigin;\n\t}\n\n\tif (!settings.checkOrigin) {\n\t\treturn [];\n\t}\n\n\tconst allowedOrigins: string[] = [];\n\tfor (const iframe of iframes) {\n\t\tconst origin = extractIframeOrigin(iframe);\n\t\tif (origin) {\n\t\t\tallowedOrigins.push(origin);\n\t\t}\n\t}\n\treturn allowedOrigins;\n}\n\nfunction extractIframeOrigin(iframe: HTMLIFrameElement): string | null {\n\ttry {\n\t\tconst origin = new URL(iframe.src).origin;\n\t\tif (origin !== \"about:blank\") {\n\t\t\treturn origin;\n\t\t}\n\t} catch (error) {}\n\treturn null;\n}\n\nfunction addChildResizeListener(iframe: HTMLIFrameElement, settings: Settings, allowedOrigins: string[]) {\n\tif (isIframeSameOrigin(iframe)) {\n\t\treturn addSameOriginChildResizeListener(iframe);\n\t}\n\treturn addCrossOriginChildResizeListener(iframe, settings, allowedOrigins);\n}\n\nfunction addCrossOriginChildResizeListener(iframe: HTMLIFrameElement, settings: Settings, allowedOrigins: string[]) {\n\tconst handleIframeResizedMessage = (event: MessageEvent) => {\n\t\tconst isOriginValid = !settings.checkOrigin || allowedOrigins.includes(event.origin);\n\n\t\tif (isOriginValid && event.data?.type === \"iframe-resized\" && iframe.contentWindow === event.source) {\n\t\t\tconst { width, height } = (event as IframeResizeEvent).data;\n\t\t\tupdateIframeDimensions({ width, height, iframe, settings });\n\t\t}\n\t};\n\n\twindow.addEventListener(\"message\", handleIframeResizedMessage, false);\n\n\treturn () => window.removeEventListener(\"message\", handleIframeResizedMessage, false);\n}\n\nfunction addSameOriginChildResizeListener(iframe: HTMLIFrameElement) {\n\tconst startListener = () => {\n\t\tconst contentBody = iframe.contentDocument?.body;\n\n\t\tif (!contentBody) {\n\t\t\tconsole.error(\"Unable to observe the iframe content document body\");\n\t\t\treturn;\n\t\t}\n\n\t\tresizeObserver.observe(contentBody);\n\t};\n\n\tiframe.addEventListener(\"load\", startListener);\n\n\treturn () => {\n\t\tif (iframe.contentDocument?.body) {\n\t\t\tresizeObserver.unobserve(iframe.contentDocument.body);\n\t\t}\n\t\tiframe.removeEventListener(\"load\", startListener);\n\t};\n}\n\nfunction createResizeObserver() {\n\tconst handleEntry = ({ target }: ResizeObserverEntry) => {\n\t\tconst matchingRegisteredIframe = registeredIframes.find((value) => value.iframe.contentDocument?.body === target);\n\t\tif (!matchingRegisteredIframe) {\n\t\t\treturn;\n\t\t}\n\t\tconst { iframe, settings } = matchingRegisteredIframe;\n\t\tconst { scrollHeight, scrollWidth } = iframe.contentDocument?.documentElement ?? {};\n\t\tif (scrollHeight !== undefined && scrollWidth !== undefined) {\n\t\t\tupdateIframeDimensions({ width: scrollWidth, height: scrollHeight, iframe, settings });\n\t\t}\n\t};\n\n\tconst resizeObserverCallback = debounce<ResizeObserverCallback>((entries) => entries.forEach(handleEntry), 10);\n\treturn new ResizeObserver(resizeObserverCallback);\n}\n\nfunction updateIframeDimensions({ width, height, iframe, settings }: { iframe: HTMLIFrameElement; width: number; height: number; settings: Settings }) {\n\tiframe.style.width = `${width}px`;\n\tiframe.style.height = `${height + settings.offsetSize}px`;\n}\n\nexport { initialize };\n","import { debounce, isInIframe } from \"~/common\";\nimport type { IframeResizeEventData } from \"./type\";\n\nif (isInIframe()) {\n\tinitializeChildListener();\n}\n\nfunction initializeChildListener() {\n\twindow.addEventListener(\"load\", () => {\n\t\tconst resizeObserverCallback = debounce<ResizeObserverCallback>(() => {\n\t\t\tconst data: IframeResizeEventData = {\n\t\t\t\ttype: \"iframe-resized\",\n\t\t\t\twidth: document.documentElement.scrollWidth,\n\t\t\t\theight: document.documentElement.scrollHeight,\n\t\t\t};\n\t\t\twindow.parent.postMessage(data, \"*\");\n\t\t}, 10);\n\n\t\tconst resizeObserver = new ResizeObserver(resizeObserverCallback);\n\t\tresizeObserver.observe(document.body);\n\t});\n}\n\nexport { initializeChildListener };\n"],"names":["isInIframe","isHtmlIframeElement","element","getDefaultSettings","isIframeSameOrigin","iframe","debounce","f","delay","timer","args","resizeObserver","createResizeObserver","registeredIframes","initialize","clientSettings","selector","finalSettings","iframes","resolveIframesToRegister","allowedOrigins","registerIframesAllowOrigins","length","unsubscribeResizeListener","addChildResizeListener","settings","origin","extractIframeOrigin","addSameOriginChildResizeListener","addCrossOriginChildResizeListener","handleIframeResizedMessage","event","_a","width","height","updateIframeDimensions","startListener","contentBody","handleEntry","target","matchingRegisteredIframe","value","scrollHeight","scrollWidth","resizeObserverCallback","entries","initializeChildListener","data"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(o,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(o=typeof globalThis<"u"?globalThis:o||self,d(o.iframeResizer={}))})(this,function(o){"use strict";const d=()=>window&&window.self!==window.top,f=e=>e instanceof HTMLIFrameElement,y=()=>({offsetSize:0,checkOrigin:!0}),O=e=>{try{return new URL(e.src,window.location.origin).origin===window.location.origin}catch{return!1}};function m(e,i){let n;return(...t)=>{clearTimeout(n),n=setTimeout(()=>e.apply(void 0,t),i)}}const g=S(),l=[],z=(e,i)=>{const n={...y(),...e},t=p(i),r=v(n,t);return t.map(a=>{const s=l.push({iframe:a,settings:n}),c=E(a,n,r);return{unsubscribe:()=>{c(),l.splice(s-1,1)}}})};function p(e){return typeof e=="string"?Array.from(document.querySelectorAll(e)).filter(f):e?f(e)?[e]:[]:Array.from(document.getElementsByTagName("iframe"))}function v(e,i){if(Array.isArray(e.checkOrigin))return e.checkOrigin;if(!e.checkOrigin)return[];const n=[];for(const t of i){const r=L(t);r&&n.push(r)}return n}function L(e){try{const i=new URL(e.src).origin;if(i!=="about:blank")return i}catch{}return null}function E(e,i,n){return O(e)?I(e):R(e,i,n)}function R(e,i,n){const t=r=>{var s;if((!i.checkOrigin||n.includes(r.origin))&&((s=r.data)==null?void 0:s.type)==="iframe-resized"&&e.contentWindow===r.source){const{width:c,height:u}=r.data;h({width:c,height:u,iframe:e,settings:i})}};return window.addEventListener("message",t,!1),()=>window.removeEventListener("message",t,!1)}function I(e){const i=()=>{var t;const n=(t=e.contentDocument)==null?void 0:t.body;if(!n){console.error("Unable to observe the iframe content document body");return}g.observe(n)};return e.addEventListener("load",i),()=>{var n;(n=e.contentDocument)!=null&&n.body&&g.unobserve(e.contentDocument.body),e.removeEventListener("load",i)}}function S(){const e=({target:n})=>{var u;const t=l.find(k=>{var w;return((w=k.iframe.contentDocument)==null?void 0:w.body)===n});if(!t)return;const{iframe:r,settings:a}=t,{scrollHeight:s,scrollWidth:c}=((u=r.contentDocument)==null?void 0:u.documentElement)??{};s!==void 0&&c!==void 0&&h({width:c,height:s,iframe:r,settings:a})},i=m(n=>n.forEach(e),10);return new ResizeObserver(i)}function h({width:e,height:i,iframe:n,settings:t}){n.style.width=`${e}px`,n.style.height=`${i+t.offsetSize}px`}d()&&b();function b(){window.addEventListener("load",()=>{const e=m(()=>{const n={type:"iframe-resized",width:document.documentElement.scrollWidth,height:document.documentElement.scrollHeight};window.parent.postMessage(n,"*")},10);new ResizeObserver(e).observe(document.body)})}o.initialize=z,o.initializeChildListener=b,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})});
|
|
2
|
+
//# sourceMappingURL=index.umd.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.cjs","sources":["../src/common.ts","../src/parent.ts","../src/child.ts"],"sourcesContent":["import type { Settings } from \"~/type\";\n\nconst isInIframe = () => window && window.self !== window.top;\n\nconst isSameOriginIframe = (iframe: HTMLIFrameElement): iframe is HTMLIFrameElement & { contentDocument: Document } => !!iframe.contentDocument;\n\nconst isHtmlIframeElement = (element: Element): element is HTMLIFrameElement => element instanceof HTMLIFrameElement;\n\nconst deferWhenDomContentIsLoaded = (document: Document, executable: () => void) => {\n\tdocument.readyState === \"loading\" ? document.addEventListener(\"DOMContentLoaded\", executable) : executable();\n};\n\nconst deferWhenPageIsLoaded = (document: Document, executable: () => void) => {\n\tdocument.readyState !== \"complete\" ? document.addEventListener(\"load\", executable) : executable();\n};\n\nconst getDefaultSettings: () => Settings = () => ({ offsetSize: 0, checkOrigin: true });\n\nconst isIframeSameOrigin = (iframe: HTMLIFrameElement) => {\n\ttry {\n\t\tconst iframeSrc = new URL(iframe.src, window.location.origin);\n\t\treturn iframeSrc.origin === window.location.origin;\n\t} catch (e) {\n\t\treturn false;\n\t}\n};\n\n// biome-ignore lint/suspicious/noExplicitAny:\nfunction debounce<T extends (...args: any[]) => any>(f: T, delay: number) {\n\tlet timer: NodeJS.Timeout;\n\treturn (...args: unknown[]) => {\n\t\tclearTimeout(timer);\n\t\ttimer = setTimeout(() => f.apply(undefined, args), delay);\n\t};\n}\n\nexport {\n\tisInIframe,\n\tisSameOriginIframe,\n\tdeferWhenDomContentIsLoaded,\n\tisHtmlIframeElement,\n\tdeferWhenPageIsLoaded,\n\tisIframeSameOrigin,\n\tdebounce,\n\tgetDefaultSettings,\n};\n","import { debounce, getDefaultSettings, isHtmlIframeElement, isIframeSameOrigin } from \"~/common\";\nimport type { IframeResizeEvent, InitializeFunction, Settings } from \"./type\";\n\nconst resizeObserver = createResizeObserver();\nconst registeredIframes: Array<{ iframe: HTMLIFrameElement; settings: Settings }> = [];\n\nconst initialize: InitializeFunction = (clientSettings, selector) => {\n\tconst finalSettings = { ...getDefaultSettings(), ...clientSettings };\n\tconst iframes = resolveIframesToRegister(selector);\n\tconst allowedOrigins = registerIframesAllowOrigins(finalSettings, iframes);\n\n\treturn iframes.map((iframe) => {\n\t\tconst length = registeredIframes.push({ iframe, settings: finalSettings });\n\t\tconst unsubscribeResizeListener = addChildResizeListener(iframe, finalSettings, allowedOrigins);\n\t\treturn {\n\t\t\tunsubscribe: () => {\n\t\t\t\tunsubscribeResizeListener();\n\t\t\t\tregisteredIframes.splice(length - 1, 1);\n\t\t\t},\n\t\t};\n\t});\n};\n\nfunction resolveIframesToRegister(selector?: string | HTMLIFrameElement): HTMLIFrameElement[] {\n\tif (typeof selector === \"string\") {\n\t\treturn Array.from(document.querySelectorAll<HTMLElement>(selector)).filter(isHtmlIframeElement);\n\t}\n\tif (selector) {\n\t\treturn isHtmlIframeElement(selector) ? [selector] : [];\n\t}\n\treturn Array.from(document.getElementsByTagName(\"iframe\"));\n}\n\nfunction registerIframesAllowOrigins(settings: Settings, iframes: HTMLIFrameElement[]) {\n\tif (Array.isArray(settings.checkOrigin)) {\n\t\treturn settings.checkOrigin;\n\t}\n\n\tif (!settings.checkOrigin) {\n\t\treturn [];\n\t}\n\n\tconst allowedOrigins: string[] = [];\n\tfor (const iframe of iframes) {\n\t\tconst origin = extractIframeOrigin(iframe);\n\t\tif (origin) {\n\t\t\tallowedOrigins.push(origin);\n\t\t}\n\t}\n\treturn allowedOrigins;\n}\n\nfunction extractIframeOrigin(iframe: HTMLIFrameElement): string | null {\n\ttry {\n\t\tconst origin = new URL(iframe.src).origin;\n\t\tif (origin !== \"about:blank\") {\n\t\t\treturn origin;\n\t\t}\n\t} catch (error) {}\n\treturn null;\n}\n\nfunction addChildResizeListener(iframe: HTMLIFrameElement, settings: Settings, allowedOrigins: string[]) {\n\tif (isIframeSameOrigin(iframe)) {\n\t\treturn addSameOriginChildResizeListener(iframe);\n\t}\n\treturn addCrossOriginChildResizeListener(iframe, settings, allowedOrigins);\n}\n\nfunction addCrossOriginChildResizeListener(iframe: HTMLIFrameElement, settings: Settings, allowedOrigins: string[]) {\n\tconst handleIframeResizedMessage = (event: MessageEvent) => {\n\t\tconst isOriginValid = !settings.checkOrigin || allowedOrigins.includes(event.origin);\n\n\t\tif (isOriginValid && event.data?.type === \"iframe-resized\" && iframe.contentWindow === event.source) {\n\t\t\tconst { width, height } = (event as IframeResizeEvent).data;\n\t\t\tupdateIframeDimensions({ width, height, iframe, settings });\n\t\t}\n\t};\n\n\twindow.addEventListener(\"message\", handleIframeResizedMessage, false);\n\n\treturn () => window.removeEventListener(\"message\", handleIframeResizedMessage, false);\n}\n\nfunction addSameOriginChildResizeListener(iframe: HTMLIFrameElement) {\n\tconst startListener = () => {\n\t\tconst contentBody = iframe.contentDocument?.body;\n\n\t\tif (!contentBody) {\n\t\t\tconsole.error(\"Unable to observe the iframe content document body\");\n\t\t\treturn;\n\t\t}\n\n\t\tresizeObserver.observe(contentBody);\n\t};\n\n\tiframe.addEventListener(\"load\", startListener);\n\n\treturn () => {\n\t\tif (iframe.contentDocument?.body) {\n\t\t\tresizeObserver.unobserve(iframe.contentDocument.body);\n\t\t}\n\t\tiframe.removeEventListener(\"load\", startListener);\n\t};\n}\n\nfunction createResizeObserver() {\n\tconst handleEntry = ({ target }: ResizeObserverEntry) => {\n\t\tconst matchingRegisteredIframe = registeredIframes.find((value) => value.iframe.contentDocument?.body === target);\n\t\tif (!matchingRegisteredIframe) {\n\t\t\treturn;\n\t\t}\n\t\tconst { iframe, settings } = matchingRegisteredIframe;\n\t\tconst { scrollHeight, scrollWidth } = iframe.contentDocument?.documentElement ?? {};\n\t\tif (scrollHeight !== undefined && scrollWidth !== undefined) {\n\t\t\tupdateIframeDimensions({ width: scrollWidth, height: scrollHeight, iframe, settings });\n\t\t}\n\t};\n\n\tconst resizeObserverCallback = debounce<ResizeObserverCallback>((entries) => entries.forEach(handleEntry), 10);\n\treturn new ResizeObserver(resizeObserverCallback);\n}\n\nfunction updateIframeDimensions({ width, height, iframe, settings }: { iframe: HTMLIFrameElement; width: number; height: number; settings: Settings }) {\n\tiframe.style.width = `${width}px`;\n\tiframe.style.height = `${height + settings.offsetSize}px`;\n}\n\nexport { initialize };\n","import { debounce, isInIframe } from \"~/common\";\nimport type { IframeResizeEventData } from \"./type\";\n\nif (isInIframe()) {\n\tinitializeChildListener();\n}\n\nfunction initializeChildListener() {\n\twindow.addEventListener(\"load\", () => {\n\t\tconst resizeObserverCallback = debounce<ResizeObserverCallback>(() => {\n\t\t\tconst data: IframeResizeEventData = {\n\t\t\t\ttype: \"iframe-resized\",\n\t\t\t\twidth: document.documentElement.scrollWidth,\n\t\t\t\theight: document.documentElement.scrollHeight,\n\t\t\t};\n\t\t\twindow.parent.postMessage(data, \"*\");\n\t\t}, 10);\n\n\t\tconst resizeObserver = new ResizeObserver(resizeObserverCallback);\n\t\tresizeObserver.observe(document.body);\n\t});\n}\n\nexport { initializeChildListener };\n"],"names":["isInIframe","isHtmlIframeElement","element","getDefaultSettings","isIframeSameOrigin","iframe","debounce","f","delay","timer","args","resizeObserver","createResizeObserver","registeredIframes","initialize","clientSettings","selector","finalSettings","iframes","resolveIframesToRegister","allowedOrigins","registerIframesAllowOrigins","length","unsubscribeResizeListener","addChildResizeListener","settings","origin","extractIframeOrigin","addSameOriginChildResizeListener","addCrossOriginChildResizeListener","handleIframeResizedMessage","event","_a","width","height","updateIframeDimensions","startListener","contentBody","handleEntry","target","matchingRegisteredIframe","value","scrollHeight","scrollWidth","resizeObserverCallback","entries","initializeChildListener","data"],"mappings":"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"}
|
package/dist/parent.d.ts
ADDED
package/dist/type.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
interface Window {
|
|
2
|
+
iframeResizer: {
|
|
3
|
+
initialize: InitializeFunction;
|
|
4
|
+
};
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type InitializeFunction = (settings?: Partial<Settings>, selector?: string | HTMLIFrameElement) => InitializeResult[];
|
|
8
|
+
export type InitializeResult = { unsubscribe: () => void };
|
|
9
|
+
|
|
10
|
+
export type Settings = {
|
|
11
|
+
offsetSize: number;
|
|
12
|
+
checkOrigin: string[] | boolean;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type IframeResizeEventData = {
|
|
16
|
+
type: "iframe-resized";
|
|
17
|
+
width: number;
|
|
18
|
+
height: number;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type IframeResizeEvent = MessageEvent<IframeResizeEventData>;
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@open-iframe-resizer/core",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "1.0.0-rc1",
|
|
5
|
+
"description": "An open iframe resizer library",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"iframe-resizer",
|
|
9
|
+
"iframe",
|
|
10
|
+
"resize"
|
|
11
|
+
],
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/Lemick/open-iframe-resizer.git"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./dist/index.cjs",
|
|
18
|
+
"module": "./dist/index.js",
|
|
19
|
+
"typings": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js",
|
|
24
|
+
"require": "./dist/index.cjs"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"docs": "npm run typedoc",
|
|
32
|
+
"lint": "biome lint ./src",
|
|
33
|
+
"build": "tsc && npm run lint && vite build && typedoc",
|
|
34
|
+
"build:watch": "vite build --watch && typedoc",
|
|
35
|
+
"build:usecases-html": "node scripts/generate-use-cases-html.js",
|
|
36
|
+
"dev": "concurrently \"vite build --watch\" \"npm run serve\"",
|
|
37
|
+
"serve": "concurrently \"vite --port 5550\" \"vite --port 5551\"",
|
|
38
|
+
"test": "npm run test:unit && npm run test:e2e",
|
|
39
|
+
"test:e2e": "npx playwright install --with-deps && npx playwright test",
|
|
40
|
+
"test:unit": "vitest run"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@microsoft/tsdoc": "^0.14.1",
|
|
44
|
+
"picocolors": "^1.0.1"
|
|
45
|
+
}
|
|
46
|
+
}
|