-
Notifications
You must be signed in to change notification settings - Fork 254
Open
Description
I have a situation where we are embedding a Zoid component within a same-origin iframe src=about:blank
. When I attempt to render the component using render("body", IFRAME)
the component renders successfully on Chrome 128 and on Safari <17 but does NOT render on Safari v17.
I've been trying to dig through the Safari 17 Release notes but I can't determine exactly what the change is that causes this.
This is the local setup you can use to re-create the issue:
iframe2.html
<!DOCTYPE html>
<html lang="en" style="overflow: hidden">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Same-Origin iFrame Content</title>
<script>
(function() {
const originalPostMessage = window.postMessage;
window.postMessage = function(...args) {
console.log('postMessage called with:', args);
return originalPostMessage.apply(window, args);
};
})();
</script>
</head>
<body style="height: 100vh">
<iframe id="dynamicFrame" src="about:blank"
style="display: block !important; margin: 0 !important; width: 50% !important; height: 100vh !important; position: fixed; top: 0; right: 0; border: none;"
allowpaymentrequest="true" allow="payment"></iframe>
<script>
// Function to fetch the content of index.html
async function fetchIndexContent() {
try {
const response = await fetch('index.html');
return await response.text();
} catch (error) {
console.error('Error fetching index.html:', error);
return '<p>Error loading content</p>';
}
}
// Function to inject content into the iframe
// This works for Chrome and Safari
async function injectContentSuccessfully() {
const iframe = document.getElementById('dynamicFrame');
const content = await fetchIndexContent();
// Use srcdoc attribute for Safari compatibility
iframe.srcdoc = content;
// Fallback for older browsers that don't support srcdoc
if (!('srcdoc' in iframe)) {
const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
iframeDoc.open();
iframeDoc.write(content);
iframeDoc.close();
}
}
// Function to inject content into the iframe contentDocument
// This works for Chrome but does not work for Safari
async function injectContent_DoesNotLaunch() {
const iframe = document.getElementById('dynamicFrame');
const content = await fetchIndexContent();
// Get the iframe's document object
let iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
// Write content to the iframe
iframeDocument.open();
iframeDocument.write(content);
iframeDocument.close();
}
// Call the function to inject content when the page loads
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', injectContentSuccessfully);
} else {
injectContentSuccessfully();
}
</script>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Zoid Component Playground</title>
</head>
<body style="background-color: #f0f0f0;">
<style>
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
height: 100%;
height: -webkit-fill-available; /* WebKit browsers (iOS Safari, etc.) */
background-color: lightblue;
}
.playground {
padding: 1rem;
text-align: center;
}
@supports (-webkit-touch-callout: none) {
body {
min-height: -webkit-fill-available;
}
}
</style>
<div class="playground" style="background-color: #f0f0f0;">
<zoid-component></zoid-component> <!-- REPLACE THIS LINE WITH YOUR ZOID COMPONENT -->
</div>
<!-- This script includes the zoid component and the zoid library -->
<script type="module" src="./src/main.ts"></script>
</body>
</html>
Another question I had while I was trying to investigate this:
- Is it possible to render the zoid component to the
window.parent
usingrenderTo
? It seems like since the code is being run from an iframe on the same domain as the parent/top window, I should be able to do this since it's not cross-origin. However, when I do this the component never finishes fully rendering. I see the RENDER and DISPLAY events fire successfully, but the RENDERED event is never received. In particular, I eventually see the following error in the console:
Error: No ack for postMessage ce2() in http://localhost:3030 in 10000ms
(localhost:3030 is the zoid component URL). Is there something I'm missing here?
Metadata
Metadata
Assignees
Labels
No labels