Merge pull request #18902 from cpennington/fix-educator-3262-v3

Load all webpack chunks into fragments as correctly-typed resources
This commit is contained in:
Calen Pennington
2018-09-13 10:11:26 -04:00
committed by GitHub
12 changed files with 60 additions and 26 deletions

View File

@@ -63,3 +63,7 @@ def no_webpack_loader(monkeypatch):
"webpack_loader.utils.get_as_tags",
lambda entry, extension=None, config='DEFAULT', attrs='': []
)
monkeypatch.setattr(
"webpack_loader.utils.get_files",
lambda entry, extension=None, config='DEFAULT', attrs='': []
)

View File

@@ -40,6 +40,7 @@ from xmodule.modulestore.django import ModuleI18nService, modulestore
from xmodule.partitions.partitions_service import PartitionService
from xmodule.services import SettingsService
from xmodule.studio_editable import has_author_view
from xmodule.util.xmodule_django import add_webpack_to_fragment
from xmodule.x_module import AUTHOR_VIEW, PREVIEW_VIEWS, STUDENT_VIEW, ModuleSystem, XModule, XModuleDescriptor
import webpack_loader.utils
@@ -304,11 +305,9 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
if isinstance(xblock, (XModule, XModuleDescriptor)):
# Add the webpackified asset tags
class_name = getattr(xblock.__class__, 'unmixed_class', xblock.__class__).__name__
for tag in webpack_loader.utils.get_as_tags(class_name):
frag.add_resource(tag, mimetype='text/html', placement='head')
add_webpack_to_fragment(frag, class_name)
for tag in webpack_loader.utils.get_as_tags("js/factories/xblock_validation"):
frag.add_resource(tag, mimetype='text/html', placement='head')
add_webpack_to_fragment(frag, "js/factories/xblock_validation")
html = render_to_string('studio_xblock_wrapper.html', template_context)
frag = wrap_fragment(frag, html)

View File

@@ -96,15 +96,21 @@ define(['jquery', 'underscore', 'common/js/components/utils/view_utils', 'js/vie
data: this.getRenderParameters(options.page_number, options.force_render),
headers: {Accept: 'application/json'},
success: function(fragment) {
self.handleXBlockFragment(fragment, options);
self.processPaging({requested_page: options.page_number});
self.page.updatePreviewButton(self.collection.showChildrenPreviews);
self.page.renderAddXBlockComponents();
if (options.force_render) {
var $target = $('.studio-xblock-wrapper[data-locator="' + options.force_render + '"]');
// Scroll us to the element with a little buffer at the top for context.
ViewUtils.setScrollOffset($target, ($(window).height() * 0.10));
var originalDone = options.done;
options.done = function() {
self.processPaging({ requested_page: options.page_number });
self.page.updatePreviewButton(self.collection.showChildrenPreviews);
self.page.renderAddXBlockComponents();
if (options.force_render) {
var $target = $('.studio-xblock-wrapper[data-locator="' + options.force_render + '"]');
// Scroll us to the element with a little buffer at the top for context.
ViewUtils.setScrollOffset($target, ($(window).height() * 0.10));
}
if (originalDone) {
originalDone();
}
}
self.handleXBlockFragment(fragment, options);
}
});
},

View File

@@ -137,7 +137,12 @@ define(['jquery', 'underscore', 'common/js/components/utils/view_utils', 'js/vie
// that at least the rendered HTML will be in place.
try {
return this.addXBlockFragmentResources(resources).done(function() {
blockView.updateHtml(element, html);
console.log('Updating HTML');
try {
blockView.updateHtml(element, html);
} catch (e) {
console.error(e, e.stack);
}
});
} catch (e) {
console.error(e, e.stack);

View File

@@ -17,3 +17,7 @@ def no_webpack_loader(monkeypatch):
"webpack_loader.utils.get_as_tags",
lambda entry, extension=None, config='DEFAULT', attrs='': []
)
monkeypatch.setattr(
"webpack_loader.utils.get_files",
lambda entry, extension=None, config='DEFAULT', attrs='': []
)

View File

@@ -149,13 +149,10 @@
}
} else if (mimetype === 'application/javascript') {
if (kind === 'text') {
eval.call(window, data);
console.log("JavaScript text resource eval'd", resource);
// xss-lint: disable=javascript-jquery-append,javascript-concat-html
$head.append('<script>' + data + '</script>');
} else if (kind === 'url') {
// This is a dependency loaded from the LMS (not ideal)
return ViewUtils.loadJavaScript(data).done(function() {
console.log('JavaScript url resource loaded', resource);
});
$script(data, data);
}
} else if (mimetype === 'text/html') {
if (placement === 'head') {

View File

@@ -6,6 +6,7 @@ runtime environment with the djangoapps in common configured to load
# NOTE: we are importing this method so that any module that imports us has access to get_current_request
from crum import get_current_request
import webpack_loader
def get_current_request_hostname():
@@ -18,3 +19,14 @@ def get_current_request_hostname():
hostname = request.META.get('HTTP_HOST')
return hostname
def add_webpack_to_fragment(fragment, bundle_name, extension=None, config='DEFAULT'):
"""
Add all webpack chunks to the supplied fragment as the appropriate resource type.
"""
for chunk in webpack_loader.utils.get_files(bundle_name, extension, config):
if chunk['name'].endswith(('.js', '.js.gz')):
fragment.add_javascript_url(chunk['url'])
elif chunk['name'].endswith(('.css', '.css.gz')):
fragment.add_css_url(chunk['url'])

View File

@@ -16,6 +16,7 @@ from xmodule.mako_module import MakoTemplateBlockBase
from xmodule.progress import Progress
from xmodule.seq_module import SequenceFields
from xmodule.studio_editable import StudioEditableBlock
from xmodule.util.xmodule_django import add_webpack_to_fragment
from xmodule.x_module import STUDENT_VIEW, XModuleFields
from xmodule.xml_module import XmlParserMixin
@@ -98,8 +99,7 @@ class VerticalBlock(SequenceFields, XModuleFields, StudioEditableBlock, XmlParse
'bookmark_id': u"{},{}".format(child_context['username'], unicode(self.location)), # pylint: disable=no-member
}))
for tag in webpack_loader.utils.get_as_tags('VerticalStudentView'):
fragment.add_resource(tag, mimetype='text/html', placement='head')
add_webpack_to_fragment(fragment, 'VerticalStudentView')
fragment.initialize_js('VerticalStudentView')
return fragment

View File

@@ -32,6 +32,7 @@ from xmodule import block_metadata_utils
from xmodule.fields import RelativeTime
from xmodule.errortracker import exc_info_to_str
from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.util.xmodule_django import add_webpack_to_fragment
from opaque_keys.edx.keys import UsageKey
from opaque_keys.edx.asides import AsideUsageKeyV2, AsideDefinitionKeyV2
@@ -260,8 +261,7 @@ def shim_xmodule_js(block, fragment):
fragment.initialize_js('XBlockToXModuleShim')
fragment.json_init_args = {'xmodule-type': block.js_module_name}
for tag in webpack_loader.utils.get_as_tags('XModuleShim'):
fragment.add_resource(tag, mimetype='text/html', placement='head')
add_webpack_to_fragment(fragment, 'XModuleShim')
class XModuleFields(object):

View File

@@ -20,3 +20,7 @@ def no_webpack_loader(monkeypatch):
"webpack_loader.utils.get_as_tags",
lambda entry, extension=None, config='DEFAULT', attrs='': []
)
monkeypatch.setattr(
"webpack_loader.utils.get_files",
lambda entry, extension=None, config='DEFAULT', attrs='': []
)

View File

@@ -26,6 +26,7 @@ from xblock.exceptions import InvalidScopeError
from xblock.scorable import ScorableXBlockMixin
from xmodule.seq_module import SequenceModule
from xmodule.util.xmodule_django import add_webpack_to_fragment
from xmodule.vertical_block import VerticalBlock
from xmodule.x_module import shim_xmodule_js, XModuleDescriptor, XModule, PREVIEW_VIEWS, STUDIO_VIEW
@@ -149,8 +150,7 @@ def wrap_xblock(
if isinstance(block, (XModule, XModuleDescriptor)):
# Add the webpackified asset tags
for tag in webpack_loader.utils.get_as_tags(class_name):
frag.add_resource(tag, mimetype='text/html', placement='head')
add_webpack_to_fragment(frag, class_name)
return wrap_fragment(frag, render_to_string('xblock_wrapper.html', template_context))

View File

@@ -106,7 +106,10 @@ module.exports = Merge.smart({
Popper: 'popper.js', // used by bootstrap
CodeMirror: 'codemirror',
'edx.HtmlUtils': 'edx-ui-toolkit/js/utils/html-utils',
AjaxPrefix: 'ajax_prefix'
AjaxPrefix: 'ajax_prefix',
// This is used by some XModules/XBlocks, which don't have
// any other way to declare that dependency.
$script: 'scriptjs'
}),
// Note: Until karma-webpack releases v3, it doesn't play well with