function openfile101(filename,mode) {
if (mode=="w") {
var tabs = document.querySelectorAll(".tabbox li");
for (var i = 0; i < tabs.length; i++) {
tabName = tabs[i].getElementsByTagName("span")[0].innerText;
if (tabName==filename) {
textareas = document.getElementsByTagName("textarea");
textareas[i+2].value="";
}
}
}
}
function filewrite101(filename,data,mode) {
var tabs = document.querySelectorAll(".tabbox li");
for (var i = 0; i < tabs.length; i++) {
tabName = tabs[i].getElementsByTagName("span")[0].innerText;
if (tabName==filename) {
textareas = document.getElementsByTagName("textarea");
if (textareas[i+2].value=="") {
textareas[i+2].value = data;
} else {
textareas[i+2].value = textareas[i+2].value + "\n" + data;
}
}
}
}
preview_div = document.getElementById("codeEditor");
editor_div = document.getElementById("preview");
split = document.getElementById("splitbar");
var editor;
split.onmousedown = function(event) {
var t = event.target;
var xCord = event.clientX-12;
//var xPercent = xCord / window.innerWidth
var xPercent = (xCord) / document.getElementById("codeSection").offsetWidth;
t.ondragstart = function() {
return false;
};
moveAt(xPercent)
function moveAt(xPercent) {
var p = (xPercent * 100).toFixed(2)
if(p < 20) { p = 20 }
if(p > 95) { p = 95 }
editor_div.style.width = (100 - p -0.5) + "%"
preview_div.style.width = (p-0.5) + "%"
}
function onMouseMove(event) {
var xCord = event.clientX;
// var yCord = event.clienty
//var xPercent = xCord / window.innerWidth
var xPercent = xCord / document.getElementById("codeSection").offsetWidth;
// var yPercent = yCord / window.innerHeight
moveAt(xPercent);
}
document.addEventListener('mousemove', onMouseMove)
t.onmouseup = function() {
document.removeEventListener('mousemove', onMouseMove)
document.removeEventListener('mouseup', onMouseMove)
t.onmouseup = null;
}
// Added InCase The Handle Get Orphaned
document.addEventListener('mouseup', () => {
document.removeEventListener('mouseup', onMouseMove)
document.removeEventListener('mousemove', onMouseMove)
})
}
function outputError(msg) {
// Display the error message
document.getElementById("error").innerHTML = "" + msg + "";
// Disable the button by changing its styles and preventing pointer events
document.getElementById("generateKeywordsButton").style.pointerEvents = "none";
document.getElementById("generateKeywordsButton").style.cursor = "not-allowed";
document.getElementById("generateKeywordsButton").style.backgroundColor = "red";
// Disable the button by changing its styles and preventing pointer events
document.getElementById("generateflowgraph").style.pointerEvents = "none";
document.getElementById("generateflowgraph").style.cursor = "not-allowed";
document.getElementById("generateflowgraph").style.backgroundColor = "red";
// Optionally, you can also store the disabled state in a flag
buttonDisabled = true;
}
function clearError() {
document.getElementById("error").innerHTML = "";
}
function changeOutput(className) {
theme = className;
document.getElementById("preview").classList=[className]
if (className=="seti") {
document.getElementById("codeEditor").style.backgroundColor="#151718";
} else if (className=="eclipse") {
document.getElementById("codeEditor").style.backgroundColor="#EEE";
} else {
document.getElementById("codeEditor").style.backgroundColor="#0F192A";
}
}
$('#codeCanvas').hide();
$(document).ready(function () {
var output = $('#edoutput');
var outf = function (text) {
if (text.endsWith('\n\n')) text=text.substring(0,text.length-1);
output.text(output.text() + text);
};
var defaultTimeLimit = Sk.execLimit;
var keymap = {
Tab: function(cm) { if (cm.somethingSelected()) { cm.indentSelection("add") } else {cm.replaceSelection(cm.getOption("indentWithTabs")? "\t": Array(cm.getOption("indentUnit") + 1).join(" "), "end", "+input") }},
"Shift-Tab": (cm) => cm.execCommand("indentLess"),
Insert: (cm) => {cm.toggleOverwrite(false)},
"Ctrl-Q": function(cm){ cm.foldCode(cm.getCursor())},
"Ctrl-Enter" : function (editor) {
if (document.getElementById("firstTab").className != "selected") {
document.getElementById("firstTab").click();
}
var tabs = document.querySelectorAll(".tabbox li");
for (var i = 0; i < tabs.length; i++) {
tabName = tabs[i].getElementsByTagName("span")[0].innerText;
if (tabName.slice(-3) != ".py") {
textareas = document.getElementsByTagName("textarea");
textareas[i+2].id=tabName;
}
}
Sk.execLimit = defaultTimeLimit;
Sk.configure({output: outf,read: builtinRead, inputfun:sInput, inputfunTakesPrompt: true, __future__: Sk.python3});
Sk.inBrowser = true;
Sk.canvas = "mycanvas";
if (editor.getValue().indexOf('turtle') > -1 ) {
$('#codeCanvas').hide()
} else {
$('#codeCanvas').hide();
}
Sk.pre = "edoutput";
(Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = 'mycanvas';
$('#edoutput').text('');
$("#programInputField").off("keyup");
$('#submitInput').off('click');
document.getElementById("inputPrompt").style.display="none";
var marks = editor.getAllMarks();
for (let i = 0; i < marks.length; i++) {marks[i].clear();}
clearError();
try {
$("#skulpt_stop").hide()
$("#skulpt_run").hide()
var pre4s = Sk.misceval.asyncToPromise(function() {
return Sk.importMainWithBody("",false,editor.getValue(),true);
});
pre4s.then(function () {
setTimeout(function() {$("#skulpt_stop").hide(); $("#skulpt_run").hide();}, 300);
console.log("Finished running the programm");
}, function (err) {
$("#skulpt_stop").hide()
$("#skulpt_run").hide()
console.info('errorHandler', err);
// do something with the Python/Skulpt errror here
var msg = err.toString().replace("ValueError:","Error: ");
if (err.traceback) {
for (let i = 0; i < err.traceback.length; i++) {
if (err.traceback[i].filename==".py") {
msg += "
> main.py line " + err.traceback[i].lineno;
} else {
msg += "
> " + err.traceback[i].filename.replace("src/lib/","") + " line " + err.traceback[i].lineno;
}
//if ("colno" in err.traceback[i]) {
// ret += " column " + err.traceback[i].colno;
// }
if (err.traceback[i].filename==".py") {
editor.markText({line: err.traceback[i].lineno-1, ch: 0}, {line: err.traceback[i].lineno, ch: 0}, {className: "line-error"});
}
}
}
outputError(msg);
});
} catch(e) {
$("#skulpt_stop").hide()
$("#skulpt_run").hide()
outf(e.toString() + "\n");
}
},
"Shift-Enter": function (editor) {
if (document.getElementById("firstTab").className != "selected") {
document.getElementById("firstTab").click();
}
var tabs = document.querySelectorAll(".tabbox li");
for (var i = 0; i < tabs.length; i++) {
tabName = tabs[i].getElementsByTagName("span")[0].innerText;
if (tabName.slice(-3) != ".py") {
textareas = document.getElementsByTagName("textarea");
textareas[i+2].id=tabName;
}
}
Sk.execLimit = defaultTimeLimit;
Sk.configure({output: outf, read: builtinRead, inputfun:sInput, inputfunTakesPrompt: true, __future__: Sk.python3});
Sk.inBrowser = true;
Sk.canvas = "mycanvas";
Sk.pre = "edoutput";
if (editor.getValue().indexOf('turtle') > -1 ) {
$('#codeCanvas').show()
} else {
$('#codeCanvas').hide();
}
try {
$('#edoutput').text('');
document.getElementById("inputPrompt").style.display="none";
var marks = editor.getAllMarks();
for (let i = 0; i < marks.length; i++) {marks[i].clear();}
clearError();
$("#programInputField").off("keyup");
$('#submitInput').off('click');
$("#skulpt_stop").hide()
$("#skulpt_run").hide()
var pre4s = Sk.misceval.asyncToPromise(function() {
return Sk.importMainWithBody("",false,editor.getValue(),true);
});
pre4s.then(function () {
setTimeout(function() {$("#skulpt_stop").hide(); $("#skulpt_run").hide();}, 300);
console.log("Finished running the programm");
}, function (err) {
$("#skulpt_stop").hide()
$("#skulpt_run").show()
console.info('errorHandler', err);
// do something with the Python/Skulpt errror here
var msg = err.toString();
if (err.traceback) {
for (let i = 0; i < err.traceback.length; i++) {
//ret += "\n at " + err.traceback[i].filename + " line " + err.traceback[i].lineno;
//if ("colno" in err.traceback[i]) {
// ret += " column " + err.traceback[i].colno;
// }
editor.markText({line: err.traceback[i].lineno-1, ch: 0}, {line: err.traceback[i].lineno, ch: 0}, {className: "line-error"});
}
}
// let ret = err.toString(); // Simple output message
// Create stacktrace message
// if (err.traceback) {
// for (let i = 0; i < err.traceback.length; i++) {
//ret += "\n at " + err.traceback[i].filename + " line " + err.traceback[i].lineno;
// if ("colno" in err.traceback[i]) {
// ret += " column " + err.traceback[i].colno;
// }
// }
// }
outputError(msg);
});
} catch(e) {
$("#skulpt_stop").hide()
$("#skulpt_run").hide()
outf(e.toString() + "\n");
}
}
}
editor = CodeMirror.fromTextArea(document.getElementById('code'), {
parserfile: ["parsepython.js"],
mode: "python",
autofocus: true,
theme: theme,
lineNumbers: true,
textWrapping: false,
indentUnit: 4,
height: "100%",
autoMatchParens: true,
extraKeys: keymap,
matchBrackets: true,
styleActiveLine: true,
foldGutter: true,
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
parserConfig: {'pythonVersion': 2, 'strictErrors': true}
});
editor.setOption("theme", theme);
changeOutput(theme);
$("#eclipse").click(function (e) {editor.setOption("theme", "eclipse"); changeOutput("eclipse");} );
$("#seti").click(function (e) {editor.setOption("theme", "seti"); changeOutput("seti");} );
$("#midnight").click(function (e) {editor.setOption("theme", "midnight"); changeOutput("midnight");} );
$("#downloadBtn").click(function (e) {
const blob = new Blob([editor.getValue()], { type: "text/plain"});
const url = URL.createObjectURL(blob);
const downloadAs = document.querySelectorAll(".nav ul li.selected")[0].innerText;
const domNode = document.createElement('a');
downloadAs && (domNode.download = downloadAs);
!downloadAs && (domNode.target = "_blank");
domNode.href = url;
domNode.style.display = 'none';
document.body.appendChild(domNode);
domNode.click();
document.body.removeChild(domNode);
} );
$("#textIncrease").click(function (e) {
var size = parseInt($('#codeSection').css('font-size'));
if (size<=24) $("#codeSection").css("font-size", (size+2) + "px");
} );
$("#textDecrease").click(function (e) {
var size = parseInt($('#codeSection').css('font-size'));
if (size>=12) $("#codeSection").css("font-size", (size-2) + "px");
} );
$("#skulpt_run").click(function (e) { keymap["Ctrl-Enter"](editor)} );
var exampleCode = function (id, text) {
$(id).click(function (e) {
editor.setValue(text);
editor.focus(); // so that F5 works, hmm
});
};
/*exampleCode('#codeexample1', "print(\"Hello, World!\")");
exampleCode('#codeexample2', "for i in range(5):\n print(i)");*/
$('#clearoutput').click(function (e) {
$('#edoutput').text('');
$('#codeCanvas').hide();
document.getElementById("inputPrompt").style.display="none";
clearError();
$("#programInputField").off("keyup");
$('#submitInput').off('click');
var marks = editor.getAllMarks();
for (let i = 0; i < marks.length; i++) {marks[i].clear();}
});
$('#helpBtn').click(function (e) {
$('#edoutput').text('');
$('#codeCanvas').hide();
document.getElementById("inputPrompt").style.display="none";
clearError();
$("#programInputField").off("keyup");
$('#submitInput').off('click');
var marks = editor.getAllMarks();
for (let i = 0; i < marks.length; i++) {marks[i].clear();}
var html = `
HELP
Help using LonePy Python Compiler
Shortcut Keys:
When using this IDE, click on your code and use the following shortcuts:
CTRL + ENTER to execute your code (equivalent to clicking the RUN button)
CTRL + A to select all of your code
CTRL + C to copy the selected code to your clipboard
CTRL + V to pasted some code from the clipboard
You can also select a section of code and use:
TAB key to indent all the selected code
SHIFT + TAB to unindent the selected code
You can collapse or expand a section of code using CTRL + Q (Based on the position of your cursor in the code)
Only sections of code that are indented can be collpased/Expanded.
You can undo and redo previous changes made to your code using:
CTRL + Z to undo changes
CTRL + Y to redo changes that have been undone.
Need help with the Python syntax?
Access the Python helpsheet by clicking on the green bar to the right -> (only availbale in full screen view)
Built-in libraries:
This IDE includes some built-in libraries that you can import in your projects including:
Turtle library (import turtle)
Random library (import random)
Time library (import time)
Datetime library (import datetime)
Math library (import math)
JSON library (import json)
`;
$('#edoutput').html(html);
});
$("#skulpt_stop").click(function (e) {
$("#skulpt_stop").hide()
$("#skulpt_run").hide()
Sk.execLimit = 1;
Sk.timeoutMsg = function() {
Sk.execLimit = defaultTimeLimit;
return "Program Stopped.";
}} );
function sInput(pprompt){
return new Promise(function(resolve,reject){
var modal = document.getElementById("inputs");
document.getElementById("inputMsg").innerText = pprompt;
document.getElementById("programInputField").innerText="";
document.getElementById("inputPrompt").style.display="block";
// When the user clicks on the button, open the modal
modal.style.display = "block";
document.getElementById("programInputField").focus();
$("#programInputField").on("keyup",function(e){
if (e.keyCode == 13)
{
// remove keyup handler from #output
$("#programInputField").off("keyup");
$('#submitInput').off('click');
// resolve the promise with the value of the input field
document.getElementById("inputPrompt").style.display="none";
outf(pprompt + " " + $("#programInputField").text() + "\n");
resolve($("#programInputField").text());
}
})
$('#submitInput').click(function (e) {
$("#programInputField").off("keyup");
$('#submitInput').off('click');
// resolve the promise with the value of the input field
document.getElementById("inputPrompt").style.display="none";
outf(pprompt + " " + $("#programInputField").text() + "\n");
resolve($("#programInputField").text());
});
});
}
function loadDependency(filename) {
return new Promise(function(resolve, reject) {
var scriptElement = document.createElement("script");
scriptElement.type = "text/javascript";
scriptElement.src = filename;
scriptElement.onload = function() {
resolve(true);
}
scriptElement.onerror = function() {
resolve(false);
}
document.body.appendChild(scriptElement);
});
}
function builtinRead(x) {
var ignoredBuiltins = ['src/builtin/os.js','src/builtin/os/__init__.js','src/lib/os.js','src/lib/os/__init__.js','./os.js','./os/__init__.js','src/builtin/os.py','src/builtin/os/__init__.py','src/lib/os.py','src/lib/os/.py'];
if (x==="src/builtin/os.js") {
return "var $builtinmodule = function (name) {var mod = {}; mod.system = new Sk.builtin.func(function (cmd) { Sk.builtin.pyCheckArgs('system', arguments, 1, 1); Sk.builtin.pyCheckType('cmd', 'string', Sk.builtin.checkString(cmd)); var value = Sk.ffi.remapToJs(cmd); if (value === 'cls' || value === 'clear') { $('#edoutput').text(''); return Sk.builtin.asnum$(0); } return new Sk.builtin.str('sh: ' + value + ': command not found.'); }); return mod;};";}
if (x==="src/builtin/json.js") {
return 'var $builtinmodule=function(r){"use strict";var e={},a=function(r){Sk.builtin.pyCheckArgs("dumps",arguments,1,1/0,!0,!1);var e,a,t,i=Array.prototype.slice.call(arguments,1),s=new Sk.builtins.dict(r),n=!1;return e={ascii:!0,separators:{item_separator:", ",key_separator:": "}},s=Sk.ffi.remapToJs(s),a=Sk.ffi.remapToJs(i[0]),"boolean"==typeof s.ensure_ascii&&!1===s.ensure_ascii&&(e.ascii=!1),"boolean"==typeof s.sort_keys&&s.sort_keys&&(n=!0),n||(e.cmp=function(r,e){return 0}),"object"==typeof s.separators&&2==s.separators.length&&(e.separators.item_separator=s.separators[0],e.separators.key_separator=s.separators[1]),s.indent&&(e.space=s.indent),s.default,t=JSON.stringify(a,e,s.indent||1),new Sk.builtin.str(t)};a.co_kwargs=!0,e.dumps=new Sk.builtin.func(a);var t=function(r){Sk.builtin.pyCheckArgs("loads",arguments,1,1/0,!0,!1);var e,a,t=Array.prototype.slice.call(arguments,1),i=new Sk.builtins.dict(r);return i=Sk.ffi.remapToJs(i),e=t[0].v,a=JSON.parse(e),Sk.ffi.remapToPy(a)};t.co_kwargs=!0,e.loads=new Sk.builtin.func(t);var i=function(r){Sk.builtin.pyCheckArgs("load",arguments,1,1/0,!0,!1);var e,a,t,i=Array.prototype.slice.call(arguments,1),s=new Sk.builtins.dict(r);return s=Sk.ffi.remapToJs(s),t=i[0],e=Sk.misceval.callsim(Sk.builtin.file.prototype.read,t).v,a=JSON.parse(e),Sk.ffi.remapToPy(a)};return i.co_kwargs=!0,e.load=new Sk.builtin.func(i),e};';}
if (Sk.builtinFiles === undefined || Sk.builtinFiles["files"][x] === undefined) {
// means this name "x" is not a builtin library in Python
if ((x.slice(0,8) === "src/lib/") && (x.slice(-3)===".py")) {
var tabs = document.querySelectorAll(".tabbox li");
for (var i = 0; i < tabs.length; i++) {
tabName = tabs[i].getElementsByTagName("span")[0].innerText;
if (tabName == x.slice(8)) {
textareas = document.getElementsByTagName("textarea");
return textareas[i+2].value;
}
}
}
else {
throw "File not found: '" + x + "'";
}
}
else {
if (Sk.builtinFiles &&
Sk.builtinFiles.files &&
Sk.builtinFiles.files[x] &&
ignoredBuiltins.indexOf(x) === -1) {
console.log('builtin: ' + x);
return Sk.builtinFiles.files[x];
}
//return Sk.builtinFiles["files"][x];
}
//}
}
editor.focus();
});
var tab=1;
var that = null;
var currentTextarea = "main";
class Tab {
constructor(id) {
that = this;
this.main = document.querySelector(id);
this.add = this.main.querySelector(".tabAdd");
this.ul = this.main.querySelector(".nav ul:first-child");
this.sectionFather = document.querySelector(".tabCon");
this.init();
}
init() {
this.updateNode();
this.add.onclick = this.addTab;
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].index = i;
this.lis[i].onclick = this.toggleTab;
if (this.remove[i]) {
this.remove[i].onclick = this.removeTab;
}
}
}
updateNode() {
this.lis = this.main.querySelectorAll("li");
this.sections = document.querySelectorAll("section");
this.remove = this.main.querySelectorAll(".nav ul .iconfont");
}
toggleTab() {
that.clearClass();
this.className = "selected";
//that.sections[this.index].className = "selected";
if (currentTextarea!="") document.getElementById(currentTextarea).value = editor.getValue();
if (this.index==0) {
currentTextarea="main";
} else {
currentTextarea=that.sections[this.index].getElementsByTagName("textarea")[0].id;
}
editor.setValue(document.getElementById(currentTextarea).value);
}
addTab() {
tab++;
var li =
'new_module.py⨯';
var sec = '';
that.clearClass();
that.ul.insertAdjacentHTML("beforeend", li);
that.sectionFather.insertAdjacentHTML("beforeend", sec);
that.init();
document.getElementById(currentTextarea).value = editor.getValue();
currentTextarea = 'code_'+tab;
editor.setValue("");
}
removeTab(e) {
e.stopPropagation();
if (window.confirm("Are you sure you would like to delete this tab and all its content?")) {
document.getElementById(currentTextarea).value = editor.getValue();
var index = this.parentNode.index;
that.lis[index].remove();
that.sections[index].remove();
that.init();
// clearClass();
//if (document.querySelector(".selected")) {
currentTextarea = "";
that.lis[0] && that.lis[0].click();
//return;
//}
index--;
currentTextarea = "";
that.lis[index] && that.lis[index].click();
//editor.setValue(document.getElementById(currentTextarea).value);
//that.lis[index][0].className="selected";
}
}
clearClass() {
for (var i = 0; i < this.lis.length; i++) {
this.lis[i].className = "";
//this.sections[i].className = "";
}
}
}
document.getElementById('exit').addEventListener('click', () => {
if (confirm('Are you sure you want to exit?')) {
window.close();
}
});
function toggleScreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen();
document.getElementById("icon101").style.display="none";
document.getElementById("icon102").style.display="inline-block";
} else if (document.exitFullscreen) {
document.exitFullscreen();
//document.getElementById("icon102").style.display="none";
//document.getElementById("icon101").style.display="inline-block";
}
}
$("#icon101").click(function (e) {
toggleScreen();
} );
$("#icon102").click(function (e) {
toggleScreen();
} );
if (document.addEventListener)
{
document.addEventListener('fullscreenchange', exitHandler, false);
document.addEventListener('mozfullscreenchange', exitHandler, false);
document.addEventListener('MSFullscreenChange', exitHandler, false);
document.addEventListener('webkitfullscreenchange', exitHandler, false);
}
function exitHandler()
{
if (!document.webkitIsFullScreen && !document.mozFullScreen && !document.msFullscreenElement)
{
document.exitFullscreen();
document.getElementById("icon102").style.display="none";
document.getElementById("icon101").style.display="inline-block";
}
}
document.getElementById("main").value = document.getElementById("code").value;