diff --git a/common/lib/xmodule/xmodule/assets/split_test/public/js/split_test_staff.js b/common/lib/xmodule/xmodule/assets/split_test/public/js/split_test_staff.js index 5dc4035b73..16e9c3d2bb 100644 --- a/common/lib/xmodule/xmodule/assets/split_test/public/js/split_test_staff.js +++ b/common/lib/xmodule/xmodule/assets/split_test/public/js/split_test_staff.js @@ -13,7 +13,7 @@ window.ABTestSelector = function(runtime, elem) { // force this id to remain a string, even if it looks like something else var child_group_id = $(this).data('group-id').toString(); if (child_group_id === group_id) { - _this.content_container.html($(this).text()); + _this.content_container.html(edx.HtmlUtils.HTML($(this).text()).toString()); XBlock.initializeBlocks(_this.content_container, $(elem).data('request-token')); } }); diff --git a/common/static/common/js/discussion/views/new_post_view.js b/common/static/common/js/discussion/views/new_post_view.js index db9a886de5..cfa603355c 100644 --- a/common/static/common/js/discussion/views/new_post_view.js +++ b/common/static/common/js/discussion/views/new_post_view.js @@ -59,8 +59,11 @@ startHeader: this.startHeader, form_id: this.mode + (this.topicId ? '-' + this.topicId : '') }); - this.$el.html(_.template($('#new-post-template').html())(context)); - threadTypeTemplate = _.template($('#thread-type-template').html()); + edx.HtmlUtils.setHtml( + this.$el, + edx.HtmlUtils.template($('#new-post-template').html())(context) + ); + threadTypeTemplate = edx.HtmlUtils.template($('#thread-type-template').html()); if ($('.js-group-select').prop('disabled')) { $('.group-selector-wrapper').addClass('disabled'); } @@ -77,7 +80,7 @@ if (this.course_settings.get('is_discussion_division_enabled')) { this.topicView.on('thread:topic_change', this.updateVisibilityMessage); } - this.addField(this.topicView.render()); + this.addField(edx.HtmlUtils.HTML(this.topicView.render())); } else { this.group_name = this.getGroupName(); this.updateVisibilityMessage(null, this.is_commentable_divided); @@ -86,7 +89,10 @@ }; NewPostView.prototype.addField = function(fieldView) { - return this.$('.forum-new-post-form-wrapper').append(fieldView); + return edx.HtmlUtils.append( + this.$('.forum-new-post-form-wrapper'), + fieldView + ); }; NewPostView.prototype.isTabMode = function() { diff --git a/common/static/common/js/discussion/views/response_comment_edit_view.js b/common/static/common/js/discussion/views/response_comment_edit_view.js index 34cfa4153a..c2cafdfc7e 100644 --- a/common/static/common/js/discussion/views/response_comment_edit_view.js +++ b/common/static/common/js/discussion/views/response_comment_edit_view.js @@ -43,8 +43,11 @@ ResponseCommentEditView.prototype.render = function() { var context = $.extend({mode: this.options.mode, startHeader: this.options.startHeader}, this.model.attributes); - this.template = _.template($('#response-comment-edit-template').html()); - this.$el.html(this.template(context)); + this.template = edx.HtmlUtils.template($('#response-comment-edit-template').html()); + edx.HtmlUtils.setHtml( + this.$el, + this.template(context) + ); this.delegateEvents(); DiscussionUtil.makeWmdEditor(this.$el, $.proxy(this.$, this), 'edit-comment-body'); return this; diff --git a/common/static/common/js/discussion/views/thread_response_edit_view.js b/common/static/common/js/discussion/views/thread_response_edit_view.js index 13da03e001..d30e5dcc13 100644 --- a/common/static/common/js/discussion/views/thread_response_edit_view.js +++ b/common/static/common/js/discussion/views/thread_response_edit_view.js @@ -43,8 +43,11 @@ ThreadResponseEditView.prototype.render = function() { var context = $.extend({mode: this.options.mode, startHeader: this.options.startHeader}, this.model.attributes); - this.template = _.template($('#thread-response-edit-template').html()); - this.$el.html(this.template(context)); + this.template = edx.HtmlUtils.template($('#thread-response-edit-template').html()); + edx.HtmlUtils.setHtml( + this.$el, + this.template(context) + ); this.delegateEvents(); DiscussionUtil.makeWmdEditor(this.$el, $.proxy(this.$, this), 'edit-post-body'); return this; diff --git a/common/templates/admin/student/loginfailures/change_form_template.html b/common/templates/admin/student/loginfailures/change_form_template.html index ce3b4766c2..73cc3ee9cd 100644 --- a/common/templates/admin/student/loginfailures/change_form_template.html +++ b/common/templates/admin/student/loginfailures/change_form_template.html @@ -4,13 +4,13 @@
{% if original.lockout_until %} {% endif %} - {% trans 'Close' %} + {% trans 'Close' as tmsg %}{{tmsg|force_escape}}
{% endblock %} @@ -19,14 +19,14 @@ {% if original.lockout_until %} {% endif %} - {% trans 'Close' %} + {% trans 'Close' as tmsg %}{{tmsg|force_escape}} {% endblock %} diff --git a/lms/djangoapps/support/static/support/js/views/enrollment.js b/lms/djangoapps/support/static/support/js/views/enrollment.js index 205332b612..02e5b17552 100644 --- a/lms/djangoapps/support/static/support/js/views/enrollment.js +++ b/lms/djangoapps/support/static/support/js/views/enrollment.js @@ -7,8 +7,9 @@ 'moment', 'support/js/views/enrollment_modal', 'support/js/collections/enrollment', - 'text!support/templates/enrollment.underscore' - ], function(Backbone, _, moment, EnrollmentModal, EnrollmentCollection, enrollmentTemplate) { + 'text!support/templates/enrollment.underscore', + 'edx-ui-toolkit/js/utils/html-utils' + ], function(Backbone, _, moment, EnrollmentModal, EnrollmentCollection, enrollmentTemplate, HtmlUtils) { return Backbone.View.extend({ ENROLLMENT_CHANGE_REASONS: { @@ -35,14 +36,16 @@ render: function() { var user = this.enrollments.user; - this.$el.html(_.template(enrollmentTemplate)({ - user: user, - enrollments: this.enrollments, - formatDate: function(date) { - return date ? moment.utc(date).format('lll z') : 'N/A'; - } - })); - + HtmlUtils.setHtml( + this.$el, + HtmlUtils.template(enrollmentTemplate)({ + user: user, + enrollments: this.enrollments, + formatDate: function(date) { + return date ? moment.utc(date).format('lll z') : 'N/A'; + } + }) + ); this.checkInitialSearch(); return this; }, diff --git a/lms/static/js/certificates/views/certificate_whitelist_editor.js b/lms/static/js/certificates/views/certificate_whitelist_editor.js index 24ca758919..fcd226f320 100644 --- a/lms/static/js/certificates/views/certificate_whitelist_editor.js +++ b/lms/static/js/certificates/views/certificate_whitelist_editor.js @@ -8,9 +8,10 @@ 'underscore', 'gettext', 'backbone', - 'js/certificates/models/certificate_exception' + 'js/certificates/models/certificate_exception', + 'edx-ui-toolkit/js/utils/html-utils' ], - function($, _, gettext, Backbone, CertificateExceptionModel) { + function($, _, gettext, Backbone, CertificateExceptionModel, HtmlUtils) { return Backbone.View.extend({ el: '#certificate-white-list-editor', message_div: '.message', @@ -21,7 +22,7 @@ render: function() { var template = this.loadTemplate('certificate-white-list-editor'); - this.$el.html(template()); + this.$el.html(HtmlUtils.HTML(template()).toString()); }, loadTemplate: function(name) { @@ -59,12 +60,12 @@ var message = ''; if (this.collection.findWhere(model)) { - message = gettext('<%= user %> already in exception list.'); + message = gettext('<%- user %> already in exception list.'); this.escapeAndShowMessage( _.template(message)({user: (user_name || user_email)}) ); } else if (certificate_exception.isValid()) { - message = gettext('<%= user %> has been successfully added to the exception list. Click Generate Exception Certificate below to send the certificate.'); // eslint-disable-line max-len + message = gettext('<%- user %> has been successfully added to the exception list. Click Generate Exception Certificate below to send the certificate.'); // eslint-disable-line max-len certificate_exception.save( null, { @@ -88,7 +89,8 @@ escapeAndShowMessage: function(message) { $(this.message_div + '>p').remove(); - this.$(this.message_div).removeClass('hidden').append('

' + _.escape(message) + '

'); + // eslint-disable-next-line max-len + this.$(this.message_div).removeClass('hidden').append(HtmlUtils.joinHtml(HtmlUtils.HTML('

'), message, HtmlUtils.HTML('

')).toString()); }, showSuccess: function(caller, add_model, message) { diff --git a/lms/static/js/edxnotes/views/shim.js b/lms/static/js/edxnotes/views/shim.js index 942731af9c..453247039d 100644 --- a/lms/static/js/edxnotes/views/shim.js +++ b/lms/static/js/edxnotes/views/shim.js @@ -1,8 +1,8 @@ (function(define, undefined) { 'use strict'; define([ - 'jquery', 'underscore', 'annotator_1.2.9', 'js/edxnotes/utils/utils' - ], function($, _, Annotator, Utils) { + 'jquery', 'underscore', 'annotator_1.2.9', 'js/edxnotes/utils/utils', 'edx-ui-toolkit/js/utils/html-utils' + ], function($, _, Annotator, Utils, HtmlUtils) { var _t = Annotator._t; /** @@ -48,9 +48,15 @@ // It depends on the number of annotatable components on the page. var tagsField = $('li.annotator-item >input', this.annotator.editor.element).attr('id'); if ($("label.sr[for='" + tagsField + "']", this.annotator.editor.element).length === 0) { - $('').insertBefore( - $('#' + tagsField, this.annotator.editor.element) - ); + HtmlUtils.prepend( + $('#' + tagsField, this.annotator.editor.element), + $(HtmlUtils.joinHtml( + HtmlUtils.HTML('') + ))); } return this; }, @@ -159,14 +165,15 @@ .addField({ load: function(field, annotation) { if (annotation.text) { - $(field).html(Utils.nl2br(Annotator.Util.escape(annotation.text))); + $(field).html(HtmlUtils.HTML(Utils.nl2br(annotation.text)).toString()); } else { - $(field).html('' + _t('No Comment') + ''); + // eslint-disable-next-line max-len + $(field).html(HtmlUtils.joinHtml(HtmlUtils.HTML(''), _t('No Comment'), HtmlUtils.HTML('')).toString()); } return self.publish('annotationViewerTextField', [field, annotation]); } }) - .element.appendTo(this.wrapper).bind({ + .element.appendTo(this.wrapper).bind({ // xss-lint: disable=javascript-jquery-insert-into-target mouseover: this.clearViewerHideTimer, mouseout: this.startViewerHideTimer }); @@ -210,9 +217,15 @@ // It depends on the number of annotatable components on the page. var noteField = $('li.annotator-item >textarea', this.element).attr('id'); if ($("label.sr[for='" + noteField + "']", this.element).length === 0) { - $('').insertBefore( - $('#' + noteField, this.element) - ); + HtmlUtils.prepend( + $('#' + noteField, this.element), + $(HtmlUtils.joinHtml( + HtmlUtils.HTML('') + ))); } if (event.type === 'keydown') { @@ -234,6 +247,7 @@ * Modifies Annotator.onHighlightMouseover to avoid showing the viewer if the * editor is opened. **/ + // xss-lint: disable=javascript-jquery-insertion Annotator.prototype.onHighlightMouseover = _.wrap( Annotator.prototype.onHighlightMouseover, function(func, event) { diff --git a/lms/static/js/edxnotes/views/tabs/search_results.js b/lms/static/js/edxnotes/views/tabs/search_results.js index b680047c79..b08fc55931 100644 --- a/lms/static/js/edxnotes/views/tabs/search_results.js +++ b/lms/static/js/edxnotes/views/tabs/search_results.js @@ -2,8 +2,8 @@ 'use strict'; define([ 'jquery', 'underscore', 'gettext', 'js/edxnotes/views/tab_panel', 'js/edxnotes/views/tab_view', - 'js/edxnotes/views/search_box' - ], function($, _, gettext, TabPanelView, TabView, SearchBoxView) { + 'js/edxnotes/views/search_box', 'edx-ui-toolkit/js/utils/html-utils', 'edx-ui-toolkit/js/utils/string-utils' + ], function($, _, gettext, TabPanelView, TabView, SearchBoxView, HtmlUtils, StringUtils) { var view = 'Search Results'; var SearchResultsView = TabView.extend({ PanelConstructor: TabPanelView.extend({ @@ -16,7 +16,7 @@ ].join(' '); }, renderContent: function() { - this.$el.append(this.getNotes(this.collection.toArray())); + this.$el.append(HtmlUtils.HTML(this.getNotes(this.collection.toArray())).toString()); return this; } }), @@ -31,10 +31,10 @@ ].join(' '); }, renderContent: function() { - var message = gettext('No results found for "%(query_string)s". Please try searching again.'); + var message = gettext('No results found for "{query_string}". Please try searching again.'); this.$el.append($('

', { - text: interpolate(message, { + text: StringUtils.interpolate(message, { query_string: this.options.searchQuery }, true) })); diff --git a/lms/static/js/financial-assistance/views/financial_assistance_form_view.js b/lms/static/js/financial-assistance/views/financial_assistance_form_view.js index 444b3cc24a..bcd80d508e 100644 --- a/lms/static/js/financial-assistance/views/financial_assistance_form_view.js +++ b/lms/static/js/financial-assistance/views/financial_assistance_form_view.js @@ -10,6 +10,7 @@ 'text!../../../templates/financial-assistance/financial_assessment_form.underscore', 'text!../../../templates/financial-assistance/financial_assessment_submitted.underscore', 'text!templates/student_account/form_field.underscore', + 'edx-ui-toolkit/js/utils/html-utils', 'string_utils' ], function( @@ -21,7 +22,8 @@ FormView, formViewTpl, successTpl, - formFieldTpl + formFieldTpl, + HtmlUtils ) { return FormView.extend({ el: '.financial-assistance-wrapper', @@ -74,7 +76,7 @@ fields: html || '' }); - this.$el.html(_.template(this.tpl)(data)); + HtmlUtils.setHtml(this.$el, HtmlUtils.template(this.tpl)(data)); this.postRender(); this.validateCountry(); @@ -83,7 +85,7 @@ }, renderSuccess: function() { - this.$el.html(_.template(this.successTpl)({ + HtmlUtils.setHtml(this.$el, HtmlUtils.template(this.successTpl)({ course: this.model.get('course'), dashboard_url: this.context.dashboard_url })); @@ -103,7 +105,9 @@ msg = gettext('An error has occurred. Check your Internet connection and try again.'); } - this.errors = ['

  • ' + msg + '
  • ']; + this.errors = [HtmlUtils.joinHtml( + HtmlUtils.HTML('
  • '), msg, HtmlUtils.HTML('
  • ') + ).toString()]; this.renderErrors(this.defaultFormErrorsTitle, this.errors); this.toggleDisableButton(false); }, @@ -122,14 +126,22 @@ // Translators: link_start and link_end denote the html to link back to the profile page. gettext(txt.join('')), { - link_start: '', + link_start: HtmlUtils.joinHtml( + HtmlUtils.HTML('') + ).toString(), link_end: '' } ); if (!this.model.get('country')) { $countryLabel.addClass('error'); - this.renderErrors(this.defaultFormErrorsTitle, ['
  • ' + msg + '
  • ']); + this.renderErrors(this.defaultFormErrorsTitle, [HtmlUtils.joinHtml( + HtmlUtils.HTML('
  • '), + msg, + HtmlUtils.HTML('
  • ') + ).toString()]); this.toggleDisableButton(true); } }, diff --git a/lms/static/js/groups/views/cohort_editor.js b/lms/static/js/groups/views/cohort_editor.js index 33a0c15b51..feb4513281 100644 --- a/lms/static/js/groups/views/cohort_editor.js +++ b/lms/static/js/groups/views/cohort_editor.js @@ -1,9 +1,9 @@ /* globals _, NotificationModel, NotificationView, interpolate_text */ (function(define) { 'use strict'; - define(['backbone', 'underscore', 'jquery', 'gettext', 'js/groups/views/cohort_form', 'string_utils', - 'js/models/notification', 'js/views/notification'], - function(Backbone, _, $, gettext, CohortFormView) { + define(['backbone', 'underscore', 'jquery', 'gettext', 'js/groups/views/cohort_form', + 'edx-ui-toolkit/js/utils/html-utils', 'string_utils', 'js/models/notification', 'js/views/notification'], + function(Backbone, _, $, gettext, CohortFormView, HtmlUtils) { var CohortEditorView = Backbone.View.extend({ events: { @@ -14,8 +14,8 @@ }, initialize: function(options) { - this.template = _.template($('#cohort-editor-tpl').text()); - this.groupHeaderTemplate = _.template($('#cohort-group-header-tpl').text()); + this.template = HtmlUtils.template($('#cohort-editor-tpl').text()); + this.groupHeaderTemplate = HtmlUtils.template($('#cohort-group-header-tpl').text()); this.cohorts = options.cohorts; this.contentGroups = options.contentGroups; this.context = options.context; @@ -29,7 +29,7 @@ preassignedNotifications: null, render: function() { - this.$el.html(this.template({ + HtmlUtils.setHtml(this.$el, this.template({ cohort: this.model })); this.renderGroupHeader(); @@ -44,7 +44,7 @@ }, renderGroupHeader: function() { - this.$('.cohort-management-group-header').html(this.groupHeaderTemplate({ + HtmlUtils.setHtml(this.$('.cohort-management-group-header'), this.groupHeaderTemplate({ cohort: this.model })); },