2022-09-17 16:50:08 +00:00
|
|
|
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 = "/";
|
2022-10-27 14:04:15 +00:00
|
|
|
var mainProg = null;
|
2023-04-18 19:25:54 +00:00
|
|
|
var theme = "qbjs";
|
2023-04-26 22:17:57 +00:00
|
|
|
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"),
|
2023-05-12 12:18:04 +00:00
|
|
|
themePicker: _el("theme-picker")
|
2023-04-26 22:17:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
function _el(id) {
|
|
|
|
return document.getElementById(id);
|
|
|
|
}
|
2022-09-17 16:50:08 +00:00
|
|
|
|
|
|
|
async function init() {
|
2023-04-18 19:25:54 +00:00
|
|
|
document.body.style.display = "initial";
|
|
|
|
|
2022-09-17 16:50:08 +00:00
|
|
|
if (window.innerWidth < 1200) {
|
|
|
|
sizeMode = "max";
|
|
|
|
}
|
|
|
|
|
2022-10-27 14:04:15 +00:00
|
|
|
var srcUrl = null;
|
2023-06-14 15:23:56 +00:00
|
|
|
if (url && (url.indexOf("?") || url.indexOf("#"))) {
|
|
|
|
var pindex = url.indexOf("?");
|
|
|
|
if (pindex == -1) {
|
|
|
|
pindex = url.indexOf("#");
|
|
|
|
}
|
|
|
|
var queryString = url.substring(pindex + 1);
|
2022-09-17 16:50:08 +00:00
|
|
|
var nvpairs = queryString.split("&");
|
|
|
|
for (var i = 0; i < nvpairs.length; i++) {
|
2023-06-14 15:23:56 +00:00
|
|
|
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;
|
|
|
|
}
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (appMode == "play") {
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.loadScreen.style.display = "block";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
2023-05-23 16:15:58 +00:00
|
|
|
else if (appMode == "ide") {
|
|
|
|
var stheme = localStorage.getItem("@@_theme");
|
|
|
|
if (stheme && stheme != "") {
|
|
|
|
theme = stheme;
|
|
|
|
}
|
|
|
|
_e.ideTheme.href = "codemirror/themes/" + theme + ".css";
|
|
|
|
}
|
2022-09-17 16:50:08 +00:00
|
|
|
|
|
|
|
// initialize the code editor
|
|
|
|
editor = CodeMirror(document.querySelector("#code"), {
|
|
|
|
lineNumbers: true,
|
|
|
|
tabSize: 4,
|
|
|
|
indentUnit: 4,
|
|
|
|
value: qbcode,
|
|
|
|
module: "qbjs",
|
2023-04-18 19:25:54 +00:00
|
|
|
theme: theme,
|
2022-09-17 16:50:08 +00:00
|
|
|
height: "auto",
|
|
|
|
styleActiveLine: true,
|
|
|
|
smartIndent: false,
|
|
|
|
extraKeys: {
|
|
|
|
"Tab": function(cm) {
|
|
|
|
cm.replaceSelection(" ", "end");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2023-03-21 17:05:37 +00:00
|
|
|
// 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();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-10-27 14:04:15 +00:00
|
|
|
if (srcUrl) {
|
2023-06-14 15:23:56 +00:00
|
|
|
var res = await fetch(srcUrl);
|
2022-10-27 14:04:15 +00:00
|
|
|
var contentType = res.headers.get("Content-Type");
|
2023-06-14 15:23:56 +00:00
|
|
|
if (contentType == "application/zip" ||
|
|
|
|
contentType == "application/zip-compressed" ||
|
|
|
|
contentType == "application/x-zip-compressed") {
|
2022-10-27 14:04:15 +00:00
|
|
|
// load a project
|
|
|
|
await loadProject(await res.arrayBuffer(), mainProg);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// otherwise, assume a single source file
|
|
|
|
var decoder = new TextDecoder("iso-8859-1");
|
|
|
|
qbcode = decoder.decode(await res.arrayBuffer());
|
|
|
|
editor.setValue(qbcode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-17 16:50:08 +00:00
|
|
|
var warnCount = 0;
|
|
|
|
changeTab("console");
|
|
|
|
window.onresize();
|
|
|
|
|
|
|
|
if (appMode == "auto") {
|
|
|
|
runProgram();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-18 19:25:54 +00:00
|
|
|
async function getErrorLine(error, stackDepth) {
|
2023-04-26 22:17:57 +00:00
|
|
|
if (!stackDepth) {
|
2023-04-18 19:25:54 +00:00
|
|
|
stackDepth = 0;
|
|
|
|
}
|
|
|
|
else if (error._stackDepth) {
|
|
|
|
stackDepth = error._stackDepth;
|
|
|
|
}
|
|
|
|
|
|
|
|
var cdepth = 0;
|
|
|
|
var srcLine = "";
|
|
|
|
if (error.line) { // safari
|
|
|
|
srcLine = error.line - 1;
|
|
|
|
}
|
2023-05-12 12:18:04 +00:00
|
|
|
|
|
|
|
if (!error.stack) { return 0; }
|
|
|
|
|
2023-04-18 19:25:54 +00:00
|
|
|
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("<anonymous>:");
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-09-17 16:50:08 +00:00
|
|
|
async function runProgram() {
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.loadScreen.style.display = "none";
|
2022-09-17 16:50:08 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.jsCode.innerHTML = jsCode;
|
2022-09-17 16:50:08 +00:00
|
|
|
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
|
2023-04-18 19:25:54 +00:00
|
|
|
var srcLine = await getErrorLine(error);
|
|
|
|
console.log("returned: " + srcLine);
|
2022-09-17 16:50:08 +00:00
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
var table = _el("warning-table");
|
2022-09-17 16:50:08 +00:00
|
|
|
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%");
|
|
|
|
tr.codeLine = srcLine - 1;
|
|
|
|
tr.onclick = gotoWarning;
|
|
|
|
table.append(tr);
|
|
|
|
}
|
|
|
|
|
|
|
|
consoleVisible = true;
|
|
|
|
window.onresize();
|
|
|
|
QB.halt();
|
|
|
|
GX.sceneStop();
|
|
|
|
}
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.gxContainer.focus();
|
2022-09-17 16:50:08 +00:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function stopProgram() {
|
|
|
|
QB.halt();
|
|
|
|
GX.sceneStop();
|
|
|
|
}
|
|
|
|
|
|
|
|
function shareProgram() {
|
|
|
|
var zout = new Shorty();
|
|
|
|
var b64 = LZUTF8.compress(editor.getValue(), { outputEncoding: "Base64" });
|
|
|
|
var baseUrl = location.href.split('?')[0];
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
var mode = _e.shareMode.value;
|
|
|
|
var codeShare = _e.shareCode;
|
2022-09-17 16:50:08 +00:00
|
|
|
var url = baseUrl + "?";
|
|
|
|
if (mode) {
|
|
|
|
url += "mode=" + mode + "&";
|
|
|
|
}
|
|
|
|
url += "code=" + b64;
|
|
|
|
codeShare.value = url;
|
2023-04-26 22:17:57 +00:00
|
|
|
if (!_e.shareDialog.open) {
|
|
|
|
_e.shareDialog.showModal();
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
codeShare.focus();
|
|
|
|
codeShare.select();
|
|
|
|
|
|
|
|
var exportVisible = (mode == "play" || mode == "auto");
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.exportButton.style.display = (exportVisible) ? "block" : "none";
|
2023-04-18 19:25:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function changeTheme(newTheme) {
|
|
|
|
theme = newTheme;
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.ideTheme.href = "codemirror/themes/" + theme + ".css";
|
2023-04-18 19:25:54 +00:00
|
|
|
editor.setOption("theme", theme);
|
2023-05-12 12:18:04 +00:00
|
|
|
localStorage.setItem("@@_theme", theme);
|
|
|
|
}
|
|
|
|
|
|
|
|
function showOptionDialog() {
|
|
|
|
_e.themePicker.value = theme;
|
|
|
|
showDialog(_e.optionsDialog);
|
2023-04-18 19:25:54 +00:00
|
|
|
}
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
function showDialog(dlg) {
|
|
|
|
if (typeof dlg == "string") {
|
|
|
|
dlg = _el(dlg);
|
|
|
|
}
|
|
|
|
if (!dlg.open) {
|
|
|
|
dlg.showModal();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-17 16:50:08 +00:00
|
|
|
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}";
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
var mode = _e.shareMode.value;
|
2022-09-17 16:50:08 +00:00
|
|
|
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();
|
|
|
|
});
|
2022-10-27 14:04:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function saveProject() {
|
|
|
|
var vfs = QB.vfs();
|
|
|
|
var node = vfs.getNode("/");
|
|
|
|
var count = vfs.getChildren(node, vfs.FILE).length;
|
2022-11-01 03:55:08 +00:00
|
|
|
if (count < 1) {
|
|
|
|
count = vfs.getChildren(node, vfs.DIRECTORY).length;
|
|
|
|
}
|
2022-10-27 14:04:15 +00:00
|
|
|
|
|
|
|
// save a single .bas file
|
|
|
|
if (count == 0) {
|
|
|
|
var progFile = new Blob([ editor.getValue() ]);
|
2023-04-18 19:25:54 +00:00
|
|
|
QB.downloadFile(progFile, "program.bas");
|
2022-10-27 14:04:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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) {
|
2023-04-18 19:25:54 +00:00
|
|
|
QB.downloadFile(content, "project.zip");
|
2022-10-27 14:04:15 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function openProject() {
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.fileInput.click();
|
2022-10-27 14:04:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async function onOpenProject(event) {
|
|
|
|
var f = event.target.files[0];
|
2022-09-17 16:50:08 +00:00
|
|
|
|
2022-10-27 14:04:15 +00:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.fileInput.onchange = onOpenProject;
|
2022-10-27 14:04:15 +00:00
|
|
|
|
|
|
|
async function loadProject(zipData, mainFilename) {
|
|
|
|
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 {
|
2022-11-01 03:55:08 +00:00
|
|
|
console.log(filename);
|
|
|
|
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);
|
|
|
|
}
|
2022-10-27 14:04:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!mainFound) {
|
2023-04-26 22:17:57 +00:00
|
|
|
var fileList = _e.progSelSources;
|
2022-10-27 14:04:15 +00:00
|
|
|
fileList.innerHTML = "";
|
|
|
|
for (var i=0; i < basFiles.length; i++) {
|
|
|
|
var opt = new Option(basFiles[i], basFiles[i]);
|
|
|
|
fileList.append(opt);
|
|
|
|
}
|
2023-04-26 22:17:57 +00:00
|
|
|
showDialog(_e.progSelDialog);
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
|
2022-10-27 14:04:15 +00:00
|
|
|
refreshFS();
|
|
|
|
});
|
|
|
|
|
|
|
|
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;
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
2022-10-27 14:04:15 +00:00
|
|
|
return parent;
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-27 14:04:15 +00:00
|
|
|
function onSelMainProg() {
|
2023-04-26 22:17:57 +00:00
|
|
|
var fileList = _e.progSelSources;
|
2022-10-27 14:04:15 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-17 16:50:08 +00:00
|
|
|
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() {
|
2023-04-26 22:17:57 +00:00
|
|
|
open(_e.shareCode.value, "_blank");
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function closeDialog() {
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.shareDialog.close();
|
|
|
|
_e.progSelDialog.close();
|
|
|
|
_e.optionsDialog.close();
|
|
|
|
_e.aboutDialog.close();
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async function displayWarnings() {
|
|
|
|
var wstr = "";
|
|
|
|
var w = await QBCompiler.getWarnings();
|
|
|
|
warnCount = w.length;
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
var wdiv = _e.warningContainer;
|
2022-09-17 16:50:08 +00:00
|
|
|
wdiv.innerHTML = "";
|
|
|
|
var table = document.createElement("table");
|
2023-04-26 22:17:57 +00:00
|
|
|
table.style.width = "100%";
|
2022-09-17 16:50:08 +00:00
|
|
|
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;
|
2023-04-18 19:25:54 +00:00
|
|
|
tr.onclick = gotoWarning;
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!consoleVisible && w.length > 0) {
|
|
|
|
consoleVisible = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function gotoWarning() {
|
2023-04-26 22:17:57 +00:00
|
|
|
if (selectedError ) { selectedError.classList.remove("selected"); }
|
|
|
|
editor.setCursor({ line: this.codeLine});
|
|
|
|
this.classList.add("selected");
|
|
|
|
selectedError = this;
|
2022-09-17 16:50:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
2023-04-26 22:17:57 +00:00
|
|
|
if (!consoleVisible) {
|
|
|
|
_e.tbConsoleShow.style.display = "inline-block";
|
|
|
|
_e.tbConsoleHide.style.display = "none";
|
2023-05-12 12:18:04 +00:00
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
_e.tbConsoleHide.style.display = "inline-block";
|
|
|
|
_e.tbConsoleShow.style.display = "none";
|
|
|
|
}
|
2022-09-17 16:50:08 +00:00
|
|
|
window.dispatchEvent(new Event('resize'));
|
|
|
|
}
|
|
|
|
|
|
|
|
function changeTab(tabName) {
|
|
|
|
if (tabName == currTab) { return; }
|
2023-04-26 22:17:57 +00:00
|
|
|
_el("tab-" + currTab).classList.remove("active");
|
|
|
|
_el("tab-" + tabName).classList.add("active");
|
2022-09-17 16:50:08 +00:00
|
|
|
currTab = tabName;
|
|
|
|
|
|
|
|
if (currTab == "console") {
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.warningContainer.style.display = "block";
|
|
|
|
_e.jsCode.style.display = "none";
|
|
|
|
_e.fsBrowser.style.display = "none";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
else if (currTab == "js") {
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.warningContainer.style.display = "none";
|
|
|
|
_e.fsBrowser.style.display = "none";
|
|
|
|
_e.jsCode.style.display = "block";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
else if (currTab == "fs") {
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.fsBrowser.style.display = "block";
|
|
|
|
_e.warningContainer.style.display = "none";
|
|
|
|
_e.jsCode.style.display = "none";
|
2022-09-17 16:50:08 +00:00
|
|
|
refreshFS();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function displayTypes() {
|
|
|
|
var tstr = "";
|
|
|
|
var t = QBCompiler.getTypes();
|
|
|
|
for (var i=0; i < t.length; i++) {
|
|
|
|
tstr += t[i].name
|
|
|
|
}
|
2023-04-26 22:17:57 +00:00
|
|
|
var wdiv = _e.warningContainer;
|
2022-09-17 16:50:08 +00:00
|
|
|
wdiv.innerHTML = tstr;
|
|
|
|
}
|
|
|
|
|
|
|
|
function slideLeft() {
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.tbSlideRight.style.display = "inline-block";
|
2022-09-17 16:50:08 +00:00
|
|
|
if (sizeMode == "max" && window.innerWidth >= 1200) {
|
|
|
|
sizeMode = "normal"
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sizeMode = "min"
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.tbSlideLeft.style.display = "none";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
window.dispatchEvent(new Event('resize'));
|
|
|
|
}
|
|
|
|
|
|
|
|
function slideRight() {
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.tbSlideLeft.style.display = "inline-block";
|
2022-09-17 16:50:08 +00:00
|
|
|
if (sizeMode == "min" && window.innerWidth >= 1200) {
|
|
|
|
sizeMode = "normal"
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
sizeMode = "max"
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.tbSlideRight.style.display = "none";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
window.dispatchEvent(new Event('resize'));
|
|
|
|
}
|
|
|
|
|
|
|
|
window.onresize = function() {
|
|
|
|
if (!editor) { return; }
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
var f = _e.gxContainer;
|
|
|
|
var jsDiv = _e.outputContainer;
|
2022-09-17 16:50:08 +00:00
|
|
|
|
|
|
|
if (appMode == "play" || appMode == "auto") {
|
|
|
|
f.style.left = "0px";
|
|
|
|
f.style.top = "0px";
|
2023-06-14 15:23:56 +00:00
|
|
|
f.style.width = window.innerWidth + "px";
|
|
|
|
f.style.height = window.innerHeight + "px";
|
2022-09-17 16:50:08 +00:00
|
|
|
f.style.border = "0px";
|
2023-04-26 22:17:57 +00:00
|
|
|
_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";
|
2022-09-17 16:50:08 +00:00
|
|
|
jsDiv.style.display = "none";
|
2023-06-14 15:23:56 +00:00
|
|
|
_e.vslider.style.display = "none";
|
|
|
|
splitHeight = 0;
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
else {
|
2023-04-26 22:17:57 +00:00
|
|
|
var cmwidth = splitWidth;
|
2022-09-17 16:50:08 +00:00
|
|
|
if (sizeMode == "min") {
|
2023-04-26 22:17:57 +00:00
|
|
|
cmwidth = -10;
|
2022-09-17 16:50:08 +00:00
|
|
|
editor.getWrapperElement().style.display = "none";
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.rightPanel.style.display = "block";
|
|
|
|
_e.slider.style.display = "none";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
else if (sizeMode == "max") {
|
2023-04-26 22:17:57 +00:00
|
|
|
cmwidth = window.innerWidth - 12;
|
|
|
|
_e.rightPanel.style.display = "none";
|
|
|
|
_e.slider.style.display = "none";
|
2022-09-17 16:50:08 +00:00
|
|
|
editor.getWrapperElement().style.display = "block";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
editor.getWrapperElement().style.display = "block";
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.rightPanel.style.display = "block";
|
|
|
|
_e.slider.style.display = "block";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.rightPanel.style.left = (cmwidth + 15) + "px";
|
|
|
|
f.style.width = (window.innerWidth - (cmwidth + 22)) + "px";
|
2022-09-17 16:50:08 +00:00
|
|
|
jsDiv.style.width = f.style.width;
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.slider.style.left = (cmwidth + 7) + "px";
|
2022-09-17 16:50:08 +00:00
|
|
|
|
|
|
|
if (consoleVisible) {
|
2023-05-12 12:18:04 +00:00
|
|
|
_e.vslider.style.display = "block";
|
2023-04-26 22:17:57 +00:00
|
|
|
f.style.height = (window.innerHeight - splitHeight) + "px";
|
2022-09-17 16:50:08 +00:00
|
|
|
jsDiv.style.display = "block";
|
2023-04-26 22:17:57 +00:00
|
|
|
jsDiv.style.top = (window.innerHeight - splitHeight + 10) + "px";
|
|
|
|
_e.outputContent.style.height = (splitHeight - 77) + "px";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
else {
|
2023-05-12 12:18:04 +00:00
|
|
|
_e.vslider.style.display = "none";
|
2023-04-26 22:17:57 +00:00
|
|
|
f.style.height = (window.innerHeight - 40) + "px";
|
2022-09-17 16:50:08 +00:00
|
|
|
jsDiv.style.display = "none";
|
|
|
|
}
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
editor.setSize(cmwidth, window.innerHeight - 40);
|
|
|
|
_e.code.style.height = (window.innerHeight - 40) + "px";
|
|
|
|
_e.slider.style.height = (window.innerHeight - 40) + "px";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
QB.resize(f.clientWidth, f.clientHeight);
|
|
|
|
}
|
|
|
|
window.onresize();
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
|
2022-09-17 16:50:08 +00:00
|
|
|
function checkButtonState() {
|
2023-04-26 22:17:57 +00:00
|
|
|
var stopButton = _e.tbStop;
|
|
|
|
var runButton = _e.tbRun;
|
2022-09-17 16:50:08 +00:00
|
|
|
if (GX.sceneActive() || QB.running()) {
|
2023-04-26 22:17:57 +00:00
|
|
|
stopButton.style.display = "inline-block";
|
|
|
|
runButton.style.display = "none";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
stopButton.style.display = "none";
|
2023-04-26 22:17:57 +00:00
|
|
|
runButton.style.display = "inline-block";
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
var contents = _e.fsContents;
|
2022-09-17 16:50:08 +00:00
|
|
|
while (contents.firstChild) {
|
|
|
|
contents.removeChild(contents.firstChild);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!node) {
|
|
|
|
// TODO: better error reporting
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
currPath = vfs.fullPath(node)
|
2023-04-26 22:17:57 +00:00
|
|
|
_e.fsUrl.innerHTML = currPath;
|
2022-09-17 16:50:08 +00:00
|
|
|
|
|
|
|
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);
|
2022-10-28 19:58:21 +00:00
|
|
|
contents.appendChild(document.createElement("span"));
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2022-10-28 19:58:21 +00:00
|
|
|
a = document.createElement("a");
|
|
|
|
a.className = "fs-delete";
|
|
|
|
a.vfsnode = folders[i];
|
|
|
|
a.onclick = function() { deleteDir(this.vfsnode); };
|
|
|
|
contents.appendChild(a);
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2022-10-28 19:58:21 +00:00
|
|
|
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();
|
2022-09-17 16:50:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
console.log(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++) {
|
|
|
|
console.log("processing[" + i + "]...");
|
2022-11-01 03:55:08 +00:00
|
|
|
|
2022-09-17 16:50:08 +00:00
|
|
|
var f = files[i];
|
2022-11-01 03:55:08 +00:00
|
|
|
if (!f.type && f.size%4096 == 0) {
|
|
|
|
// this is a folder, skip
|
|
|
|
console.log(" -> skipping folder [" + i + "]");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-09-17 16:50:08 +00:00
|
|
|
var file = vfs.createFile(f.name, parentDir);
|
|
|
|
var data = await f.arrayBuffer();
|
|
|
|
console.log(data);
|
|
|
|
vfs.writeData(file, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
refreshFS();
|
|
|
|
}
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
_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;
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-09-17 16:50:08 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-04-26 22:17:57 +00:00
|
|
|
var dropArea = _e.outputContent;
|
2022-09-17 16:50:08 +00:00
|
|
|
dropArea.addEventListener("drop", fileDrop, false);
|
|
|
|
dropArea.addEventListener("dragover", fileDragOver, false);
|
|
|
|
dropArea.addEventListener("dragenter", fileDragEnter, false);
|
2023-05-12 12:18:04 +00:00
|
|
|
dropArea.addEventListener("dragleave", fileDragLeave, false);
|
|
|
|
|
2023-06-03 20:34:10 +00:00
|
|
|
if (!inIframe()) {
|
|
|
|
addEventListener("beforeunload", function(e) {
|
|
|
|
e.preventDefault();
|
|
|
|
return e.returnValue = "stop";
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function inIframe () {
|
|
|
|
try {
|
|
|
|
return window.self !== window.top;
|
|
|
|
} catch (e) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|