Merge pull request #24246 from edx/private_to_public_edd9b02

Mergeback PR from private to public.
This commit is contained in:
edx-pipeline-bot
2020-06-18 12:22:20 +05:00
committed by GitHub
16 changed files with 213 additions and 174 deletions

View File

@@ -8,10 +8,11 @@ define([
'js/views/list_item_editor',
'js/certificates/models/signatory',
'js/certificates/views/signatory_editor',
'text!templates/certificate-editor.underscore'
'text!templates/certificate-editor.underscore',
'edx-ui-toolkit/js/utils/html-utils'
],
function($, _, Backbone, gettext,
ListItemEditorView, SignatoryModel, SignatoryEditorView, certificateEditorTemplate) {
ListItemEditorView, SignatoryModel, SignatoryEditorView, certificateEditorTemplate, HtmlUtils) {
'use strict';
// If signatories limit is required to specific value then we can change it.
@@ -75,7 +76,7 @@ function($, _, Backbone, gettext,
isEditingAllCollections: true,
eventAgg: self.eventAgg
});
self.$('div.signatory-edit-list').append($(signatory_view.render()));
self.$('div.signatory-edit-list').append(HtmlUtils.HTML((signatory_view.render())).toString());
});
this.disableAddSignatoryButton();
return this;

View File

@@ -8,9 +8,10 @@ define([
'js/views/baseview',
'common/js/components/utils/view_utils',
'common/js/components/views/feedback_notification',
'text!templates/certificate-web-preview.underscore'
'text!templates/certificate-web-preview.underscore',
'edx-ui-toolkit/js/utils/html-utils'
],
function(_, gettext, BaseView, ViewUtils, NotificationView, certificateWebPreviewTemplate) {
function(_, gettext, BaseView, ViewUtils, NotificationView, certificateWebPreviewTemplate, HtmlUtils) {
'use strict';
var CertificateWebPreview = BaseView.extend({
el: $('.preview-certificate'),
@@ -27,7 +28,7 @@ function(_, gettext, BaseView, ViewUtils, NotificationView, certificateWebPrevie
},
render: function() {
this.$el.html(_.template(certificateWebPreviewTemplate)({
HtmlUtils.setHtml(this.$el, HtmlUtils.template(certificateWebPreviewTemplate)({
course_modes: this.course_modes,
certificate_web_view_url: this.certificate_web_view_url,
is_active: this.is_active
@@ -36,13 +37,8 @@ function(_, gettext, BaseView, ViewUtils, NotificationView, certificateWebPrevie
},
toggleCertificateActivation: function() {
var msg = 'Activating';
if (this.is_active) {
msg = 'Deactivating';
}
var notification = new NotificationView.Mini({
title: gettext(msg)
title: gettext(this.is_active ? 'Deactivating' : 'Activating')
});
$.ajax({

View File

@@ -11,10 +11,11 @@ define([
'js/views/baseview',
'js/certificates/views/signatory_editor',
'text!templates/signatory-details.underscore',
'text!templates/signatory-actions.underscore'
'text!templates/signatory-actions.underscore',
'edx-ui-toolkit/js/utils/html-utils'
],
function($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, SignatoryEditorView,
signatoryDetailsTemplate, signatoryActionsTemplate) {
signatoryDetailsTemplate, signatoryActionsTemplate, HtmlUtils) {
'use strict';
var SignatoryDetailsView = BaseView.extend({
tagName: 'div',
@@ -52,20 +53,20 @@ function($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Signa
editSignatory: function(event) {
// Retrieve the edit view for this model
if (event && event.preventDefault) { event.preventDefault(); }
this.$el.html(this.edit_view.render());
$(_.template(signatoryActionsTemplate)()).appendTo(this.el);
this.$el.html(HtmlUtils.HTML(this.edit_view.render()).toString());
this.$el.append(HtmlUtils.template(signatoryActionsTemplate)().toString());
this.edit_view.delegateEvents();
this.delegateEvents();
},
saveSignatoryData: function(event) {
// Persist the data for this model
if (event && event.preventDefault) { event.preventDefault(); }
var certificate = this.model.get('certificate');
var self = this;
if (event && event.preventDefault) { event.preventDefault(); }
if (!certificate.isValid()) {
return;
}
var self = this;
ViewUtils.runOperationShowingMessage(
gettext('Saving'),
function() {
@@ -94,7 +95,7 @@ function($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Signa
var attributes = $.extend({}, this.model.attributes, {
signatory_number: this.model.collection.indexOf(this.model) + 1
});
return $(this.el).html(_.template(signatoryDetailsTemplate)(attributes));
return HtmlUtils.setHtml(this.$el, HtmlUtils.template(signatoryDetailsTemplate)(attributes));
}
});
return SignatoryDetailsView;

View File

@@ -11,11 +11,12 @@ define([
'common/js/components/views/feedback_notification',
'js/models/uploads',
'js/views/uploads',
'text!templates/signatory-editor.underscore'
'text!templates/signatory-editor.underscore',
'edx-ui-toolkit/js/utils/html-utils'
],
function($, _, Backbone, gettext,
TemplateUtils, ViewUtils, PromptView, NotificationView, FileUploadModel, FileUploadDialog,
signatoryEditorTemplate) {
signatoryEditorTemplate, HtmlUtils) {
'use strict';
var SignatoryEditorView = Backbone.View.extend({
tagName: 'div',
@@ -78,7 +79,7 @@ function($, _, Backbone, gettext,
is_editing_all_collections: this.isEditingAllCollections,
total_saved_signatories: this.getTotalSignatoriesOnServer()
});
return $(this.el).html(_.template(signatoryEditorTemplate)(attributes));
return HtmlUtils.setHtml(this.$el, HtmlUtils.template(signatoryEditorTemplate)(attributes));
},
setSignatoryName: function(event) {
@@ -127,10 +128,9 @@ function($, _, Backbone, gettext,
deleteItem: function(event) {
// Remove the specified model from the collection
if (event && event.preventDefault) { event.preventDefault(); }
var model = this.model;
var self = this;
var titleTextTemplate = _.template(gettext('Delete "<%= signatoryName %>" from the list of signatories?'));
var titleTextTemplate = _.template(gettext('Delete "<%- signatoryName %>" from the list of signatories?'));
var confirm = new PromptView.Warning({
title: titleTextTemplate({signatoryName: model.get('name')}),
message: gettext('This action cannot be undone.'),
@@ -148,9 +148,9 @@ function($, _, Backbone, gettext,
deleting.show();
model.destroy({
wait: true,
success: function(model) {
success: function(model2) {
deleting.hide();
self.eventAgg.trigger('onSignatoryRemoved', model);
self.eventAgg.trigger('onSignatoryRemoved', model2);
}
});
}
@@ -165,18 +165,20 @@ function($, _, Backbone, gettext,
}
}
});
if (event && event.preventDefault) { event.preventDefault(); }
confirm.show();
},
uploadSignatureImage: function(event) {
var upload, self, modal;
event.preventDefault();
var upload = new FileUploadModel({
upload = new FileUploadModel({
title: gettext('Upload signature image.'),
message: gettext('Image must be in PNG format.'),
mimeTypes: ['image/png']
});
var self = this;
var modal = new FileUploadDialog({
self = this;
modal = new FileUploadDialog({
model: upload,
onSuccess: function(response) {
self.model.set('signature_image_path', response.asset.url);
@@ -192,12 +194,13 @@ function($, _, Backbone, gettext,
*/
toggleValidationErrorMessage: function(modelAttribute) {
var selector = 'div.add-signatory-' + modelAttribute;
var errorMessage;
if (!this.model.isValid() && _.has(this.model.validationError, modelAttribute)) {
// Show the error message if it is not exist before.
if (!$(selector).hasClass('error')) {
var errorMessage = this.model.validationError[modelAttribute];
errorMessage = this.model.validationError[modelAttribute];
$(selector).addClass('error');
$(selector).append("<span class='message-error'>" + errorMessage + '</span>');
$(selector).append(HtmlUtils.joinHtml(HtmlUtils.HTML("<span class='message-error'>"), errorMessage, HtmlUtils.HTML('</span>')).toString()); // eslint-disable-line max-len
}
} else {
// Remove the error message.

View File

@@ -22,7 +22,11 @@ function($, _, gettext, ViewUtils, StringUtils, HtmlUtils) {
showError = function(containerElSelector, error) {
var errorWrapperElSelector, errorHtml;
errorWrapperElSelector = containerElSelector + ' .wrapper-error';
errorHtml = '<div class="error" aria-live="polite" id="course-id-error">' + error + '</div>';
errorHtml = HtmlUtils.joinHtml(
HtmlUtils.HTML('<div class="error" aria-live="polite" id="course-id-error">'),
error,
HtmlUtils.HTML('</div>')
);
HtmlUtils.setHtml($(errorWrapperElSelector), HtmlUtils.HTML(errorHtml));
$(errorWrapperElSelector).css('display', 'inline-block');
$(errorWrapperElSelector).fadeOut(5000);

View File

@@ -1,5 +1,8 @@
define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js/utils/date_utils'],
function(Backbone, _, gettext, ValidationHelpers, DateUtils) {
define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js/utils/date_utils',
'edx-ui-toolkit/js/utils/string-utils'
],
function(Backbone, _, gettext, ValidationHelpers, DateUtils, StringUtils) {
'use strict';
var CourseDetails = Backbone.Model.extend({
defaults: {
org: '',
@@ -51,11 +54,17 @@ define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js
if (newattrs.start_date && newattrs.end_date && newattrs.start_date >= newattrs.end_date) {
errors.end_date = gettext('The course end date must be later than the course start date.');
}
if (newattrs.start_date && newattrs.enrollment_start && newattrs.start_date < newattrs.enrollment_start) {
errors.enrollment_start = gettext('The course start date must be later than the enrollment start date.');
if (newattrs.start_date && newattrs.enrollment_start &&
newattrs.start_date < newattrs.enrollment_start) {
errors.enrollment_start = gettext(
'The course start date must be later than the enrollment start date.'
);
}
if (newattrs.enrollment_start && newattrs.enrollment_end && newattrs.enrollment_start >= newattrs.enrollment_end) {
errors.enrollment_end = gettext('The enrollment start date cannot be after the enrollment end date.');
if (newattrs.enrollment_start && newattrs.enrollment_end &&
newattrs.enrollment_start >= newattrs.enrollment_end) {
errors.enrollment_end = gettext(
'The enrollment start date cannot be after the enrollment end date.'
);
}
if (newattrs.end_date && newattrs.enrollment_end && newattrs.end_date < newattrs.enrollment_end) {
errors.enrollment_end = gettext('The enrollment end date cannot be after the course end date.');
@@ -78,7 +87,9 @@ define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js
max: 100
};
if (!ValidationHelpers.validateIntegerRange(newattrs.entrance_exam_minimum_score_pct, range)) {
errors.entrance_exam_minimum_score_pct = interpolate(gettext('Please enter an integer between %(min)s and %(max)s.'), range, true);
errors.entrance_exam_minimum_score_pct = StringUtils.interpolate(gettext(
'Please enter an integer between %(min)s and %(max)s.'
), range, true);
}
}
if (!_.isEmpty(errors)) return errors;
@@ -90,7 +101,8 @@ define(['backbone', 'underscore', 'gettext', 'js/models/validation_helpers', 'js
set_videosource: function(newsource) {
// newsource either is <video youtube="speed:key, *"/> or just the "speed:key, *" string
// returns the videosource for the preview which iss the key whose speed is closest to 1
if (_.isEmpty(newsource) && !_.isEmpty(this.get('intro_video'))) this.set({intro_video: null}, {validate: true});
if (_.isEmpty(newsource) &&
!_.isEmpty(this.get('intro_video'))) this.set({intro_video: null}, {validate: true});
// TODO remove all whitespace w/in string
else {
if (this.get('intro_video') !== newsource) this.set('intro_video', newsource, {validate: true});

View File

@@ -1,6 +1,7 @@
/* globals _ */
define(['backbone', 'js/models/location', 'js/collections/course_grader'],
function(Backbone, Location, CourseGraderCollection) {
define(['backbone', 'js/models/location', 'js/collections/course_grader', 'edx-ui-toolkit/js/utils/string-utils'],
function(Backbone, Location, CourseGraderCollection, StringUtils) {
'use strict';
var CourseGradingPolicy = Backbone.Model.extend({
defaults: {
graders: null, // CourseGraderCollection
@@ -37,9 +38,15 @@ define(['backbone', 'js/models/location', 'js/collections/course_grader'],
},
gracePeriodToDate: function() {
var newDate = new Date();
if (this.has('grace_period') && this.get('grace_period').hours) { newDate.setHours(this.get('grace_period').hours); } else newDate.setHours(0);
if (this.has('grace_period') && this.get('grace_period').minutes) { newDate.setMinutes(this.get('grace_period').minutes); } else newDate.setMinutes(0);
if (this.has('grace_period') && this.get('grace_period').seconds) { newDate.setSeconds(this.get('grace_period').seconds); } else newDate.setSeconds(0);
if (this.has('grace_period') && this.get('grace_period').hours) {
newDate.setHours(this.get('grace_period').hours);
} else newDate.setHours(0);
if (this.has('grace_period') && this.get('grace_period').minutes) {
newDate.setMinutes(this.get('grace_period').minutes);
} else newDate.setMinutes(0);
if (this.has('grace_period') && this.get('grace_period').seconds) {
newDate.setSeconds(this.get('grace_period').seconds);
} else newDate.setSeconds(0);
return newDate;
},
@@ -62,6 +69,7 @@ define(['backbone', 'js/models/location', 'js/collections/course_grader'],
return parseInt(minimum_grade_credit);
},
validate: function(attrs) {
var minimumGradeCutoff;
if (_.has(attrs, 'grace_period')) {
if (attrs.grace_period === null) {
return {
@@ -71,12 +79,13 @@ define(['backbone', 'js/models/location', 'js/collections/course_grader'],
}
if (this.get('is_credit_course') && _.has(attrs, 'minimum_grade_credit')) {
// Getting minimum grade cutoff value
var minimum_grade_cutoff = _.min(_.values(attrs.grade_cutoffs));
if (isNaN(attrs.minimum_grade_credit) || attrs.minimum_grade_credit === null || attrs.minimum_grade_credit < minimum_grade_cutoff) {
minimumGradeCutoff = _.min(_.values(attrs.grade_cutoffs));
if (isNaN(attrs.minimum_grade_credit) || attrs.minimum_grade_credit === null ||
attrs.minimum_grade_credit < minimumGradeCutoff) {
return {
minimum_grade_credit: interpolate(
minimum_grade_credit: StringUtils.interpolate(
gettext('Not able to set passing grade to less than %(minimum_grade_cutoff)s%.'),
{minimum_grade_cutoff: minimum_grade_cutoff * 100},
{minimum_grade_cutoff: minimumGradeCutoff * 100},
true
)
};

View File

@@ -9,6 +9,7 @@ define(['js/views/baseview', 'underscore'], function(BaseView, _) {
// Backbone model cid is only unique within the collection.
this.uniqueId = _.uniqueId(templateName + '_');
this.template = this.loadTemplate(templateName);
// xss-lint: disable=javascript-jquery-html
this.$el.html(this.template({model: this.model, uniqueId: this.uniqueId}));
this.listenTo(this.model, 'change', this.render);
this.render();

View File

@@ -1,6 +1,7 @@
define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/views/feedback_prompt',
'common/js/components/views/feedback_notification'],
function(BaseView, _, gettext, PromptView, NotificationView) {
'common/js/components/views/feedback_notification', 'edx-ui-toolkit/js/utils/html-utils'],
function(BaseView, _, gettext, PromptView, NotificationView, HtmlUtils) {
'use strict';
var AssetView = BaseView.extend({
initialize: function() {
this.template = this.loadTemplate('asset');
@@ -14,7 +15,7 @@ define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/view
render: function() {
var uniqueId = _.uniqueId('lock_asset_');
this.$el.html(this.template({
var attributes = {
display_name: this.model.get('display_name'),
thumbnail: this.model.get('thumbnail'),
date_added: this.model.get('date_added'),
@@ -23,32 +24,32 @@ define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/view
portable_url: this.model.get('portable_url'),
asset_type: this.model.get_extension(),
uniqueId: uniqueId
}));
};
this.$el.html(HtmlUtils.HTML(this.template(attributes)).toString());
this.updateLockState();
return this;
},
updateLockState: function() {
var locked_class = 'is-locked';
var lockedClass = 'is-locked';
// Add a class of "locked" to the tr element if appropriate,
// and toggle locked state of hidden checkbox.
if (this.model.get('locked')) {
this.$el.addClass(locked_class);
this.$el.addClass(lockedClass);
this.$el.find('.lock-checkbox').attr('checked', 'checked');
} else {
this.$el.removeClass(locked_class);
this.$el.removeClass(lockedClass);
this.$el.find('.lock-checkbox').removeAttr('checked');
}
},
confirmDelete: function(e) {
var asset = this.model;
if (e && e.preventDefault) { e.preventDefault(); }
var asset = this.model,
collection = this.model.collection;
new PromptView.Warning({
title: gettext('Delete File Confirmation'),
message: gettext('Are you sure you wish to delete this item. It cannot be reversed!\n\nAlso any content that links/refers to this item will no longer work (e.g. broken images and/or links)'),
message: gettext('Are you sure you wish to delete this item. It cannot be reversed!\n\nAlso any content that links/refers to this item will no longer work (e.g. broken images and/or links)'), // eslint-disable-line max-len
actions: {
primary: {
text: gettext('Delete'),
@@ -76,7 +77,7 @@ define(['js/views/baseview', 'underscore', 'gettext', 'common/js/components/view
}).show();
},
lockAsset: function(e) {
lockAsset: function() {
var asset = this.model;
var saving = new NotificationView.Mini({
title: gettext('Saving')

View File

@@ -1,102 +1,105 @@
define(['js/views/baseview', 'codemirror', 'common/js/components/views/feedback_notification', 'js/views/course_info_helper', 'js/utils/modal'],
function(BaseView, CodeMirror, NotificationView, CourseInfoHelper, ModalUtils) {
define([
'js/views/baseview',
'codemirror',
'common/js/components/views/feedback_notification',
'js/views/course_info_helper',
'js/utils/modal',
'edx-ui-toolkit/js/utils/html-utils'
],
function(BaseView, CodeMirror, NotificationView, CourseInfoHelper, ModalUtils, HtmlUtils) {
'use strict';
// the handouts view is dumb right now; it needs tied to a model and all that jazz
var CourseInfoHandoutsView = BaseView.extend({
// collection is CourseUpdateCollection
events: {
'click .save-button': 'onSave',
'click .cancel-button': 'onCancel',
'click .edit-button': 'onEdit'
},
var CourseInfoHandoutsView = BaseView.extend({
// collection is CourseUpdateCollection
events: {
'click .save-button': 'onSave',
'click .cancel-button': 'onCancel',
'click .edit-button': 'onEdit'
},
initialize: function() {
this.template = this.loadTemplate('course_info_handouts');
var self = this;
this.model.fetch({
complete: function() {
self.render();
},
reset: true
});
},
initialize: function() {
var self = this;
this.template = this.loadTemplate('course_info_handouts');
this.model.fetch({
complete: function() {
self.render();
},
reset: true
});
},
render: function() {
CourseInfoHelper.changeContentToPreview(
this.model, 'data', this.options.base_asset_url);
render: function() {
CourseInfoHelper.changeContentToPreview(
this.model, 'data', this.options.base_asset_url);
this.$el.html(HtmlUtils.HTML($(this.template({model: this.model}))).toString());
HtmlUtils.setHtml($('.handouts-content'), HtmlUtils.HTML(this.model.get('data')));
this.$preview = this.$el.find('.handouts-content');
this.$form = this.$el.find('.edit-handouts-form');
this.$editor = this.$form.find('.handouts-content-editor');
this.$form.hide();
this.$el.html(
$(this.template({
model: this.model
}))
);
$('.handouts-content').html(this.model.get('data'));
this.$preview = this.$el.find('.handouts-content');
this.$form = this.$el.find('.edit-handouts-form');
this.$editor = this.$form.find('.handouts-content-editor');
this.$form.hide();
return this;
},
return this;
},
onEdit: function() {
var self = this;
this.$editor.val(this.$preview.html());
this.$form.show();
onEdit: function(event) {
var self = this;
this.$editor.val(this.$preview.html());
this.$form.show();
this.$codeMirror = CourseInfoHelper.editWithCodeMirror(
self.model, 'data', self.options.base_asset_url, this.$editor.get(0));
this.$codeMirror = CourseInfoHelper.editWithCodeMirror(
self.model, 'data', self.options.base_asset_url, this.$editor.get(0));
ModalUtils.showModalCover(false, function() { self.closeEditor(); });
},
ModalUtils.showModalCover(false, function() { self.closeEditor(); });
},
onSave: function(event) {
var handoutsContent = this.$codeMirror.getValue();
$('#handout_error').removeClass('is-shown');
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
if ($('.CodeMirror-lines').find('.cm-error').length == 0) {
if (handoutsContent === '') {
handoutsContent = '<ol></ol>';
}
this.model.set('data', handoutsContent);
var saving = new NotificationView.Mini({
title: gettext('Saving')
});
saving.show();
this.model.save({}, {
success: function() {
saving.hide();
}
});
this.render();
this.$form.hide();
this.closeEditor();
analytics.track('Saved Course Handouts', {
course: course_location_analytics
});
} else {
$('#handout_error').addClass('is-shown');
$('.save-button').addClass('is-disabled').attr('aria-disabled', true);
event.preventDefault();
onSave: function(event) {
var saving = new NotificationView.Mini({
title: gettext('Saving')
});
var handoutsContent = this.$codeMirror.getValue();
$('#handout_error').removeClass('is-shown');
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
if ($('.CodeMirror-lines').find('.cm-error').length === 0) {
if (handoutsContent === '') {
handoutsContent = '<ol></ol>';
}
},
onCancel: function(event) {
$('#handout_error').removeClass('is-shown');
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
this.model.set('data', handoutsContent);
saving.show();
this.model.save({}, {
success: function() {
saving.hide();
}
});
this.render();
this.$form.hide();
this.closeEditor();
},
closeEditor: function() {
$('#handout_error').removeClass('is-shown');
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
this.$form.hide();
ModalUtils.hideModalCover();
this.$form.find('.CodeMirror').remove();
this.$codeMirror = null;
analytics.track('Saved Course Handouts', { // eslint-disable-line no-undef
course: course_location_analytics // eslint-disable-line no-undef
});
} else {
$('#handout_error').addClass('is-shown');
$('.save-button').addClass('is-disabled').attr('aria-disabled', true);
event.preventDefault();
}
});
},
return CourseInfoHandoutsView;
}); // end define()
onCancel: function() {
$('#handout_error').removeClass('is-shown');
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
this.$form.hide();
this.closeEditor();
},
closeEditor: function() {
$('#handout_error').removeClass('is-shown');
$('.save-button').removeClass('is-disabled').attr('aria-disabled', false);
this.$form.hide();
ModalUtils.hideModalCover();
this.$form.find('.CodeMirror').remove();
this.$codeMirror = null;
}
});
return CourseInfoHandoutsView;
}); // end define()

View File

@@ -1,5 +1,12 @@
<%namespace name='static' file='../static_content.html'/>
<%page expression_filter="h"/>
<%namespace name='static' file='../static_content.html'/>
<%!
from openedx.core.djangolib.js_utils import (
dump_js_escaped_json
)
%>
<%! import json %>
<!DOCTYPE HTML>
<script src="${static.url('js/vendor/xdomain.min.js')}"></script>
<script>xdomain.masters(${xdomain_masters});</script>
<script>xdomain.masters(${json.loads(xdomain_masters) | n, dump_js_escaped_json});</script>

View File

@@ -5,9 +5,10 @@
[
'gettext', 'jquery', 'underscore', 'backbone', 'moment',
'text!learner_profile/templates/badge.underscore',
'learner_profile/js/views/share_modal_view'
'learner_profile/js/views/share_modal_view',
'edx-ui-toolkit/js/utils/html-utils'
],
function(gettext, $, _, Backbone, Moment, badgeTemplate, ShareModalView) {
function(gettext, $, _, Backbone, Moment, badgeTemplate, ShareModalView, HtmlUtils) {
var BadgeView = Backbone.View.extend({
initialize: function(options) {
this.options = _.extend({}, options);
@@ -35,7 +36,7 @@
modal.$el.fadeIn('short', 'swing', _.bind(modal.ready, modal));
},
render: function() {
this.$el.html(this.template(this.context));
this.$el.html(HtmlUtils.HTML(this.template(this.context)).toString());
this.shareButton = this.$el.find('.share-button');
return this;
}

View File

@@ -3,9 +3,10 @@
define(
[
'gettext', 'jquery', 'underscore', 'backbone', 'text!learner_profile/templates/section_two.underscore'
'gettext', 'jquery', 'underscore', 'backbone', 'text!learner_profile/templates/section_two.underscore',
'edx-ui-toolkit/js/utils/html-utils'
],
function(gettext, $, _, Backbone, sectionTwoTemplate) {
function(gettext, $, _, Backbone, sectionTwoTemplate, HtmlUtils) {
var SectionTwoTab = Backbone.View.extend({
attributes: {
class: 'wrapper-profile-section-two'
@@ -17,10 +18,7 @@
render: function() {
var self = this;
var showFullProfile = this.options.showFullProfile();
this.$el.html(this.template({
ownProfile: self.options.ownProfile,
showFullProfile: showFullProfile
}));
this.$el.html(HtmlUtils.HTML(this.template({ownProfile: self.options.ownProfile, showFullProfile: showFullProfile})).toString()); // eslint-disable-line max-len
if (showFullProfile) {
_.each(this.options.viewList, function(fieldView) {
self.$el.find('.field-container').append(fieldView.render().el);

View File

@@ -4,9 +4,10 @@
define(
[
'gettext', 'jquery', 'underscore', 'backbone', 'moment',
'text!learner_profile/templates/share_modal.underscore'
'text!learner_profile/templates/share_modal.underscore',
'edx-ui-toolkit/js/utils/html-utils'
],
function(gettext, $, _, Backbone, Moment, badgeModalTemplate) {
function(gettext, $, _, Backbone, Moment, badgeModalTemplate, HtmlUtils) {
var ShareModalView = Backbone.View.extend({
attributes: {
class: 'badges-overlay'
@@ -45,7 +46,7 @@
this.$el.find('.badges-modal').focus();
},
render: function() {
this.$el.html(this.template(this.model.toJSON()));
this.$el.html(HtmlUtils.HTML(this.template(this.model.toJSON())).toString());
return this;
}
});

View File

@@ -64,7 +64,7 @@
<td width="70">
<a href="{% with_link_tracking homepage_url %}"><img
src="http://localhost:18000/static/red-theme/images/logo.png"
alt="{% blocktrans %}Go to {{ platform_name }} Home Page{% endblocktrans %}"/></a>
alt="{% filter force_escape %} {% blocktrans %}Go to {{ platform_name }} Home Page{% endblocktrans %} {% endfilter %}"/></a>
</td>
<td align="right" style="text-align: {{ LANGUAGE_BIDI|yesno:"left,right" }};">
<a class="login" href="{% with_link_tracking dashboard_url %}" style="color: #960909;">{% trans "Sign In" %}</a>
@@ -97,7 +97,7 @@
<td height="32" width="42">
<a href="{{ social_media_urls.linkedin|safe }}">
<img src="https://media.sailthru.com/595/1k1/8/o/599f354ec70cb.png"
width="32" height="32" alt="{% blocktrans %}{{ platform_name }} on LinkedIn{% endblocktrans %}"/>
width="32" height="32" alt="{% filter force_escape %} {% blocktrans %}{{ platform_name }} on LinkedIn{% endblocktrans %} {% endfilter %}"/>
</a>
</td>
{% endif %}
@@ -105,7 +105,7 @@
<td height="32" width="42">
<a href="{{ social_media_urls.twitter|safe }}">
<img src="https://media.sailthru.com/595/1k1/8/o/599f354d9c26e.png"
width="32" height="32" alt="{% blocktrans %}{{ platform_name }} on Twitter{% endblocktrans %}"/>
width="32" height="32" alt="{% filter force_escape %} {% blocktrans %}{{ platform_name }} on Twitter{% endblocktrans %} {% endfilter %}"/>
</a>
</td>
{% endif %}
@@ -113,7 +113,7 @@
<td height="32" width="42">
<a href="{{ social_media_urls.facebook|safe }}">
<img src="https://media.sailthru.com/595/1k1/8/o/599f355052c8e.png"
width="32" height="32" alt="{% blocktrans %}{{ platform_name }} on Facebook{% endblocktrans %}"/>
width="32" height="32" alt="{% filter force_escape %} {% blocktrans %}{{ platform_name }} on Facebook{% endblocktrans %} {% endfilter %}"/>
</a>
</td>
{% endif %}
@@ -121,7 +121,7 @@
<td height="32" width="42">
<a href="{{ social_media_urls.google_plus|safe }}">
<img src="https://media.sailthru.com/595/1k1/8/o/599f354fc554a.png"
width="32" height="32" alt="{% blocktrans %}{{ platform_name }} on Google Plus{% endblocktrans %}"/>
width="32" height="32" alt="{% filter force_escape %} {% blocktrans %}{{ platform_name }} on Google Plus{% endblocktrans %} {% endfilter %}"/>
</a>
</td>
{% endif %}
@@ -129,7 +129,7 @@
<td height="32" width="42">
<a href="{{ social_media_urls.reddit|safe }}">
<img src="https://media.sailthru.com/595/1k1/8/o/599f354e326b9.png"
width="32" height="32" alt="{% blocktrans %}{{ platform_name }} on Reddit{% endblocktrans %}"/>
width="32" height="32" alt="{% filter force_escape %} {% blocktrans %}{{ platform_name }} on Reddit{% endblocktrans %} {% endfilter %}"/>
</a>
</td>
{% endif %}
@@ -143,14 +143,14 @@
{% if mobile_store_urls.apple %}
<a href="{{ mobile_store_urls.apple|safe }}" style="text-decoration: none">
<img src="https://media.sailthru.com/595/1k1/6/2/5931cfbba391b.png"
alt="{% trans "Download the iOS app on the Apple Store" %}"
alt="{% trans "Download the iOS app on the Apple Store" as tmsg %}{{ tmsg | force_escape }}"
width="136" height="50" style="margin-{{ LANGUAGE_BIDI|yesno:"left,right" }}: 10px"/>
</a>
{% endif %}
{% if mobile_store_urls.google %}
<a href="{{ mobile_store_urls.google|safe }}" style="text-decoration: none">
<img src="https://media.sailthru.com/595/1k1/6/2/5931cf879a033.png"
alt="{% trans "Download the Android app on the Google Play Store" %}"
alt="{% trans "Download the Android app on the Google Play Store" as tmsg %}{{ tmsg | force_escape }}"
width="136" height="50"/>
</a>
{% endif %}
@@ -171,9 +171,9 @@
<tr>
<!-- COPYRIGHT -->
<td>
&copy; {% now "Y" %} {{ platform_name }}, {% trans "All rights reserved" %}.<br/>
&copy; {% now "Y" %} {{ platform_name }}, {% trans "All rights reserved" as tmsg %}{{ tmsg | force_escape }}.<br/>
<br/>
{% trans "Our mailing address is" %}:<br/>
{% trans "Our mailing address is" as tmsg %}{{ tmsg | force_escape }}:<br/>
{{ contact_mailing_address }}
</td>
</tr>

View File

@@ -1,3 +1,4 @@
<%page expression_filter="h"/>
<%!
from django.utils.translation import ugettext as _
%>
@@ -5,10 +6,10 @@ from django.utils.translation import ugettext as _
<header>
<div class="social-sharing">
<div class="sharing-message">${_("Share with friends and family!")}</div>
<a href="http://twitter.com/intent/tweet?text=I+just+enrolled+in+${course.number}+${course.display_name_with_default_escaped}!+(http://class.stanford.edu)" class="share">
<a href="http://twitter.com/intent/tweet?text=I+just+enrolled+in+${course.number}+${course.display_name_with_default}!+(http://class.stanford.edu)" class="share">
<span class="icon fa fa-twitter" aria-hidden="true"></span><span class="sr">${_("Tweet that you've enrolled in this course")}</span>
</a>
<a href="mailto:?subject=Take%20a%20course%20at%20Stanford%20online!&body=I%20just%20enrolled%20in%20${course.number}%20${course.display_name_with_default_escaped}+(http://class.stanford.edu)" class="share">
<a href="mailto:?subject=Take%20a%20course%20at%20Stanford%20online!&body=I%20just%20enrolled%20in%20${course.number}%20${course.display_name_with_default}+(http://class.stanford.edu)" class="share">
<span class="icon fa fa-envelope" aria-hidden="true"></span><span class="sr">${_("Email someone to say you've enrolled in this course")}</span>
</a>
</div>