diff --git a/.jshintignore b/.jshintignore index 26e4c15e1e439d5b429536116e93c9946fa4d135..0065f2da20e4648c1e355d2ffcf010a2f3e6b7a5 100644 --- a/.jshintignore +++ b/.jshintignore @@ -1,4 +1,6 @@ **/vendor +cms/static/cms/js/build.js +cms/static/cms/js/spec/main.js cms/static/js/i18n/**/*.js lms/static/js/i18n/**/*.js lms/static/lms/js/build.js diff --git a/cms/static/cms/js/build.js b/cms/static/cms/js/build.js index 65e78c3e62a2a6d98bfb356a25fa055c547e4997..f6a3c1534c80c0f1258a63540b10595881231508 100644 --- a/cms/static/cms/js/build.js +++ b/cms/static/cms/js/build.js @@ -1,8 +1,8 @@ -(function () { +(function() { 'use strict'; var commonLibrariesPath = 'common/js/common_libraries'; - var getModule = function (moduleName, excludeCommonDeps) { + var getModule = function(moduleName, excludeCommonDeps) { var module = { name: moduleName }; @@ -14,7 +14,7 @@ return module; }; - var getModulesList = function (modules) { + var getModulesList = function(modules) { var result = [getModule(commonLibrariesPath)]; return result.concat(modules.map(function (moduleName) { return getModule(moduleName, true); @@ -92,7 +92,7 @@ /** * Stub out requireJS text in the optimized file, but leave available for non-optimized development use. */ - stubModules: ["text"], + stubModules: ['text'], /** * If shim config is used in the app during runtime, duplicate the config @@ -170,4 +170,4 @@ */ logLevel: 1 }; -} ()) +}()) diff --git a/cms/static/cms/js/require-config.js b/cms/static/cms/js/require-config.js index 70e8d61e0b0fe9ad1f570595555721b8182e9fab..7cd1f1caf1e1c0211768638acf3c9f1ff5d7ba2c 100644 --- a/cms/static/cms/js/require-config.js +++ b/cms/static/cms/js/require-config.js @@ -1,5 +1,6 @@ -;(function (require, define) { +;(function(require, define) { 'use strict'; + if (window) { // MathJax Fast Preview was introduced in 2.5. However, it // causes undesirable flashing/font size changes when @@ -16,300 +17,300 @@ // needs to be served. To handle this, we load the correct file in the // rendered template and then use this to ensure that RequireJS knows // how to find it. - define("gettext", function () { return window.gettext; }); + define('gettext', function() { return window.gettext; }); } require.config({ // NOTE: baseUrl has been previously set in cms/static/templates/base.html waitSeconds: 60, paths: { - "domReady": "js/vendor/domReady", - "mustache": "js/vendor/mustache", - "codemirror": "js/vendor/codemirror-compressed", - "codemirror/stex": "js/vendor/CodeMirror/stex", - "jquery": "common/js/vendor/jquery", - "jquery-migrate": "common/js/vendor/jquery-migrate", - "jquery.ui": "js/vendor/jquery-ui.min", - "jquery.form": "js/vendor/jquery.form", - "jquery.markitup": "js/vendor/markitup/jquery.markitup", - "jquery.leanModal": "js/vendor/jquery.leanModal", - "jquery.ajaxQueue": "js/vendor/jquery.ajaxQueue", - "jquery.smoothScroll": "js/vendor/jquery.smooth-scroll.min", - "jquery.timepicker": "js/vendor/timepicker/jquery.timepicker", - "jquery.cookie": "js/vendor/jquery.cookie", - "jquery.qtip": "js/vendor/jquery.qtip.min", - "jquery.scrollTo": "common/js/vendor/jquery.scrollTo", - "jquery.flot": "js/vendor/flot/jquery.flot.min", - "jquery.fileupload": "js/vendor/jQuery-File-Upload/js/jquery.fileupload", - "jquery.fileupload-process": "js/vendor/jQuery-File-Upload/js/jquery.fileupload-process", - "jquery.fileupload-validate": "js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate", - "jquery.iframe-transport": "js/vendor/jQuery-File-Upload/js/jquery.iframe-transport", - "jquery.inputnumber": "js/vendor/html5-input-polyfills/number-polyfill", - "jquery.immediateDescendents": "coffee/src/jquery.immediateDescendents", - "datepair": "js/vendor/timepicker/datepair", - "date": "js/vendor/date", - "moment": "js/vendor/moment.min", - "moment-with-locales": "js/vendor/moment-with-locales.min", - "text": 'js/vendor/requirejs/text', - "underscore": "common/js/vendor/underscore", - "underscore.string": "common/js/vendor/underscore.string", - "backbone": "common/js/vendor/backbone", - "backbone-relational" : "js/vendor/backbone-relational.min", - "backbone.associations": "js/vendor/backbone-associations-min", - "backbone.paginator": "common/js/vendor/backbone.paginator", - "tinymce": "js/vendor/tinymce/js/tinymce/tinymce.full.min", - "jquery.tinymce": "js/vendor/tinymce/js/tinymce/jquery.tinymce.min", - "xmodule": "/xmodule/xmodule", - "xblock/core": "js/xblock/core", - "xblock": "coffee/src/xblock", - "utility": "js/src/utility", - "accessibility": "js/src/accessibility_tools", - "URI": "js/vendor/URI.min", - "ieshim": "js/src/ie_shim", - "tooltip_manager": "js/src/tooltip_manager", - "modernizr": "edx-pattern-library/js/modernizr-custom", - "afontgarde": "edx-pattern-library/js/afontgarde", - "edxicons": "edx-pattern-library/js/edx-icons", - "draggabilly": "js/vendor/draggabilly", + 'domReady': 'js/vendor/domReady', + 'mustache': 'js/vendor/mustache', + 'codemirror': 'js/vendor/codemirror-compressed', + 'codemirror/stex': 'js/vendor/CodeMirror/stex', + 'jquery': 'common/js/vendor/jquery', + 'jquery-migrate': 'common/js/vendor/jquery-migrate', + 'jquery.ui': 'js/vendor/jquery-ui.min', + 'jquery.form': 'js/vendor/jquery.form', + 'jquery.markitup': 'js/vendor/markitup/jquery.markitup', + 'jquery.leanModal': 'js/vendor/jquery.leanModal', + 'jquery.ajaxQueue': 'js/vendor/jquery.ajaxQueue', + 'jquery.smoothScroll': 'js/vendor/jquery.smooth-scroll.min', + 'jquery.timepicker': 'js/vendor/timepicker/jquery.timepicker', + 'jquery.cookie': 'js/vendor/jquery.cookie', + 'jquery.qtip': 'js/vendor/jquery.qtip.min', + 'jquery.scrollTo': 'common/js/vendor/jquery.scrollTo', + 'jquery.flot': 'js/vendor/flot/jquery.flot.min', + 'jquery.fileupload': 'js/vendor/jQuery-File-Upload/js/jquery.fileupload', + 'jquery.fileupload-process': 'js/vendor/jQuery-File-Upload/js/jquery.fileupload-process', + 'jquery.fileupload-validate': 'js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate', + 'jquery.iframe-transport': 'js/vendor/jQuery-File-Upload/js/jquery.iframe-transport', + 'jquery.inputnumber': 'js/vendor/html5-input-polyfills/number-polyfill', + 'jquery.immediateDescendents': 'coffee/src/jquery.immediateDescendents', + 'datepair': 'js/vendor/timepicker/datepair', + 'date': 'js/vendor/date', + 'moment': 'js/vendor/moment.min', + 'moment-with-locales': 'js/vendor/moment-with-locales.min', + 'text': 'js/vendor/requirejs/text', + 'underscore': 'common/js/vendor/underscore', + 'underscore.string': 'common/js/vendor/underscore.string', + 'backbone': 'common/js/vendor/backbone', + 'backbone-relational': 'js/vendor/backbone-relational.min', + 'backbone.associations': 'js/vendor/backbone-associations-min', + 'backbone.paginator': 'common/js/vendor/backbone.paginator', + 'tinymce': 'js/vendor/tinymce/js/tinymce/tinymce.full.min', + 'jquery.tinymce': 'js/vendor/tinymce/js/tinymce/jquery.tinymce.min', + 'xmodule': '/xmodule/xmodule', + 'xblock/cms.runtime.v1': 'cms/js/xblock/cms.runtime.v1', + 'xblock': 'common/js/xblock', + 'utility': 'js/src/utility', + 'accessibility': 'js/src/accessibility_tools', + 'URI': 'js/vendor/URI.min', + 'ieshim': 'js/src/ie_shim', + 'tooltip_manager': 'js/src/tooltip_manager', + 'modernizr': 'edx-pattern-library/js/modernizr-custom', + 'afontgarde': 'edx-pattern-library/js/afontgarde', + 'edxicons': 'edx-pattern-library/js/edx-icons', + 'draggabilly': 'js/vendor/draggabilly', // Files needed for Annotations feature - "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', - "lang_edx": "js/src/lang_edx", + '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', + 'lang_edx': 'js/src/lang_edx', // end of Annotation tool files // externally hosted files - "mathjax": "//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured", // jshint ignore:line - "youtube": [ - // youtube URL does not end in ".js". We add "?noext" to the path so - // that require.js adds the ".js" to the query component of the URL, + 'mathjax': '//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // jshint ignore:line + 'youtube': [ + // youtube URL does not end in '.js'. We add '?noext' to the path so + // that require.js adds the '.js' to the query component of the URL, // and leaves the path component intact. - "//www.youtube.com/player_api?noext", + '//www.youtube.com/player_api?noext', // if youtube fails to load, fallback on a local file // so that require doesn't fall over - "js/src/youtube_fallback" + 'js/src/youtube_fallback' ] }, shim: { - "gettext": { - exports: "gettext" + 'gettext': { + exports: 'gettext' }, - "date": { - exports: "Date" + 'date': { + exports: 'Date' }, - "jquery-migrate": ['jquery'], - "jquery.ui": { - deps: ["jquery"], - exports: "jQuery.ui" + 'jquery-migrate': ['jquery'], + 'jquery.ui': { + deps: ['jquery'], + exports: 'jQuery.ui' }, - "jquery.form": { - deps: ["jquery"], - exports: "jQuery.fn.ajaxForm" + 'jquery.form': { + deps: ['jquery'], + exports: 'jQuery.fn.ajaxForm' }, - "jquery.markitup": { - deps: ["jquery"], - exports: "jQuery.fn.markitup" + 'jquery.markitup': { + deps: ['jquery'], + exports: 'jQuery.fn.markitup' }, - "jquery.leanmodal": { - deps: ["jquery"], - exports: "jQuery.fn.leanModal" + 'jquery.leanmodal': { + deps: ['jquery'], + exports: 'jQuery.fn.leanModal' }, - "jquery.ajaxQueue": { - deps: ["jquery"], - exports: "jQuery.fn.ajaxQueue" + 'jquery.ajaxQueue': { + deps: ['jquery'], + exports: 'jQuery.fn.ajaxQueue' }, - "jquery.smoothScroll": { - deps: ["jquery"], - exports: "jQuery.fn.smoothScroll" + 'jquery.smoothScroll': { + deps: ['jquery'], + exports: 'jQuery.fn.smoothScroll' }, - "jquery.cookie": { - deps: ["jquery"], - exports: "jQuery.fn.cookie" + 'jquery.cookie': { + deps: ['jquery'], + exports: 'jQuery.fn.cookie' }, - "jquery.qtip": { - deps: ["jquery"], - exports: "jQuery.fn.qtip" + 'jquery.qtip': { + deps: ['jquery'], + exports: 'jQuery.fn.qtip' }, - "jquery.scrollTo": { - deps: ["jquery"], - exports: "jQuery.fn.scrollTo" + 'jquery.scrollTo': { + deps: ['jquery'], + exports: 'jQuery.fn.scrollTo' }, - "jquery.flot": { - deps: ["jquery"], - exports: "jQuery.fn.plot" + 'jquery.flot': { + deps: ['jquery'], + exports: 'jQuery.fn.plot' }, - "jquery.fileupload": { - deps: ["jquery.ui", "jquery.iframe-transport"], - exports: "jQuery.fn.fileupload" + 'jquery.fileupload': { + deps: ['jquery.ui', 'jquery.iframe-transport'], + exports: 'jQuery.fn.fileupload' }, - "jquery.fileupload-process": { - deps: ["jquery.fileupload"] + 'jquery.fileupload-process': { + deps: ['jquery.fileupload'] }, - "jquery.fileupload-validate": { - deps: ["jquery.fileupload"] + 'jquery.fileupload-validate': { + deps: ['jquery.fileupload'] }, - "jquery.inputnumber": { - deps: ["jquery"], - exports: "jQuery.fn.inputNumber" + 'jquery.inputnumber': { + deps: ['jquery'], + exports: 'jQuery.fn.inputNumber' }, - "jquery.tinymce": { - deps: ["jquery", "tinymce"], - exports: "jQuery.fn.tinymce" + 'jquery.tinymce': { + deps: ['jquery', 'tinymce'], + exports: 'jQuery.fn.tinymce' }, - "datepair": { - deps: ["jquery.ui", "jquery.timepicker"] + 'datepair': { + deps: ['jquery.ui', 'jquery.timepicker'] }, - "underscore": { - exports: "_" + 'underscore': { + exports: '_' }, - "backbone": { - deps: ["underscore", "jquery"], - exports: "Backbone" + 'backbone': { + deps: ['underscore', 'jquery'], + exports: 'Backbone' }, - "backbone.associations": { - deps: ["backbone"], - exports: "Backbone.Associations" + 'backbone.associations': { + deps: ['backbone'], + exports: 'Backbone.Associations' }, - "backbone.paginator": { - deps: ["backbone"], - exports: "Backbone.PageableCollection" + 'backbone.paginator': { + deps: ['backbone'], + exports: 'Backbone.PageableCollection' }, - "youtube": { - exports: "YT" + 'youtube': { + exports: 'YT' }, - "codemirror": { - exports: "CodeMirror" + 'codemirror': { + exports: 'CodeMirror' }, - "codemirror/stex": { - deps: ["codemirror"] + 'codemirror/stex': { + deps: ['codemirror'] }, - "tinymce": { - exports: "tinymce" + 'tinymce': { + exports: 'tinymce' }, - "lang_edx": { - deps: ["jquery"] + 'lang_edx': { + deps: ['jquery'] }, - "mathjax": { - exports: "MathJax", + 'mathjax': { + exports: 'MathJax', init: function() { window.MathJax.Hub.Config({ tex2jax: { inlineMath: [ - ["\\(","\\)"], + ['\\(','\\)'], ['[mathjaxinline]','[/mathjaxinline]'] ], displayMath: [ - ["\\[","\\]"], + ['\\[','\\]'], ['[mathjax]','[/mathjax]'] ] } - }); - // In order to eliminate all flashing during interactive - // preview, it is necessary to set processSectionDelay to 0 - // (remove delay between input and output phases). This - // effectively disables fast preview, regardless of - // the fast preview setting as shown in the context menu. - window.MathJax.Hub.processSectionDelay = 0; - window.MathJax.Hub.Configured(); + }); + // In order to eliminate all flashing during interactive + // preview, it is necessary to set processSectionDelay to 0 + // (remove delay between input and output phases). This + // effectively disables fast preview, regardless of + // the fast preview setting as shown in the context menu. + window.MathJax.Hub.processSectionDelay = 0; + window.MathJax.Hub.Configured(); } }, - "URI": { - exports: "URI" + 'URI': { + exports: 'URI' }, - "tooltip_manager": { - deps: ["jquery", "underscore"] + 'tooltip_manager': { + deps: ['jquery', 'underscore'] }, - "jquery.immediateDescendents": { - deps: ["jquery"] + 'jquery.immediateDescendents': { + deps: ['jquery'] }, - "xblock/core": { - exports: "XBlock", - deps: ["jquery", "jquery.immediateDescendents"] + 'xblock/core': { + exports: 'XBlock', + deps: ['jquery', 'jquery.immediateDescendents'] }, - "xblock/runtime.v1": { - exports: "XBlock", - deps: ["xblock/core"] + 'xblock/runtime.v1': { + exports: 'XBlock', + deps: ['xblock/core'] }, - "coffee/src/main": { - deps: ["coffee/src/ajax_prefix"] + 'coffee/src/main': { + deps: ['coffee/src/ajax_prefix'] }, - "js/src/logger": { - exports: "Logger", - deps: ["coffee/src/ajax_prefix"] + 'js/src/logger': { + exports: 'Logger', + deps: ['coffee/src/ajax_prefix'] }, - "modernizr": { - exports: "Modernizr" + 'modernizr': { + exports: 'Modernizr' }, - "afontgarde": { - exports: "AFontGarde" + 'afontgarde': { + exports: 'AFontGarde' }, // the following are all needed for annotation tools - "video.dev": { - exports:"videojs" + 'video.dev': { + exports: 'videojs' }, - "vjs.youtube": { - deps: ["video.dev"] + 'vjs.youtube': { + deps: ['video.dev'] }, - "rangeslider": { - deps: ["video.dev"] + 'rangeslider': { + deps: ['video.dev'] }, - "annotator": { - exports: "Annotator" + 'annotator': { + exports: 'Annotator' }, - "annotator-harvardx":{ - deps: ["annotator"] + 'annotator-harvardx': { + deps: ['annotator'] }, - "share-annotator": { - deps: ["annotator"] + 'share-annotator': { + deps: ['annotator'] }, - "richText-annotator": { - deps: ["annotator", "tinymce"] + 'richText-annotator': { + deps: ['annotator', 'tinymce'] }, - "reply-annotator": { - deps: ["annotator"] + 'reply-annotator': { + deps: ['annotator'] }, - "tags-annotator": { - deps: ["annotator"] + 'tags-annotator': { + deps: ['annotator'] }, - "diacritic-annotator": { - deps: ["annotator"] + 'diacritic-annotator': { + deps: ['annotator'] }, - "flagging-annotator": { - deps: ["annotator"] + 'flagging-annotator': { + deps: ['annotator'] }, - "grouping-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"] + '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"] + '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 annotation tool files } diff --git a/cms/static/cms/js/spec/main.js b/cms/static/cms/js/spec/main.js new file mode 100644 index 0000000000000000000000000000000000000000..076c47376c0f842c102789e4153bd046603cf12c --- /dev/null +++ b/cms/static/cms/js/spec/main.js @@ -0,0 +1,299 @@ +(function(requirejs, requireSerial) { + 'use strict'; + + var i, specHelpers, testFiles; + + requirejs.config({ + baseUrl: '/base/', + paths: { + 'gettext': 'xmodule_js/common_static/js/test/i18n', + 'mustache': 'xmodule_js/common_static/js/vendor/mustache', + 'codemirror': 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror', + 'jquery': 'xmodule_js/common_static/common/js/vendor/jquery', + 'jquery-migrate': 'xmodule_js/common_static/common/js/vendor/jquery-migrate', + 'jquery.ui': 'xmodule_js/common_static/js/vendor/jquery-ui.min', + 'jquery.form': 'xmodule_js/common_static/js/vendor/jquery.form', + 'jquery.markitup': 'xmodule_js/common_static/js/vendor/markitup/jquery.markitup', + 'jquery.leanModal': 'xmodule_js/common_static/js/vendor/jquery.leanModal', + 'jquery.ajaxQueue': 'xmodule_js/common_static/js/vendor/jquery.ajaxQueue', + 'jquery.smoothScroll': 'xmodule_js/common_static/js/vendor/jquery.smooth-scroll.min', + 'jquery.scrollTo': 'common/js/vendor/jquery.scrollTo', + 'jquery.timepicker': 'xmodule_js/common_static/js/vendor/timepicker/jquery.timepicker', + 'jquery.cookie': 'xmodule_js/common_static/js/vendor/jquery.cookie', + 'jquery.qtip': 'xmodule_js/common_static/js/vendor/jquery.qtip.min', + 'jquery.fileupload': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload', + 'jquery.fileupload-process': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-process', // jshint ignore:line + 'jquery.fileupload-validate': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate', // jshint ignore:line + 'jquery.iframe-transport': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport', // jshint ignore:line + 'jquery.inputnumber': 'xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill', + 'jquery.immediateDescendents': 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents', + 'jquery.simulate': 'xmodule_js/common_static/js/vendor/jquery.simulate', + 'datepair': 'xmodule_js/common_static/js/vendor/timepicker/datepair', + 'date': 'xmodule_js/common_static/js/vendor/date', + 'moment': 'xmodule_js/common_static/js/vendor/moment.min', + 'moment-with-locales': 'xmodule_js/common_static/js/vendor/moment-with-locales.min', + 'text': 'xmodule_js/common_static/js/vendor/requirejs/text', + 'underscore': 'common/js/vendor/underscore', + 'underscore.string': 'common/js/vendor/underscore.string', + 'backbone': 'common/js/vendor/backbone', + 'backbone.associations': 'xmodule_js/common_static/js/vendor/backbone-associations-min', + 'backbone.paginator': 'common/js/vendor/backbone.paginator', + 'backbone-relational': 'xmodule_js/common_static/js/vendor/backbone-relational.min', + 'tinymce': 'xmodule_js/common_static/js/vendor/tinymce/js/tinymce/tinymce.full.min', + 'jquery.tinymce': 'xmodule_js/common_static/js/vendor/tinymce/js/tinymce/jquery.tinymce', + 'xmodule': 'xmodule_js/src/xmodule', + 'xblock/cms.runtime.v1': 'cms/js/xblock/cms.runtime.v1', + 'xblock': 'common/js/xblock', + 'utility': 'xmodule_js/common_static/js/src/utility', + 'accessibility': 'xmodule_js/common_static/js/src/accessibility_tools', + 'sinon': 'xmodule_js/common_static/js/vendor/sinon-1.17.0', + 'squire': 'xmodule_js/common_static/js/vendor/Squire', + 'jasmine-imagediff': 'xmodule_js/common_static/js/vendor/jasmine-imagediff', + 'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly', + 'domReady': 'xmodule_js/common_static/js/vendor/domReady', + 'URI': 'xmodule_js/common_static/js/vendor/URI.min', + 'mock-ajax': 'xmodule_js/common_static/js/vendor/mock-ajax', + 'modernizr': 'edx-pattern-library/js/modernizr-custom', + 'afontgarde': 'edx-pattern-library/js/afontgarde', + 'edxicons': 'edx-pattern-library/js/edx-icons', + 'mathjax': '//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // jshint ignore:line + 'youtube': '//www.youtube.com/player_api?noext', + 'coffee/src/ajax_prefix': 'xmodule_js/common_static/coffee/src/ajax_prefix', + 'js/spec/test_utils': 'js/spec/test_utils' + }, + shim: { + 'gettext': { + exports: 'gettext' + }, + 'date': { + exports: 'Date' + }, + 'jquery-migrate': ['jquery'], + 'jquery.ui': { + deps: ['jquery'], + exports: 'jQuery.ui' + }, + 'jquery.form': { + deps: ['jquery'], + exports: 'jQuery.fn.ajaxForm' + }, + 'jquery.markitup': { + deps: ['jquery'], + exports: 'jQuery.fn.markitup' + }, + 'jquery.leanModal': { + deps: ['jquery'], + exports: 'jQuery.fn.leanModal' + }, + 'jquery.smoothScroll': { + deps: ['jquery'], + exports: 'jQuery.fn.smoothScroll' + }, + 'jquery.ajaxQueue': { + deps: ['jquery'], + exports: 'jQuery.fn.ajaxQueue' + }, + 'jquery.scrollTo': { + deps: ['jquery'], + exports: 'jQuery.fn.scrollTo' + }, + 'jquery.cookie': { + deps: ['jquery'], + exports: 'jQuery.fn.cookie' + }, + 'jquery.qtip': { + deps: ['jquery'], + exports: 'jQuery.fn.qtip' + }, + 'jquery.fileupload': { + deps: ['jquery.ui', 'jquery.iframe-transport'], + exports: 'jQuery.fn.fileupload' + }, + 'jquery.fileupload-process': { + deps: ['jquery.fileupload'] + }, + 'jquery.fileupload-validate': { + deps: ['jquery.fileupload'] + }, + 'jquery.inputnumber': { + deps: ['jquery'], + exports: 'jQuery.fn.inputNumber' + }, + 'jquery.simulate': { + deps: ['jquery'], + exports: 'jQuery.fn.simulate' + }, + 'jquery.tinymce': { + deps: ['jquery', 'tinymce'], + exports: 'jQuery.fn.tinymce' + }, + 'datepair': { + deps: ['jquery.ui', 'jquery.timepicker'] + }, + 'underscore': { + exports: '_' + }, + 'backbone': { + deps: ['underscore', 'jquery'], + exports: 'Backbone' + }, + 'backbone.associations': { + deps: ['backbone'], + exports: 'Backbone.Associations' + }, + 'backbone.paginator': { + deps: ['backbone'], + exports: 'Backbone.PageableCollection' + }, + 'backbone-relational': { + deps: ['backbone'] + }, + 'youtube': { + exports: 'YT' + }, + 'codemirror': { + exports: 'CodeMirror' + }, + 'tinymce': { + exports: 'tinymce' + }, + 'mathjax': { + exports: 'MathJax', + init: function() { + window.MathJax.Hub.Config({ + tex2jax: { + inlineMath: [['\\(', '\\)'], ['[mathjaxinline]', '[/mathjaxinline]']], + displayMath: [['\\[', '\\]'], ['[mathjax]', '[/mathjax]']] + } + }); + return window.MathJax.Hub.Configured(); + } + }, + 'URI': { + exports: 'URI' + }, + 'xmodule': { + exports: 'XModule' + }, + 'sinon': { + exports: 'sinon' + }, + 'jasmine-imagediff': {}, + 'common/js/spec_helpers/jasmine-extensions': { + deps: ['jquery'] + }, + 'common/js/spec_helpers/jasmine-stealth': { + deps: ['underscore', 'underscore.string'] + }, + 'common/js/spec_helpers/jasmine-waituntil': { + deps: ['jquery'] + }, + 'xblock/core': { + exports: 'XBlock', + deps: ['jquery', 'jquery.immediateDescendents'] + }, + 'xblock/runtime.v1': { + exports: 'XBlock', + deps: ['xblock/core'] + }, + 'mock-ajax': { + deps: ['jquery'] + }, + 'coffee/src/main': { + deps: ['coffee/src/ajax_prefix'] + }, + 'coffee/src/ajax_prefix': { + deps: ['jquery'] + }, + 'modernizr': { + exports: 'Modernizr' + }, + 'afontgarde': { + exports: 'AFontGarde' + } + } + }); + + jasmine.getFixtures().fixturesPath += 'coffee/fixtures'; + + testFiles = [ + 'cms/js/spec/xblock/cms.runtime.v1_spec', + 'coffee/spec/main_spec', + 'coffee/spec/models/course_spec', + 'coffee/spec/models/metadata_spec', + 'coffee/spec/models/section_spec', + 'coffee/spec/models/settings_course_grader_spec', + 'coffee/spec/models/settings_grading_spec', + 'coffee/spec/models/textbook_spec', + 'coffee/spec/models/upload_spec', + 'coffee/spec/views/course_info_spec', + 'coffee/spec/views/metadata_edit_spec', + 'coffee/spec/views/module_edit_spec', + 'coffee/spec/views/textbook_spec', + 'coffee/spec/views/upload_spec', + 'js/spec/video/transcripts/utils_spec', + 'js/spec/video/transcripts/editor_spec', + 'js/spec/video/transcripts/videolist_spec', + 'js/spec/video/transcripts/message_manager_spec', + 'js/spec/video/transcripts/file_uploader_spec', + 'js/spec/models/component_template_spec', + 'js/spec/models/explicit_url_spec', + 'js/spec/models/xblock_info_spec', + 'js/spec/models/xblock_validation_spec', + 'js/spec/models/license_spec', + 'js/spec/utils/drag_and_drop_spec', + 'js/spec/utils/handle_iframe_binding_spec', + 'js/spec/utils/module_spec', + 'js/spec/views/active_video_upload_list_spec', + 'js/spec/views/previous_video_upload_spec', + 'js/spec/views/previous_video_upload_list_spec', + 'js/spec/views/assets_spec', + 'js/spec/views/baseview_spec', + 'js/spec/views/container_spec', + 'js/spec/views/paged_container_spec', + 'js/spec/views/group_configuration_spec', + 'js/spec/views/unit_outline_spec', + 'js/spec/views/xblock_spec', + 'js/spec/views/xblock_editor_spec', + 'js/spec/views/xblock_string_field_editor_spec', + 'js/spec/views/xblock_validation_spec', + 'js/spec/views/license_spec', + 'js/spec/views/paging_spec', + 'js/spec/views/login_studio_spec', + 'js/spec/views/pages/container_spec', + 'js/spec/views/pages/container_subviews_spec', + 'js/spec/views/pages/group_configurations_spec', + 'js/spec/views/pages/course_outline_spec', + 'js/spec/views/pages/course_rerun_spec', + 'js/spec/views/pages/index_spec', + 'js/spec/views/pages/library_users_spec', + 'js/spec/views/modals/base_modal_spec', + 'js/spec/views/modals/edit_xblock_spec', + 'js/spec/views/modals/validation_error_modal_spec', + 'js/spec/views/settings/main_spec', + 'js/spec/factories/xblock_validation_spec', + 'js/certificates/spec/models/certificate_spec', + 'js/certificates/spec/views/certificate_details_spec', + 'js/certificates/spec/views/certificate_editor_spec', + 'js/certificates/spec/views/certificates_list_spec', + 'js/certificates/spec/views/certificate_preview_spec' + ]; + + i = 0; + + while (i < testFiles.length) { + testFiles[i] = '/base/' + testFiles[i] + '.js'; + i++; + } + + specHelpers = [ + 'common/js/spec_helpers/jasmine-extensions', + 'common/js/spec_helpers/jasmine-stealth', + 'common/js/spec_helpers/jasmine-waituntil' + ]; + + requireSerial(specHelpers.concat(testFiles), function() { + return window.__karma__.start(); + }); + +}).call(this, requirejs, requireSerial); // jshint ignore:line diff --git a/cms/static/cms/js/spec/main_squire.js b/cms/static/cms/js/spec/main_squire.js new file mode 100644 index 0000000000000000000000000000000000000000..8e65cef81ba072b0b62f08aa7a6846cd2b187531 --- /dev/null +++ b/cms/static/cms/js/spec/main_squire.js @@ -0,0 +1,218 @@ +(function(requirejs, requireSerial) { + 'use strict'; + + var i, specHelpers, testFiles; + + requirejs.config({ + baseUrl: '/base/', + paths: { + 'gettext': 'xmodule_js/common_static/js/test/i18n', + 'mustache': 'xmodule_js/common_static/js/vendor/mustache', + 'codemirror': 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror', + 'jquery': 'common/js/vendor/jquery', + 'jquery-migrate': 'common/js/vendor/jquery-migrate', + 'jquery.ui': 'xmodule_js/common_static/js/vendor/jquery-ui.min', + 'jquery.form': 'xmodule_js/common_static/js/vendor/jquery.form', + 'jquery.markitup': 'xmodule_js/common_static/js/vendor/markitup/jquery.markitup', + 'jquery.leanModal': 'xmodule_js/common_static/js/vendor/jquery.leanModal', + 'jquery.smoothScroll': 'xmodule_js/common_static/js/vendor/jquery.smooth-scroll.min', + 'jquery.scrollTo': 'common/js/vendor/jquery.scrollTo', + 'jquery.timepicker': 'xmodule_js/common_static/js/vendor/timepicker/jquery.timepicker', + 'jquery.cookie': 'xmodule_js/common_static/js/vendor/jquery.cookie', + 'jquery.qtip': 'xmodule_js/common_static/js/vendor/jquery.qtip.min', + 'jquery.fileupload': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload', + 'jquery.fileupload-process': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-process', // jshint ignore:line + 'jquery.fileupload-validate': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate', // jshint ignore:line + 'jquery.iframe-transport': 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport', // jshint ignore:line + 'jquery.inputnumber': 'xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill', + 'jquery.immediateDescendents': 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents', + 'datepair': 'xmodule_js/common_static/js/vendor/timepicker/datepair', + 'date': 'xmodule_js/common_static/js/vendor/date', + 'text': 'xmodule_js/common_static/js/vendor/requirejs/text', + 'underscore': 'common/js/vendor/underscore', + 'underscore.string': 'common/js/vendor/underscore.string', + 'backbone': 'common/js/vendor/backbone', + 'backbone.associations': 'xmodule_js/common_static/js/vendor/backbone-associations-min', + 'backbone.paginator': 'common/js/vendor/backbone.paginator', + 'tinymce': 'xmodule_js/common_static/js/vendor/tinymce/js/tinymce/tinymce.full.min', + 'jquery.tinymce': 'xmodule_js/common_static/js/vendor/tinymce/js/tinymce/jquery.tinymce', + 'xmodule': 'xmodule_js/src/xmodule', + 'xblock/cms.runtime.v1': 'cms/js/xblock/cms.runtime.v1', + 'xblock': 'common/js/xblock', + 'utility': 'xmodule_js/common_static/js/src/utility', + 'sinon': 'xmodule_js/common_static/js/vendor/sinon-1.17.0', + 'squire': 'xmodule_js/common_static/js/vendor/Squire', + 'modernizr': 'edx-pattern-library/js/modernizr-custom', + 'afontgarde': 'edx-pattern-library/js/afontgarde', + 'edxicons': 'edx-pattern-library/js/edx-icons', + 'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly', + 'domReady': 'xmodule_js/common_static/js/vendor/domReady', + 'URI': 'xmodule_js/common_static/js/vendor/URI.min', + 'mathjax': '//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // jshint ignore:line + 'youtube': '//www.youtube.com/player_api?noext', + 'coffee/src/ajax_prefix': 'xmodule_js/common_static/coffee/src/ajax_prefix' + }, + shim: { + 'gettext': { + exports: 'gettext' + }, + 'date': { + exports: 'Date' + }, + 'jquery.ui': { + deps: ['jquery'], + exports: 'jQuery.ui' + }, + 'jquery.form': { + deps: ['jquery'], + exports: 'jQuery.fn.ajaxForm' + }, + 'jquery.markitup': { + deps: ['jquery'], + exports: 'jQuery.fn.markitup' + }, + 'jquery.leanModal': { + deps: ['jquery'], + exports: 'jQuery.fn.leanModal' + }, + 'jquery.smoothScroll': { + deps: ['jquery'], + exports: 'jQuery.fn.smoothScroll' + }, + 'jquery.scrollTo': { + deps: ['jquery'], + exports: 'jQuery.fn.scrollTo' + }, + 'jquery.cookie': { + deps: ['jquery'], + exports: 'jQuery.fn.cookie' + }, + 'jquery.qtip': { + deps: ['jquery'], + exports: 'jQuery.fn.qtip' + }, + 'jquery.fileupload': { + deps: ['jquery.ui', 'jquery.iframe-transport'], + exports: 'jQuery.fn.fileupload' + }, + 'jquery.fileupload-process': { + deps: ['jquery.fileupload'] + }, + 'jquery.fileupload-validate': { + deps: ['jquery.fileupload'] + }, + 'jquery.inputnumber': { + deps: ['jquery'], + exports: 'jQuery.fn.inputNumber' + }, + 'jquery.tinymce': { + deps: ['jquery', 'tinymce'], + exports: 'jQuery.fn.tinymce' + }, + 'datepair': { + deps: ['jquery.ui', 'jquery.timepicker'] + }, + 'underscore': { + exports: '_' + }, + 'backbone': { + deps: ['underscore', 'jquery'], + exports: 'Backbone' + }, + 'backbone.associations': { + deps: ['backbone'], + exports: 'Backbone.Associations' + }, + 'backbone.paginator': { + deps: ['backbone'], + exports: 'Backbone.PageableCollection' + }, + 'youtube': { + exports: 'YT' + }, + 'codemirror': { + exports: 'CodeMirror' + }, + 'tinymce': { + exports: 'tinymce' + }, + 'mathjax': { + exports: 'MathJax', + init: function() { + window.MathJax.Hub.Config({ + tex2jax: { + inlineMath: [['\\(', '\\)'], ['[mathjaxinline]', '[/mathjaxinline]']], + displayMath: [['\\[', '\\]'], ['[mathjax]', '[/mathjax]']] + } + }); + window.MathJax.Hub.Configured(); + } + }, + 'URI': { + exports: 'URI' + }, + 'xmodule': { + exports: 'XModule' + }, + 'sinon': { + exports: 'sinon' + }, + 'common/js/spec_helpers/jasmine-extensions': { + deps: ['jquery'] + }, + 'common/js/spec_helpers/jasmine-stealth': { + deps: ['underscore', 'underscore.string'] + }, + 'common/js/spec_helpers/jasmine-waituntil': { + deps: ['jquery'] + }, + 'xblock/core': { + exports: 'XBlock', + deps: ['jquery', 'jquery.immediateDescendents'] + }, + 'xblock/runtime.v1': { + exports: 'XBlock', + deps: ['xblock/core'] + }, + 'coffee/src/main': { + deps: ['coffee/src/ajax_prefix'] + }, + 'coffee/src/ajax_prefix': { + deps: ['jquery'] + }, + 'modernizr': { + exports: 'Modernizr' + }, + 'afontgarde': { + exports: 'AFontGarde' + } + } + }); + + jasmine.getFixtures().fixturesPath += 'coffee/fixtures'; + + testFiles = [ + 'coffee/spec/views/assets_spec', + 'js/spec/video/translations_editor_spec', + 'js/spec/video/file_uploader_editor_spec', + 'js/spec/models/group_configuration_spec' + ]; + + i = 0; + + while (i < testFiles.length) { + testFiles[i] = '/base/' + testFiles[i] + '.js'; + i++; + } + + specHelpers = [ + 'common/js/spec_helpers/jasmine-extensions', + 'common/js/spec_helpers/jasmine-stealth', + 'common/js/spec_helpers/jasmine-waituntil' + ]; + + requireSerial(specHelpers.concat(testFiles), function() { + return window.__karma__.start(); + }); + +}).call(this, requirejs, requireSerial); // jshint ignore:line diff --git a/cms/static/js/spec/xblock/cms.runtime.v1_spec.js b/cms/static/cms/js/spec/xblock/cms.runtime.v1_spec.js similarity index 79% rename from cms/static/js/spec/xblock/cms.runtime.v1_spec.js rename to cms/static/cms/js/spec/xblock/cms.runtime.v1_spec.js index c508c21548fb81b1872b2c4bfa171958e0645b4f..893fe6827a6d1620cf2974d6a1577357c6025644 100644 --- a/cms/static/js/spec/xblock/cms.runtime.v1_spec.js +++ b/cms/static/cms/js/spec/xblock/cms.runtime.v1_spec.js @@ -1,10 +1,11 @@ -define(["js/spec_helpers/edit_helpers", "js/views/modals/base_modal", "xblock/cms.runtime.v1"], - function (EditHelpers, BaseModal) { +define(['js/spec_helpers/edit_helpers', 'js/views/modals/base_modal', 'xblock/cms.runtime.v1'], + function(EditHelpers, BaseModal) { + 'use strict'; - describe("Studio Runtime v1", function() { + describe('Studio Runtime v1', function() { var runtime; - beforeEach(function () { + beforeEach(function() { EditHelpers.installEditTemplates(); runtime = new window.StudioRuntime.v1(); }); @@ -20,7 +21,7 @@ define(["js/spec_helpers/edit_helpers", "js/views/modals/base_modal", "xblock/cm }); it('shows save notifications', function() { - var title = "Mock saving...", + var title = 'Mock saving...', notificationSpy = EditHelpers.createNotificationSpy(); runtime.notify('save', { state: 'start', @@ -34,9 +35,9 @@ define(["js/spec_helpers/edit_helpers", "js/views/modals/base_modal", "xblock/cm }); it('shows error messages', function() { - var title = "Mock Error", - message = "This is a mock error.", - notificationSpy = EditHelpers.createNotificationSpy("Error"); + var title = 'Mock Error', + message = 'This is a mock error.', + notificationSpy = EditHelpers.createNotificationSpy('Error'); runtime.notify('error', { title: title, message: message @@ -44,7 +45,7 @@ define(["js/spec_helpers/edit_helpers", "js/views/modals/base_modal", "xblock/cm EditHelpers.verifyNotificationShowing(notificationSpy, title); }); - describe("Modal Dialogs", function() { + describe('Modal Dialogs', function() { var MockModal, modal, showMockModal; MockModal = BaseModal.extend({ @@ -55,12 +56,12 @@ define(["js/spec_helpers/edit_helpers", "js/views/modals/base_modal", "xblock/cm showMockModal = function() { modal = new MockModal({ - title: "Mock Modal" + title: 'Mock Modal' }); modal.show(); }; - beforeEach(function () { + beforeEach(function() { EditHelpers.installEditTemplates(); }); @@ -68,7 +69,7 @@ define(["js/spec_helpers/edit_helpers", "js/views/modals/base_modal", "xblock/cm EditHelpers.hideModalIfShowing(modal); }); - it('cancels a modal dialog', function () { + it('cancels a modal dialog', function() { showMockModal(); runtime.notify('modal-shown', modal); expect(EditHelpers.isShowingModal(modal)).toBeTruthy(); diff --git a/cms/static/cms/js/xblock/cms.runtime.v1.js b/cms/static/cms/js/xblock/cms.runtime.v1.js new file mode 100644 index 0000000000000000000000000000000000000000..6c5e73aaf35f43f07c0dbb967c0663fcae882376 --- /dev/null +++ b/cms/static/cms/js/xblock/cms.runtime.v1.js @@ -0,0 +1,188 @@ +define(['jquery', 'backbone', 'xblock/runtime.v1', 'URI', 'gettext', 'js/utils/modal', + 'common/js/components/views/feedback_notification'], + function($, Backbone, XBlock, URI, gettext, ModalUtils, NotificationView) { + 'use strict'; + + var __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { + var key; + for (key in parent) { + if (__hasProp.call(parent, key)) { + child[key] = parent[key]; + } + } + function Ctor() { + this.constructor = child; + } + Ctor.prototype = parent.prototype; + child.prototype = new Ctor(); + child.__super__ = parent.prototype; + return child; + }, + BaseRuntime = {}, + PreviewRuntime = {}, + StudioRuntime = {}; + + BaseRuntime.v1 = (function(_super) { + + __extends(v1, _super); + + v1.prototype.handlerUrl = function(element, handlerName, suffix, query) { + var uri; + uri = URI(this.handlerPrefix) + .segment($(element).data('usage-id')) + .segment('handler') + .segment(handlerName); + if (suffix !== null) { + uri.segment(suffix); + } + if (query !== null) { + uri.search(query); + } + return uri.toString(); + }; + + function v1() { + v1.__super__.constructor.call(this); + this.dispatcher = _.clone(Backbone.Events); + this.listenTo('save', this._handleSave); + this.listenTo('cancel', this._handleCancel); + this.listenTo('error', this._handleError); + this.listenTo('modal-shown', function(data) { + this.modal = data; + }); + this.listenTo('modal-hidden', function() { + this.modal = null; + }); + this.listenTo('page-shown', function(data) { + this.page = data; + }); + } + + /** + * Notify the Studio client-side runtime of an event so that it + * can update the UI in a consistent way. + * + * @param {string} name The name of the event. + * @param {object} data A JSON representation of the data to be included with the event. + */ + v1.prototype.notify = function(name, data) { + this.dispatcher.trigger(name, data); + }; + + /** + * Listen to a Studio event and invoke the specified callback when it is triggered. + * + * @param {string} name The name of the event. + * @param {function} callback The callback to be invoked. + */ + v1.prototype.listenTo = function(name, callback) { + this.dispatcher.bind(name, callback, this); + }; + + /** + * Refresh the view for the xblock represented by the specified element. + * + * @param {element} element The element representing the XBlock. + */ + v1.prototype.refreshXBlock = function(element) { + if (this.page) { + this.page.refreshXBlock(element); + } + }; + + v1.prototype._handleError = function(data) { + var message, title; + message = data.message || data.msg; + if (message) { + // TODO: remove 'Open Assessment' specific default title + title = data.title || gettext('OpenAssessment Save Error'); + this.alert = new NotificationView.Error({ + title: title, + message: message, + closeIcon: false, + shown: false + }); + this.alert.show(); + } + }; + + v1.prototype._handleSave = function(data) { + var message; + // Starting to save, so show a notification + if (data.state === 'start') { + message = data.message || gettext('Saving'); + this.notification = new NotificationView.Mini({ + title: message + }); + this.notification.show(); + } else if (data.state === 'end') { + // Finished saving, so hide the notification and refresh appropriately + this._hideAlerts(); + + if (this.modal && this.modal.onSave) { + // Notify the modal that the save has completed so that it can hide itself + // and then refresh the xblock. + this.modal.onSave(); + } else if (data.element) { + // ... else ask it to refresh the newly saved xblock + this.refreshXBlock(data.element); + } + this.notification.hide(); + } + }; + + v1.prototype._handleCancel = function() { + this._hideAlerts(); + if (this.modal) { + this.modal.cancel(); + this.notify('modal-hidden'); + } + }; + + /** + * Hide any alerts that are being shown. + */ + v1.prototype._hideAlerts = function() { + if (this.alert && this.alert.options.shown) { + this.alert.hide(); + } + }; + + return v1; + + })(XBlock.Runtime.v1); + + PreviewRuntime.v1 = (function(_super) { + + __extends(v1, _super); + + function v1() { + return v1.__super__.constructor.apply(this, arguments); + } + + v1.prototype.handlerPrefix = '/preview/xblock'; + + return v1; + + })(BaseRuntime.v1); + + StudioRuntime.v1 = (function(_super) { + + __extends(v1, _super); + + function v1() { + return v1.__super__.constructor.apply(this, arguments); + } + + v1.prototype.handlerPrefix = '/xblock'; + + return v1; + + })(BaseRuntime.v1); + + // Install the runtime's into the global namespace + window.BaseRuntime = BaseRuntime; + window.PreviewRuntime = PreviewRuntime; + window.StudioRuntime = StudioRuntime; + }); diff --git a/cms/static/coffee/spec/main.coffee b/cms/static/coffee/spec/main.coffee deleted file mode 100644 index 3685cf47ac187a752172e196518cbbd1d4ecad05..0000000000000000000000000000000000000000 --- a/cms/static/coffee/spec/main.coffee +++ /dev/null @@ -1,299 +0,0 @@ -requirejs.config({ - baseUrl: '/base/', - paths: { - "gettext": "xmodule_js/common_static/js/test/i18n", - "mustache": "xmodule_js/common_static/js/vendor/mustache", - "codemirror": "xmodule_js/common_static/js/vendor/CodeMirror/codemirror", - "jquery": "xmodule_js/common_static/common/js/vendor/jquery", - "jquery-migrate": "xmodule_js/common_static/common/js/vendor/jquery-migrate", - "jquery.ui": "xmodule_js/common_static/js/vendor/jquery-ui.min", - "jquery.form": "xmodule_js/common_static/js/vendor/jquery.form", - "jquery.markitup": "xmodule_js/common_static/js/vendor/markitup/jquery.markitup", - "jquery.leanModal": "xmodule_js/common_static/js/vendor/jquery.leanModal", - "jquery.ajaxQueue": "xmodule_js/common_static/js/vendor/jquery.ajaxQueue", - "jquery.smoothScroll": "xmodule_js/common_static/js/vendor/jquery.smooth-scroll.min", - "jquery.scrollTo": "common/js/vendor/jquery.scrollTo", - "jquery.timepicker": "xmodule_js/common_static/js/vendor/timepicker/jquery.timepicker", - "jquery.cookie": "xmodule_js/common_static/js/vendor/jquery.cookie", - "jquery.qtip": "xmodule_js/common_static/js/vendor/jquery.qtip.min", - "jquery.fileupload": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload", - "jquery.fileupload-process": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-process", - "jquery.fileupload-validate": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate", - "jquery.iframe-transport": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport", - "jquery.inputnumber": "xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill", - "jquery.immediateDescendents": "xmodule_js/common_static/coffee/src/jquery.immediateDescendents", - "jquery.simulate": "xmodule_js/common_static/js/vendor/jquery.simulate", - "datepair": "xmodule_js/common_static/js/vendor/timepicker/datepair", - "date": "xmodule_js/common_static/js/vendor/date", - "moment": "xmodule_js/common_static/js/vendor/moment.min", - "moment-with-locales": "xmodule_js/common_static/js/vendor/moment-with-locales.min", - "text": "xmodule_js/common_static/js/vendor/requirejs/text", - "underscore": "common/js/vendor/underscore", - "underscore.string": "common/js/vendor/underscore.string", - "backbone": "common/js/vendor/backbone", - "backbone.associations": "xmodule_js/common_static/js/vendor/backbone-associations-min", - "backbone.paginator": "common/js/vendor/backbone.paginator", - "backbone-relational": "xmodule_js/common_static/js/vendor/backbone-relational.min", - "tinymce": "xmodule_js/common_static/js/vendor/tinymce/js/tinymce/tinymce.full.min", - "jquery.tinymce": "xmodule_js/common_static/js/vendor/tinymce/js/tinymce/jquery.tinymce", - "xmodule": "xmodule_js/src/xmodule", - "xblock/cms.runtime.v1": "coffee/src/xblock/cms.runtime.v1", - "xblock/core": "xmodule_js/common_static/js/xblock/core", - "xblock": "xmodule_js/common_static/coffee/src/xblock", - "utility": "xmodule_js/common_static/js/src/utility", - "accessibility": "xmodule_js/common_static/js/src/accessibility_tools", - "sinon": "xmodule_js/common_static/js/vendor/sinon-1.17.0", - "squire": "xmodule_js/common_static/js/vendor/Squire", - "jasmine-imagediff": "xmodule_js/common_static/js/vendor/jasmine-imagediff", - "draggabilly": "xmodule_js/common_static/js/vendor/draggabilly", - "domReady": "xmodule_js/common_static/js/vendor/domReady", - "URI": "xmodule_js/common_static/js/vendor/URI.min", - "mock-ajax": "xmodule_js/common_static/js/vendor/mock-ajax", - "modernizr": "edx-pattern-library/js/modernizr-custom", - "afontgarde": "edx-pattern-library/js/afontgarde", - "edxicons": "edx-pattern-library/js/edx-icons", - - "mathjax": "//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured", - "youtube": "//www.youtube.com/player_api?noext", - - "coffee/src/ajax_prefix": "xmodule_js/common_static/coffee/src/ajax_prefix", - "js/spec/test_utils": "js/spec/test_utils", - } - shim: { - "gettext": { - exports: "gettext" - }, - "date": { - exports: "Date" - }, - "jquery-migrate": ['jquery'], - "jquery.ui": { - deps: ["jquery"], - exports: "jQuery.ui" - }, - "jquery.form": { - deps: ["jquery"], - exports: "jQuery.fn.ajaxForm" - }, - "jquery.markitup": { - deps: ["jquery"], - exports: "jQuery.fn.markitup" - }, - "jquery.leanModal": { - deps: ["jquery"], - exports: "jQuery.fn.leanModal" - }, - "jquery.smoothScroll": { - deps: ["jquery"], - exports: "jQuery.fn.smoothScroll" - }, - "jquery.ajaxQueue": { - deps: ["jquery"], - exports: "jQuery.fn.ajaxQueue" - }, - "jquery.scrollTo": { - deps: ["jquery"], - exports: "jQuery.fn.scrollTo" - }, - "jquery.cookie": { - deps: ["jquery"], - exports: "jQuery.fn.cookie" - }, - "jquery.qtip": { - deps: ["jquery"], - exports: "jQuery.fn.qtip" - }, - "jquery.fileupload": { - deps: ["jquery.ui", "jquery.iframe-transport"], - exports: "jQuery.fn.fileupload" - }, - "jquery.fileupload-process": { - deps: ["jquery.fileupload"] - }, - "jquery.fileupload-validate": { - deps: ["jquery.fileupload"] - }, - "jquery.inputnumber": { - deps: ["jquery"], - exports: "jQuery.fn.inputNumber" - }, - "jquery.simulate": { - deps: ["jquery"], - exports: "jQuery.fn.simulate" - }, - "jquery.tinymce": { - deps: ["jquery", "tinymce"], - exports: "jQuery.fn.tinymce" - }, - "datepair": { - deps: ["jquery.ui", "jquery.timepicker"] - }, - "underscore": { - exports: "_" - }, - "backbone": { - deps: ["underscore", "jquery"], - exports: "Backbone" - }, - "backbone.associations": { - deps: ["backbone"], - exports: "Backbone.Associations" - }, - "backbone.paginator": { - deps: ["backbone"], - exports: "Backbone.PageableCollection" - }, - "backbone-relational": { - deps: ["backbone"], - }, - "youtube": { - exports: "YT" - }, - "codemirror": { - exports: "CodeMirror" - }, - "tinymce": { - exports: "tinymce" - }, - "mathjax": { - exports: "MathJax", - init: -> - MathJax.Hub.Config - tex2jax: - inlineMath: [ - ["\\(", "\\)"], - ['[mathjaxinline]', '[/mathjaxinline]'] - ] - displayMath: [ - ["\\[", "\\]"], - ['[mathjax]', '[/mathjax]'] - ] - MathJax.Hub.Configured() - }, - "URI": { - exports: "URI" - }, - "xmodule": { - exports: "XModule" - }, - "sinon": { - exports: "sinon" - }, - "jasmine-imagediff": {}, - "common/js/spec_helpers/jasmine-extensions": { - deps: ["jquery"] - }, - "common/js/spec_helpers/jasmine-stealth": { - deps: ["underscore", "underscore.string"] - }, - "common/js/spec_helpers/jasmine-waituntil": { - deps: ["jquery"] - }, - "xblock/core": { - exports: "XBlock", - deps: ["jquery", "jquery.immediateDescendents"] - }, - "xblock/runtime.v1": { - exports: "XBlock", - deps: ["xblock/core"] - }, - "mock-ajax": { - deps: ["jquery"] - } - - "coffee/src/main": { - deps: ["coffee/src/ajax_prefix"] - }, - "coffee/src/ajax_prefix": { - deps: ["jquery"] - }, - "modernizr": { - exports: "Modernizr" - }, - "afontgarde": { - exports: "AFontGarde" - } - } -}); - -jasmine.getFixtures().fixturesPath += 'coffee/fixtures' - -testFiles = [ - "coffee/spec/main_spec", - "coffee/spec/models/course_spec", - "coffee/spec/models/metadata_spec", - "coffee/spec/models/section_spec", - "coffee/spec/models/settings_course_grader_spec", - "coffee/spec/models/settings_grading_spec", - "coffee/spec/models/textbook_spec", - "coffee/spec/models/upload_spec", - "coffee/spec/views/course_info_spec", - "coffee/spec/views/metadata_edit_spec", - "coffee/spec/views/module_edit_spec", - "coffee/spec/views/textbook_spec", - "coffee/spec/views/upload_spec", - "js/spec/video/transcripts/utils_spec", - "js/spec/video/transcripts/editor_spec", - "js/spec/video/transcripts/videolist_spec", - "js/spec/video/transcripts/message_manager_spec", - "js/spec/video/transcripts/file_uploader_spec", - "js/spec/models/component_template_spec", - "js/spec/models/explicit_url_spec", - "js/spec/models/xblock_info_spec", - "js/spec/models/xblock_validation_spec", - "js/spec/models/license_spec", - "js/spec/utils/drag_and_drop_spec", - "js/spec/utils/handle_iframe_binding_spec", - "js/spec/utils/module_spec", - "js/spec/views/active_video_upload_list_spec", - "js/spec/views/previous_video_upload_spec", - "js/spec/views/previous_video_upload_list_spec", - "js/spec/views/assets_spec", - "js/spec/views/baseview_spec", - "js/spec/views/container_spec", - "js/spec/views/paged_container_spec", - "js/spec/views/group_configuration_spec", - "js/spec/views/unit_outline_spec", - "js/spec/views/xblock_spec", - "js/spec/views/xblock_editor_spec", - "js/spec/views/xblock_string_field_editor_spec", - "js/spec/views/xblock_validation_spec", - "js/spec/views/license_spec", - "js/spec/views/paging_spec", - "js/spec/views/login_studio_spec", - "js/spec/views/pages/container_spec", - "js/spec/views/pages/container_subviews_spec", - "js/spec/views/pages/group_configurations_spec", - "js/spec/views/pages/course_outline_spec", - "js/spec/views/pages/course_rerun_spec", - "js/spec/views/pages/index_spec", - "js/spec/views/pages/library_users_spec", - "js/spec/views/modals/base_modal_spec", - "js/spec/views/modals/edit_xblock_spec", - "js/spec/views/modals/validation_error_modal_spec", - "js/spec/views/settings/main_spec", - "js/spec/factories/xblock_validation_spec", - "js/spec/xblock/cms.runtime.v1_spec", - "js/certificates/spec/models/certificate_spec", - "js/certificates/spec/views/certificate_details_spec", - "js/certificates/spec/views/certificate_editor_spec", - "js/certificates/spec/views/certificates_list_spec", - "js/certificates/spec/views/certificate_preview_spec" -] - -i = 0 -while i < testFiles.length - testFiles[i] = '/base/' + testFiles[i] + '.js' - i++ - -specHelpers = [ - 'common/js/spec_helpers/jasmine-extensions', - 'common/js/spec_helpers/jasmine-stealth', - 'common/js/spec_helpers/jasmine-waituntil' -] - -# Jasmine has a global stack for creating a tree of specs. We need to load -# spec files one by one, otherwise some end up getting nested under others. -requireSerial specHelpers.concat(testFiles), -> -# start test run, once Require.js is done - window.__karma__.start() diff --git a/cms/static/coffee/spec/main_squire.coffee b/cms/static/coffee/spec/main_squire.coffee deleted file mode 100644 index 3743e9602dbc7b8503354fe9f8c620f6345bce33..0000000000000000000000000000000000000000 --- a/cms/static/coffee/spec/main_squire.coffee +++ /dev/null @@ -1,218 +0,0 @@ -requirejs.config({ - baseUrl: '/base/', - - paths: { - "gettext": "xmodule_js/common_static/js/test/i18n", - "mustache": "xmodule_js/common_static/js/vendor/mustache", - "codemirror": "xmodule_js/common_static/js/vendor/CodeMirror/codemirror", - "jquery": "common/js/vendor/jquery", - "jquery-migrate": "common/js/vendor/jquery-migrate", - "jquery.ui": "xmodule_js/common_static/js/vendor/jquery-ui.min", - "jquery.form": "xmodule_js/common_static/js/vendor/jquery.form", - "jquery.markitup": "xmodule_js/common_static/js/vendor/markitup/jquery.markitup", - "jquery.leanModal": "xmodule_js/common_static/js/vendor/jquery.leanModal", - "jquery.smoothScroll": "xmodule_js/common_static/js/vendor/jquery.smooth-scroll.min", - "jquery.scrollTo": "common/js/vendor/jquery.scrollTo", - "jquery.timepicker": "xmodule_js/common_static/js/vendor/timepicker/jquery.timepicker", - "jquery.cookie": "xmodule_js/common_static/js/vendor/jquery.cookie", - "jquery.qtip": "xmodule_js/common_static/js/vendor/jquery.qtip.min", - "jquery.fileupload": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload", - "jquery.fileupload-process": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-process", - "jquery.fileupload-validate": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate", - "jquery.iframe-transport": "xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport", - "jquery.inputnumber": "xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill", - "jquery.immediateDescendents": "xmodule_js/common_static/coffee/src/jquery.immediateDescendents", - "datepair": "xmodule_js/common_static/js/vendor/timepicker/datepair", - "date": "xmodule_js/common_static/js/vendor/date", - "text": "xmodule_js/common_static/js/vendor/requirejs/text", - "underscore": "common/js/vendor/underscore", - "underscore.string": "common/js/vendor/underscore.string", - "backbone": "common/js/vendor/backbone", - "backbone.associations": "xmodule_js/common_static/js/vendor/backbone-associations-min", - "backbone.paginator": "common/js/vendor/backbone.paginator", - "tinymce": "xmodule_js/common_static/js/vendor/tinymce/js/tinymce/tinymce.full.min", - "jquery.tinymce": "xmodule_js/common_static/js/vendor/tinymce/js/tinymce/jquery.tinymce", - "xmodule": "xmodule_js/src/xmodule", - "xblock/cms.runtime.v1": "coffee/src/xblock/cms.runtime.v1", - "xblock/core": "xmodule_js/common_static/js/xblock/core", - "xblock": "xmodule_js/common_static/coffee/src/xblock", - "utility": "xmodule_js/common_static/js/src/utility", - "sinon": "xmodule_js/common_static/js/vendor/sinon-1.17.0", - "squire": "xmodule_js/common_static/js/vendor/Squire", - "modernizr": "edx-pattern-library/js/modernizr-custom", - "afontgarde": "edx-pattern-library/js/afontgarde", - "edxicons": "edx-pattern-library/js/edx-icons", - "draggabilly": "xmodule_js/common_static/js/vendor/draggabilly", - "domReady": "xmodule_js/common_static/js/vendor/domReady", - "URI": "xmodule_js/common_static/js/vendor/URI.min", - - "mathjax": "//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured", - "youtube": "//www.youtube.com/player_api?noext", - - "coffee/src/ajax_prefix": "xmodule_js/common_static/coffee/src/ajax_prefix" - } - shim: { - "gettext": { - exports: "gettext" - }, - "date": { - exports: "Date" - }, - "jquery.ui": { - deps: ["jquery"], - exports: "jQuery.ui" - }, - "jquery.form": { - deps: ["jquery"], - exports: "jQuery.fn.ajaxForm" - }, - "jquery.markitup": { - deps: ["jquery"], - exports: "jQuery.fn.markitup" - }, - "jquery.leanModal": { - deps: ["jquery"], - exports: "jQuery.fn.leanModal" - }, - "jquery.smoothScroll": { - deps: ["jquery"], - exports: "jQuery.fn.smoothScroll" - }, - "jquery.scrollTo": { - deps: ["jquery"], - exports: "jQuery.fn.scrollTo" - }, - "jquery.cookie": { - deps: ["jquery"], - exports: "jQuery.fn.cookie" - }, - "jquery.qtip": { - deps: ["jquery"], - exports: "jQuery.fn.qtip" - }, - "jquery.fileupload": { - deps: ["jquery.ui", "jquery.iframe-transport"], - exports: "jQuery.fn.fileupload" - }, - "jquery.fileupload-process": { - deps: ["jquery.fileupload"] - }, - "jquery.fileupload-validate": { - deps: ["jquery.fileupload"] - }, - "jquery.inputnumber": { - deps: ["jquery"], - exports: "jQuery.fn.inputNumber" - }, - "jquery.tinymce": { - deps: ["jquery", "tinymce"], - exports: "jQuery.fn.tinymce" - }, - "datepair": { - deps: ["jquery.ui", "jquery.timepicker"] - }, - "underscore": { - exports: "_" - }, - "backbone": { - deps: ["underscore", "jquery"], - exports: "Backbone" - }, - "backbone.associations": { - deps: ["backbone"], - exports: "Backbone.Associations" - }, - "backbone.paginator": { - deps: ["backbone"], - exports: "Backbone.PageableCollection" - }, - "youtube": { - exports: "YT" - }, - "codemirror": { - exports: "CodeMirror" - }, - "tinymce": { - exports: "tinymce" - }, - "mathjax": { - exports: "MathJax", - init: -> - MathJax.Hub.Config - tex2jax: - inlineMath: [ - ["\\(","\\)"], - ['[mathjaxinline]','[/mathjaxinline]'] - ] - displayMath: [ - ["\\[","\\]"], - ['[mathjax]','[/mathjax]'] - ] - MathJax.Hub.Configured(); - }, - "URI": { - exports: "URI" - }, - "xmodule": { - exports: "XModule" - }, - "sinon": { - exports: "sinon" - }, - "common/js/spec_helpers/jasmine-extensions": { - deps: ["jquery"] - }, - "common/js/spec_helpers/jasmine-stealth": { - deps: ["underscore", "underscore.string"] - }, - "common/js/spec_helpers/jasmine-waituntil": { - deps: ["jquery"] - }, - "xblock/core": { - exports: "XBlock", - deps: ["jquery", "jquery.immediateDescendents"] - }, - "xblock/runtime.v1": { - exports: "XBlock", - deps: ["xblock/core"] - }, - - "coffee/src/main": { - deps: ["coffee/src/ajax_prefix"] - }, - "coffee/src/ajax_prefix": { - deps: ["jquery"] - }, - "modernizr": { - exports: "Modernizr" - }, - "afontgarde": { - exports: "AFontGarde" - } - } -}); - -jasmine.getFixtures().fixturesPath += 'coffee/fixtures' - -testFiles = [ - 'coffee/spec/views/assets_spec', - 'js/spec/video/translations_editor_spec', - 'js/spec/video/file_uploader_editor_spec', - 'js/spec/models/group_configuration_spec' -] -i = 0 -while i < testFiles.length - testFiles[i] = '/base/' + testFiles[i] + '.js' - i++ - -specHelpers = [ - 'common/js/spec_helpers/jasmine-extensions', - 'common/js/spec_helpers/jasmine-stealth', - 'common/js/spec_helpers/jasmine-waituntil' -] - -# Jasmine has a global stack for creating a tree of specs. We need to load -# spec files one by one, otherwise some end up getting nested under others. -requireSerial specHelpers.concat(testFiles), -> -# start test run, once Require.js is done - window.__karma__.start() diff --git a/cms/static/coffee/src/xblock/cms.runtime.v1.coffee b/cms/static/coffee/src/xblock/cms.runtime.v1.coffee deleted file mode 100644 index 4cbade87bfa60536fd3e0f3647aa5dc27a259a1d..0000000000000000000000000000000000000000 --- a/cms/static/coffee/src/xblock/cms.runtime.v1.coffee +++ /dev/null @@ -1,96 +0,0 @@ -define [ - "jquery", "backbone", "xblock/runtime.v1", "URI", "gettext", - "js/utils/modal", "common/js/components/views/feedback_notification" -], ($, Backbone, XBlock, URI, gettext, ModalUtils, NotificationView) -> - - @BaseRuntime = {} - - class BaseRuntime.v1 extends XBlock.Runtime.v1 - handlerUrl: (element, handlerName, suffix, query, thirdparty) -> - uri = URI(@handlerPrefix).segment($(element).data('usage-id')) - .segment('handler') - .segment(handlerName) - if suffix? then uri.segment(suffix) - if query? then uri.search(query) - uri.toString() - - constructor: () -> - super() - @dispatcher = _.clone(Backbone.Events) - @listenTo('save', @_handleSave) - @listenTo('cancel', @_handleCancel) - @listenTo('error', @_handleError) - @listenTo('modal-shown', (data) -> - @modal = data) - @listenTo('modal-hidden', () -> - @modal = null) - @listenTo('page-shown', (data) -> - @page = data) - - # Notify the Studio client-side runtime of an event so that it can update the UI in a consistent way. - notify: (name, data) -> - @dispatcher.trigger(name, data) - - # Listen to a Studio event and invoke the specified callback when it is triggered. - listenTo: (name, callback) -> - @dispatcher.bind(name, callback, this) - - # Refresh the view for the xblock represented by the specified element. - refreshXBlock: (element) -> - if @page - @page.refreshXBlock(element) - - _handleError: (data) -> - message = data.message || data.msg - if message - # TODO: remove 'Open Assessment' specific default title - title = data.title || gettext("OpenAssessment Save Error") - @alert = new NotificationView.Error - title: title - message: message - closeIcon: false - shown: false - @alert.show() - - _handleSave: (data) -> - # Starting to save, so show a notification - if data.state == 'start' - message = data.message || gettext('Saving') - @notification = new NotificationView.Mini - title: message - @notification.show() - - # Finished saving, so hide the notification and refresh appropriately - else if data.state == 'end' - @_hideAlerts() - - # Notify the modal that the save has completed so that it can hide itself - # and then refresh the xblock. - if @modal and @modal.onSave - @modal.onSave() - # ... else ask it to refresh the newly saved xblock - else if data.element - @refreshXBlock(data.element) - - @notification.hide() - - _handleCancel: () -> - @_hideAlerts() - if @modal - @modal.cancel() - @notify('modal-hidden') - - _hideAlerts: () -> - # Hide any alerts that are being shown - if @alert && @alert.options.shown - @alert.hide() - - @PreviewRuntime = {} - - class PreviewRuntime.v1 extends BaseRuntime.v1 - handlerPrefix: '/preview/xblock' - - @StudioRuntime = {} - - class StudioRuntime.v1 extends BaseRuntime.v1 - handlerPrefix: '/xblock' diff --git a/cms/static/karma_cms.conf.js b/cms/static/karma_cms.conf.js index edfb65d9f49bad318d3cef8101ee564b97a11ac2..f2ef478cd36b8c39d449be6c9e66fc1bca8ed598 100644 --- a/cms/static/karma_cms.conf.js +++ b/cms/static/karma_cms.conf.js @@ -21,11 +21,13 @@ var options = { // Make sure the patterns in sourceFiles and specFiles do not match the same file. // Otherwise Istanbul which is used for coverage tracking will cause tests to not run. sourceFiles: [ + {pattern: 'cms/**/!(*spec|djangojs).js'}, {pattern: 'coffee/src/**/!(*spec).js'}, {pattern: 'js/**/!(*spec|djangojs).js'} ], specFiles: [ + {pattern: 'cms/**/*spec.js'}, {pattern: 'coffee/spec/**/*spec.js'}, {pattern: 'js/certificates/spec/**/*spec.js'}, {pattern: 'js/spec/**/*spec.js'} @@ -37,10 +39,10 @@ var options = { ], runFiles: [ - {pattern: 'coffee/spec/main.js', included: true} + {pattern: 'cms/js/spec/main.js', included: true} ] }; -module.exports = function (config) { +module.exports = function(config) { configModule.configure(config, options); }; diff --git a/cms/static/karma_cms_squire.conf.js b/cms/static/karma_cms_squire.conf.js index 093e51bb554137ef63f5178e5474236d127421e8..d8bdda0c989446934b01330e470fe1a27fd36b00 100644 --- a/cms/static/karma_cms_squire.conf.js +++ b/cms/static/karma_cms_squire.conf.js @@ -36,7 +36,7 @@ var options = { ], runFiles: [ - {pattern: 'coffee/spec/main_squire.js', included: true} + {pattern: 'cms/js/spec/main_squire.js', included: true} ] }; diff --git a/common/static/coffee/spec/xblock/core_spec.coffee b/common/static/coffee/spec/xblock/core_spec.coffee deleted file mode 100644 index e04184710a9c5b4a06e11263ee575adadb95c3d8..0000000000000000000000000000000000000000 --- a/common/static/coffee/spec/xblock/core_spec.coffee +++ /dev/null @@ -1,96 +0,0 @@ -describe "XBlock", -> - beforeEach -> - setFixtures """ - <div> - <div class='xblock' - id='vA' - data-runtime-version="A" - data-runtime-class="TestRuntime" - data-init="initFnA" - data-name="a-name" - /> - <div> - <div class='xblock' - id='vZ' - data-runtime-version="Z" - data-runtime-class="TestRuntime" - data-init="initFnZ" - data-request-token="req-token-z" - /> - </div> - <div class='xblock' id='missing-version' data-init='initFnA' data-name='no-version'/> - <div class='xblock' id='missing-init' data-runtime-version="A" data-name='no-init'/> - </div> - """ - - describe "initializeBlock", -> - beforeEach -> - window.TestRuntime = {} - @runtimeA = {name: 'runtimeA'} - @runtimeZ = {name: 'runtimeZ'} - TestRuntime.vA = jasmine.createSpy().and.returnValue(@runtimeA) - TestRuntime.vZ = jasmine.createSpy().and.returnValue(@runtimeZ) - - window.initFnA = jasmine.createSpy() - window.initFnZ = jasmine.createSpy() - - @fakeChildren = ['list', 'of', 'children'] - spyOn(XBlock, 'initializeXBlocks').and.returnValue(@fakeChildren) - - @vANode = $('#vA')[0] - @vZNode = $('#vZ')[0] - - @vABlock = XBlock.initializeBlock(@vANode, 'req-token-a') - @vZBlock = XBlock.initializeBlock(@vZNode) - @missingVersionBlock = XBlock.initializeBlock($('#missing-version')[0]) - @missingInitBlock = XBlock.initializeBlock($('#missing-init')[0]) - - it "loads the right runtime version", -> - expect(TestRuntime.vA).toHaveBeenCalledWith() - expect(TestRuntime.vZ).toHaveBeenCalledWith() - - it "loads the right init function", -> - expect(window.initFnA).toHaveBeenCalledWith(@runtimeA, @vANode, {}) - expect(window.initFnZ).toHaveBeenCalledWith(@runtimeZ, @vZNode, {}) - - it "loads when missing versions", -> - expect(@missingVersionBlock.element).toBe($('#missing-version')[0]) - expect(@missingVersionBlock.name).toBe('no-version') - - it "loads when missing init fn", -> - expect(@missingInitBlock.element).toBe($('#missing-init')[0]) - expect(@missingInitBlock.name).toBe('no-init') - - it "adds names to blocks", -> - expect(@vABlock.name).toBe('a-name') - - it "leaves leaves missing names undefined", -> - expect(@vZBlock.name).toBeUndefined() - - it "attaches the element to the block", -> - expect(@vABlock.element).toBe(@vANode) - expect(@vZBlock.element).toBe(@vZNode) - expect(@missingVersionBlock.element).toBe($('#missing-version')[0]) - expect(@missingInitBlock.element).toBe($('#missing-init')[0]) - - it "passes through the request token", -> - expect(XBlock.initializeXBlocks).toHaveBeenCalledWith($(@vANode), 'req-token-a') - expect(XBlock.initializeXBlocks).toHaveBeenCalledWith($(@vZNode), 'req-token-z') - - - describe "initializeBlocks", -> - beforeEach -> - spyOn(XBlock, 'initializeBlock') - - @vANode = $('#vA')[0] - @vZNode = $('#vZ')[0] - - it "initializes children", -> - XBlock.initializeBlocks($('#jasmine-fixtures')) - expect(XBlock.initializeBlock).toHaveBeenCalledWith(@vANode, undefined) - expect(XBlock.initializeBlock).toHaveBeenCalledWith(@vZNode, undefined) - - it "only initializes matching request tokens", -> - XBlock.initializeBlocks($('#jasmine-fixtures'), 'req-token-z') - expect(XBlock.initializeBlock).not.toHaveBeenCalledWith(@vANode, jasmine.any(Object)) - expect(XBlock.initializeBlock).toHaveBeenCalledWith(@vZNode, 'req-token-z') diff --git a/common/static/coffee/spec/xblock/runtime.v1_spec.coffee b/common/static/coffee/spec/xblock/runtime.v1_spec.coffee deleted file mode 100644 index 7bad77494d631d6587da1105cf89e7d047fe018b..0000000000000000000000000000000000000000 --- a/common/static/coffee/spec/xblock/runtime.v1_spec.coffee +++ /dev/null @@ -1,21 +0,0 @@ -describe "XBlock.Runtime.v1", -> - beforeEach -> - setFixtures """ - <div class='xblock' data-handler-prefix='/xblock/fake-usage-id/handler'/> - """ - @children = [ - {name: 'childA'}, - {name: 'childB'} - ] - - @element = $('.xblock')[0] - $(@element).prop('xblock_children', @children) - - @runtime = new XBlock.Runtime.v1(@element) - - it "provides a list of children", -> - expect(@runtime.children(@element)).toBe(@children) - - it "maps children by name", -> - expect(@runtime.childMap(@element, 'childA')).toBe(@children[0]) - expect(@runtime.childMap(@element, 'childB')).toBe(@children[1]) diff --git a/common/static/coffee/src/xblock/runtime.v1.coffee b/common/static/coffee/src/xblock/runtime.v1.coffee deleted file mode 100644 index fbe70dc878602d0da1b370db2f61524366f6aba7..0000000000000000000000000000000000000000 --- a/common/static/coffee/src/xblock/runtime.v1.coffee +++ /dev/null @@ -1,14 +0,0 @@ -class XBlock.Runtime.v1 - children: (block) => $(block).prop('xblock_children') - childMap: (block, childName) => - for child in @children(block) - return child if child.name == childName - - # Notify the client-side runtime that an event has occurred. - # This allows the runtime to update the UI in a consistent way - # for different XBlocks. - # `name` is an arbitrary string (for example, "save") - # `data` is an object (for example, {state: 'starting'}) - # The default implementation is a no-op. - # WARNING: This is an interim solution and not officially supported! - notify: (name, data) -> undefined diff --git a/common/static/common/js/karma.common.conf.js b/common/static/common/js/karma.common.conf.js index 36be0d44a50a69c8fdda68f1b3d7bfe35ea592b2..f816b3ce7cc7600134cdda85c18185f53fd106f3 100644 --- a/common/static/common/js/karma.common.conf.js +++ b/common/static/common/js/karma.common.conf.js @@ -54,8 +54,7 @@ var commonFiles = { ], sourceFiles: [ - {pattern: 'common/js/components/**/*.js'}, - {pattern: 'common/js/utils/**/*.js'} + {pattern: 'common/js/!(spec_helpers)/**/!(*spec).js'} ], specFiles: [ diff --git a/common/static/common/js/spec/xblock/core_spec.js b/common/static/common/js/spec/xblock/core_spec.js new file mode 100644 index 0000000000000000000000000000000000000000..9e2a33c363650605fb0feb7f3ab4130cbc8b2fa4 --- /dev/null +++ b/common/static/common/js/spec/xblock/core_spec.js @@ -0,0 +1,111 @@ +(function() { + 'use strict'; + + describe('XBlock', function() { + beforeEach(function() { + return setFixtures( + '<div>\n' + + ' <div class="xblock"\n' + + ' id="vA"\n' + + ' data-runtime-version="A"\n' + + ' data-runtime-class="TestRuntime"\n' + + ' data-init="initFnA"\n' + + ' data-name="a-name"\n' + + ' />\n' + + ' <div>\n' + + ' <div class="xblock"\n' + + ' id="vZ"\n' + + ' data-runtime-version="Z"\n' + + ' data-runtime-class="TestRuntime"\n' + + ' data-init="initFnZ"\n' + + ' data-request-token="req-token-z"\n' + + ' />\n' + + ' </div>\n' + + ' <div class="xblock" id="missing-version" data-init="initFnA" data-name="no-version"/>\n' + + ' <div class="xblock" id="missing-init" data-runtime-version="A" data-name="no-init"/>\n' + + '</div>'); + }); + describe('initializeBlock', function() { + beforeEach(function() { + window.TestRuntime = {}; + this.runtimeA = { + name: 'runtimeA' + }; + this.runtimeZ = { + name: 'runtimeZ' + }; + window.TestRuntime.vA = jasmine.createSpy().and.returnValue(this.runtimeA); + window.TestRuntime.vZ = jasmine.createSpy().and.returnValue(this.runtimeZ); + window.initFnA = jasmine.createSpy(); + window.initFnZ = jasmine.createSpy(); + this.fakeChildren = ['list', 'of', 'children']; + spyOn(XBlock, 'initializeXBlocks').and.returnValue(this.fakeChildren); + this.vANode = $('#vA')[0]; + this.vZNode = $('#vZ')[0]; + this.vABlock = XBlock.initializeBlock(this.vANode, 'req-token-a'); + this.vZBlock = XBlock.initializeBlock(this.vZNode); + this.missingVersionBlock = XBlock.initializeBlock($('#missing-version')[0]); + this.missingInitBlock = XBlock.initializeBlock($('#missing-init')[0]); + }); + + it('loads the right runtime version', function() { + expect(window.TestRuntime.vA).toHaveBeenCalledWith(); + expect(window.TestRuntime.vZ).toHaveBeenCalledWith(); + }); + + it('loads the right init function', function() { + expect(window.initFnA).toHaveBeenCalledWith(this.runtimeA, this.vANode, {}); + expect(window.initFnZ).toHaveBeenCalledWith(this.runtimeZ, this.vZNode, {}); + }); + + it('loads when missing versions', function() { + expect(this.missingVersionBlock.element).toBe($('#missing-version')[0]); + expect(this.missingVersionBlock.name).toBe('no-version'); + }); + + it('loads when missing init fn', function() { + expect(this.missingInitBlock.element).toBe($('#missing-init')[0]); + expect(this.missingInitBlock.name).toBe('no-init'); + }); + + it('adds names to blocks', function() { + expect(this.vABlock.name).toBe('a-name'); + }); + + it('leaves leaves missing names undefined', function() { + expect(this.vZBlock.name).toBeUndefined(); + }); + + it('attaches the element to the block', function() { + expect(this.vABlock.element).toBe(this.vANode); + expect(this.vZBlock.element).toBe(this.vZNode); + expect(this.missingVersionBlock.element).toBe($('#missing-version')[0]); + expect(this.missingInitBlock.element).toBe($('#missing-init')[0]); + }); + + it('passes through the request token', function() { + expect(XBlock.initializeXBlocks).toHaveBeenCalledWith($(this.vANode), 'req-token-a'); + expect(XBlock.initializeXBlocks).toHaveBeenCalledWith($(this.vZNode), 'req-token-z'); + }); + }); + describe('initializeBlocks', function() { + beforeEach(function() { + spyOn(XBlock, 'initializeBlock'); + this.vANode = $('#vA')[0]; + this.vZNode = $('#vZ')[0]; + }); + + it('initializes children', function() { + XBlock.initializeBlocks($('#jasmine-fixtures')); + expect(XBlock.initializeBlock).toHaveBeenCalledWith(this.vANode, void 0); + expect(XBlock.initializeBlock).toHaveBeenCalledWith(this.vZNode, void 0); + }); + + it('only initializes matching request tokens', function() { + XBlock.initializeBlocks($('#jasmine-fixtures'), 'req-token-z'); + expect(XBlock.initializeBlock).not.toHaveBeenCalledWith(this.vANode, jasmine.any(Object)); + expect(XBlock.initializeBlock).toHaveBeenCalledWith(this.vZNode, 'req-token-z'); + }); + }); + }); +}).call(this); diff --git a/common/static/common/js/spec/xblock/runtime.v1_spec.js b/common/static/common/js/spec/xblock/runtime.v1_spec.js new file mode 100644 index 0000000000000000000000000000000000000000..49ea310e97681775d886bb8b8c8b37f66b3b5c67 --- /dev/null +++ b/common/static/common/js/spec/xblock/runtime.v1_spec.js @@ -0,0 +1,28 @@ +(function() { + 'use strict'; + + describe('XBlock.Runtime.v1', function() { + beforeEach(function() { + setFixtures('<div class="xblock" data-handler-prefix="/xblock/fake-usage-id/handler"/>'); + this.children = [ + { + name: 'childA' + }, { + name: 'childB' + } + ]; + this.element = $('.xblock')[0]; + $(this.element).prop('xblock_children', this.children); + this.runtime = new XBlock.Runtime.v1(this.element); + }); + + it('provides a list of children', function() { + expect(this.runtime.children(this.element)).toBe(this.children); + }); + + it('maps children by name', function() { + expect(this.runtime.childMap(this.element, 'childA')).toBe(this.children[0]); + expect(this.runtime.childMap(this.element, 'childB')).toBe(this.children[1]); + }); + }); +}).call(this); diff --git a/common/static/js/xblock/core.js b/common/static/common/js/xblock/core.js similarity index 78% rename from common/static/js/xblock/core.js rename to common/static/common/js/xblock/core.js index 0cbaac3209200a26478ad5b2146ea686c8113a93..02c6ef31f868b7fe232581a093a849d42c05045a 100644 --- a/common/static/js/xblock/core.js +++ b/common/static/common/js/xblock/core.js @@ -1,13 +1,15 @@ (function($, JSON) { - 'use strict'; - function initializeBlockLikes(block_class, initializer, element, requestToken) { - var requestToken = requestToken || $(element).data('request-token'); + var XBlock; + + function initializeBlockLikes(blockClass, initializer, element, requestToken) { + var selector; + requestToken = requestToken || $(element).data('request-token'); if (requestToken) { - var selector = '.' + block_class + '[data-request-token="' + requestToken + '"]'; + selector = '.' + blockClass + '[data-request-token="' + requestToken + '"]'; } else { - var selector = '.' + block_class; + selector = '.' + blockClass; } return $(element).immediateDescendents(selector).map(function(idx, elem) { return initializer(elem, requestToken); @@ -15,17 +17,19 @@ } function elementRuntime(element) { - var $element = $(element); - var runtime = $element.data('runtime-class'); - var version = $element.data('runtime-version'); - var initFnName = $element.data('init'); + var $element = $(element), + runtime = $element.data('runtime-class'), + version = $element.data('runtime-version'), + initFnName = $element.data('init'); if (runtime && version && initFnName) { - return new window[runtime]['v' + version]; + return new window[runtime]['v' + version](); } else { if (runtime || version || initFnName) { - var elementTag = $('<div>').append($element.clone()).html(); - console.log('Block ' + elementTag + ' is missing data-runtime, data-runtime-version or data-init, and can\'t be initialized'); + console.log( + 'Block ' + $element.outerHTML + ' is missing data-runtime, data-runtime-version or data-init, ' + + 'and can\'t be initialized' + ); } // else this XBlock doesn't have a JS init function. return null; } @@ -42,14 +46,13 @@ * The constructor is called with the arguments 'runtime', 'element', * and then all of 'block_args'. */ - function constructBlock(element, block_args) { + function constructBlock(element, blockArgs) { var block; var $element = $(element); var runtime = elementRuntime(element); - block_args.unshift(element); - block_args.unshift(runtime); - + blockArgs.unshift(element); + blockArgs.unshift(runtime); if (runtime) { @@ -59,7 +62,7 @@ // This create a new constructor that can then apply() the block_args // to the initFn. function Block() { - return initFn.apply(this, block_args); + return initFn.apply(this, blockArgs); } Block.prototype = initFn.prototype; @@ -78,7 +81,7 @@ return block; } - var XBlock = { + XBlock = { Runtime: {}, /** @@ -88,11 +91,12 @@ * the children themselves. */ initializeBlock: function(element, requestToken) { - var $element = $(element); + var $element = $(element), + children, asides; - var requestToken = requestToken || $element.data('request-token'); - var children = XBlock.initializeXBlocks($element, requestToken); - var asides = XBlock.initializeXBlockAsides($element, requestToken); + requestToken = requestToken || $element.data('request-token'); + children = XBlock.initializeXBlocks($element, requestToken); + asides = XBlock.initializeXBlockAsides($element, requestToken); if (asides) { children = children.concat(asides); } @@ -106,7 +110,7 @@ * If requestToken is omitted, use the data-request-token attribute from element, or use * the request-tokens specified on the children themselves. */ - initializeAside: function(element, requestToken) { + initializeAside: function(element) { var blockUsageId = $(element).data('block-id'); var blockElement = $(element).siblings('[data-usage-id="' + blockUsageId + '"]')[0]; return constructBlock(element, [blockElement, initArgs(element)]); diff --git a/common/static/common/js/xblock/runtime.v1.js b/common/static/common/js/xblock/runtime.v1.js new file mode 100644 index 0000000000000000000000000000000000000000..1c196cb1ec58bbeeb6a8833b1430d6b4438652e0 --- /dev/null +++ b/common/static/common/js/xblock/runtime.v1.js @@ -0,0 +1,50 @@ +(function() { + 'use strict'; + + XBlock.Runtime.v1 = (function() { + + function v1() { + var _this = this; + this.childMap = function() { + return v1.prototype.childMap.apply(_this, arguments); + }; + this.children = function() { + return v1.prototype.children.apply(_this, arguments); + }; + } + + v1.prototype.children = function(block) { + return $(block).prop('xblock_children'); + }; + + v1.prototype.childMap = function(block, childName) { + var child, _i, _len, _ref; + _ref = this.children(block); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (child.name === childName) { + return child; + } + } + }; + + /** + * Notify the client-side runtime that an event has occurred. + * + * This allows the runtime to update the UI in a consistent way + * for different XBlocks. + * `name` is an arbitrary string (for example, "save") + * `data` is an object (for example, {state: 'starting'}) + * The default implementation is a no-op. + * + * WARNING: This is an interim solution and not officially supported! + */ + v1.prototype.notify = function() { + // Do nothing + }; + + return v1; + + })(); + +}).call(this); diff --git a/common/static/karma_common.conf.js b/common/static/karma_common.conf.js index cf19a73fd72cd63d32b43ad733134d5266bf850e..9a1c333b9d8f073c5fd2d18d3544701037453609 100644 --- a/common/static/karma_common.conf.js +++ b/common/static/karma_common.conf.js @@ -11,7 +11,7 @@ var options = { useRequireJs: false, - normalizePathsForCoverageFunc: function (appRoot, pattern) { + normalizePathsForCoverageFunc: function(appRoot, pattern) { return path.join(appRoot, '/common/static/' + pattern); }, @@ -50,16 +50,17 @@ var options = { // Make sure the patterns in sourceFiles and specFiles do not match the same file. // Otherwise Istanbul which is used for coverage tracking will cause tests to not run. sourceFiles: [ - {pattern: 'js/xblock/**/*.js', included: true}, {pattern: 'coffee/src/**/*.js', included: true}, - {pattern: 'js/src/**/*.js', included: true}, - {pattern: 'js/capa/src/**/*.js', included: true} + {pattern: 'common/js/xblock/core.js', included: true}, + {pattern: 'common/js/xblock/runtime.v1.js', included: true}, + {pattern: 'js/capa/src/**/*.js', included: true}, + {pattern: 'js/src/**/*.js', included: true} ], specFiles: [ {pattern: 'coffee/spec/**/*.js', included: true}, - {pattern: 'js/spec/**/*.js', included: true}, - {pattern: 'js/capa/spec/**/*.js', included: true} + {pattern: 'common/js/spec/xblock/*.js', included: true}, + {pattern: 'js/**/*spec.js', included: true} ], fixtureFiles: [ @@ -69,6 +70,6 @@ var options = { ] }; -module.exports = function (config) { +module.exports = function(config) { configModule.configure(config, options); }; diff --git a/lms/envs/common.py b/lms/envs/common.py index 5d8db0c6db9922576ae76699bc9196f87d36c941..5ea1ecac1dd05d4f1bba4e00c107726171019b24 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -1528,9 +1528,14 @@ PIPELINE_CSS = { } -common_js = set(rooted_glob(COMMON_ROOT / 'static', 'coffee/src/**/*.js')) - set(courseware_js + discussion_js + notes_js + instructor_dash_js) # pylint: disable=line-too-long -project_js = set(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/**/*.js')) - set(courseware_js + discussion_js + notes_js + instructor_dash_js) # pylint: disable=line-too-long - +separately_bundled_js = set(courseware_js + discussion_js + notes_js + instructor_dash_js) +common_js = sorted(set(rooted_glob(COMMON_ROOT / 'static', 'coffee/src/**/*.js')) - separately_bundled_js) +xblock_runtime_js = [ + 'common/js/xblock/core.js', + 'common/js/xblock/runtime.v1.js', + 'lms/js/xblock/lms.runtime.v1.js', +] +lms_application_js = sorted(set(rooted_glob(PROJECT_ROOT / 'static', 'coffee/src/**/*.js')) - separately_bundled_js) PIPELINE_JS = { 'base_application': { @@ -1539,13 +1544,14 @@ PIPELINE_JS = { }, 'application': { - - # Application will contain all paths not in courseware_only_js - 'source_filenames': ['js/xblock/core.js'] + sorted(common_js) + sorted(project_js) + base_application_js + [ - 'js/sticky_filter.js', - 'js/query-params.js', - 'js/vendor/moment.min.js', - ], + 'source_filenames': ( + common_js + xblock_runtime_js + base_application_js + lms_application_js + + [ + 'js/sticky_filter.js', + 'js/query-params.js', + 'js/vendor/moment.min.js', + ] + ), 'output_filename': 'js/lms-application.js', }, 'proctoring': { diff --git a/lms/static/coffee/src/xblock/lms.runtime.v1.coffee b/lms/static/coffee/src/xblock/lms.runtime.v1.coffee deleted file mode 100644 index f10b1ae1c506d7e018b0753eb2c845f1a6b700b5..0000000000000000000000000000000000000000 --- a/lms/static/coffee/src/xblock/lms.runtime.v1.coffee +++ /dev/null @@ -1,18 +0,0 @@ -@LmsRuntime = {} - -class LmsRuntime.v1 extends XBlock.Runtime.v1 - handlerUrl: (element, handlerName, suffix, query, thirdparty) -> - courseId = $(element).data("course-id") - usageId = $(element).data("usage-id") - handlerAuth = if thirdparty then "handler_noauth" else "handler" - - uri = URI('/courses').segment(courseId) - .segment('xblock') - .segment(usageId) - .segment(handlerAuth) - .segment(handlerName) - - if suffix? then uri.segment(suffix) - if query? then uri.search(query) - - uri.toString() diff --git a/lms/static/karma_lms_coffee.conf.js b/lms/static/karma_lms_coffee.conf.js index aab58949281de9cf5cb83145c707354c18cd3a29..78866c684c879e3a22beb7cf9a931a78ecd12678 100644 --- a/lms/static/karma_lms_coffee.conf.js +++ b/lms/static/karma_lms_coffee.conf.js @@ -29,6 +29,7 @@ var options = { {pattern: 'common/js/vendor/jquery.js', included: true}, {pattern: 'common/js/vendor/jquery-migrate.js', included: true}, {pattern: 'common/js/vendor/underscore.js', included: true}, + {pattern: 'common/js/xblock/*.js', included: true}, {pattern: 'xmodule_js/common_static/js/src/logger.js', included: true}, {pattern: 'xmodule_js/common_static/js/test/i18n.js', included: true}, {pattern: 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js', included: true}, @@ -38,8 +39,6 @@ var options = { {pattern: 'xmodule_js/common_static/js/vendor/jquery-ui.min.js', included: true}, {pattern: 'xmodule_js/common_static/js/vendor/URI.min.js', included: true}, - {pattern: 'xmodule_js/common_static/js/xblock/*.js', included: true}, - {pattern: 'xmodule_js/common_static/coffee/src/xblock/*.js', included: true}, {pattern: 'xmodule_js/src/capa/*.js', included: true}, {pattern: 'xmodule_js/src/video/*.js', included: true}, {pattern: 'xmodule_js/src/xmodule.js', included: true}, diff --git a/lms/static/lms/js/require-config.js b/lms/static/lms/js/require-config.js index a1f37133f4b8f625ad30e3daaf469fed6f5ccc9f..bda10131a461dbcfa880aff443abae63e66a4d6f 100644 --- a/lms/static/lms/js/require-config.js +++ b/lms/static/lms/js/require-config.js @@ -1,4 +1,5 @@ -;(function (require, define) { +;(function(require, define) { + 'use strict'; // 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. @@ -24,207 +25,207 @@ } } else { - console.error("Expected library to be included on page, but not found on window object: " + name); + console.error('Expected library to be included on page, but not found on window object: ' + name); } }; - defineDependency("jQuery", "jquery"); - defineDependency("jQuery", "jquery-migrate"); - defineDependency("_", "underscore"); - defineDependency("s", "underscore.string"); - // Underscore.string no longer installs itself directly on "_". For compatibility with existing - // code, add it to "_" with its previous name. + defineDependency('jQuery', 'jquery'); + defineDependency('jQuery', 'jquery-migrate'); + defineDependency('_', 'underscore'); + defineDependency('s', 'underscore.string'); + // Underscore.string no longer installs itself directly on '_'. For compatibility with existing + // code, add it to '_' with its previous name. if (window._ && window.s) { window._.str = window.s; } - defineDependency("gettext", "gettext"); - defineDependency("Logger", "logger"); - defineDependency("URI", "URI"); - defineDependency("Backbone", "backbone"); - defineDependency("Modernizr", "modernizr"); + defineDependency('gettext', 'gettext'); + defineDependency('Logger', 'logger'); + defineDependency('URI', 'URI'); + defineDependency('Backbone', 'backbone'); + defineDependency('Modernizr', 'modernizr'); - // Add the UI Toolkit helper classes that have been installed in the "edx" namespace - defineDependency("edx.HtmlUtils", "edx-ui-toolkit/js/utils/html-utils"); - defineDependency("edx.StringUtils", "edx-ui-toolkit/js/utils/string-utils"); + // Add the UI Toolkit helper classes that have been installed in the 'edx' namespace + defineDependency('edx.HtmlUtils', 'edx-ui-toolkit/js/utils/html-utils'); + defineDependency('edx.StringUtils', 'edx-ui-toolkit/js/utils/string-utils'); // utility.js adds two functions to the window object, but does not return anything - defineDependency("isExternal", "utility", true); + defineDependency('isExternal', 'utility', true); } require.config({ // NOTE: baseUrl has been previously set in lms/templates/main.html waitSeconds: 60, paths: { - "annotator_1.2.9": "js/vendor/edxnotes/annotator-full.min", - "date": "js/vendor/date", - "moment": "js/vendor/moment.min", - "moment-with-locales": "xmodule_js/common_static/js/vendor/moment-with-locales.min", - "text": "js/vendor/requirejs/text", - "logger": "js/src/logger", - "backbone": "common/js/vendor/backbone", - "backbone-super": "js/vendor/backbone-super", - "backbone.paginator": "common/js/vendor/backbone.paginator", - "underscore": "common/js/vendor/underscore", - "underscore.string": "common/js/vendor/underscore.string", + 'annotator_1.2.9': 'js/vendor/edxnotes/annotator-full.min', + 'date': 'js/vendor/date', + 'moment': 'js/vendor/moment.min', + 'moment-with-locales': 'xmodule_js/common_static/js/vendor/moment-with-locales.min', + 'text': 'js/vendor/requirejs/text', + 'logger': 'js/src/logger', + 'backbone': 'common/js/vendor/backbone', + 'backbone-super': 'js/vendor/backbone-super', + 'backbone.paginator': 'common/js/vendor/backbone.paginator', + 'underscore': 'common/js/vendor/underscore', + 'underscore.string': 'common/js/vendor/underscore.string', // The jquery-migrate library was added in upgrading from // jQuery 1.7.x to 2.2.x. This config allows developers - // to depend on "jquery" which opaquely requires both + // to depend on 'jquery' which opaquely requires both // libraries. - "jquery": "common/js/vendor/jquery", - "jquery-migrate": "common/js/vendor/jquery-migrate", - "jquery.scrollTo": "common/js/vendor/jquery.scrollTo", - "jquery.cookie": "js/vendor/jquery.cookie", + 'jquery': 'common/js/vendor/jquery', + 'jquery-migrate': 'common/js/vendor/jquery-migrate', + 'jquery.scrollTo': 'common/js/vendor/jquery.scrollTo', + 'jquery.cookie': 'js/vendor/jquery.cookie', 'jquery.timeago': 'js/vendor/jquery.timeago', - "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", - "modernizr": "edx-pattern-library/js/modernizr-custom", - "afontgarde": "edx-pattern-library/js/afontgarde", - "edxicons": "edx-pattern-library/js/edx-icons", - "draggabilly": "js/vendor/draggabilly", + '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', + 'modernizr': 'edx-pattern-library/js/modernizr-custom', + 'afontgarde': 'edx-pattern-library/js/afontgarde', + 'edxicons': 'edx-pattern-library/js/edx-icons', + 'draggabilly': 'js/vendor/draggabilly', // 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", - "picturefill": "common/js/vendor/picturefill" + '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', + 'picturefill': 'common/js/vendor/picturefill' // end of files needed by OVA }, shim: { - "annotator_1.2.9": { - deps: ["jquery"], - exports: "Annotator" + 'annotator_1.2.9': { + deps: ['jquery'], + exports: 'Annotator' }, - "date": { - exports: "Date" + 'date': { + exports: 'Date' }, - "jquery": { - exports: "jQuery" + 'jquery': { + exports: 'jQuery' }, - "jquery-migrate": ['jquery'], - "jquery.cookie": { - deps: ["jquery"], - exports: "jQuery.fn.cookie" + 'jquery-migrate': ['jquery'], + 'jquery.cookie': { + deps: ['jquery'], + exports: 'jQuery.fn.cookie' }, - "jquery.timeago": { - deps: ["jquery"], - exports: "jQuery.timeago" + 'jquery.timeago': { + deps: ['jquery'], + exports: 'jQuery.timeago' }, - "jquery.url": { - deps: ["jquery"], - exports: "jQuery.url" + 'jquery.url': { + deps: ['jquery'], + exports: 'jQuery.url' }, - "jquery.fileupload": { - deps: ["jquery.ui", "jquery.iframe-transport"], - exports: "jQuery.fn.fileupload" + 'jquery.fileupload': { + deps: ['jquery.ui', 'jquery.iframe-transport'], + exports: 'jQuery.fn.fileupload' }, - "jquery.tinymce": { - deps: ["jquery", "tinymce"], - exports: "jQuery.fn.tinymce" + 'jquery.tinymce': { + deps: ['jquery', 'tinymce'], + exports: 'jQuery.fn.tinymce' }, - "backbone.paginator": { - deps: ["backbone"], - exports: "Backbone.PageableCollection" + 'backbone.paginator': { + deps: ['backbone'], + exports: 'Backbone.PageableCollection' }, - "backbone-super": { - deps: ["backbone"] + 'backbone-super': { + deps: ['backbone'] }, - "string_utils": { - deps: ["underscore"], - exports: "interpolate_text" + 'string_utils': { + deps: ['underscore'], + exports: 'interpolate_text' }, // Needed by OVA - "video.dev": { - exports:"videojs" + 'video.dev': { + exports: 'videojs' }, - "vjs.youtube": { - deps: ["video.dev"] + 'vjs.youtube': { + deps: ['video.dev'] }, - "rangeslider": { - deps: ["video.dev"] + 'rangeslider': { + deps: ['video.dev'] }, - "annotator": { - exports: "Annotator" + 'annotator': { + exports: 'Annotator' }, - "annotator-harvardx":{ - deps: ["annotator"] + 'annotator-harvardx': { + deps: ['annotator'] }, - "share-annotator": { - deps: ["annotator"] + 'share-annotator': { + deps: ['annotator'] }, - "richText-annotator": { - deps: ["annotator", "tinymce"] + 'richText-annotator': { + deps: ['annotator', 'tinymce'] }, - "reply-annotator": { - deps: ["annotator"] + 'reply-annotator': { + deps: ['annotator'] }, - "tags-annotator": { - deps: ["annotator"] + 'tags-annotator': { + deps: ['annotator'] }, - "diacritic-annotator": { - deps: ["annotator"] + 'diacritic-annotator': { + deps: ['annotator'] }, - "flagging-annotator": { - deps: ["annotator"] + 'flagging-annotator': { + deps: ['annotator'] }, - "grouping-annotator": { - deps: ["annotator"] + 'grouping-annotator': { + deps: ['annotator'] }, - "ova": { - exports: "ova", + '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" + '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", + '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" + '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" + 'tinymce': { + exports: 'tinymce' }, // End of needed by OVA - "moment": { - exports: "moment" + 'moment': { + exports: 'moment' }, - "moment-with-locales": { - exports: "moment" + 'moment-with-locales': { + exports: 'moment' }, - "afontgarde": { - exports: "AFontGarde" + 'afontgarde': { + exports: 'AFontGarde' }, // Because Draggabilly is being used by video code, the namespaced version of // require is not being recognized. Therefore the library is being added to the // global namespace instead of being registered in require. - "draggabilly": { - exports: "Draggabilly" + 'draggabilly': { + exports: 'Draggabilly' } } }); diff --git a/lms/static/lms/js/spec/main.js b/lms/static/lms/js/spec/main.js index 5d397d92953bb7f575c950ddfe32cfdf0b5c2eaa..6d58500cce713ad506d765dc893a5a62631a1a47 100644 --- a/lms/static/lms/js/spec/main.js +++ b/lms/static/lms/js/spec/main.js @@ -56,9 +56,8 @@ 'coffee/src/ajax_prefix': 'xmodule_js/common_static/coffee/src/ajax_prefix', 'coffee/src/instructor_dashboard/student_admin': 'coffee/src/instructor_dashboard/student_admin', 'xmodule_js/common_static/js/test/add_ajax_prefix': 'xmodule_js/common_static/js/test/add_ajax_prefix', - 'xblock/core': 'xmodule_js/common_static/js/xblock/core', - 'xblock/runtime.v1': 'xmodule_js/common_static/coffee/src/xblock/runtime.v1', - 'xblock/lms.runtime.v1': 'coffee/src/xblock/lms.runtime.v1', + 'xblock/lms.runtime.v1': 'lms/js/xblock/lms.runtime.v1', + 'xblock': 'common/js/xblock', 'capa/display': 'xmodule_js/src/capa/display', 'string_utils': 'xmodule_js/common_static/js/src/string_utils', 'logger': 'xmodule_js/common_static/js/src/logger', diff --git a/lms/static/lms/js/xblock/lms.runtime.v1.js b/lms/static/lms/js/xblock/lms.runtime.v1.js new file mode 100644 index 0000000000000000000000000000000000000000..50903ccaa39577383b682747bfaeaa14dfb0dd9e --- /dev/null +++ b/lms/static/lms/js/xblock/lms.runtime.v1.js @@ -0,0 +1,55 @@ +(function(URI) { + 'use strict'; + + var __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { + var key; + for (key in parent) { + if (__hasProp.call(parent, key)) { + child[key] = parent[key]; + } + } + function Ctor() { + this.constructor = child; + } + Ctor.prototype = parent.prototype; + child.prototype = new Ctor(); + child.__super__ = parent.prototype; + return child; + }; + + this.LmsRuntime = {}; + + this.LmsRuntime.v1 = (function(_super) { + + __extends(v1, _super); + + function v1() { + return v1.__super__.constructor.apply(this, arguments); + } + + v1.prototype.handlerUrl = function(element, handlerName, suffix, query, thirdparty) { + var courseId, handlerAuth, uri, usageId; + courseId = $(element).data('course-id'); + usageId = $(element).data('usage-id'); + handlerAuth = thirdparty ? 'handler_noauth' : 'handler'; + uri = URI('/courses') + .segment(courseId) + .segment('xblock') + .segment(usageId) + .segment(handlerAuth) + .segment(handlerName); + if (suffix !== null) { + uri.segment(suffix); + } + if (query !== null) { + uri.search(query); + } + return uri.toString(); + }; + + return v1; + + })(XBlock.Runtime.v1); + +}).call(this, URI); // jshint ignore:line