Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 1 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /css/css-sizing/responsive-iframe/responsive-iframe-navigation.html?origin=cross - WPT Dashboard Interop Dashboard
- /css/css-sizing/responsive-iframe/responsive-iframe-navigation.html?origin=same - WPT Dashboard Interop Dashboard
<!doctype HTML>
<title>Responsive iframe should keep size during navigation</title>
<link rel="author" href="mailto:kojii@chromium.org">
<meta name="variant" content="?origin=same">
<meta name="variant" content="?origin=cross">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<style>
iframe {
frame-sizing: content-height;
}
</style>
<script>
const params = new URLSearchParams(window.location.search);
const origin = params.get('origin');
const iframe = document.createElement('iframe');
iframe.id = 'iframe';
iframe.frameBorder = '0';
iframe.src = 'resources/iframe-contents-navigation.html';
document.addEventListener('DOMContentLoaded', () => {
document.body.appendChild(iframe);
});
async_test(t => {
let numIframeLoadEvents = 0;
const heights = [];
// Use `ResizeObserver` to catch all resizes.
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
assert_equals(entry.target, iframe);
heights.push(entry.contentRect.height);
switch (numIframeLoadEvents) {
case 0:
break;
case 1:
if (origin === 'cross') {
// At this point, it could be either 2 or 3 heights.
if (heights.length === 3) {
assert_array_equals(heights, [150, 200, 150]);
} else {
assert_array_equals(heights, [150, 200]);
}
} else {
assert_array_equals(heights, [150, 200]);
}
break;
case 2:
if (origin === 'cross') {
// We expect heights to have transitioned: 150 -> 200 -> 150 -> 400.
assert_array_equals(heights, [150, 200, 150, 400]);
} else {
assert_array_equals(heights, [150, 200, 400]);
}
t.done();
break;
default:
assert_less_than(numIframeLoadEvents, 3, "Unexpected iframe load events");
break;
}
}
});
resizeObserver.observe(iframe);
window.addEventListener('message', t.step_func((e) => {
const data = e.data;
if (data && data.action === 'slow-will-block') {
// Check the initial viewport size of the child content.
const viewportHeight = data.viewportHeight;
if (origin === 'cross') {
assert_equals(viewportHeight, 150, "Cross-origin should see reset viewport height");
} else {
assert_equals(viewportHeight, 200, "Same-origin should see retained viewport height");
}
// Check re-layouts don't reset the height while loading new content.
triggerLayouts();
}
}));
iframe.addEventListener('load', t.step_func(() => {
++numIframeLoadEvents;
switch (numIframeLoadEvents) {
case 1:
assert_equals(iframe.offsetHeight, 200, "Initial height should be 200px");
let src = 'iframe-contents-slow.html';
if (origin === 'cross') {
const url = new URL(`resources/${src}`, window.location.href);
src = get_host_info().HTTP_REMOTE_ORIGIN + url.pathname;
}
iframe.contentWindow.postMessage({action: 'navigate', url: src}, '*');
break;
case 2:
break;
}
}));
function triggerLayouts() {
// Trigger layout by appending a `div`.
const div = document.createElement('div');
div.textContent = 'Trigger Layout';
document.body.appendChild(div);
document.body.offsetTop; // Force layout.
// Trigger layout by toggling `display: none`.
iframe.style.display = 'none';
document.body.offsetTop; // Force layout.
iframe.style.display = '';
document.body.offsetTop; // Force layout.
}
}, "Responsive iframe preserves size during navigation");
</script>