1
1
Fork 0
mirror of https://github.com/boxgaming/qbjs.git synced 2024-05-12 08:00:12 +00:00

Refactored IDE code to be encapsulated by "IDE" function. Issues: #86, #87, #89, #90

This commit is contained in:
boxgaming 2024-01-08 12:06:04 -06:00
parent cb8b666256
commit 8c6aefc403
8 changed files with 1178 additions and 927 deletions

View file

@ -105,6 +105,8 @@ dialog a:hover { color: #fff !important; }
a:before { content: ""; }
a:after { content: ""; }
a:hover { text-decoration: underline; }
dialog a.disabled, dialog a.disabled:hover { color: #999 !important; }
dialog a.disabled:hover { text-decoration: none; }
#fs-contents a { font-variant: normal; font-family: Verdana, Geneva, Tahoma, sans-serif; font-size: 13px; }
#fs-contents a:hover { text-decoration: none; }

View file

@ -43,6 +43,7 @@ a:active { border: 2px inset;}
a:hover { color: #000; }
a:before { content: ""; }
a:after { content: ""; }
dialog a.disabled:active { border: 2px outset; }
li a, li a:link, li a:visited { border: 0; text-decoration: underline; }
li a:active { border: 0; }

73
img/upload-hover.svg Normal file
View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 256 256"
version="1.1"
id="svg1"
sodipodi:docname="upload-hover.svg"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="3.6679688"
inkscape:cx="128"
inkscape:cy="128"
inkscape:window-width="1920"
inkscape:window-height="1177"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<defs
id="defs1" />
<rect
fill="none"
height="256"
width="256"
id="rect1" />
<path
d="M176,128h48a8,8,0,0,1,8,8v64a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V136a8,8,0,0,1,8-8H80"
fill="none"
stroke="#000"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="12"
id="path1"
style="fill:none;fill-opacity:1;stroke:#cccccc;stroke-opacity:1;stroke-width:16;stroke-dasharray:none" />
<line
fill="none"
stroke="#000"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="12"
x1="128"
x2="128"
y1="128"
y2="24"
id="line1"
style="fill:none;fill-opacity:1;stroke:#cccccc;stroke-opacity:1;stroke-width:16;stroke-dasharray:none" />
<polyline
fill="none"
points="80 72 128 24 176 72"
stroke="#000"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="12"
id="polyline1"
style="fill:none;fill-opacity:1;stroke:#cccccc;stroke-opacity:1;stroke-width:16;stroke-dasharray:none" />
<circle
cx="188"
cy="168"
r="10"
id="circle1"
style="fill:#cccccc;fill-opacity:1;stroke:#cccccc;stroke-opacity:1;stroke-width:5;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

73
img/upload.svg Normal file
View file

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
viewBox="0 0 256 256"
version="1.1"
id="svg1"
sodipodi:docname="upload.svg"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="3.6679688"
inkscape:cx="128"
inkscape:cy="128"
inkscape:window-width="1920"
inkscape:window-height="1177"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<defs
id="defs1" />
<rect
fill="none"
height="256"
width="256"
id="rect1" />
<path
d="M176,128h48a8,8,0,0,1,8,8v64a8,8,0,0,1-8,8H32a8,8,0,0,1-8-8V136a8,8,0,0,1,8-8H80"
fill="none"
stroke="#000"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="12"
id="path1"
style="fill:none;fill-opacity:1;stroke:#666666;stroke-opacity:1;stroke-width:16;stroke-dasharray:none" />
<line
fill="none"
stroke="#000"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="12"
x1="128"
x2="128"
y1="128"
y2="24"
id="line1"
style="fill:none;fill-opacity:1;stroke:#666666;stroke-opacity:1;stroke-width:16;stroke-dasharray:none" />
<polyline
fill="none"
points="80 72 128 24 176 72"
stroke="#000"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="12"
id="polyline1"
style="fill:none;fill-opacity:1;stroke:#666666;stroke-opacity:1;stroke-width:16;stroke-dasharray:none" />
<circle
cx="188"
cy="168"
r="10"
id="circle1"
style="fill:#666666;fill-opacity:1;stroke:#666666;stroke-opacity:1;stroke-width:5;stroke-dasharray:none" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -27,21 +27,21 @@
</head>
<body style="display:none">
<div id="toolbar">
<a href="javascript:openProject()" class="toolbar-button" id="toolbar-button-open" title="Open"></a>
<a href="javascript:saveProject()" class="toolbar-button" id="toolbar-button-save" title="Save"></a>
<a href="javascript:IDE.openProject()" class="toolbar-button" id="toolbar-button-open" title="Open"></a>
<a href="javascript:IDE.saveProject()" class="toolbar-button" id="toolbar-button-save" title="Save"></a>
<div class="spacer"></div>
<a href="javascript:runProgram()" class="toolbar-button" id="toolbar-button-run" title="Run"></a>
<a href="javascript:stopProgram()" class="toolbar-button" id="toolbar-button-stop" title="Stop"></a>
<a href="javascript:shareProgram()" class="toolbar-button" id="toolbar-button-share" title="Share / Export"></a>
<a href="javascript:IDE.runProgram()" class="toolbar-button" id="toolbar-button-run" title="Run"></a>
<a href="javascript:IDE.stopProgram()" class="toolbar-button" id="toolbar-button-stop" title="Stop"></a>
<a href="javascript:IDE.shareProgram()" class="toolbar-button" id="toolbar-button-share" title="Share / Export"></a>
<div class="spacer"></div>
<a href="javascript:showOptionDialog()" class="toolbar-button" id="toolbar-button-settings" title="Settings"></a>
<a href="javascript:IDE.showOptionDialog()" class="toolbar-button" id="toolbar-button-settings" title="Settings"></a>
<a href="javascript:showDialog('about-dialog')" class="toolbar-button" id="toolbar-button-about" title="About QBJS"></a>
<a href="javascript:IDE.showDialog('about-dialog')" class="toolbar-button" id="toolbar-button-about" title="About QBJS"></a>
<div class="spacer" style="float:right"></div>
<a href="javascript:showConsole()" class="toolbar-button" id="toolbar-button-console-show" title="Show Console"></a>
<a href="javascript:showConsole()" class="toolbar-button" id="toolbar-button-console-hide" title="Hide Console" style="display:none"></a>
<a href="javascript:slideRight()" class="toolbar-button" id="toolbar-button-slide-right" title="Slide View Right"></a>
<a href="javascript:slideLeft()" class="toolbar-button" id="toolbar-button-slide-left" title="Slide View Left"></a>
<a href="javascript:IDE.showConsole()" class="toolbar-button" id="toolbar-button-console-show" title="Show Console"></a>
<a href="javascript:IDE.showConsole()" class="toolbar-button" id="toolbar-button-console-hide" title="Hide Console" style="display:none"></a>
<a href="javascript:IDE.slideRight()" class="toolbar-button" id="toolbar-button-slide-right" title="Slide View Right"></a>
<a href="javascript:IDE.slideLeft()" class="toolbar-button" id="toolbar-button-slide-left" title="Slide View Left"></a>
</div>
<div id="code-container">
<div id="code"></div>
@ -55,7 +55,7 @@
<div id="vslider"></div>
<div id="output-container">
<div id="tabs">
<div id="tab-console" class="tab active" onclick="changeTab('console')">Console</div><div id="tab-js" class="tab" onclick="changeTab('js')">Javascript</div><div id="tab-fs" class="tab" onclick="changeTab('fs')">Files</div><div id="tab-help" class="tab" onclick="changeTab('help')">Help</div>
<div id="tab-console" class="tab active" onclick="IDE.changeTab('console')">Console</div><div id="tab-js" class="tab" onclick="IDE.changeTab('js')">Javascript</div><div id="tab-fs" class="tab" onclick="IDE.changeTab('fs')">Files</div><div id="tab-help" class="tab" onclick="IDE.changeTab('help')">Help</div>
</div>
<div id="output-content">
<div id="warning-container"></div>
@ -63,8 +63,9 @@
<div id="fs-browser">
<div id="fs-path">
<span id="fs-url">/</span>
<div id="fs-refresh" title="Refresh" onclick="refreshFS()"></div>
<div id="fs-new-folder" title="New Directory" onclick="onNewDirectory()"></div>
<div id="fs-refresh" title="Refresh" onclick="IDE.refreshFS()"></div>
<div id="fs-new-folder" title="New Directory" onclick="IDE.onNewDirectory()"></div>
<div id="fs-upload" title="Upload" onclick="IDE.onUploadFile()"></div>
</div>
<div id="fs-contents">
</div>
@ -92,15 +93,15 @@
<div style="margin-bottom:5px">Copy the link below to share your code:</div>
<div><textarea id="share-code" rows="15" cols="60" readonly></textarea></div>
<div style="margin-top: 5px; float:left">Launch Mode:
<select id="share-mode" onchange="shareProgram()">
<select id="share-mode" onchange="IDE.shareProgram()">
<option value="">IDE (Default)</option>
<option value="play">Play</option>
<option value="auto">Auto</option>
</select>
</div>
<a id="export-button" href="javascript:exportProgram()" style="display: none; float:left; margin-top: 7px; margin-left: 10px">Export</a>
<a href="javascript:closeDialog()" style="display:block; float:right; margin-top: 7px">Close</a>
<a href="javascript:testShare()" style="display: block; float:right; margin-top: 7px; margin-right: 10px">Test</a>
<a id="export-button" href="javascript:IDE.exportProgram()" style="float:left; margin-top: 7px; margin-left: 10px">Export</a>
<a href="javascript:IDE.closeDialog()" style="display:block; float:right; margin-top: 7px">Close</a>
<a href="javascript:IDE.testShare()" style="display: block; float:right; margin-top: 7px; margin-right: 10px">Test</a>
</dialog>
<dialog id="prog-sel-dialog">
@ -110,14 +111,14 @@
</div>
<select id="prog-sel-sources" size="10" style="display:block; width:100%; margin-top:10px"></select>
<div style="text-align:center; margin-top:10px">
<a href="javascript:onSelMainProg()">Ok</a>
<a href="javascript:closeDialog()">Cancel</a>
<a href="javascript:IDE.onSelMainProg()">Ok</a>
<a href="javascript:IDE.closeDialog()">Cancel</a>
</div>
</dialog>
<dialog id="options-dialog">
<div>Select a theme:</div>
<select id="theme-picker" onchange="changeTheme(this.value)">
<select id="theme-picker" onchange="IDE.changeTheme(this.value)">
<option value="qbjs">Default</option>
<option value="qb45">QBasic</option>
<option value="qb64-vscode">QB64 VSCode</option>
@ -125,7 +126,7 @@
<option value="vscode-dark">VSCode Dark</option>
</select>
<div>
<a href="javascript:closeDialog()" style="display:block; float:right; margin-top: 7px">Close</a>
<a href="javascript:IDE.closeDialog()" style="display:block; float:right; margin-top: 7px">Close</a>
</div>
</dialog>
@ -139,14 +140,14 @@
QBJS brings the fun and accessibility of QBasic to the browser.<br/>
Learn more:<br/>
<ul>
<li><a href="javascript:showHelp('language')">QBasic Language Support</a></li>
<li><a href="javascript:showHelp('keywords')">Supported Keywords</a></li>
<li><a href="javascript:showHelp('samples')">Samples</a></li>
<li><a href="javascript:IDE.showHelp('language')">QBasic Language Support</a></li>
<li><a href="javascript:IDE.showHelp('keywords')">Supported Keywords</a></li>
<li><a href="javascript:IDE.showHelp('samples')">Samples</a></li>
</ul>
</p>
<p>Copyright (c) 2022-2023 boxgaming</p>
<div>
<a href="javascript:closeDialog()" style="display:block; float:right">Close</a>
<a href="javascript:IDE.closeDialog()" style="display:block; float:right">Close</a>
</div>
</div>
</dialog>

View file

@ -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

View file

@ -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;

View file

@ -1,3 +1,5 @@
var IDE = new function() {
var QBCompiler = null;
// if code has been passed on the query string load it into the editor
var qbcode = "";
@ -58,7 +60,7 @@ function _el(id) {
return document.getElementById(id);
}
async function init() {
async function _init() {
document.body.style.display = "initial";
if (window.innerWidth < 1200) {
@ -143,8 +145,14 @@ async function init() {
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();
_runProgram();
}
}
// compile
else if (event.code == 'F11') {
@ -166,7 +174,7 @@ async function init() {
// load a project
await loadProject(await res.arrayBuffer(), mainProg, function() {
if (appMode == "auto") {
runProgram();
_runProgram();
}
});
}
@ -179,15 +187,15 @@ async function init() {
}
var warnCount = 0;
changeTab("console");
_changeTab("console");
window.onresize();
if (appMode == "auto") {
runProgram();
_runProgram();
}
}
async function getErrorLine(error, stackDepth) {
function _getErrorLine(error, stackDepth) {
if (!stackDepth) {
stackDepth = 0;
}
@ -235,11 +243,11 @@ async function getErrorLine(error, stackDepth) {
return srcLine;
}
async function runProgram() {
async function _runProgram() {
_e.loadScreen.style.display = "none";
if (sizeMode == "max") {
slideLeft();
_slideLeft();
}
GX.reset();
QB.start();
@ -261,18 +269,18 @@ async function runProgram() {
console.error(error);
// find the source line, if possible
var srcLine = await getErrorLine(error);
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, "<div style='white-space:pre'>" + error.message + "\n<div style='color:#666'>" + error.stack + "</div></div>", "99%");
_addWarningCell(tr, "ERROR");
_addWarningCell(tr, ":");
_addWarningCell(tr, srcLine);
_addWarningCell(tr, ":");
_addWarningCell(tr, "<div style='white-space:pre'>" + error.message + "\n<div style='color:#666'>" + error.stack + "</div></div>", "99%");
tr.codeLine = srcLine - 1;
tr.onclick = gotoWarning;
tr.onclick = _gotoWarning;
table.append(tr);
}
@ -286,12 +294,12 @@ async function runProgram() {
return false;
}
function stopProgram() {
function _stopProgram() {
QB.halt();
GX.sceneStop();
}
function shareProgram() {
function _shareProgram() {
var zout = new Shorty();
var b64 = LZUTF8.compress(editor.getValue(), { outputEncoding: "Base64" });
var baseUrl = location.href.split('?')[0];
@ -311,22 +319,28 @@ function shareProgram() {
codeShare.select();
var exportVisible = (mode == "play" || mode == "auto");
_e.exportButton.style.display = (exportVisible) ? "block" : "none";
_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");
}
}
function changeTheme(newTheme) {
function _changeTheme(newTheme) {
theme = newTheme;
_e.ideTheme.href = "codemirror/themes/" + theme + ".css";
editor.setOption("theme", theme);
localStorage.setItem("@@_theme", theme);
}
function showOptionDialog() {
function _showOptionDialog() {
_e.themePicker.value = theme;
showDialog(_e.optionsDialog);
_showDialog(_e.optionsDialog);
}
function showDialog(dlg) {
function _showDialog(dlg) {
if (typeof dlg == "string") {
dlg = _el(dlg);
}
@ -335,7 +349,10 @@ function showDialog(dlg) {
}
}
async function exportProgram() {
async function _exportProgram() {
var mode = _e.shareMode.value;
if (mode == "") { return; }
var zip = new JSZip();
var qbCode = editor.getValue();
@ -385,7 +402,7 @@ function addVFSFiles(vfs, zip, parent) {
}
}
async function saveProject() {
async function _saveProject() {
var vfs = QB.vfs();
var node = vfs.getNode("/");
var count = vfs.getChildren(node, vfs.FILE).length;
@ -414,7 +431,7 @@ async function saveProject() {
}
}
async function openProject() {
async function _openProject() {
_e.fileInput.click();
}
@ -477,10 +494,10 @@ async function loadProject(zipData, mainFilename, fnCallback) {
var opt = new Option(basFiles[i], basFiles[i]);
fileList.append(opt);
}
showDialog(_e.progSelDialog);
_showDialog(_e.progSelDialog);
}
refreshFS();
_refreshFS();
if (fnCallback) {
fnCallback();
}
@ -505,7 +522,7 @@ async function loadProject(zipData, mainFilename, fnCallback) {
}
}
function onSelMainProg() {
function _onSelMainProg() {
var fileList = _e.progSelSources;
if (fileList.value == "") {
alert("No file selected.");
@ -529,11 +546,11 @@ async function getFile(path, type) {
}
}
function testShare() {
function _testShare() {
open(_e.shareCode.value, "_blank");
}
function closeDialog() {
function _closeDialog() {
_e.shareDialog.close();
_e.progSelDialog.close();
_e.optionsDialog.close();
@ -562,14 +579,14 @@ async function displayWarnings() {
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%");
_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;
tr.onclick = _gotoWarning;
}
}
if (!consoleVisible && w.length > 0) {
@ -577,14 +594,14 @@ async function displayWarnings() {
}
}
function gotoWarning() {
function _gotoWarning() {
if (selectedError ) { selectedError.classList.remove("selected"); }
editor.setCursor({ line: this.codeLine});
this.classList.add("selected");
selectedError = this;
};
}
function addWarningCell(tr, text, width) {
function _addWarningCell(tr, text, width) {
var td = document.createElement("td");
td.innerHTML = text;
td.vAlign = "top";
@ -594,7 +611,7 @@ function addWarningCell(tr, text, width) {
tr.append(td);
}
function showConsole() {
function _showConsole() {
consoleVisible = !consoleVisible;
if (!consoleVisible) {
_e.tbConsoleShow.style.display = "inline-block";
@ -608,7 +625,7 @@ function showConsole() {
window.dispatchEvent(new Event('resize'));
}
function changeTab(tabName) {
function _changeTab(tabName) {
if (tabName == currTab) { return; }
_el("tab-" + currTab).classList.remove("active");
_el("tab-" + tabName).classList.add("active");
@ -631,7 +648,7 @@ function changeTab(tabName) {
_e.warningContainer.style.display = "none";
_e.jsCode.style.display = "none";
_e.help.style.display = "none";
refreshFS();
_refreshFS();
}
else if (currTab == "help") {
_e.warningContainer.style.display = "none";
@ -641,15 +658,15 @@ function changeTab(tabName) {
}
}
function showHelp(page) {
changeTab("help");
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();
_showConsole();
}
function displayTypes() {
@ -662,7 +679,7 @@ function displayTypes() {
wdiv.innerHTML = tstr;
}
function slideLeft() {
function _slideLeft() {
_e.tbSlideRight.style.display = "inline-block";
if (sizeMode == "max" && window.innerWidth >= 1200) {
sizeMode = "normal"
@ -674,7 +691,7 @@ function slideLeft() {
window.dispatchEvent(new Event('resize'));
}
function slideRight() {
function _slideRight() {
_e.tbSlideLeft.style.display = "inline-block";
if (sizeMode == "min" && window.innerWidth >= 1200) {
sizeMode = "normal"
@ -773,10 +790,10 @@ function checkButtonState() {
setTimeout(checkButtonState, 100);
}
checkButtonState();
init();
_init();
// Virtual File System Viewer
function refreshFS() {
function _refreshFS() {
var vfs = QB.vfs();
var node = vfs.getNode(currPath);
if (!node) {
@ -840,7 +857,7 @@ function refreshFS() {
function deleteFile(node) {
if (confirm("This will permanently delete file '" + node.name + "'.\nAre you sure you wish to continue?")) {
vfs.removeFile(node);
refreshFS();
_refreshFS();
}
}
@ -851,24 +868,24 @@ function refreshFS() {
}
if (confirm("This will permanently delete directory '" + node.name + "'.\nAre you sure you wish to continue?")) {
vfs.removeDirectory(node);
refreshFS();
_refreshFS();
}
}
}
function onNewDirectory() {
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();
_refreshFS();
}
}
function chdir(path) {
currPath = path;
refreshFS();
_refreshFS();
}
function saveFile(path) {
@ -896,7 +913,6 @@ async function fileDrop(e) {
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) {
@ -909,7 +925,56 @@ async function fileDrop(e) {
vfs.writeData(file, data);
}
refreshFS();
_refreshFS();
}
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) {
@ -980,3 +1045,29 @@ function inIframe () {
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;
};