Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 47 additions & 13 deletions common/templates/xblock_v2/xblock_iframe.html
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@
<!-- The default stylesheet will set the body min-height to 100% (a common strategy to allow for background
images to fill the viewport), but this has the undesireable side-effect of causing an infinite loop via the onResize
event listeners below, in certain situations. Resetting it to the default "auto" skirts the problem.-->
<body style="min-height: auto; background-color: white;" class="view-container">
<div class="wrapper xblock-iframe-content">
<body style="background-color: white;" class="view-container">
<div id="content" class="wrapper xblock-iframe-content">
<!-- fragment body -->
{{ fragment.body_html | safe }}
<!-- fragment foot -->
Expand Down Expand Up @@ -360,7 +360,7 @@
error_message_div.html('Error: '+response.message);
error_message_div.css('display', 'block');
}
});
});
});
});
}
Expand Down Expand Up @@ -437,21 +437,55 @@
const rootNode = document.querySelector('.xblock, .xblock-v1'); // will always return the first matching element
initializeXBlockAndChildren(rootNode, () => {
});
(function() {
// If this view is rendered in an iframe within the authoring microfrontend app
// it will report the height of its contents to the parent window when the
// document loads, window resizes, or DOM mutates.
if (window !== window.parent) {
var lastHeight = window.parent[0].offsetHeight;
var lastWidth = window.parent[0].offsetWidth;
Comment on lines +445 to +446
Copy link
Contributor

@bradenmacdonald bradenmacdonald Apr 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@navinkarkera Apparently these lines are causing same-origin errors:

Uncaught SecurityError: Failed to read a named property 'offsetHeight' from 'Window': Blocked a frame with origin "https://studio.stage.edx.org/" from accessing a cross-origin frame.

Can we change the initial value of lastHeight and lastWidth to something that doesn't try to access window.parent?

Also what is the [0] in window.parent[0] even doing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bradenmacdonald Turns out that we don't even need this piece of code.

Created a very small PR: #36643


let lastHeight = -1;
function checkFrameHeight() {
const newHeight = document.documentElement.scrollHeight;
if (newHeight !== lastHeight) {
lastHeight = newHeight;
function dispatchResizeMessage(event) {
// Note: event is actually an Array of MutationRecord objects when fired from the MutationObserver
var newHeight = rootNode.scrollHeight;
var newWidth = rootNode.offsetWidth;

window.parent.postMessage(
{
type: 'plugin.resize',
payload: {
width: newWidth,
height: newHeight,
}
}, document.referrer
);

lastHeight = newHeight;
lastWidth = newWidth;

// Within the authoring microfrontend the iframe resizes to match the
// height of this document and it should never scroll. It does scroll
// ocassionally when javascript is used to focus elements on the page
// before the parent iframe has been resized to match the content
// height. This window.scrollTo is an attempt to keep the content at the
// top of the page.
window.scrollTo(0, 0);
}

// Create an observer instance linked to the callback function
const observer = new MutationObserver(dispatchResizeMessage);

// Start observing the target node for configured mutations
observer.observe(rootNode, { attributes: true, childList: true, subtree: true });

const resizeObserver = new ResizeObserver(dispatchResizeMessage);
resizeObserver.observe(rootNode);
}
}
// Check the size whenever the DOM changes:
new MutationObserver(checkFrameHeight).observe(document.body, { attributes: true, childList: true, subtree: true });
// And whenever the IFrame is resized
window.addEventListener('resize', checkFrameHeight);
}());
}

window.addEventListener('load', blockFrameJS);

</script>
</body>
</html>
13 changes: 9 additions & 4 deletions openedx/core/djangoapps/content_libraries/api/libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,17 @@ class LibraryXBlockMetadata(PublishableItem):
Class that represents the metadata about an XBlock in a content library.
"""
usage_key: LibraryUsageLocatorV2
# TODO: move tags_count to LibraryItem as all objects under a library can be tagged.
tags_count: int = 0

@classmethod
def from_component(cls, library_key, component, associated_collections=None):
"""
Construct a LibraryXBlockMetadata from a Component object.
"""
# Import content_tagging.api here to avoid circular imports
from openedx.core.djangoapps.content_tagging.api import get_object_tag_counts

last_publish_log = component.versioning.last_publish_log

published_by = None
Expand All @@ -227,12 +232,11 @@ def from_component(cls, library_key, component, associated_collections=None):
published = component.versioning.published
last_draft_created = draft.created if draft else None
last_draft_created_by = draft.publishable_entity_version.created_by if draft else None
usage_key = library_component_usage_key(library_key, component)
tags = get_object_tag_counts(str(usage_key), count_implicit=True)

return cls(
usage_key=library_component_usage_key(
library_key,
component,
),
usage_key=usage_key,
display_name=draft.title,
created=component.created,
modified=draft.created,
Expand All @@ -245,6 +249,7 @@ def from_component(cls, library_key, component, associated_collections=None):
has_unpublished_changes=component.versioning.has_unpublished_changes,
collections=associated_collections or [],
can_stand_alone=component.publishable_entity.can_stand_alone,
tags_count=tags.get(str(usage_key), 0),
)


Expand Down
Loading