Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
b4e80863
Commit
b4e80863
authored
Apr 26, 2016
by
Awais Jibran
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #12049 from edx/aj/safe-templates
Safe templates
parents
5adf6fec
34b06932
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
98 additions
and
56 deletions
+98
-56
cms/static/js/views/settings/advanced.js
+12
-4
cms/static/js/views/settings/grader.js
+15
-4
cms/static/js/views/settings/grading.js
+38
-30
cms/static/js/views/settings/main.js
+14
-12
cms/static/js/views/validation.js
+13
-5
cms/templates/js/course_grade_cutoff.underscore
+5
-0
cms/templates/settings_graders.html
+1
-1
No files found.
cms/static/js/views/settings/advanced.js
View file @
b4e80863
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
)));
}
});
...
...
cms/static/js/views/settings/grader.js
View file @
b4e80863
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
:
...
...
cms/static/js/views/settings/grading.js
View file @
b4e80863
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
);
//
a
dd fail which is not in data
var
failBar
=
$
(
this
.
gradeCutoffTemplate
({
//
A
dd 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
...
...
cms/static/js/views/settings/main.js
View file @
b4e80863
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
())
;
}
});
...
...
cms/static/js/views/validation.js
View file @
b4e80863
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
{
...
...
cms/templates/js/course_grade_cutoff.underscore
0 → 100644
View file @
b4e80863
<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>
cms/templates/settings_graders.html
View file @
b4e80863
...
...
@@ -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>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment