Skip to content

Commit

Permalink
fix: defer event bind until contentWindow exists
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisvxd committed Apr 3, 2024
1 parent 9296074 commit f472135
Showing 1 changed file with 32 additions and 14 deletions.
46 changes: 32 additions & 14 deletions src/view/event-bindings/bind-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,40 @@ function getOptions(
};
}

let loaded = false;
const getWin = (el: HTMLElement | Window) => {
let win = el as Window | null;

function bindEvent(win: Window, binding: EventBinding, options: EventOptions) {
if ((el as HTMLElement).nodeName === 'IFRAME') {
win = (el as HTMLIFrameElement).contentWindow;
}

return win;
};

function bindEvent(
el: HTMLElement | Window,
binding: EventBinding,
options: EventOptions,
) {
let timer: number | undefined;

if (!loaded) {
// Some browsers require us to defer binding events, i.e. Safari
if ((el as HTMLElement).nodeName === 'IFRAME') {
timer = setInterval(() => {
if ((win as Window).document.readyState === 'complete') {
win.addEventListener(binding.eventName, binding.fn, options);
loaded = true;
const currentWin = getWin(el);

if (currentWin?.document.readyState === 'complete') {
currentWin.addEventListener(binding.eventName, binding.fn, options);
clearInterval(timer);
}
}, 100);
} else {
win.addEventListener(binding.eventName, binding.fn, options);

return timer;
}

const win = getWin(el);

win?.addEventListener(binding.eventName, binding.fn, options);

return timer;
}

Expand All @@ -49,18 +66,19 @@ export default function bindEvents(
'[data-rfd-iframe]',
) as HTMLIFrameElement[];

const windows = [el, ...iframes.map((iframe) => iframe.contentWindow)];
const els = [el, ...iframes];

return windows.map((win) => {
if (!win) return function unbind() {};
return els.map((currentEl) => {
if (!currentEl) return function unbind() {};

const options = getOptions(sharedOptions, binding.options);

const timer = bindEvent(win as Window, binding, options);
const timer = bindEvent(currentEl, binding, options);

return function unbind() {
clearInterval(timer);
win.removeEventListener(binding.eventName, binding.fn, options);
const win = getWin(currentEl);
win?.removeEventListener(binding.eventName, binding.fn, options);
};
});
},
Expand Down

0 comments on commit f472135

Please sign in to comment.