@pexip-engage-public/plugin 1.1.25-canary-20250708143730 → 1.1.25
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/CHANGELOG.md +7 -2
- package/dist/events/index.d.ts +0 -11
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +0 -2
- package/dist/events/index.js.map +1 -1
- package/dist/instance/PluginInstance.d.ts +1 -1
- package/dist/instance/PluginInstance.d.ts.map +1 -1
- package/dist/instance/PluginInstance.js +27 -30
- package/dist/instance/PluginInstance.js.map +1 -1
- package/dist/state/PluginState.schema.d.ts +6 -6
- package/package.json +9 -10
- package/src/@types/iframe-resizer.iframeResizer.d.ts +211 -0
- package/src/events/index.ts +0 -14
- package/src/instance/PluginInstance.ts +40 -42
- package/dist/resizer/api-resize-handlers.d.ts +0 -9
- package/dist/resizer/api-resize-handlers.d.ts.map +0 -1
- package/dist/resizer/api-resize-handlers.js +0 -12
- package/dist/resizer/api-resize-handlers.js.map +0 -1
- package/dist/resizer/child.d.ts +0 -12
- package/dist/resizer/child.d.ts.map +0 -1
- package/dist/resizer/child.js +0 -80
- package/dist/resizer/child.js.map +0 -1
- package/dist/resizer/common.d.ts +0 -27
- package/dist/resizer/common.d.ts.map +0 -1
- package/dist/resizer/common.js +0 -82
- package/dist/resizer/common.js.map +0 -1
- package/dist/resizer/index.d.ts +0 -2
- package/dist/resizer/index.d.ts.map +0 -1
- package/dist/resizer/index.js +0 -2
- package/dist/resizer/index.js.map +0 -1
- package/dist/resizer/parent.d.ts +0 -4
- package/dist/resizer/parent.d.ts.map +0 -1
- package/dist/resizer/parent.js +0 -185
- package/dist/resizer/parent.js.map +0 -1
- package/dist/resizer/types.d.ts +0 -101
- package/dist/resizer/types.d.ts.map +0 -1
- package/dist/resizer/types.js +0 -2
- package/dist/resizer/types.js.map +0 -1
- package/src/resizer/api-resize-handlers.ts +0 -17
- package/src/resizer/child.ts +0 -128
- package/src/resizer/common.ts +0 -117
- package/src/resizer/index.ts +0 -0
- package/src/resizer/parent.ts +0 -277
- package/src/resizer/types.ts +0 -108
package/dist/resizer/types.d.ts
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Automatically resize the selected iframes when their inner content grows.
|
|
3
|
-
* @param settings The settings for the selected iframes. The default settings properties are picked if empty.
|
|
4
|
-
* @param selector The selector for the iframe(s) or the HTMLIFrameElement to be resized. If empty, all document iframe elements will be selected.
|
|
5
|
-
* @returns A result array, which can be used to clean up the listeners if you often remove iframes from the document.
|
|
6
|
-
*/
|
|
7
|
-
export type InitializeFunction = (settings?: Partial<Settings>, selector?: string | HTMLIFrameElement) => InitializeResult[];
|
|
8
|
-
export type InitializeResult = {
|
|
9
|
-
unsubscribe: () => void;
|
|
10
|
-
};
|
|
11
|
-
export type Settings = {
|
|
12
|
-
/**
|
|
13
|
-
* Offset added to the resize size (in pixels).
|
|
14
|
-
*
|
|
15
|
-
* Default: `0`
|
|
16
|
-
*/
|
|
17
|
-
offsetSize: number;
|
|
18
|
-
/**
|
|
19
|
-
* Specifies whether to check the origin of incoming messages.
|
|
20
|
-
* Accepts an array of allowed origins or a boolean.
|
|
21
|
-
* If `true`, incoming messages are allowed from the origins of the registered iframes.
|
|
22
|
-
*
|
|
23
|
-
* Default: `true`
|
|
24
|
-
*/
|
|
25
|
-
checkOrigin: string[] | boolean;
|
|
26
|
-
/**
|
|
27
|
-
* By default, the root element observed for resizing is the <html> document.
|
|
28
|
-
* In more complex layouts, the scrolling container may be elsewhere.
|
|
29
|
-
* This setting allows you to customize the root element that should be observed for resize events.
|
|
30
|
-
*
|
|
31
|
-
* Default: `undefined`
|
|
32
|
-
*/
|
|
33
|
-
targetElementSelector?: string;
|
|
34
|
-
/**
|
|
35
|
-
* Customize the padding style of the iframe body.
|
|
36
|
-
*
|
|
37
|
-
* Default: `undefined`
|
|
38
|
-
*/
|
|
39
|
-
bodyPadding?: string;
|
|
40
|
-
/**
|
|
41
|
-
* Customize the margin style of the iframe body.
|
|
42
|
-
*
|
|
43
|
-
* Default: `undefined`
|
|
44
|
-
*/
|
|
45
|
-
bodyMargin?: string;
|
|
46
|
-
/**
|
|
47
|
-
* Called whenever the observed content size changes and the iframe is about to be resized.
|
|
48
|
-
* Return `false` to cancel the resize; returning `true` or nothing will allow it.
|
|
49
|
-
*
|
|
50
|
-
* Default: `undefined`
|
|
51
|
-
*/
|
|
52
|
-
onBeforeIframeResize?: (context: BeforeResizeContext) => boolean | undefined;
|
|
53
|
-
/**
|
|
54
|
-
* Listener that is called after the iframe has been resized.
|
|
55
|
-
* You can use a predefined handler like `updateParentScrollOnResize` or create your own custom handler.
|
|
56
|
-
*
|
|
57
|
-
* Default: `undefined`
|
|
58
|
-
*/
|
|
59
|
-
onIframeResize?: (context: ResizeContext) => void;
|
|
60
|
-
};
|
|
61
|
-
export type IframeResizeEventData = {
|
|
62
|
-
type: "iframe-resized";
|
|
63
|
-
width: number;
|
|
64
|
-
height?: number;
|
|
65
|
-
};
|
|
66
|
-
export type IframeChildInitEventData = {
|
|
67
|
-
type: "iframe-child-init";
|
|
68
|
-
targetElementSelector?: string;
|
|
69
|
-
bodyPadding?: string;
|
|
70
|
-
bodyMargin?: string;
|
|
71
|
-
};
|
|
72
|
-
export type IframeResizeEvent = MessageEvent<IframeResizeEventData>;
|
|
73
|
-
export type InteractionState = {
|
|
74
|
-
isHovered: boolean;
|
|
75
|
-
};
|
|
76
|
-
export type ResizeRenderState = {
|
|
77
|
-
rect: DOMRect;
|
|
78
|
-
};
|
|
79
|
-
export type ResizeContext = {
|
|
80
|
-
iframe: HTMLIFrameElement;
|
|
81
|
-
settings: Settings;
|
|
82
|
-
interactionState: InteractionState;
|
|
83
|
-
previousRenderState: ResizeRenderState;
|
|
84
|
-
nextRenderState: ResizeRenderState;
|
|
85
|
-
};
|
|
86
|
-
export type BeforeResizeContext = {
|
|
87
|
-
iframe: HTMLIFrameElement;
|
|
88
|
-
settings: Settings;
|
|
89
|
-
observedHeight: number;
|
|
90
|
-
};
|
|
91
|
-
export type RegisteredElement = {
|
|
92
|
-
iframe: HTMLIFrameElement;
|
|
93
|
-
settings: Settings;
|
|
94
|
-
interactionState: InteractionState;
|
|
95
|
-
initContext: {
|
|
96
|
-
isInitialized: boolean;
|
|
97
|
-
retryAttempts: number;
|
|
98
|
-
retryTimeoutId?: number;
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/resizer/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,KAClC,gBAAgB,EAAE,CAAC;AACxB,MAAM,MAAM,gBAAgB,GAAG;IAAE,WAAW,EAAE,MAAM,IAAI,CAAA;CAAE,CAAC;AAE3D,MAAM,MAAM,QAAQ,GAAG;IACrB;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAChC;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,GAAG,SAAS,CAAC;IAE7E;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;CACnD,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,YAAY,CAAC,qBAAqB,CAAC,CAAC;AAEpE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,mBAAmB,EAAE,iBAAiB,CAAC;IACvC,eAAe,EAAE,iBAAiB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,WAAW,EAAE;QAAE,aAAa,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzF,CAAC"}
|
package/dist/resizer/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/resizer/types.ts"],"names":[],"mappings":""}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { ResizeContext } from "./types.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Resize handler that scrolls to restore the iframe's position in the viewport as it was before the resize.
|
|
5
|
-
*
|
|
6
|
-
* *Note:* This behavior only triggers if the iframe currently has focus,
|
|
7
|
-
* in order to try to limit the number of scroll as it can affect the user experience.
|
|
8
|
-
*/
|
|
9
|
-
export const updateParentScrollOnResize = ({
|
|
10
|
-
previousRenderState,
|
|
11
|
-
nextRenderState,
|
|
12
|
-
iframe,
|
|
13
|
-
}: ResizeContext) => {
|
|
14
|
-
if (document.activeElement === iframe) {
|
|
15
|
-
window.scrollBy(0, nextRenderState.rect.bottom - previousRenderState.rect.bottom);
|
|
16
|
-
}
|
|
17
|
-
};
|
package/src/resizer/child.ts
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
IFrameMessage,
|
|
3
|
-
IFrameObjectMessage,
|
|
4
|
-
IframeChildMessageEventData,
|
|
5
|
-
IframeParentMessageEventData,
|
|
6
|
-
} from "../events/index.js";
|
|
7
|
-
import {
|
|
8
|
-
applyStyleSettings,
|
|
9
|
-
deferWhenWindowDocumentIsLoaded,
|
|
10
|
-
getBoundingRectSize,
|
|
11
|
-
getExponentialBackoffDelay,
|
|
12
|
-
isBrowser,
|
|
13
|
-
isInIframe,
|
|
14
|
-
resolveElementToObserve,
|
|
15
|
-
} from "./common.js";
|
|
16
|
-
import type { IframeChildInitEventData, IframeResizeEventData } from "./types.js";
|
|
17
|
-
|
|
18
|
-
export class IframeChildInstance {
|
|
19
|
-
#queue: IFrameMessage[] = [];
|
|
20
|
-
#isQueueConsumed = false;
|
|
21
|
-
#initialized = false;
|
|
22
|
-
#resizeObserver: ResizeObserver | null = null;
|
|
23
|
-
|
|
24
|
-
#getResizeObserverInstance = () => {
|
|
25
|
-
if (!this.#resizeObserver) {
|
|
26
|
-
this.#resizeObserver = new ResizeObserver((entries) => {
|
|
27
|
-
if (!entries[0]?.target) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
const { height, width } = getBoundingRectSize(entries[0].target);
|
|
31
|
-
|
|
32
|
-
const data: IframeResizeEventData = {
|
|
33
|
-
height,
|
|
34
|
-
type: "iframe-resized",
|
|
35
|
-
width,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
window.parent.postMessage(data, "*");
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return this.#resizeObserver;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
#handleInitializeSignal = (event: MessageEvent<IframeChildInitEventData>, nthRetry = 0) => {
|
|
46
|
-
const { targetElementSelector, bodyPadding, bodyMargin } = event.data;
|
|
47
|
-
const elementToObserve = resolveElementToObserve(document, targetElementSelector);
|
|
48
|
-
|
|
49
|
-
if (this.#initialized || window.parent !== event.source) {
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (!elementToObserve) {
|
|
54
|
-
return setTimeout(
|
|
55
|
-
() => this.#handleInitializeSignal(event, nthRetry + 1),
|
|
56
|
-
getExponentialBackoffDelay(nthRetry),
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
applyStyleSettings(document, { bodyMargin, bodyPadding });
|
|
61
|
-
|
|
62
|
-
const resizeObserver = this.#getResizeObserverInstance();
|
|
63
|
-
resizeObserver.disconnect();
|
|
64
|
-
resizeObserver.observe(elementToObserve);
|
|
65
|
-
this.#initialized = true;
|
|
66
|
-
this.#isQueueConsumed = true;
|
|
67
|
-
this.#queue.forEach((message) => this.sendMessage(message));
|
|
68
|
-
this.#queue.length = 0;
|
|
69
|
-
|
|
70
|
-
this.#onReady();
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
sendMessage = (message: IFrameMessage) => {
|
|
74
|
-
if (!isBrowser()) return;
|
|
75
|
-
|
|
76
|
-
if (!isInIframe() && !this.#isQueueConsumed) {
|
|
77
|
-
this.#queue.push(message);
|
|
78
|
-
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const data: IframeParentMessageEventData = {
|
|
83
|
-
message,
|
|
84
|
-
type: "iframe-parent-message",
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
window.parent.postMessage(data, "*");
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
#handleMessage = (
|
|
91
|
-
event: MessageEvent<IframeChildInitEventData | IframeChildMessageEventData>,
|
|
92
|
-
) => {
|
|
93
|
-
if (event.data?.type === "iframe-child-init") {
|
|
94
|
-
return deferWhenWindowDocumentIsLoaded(() =>
|
|
95
|
-
this.#handleInitializeSignal(event as MessageEvent<IframeChildInitEventData>),
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (event.data?.type === "iframe-child-message") {
|
|
100
|
-
this.#onMessage(event.data.message);
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
readonly #onReady: () => void;
|
|
105
|
-
readonly #onMessage: (message: IFrameObjectMessage) => void;
|
|
106
|
-
|
|
107
|
-
constructor({
|
|
108
|
-
onReady,
|
|
109
|
-
onMessage,
|
|
110
|
-
}: {
|
|
111
|
-
onReady: () => void;
|
|
112
|
-
onMessage: (message: IFrameObjectMessage) => void;
|
|
113
|
-
}) {
|
|
114
|
-
this.#onReady = onReady;
|
|
115
|
-
this.#onMessage = onMessage;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
initialize = () => {
|
|
119
|
-
if (!isBrowser() || !isInIframe()) return;
|
|
120
|
-
|
|
121
|
-
window.addEventListener("message", this.#handleMessage);
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
unsubscribe = () => {
|
|
125
|
-
window.removeEventListener("message", this.#handleMessage);
|
|
126
|
-
this.#resizeObserver?.disconnect();
|
|
127
|
-
};
|
|
128
|
-
}
|
package/src/resizer/common.ts
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import type { Settings } from "./types.js";
|
|
2
|
-
|
|
3
|
-
export const isBrowser = () => typeof window !== "undefined";
|
|
4
|
-
|
|
5
|
-
export const isInIframe = () => window.self !== window.top;
|
|
6
|
-
|
|
7
|
-
export const isHtmlIframeElement = (element: Element): element is HTMLIFrameElement =>
|
|
8
|
-
element instanceof HTMLIFrameElement;
|
|
9
|
-
|
|
10
|
-
export const deferWhenWindowDocumentIsLoaded = (executable: () => void) => {
|
|
11
|
-
window.document.readyState === "complete"
|
|
12
|
-
? executable()
|
|
13
|
-
: window.addEventListener("load", executable);
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Post the message twice, it assures the target to receive the message at least once
|
|
18
|
-
*/
|
|
19
|
-
export const postMessageSafelyToCrossOriginIframe = (
|
|
20
|
-
iframe: HTMLIFrameElement,
|
|
21
|
-
executable: () => void,
|
|
22
|
-
) => {
|
|
23
|
-
executable();
|
|
24
|
-
iframe.addEventListener("load", executable);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export const deferWhenSameOriginIframeIsLoaded = (
|
|
28
|
-
iframe: HTMLIFrameElement,
|
|
29
|
-
executable: () => void,
|
|
30
|
-
) => {
|
|
31
|
-
const isLoadingCompleted = iframe.contentWindow?.document.readyState === "complete";
|
|
32
|
-
const isNotBlankPage =
|
|
33
|
-
iframe.src !== "about:blank" && iframe.contentWindow?.location.href !== "about:blank"; // Chrome browsers load once with an empty location
|
|
34
|
-
|
|
35
|
-
return isNotBlankPage && isLoadingCompleted
|
|
36
|
-
? executable()
|
|
37
|
-
: iframe.addEventListener("load", executable);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export const getDefaultSettings: () => Settings = () => ({
|
|
41
|
-
checkOrigin: true,
|
|
42
|
-
enableLegacyLibSupport: false,
|
|
43
|
-
offsetSize: 0,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
export const isIframeSameOrigin = (iframe: HTMLIFrameElement) => {
|
|
47
|
-
try {
|
|
48
|
-
return new URL(iframe.src).origin === window.location.origin;
|
|
49
|
-
} catch (e) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const extractIframeOrigin = (iframe: HTMLIFrameElement): string | null => {
|
|
55
|
-
try {
|
|
56
|
-
const origin = new URL(iframe.src).origin;
|
|
57
|
-
if (origin !== "about:blank") {
|
|
58
|
-
return origin;
|
|
59
|
-
}
|
|
60
|
-
} catch (error) {}
|
|
61
|
-
|
|
62
|
-
return null;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export const removeUndefinedProperties = <T extends { [key: string]: unknown }>(object: T): T => {
|
|
66
|
-
Object.keys(object).forEach((key) => object[key] === undefined && delete object[key]);
|
|
67
|
-
|
|
68
|
-
return object;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
export const getBoundingRectSize = (element: Element) => {
|
|
72
|
-
const { height, width } = element.getBoundingClientRect();
|
|
73
|
-
|
|
74
|
-
return { height: Math.ceil(height), width: Math.ceil(width) };
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export const resolveElementToObserve = (
|
|
78
|
-
document: Document | null,
|
|
79
|
-
targetElementSelector?: string,
|
|
80
|
-
) => {
|
|
81
|
-
if (!document) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return targetElementSelector
|
|
86
|
-
? document.querySelector(targetElementSelector)
|
|
87
|
-
: document.documentElement;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
export const applyStyleSettings = (
|
|
91
|
-
document: Document,
|
|
92
|
-
styleSettings: { bodyMargin?: string; bodyPadding?: string },
|
|
93
|
-
) => {
|
|
94
|
-
if (!document) {
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (styleSettings.bodyPadding) {
|
|
99
|
-
document.body.style.padding = styleSettings.bodyPadding;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (styleSettings.bodyMargin) {
|
|
103
|
-
document.body.style.margin = styleSettings.bodyMargin;
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
export const getExponentialBackoffDelay = (nthRetry: number) => {
|
|
108
|
-
if (nthRetry <= 100) {
|
|
109
|
-
return 100; // for 10 seconds
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (nthRetry <= 120) {
|
|
113
|
-
return 1000; // for 20 seconds
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return 10000;
|
|
117
|
-
};
|
package/src/resizer/index.ts
DELETED
|
File without changes
|
package/src/resizer/parent.ts
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
applyStyleSettings,
|
|
3
|
-
deferWhenSameOriginIframeIsLoaded,
|
|
4
|
-
extractIframeOrigin,
|
|
5
|
-
getBoundingRectSize,
|
|
6
|
-
getDefaultSettings,
|
|
7
|
-
getExponentialBackoffDelay,
|
|
8
|
-
isBrowser,
|
|
9
|
-
isHtmlIframeElement,
|
|
10
|
-
isIframeSameOrigin,
|
|
11
|
-
postMessageSafelyToCrossOriginIframe,
|
|
12
|
-
removeUndefinedProperties,
|
|
13
|
-
resolveElementToObserve,
|
|
14
|
-
} from "./common.js";
|
|
15
|
-
import type {
|
|
16
|
-
IframeChildInitEventData,
|
|
17
|
-
IframeResizeEvent,
|
|
18
|
-
InitializeFunction,
|
|
19
|
-
RegisteredElement,
|
|
20
|
-
ResizeContext,
|
|
21
|
-
Settings,
|
|
22
|
-
} from "./types.js";
|
|
23
|
-
|
|
24
|
-
const getResizeObserverInstance = createResizerObserverLazyFactory();
|
|
25
|
-
let registeredElements: Array<RegisteredElement> = [];
|
|
26
|
-
|
|
27
|
-
const initialize: InitializeFunction = (clientSettings, selector) => {
|
|
28
|
-
if (!isBrowser()) {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
const finalSettings = {
|
|
32
|
-
...getDefaultSettings(),
|
|
33
|
-
...removeUndefinedProperties(clientSettings ?? {}),
|
|
34
|
-
};
|
|
35
|
-
const iframes = resolveIframesToRegister(selector);
|
|
36
|
-
const allowedOrigins = registerIframesAllowOrigins(finalSettings, iframes);
|
|
37
|
-
|
|
38
|
-
return iframes.map((iframe) => {
|
|
39
|
-
const registeredElement: RegisteredElement = {
|
|
40
|
-
iframe,
|
|
41
|
-
initContext: { isInitialized: false, retryAttempts: 0 },
|
|
42
|
-
interactionState: { isHovered: false },
|
|
43
|
-
settings: finalSettings,
|
|
44
|
-
};
|
|
45
|
-
const unsubscribe = addChildResizeListener(registeredElement, allowedOrigins);
|
|
46
|
-
registeredElements.push(registeredElement);
|
|
47
|
-
|
|
48
|
-
return {
|
|
49
|
-
unsubscribe: () => {
|
|
50
|
-
unsubscribe();
|
|
51
|
-
registeredElements = registeredElements.filter((entry) => entry.iframe !== iframe);
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
});
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
function resolveIframesToRegister(selector?: string | HTMLIFrameElement): HTMLIFrameElement[] {
|
|
58
|
-
if (typeof selector === "string") {
|
|
59
|
-
return Array.from(document.querySelectorAll<HTMLElement>(selector)).filter(isHtmlIframeElement);
|
|
60
|
-
}
|
|
61
|
-
if (selector) {
|
|
62
|
-
return isHtmlIframeElement(selector) ? [selector] : [];
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return Array.from(document.getElementsByTagName("iframe"));
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function registerIframesAllowOrigins(settings: Settings, iframes: HTMLIFrameElement[]) {
|
|
69
|
-
if (Array.isArray(settings.checkOrigin)) {
|
|
70
|
-
return settings.checkOrigin;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (!settings.checkOrigin) {
|
|
74
|
-
return [];
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const allowedOrigins: string[] = [];
|
|
78
|
-
for (const iframe of iframes) {
|
|
79
|
-
const origin = extractIframeOrigin(iframe);
|
|
80
|
-
if (origin) {
|
|
81
|
-
allowedOrigins.push(origin);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return allowedOrigins;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function addChildResizeListener(registeredElement: RegisteredElement, allowedOrigins: string[]) {
|
|
89
|
-
const removeResizeListener = isIframeSameOrigin(registeredElement.iframe)
|
|
90
|
-
? addSameOriginChildResizeListener(registeredElement)
|
|
91
|
-
: addCrossOriginChildResizeListener(registeredElement, allowedOrigins);
|
|
92
|
-
|
|
93
|
-
const removeInteractionListeners = addInteractionListeners(registeredElement);
|
|
94
|
-
|
|
95
|
-
return () => {
|
|
96
|
-
removeResizeListener();
|
|
97
|
-
removeInteractionListeners();
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function addCrossOriginChildResizeListener(
|
|
102
|
-
registeredElement: RegisteredElement,
|
|
103
|
-
allowedOrigins: string[],
|
|
104
|
-
) {
|
|
105
|
-
const {
|
|
106
|
-
iframe,
|
|
107
|
-
initContext,
|
|
108
|
-
settings: { checkOrigin, targetElementSelector, bodyPadding, bodyMargin },
|
|
109
|
-
} = registeredElement;
|
|
110
|
-
|
|
111
|
-
const handleIframeResizedMessage = (event: MessageEvent) => {
|
|
112
|
-
const isOriginValid = !checkOrigin || allowedOrigins.includes(event.origin);
|
|
113
|
-
const isIframeTarget = iframe.contentWindow === event.source;
|
|
114
|
-
|
|
115
|
-
if (!isIframeTarget || !isOriginValid) {
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (event.data?.type === "iframe-resized") {
|
|
120
|
-
const { height } = (event as IframeResizeEvent).data;
|
|
121
|
-
height && resizeIframe({ newHeight: height, registeredElement });
|
|
122
|
-
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
window.addEventListener("message", handleIframeResizedMessage);
|
|
128
|
-
|
|
129
|
-
const initMessage: IframeChildInitEventData = {
|
|
130
|
-
bodyMargin,
|
|
131
|
-
bodyPadding,
|
|
132
|
-
targetElementSelector,
|
|
133
|
-
type: "iframe-child-init",
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const sendInitializationMessageToChild = () => {
|
|
137
|
-
postMessageSafelyToCrossOriginIframe(iframe, () =>
|
|
138
|
-
iframe.contentWindow?.postMessage(initMessage, "*"),
|
|
139
|
-
);
|
|
140
|
-
initContext.retryAttempts++;
|
|
141
|
-
initContext.retryTimeoutId = window.setTimeout(
|
|
142
|
-
sendInitializationMessageToChild,
|
|
143
|
-
getExponentialBackoffDelay(initContext.retryAttempts),
|
|
144
|
-
);
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
sendInitializationMessageToChild();
|
|
148
|
-
|
|
149
|
-
return () => window.removeEventListener("message", handleIframeResizedMessage);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function addSameOriginChildResizeListener(registeredElement: RegisteredElement) {
|
|
153
|
-
const { iframe, settings } = registeredElement;
|
|
154
|
-
const { targetElementSelector } = settings;
|
|
155
|
-
let nthRetry = 0;
|
|
156
|
-
|
|
157
|
-
const initialize = () => {
|
|
158
|
-
const elementToObserve = resolveElementToObserve(iframe.contentDocument, targetElementSelector);
|
|
159
|
-
|
|
160
|
-
if (!iframe.contentDocument || !elementToObserve) {
|
|
161
|
-
nthRetry++;
|
|
162
|
-
|
|
163
|
-
return setTimeout(initialize, getExponentialBackoffDelay(nthRetry));
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
applyStyleSettings(iframe.contentDocument, settings);
|
|
167
|
-
getResizeObserverInstance().observe(elementToObserve);
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
deferWhenSameOriginIframeIsLoaded(iframe, initialize);
|
|
171
|
-
|
|
172
|
-
return () => {
|
|
173
|
-
const elementToObserve = resolveElementToObserve(iframe.contentDocument, targetElementSelector);
|
|
174
|
-
if (elementToObserve) {
|
|
175
|
-
getResizeObserverInstance().unobserve(elementToObserve);
|
|
176
|
-
}
|
|
177
|
-
iframe.removeEventListener("load", initialize);
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function addInteractionListeners({ iframe, interactionState }: RegisteredElement) {
|
|
182
|
-
const onMouseEnter = () => {
|
|
183
|
-
interactionState.isHovered = true;
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
const onMouseLeave = () => {
|
|
187
|
-
interactionState.isHovered = false;
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
iframe.addEventListener("mouseenter", onMouseEnter);
|
|
191
|
-
iframe.addEventListener("mouseleave", onMouseLeave);
|
|
192
|
-
|
|
193
|
-
return () => {
|
|
194
|
-
iframe.removeEventListener("mouseenter", onMouseEnter);
|
|
195
|
-
iframe.removeEventListener("mouseleave", onMouseLeave);
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function createResizerObserverLazyFactory() {
|
|
200
|
-
let resizeObserver: ResizeObserver | null = null;
|
|
201
|
-
|
|
202
|
-
return () => {
|
|
203
|
-
if (!resizeObserver) {
|
|
204
|
-
const handleEntry = ({ target }: ResizeObserverEntry) => {
|
|
205
|
-
const matchingRegisteredElement = registeredElements.find(
|
|
206
|
-
({ iframe }) => iframe.contentDocument === target.ownerDocument,
|
|
207
|
-
);
|
|
208
|
-
if (!matchingRegisteredElement) {
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const { iframe, settings } = matchingRegisteredElement;
|
|
213
|
-
const observedElement = resolveElementToObserve(
|
|
214
|
-
iframe.contentDocument,
|
|
215
|
-
settings.targetElementSelector,
|
|
216
|
-
);
|
|
217
|
-
if (!observedElement) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const { height } = getBoundingRectSize(observedElement);
|
|
222
|
-
if (!height) {
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
resizeIframe({ newHeight: height, registeredElement: matchingRegisteredElement });
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
resizeObserver = new ResizeObserver((entries) => entries.forEach(handleEntry));
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return resizeObserver;
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
function resizeIframe({
|
|
236
|
-
registeredElement,
|
|
237
|
-
newHeight,
|
|
238
|
-
}: {
|
|
239
|
-
registeredElement: RegisteredElement;
|
|
240
|
-
newHeight: number;
|
|
241
|
-
}) {
|
|
242
|
-
const { iframe, settings, interactionState, initContext } = registeredElement;
|
|
243
|
-
|
|
244
|
-
if (!initContext.isInitialized) {
|
|
245
|
-
initContext.isInitialized = true;
|
|
246
|
-
clearTimeout(initContext.retryTimeoutId);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (
|
|
250
|
-
settings.onBeforeIframeResize?.({
|
|
251
|
-
iframe,
|
|
252
|
-
observedHeight: newHeight,
|
|
253
|
-
settings: { ...settings },
|
|
254
|
-
}) === false
|
|
255
|
-
) {
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
const previousBoundingRect = iframe.getBoundingClientRect();
|
|
260
|
-
const newCalculatedHeight = newHeight + settings.offsetSize;
|
|
261
|
-
iframe.style.height = `${newCalculatedHeight}px`;
|
|
262
|
-
|
|
263
|
-
if (!settings.onIframeResize) {
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const resizeContext: ResizeContext = {
|
|
268
|
-
iframe,
|
|
269
|
-
interactionState: { ...interactionState },
|
|
270
|
-
nextRenderState: { rect: iframe.getBoundingClientRect() },
|
|
271
|
-
previousRenderState: { rect: previousBoundingRect },
|
|
272
|
-
settings: { ...settings },
|
|
273
|
-
};
|
|
274
|
-
settings.onIframeResize(resizeContext);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
export { initialize };
|