. The element
# passed to the constructor should be the
.
-define ['jquery', 'i18n!paginated_list', 'vendor/spin'], ($, I18n, Spinner) ->
+define ['jquery', 'i18n!paginated_list', 'vendor/spin', 'str/htmlEscape'], ($, I18n, Spinner, htmlEscape) ->
class PaginatedList
##
# I18n keys used by class
@@ -132,11 +132,11 @@ define ['jquery', 'i18n!paginated_list', 'vendor/spin'], ($, I18n, Spinner) ->
##
# animate loaded results
# @api private
- animateInResults: (results) ->
+ animateInResults: ($results) ->
empty = @el.list.children().length == 0
- results.css('display', 'none')
- @el.list.append results
- results.slideDown()
+ $results.css('display', 'none')
+ @el.list.append $results
+ $results.slideDown()
##
# keep track of what page we're on. when the last page
@@ -146,7 +146,7 @@ define ['jquery', 'i18n!paginated_list', 'vendor/spin'], ($, I18n, Spinner) ->
if @hasNextPage()
@options.requestParams.page++
unless @pageLinkPresent
- @el.wrapper.append @viewMoreLink()
+ @el.wrapper.append @viewMoreLinkHtml()
@pageLinkPresent = true
else
@el.wrapper.find('.view-more-link').remove()
@@ -162,12 +162,12 @@ define ['jquery', 'i18n!paginated_list', 'vendor/spin'], ($, I18n, Spinner) ->
# template for view more link
# @return String
# @api private
- viewMoreLink: ->
- '
' + @keys.viewMore + ''
+ viewMoreLinkHtml: ->
+ '
' + htmlEscape(@keys.viewMore) + ''
##
# template for no results notification
# @return String
# @api private
noResults: ->
- @el.list.append "
#{@keys.noResults}"
+ @el.list.append "
#{htmlEscape @keys.noResults}"
diff --git a/app/coffeescripts/backbone-ext/Backbone.syncWithMultipart.coffee b/app/coffeescripts/backbone-ext/Backbone.syncWithMultipart.coffee
index b97231851f7..c032982e451 100644
--- a/app/coffeescripts/backbone-ext/Backbone.syncWithMultipart.coffee
+++ b/app/coffeescripts/backbone-ext/Backbone.syncWithMultipart.coffee
@@ -5,7 +5,12 @@ define [
'underscore'
'jquery'
'compiled/behaviors/authenticity_token'
-], (Backbone, _, $, authenticity_token) ->
+ 'str/htmlEscape'
+], (Backbone, _, $, authenticity_token, htmlEscape) ->
+ ###
+ xsslint safeString.identifier iframeId httpMethod
+ xsslint jqueryObject.identifier el
+ ###
Backbone.syncWithoutMultipart = Backbone.sync
Backbone.syncWithMultipart = (method, model, options) ->
@@ -35,7 +40,7 @@ define [
$el[0]
_.flatten(inputs)
$form = $("""
-
""").hide()
@@ -43,7 +48,7 @@ define [
if options.proxyAttachment
$form.prepend """
-
+
"""
_.each toForm(model.toJSON()), (el) ->
diff --git a/app/coffeescripts/backbone-ext/View.coffee b/app/coffeescripts/backbone-ext/View.coffee
index 479ba7ca470..06c2650f9f5 100644
--- a/app/coffeescripts/backbone-ext/View.coffee
+++ b/app/coffeescripts/backbone-ext/View.coffee
@@ -250,6 +250,10 @@ define [
#
# @api private
+ ###
+ xsslint safeString.method format
+ ###
+
createBindings: (index, el) =>
@$('[data-bind]').each (index, el) =>
$el = $ el
diff --git a/app/coffeescripts/badge_counts.coffee b/app/coffeescripts/badge_counts.coffee
index 29d4ac26627..acdc627a375 100644
--- a/app/coffeescripts/badge_counts.coffee
+++ b/app/coffeescripts/badge_counts.coffee
@@ -4,5 +4,5 @@ define ['jquery'], ($) ->
for type, unread of ENV.badge_counts
if unread > 0
type = "grades" if type is "submissions"
- $badge = $("
").append(unread).addClass("nav-badge")
+ $badge = $("
").text(unread).addClass("nav-badge")
$("#section-tabs .#{type}").append($badge)
diff --git a/app/coffeescripts/behaviors/SyllabusBehaviors.coffee b/app/coffeescripts/behaviors/SyllabusBehaviors.coffee
index a2d75a749e8..b78b308338d 100644
--- a/app/coffeescripts/behaviors/SyllabusBehaviors.coffee
+++ b/app/coffeescripts/behaviors/SyllabusBehaviors.coffee
@@ -231,6 +231,9 @@ define [
$course_syllabus.loadingImage()
success: (data) ->
+ ###
+ xsslint safeString.property syllabus_body
+ ###
$course_syllabus.loadingImage('remove').html data.course.syllabus_body
$course_syllabus.data('syllabus_body', data.course.syllabus_body)
$course_syllabus_details.hide()
diff --git a/app/coffeescripts/behaviors/favicon.coffee b/app/coffeescripts/behaviors/favicon.coffee
index a5ed75f511f..7b13784f20f 100644
--- a/app/coffeescripts/behaviors/favicon.coffee
+++ b/app/coffeescripts/behaviors/favicon.coffee
@@ -1,14 +1,14 @@
define ['jquery', 'INST'], ($, INST) ->
- link = null
+ $link = null
set = (env) ->
- link.remove() if link
+ $link.remove() if $link
favicon = if env == 'development'
'/favicon-green.ico'
else if env == 'test'
'/favicon-yellow.ico'
else
'/favicon.ico'
- link = $('
').attr(rel: 'icon', type: 'image/x-icon', href: favicon)
- $(document.head).append(link)
+ $link = $('
').attr(rel: 'icon', type: 'image/x-icon', href: favicon)
+ $(document.head).append($link)
set(INST?.environment)
set
diff --git a/app/coffeescripts/behaviors/ujsLinks.coffee b/app/coffeescripts/behaviors/ujsLinks.coffee
index dfc5adb6e71..c98d412e631 100644
--- a/app/coffeescripts/behaviors/ujsLinks.coffee
+++ b/app/coffeescripts/behaviors/ujsLinks.coffee
@@ -1,7 +1,7 @@
# copied from
# https://github.com/rails/jquery-ujs
-define ['jquery', 'compiled/behaviors/authenticity_token'], ($, authenticity_token) ->
+define ['jquery', 'compiled/behaviors/authenticity_token', 'str/htmlEscape'], ($, authenticity_token, htmlEscape) ->
##
# Handles "data-method" on links such as:
@@ -11,12 +11,12 @@ define ['jquery', 'compiled/behaviors/authenticity_token'], ($, authenticity_tok
href = link.data('url') || link.attr('href')
method = link.data('method')
target = link.attr('target')
- form = $("
")
- metadataInput = "
"
- metadataInput += "
"
+ form = $("
")
+ metadataInputHtml = "
"
+ metadataInputHtml += "
"
form.attr('target', target) if target
- form.hide().append(metadataInput).appendTo('body').submit()
+ form.hide().append(metadataInputHtml).appendTo('body').submit()
# For 'data-confirm' attribute:
diff --git a/app/coffeescripts/bundles/dashboard.coffee b/app/coffeescripts/bundles/dashboard.coffee
index 0f788c1432e..780938c0ea6 100644
--- a/app/coffeescripts/bundles/dashboard.coffee
+++ b/app/coffeescripts/bundles/dashboard.coffee
@@ -11,8 +11,8 @@ require [
if ENV.DASHBOARD_SIDEBAR_URL
rightSide = $('#right-side')
rightSide.disableWhileLoading(
- $.get ENV.DASHBOARD_SIDEBAR_URL , (data) ->
- rightSide.html data
+ $.get ENV.DASHBOARD_SIDEBAR_URL , (html) ->
+ rightSide.html html
newCourseForm()
)
diff --git a/app/coffeescripts/bundles/legacy/courses_show.coffee b/app/coffeescripts/bundles/legacy/courses_show.coffee
index 3c64098af6a..684d7479f0b 100644
--- a/app/coffeescripts/bundles/legacy/courses_show.coffee
+++ b/app/coffeescripts/bundles/legacy/courses_show.coffee
@@ -39,9 +39,9 @@ require [
$link.hide()
$.ajaxJSON $(this).attr("href"), "GET", {}, (data) ->
$("#home_page").loadingImage "remove"
- body = htmlEscape($.trim(data.wiki_page.body))
- body = htmlEscape(I18n.t("empty_body", "No Content")) if body.length is 0
- $("#home_page_content").html body
+ bodyHtml = htmlEscape($.trim(data.wiki_page.body))
+ bodyHtml = htmlEscape(I18n.t("empty_body", "No Content")) if bodyHtml.length is 0
+ $("#home_page_content").html bodyHtml
$("html,body").scrollTo $("#home_page")
$(".dashboard_view_link").click (event) ->
diff --git a/app/coffeescripts/bundles/legacy/user_outcome_results.coffee b/app/coffeescripts/bundles/legacy/user_outcome_results.coffee
index 7e262a1d8cf..46d977d23bd 100644
--- a/app/coffeescripts/bundles/legacy/user_outcome_results.coffee
+++ b/app/coffeescripts/bundles/legacy/user_outcome_results.coffee
@@ -7,7 +7,7 @@ require [
showAllArtifacts.click (event) ->
event.preventDefault()
$("tr.artifact_details").toggle()
- if showAllArtifacts.html() is I18n.t("#buttons.show_all_artifacts", "Show All Artifacts")
- showAllArtifacts.html I18n("#buttons.hide_all_artifacts", "Hide All Artifacts")
+ if showAllArtifacts.text() is I18n.t("#buttons.show_all_artifacts", "Show All Artifacts")
+ showAllArtifacts.text I18n("#buttons.hide_all_artifacts", "Hide All Artifacts")
else
- showAllArtifacts.html I18n.t("#buttons.show_all_artifacts", "Show All Artifacts")
\ No newline at end of file
+ showAllArtifacts.text I18n.t("#buttons.show_all_artifacts", "Show All Artifacts")
diff --git a/app/coffeescripts/bundles/profile_show.coffee b/app/coffeescripts/bundles/profile_show.coffee
index 4746b6c5f45..c278d7c9be5 100644
--- a/app/coffeescripts/bundles/profile_show.coffee
+++ b/app/coffeescripts/bundles/profile_show.coffee
@@ -80,10 +80,10 @@ require [
@$linkFields ?= @$ '#profile_link_fields'
$row = $ """
- |
+ |
→ |
- |
- #{I18n.t("Remove")} |
+ |
+ #{htmlEscape I18n.t("Remove")} |
"""
@$linkFields.append $row
diff --git a/app/coffeescripts/bundles/quiz_show.coffee b/app/coffeescripts/bundles/quiz_show.coffee
index 02fab2cc4e3..cfdce0dff4d 100644
--- a/app/coffeescripts/bundles/quiz_show.coffee
+++ b/app/coffeescripts/bundles/quiz_show.coffee
@@ -20,8 +20,8 @@ require [
if ENV.SUBMISSION_VERSIONS_URL && !ENV.IS_SURVEY
versions = $("#quiz-submission-version-table")
versions.css(height: "100px")
- dfd = $.get ENV.SUBMISSION_VERSIONS_URL, (data) ->
- versions.html(data)
+ dfd = $.get ENV.SUBMISSION_VERSIONS_URL, (html) ->
+ versions.html(html)
versions.css(height: "auto")
versions.disableWhileLoading(dfd)
diff --git a/app/coffeescripts/bundles/zip_file_imports.coffee b/app/coffeescripts/bundles/zip_file_imports.coffee
index eff6ce3924d..67bfea94294 100644
--- a/app/coffeescripts/bundles/zip_file_imports.coffee
+++ b/app/coffeescripts/bundles/zip_file_imports.coffee
@@ -1,12 +1,13 @@
require [
'i18n!zip_file_imports' # I18n
'jquery' # $
+ 'str/htmlEscape'
'jquery.ajaxJSON' # getJSON
'jquery.instructure_forms' # ajaxJSONFiles
'jqueryui/dialog'
'compiled/jquery.rails_flash_notifications'
'jqueryui/progressbar' # /\.progressbar/
-], (I18n, $) ->
+], (I18n, $, htmlEscape) ->
$(document).ready ->
$zipFile = $("#zip_file_import_form #zip_file")
@@ -73,7 +74,7 @@ require [
importFailed []
else if zfi.workflow_state == 'imported'
$("#uploading_progressbar").progressbar 'value', 100
- $("#uploading_please_wait_dialog").prepend I18n.t('notices.uploading_complete', "Uploading complete!")
+ $("#uploading_please_wait_dialog").prepend htmlEscape I18n.t('notices.uploading_complete', "Uploading complete!")
location.href = $("#return_to").val()
else
pollImport.errorCount = 0
diff --git a/app/coffeescripts/calendar/Calendar.coffee b/app/coffeescripts/calendar/Calendar.coffee
index e6260fd91f3..aaf2dfda4e6 100644
--- a/app/coffeescripts/calendar/Calendar.coffee
+++ b/app/coffeescripts/calendar/Calendar.coffee
@@ -156,7 +156,7 @@ define [
dayClick: @dayClick
addEventClick: @addEventClick
titleFormat:
- week: "MMM d[ yyyy]{ '–'[ MMM] d, yyyy}"
+ week: "MMM d[ yyyy]{ '–'[ MMM] d, yyyy}"
viewDisplay: @viewDisplay
windowResize: @windowResize
drop: @drop
@@ -275,8 +275,8 @@ define [
I18n.t('event_event_title', 'Event Title:')
$element.attr('title', $.trim("#{timeString}\n#{$element.find('.fc-event-title').text()}\n\n#{I18n.t('calendar_title', 'Calendar:')} #{htmlEscape(event.contextInfo.name)}"))
- $element.find('.fc-event-inner').prepend($("
#{I18n.t('calendar_title', 'Calendar:')} #{htmlEscape(event.contextInfo.name)}"))
- $element.find('.fc-event-title').prepend($("
#{screenReaderTitleHint} "))
+ $element.find('.fc-event-inner').prepend($("
#{htmlEscape I18n.t('calendar_title', 'Calendar:')} #{htmlEscape(event.contextInfo.name)}"))
+ $element.find('.fc-event-title').prepend($("
#{htmlEscape screenReaderTitleHint} "))
$element.find('.fc-event-title').toggleClass('calendar__event--completed', event.isCompleted())
element.find('.fc-event-inner').prepend($('
', {'class': "icon-#{event.iconType()}"}))
true
@@ -408,20 +408,20 @@ define [
drawNowLine: =>
return unless @currentView == 'week'
- if !@nowLine
- @nowLine = $('
', {'class': 'calendar-nowline'})
- $('.fc-agenda-slots').parent().append(@nowLine)
+ if !@$nowLine
+ @$nowLine = $('
', {'class': 'calendar-nowline'})
+ $('.fc-agenda-slots').parent().append(@$nowLine)
now = $.fudgeDateForProfileTimezone(new Date)
midnight = new Date(now.getTime())
midnight.setHours(0, 0, 0)
seconds = (now.getTime() - midnight.getTime())/1000
- @nowLine.toggle(@isSameWeek(@getCurrentDate(), now))
+ @$nowLine.toggle(@isSameWeek(@getCurrentDate(), now))
- @nowLine.css('width', $('.fc-agenda-slots .fc-widget-content:first').css('width'))
+ @$nowLine.css('width', $('.fc-agenda-slots .fc-widget-content:first').css('width'))
secondHeight = $('.fc-agenda-slots').css('height').replace('px', '')/24/3600
- @nowLine.css('top', seconds*secondHeight + 'px')
+ @$nowLine.css('top', seconds*secondHeight + 'px')
setDateTitle: (title) =>
@header.setHeaderText(title)
@@ -642,7 +642,7 @@ define [
@agenda.fetch(@visibleContextList, start)
renderDateRange: (start, end) =>
- @setDateTitle(I18n.l('#date.formats.medium', start)+' – '+I18n.l('#date.formats.medium', end))
+ @setDateTitle(I18n.l('#date.formats.medium', start)+' – '+I18n.l('#date.formats.medium', end))
# for "load more" with voiceover, we want the alert to happen later so
# the focus change doesn't interrupt it.
window.setTimeout =>
@@ -671,15 +671,16 @@ define [
colorizeContexts: =>
colors = colorSlicer.getColors(@contextCodes.length, 275, {unsafe: !ENV.SETTINGS.use_high_contrast})
- html = for contextCode, index in @contextCodes
+ html = (for contextCode, index in @contextCodes
color = colors[index]
".group_#{contextCode}{
color: #{color};
border-color: #{color};
background-color: #{color};
}"
+ ).join('')
- $styleContainer.html ""
+ $styleContainer.html ""
dataFromDocumentHash: () =>
data = {}
diff --git a/app/coffeescripts/calendar/EditAssignmentDetails.coffee b/app/coffeescripts/calendar/EditAssignmentDetails.coffee
index d86fd6a1fa3..cbbb5f6f98e 100644
--- a/app/coffeescripts/calendar/EditAssignmentDetails.coffee
+++ b/app/coffeescripts/calendar/EditAssignmentDetails.coffee
@@ -13,24 +13,24 @@ define [
constructor: (selector, @event, @contextChangeCB, @closeCB) ->
@currentContextInfo = null
tpl = if @event.override then editAssignmentOverrideTemplate else editAssignmentTemplate
- @form = $(tpl({
+ @$form = $(tpl({
title: @event.title
contexts: @event.possibleContexts()
}))
- $(selector).append @form
+ $(selector).append @$form
@setupTimeAndDatePickers()
- @form.submit @formSubmit
- @form.find(".more_options_link").click @moreOptionsClick
- @form.find("select.context_id").change @contextChange
- @form.find("select.context_id").triggerHandler('change', false)
+ @$form.submit @formSubmit
+ @$form.find(".more_options_link").click @moreOptionsClick
+ @$form.find("select.context_id").change @contextChange
+ @$form.find("select.context_id").triggerHandler('change', false)
# Hide the context selector completely if this is an existing event, since it can't be changed.
if !@event.isNewEvent()
- @form.find(".context_select").hide()
- @form.attr('method', 'PUT')
- @form.attr('action', $.replaceTags(@event.contextInfo.assignment_url, 'id', @event.object.id))
+ @$form.find(".context_select").hide()
+ @$form.attr('method', 'PUT')
+ @$form.attr('action', $.replaceTags(@event.contextInfo.assignment_url, 'id', @event.object.id))
contextInfoForCode: (code) ->
for context in @event.possibleContexts()
@@ -39,14 +39,14 @@ define [
return null
activate: () =>
- @form.find("select.context_id").change()
+ @$form.find("select.context_id").change()
if @event.assignment?.assignment_group_id
- @form.find(".assignment_group_select .assignment_group").val(@event.assignment.assignment_group_id)
+ @$form.find(".assignment_group_select .assignment_group").val(@event.assignment.assignment_group_id)
moreOptionsClick: (jsEvent) =>
jsEvent.preventDefault()
pieces = $(jsEvent.target).attr('href').split("#")
- data = @form.getFormData( object_name: 'assignment' )
+ data = @$form.getFormData( object_name: 'assignment' )
params = {}
if data.title then params['title'] = data.title
if data.due_at then params['due_at'] = data.due_at
@@ -56,7 +56,7 @@ define [
window.location.href = pieces.join("#")
setContext: (newContext) =>
- @form.find("select.context_id").val(newContext).triggerHandler('change', false)
+ @$form.find("select.context_id").val(newContext).triggerHandler('change', false)
contextChange: (jsEvent, propagate) =>
return if @ignoreContextChange
@@ -72,30 +72,30 @@ define [
# TODO: support adding a new assignment group from this select box
assignmentGroupsSelectOptionsInfo =
collection: @currentContextInfo.assignment_groups
- @form.find(".assignment_group").html(genericSelectOptionsTemplate(assignmentGroupsSelectOptionsInfo))
+ @$form.find(".assignment_group").html(genericSelectOptionsTemplate(assignmentGroupsSelectOptionsInfo))
# Update the edit and more options links with the new context
- @form.attr('action', @currentContextInfo.create_assignment_url)
+ @$form.attr('action', @currentContextInfo.create_assignment_url)
moreOptionsUrl = if @event.assignment
"#{@event.assignment.html_url}/edit"
else
@currentContextInfo.new_assignment_url
- @form.find(".more_options_link").attr('href', moreOptionsUrl)
+ @$form.find(".more_options_link").attr('href', moreOptionsUrl)
setupTimeAndDatePickers: () =>
- @form.find(".datetime_field").datetime_field()
+ @$form.find(".datetime_field").datetime_field()
startDate = @event.startDate()
endDate = @event.endDate()
if @event.allDay
- @form.find(".datetime_field").val(startDate.toString('MMM d, yyyy')).change()
+ @$form.find(".datetime_field").val(startDate.toString('MMM d, yyyy')).change()
else if startDate
- @form.find(".datetime_field").val(startDate.toString('MMM d, yyyy h:mmtt')).change()
+ @$form.find(".datetime_field").val(startDate.toString('MMM d, yyyy h:mmtt')).change()
formSubmit: (e) =>
e.preventDefault()
- form = @form.getFormData()
+ form = @$form.getFormData()
if form['assignment[due_at]']? then @submitAssignment(form) else @submitOverride(form)
submitAssignment: (form) ->
@@ -104,12 +104,12 @@ define [
if dueAtString == ''
dueAt = null
else
- dueAt = @form.find("#assignment_due_at").data('date')
+ dueAt = @$form.find("#assignment_due_at").data('date')
params = {
- 'assignment[name]': @form.find("#assignment_title").val()
- 'assignment[published]': @form.find("#assignment_published").val() if @form.find("#assignment_published").is(':checked')
+ 'assignment[name]': @$form.find("#assignment_title").val()
+ 'assignment[published]': @$form.find("#assignment_published").val() if @$form.find("#assignment_published").is(':checked')
'assignment[due_at]': if dueAt then $.unfudgeDateForProfileTimezone(dueAt).toISOString() else ''
- 'assignment[assignment_group_id]': @form.find(".assignment_group").val()
+ 'assignment[assignment_group_id]': @$form.find(".assignment_group").val()
}
if @event.isNewEvent()
@@ -117,7 +117,7 @@ define [
assignment:
title: params['assignment[name]']
due_at: if dueAt then dueAt.toISOString() else null
- context_code: @form.find(".context_id").val()
+ context_code: @$form.find(".context_id").val()
newEvent = commonEventFactory(objectData, @event.possibleContexts())
newEvent.save(params)
else
@@ -129,7 +129,7 @@ define [
submitOverride: (form) ->
dueAt = form['assignment_override[due_at]']
- dueAt = if dueAt is '' then null else @form.find('#assignment_override_due_at').data('date')
+ dueAt = if dueAt is '' then null else @$form.find('#assignment_override_due_at').data('date')
params = 'assignment_override[due_at]': if dueAt then $.unfudgeDateForProfileTimezone(dueAt).toISOString() else ''
@event.start = dueAt
@event.save(params)
diff --git a/app/coffeescripts/calendar/EditCalendarEventDetails.coffee b/app/coffeescripts/calendar/EditCalendarEventDetails.coffee
index 3803137a677..dfd420b7eaf 100644
--- a/app/coffeescripts/calendar/EditCalendarEventDetails.coffee
+++ b/app/coffeescripts/calendar/EditCalendarEventDetails.coffee
@@ -14,24 +14,24 @@ define [
class EditCalendarEventDetails
constructor: (selector, @event, @contextChangeCB, @closeCB) ->
@currentContextInfo = null
- @form = $(editCalendarEventTemplate({
+ @$form = $(editCalendarEventTemplate({
title: @event.title
contexts: @event.possibleContexts()
lockedTitle: @event.lockedTitle
location_name: @event.location_name
}))
- $(selector).append @form
+ $(selector).append @$form
@setupTimeAndDatePickers()
- @form.submit @formSubmit
- @form.find(".more_options_link").click @moreOptionsClick
- @form.find("select.context_id").change @contextChange
- @form.find("select.context_id").triggerHandler('change', false)
+ @$form.submit @formSubmit
+ @$form.find(".more_options_link").click @moreOptionsClick
+ @$form.find("select.context_id").change @contextChange
+ @$form.find("select.context_id").triggerHandler('change', false)
# Hide the context selector completely if this is an existing event, since it can't be changed.
if !@event.isNewEvent()
- @form.find(".context_select").hide()
+ @$form.find(".context_select").hide()
contextInfoForCode: (code) ->
for context in @event.possibleContexts()
@@ -40,20 +40,20 @@ define [
return null
activate: () =>
- @form.find("select.context_id").change()
+ @$form.find("select.context_id").change()
getFormData: =>
- data = @form.getFormData(object_name: 'calendar_event')
+ data = @$form.getFormData(object_name: 'calendar_event')
data = _.omit(data, 'date', 'start_time', 'end_time')
- date = @form.find('input[name=date]').data('date')
+ date = @$form.find('input[name=date]').data('date')
if date
- start_time = @form.find('input[name=start_time]').data('date')
+ start_time = @$form.find('input[name=start_time]').data('date')
start_at = date.toString('yyyy-MM-dd')
start_at += start_time.toString(' HH:mm') if start_time
data.start_at = tz.parse(start_at)
- end_time = @form.find('input[name=end_time]').data('date')
+ end_time = @$form.find('input[name=end_time]').data('date')
end_at = date.toString('yyyy-MM-dd')
end_at += end_time.toString(' HH:mm') if end_time
data.end_at = tz.parse(end_at)
@@ -69,9 +69,9 @@ define [
data = @getFormData()
# override parsed input with user input (for 'More Options' only)
- data.start_date = @form.find('input[name=date]').val()
- data.start_time = @form.find('input[name=start_time]').val()
- data.end_time = @form.find('input[name=end_time]').val()
+ data.start_date = @$form.find('input[name=date]').val()
+ data.start_time = @$form.find('input[name=start_time]').val()
+ data.end_time = @$form.find('input[name=end_time]').val()
if data.title then params['title'] = data.title
if data.location_name then params['location_name'] = data.location_name
@@ -84,7 +84,7 @@ define [
window.location.href = pieces.join("#")
setContext: (newContext) =>
- @form.find("select.context_id").val(newContext).triggerHandler('change', false)
+ @$form.find("select.context_id").val(newContext).triggerHandler('change', false)
contextChange: (jsEvent, propagate) =>
context = $(jsEvent.target).val()
@@ -101,21 +101,21 @@ define [
moreOptionsHref = @currentContextInfo.new_calendar_event_url
else
moreOptionsHref = @event.fullDetailsURL() + '/edit'
- @form.find(".more_options_link").attr 'href', moreOptionsHref
+ @$form.find(".more_options_link").attr 'href', moreOptionsHref
setupTimeAndDatePickers: () =>
- @form.find(".date_field").date_field()
+ @$form.find(".date_field").date_field()
# TODO: Refactor this logic that forms a relationship between two time fields into a module
- @form.find(".time_field").time_field().
+ @$form.find(".time_field").time_field().
blur (jsEvent) =>
- start_time = @form.find(".time_field.start_time").next(".datetime_suggest").text()
- if @form.find(".time_field.start_time").next(".datetime_suggest").hasClass('invalid_datetime')
+ start_time = @$form.find(".time_field.start_time").next(".datetime_suggest").text()
+ if @$form.find(".time_field.start_time").next(".datetime_suggest").hasClass('invalid_datetime')
start_time = null
- start_time ?= @form.find(".time_field.start_time").val()
- end_time = @form.find(".time_field.end_time").next(".datetime_suggest").text()
- if @form.find(".time_field.end_time").next(".datetime_suggest").hasClass('invalid_datetime')
+ start_time ?= @$form.find(".time_field.start_time").val()
+ end_time = @$form.find(".time_field.end_time").next(".datetime_suggest").text()
+ if @$form.find(".time_field.end_time").next(".datetime_suggest").hasClass('invalid_datetime')
end_time = null
- end_time ?= @form.find(".time_field.end_time").val()
+ end_time ?= @$form.find(".time_field.end_time").val()
startDate = Date.parse(start_time)
endDate = Date.parse(end_time)
@@ -128,21 +128,21 @@ define [
else
if endDate < startDate then endDate = startDate
if startDate
- @form.find(".time_field.start_time").val(startDate.toString('h:mmtt').toLowerCase())
+ @$form.find(".time_field.start_time").val(startDate.toString('h:mmtt').toLowerCase())
if endDate
- @form.find(".time_field.end_time").val(endDate.toString('h:mmtt').toLowerCase())
+ @$form.find(".time_field.end_time").val(endDate.toString('h:mmtt').toLowerCase())
startDate = @event.startDate()
endDate = @event.endDate()
if !@event.allDay
if startDate
- @form.find(".time_field.start_time").val(startDate.toString('h:mmtt')).change().blur()
+ @$form.find(".time_field.start_time").val(startDate.toString('h:mmtt')).change().blur()
if endDate
- @form.find(".time_field.end_time").val(endDate.toString('h:mmtt')).change().blur()
+ @$form.find(".time_field.end_time").val(endDate.toString('h:mmtt')).change().blur()
if startDate
- @form.find(".date_field").val(startDate.toString('MMM d, yyyy')).change()
+ @$form.find(".date_field").val(startDate.toString('MMM d, yyyy')).change()
formSubmit: (jsEvent) =>
jsEvent.preventDefault()
@@ -165,7 +165,7 @@ define [
start_at: if data.start_at then data.start_at.toISOString() else null
end_at: if data.end_at then data.end_at.toISOString() else null
location_name: location_name
- context_code: @form.find(".context_id").val()
+ context_code: @$form.find(".context_id").val()
newEvent = commonEventFactory(objectData, @event.possibleContexts())
newEvent.save(params)
else
diff --git a/app/coffeescripts/developer_keys.coffee b/app/coffeescripts/developer_keys.coffee
index f5432720a90..f6efe51ef6d 100644
--- a/app/coffeescripts/developer_keys.coffee
+++ b/app/coffeescripts/developer_keys.coffee
@@ -7,7 +7,7 @@ define [
'jquery.ajaxJSON'
'jquery.instructure_date_and_time'
'jqueryui/dialog'
-], (I18n, $, developer_key, developer_key_form, preventDefault) ->
+], (I18n, $, developer_key, developerKeyFormTemplate, preventDefault) ->
page = 0
buildKey = (key) ->
key.icon_image_url = key.icon_url || "/images/blank.png"
@@ -20,7 +20,7 @@ define [
$key.data('key', key)
buildForm = (key, $orig) ->
- $form = $(developer_key_form(key || {}))
+ $form = $(developerKeyFormTemplate(key || {}))
$form.formSubmit({
beforeSubmit: ->
$("#edit_dialog button.submit").text(I18n.t('button.saving', "Saving Key..."))
@@ -72,7 +72,7 @@ define [
$form = buildForm()
$("#edit_dialog").empty().append($form).dialog('open')
)
- $("#edit_dialog").html(developer_key_form({})).dialog({
+ $("#edit_dialog").html(developerKeyFormTemplate({})).dialog({
autoOpen: false,
width: 350
}).on('click', '.cancel', () ->
diff --git a/app/coffeescripts/discussions/EntryEditor.coffee b/app/coffeescripts/discussions/EntryEditor.coffee
index 23929a0717e..457c8bfae30 100644
--- a/app/coffeescripts/discussions/EntryEditor.coffee
+++ b/app/coffeescripts/discussions/EntryEditor.coffee
@@ -48,7 +48,7 @@ define [
createCancelButton: ->
$('
')
- .html(I18n.t('cancel', 'Cancel'))
+ .text(I18n.t('cancel', 'Cancel'))
.css(marginLeft: '5px')
.attr('href', 'javascript:')
.addClass('cancel_button')
diff --git a/app/coffeescripts/discussions/Reply.coffee b/app/coffeescripts/discussions/Reply.coffee
index f30bae4c27a..f4f8ea4c44e 100644
--- a/app/coffeescripts/discussions/Reply.coffee
+++ b/app/coffeescripts/discussions/Reply.coffee
@@ -8,8 +8,9 @@ define [
'jst/discussions/_reply_attachment'
'compiled/fn/preventDefault'
'compiled/views/editor/KeyboardShortcuts'
+ 'str/stripTags'
'tinymce.editor_box'
-], (Backbone, _, I18n, $, Entry, htmlEscape, replyAttachmentTemplate, preventDefault, KeyboardShortcuts) ->
+], (Backbone, _, I18n, $, Entry, htmlEscape, replyAttachmentTemplate, preventDefault, KeyboardShortcuts, stripTags) ->
class Reply
@@ -87,7 +88,7 @@ define [
submit: =>
@hide()
@textArea._setContentCode ''
- @view.model.set 'notification', "
#{I18n.t 'saving_reply', 'Saving reply...'}
"
+ @view.model.set 'notification', "
#{htmlEscape I18n.t 'saving_reply', 'Saving reply...'}
"
entry = new Entry @getModelAttributes()
entry.save null,
success: @onPostReplySuccess
@@ -112,7 +113,7 @@ define [
now = new Date().getTime()
# TODO: remove this summary, server should send it in create response and no further
# work is required
- summary: $('
').html(@content).text()
+ summary: stripTags(@content)
message: @content
parent_id: if @options.topLevel then null else @view.model.get 'id'
user_id: ENV.current_user_id
diff --git a/app/coffeescripts/editor/EditorToggle.coffee b/app/coffeescripts/editor/EditorToggle.coffee
index c5d6572abae..8c654683fcb 100644
--- a/app/coffeescripts/editor/EditorToggle.coffee
+++ b/app/coffeescripts/editor/EditorToggle.coffee
@@ -7,6 +7,10 @@ define [
'tinymce.editor_box'
], (_, I18n, $, Backbone, preventDefault) ->
+ ###
+ xsslint safeString.property content
+ ###
+
##
# Toggles an element between a rich text editor and itself
class EditorToggle
@@ -103,7 +107,7 @@ define [
# @api private
createDone: ->
$('
')
- .html(@options.doneText)
+ .text(@options.doneText)
.attr('href', '#')
.addClass('btn edit-html-done edit_html_done')
.attr('title', I18n.t('done.title', 'Click to finish editing the rich text area'))
diff --git a/app/coffeescripts/editor/editorAccessibility.coffee b/app/coffeescripts/editor/editorAccessibility.coffee
index 0c7aa7f11f1..de2188f6cb6 100644
--- a/app/coffeescripts/editor/editorAccessibility.coffee
+++ b/app/coffeescripts/editor/editorAccessibility.coffee
@@ -1,7 +1,8 @@
define [
'i18n!editor_accessibility'
'jquery'
-], (I18n, $) ->
+ 'str/htmlEscape'
+], (I18n, $, htmlEscape) ->
##
# Used to insert accessibility titles into core TinyMCE components
class EditorAccessiblity
@@ -32,7 +33,7 @@ define [
@$el.find("##{@id_prepend}_instructure_record").attr('aria-disabled', 'true')
@$el.find("##{@id_prepend}_instructure_record").removeAttr('role')
- @$el.find("##{@id_prepend}_instructure_record_voice").append('
').append(I18n.t('accessibles.record', 'This feature is inaccessible for screen readers.'))
+ @$el.find("##{@id_prepend}_instructure_record_voice").append('
').append(htmlEscape(I18n.t('accessibles.record', 'This feature is inaccessible for screen readers.')))
@$el.find("##{@id_prepend}_instructure_record img").attr('alt',
@$el.find("##{@id_prepend}_instructure_record img").attr('alt') + ", " + I18n.t('accessibles.record', 'This feature is inaccessible for screen readers.'));
diff --git a/app/coffeescripts/gradebook2/CurveGradesDialog.coffee b/app/coffeescripts/gradebook2/CurveGradesDialog.coffee
index aa1604deb12..6a70bdd57e9 100644
--- a/app/coffeescripts/gradebook2/CurveGradesDialog.coffee
+++ b/app/coffeescripts/gradebook2/CurveGradesDialog.coffee
@@ -2,13 +2,14 @@ define [
'i18n!gradebook2'
'jquery'
'jst/CurveGradesDialog'
+ 'str/htmlEscape'
'jquery.disableWhileLoading'
'jquery.instructure_forms'
'jqueryui/dialog'
'jquery.instructure_misc_plugins'
'compiled/jquery/fixDialogButtons'
'vendor/jquery.ba-tinypubsub'
-], (I18n, $, curveGradesDialogTemplate) ->
+], (I18n, $, curveGradesDialogTemplate, htmlEscape) ->
class CurveGradesDialog
constructor: ({@assignment, @students, context_url}) ->
@@ -133,12 +134,12 @@ define [
pct = (users.length / maxCount)
cnt = users.length
color = (if idx == 0 then "#a03536" else "#007ab8")
- $("#results_list").prepend "
| "
- $("#results_values").prepend "
" + idx + " | "
+ $("#results_list").prepend "
| "
+ $("#results_values").prepend "
" + htmlEscape(idx) + " | "
skipCount = 0
else
skipCount++
idx--
- $("#results_list").prepend "
 " + maxCount + " 0 | "
+ $("#results_list").prepend "
 " + htmlEscape(maxCount) + " 0 | "
$("#results_values").prepend "
| "
finalScores
diff --git a/app/coffeescripts/gradebook2/Gradebook.coffee b/app/coffeescripts/gradebook2/Gradebook.coffee
index c976905b95f..f2300f5f271 100644
--- a/app/coffeescripts/gradebook2/Gradebook.coffee
+++ b/app/coffeescripts/gradebook2/Gradebook.coffee
@@ -410,16 +410,15 @@ define [
window.location.reload()
assignmentGroupHtml: (group_name, group_weight) =>
- escaped_group_name = htmlEscape(group_name)
if @weightedGroups()
percentage = I18n.toPercentage(group_weight, precision: 2)
"""
- #{escaped_group_name}
- #{I18n.t 'percent_of_grade', "%{percentage} of grade", percentage: percentage}
+ #{htmlEscape(group_name)}
+ #{htmlEscape I18n.t 'percent_of_grade', "%{percentage} of grade", percentage: percentage}
"""
else
- "#{escaped_group_name}"
+ htmlEscape(group_name)
# filter, sort, and build the dataset for slickgrid to read from, then force
# a full redraw
@@ -536,7 +535,7 @@ define [
(SubmissionCell[assignment.grading_type] || SubmissionCell).formatter(row, col, submission, assignment)
staticCellFormatter: (row, col, val) =>
- "
#{val}
"
+ "
#{htmlEscape(val)}
"
uneditableCellFormatter: (row, col) =>
"
"
@@ -654,7 +653,7 @@ define [
columnDef.name = columnDef.unminimizedName
columnDef.minimized = false
@$grid.find(".l#{colIndex}").add($columnHeader).removeClass('minimized')
- $columnHeader.find('.slick-column-name').html(columnDef.name)
+ $columnHeader.find('.slick-column-name').html($.raw(columnDef.name))
@assignmentsToHide = $.grep @assignmentsToHide, (el) -> el != columnDef.id
userSettings.contextSet('hidden_columns', _.uniq(@assignmentsToHide))
@@ -678,7 +677,7 @@ define [
# add lines for dropped, late, resubmitted
Array::push.apply htmlLines, $.map(SubmissionCell.classesBasedOnSubmission(submission, assignment), (c)=> GRADEBOOK_TRANSLATIONS["#submission_tooltip_#{c}"])
else if assignment.points_possible?
- htmlLines.push I18n.t('points_out_of', "out of %{points_possible}", points_possible: assignment.points_possible)
+ htmlLines.push htmlEscape(I18n.t('points_out_of', "out of %{points_possible}", points_possible: assignment.points_possible))
$hoveredCell.data('tooltip', $("
",
class: 'gradebook-tooltip'
@@ -687,7 +686,7 @@ define [
top: offset.top
zIndex: 10000
display: 'block'
- html: htmlLines.join('
')
+ html: $.raw(htmlLines.join('
'))
).appendTo('body')
.css('top', (i, top) -> parseInt(top) - $(this).outerHeight()))
@@ -972,7 +971,7 @@ define [
@parentColumns = [
id: 'student'
- name: I18n.t 'student_name', 'Student Name'
+ name: htmlEscape I18n.t 'student_name', 'Student Name'
field: 'display_name'
width: 150
cssClass: "meta-cell"
@@ -981,7 +980,7 @@ define [
formatter: @htmlContentFormatter
,
id: 'secondary_identifier'
- name: I18n.t 'secondary_id', 'Secondary ID'
+ name: htmlEscape I18n.t 'secondary_id', 'Secondary ID'
field: 'secondary_identifier'
width: 100
cssClass: "meta-cell secondary_identifier_cell"
@@ -1046,7 +1045,7 @@ define [
field: "total_grade"
formatter: @groupTotalFormatter
name: """
- #{total}
+ #{htmlEscape total}
"""
toolTip: total
@@ -1208,6 +1207,10 @@ define [
else
@totalGradeWarning = null
+ ###
+ xsslint jqueryObject.identifier createLink
+ xsslint jqueryObject.function showLink hideLink
+ ###
showCustomColumnDropdownOption: ->
linkContainer = $("
").appendTo(".gradebook_drop_down")
diff --git a/app/coffeescripts/gradebook2/OutcomeGradebookGrid.coffee b/app/coffeescripts/gradebook2/OutcomeGradebookGrid.coffee
index af8d296e5e6..2b415a60e9b 100644
--- a/app/coffeescripts/gradebook2/OutcomeGradebookGrid.coffee
+++ b/app/coffeescripts/gradebook2/OutcomeGradebookGrid.coffee
@@ -9,6 +9,10 @@ define [
'jst/gradebook2/outcome_gradebook_student_cell'
], (I18n, $, _, HeaderFilterView, OutcomeColumnView, numberCompare, cellTemplate, studentCellTemplate) ->
+ ###
+ xsslint safeString.method cellHtml
+ ###
+
Grid =
filter: ['mastery', 'near-mastery', 'remedial']
diff --git a/app/coffeescripts/gradebook2/SubmissionCell.coffee b/app/coffeescripts/gradebook2/SubmissionCell.coffee
index 57035669650..b38b9982e6c 100644
--- a/app/coffeescripts/gradebook2/SubmissionCell.coffee
+++ b/app/coffeescripts/gradebook2/SubmissionCell.coffee
@@ -15,7 +15,7 @@ define [
init: () ->
submission = @opts.item[@opts.column.field]
- @$wrapper = $(@cellWrapper("")).appendTo(@opts.container)
+ @$wrapper = $(@cellWrapper("")).appendTo(@opts.container)
@$input = @$wrapper.find('input').focus().select()
destroy: () ->
@@ -82,15 +82,15 @@ define [
if turnitin = extractData(opts.submission)
specialClasses.push('turnitin')
- innerContents += ""
+ innerContents += ""
tooltipText = $.map(specialClasses, (c)-> GRADEBOOK_TRANSLATIONS["submission_tooltip_#{c}"]).join ', '
"""
- #{ if tooltipText then ''+ tooltipText + '
' else ''}
-
+ #{$.raw if tooltipText then '
'+ htmlEscape(tooltipText) + '
' else ''}
+
- #{innerContents}
+ #{$.raw innerContents}
"""
@@ -112,7 +112,7 @@ define [
@submissionIcon: (submission_type) ->
klass = SubmissionCell.iconFromSubmissionType(submission_type)
- "
"
+ "
"
@iconFromSubmissionType: (submission_type) ->
switch submission_type
@@ -135,7 +135,7 @@ define [
@$wrapper = $(@cellWrapper("""
""", { classes: 'gradebook-cell-out-of-formatter' })).appendTo(@opts.container)
@@ -144,7 +144,7 @@ define [
class SubmissionCell.letter_grade extends SubmissionCell
@formatter: (row, col, submission, assignment) ->
innerContents = if submission.score
- "#{submission.grade}
#{submission.score}"
+ "#{htmlEscape submission.grade}
#{htmlEscape submission.score}"
else
submission.grade
@@ -165,7 +165,7 @@ define [
htmlFromSubmission: (options={}) ->
cssClass = classFromSubmission(options.submission)
SubmissionCell::cellWrapper("""
-
#{cssClass}
+
#{htmlEscape cssClass}
""", options)
# htmlFromSubmission = (submission, editable = false) ->
diff --git a/app/coffeescripts/handlebars_helpers.coffee b/app/coffeescripts/handlebars_helpers.coffee
index 01b4b3cea54..b9837f53002 100644
--- a/app/coffeescripts/handlebars_helpers.coffee
+++ b/app/coffeescripts/handlebars_helpers.coffee
@@ -53,7 +53,7 @@ define [
courseText = I18n.t('#helpers.course', 'Course')
courseDatetime = $.datetimeString(datetime, timezone: ENV.CONTEXT_TIMEZONE)
if localDatetime != courseDatetime
- titleText = "#{localText}: #{localDatetime}
#{courseText}: #{courseDatetime}"
+ titleText = "#{htmlEscape localText}: #{htmlEscape localDatetime}
#{htmlEscape courseText}: #{htmlEscape courseDatetime}"
if justText
new Handlebars.SafeString titleText
@@ -71,7 +71,7 @@ define [
else
timeTitle = $.datetimeString(datetime)
- new Handlebars.SafeString "
"
+ new Handlebars.SafeString "
"
@@ -79,7 +79,7 @@ define [
formattedDate : (datetime, format, {hash: {pubdate}}) ->
return unless datetime?
datetime = tz.parse(datetime) unless _.isDate datetime
- new Handlebars.SafeString "
"
+ new Handlebars.SafeString "
"
# IMPORTANT: these next two handlebars helpers emit profile-timezone
# human-formatted strings. don't send them as is to the server (you can
@@ -332,11 +332,11 @@ define [
attributes = for key, val of inputProps when val?
"#{htmlEscape key}=\"#{htmlEscape val}\""
- hiddenDisabled = if inputProps.disabled then "disabled" else ""
+ hiddenDisabledHtml = if inputProps.disabled then "disabled" else ""
new Handlebars.SafeString """
-
-
+
+
"""
toPercentage: (number) ->
diff --git a/app/coffeescripts/helpDialog.coffee b/app/coffeescripts/helpDialog.coffee
index 954f04f85ea..fee033ca524 100644
--- a/app/coffeescripts/helpDialog.coffee
+++ b/app/coffeescripts/helpDialog.coffee
@@ -85,9 +85,9 @@ define [
if newTitle = @$dialog.find("a[href='#{panelId}'] .text").text()
newTitle = $("
-
#{newTitle}
+
#{htmlEscape(newTitle)}
")
else
newTitle = @defaultTitle
@@ -114,11 +114,12 @@ define [
@$dialog.dialog('close')
$.when(coursesDfd, @helpLinksDfd).done ([courses]) ->
- options = $.map courses, (c) ->
- "
"
- $form.find('[name="recipients[]"]').html(options.join '')
+ ).join('')
+ $form.find('[name="recipients[]"]').html(optionsHtml)
initTriggers: ->
$('.help_dialog_trigger').click preventDefault @open
diff --git a/app/coffeescripts/jobs.coffee b/app/coffeescripts/jobs.coffee
index 869e9e53528..0419f84cdcb 100644
--- a/app/coffeescripts/jobs.coffee
+++ b/app/coffeescripts/jobs.coffee
@@ -5,6 +5,9 @@ define [
'jquery.ajaxJSON'
'jqueryui/dialog'
], (I18n, $, Slick) ->
+ ###
+ xsslint safeString.identifier klass d out_of runtime_string
+ ###
fillin_job_data = (job) ->
$('#show-job .show-field').each (idx, field) =>
diff --git a/app/coffeescripts/jquery.rails_flash_notifications.coffee b/app/coffeescripts/jquery.rails_flash_notifications.coffee
index 5bc6e555ac5..81bd232c82d 100644
--- a/app/coffeescripts/jquery.rails_flash_notifications.coffee
+++ b/app/coffeescripts/jquery.rails_flash_notifications.coffee
@@ -23,6 +23,9 @@ define [
$this.stop(true, true).remove()
initFlashContainer() # look for the container on script load
+ ###
+ xsslint safeString.function escapeContent
+ ###
escapeContent = (content) ->
if content.hasOwnProperty('html') then content.html else htmlEscape(content)
@@ -37,10 +40,10 @@ define [
flashBox = (type, content, timeout, cssOptions = {}) ->
$node = $("""
-
+
#{escapeContent(content)}
- #{I18n.t("close", "Close")}
+ #{htmlEscape I18n.t("close", "Close")}
""")
diff --git a/app/coffeescripts/jquery/mediaCommentThumbnail.coffee b/app/coffeescripts/jquery/mediaCommentThumbnail.coffee
index 6c6bf9a356e..bde7ba77891 100644
--- a/app/coffeescripts/jquery/mediaCommentThumbnail.coffee
+++ b/app/coffeescripts/jquery/mediaCommentThumbnail.coffee
@@ -26,8 +26,8 @@ define [
"#{dimensions.width}/height/#{dimensions.height}/bgcolor/000000/type/2/vid_sec/5"
$thumbnail = $ "