Have DiscussionXBlock take care of loading JS and CSS files it depends on.
* Add openedx.core.lib.xblock_builtin.get_css_dependencies and get_js_dependencies, which respect PIPELINE_ENABLED setting when determining dependencies. * Move new discussion-related Sass files into discussion subdirectory. * Use "load_unicode" instead of "render_template" to load JS to add to fragment for DiscussionXBlock. * Remove unused "course" parameter from context for DiscussionXBlock.student_view. * Add RTL stylesheet for DiscussionXBlock, and enable the block to load correct stylesheet. * Load MathJax only once, and include code for configuring MathJax in discussion bundle. * Make sure username renders correctly in DiscussionXBlock response header. * Move WYSIWYIG Markdown editor styles to _build-discussion.scss. * Remove unnecessary import of discussion/utilities/v1-compatibility from _build-discussion.scss. * Keep courseware-chromeless.html in sync with courseware.html. * Load CSS for discussions on Teams tab. This makes it possible to remove CSS for discussions from Sass files for "Course" tab. * Load js/src/tooltip_manager.js, jquery.autocomplete.js and jquery.autocomplete.css on "Course" tab.
This commit is contained in:
committed by
Jillian Vogel
parent
5573690af6
commit
baa9d06e97
@@ -22,7 +22,11 @@ from openedx.core.lib.xblock_utils import (
|
||||
replace_jump_to_id_urls,
|
||||
replace_course_urls,
|
||||
replace_static_urls,
|
||||
sanitize_html_id
|
||||
sanitize_html_id,
|
||||
)
|
||||
from openedx.core.lib.xblock_builtin import (
|
||||
get_css_dependencies,
|
||||
get_js_dependencies,
|
||||
)
|
||||
|
||||
|
||||
@@ -181,3 +185,41 @@ class TestXblockUtils(SharedModuleStoreTestCase):
|
||||
clean_string = sanitize_html_id(dirty_string)
|
||||
|
||||
self.assertEqual(clean_string, 'I_have_un_allowed_characters')
|
||||
|
||||
@ddt.data(
|
||||
(True, ["combined.css"]),
|
||||
(False, ["a.css", "b.css", "c.css"]),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_get_css_dependencies(self, pipeline_enabled, expected_css_dependencies):
|
||||
"""
|
||||
Verify that `get_css_dependencies` returns correct list of files.
|
||||
"""
|
||||
pipeline_css = {
|
||||
'style-group': {
|
||||
'source_filenames': ["a.css", "b.css", "c.css"],
|
||||
'output_filename': "combined.css"
|
||||
}
|
||||
}
|
||||
with self.settings(PIPELINE_ENABLED=pipeline_enabled, PIPELINE_CSS=pipeline_css):
|
||||
css_dependencies = get_css_dependencies("style-group")
|
||||
self.assertEqual(css_dependencies, expected_css_dependencies)
|
||||
|
||||
@ddt.data(
|
||||
(True, ["combined.js"]),
|
||||
(False, ["a.js", "b.js", "c.js"]),
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_get_js_dependencies(self, pipeline_enabled, expected_js_dependencies):
|
||||
"""
|
||||
Verify that `get_js_dependencies` returns correct list of files.
|
||||
"""
|
||||
pipeline_js = {
|
||||
'js-group': {
|
||||
'source_filenames': ["a.js", "b.js", "c.js"],
|
||||
'output_filename': "combined.js"
|
||||
}
|
||||
}
|
||||
with self.settings(PIPELINE_ENABLED=pipeline_enabled, PIPELINE_JS=pipeline_js):
|
||||
js_dependencies = get_js_dependencies("js-group")
|
||||
self.assertEqual(js_dependencies, expected_js_dependencies)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
"""
|
||||
Helper functions shared by built-in XBlocks.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
def get_css_dependencies(group):
|
||||
"""
|
||||
Returns list of CSS dependencies belonging to `group` in settings.PIPELINE_JS.
|
||||
|
||||
Respects `PIPELINE_ENABLED` setting.
|
||||
"""
|
||||
if settings.PIPELINE_ENABLED:
|
||||
return [settings.PIPELINE_CSS[group]['output_filename']]
|
||||
else:
|
||||
return settings.PIPELINE_CSS[group]['source_filenames']
|
||||
|
||||
|
||||
def get_js_dependencies(group):
|
||||
"""
|
||||
Returns list of JS dependencies belonging to `group` in settings.PIPELINE_JS.
|
||||
|
||||
Respects `PIPELINE_ENABLED` setting.
|
||||
"""
|
||||
if settings.PIPELINE_ENABLED:
|
||||
return [settings.PIPELINE_JS[group]['output_filename']]
|
||||
else:
|
||||
return settings.PIPELINE_JS[group]['source_filenames']
|
||||
|
||||
@@ -4,6 +4,9 @@ Discussion XBlock
|
||||
"""
|
||||
import logging
|
||||
|
||||
from django.templatetags.static import static
|
||||
from django.utils.translation import get_language_bidi
|
||||
|
||||
from xblockutils.resources import ResourceLoader
|
||||
from xblockutils.studio_editable import StudioEditableXBlockMixin
|
||||
from xmodule.raw_module import RawDescriptor
|
||||
@@ -13,6 +16,9 @@ from xblock.fields import Scope, String, UNIQUE_ID
|
||||
from xblock.fragment import Fragment
|
||||
from xmodule.xml_module import XmlParserMixin
|
||||
|
||||
from openedx.core.lib.xblock_builtin import get_css_dependencies, get_js_dependencies
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
loader = ResourceLoader(__name__) # pylint: disable=invalid-name
|
||||
|
||||
@@ -88,6 +94,57 @@ class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, XmlParserMixin):
|
||||
return None
|
||||
return user_service._django_user # pylint: disable=protected-access
|
||||
|
||||
@staticmethod
|
||||
def vendor_js_dependencies():
|
||||
"""
|
||||
Returns list of vendor JS files that this XBlock depends on.
|
||||
|
||||
The helper function that it uses to obtain the list of vendor JS files
|
||||
works in conjunction with the Django pipeline to ensure that in development mode
|
||||
the files are loaded individually, but in production just the single bundle is loaded.
|
||||
"""
|
||||
return get_js_dependencies('discussion_vendor')
|
||||
|
||||
@staticmethod
|
||||
def js_dependencies():
|
||||
"""
|
||||
Returns list of JS files that this XBlock depends on.
|
||||
|
||||
The helper function that it uses to obtain the list of JS files
|
||||
works in conjunction with the Django pipeline to ensure that in development mode
|
||||
the files are loaded individually, but in production just the single bundle is loaded.
|
||||
"""
|
||||
return get_js_dependencies('discussion')
|
||||
|
||||
@staticmethod
|
||||
def css_dependencies():
|
||||
"""
|
||||
Returns list of CSS files that this XBlock depends on.
|
||||
|
||||
The helper function that it uses to obtain the list of CSS files
|
||||
works in conjunction with the Django pipeline to ensure that in development mode
|
||||
the files are loaded individually, but in production just the single bundle is loaded.
|
||||
"""
|
||||
if get_language_bidi():
|
||||
return get_css_dependencies('style-inline-discussion-rtl')
|
||||
else:
|
||||
return get_css_dependencies('style-inline-discussion')
|
||||
|
||||
def add_resource_urls(self, fragment):
|
||||
"""
|
||||
Adds URLs for JS and CSS resources that this XBlock depends on to `fragment`.
|
||||
"""
|
||||
# Head dependencies
|
||||
for vendor_js_file in self.vendor_js_dependencies():
|
||||
fragment.add_resource_url(static(vendor_js_file), "application/javascript", "head")
|
||||
|
||||
for css_file in self.css_dependencies():
|
||||
fragment.add_css_url(static(css_file))
|
||||
|
||||
# Body dependencies
|
||||
for js_file in self.js_dependencies():
|
||||
fragment.add_javascript_url(static(js_file))
|
||||
|
||||
def has_permission(self, permission):
|
||||
"""
|
||||
Encapsulates lms specific functionality, as `has_permission` is not
|
||||
@@ -108,12 +165,11 @@ class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, XmlParserMixin):
|
||||
"""
|
||||
fragment = Fragment()
|
||||
|
||||
course = self.runtime.modulestore.get_course(self.course_key)
|
||||
self.add_resource_urls(fragment)
|
||||
|
||||
context = {
|
||||
'discussion_id': self.discussion_id,
|
||||
'user': self.django_user,
|
||||
'course': course,
|
||||
'course_id': self.course_key,
|
||||
'can_create_thread': self.has_permission("create_thread"),
|
||||
'can_create_comment': self.has_permission("create_comment"),
|
||||
|
||||
Reference in New Issue
Block a user