Skip to content

Commit

Permalink
feat: run_js & eval_js support set arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
wang0618 committed Oct 24, 2020
1 parent 2c45d43 commit d6c82f6
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 18 deletions.
5 changes: 4 additions & 1 deletion docs/spec.rst
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,10 @@ run_script
^^^^^^^^^^^^^^^
运行js代码

命令 spec 字段为字符串格式的要运行的js代码
命令 spec 字段:

* code: 字符串格式的要运行的js代码
* args: 传递给代码的局部变量。字典类型,字典键表示变量名,字典值表示变量值(变量值需要可以被json序列化)

download
^^^^^^^^^^^^^^^
Expand Down
29 changes: 18 additions & 11 deletions pywebio/session/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,23 +148,30 @@ def download(name, content):
send_msg('download', spec=dict(name=name, content=content))


def run_js(code):
def run_js(code, **args):
"""运行js代码.
代码运行在浏览器的JS全局作用域中
:param str code: js代码
:param args: 传递给js代码的局部变量。变量值需要可以被json序列化
Example::
run_js('console.log(a + b)', a=1, b=2)
"""
from ..io_ctrl import send_msg
send_msg('run_script', spec=code)
send_msg('run_script', spec=dict(code=code, args=args))


@chose_impl
def eval_js(expression):
def eval_js(expression, **args):
"""执行js表达式,并获取表达式的值
:param str expression: js表达式. 表达式的值需要能JSON序列化
:return: js表达式的值
:param args: 传递给js代码的局部变量。变量值需要可以被json序列化
注意⚠️:在 :ref:`基于协程 <coroutine_based_session>` 的会话上下文中,需要使用 ``await eval_js(expression)`` 语法来进行调用。
Expand All @@ -174,29 +181,29 @@ def eval_js(expression):
function_res = eval_js('''(function(){
var a = 1;
a += 100;
a += b;
return a;
})()''')
})()''', b=100)
"""
script = r"""
(function(WebIO){
let result = null;
let ____result____ = null; // to avoid naming conflict
try{
result = eval(%r);
____result____ = eval(%r);
}catch{};
WebIO.sendMessage({
event: "js_yield",
task_id: WebIOCurrentTaskID, // local var in run_script command
data: result || null
data: ____result____ || null
});
})(WebIO);""" % expression

run_js(script)
run_js(script, **args)

res = yield next_client_event()
assert res[
'event'] == 'js_yield', "Internal Error, please report this bug on https://github.com/wang0618/PyWebIO/issues"
assert res['event'] == 'js_yield', "Internal Error, please report this bug on " \
"https://github.com/wang0618/PyWebIO/issues"
return res['data']


Expand Down
5 changes: 2 additions & 3 deletions test/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,11 +365,10 @@ def test_output(browser: Chrome, enable_percy=False):

def basic_input():
js_res = yield eval_js('''(function(){
var a = 0;
for(var i=0;i<=100;i++)
for(var i=0;i<=limit;i++)
a += i;
return a;
})()''')
})()''', a=0, limit=100)
assert js_res == 5050

age = yield input("How old are you?", type=NUMBER)
Expand Down
12 changes: 9 additions & 3 deletions webiojs/src/handlers/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ export class ScriptHandler implements CommandHandler {
}

handle_message(msg: Command) {
let script = msg.spec as string;
const script_func = new Function('WebIOCurrentTaskID', script);
script_func(msg.task_id);
let script = msg.spec.code as string;
let args = msg.spec.args as { [i: string]: any };
let arg_names:string[] = ['WebIOCurrentTaskID'], arg_vals:any[] = [msg.task_id];
for(let key in args){
arg_names.push(key);
arg_vals.push(args[key]);
}
const script_func = new Function(...arg_names, script);
script_func(...arg_vals);
}
}

0 comments on commit d6c82f6

Please sign in to comment.