diff --git a/cms/envs/bok_choy.py b/cms/envs/bok_choy.py index 84916debe9..0204e8cbe6 100644 --- a/cms/envs/bok_choy.py +++ b/cms/envs/bok_choy.py @@ -1,9 +1,9 @@ """ -Settings for Bok Choy tests that are used for running CMS and LMS. +Settings for Bok Choy tests that are used when running Studio. Bok Choy uses two different settings files: 1. test_static_optimized is used when invoking collectstatic -2. bok_choy is used when running CMS and LMS +2. bok_choy is used when running the tests Note: it isn't possible to have a single settings file, because Django doesn't support both generating static assets to a directory and also serving static diff --git a/cms/envs/common.py b/cms/envs/common.py index a683dce912..bae11ac423 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -455,7 +455,7 @@ MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage' EMBARGO_SITE_REDIRECT_URL = None ############################### Pipeline ####################################### -STATICFILES_STORAGE = 'cms.lib.django_require.staticstorage.OptimizedCachedRequireJsStorage' +STATICFILES_STORAGE = 'openedx.core.lib.django_require.staticstorage.OptimizedCachedRequireJsStorage' from openedx.core.lib.rooted_paths import rooted_glob @@ -573,7 +573,7 @@ REQUIRE_BASE_URL = "./" # A sensible value would be 'app.build.js'. Leave blank to use the built-in default build profile. # Set to False to disable running the default profile (e.g. if only using it to build Standalone # Modules) -REQUIRE_BUILD_PROFILE = "build.js" +REQUIRE_BUILD_PROFILE = "cms/js/build.js" # The name of the require.js script used by your project, relative to REQUIRE_BASE_URL. REQUIRE_JS = "js/vendor/require.js" @@ -592,6 +592,8 @@ REQUIRE_EXCLUDE = ("build.txt",) # It can also be a path to a custom class that subclasses require.environments.Environment and defines some "args" function that returns a list with the command arguments to execute. REQUIRE_ENVIRONMENT = "node" +################################# TENDER ###################################### + # If you want to enable Tender integration (http://tenderapp.com/), # put in the subdomain where Tender hosts tender_widget.js. For example, # if you want to use the URL https://example.tenderapp.com/tender_widget.js, diff --git a/cms/envs/devstack_optimized.py b/cms/envs/devstack_optimized.py index 5694a96ff1..7e1cc2c792 100644 --- a/cms/envs/devstack_optimized.py +++ b/cms/envs/devstack_optimized.py @@ -29,6 +29,9 @@ TEST_ROOT = REPO_ROOT / "test_root" # pylint: disable=no-value-for-parameter # Enable debug so that static assets are served by Django DEBUG = True +# Set REQUIRE_DEBUG to false so that it behaves like production +REQUIRE_DEBUG = False + # Serve static files at /static directly from the staticfiles directory under test root. # Note: optimized files for testing are generated with settings from test_static_optimized STATIC_URL = "/static/" diff --git a/cms/envs/test_static_optimized.py b/cms/envs/test_static_optimized.py index ae5d91f521..9d7a8fc63d 100644 --- a/cms/envs/test_static_optimized.py +++ b/cms/envs/test_static_optimized.py @@ -33,3 +33,4 @@ STATIC_ROOT = (TEST_ROOT / "staticfiles" / "cms").abspath() # 1. Uglify is by far the slowest part of the build process # 2. Having full source code makes debugging tests easier for developers os.environ['REQUIRE_BUILD_PROFILE_OPTIMIZE'] = 'none' +PIPELINE_JS_COMPRESSOR = None diff --git a/cms/static/build.js b/cms/static/cms/js/build.js similarity index 94% rename from cms/static/build.js rename to cms/static/cms/js/build.js index 933041abe5..dc9abfdc5b 100644 --- a/cms/static/build.js +++ b/cms/static/cms/js/build.js @@ -1,19 +1,21 @@ (function () { 'use strict'; + var commonLibrariesPath = 'common/js/common_libraries'; + var getModule = function (moduleName, excludeCommonDeps) { var module = { name: moduleName }; if (excludeCommonDeps) { - module.exclude = ['js/factories/common_deps']; + module.exclude = [commonLibrariesPath]; } return module; }; var getModulesList = function (modules) { - var result = [getModule('js/factories/common_deps')]; + var result = [getModule(commonLibrariesPath)]; return result.concat(modules.map(function (moduleName) { return getModule(moduleName, true); })); @@ -84,6 +86,17 @@ 'tender': 'empty:', 'youtube': 'empty:' }, + + /** + * Inline requireJS text templates. + */ + inlineText: true, + + /** + * Stub out requireJS text in the optimized file, but leave available for non-optimized development use. + */ + stubModules: ["text"], + /** * If shim config is used in the app during runtime, duplicate the config * here. Necessary if shim config is used, so that the shim's dependencies diff --git a/cms/static/require-config.js b/cms/static/cms/js/require-config.js similarity index 100% rename from cms/static/require-config.js rename to cms/static/cms/js/require-config.js diff --git a/cms/templates/base.html b/cms/templates/base.html index 948ebf3c58..1e52fb589e 100644 --- a/cms/templates/base.html +++ b/cms/templates/base.html @@ -36,7 +36,7 @@ import json - <%block name="view_notes"> + <%block name="view_notes"> ${_("Skip to main content")} @@ -46,7 +46,7 @@ import json var require = {baseUrl: window.baseUrl}; - + ## js templates + diff --git a/cms/static/js/factories/common_deps.js b/common/static/common/js/common_libraries.js similarity index 82% rename from cms/static/js/factories/common_deps.js rename to common/static/common/js/common_libraries.js index ded2bed352..1e935d6821 100644 --- a/cms/static/js/factories/common_deps.js +++ b/common/static/common/js/common_libraries.js @@ -1 +1 @@ -define(['domReady!', 'jquery', 'backbone', 'underscore', 'gettext', 'text']); +define(['domReady!', 'jquery', 'backbone', 'underscore', 'gettext']); diff --git a/lms/djangoapps/teams/static/teams/js/spec/teams_factory_spec.js b/lms/djangoapps/teams/static/teams/js/spec/teams_factory_spec.js index 1bc683c435..eb5709354a 100644 --- a/lms/djangoapps/teams/static/teams/js/spec/teams_factory_spec.js +++ b/lms/djangoapps/teams/static/teams/js/spec/teams_factory_spec.js @@ -2,12 +2,12 @@ define(["jquery", "backbone", "teams/js/teams_tab_factory"], function($, Backbone, TeamsTabFactory) { 'use strict'; - describe("teams django app", function() { + describe("Teams tab", function() { var teamsTab; beforeEach(function() { setFixtures('
'); - teamsTab = new TeamsTabFactory({results: []}, '', 'edX/DemoX/Demo_Course'); + teamsTab = new TeamsTabFactory($(".teams-content"), {results: []}, '', 'edX/DemoX/Demo_Course'); }); afterEach(function() { diff --git a/lms/djangoapps/teams/static/teams/js/teams_tab_factory.js b/lms/djangoapps/teams/static/teams/js/teams_tab_factory.js index 1fa785cca4..8a0a6cc64a 100644 --- a/lms/djangoapps/teams/static/teams/js/teams_tab_factory.js +++ b/lms/djangoapps/teams/static/teams/js/teams_tab_factory.js @@ -3,11 +3,11 @@ define(['jquery', 'teams/js/views/teams_tab', 'teams/js/collections/topic'], function ($, TeamsTabView, TopicCollection) { - return function (topics, topics_url, course_id) { + return function (element, topics, topics_url, course_id) { var topicCollection = new TopicCollection(topics, {url: topics_url, course_id: course_id, parse: true}); topicCollection.bootstrap(); var view = new TeamsTabView({ - el: $('.teams-content'), + el: element, topicCollection: topicCollection }); view.render(); diff --git a/lms/djangoapps/teams/templates/teams/teams.html b/lms/djangoapps/teams/templates/teams/teams.html index 4752404542..912d3d5b68 100644 --- a/lms/djangoapps/teams/templates/teams/teams.html +++ b/lms/djangoapps/teams/templates/teams/teams.html @@ -21,11 +21,7 @@ <%block name="js_extra"> - +<%static:require_module module_name="teams/js/teams_tab_factory" class_name="TeamsTabFactory"> + TeamsTabFactory($('.teams-content'), ${ json.dumps(topics, cls=EscapedEdxJSONEncoder) }, '${ topics_url }', '${ unicode(course.id) }'); + diff --git a/lms/envs/bok_choy.py b/lms/envs/bok_choy.py index 897029a772..00cfaadbcb 100644 --- a/lms/envs/bok_choy.py +++ b/lms/envs/bok_choy.py @@ -1,5 +1,13 @@ """ -Settings for bok choy tests +Settings for Bok Choy tests that are used when running LMS. + +Bok Choy uses two different settings files: +1. test_static_optimized is used when invoking collectstatic +2. bok_choy is used when running the tests + +Note: it isn't possible to have a single settings file, because Django doesn't +support both generating static assets to a directory and also serving static +from the same directory. """ import os @@ -48,6 +56,20 @@ update_module_store_settings( ) ############################ STATIC FILES ############################# + +# Enable debug so that static assets are served by Django +DEBUG = True + +# Serve static files at /static directly from the staticfiles directory under test root +# Note: optimized files for testing are generated with settings from test_static_optimized +STATIC_URL = "/static/" +STATICFILES_FINDERS = ( + 'staticfiles.finders.FileSystemFinder', +) +STATICFILES_DIRS = ( + (TEST_ROOT / "staticfiles" / "lms").abspath(), +) + DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' MEDIA_ROOT = TEST_ROOT / "uploads" MEDIA_URL = "/static/uploads/" @@ -74,9 +96,6 @@ OPEN_ENDED_GRADING_INTERFACE['url'] = 'http://localhost:8041/' EDXNOTES_PUBLIC_API = 'http://localhost:8042/api/v1' EDXNOTES_INTERNAL_API = 'http://localhost:8042/api/v1' -# Enable django-pipeline and staticfiles -STATIC_ROOT = (TEST_ROOT / "staticfiles" / "lms").abspath() - # Silence noisy logs import logging LOG_OVERRIDES = [ @@ -106,9 +125,6 @@ FEATURES['ENABLE_TEAMS'] = True # Enable custom content licensing FEATURES['LICENSING'] = True -# Unfortunately, we need to use debug mode to serve staticfiles -DEBUG = True - ########################### Entrance Exams ################################# FEATURES['MILESTONES_APP'] = True FEATURES['ENTRANCE_EXAMS'] = True diff --git a/lms/envs/common.py b/lms/envs/common.py index 1cd367d770..e49b889451 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -1199,7 +1199,7 @@ X_FRAME_OPTIONS = 'ALLOW' ############################### Pipeline ####################################### -STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage' +STATICFILES_STORAGE = 'openedx.core.lib.django_require.staticstorage.OptimizedCachedRequireJsStorage' from openedx.core.lib.rooted_paths import rooted_glob @@ -1231,6 +1231,8 @@ base_vendor_js = [ 'js/vendor/underscore-min.js', 'js/vendor/require.js', 'js/RequireJS-namespace-undefine.js', + 'js/vendor/URI.min.js', + 'js/vendor/backbone-min.js' ] main_vendor_js = base_vendor_js + [ @@ -1239,7 +1241,12 @@ main_vendor_js = base_vendor_js + [ 'js/vendor/jquery.qtip.min.js', 'js/vendor/swfobject/swfobject.js', 'js/vendor/jquery.ba-bbq.min.js', - 'js/vendor/URI.min.js', +] + +# Common files used by both RequireJS code and non-RequireJS code +base_application_js = [ + 'js/src/utility.js', + 'js/src/logger.js', ] dashboard_js = ( @@ -1265,7 +1272,6 @@ student_account_js = [ 'js/toggle_login_modal.js', 'js/sticky_filter.js', 'js/query-params.js', - 'js/src/utility.js', 'js/src/accessibility_tools.js', 'js/src/ie_shim.js', 'js/src/string_utils.js', @@ -1291,7 +1297,6 @@ verify_student_js = [ 'js/toggle_login_modal.js', 'js/sticky_filter.js', 'js/query-params.js', - 'js/src/utility.js', 'js/src/accessibility_tools.js', 'js/src/ie_shim.js', 'js/src/string_utils.js', @@ -1478,20 +1483,23 @@ project_js = set(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/**/*.js')) - s PIPELINE_JS = { + 'base_application': { + 'source_filenames': base_application_js, + 'output_filename': 'js/lms-base-application.js', + }, + 'application': { # Application will contain all paths not in courseware_only_js - 'source_filenames': ['js/xblock/core.js'] + sorted(common_js) + sorted(project_js) + [ + 'source_filenames': ['js/xblock/core.js'] + sorted(common_js) + sorted(project_js) + base_application_js + [ 'js/form.ext.js', 'js/my_courses_dropdown.js', 'js/toggle_login_modal.js', 'js/sticky_filter.js', 'js/query-params.js', - 'js/src/utility.js', 'js/src/accessibility_tools.js', 'js/src/ie_shim.js', 'js/src/string_utils.js', - 'js/src/logger.js', ], 'output_filename': 'js/lms-application.js', }, @@ -1579,10 +1587,6 @@ PIPELINE_JS = { 'source_filenames': certificates_web_view_js, 'output_filename': 'js/certificates/web_view.js' }, - 'utility': { - 'source_filenames': ['js/src/utility.js'], - 'output_filename': 'js/utility.js' - }, 'credit_wv': { 'source_filenames': credit_web_view_js, 'output_filename': 'js/credit/web_view.js' @@ -1616,7 +1620,10 @@ PIPELINE_JS_COMPRESSOR = "pipeline.compressors.uglifyjs.UglifyJSCompressor" STATICFILES_IGNORE_PATTERNS = ( "sass/*", - "coffee/*", + "coffee/*.coffee", + "coffee/*/*.coffee", + "coffee/*/*/*.coffee", + "coffee/*/*/*/*.coffee", # Symlinks used by js-test-tool "xmodule_js", @@ -1628,6 +1635,36 @@ PIPELINE_UGLIFYJS_BINARY = 'node_modules/.bin/uglifyjs' PIPELINE_COMPILE_INPLACE = True +################################# DJANGO-REQUIRE ############################### + +# The baseUrl to pass to the r.js optimizer, relative to STATIC_ROOT. +REQUIRE_BASE_URL = "./" + +# The name of a build profile to use for your project, relative to REQUIRE_BASE_URL. +# A sensible value would be 'app.build.js'. Leave blank to use the built-in default build profile. +# Set to False to disable running the default profile (e.g. if only using it to build Standalone +# Modules) +REQUIRE_BUILD_PROFILE = "lms/js/build.js" + +# The name of the require.js script used by your project, relative to REQUIRE_BASE_URL. +REQUIRE_JS = "js/vendor/require.js" + +# A dictionary of standalone modules to build with almond.js. +REQUIRE_STANDALONE_MODULES = {} + +# Whether to run django-require in debug mode. +REQUIRE_DEBUG = False + +# A tuple of files to exclude from the compilation result of r.js. +REQUIRE_EXCLUDE = ("build.txt",) + +# The execution environment in which to run r.js: auto, node or rhino. +# auto will autodetect the environment and make use of node if available and rhino if not. +# It can also be a path to a custom class that subclasses require.environments.Environment +# and defines some "args" function that returns a list with the command arguments to execute. +REQUIRE_ENVIRONMENT = "node" + + ################################# CELERY ###################################### # Message configuration diff --git a/lms/envs/devstack.py b/lms/envs/devstack.py index d097e5a74a..ca98653994 100644 --- a/lms/envs/devstack.py +++ b/lms/envs/devstack.py @@ -79,6 +79,12 @@ def should_show_debug_toolbar(_): ########################### PIPELINE ################################# +# # Skip RequireJS optimizer in development +STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage' + +# Whether to run django-require in debug mode. +REQUIRE_DEBUG = DEBUG + PIPELINE_SASS_ARGUMENTS = '--debug-info --require {proj_dir}/static/sass/bourbon/lib/bourbon.rb'.format(proj_dir=PROJECT_ROOT) ########################### VERIFIED CERTIFICATES ################################# diff --git a/lms/envs/devstack_optimized.py b/lms/envs/devstack_optimized.py index 26b8cc3e21..71778a32f9 100644 --- a/lms/envs/devstack_optimized.py +++ b/lms/envs/devstack_optimized.py @@ -29,6 +29,9 @@ TEST_ROOT = REPO_ROOT / "test_root" # pylint: disable=no-value-for-parameter # Enable debug so that static assets are served by Django DEBUG = True +# Set REQUIRE_DEBUG to false so that it behaves like production +REQUIRE_DEBUG = False + # Serve static files at /static directly from the staticfiles directory under test root. # Note: optimized files for testing are generated with settings from test_static_optimized STATIC_URL = "/static/" diff --git a/lms/envs/test_static_optimized.py b/lms/envs/test_static_optimized.py index 8ee4091d47..223724ee16 100644 --- a/lms/envs/test_static_optimized.py +++ b/lms/envs/test_static_optimized.py @@ -45,3 +45,4 @@ STATIC_ROOT = (TEST_ROOT / "staticfiles" / "lms").abspath() # 1. Uglify is by far the slowest part of the build process # 2. Having full source code makes debugging tests easier for developers os.environ['REQUIRE_BUILD_PROFILE_OPTIMIZE'] = 'none' +PIPELINE_JS_COMPRESSOR = None diff --git a/lms/static/lms/js/build.js b/lms/static/lms/js/build.js new file mode 100644 index 0000000000..be47a8bd71 --- /dev/null +++ b/lms/static/lms/js/build.js @@ -0,0 +1,137 @@ +(function () { + 'use strict'; + + var getModulesList = function (modules) { + return modules.map(function (moduleName) { + return { name: moduleName }; + }); + }; + + var jsOptimize = process.env.REQUIRE_BUILD_PROFILE_OPTIMIZE !== undefined ? + process.env.REQUIRE_BUILD_PROFILE_OPTIMIZE : 'uglify2'; + + return { + namespace: "RequireJS", + /** + * List the modules that will be optimized. All their immediate and deep + * dependencies will be included in the module's file when the build is + * done. + */ + modules: getModulesList([ + 'teams/js/teams_tab_factory' + ]), + + /** + * By default all the configuration for optimization happens from the command + * line or by properties in the config file, and configuration that was + * passed to requirejs as part of the app's runtime "main" JS file is *not* + * considered. However, if you prefer the "main" JS file configuration + * to be read for the build so that you do not have to duplicate the values + * in a separate configuration, set this property to the location of that + * main JS file. The first requirejs({}), require({}), requirejs.config({}), + * or require.config({}) call found in that file will be used. + * As of 2.1.10, mainConfigFile can be an array of values, with the last + * value's config take precedence over previous values in the array. + */ + mainConfigFile: 'require-config.js', + /** + * Set paths for modules. If relative paths, set relative to baseUrl above. + * If a special value of "empty:" is used for the path value, then that + * acts like mapping the path to an empty file. It allows the optimizer to + * resolve the dependency to path, but then does not include it in the output. + * Useful to map module names that are to resources on a CDN or other + * http: URL when running in the browser and during an optimization that + * file should be skipped because it has no dependencies. + */ + paths: { + 'gettext': 'empty:', + 'coffee/src/ajax_prefix': 'empty:', + 'jquery': 'empty:', + 'jquery.cookie': 'empty:', + 'jquery.url': 'empty:', + 'backbone': 'empty:', + 'underscore': 'empty:', + 'logger': 'empty:', + 'utility': 'empty:', + 'URI': 'empty:' + }, + + /** + * Inline requireJS text templates. + */ + inlineText: true, + + /** + * Stub out requireJS text in the optimized file, but leave available for non-optimized development use. + */ + stubModules: ["text"], + + /** + * If shim config is used in the app during runtime, duplicate the config + * here. Necessary if shim config is used, so that the shim's dependencies + * are included in the build. Using "mainConfigFile" is a better way to + * pass this information though, so that it is only listed in one place. + * However, if mainConfigFile is not an option, the shim config can be + * inlined in the build config. + */ + shim: {}, + /** + * Introduced in 2.1.2: If using "dir" for an output directory, normally the + * optimize setting is used to optimize the build bundles (the "modules" + * section of the config) and any other JS file in the directory. However, if + * the non-build bundle JS files will not be loaded after a build, you can + * skip the optimization of those files, to speed up builds. Set this value + * to true if you want to skip optimizing those other non-build bundle JS + * files. + */ + skipDirOptimize: true, + /** + * When the optimizer copies files from the source location to the + * destination directory, it will skip directories and files that start + * with a ".". If you want to copy .directories or certain .files, for + * instance if you keep some packages in a .packages directory, or copy + * over .htaccess files, you can set this to null. If you want to change + * the exclusion rules, change it to a different regexp. If the regexp + * matches, it means the directory will be excluded. This used to be + * called dirExclusionRegExp before the 1.0.2 release. + * As of 1.0.3, this value can also be a string that is converted to a + * RegExp via new RegExp(). + */ + fileExclusionRegExp: /^\.|spec|spec_helpers/, + /** + * Allow CSS optimizations. Allowed values: + * - "standard": @import inlining and removal of comments, unnecessary + * whitespace and line returns. + * Removing line returns may have problems in IE, depending on the type + * of CSS. + * - "standard.keepLines": like "standard" but keeps line returns. + * - "none": skip CSS optimizations. + * - "standard.keepComments": keeps the file comments, but removes line + * returns. (r.js 1.0.8+) + * - "standard.keepComments.keepLines": keeps the file comments and line + * returns. (r.js 1.0.8+) + * - "standard.keepWhitespace": like "standard" but keeps unnecessary whitespace. + */ + optimizeCss: 'none', + /** + * How to optimize all the JS files in the build output directory. + * Right now only the following values are supported: + * - "uglify": Uses UglifyJS to minify the code. + * - "uglify2": Uses UglifyJS2. + * - "closure": Uses Google's Closure Compiler in simple optimization + * mode to minify the code. Only available if REQUIRE_ENVIRONMENT is "rhino" (the default). + * - "none": No minification will be done. + */ + optimize: jsOptimize, + /** + * Sets the logging level. It is a number: + * TRACE: 0, + * INFO: 1, + * WARN: 2, + * ERROR: 3, + * SILENT: 4 + * Default is 0. + */ + logLevel: 1 + }; +} ()) diff --git a/lms/static/lms/js/require-config.js b/lms/static/lms/js/require-config.js new file mode 100644 index 0000000000..f0a9f84c44 --- /dev/null +++ b/lms/static/lms/js/require-config.js @@ -0,0 +1,185 @@ +;(function (require, define) { + + // We do not wish to bundle common libraries (that may also be used by non-RequireJS code on the page + // into the optimized files. Therefore load these libraries through script tags and explicitly define them. + // Note that when the optimizer executes this code, window will not be defined. + if (window) { + var defineDependency = function (globalVariable, name, noShim) { + if (window[globalVariable]) { + if (noShim) { + define(name, {}); + } + else { + define(name, [], function() {return window[globalVariable];}); + } + } + else { + console.error("Expected library to be included on page, but not found on window object: " + name); + } + }; + defineDependency("jQuery", "jquery"); + defineDependency("_", "underscore"); + defineDependency("gettext", "gettext"); + defineDependency("Logger", "logger"); + defineDependency("URI", "URI"); + defineDependency("Backbone", "backbone"); + // utility.js adds two functions to the window object, but does not return anything + defineDependency("isExternal", "utility", true); + } + + require.config({ + // NOTE: baseUrl has been previously set in lms/templates/main.html + waitSeconds: 60, + paths: { + "gettext": "/i18n", + "annotator_1.2.9": "js/vendor/edxnotes/annotator-full.min", + "date": "js/vendor/date", + "text": "js/vendor/requirejs/text", + "logger": "js/src/logger", + "backbone": "js/vendor/backbone-min", + "backbone-super": "js/vendor/backbone-super", + "backbone.paginator": "js/vendor/backbone.paginator.min", + "underscore": "js/vendor/underscore-min", + "underscore.string": "js/vendor/underscore.string.min", + "jquery": "js/vendor/jquery.min", + "jquery.cookie": "js/vendor/jquery.cookie", + "jquery.url": "js/vendor/url.min", + "jquery.ui": "js/vendor/jquery-ui.min", + "jquery.iframe-transport": "js/vendor/jQuery-File-Upload/js/jquery.iframe-transport", + "jquery.fileupload": "js/vendor/jQuery-File-Upload/js/jquery.fileupload", + "URI": "js/vendor/URI.min", + "string_utils": "js/src/string_utils", + "utility": "js/src/utility", + + // Files needed by OVA + "annotator": "js/vendor/ova/annotator-full", + "annotator-harvardx": "js/vendor/ova/annotator-full-firebase-auth", + "video.dev": "js/vendor/ova/video.dev", + "vjs.youtube": "js/vendor/ova/vjs.youtube", + "rangeslider": "js/vendor/ova/rangeslider", + "share-annotator": "js/vendor/ova/share-annotator", + "richText-annotator": "js/vendor/ova/richText-annotator", + "reply-annotator": "js/vendor/ova/reply-annotator", + "grouping-annotator": "js/vendor/ova/grouping-annotator", + "tags-annotator": "js/vendor/ova/tags-annotator", + "diacritic-annotator": "js/vendor/ova/diacritic-annotator", + "flagging-annotator": "js/vendor/ova/flagging-annotator", + "jquery-Watch": "js/vendor/ova/jquery-Watch", + "openseadragon": "js/vendor/ova/openseadragon", + "osda": "js/vendor/ova/OpenSeaDragonAnnotation", + "ova": "js/vendor/ova/ova", + "catch": "js/vendor/ova/catch/js/catch", + "handlebars": "js/vendor/ova/catch/js/handlebars-1.1.2", + "tinymce": "js/vendor/tinymce/js/tinymce/tinymce.full.min", + "jquery.tinymce": "js/vendor/tinymce/js/tinymce/jquery.tinymce.min" + // end of files needed by OVA + }, + shim: { + "gettext": { + exports: "gettext" + }, + "annotator_1.2.9": { + deps: ["jquery"], + exports: "Annotator" + }, + "date": { + exports: "Date" + }, + "jquery": { + exports: "$" + }, + "jquery.cookie": { + deps: ["jquery"], + exports: "jQuery.fn.cookie" + }, + "jquery.url": { + deps: ["jquery"], + exports: "jQuery.url" + }, + "jquery.fileupload": { + deps: ["jquery.ui", "jquery.iframe-transport"], + exports: "jQuery.fn.fileupload" + }, + "jquery.tinymce": { + deps: ["jquery", "tinymce"], + exports: "jQuery.fn.tinymce" + }, + "underscore": { + exports: "_" + }, + "backbone": { + deps: ["underscore", "jquery"], + exports: "Backbone" + }, + "backbone.paginator": { + deps: ["backbone"], + exports: "Backbone.Paginator" + }, + "backbone-super": { + deps: ["backbone"] + }, + "string_utils": { + deps: ["underscore"], + exports: "interpolate_text" + }, + // Needed by OVA + "video.dev": { + exports:"videojs" + }, + "vjs.youtube": { + deps: ["video.dev"] + }, + "rangeslider": { + deps: ["video.dev"] + }, + "annotator": { + exports: "Annotator" + }, + "annotator-harvardx":{ + deps: ["annotator"] + }, + "share-annotator": { + deps: ["annotator"] + }, + "richText-annotator": { + deps: ["annotator", "tinymce"] + }, + "reply-annotator": { + deps: ["annotator"] + }, + "tags-annotator": { + deps: ["annotator"] + }, + "diacritic-annotator": { + deps: ["annotator"] + }, + "flagging-annotator": { + deps: ["annotator"] + }, + "grouping-annotator": { + deps: ["annotator"] + }, + "ova": { + exports: "ova", + deps: [ + "annotator", "annotator-harvardx", "video.dev", "vjs.youtube", "rangeslider", "share-annotator", + "richText-annotator", "reply-annotator", "tags-annotator", "flagging-annotator", + "grouping-annotator", "diacritic-annotator", "jquery-Watch", "catch", "handlebars", "URI" + ] + }, + "osda": { + exports: "osda", + deps: [ + "annotator", "annotator-harvardx", "video.dev", "vjs.youtube", "rangeslider", "share-annotator", + "richText-annotator", "reply-annotator", "tags-annotator", "flagging-annotator", + "grouping-annotator", "diacritic-annotator", "openseadragon", "jquery-Watch", "catch", "handlebars", + "URI" + ] + }, + "tinymce": { + exports: "tinymce" + } + // End of needed by OVA + } + }); +}).call(this, require || RequireJS.require, define || RequireJS.define); diff --git a/lms/static/require-config-lms.js b/lms/static/require-config-lms.js deleted file mode 100644 index 7a7c760c2e..0000000000 --- a/lms/static/require-config-lms.js +++ /dev/null @@ -1,167 +0,0 @@ -;(function (require, define) { - var paths = {}, config; - - // jquery, underscore, gettext, URI, tinymce, or jquery.tinymce may already - // have been loaded and we do not want to load them a second time. Check if - // it is the case and use the global var instead. - if (window.jQuery) { - define("jquery", [], function() {return window.jQuery;}); - } else { - paths.jquery = "js/vendor/jquery.min"; - } - if (window._) { - define("underscore", [], function() {return window._;}); - } else { - paths.jquery = "js/vendor/underscore-min"; - } - if (window.gettext) { - define("gettext", [], function() {return window.gettext;}); - } else { - paths.gettext = "/i18n"; - } - if (window.Logger) { - define("logger", [], function() {return window.Logger;}); - } else { - paths.logger = "js/src/logger"; - } - if (window.URI) { - define("URI", [], function() {return window.URI;}); - } else { - paths.URI = "js/vendor/URI.min"; - } - if (window.tinymce) { - define('tinymce', [], function() {return window.tinymce;}); - } else { - paths.tinymce = "js/vendor/tinymce/js/tinymce/tinymce.full.min"; - } - if (window.jquery && window.jquery.tinymce) { - define("jquery.tinymce", [], function() {return window.jquery.tinymce;}); - } else { - paths.tinymce = "js/vendor/tinymce/js/tinymce/jquery.tinymce.min"; - } - - config = { - // NOTE: baseUrl has been previously set in lms/static/templates/main.html - waitSeconds: 60, - paths: { - "annotator_1.2.9": "js/vendor/edxnotes/annotator-full.min", - "date": "js/vendor/date", - "text": 'js/vendor/requirejs/text', - "backbone": "js/vendor/backbone-min", - "backbone-super": "js/vendor/backbone-super", - "backbone.paginator": "js/vendor/backbone.paginator.min", - "underscore.string": "js/vendor/underscore.string.min", - // Files needed by OVA - "annotator": "js/vendor/ova/annotator-full", - "annotator-harvardx": "js/vendor/ova/annotator-full-firebase-auth", - "video.dev": "js/vendor/ova/video.dev", - "vjs.youtube": 'js/vendor/ova/vjs.youtube', - "rangeslider": 'js/vendor/ova/rangeslider', - "share-annotator": 'js/vendor/ova/share-annotator', - "richText-annotator": 'js/vendor/ova/richText-annotator', - "reply-annotator": 'js/vendor/ova/reply-annotator', - "grouping-annotator": 'js/vendor/ova/grouping-annotator', - "tags-annotator": 'js/vendor/ova/tags-annotator', - "diacritic-annotator": 'js/vendor/ova/diacritic-annotator', - "flagging-annotator": 'js/vendor/ova/flagging-annotator', - "jquery-Watch": 'js/vendor/ova/jquery-Watch', - "openseadragon": 'js/vendor/ova/openseadragon', - "osda": 'js/vendor/ova/OpenSeaDragonAnnotation', - "ova": 'js/vendor/ova/ova', - "catch": 'js/vendor/ova/catch/js/catch', - "handlebars": 'js/vendor/ova/catch/js/handlebars-1.1.2' - // end of files needed by OVA - }, - shim: { - "annotator_1.2.9": { - deps: ["jquery"], - exports: "Annotator" - }, - "date": { - exports: "Date" - }, - "jquery": { - exports: "$" - }, - "underscore": { - exports: "_" - }, - "backbone": { - deps: ["underscore", "jquery"], - exports: "Backbone" - }, - "backbone.paginator": { - deps: ["backbone"], - exports: "Backbone.Paginator" - }, - "backbone-super": { - deps: ["backbone"] - }, - "logger": { - exports: "Logger" - }, - // Needed by OVA - "video.dev": { - exports:"videojs" - }, - "vjs.youtube": { - deps: ["video.dev"] - }, - "rangeslider": { - deps: ["video.dev"] - }, - "annotator": { - exports: "Annotator" - }, - "annotator-harvardx":{ - deps: ["annotator"] - }, - "share-annotator": { - deps: ["annotator"] - }, - "richText-annotator": { - deps: ["annotator", "tinymce"] - }, - "reply-annotator": { - deps: ["annotator"] - }, - "tags-annotator": { - deps: ["annotator"] - }, - "diacritic-annotator": { - deps: ["annotator"] - }, - "flagging-annotator": { - deps: ["annotator"] - }, - "grouping-annotator": { - deps: ["annotator"] - }, - "ova": { - exports: "ova", - deps: [ - "annotator", "annotator-harvardx", "video.dev", "vjs.youtube", "rangeslider", "share-annotator", - "richText-annotator", "reply-annotator", "tags-annotator", "flagging-annotator", - "grouping-annotator", "diacritic-annotator", "jquery-Watch", "catch", "handlebars", "URI" - ] - }, - "osda": { - exports: "osda", - deps: [ - "annotator", "annotator-harvardx", "video.dev", "vjs.youtube", "rangeslider", "share-annotator", - "richText-annotator", "reply-annotator", "tags-annotator", "flagging-annotator", - "grouping-annotator", "diacritic-annotator", "openseadragon", "jquery-Watch", "catch", "handlebars", - "URI" - ] - } - // End of needed by OVA - } - }; - - for (var key in paths) { - if ({}.hasOwnProperty.call(paths, key)) { - config.paths[key] = paths[key]; - } - } - require.config(config); -}).call(this, require || RequireJS.require, define || RequireJS.define); diff --git a/lms/templates/commerce/checkout_receipt.html b/lms/templates/commerce/checkout_receipt.html index 3ff3b73bc7..dc9ca30510 100644 --- a/lms/templates/commerce/checkout_receipt.html +++ b/lms/templates/commerce/checkout_receipt.html @@ -19,9 +19,7 @@ from django.utils.translation import ugettext as _ <%block name="js_extra"> - - diff --git a/lms/templates/discussion/_js_head_dependencies.html b/lms/templates/discussion/_js_head_dependencies.html index 4bf92ae79c..902e5c42ff 100644 --- a/lms/templates/discussion/_js_head_dependencies.html +++ b/lms/templates/discussion/_js_head_dependencies.html @@ -10,8 +10,6 @@ - - diff --git a/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html b/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html index 4aa1dec037..be681e0906 100644 --- a/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html +++ b/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html @@ -34,7 +34,6 @@ from django.core.urlresolvers import reverse window.Range.prototype = { }; } - diff --git a/lms/templates/main.html b/lms/templates/main.html index 7d2c3cc53c..d06f612e8f 100644 --- a/lms/templates/main.html +++ b/lms/templates/main.html @@ -57,7 +57,7 @@ from branding import api as branding_api % endif - + @@ -66,26 +66,22 @@ from branding import api as branding_api % if disable_courseware_js: <%static:js group='base_vendor'/> + <%static:js group='base_application'/> % else: <%static:js group='main_vendor'/> + <%static:js group='application'/> + <%static:js group='module-js'/> % endif - + <%block name="headextra"/> @@ -160,11 +156,6 @@ from branding import api as branding_api % endif - % if not disable_courseware_js: - <%static:js group='application'/> - <%static:js group='module-js'/> - % endif - <%block name="js_extra"/> diff --git a/lms/templates/student_account/finish_auth.html b/lms/templates/student_account/finish_auth.html index 99bddc2dff..e868289bcf 100644 --- a/lms/templates/student_account/finish_auth.html +++ b/lms/templates/student_account/finish_auth.html @@ -4,11 +4,6 @@ <%block name="pagetitle">${_("Please Wait")} -<%block name="js_extra"> - - <%static:js group='utility'/> - - <%block name="headextra"> - - <%static:js group='student_account'/> diff --git a/lms/templates/verify_student/incourse_reverify.html b/lms/templates/verify_student/incourse_reverify.html index a7b101dff4..3c7be5e68a 100644 --- a/lms/templates/verify_student/incourse_reverify.html +++ b/lms/templates/verify_student/incourse_reverify.html @@ -18,9 +18,7 @@ from django.utils.translation import ugettext as _ % endfor <%block name="js_extra"> - - <%static:js group='incourse_reverify'/> diff --git a/lms/templates/verify_student/pay_and_verify.html b/lms/templates/verify_student/pay_and_verify.html index 7b90d72001..9c02e5f40a 100644 --- a/lms/templates/verify_student/pay_and_verify.html +++ b/lms/templates/verify_student/pay_and_verify.html @@ -35,9 +35,7 @@ from verify_student.views import PayAndVerifyView % endfor <%block name="js_extra"> - - <%static:js group='verify_student'/> diff --git a/lms/templates/verify_student/reverify.html b/lms/templates/verify_student/reverify.html index 8218392e95..d3e6340115 100644 --- a/lms/templates/verify_student/reverify.html +++ b/lms/templates/verify_student/reverify.html @@ -16,9 +16,7 @@ from django.utils.translation import ugettext as _ % endfor <%block name="js_extra"> - - <%static:js group='reverify'/> diff --git a/lms/urls.py b/lms/urls.py index adc0a090c6..72ffb245dd 100644 --- a/lms/urls.py +++ b/lms/urls.py @@ -137,7 +137,7 @@ js_info_dict = { urlpatterns += ( # Serve catalog of localized strings to be rendered by Javascript - url(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict), + url(r'^i18n.js$', 'django.views.i18n.javascript_catalog', js_info_dict), ) # sysadmin dashboard, to see what courses are loaded, to delete & load courses diff --git a/cms/lib/django_require/__init__.py b/openedx/core/lib/django_require/__init__.py similarity index 100% rename from cms/lib/django_require/__init__.py rename to openedx/core/lib/django_require/__init__.py diff --git a/cms/lib/django_require/staticstorage.py b/openedx/core/lib/django_require/staticstorage.py similarity index 100% rename from cms/lib/django_require/staticstorage.py rename to openedx/core/lib/django_require/staticstorage.py