Commit 20897287 by Robert Raposa

Safe template marathon work

parent 25a7d60a
<%page expression_filter="h"/>
<%! <%!
from django.contrib.staticfiles.storage import staticfiles_storage from django.contrib.staticfiles.storage import staticfiles_storage
from pipeline_mako import compressed_css, compressed_js from pipeline_mako import compressed_css, compressed_js
from django.utils.translation import get_language_bidi from django.utils.translation import get_language_bidi
from mako.exceptions import TemplateLookupException from mako.exceptions import TemplateLookupException
from openedx.core.djangoapps.theming.helpers import get_page_title_breadcrumbs, get_value, get_template_path, get_themed_template_path, is_request_in_themed_site from openedx.core.djangolib.js_utils import js_escaped_string
from openedx.core.djangoapps.theming.helpers import (
get_page_title_breadcrumbs,
get_value,
get_template_path,
get_themed_template_path,
is_request_in_themed_site,
)
from certificates.api import get_asset_url_by_slug from certificates.api import get_asset_url_by_slug
from lang_pref.api import released_languages from lang_pref.api import released_languages
%> %>
...@@ -14,14 +22,16 @@ try: ...@@ -14,14 +22,16 @@ try:
url = staticfiles_storage.url(file) url = staticfiles_storage.url(file)
except: except:
url = file url = file
%>${url}${"?raw" if raw else ""}</%def> ## HTML-escaping must be handled by caller
%>${url | n, decode.utf8}${"?raw" if raw else ""}</%def>
<%def name='certificate_asset_url(slug)'><% <%def name='certificate_asset_url(slug)'><%
try: try:
url = get_asset_url_by_slug(slug) url = get_asset_url_by_slug(slug)
except: except:
url = '' url = ''
%>${url}</%def> ## HTML-escaping must be handled by caller
%>${url | n, decode.utf8}</%def>
<%def name='css(group, raw=False)'> <%def name='css(group, raw=False)'>
<% <%
...@@ -32,7 +42,7 @@ except: ...@@ -32,7 +42,7 @@ except:
%> %>
% if settings.PIPELINE_ENABLED: % if settings.PIPELINE_ENABLED:
${compressed_css(group, raw=raw)} ${compressed_css(group, raw=raw) | n, decode.utf8}
% else: % else:
% for filename in settings.PIPELINE_CSS[group]['source_filenames']: % for filename in settings.PIPELINE_CSS[group]['source_filenames']:
<link rel="stylesheet" href="${staticfiles_storage.url(filename.replace('.scss', '.css'))}${"?raw" if raw else ""}" type="text/css" media="all" / > <link rel="stylesheet" href="${staticfiles_storage.url(filename.replace('.scss', '.css'))}${"?raw" if raw else ""}" type="text/css" media="all" / >
...@@ -42,7 +52,7 @@ except: ...@@ -42,7 +52,7 @@ except:
<%def name='js(group)'> <%def name='js(group)'>
% if settings.PIPELINE_ENABLED: % if settings.PIPELINE_ENABLED:
${compressed_js(group)} ${compressed_js(group) | n, decode.utf8}
% else: % else:
% for filename in settings.PIPELINE_JS[group]['source_filenames']: % for filename in settings.PIPELINE_JS[group]['source_filenames']:
<script type="text/javascript" src="${staticfiles_storage.url(filename.replace('.coffee', '.js'))}"></script> <script type="text/javascript" src="${staticfiles_storage.url(filename.replace('.coffee', '.js'))}"></script>
...@@ -65,23 +75,23 @@ from django.template.engine import Engine ...@@ -65,23 +75,23 @@ from django.template.engine import Engine
from django.template.loaders.filesystem import Loader from django.template.loaders.filesystem import Loader
engine = Engine(dirs=settings.DEFAULT_TEMPLATE_ENGINE['DIRS']) engine = Engine(dirs=settings.DEFAULT_TEMPLATE_ENGINE['DIRS'])
source, template_path = Loader(engine).load_template_source(path) source, template_path = Loader(engine).load_template_source(path)
%>${source}</%def> %>${source | n, decode.utf8}</%def>
<%def name="require_module(module_name, class_name)"> <%def name="require_module(module_name, class_name)">
<script type="text/javascript"> <script type="text/javascript">
(function (require) { (function (require) {
% if settings.REQUIRE_DEBUG: % if settings.REQUIRE_DEBUG:
require(['${module_name}'], function (${class_name}) { require(['${module_name | n, js_escaped_string}'], function (${class_name | n, decode.utf8}) {
${caller.body()} ${caller.body() | n, decode.utf8}
}); });
% else: % else:
## The "raw" parameter is specified to avoid the URL from being further maninpulated by ## The "raw" parameter is specified to avoid the URL from being further maninpulated by
## static_replace calls (as woudl happen if require_module is used within courseware). ## static_replace calls (as woudl happen if require_module is used within courseware).
## Without specifying "raw", a call to static_replace would result in the MD5 hash being ## Without specifying "raw", a call to static_replace would result in the MD5 hash being
## being appended more than once, causing the import to fail in production environments. ## being appended more than once, causing the import to fail in production environments.
require(['${staticfiles_storage.url(module_name + ".js") + "?raw"}'], function () { require(['${staticfiles_storage.url(module_name + ".js") + "?raw" | n, js_escaped_string}'], function () {
require(['${module_name}'], function (${class_name}) { require(['${module_name | n, js_escaped_string}'], function (${class_name | n, decode.utf8}) {
${caller.body()} ${caller.body() | n, decode.utf8}
}); });
}); });
% endif % endif
......
<%page expression_filter="h"/>
<%inherit file="/main.html" /> <%inherit file="/main.html" />
<%namespace name='static' file='/static_content.html'/> <%namespace name='static' file='/static_content.html'/>
<%! <%!
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.template.defaultfilters import escapejs
from edxnotes.helpers import is_feature_enabled as is_edxnotes_enabled from edxnotes.helpers import is_feature_enabled as is_edxnotes_enabled
from openedx.core.djangolib.markup import HTML
from openedx.core.djangolib.js_utils import js_escaped_string
%> %>
<%def name="course_name()"> <%def name="course_name()">
<% return _("{course_number} Courseware").format(course_number=course.display_number_with_default) %> <% return _("{course_number} Courseware").format(course_number=course.display_number_with_default) %>
...@@ -38,7 +41,7 @@ ${static.get_page_title_breadcrumbs(course_name())} ...@@ -38,7 +41,7 @@ ${static.get_page_title_breadcrumbs(course_name())}
% endif % endif
<%include file="../discussion/_js_head_dependencies.html" /> <%include file="../discussion/_js_head_dependencies.html" />
${fragment.head_html()} ${HTML(fragment.head_html())}
</%block> </%block>
<%block name="js_extra"> <%block name="js_extra">
...@@ -57,37 +60,16 @@ ${static.get_page_title_breadcrumbs(course_name())} ...@@ -57,37 +60,16 @@ ${static.get_page_title_breadcrumbs(course_name())}
% endif % endif
<script type="text/javascript"> <script type="text/javascript">
var $$course_id = "${course.id | escapejs}"; var $$course_id = "${course.id | n, js_escaped_string}";
$(function(){
$(".ui-accordion-header a, .ui-accordion-content .subtitle").each(function() {
var elemText = $(this).text().replace(/^\s+|\s+$/g,''); // Strip leading and trailing whitespace
var wordArray = elemText.split(" ");
var finalTitle = "";
if (wordArray.length > 0) {
for (i=0;i<=wordArray.length-1;i++) {
finalTitle += wordArray[i];
if (i == (wordArray.length-2)) {
finalTitle += "&nbsp;";
} else if (i == (wordArray.length-1)) {
// Do nothing
} else {
finalTitle += " ";
}
}
}
$(this).html(finalTitle);
});
});
</script> </script>
${fragment.foot_html()} ${HTML(fragment.foot_html())}
</%block> </%block>
<div class="course-wrapper"> <div class="course-wrapper">
<section class="course-content" id="course-content"> <section class="course-content" id="course-content">
${fragment.body_html()} ${HTML(fragment.body_html())}
</section> </section>
</div> </div>
......
<%page expression_filter="h"/>
<%inherit file="/main.html" /> <%inherit file="/main.html" />
<%namespace name='static' file='/static_content.html'/> <%namespace name='static' file='/static_content.html'/>
<%! <%!
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.template.defaultfilters import escapejs
from django.conf import settings from django.conf import settings
from edxnotes.helpers import is_feature_enabled as is_edxnotes_enabled from edxnotes.helpers import is_feature_enabled as is_edxnotes_enabled
from openedx.core.djangolib.markup import HTML
from openedx.core.djangolib.js_utils import js_escaped_string
%> %>
<% <%
include_special_exams = settings.FEATURES.get('ENABLE_SPECIAL_EXAMS', False) and (course.enable_proctored_exams or course.enable_timed_exams) include_special_exams = settings.FEATURES.get('ENABLE_SPECIAL_EXAMS', False) and (course.enable_proctored_exams or course.enable_timed_exams)
...@@ -58,7 +61,7 @@ ${static.get_page_title_breadcrumbs(course_name())} ...@@ -58,7 +61,7 @@ ${static.get_page_title_breadcrumbs(course_name())}
% endif % endif
<%include file="../discussion/_js_head_dependencies.html" /> <%include file="../discussion/_js_head_dependencies.html" />
${fragment.head_html()} ${HTML(fragment.head_html())}
</%block> </%block>
<%block name="js_extra"> <%block name="js_extra">
...@@ -87,31 +90,10 @@ ${static.get_page_title_breadcrumbs(course_name())} ...@@ -87,31 +90,10 @@ ${static.get_page_title_breadcrumbs(course_name())}
% endif % endif
<script type="text/javascript"> <script type="text/javascript">
var $$course_id = "${course.id | escapejs}"; var $$course_id = "${course.id | n, js_escaped_string}";
$(function(){
$(".ui-accordion-header a, .ui-accordion-content .subtitle-name").each(function() {
var elemText = $(this).text().replace(/^\s+|\s+$/g,''); // Strip leading and trailing whitespace
var wordArray = elemText.split(" ");
var finalTitle = "";
if (wordArray.length > 0) {
for (i=0;i<=wordArray.length-1;i++) {
finalTitle += wordArray[i];
if (i == (wordArray.length-2)) {
finalTitle += "&nbsp;";
} else if (i == (wordArray.length-1)) {
// Do nothing
} else {
finalTitle += " ";
}
}
}
$(this).html(finalTitle);
});
});
</script> </script>
${fragment.foot_html()} ${HTML(fragment.foot_html())}
</%block> </%block>
...@@ -159,7 +141,7 @@ ${fragment.foot_html()} ...@@ -159,7 +141,7 @@ ${fragment.foot_html()}
<div class="accordion"> <div class="accordion">
<nav class="course-navigation" aria-label="${_('Course')}"> <nav class="course-navigation" aria-label="${_('Course')}">
% if accordion.strip(): % if accordion.strip():
${accordion} ${HTML(accordion)}
% else: % else:
<div class="chapter">${_("No content has been added to this course")}</div> <div class="chapter">${_("No content has been added to this course")}</div>
% endif % endif
...@@ -200,7 +182,7 @@ ${fragment.foot_html()} ...@@ -200,7 +182,7 @@ ${fragment.foot_html()}
% endif % endif
% endif % endif
${fragment.body_html()} ${HTML(fragment.body_html())}
</main> </main>
</section> </section>
......
<%page expression_filter="h"/>
<%! <%!
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
import json
from openedx.core.djangolib.markup import HTML
%> %>
<%def name="render_dropdown(map)"> <%def name="render_dropdown(map)">
% for child in map["children"]: % for child in map["children"]:
% if child in map["entries"]: % if child in map["entries"]:
${render_entry(map["entries"], child)} ${HTML(render_entry(map["entries"], child))}
%else: %else:
${render_category(map["subcategories"], child)} ${HTML(render_category(map["subcategories"], child))}
%endif %endif
%endfor %endfor
</%def> </%def>
...@@ -27,7 +29,7 @@ import json ...@@ -27,7 +29,7 @@ import json
<li class="forum-nav-browse-menu-item"> <li class="forum-nav-browse-menu-item">
<button type="button" class="forum-nav-browse-title">${category}</button> <button type="button" class="forum-nav-browse-title">${category}</button>
<ul class="forum-nav-browse-submenu"> <ul class="forum-nav-browse-submenu">
${render_dropdown(categories[category])} ${HTML(render_dropdown(categories[category]))}
</ul> </ul>
</li> </li>
</%def> </%def>
...@@ -50,6 +52,6 @@ import json ...@@ -50,6 +52,6 @@ import json
${_("Posts I'm Following")} ${_("Posts I'm Following")}
</button> </button>
</li> </li>
${render_dropdown(category_map)} ${HTML(render_dropdown(category_map))}
</ul> </ul>
</div> </div>
<%! from django.utils.translation import ugettext as _ %> <%page expression_filter="h"/>
<%!
from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import HTML
from openedx.core.djangolib.js_utils import (
dump_js_escaped_json, js_escaped_string
)
%>
<%inherit file="main.html" /> <%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%block name="pagetitle">${_('{course_number} Textbook').format(course_number=course.display_number_with_default) | h}</%block> <%block name="pagetitle">${_('{course_number} Textbook').format(course_number=course.display_number_with_default)}</%block>
<%block name="headextra"> <%block name="headextra">
<%static:css group='style-course-vendor'/> <%static:css group='style-course-vendor'/>
...@@ -30,21 +38,17 @@ ...@@ -30,21 +38,17 @@
// chapters, and it should be in-bounds. // chapters, and it should be in-bounds.
chapterToLoad = options.chapterNum; chapterToLoad = options.chapterNum;
} }
var anchorToLoad = null;
if (options.chapters) {
anchorToLoad = options.anchor_id;
}
var onComplete = function() {}; var onComplete = function() {};
if(options.notesEnabled) { if(options.notesEnabled) {
onComplete = function(url) { onComplete = function(url) {
return function() { return function() {
$('#viewerContainer').trigger('notes:init', [url, "${storage}", "${token}"]); $('#viewerContainer').trigger('notes:init', [url, "${storage | n, js_escaped_string}", "${token | n, js_escaped_string}"]);
} }
}; };
} }
loadUrl = function htmlViewLoadUrl(url, anchorId) { loadUrl = function htmlViewLoadUrl(url) {
// clear out previous load, if any: // clear out previous load, if any:
parentElement = document.getElementById('bookpage'); parentElement = document.getElementById('bookpage');
while (parentElement.hasChildNodes()) while (parentElement.hasChildNodes())
...@@ -52,19 +56,14 @@ ...@@ -52,19 +56,14 @@
// load new URL in: // load new URL in:
$('#bookpage').load(url, null, onComplete(url)); $('#bookpage').load(url, null, onComplete(url));
// if there is an anchor set, then go to that location:
if (anchorId != null) {
// TODO: add implementation....
}
}; };
loadChapterUrl = function htmlViewLoadChapterUrl(chapterNum, anchorId) { loadChapterUrl = function htmlViewLoadChapterUrl(chapterNum) {
if (chapterNum < 1 || chapterNum > chapterUrls.length) { if (chapterNum < 1 || chapterNum > chapterUrls.length) {
return; return;
} }
var chapterUrl = chapterUrls[chapterNum-1]; var chapterUrl = chapterUrls[chapterNum-1];
loadUrl(chapterUrl, anchorId); loadUrl(chapterUrl);
}; };
// define navigation links for chapters: // define navigation links for chapters:
...@@ -72,7 +71,7 @@ ...@@ -72,7 +71,7 @@
var loadChapterUrlHelper = function(i) { var loadChapterUrlHelper = function(i) {
return function(event) { return function(event) {
// when opening a new chapter, always open to the top: // when opening a new chapter, always open to the top:
loadChapterUrl(i, null); loadChapterUrl(i);
}; };
}; };
for (var index = 1; index <= chapterUrls.length; index += 1) { for (var index = 1; index <= chapterUrls.length; index += 1) {
...@@ -82,9 +81,9 @@ ...@@ -82,9 +81,9 @@
// finally, load the appropriate url/page // finally, load the appropriate url/page
if (urlToLoad != null) { if (urlToLoad != null) {
loadUrl(urlToLoad, anchorToLoad); loadUrl(urlToLoad);
} else { } else {
loadChapterUrl(chapterToLoad, anchorToLoad); loadChapterUrl(chapterToLoad);
} }
} }
...@@ -93,20 +92,17 @@ ...@@ -93,20 +92,17 @@
$(document).ready(function() { $(document).ready(function() {
var options = {}; var options = {};
%if 'url' in textbook: %if 'url' in textbook:
options.url = "${textbook['url']}"; options.url = "${textbook['url'] | n, js_escaped_string}";
%endif %endif
%if 'chapters' in textbook: %if 'chapters' in textbook:
var chptrs = []; var chptrs = [];
%for chap in textbook['chapters']: %for chap in textbook['chapters']:
chptrs.push("${chap['url']}"); chptrs.push("${chap['url'] | n, js_escaped_string}");
%endfor %endfor
options.chapters = chptrs; options.chapters = chptrs;
%endif %endif
%if chapter is not None: %if chapter is not None:
options.chapterNum = ${chapter}; options.chapterNum = ${int(chapter) | n, dump_js_escaped_json};
%endif
%if anchor_id is not UNDEFINED and anchor_id is not None:
options.anchor_id = ${anchor_id};
%endif %endif
options.notesEnabled = false; options.notesEnabled = false;
...@@ -136,7 +132,7 @@ ...@@ -136,7 +132,7 @@
</%def> </%def>
%for (index, entry) in enumerate(textbook['chapters']): %for (index, entry) in enumerate(textbook['chapters']):
${print_entry(entry, index+1)} ${HTML(print_entry(entry, index+1))}
% endfor % endfor
</ul> </ul>
</section> </section>
......
<%! from django.utils.translation import ugettext as _ %> <%page expression_filter="h"/>
<%!
from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import HTML
from openedx.core.djangolib.js_utils import (
dump_js_escaped_json, js_escaped_string
)
%>
<%inherit file="main.html" /> <%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%block name="pagetitle">${_("{course_number} Textbook").format(course_number=course.display_number_with_default) | h}</%block> <%block name="pagetitle">${_("{course_number} Textbook").format(course_number=course.display_number_with_default)}</%block>
<%block name="headextra"> <%block name="headextra">
<%static:css group='style-course-vendor'/> <%static:css group='style-course-vendor'/>
...@@ -14,7 +22,7 @@ ...@@ -14,7 +22,7 @@
<%block name="js_extra"> <%block name="js_extra">
<script type="text/javascript" src="${static.url('js/jquery.treeview.js')}"></script> <script type="text/javascript" src="${static.url('js/jquery.treeview.js')}"></script>
<script> <script>
var page=${ page }; var page = ${page | n, dump_js_escaped_json};
$(document).ready(function(){ $(document).ready(function(){
if(!page) { if(!page) {
...@@ -36,20 +44,20 @@ function goto_page(n) { ...@@ -36,20 +44,20 @@ function goto_page(n) {
if(n<10) { if(n<10) {
prefix="00"; prefix="00";
} }
$("#bookpage").attr("src","${ book_url }p"+prefix+n+".png"); $("#bookpage").attr("src","${book_url | n, js_escaped_string}p"+prefix+n+".png");
$.cookie("book_page", n, {'expires':3650, 'path':'/'}); $.cookie("book_page", n, {'expires':3650, 'path':'/'});
}; };
function prev_page() { function prev_page() {
var newpage=page-1; var newpage=page-1;
if(newpage< ${start_page}) newpage=${start_page}; if(newpage < ${start_page | n, dump_js_escaped_json}) newpage=${start_page | n, dump_js_escaped_json};
goto_page(newpage); goto_page(newpage);
Logger.log("book", {"type":"prevpage","new":page}); Logger.log("book", {"type":"prevpage","new":page});
} }
function next_page() { function next_page() {
var newpage=page+1; var newpage=page+1;
if(newpage> ${end_page}) newpage=${end_page}; if(newpage > ${end_page | n, dump_js_escaped_json}) newpage=${end_page | n, dump_js_escaped_json};
goto_page(newpage); goto_page(newpage);
Logger.log("book", {"type":"nextpage","new":page}); Logger.log("book", {"type":"nextpage","new":page});
} }
...@@ -88,7 +96,7 @@ $("#open_close_accordion a").click(function(){ ...@@ -88,7 +96,7 @@ $("#open_close_accordion a").click(function(){
% if len(entry) > 0: % if len(entry) > 0:
<ul> <ul>
% for child in entry: % for child in entry:
${print_entry(child)} ${HTML(print_entry(child))}
% endfor % endfor
</ul> </ul>
% endif % endif
...@@ -96,7 +104,7 @@ $("#open_close_accordion a").click(function(){ ...@@ -96,7 +104,7 @@ $("#open_close_accordion a").click(function(){
</%def> </%def>
% for entry in table_of_contents: % for entry in table_of_contents:
${print_entry(entry)} ${HTML(print_entry(entry))}
% endfor % endfor
## Don't delete this empty list item. Without it, Jquery.TreeView won't ## Don't delete this empty list item. Without it, Jquery.TreeView won't
...@@ -118,7 +126,7 @@ $("#open_close_accordion a").click(function(){ ...@@ -118,7 +126,7 @@ $("#open_close_accordion a").click(function(){
</ul> </ul>
</nav> </nav>
<img id="bookpage" src="${ book_url }p${ "%03i"%(page) }.png"> <img id="bookpage" src="${book_url}p${"%03i"%(page)}.png">
</section> </section>
</section> </section>
</div> </div>
......
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