Skip to content

Commit

Permalink
feat: connected iframe template
Browse files Browse the repository at this point in the history
  • Loading branch information
PKulkoRaccoonGang committed Mar 5, 2024
1 parent 8611e71 commit c6da976
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ HOTJAR_VERSION=6
HOTJAR_DEBUG=false
INVITE_STUDENTS_EMAIL_TO=''
AI_TRANSLATIONS_BASE_URL=''
SECURE_ORIGIN_XBLOCK_BOOTSTRAP_HTML_URL=/xblock-bootstrap.html
SECURE_ORIGIN_XBLOCK_BOOTSTRAP_HTML_URL=null
126 changes: 124 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@
"jest-expect-message": "^1.1.3",
"react-test-renderer": "17.0.2",
"reactifex": "1.1.1",
"ts-loader": "^9.5.0"
"ts-loader": "^9.5.0",
"copy-webpack-plugin": "^11.0.0"
},
"peerDependencies": {
"decode-uri-component": ">=0.2.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class LibraryBlock extends React.Component {
const html = wrapBlockHtmlForIFrame(
view.html,
view.resources,
getConfig().LMS_BASE_URL,
getConfig().STUDIO_BASE_URL,
);

// Load the XBlock HTML into the IFrame:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ function blockFrameJS() {
* Only required for legacy XBlocks that don't declare their
* JS and CSS dependencies properly.
*/
export default function wrapBlockHtmlForIFrame(html, sourceResources, lmsBaseUrl) {
export default function wrapBlockHtmlForIFrame(html, sourceResources, studioBaseUrl) {
const resources = sourceResources.map(([id, obj]) => ({ id, ...obj }));
/* Separate resources by kind. */
const urlResources = resources.filter((r) => r.kind === 'url');
Expand All @@ -223,13 +223,13 @@ export default function wrapBlockHtmlForIFrame(html, sourceResources, lmsBaseUrl
/* Extract CSS resources. */
const cssUrls = urlResources.filter((r) => r.mimetype === 'text/css').map((r) => r.data);
const sheets = textResources.filter((r) => r.mimetype === 'text/css').map((r) => r.data);
let cssTags = cssUrls.map((url) => `<link rel="stylesheet" href="${url}">`).join('\n');
let cssTags = cssUrls.map((url) => `<link rel="stylesheet" href="${studioBaseUrl}${url}">`).join('\n');
cssTags += sheets.map((sheet) => `<style>${sheet}</style>`).join('\n');

/* Extract JS resources. */
const jsUrls = urlResources.filter((r) => r.mimetype === 'application/javascript').map((r) => r.data);
const scripts = textResources.filter((r) => r.mimetype === 'application/javascript').map((r) => r.data);
let jsTags = jsUrls.map((url) => `<script src="${url}"></script>`).join('\n');
let jsTags = jsUrls.map((url) => `<script src="${studioBaseUrl}${url}"></script>`).join('\n');
jsTags += scripts.map((script) => `<script>${script}</script>`).join('\n');

// Most older XModules/XBlocks have a ton of undeclared dependencies on various JavaScript in the global scope.
Expand All @@ -240,14 +240,15 @@ export default function wrapBlockHtmlForIFrame(html, sourceResources, lmsBaseUrl
// Otherwise, if the XBlock uses 'student_view', 'author_view', or 'studio_view', include known required globals:
let legacyIncludes = '';
if (
html.indexOf('xblock-v1-student_view') !== -1
html.indexOf('wrapper-xblock-message') !== -1
|| html.indexOf('xblock-v1-student_view') !== -1
|| html.indexOf('xblock-v1-public_view') !== -1
|| html.indexOf('xblock-v1-studio_view') !== -1
|| html.indexOf('xblock-v1-author_view') !== -1
) {
legacyIncludes += `
<!-- gettext & XBlock JS i18n code -->
<script type="text/javascript" src="${lmsBaseUrl}/static/js/i18n/en/djangojs.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/i18n/en/djangojs.js"></script>
<!-- Most XBlocks require jQuery: -->
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<!-- The Video XBlock requires "ajaxWithPrefix" -->
Expand All @@ -259,21 +260,21 @@ export default function wrapBlockHtmlForIFrame(html, sourceResources, lmsBaseUrl
<!-- The Video XBlock requires "Slider" from jQuery-UI: -->
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<!-- The video XBlock depends on Underscore.JS -->
<script type="text/javascript" src="${lmsBaseUrl}/static/common/js/vendor/underscore.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/common/js/vendor/underscore.js"></script>
<!-- The video XBlock depends on jquery-cookie -->
<script type="text/javascript" src="${lmsBaseUrl}/static/js/vendor/jquery.cookie.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/vendor/jquery.cookie.js"></script>
<!--The Video XBlock has an undeclared dependency on 'Logger' -->
<script>
window.Logger = { log: function() { } };
</script>
<!-- Builtin XBlock types depend on RequireJS -->
<script type="text/javascript" src="${lmsBaseUrl}/static/common/js/vendor/require.js"></script>
<script type="text/javascript" src="${lmsBaseUrl}/static/js/RequireJS-namespace-undefine.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/common/js/vendor/require.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/RequireJS-namespace-undefine.js"></script>
<script>
// The minimal RequireJS configuration required for common LMS building XBlock types to work:
(function (require, define) {
require.config({
baseUrl: "${lmsBaseUrl}/static/",
baseUrl: "${studioBaseUrl}/static/studio/",
paths: {
accessibility: 'js/src/accessibility_tools',
draggabilly: 'js/vendor/draggabilly',
Expand All @@ -289,7 +290,24 @@ export default function wrapBlockHtmlForIFrame(html, sourceResources, lmsBaseUrl
}).call(this, require || RequireJS.require, define || RequireJS.define);
</script>
<!-- edX HTML Utils requires GlobalLoader -->
<script type="text/javascript" src="${lmsBaseUrl}/static/edx-ui-toolkit/js/utils/global-loader.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/edx-ui-toolkit/js/utils/global-loader.js"></script>
<!-- CMS -->
<script type="text/javascript" src="https://static.hotjar.com/c/hotjar-0.js?sv=6"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/models/xblock_info.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/views/xblock.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/views/utils/xblock_utils.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/common/js/components/utils/view_utils.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/utils/module.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/common/js/components/views/feedback_notification.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/common/js/components/views/feedback_prompt.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/views/baseview.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/utils/handle_iframe_binding.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/utils/templates.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/common/js/components/views/feedback.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/vendor/requirejs/text.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/bundles/SequenceBlockDisplay.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/vendor/url.min.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/js/vendor/URI.min.js"></script>
<script>
// The video XBlock has an undeclared dependency on edX HTML Utils
RequireJS.require(['HtmlUtils'], function (HtmlUtils) {
Expand All @@ -307,7 +325,7 @@ export default function wrapBlockHtmlForIFrame(html, sourceResources, lmsBaseUrl
files (defined in webpack.common.config.js) to get that entry point and all
of its dependencies.
-->
<script type="text/javascript" src="${lmsBaseUrl}/static/bundles/commons.js"></script>
<script type="text/javascript" src="${studioBaseUrl}/static/studio/bundles/commons.js"></script>
<!-- The video XBlock (and perhaps others?) expect this global: -->
<script>
window.onTouchBasedDevice = function() { return navigator.userAgent.match(/iPhone|iPod|iPad|Android/i); };
Expand All @@ -316,9 +334,13 @@ export default function wrapBlockHtmlForIFrame(html, sourceResources, lmsBaseUrl
<link rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- Capa Problem Editing requires CodeMirror -->
<link rel="stylesheet" href="${lmsBaseUrl}/static/js/vendor/CodeMirror/codemirror.css">
<link rel="stylesheet" href="${studioBaseUrl}/static/studio/js/vendor/CodeMirror/codemirror.css">
<!-- Built-in XBlocks (and some plugins) depends on LMS CSS -->
<link rel="stylesheet" href="${lmsBaseUrl}/static/css/lms-course.css">
<!--<link rel="stylesheet" href="${studioBaseUrl}/static/css/lms-course.css"> -->
<!-- Built-in XBlocks (and some plugins) depends on CMS CSS -->
<link rel="stylesheet" href="${studioBaseUrl}/static/studio/css/studio-main-v1.css">
<link rel="stylesheet" href="${studioBaseUrl}/static/studio/css/vendor/normalize.css">
<link rel="stylesheet" href="${studioBaseUrl}/static/studio/css/vendor/html5-input-polyfills/number-polyfill.css">
<!-- Configure and load MathJax -->
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
Expand Down Expand Up @@ -379,8 +401,18 @@ export default function wrapBlockHtmlForIFrame(html, sourceResources, lmsBaseUrl
<!-- A Studio-served 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 in certain situations. Resetting it to the default "auto" skirts the problem. -->
<body style="min-height: auto; background-color: white">
${html}
<body class="wrapper-xblock level-page studio-xblock-wrapper" style="min-height: auto; background-color: white">
<article class="xblock-render">
<div class="xblock xblock-author_view xblock-author_view-vertical xblock-initialized">
<div class="reorderable-container ui-sortable">
<div class="studio-xblock-wrapper is-draggable">
<section class="wrapper-xblock is-collapsible level-element">
${html}
</section>
</div>
</div>
</div>
</article>
${jsTags}
<script>
window.addEventListener('load', (${blockFrameJS.toString()}));
Expand Down
2 changes: 1 addition & 1 deletion src/course-unit/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,6 @@ export async function setXBlockOrderList(blockId, children) {
export async function getXBlockEditIframeData(itemId) {
const { data } = await getAuthenticatedHttpClient()
.get(getXBlockContainerPreview(itemId));
// console.log({ data });
console.log({ data });
return camelCaseObject(data);
}
1 change: 1 addition & 0 deletions src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ initialize({
ENABLE_UNIT_PAGE: process.env.ENABLE_UNIT_PAGE || 'false',
ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN: process.env.ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN || 'false',
ENABLE_TAGGING_TAXONOMY_PAGES: process.env.ENABLE_TAGGING_TAXONOMY_PAGES || 'false',
SECURE_ORIGIN_XBLOCK_BOOTSTRAP_HTML_URL: process.env.SECURE_ORIGIN_XBLOCK_BOOTSTRAP_HTML_URL,
}, 'CourseAuthoringConfig');
},
},
Expand Down
13 changes: 13 additions & 0 deletions webpack.dev.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const path = require('path');
const { createConfig } = require('@openedx/frontend-build');
const CopyPlugin = require('copy-webpack-plugin');

const config = createConfig('webpack-dev', {
resolve: {
Expand All @@ -14,4 +15,16 @@ const config = createConfig('webpack-dev', {
},
});

/**
* Allow serving xblock-bootstrap.html from the MFE itself.
*/
config.plugins.push(
new CopyPlugin({
patterns: [{
context: path.resolve(__dirname, 'src/course-unit/course-xblock/library-authoring/edit-block/LibraryBlock'),
from: 'xblock-bootstrap.html',
}],
}),
);

module.exports = config;

0 comments on commit c6da976

Please sign in to comment.