diff --git a/common/templates/xblock_v2/xblock_iframe.html b/common/templates/xblock_v2/xblock_iframe.html index add3c46bce55..69af639da2a8 100644 --- a/common/templates/xblock_v2/xblock_iframe.html +++ b/common/templates/xblock_v2/xblock_iframe.html @@ -180,8 +180,8 @@ - -
+ +
{{ fragment.body_html | safe }} @@ -360,7 +360,7 @@ error_message_div.html('Error: '+response.message); error_message_div.css('display', 'block'); } - }); + }); }); }); } @@ -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; - 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); + diff --git a/openedx/core/djangoapps/content_libraries/api/libraries.py b/openedx/core/djangoapps/content_libraries/api/libraries.py index de7be56f7fab..e6ba323b9aae 100644 --- a/openedx/core/djangoapps/content_libraries/api/libraries.py +++ b/openedx/core/djangoapps/content_libraries/api/libraries.py @@ -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 @@ -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, @@ -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), )