Closed aalexei closed 2 years ago
@aalexei thx for the bug report. https://jsfiddle.net/6ravphnc/ has a javascript fiddle for the code to be executed
a = 3;
b = 5;
c = a * b;
d = {r: c, appName: navigator.appName, appVersion: navigator.appVersion}
alert(JSON.stringify(d))
Debugging the javscript code in justpy_core.js shows that
case 'run_javascript':
this.handleRunJavascriptEvent(msg);
break;
is triggered correctly.
which then calls the evaluation code:
/**
* Handles the run_javascript event
* @param msg
*/
handleRunJavascriptEvent(msg){
function eval_success(js_result) {
e = {
'event_type': 'result_ready',
'visibility': document.visibilityState,
'page_id': page_id,
'websocket_id': websocket_id,
'request_id': msg.request_id,
'result': js_result //JSON.stringify(js_result)
};
if (this.result_ready) {
if (msg.send) send_to_server(e, 'page_event', false);
}
}
const jsPromise = (new Promise(function () {
return eval(msg.data);
})).then(
(value) => {eval_success(value);},
(reason) => {
if (this.debug){
console.log(reason);
}
}
);
}
which shows an error in the console:
Uncaught (in promise) ReferenceError: assignment to undeclared variable a
So the javascript is not o.k. in the first place for more current javascript environments.
https://jsfiddle.net/wpdb801x/ has an improved version
var a = 3;
var b = 5;
var c = a * b;
var d = {r: c, appName: navigator.appName, appVersion: navigator.appVersion}
Oh, I don't think it's the js code. That was just an example of the problem. I've stopped being able to get javascript return values in other code that used to work. Seems wp.on("result_ready", result_ready)
doesn't trigger any more.
e.g shouldn't this trigger result_ready() callback?
async def page_ready(self, msg):
jp.run_task(msg.page.run_javascript("send_to_server('hello', 'result_ready');"))
async def result_ready(self, msg):
print('Triggered:', msg)
def result_test():
wp = jp.WebPage()
wp.on("page_ready", page_ready)
wp.on("result_ready", result_ready)
return wp
jp.justpy(result_test)
On debug setting I get:
DEBUG justpy: Socket 0 data received: {"type":"result_ready","event_data":"hello"}
but the result_ready
method doesn't get called.
Alternatively, if there is a better way to get return values from javascript I can recode my modules to use that.
The html page below uses a slight modified version of the javascript code for better debugging. See also https://jsfiddle.net/wf_bitplan_com/eaxzt5hq/19/
When entering
a = 3;
b = 5;
c = a * b;
d = {r: c, appName: navigator.appName, appVersion: navigator.appVersion};
it will try to send
{"type":"page_event","event_data":{"event_type":"result_ready","visibility":"visible","page_id":"1","websocket_id":"","result":"Error in javascript"}}
and with
var a = 3;
var b = 5;
var c = a * b;
var d = {r: c, appName: navigator.appName, appVersion: navigator.appVersion};
(d)
it will try to send
{"type":"page_event","event_data":{"event_type":"result_ready","visibility":"visible","page_id":"1","websocket_id":"","result":{"r":15,"appName":"Netscape","appVersion":"5.0 (Macintosh)"}}}
Testpage with javascript code source
<html>
<head>
<title>Javascript eval</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type='text/javascript'>
// legacy global variable
var websocket_id = '';
function evaluate_javascript(code) {
msg = {
'data': code,
'send': true
}
let justpy_core = new JustpyCore(
this,
page_id="1"
);
justpy_core.handleRunJavascriptEvent(msg)
}
// send to server surrogate for debugging
function send_to_server(e,event_type,debug_flag) {
const json_msg = JSON.stringify({'type': event_type, 'event_data': e});
document.getElementById("#result").innerText = json_msg;
}
class JustpyCore {
constructor(window,page_id) {
this.window = window;
this.page_id= page_id;
this.page_ready=true;
this.result_ready=true;
this.debug = true;
}
/**
* handle Error
*/
handleError(error) {
if (this.debug) {
console.log(error);
}
this.send_result("Error in javascript")
}
/**
* send javascript eval result back to server
* @param js_result - the javascript result to send
*/
send_result(js_result) {
let e = {
'event_type': 'result_ready',
'visibility': document.visibilityState,
'page_id': this.page_id,
'websocket_id': websocket_id,
'request_id': msg.request_id,
'result': js_result //JSON.stringify(js_result)
};
if (this.result_ready) {
if (msg.send) {
send_to_server(e, 'page_event', false);
}
}
}
/**
* Handles the run_javascript event
* @param msg
*/
handleRunJavascriptEvent(msg) {
/**
* callback to send javascript result back to server
*/
const jsPromise = new Promise((resolve, reject) => {
try{
let eval_result=eval(msg.data)
resolve(eval_result)
} catch(error){
reject(error)
}
});
jsPromise.then((value) => {
this.send_result(value);
}).catch((error) => {
this.handleError(error);
});
}
}
</script>
</head>
<body>
<textarea id="#editor" oninput="evaluate_javascript(event.currentTarget.value)" rows="4" cols="80">
a = 3;
b = 5;
c = a * b;
d = {r: c, appName: navigator.appName, appVersion: navigator.appVersion};
</textarea>
<textarea id="#result" rows="4" cols="80"></textarea>
</body>
</html>
To try the fix i am releasing a 0.11 version
Then fixed it. Thanks for your work!
The example in the docs at https://justpy.io/tutorial/page_events/#run_javascript-example no longer works. Neither does the code technique in #240. Seems
wp.on("result_ready", result_ready)
never triggers. Using Justpy 0.10.2.