Work on "democode" experiment (curr. not working)

Currently not working!
master
Hauke D 7 years ago
parent 1784206275
commit 044c55394e

@ -7,7 +7,7 @@
<iframe name="perlrunner" sandbox="allow-scripts" <iframe name="perlrunner" sandbox="allow-scripts"
src="perlrunner.html" style="display: none;"></iframe> src="perlrunner.html" style="display: none;"></iframe>
<iframe sandbox="allow-scripts" src="perleditor.html" <iframe sandbox="allow-scripts" src="perleditor.html#i1f=Foo%0ABar%0AQuz&i1n=in1.txt&script=use warnings;%0Ause strict;%0A%0Awhile (<>) {%0A s/[aeiou]/_/gi;%0A}&cmdline=perl script.pl in1.txt"
style="border:1px solid black;width:100%;height:20em;"></iframe> style="border:1px solid black;width:100%;height:20em;"></iframe>
<iframe sandbox="allow-scripts" src="perleditor.html" <iframe sandbox="allow-scripts" src="perleditor.html"

@ -36,16 +36,18 @@ body {
.text { .text {
font-family: Calibri, Ubuntu, "Droid Sans", Tahoma, Arial, Helvetica, sans-serif; font-family: Calibri, Ubuntu, "Droid Sans", Tahoma, Arial, Helvetica, sans-serif;
} }
pre,textarea,code,.code,.CodeMirror { pre,textarea,code,.code,.filename,.CodeMirror {
font-family: Consolas, "Ubuntu Mono", "Droid Sans Mono", "Lucida Console", "Courier New", Courier, monospace; font-family: Consolas, "Ubuntu Mono", "Droid Sans Mono", "Lucida Console", "Courier New", Courier, monospace;
} }
pre { pre {
margin: 0; margin: 0;
} }
.cm-resize-frame { .CodeMirror {
overflow: hidden;
resize: vertical;
border: 1px solid grey; border: 1px solid grey;
height: auto;
}
.CodeMirror-scroll {
max-height: 10em;
} }
</style> </style>
@ -55,43 +57,37 @@ pre {
integrity="sha256-Uu9QBfi8gU6J/MzQunal8ewmY+i/BbCkBrcAXA5bcCM=" crossorigin="anonymous"></script> integrity="sha256-Uu9QBfi8gU6J/MzQunal8ewmY+i/BbCkBrcAXA5bcCM=" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" <script src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script> integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script> <script>
"use strict"; "use strict";
function makeCM (textarea,plain,ro) { function makeCM (textarea,plain,ro) {
var resize_frame = $('<div/>').addClass("cm-resize-frame"); return CodeMirror.fromTextArea( textarea[0], {
textarea.wrap(resize_frame);
var cm = CodeMirror.fromTextArea( textarea[0], {
viewportMargin: Infinity, // so browser's search works, not good for long documents though viewportMargin: Infinity, // so browser's search works, not good for long documents though
lineNumbers:true, indentWithTabs:true, lineNumbers:true, indentWithTabs:true,
tabSize:4, indentUnit:4, tabSize:4, indentUnit:4,
mode: plain?"text/plain":"perl", mode: plain?"text/plain":"perl",
readOnly: ro?true:false, readOnly: ro?true:false,
} ); } );
// Thanks to https://codepen.io/sakifargo/pen/KodNyR
//cm.setSize(null,'auto'); //TODO: this causes the auto-resize to no longer work
//TODO: but if we remove the above line, we don't get any more scroll bars...
var fr = resize_frame[0];
var cm_resize = function() { cm.setSize(fr.clientWidth + 2, fr.clientHeight - 10); };
//cm_resize(); //TODO: if I call this here, the CM's width shrinks to zero, why?
if (window.ResizeObserver)
new ResizeObserver(cm_resize).observe(fr);
else if (window.MutationObserver)
new MutationObserver(cm_resize).observe(fr, {attributes: true});
return cm;
} }
var cm_std = { 1:null, 2:null }; // 1=stdout, 2=stderr var mergeStdOutErr = 0;
var cm_std = { 1:null, 2:null }; // 1=stdout, 2=stderr
function stdOutput (which, data) { // 1=stdout, 2=stderr function stdOutput (which, data) { // 1=stdout, 2=stderr
if (mergeStdOutErr) which = 1;
if (!cm_std[which]) { if (!cm_std[which]) {
var d = $(which==1?'#stdout':'#stderr'); var div = $(which==1?'#stdout':'#stderr');
d.show(); div.show();
cm_std[which] = makeCM($('textarea',d),1,1); cm_std[which] = makeCM($('textarea',div),1,1);
div.data('CodeMirrorInstance', cm_std[which]);
} }
if (data && data.length) if (data && data.length)
cm_std[which].setValue( cm_std[which].getValue() + data ); cm_std[which].setValue( cm_std[which].getValue() + data );
} }
function clearStdOutput () {
if (cm_std["1"]) cm_std["1"].setValue("");
if (cm_std["2"]) cm_std["2"].setValue("");
}
var perlRunner; var perlRunner;
@ -134,7 +130,7 @@ function findPerlRunner () {
}, 100); }, 100);
} }
function parseCmdLine(str) { //TODO: use this function parseCmdLine(str) {
var re = /"((?:\\"|\\\\|[^"])*)"|'((?:\\'|\\\\|[^'])*)'|(\S+)/g; var re = /"((?:\\"|\\\\|[^"])*)"|'((?:\\'|\\\\|[^'])*)'|(\S+)/g;
var argv = []; var argv = [];
var match; var match;
@ -157,35 +153,87 @@ function parseParams(str) { // Thanks to https://stackoverflow.com/a/26849194
}, {}); }, {});
} }
function hashchange () { //TODO: implement function initialize (hash) {
var hash = parseParams(window.location.hash); console.log("hash", hash); //DB
//console.log("hash", hash); // script
if (hash["script"] || hash["scripturl"]) {
var script = $('#script');
script.show();
var cm = makeCM($('#perlcode'));
script.data('CodeMirrorInstance', cm);
if (hash["script"])
cm.setValue(hash.script);
else if (hash["scripturl"]) {
//TODO: fetch URL
}
else throw "internal error: this shouldn't happen";
if (hash["scriptfn"])
$('.filename',script).text(hash.scriptfn);
}
if (hash["cmdline"]) {
$('#argv').val(hash.cmdline);
}
// input files
$('.inputs').remove();
for (var i=1;;i++) {
if (!( hash["i"+i+"f"] || hash["i"+i+"u"] )) break;
var fn = hash["i"+i+"n"] || "input"+i+".txt";
var div = $('<div/>',{class:"codewithfn inputs"});
div.append( $('<div/>',{class:"filename",text:fn}) );
var ta = $('<textarea/>').appendTo(div);
$('#inputhere').before(div);
var cm = makeCM(ta,1,0);
div.data('CodeMirrorInstance', cm);
if (hash["i"+i+"f"]) {
cm.setValue(hash["i"+i+"f"]);
}
else if (hash["i"+i+"u"]) {
//TODO: fetch URLs
}
}
// stdout/stderr
if (hash["mergestdouterr"]) {
mergeStdOutErr = 1;
$('#stdout>.filename').text("STDOUT+STDERR");
}
else {
mergeStdOutErr = 0;
$('#stdout>.filename').text("STDOUT");
}
clearStdOutput();
// output files
for (var i=1;;i++) {
if (hash["o"+i+"n"]) {
var div = $('<div/>',{class:"codewithfn outputs"});
div.append( $('<div/>',{class:"filename",text:hash["o"+i+"n"]}) );
var ta = $('<textarea/>').appendTo(div);
$('#outputhere').before(div);
var cm = makeCM(ta,1,1);
div.data('CodeMirrorInstance', cm);
}
else break;
}
} }
//$(window).on('hashchange',hashchange); //TODO: should we support this? or just messages?
hashchange();
$(function () { $(function () {
var perl_cm = makeCM($('#perlcode')); initialize(parseParams(window.location.hash.substr(1)));
var btn_runperl = $('#runperl'); var btn_runperl = $('#runperl');
btn_runperl.click( function () { btn_runperl.click( function () {
if (cm_std["1"]) cm_std["1"].setValue(""); clearStdOutput();
if (cm_std["2"]) cm_std["2"].setValue("");
var runperl = {
//TODO: input files
script: perl_cm.getValue(),
};
var argv = parseCmdLine($('#argv').val()); var argv = parseCmdLine($('#argv').val());
if (argv.length<1 || argv[0]!="perl") { if (argv.length<1 || argv[0]!="perl") {
console.error("invalid command line"); console.error("invalid command line");
return; return }
} else argv.shift();
else {
argv.shift(); var runperl = {
runperl.argv = argv; //TODO: input files
} argv: argv,
//TODO: script: perl_cm.getValue(),
};
btn_runperl.prop("disabled",true); btn_runperl.prop("disabled",true);
perlRunner.postMessage({ runPerl: runperl },'*'); perlRunner.postMessage({ runPerl: runperl },'*');
@ -200,31 +248,29 @@ $(function () {
</head> </head>
<body> <body>
<div> <div id="inputhere" style="display:none;"></div>
<input type="text" id="argv" class="code" size="60" value='perl script.pl'/>
</div>
<textarea id="perlcode"> <div id="script" class="codewithfn" style="display:none;">
use warnings; <div class="filename">script.pl</div>
use strict; <textarea id="perlcode"></textarea>
</div>
print "Hello, World!\n";
</textarea>
<div class="text" style="text-align:right;"> <div>
<button id="runperl"><code>perl</code> &#x25BA;</button> <button id="runperl"><code>perl</code> &#x25BA;</button>
<input type="text" id="argv" class="code" size="60" value='perl' />
</div> </div>
<div id="stdout" style="display:none;"> <div id="stdout" class="codewithfn" style="display:none;">
<code>STDOUT:</code><br/> <div class="filename">STDOUT</div>
<textarea></textarea> <textarea></textarea>
</div> </div>
<div id="stderr" style="display:none;"> <div id="stderr" class="codewithfn" style="display:none;">
<code>STDERR:</code><br/> <div class="filename">STDERR</div>
<textarea></textarea> <textarea></textarea>
</div> </div>
<div id="outputhere" style="display:none;"></div>
</body> </body>
</html> </html>

@ -25,8 +25,9 @@ You should have received a copy of the licenses along with this program.
If not, see http://perldoc.perl.org/index-licence.html If not, see http://perldoc.perl.org/index-licence.html
--> -->
<script src="https://webperlcdn.zero-g.net/v0.07-beta/webperl.js" <script src="../webperl.js"></script>
integrity="sha256-jL8SB7St5ou4+hb0frK0k6VCQXsWQ1wolDrdU7i4juc" crossorigin="anonymous"></script> <!--script src="https://webperlcdn.zero-g.net/v0.07-beta/webperl.js"
integrity="sha256-jL8SB7St5ou4+hb0frK0k6VCQXsWQ1wolDrdU7i4juc" crossorigin="anonymous"></script-->
<script> <script>
"use strict"; "use strict";
@ -42,14 +43,13 @@ Perl.addStateChangeListener(function (from,to) {
knownClients[i].postMessage({ perlRunnerState: Perl.state },'*'); knownClients[i].postMessage({ perlRunnerState: Perl.state },'*');
if (to=="Ended") { if (to=="Ended") {
if (currentClient) { if (currentClient) {
for (var c=1;c<=2;c++) { for (var c=1;c<=2;c++) // flush buffers
if (stdbuf[c].length) if (stdbuf[c].length)
currentClient.postMessage({ perlOutput: { chan:c, data:stdbuf[c] } },'*'); 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?"); else console.error("state change to Ended with no current client?");
//TODO: how to handle nonzero exit codes and communicate them back to the client
//TODO: post output files
window.location.reload(false); window.location.reload(false);
} }
}); });

Loading…
Cancel
Save