Browse Source

add DukWeb.eval() so that Duktape code can interface with web side, some styling etc

pull/2/head
Sami Vaarala 11 years ago
parent
commit
6a4de61167
  1. 23
      dukweb/dukweb.c
  2. 28
      dukweb/dukweb_extra.js
  3. 40
      dukweb/dukweb_test.html
  4. 15
      dukweb/style.css

23
dukweb/dukweb.c

@ -6,11 +6,22 @@
#include <stdio.h>
#include <string.h>
#include <emscripten.h>
#include "duktape.h"
static duk_context *dukweb_ctx = NULL;
static char duk__evalbuf[1024 * 1024];
static int dukweb__emscripten_run_script(duk_context *ctx) {
const char *code = duk_get_string(ctx, -1);
if (!code) {
return DUK_RET_TYPE_ERROR;
}
/* FIXME: return value */
emscripten_run_script(code);
return 0;
}
void dukweb_open(void) {
if (dukweb_ctx) {
printf("dukweb_open: heap already exists, destroying previous heap first\n");
@ -19,6 +30,16 @@ void dukweb_open(void) {
}
printf("dukweb_open: creating heap\n");
dukweb_ctx = duk_create_heap_default();
/* add a binding to emscripten_run_script(), let init code move it
* to a better place
*/
duk_push_global_object(dukweb_ctx);
duk_push_string(dukweb_ctx, "emscripten_run_script");
duk_push_c_function(dukweb_ctx, dukweb__emscripten_run_script, 1 /*nargs*/);
duk_put_prop(dukweb_ctx, -3);
duk_set_top(dukweb_ctx, 0);
}
void dukweb_close(void) {
@ -44,6 +65,8 @@ static int dukweb__tostring_wrapper(duk_context *ctx) {
/* A very limited eval facility: one string input (eval code), one string
* output (eval result or error, coerced with ToString()). Data marshalling
* needs to be implemented on top of this.
*
* FIXME: proper return value model which identifies errors from success values
*/
const char *dukweb_eval(const char *code) {
const char *res;

28
dukweb/dukweb_extra.js

@ -114,6 +114,20 @@ Duktape.eval = function(code) {
return JSON.parse(res);
};
/*
* Handlers for Duktape's print() and alert() replacements.
*/
// Expect web page to override this, e.g. to append to some buffer.
Duktape.printHandler = function(msg) {
log(msg);
}
// Expect web page to override this, e.g. to use browser alert().
Duktape.alertHandler = function(msg) {
log(msg);
}
/*
* Initialize Duktape heap automatically (not closed for now), and use
* Duktape.eval() to pull in some convenience properties like Duktape
@ -125,4 +139,18 @@ Duktape.version = Duktape.eval('Duktape.version');
Duktape.env = Duktape.eval('Duktape.env');
Duktape.logOwnProperties();
/*
* Initialize a 'DukWeb' instance inside Duktape for interfacing with the
* browser side.
*/
Duktape.eval('DukWeb = {};');
Duktape.eval('DukWeb.userAgent = ' + (JSON.stringify(navigator.userAgent.toString()) || '"unknown"') + ';');
Duktape.eval('DukWeb.emscripten_run_script = emscripten_run_script; delete this.emscripten_run_script;');
Duktape.eval('DukWeb.eval = DukWeb.emscripten_run_script;') // FIXME: better binding
Duktape.eval('DukWeb.print = function() { DukWeb.eval("Duktape.printHandler(" + JSON.stringify(Array.prototype.join.call(arguments, " ")) + ")") };');
Duktape.eval('DukWeb.alert = function() { DukWeb.eval("Duktape.alertHandler(" + JSON.stringify(Array.prototype.join.call(arguments, " ")) + ")") };');
Duktape.eval('print = DukWeb.print;');
Duktape.eval('alert = DukWeb.print;'); // intentionally bound to print()
//console.log('=== ' + Duktape.eval('Duktape.enc("jsonx", { env: Duktape.env, version: Duktape.version })') + ' ===');

40
dukweb/dukweb_test.html

@ -10,10 +10,22 @@
<h1>Dukweb.js test</h1>
<p id="dukweb-intro">Works in Chrome/Chromium. On Firefox, a "double union" self test fails
for some reason at the moment.</p>
for some reason at the moment. There is much to improve in the Duktape/browser bindings and
errors are not handled nicely yet, so keep your Javascript Console open. Also note that this
page takes a few seconds to (re)load.</p>
<textarea id="dukweb-input">
"Duktape version is " + Duktape.version
// This code runs inside the Duktape VM, print() and alert() are bound
// to more useful functions.
print("Duktape version is " + Duktape.version);
alert("alert from Duktape code");
// The DukWeb object provides bindings to access the underlying web
// environment. Most importantly, you can use DukWeb.eval() to run
// code in the browser.
DukWeb.eval('alert("your browser userAgent is: " + navigator.userAgent.toString())');
</textarea>
<div id="dukweb-evaluate-wrapper">
@ -25,18 +37,36 @@ for some reason at the moment.</p>
<script type="text/javascript">
//<![CDATA[
// Override handlers for Duktape print() and alert() replacements, because
// we want to redirect output in our own way.
var dukWebOutput = [];
function dukWebAppendOutput(txt) {
var oldtxt = $('#dukweb-output').text();
var newtxt = oldtxt + txt; // find out a better way
$('#dukweb-output').text(newtxt);
}
Duktape.printHandler = function(msg) {
dukWebAppendOutput(msg + '\n');
}
Duktape.alertHandler = function(msg) {
dukWebAppendOutput(msg + '\n');
}
$('#dukweb-evaluate').click(function () {
$('#dukweb-output').text('');
dukWebOutput = [];
var code = $('#dukweb-input').val();
try {
var res = Duktape.eval(code);
$('#dukweb-output').text(res);
dukWebAppendOutput('==> ' + res + '\n');
} catch (e) {
$('#dukweb-output').text(e.stack || e);
dukWebAppendOutput('==> ' + (e.stack || e) + '\n');
}
});
//]]>
</script>
</body>
</html>

15
dukweb/style.css

@ -3,6 +3,7 @@ body {
}
#dukweb-intro {
width: 80%;
color: #aaaaaa;
font-style: italic;
}
@ -10,13 +11,17 @@ body {
#dukweb-input {
width: 80%;
height: 20em;
border: 1px solid #cccccc;
border: 2px solid #cccccc;
border-radius: 5px;
padding: 6px;
}
#dukweb-output {
width: 80%;
height: 20em;
border: 1px solid #cccccc;
border: 2px solid #cccccc;
border-radius: 5px;
padding: 6px;
}
#dukweb-evaluate-wrapper {
@ -27,9 +32,15 @@ body {
#dukweb-evaluate {
color: #333333;
background: #eeeeff;
font-size: 200%;
border: 2px solid #ccccff;
border-radius: 5px;
padding: 8px;
}
#dukweb-evaluate:hover {
background: #f8f8ff;
cursor: pointer;
}
#dukweb-evaluate span {

Loading…
Cancel
Save