-
Console
Javascript
Files
Help
+
Console
Javascript
Files
Help
@@ -63,8 +63,9 @@
@@ -92,15 +93,15 @@
Copy the link below to share your code:
Launch Mode:
-
-
Export
-
Close
-
Test
+
Export
+
Close
+
Test
@@ -139,14 +140,14 @@
QBJS brings the fun and accessibility of QBasic to the browser.
Learn more:
Copyright (c) 2022-2023 boxgaming
diff --git a/lib/web/console.bas b/lib/web/console.bas
index 7c86083..18c9580 100644
--- a/lib/web/console.bas
+++ b/lib/web/console.bas
@@ -42,19 +42,20 @@ Sub Log (msg As String, msgType As String)
console.log(msgType + ":" + msg);
return;
}
- var errorLine = await getErrorLine(new Error(), 1);
+ var errorLine = await IDE.getErrorLine(new Error(), 1);
var tr = document.createElement("tr");
- addWarningCell(tr, msgType);
- addWarningCell(tr, ":");
- addWarningCell(tr, errorLine);
- addWarningCell(tr, ":");
- addWarningCell(tr, await func_EscapeHtml(msg), "99%");
+ IDE.addWarningCell(tr, msgType);
+ IDE.addWarningCell(tr, ":");
+ IDE.addWarningCell(tr, errorLine);
+ IDE.addWarningCell(tr, ":");
+ IDE.addWarningCell(tr, await func_EscapeHtml(msg), "99%");
tr.codeLine = errorLine - 1;
- tr.onclick = gotoWarning;
+ tr.onclick = IDE.gotoWarning;
t.append(tr);
var container = document.getElementById("output-content");
container.scrollTop = container.scrollHeight;
- changeTab("console");
+ IDE.changeTab("console");
+ IDE.showConsole();
$End If
End Sub
@@ -66,12 +67,13 @@ Sub Echo (msg As String)
return;
}
var tr = document.createElement("tr");
- addWarningCell(tr, await func_EscapeHtml(msg));
+ IDE.addWarningCell(tr, await func_EscapeHtml(msg));
tr.firstChild.colSpan = "5";
t.append(tr);
var container = document.getElementById("output-content");
container.scrollTop = container.scrollHeight;
- changeTab("console");
+ IDE.changeTab("console");
+ IDE.showConsole();
$End If
End Sub
diff --git a/qbjs-ide.css b/qbjs-ide.css
index fa86865..9748a7d 100644
--- a/qbjs-ide.css
+++ b/qbjs-ide.css
@@ -193,6 +193,7 @@ dialog textarea,
}
dialog a { color: #333 !important; }
dialog a:hover { color: #000 !important; }
+dialog a.disabled, dialog a.disabled:hover { color: #999 !important; }
#logo {
position: absolute;
@@ -213,7 +214,7 @@ dialog a:hover { color: #000 !important; }
padding: 5px;
border: 1px solid #333;
}
-#fs-refresh, #fs-new-folder {
+#fs-refresh, #fs-new-folder, #fs-upload {
float: right;
margin-top: -3px;
cursor: pointer;
@@ -236,6 +237,13 @@ dialog a:hover { color: #000 !important; }
#fs-new-folder:hover {
background-image: url('img/new-folder-hover.svg');
}
+#fs-upload {
+ margin-right: 8px;
+ background-image: url('img/upload.svg');
+}
+#fs-upload:hover {
+ background-image: url('img/upload-hover.svg');
+}
.fs-file, .fs-dir, .fs-delete {
display: block;
diff --git a/qbjs-ide.js b/qbjs-ide.js
index 47b4cc5..86532e3 100644
--- a/qbjs-ide.js
+++ b/qbjs-ide.js
@@ -1,982 +1,1073 @@
-var QBCompiler = null;
-// if code has been passed on the query string load it into the editor
-var qbcode = "";
-var url = location.href;
-var sizeMode = "normal";
-var appMode = "ide";
-var consoleVisible = false;
-var currTab = "js";
-var editor;
-var selectedError = null;
-var currPath = "/";
-var mainProg = null;
-var theme = "qbjs";
-var splitWidth = 600;
-var splitHeight = 327;
-var sliding = false;
-var vsliding = false;
-var _e = {
- ideTheme: _el("ide-theme"),
- loadScreen: _el("gx-load-screen"),
- jsCode: _el("js-code"),
- warningContainer: _el("warning-container"),
- gxContainer: _el("gx-container"),
- shareMode: _el("share-mode"),
- shareCode: _el("share-code"),
- shareDialog: _el("share-dialog"),
- exportButton: _el("export-button"),
- fileInput: _el("file-input"),
- progSelSources: _el("prog-sel-sources"),
- progSelDialog: _el("prog-sel-dialog"),
- optionsDialog: _el("options-dialog"),
- aboutDialog: _el("about-dialog"),
- toolbar: _el("toolbar"),
- tbConsoleShow: _el("toolbar-button-console-show"),
- tbConsoleHide: _el("toolbar-button-console-hide"),
- tbSlideRight: _el("toolbar-button-slide-right"),
- tbSlideLeft: _el("toolbar-button-slide-left"),
- tbRun: _el("toolbar-button-run"),
- tbStop: _el("toolbar-button-stop"),
- outputContainer: _el("output-container"),
- outputContent: _el("output-content"),
- codeContainer: _el("code-container"),
- rightPanel: _el("game-container"),
- slider: _el("slider"),
- vslider: _el("vslider"),
- fsBrowser: _el("fs-browser"),
- fsContents: _el("fs-contents"),
- fsUrl: _el("fs-url"),
- code: _el("code"),
- themePicker: _el("theme-picker"),
- help: _el("help"),
- helpSidebar: _el("help-sidebar"),
- helpPage: _el("help-page"),
- helpContainer: _el("help-container")
-};
+var IDE = new function() {
-function _el(id) {
- return document.getElementById(id);
-}
+ var QBCompiler = null;
+ // if code has been passed on the query string load it into the editor
+ var qbcode = "";
+ var url = location.href;
+ var sizeMode = "normal";
+ var appMode = "ide";
+ var consoleVisible = false;
+ var currTab = "js";
+ var editor;
+ var selectedError = null;
+ var currPath = "/";
+ var mainProg = null;
+ var theme = "qbjs";
+ var splitWidth = 600;
+ var splitHeight = 327;
+ var sliding = false;
+ var vsliding = false;
+ var _e = {
+ ideTheme: _el("ide-theme"),
+ loadScreen: _el("gx-load-screen"),
+ jsCode: _el("js-code"),
+ warningContainer: _el("warning-container"),
+ gxContainer: _el("gx-container"),
+ shareMode: _el("share-mode"),
+ shareCode: _el("share-code"),
+ shareDialog: _el("share-dialog"),
+ exportButton: _el("export-button"),
+ fileInput: _el("file-input"),
+ progSelSources: _el("prog-sel-sources"),
+ progSelDialog: _el("prog-sel-dialog"),
+ optionsDialog: _el("options-dialog"),
+ aboutDialog: _el("about-dialog"),
+ toolbar: _el("toolbar"),
+ tbConsoleShow: _el("toolbar-button-console-show"),
+ tbConsoleHide: _el("toolbar-button-console-hide"),
+ tbSlideRight: _el("toolbar-button-slide-right"),
+ tbSlideLeft: _el("toolbar-button-slide-left"),
+ tbRun: _el("toolbar-button-run"),
+ tbStop: _el("toolbar-button-stop"),
+ outputContainer: _el("output-container"),
+ outputContent: _el("output-content"),
+ codeContainer: _el("code-container"),
+ rightPanel: _el("game-container"),
+ slider: _el("slider"),
+ vslider: _el("vslider"),
+ fsBrowser: _el("fs-browser"),
+ fsContents: _el("fs-contents"),
+ fsUrl: _el("fs-url"),
+ code: _el("code"),
+ themePicker: _el("theme-picker"),
+ help: _el("help"),
+ helpSidebar: _el("help-sidebar"),
+ helpPage: _el("help-page"),
+ helpContainer: _el("help-container")
+ };
-async function init() {
- document.body.style.display = "initial";
-
- if (window.innerWidth < 1200) {
- sizeMode = "max";
+ function _el(id) {
+ return document.getElementById(id);
}
- var srcUrl = null;
- if (url && (url.indexOf("?") || url.indexOf("#"))) {
- var pindex = url.indexOf("?");
- if (pindex == -1) {
- pindex = url.indexOf("#");
- }
- var queryString = url.substring(pindex + 1);
- var nvpairs = queryString.split("&");
- for (var i = 0; i < nvpairs.length; i++) {
- var pname = "";
- var pvalue = "";
- var nvidx = nvpairs[i].indexOf("=");
- if (nvidx > -1) {
- pname = nvpairs[i].substring(0, nvidx);
- pvalue = nvpairs[i].substring(nvidx + 1);
+ async function _init() {
+ document.body.style.display = "initial";
- if (pname == "qbcode") {
- var zin = new Shorty();
- qbcode = zin.inflate(atob(pvalue));
- break;
- }
- else if (pname == "code") {
- qbcode = LZUTF8.decompress(pvalue, { inputEncoding: "Base64" });
- }
- else if (pname == "mode") {
- appMode = pvalue;
- }
- else if (pname == "src") {
- srcUrl = decodeURIComponent(pvalue);
- }
- else if (pname == "main") {
- mainProg = pvalue;
+ if (window.innerWidth < 1200) {
+ sizeMode = "max";
+ }
+
+ var srcUrl = null;
+ if (url && (url.indexOf("?") || url.indexOf("#"))) {
+ var pindex = url.indexOf("?");
+ if (pindex == -1) {
+ pindex = url.indexOf("#");
+ }
+ var queryString = url.substring(pindex + 1);
+ var nvpairs = queryString.split("&");
+ for (var i = 0; i < nvpairs.length; i++) {
+ var pname = "";
+ var pvalue = "";
+ var nvidx = nvpairs[i].indexOf("=");
+ if (nvidx > -1) {
+ pname = nvpairs[i].substring(0, nvidx);
+ pvalue = nvpairs[i].substring(nvidx + 1);
+
+ if (pname == "qbcode") {
+ var zin = new Shorty();
+ qbcode = zin.inflate(atob(pvalue));
+ break;
+ }
+ else if (pname == "code") {
+ qbcode = LZUTF8.decompress(pvalue, { inputEncoding: "Base64" });
+ }
+ else if (pname == "mode") {
+ appMode = pvalue;
+ }
+ else if (pname == "src") {
+ srcUrl = decodeURIComponent(pvalue);
+ }
+ else if (pname == "main") {
+ mainProg = pvalue;
+ }
}
}
}
- }
- if (appMode == "play") {
- _e.loadScreen.style.display = "block";
- }
- else if (appMode == "ide") {
- var stheme = localStorage.getItem("@@_theme");
- if (stheme && stheme != "") {
- theme = stheme;
+ if (appMode == "play") {
+ _e.loadScreen.style.display = "block";
}
- _e.ideTheme.href = "codemirror/themes/" + theme + ".css";
- GitHelp.navhome();
- }
-
- // initialize the code editor
- editor = CodeMirror(document.querySelector("#code"), {
- lineNumbers: true,
- tabSize: 4,
- indentUnit: 4,
- value: qbcode,
- module: "qbjs",
- theme: theme,
- height: "auto",
- styleActiveLine: true,
- smartIndent: false,
- extraKeys: {
- "Tab": function(cm) {
- cm.replaceSelection(" ", "end");
+ else if (appMode == "ide") {
+ var stheme = localStorage.getItem("@@_theme");
+ if (stheme && stheme != "") {
+ theme = stheme;
}
+ _e.ideTheme.href = "codemirror/themes/" + theme + ".css";
+ GitHelp.navhome();
}
- });
- editor.setSize(600, 600);
- editor.on("beforeChange", (cm, change) => {
- if (change.origin === "paste") {
- const newText = change.text.map(line => line.replace(/\t/g, " "));
- change.update(null, null, newText);
- }
- });
- // if IDE mode, capture the F5 event
- if (appMode != "play" && appMode != "auto") {
- window.addEventListener("keydown", function(event) {
- // run
- if (event.code == 'F5') {
- event.preventDefault();
- runProgram();
- }
- // compile
- else if (event.code == 'F11') {
- event.preventDefault();
- shareProgram();
+ // initialize the code editor
+ editor = CodeMirror(document.querySelector("#code"), {
+ lineNumbers: true,
+ tabSize: 4,
+ indentUnit: 4,
+ value: qbcode,
+ module: "qbjs",
+ theme: theme,
+ height: "auto",
+ styleActiveLine: true,
+ smartIndent: false,
+ extraKeys: {
+ "Tab": function(cm) {
+ cm.replaceSelection(" ", "end");
+ }
}
});
- }
- if (appMode == "ide") {
- editor.focus();
- }
-
- if (srcUrl) {
- var res = await fetch(srcUrl);
- var contentType = res.headers.get("Content-Type");
- if (contentType == "application/zip" ||
- contentType == "application/zip-compressed" ||
- contentType == "application/x-zip-compressed") {
- // load a project
- await loadProject(await res.arrayBuffer(), mainProg, function() {
- if (appMode == "auto") {
- runProgram();
+ editor.setSize(600, 600);
+ editor.on("beforeChange", (cm, change) => {
+ if (change.origin === "paste") {
+ const newText = change.text.map(line => line.replace(/\t/g, " "));
+ change.update(null, null, newText);
+ }
+ });
+
+ // if IDE mode, capture the F5 event
+ if (appMode != "play" && appMode != "auto") {
+ window.addEventListener("keydown", function(event) {
+ // run
+ if (event.code == 'F5') {
+ if (event.shiftKey) {
+ QB.halt();
+ GX.sceneStop();
+ }
+ else if (!QB.running() && !GX.sceneActive()) {
+ event.preventDefault();
+ _runProgram();
+ }
+ }
+ // compile
+ else if (event.code == 'F11') {
+ event.preventDefault();
+ shareProgram();
}
});
}
- else {
- // otherwise, assume a single source file
- var decoder = new TextDecoder("iso-8859-1");
- qbcode = decoder.decode(await res.arrayBuffer());
- editor.setValue(qbcode);
+ if (appMode == "ide") {
+ editor.focus();
}
- }
-
- var warnCount = 0;
- changeTab("console");
- window.onresize();
-
- if (appMode == "auto") {
- runProgram();
- }
-}
-
-async function getErrorLine(error, stackDepth) {
- if (!stackDepth) {
- stackDepth = 0;
- }
- else if (error._stackDepth) {
- stackDepth = error._stackDepth;
- }
-
- var cdepth = 0;
- var srcLine = "";
- if (error.line) { // safari
- srcLine = error.line - 1;
- }
-
- if (!error.stack) { return 0; }
-
- var stack = error.stack.split("\n");
- for (var i=0; i < stack.length; i++) {
- // chrome
- if (stack[i].trim().indexOf("(eval at runProgram") > -1) {
- if (cdepth == stackDepth) {
- var idx = stack[i].indexOf("
:");
- var pos = stack[i].substring(idx + 12);
- pos = pos.substring(0, pos.length - 1);
- pos = pos.split(":");
- srcLine = pos[0] - 2;
+
+ if (srcUrl) {
+ var res = await fetch(srcUrl);
+ var contentType = res.headers.get("Content-Type");
+ if (contentType == "application/zip" ||
+ contentType == "application/zip-compressed" ||
+ contentType == "application/x-zip-compressed") {
+ // load a project
+ await loadProject(await res.arrayBuffer(), mainProg, function() {
+ if (appMode == "auto") {
+ _runProgram();
+ }
+ });
}
- cdepth++;
- }
- // firefox
- else if (stack[i].trim().indexOf("> AsyncFunction:") > -1) {
- if (cdepth == stackDepth) {
- var idx = stack[i].indexOf("> AsyncFunction:");
- var pos = stack[i].substring(idx + 16);
- pos = pos.split(":");
- srcLine = pos[0] - 2;
+ else {
+ // otherwise, assume a single source file
+ var decoder = new TextDecoder("iso-8859-1");
+ qbcode = decoder.decode(await res.arrayBuffer());
+ editor.setValue(qbcode);
}
- cdepth++;
- }
- }
-
- if (!isNaN(srcLine)) {
- srcLine = QBCompiler.getSourceLine(srcLine);
- }
-
- return srcLine;
-}
-
-async function runProgram() {
- _e.loadScreen.style.display = "none";
-
- if (sizeMode == "max") {
- slideLeft();
- }
- GX.reset();
- QB.start();
- var qbCode = editor.getValue();
- if (!QBCompiler) { QBCompiler = await _QBCompiler(); }
- var jsCode = await QBCompiler.compile(qbCode);
-
- await displayWarnings();
-
- _e.jsCode.innerHTML = jsCode;
- window.onresize();
-
- try {
- const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
- var codeFn = new AsyncFunction(jsCode);
- await codeFn();
- }
- catch (error) {
- console.error(error);
-
- // find the source line, if possible
- var srcLine = await getErrorLine(error);
-
- var table = _el("warning-table");
- if (table) {
- tr = document.createElement("tr");
- addWarningCell(tr, "ERROR");
- addWarningCell(tr, ":");
- addWarningCell(tr, srcLine);
- addWarningCell(tr, ":");
- addWarningCell(tr, "" + error.message + "\n
" + error.stack + "
", "99%");
- tr.codeLine = srcLine - 1;
- tr.onclick = gotoWarning;
- table.append(tr);
}
- consoleVisible = true;
+ var warnCount = 0;
+ _changeTab("console");
window.onresize();
+
+ if (appMode == "auto") {
+ _runProgram();
+ }
+ }
+
+ function _getErrorLine(error, stackDepth) {
+ if (!stackDepth) {
+ stackDepth = 0;
+ }
+ else if (error._stackDepth) {
+ stackDepth = error._stackDepth;
+ }
+
+ var cdepth = 0;
+ var srcLine = "";
+ if (error.line) { // safari
+ srcLine = error.line - 1;
+ }
+
+ if (!error.stack) { return 0; }
+
+ var stack = error.stack.split("\n");
+ for (var i=0; i < stack.length; i++) {
+ // chrome
+ if (stack[i].trim().indexOf("(eval at runProgram") > -1) {
+ if (cdepth == stackDepth) {
+ var idx = stack[i].indexOf(":");
+ var pos = stack[i].substring(idx + 12);
+ pos = pos.substring(0, pos.length - 1);
+ pos = pos.split(":");
+ srcLine = pos[0] - 2;
+ }
+ cdepth++;
+ }
+ // firefox
+ else if (stack[i].trim().indexOf("> AsyncFunction:") > -1) {
+ if (cdepth == stackDepth) {
+ var idx = stack[i].indexOf("> AsyncFunction:");
+ var pos = stack[i].substring(idx + 16);
+ pos = pos.split(":");
+ srcLine = pos[0] - 2;
+ }
+ cdepth++;
+ }
+ }
+
+ if (!isNaN(srcLine)) {
+ srcLine = QBCompiler.getSourceLine(srcLine);
+ }
+
+ return srcLine;
+ }
+
+ async function _runProgram() {
+ _e.loadScreen.style.display = "none";
+
+ if (sizeMode == "max") {
+ _slideLeft();
+ }
+ GX.reset();
+ QB.start();
+ var qbCode = editor.getValue();
+ if (!QBCompiler) { QBCompiler = await _QBCompiler(); }
+ var jsCode = await QBCompiler.compile(qbCode);
+
+ await displayWarnings();
+
+ _e.jsCode.innerHTML = jsCode;
+ window.onresize();
+
+ try {
+ const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
+ var codeFn = new AsyncFunction(jsCode);
+ await codeFn();
+ }
+ catch (error) {
+ console.error(error);
+
+ // find the source line, if possible
+ var srcLine = await _getErrorLine(error);
+
+ var table = _el("warning-table");
+ if (table) {
+ tr = document.createElement("tr");
+ _addWarningCell(tr, "ERROR");
+ _addWarningCell(tr, ":");
+ _addWarningCell(tr, srcLine);
+ _addWarningCell(tr, ":");
+ _addWarningCell(tr, "" + error.message + "\n
" + error.stack + "
", "99%");
+ tr.codeLine = srcLine - 1;
+ tr.onclick = _gotoWarning;
+ table.append(tr);
+ }
+
+ consoleVisible = true;
+ window.onresize();
+ QB.halt();
+ GX.sceneStop();
+ }
+ _e.gxContainer.focus();
+
+ return false;
+ }
+
+ function _stopProgram() {
QB.halt();
GX.sceneStop();
}
- _e.gxContainer.focus();
- return false;
-}
+ function _shareProgram() {
+ var zout = new Shorty();
+ var b64 = LZUTF8.compress(editor.getValue(), { outputEncoding: "Base64" });
+ var baseUrl = location.href.split('?')[0];
-function stopProgram() {
- QB.halt();
- GX.sceneStop();
-}
+ var mode = _e.shareMode.value;
+ var codeShare = _e.shareCode;
+ var url = baseUrl + "?";
+ if (mode) {
+ url += "mode=" + mode + "&";
+ }
+ url += "code=" + b64;
+ codeShare.value = url;
+ if (!_e.shareDialog.open) {
+ _e.shareDialog.showModal();
+ }
+ codeShare.focus();
+ codeShare.select();
-function shareProgram() {
- var zout = new Shorty();
- var b64 = LZUTF8.compress(editor.getValue(), { outputEncoding: "Base64" });
- var baseUrl = location.href.split('?')[0];
-
- var mode = _e.shareMode.value;
- var codeShare = _e.shareCode;
- var url = baseUrl + "?";
- if (mode) {
- url += "mode=" + mode + "&";
- }
- url += "code=" + b64;
- codeShare.value = url;
- if (!_e.shareDialog.open) {
- _e.shareDialog.showModal();
- }
- codeShare.focus();
- codeShare.select();
-
- var exportVisible = (mode == "play" || mode == "auto");
- _e.exportButton.style.display = (exportVisible) ? "block" : "none";
-}
-
-function changeTheme(newTheme) {
- theme = newTheme;
- _e.ideTheme.href = "codemirror/themes/" + theme + ".css";
- editor.setOption("theme", theme);
- localStorage.setItem("@@_theme", theme);
-}
-
-function showOptionDialog() {
- _e.themePicker.value = theme;
- showDialog(_e.optionsDialog);
-}
-
-function showDialog(dlg) {
- if (typeof dlg == "string") {
- dlg = _el(dlg);
- }
- if (!dlg.open) {
- dlg.showModal();
- }
-}
-
-async function exportProgram() {
- var zip = new JSZip();
-
- var qbCode = editor.getValue();
- if (!QBCompiler) { QBCompiler = await _QBCompiler(); }
- var jsCode = "async function __qbjs_run() {\n" + await QBCompiler.compile(qbCode) + "\n}";
-
- var mode = _e.shareMode.value;
- zip.file("index.html", await getFile("export/" + mode + ".html", "text"));
- zip.file("program.js", jsCode);
- zip.file("fullscreen.png", await getFile("export/fullscreen.png", "blob"));
- zip.file("logo.png", await getFile("logo.png", "blob"));
- zip.file("dosvga.ttf", await getFile("dosvga.ttf", "blob"));
- zip.file("play.png", await getFile("play.png", "blob"));
- zip.file("qbjs.css", await getFile("export/qbjs.css", "text"));
- zip.file("qb.js", await getFile("qb.js", "text"));
- zip.file("vfs.js", await getFile("vfs.js", "text"));
-
- zip.file("gx/gx.js", await getFile("gx/gx.js", "text"));
- zip.file("gx/__gx_font_default.png", await getFile("gx/__gx_font_default.png", "blob"));
- zip.file("gx/__gx_font_default_black.png", await getFile("gx/__gx_font_default_black.png", "blob"));
-
- // include vfs content
- var vfs = QB.vfs();
- var node = vfs.getNode("/");
- addVFSFiles(vfs, zip, node);
-
- zip.generateAsync({type:"blob"}).then(function(content) {
- const link = document.createElement("a");
- link.href = URL.createObjectURL(content);
- link.download = "program.zip";
- link.click();
- link.remove();
- });
-}
-
-function addVFSFiles(vfs, zip, parent) {
- var files = vfs.getChildren(parent, vfs.FILE);
- for (var i=0; i < files.length; i++) {
- var f = files[i];
- var path = vfs.fullPath(f).substring(1);
- zip.file(path, f.data);
+ var exportVisible = (mode == "play" || mode == "auto");
+ _e.exportButton.title = (exportVisible) ? "" : "Select Play or Auto mode to enable Export";
+ if (exportVisible) {
+ _e.exportButton.classList.remove("disabled");
+ }
+ else {
+ _e.exportButton.classList.add("disabled");
+ }
}
- var dirs = vfs.getChildren(parent, vfs.DIRECTORY);
- for (var i=0; i < dirs.length; i++) {
- addVFSFiles(vfs, zip, dirs[i]);
- }
-}
-
-async function saveProject() {
- var vfs = QB.vfs();
- var node = vfs.getNode("/");
- var count = vfs.getChildren(node, vfs.FILE).length;
- if (count < 1) {
- count = vfs.getChildren(node, vfs.DIRECTORY).length;
+ function _changeTheme(newTheme) {
+ theme = newTheme;
+ _e.ideTheme.href = "codemirror/themes/" + theme + ".css";
+ editor.setOption("theme", theme);
+ localStorage.setItem("@@_theme", theme);
}
- // save a single .bas file
- if (count == 0) {
- var progFile = new Blob([ editor.getValue() ]);
- QB.downloadFile(progFile, "program.bas");
+ function _showOptionDialog() {
+ _e.themePicker.value = theme;
+ _showDialog(_e.optionsDialog);
}
- // save a project .zip file
- else {
+ function _showDialog(dlg) {
+ if (typeof dlg == "string") {
+ dlg = _el(dlg);
+ }
+ if (!dlg.open) {
+ dlg.showModal();
+ }
+ }
+
+ async function _exportProgram() {
+ var mode = _e.shareMode.value;
+ if (mode == "") { return; }
+
var zip = new JSZip();
- zip.file("main.bas", editor.getValue());
+ var qbCode = editor.getValue();
+ if (!QBCompiler) { QBCompiler = await _QBCompiler(); }
+ var jsCode = "async function __qbjs_run() {\n" + await QBCompiler.compile(qbCode) + "\n}";
+
+ var mode = _e.shareMode.value;
+ zip.file("index.html", await getFile("export/" + mode + ".html", "text"));
+ zip.file("program.js", jsCode);
+ zip.file("fullscreen.png", await getFile("export/fullscreen.png", "blob"));
+ zip.file("logo.png", await getFile("logo.png", "blob"));
+ zip.file("dosvga.ttf", await getFile("dosvga.ttf", "blob"));
+ zip.file("play.png", await getFile("play.png", "blob"));
+ zip.file("qbjs.css", await getFile("export/qbjs.css", "text"));
+ zip.file("qb.js", await getFile("qb.js", "text"));
+ zip.file("vfs.js", await getFile("vfs.js", "text"));
+
+ zip.file("gx/gx.js", await getFile("gx/gx.js", "text"));
+ zip.file("gx/__gx_font_default.png", await getFile("gx/__gx_font_default.png", "blob"));
+ zip.file("gx/__gx_font_default_black.png", await getFile("gx/__gx_font_default_black.png", "blob"));
+
+ // include vfs content
var vfs = QB.vfs();
var node = vfs.getNode("/");
addVFSFiles(vfs, zip, node);
zip.generateAsync({type:"blob"}).then(function(content) {
- QB.downloadFile(content, "project.zip");
+ const link = document.createElement("a");
+ link.href = URL.createObjectURL(content);
+ link.download = "program.zip";
+ link.click();
+ link.remove();
});
}
-}
-async function openProject() {
- _e.fileInput.click();
-}
-
-async function onOpenProject(event) {
- var f = event.target.files[0];
-
- // load a single BASIC source file
- if (f.name.toLowerCase().endsWith(".bas") || f.type.startsWith("text/")) {
- var fr = new FileReader();
- fr.onload = function() {
- editor.setValue(fr.result);
+ function addVFSFiles(vfs, zip, parent) {
+ var files = vfs.getChildren(parent, vfs.FILE);
+ for (var i=0; i < files.length; i++) {
+ var f = files[i];
+ var path = vfs.fullPath(f).substring(1);
+ zip.file(path, f.data);
+ }
+
+ var dirs = vfs.getChildren(parent, vfs.DIRECTORY);
+ for (var i=0; i < dirs.length; i++) {
+ addVFSFiles(vfs, zip, dirs[i]);
}
- fr.readAsText(f);
}
- // load a project from a zip file
- else if (f.name.endsWith(".zip") || f.type == "application/x-zip-compressed") {
- await loadProject(f);
+ async function _saveProject() {
+ var vfs = QB.vfs();
+ var node = vfs.getNode("/");
+ var count = vfs.getChildren(node, vfs.FILE).length;
+ if (count < 1) {
+ count = vfs.getChildren(node, vfs.DIRECTORY).length;
+ }
+
+ // save a single .bas file
+ if (count == 0) {
+ var progFile = new Blob([ editor.getValue() ]);
+ QB.downloadFile(progFile, "program.bas");
+ }
+
+ // save a project .zip file
+ else {
+ var zip = new JSZip();
+ zip.file("main.bas", editor.getValue());
+
+ var vfs = QB.vfs();
+ var node = vfs.getNode("/");
+ addVFSFiles(vfs, zip, node);
+
+ zip.generateAsync({type:"blob"}).then(function(content) {
+ QB.downloadFile(content, "project.zip");
+ });
+ }
}
-}
-_e.fileInput.onchange = onOpenProject;
+ async function _openProject() {
+ _e.fileInput.click();
+ }
-async function loadProject(zipData, mainFilename, fnCallback) {
- if (!mainFilename) {
- mainFilename = "main.bas";
- }
- else {
- mainFilename = mainFilename.toLowerCase();
- }
- var vfs = GX.vfs();
- vfs.reset();
- JSZip.loadAsync(zipData).then(async function(zip) {
- var basFiles = [];
- var fnames = "";
- var mainFound = false;
- for (let [filename, file] of Object.entries(zip.files)) {
- fnames += filename + " - " + zip.files[filename].name + "\n";
- var parentDir = dirFromPath(vfs.getParentPath(filename));
- if (filename.toLowerCase() == mainFilename) {
- var text = await zip.file(filename).async("text");
- editor.setValue(text);
- mainFound = true;
+ async function onOpenProject(event) {
+ var f = event.target.files[0];
+
+ // load a single BASIC source file
+ if (f.name.toLowerCase().endsWith(".bas") || f.type.startsWith("text/")) {
+ var fr = new FileReader();
+ fr.onload = function() {
+ editor.setValue(fr.result);
}
- else {
- if (zip.file(filename)) {
- var fdata = await zip.file(filename).async("arraybuffer");
- var f = vfs.createFile(vfs.getFileName(filename), parentDir);
- vfs.writeData(f, fdata);
- if (filename.toLowerCase().endsWith(".bas")) {
- basFiles.push(filename);
+ fr.readAsText(f);
+ }
+
+ // load a project from a zip file
+ else if (f.name.endsWith(".zip") || f.type == "application/x-zip-compressed") {
+ await loadProject(f);
+ }
+
+ }
+ _e.fileInput.onchange = onOpenProject;
+
+ async function loadProject(zipData, mainFilename, fnCallback) {
+ if (!mainFilename) {
+ mainFilename = "main.bas";
+ }
+ else {
+ mainFilename = mainFilename.toLowerCase();
+ }
+ var vfs = GX.vfs();
+ vfs.reset();
+ JSZip.loadAsync(zipData).then(async function(zip) {
+ var basFiles = [];
+ var fnames = "";
+ var mainFound = false;
+ for (let [filename, file] of Object.entries(zip.files)) {
+ fnames += filename + " - " + zip.files[filename].name + "\n";
+ var parentDir = dirFromPath(vfs.getParentPath(filename));
+ if (filename.toLowerCase() == mainFilename) {
+ var text = await zip.file(filename).async("text");
+ editor.setValue(text);
+ mainFound = true;
+ }
+ else {
+ if (zip.file(filename)) {
+ var fdata = await zip.file(filename).async("arraybuffer");
+ var f = vfs.createFile(vfs.getFileName(filename), parentDir);
+ vfs.writeData(f, fdata);
+ if (filename.toLowerCase().endsWith(".bas")) {
+ basFiles.push(filename);
+ }
}
}
}
- }
- if (!mainFound) {
- var fileList = _e.progSelSources;
- fileList.innerHTML = "";
- for (var i=0; i < basFiles.length; i++) {
- var opt = new Option(basFiles[i], basFiles[i]);
- fileList.append(opt);
+ if (!mainFound) {
+ var fileList = _e.progSelSources;
+ fileList.innerHTML = "";
+ for (var i=0; i < basFiles.length; i++) {
+ var opt = new Option(basFiles[i], basFiles[i]);
+ fileList.append(opt);
+ }
+ _showDialog(_e.progSelDialog);
}
- showDialog(_e.progSelDialog);
- }
- refreshFS();
- if (fnCallback) {
- fnCallback();
- }
- });
-
- function dirFromPath(path) {
- var vfs = GX.vfs();
- if (path == "") { return vfs.rootDirectory(); }
-
- var dirnames = path.split("/");
- var dirpath = ""
- var parent = vfs.rootDirectory();
- for (var i=0; i < dirnames.length; i++) {
- dirpath += "/" + dirnames[i];
- var dir = vfs.getNode(dirpath);
- if (!dir) {
- dir = vfs.createDirectory(dirnames[i], parent);
+ _refreshFS();
+ if (fnCallback) {
+ fnCallback();
}
- parent = dir;
- }
- return parent;
- }
-}
+ });
-function onSelMainProg() {
- var fileList = _e.progSelSources;
- if (fileList.value == "") {
- alert("No file selected.");
- }
- else {
- var vfs = GX.vfs();
- var file = vfs.getNode("/" + fileList.value);
- editor.setValue(vfs.readText(file));
- vfs.removeFile(file);
- closeProgSelDlg();
- }
-}
-
-async function getFile(path, type) {
- var file = await fetch(path);
- if (type == "text") {
- return await file.text();
- }
- else if (type == "blob") {
- return await file.blob();
- }
-}
-
-function testShare() {
- open(_e.shareCode.value, "_blank");
-}
-
-function closeDialog() {
- _e.shareDialog.close();
- _e.progSelDialog.close();
- _e.optionsDialog.close();
- _e.aboutDialog.close();
-}
-
-async function displayWarnings() {
- var wstr = "";
- var w = await QBCompiler.getWarnings();
- warnCount = w.length;
-
- var wdiv = _e.warningContainer;
- wdiv.innerHTML = "";
- var table = document.createElement("table");
- table.style.width = "100%";
- table.id = "warning-table";
- table.cellPadding = 2;
- table.cellSpacing = 0;
- table.style.cursor = "default";
- wdiv.appendChild(table);
-
- selectedError = null;
- if (warnCount > 0) {
- for (var i=0; i < w.length; i++) {
- var tr = document.createElement("tr");
- var td1 = document.createElement("td");
- var td2 = document.createElement("td");
- var td3 = document.createElement("td");
- addWarningCell(tr, "WARN");
- addWarningCell(tr, ":");
- addWarningCell(tr, w[i].line);
- addWarningCell(tr, ":");
- addWarningCell(tr, w[i].text, "99%");
- table.append(tr);
- tr.codeLine = w[i].line - 1;
- tr.onclick = gotoWarning;
+ function dirFromPath(path) {
+ var vfs = GX.vfs();
+ if (path == "") { return vfs.rootDirectory(); }
+
+ var dirnames = path.split("/");
+ var dirpath = ""
+ var parent = vfs.rootDirectory();
+ for (var i=0; i < dirnames.length; i++) {
+ dirpath += "/" + dirnames[i];
+ var dir = vfs.getNode(dirpath);
+ if (!dir) {
+ dir = vfs.createDirectory(dirnames[i], parent);
+ }
+ parent = dir;
+ }
+ return parent;
}
}
- if (!consoleVisible && w.length > 0) {
- consoleVisible = true;
- }
-}
-function gotoWarning() {
- if (selectedError ) { selectedError.classList.remove("selected"); }
- editor.setCursor({ line: this.codeLine});
- this.classList.add("selected");
- selectedError = this;
-};
-
-function addWarningCell(tr, text, width) {
- var td = document.createElement("td");
- td.innerHTML = text;
- td.vAlign = "top";
- if (width != undefined) {
- td.width = width;
- }
- tr.append(td);
-}
-
-function showConsole() {
- consoleVisible = !consoleVisible;
- if (!consoleVisible) {
- _e.tbConsoleShow.style.display = "inline-block";
- _e.tbConsoleHide.style.display = "none";
-
- }
- else {
- _e.tbConsoleHide.style.display = "inline-block";
- _e.tbConsoleShow.style.display = "none";
- }
- window.dispatchEvent(new Event('resize'));
-}
-
-function changeTab(tabName) {
- if (tabName == currTab) { return; }
- _el("tab-" + currTab).classList.remove("active");
- _el("tab-" + tabName).classList.add("active");
- currTab = tabName;
-
- if (currTab == "console") {
- _e.warningContainer.style.display = "block";
- _e.jsCode.style.display = "none";
- _e.fsBrowser.style.display = "none";
- _e.help.style.display = "none";
- }
- else if (currTab == "js") {
- _e.warningContainer.style.display = "none";
- _e.fsBrowser.style.display = "none";
- _e.jsCode.style.display = "block";
- _e.help.style.display = "none";
- }
- else if (currTab == "fs") {
- _e.fsBrowser.style.display = "block";
- _e.warningContainer.style.display = "none";
- _e.jsCode.style.display = "none";
- _e.help.style.display = "none";
- refreshFS();
- }
- else if (currTab == "help") {
- _e.warningContainer.style.display = "none";
- _e.jsCode.style.display = "none";
- _e.fsBrowser.style.display = "none";
- _e.help.style.display = "block";
- }
-}
-
-function showHelp(page) {
- changeTab("help");
- var helpUrl = "";
- if (page == "language") { GitHelp.wikinav("https://raw.githubusercontent.com/wiki/boxgaming/qbjs/QBasic-Language-Support.md"); }
- else if (page == "keywords") { GitHelp.wikinav("https://raw.githubusercontent.com/wiki/boxgaming/qbjs/Supported-Keywords.md"); }
- else if (page == "samples") { GitHelp.wikinav("https://raw.githubusercontent.com/wiki/boxgaming/qbjs/Samples.md"); }
- else { GitHelp.navhome(); }
- consoleVisible = false;
- showConsole();
-}
-
-function displayTypes() {
- var tstr = "";
- var t = QBCompiler.getTypes();
- for (var i=0; i < t.length; i++) {
- tstr += t[i].name
- }
- var wdiv = _e.warningContainer;
- wdiv.innerHTML = tstr;
-}
-
-function slideLeft() {
- _e.tbSlideRight.style.display = "inline-block";
- if (sizeMode == "max" && window.innerWidth >= 1200) {
- sizeMode = "normal"
- }
- else {
- sizeMode = "min"
- _e.tbSlideLeft.style.display = "none";
- }
- window.dispatchEvent(new Event('resize'));
-}
-
-function slideRight() {
- _e.tbSlideLeft.style.display = "inline-block";
- if (sizeMode == "min" && window.innerWidth >= 1200) {
- sizeMode = "normal"
- }
- else {
- sizeMode = "max"
- _e.tbSlideRight.style.display = "none";
- }
- window.dispatchEvent(new Event('resize'));
-}
-
-window.onresize = function() {
- if (!editor) { return; }
-
- var f = _e.gxContainer;
- var jsDiv = _e.outputContainer;
-
- if (appMode == "play" || appMode == "auto") {
- f.style.left = "0px";
- f.style.top = "0px";
- f.style.width = window.innerWidth + "px";
- f.style.height = window.innerHeight + "px";
- f.style.border = "0px";
- _e.codeContainer.style.display = "none";
- _e.slider.style.display = "none";
- _e.rightPanel.style.left = "0px";
- _e.rightPanel.style.top = "0px";
- _e.rightPanel.style.right = "0px";
- _e.rightPanel.style.bottom = "0px";
- _e.rightPanel.style.backgroundColor = "#000";
- _e.toolbar.style.display = "none";
- jsDiv.style.display = "none";
- _e.vslider.style.display = "none";
- splitHeight = 0;
- }
- else {
- var cmwidth = splitWidth;
- if (sizeMode == "min") {
- cmwidth = -10;
- editor.getWrapperElement().style.display = "none";
- _e.rightPanel.style.display = "block";
- _e.slider.style.display = "none";
- }
- else if (sizeMode == "max") {
- cmwidth = window.innerWidth - 12;
- _e.rightPanel.style.display = "none";
- _e.slider.style.display = "none";
- editor.getWrapperElement().style.display = "block";
+ function _onSelMainProg() {
+ var fileList = _e.progSelSources;
+ if (fileList.value == "") {
+ alert("No file selected.");
}
else {
- editor.getWrapperElement().style.display = "block";
- _e.rightPanel.style.display = "block";
- _e.slider.style.display = "block";
+ var vfs = GX.vfs();
+ var file = vfs.getNode("/" + fileList.value);
+ editor.setValue(vfs.readText(file));
+ vfs.removeFile(file);
+ closeProgSelDlg();
}
+ }
- _e.rightPanel.style.left = (cmwidth + 15) + "px";
- f.style.width = (window.innerWidth - (cmwidth + 22)) + "px";
- jsDiv.style.width = f.style.width;
+ async function getFile(path, type) {
+ var file = await fetch(path);
+ if (type == "text") {
+ return await file.text();
+ }
+ else if (type == "blob") {
+ return await file.blob();
+ }
+ }
- _e.slider.style.left = (cmwidth + 7) + "px";
+ function _testShare() {
+ open(_e.shareCode.value, "_blank");
+ }
+
+ function _closeDialog() {
+ _e.shareDialog.close();
+ _e.progSelDialog.close();
+ _e.optionsDialog.close();
+ _e.aboutDialog.close();
+ }
+
+ async function displayWarnings() {
+ var wstr = "";
+ var w = await QBCompiler.getWarnings();
+ warnCount = w.length;
+
+ var wdiv = _e.warningContainer;
+ wdiv.innerHTML = "";
+ var table = document.createElement("table");
+ table.style.width = "100%";
+ table.id = "warning-table";
+ table.cellPadding = 2;
+ table.cellSpacing = 0;
+ table.style.cursor = "default";
+ wdiv.appendChild(table);
+
+ selectedError = null;
+ if (warnCount > 0) {
+ for (var i=0; i < w.length; i++) {
+ var tr = document.createElement("tr");
+ var td1 = document.createElement("td");
+ var td2 = document.createElement("td");
+ var td3 = document.createElement("td");
+ _addWarningCell(tr, "WARN");
+ _addWarningCell(tr, ":");
+ _addWarningCell(tr, w[i].line);
+ _addWarningCell(tr, ":");
+ _addWarningCell(tr, w[i].text, "99%");
+ table.append(tr);
+ tr.codeLine = w[i].line - 1;
+ tr.onclick = _gotoWarning;
+ }
+ }
+ if (!consoleVisible && w.length > 0) {
+ consoleVisible = true;
+ }
+ }
+
+ function _gotoWarning() {
+ if (selectedError ) { selectedError.classList.remove("selected"); }
+ editor.setCursor({ line: this.codeLine});
+ this.classList.add("selected");
+ selectedError = this;
+ }
+
+ function _addWarningCell(tr, text, width) {
+ var td = document.createElement("td");
+ td.innerHTML = text;
+ td.vAlign = "top";
+ if (width != undefined) {
+ td.width = width;
+ }
+ tr.append(td);
+ }
+
+ function _showConsole() {
+ consoleVisible = !consoleVisible;
+ if (!consoleVisible) {
+ _e.tbConsoleShow.style.display = "inline-block";
+ _e.tbConsoleHide.style.display = "none";
- if (consoleVisible) {
- _e.vslider.style.display = "block";
- f.style.height = (window.innerHeight - splitHeight) + "px";
- jsDiv.style.display = "block";
- jsDiv.style.top = (window.innerHeight - splitHeight + 10) + "px";
- _e.outputContent.style.height = (splitHeight - 77) + "px";
- _e.helpContainer.style.height = (splitHeight - 110) + "px";
}
else {
- _e.vslider.style.display = "none";
- f.style.height = (window.innerHeight - 40) + "px";
+ _e.tbConsoleHide.style.display = "inline-block";
+ _e.tbConsoleShow.style.display = "none";
+ }
+ window.dispatchEvent(new Event('resize'));
+ }
+
+ function _changeTab(tabName) {
+ if (tabName == currTab) { return; }
+ _el("tab-" + currTab).classList.remove("active");
+ _el("tab-" + tabName).classList.add("active");
+ currTab = tabName;
+
+ if (currTab == "console") {
+ _e.warningContainer.style.display = "block";
+ _e.jsCode.style.display = "none";
+ _e.fsBrowser.style.display = "none";
+ _e.help.style.display = "none";
+ }
+ else if (currTab == "js") {
+ _e.warningContainer.style.display = "none";
+ _e.fsBrowser.style.display = "none";
+ _e.jsCode.style.display = "block";
+ _e.help.style.display = "none";
+ }
+ else if (currTab == "fs") {
+ _e.fsBrowser.style.display = "block";
+ _e.warningContainer.style.display = "none";
+ _e.jsCode.style.display = "none";
+ _e.help.style.display = "none";
+ _refreshFS();
+ }
+ else if (currTab == "help") {
+ _e.warningContainer.style.display = "none";
+ _e.jsCode.style.display = "none";
+ _e.fsBrowser.style.display = "none";
+ _e.help.style.display = "block";
+ }
+ }
+
+ function _showHelp(page) {
+ _changeTab("help");
+ var helpUrl = "";
+ if (page == "language") { GitHelp.wikinav("https://raw.githubusercontent.com/wiki/boxgaming/qbjs/QBasic-Language-Support.md"); }
+ else if (page == "keywords") { GitHelp.wikinav("https://raw.githubusercontent.com/wiki/boxgaming/qbjs/Supported-Keywords.md"); }
+ else if (page == "samples") { GitHelp.wikinav("https://raw.githubusercontent.com/wiki/boxgaming/qbjs/Samples.md"); }
+ else { GitHelp.navhome(); }
+ consoleVisible = false;
+ _showConsole();
+ }
+
+ function displayTypes() {
+ var tstr = "";
+ var t = QBCompiler.getTypes();
+ for (var i=0; i < t.length; i++) {
+ tstr += t[i].name
+ }
+ var wdiv = _e.warningContainer;
+ wdiv.innerHTML = tstr;
+ }
+
+ function _slideLeft() {
+ _e.tbSlideRight.style.display = "inline-block";
+ if (sizeMode == "max" && window.innerWidth >= 1200) {
+ sizeMode = "normal"
+ }
+ else {
+ sizeMode = "min"
+ _e.tbSlideLeft.style.display = "none";
+ }
+ window.dispatchEvent(new Event('resize'));
+ }
+
+ function _slideRight() {
+ _e.tbSlideLeft.style.display = "inline-block";
+ if (sizeMode == "min" && window.innerWidth >= 1200) {
+ sizeMode = "normal"
+ }
+ else {
+ sizeMode = "max"
+ _e.tbSlideRight.style.display = "none";
+ }
+ window.dispatchEvent(new Event('resize'));
+ }
+
+ window.onresize = function() {
+ if (!editor) { return; }
+
+ var f = _e.gxContainer;
+ var jsDiv = _e.outputContainer;
+
+ if (appMode == "play" || appMode == "auto") {
+ f.style.left = "0px";
+ f.style.top = "0px";
+ f.style.width = window.innerWidth + "px";
+ f.style.height = window.innerHeight + "px";
+ f.style.border = "0px";
+ _e.codeContainer.style.display = "none";
+ _e.slider.style.display = "none";
+ _e.rightPanel.style.left = "0px";
+ _e.rightPanel.style.top = "0px";
+ _e.rightPanel.style.right = "0px";
+ _e.rightPanel.style.bottom = "0px";
+ _e.rightPanel.style.backgroundColor = "#000";
+ _e.toolbar.style.display = "none";
jsDiv.style.display = "none";
+ _e.vslider.style.display = "none";
+ splitHeight = 0;
}
-
- editor.setSize(cmwidth, window.innerHeight - 40);
- _e.code.style.height = (window.innerHeight - 40) + "px";
- _e.slider.style.height = (window.innerHeight - 40) + "px";
- }
- QB.resize(f.clientWidth, f.clientHeight);
-}
-window.onresize();
+ else {
+ var cmwidth = splitWidth;
+ if (sizeMode == "min") {
+ cmwidth = -10;
+ editor.getWrapperElement().style.display = "none";
+ _e.rightPanel.style.display = "block";
+ _e.slider.style.display = "none";
+ }
+ else if (sizeMode == "max") {
+ cmwidth = window.innerWidth - 12;
+ _e.rightPanel.style.display = "none";
+ _e.slider.style.display = "none";
+ editor.getWrapperElement().style.display = "block";
+ }
+ else {
+ editor.getWrapperElement().style.display = "block";
+ _e.rightPanel.style.display = "block";
+ _e.slider.style.display = "block";
+ }
+ _e.rightPanel.style.left = (cmwidth + 15) + "px";
+ f.style.width = (window.innerWidth - (cmwidth + 22)) + "px";
+ jsDiv.style.width = f.style.width;
-function checkButtonState() {
- var stopButton = _e.tbStop;
- var runButton = _e.tbRun;
- if (GX.sceneActive() || QB.running()) {
- stopButton.style.display = "inline-block";
- runButton.style.display = "none";
- }
- else {
- stopButton.style.display = "none";
- runButton.style.display = "inline-block";
- }
- setTimeout(checkButtonState, 100);
-}
-checkButtonState();
-init();
+ _e.slider.style.left = (cmwidth + 7) + "px";
-// Virtual File System Viewer
-function refreshFS() {
- var vfs = QB.vfs();
- var node = vfs.getNode(currPath);
- if (!node) {
- currPath = "/";
- node = vfs.getNode(currPath);
- }
-
- var contents = _e.fsContents;
- while (contents.firstChild) {
- contents.removeChild(contents.firstChild);
- }
-
- if (!node) {
- // TODO: better error reporting
- return;
- }
-
- currPath = vfs.fullPath(node)
- _e.fsUrl.innerHTML = currPath;
-
- if (currPath != "/") {
- var a = document.createElement("a");
- a.className = "fs-dir";
- a.innerHTML = "..";
- a.fullpath = currPath + "/..";
- a.onclick = function() { chdir(this.fullpath); };
- contents.appendChild(a);
- contents.appendChild(document.createElement("span"));
- }
-
- var folders = vfs.getChildren(node, vfs.DIRECTORY);
- for (var i=0; i < folders.length; i++) {
- var a = document.createElement("a");
- a.className = "fs-dir";
- a.innerHTML = folders[i].name;
- a.fullpath = vfs.fullPath(folders[i]);
- a.onclick = function() { chdir(this.fullpath); };
- contents.appendChild(a);
- a = document.createElement("a");
- a.className = "fs-delete";
- a.vfsnode = folders[i];
- a.onclick = function() { deleteDir(this.vfsnode); };
- contents.appendChild(a);
- }
-
- var files = vfs.getChildren(node, vfs.FILE);
- for (var i=0; i < files.length; i++) {
- var a = document.createElement("a");
- a.className = "fs-file";
- a.innerHTML = files[i].name;
- a.fullpath = vfs.fullPath(files[i]);
- a.onclick = function() { saveFile(this.fullpath); };
- contents.appendChild(a);
- a = document.createElement("a");
- a.className = "fs-delete";
- a.vfsnode = files[i];
- a.onclick = function() { deleteFile(this.vfsnode); };
- contents.appendChild(a);
- }
-
- function deleteFile(node) {
- if (confirm("This will permanently delete file '" + node.name + "'.\nAre you sure you wish to continue?")) {
- vfs.removeFile(node);
- refreshFS();
+ if (consoleVisible) {
+ _e.vslider.style.display = "block";
+ f.style.height = (window.innerHeight - splitHeight) + "px";
+ jsDiv.style.display = "block";
+ jsDiv.style.top = (window.innerHeight - splitHeight + 10) + "px";
+ _e.outputContent.style.height = (splitHeight - 77) + "px";
+ _e.helpContainer.style.height = (splitHeight - 110) + "px";
+ }
+ else {
+ _e.vslider.style.display = "none";
+ f.style.height = (window.innerHeight - 40) + "px";
+ jsDiv.style.display = "none";
+ }
+
+ editor.setSize(cmwidth, window.innerHeight - 40);
+ _e.code.style.height = (window.innerHeight - 40) + "px";
+ _e.slider.style.height = (window.innerHeight - 40) + "px";
}
+ QB.resize(f.clientWidth, f.clientHeight);
}
+ window.onresize();
- function deleteDir(node) {
- if (vfs.getChildren(node).length > 0) {
- alert("Directory is not empty.");
+
+ function checkButtonState() {
+ var stopButton = _e.tbStop;
+ var runButton = _e.tbRun;
+ if (GX.sceneActive() || QB.running()) {
+ stopButton.style.display = "inline-block";
+ runButton.style.display = "none";
+ }
+ else {
+ stopButton.style.display = "none";
+ runButton.style.display = "inline-block";
+ }
+ setTimeout(checkButtonState, 100);
+ }
+ checkButtonState();
+ _init();
+
+ // Virtual File System Viewer
+ function _refreshFS() {
+ var vfs = QB.vfs();
+ var node = vfs.getNode(currPath);
+ if (!node) {
+ currPath = "/";
+ node = vfs.getNode(currPath);
+ }
+
+ var contents = _e.fsContents;
+ while (contents.firstChild) {
+ contents.removeChild(contents.firstChild);
+ }
+
+ if (!node) {
+ // TODO: better error reporting
return;
}
- if (confirm("This will permanently delete directory '" + node.name + "'.\nAre you sure you wish to continue?")) {
- vfs.removeDirectory(node);
- refreshFS();
+
+ currPath = vfs.fullPath(node)
+ _e.fsUrl.innerHTML = currPath;
+
+ if (currPath != "/") {
+ var a = document.createElement("a");
+ a.className = "fs-dir";
+ a.innerHTML = "..";
+ a.fullpath = currPath + "/..";
+ a.onclick = function() { chdir(this.fullpath); };
+ contents.appendChild(a);
+ contents.appendChild(document.createElement("span"));
+ }
+
+ var folders = vfs.getChildren(node, vfs.DIRECTORY);
+ for (var i=0; i < folders.length; i++) {
+ var a = document.createElement("a");
+ a.className = "fs-dir";
+ a.innerHTML = folders[i].name;
+ a.fullpath = vfs.fullPath(folders[i]);
+ a.onclick = function() { chdir(this.fullpath); };
+ contents.appendChild(a);
+ a = document.createElement("a");
+ a.className = "fs-delete";
+ a.vfsnode = folders[i];
+ a.onclick = function() { deleteDir(this.vfsnode); };
+ contents.appendChild(a);
+ }
+
+ var files = vfs.getChildren(node, vfs.FILE);
+ for (var i=0; i < files.length; i++) {
+ var a = document.createElement("a");
+ a.className = "fs-file";
+ a.innerHTML = files[i].name;
+ a.fullpath = vfs.fullPath(files[i]);
+ a.onclick = function() { saveFile(this.fullpath); };
+ contents.appendChild(a);
+ a = document.createElement("a");
+ a.className = "fs-delete";
+ a.vfsnode = files[i];
+ a.onclick = function() { deleteFile(this.vfsnode); };
+ contents.appendChild(a);
+ }
+
+ function deleteFile(node) {
+ if (confirm("This will permanently delete file '" + node.name + "'.\nAre you sure you wish to continue?")) {
+ vfs.removeFile(node);
+ _refreshFS();
+ }
+ }
+
+ function deleteDir(node) {
+ if (vfs.getChildren(node).length > 0) {
+ alert("Directory is not empty.");
+ return;
+ }
+ if (confirm("This will permanently delete directory '" + node.name + "'.\nAre you sure you wish to continue?")) {
+ vfs.removeDirectory(node);
+ _refreshFS();
+ }
}
}
-}
-function onNewDirectory() {
- var vfs = QB.vfs();
- var parent = vfs.getNode(currPath);
- var dirname = prompt("Enter new directory name");
- if (dirname && dirname != "") {
- vfs.createDirectory(dirname, parent);
- refreshFS();
- }
-}
-
-function chdir(path) {
- currPath = path;
- refreshFS();
-}
-
-function saveFile(path) {
- var vfs = QB.vfs();
- var fileNode = vfs.getNode(path);
- var fileBlob = new Blob([fileNode.data]);
- var url = URL.createObjectURL(fileBlob);
-
- var link = document.createElement("a");
- link.href = url;
- link.download = fileNode.name;
- link.click();
-}
-
-async function fileDrop(e) {
- if (currTab != "fs") { return; }
- e.stopPropagation();
- e.preventDefault();
- dropArea.style.backgroundColor = "transparent";
-
- var dt = e.dataTransfer;
- var files = dt.files;
-
- var vfs = QB.vfs();
- var parentDir = vfs.getNode(currPath);
- var fr = new FileReader();
-
- console.log(files.length);
- for (var i=0; i < files.length; i++) {
- var f = files[i];
- if (!f.type && f.size%4096 == 0) {
- // this is a folder, skip
- continue;
+ function _onNewDirectory() {
+ var vfs = QB.vfs();
+ var parent = vfs.getNode(currPath);
+ var dirname = prompt("Enter new directory name");
+ if (dirname && dirname != "") {
+ vfs.createDirectory(dirname, parent);
+ _refreshFS();
}
-
- var file = vfs.createFile(f.name, parentDir);
- var data = await f.arrayBuffer();
- vfs.writeData(file, data);
}
- refreshFS();
-}
-
-_e.slider.addEventListener("mousedown", function(event) {
- sliding = true;
-});
-_e.vslider.addEventListener("mousedown", function(event) {
- vsliding = true;
-});
-
-window.addEventListener("mousemove", function(event) {
- if (!sliding && !vsliding) { return; }
- if (sliding) {
- splitWidth = event.pageX - 10;
- window.onresize();
+ function chdir(path) {
+ currPath = path;
+ _refreshFS();
}
- else {
- splitHeight = window.innerHeight - event.pageY + 35;
- window.onresize();
+
+ function saveFile(path) {
+ var vfs = QB.vfs();
+ var fileNode = vfs.getNode(path);
+ var fileBlob = new Blob([fileNode.data]);
+ var url = URL.createObjectURL(fileBlob);
+
+ var link = document.createElement("a");
+ link.href = url;
+ link.download = fileNode.name;
+ link.click();
}
-});
-window.addEventListener("mouseup", function() {
- sliding = false;
- vsliding = false;
-});
-
-
-
-function fileDragEnter(e) {
- if (currTab != "fs") { return; }
- e.stopPropagation();
- e.preventDefault();
-
- dropArea.style.backgroundColor = "rgb(255,255,255,.1)";
-}
-
-function fileDragLeave(e) {
- if (currTab != "fs") { return; }
- e.stopPropagation();
- e.preventDefault();
-
- dropArea.style.backgroundColor = "transparent";
-}
-
-function fileDragOver(e) {
- if (currTab != "fs") { return; }
- e.stopPropagation();
- e.preventDefault();
-}
-
-var dropArea = _e.outputContent;
-dropArea.addEventListener("drop", fileDrop, false);
-dropArea.addEventListener("dragover", fileDragOver, false);
-dropArea.addEventListener("dragenter", fileDragEnter, false);
-dropArea.addEventListener("dragleave", fileDragLeave, false);
-
-if (!inIframe() && appMode == "ide") {
- addEventListener("beforeunload", function(e) {
+ async function fileDrop(e) {
+ if (currTab != "fs") { return; }
+ e.stopPropagation();
e.preventDefault();
- return e.returnValue = "stop";
- });
-}
+ dropArea.style.backgroundColor = "transparent";
-function inIframe () {
- try {
- return window.self !== window.top;
- } catch (e) {
- return true;
+ var dt = e.dataTransfer;
+ var files = dt.files;
+
+ var vfs = QB.vfs();
+ var parentDir = vfs.getNode(currPath);
+ var fr = new FileReader();
+
+ for (var i=0; i < files.length; i++) {
+ var f = files[i];
+ if (!f.type && f.size%4096 == 0) {
+ // this is a folder, skip
+ continue;
+ }
+
+ var file = vfs.createFile(f.name, parentDir);
+ var data = await f.arrayBuffer();
+ vfs.writeData(file, data);
+ }
+
+ _refreshFS();
}
-}
\ No newline at end of file
+
+ function _onUploadFile() {
+ _uploadFile(_e.fsUrl.innerHTML, null, function() {
+ _refreshFS();
+ });
+ }
+
+ function _uploadFile(destpath, filter, fnCallback) {
+ var vfs = QB.vfs();
+ var parentDir = null;
+ if (destpath == undefined || destpath == "" || destpath == "/") {
+ parentDir = vfs.rootDirectory(); //QB.vfsCwd();
+ }
+ else {
+ parentDir = vfs.getNode(destpath, vfs.rootDirectory()); //QB.vfsCwd());
+ if (!parentDir) {
+ throw Object.assign(new Error("Path not found: [" + destpath + "]"), { _stackDepth: 1 });
+ }
+ else if (parentDir && parentDir.type != vfs.DIRECTORY) {
+ throw Object.assign(new Error("Path is not a directory: [" + destpath + "]"), { _stackDepth: 1 });
+ }
+ }
+ var fileInput = document.getElementById("upload-file-input");
+ if (fileInput == null) {
+ fileInput = document.createElement("input");
+ fileInput.id = "upload-file-input";
+ fileInput.type = "file";
+ }
+ fileInput.value = null;
+ if (filter != undefined) {
+ fileInput.accept = filter;
+ }
+ fileInput.onchange = function(event) {
+ if (event.target.files.length > 0) {
+ var f = event.target.files[0];
+ var fr = new FileReader();
+ fr.onload = function() {
+ var file = vfs.createFile(f.name, parentDir);
+ vfs.writeData(file, fr.result);
+
+ if (fnCallback) {
+ fnCallback(vfs.fullPath(file));
+ }
+ }
+ fr.readAsArrayBuffer(f);
+ }
+ };
+ fileInput.click();
+ }
+
+ _e.slider.addEventListener("mousedown", function(event) {
+ sliding = true;
+ });
+ _e.vslider.addEventListener("mousedown", function(event) {
+ vsliding = true;
+ });
+
+ window.addEventListener("mousemove", function(event) {
+ if (!sliding && !vsliding) { return; }
+ if (sliding) {
+ splitWidth = event.pageX - 10;
+ window.onresize();
+ }
+ else {
+ splitHeight = window.innerHeight - event.pageY + 35;
+ window.onresize();
+ }
+ });
+
+ window.addEventListener("mouseup", function() {
+ sliding = false;
+ vsliding = false;
+ });
+
+
+
+ function fileDragEnter(e) {
+ if (currTab != "fs") { return; }
+ e.stopPropagation();
+ e.preventDefault();
+
+ dropArea.style.backgroundColor = "rgb(255,255,255,.1)";
+ }
+
+ function fileDragLeave(e) {
+ if (currTab != "fs") { return; }
+ e.stopPropagation();
+ e.preventDefault();
+
+ dropArea.style.backgroundColor = "transparent";
+ }
+
+ function fileDragOver(e) {
+ if (currTab != "fs") { return; }
+ e.stopPropagation();
+ e.preventDefault();
+ }
+
+ var dropArea = _e.outputContent;
+ dropArea.addEventListener("drop", fileDrop, false);
+ dropArea.addEventListener("dragover", fileDragOver, false);
+ dropArea.addEventListener("dragenter", fileDragEnter, false);
+ dropArea.addEventListener("dragleave", fileDragLeave, false);
+
+ if (!inIframe() && appMode == "ide") {
+ addEventListener("beforeunload", function(e) {
+ e.preventDefault();
+ return e.returnValue = "stop";
+ });
+ }
+
+ function inIframe () {
+ try {
+ return window.self !== window.top;
+ } catch (e) {
+ return true;
+ }
+ }
+
+ this.getErrorLine = _getErrorLine;
+ this.runProgram = _runProgram;
+ this.stopProgram = _stopProgram;
+ this.shareProgram = _shareProgram;
+ this.changeTheme = _changeTheme;
+ this.showOptionDialog = _showOptionDialog;
+ this.showDialog = _showDialog;
+ this.exportProgram = _exportProgram;
+ this.saveProject = _saveProject;
+ this.openProject = _openProject;
+ this.onSelMainProg = _onSelMainProg;
+ this.testShare = _testShare;
+ this.closeDialog = _closeDialog;
+ this.gotoWarning = _gotoWarning;
+ this.addWarningCell = _addWarningCell;
+ this.showConsole = _showConsole;
+ this.changeTab = _changeTab;
+ this.showHelp = _showHelp;
+ this.slideLeft = _slideLeft;
+ this.slideRight = _slideRight;
+ this.refreshFS = _refreshFS;
+ this.onNewDirectory = _onNewDirectory;
+ this.onUploadFile = _onUploadFile;
+ this.uploadFile = _uploadFile;
+};
\ No newline at end of file