diff --git a/orun/examples/cp.py b/orun/examples/cp.py index 210fe34..c646951 100644 --- a/orun/examples/cp.py +++ b/orun/examples/cp.py @@ -16,10 +16,11 @@ class MyApplication(cp.ExtApplication): wnd = Ext.create('widget.window', {'title': 'My Window', 'width': 300, 'height': 250, 'items': [{'xtype': 'button', 'text': 'Click Here', 'handler': button_click}], 'buttons': [ - {'text': 'OK', 'handler': js.FuncWithParams(ok_click, {'arg1': 1, 'arg2': 'val2'})}, - {'text': 'Close', 'handler': str(js.function('this.up(\'window\').close()'))}]}) + {'text': 'OK', 'handler': js.FuncWithParams(ok_click, {'arg1': 1, 'arg2': 'val2', 'arg3': js.cli.this.id})}, + {'text': 'Close', 'handler': js.function('this.up(\'window\').close()')}]}) wnd.show() wnd.setHeight(200) + print(repr(js.live_methods)) cp.THEME = 'classic' diff --git a/orun/extjs/base.py b/orun/extjs/base.py index 0df7f1f..b6d1d70 100644 --- a/orun/extjs/base.py +++ b/orun/extjs/base.py @@ -1,14 +1,13 @@ -import json from . import js -import re + __all__ = ['create', 'createByAlias', 'Component'] def js_ajax(fn, arg_dict = {}): i = id(fn) js.live_methods[i] = fn - func_args = ', '.join(['\'{k}\': {v}'.format( k = k,v = '\'%s\'' % v if type(v) is str else v ) for k,v in arg_dict.items()]) + func_args = ', '.join(['\'{k}\': {v}'.format( k = k,v = js.encode(v) ) for k,v in arg_dict.items()]) if func_args != '': func_args = ', ' + func_args return "%s({'url': '%s', 'method': 'GET', 'params': { 'fn': %d, 'id_': %s %s}, 'success': %s })"\ % (js.client.Ext.Ajax.request, js.AJAX_URL, i, js.client.this.id, func_args, js.function('eval(arguments[0].responseText);')) @@ -59,5 +58,4 @@ class Component(js.JsObject): pass def __str__(self): - s = json.dumps(self._js, default=js._encoder, indent=4) - return re.sub(r'("(handler|renderTo)":\s+)("([^"]+)")', r'\1\4', s) + return js.dict2extjs(self._js) diff --git a/orun/js.py b/orun/js.py index fccf3f1..2b4dec9 100644 --- a/orun/js.py +++ b/orun/js.py @@ -8,38 +8,84 @@ js_ajax = None live_methods = {} -class FuncWithParams(object): +class FuncWithParams: def __init__(self, func, params): self.func = func self.params = params -def _encoder(o): - if isinstance(o, JsObject): - return o._js - elif isinstance(o, JsNode): - return block(str(o)) - elif isinstance(o, types.FunctionType) and js_ajax: - return str(function(js_ajax(o))) - elif isinstance(o, FuncWithParams): - return str(function(js_ajax(o.func, o.params))) +def list2extjs(l): + s = '[ %s ]' + ss = [] + for v in l: + if isinstance(v, int): + ss.append('%d' % v) + elif isinstance(v, str): + ss.append('\'%s\'' % v) + elif isinstance(v, types.FunctionType): + ss.append(str(function(js_ajax(v)))) + elif isinstance(v, FuncWithParams): + ss.append(str(function(js_ajax(v.func, v.params)))) + elif isinstance(v, JsFunction): + ss.append(str(v)) + elif isinstance(v, JsNode): + ss.append(str(v)) + elif isinstance(v, dict): + ss.append(dict2extjs(v)) + elif isinstance(v, (list, tuple)): + ss.append(list2extjs(v)) + return s % ', '.join(ss) + +def dict2extjs(d): + s = '{ %s }' + ss = [] + for k, v in d.items(): + if isinstance(v, int): + ss.append('%s: %d' % (k,v)) + elif isinstance(v, str): + ss.append('%s: \'%s\'' % (k, v)) + elif isinstance(v, types.FunctionType): + ss.append('%s: %s' % (k, str(function(js_ajax(v))))) + elif isinstance(v, FuncWithParams): + ss.append('%s: %s' % (k, str(function(js_ajax(v.func, v.params))))) + elif isinstance(v, JsFunction): + ss.append('%s: %s' % (k, str(v))) + elif isinstance(v, JsNode): + ss.append('%s: %s' % (k, str(v))) + elif isinstance(v, dict): + ss.append('%s: %s' % (k, dict2extjs(v))) + elif isinstance(v, (list, tuple)): + ss.append('%s: %s' % (k, list2extjs(v))) + return s % ', '.join(ss) + def encode(o): if isinstance(o, JsNode): return str(o) elif isinstance(o, (list, tuple)): - return '[%s]' % ','.join([encode(i) for i in o]) + return list2extjs(o) + elif isinstance(o, int): + return '%d' % o + elif isinstance(o, str): + return '\'%s\'' % o + elif isinstance(o, types.FunctionType): + return str(function(js_ajax(o))) + elif isinstance(o, FuncWithParams): + return str(function(js_ajax(o.func, o.params))) + elif isinstance(o, JsFunction): + return str(o) + elif isinstance(o, JsNode): + return str(o) + elif isinstance(o, dict): + return dict2extjs(o) else: - return json.dumps(o, default=_encoder) + return o -# trick json serialize javascript block -class JsBlock(str): - def __new__(cls, *args, **kwargs): - obj = super(JsBlock, cls).__new__(cls, '%s' % args[0]) - obj.code = args[0] - return obj +class JsBlock: + def __init__(self, *args, **kwargs): + self.code = args[0] - def __str__(cls): - return cls.code + def __str__(self): + return self.code class JsFunction(JsBlock): def __str__(cls):