refactor: define resource paths (not contents) on XModule classes (#32286)

For the XBlocks types that use legacy XModule-style assets (specifically, those that
inherit from `HTMLSnippet`), this is small refactor that brings them a bit closer to being like
standard XBlocks.

Given these class attributes:

    class SomeXModuleLikeBlock(..., HTMLSnippet, ...):
        ...
        studio_view_css = { ... }
        preview_view_css = { ... }
        studio_view_js = { ... }
        preview_view_js = { ... }
        ...

we make it so their values are *paths to the resources*
rather than *the actual content of the resources*.
This is a no-op change, but it'll enable future XModule
asset refactorings which require us to operate on asset
paths rather than contents.

Part of: https://github.com/openedx/edx-platform/issues/32292
This commit is contained in:
Kyle McCormick
2023-05-25 13:30:39 -04:00
committed by GitHub
parent aa7370c773
commit 0f847df73a
12 changed files with 95 additions and 89 deletions

View File

@@ -4,7 +4,7 @@ import logging
import textwrap
from lxml import etree
from pkg_resources import resource_string
from pkg_resources import resource_filename
from web_fragments.fragment import Fragment
from xblock.core import XBlock
from xblock.fields import Scope, String
@@ -75,28 +75,28 @@ class AnnotatableBlock(
preview_view_js = {
'js': [
resource_string(__name__, 'js/src/html/display.js'),
resource_string(__name__, 'js/src/annotatable/display.js'),
resource_string(__name__, 'js/src/javascript_loader.js'),
resource_string(__name__, 'js/src/collapsible.js'),
resource_filename(__name__, 'js/src/html/display.js'),
resource_filename(__name__, 'js/src/annotatable/display.js'),
resource_filename(__name__, 'js/src/javascript_loader.js'),
resource_filename(__name__, 'js/src/collapsible.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
preview_view_css = {
'scss': [
resource_string(__name__, 'css/annotatable/display.scss'),
resource_filename(__name__, 'css/annotatable/display.scss'),
],
}
studio_view_js = {
'js': [
resource_string(__name__, 'js/src/raw/edit/xml.js'),
resource_filename(__name__, 'js/src/raw/edit/xml.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
studio_view_css = {
'scss': [
resource_string(__name__, 'css/codemirror/codemirror.scss'),
resource_filename(__name__, 'css/codemirror/codemirror.scss'),
],
}
studio_js_module_name = "XMLEditingDescriptor"

View File

@@ -19,7 +19,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.utils.encoding import smart_str
from django.utils.functional import cached_property
from lxml import etree
from pkg_resources import resource_string
from pkg_resources import resource_filename
from pytz import utc
from web_fragments.fragment import Fragment
from xblock.core import XBlock
@@ -168,32 +168,32 @@ class ProblemBlock(
preview_view_js = {
'js': [
resource_string(__name__, 'js/src/javascript_loader.js'),
resource_string(__name__, 'js/src/capa/display.js'),
resource_string(__name__, 'js/src/collapsible.js'),
resource_string(__name__, 'js/src/capa/imageinput.js'),
resource_string(__name__, 'js/src/capa/schematic.js'),
resource_filename(__name__, 'js/src/javascript_loader.js'),
resource_filename(__name__, 'js/src/capa/display.js'),
resource_filename(__name__, 'js/src/collapsible.js'),
resource_filename(__name__, 'js/src/capa/imageinput.js'),
resource_filename(__name__, 'js/src/capa/schematic.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js')
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js')
}
preview_view_css = {
'scss': [
resource_string(__name__, 'css/capa/display.scss'),
resource_filename(__name__, 'css/capa/display.scss'),
],
}
studio_view_js = {
'js': [
resource_string(__name__, 'js/src/problem/edit.js'),
resource_filename(__name__, 'js/src/problem/edit.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
studio_view_css = {
'scss': [
resource_string(__name__, 'css/editor/edit.scss'),
resource_string(__name__, 'css/problem/edit.scss'),
resource_filename(__name__, 'css/editor/edit.scss'),
resource_filename(__name__, 'css/problem/edit.scss'),
]
}

View File

@@ -9,7 +9,7 @@ import logging
from lazy import lazy
from lxml import etree
from opaque_keys.edx.locator import BlockUsageLocator
from pkg_resources import resource_string
from pkg_resources import resource_filename
from web_fragments.fragment import Fragment
from xblock.core import XBlock
from xblock.fields import ReferenceList, Scope, String
@@ -148,11 +148,11 @@ class ConditionalBlock(
preview_view_js = {
'js': [
resource_string(__name__, 'js/src/conditional/display.js'),
resource_string(__name__, 'js/src/javascript_loader.js'),
resource_string(__name__, 'js/src/collapsible.js'),
resource_filename(__name__, 'js/src/conditional/display.js'),
resource_filename(__name__, 'js/src/javascript_loader.js'),
resource_filename(__name__, 'js/src/collapsible.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
preview_view_css = {
'scss': [],
@@ -161,8 +161,8 @@ class ConditionalBlock(
mako_template = 'widgets/metadata-edit.html'
studio_js_module_name = 'SequenceDescriptor'
studio_view_js = {
'js': [resource_string(__name__, 'js/src/sequence/edit.js')],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'js': [resource_filename(__name__, 'js/src/sequence/edit.js')],
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
studio_view_css = {
'scss': [],

View File

@@ -8,7 +8,7 @@ import sys
import textwrap
from datetime import datetime
from pkg_resources import resource_string
from pkg_resources import resource_filename
from django.conf import settings
from fs.errors import ResourceNotFound
@@ -144,15 +144,15 @@ class HtmlBlockMixin( # lint-amnesty, pylint: disable=abstract-method
preview_view_js = {
'js': [
resource_string(__name__, 'js/src/html/display.js'),
resource_string(__name__, 'js/src/javascript_loader.js'),
resource_string(__name__, 'js/src/collapsible.js'),
resource_string(__name__, 'js/src/html/imageModal.js'),
resource_string(__name__, 'js/common_static/js/vendor/draggabilly.js'),
resource_filename(__name__, 'js/src/html/display.js'),
resource_filename(__name__, 'js/src/javascript_loader.js'),
resource_filename(__name__, 'js/src/collapsible.js'),
resource_filename(__name__, 'js/src/html/imageModal.js'),
resource_filename(__name__, 'js/common_static/js/vendor/draggabilly.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
preview_view_css = {'scss': [resource_string(__name__, 'css/html/display.scss')]}
preview_view_css = {'scss': [resource_filename(__name__, 'css/html/display.scss')]}
uses_xmodule_styles_setup = True
@@ -164,14 +164,14 @@ class HtmlBlockMixin( # lint-amnesty, pylint: disable=abstract-method
studio_view_js = {
'js': [
resource_string(__name__, 'js/src/html/edit.js')
resource_filename(__name__, 'js/src/html/edit.js')
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
studio_view_css = {
'scss': [
resource_string(__name__, 'css/editor/edit.scss'),
resource_string(__name__, 'css/html/edit.scss')
resource_filename(__name__, 'css/editor/edit.scss'),
resource_filename(__name__, 'css/html/edit.scss')
]
}

View File

@@ -17,7 +17,7 @@ from lazy import lazy
from lxml import etree
from lxml.etree import XMLSyntaxError
from opaque_keys.edx.locator import LibraryLocator
from pkg_resources import resource_string
from pkg_resources import resource_filename
from web_fragments.fragment import Fragment
from webob import Response
from xblock.completable import XBlockCompletionMode
@@ -97,7 +97,7 @@ class LibraryContentBlock(
preview_view_js = {
'js': [],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
preview_view_css = {
'scss': [],
@@ -107,9 +107,9 @@ class LibraryContentBlock(
studio_js_module_name = "VerticalDescriptor"
studio_view_js = {
'js': [
resource_string(__name__, 'js/src/vertical/edit.js'),
resource_filename(__name__, 'js/src/vertical/edit.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
studio_view_css = {
'scss': [],

View File

@@ -68,7 +68,7 @@ import oauthlib.oauth1
from django.conf import settings
from lxml import etree
from oauthlib.oauth1.rfc5849 import signature
from pkg_resources import resource_string
from pkg_resources import resource_filename
from pytz import UTC
from webob import Response
from web_fragments.fragment import Fragment
@@ -374,13 +374,13 @@ class LTIBlock(
preview_view_js = {
'js': [
resource_string(__name__, 'js/src/lti/lti.js')
resource_filename(__name__, 'js/src/lti/lti.js')
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
preview_view_css = {
'scss': [
resource_string(__name__, 'css/lti/lti.scss')
resource_filename(__name__, 'css/lti/lti.scss')
],
}
@@ -389,9 +389,9 @@ class LTIBlock(
studio_js_module_name = 'MetadataOnlyEditingDescriptor'
studio_view_js = {
'js': [
resource_string(__name__, 'js/src/raw/edit/metadata-only.js')
resource_filename(__name__, 'js/src/raw/edit/metadata-only.js')
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
studio_view_css = {
'scss': [],

View File

@@ -13,7 +13,7 @@ import logging
from collections import OrderedDict
from copy import deepcopy
from pkg_resources import resource_string
from pkg_resources import resource_filename
from web_fragments.fragment import Fragment
from lxml import etree
@@ -86,15 +86,15 @@ class PollBlock(
preview_view_js = {
'js': [
resource_string(__name__, 'js/src/javascript_loader.js'),
resource_string(__name__, 'js/src/poll/poll.js'),
resource_string(__name__, 'js/src/poll/poll_main.js')
resource_filename(__name__, 'js/src/javascript_loader.js'),
resource_filename(__name__, 'js/src/poll/poll.js'),
resource_filename(__name__, 'js/src/poll/poll_main.js')
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
preview_view_css = {
'scss': [
resource_string(__name__, 'css/poll/display.scss')
resource_filename(__name__, 'css/poll/display.scss')
],
}
@@ -102,7 +102,7 @@ class PollBlock(
# the static_content command happy.
studio_view_js = {
'js': [],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js')
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js')
}
studio_view_css = {

View File

@@ -14,7 +14,7 @@ from django.conf import settings
from lxml import etree
from opaque_keys.edx.keys import UsageKey
from pkg_resources import resource_string
from pkg_resources import resource_filename
from pytz import UTC
from web_fragments.fragment import Fragment
from xblock.completable import XBlockCompletionMode
@@ -273,14 +273,14 @@ class SequenceBlock(
preview_view_js = {
'js': [
resource_string(__name__, 'js/src/sequence/display.js'),
resource_filename(__name__, 'js/src/sequence/display.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js')
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js')
}
preview_view_css = {
'scss': [
resource_string(__name__, 'css/sequence/display.scss'),
resource_filename(__name__, 'css/sequence/display.scss'),
],
}
@@ -288,7 +288,7 @@ class SequenceBlock(
# the static_content command happy.
studio_view_js = {
'js': [],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js')
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js')
}
studio_view_css = {

View File

@@ -12,7 +12,7 @@ from uuid import uuid4
from django.utils.functional import cached_property
from lxml import etree
from pkg_resources import resource_string
from pkg_resources import resource_filename
from web_fragments.fragment import Fragment
from webob import Response
from xblock.core import XBlock
@@ -160,7 +160,7 @@ class SplitTestBlock( # lint-amnesty, pylint: disable=abstract-method
preview_view_js = {
'js': [],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
preview_view_css = {
'scss': [],
@@ -169,8 +169,8 @@ class SplitTestBlock( # lint-amnesty, pylint: disable=abstract-method
mako_template = "widgets/metadata-only-edit.html"
studio_js_module_name = 'SequenceDescriptor'
studio_view_js = {
'js': [resource_string(__name__, 'js/src/sequence/edit.js')],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'js': [resource_filename(__name__, 'js/src/sequence/edit.js')],
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
studio_view_css = {
'scss': [],

View File

@@ -13,7 +13,7 @@ import os
import sys
import textwrap
from collections import defaultdict
from pkg_resources import resource_string
from pkg_resources import resource_filename
import django
from docopt import docopt
@@ -43,27 +43,27 @@ class VideoBlock(HTMLSnippet): # lint-amnesty, pylint: disable=abstract-method
preview_view_js = {
'js': [
resource_string(__name__, 'js/src/video/10_main.js'),
resource_filename(__name__, 'js/src/video/10_main.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js')
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js')
}
preview_view_css = {
'scss': [
resource_string(__name__, 'css/video/display.scss'),
resource_string(__name__, 'css/video/accessible_menu.scss'),
resource_filename(__name__, 'css/video/display.scss'),
resource_filename(__name__, 'css/video/accessible_menu.scss'),
],
}
studio_view_js = {
'js': [
resource_string(__name__, 'js/src/tabs/tabs-aggregator.js'),
resource_filename(__name__, 'js/src/tabs/tabs-aggregator.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
studio_view_css = {
'scss': [
resource_string(__name__, 'css/tabs/tabs.scss'),
resource_filename(__name__, 'css/tabs/tabs.scss'),
]
}
@@ -132,7 +132,9 @@ def _write_styles(selector, output_root, classes, css_attribute, suffix):
for class_ in classes:
class_css = getattr(class_, css_attribute)()
for filetype in ('sass', 'scss', 'css'):
for idx, fragment in enumerate(class_css.get(filetype, [])):
for idx, fragment_path in enumerate(class_css.get(filetype, [])):
with open(fragment_path, 'rb') as fragment_file:
fragment = fragment_file.read()
css_fragments[idx, filetype, fragment].add(class_.__name__)
css_imports = defaultdict(set)
for (idx, filetype, fragment), classes in sorted(css_fragments.items()): # lint-amnesty, pylint: disable=redefined-argument-from-local
@@ -177,10 +179,14 @@ def _write_js(output_root, classes, js_attribute):
fragment_owners = defaultdict(list)
for class_ in classes:
module_js = getattr(class_, js_attribute)()
with open(module_js.get('xmodule_js'), 'rb') as xmodule_js_file:
xmodule_js_fragment = xmodule_js_file.read()
# It will enforce 000 prefix for xmodule.js.
fragment_owners[(0, 'js', module_js.get('xmodule_js'))].append(getattr(class_, js_attribute + '_bundle_name')())
fragment_owners[(0, 'js', xmodule_js_fragment)].append(getattr(class_, js_attribute + '_bundle_name')())
for filetype in ('coffee', 'js'):
for idx, fragment in enumerate(module_js.get(filetype, [])):
for idx, fragment_path in enumerate(module_js.get(filetype, [])):
with open(fragment_path, 'rb') as fragment_file:
fragment = fragment_file.read()
fragment_owners[(idx + 1, filetype, fragment)].append(getattr(class_, js_attribute + '_bundle_name')())
for (idx, filetype, fragment), owners in sorted(fragment_owners.items()):

View File

@@ -6,7 +6,7 @@ from string import Template
from xblock.core import XBlock
from lxml import etree
from pkg_resources import resource_string
from pkg_resources import resource_filename
from web_fragments.fragment import Fragment
from xmodule.editing_block import EditingMixin
from xmodule.raw_block import RawMixin
@@ -67,17 +67,17 @@ class CustomTagBlock(CustomTagTemplateBlock): # pylint: disable=abstract-method
preview_view_js = {
'js': [],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
preview_view_css = {
'scss': [],
}
studio_view_js = {
'js': [resource_string(__name__, 'js/src/raw/edit/xml.js')],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'js': [resource_filename(__name__, 'js/src/raw/edit/xml.js')],
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
studio_view_css = {
'scss': [resource_string(__name__, 'css/codemirror/codemirror.scss')],
'scss': [resource_filename(__name__, 'css/codemirror/codemirror.scss')],
}
def studio_view(self, _context):

View File

@@ -10,7 +10,7 @@ If student have answered - words he entered and cloud.
import json
import logging
from pkg_resources import resource_string
from pkg_resources import resource_filename
from web_fragments.fragment import Fragment
from xblock.core import XBlock
@@ -114,21 +114,21 @@ class WordCloudBlock( # pylint: disable=abstract-method
preview_view_js = {
'js': [
resource_string(__name__, 'assets/word_cloud/src/js/word_cloud.js'),
resource_filename(__name__, 'assets/word_cloud/src/js/word_cloud.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
preview_view_css = {
'scss': [
resource_string(__name__, 'css/word_cloud/display.scss'),
resource_filename(__name__, 'css/word_cloud/display.scss'),
],
}
studio_view_js = {
'js': [
resource_string(__name__, 'js/src/raw/edit/metadata-only.js'),
resource_filename(__name__, 'js/src/raw/edit/metadata-only.js'),
],
'xmodule_js': resource_string(__name__, 'js/src/xmodule.js'),
'xmodule_js': resource_filename(__name__, 'js/src/xmodule.js'),
}
studio_view_css = {
'scss': [],