# HG changeset patch # User Sylvain Thénault # Date 1309356789 -7200 # Node ID 335f14e8e5a753e5f76c795bf297cfe81111c3d0 # Parent 34154f48d255287e244f8d8edb7de2cc6483903b [uilib] new js_dumps function allowing usage of bare js string (wrapped into JSString) modify magic 'js' object to consider them as well diff -r 34154f48d255 -r 335f14e8e5a7 uilib.py --- a/uilib.py Wed Jun 29 16:04:01 2011 +0200 +++ b/uilib.py Wed Jun 29 16:13:09 2011 +0200 @@ -31,7 +31,7 @@ from logilab.mtconverter import xml_escape, html_unescape from logilab.common.date import ustrftime -from cubicweb.utils import json_dumps +from cubicweb.utils import JSString, json_dumps def rql_for_eid(eid): @@ -281,16 +281,23 @@ self.args = args self.parent = parent def __unicode__(self): - args = u','.join(json_dumps(arg) for arg in self.args) + args = [] + for arg in self.args: + if isinstance(arg, JSString): + args.append(arg) + else: + args.append(json_dumps(arg)) if self.parent: - return u'%s(%s)' % (self.parent, args) - return args + return u'%s(%s)' % (self.parent, ','.join(args)) + return ','.join(args) class _JS(object): def __getattr__(self, attr): return _JSId(attr) -"""magic object to return strings suitable to call some javascript function with +js = _JS() +js.__doc__ = """\ +magic object to return strings suitable to call some javascript function with the given arguments (which should be correctly typed). >>> str(js.pouet(1, "2")) @@ -298,9 +305,10 @@ >>> str(js.cw.pouet(1, "2")) 'cw.pouet(1,"2")' >>> str(js.cw.pouet(1, "2").pouet(None)) -'cw.pouet(1,"2").pouet(null)') +'cw.pouet(1,"2").pouet(null)' +>>> str(js.cw.pouet(1, JSString("$")).pouet(None)) +'cw.pouet(1,$).pouet(null)' """ -js = _JS() def domid(string): """return a valid DOM id from a string (should also be usable in jQuery diff -r 34154f48d255 -r 335f14e8e5a7 utils.py --- a/utils.py Wed Jun 29 16:04:01 2011 +0200 +++ b/utils.py Wed Jun 29 16:13:09 2011 +0200 @@ -444,7 +444,7 @@ else: import json except ImportError: - json_dumps = None + json_dumps = JSString = None else: from logilab.common.date import ustrftime @@ -478,6 +478,40 @@ return json.dumps(value, cls=CubicWebJsonEncoder) + class JSString(str): + """use this string sub class in values given to :func:`js_dumps` to + insert raw javascript chain in some JSON string + """ + + def _dict2js(d, predictable=False): + res = [key + ': ' + js_dumps(val, predictable) + for key, val in d.iteritems()] + return '{%s}' % ', '.join(res) + + def _list2js(l, predictable=False): + return '[%s]' % ', '.join([js_dumps(val, predictable) for val in l]) + + def js_dumps(something, predictable=False): + """similar as :func:`json_dumps`, except values which are instances of + :class:`JSString` are expected to be valid javascript and will be output + as is + + >>> js_dumps({'hop': JSString('$.hop'), 'bar': None}, predictable=True) + '{bar: null, hop: $.hop}' + >>> js_dumps({'hop': '$.hop'}) + '{hop: "$.hop"}' + >>> js_dumps({'hip': {'hop': JSString('momo')}}) + '{hip: {hop: momo}}' + """ + if isinstance(something, dict): + return _dict2js(something, predictable) + if isinstance(something, list): + return _list2js(something, predictable) + if isinstance(something, JSString): + return something + return json_dumps(something) + + @deprecated('[3.7] merge_dicts is deprecated') def merge_dicts(dict1, dict2): """update a copy of `dict1` with `dict2`"""