import { sleep } from '../utils/async';
import css from '../styles/dialog';
import { OpenDialog } from '.';
import { addPostMessageHandler } from './shared';
const TEMPLATE = `
`;
/**
* Embeds Bitski's dialog styles
*/
const injectStyles = () => {
if (document.getElementById('BitskiSDKEmbeddedStyles')) {
return;
}
const style = document.createElement('style');
style.setAttribute('type', 'text/css');
style.setAttribute('id', 'BitskiSDKEmbeddedStyles');
style.appendChild(document.createTextNode(css));
const head = document.head || document.getElementsByTagName('head')[0];
head.appendChild(style);
};
const findOrCreateContainer = (iframe: HTMLElement): HTMLElement => {
const existingContainer = document.querySelector('#bitski-dialog-container') as HTMLElement;
if (existingContainer) {
return existingContainer;
}
const container = document.createElement('div');
container.id = 'bitski-dialog-container';
document.body.appendChild(container);
container.innerHTML = TEMPLATE;
const body = container.querySelector('.bitski-dialog-body');
if (body) {
body.appendChild(iframe);
}
return container;
};
const createIframe = (url: string): HTMLElement => {
const iframe = document.createElement('iframe');
iframe.style.position = 'absolute';
iframe.style.top = '0';
iframe.style.left = '0';
iframe.style.width = '100%';
iframe.style.height = '100%';
iframe.frameBorder = '0';
iframe.src = url;
return iframe;
};
const addCloseHandlers = (container: HTMLElement, close: () => void) => {
// Close on click outside of the dialog
container.addEventListener('click', (event) => {
if (event.target === container) {
close();
}
});
// Close on escape press
document.addEventListener('keyup', (e) => {
if (e.key === 'Escape') {
close();
}
});
// Close on close button click
const closeButton = container.querySelector('.bitski-close-button');
if (closeButton) {
closeButton.addEventListener('click', () => {
close();
});
}
};
export const openIframeDialog: OpenDialog = (opts) => {
injectStyles();
const iframe = createIframe(opts.url);
const container = findOrCreateContainer(iframe);
const close = async () => {
container.classList.remove('bitski-visible', 'bitski-loaded');
await sleep(500);
container.remove();
};
return {
result: new Promise((resolve, reject) => {
addCloseHandlers(container, () => {
try {
resolve(opts.handleClose());
} catch (e) {
reject(e);
} finally {
close();
}
});
addPostMessageHandler(opts.handleMessage, close, resolve, reject);
// A short delay is required before triggering animations
setTimeout(() => {
container.classList.add('bitski-visible', 'bitski-loaded');
}, 10);
}),
cancel: close,
};
};