mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Add coordinated blog iframe resize messaging
This commit is contained in:
1 parent
a76326eacf
commit
60cf6bb9c1
2 files changed
+166
No files matched your search
@@ -132,6 +132,76 @@ function resolveNotes() {
|
||||
return buildDefaultNotes();
|
||||
}
|
||||
|
||||
function setupEmbedHeightBroadcast({ root, registerCleanup }) {
|
||||
if (typeof window === 'undefined' || !root || window.parent === window) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parentOrigin = (() => {
|
||||
try {
|
||||
if (document.referrer) {
|
||||
return new URL(document.referrer).origin;
|
||||
}
|
||||
} catch (error) {
|
||||
userLogger.error('[blog] failed to parse parent origin for resize messaging', error);
|
||||
}
|
||||
return '*';
|
||||
})();
|
||||
|
||||
let lastHeight = null;
|
||||
|
||||
const postHeight = (force = false) => {
|
||||
const rect = root.getBoundingClientRect();
|
||||
const height = Math.ceil(rect.height);
|
||||
if (!Number.isFinite(height) || height < 0) {
|
||||
return;
|
||||
}
|
||||
if (!force && height === lastHeight) {
|
||||
return;
|
||||
}
|
||||
lastHeight = height;
|
||||
try {
|
||||
window.parent.postMessage({ type: 'bitvid-blog-resize', height }, parentOrigin);
|
||||
} catch (error) {
|
||||
userLogger.error('[blog] failed to post resize message', error);
|
||||
}
|
||||
};
|
||||
|
||||
const rafId = window.requestAnimationFrame(() => {
|
||||
postHeight();
|
||||
});
|
||||
registerCleanup(() => {
|
||||
window.cancelAnimationFrame(rafId);
|
||||
});
|
||||
|
||||
if (typeof ResizeObserver === 'function') {
|
||||
const observer = new ResizeObserver(() => {
|
||||
postHeight();
|
||||
});
|
||||
observer.observe(root);
|
||||
registerCleanup(() => {
|
||||
observer.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
const handleMessage = (event) => {
|
||||
if (event.source !== window.parent) {
|
||||
return;
|
||||
}
|
||||
if (parentOrigin !== '*' && event.origin !== parentOrigin) {
|
||||
return;
|
||||
}
|
||||
if (event?.data?.type === 'bitvid-blog-request-height') {
|
||||
postHeight(true);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('message', handleMessage);
|
||||
registerCleanup(() => {
|
||||
window.removeEventListener('message', handleMessage);
|
||||
});
|
||||
}
|
||||
|
||||
function formatDate(unixSeconds, { includeTime = false } = {}) {
|
||||
if (!unixSeconds) {
|
||||
return '';
|
||||
@@ -724,6 +794,7 @@ function mountBlogApp({ initZapthreadsEmbed = defaultInitZapthreadsEmbed } = {})
|
||||
}
|
||||
|
||||
root.replaceChildren(main);
|
||||
setupEmbedHeightBroadcast({ root, registerCleanup });
|
||||
|
||||
registerCleanup(() => {
|
||||
root.replaceChildren();
|
||||
|
||||
@@ -11,6 +11,101 @@
|
||||
src="https://beta.bitvid.network/blog.html"
|
||||
class="h-full w-full border-none"
|
||||
></iframe>
|
||||
<script type="module">
|
||||
const iframe = document.querySelector('#blog-iframe');
|
||||
if (iframe) {
|
||||
const abortController = new AbortController();
|
||||
const { signal } = abortController;
|
||||
|
||||
const targetOrigin = (() => {
|
||||
try {
|
||||
return new URL(iframe.src, window.location.href).origin;
|
||||
} catch (error) {
|
||||
return window.location.origin;
|
||||
}
|
||||
})();
|
||||
|
||||
const applyHeight = (height) => {
|
||||
const numeric = Math.max(0, Math.round(Number(height)));
|
||||
if (!Number.isFinite(numeric)) {
|
||||
return;
|
||||
}
|
||||
iframe.style.height = `${numeric}px`;
|
||||
iframe.style.removeProperty('min-height');
|
||||
iframe.style.removeProperty('max-height');
|
||||
};
|
||||
|
||||
const handleMessage = (event) => {
|
||||
if (event.source !== iframe.contentWindow) {
|
||||
return;
|
||||
}
|
||||
if (event.origin !== targetOrigin) {
|
||||
return;
|
||||
}
|
||||
if (event.data?.type === 'bitvid-blog-resize') {
|
||||
applyHeight(event.data.height);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('message', handleMessage, { signal });
|
||||
|
||||
const requestHeight = () => {
|
||||
if (!iframe.contentWindow) {
|
||||
return;
|
||||
}
|
||||
iframe.contentWindow.postMessage(
|
||||
{ type: 'bitvid-blog-request-height' },
|
||||
targetOrigin,
|
||||
);
|
||||
};
|
||||
|
||||
const startRetryLoop = () => {
|
||||
const maxAttempts = 5;
|
||||
let attempts = 0;
|
||||
const retryIntervalMs = 200;
|
||||
const intervalId = window.setInterval(() => {
|
||||
attempts += 1;
|
||||
if (attempts > maxAttempts) {
|
||||
window.clearInterval(intervalId);
|
||||
return;
|
||||
}
|
||||
requestHeight();
|
||||
}, retryIntervalMs);
|
||||
|
||||
const stop = () => {
|
||||
window.clearInterval(intervalId);
|
||||
};
|
||||
|
||||
if (signal.aborted) {
|
||||
stop();
|
||||
} else {
|
||||
signal.addEventListener('abort', stop, { once: true });
|
||||
}
|
||||
};
|
||||
|
||||
const runInitialRequests = () => {
|
||||
requestHeight();
|
||||
startRetryLoop();
|
||||
};
|
||||
|
||||
iframe.addEventListener('load', () => {
|
||||
runInitialRequests();
|
||||
}, { signal });
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', runInitialRequests, {
|
||||
once: true,
|
||||
signal,
|
||||
});
|
||||
} else {
|
||||
runInitialRequests();
|
||||
}
|
||||
|
||||
window.addEventListener('pagehide', () => {
|
||||
abortController.abort();
|
||||
}, { once: true });
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
Reference in new issue
Block a user