diff --git a/lms/djangoapps/support/static/support/js/views/certificates.js b/lms/djangoapps/support/static/support/js/views/certificates.js index a704eab79f..310f1eb357 100644 --- a/lms/djangoapps/support/static/support/js/views/certificates.js +++ b/lms/djangoapps/support/static/support/js/views/certificates.js @@ -7,8 +7,9 @@ 'gettext', 'support/js/collections/certificate', 'text!support/templates/certificates.underscore', - 'text!support/templates/certificates_results.underscore' - ], function(Backbone, _, gettext, CertCollection, certificatesTpl, resultsTpl) { + 'text!support/templates/certificates_results.underscore', + 'edx-ui-toolkit/js/utils/html-utils' + ], function(Backbone, _, gettext, CertCollection, certificatesTpl, resultsTpl, HtmlUtils) { return Backbone.View.extend({ events: { 'submit .certificates-form': 'search', @@ -24,7 +25,7 @@ }, render: function() { - this.$el.html(_.template(certificatesTpl)); + this.$el.html(HtmlUtils.HTML(_.template(certificatesTpl)).toString()); // If there is an initial filter, then immediately trigger a search. // This is useful because it allows users to share search results: @@ -44,12 +45,12 @@ certificates: this.certificates }; - this.setResults(_.template(resultsTpl)(context)); + this.setResults(HtmlUtils.template(resultsTpl)(context)); }, renderError: function(error) { var errorMsg = error || gettext('An unexpected error occurred. Please try again.'); - this.setResults(errorMsg); + this.setResults(HtmlUtils.Text(errorMsg)); }, search: function(event) { @@ -170,7 +171,10 @@ }, setResults: function(html) { - $('.certificates-results', this.$el).html(html); + HtmlUtils.setHtml( + $('.certificates-results', this.$el), + html + ); }, disableButtons: function() { diff --git a/lms/static/js/certificates/views/certificate_whitelist.js b/lms/static/js/certificates/views/certificate_whitelist.js index d39a9b55b5..06d5114689 100644 --- a/lms/static/js/certificates/views/certificate_whitelist.js +++ b/lms/static/js/certificates/views/certificate_whitelist.js @@ -8,10 +8,11 @@ 'jquery', 'underscore', 'gettext', - 'backbone' + 'backbone', + 'edx-ui-toolkit/js/utils/html-utils' ], - function($, _, gettext, Backbone) { + function($, _, gettext, Backbone, HtmlUtils) { return Backbone.View.extend({ el: '#white-listed-students', message_div: 'div.white-listed-students > div.message', @@ -32,7 +33,7 @@ render: function() { var template = this.loadTemplate('certificate-white-list'); - this.$el.html(template({certificates: this.collection.models})); + this.$el.html(HtmlUtils.HTML(template({certificates: this.collection.models})).toString()); if (!this.active_certificate || this.collection.isEmpty()) { this.$('#generate-exception-certificates').attr('disabled', 'disabled'); } else { @@ -79,7 +80,13 @@ escapeAndShowMessage: function(message) { $(this.message_div + '>p').remove(); - $(this.message_div).removeClass('hidden').append('

' + _.escape(message) + '

').focus(); + // xss-lint: disable=javascript-jquery-append + $(this.message_div).removeClass('hidden').append(HtmlUtils.joinHtml( + HtmlUtils.HTML('

'), + _.escape(message), + HtmlUtils.HTML('

') + )) + .focus(); $(this.message_div).fadeOut(6000, 'linear'); }, diff --git a/lms/static/js/courseware/certificates_api.js b/lms/static/js/courseware/certificates_api.js index 839010e5fd..2877410c9d 100644 --- a/lms/static/js/courseware/certificates_api.js +++ b/lms/static/js/courseware/certificates_api.js @@ -13,7 +13,7 @@ $(document).ready(function() { location.reload(); }, error: function(jqXHR, textStatus, errorThrown) { - $('#errors-info').html(jqXHR.responseText); + $('#errors-info').text(jqXHR.responseText); $('.generate_certs').attr('disabled', false).removeClass('is-disabled').attr('aria-disabled', false); } }); diff --git a/lms/static/js/discovery/views/course_card.js b/lms/static/js/discovery/views/course_card.js index de709c6c4f..aa1102a4fa 100644 --- a/lms/static/js/discovery/views/course_card.js +++ b/lms/static/js/discovery/views/course_card.js @@ -4,8 +4,9 @@ 'underscore', 'backbone', 'gettext', - 'edx-ui-toolkit/js/utils/date-utils' - ], function($, _, Backbone, gettext, DateUtils) { + 'edx-ui-toolkit/js/utils/date-utils', + 'edx-ui-toolkit/js/utils/html-utils' + ], function($, _, Backbone, gettext, DateUtils, HtmlUtils) { 'use strict'; function formatDate(date, userLanguage, userTimezone) { @@ -26,7 +27,7 @@ className: 'courses-listing-item', initialize: function() { - this.tpl = _.template($(this.templateId).html()); + this.tpl = HtmlUtils.template($(this.templateId).html()); }, render: function() { @@ -51,7 +52,10 @@ userLanguage, userTimezone ); - this.$el.html(this.tpl(data)); + HtmlUtils.setHtml( + this.$el, + this.tpl(data) + ); return this; } diff --git a/lms/static/js/discovery/views/facet.js b/lms/static/js/discovery/views/facet.js index c4ef2b6fff..453cb4b57e 100644 --- a/lms/static/js/discovery/views/facet.js +++ b/lms/static/js/discovery/views/facet.js @@ -3,8 +3,9 @@ 'jquery', 'underscore', 'backbone', - 'gettext' - ], function($, _, Backbone, gettext) { + 'gettext', + 'edx-ui-toolkit/js/utils/html-utils' + ], function($, _, Backbone, gettext, HtmlUtils) { 'use strict'; return Backbone.View.extend({ @@ -14,11 +15,14 @@ className: '', initialize: function() { - this.tpl = _.template($(this.templateId).html()); + this.tpl = HtmlUtils.template($(this.templateId).html()); }, render: function(type, name, term, count) { - this.$el.html(this.tpl({name: name, term: term, count: count})); + HtmlUtils.setHtml( + this.$el, + this.tpl({name: name, term: term, count: count}) + ); this.$el.attr('data-facet', type); return this; }, diff --git a/lms/static/js/edxnotes/views/note_group.js b/lms/static/js/edxnotes/views/note_group.js index 137836ee9a..15acd28193 100644 --- a/lms/static/js/edxnotes/views/note_group.js +++ b/lms/static/js/edxnotes/views/note_group.js @@ -1,8 +1,8 @@ (function(define, undefined) { 'use strict'; define([ - 'gettext', 'underscore', 'backbone' - ], function(gettext, _, Backbone) { + 'gettext', 'underscore', 'backbone', 'edx-ui-toolkit/js/utils/html-utils' + ], function(gettext, _, Backbone, HtmlUtils) { var GroupView, ChapterView; GroupView = Backbone.View.extend({ @@ -13,12 +13,12 @@ initialize: function(options) { this.options = _.extend({}, options); - this.template = _.template(this.options.template); + this.template = HtmlUtils.template(this.options.template); this.className = this.options.className; }, render: function() { - this.$el.prepend(this.template({ + HtmlUtils.prepend(this.$el, this.template({ displayName: this.options.displayName })); @@ -26,7 +26,7 @@ }, addChild: function(child) { - this.$el.append(child); + this.$el.append(HtmlUtils.HTML(child).toString()); } }); @@ -36,7 +36,7 @@ id: function() { return 'note-group-' + _.uniqueId(); }, - template: _.template('

<%- chapterName %>

'), + template: HtmlUtils.template('

<%- chapterName %>

'), initialize: function(options) { this.children = []; @@ -45,13 +45,11 @@ render: function() { var container = document.createDocumentFragment(); - this.$el.html(this.template({ - chapterName: this.options.chapter.display_name || '' - })); + HtmlUtils.setHtml(this.$el, this.template({chapterName: this.options.chapter.display_name || ''})); _.each(this.children, function(section) { container.appendChild(section.render().el); }); - this.$el.append(container); + this.$el.append(HtmlUtils.HTML(container).toString()); return this; }, diff --git a/lms/static/js/edxnotes/views/note_item.js b/lms/static/js/edxnotes/views/note_item.js index 10e9761aff..d6d457090a 100644 --- a/lms/static/js/edxnotes/views/note_item.js +++ b/lms/static/js/edxnotes/views/note_item.js @@ -2,8 +2,8 @@ 'use strict'; define([ 'jquery', 'underscore', 'backbone', 'js/edxnotes/utils/template', - 'js/edxnotes/utils/logger' - ], function($, _, Backbone, templateUtils, NotesLogger) { + 'js/edxnotes/utils/logger', 'edx-ui-toolkit/js/utils/html-utils' + ], function($, _, Backbone, templateUtils, NotesLogger, HtmlUtils) { var NoteItemView = Backbone.View.extend({ tagName: 'article', className: 'note', @@ -25,8 +25,7 @@ render: function() { var context = this.getContext(); - this.$el.html(this.template(context)); - + this.$el.html(HtmlUtils.HTML(this.template(context)).toString()); return this; }, diff --git a/lms/static/js/edxnotes/views/tabs/course_structure.js b/lms/static/js/edxnotes/views/tabs/course_structure.js index e26f30fcf7..39b07a4050 100644 --- a/lms/static/js/edxnotes/views/tabs/course_structure.js +++ b/lms/static/js/edxnotes/views/tabs/course_structure.js @@ -2,8 +2,8 @@ 'use strict'; define([ 'gettext', 'underscore', 'js/edxnotes/views/note_group', 'js/edxnotes/views/tab_panel', - 'js/edxnotes/views/tab_view' - ], function(gettext, _, NoteGroupView, TabPanelView, TabView) { + 'js/edxnotes/views/tab_view', 'edx-ui-toolkit/js/utils/html-utils' + ], function(gettext, _, NoteGroupView, TabPanelView, TabView, HtmlUtils) { var view = 'Location in Course'; var CourseStructureView = TabView.extend({ PanelConstructor: TabPanelView.extend({ @@ -31,7 +31,7 @@ }, this); container.appendChild(chapterView.render().el); }, this); - this.$el.append(container); + this.$el.append(HtmlUtils.HTML(container).toString()); return this; }, diff --git a/lms/static/js/edxnotes/views/tabs/recent_activity.js b/lms/static/js/edxnotes/views/tabs/recent_activity.js index a82827f711..0c5712bd8d 100644 --- a/lms/static/js/edxnotes/views/tabs/recent_activity.js +++ b/lms/static/js/edxnotes/views/tabs/recent_activity.js @@ -1,8 +1,11 @@ (function(define, undefined) { 'use strict'; define([ - 'gettext', 'js/edxnotes/views/tab_panel', 'js/edxnotes/views/tab_view' - ], function(gettext, TabPanelView, TabView) { + 'gettext', + 'js/edxnotes/views/tab_panel', + 'js/edxnotes/views/tab_view', + 'edx-ui-toolkit/js/utils/html-utils' + ], function(gettext, TabPanelView, TabView, HtmlUtils) { var view = 'Recent Activity'; var RecentActivityView = TabView.extend({ PanelConstructor: TabPanelView.extend({ @@ -15,7 +18,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; } }), diff --git a/lms/static/js/groups/views/course_cohort_settings_notification.js b/lms/static/js/groups/views/course_cohort_settings_notification.js index 5d5aaa1f8d..d38380e1b9 100644 --- a/lms/static/js/groups/views/course_cohort_settings_notification.js +++ b/lms/static/js/groups/views/course_cohort_settings_notification.js @@ -1,14 +1,23 @@ (function(define) { 'use strict'; - define(['jquery', 'underscore', 'backbone', 'gettext'], function($, _, Backbone, gettext) { + define([ + 'jquery', + 'underscore', + 'backbone', + 'gettext', + 'edx-ui-toolkit/js/utils/html-utils' + ], function($, _, Backbone, gettext, HtmlUtils) { var CourseCohortSettingsNotificationView = Backbone.View.extend({ initialize: function(options) { - this.template = _.template($('#cohort-state-tpl').text()); + this.template = HtmlUtils.template($('#cohort-state-tpl').text()); this.cohortEnabled = options.cohortEnabled; }, render: function() { - this.$el.html(this.template({})); + HtmlUtils.setHtml( + this.$el, + this.template({}) + ); this.showCohortStateMessage(); return this; }, diff --git a/lms/static/js/student_account/views/account_section_view.js b/lms/static/js/student_account/views/account_section_view.js index 6c1b00a16c..5480e1511f 100644 --- a/lms/static/js/student_account/views/account_section_view.js +++ b/lms/static/js/student_account/views/account_section_view.js @@ -16,12 +16,15 @@ }, render: function() { - this.$el.html(_.template(sectionTemplate)({ - HtmlUtils: HtmlUtils, - sections: this.options.sections, - tabName: this.options.tabName, - tabLabel: this.options.tabLabel - })); + HtmlUtils.setHtml( + this.$el, + HtmlUtils.template(sectionTemplate)({ + HtmlUtils: HtmlUtils, + sections: this.options.sections, + tabName: this.options.tabName, + tabLabel: this.options.tabLabel + }) + ); this.renderFields(); }, diff --git a/lms/static/js/verify_student/views/error_view.js b/lms/static/js/verify_student/views/error_view.js index 67b1c8d954..611464d074 100644 --- a/lms/static/js/verify_student/views/error_view.js +++ b/lms/static/js/verify_student/views/error_view.js @@ -21,14 +21,16 @@ }, render: function() { - var renderedHtml = _.template($('#error-tpl').html())( + var renderedHtml = edx.HtmlUtils.template($('#error-tpl').html())( { errorTitle: this.model.get('errorTitle'), errorMsg: this.model.get('errorMsg') } ); - - $(this.el).html(renderedHtml); + edx.HtmlUtils.setHtml( + $(this.el), + renderedHtml + ); if (this.model.get('shown')) { $(this.el).show();