Merge pull request #2194 from leonelcamara/patch-31
Fixes #2182 possibly Fixes #2190
This commit is contained in:
+37
-7
@@ -119,13 +119,43 @@ def xml(value, encoding='UTF-8', key='document', quote=True):
|
|||||||
return ('<?xml version="1.0" encoding="%s"?>' % encoding) + str(xml_rec(value, key, quote))
|
return ('<?xml version="1.0" encoding="%s"?>' % encoding) + str(xml_rec(value, key, quote))
|
||||||
|
|
||||||
|
|
||||||
def json(value, default=custom_json, indent=None, sort_keys=False):
|
class JSONEncoderForHTML(json_parser.JSONEncoder):
|
||||||
value = json_parser.dumps(value, default=default, sort_keys=sort_keys, indent=indent)
|
"""An encoder that produces JSON safe to embed in HTML.
|
||||||
# replace JavaScript incompatible spacing
|
To embed JSON content in, say, a script tag on a web page, the
|
||||||
# http://timelessrepo.com/json-isnt-a-javascript-subset
|
characters &, < and > should be escaped. They cannot be escaped
|
||||||
# PY3 FIXME
|
with the usual entities (e.g. &) because they are not expanded
|
||||||
# return value.replace(ur'\u2028', '\\u2028').replace(ur'\2029', '\\u2029')
|
within <script> tags.
|
||||||
return value
|
This class also escapes the line separator and paragraph separator
|
||||||
|
characters U+2028 and U+2029, irrespective of the ensure_ascii setting,
|
||||||
|
as these characters are not valid in JavaScript strings (see
|
||||||
|
http://timelessrepo.com/json-isnt-a-javascript-subset).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def encode(self, o):
|
||||||
|
# Override JSONEncoder.encode because it has hacks for
|
||||||
|
# performance that make things more complicated.
|
||||||
|
chunks = self.iterencode(o, True)
|
||||||
|
if self.ensure_ascii:
|
||||||
|
return ''.join(chunks)
|
||||||
|
else:
|
||||||
|
return u''.join(chunks)
|
||||||
|
|
||||||
|
def iterencode(self, o, _one_shot=False):
|
||||||
|
chunks = super(JSONEncoderForHTML, self).iterencode(o, _one_shot)
|
||||||
|
for chunk in chunks:
|
||||||
|
chunk = chunk.replace('&', '\\u0026')
|
||||||
|
chunk = chunk.replace('<', '\\u003c')
|
||||||
|
chunk = chunk.replace('>', '\\u003e')
|
||||||
|
|
||||||
|
if not self.ensure_ascii:
|
||||||
|
chunk = chunk.replace(u'\u2028', '\\u2028')
|
||||||
|
chunk = chunk.replace(u'\u2029', '\\u2029')
|
||||||
|
|
||||||
|
yield chunk
|
||||||
|
|
||||||
|
|
||||||
|
def json(value, default=custom_json, indent=None, sort_keys=False, cls=JSONEncoderForHTML):
|
||||||
|
return json_parser.dumps(value, default=default, cls=cls, sort_keys=sort_keys, indent=indent)
|
||||||
|
|
||||||
def csv(value):
|
def csv(value):
|
||||||
return ''
|
return ''
|
||||||
|
|||||||
@@ -50,7 +50,8 @@ class TestSerializers(unittest.TestCase):
|
|||||||
lazy_translation = T('abc')
|
lazy_translation = T('abc')
|
||||||
self.assertEqual(json(lazy_translation), u'"abc"')
|
self.assertEqual(json(lazy_translation), u'"abc"')
|
||||||
# html helpers are xml()ed before too
|
# html helpers are xml()ed before too
|
||||||
self.assertEqual(json(SPAN('abc')), u'"<span>abc</span>"')
|
self.assertEqual(json(SPAN('abc'), cls=None), u'"<span>abc</span>"')
|
||||||
|
self.assertEqual(json(SPAN('abc')), u'"\\u003cspan\\u003eabc\\u003c/span\\u003e"')
|
||||||
# unicode keys make a difference with loads_json
|
# unicode keys make a difference with loads_json
|
||||||
base = {u'è': 1, 'b': 2}
|
base = {u'è': 1, 'b': 2}
|
||||||
base_enc = json(base)
|
base_enc = json(base)
|
||||||
|
|||||||
Reference in New Issue
Block a user