Skip to content

Commit cacabaf

Browse files
committed
feat: post component height to parent window
1 parent 0120179 commit cacabaf

1 file changed

Lines changed: 47 additions & 13 deletions

File tree

common/templates/xblock_v2/xblock_iframe.html

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@
180180
<!-- The default stylesheet will set the body min-height to 100% (a common strategy to allow for background
181181
images to fill the viewport), but this has the undesireable side-effect of causing an infinite loop via the onResize
182182
event listeners below, in certain situations. Resetting it to the default "auto" skirts the problem.-->
183-
<body style="min-height: auto; background-color: white;" class="view-container">
184-
<div class="wrapper xblock-iframe-content">
183+
<body style="background-color: white;" class="view-container">
184+
<div id="content" class="wrapper xblock-iframe-content">
185185
<!-- fragment body -->
186186
{{ fragment.body_html | safe }}
187187
<!-- fragment foot -->
@@ -360,7 +360,7 @@
360360
error_message_div.html('Error: '+response.message);
361361
error_message_div.css('display', 'block');
362362
}
363-
});
363+
});
364364
});
365365
});
366366
}
@@ -437,21 +437,55 @@
437437
const rootNode = document.querySelector('.xblock, .xblock-v1'); // will always return the first matching element
438438
initializeXBlockAndChildren(rootNode, () => {
439439
});
440+
(function() {
441+
// If this view is rendered in an iframe within the authoring microfrontend app
442+
// it will report the height of its contents to the parent window when the
443+
// document loads, window resizes, or DOM mutates.
444+
if (window !== window.parent) {
445+
var lastHeight = window.parent[0].offsetHeight;
446+
var lastWidth = window.parent[0].offsetWidth;
440447

441-
let lastHeight = -1;
442-
function checkFrameHeight() {
443-
const newHeight = document.documentElement.scrollHeight;
444-
if (newHeight !== lastHeight) {
445-
lastHeight = newHeight;
448+
function dispatchResizeMessage(event) {
449+
// Note: event is actually an Array of MutationRecord objects when fired from the MutationObserver
450+
var newHeight = rootNode.scrollHeight;
451+
var newWidth = rootNode.offsetWidth;
452+
453+
window.parent.postMessage(
454+
{
455+
type: 'plugin.resize',
456+
payload: {
457+
width: newWidth,
458+
height: newHeight,
459+
}
460+
}, document.referrer
461+
);
462+
463+
lastHeight = newHeight;
464+
lastWidth = newWidth;
465+
466+
// Within the authoring microfrontend the iframe resizes to match the
467+
// height of this document and it should never scroll. It does scroll
468+
// ocassionally when javascript is used to focus elements on the page
469+
// before the parent iframe has been resized to match the content
470+
// height. This window.scrollTo is an attempt to keep the content at the
471+
// top of the page.
472+
window.scrollTo(0, 0);
473+
}
474+
475+
// Create an observer instance linked to the callback function
476+
const observer = new MutationObserver(dispatchResizeMessage);
477+
478+
// Start observing the target node for configured mutations
479+
observer.observe(rootNode, { attributes: true, childList: true, subtree: true });
480+
481+
const resizeObserver = new ResizeObserver(dispatchResizeMessage);
482+
resizeObserver.observe(rootNode);
446483
}
447-
}
448-
// Check the size whenever the DOM changes:
449-
new MutationObserver(checkFrameHeight).observe(document.body, { attributes: true, childList: true, subtree: true });
450-
// And whenever the IFrame is resized
451-
window.addEventListener('resize', checkFrameHeight);
484+
}());
452485
}
453486

454487
window.addEventListener('load', blockFrameJS);
488+
455489
</script>
456490
</body>
457491
</html>

0 commit comments

Comments
 (0)