Mobile apps load HTML (and other) XBlocks individually using the render_xblock endpoint. This is an attmept to reduce the number of requests and JS processing needed to do so by detecting when we have math content in HTMLBlocks and only adding the Mathjax resources when necessary. This is controlled by the "courseware.optimized_render_xblock" CourseWaffleFlag. For maximum safety, we currently only optimize in this way when directly hitting HTMLBlocks, and not for ProblemBlock or VerticalBlock. This was made as part of edX's Hackathon XXV.
168 lines
5.5 KiB
HTML
168 lines
5.5 KiB
HTML
<%page expression_filter="h"/>
|
|
<%inherit file="/main.html" />
|
|
<%namespace name='static' file='/static_content.html'/>
|
|
<%!
|
|
from django.utils.translation import ugettext as _
|
|
|
|
from openedx.core.djangolib.markup import HTML
|
|
from openedx.core.djangolib.js_utils import js_escaped_string
|
|
|
|
%>
|
|
<%def name="course_name()">
|
|
<% return _("{course_number} Courseware").format(course_number=course.display_number_with_default) %>
|
|
</%def>
|
|
<%block name="bodyclass">view-in-course view-courseware courseware ${course.css_class or ''}</%block>
|
|
<%block name="title"><title>
|
|
% if section_title:
|
|
${static.get_page_title_breadcrumbs(section_title, course_name())}
|
|
% else:
|
|
${static.get_page_title_breadcrumbs(course_name())}
|
|
%endif
|
|
</title></%block>
|
|
|
|
<%block name="header_extras">
|
|
% for template_name in ["image-modal"]:
|
|
<script type="text/template" id="${template_name}-tpl">
|
|
<%static:include path="common/templates/${template_name}.underscore" />
|
|
</script>
|
|
% endfor
|
|
<%
|
|
header_file = None
|
|
%>
|
|
</%block>
|
|
|
|
<%block name="headextra">
|
|
<%static:css group='style-course-vendor'/>
|
|
<%static:css group='style-course'/>
|
|
## Utility: Notes
|
|
% if edx_notes_enabled:
|
|
<%static:css group='style-student-notes'/>
|
|
% endif
|
|
|
|
<script type="text/javascript" src="${static.url('js/jquery.autocomplete.js')}" async></script>
|
|
<script type="text/javascript" src="${static.url('js/src/tooltip_manager.js')}" async></script>
|
|
|
|
<link href="${static.url('css/vendor/jquery.autocomplete.css')}" rel="preload" type="text/css">
|
|
${HTML(fragment.head_html())}
|
|
|
|
% if is_learning_mfe:
|
|
## If this chromeless view is in an iframe in the learning microfrontend app
|
|
## then add a base tag in the head (of the iframe document) to force links
|
|
## in this iframe to navigate the parent window.
|
|
<base target="_parent">
|
|
%endif
|
|
</%block>
|
|
|
|
<%block name="js_extra">
|
|
<script type="text/javascript" src="${static.url('common/js/vendor/jquery.scrollTo.js')}" async></script>
|
|
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}" async></script>
|
|
|
|
<%static:js group='courseware'/>
|
|
|
|
% if enable_mathjax:
|
|
<%include file="/mathjax_include.html" args="disable_fast_preview=True"/>
|
|
% endif
|
|
% if staff_access:
|
|
<%include file="xqa_interface.html"/>
|
|
% endif
|
|
|
|
<script type="text/javascript">
|
|
var $$course_id = "${course.id | n, js_escaped_string}";
|
|
</script>
|
|
|
|
${HTML(fragment.foot_html())}
|
|
|
|
</%block>
|
|
|
|
<div class="course-wrapper chromeless">
|
|
<section class="course-content" id="course-content"\
|
|
% if enable_completion_on_view_service:
|
|
data-enable-completion-on-view-service="true" \
|
|
% else:
|
|
data-enable-completion-on-view-service="false" \
|
|
% endif
|
|
style="display: block; width: auto; margin: 0;"
|
|
>
|
|
<main id="main" tabindex="-1" aria-label="Content">
|
|
${HTML(fragment.body_html())}
|
|
</main>
|
|
</section>
|
|
</div>
|
|
% if not is_learning_mfe:
|
|
|
|
% if course.show_calculator or edx_notes_enabled:
|
|
<nav class="nav-utilities ${"has-utility-calculator" if course.show_calculator else ""}" aria-label="${_('Course Utilities')}">
|
|
## Utility: Notes
|
|
% if edx_notes_enabled:
|
|
<%include file="/edxnotes/toggle_notes.html" args="course=course"/>
|
|
% endif
|
|
|
|
## Utility: Calc
|
|
% if course.show_calculator:
|
|
<%include file="/calculator/toggle_calculator.html" />
|
|
% endif
|
|
</nav>
|
|
% endif
|
|
% else:
|
|
% if edx_notes_enabled:
|
|
<%include file="/edxnotes/toggle_notes.html" args="course=course"/>
|
|
% endif
|
|
% endif
|
|
|
|
% if is_learning_mfe:
|
|
<script type="text/javascript">
|
|
(function() {
|
|
// If this view is rendered in an iframe within the learning 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) {
|
|
document.body.className += ' view-in-mfe';
|
|
var lastHeight = window.offsetHeight;
|
|
var lastWidth = window.offsetWidth;
|
|
var contentElement = document.getElementById('content');
|
|
|
|
function dispatchResizeMessage(event) {
|
|
// Note: event is actually an Array of MutationRecord objects
|
|
// when fired from the MutationObserver
|
|
var eventType = event.type || 'mutate';
|
|
var newHeight = contentElement.offsetHeight;
|
|
var newWidth = contentElement.offsetWidth;
|
|
|
|
if (eventType !== 'load' && newWidth === lastWidth && newHeight === lastHeight) {
|
|
return;
|
|
}
|
|
|
|
window.parent.postMessage({
|
|
type: 'plugin.resize',
|
|
payload: {
|
|
width: newWidth,
|
|
height: newHeight,
|
|
}
|
|
}, document.referrer
|
|
);
|
|
|
|
lastHeight = newHeight;
|
|
lastWidth = newWidth;
|
|
|
|
// Within the learning 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. See TNL-7094
|
|
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(document.body, { attributes: true, childList: true, subtree: true });
|
|
|
|
window.addEventListener('load', dispatchResizeMessage);
|
|
window.addEventListener('resize', dispatchResizeMessage);
|
|
}
|
|
}());
|
|
</script>
|
|
% endif
|