Skip to content
Snippets Groups Projects
Unverified Commit 947d8273 authored by Calen Pennington's avatar Calen Pennington Committed by GitHub
Browse files

Merge pull request #18341 from edx/revert-18290-switch-container-factory-to-webpack

Revert "Switch container factory to webpack"
parents 6d8aebe0 18d93b00
No related merge requests found
Showing
with 361 additions and 335 deletions
......@@ -17,26 +17,17 @@ DEPRECATED_SETTINGS = ["CSS Class for Course Reruns", "Hide Progress Tab", "XQA
@step('I select the Advanced Settings$')
def i_select_advanced_settings(step):
world.wait_for_js_to_load() # pylint: disable=no-member
world.wait_for_js_variable_truthy('window.studioNavMenuActive') # pylint: disable=no-member
for _ in range(5):
world.click_course_settings() # pylint: disable=no-member
# The click handlers are set up so that if you click <body>
# the menu disappears. This means that if we're even a *little*
# bit off on the last item ('Advanced Settings'), the menu
# will close and the test will fail.
# For this reason, we retrieve the link and visit it directly
# This is what the browser *should* be doing, since it's just a native
# link with no JavaScript involved.
link_css = 'li.nav-course-settings-advanced a'
try:
world.wait_for_visible(link_css) # pylint: disable=no-member
break
except AssertionError:
continue
world.click_course_settings()
# The click handlers are set up so that if you click <body>
# the menu disappears. This means that if we're even a *little*
# bit off on the last item ('Advanced Settings'), the menu
# will close and the test will fail.
# For this reason, we retrieve the link and visit it directly
# This is what the browser *should* be doing, since it's just a native
# link with no JavaScript involved.
link_css = 'li.nav-course-settings-advanced a'
world.wait_for_visible(link_css)
link = world.css_find(link_css).first['href']
world.visit(link)
......
......@@ -247,6 +247,7 @@ def create_unit_from_course_outline():
world.css_click(selector)
world.wait_for_mathjax()
world.wait_for_xmodule()
world.wait_for_loading()
assert world.is_css_present('ul.new-component-type')
......
......@@ -15,6 +15,11 @@ Feature: CMS.HTML Editor
Then I can modify the display name
And my display name change is persisted on save
Scenario: Edit High Level source is available for LaTeX html
Given I have created an E-text Written in LaTeX
When I edit and select Settings
Then Edit High Level Source is visible
Scenario: TinyMCE image plugin sets urls correctly
Given I have created a Blank HTML Page
When I edit the page
......
......@@ -82,7 +82,22 @@ Feature: CMS.Problem Editor
And I can modify the display name
Then If I press Cancel my changes are not persisted
Scenario: Edit High Level source is available for LaTeX problem
Given I have created a LaTeX Problem
When I edit and select Settings
Then Edit High Level Source is visible
Scenario: Cheat sheet visible on toggle
Given I have created a Blank Common Problem
And I can edit the problem
Then I can see cheatsheet
Scenario: Reply on Annotation and Return to Annotation link works for Annotation problem
Given I have created a unit with advanced module "annotatable"
And I have created an advanced component "Annotation" of type "annotatable"
And I have created an advanced problem of type "Blank Advanced Problem"
And I edit first blank advanced problem for annotation response
When I mouseover on "annotatable-span"
Then I can see Reply to Annotation link
And I see that page has scrolled "down" when I click on "annotatable-reply" link
And I see that page has scrolled "up" when I click on "annotation-return" link
// This file is designed to load all the XModule Javascript files in one wad
// using requirejs. It is passed through the Mako template system, which
// populates the `urls` variable with a list of paths to XModule JS files.
// These files assume that several libraries are available and bound to
// variables in the global context, so we load those libraries with requirejs
// and attach them to the global context manually.
define(
[
'jquery', 'underscore', 'codemirror', 'tinymce', 'scriptjs',
'jquery.tinymce', 'jquery.qtip', 'jquery.scrollTo', 'jquery.flot',
'jquery.cookie',
'utility'
],
function($, _, CodeMirror, tinymce, $script) {
'use strict';
window.$ = $;
window._ = _;
$script(
'//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js' +
'?config=TeX-MML-AM_SVG&delayStartupUntil=configured',
'mathjax'
);
window.CodeMirror = CodeMirror;
window.RequireJS = {
requirejs: {}, // This is never used by current xmodules
require: $script, // $script([deps], callback) acts approximately like the require function
define: define
};
/**
* Loads all modules one-by-one in exact order.
* The module should be used until we'll use RequireJS for XModules.
* @param {Array} modules A list of urls.
* @return {jQuery Promise}
**/
function requireQueue(modules) {
var deferred = $.Deferred();
function loadScript(queue) {
$script.ready('mathjax', function() {
// Loads the next script if queue is not empty.
if (queue.length) {
$script([queue.shift()], function() {
loadScript(queue);
});
} else {
deferred.resolve();
}
});
}
loadScript(modules.concat());
return deferred.promise();
}
// if (!window.xmoduleUrls) {
// throw Error('window.xmoduleUrls must be defined');
// }
return requireQueue([]);
}
);
## This file is designed to load all the XModule Javascript files in one wad
## using requirejs. It is passed through the Mako template system, which
## populates the `urls` variable with a list of paths to XModule JS files.
## These files assume that several libraries are available and bound to
## variables in the global context, so we load those libraries with requirejs
## and attach them to the global context manually.
define(["jquery", "underscore", "codemirror", "tinymce",
"jquery.tinymce", "jquery.qtip", "jquery.scrollTo", "jquery.flot",
"jquery.cookie",
"utility"],
function($, _, CodeMirror, tinymce) {
window.$ = $;
window._ = _;
require(['mathjax']);
window.CodeMirror = CodeMirror;
window.RequireJS = {
'requirejs': requirejs,
'require': require,
'define': define
};
/**
* Loads all modules one-by-one in exact order.
* The module should be used until we'll use RequireJS for XModules.
* @param {Array} modules A list of urls.
* @return {jQuery Promise}
**/
var requireQueue = function(modules) {
var deferred = $.Deferred();
var loadScript = function (queue) {
// Loads the next script if queue is not empty.
if (queue.length) {
require([queue.shift()], function() {
loadScript(queue);
});
} else {
deferred.resolve();
}
};
loadScript(modules.concat());
return deferred.promise();
};
return requireQueue(${urls});
});
"""
URL patterns for Javascript files used to load all of the XModule JS in one wad.
"""
from django.conf.urls import url
from pipeline_js.views import xmodule_js_files, requirejs_xmodule
urlpatterns = [
url(r'^files\.json$', xmodule_js_files, name='xmodule_js_files'),
url(r'^xmodule\.js$', requirejs_xmodule, name='requirejs_xmodule'),
]
"""
Utilities for returning XModule JS (used by requirejs)
Views for returning XModule JS (used by requirejs)
"""
import json
from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage
from django.http import HttpResponse
from edxmako.shortcuts import render_to_response
def get_xmodule_urls():
......@@ -16,3 +21,24 @@ def get_xmodule_urls():
else:
paths = [pipeline_js_settings["output_filename"]]
return [staticfiles_storage.url(path) for path in paths]
def xmodule_js_files(request): # pylint: disable=unused-argument
"""
View function that returns XModule URLs as a JSON list; meant to be used
as an API
"""
urls = get_xmodule_urls()
return HttpResponse(json.dumps(urls), content_type="application/json")
def requirejs_xmodule(request): # pylint: disable=unused-argument
"""
View function that returns a requirejs-wrapped Javascript file that
loads all the XModule URLs; meant to be loaded via requireJS
"""
return render_to_response(
"xmodule.js",
{"urls": get_xmodule_urls()},
content_type="text/javascript",
)
......@@ -110,6 +110,10 @@ FEATURES['ENABLE_DISCUSSION_SERVICE'] = False
# We do not yet understand why this occurs. Setting this to true is a stopgap measure
USE_I18N = True
# Override the test stub webpack_loader that is installed in test.py.
INSTALLED_APPS = [app for app in INSTALLED_APPS if app != 'openedx.tests.util.webpack_loader']
INSTALLED_APPS.append('webpack_loader')
# Include the lettuce app for acceptance testing, including the 'harvest' django-admin command
# django.contrib.staticfiles used to be loaded by lettuce, now we must add it ourselves
# django.contrib.staticfiles is not added to lms as there is a ^/static$ route built in to the app
......
......@@ -49,9 +49,6 @@ update_module_store_settings(
# Needed to enable licensing on video modules
XBLOCK_SETTINGS.update({'VideoDescriptor': {'licensing_enabled': True}})
# Capture the console log via template includes, until webdriver supports log capture again
CAPTURE_CONSOLE_LOG = True
############################ STATIC FILES #############################
# Enable debug so that static assets are served by Django
......
......@@ -16,9 +16,3 @@ LOGGING['handlers']['local'] = LOGGING['handlers']['tracking'] = {
}
LOGGING['loggers']['tracking']['handlers'] = ['console']
# Point the URL used to test YouTube availability to our stub YouTube server
BOK_CHOY_HOST = os.environ['BOK_CHOY_HOSTNAME']
YOUTUBE['API'] = "http://{}:{}/get_youtube_api/".format(BOK_CHOY_HOST, YOUTUBE_PORT)
YOUTUBE['METADATA_URL'] = "http://{}:{}/test_youtube/".format(BOK_CHOY_HOST, YOUTUBE_PORT)
YOUTUBE['TEXT_API']['url'] = "{}:{}/test_transcripts_youtube/".format(BOK_CHOY_HOST, YOUTUBE_PORT)
......@@ -54,6 +54,8 @@ TEST_ROOT = path('test_root')
# Want static files in the same dir for running on jenkins.
STATIC_ROOT = TEST_ROOT / "staticfiles"
INSTALLED_APPS = [app for app in INSTALLED_APPS if app != 'webpack_loader']
INSTALLED_APPS.append('openedx.tests.util.webpack_loader')
WEBPACK_LOADER['DEFAULT']['STATS_FILE'] = STATIC_ROOT / "webpack-stats.json"
GITHUB_REPO_ROOT = TEST_ROOT / "data"
......
......@@ -19,19 +19,24 @@
modules: getModulesList([
'js/factories/asset_index',
'js/factories/base',
'js/factories/container',
'js/factories/course_create_rerun',
'js/factories/course_info',
'js/factories/edit_tabs',
'js/factories/export',
'js/factories/group_configurations',
'js/certificates/factories/certificates_page_factory',
'js/factories/index',
'js/factories/library',
'js/factories/manage_users',
'js/factories/outline',
'js/factories/register',
'js/factories/settings',
'js/factories/settings_advanced',
'js/factories/settings_graders',
'js/factories/videos_index'
'js/factories/textbooks',
'js/factories/videos_index',
'js/factories/xblock_validation'
]),
/**
* By default all the configuration for optimization happens from the command
......
/* globals AjaxPrefix */
define([
'domReady',
'jquery',
'underscore',
'underscore.string',
'backbone',
'gettext',
'../../common/js/components/views/feedback_notification',
'jquery.cookie'
], function(domReady, $, _, str, Backbone, gettext, NotificationView) {
(function(AjaxPrefix) {
'use strict';
var main, sendJSON;
main = function() {
AjaxPrefix.addAjaxPrefix(jQuery, function() {
return $("meta[name='path_prefix']").attr('content');
});
window.CMS = window.CMS || {};
window.CMS.URL = window.CMS.URL || {};
window.onTouchBasedDevice = function() {
return navigator.userAgent.match(/iPhone|iPod|iPad|Android/i);
};
_.extend(window.CMS, Backbone.Events);
Backbone.emulateHTTP = true;
$.ajaxSetup({
headers: {
'X-CSRFToken': $.cookie('csrftoken')
},
dataType: 'json',
content: {
script: false
}
});
$(document).ajaxError(function(event, jqXHR, ajaxSettings) {
var msg, contentType,
message = gettext('This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online.'); // eslint-disable-line max-len
if (ajaxSettings.notifyOnError === false) {
return;
}
contentType = jqXHR.getResponseHeader('content-type');
if (contentType && contentType.indexOf('json') > -1 && jqXHR.responseText) {
message = JSON.parse(jqXHR.responseText).error;
}
msg = new NotificationView.Error({
title: gettext("Studio's having trouble saving your work"),
message: message
define([
'domReady',
'jquery',
'underscore.string',
'backbone',
'gettext',
'../../common/js/components/views/feedback_notification',
'jquery.cookie'
], function(domReady, $, str, Backbone, gettext, NotificationView) {
var main, sendJSON;
main = function() {
AjaxPrefix.addAjaxPrefix(jQuery, function() {
return $("meta[name='path_prefix']").attr('content');
});
console.log('Studio AJAX Error', { // eslint-disable-line no-console
url: event.currentTarget.URL,
response: jqXHR.responseText,
status: jqXHR.status
});
return msg.show();
});
sendJSON = function(url, data, callback, type) { // eslint-disable-line no-param-reassign
if ($.isFunction(data)) {
callback = data;
data = undefined;
}
return $.ajax({
url: url,
type: type,
contentType: 'application/json; charset=utf-8',
window.CMS = window.CMS || {};
window.CMS.URL = window.CMS.URL || {};
window.onTouchBasedDevice = function() {
return navigator.userAgent.match(/iPhone|iPod|iPad|Android/i);
};
_.extend(window.CMS, Backbone.Events);
Backbone.emulateHTTP = true;
$.ajaxSetup({
headers: {
'X-CSRFToken': $.cookie('csrftoken')
},
dataType: 'json',
data: JSON.stringify(data),
success: callback,
global: data ? data.global : true // Trigger global AJAX error handler or not
content: {
script: false
}
});
$(document).ajaxError(function(event, jqXHR, ajaxSettings) {
var msg, contentType,
message = gettext('This may be happening because of an error with our server or your internet connection. Try refreshing the page or making sure you are online.'); // eslint-disable-line max-len
if (ajaxSettings.notifyOnError === false) {
return;
}
contentType = jqXHR.getResponseHeader('content-type');
if (contentType && contentType.indexOf('json') > -1 && jqXHR.responseText) {
message = JSON.parse(jqXHR.responseText).error;
}
msg = new NotificationView.Error({
title: gettext("Studio's having trouble saving your work"),
message: message
});
console.log('Studio AJAX Error', { // eslint-disable-line no-console
url: event.currentTarget.URL,
response: jqXHR.responseText,
status: jqXHR.status
});
return msg.show();
});
sendJSON = function(url, data, callback, type) { // eslint-disable-line no-param-reassign
if ($.isFunction(data)) {
callback = data;
data = undefined;
}
return $.ajax({
url: url,
type: type,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(data),
success: callback,
global: data ? data.global : true // Trigger global AJAX error handler or not
});
};
$.postJSON = function(url, data, callback) { // eslint-disable-line no-param-reassign
return sendJSON(url, data, callback, 'POST');
};
$.patchJSON = function(url, data, callback) { // eslint-disable-line no-param-reassign
return sendJSON(url, data, callback, 'PATCH');
};
return domReady(function() {
if (window.onTouchBasedDevice()) {
return $('body').addClass('touch-based-device');
}
});
};
$.postJSON = function(url, data, callback) { // eslint-disable-line no-param-reassign
return sendJSON(url, data, callback, 'POST');
};
$.patchJSON = function(url, data, callback) { // eslint-disable-line no-param-reassign
return sendJSON(url, data, callback, 'PATCH');
};
return domReady(function() {
if (window.onTouchBasedDevice()) {
return $('body').addClass('touch-based-device');
}
return null;
});
};
main();
return main;
});
main();
return main;
});
}).call(this, AjaxPrefix);
......@@ -4,7 +4,6 @@
(function(requirejs, requireSerial) {
'use strict';
var i, specHelpers, testFiles;
if (window) {
define('add-a11y-deps',
[
......@@ -21,6 +20,8 @@
});
}
var i, specHelpers, testFiles;
requirejs.config({
baseUrl: '/base/',
paths: {
......@@ -229,6 +230,7 @@
testFiles = [
'cms/js/spec/main_spec',
'cms/js/spec/xblock/cms.runtime.v1_spec',
'js/spec/models/course_spec',
'js/spec/models/metadata_spec',
'js/spec/models/section_spec',
......@@ -261,21 +263,32 @@
'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/module_edit_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/move_xblock_modal_spec',
'js/spec/views/modals/validation_error_modal_spec',
'js/spec/views/move_xblock_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',
......
jasmine.getFixtures().fixturesPath = '/base/templates';
import 'common/js/spec_helpers/jasmine-extensions';
import 'common/js/spec_helpers/jasmine-stealth';
import 'common/js/spec_helpers/jasmine-waituntil';
// These libraries are used by the tests (and the code under test)
// but not explicitly imported
import 'jquery.ui';
import _ from 'underscore';
import str from 'underscore.string';
import HtmlUtils from 'edx-ui-toolkit/js/utils/html-utils';
import StringUtils from 'edx-ui-toolkit/js/utils/string-utils';
window._ = _;
window._.str = str;
window.edx = window.edx || {};
window.edx.HtmlUtils = HtmlUtils;
window.edx.StringUtils = StringUtils;
// These are the tests that will be run
import './xblock/cms.runtime.v1_spec.js';
import '../../../js/spec/factories/xblock_validation_spec.js';
import '../../../js/spec/views/container_spec.js';
import '../../../js/spec/views/login_studio_spec.js';
import '../../../js/spec/views/modals/edit_xblock_spec.js';
import '../../../js/spec/views/module_edit_spec.js';
import '../../../js/spec/views/move_xblock_spec.js';
import '../../../js/spec/views/pages/container_spec.js';
import '../../../js/spec/views/pages/container_subviews_spec.js';
import '../../../js/spec/views/pages/course_outline_spec.js';
import '../../../js/spec/views/xblock_editor_spec.js';
import '../../../js/spec/views/xblock_string_field_editor_spec.js';
window.__karma__.start(); // eslint-disable-line no-underscore-dangle
import EditHelpers from 'js/spec_helpers/edit_helpers';
import BaseModal from 'js/views/modals/base_modal';
import 'xblock/cms.runtime.v1';
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() {
'use strict';
describe('Studio Runtime v1', function() {
var runtime;
var runtime;
beforeEach(function() {
EditHelpers.installEditTemplates();
runtime = new window.StudioRuntime.v1();
});
beforeEach(function() {
EditHelpers.installEditTemplates();
runtime = new window.StudioRuntime.v1();
});
it('allows events to be listened to', function() {
var canceled = false;
runtime.listenTo('cancel', function() {
canceled = true;
});
expect(canceled).toBeFalsy();
runtime.notify('cancel', {});
expect(canceled).toBeTruthy();
});
it('allows events to be listened to', function() {
var canceled = false;
runtime.listenTo('cancel', function() {
canceled = true;
});
expect(canceled).toBeFalsy();
runtime.notify('cancel', {});
expect(canceled).toBeTruthy();
});
it('shows save notifications', function() {
var title = 'Mock saving...',
notificationSpy = EditHelpers.createNotificationSpy();
runtime.notify('save', {
state: 'start',
message: title
});
EditHelpers.verifyNotificationShowing(notificationSpy, title);
runtime.notify('save', {
state: 'end'
});
EditHelpers.verifyNotificationHidden(notificationSpy);
});
it('shows save notifications', function() {
var title = 'Mock saving...',
notificationSpy = EditHelpers.createNotificationSpy();
runtime.notify('save', {
state: 'start',
message: title
});
EditHelpers.verifyNotificationShowing(notificationSpy, title);
runtime.notify('save', {
state: 'end'
});
EditHelpers.verifyNotificationHidden(notificationSpy);
});
it('shows error messages', function() {
var title = 'Mock Error',
message = 'This is a mock error.',
notificationSpy = EditHelpers.createNotificationSpy('Error');
runtime.notify('error', {
title: title,
message: message
});
EditHelpers.verifyNotificationShowing(notificationSpy, title);
});
it('shows error messages', function() {
var title = 'Mock Error',
message = 'This is a mock error.',
notificationSpy = EditHelpers.createNotificationSpy('Error');
runtime.notify('error', {
title: title,
message: message
});
EditHelpers.verifyNotificationShowing(notificationSpy, title);
});
describe('Modal Dialogs', function() {
var MockModal, modal, showMockModal;
describe('Modal Dialogs', function() {
var MockModal, modal, showMockModal;
MockModal = BaseModal.extend({
getContentHtml: function() {
return readFixtures('mock/mock-modal.underscore');
}
});
MockModal = BaseModal.extend({
getContentHtml: function() {
return readFixtures('mock/mock-modal.underscore');
}
});
showMockModal = function() {
modal = new MockModal({
title: 'Mock Modal'
});
modal.show();
};
showMockModal = function() {
modal = new MockModal({
title: 'Mock Modal'
});
modal.show();
};
beforeEach(function() {
EditHelpers.installEditTemplates();
});
beforeEach(function() {
EditHelpers.installEditTemplates();
});
afterEach(function() {
EditHelpers.hideModalIfShowing(modal);
});
afterEach(function() {
EditHelpers.hideModalIfShowing(modal);
});
it('cancels a modal dialog', function() {
showMockModal();
runtime.notify('modal-shown', modal);
expect(EditHelpers.isShowingModal(modal)).toBeTruthy();
runtime.notify('cancel');
expect(EditHelpers.isShowingModal(modal)).toBeFalsy();
it('cancels a modal dialog', function() {
showMockModal();
runtime.notify('modal-shown', modal);
expect(EditHelpers.isShowingModal(modal)).toBeTruthy();
runtime.notify('cancel');
expect(EditHelpers.isShowingModal(modal)).toBeFalsy();
});
});
});
});
});
......@@ -26,35 +26,8 @@ define([
IframeUtils,
DropdownMenuView
) {
'use strict';
var $body;
function smoothScrollLink(e) {
(e).preventDefault();
$.smoothScroll({
offset: -200,
easing: 'swing',
speed: 1000,
scrollElement: null,
scrollTarget: $(this).attr('href')
});
}
function hideNotification(e) {
(e).preventDefault();
$(this)
.closest('.wrapper-notification')
.removeClass('is-shown')
.addClass('is-hiding')
.attr('aria-hidden', 'true');
}
function hideAlert(e) {
(e).preventDefault();
$(this).closest('.wrapper-alert').removeClass('is-shown');
}
domReady(function() {
var dropdownMenuView;
......@@ -71,14 +44,14 @@ define([
$('.action-notification-close').bind('click', hideNotification);
// nav - dropdown related
$body.click(function() {
$body.click(function(e) {
$('.nav-dd .nav-item .wrapper-nav-sub').removeClass('is-shown');
$('.nav-dd .nav-item .title').removeClass('is-selected');
});
$('.nav-dd .nav-item, .filterable-column .nav-item').click(function(e) {
var $subnav = $(this).find('.wrapper-nav-sub'),
$title = $(this).find('.title');
$subnav = $(this).find('.wrapper-nav-sub');
$title = $(this).find('.title');
if ($subnav.hasClass('is-shown')) {
$subnav.removeClass('is-shown');
......@@ -95,8 +68,7 @@ define([
});
// general link management - new window/tab
$('a[rel="external"]:not([title])')
.attr('title', gettext('This link will open in a new browser window/tab'));
$('a[rel="external"]:not([title])').attr('title', gettext('This link will open in a new browser window/tab'));
$('a[rel="external"]').attr('target', '_blank');
// general link management - lean modal window
......@@ -125,7 +97,39 @@ define([
});
dropdownMenuView.postRender();
}
window.studioNavMenuActive = true;
});
function smoothScrollLink(e) {
(e).preventDefault();
$.smoothScroll({
offset: -200,
easing: 'swing',
speed: 1000,
scrollElement: null,
scrollTarget: $(this).attr('href')
});
}
function smoothScrollTop(e) {
(e).preventDefault();
$.smoothScroll({
offset: -200,
easing: 'swing',
speed: 1000,
scrollElement: null,
scrollTarget: $('#view-top')
});
}
function hideNotification(e) {
(e).preventDefault();
$(this).closest('.wrapper-notification').removeClass('is-shown').addClass('is-hiding').attr('aria-hidden', 'true');
}
function hideAlert(e) {
(e).preventDefault();
$(this).closest('.wrapper-alert').removeClass('is-shown');
}
}); // end require()
// We can't convert this to an es6 module until all factories that use it have been converted out
// of RequireJS
define(['js/base', 'cms/js/main', 'js/src/logger', 'datepair', 'accessibility',
'ieshim', 'tooltip_manager', 'lang_edx', 'js/models/course'],
function() {
......
import * as $ from 'jquery';
import * as _ from 'underscore';
import * as XBlockContainerInfo from 'js/models/xblock_container_info';
import * as ContainerPage from 'js/views/pages/container';
import * as ComponentTemplates from 'js/collections/component_template';
import * as xmoduleLoader from 'xmodule';
import './base';
import 'cms/js/main';
import 'xblock/cms.runtime.v1';
define([
'jquery', 'underscore', 'js/models/xblock_container_info', 'js/views/pages/container',
'js/collections/component_template', 'xmodule', 'cms/js/main',
'xblock/cms.runtime.v1'
],
function($, _, XBlockContainerInfo, ContainerPage, ComponentTemplates, xmoduleLoader) {
'use strict';
return function(componentTemplates, XBlockInfoJson, action, options) {
var main_options = {
el: $('#content'),
model: new XBlockContainerInfo(XBlockInfoJson, {parse: true}),
action: action,
templates: new ComponentTemplates(componentTemplates, {parse: true})
};
'use strict';
export default function ContainerFactory(componentTemplates, XBlockInfoJson, action, options) {
var main_options = {
el: $('#content'),
model: new XBlockContainerInfo(XBlockInfoJson, {parse: true}),
action: action,
templates: new ComponentTemplates(componentTemplates, {parse: true})
xmoduleLoader.done(function() {
var view = new ContainerPage(_.extend(main_options, options));
view.render();
});
};
xmoduleLoader.done(function() {
var view = new ContainerPage(_.extend(main_options, options));
view.render();
});
};
export {ContainerFactory}
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment