reframer
Version:
A declarative wrapper to iframe-resizer. Just add reframer class to any iframe. Cool!
170 lines (139 loc) • 5.05 kB
JavaScript
import { iframeResize } from "iframe-resizer";
//if (typeof window === 'undefined') return;
let win = window,
doc = document,
$ = function (q) { return doc.querySelector(q) },
$$ = function (q) { return doc.querySelectorAll(q) },
domReady = f => doc.readyState[7] ? f() : setTimeout(domReady, 9, f),
defaultConfig = {}
doc.head.insertAdjacentHTML('beforeend', '<style>iframe.resizable:not(.resizable-processed){display:none}</style>');
function getTargetIframes(targetIframes) {
let queueIframes = [];
// Set default iframe selector if not present
if (typeof targetIframes == 'undefined' || !targetIframes) {
targetIframes = 'iframe.resizable';
}
// If css selector
if (typeof targetIframes === 'string') {
queueIframes = $$(targetIframes);
}
// if single node
else if (targetIframes.dispatchEvent) {
queueIframes.push(targetIframes);
}
// if from qsa
else {
queueIframes = targetIframes;
}
return queueIframes;
}
let parentEvents = [];
window.meAsParent = window.meAsParent || {}
meAsParent.on = function (event, callback) {
let eventId = parentEvents.push({ event: event, callback: callback });
return function () { delete parentEvents[eventId - 1] }
}
meAsParent.trigger = function (event, data, targetIframes) {
let queueIframes = getTargetIframes(targetIframes);
queueIframes.forEach(function (iframe) {
parentMessageHandler({
iframe: iframe,
message: {
event: event,
data: data
}
});
});
}
meAsParent.send = function (event, data, targetIframes) {
let queueIframes = getTargetIframes(targetIframes);
queueIframes.forEach(function (iframe) {
iframe?.iFrameResizer?.sendMessage({ event: event, data: data })
});
}
function parentMessageHandler({ iframe, message }) {
let { event, data } = message;
parentEvents.forEach(function (e) {
if (e.event == event) e.callback({ iframe, data });
});
}
let childEvents = [];
window.meAsChild = window.meAsChild || {}
meAsChild.on = function (event, callback) {
let eventId = childEvents.push({ event: event, callback: callback });
return function () { delete childEvents[eventId - 1] }
}
meAsChild.trigger = function (event, data) {
childMessageHandler({ event, data });
}
meAsChild.send = function (event, data) {
let ctrl = setInterval(function () {
if (typeof parentIFrame !== 'undefined') {
clearInterval(ctrl);
parentIFrame.sendMessage({ event: event, data: data });
}
}, 10);
}
function childMessageHandler({ event, data }) {
childEvents.forEach(function (e) {
if (e.event == event) e.callback(data);
})
}
function processIframe(config) {
let idSel = '#' + config.id;
meAsParent.trigger('beforeResize', config, idSel);
resizer.onMessage = parentMessageHandler;
resizer.onInit = function (iframe) {
meAsParent.trigger('initialized', config, idSel);
}
iframeResize(resizer, idSel);
}
function ECF(embedURL, config = {}) {
config.resizer = Object.assign(defaultConfig.resizer, config.resizer);
config = Object.assign(defaultConfig, config);
config.id = 'ecf-' + parseInt(Math.random() * 1e16);
let ecfNode = config.insertInto ? $(config.insertInto) : doc.currentScript || $$('script').pop();
let i = doc.createElement('iframe');
i.id = config.id;
if (config.lazyloadClass) {
i.setAttribute('data-src', embedURL);
i.classList.add(config.lazyloadClass);
}
else {
i.src = embedURL;
}
ecfNode.insertAdjacentElement(config.insertPosition, i);
processIframe(config);
return;
}
export default ECF;
domReady(() => {
const observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
mutation.addedNodes.forEach(function (node) {
if (node.nodeName.toLowerCase() == 'iframe' && node.classList.contains('resizable')) {
let config = Object.assign(defaultConfig, { ...node.dataset });
config.id = node.id || 'resizable-' + parseInt(Math.random() * 1e16);
node.id = config.id;
processIframe(config);
}
});
});
});
observer.observe(doc.body, { attributes: false, childList: true, subtree: true });
$$('iframe.resizable').forEach(function (node) {
let config = Object.assign(defaultConfig, { ...node.dataset });
config.id = node.id || 'resizable-' + parseInt(Math.random() * 1e16);
node.id = config.id;
processIframe(config);
});
if (win.top !== win.self) {
win.iFrameResizer = {
onMessage: childMessageHandler,
onReady: function () {
meAsChild.trigger('ready');
}
}
import("iframe-resizer/js/iframeResizer.contentWindow");
}
});