Commit 182921f1 by Brian Jacobel

Merge pull request #12433 from edx/bjacobel/upgrade-jquery

Upgrade jQuery to 2.2
parents 136f3d34 f4bede6c
......@@ -27,7 +27,8 @@
"mustache": "js/vendor/mustache",
"codemirror": "js/vendor/codemirror-compressed",
"codemirror/stex": "js/vendor/CodeMirror/stex",
"jquery": "js/vendor/jquery.min",
"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",
......@@ -37,7 +38,7 @@
"jquery.timepicker": "js/vendor/timepicker/jquery.timepicker",
"jquery.cookie": "js/vendor/jquery.cookie",
"jquery.qtip": "js/vendor/jquery.qtip.min",
"jquery.scrollTo": "js/vendor/jquery.scrollTo-1.4.2-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",
......@@ -112,6 +113,7 @@
"date": {
exports: "Date"
},
"jquery-migrate": ['jquery'],
"jquery.ui": {
deps: ["jquery"],
exports: "jQuery.ui"
......@@ -146,7 +148,7 @@
},
"jquery.scrollTo": {
deps: ["jquery"],
exports: "jQuery.fn.scrollTo",
exports: "jQuery.fn.scrollTo"
},
"jquery.flot": {
deps: ["jquery"],
......
......@@ -4,14 +4,15 @@ requirejs.config({
"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/js/vendor/jquery.min",
"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": "xmodule_js/common_static/js/vendor/jquery.scrollTo-1.4.2-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",
......@@ -65,6 +66,7 @@ requirejs.config({
"date": {
exports: "Date"
},
"jquery-migrate": ['jquery'],
"jquery.ui": {
deps: ["jquery"],
exports: "jQuery.ui"
......
......@@ -33,7 +33,7 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h
server && server.restore()
it "successful AJAX request does not pop an error notification", ->
server = AjaxHelpers.server([200, {}, ''])
server = AjaxHelpers.server([200, {"Content-Type": "application/json"}, "{}"])
expect($("#page-notification")).toBeEmpty()
$.ajax("/test")
......@@ -42,7 +42,7 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h
expect($("#page-notification")).toBeEmpty()
it "AJAX request with error should pop an error notification", ->
server = AjaxHelpers.server([500, {}, ''])
server = AjaxHelpers.server([500, {"Content-Type": "application/json"}, "{}"])
$.ajax("/test")
server.respond()
......@@ -50,7 +50,7 @@ require ["jquery", "backbone", "coffee/src/main", "common/js/spec_helpers/ajax_h
expect($("#page-notification")).toContainElement('div.wrapper-notification-error')
it "can override AJAX request with error so it does not pop an error notification", ->
server = AjaxHelpers.server([500, {}, ''])
server = AjaxHelpers.server([500, {"Content-Type": "application/json"}, "{}"])
$.ajax
url: "/test"
......
......@@ -5,13 +5,14 @@ requirejs.config({
"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/js/vendor/jquery.min",
"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": "xmodule_js/common_static/js/vendor/jquery.scrollTo-1.4.2-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",
......
......@@ -34,7 +34,7 @@ define ["js/models/section", "common/js/spec_helpers/ajax_helpers", "js/utils/mo
})
it "show/hide a notification when it saves to the server", ->
server = AjaxHelpers.server([200, {}, ''])
server = AjaxHelpers.server([200, {"Content-Type": "application/json"}, "{}"])
@model.save()
expect(Section.prototype.showNotification).toHaveBeenCalled()
......@@ -43,7 +43,7 @@ define ["js/models/section", "common/js/spec_helpers/ajax_helpers", "js/utils/mo
it "don't hide notification when saving fails", ->
# this is handled by the global AJAX error handler
server = AjaxHelpers.server([500, {}, ''])
server = AjaxHelpers.server([500, {"Content-Type": "application/json"}, "{}"])
@model.save()
server.respond()
......
......@@ -84,7 +84,7 @@ define ["jquery", "common/js/spec_helpers/ajax_helpers", "squire"],
expect(@confirmationSpies.constructor).not.toHaveBeenCalled()
expect(@collection.contains(@model)).toBeTruthy()
# return a success response
requests[0].respond(200)
requests[0].respond(204)
expect(@confirmationSpies.constructor).toHaveBeenCalled()
expect(@confirmationSpies.show).toHaveBeenCalled()
savingOptions = @confirmationSpies.constructor.calls.mostRecent().args[0]
......@@ -118,7 +118,7 @@ define ["jquery", "common/js/spec_helpers/ajax_helpers", "squire"],
expect(savingOptions.title).toMatch("Saving")
expect(@model.get("locked")).toBeFalsy()
# return a success response
requests[0].respond(200)
requests[0].respond(204)
expect(@savingSpies.hide).toHaveBeenCalled()
expect(@model.get("locked")).toBeTruthy()
......
......@@ -87,7 +87,7 @@ define ["js/models/textbook", "js/models/chapter", "js/collections/chapter", "js
savingOptions = @savingSpies.constructor.calls.mostRecent().args[0]
expect(savingOptions.title).toMatch(/Deleting/)
# return a success response
requests[0].respond(200)
requests[0].respond(204)
expect(@savingSpies.hide).toHaveBeenCalled()
expect(@collection.contains(@model)).toBeFalsy()
......
......@@ -58,6 +58,20 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
};
beforeEach(function() {
window.course = new Course({
id: '5',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
window.certWebPreview = new CertificatePreview({
course_modes: ['honor', 'test'],
certificate_web_view_url: '/users/1/courses/orgX/009/2016'
});
window.CMS.User = {isGlobalStaff: true};
TemplateHelpers.installTemplates(['certificate-details', 'signatory-details', 'signatory-editor', 'signatory-actions'], true);
window.course = new Course({
......@@ -99,6 +113,12 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
delete window.CMS.User;
});
afterEach(function() {
delete window.course;
delete window.CMS.User;
});
describe('The Certificate Details view', function() {
it('should parse a JSON string collection into a Backbone model collection', function () {
......@@ -234,7 +254,7 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
this.view.$(SELECTORS.signatory_panel_save).click();
ViewHelpers.verifyNotificationShowing(notificationSpy, /Saving/);
requests[0].respond(200);
requests[0].respond(204);
ViewHelpers.verifyNotificationHidden(notificationSpy);
expect(this.view.$(SELECTORS.signatory_name_value)).toContainText('New Signatory Test Name');
......
......@@ -28,8 +28,6 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
};
beforeEach(function() {
appendSetFixtures('<div class="preview-certificate nav-actions"></div>');
window.course = new Course({
id: '5',
name: 'Course Name',
......@@ -40,6 +38,8 @@ function(_, $, Course, CertificatePreview, TemplateHelpers, ViewHelpers, AjaxHel
});
window.CMS.User = {isGlobalStaff: true};
TemplateHelpers.installTemplate('certificate-web-preview', true);
appendSetFixtures('<div class="preview-certificate nav-actions"></div>');
this.view = new CertificatePreview({
el: $('.preview-certificate'),
course_modes: ['test1', 'test2', 'test3'],
......
......@@ -331,7 +331,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
expect(savingOptions.title).toMatch(/Saving/);
expect($('#unit-1')).toHaveClass('was-dropped');
expect(request.requestBody).toEqual('{"children":["fourth-unit-id","first-unit-id"]}');
request.respond(200);
request.respond(204);
expect(this.savingSpies.hide).toHaveBeenCalled();
this.clock.tick(1001);
expect($('#unit-1')).not.toHaveClass('was-dropped');
......@@ -360,7 +360,7 @@ define(["js/utils/drag_and_drop", "common/js/components/views/feedback_notificat
expect(request.requestBody).toEqual(
'{"children":["second-unit-id","first-unit-id","third-unit-id"]}'
);
request.respond(200);
request.respond(204);
this.clock.tick(1001);
expect($('#unit-1')).not.toHaveClass('was-dropped');
// parent
......
......@@ -491,21 +491,6 @@ define([
AjaxHelpers.expectNoRequests(requests);
});
it('should have appropriate class names on focus/blur', function (done) {
var groupInput = this.view.$(SELECTORS.inputGroupName).first(),
groupFields = this.view.$(SELECTORS.groupFields);
groupInput.focus();
jasmine.waitUntil(function() {
return groupFields.hasClass('is-focused');
}).then(function () {
groupInput.blur();
jasmine.waitUntil(function() {
return !groupFields.hasClass('is-focused');
}).then(done);
});
});
describe('removes all newly created groups on cancel', function () {
it('if the model has a non-empty groups', function() {
var groups = this.model.get('groups');
......
......@@ -253,6 +253,16 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/components/u
])
]);
// Create a mock Course object as the JS now expects it.
window.course = new Course({
id: '333',
name: 'Course Name',
url_name: 'course_name',
org: 'course_org',
num: 'course_num',
revision: 'course_rev'
});
});
afterEach(function () {
......
......@@ -101,7 +101,7 @@ define(["jquery", "common/js/spec_helpers/ajax_helpers", "common/js/spec_helpers
var values_with_blank = values.slice();
values_with_blank[i] = '';
fillInLibraryFields.apply(this, values_with_blank);
expect($('.create-library li.field.text input[value=]').parent()).toHaveClass('error');
expect($('.create-library li.field.text input').parent()).toHaveClass('error');
expect($('.new-library-save')).toHaveClass('is-disabled');
expect($('.new-library-save')).toHaveAttr('aria-disabled', 'true');
$('.new-library-save').click();
......
......@@ -5,11 +5,11 @@ define([
function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
"use strict";
describe("Library Instructor Access Page", function () {
const changeRoleUrl = "dummy_change_role_url/@@EMAIL@@";
var changeRoleUrl = "dummy_change_role_url/@@EMAIL@@";
var team_member_fixture = readFixtures("team-member.underscore");
function setRole(email, role){
var user_li = $("li.user-item[data-email="+ email + "]");
var user_li = $('li.user-item[data-email="'+ email + '"]');
var role_action = $("li.action-role a.make-"+role, user_li);
expect(role_action).toBeVisible();
role_action.click();
......@@ -48,7 +48,7 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
});
it("can give a user permission to use the library", function () {
const email = 'other@example.com';
var email = 'other@example.com';
var requests = AjaxHelpers.requests(this);
var reloadSpy = spyOn(ViewUtils, 'reload');
$('.create-user-button').click();
......@@ -61,7 +61,7 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
});
it("can promote user", function() {
const email = "staff@example.com";
var email = "staff@example.com";
var requests = AjaxHelpers.requests(this);
var reloadSpy = spyOn(ViewUtils, 'reload');
setRole("staff@example.com", 'staff');
......
......@@ -144,7 +144,7 @@ define([
// select the entrance-exam-enabled checkbox. grade requirement section should be visible.
entrance_exam_enabled_field
.attr('checked', 'true')
.prop('checked', true)
.trigger('change');
this.view.render();
......@@ -152,7 +152,7 @@ define([
// deselect the entrance-exam-enabled checkbox. grade requirement section should be hidden.
entrance_exam_enabled_field
.removeAttr('checked')
.prop('checked', false)
.trigger('change');
expect(this.view.$(SELECTORS.grade_requirement_div)).toBeHidden();
......@@ -173,7 +173,7 @@ define([
// select the entrance-exam-enabled checkbox.
entrance_exam_enabled_field
.attr('checked', 'true')
.prop('checked', true)
.trigger('change');
// input a valid value for entrance exam minimum score.
......
......@@ -99,7 +99,7 @@ define(["jquery", "URI", "common/js/spec_helpers/ajax_helpers", "common/js/compo
mimetype: "application/javascript", kind: "url", data: missingJavaScriptUrl
}]
]);
expect(promise.isRejected()).toBe(true);
expect(promise.state()).toBe("rejected");
});
it('Triggers an event to the runtime when a notification-action-button is clicked', function () {
......
......@@ -10,8 +10,8 @@ define(["js/views/validation", "codemirror", "js/models/course_update",
// collection is CourseUpdateCollection
events: {
"click .new-update-button" : "onNew",
"click #course-update-view .save-button" : "onSave",
"click #course-update-view .cancel-button" : "onCancel",
"click .save-button" : "onSave",
"click .cancel-button" : "onCancel",
"click .post-actions > .edit-button" : "onEdit",
"click .post-actions > .delete-button" : "onDelete"
},
......
......@@ -12,8 +12,8 @@ function(BaseView, _, str, gettext, groupEditTemplate) {
events: {
'click .action-close': 'removeGroup',
'change .group-name': 'changeName',
'focus .groups-fields input': 'onFocus',
'blur .groups-fields input': 'onBlur'
'focus .group-name': 'onFocus',
'blur .group-name': 'onBlur'
},
className: function() {
......
......@@ -215,7 +215,6 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
}
});
AbstractEditor = BaseView.extend({
tagName: 'section',
templateName: null,
......@@ -328,6 +327,7 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
};
}
});
TimedExaminationPreferenceEditor = AbstractEditor.extend({
templateName: 'timed-examination-preference-editor',
className: 'edit-settings-timed-examination',
......@@ -496,6 +496,7 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
};
}
});
AccessEditor = AbstractEditor.extend({
templateName: 'access-editor',
className: 'edit-settings-access',
......@@ -548,13 +549,14 @@ define(['jquery', 'backbone', 'underscore', 'gettext', 'js/views/baseview',
};
}
});
GradingEditor = AbstractEditor.extend({
templateName: 'grading-editor',
className: 'edit-settings-grading',
afterRender: function () {
AbstractEditor.prototype.afterRender.call(this);
this.setValue(this.model.get('format'));
this.setValue(this.model.get('format') || 'notgraded');
},
setValue: function (value) {
......
......@@ -89,7 +89,7 @@ function($, _, AbstractEditor, FileUpload, UploadDialog) {
items = this.$el.find('ol').find('.list-settings-item');
_.each(items, function(element, index) {
var key = $(element).find('select').val(),
var key = $(element).find('select option:selected').val(),
value = $(element).find('.input').val();
// Keys should be unique, so if our keys are duplicated and
......
......@@ -13,6 +13,11 @@ var options = {
libraryFiles: [],
libraryFilesToInclude: [
{pattern: 'common/js/vendor/jquery.js', included: true},
{pattern: 'common/js/vendor/jquery-migrate.js', included: true}
],
// 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: [
......
......@@ -13,6 +13,11 @@ var options = {
libraryFiles: [],
libraryFilesToInclude: [
{pattern: 'common/js/vendor/jquery.js', included: true},
{pattern: 'common/js/vendor/jquery-migrate.js', included: true}
],
// 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: [
......
......@@ -93,12 +93,12 @@ def render_require_js_path_overrides(path_overrides): # pylint: disable=invalid
For example:
"js/vendor/jquery.min.js" --> "js/vendor/jquery.min.abcd1234"
"js/vendor/jquery.js" --> "js/vendor/jquery.abcd1234"
To achive this we will add overrided paths in requirejs config at runtime.
So that any reference to 'jquery' in a JavaScript module
will cause RequireJS to load '/static/js/vendor/jquery.min.abcd1234.js'
will cause RequireJS to load '/static/js/vendor/jquery.abcd1234.js'
If running in DEBUG mode (as in devstack), the resolved JavaScript URLs
won't contain hashes, so the new paths will match the original paths.
......
......@@ -14,7 +14,7 @@ class RequireJSPathOverridesTest(TestCase):
"""Test RequireJS path overrides. """
OVERRIDES = {
'jquery': 'js/vendor/jquery.min.js',
'jquery': 'common/js/vendor/jquery.js',
'backbone': 'common/js/vendor/backbone.js',
'text': 'js/vendor/text.js'
}
......@@ -24,7 +24,7 @@ class RequireJSPathOverridesTest(TestCase):
"(function (require) {",
"require.config({",
"paths: {",
"'jquery': 'js/vendor/jquery.min',",
"'jquery': 'common/js/vendor/jquery',",
"'text': 'js/vendor/text',",
"'backbone': 'common/js/vendor/backbone'",
"}",
......
......@@ -28,7 +28,8 @@ var options = {
{pattern: 'common_static/edx-ui-toolkit/js/utils/global-loader.js', included: true},
{pattern: 'common_static/js/vendor/CodeMirror/codemirror.js', included: true},
{pattern: 'common_static/js/vendor/draggabilly.js'},
{pattern: 'common_static/js/vendor/jquery.min.js', included: true},
{pattern: 'common_static/common/js/vendor/jquery.js', included: true},
{pattern: 'common_static/common/js/vendor/jquery-migrate.js', included: true},
{pattern: 'common_static/js/vendor/jquery.cookie.js', included: true},
{pattern: 'common_static/js/vendor/jquery.leanModal.js', included: true},
{pattern: 'common_static/js/vendor/jquery.timeago.js', included: true},
......
......@@ -289,9 +289,9 @@ describe 'Problem', ->
$('#input_example_1').replaceWith(html)
@problem.checkAnswersAndCheckButton true
@checkDisabled true
$('#input_1_1_1').attr('checked', true).trigger('click')
$('#input_1_1_1').click()
@checkDisabled false
$('#input_1_1_1').attr('checked', false).trigger('click')
$('#input_1_1_1').click()
@checkDisabled true
it 'should become enabled after a radiobutton is checked', ->
......
......@@ -343,7 +343,7 @@
expect(parseIntAttribute(item, 'data-index')).toEqual(index);
expect(parseIntAttribute(item, 'data-start')).toEqual(captionsData.start[index]);
expect(item.attr('tabindex')).toEqual(0);
expect(item.attr('tabindex')).toEqual('0');
expect(item.text().trim()).toEqual(captionsData.text[index]);
});
});
......@@ -432,7 +432,7 @@
expect(parseIntAttribute(item, 'data-index')).toEqual(index);
expect(parseIntAttribute(item, 'data-start')).toEqual(captionsData.start[index]);
expect(item.attr('tabindex')).toEqual(0);
expect(item.attr('tabindex')).toEqual('0');
expect(item.text().trim()).toEqual(text);
});
}).always(done);
......@@ -842,7 +842,7 @@
function (index, item) {
expect(parseIntAttribute($(item), 'data-index')).toEqual(index);
expect(parseIntAttribute($(item), 'data-start')).toEqual(captionsData.start[index]);
expect($(item).attr('tabindex')).toEqual(0);
expect($(item).attr('tabindex')).toEqual('0');
expect($(item).text().trim()).toEqual(captionsData.text[index]);
});
});
......
......@@ -49,8 +49,8 @@
});
it('from the start, focus grabbers are disabled', function () {
expect(state.focusGrabber.elFirst.attr('tabindex')).toBe(-1);
expect(state.focusGrabber.elLast.attr('tabindex')).toBe(-1);
expect(state.focusGrabber.elFirst.attr('tabindex')).toBe('-1');
expect(state.focusGrabber.elLast.attr('tabindex')).toBe('-1');
});
it(
......
......@@ -55,7 +55,7 @@
expect(btnPlay).not.toHaveClass('is-hidden');
expect(btnPlay).toHaveAttrs({
'aria-hidden': 'false',
'tabindex': 0
'tabindex': '0'
});
state.videoPlayPlaceholder.hide();
......@@ -63,7 +63,7 @@
expect(btnPlay).toHaveClass('is-hidden');
expect(btnPlay).toHaveAttrs({
'aria-hidden': 'true',
'tabindex': -1
'tabindex': '-1'
});
});
......
......@@ -39,15 +39,15 @@ class @Annotatable
# the associated problem. The reply buttons are part of the tooltip
# content. It's important that the tooltips be configured to render
# as descendants of the annotation module and *not* the document.body.
@$el.delegate @replySelector, 'click', @onClickReply
@$el.on 'click', @replySelector, @onClickReply
# Initialize handler for 'return to annotation' events triggered from problems.
# 1) There are annotationinput capa problems rendered on the page
# 2) Each one has an embedded return link (see annotation capa problem template).
# Since the capa problem injects HTML content via AJAX, the best we can do is
# is let the click events bubble up to the body and handle them there.
$('body').delegate @problemReturnSelector, 'click', @onClickReturn
# is let the click events bubble up to the body and handle them there.
$(document).on 'click', @problemReturnSelector, @onClickReturn
initTips: () ->
# tooltips are used to display annotations for highlighted text spans
@$(@spanSelector).each (index, el) =>
......@@ -91,8 +91,9 @@ class @Annotatable
onMoveTip: (event, api, position) =>
###
This method handles an edge case in which a tooltip is displayed above
a non-overlapping span like this:
This method handles a vertical positioning bug in Firefox as
well as an edge case in which a tooltip is displayed above a
non-overlapping span like this:
(( TOOLTIP ))
\/
......@@ -115,28 +116,33 @@ class @Annotatable
# we want to choose the largest of the two non-overlapping spans and display
# the tooltip above the center of it (see api.options.position settings)
focus_rect = (if rects[0].width > rects[1].width then rects[0] else rects[1])
rect_center = focus_rect.left + (focus_rect.width / 2)
rect_top = focus_rect.top
tip_width = $(tip).width()
tip_height = $(tip).height()
else
# always compute the new position because Firefox doesn't
# properly vertically position the tooltip
focus_rect = rects[0]
# tooltip is positioned relative to its container, so we need to factor in offsets
container_offset = $(container).offset()
offset_left = -container_offset.left
offset_top = $(document).scrollTop() - container_offset.top
rect_center = focus_rect.left + (focus_rect.width / 2)
rect_top = focus_rect.top
tip_width = $(tip).width()
tip_height = $(tip).height()
tip_left = offset_left + rect_center - (tip_width / 2)
tip_top = offset_top + rect_top - tip_height + adjust_y
# tooltip is positioned relative to its container, so we need to factor in offsets
container_offset = $(container).offset()
offset_left = -container_offset.left
offset_top = $(document).scrollTop() - container_offset.top
# make sure the new tip position doesn't clip the edges of the screen
win_width = $(window).width()
if tip_left < offset_left
tip_left = offset_left
else if tip_left + tip_width > win_width + offset_left
tip_left = win_width + offset_left - tip_width
tip_left = offset_left + rect_center - (tip_width / 2)
tip_top = offset_top + rect_top - tip_height + adjust_y
# final step: update the position object (used by qtip2 to show the tip after the move event)
$.extend position, 'left': tip_left, 'top': tip_top
# make sure the new tip position doesn't clip the edges of the screen
win_width = $(window).width()
if tip_left < offset_left
tip_left = offset_left
else if tip_left + tip_width > win_width + offset_left
tip_left = win_width + offset_left - tip_width
# final step: update the position object (used by qtip2 to show the tip after the move event)
$.extend position, 'left': tip_left, 'top': tip_top
getSpanForProblemReturn: (el) ->
problem_id = $(@problemReturnSelector).index(el)
......@@ -144,7 +150,7 @@ class @Annotatable
getProblem: (el) ->
problem_id = @getProblemId(el)
$(@problemSelector).has(@problemInputSelector).eq(problem_id)
$(@problemInputSelector).eq(problem_id)
getProblemId: (el) ->
$(el).data('problem-id')
......@@ -208,7 +214,7 @@ class @Annotatable
onAfter: @_once => after?.call this, el
offset: offset
}) if $(el).length > 0
afterScrollToProblem: (problem_el) ->
problem_el.effect 'highlight', {}, 500
......
......@@ -129,7 +129,8 @@ if Backbone?
isPrivilegedUser: DiscussionUtil.isPrivilegedUser()
})
)
@$(".forum-nav-sort-control").val(@collection.sort_preference)
@$(".forum-nav-sort-control option").removeProp("selected")
@$(".forum-nav-sort-control option[value=#{@collection.sort_preference}]").prop("selected", true)
$(window).bind "load scroll resize", @updateSidebar
......@@ -524,5 +525,3 @@ if Backbone?
type: "POST"
error: () =>
$('input.email-setting').attr('checked','checked')
......@@ -3,6 +3,7 @@ define([
'edx-ui-toolkit/js/utils/html-utils',
'domReady!',
'jquery',
'jquery-migrate',
'backbone',
'underscore',
'gettext'
......
(function(requirejs, define) {
'use strict';
requirejs.config({
baseUrl: '/base/',
paths: {
'gettext': 'js/test/i18n',
'jquery': 'js/vendor/jquery.min',
'jquery': 'common/js/vendor/jquery',
'jquery-migrate': 'common/js/vendor/jquery-migrate',
'jquery.ui': 'js/vendor/jquery-ui.min',
'jquery.flot': 'js/vendor/flot/jquery.flot.min',
'jquery.form': 'js/vendor/jquery.form',
......@@ -11,7 +14,7 @@
'jquery.leanModal': 'js/vendor/jquery.leanModal',
'jquery.ajaxQueue': 'js/vendor/jquery.ajaxQueue',
'jquery.smoothScroll': 'js/vendor/jquery.smooth-scroll.min',
'jquery.scrollTo': 'js/vendor/jquery.scrollTo-1.4.2-min',
'jquery.scrollTo': 'common/js/vendor/jquery.scrollTo',
'jquery.timepicker': 'js/vendor/timepicker/jquery.timepicker',
'jquery.cookie': 'js/vendor/jquery.cookie',
'jquery.qtip': 'js/vendor/jquery.qtip.min',
......
/**
* jQuery.ScrollTo - Easy element scrolling using jQuery.
* Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 5/25/2009
* @author Ariel Flesler
* @version 1.4.2
*
* http://flesler.blogspot.com/2007/10/jqueryscrollto.html
*/
;(function(d){var k=d.scrollTo=function(a,i,e){d(window).scrollTo(a,i,e)};k.defaults={axis:'xy',duration:parseFloat(d.fn.jquery)>=1.3?0:1};k.window=function(a){return d(window)._scrollable()};d.fn._scrollable=function(){return this.map(function(){var a=this,i=!a.nodeName||d.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!i)return a;var e=(a.contentWindow||a).document||a.ownerDocument||a;return d.browser.safari||e.compatMode=='BackCompat'?e.body:e.documentElement})};d.fn.scrollTo=function(n,j,b){if(typeof j=='object'){b=j;j=0}if(typeof b=='function')b={onAfter:b};if(n=='max')n=9e9;b=d.extend({},k.defaults,b);j=j||b.speed||b.duration;b.queue=b.queue&&b.axis.length>1;if(b.queue)j/=2;b.offset=p(b.offset);b.over=p(b.over);return this._scrollable().each(function(){var q=this,r=d(q),f=n,s,g={},u=r.is('html,body');switch(typeof f){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)){f=p(f);break}f=d(f,this);case'object':if(f.is||f.style)s=(f=d(f)).offset()}d.each(b.axis.split(''),function(a,i){var e=i=='x'?'Left':'Top',h=e.toLowerCase(),c='scroll'+e,l=q[c],m=k.max(q,i);if(s){g[c]=s[h]+(u?0:l-r.offset()[h]);if(b.margin){g[c]-=parseInt(f.css('margin'+e))||0;g[c]-=parseInt(f.css('border'+e+'Width'))||0}g[c]+=b.offset[h]||0;if(b.over[h])g[c]+=f[i=='x'?'width':'height']()*b.over[h]}else{var o=f[h];g[c]=o.slice&&o.slice(-1)=='%'?parseFloat(o)/100*m:o}if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],m);if(!a&&b.queue){if(l!=g[c])t(b.onAfterFirst);delete g[c]}});t(b.onAfter);function t(a){r.animate(g,j,b.easing,a&&function(){a.call(this,n,b)})}}).end()};k.max=function(a,i){var e=i=='x'?'Width':'Height',h='scroll'+e;if(!d(a).is('html,body'))return a[h]-d(a)[e.toLowerCase()]();var c='client'+e,l=a.ownerDocument.documentElement,m=a.ownerDocument.body;return Math.max(l[h],m[h])-Math.min(l[c],m[c])};function p(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);
\ No newline at end of file
......@@ -19,7 +19,8 @@ var options = {
libraryFilesToInclude: [
{pattern: 'coffee/src/ajax_prefix.js', included: true},
{pattern: 'js/vendor/draggabilly.js', included: true},
{pattern: 'js/vendor/jquery.min.js', included: true},
{pattern: 'common/js/vendor/jquery.js', included: true},
{pattern: 'common/js/vendor/jquery-migrate.js', included: true},
{pattern: 'coffee/src/jquery.immediateDescendents.js', included: true},
{pattern: 'js/vendor/jquery.leanModal.js', included: true},
{pattern: 'js/vendor/jquery.timeago.js', included: true},
......
......@@ -229,10 +229,9 @@ Feature: LMS.Answer problems
Given I am viewing a "<ProblemType>" problem
When I answer a "<ProblemType>" problem "<InitialCorrectness>ly"
Then my "<ProblemType>" answer is marked "<InitialCorrectness>"
And I input an answer on a "<ProblemType>" problem "<OtherCorrectness>ly"
And I reset the problem
Then my "<ProblemType>" answer is NOT marked "<InitialCorrectness>"
And my "<ProblemType>" answer is NOT marked "<OtherCorrectness>"
And I reset the problem
Examples:
| ProblemType | InitialCorrectness | OtherCorrectness |
......
......@@ -1240,7 +1240,8 @@ proctoring_js = (
# In the future, we will likely refactor this to use
# RequireJS and an optimizer.
base_vendor_js = [
'js/vendor/jquery.min.js',
'common/js/vendor/jquery.js',
'common/js/vendor/jquery-migrate.js',
'js/vendor/jquery.cookie.js',
'js/vendor/url.min.js',
'common/js/vendor/underscore.js',
......@@ -1352,14 +1353,16 @@ incourse_reverify_js = [
ccx_js = sorted(rooted_glob(PROJECT_ROOT / 'static', 'js/ccx/**/*.js'))
certificates_web_view_js = [
'js/vendor/jquery.min.js',
'common/js/vendor/jquery.js',
'common/js/vendor/jquery-migrate.js',
'js/vendor/jquery.cookie.js',
'js/src/logger.js',
'js/utils/facebook.js',
]
credit_web_view_js = [
'js/vendor/jquery.min.js',
'common/js/vendor/jquery.js',
'common/js/vendor/jquery-migrate.js',
'js/vendor/jquery.cookie.js',
'js/src/logger.js',
]
......
......@@ -8,9 +8,6 @@ describe 'FeedbackForm', ->
spyOn($, 'postWithPrefix').and.callFake (url, data, callback, format) ->
callback()
it 'binds to the #feedback_button', ->
expect($('#feedback_button')).toHandle 'click'
it 'post data to /send_feedback on click', ->
$('#feedback_subject').val 'Awesome!'
$('#feedback_message').val 'This site is really good.'
......
......@@ -3,12 +3,6 @@ describe 'AutoEnrollment', ->
loadFixtures 'coffee/fixtures/autoenrollment.html'
@autoenrollment = new AutoEnrollmentViaCsv $('.auto_enroll_csv')
it 'binds to the enrollment_signup_button on click event', ->
expect(@autoenrollment.$enrollment_signup_button).toHandle 'click'
it 'binds to the browse button on change event', ->
expect(@autoenrollment.$browse_button).toHandle 'change'
it 'binds the ajax call and the result will be success', ->
spyOn($, "ajax").and.callFake((params) =>
params.success({row_errors: [], general_errors: [], warnings: []})
......
......@@ -15,8 +15,8 @@ ReportDownloads = -> window.InstructorDashboard.util.ReportDownloads
class @DataDownload_Certificate
constructor: (@$container) ->
# gather elements
@$list_issued_certificate_table_btn = @$container.find("input[name='issued-certificates-list']'")
@$list_issued_certificate_csv_btn = @$container.find("input[name='issued-certificates-csv']'")
@$list_issued_certificate_table_btn = @$container.find("input[name='issued-certificates-list']")
@$list_issued_certificate_csv_btn = @$container.find("input[name='issued-certificates-csv']")
@$certificate_display_table = @$container.find '.certificate-data-display-table'
@$certificates_request_response_error = @$container.find '.issued-certificates-error.request-response-error'
......@@ -72,18 +72,18 @@ class DataDownload
new DataDownload_Certificate @$section.find '.issued_certificates'
# gather elements
@$list_studs_btn = @$section.find("input[name='list-profiles']'")
@$list_studs_csv_btn = @$section.find("input[name='list-profiles-csv']'")
@$list_proctored_exam_results_csv_btn = @$section.find("input[name='proctored-exam-results-report']'")
@$survey_results_csv_btn = @$section.find("input[name='survey-results-report']'")
@$list_studs_btn = @$section.find("input[name='list-profiles']")
@$list_studs_csv_btn = @$section.find("input[name='list-profiles-csv']")
@$list_proctored_exam_results_csv_btn = @$section.find("input[name='proctored-exam-results-report']")
@$survey_results_csv_btn = @$section.find("input[name='survey-results-report']")
@$list_may_enroll_csv_btn = @$section.find("input[name='list-may-enroll-csv']")
@$list_problem_responses_csv_input = @$section.find("input[name='problem-location']")
@$list_problem_responses_csv_btn = @$section.find("input[name='list-problem-responses-csv']")
@$list_anon_btn = @$section.find("input[name='list-anon-ids']'")
@$grade_config_btn = @$section.find("input[name='dump-gradeconf']'")
@$calculate_grades_csv_btn = @$section.find("input[name='calculate-grades-csv']'")
@$problem_grade_report_csv_btn = @$section.find("input[name='problem-grade-report']'")
@$async_report_btn = @$section.find("input[class='async-report-btn']'")
@$list_anon_btn = @$section.find("input[name='list-anon-ids']")
@$grade_config_btn = @$section.find("input[name='dump-gradeconf']")
@$calculate_grades_csv_btn = @$section.find("input[name='calculate-grades-csv']")
@$problem_grade_report_csv_btn = @$section.find("input[name='problem-grade-report']")
@$async_report_btn = @$section.find("input[class='async-report-btn']")
# response areas
@$download = @$section.find '.data-download-container'
......
......@@ -13,10 +13,10 @@ class ECommerce
# this object to call event handlers like 'onClickTitle'
@$section.data 'wrapper', @
# gather elements
@$list_sale_csv_btn = @$section.find("input[name='list-sale-csv']'")
@$list_order_sale_csv_btn = @$section.find("input[name='list-order-sale-csv']'")
@$download_company_name = @$section.find("input[name='download_company_name']'")
@$active_company_name = @$section.find("input[name='active_company_name']'")
@$list_sale_csv_btn = @$section.find("input[name='list-sale-csv']")
@$list_order_sale_csv_btn = @$section.find("input[name='list-order-sale-csv']")
@$download_company_name = @$section.find("input[name='download_company_name']")
@$active_company_name = @$section.find("input[name='active_company_name']")
@$spent_company_name = @$section.find('input[name="spent_company_name"]')
@$download_coupon_codes = @$section.find('input[name="download-coupon-codes-csv"]')
......@@ -89,4 +89,4 @@ class ECommerce
_.defaults window, InstructorDashboard: {}
_.defaults window.InstructorDashboard, sections: {}
_.defaults window.InstructorDashboard.sections,
ECommerce: ECommerce
\ No newline at end of file
ECommerce: ECommerce
......@@ -19,15 +19,15 @@ class SendEmail
constructor: (@$container) ->
# gather elements
@$emailEditor = XBlock.initializeBlock($('.xblock-studio_view'));
@$send_to = @$container.find("select[name='send_to']'")
@$subject = @$container.find("input[name='subject']'")
@$btn_send = @$container.find("input[name='send']'")
@$send_to = @$container.find("select[name='send_to']")
@$subject = @$container.find("input[name='subject']")
@$btn_send = @$container.find("input[name='send']")
@$task_response = @$container.find(".request-response")
@$request_response_error = @$container.find(".request-response-error")
@$content_request_response_error = @$container.find(".content-request-response-error")
@$history_request_response_error = @$container.find(".history-request-response-error")
@$btn_task_history_email = @$container.find("input[name='task-history-email']'")
@$btn_task_history_email_content = @$container.find("input[name='task-history-email-content']'")
@$btn_task_history_email = @$container.find("input[name='task-history-email']")
@$btn_task_history_email_content = @$container.find("input[name='task-history-email-content']")
@$table_task_history_email = @$container.find(".task-history-email-table")
@$table_email_content_history = @$container.find(".content-history-email-table")
@$email_content_table_inner = @$container.find(".content-history-table-inner")
......
......@@ -32,7 +32,7 @@ $ ->
# fix for ie
if !Array::indexOf
Array::indexOf = (obj, start = 0) ->
for ele, i in this[start..]
if ele is obj
return i + start
for ele, i in this[start..]
if ele is obj
return i + start
return -1
......@@ -6,23 +6,6 @@ define([
var _t = Annotator._t;
/**
* We currently run JQuery 1.7.2 in Jasmine tests and LMS.
* AnnotatorJS 1.2.9. uses two calls to addBack (in the two functions
* 'isAnnotator' and 'onHighlightMouseover') which was only defined in
* JQuery 1.8.0. In LMS, it works without throwing an error because
* JQuery.UI 1.10.0 adds support to jQuery<1.8 by augmenting '$.fn' with
* that missing function. It is not the case for all Jasmine unit tests,
* so we add it here if necessary.
**/
if (!$.fn.addBack) {
$.fn.addBack = function (selector) {
return this.add(
selector === null ? this.prevObject : this.prevObject.filter(selector)
);
};
}
/**
* The original _setupDynamicStyle uses a very expensive call to
* Util.maxZIndex(...) that sets the z-index of .annotator-adder,
* .annotator-outer, .annotator-notice, .annotator-filter. We set these
......
......@@ -56,7 +56,7 @@
if (!groupsEnabled) {
// If the user has chosen 'no', then clear the selection by setting
// it to the first option which represents no selection.
this.$('.input-cohort-group-association').val('None');
this.$('.input-cohort-group-association').val(null);
}
// Enable the select if the user has chosen groups, else disable it
this.$('.input-cohort-group-association').prop('disabled', !groupsEnabled);
......@@ -69,7 +69,7 @@
getSelectedContentGroup: function() {
var selectValue = this.$('.input-cohort-group-association').val(),
ids, groupId, userPartitionId, i, contentGroup;
if (!this.hasAssociatedContentGroup() || selectValue === 'None') {
if (!this.hasAssociatedContentGroup() || _.isNull(selectValue)) {
return null;
}
ids = selectValue.split(':');
......@@ -107,7 +107,7 @@
errorMessages.push(gettext('You must specify a name for the cohort'));
}
if (this.hasAssociatedContentGroup() && fieldData.group_id === null) {
if (this.$('.input-cohort-group-association').val() === 'None') {
if (_.isNull(this.$('.input-cohort-group-association').val())) {
errorMessages.push(gettext('You did not select a content group'));
} else {
// If a value was selected, then it must be for a non-existent/deleted content group
......
......@@ -17,12 +17,18 @@ var edx = edx || {};
},
clicked: function (event) {
if (event.currentTarget.checked) {
this.$el.find('#coupon_expiration_date').show();
this.show(this.$('#coupon_expiration_date'));
this.$el.find('#coupon_expiration_date').focus();
}
else {
this.$el.find('#coupon_expiration_date').hide();
this.hide(this.$('#coupon_expiration_date'));
}
},
show: function ($el) {
$el.css('display', 'inline');
},
hide: function ($el) {
$el.css('display', 'none');
}
});
......
define(['jquery', 'logger', 'js/courseware/toggle_element_visibility'],
function ($, Logger, ToggleElementVisibility) {
define(['jquery', 'logger', 'js/courseware/toggle_element_visibility', 'moment'],
function ($, Logger, ToggleElementVisibility, moment) {
'use strict';
describe('show/hide with mouse click', function () {
......@@ -43,7 +43,7 @@ define(['jquery', 'logger', 'js/courseware/toggle_element_visibility'],
$update.siblings('.toggle-visibility-button').trigger('click');
expect(Logger.log).toHaveBeenCalledWith('edx.course.home.course_update.toggled', {
action: 'hide',
publish_date: '2015-12-01T00:00:00+00:00'
publish_date: moment('December 1, 2015', 'MMM DD, YYYY').format()
});
});
});
......
......@@ -107,6 +107,12 @@ define([
'templates/discovery/filter_bar'
]);
DiscoveryFactory(MEANINGS);
jasmine.clock().install();
});
afterEach(function () {
jasmine.clock().uninstall();
});
it('does search', function () {
......@@ -121,22 +127,20 @@ define([
it('loads more', function () {
var requests = AjaxHelpers.requests(this);
jasmine.clock().install();
$('.discovery-input').val('test');
$('.discovery-submit').trigger('click');
AjaxHelpers.respondWithJson(requests, JSON_RESPONSE);
expect($('.courses-listing article').length).toEqual(1);
expect($('.courses-listing .course-title')).toContainHtml('edX Demonstration Course');
jasmine.clock().tick(500);
window.scroll(0, $(document).height());
$(window).trigger('scroll');
jasmine.clock().tick(500);
// TODO: determine why the search API is invoked twice
AjaxHelpers.respondWithJson(requests, JSON_RESPONSE);
AjaxHelpers.respondWithJson(requests, JSON_RESPONSE);
expect($('.courses-listing article').length).toEqual(2);
jasmine.clock().uninstall();
});
it('displays not found message', function () {
......
......@@ -223,7 +223,7 @@ define(['backbone', 'jquery', 'common/js/spec_helpers/ajax_helpers', 'common/js/
clearContentGroup = function() {
cohortsView.$('.radio-no').prop('checked', true).change();
expect(cohortsView.$('.input-cohort-group-association').prop('disabled')).toBeTruthy();
expect(cohortsView.$('.input-cohort-group-association').val()).toBe('None');
expect(cohortsView.$('.input-cohort-group-association').val()).toBe(null);
};
verifyMessage = function(expectedTitle, expectedMessageType, expectedAction, hasDetails) {
......
......@@ -22,7 +22,6 @@ define(['backbone', 'jquery', 'js/instructor_dashboard/ecommerce'],
it("shows the input field when the checkbox is checked", function () {
var target = expiryCouponView.$el.find('input[type="checkbox"]');
target.attr("checked","checked");
target.click();
expect(expiryCouponView.$el.find('#coupon_expiration_date').is(':visible')).toBe(true);
});
......@@ -30,7 +29,6 @@ define(['backbone', 'jquery', 'js/instructor_dashboard/ecommerce'],
it("hides the input field when the checkbox is unchecked", function () {
var target = expiryCouponView.$el.find('input[type="checkbox"]');
expect(expiryCouponView.$el.find('#coupon_expiration_date')).toHaveAttr('style','display: none;');
});
});
});
......@@ -8,7 +8,8 @@
paths: {
'gettext': 'xmodule_js/common_static/js/test/i18n',
'codemirror': 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror',
'jquery': 'xmodule_js/common_static/js/vendor/jquery.min',
'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.eventDrag': 'xmodule_js/common_static/js/vendor/jquery.event.drag-2.2',
'jquery.flot': 'xmodule_js/common_static/js/vendor/flot/jquery.flot.min',
......@@ -18,7 +19,7 @@
'jquery.ajaxQueue': 'xmodule_js/common_static/js/vendor/jquery.ajaxQueue',
'jquery.ajax-retry': 'js/vendor/jquery.ajax-retry',
'jquery.smoothScroll': 'xmodule_js/common_static/js/vendor/jquery.smooth-scroll.min',
'jquery.scrollTo': 'xmodule_js/common_static/js/vendor/jquery.scrollTo-1.4.2-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',
......@@ -92,7 +93,7 @@
// Discussion classes loaded explicitly until they are converted to use RequireJS
'DiscussionModuleView': 'xmodule_js/common_static/coffee/src/discussion/discussion_module_view',
'js/bookmarks/collections/bookmarks': 'js/bookmarks/collections/bookmarks',
'js/bookmarks/models/bookmark': 'js/bookmarks/models/bookmark',
'js/bookmarks/views/bookmarks_list_button': 'js/bookmarks/views/bookmarks_list_button',
......@@ -119,6 +120,7 @@
'date': {
exports: 'Date'
},
"jquery-migrate": ['jquery'],
'jquery.ui': {
deps: ['jquery'],
exports: 'jQuery.ui'
......@@ -289,6 +291,10 @@
exports: 'coffee/src/instructor_dashboard/student_admin',
deps: ['jquery', 'underscore', 'coffee/src/instructor_dashboard/util', 'string_utils']
},
'coffee/src/instructor_dashboard/util': {
exports: 'coffee/src/instructor_dashboard/util',
deps: ['jquery', 'underscore', 'slick.core', 'slick.grid']
},
'js/instructor_dashboard/certificates': {
exports: 'js/instructor_dashboard/certificates',
deps: ['jquery', 'gettext', 'underscore']
......@@ -492,6 +498,14 @@
exports: 'Annotator',
deps: ['jquery']
},
'slick.core': {
deps: ['jquery'],
exports: 'Slick'
},
'slick.grid': {
deps: ['jquery', 'jquery.eventDrag', 'slick.core'],
exports: 'Slick'
},
// Discussions
'xmodule_js/common_static/coffee/src/discussion/utils': {
deps: [
......
......@@ -132,6 +132,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
});
it("expects all fields to behave correctly", function () {
var i, view;
requests = AjaxHelpers.requests(this);
......@@ -146,9 +147,8 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
expect(sectionsData[0].fields.length).toBe(6);
var textFields = [sectionsData[0].fields[1], sectionsData[0].fields[2]];
for (var i = 0; i < textFields.length ; i++) {
var view = textFields[i].view;
for (i = 0; i < textFields.length ; i++) {
view = textFields[i].view;
FieldViewsSpecHelpers.verifyTextField(view, {
title: view.options.title,
valueAttribute: view.options.valueAttribute,
......
......@@ -3,13 +3,14 @@
define([
'jquery',
'underscore',
'sinon',
'common/js/spec_helpers/template_helpers',
'common/js/spec_helpers/ajax_helpers',
'js/student_account/models/LoginModel',
'js/student_account/views/LoginView',
'js/student_account/models/PasswordResetModel'
],
function($, _, TemplateHelpers, AjaxHelpers, LoginModel, LoginView, PasswordResetModel) {
function($, _, sinon, TemplateHelpers, AjaxHelpers, LoginModel, LoginView, PasswordResetModel) {
describe('edx.student.account.LoginView', function() {
var model = null,
......@@ -267,13 +268,25 @@
});
it('displays an error if there is no internet connection', function () {
var clock,
oldTimeout,
timeout;
// We're defining "no internet connection" in this case as the
// request timing out. We use a combination of the sinon fake
// timer and jQuery.ajaxSetup() to force a request timeout.
clock = sinon.useFakeTimers();
oldTimeout = $.ajaxSetup().timeout;
timeout = 1;
$.ajaxSetup({timeout: timeout});
createLoginView(this);
// Submit the form, with successful validation
submitForm(true);
// Simulate an error from the LMS servers
AjaxHelpers.respondWithError(requests, 0);
// Simulate a request timeout
clock.tick(timeout + 1);
// Expect that an error is displayed and that auth complete is not triggered
expect(view.$errors).not.toHaveClass('hidden');
......@@ -281,7 +294,12 @@
expect(view.$errors.text()).toContain(
'An error has occurred. Check your Internet connection and try again.'
);
// Finally, restore the old timeout and turn off the fake timer.
$.ajaxSetup({timeout: oldTimeout});
clock.restore();
});
it('displays an error if there is a server error', function () {
createLoginView(this);
......
......@@ -54,6 +54,11 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
TemplateHelpers.installTemplate("templates/fields/message_banner");
});
afterEach(function () {
// image_field.js's window.onBeforeUnload breaks Karma in Chrome, clean it up after each test
$(window).off('beforeunload');
});
var createFakeImageFile = function (size) {
var fileFakeData = 'i63ljc6giwoskyb9x5sw0169bdcmcxr3cdz8boqv0lik971972cmd6yknvcxr5sw0nvc169bdcmcxsdf';
return new Blob(
......@@ -260,6 +265,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
// Verify image upload progress message
verifyImageUploadButtonMessage(imageView, true);
window.onbeforeunload = null;
$(window).trigger('beforeunload');
expect(imageView.onBeforeUnload).toHaveBeenCalled();
});
......
......@@ -42,7 +42,7 @@ define([
// Simulate the server response
if ( succeeds ) {
AjaxHelpers.respondWithJson( requests, {} );
AjaxHelpers.respondWithJson( requests, {url: '/arbitrary-url/'} );
} else {
AjaxHelpers.respondWithTextError( requests, 400, SERVER_ERROR_MSG );
}
......
......@@ -240,8 +240,8 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
verifyEditableField(view, _.extend({
valueSelector: '.u-field-value',
valueInputSelector: '.u-field-value > input'
}, data
), requests);
}, data),
requests);
};
var verifyDropDownField = function (view, data, requests) {
......
......@@ -28,7 +28,7 @@
},
parse : function(response) {
if (_.isNull(response)) {
if (_.isNull(response) || _.isUndefined(response)) {
return {};
}
......
......@@ -78,7 +78,8 @@
$(this.el).show(); // Show in case the form was hidden for auto-submission
this.errors = _.flatten(
_.map(
JSON.parse(error.responseText),
// Something is passing this 'undefined'. Protect against this.
JSON.parse(error.responseText || "[]"),
function(error_list) {
return _.map(
error_list,
......
......@@ -218,13 +218,13 @@
this.backend = this.backends[obj.backendName] || obj.backend;
this.captureSoundPath = obj.captureSoundPath || "";
_.extend( this.backend, Backbone.Events );
this.backend.initialize({
wrapper: "#camera",
video: '#photo_id_video',
canvas: '#photo_id_canvas'
});
_.extend( this.backend, Backbone.Events );
this.listenTo( this.backend, 'error', this.handleError );
this.listenTo( this.backend, 'webcam-loaded', this.handleWebcamLoaded );
},
......
......@@ -13,6 +13,8 @@ var options = {
// Avoid adding files to this list. Use RequireJS.
libraryFilesToInclude: [
{pattern: 'common/js/vendor/jquery.js', included: true},
{pattern: 'common/js/vendor/jquery-migrate.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.event.drag-2.2.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/slick.core.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/slick.grid.js', included: true}
......
......@@ -25,7 +25,8 @@ var options = {
{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},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.min.js', included: true},
{pattern: 'common/js/vendor/jquery.js', included: true},
{pattern: 'common/js/vendor/jquery-migrate.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/jquery.cookie.js', included: true},
{pattern: 'xmodule_js/common_static/js/vendor/flot/jquery.flot.js', included: true},
{pattern: 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js', included: true},
......
......@@ -66,6 +66,7 @@
'gettext': 'empty:',
'coffee/src/ajax_prefix': 'empty:',
'jquery': 'empty:',
'jquery-migrate': 'empty:',
'jquery.cookie': 'empty:',
'jquery.url': 'empty:',
'backbone': 'empty:',
......
......@@ -28,6 +28,7 @@
}
};
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
......@@ -64,7 +65,13 @@
"backbone.paginator": "js/vendor/backbone.paginator.min",
"underscore": "common/js/vendor/underscore",
"underscore.string": "common/js/vendor/underscore.string",
"jquery": "js/vendor/jquery.min",
// 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
// 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.timeago': 'js/vendor/jquery.timeago',
"jquery.url": "js/vendor/url.min",
......@@ -111,6 +118,10 @@
"date": {
exports: "Date"
},
"jquery": {
exports: "jQuery"
},
"jquery-migrate": ['jquery'],
"jquery.cookie": {
deps: ["jquery"],
exports: "jQuery.fn.cookie"
......
......@@ -45,7 +45,7 @@ ${static.get_page_title_breadcrumbs(course_name())}
</%block>
<%block name="js_extra">
<script type="text/javascript" src="${static.url('js/vendor/jquery.scrollTo-1.4.2-min.js')}"></script>
<script type="text/javascript" src="${static.url('common/js/vendor/jquery.scrollTo.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
## codemirror
......
......@@ -65,7 +65,7 @@ ${static.get_page_title_breadcrumbs(course_name())}
</%block>
<%block name="js_extra">
<script type="text/javascript" src="${static.url('js/vendor/jquery.scrollTo-1.4.2-min.js')}"></script>
<script type="text/javascript" src="${static.url('common/js/vendor/jquery.scrollTo.js')}"></script>
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
## codemirror
......
......@@ -21,7 +21,7 @@
</body>
</html>
<script type="text/javascript" src="${static.url('js/vendor/jquery.min.js')}"></script>
<script type="text/javascript" src="${static.url('common/js/vendor/jquery.js')}"></script>
<script type="text/javascript">
$(document).ready(function() {
......
......@@ -2,15 +2,18 @@
"name": "edx",
"version": "0.1.0",
"dependencies": {
"backbone": "~1.3.2",
"coffee-script": "1.6.1",
"edx-pattern-library": "~0.12.4",
"edx-ui-toolkit": "~0.9.1",
"jquery": "~2.2.0",
"jquery-migrate": "^1.4.1",
"jquery.scrollto": "~2.1.2",
"picturefill": "~3.0.2",
"requirejs": "~2.1.22",
"uglify-js": "2.4.24",
"underscore": "~1.8.3",
"underscore.string": "~3.3.4",
"picturefill": "~3.0.2",
"backbone": "~1.3.2"
"underscore.string": "~3.3.4"
},
"devDependencies": {
"edx-custom-a11y-rules": "edx/edx-custom-a11y-rules",
......
......@@ -45,6 +45,9 @@ SASS_LOAD_PATHS = [
# A list of NPM installed libraries that should be copied into the common
# static directory.
NPM_INSTALLED_LIBRARIES = [
'jquery/dist/jquery.js',
'jquery-migrate/dist/jquery-migrate.js',
'jquery.scrollto/jquery.scrollTo.js',
'underscore/underscore.js',
'underscore.string/dist/underscore.string.js',
'picturefill/dist/picturefill.js',
......
......@@ -10,7 +10,6 @@
"date": "1.0",
"domready": "2.0.1",
"draggabilly": "1.2.4",
"jquery": "1.7.2",
"jquery-form": "3.18.0",
"jquery-watch": "2.0",
"moment": "2.10.6",
......
......@@ -22,7 +22,6 @@
"domReady": "2.0.1",
"draggabilly": "1.2.4",
// "history": "1.8b2",
"jquery": "1.7.2",
// "jquery.ajaxQueue": "unknown",
// "jquery.ajax-retry": "unknown",
"jquery.colorhelpers": "1.1",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment