Commit 34b06932 by Awais Jibran

Safe tempaltes

parent f7ec039b
define(["js/views/validation", "jquery", "underscore", "gettext", "codemirror", "js/views/modals/validation_error_modal"],
function(ValidatingView, $, _, gettext, CodeMirror, ValidationErrorModal) {
define(["js/views/validation",
"jquery",
"underscore",
"gettext",
"codemirror",
"js/views/modals/validation_error_modal",
'edx-ui-toolkit/js/utils/html-utils'],
function(ValidatingView, $, _, gettext, CodeMirror, ValidationErrorModal, HtmlUtils) {
var AdvancedView = ValidatingView.extend({
error_saving : "error_saving",
......@@ -13,7 +19,9 @@ var AdvancedView = ValidatingView.extend({
// TODO enable/disable save based on validation (currently enabled whenever there are changes)
},
initialize : function() {
this.template = _.template($("#advanced_entry-tpl").text());
this.template = HtmlUtils.template(
$("#advanced_entry-tpl").text()
);
this.listenTo(this.model, 'invalid', this.handleValidationError);
this.render();
},
......@@ -33,7 +41,7 @@ var AdvancedView = ValidatingView.extend({
_.each(_.sortBy(_.keys(this.model.attributes), function(key) { return self.model.get(key).display_name; }),
function(key) {
if (self.render_deprecated || !self.model.get(key).deprecated) {
listEle$.append(self.renderTemplate(key, self.model.get(key)));
HtmlUtils.append(listEle$, self.renderTemplate(key, self.model.get(key)));
}
});
......
define(["js/views/validation", "underscore", "jquery"], function(ValidatingView, _, $) {
define(["js/views/validation",
'gettext',
'edx-ui-toolkit/js/utils/string-utils',
"edx-ui-toolkit/js/utils/html-utils",
"underscore",
"jquery"],
function(ValidatingView, gettext, StringUtils, HtmlUtils, _, $) {
var GraderView = ValidatingView.extend({
// Model class is CMS.Models.Settings.CourseGrader
......@@ -49,9 +55,14 @@ var GraderView = ValidatingView.extend({
if (this.setField(event) != this.oldName && !_.isEmpty(this.oldName)) {
// overload the error display logic
this._cacheValidationErrors.push(event.currentTarget);
$(event.currentTarget).parent().append(
this.errorTemplate({message : 'For grading to work, you must change all "' + this.oldName +
'" subsections to "' + this.model.get('type') + '".'}));
var message = StringUtils.interpolate(
gettext('For grading to work, you must change all {oldName} subsections to {newName}.'),
{
oldName: this.oldName,
newName: this.model.get('type')
}
);
HtmlUtils.append($(event.currentTarget).parent(), this.errorTemplate({message : message}));
}
break;
default:
......
define(["js/views/validation", "underscore", "jquery", "jquery.ui", "js/views/settings/grader"],
function(ValidatingView, _, $, ui, GraderView) {
define(["js/views/validation",
"underscore",
"jquery",
"jquery.ui",
"js/views/settings/grader",
'edx-ui-toolkit/js/utils/string-utils',
'edx-ui-toolkit/js/utils/html-utils',
],
function(ValidatingView, _, $, ui, GraderView, StringUtils, HtmlUtils) {
var GradingView = ValidatingView.extend({
// Model class is CMS.Models.Settings.CourseGradingPolicy
......@@ -21,13 +28,12 @@ var GradingView = ValidatingView.extend({
initialize : function() {
// load template for grading view
var self = this;
this.template = _.template($("#course_grade_policy-tpl").text());
this.gradeCutoffTemplate = _.template('<li class="grade-specific-bar" style="width:<%= width %>%"><span class="letter-grade" contenteditable="true">' +
'<%= descriptor %>' +
'</span><span class="range"></span>' +
'<% if (removable) {%><a href="#" class="remove-button">remove</a><% ;} %>' +
'</li>');
this.template = HtmlUtils.template(
$("#course_grade_policy-tpl").text()
);
this.gradeCutoffTemplate = HtmlUtils.template(
$("#course_grade_cutoff-tpl").text()
);
this.setupCutoffs();
this.listenTo(this.model, 'invalid', this.handleValidationError);
......@@ -68,7 +74,7 @@ var GradingView = ValidatingView.extend({
},
this);
gradeCollection.each(function(gradeModel) {
$(gradelist).append(self.template({model : gradeModel }));
HtmlUtils.append(gradelist, self.template({model : gradeModel }));
var newEle = gradelist.children().last();
var newView = new GraderView({el: newEle,
model : gradeModel, collection : gradeCollection });
......@@ -147,7 +153,7 @@ var GradingView = ValidatingView.extend({
gradeBarWidth : null, // cache of value since it won't change (more certain)
renderCutoffBar: function() {
var gradeBar =this.$el.find('.grade-bar');
var gradeBar = this.$el.find('.grade-bar');
this.gradeBarWidth = gradeBar.width();
var gradelist = gradeBar.children('.grades');
// HACK fixing a duplicate call issue by undoing previous call effect. Need to figure out why called 2x
......@@ -156,15 +162,15 @@ var GradingView = ValidatingView.extend({
// Can probably be simplified to one variable now.
var removable = false;
var draggable = false; // first and last are not removable, first is not draggable
_.each(this.descendingCutoffs,
function(cutoff, index) {
var newBar = this.gradeCutoffTemplate({
descriptor : cutoff['designation'] ,
_.each(this.descendingCutoffs, function(cutoff) {
HtmlUtils.append(gradelist, this.gradeCutoffTemplate({
descriptor : cutoff.designation,
width : nextWidth,
removable : removable });
gradelist.append(newBar);
contenteditable: true,
removable : removable})
);
if (draggable) {
newBar = gradelist.children().last(); // get the dom object not the unparsed string
var newBar = gradelist.children().last(); // get the dom object not the unparsed string
newBar.resizable({
handles: "e",
containment : "parent",
......@@ -174,19 +180,18 @@ var GradingView = ValidatingView.extend({
});
}
// prepare for next
nextWidth = cutoff['cutoff'];
nextWidth = cutoff.cutoff;
removable = true; // first is not removable, all others are
draggable = true;
},
this);
// add fail which is not in data
var failBar = $(this.gradeCutoffTemplate({
// Add fail which is not in data
HtmlUtils.append(gradelist, this.gradeCutoffTemplate({
descriptor : this.failLabel(),
width : nextWidth,
contenteditable: false,
removable : false
}));
failBar.find("span[contenteditable=true]").attr("contenteditable", false);
gradelist.append(failBar);
gradelist.children().last().resizable({
handles: "e",
containment : "parent",
......@@ -298,10 +303,13 @@ var GradingView = ValidatingView.extend({
this.descendingCutoffs.push({designation: this.GRADES[gradeLength], cutoff: failBarWidth});
this.descendingCutoffs[gradeLength - 1]['cutoff'] = Math.round(targetWidth);
var $newGradeBar = this.gradeCutoffTemplate({ descriptor : this.GRADES[gradeLength],
width : targetWidth, removable : true });
var newGradeHtml = this.gradeCutoffTemplate({
descriptor : this.GRADES[gradeLength],
width : targetWidth,
contenteditable: true,
removable : true });
var gradeDom = this.$el.find('.grades');
gradeDom.children().last().before($newGradeBar);
gradeDom.children().last().before(HtmlUtils.ensureHtml(newGradeHtml).toString());
var newEle = gradeDom.children()[gradeLength];
$(newEle).resizable({
handles: "e",
......@@ -313,8 +321,8 @@ var GradingView = ValidatingView.extend({
// Munge existing grade labels?
// If going from Pass/Fail to 3 levels, change to Pass to A
if (gradeLength === 1 && this.descendingCutoffs[0]['designation'] === 'Pass') {
this.descendingCutoffs[0]['designation'] = this.GRADES[0];
if (gradeLength === 1 && this.descendingCutoffs[0].designation === 'Pass') {
this.descendingCutoffs[0].designation = this.GRADES[0];
this.setTopGradeLabel();
}
this.setFailLabel();
......@@ -349,10 +357,10 @@ var GradingView = ValidatingView.extend({
else return 'F';
},
setFailLabel: function() {
this.$el.find('.grades .letter-grade').last().html(this.failLabel());
this.$el.find('.grades .letter-grade').last().text(this.failLabel());
},
setTopGradeLabel: function() {
this.$el.find('.grades .letter-grade').first().html(this.descendingCutoffs[0]['designation']);
this.$el.find('.grades .letter-grade').first().text(this.descendingCutoffs[0].designation);
},
setupCutoffs: function() {
// Instrument grading scale
......
define(["js/views/validation", "codemirror", "underscore", "jquery", "jquery.ui", "js/utils/date_utils", "js/models/uploads",
"js/views/uploads", "js/views/license", "js/models/license",
"common/js/components/views/feedback_notification", "jquery.timepicker", "date", "gettext"],
"common/js/components/views/feedback_notification", "jquery.timepicker", "date", "gettext",
'edx-ui-toolkit/js/utils/string-utils'],
function(ValidatingView, CodeMirror, _, $, ui, DateUtils, FileUploadModel,
FileUploadDialog, LicenseView, LicenseModel, NotificationView,
timepicker, date, gettext) {
timepicker, date, gettext, StringUtils) {
var DetailsView = ValidatingView.extend({
// Model class is CMS.Models.Settings.CourseDetails
......@@ -25,7 +26,6 @@ var DetailsView = ValidatingView.extend({
initialize : function(options) {
options = options || {};
this.fileAnchorTemplate = _.template('<a href="<%= fullpath %>"> <i class="icon fa fa-file"></i><%= filename %></a>');
// fill in fields
this.$el.find("#course-language").val(this.model.get('language'));
this.$el.find("#course-organization").val(this.model.get('org'));
......@@ -115,7 +115,7 @@ var DetailsView = ValidatingView.extend({
paceToggleTip.text(gettext('Course pacing cannot be changed once a course has started.'));
}
this.licenseView.render()
this.licenseView.render();
return this;
},
......@@ -139,14 +139,16 @@ var DetailsView = ValidatingView.extend({
var now = new Date(),
hours = now.getUTCHours(),
minutes = now.getUTCMinutes(),
currentTimeText = gettext('%(hours)s:%(minutes)s (current UTC time)');
currentTimeText = StringUtils.interpolate(
gettext('{hours}:{minutes} (current UTC time)'),
{
'hours': hours,
'minutes': minutes
}
);
$(e.currentTarget).attr('title', interpolate(currentTimeText, {
'hours': hours,
'minutes': minutes
}, true));
$(e.currentTarget).attr('title', currentTimeText);
},
updateModel: function(event) {
switch (event.currentTarget.id) {
case 'course-language':
......@@ -322,8 +324,8 @@ var DetailsView = ValidatingView.extend({
},
handleLicenseChange: function() {
this.showNotificationBar()
this.model.set("license", this.licenseModel.toString())
this.showNotificationBar();
this.model.set("license", this.licenseModel.toString());
}
});
......
define(["js/views/baseview", "underscore", "jquery", "gettext", "common/js/components/views/feedback_notification", "common/js/components/views/feedback_alert", "js/views/baseview", "jquery.smoothScroll"],
function(BaseView, _, $, gettext, NotificationView, AlertView) {
define(["edx-ui-toolkit/js/utils/html-utils",
"js/views/baseview",
"underscore",
"jquery",
"gettext",
"common/js/components/views/feedback_notification",
"common/js/components/views/feedback_alert",
"js/views/baseview",
"jquery.smoothScroll"],
function(HtmlUtils, BaseView, _, $, gettext, NotificationView, AlertView) {
var ValidatingView = BaseView.extend({
// Intended as an abstract class which catches validation errors on the model and
......@@ -10,7 +18,7 @@ var ValidatingView = BaseView.extend({
this.selectorToField = _.invert(this.fieldToSelectorMap);
},
errorTemplate : _.template('<span class="message-error"><%= message %></span>'),
errorTemplate : HtmlUtils.template('<span class="message-error"><%- message %></span>'),
save_title: gettext("You've made some changes"),
save_message: gettext("Your changes will not take effect until you save your progress."),
......@@ -34,7 +42,7 @@ var ValidatingView = BaseView.extend({
var ele = this.$el.find('#' + this.fieldToSelectorMap[field]);
this._cacheValidationErrors.push(ele);
this.getInputElements(ele).addClass('error');
$(ele).parent().append(this.errorTemplate({message : error[field]}));
HtmlUtils.append($(ele).parent(), this.errorTemplate({message : error[field]}));
}
$('.wrapper-notification-warning').addClass('wrapper-notification-warning-w-errors');
$('.action-save').addClass('is-disabled');
......@@ -60,7 +68,7 @@ var ValidatingView = BaseView.extend({
// Set model field and return the new value.
this.clearValidationErrors();
var field = this.selectorToField[event.currentTarget.id];
var newVal = ''
var newVal = '';
if(event.currentTarget.type == 'checkbox'){
newVal = $(event.currentTarget).is(":checked").toString();
}else{
......
<li class="grade-specific-bar" style="width:<%- width %>%">
<span class="letter-grade" contenteditable="<%- contenteditable %>"><%- descriptor %></span>
<span class="range"></span>
<% if (removable) {%><a href="#" class="remove-button">remove</a><% ;} %>
</li>
......@@ -15,7 +15,7 @@
%>
<%block name="header_extras">
% for template_name in ["course_grade_policy"]:
% for template_name in ["course_grade_policy", "course_grade_cutoff"]:
<script type="text/template" id="${template_name}-tpl">
<%static:include path="js/${template_name}.underscore" />
</script>
......
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