Merge "Fix on async messaging to don't escape message string marked as safe."
This commit is contained in:
commit
216d566c9c
@ -22,6 +22,7 @@ messaging needs (e.g. AJAX communication, etc.).
|
||||
from django.contrib import messages as _messages
|
||||
from django.contrib.messages import constants
|
||||
from django.utils.encoding import force_unicode
|
||||
from django.utils.safestring import SafeData
|
||||
|
||||
|
||||
def add_message(request, level, message, extra_tags='', fail_silently=False):
|
||||
@ -30,8 +31,13 @@ def add_message(request, level, message, extra_tags='', fail_silently=False):
|
||||
"""
|
||||
if request.is_ajax():
|
||||
tag = constants.DEFAULT_TAGS[level]
|
||||
# if message is marked as safe, pass "safe" tag as extra_tags so that
|
||||
# client can skip HTML escape for the message when rendering
|
||||
if isinstance(message, SafeData):
|
||||
extra_tags = extra_tags + ' safe'
|
||||
request.horizon['async_messages'].append([tag,
|
||||
force_unicode(message)])
|
||||
force_unicode(message),
|
||||
extra_tags])
|
||||
else:
|
||||
return _messages.add_message(request, level, message,
|
||||
extra_tags, fail_silently)
|
||||
|
@ -98,8 +98,8 @@ class HorizonMiddleware(object):
|
||||
# Drop our messages back into the session as per usual so they
|
||||
# don't disappear during the redirect. Not that we explicitly
|
||||
# use django's messages methods here.
|
||||
for tag, message in queued_msgs:
|
||||
getattr(django_messages, tag)(request, message)
|
||||
for tag, message, extra_tags in queued_msgs:
|
||||
getattr(django_messages, tag)(request, message, extra_tags)
|
||||
redirect_response = http.HttpResponse()
|
||||
redirect_response['X-Horizon-Location'] = response['location']
|
||||
return redirect_response
|
||||
|
@ -1,9 +1,15 @@
|
||||
horizon.alert = function (type, message) {
|
||||
horizon.alert = function (type, message, extra_tags) {
|
||||
safe = false
|
||||
// Check if the message is tagged as safe.
|
||||
if (typeof(extra_tags) !== "undefined" && _.contains(extra_tags.split(' '), 'safe')) {
|
||||
safe = true
|
||||
}
|
||||
var template = horizon.templates.compiled_templates["#alert_message_template"],
|
||||
params = {
|
||||
"type": type,
|
||||
"type_capitalized": horizon.utils.capitalize(type),
|
||||
"message": message
|
||||
"message": message,
|
||||
"safe": safe
|
||||
};
|
||||
return $(template.render(params)).hide().prependTo("#main_content .messages").fadeIn(100);
|
||||
};
|
||||
@ -26,7 +32,7 @@ horizon.addInitFunction(function () {
|
||||
$("body").ajaxComplete(function(event, request, settings){
|
||||
var message_array = $.parseJSON(horizon.ajax.get_messages(request));
|
||||
$(message_array).each(function (index, item) {
|
||||
horizon.alert(item[0], item[1]);
|
||||
horizon.alert(item[0], item[1], item[2]);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -25,4 +25,14 @@ horizon.addInitFunction(function () {
|
||||
equal($('#main_content .messages .alert-success').length, 0, "Verify our success message was removed.");
|
||||
equal($('#main_content .messages .alert').length, 0, "Verify no messages remain.");
|
||||
});
|
||||
|
||||
test("Alert With HTML Tag", function () {
|
||||
safe_string = "A safe message <a>here</a>!"
|
||||
message = horizon.alert("success", safe_string, "safe");
|
||||
ok(message, "Create a message with extra tag.");
|
||||
ok((message.html().indexOf(safe_string ) != -1), 'Verify the message with HTML tag was not escaped.');
|
||||
equal($('#main_content .messages .alert').length, 1, "Verify our message was added to the DOM.");
|
||||
horizon.clearAllMessages();
|
||||
equal($('#main_content .messages .alert').length, 0, "Verify our message was removed.");
|
||||
});
|
||||
});
|
||||
|
@ -7,7 +7,15 @@
|
||||
{% jstemplate %}
|
||||
<div class="alert alert-block fade in alert-[[type]]">
|
||||
<a class="close" data-dismiss="alert" href="#">×</a>
|
||||
<p><strong>[[type_capitalized]]: </strong>[[message]]</p>
|
||||
<p>
|
||||
<strong>[[type_capitalized]]: </strong>
|
||||
[[#safe]]
|
||||
[[[message]]]
|
||||
[[/safe]]
|
||||
[[^safe]]
|
||||
[[message]]
|
||||
[[/safe]]
|
||||
</p>
|
||||
</div>
|
||||
{% endjstemplate %}
|
||||
{% endblock %}
|
||||
|
@ -120,6 +120,7 @@ class JSTemplateNode(template.Node):
|
||||
|
||||
def render(self, context, ):
|
||||
output = self.nodelist.render(context)
|
||||
output = output.replace('[[[', '{{{').replace(']]]', '}}}')
|
||||
output = output.replace('[[', '{{').replace(']]', '}}')
|
||||
output = output.replace('[%', '{%').replace('%]', '%}')
|
||||
return output
|
||||
@ -128,7 +129,8 @@ class JSTemplateNode(template.Node):
|
||||
@register.tag
|
||||
def jstemplate(parser, token):
|
||||
"""
|
||||
Replaces ``[[`` and ``]]`` with ``{{`` and ``}}`` and
|
||||
Replaces ``[[[`` and ``]]]`` with ``{{{`` and ``}}}``,
|
||||
``[[`` and ``]]`` with ``{{`` and ``}}`` and
|
||||
``[%`` and ``%]`` with ``{%`` and ``%}`` to avoid conflicts
|
||||
with Django's template engine when using any of the Mustache-based
|
||||
templating libraries.
|
||||
|
@ -18,6 +18,7 @@ import json
|
||||
|
||||
from django import http
|
||||
from django.utils.encoding import force_unicode
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from horizon import messages
|
||||
@ -29,7 +30,21 @@ class MessageTests(test.TestCase):
|
||||
def test_middleware_header(self):
|
||||
req = self.request
|
||||
string = _("Giant ants are attacking San Francisco!")
|
||||
expected = ["error", force_unicode(string)]
|
||||
expected = ["error", force_unicode(string), ""]
|
||||
self.assertTrue("async_messages" in req.horizon)
|
||||
self.assertItemsEqual(req.horizon['async_messages'], [])
|
||||
req.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
|
||||
messages.error(req, string)
|
||||
self.assertItemsEqual(req.horizon['async_messages'], [expected])
|
||||
res = http.HttpResponse()
|
||||
res = middleware.HorizonMiddleware().process_response(req, res)
|
||||
self.assertEqual(res['X-Horizon-Messages'],
|
||||
json.dumps([expected]))
|
||||
|
||||
def test_safe_message(self):
|
||||
req = self.request
|
||||
string = mark_safe(_("We are now safe from ants! Go <a>here</a>!"))
|
||||
expected = ["error", force_unicode(string), " safe"]
|
||||
self.assertTrue("async_messages" in req.horizon)
|
||||
self.assertItemsEqual(req.horizon['async_messages'], [])
|
||||
req.META['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
|
||||
|
Loading…
x
Reference in New Issue
Block a user