You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
webperl-for/experiments/democode/perlrunner.html

132 lines
4.3 KiB
HTML

<!doctype html>
<html lang="en-us">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebPerl Perl Runner</title>
<!-- ----- WebPerl - http://webperl.zero-g.net -----
Copyright (c) 2018 Hauke Daempfling (haukex@zero-g.net)
at the Leibniz Institute of Freshwater Ecology and Inland Fisheries (IGB),
Berlin, Germany, http://www.igb-berlin.de
This program is free software; you can redistribute it and/or modify
it under the same terms as Perl 5 itself: either the GNU General Public
License as published by the Free Software Foundation (either version 1,
or, at your option, any later version), or the "Artistic License" which
comes with Perl 5.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the licenses for details.
You should have received a copy of the licenses along with this program.
If not, see http://perldoc.perl.org/index-licence.html
-->
<!-- Possible To-Do for Later: This whole thing could probably also be
accomplished with a Web Worker, but that would probably require a
stripped-down version of webperl.js (that loads things without
using window.* and especially document.*
https://developer.mozilla.org/en-US/docs/Web/API/Worker/Worker
https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/importScripts
-->
<script src="../webperl.js"></script>
<!--script src="https://webperlcdn.zero-g.net/v0.07-beta/webperl.js"
integrity="sha256-jL8SB7St5ou4+hb0frK0k6VCQXsWQ1wolDrdU7i4juc" crossorigin="anonymous"></script-->
<script>
"use strict";
Perl.noMountIdbfs=true; // we're sandboxed
Perl.endAfterMain=true; // act like command-line perl
var knownClients = [];
var currentClient; // which client we're running Perl for, also keeps state
Perl.addStateChangeListener(function (from,to) {
if (from==to) return; // won't be needed as of v0.09-beta
for(var i=0; i<knownClients.length; i++)
knownClients[i].postMessage({ perlRunnerState: Perl.state },'*');
if (to=="Ended") {
if (currentClient) {
for (var c=1;c<=2;c++) // flush buffers
if (stdbuf[c].length)
currentClient.postMessage({ perlOutput: { chan:c, data:stdbuf[c] } },'*');
//TODO: how to handle nonzero exit codes and communicate them back to the client
//TODO: post output files
}
else console.error("state change to Ended with no current client?");
window.location.reload(false);
}
});
var stdbuf = [null,'',''];
Perl.output = function (str,chan) {
stdbuf[chan] += str;
var pos = stdbuf[chan].lastIndexOf("\n");
if (pos>-1) {
var line = stdbuf[chan].slice(0,pos);
if (currentClient)
currentClient.postMessage({ perlOutput: { chan:chan, data:line+"\n" } },'*');
else
console.warn("output on",chan==1?"STDOUT":"STDERR",
"with no client?",line);
stdbuf[chan] = stdbuf[chan].slice(pos+1);
}
};
Perl.init(function () {
FS.currentPath = ENV.HOME; // NOTE: https://github.com/kripken/emscripten/issues/5873
window.addEventListener('message', function (event) {
var data = event.data;
var result;
if (data["perlRunnerRegisterClient"]) {
result = { perlRunnerState: Perl.state };
if (!knownClients.includes(event.source))
knownClients.push(event.source);
}
else if (data["runPerl"]) {
if (!knownClients.includes(event.source))
knownClients.push(event.source);
if (currentClient) {
//TODO Later: a way to communicate these errors back to client?
console.error("Attempt to run Perl from",event.source,
"but am already running Perl for",currentClient);
return;
}
if (Perl.state!="Ready") {
console.error("Attempt to run Perl in state",Perl.state,
"from",event.source);
return;
}
currentClient = event.source;
var scriptFn = data.runPerl["scriptName"]
? data.runPerl.scriptName : 'script.pl';
Module['thisProgram'] = './'+scriptFn;
FS.writeFile( FS.joinPath([FS.cwd(), scriptFn]),
data.runPerl.script );
//TODO: input files
var argv = data.runPerl["argv"] ? data.runPerl.argv : [scriptFn];
Perl.start(argv);
}
else console.warn("Perl Runner ignoring unknown message:", data);
//console.log("runner got message", data, "result", result); //DB
if (result)
event.source.postMessage(result,
event.origin==null || event.origin=="null" ? '*' : event.origin);
});
});
</script>
</head>
<body>
</body>
</html>