mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-24 12:31:25 +00:00
electron: open workspace w/ metadata file, write files
This commit is contained in:
parent
13a4570745
commit
8b801e39df
@ -1,6 +1,6 @@
|
|||||||
[![Build Status](https://travis-ci.org/sehugg/8bitworkshop.svg?branch=master)](https://travis-ci.org/sehugg/8bitworkshop)
|
[![Build Status](https://travis-ci.org/sehugg/8bitworkshop.svg?branch=master)](https://travis-ci.org/sehugg/8bitworkshop)
|
||||||
|
|
||||||
The latest release is online at http://8bitworkshop.com/
|
The latest release is online at https://8bitworkshop.com/
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
|
@ -15,20 +15,15 @@ TODO:
|
|||||||
- watchpoints
|
- watchpoints
|
||||||
- step over (line, instruction)
|
- step over (line, instruction)
|
||||||
- slowdown beam for all platforms?
|
- slowdown beam for all platforms?
|
||||||
- show errors in list (maybe window list?)
|
- intro/help text for each platform
|
||||||
- click to go to error
|
|
||||||
- what if error in include file you can't edit b/c it never appears?
|
|
||||||
- online help
|
|
||||||
- show self-modifying code insns left of editor
|
- show self-modifying code insns left of editor
|
||||||
- update Javatari version? (and others?)
|
- update Javatari version? (and others?)
|
||||||
- sound mute?
|
- sound mute?
|
||||||
- $error updates source editor
|
- $error updates source editor
|
||||||
- online tools for music etc
|
- online tools for music etc
|
||||||
- text log debugging script
|
- text log debugging script
|
||||||
- intro/help text for each platform
|
|
||||||
- vscode/atom extension?
|
- vscode/atom extension?
|
||||||
- click to break on raster position
|
- click to break on raster position
|
||||||
- restructure src/ folders
|
|
||||||
- debug bankswitching for funky formats
|
- debug bankswitching for funky formats
|
||||||
- 'undefined' for bitmap replacer
|
- 'undefined' for bitmap replacer
|
||||||
- requestInterrupt needs to be disabled after breakpoint?
|
- requestInterrupt needs to be disabled after breakpoint?
|
||||||
|
@ -24,9 +24,18 @@ process.once('loaded', () => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// from browser: put workspace file
|
||||||
|
window.putWorkspaceFile = function(path, data) {
|
||||||
|
if (wsroot == null) throw Error("no workspace root set");
|
||||||
|
var fullpath = modpath.join(wsroot, modpath.normalize(path));
|
||||||
|
var encoding = typeof data === 'string' ? 'utf8' : null;
|
||||||
|
fs.writeFileSync(fullpath, data, {encoding:encoding});
|
||||||
|
}
|
||||||
// from electron.js: set workspace root directory
|
// from electron.js: set workspace root directory
|
||||||
ipcRenderer.on('setWorkspaceRoot', (event, data) => {
|
ipcRenderer.on('setWorkspaceRoot', (event, data) => {
|
||||||
wsroot = data.root;
|
wsroot = data.root;
|
||||||
|
var binpath = modpath.join(wsroot, 'bin');
|
||||||
|
if (!fs.existsSync(binpath)) fs.mkdirSync(binpath, {});
|
||||||
console.log('setWorkspaceRoot', wsroot);
|
console.log('setWorkspaceRoot', wsroot);
|
||||||
});
|
});
|
||||||
// from electron.js: file changed
|
// from electron.js: file changed
|
||||||
|
@ -14,6 +14,29 @@ body {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<!-- Sentry error reporting -->
|
||||||
|
<script defer
|
||||||
|
src="https://browser.sentry-cdn.com/5.22.3/bundle.tracing.min.js"
|
||||||
|
integrity="sha384-HfEJlGrJtFM0B01Wt4sGzTbxWqLMcMeGAXCbyQyB+iK9BhnDmNAtIGovhekIQOa2"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
></script>
|
||||||
|
<script defer>
|
||||||
|
Sentry.init({
|
||||||
|
dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925',
|
||||||
|
beforeBreadcrumb(breadcrumb, hint) {
|
||||||
|
if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
||||||
|
if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
||||||
|
}
|
||||||
|
return breadcrumb;
|
||||||
|
},
|
||||||
|
beforeSend(event, hint) {
|
||||||
|
const error = hint.originalException;
|
||||||
|
if (error instanceof EmuHalt) return null; // ignore EmuHalt
|
||||||
|
return event;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- for file upload -->
|
<!-- for file upload -->
|
||||||
<input type="file" id="uploadFileElem" multiple accept="*" style="display:none" onchange="handleFileUpload(this.files)">
|
<input type="file" id="uploadFileElem" multiple accept="*" style="display:none" onchange="handleFileUpload(this.files)">
|
||||||
|
|
||||||
|
208
electron.js
208
electron.js
@ -6,16 +6,33 @@ const isMac = process.platform === 'darwin'
|
|||||||
const chokidar = require('chokidar')
|
const chokidar = require('chokidar')
|
||||||
const Store = require('electron-store');
|
const Store = require('electron-store');
|
||||||
const store = new Store();
|
const store = new Store();
|
||||||
const KEY_lastWorkspaceFilePath = "lastWorkspaceFilePath";
|
const WSMETA_FILENAME = "8bitworkshop.json"
|
||||||
|
const README_FILENAME = "README.md"
|
||||||
|
|
||||||
|
// call updater
|
||||||
|
require('update-electron-app')()
|
||||||
|
|
||||||
|
// show error dialog
|
||||||
|
function showError(msg, detail) {
|
||||||
|
msg = msg.message || msg;
|
||||||
|
dialog.showMessageBoxSync({
|
||||||
|
type: "error",
|
||||||
|
message: msg,
|
||||||
|
detail: detail
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// file watcher
|
// file watcher
|
||||||
// TODO: add workspace metadata for platform, ROM output, README, etc.
|
|
||||||
class Workspace {
|
class Workspace {
|
||||||
constructor(directory, mainfile, wnd) {
|
constructor(directory, meta, wnd) {
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
this.mainfile = mainfile;
|
this.mainfile = meta.mainfile;
|
||||||
wnd.webContents.send('setWorkspaceRoot', {root:this.directory});
|
this.platform = meta.platform;
|
||||||
this.watcher = chokidar.watch(modpath.join(directory, mainfile));
|
if (!this.mainfile) throw new Error(`The "mainfile" key is missing in ${WSMETA_FILENAME}.`)
|
||||||
|
if (!this.platform) throw new Error(`The "platform" key is missing in ${WSMETA_FILENAME}.`)
|
||||||
|
var mainfilepath = modpath.join(directory, this.mainfile);
|
||||||
|
if (!fs.existsSync(mainfilepath)) throw new Error(`The file "${mainfilepath}" is missing.`);
|
||||||
|
this.watcher = chokidar.watch(mainfilepath);
|
||||||
this.watcher.on('all', (event, path) => {
|
this.watcher.on('all', (event, path) => {
|
||||||
console.log(event, path);
|
console.log(event, path);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
@ -38,34 +55,51 @@ class Workspace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openFile(path, wnd) {
|
function readWorkspaceMetadata(directory) {
|
||||||
if (!fs.existsSync(path)) {
|
// check README file
|
||||||
dialog.showMessageBox({
|
var readmepath = modpath.join(directory, README_FILENAME);
|
||||||
type: "error",
|
if (fs.existsSync(readmepath)) {
|
||||||
message: "File not found.",
|
let readme = fs.readFileSync(readmepath, 'utf8');
|
||||||
detail: path
|
let sess = {};
|
||||||
});
|
// check README for main file
|
||||||
return;
|
const re8main = /8bitworkshop.com[^)]+file=([^)&]+)/;
|
||||||
|
m = re8main.exec(readme);
|
||||||
|
if (m && m[1]) {
|
||||||
|
sess.mainfile = m[1];
|
||||||
|
}
|
||||||
|
// check README for proper platform
|
||||||
|
// unless we use githubURL=
|
||||||
|
const re8plat = /8bitworkshop.com[^)]+platform=([A-Za-z0-9._\-]+)/;
|
||||||
|
m = re8plat.exec(readme);
|
||||||
|
if (m) {
|
||||||
|
sess.platform = m[1];
|
||||||
|
}
|
||||||
|
if (sess.mainfile != null && sess.platform != null) return sess;
|
||||||
}
|
}
|
||||||
var dirname = modpath.dirname(path);
|
// check JSON file
|
||||||
var filename = modpath.basename(path);
|
var metapath = modpath.join(directory, WSMETA_FILENAME);
|
||||||
if (!wnd) wnd = BrowserWindow.getFocusedWindow();
|
if (fs.existsSync(metapath)) {
|
||||||
var ws = new Workspace(dirname, filename, wnd);
|
return JSON.parse(fs.readFileSync(metapath, 'utf8'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeWorkspaceMetadata(directory, meta) {
|
||||||
|
var metapath = modpath.join(directory, WSMETA_FILENAME);
|
||||||
|
fs.writeFileSync(metapath, JSON.stringify(meta), 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
function openWorkspace(wnd, ws) {
|
||||||
if (wnd.workspace) { wnd.workspace.close(); }
|
if (wnd.workspace) { wnd.workspace.close(); }
|
||||||
wnd.workspace = ws;
|
wnd.workspace = ws;
|
||||||
wnd.on('closed', () => {
|
wnd.on('closed', () => {
|
||||||
ws.close();
|
ws.close();
|
||||||
});
|
});
|
||||||
openWorkspace(wnd, ws);
|
|
||||||
app.addRecentDocument(path);
|
|
||||||
store.set(KEY_lastWorkspaceFilePath, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
function openWorkspace(wnd, ws) {
|
|
||||||
var qs = new URLSearchParams();
|
var qs = new URLSearchParams();
|
||||||
qs.set('electron_ws', 1);
|
qs.set('electron_ws', 1);
|
||||||
qs.set('repo', ws.directory);
|
qs.set('repo', ws.directory);
|
||||||
qs.set('file', ws.mainfile);
|
qs.set('file', ws.mainfile);
|
||||||
|
qs.set('platform', ws.platform);
|
||||||
|
console.log(qs);
|
||||||
wnd.loadURL(`file://${__dirname}/electron.html?${qs}`).then(() => {
|
wnd.loadURL(`file://${__dirname}/electron.html?${qs}`).then(() => {
|
||||||
wnd.webContents.send('setWorkspaceRoot', {root:ws.directory});
|
wnd.webContents.send('setWorkspaceRoot', {root:ws.directory});
|
||||||
});
|
});
|
||||||
@ -81,42 +115,88 @@ function reloadCurrentWindow() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openFileDialog() {
|
// TODO: better way to get this?
|
||||||
|
function getCurrentPlatform(wnd) {
|
||||||
|
var url = wnd.webContents.getURL();
|
||||||
|
if (url != null) {
|
||||||
|
console.log(url);
|
||||||
|
var m = /platform=([^&]+)/.exec(url);
|
||||||
|
if (m) return m[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openWorkspaceWindow(wspath) {
|
||||||
|
try {
|
||||||
|
// replace current window
|
||||||
|
var wnd = BrowserWindow.getFocusedWindow() || createWindow();
|
||||||
|
// read metadata file
|
||||||
|
var meta = readWorkspaceMetadata(wspath);
|
||||||
|
// does it exist?
|
||||||
|
if (meta == null) {
|
||||||
|
// create a new workspace?
|
||||||
|
var cancel = dialog.showMessageBoxSync(wnd, {
|
||||||
|
type: 'question',
|
||||||
|
title: 'Create Workspace?',
|
||||||
|
message: `Project metadata not found. Create new ${getCurrentPlatform(wnd)||""} project in this directory?`,
|
||||||
|
detail: wspath,
|
||||||
|
buttons: ['Create', 'Cancel'],
|
||||||
|
});
|
||||||
|
if (!cancel) {
|
||||||
|
var platform = getCurrentPlatform(wnd);
|
||||||
|
// choose main file
|
||||||
|
var files = dialog.showOpenDialogSync({
|
||||||
|
message: `Choose the main file of your ${platform} project, or create one.`,
|
||||||
|
defaultPath: wspath,
|
||||||
|
properties: ['openFile','promptToCreate'],
|
||||||
|
});
|
||||||
|
if (files != null) {
|
||||||
|
var mainfile = modpath.relative(wspath, files[0]);
|
||||||
|
// write new metadata
|
||||||
|
meta = {
|
||||||
|
platform: platform,
|
||||||
|
mainfile: mainfile,
|
||||||
|
};
|
||||||
|
console.log(meta);
|
||||||
|
if (meta.platform == null) {
|
||||||
|
showError("Can't determine current platform.");
|
||||||
|
} else {
|
||||||
|
writeWorkspaceMetadata(wspath, meta);
|
||||||
|
openWorkspaceWindow(wspath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(meta);
|
||||||
|
var ws = new Workspace(wspath, meta, wnd);
|
||||||
|
openWorkspace(wnd, ws);
|
||||||
|
app.addRecentDocument(wspath);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
showError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openDefaultWorkspace() {
|
||||||
|
if (process.argv.length >= 3) {
|
||||||
|
openWorkspaceWindow(modpath.resolve(process.argv[2]));
|
||||||
|
} else {
|
||||||
|
createWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openWorkspaceDialog() {
|
||||||
dialog.showOpenDialog({
|
dialog.showOpenDialog({
|
||||||
title: "Open File",
|
title: "Open Workspace",
|
||||||
properties: ['openFile','promptToCreate'],
|
properties: ['openDirectory'],
|
||||||
|
message: "Choose the directory that holds your source files.",
|
||||||
}).then((rtn) => {
|
}).then((rtn) => {
|
||||||
if (!rtn.canceled && rtn.filePaths && rtn.filePaths.length > 0) {
|
if (!rtn.canceled && rtn.filePaths && rtn.filePaths.length > 0) {
|
||||||
var path = rtn.filePaths[0];
|
var path = rtn.filePaths[0];
|
||||||
openFile(path);
|
openWorkspaceWindow(path);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function openDefaultFile() {
|
|
||||||
var wnd = createWindow();
|
|
||||||
if (process.argv.length >= 3) {
|
|
||||||
openFile(process.argv[2], wnd);
|
|
||||||
}
|
|
||||||
/* TODO
|
|
||||||
var lastfile = store.get(KEY_lastWorkspaceFilePath);
|
|
||||||
if (lastfile != null) {
|
|
||||||
openFile(lastfile);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
function openWorkspace() {
|
|
||||||
const { dialog } = require('electron')
|
|
||||||
console.log(dialog.showOpenDialog({
|
|
||||||
title: "Open Workspace",
|
|
||||||
properties: ['openDirectory','createDirectory','promptToCreate'],
|
|
||||||
message: "Choose a directory that holds your source files.",
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function openURL(url) {
|
function openURL(url) {
|
||||||
return async () => {
|
return async () => {
|
||||||
const { shell } = require('electron')
|
const { shell } = require('electron')
|
||||||
@ -147,8 +227,13 @@ function buildMenu() {
|
|||||||
label: 'File',
|
label: 'File',
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'Open File...',
|
label: 'New Playground',
|
||||||
click: openFileDialog,
|
click: openDefaultWorkspace,
|
||||||
|
accelerator: 'CmdOrCtrl+N',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Open Workspace...',
|
||||||
|
click: openWorkspaceDialog,
|
||||||
accelerator: 'CmdOrCtrl+O',
|
accelerator: 'CmdOrCtrl+O',
|
||||||
},
|
},
|
||||||
// When a file is requested from the recent documents menu, the open-file event of app module will be emitted for it.
|
// When a file is requested from the recent documents menu, the open-file event of app module will be emitted for it.
|
||||||
@ -239,13 +324,18 @@ function buildMenu() {
|
|||||||
label: 'Latest News',
|
label: 'Latest News',
|
||||||
click: openURL('https://8bitworkshop.com/blog/')
|
click: openURL('https://8bitworkshop.com/blog/')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Report an Issue',
|
||||||
|
click: openURL('https://github.com/sehugg/8bitworkshop/issues/new')
|
||||||
|
},
|
||||||
|
{ type: 'separator' },
|
||||||
{
|
{
|
||||||
label: 'Follow @8bitworkshop on Twitter',
|
label: 'Follow @8bitworkshop on Twitter',
|
||||||
click: openURL('https://twitter.com/8bitworkshop')
|
click: openURL('https://twitter.com/8bitworkshop')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Report an Issue',
|
label: 'Become a Patreon',
|
||||||
click: openURL('https://github.com/sehugg/8bitworkshop/issues/new')
|
click: openURL('https://www.patreon.com/8bitworkshop')
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -286,7 +376,7 @@ function createWindow () {
|
|||||||
// This method will be called when Electron has finished
|
// This method will be called when Electron has finished
|
||||||
// initialization and is ready to create browser windows.
|
// initialization and is ready to create browser windows.
|
||||||
// Some APIs can only be used after this event occurs.
|
// Some APIs can only be used after this event occurs.
|
||||||
app.whenReady().then(buildMenu).then(openDefaultFile)
|
app.whenReady().then(buildMenu).then(openDefaultWorkspace)
|
||||||
|
|
||||||
// Quit when all windows are closed, except on macOS. There, it's common
|
// Quit when all windows are closed, except on macOS. There, it's common
|
||||||
// for applications and their menu bar to stay active until the user quits
|
// for applications and their menu bar to stay active until the user quits
|
||||||
@ -301,12 +391,12 @@ app.on('activate', () => {
|
|||||||
// On macOS it's common to re-create a window in the app when the
|
// On macOS it's common to re-create a window in the app when the
|
||||||
// dock icon is clicked and there are no other windows open.
|
// dock icon is clicked and there are no other windows open.
|
||||||
if (BrowserWindow.getAllWindows().length === 0) {
|
if (BrowserWindow.getAllWindows().length === 0) {
|
||||||
createWindow()
|
openDefaultWorkspace()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
app.on('open-file', (event, path) => {
|
app.on('open-file', (event, path) => {
|
||||||
openFile(path);
|
openWorkspaceWindow(path);
|
||||||
})
|
})
|
||||||
|
|
||||||
// In this file you can include the rest of your app's specific main process
|
// In this file you can include the rest of your app's specific main process
|
||||||
|
BIN
images/icon.png
Normal file
BIN
images/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
14
index.html
14
index.html
@ -14,6 +14,7 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
<meta name="msapplication-starturl" content="/redir.html">
|
<meta name="msapplication-starturl" content="/redir.html">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=yes">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=yes">
|
||||||
|
<link rel="apple-touch-icon" href="/images/icon.png">
|
||||||
<style type="text/css" media="screen">
|
<style type="text/css" media="screen">
|
||||||
body {
|
body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -38,14 +39,15 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
|||||||
<script defer src="config.js"></script>
|
<script defer src="config.js"></script>
|
||||||
|
|
||||||
<!-- Sentry error reporting -->
|
<!-- Sentry error reporting -->
|
||||||
<script
|
<script defer
|
||||||
src="https://browser.sentry-cdn.com/5.20.1/bundle.min.js"
|
src="https://browser.sentry-cdn.com/5.22.3/bundle.tracing.min.js"
|
||||||
integrity="sha384-O8HdAJg1h8RARFowXd2J/r5fIWuinSBtjhwQoPesfVILeXzGpJxvyY/77OaPPXUo"
|
integrity="sha384-HfEJlGrJtFM0B01Wt4sGzTbxWqLMcMeGAXCbyQyB+iK9BhnDmNAtIGovhekIQOa2"
|
||||||
crossorigin="anonymous"></script>
|
crossorigin="anonymous"
|
||||||
<script>
|
></script>
|
||||||
|
<script defer>
|
||||||
if (window.location.host.endsWith('8bitworkshop.com')) {
|
if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
Sentry.init({
|
Sentry.init({
|
||||||
dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@sentry.io/1813925',
|
dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925',
|
||||||
beforeBreadcrumb(breadcrumb, hint) {
|
beforeBreadcrumb(breadcrumb, hint) {
|
||||||
if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
||||||
if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
--- index.html 2020-08-11 11:10:30.000000000 -0500
|
--- index.html 2020-08-29 13:22:47.000000000 -0500
|
||||||
+++ electron.html 2020-08-11 14:47:38.000000000 -0500
|
+++ electron.html 2020-08-29 13:22:40.000000000 -0500
|
||||||
@@ -3,16 +3,6 @@
|
@@ -3,18 +3,7 @@
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>8bitworkshop IDE</title>
|
<title>8bitworkshop IDE</title>
|
||||||
@ -15,9 +15,11 @@
|
|||||||
-<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
-<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
-<meta name="msapplication-starturl" content="/redir.html">
|
-<meta name="msapplication-starturl" content="/redir.html">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=yes">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=yes">
|
||||||
|
-<link rel="apple-touch-icon" href="/images/icon.png">
|
||||||
<style type="text/css" media="screen">
|
<style type="text/css" media="screen">
|
||||||
body {
|
body {
|
||||||
@@ -21,46 +11,6 @@
|
overflow: hidden;
|
||||||
|
@@ -22,50 +11,32 @@
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="css/ui.css">
|
<link rel="stylesheet" href="css/ui.css">
|
||||||
@ -36,16 +38,22 @@
|
|||||||
-<script defer src="https://www.gstatic.com/firebasejs/5.11.1/firebase-app.js"></script>
|
-<script defer src="https://www.gstatic.com/firebasejs/5.11.1/firebase-app.js"></script>
|
||||||
-<script defer src="https://www.gstatic.com/firebasejs/5.11.1/firebase-auth.js"></script>
|
-<script defer src="https://www.gstatic.com/firebasejs/5.11.1/firebase-auth.js"></script>
|
||||||
-<script defer src="config.js"></script>
|
-<script defer src="config.js"></script>
|
||||||
-
|
+</head>
|
||||||
-<!-- Sentry error reporting -->
|
+<body>
|
||||||
-<script
|
|
||||||
- src="https://browser.sentry-cdn.com/5.20.1/bundle.min.js"
|
<!-- Sentry error reporting -->
|
||||||
- integrity="sha384-O8HdAJg1h8RARFowXd2J/r5fIWuinSBtjhwQoPesfVILeXzGpJxvyY/77OaPPXUo"
|
<script defer
|
||||||
- crossorigin="anonymous"></script>
|
- src="https://browser.sentry-cdn.com/5.22.3/bundle.tracing.min.js"
|
||||||
-<script>
|
- integrity="sha384-HfEJlGrJtFM0B01Wt4sGzTbxWqLMcMeGAXCbyQyB+iK9BhnDmNAtIGovhekIQOa2"
|
||||||
|
- crossorigin="anonymous"
|
||||||
|
+src="https://browser.sentry-cdn.com/5.22.3/bundle.tracing.min.js"
|
||||||
|
+integrity="sha384-HfEJlGrJtFM0B01Wt4sGzTbxWqLMcMeGAXCbyQyB+iK9BhnDmNAtIGovhekIQOa2"
|
||||||
|
+crossorigin="anonymous"
|
||||||
|
></script>
|
||||||
|
<script defer>
|
||||||
-if (window.location.host.endsWith('8bitworkshop.com')) {
|
-if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||||
- Sentry.init({
|
- Sentry.init({
|
||||||
- dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@sentry.io/1813925',
|
- dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925',
|
||||||
- beforeBreadcrumb(breadcrumb, hint) {
|
- beforeBreadcrumb(breadcrumb, hint) {
|
||||||
- if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
- if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
||||||
- if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
- if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
||||||
@ -59,12 +67,29 @@
|
|||||||
- },
|
- },
|
||||||
- });
|
- });
|
||||||
-}
|
-}
|
||||||
-</script>
|
+Sentry.init({
|
||||||
-
|
+ dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@o320878.ingest.sentry.io/1813925',
|
||||||
</head>
|
+ beforeBreadcrumb(breadcrumb, hint) {
|
||||||
<body>
|
+ if (breadcrumb.category === 'xhr' && typeof breadcrumb.data.url === 'string') {
|
||||||
|
+ if (breadcrumb.data.url.startsWith('http')) return null; // discard external scripts
|
||||||
|
+ }
|
||||||
|
+ return breadcrumb;
|
||||||
|
+ },
|
||||||
|
+ beforeSend(event, hint) {
|
||||||
|
+ const error = hint.originalException;
|
||||||
|
+ if (error instanceof EmuHalt) return null; // ignore EmuHalt
|
||||||
|
+ return event;
|
||||||
|
+ },
|
||||||
|
+});
|
||||||
|
</script>
|
||||||
|
|
||||||
@@ -88,26 +38,6 @@
|
-</head>
|
||||||
|
-<body>
|
||||||
|
-
|
||||||
|
<!-- for file upload -->
|
||||||
|
<input type="file" id="uploadFileElem" multiple accept="*" style="display:none" onchange="handleFileUpload(this.files)">
|
||||||
|
|
||||||
|
@@ -90,26 +61,6 @@
|
||||||
<hr>
|
<hr>
|
||||||
<li><a class="dropdown-item" href="#" id="item_addfile_include">Add Include File...</a></li>
|
<li><a class="dropdown-item" href="#" id="item_addfile_include">Add Include File...</a></li>
|
||||||
<li><a class="dropdown-item" href="#" id="item_addfile_link">Add Linked File...</a></li>
|
<li><a class="dropdown-item" href="#" id="item_addfile_link">Add Linked File...</a></li>
|
||||||
@ -91,7 +116,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown dropdown-submenu">
|
<li class="dropdown dropdown-submenu">
|
||||||
@@ -133,36 +63,6 @@
|
@@ -135,36 +86,6 @@
|
||||||
<li><a class="dropdown-item" href="#" id="item_debug_expr">Break Expression...</a></li>
|
<li><a class="dropdown-item" href="#" id="item_debug_expr">Break Expression...</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
@ -128,7 +153,7 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -258,39 +158,6 @@
|
@@ -260,39 +181,6 @@
|
||||||
<span class="label"><span id="settle_label"></span> evals/clk</span>
|
<span class="label"><span id="settle_label"></span> evals/clk</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@ -168,7 +193,7 @@
|
|||||||
<!-- 8bitworkshop logo -->
|
<!-- 8bitworkshop logo -->
|
||||||
<span class="logo-gradient hidden-xs hidden-sm hidden-md pull-right" style="margin-left:auto" onclick="window.open('/','_8bitws');">8bitworkshop</span>
|
<span class="logo-gradient hidden-xs hidden-sm hidden-md pull-right" style="margin-left:auto" onclick="window.open('/','_8bitws');">8bitworkshop</span>
|
||||||
|
|
||||||
@@ -477,73 +344,6 @@
|
@@ -479,73 +367,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -242,16 +267,3 @@
|
|||||||
|
|
||||||
<script src="jquery/jquery.min.js"></script>
|
<script src="jquery/jquery.min.js"></script>
|
||||||
|
|
||||||
@@ -635,12 +435,5 @@
|
|
||||||
startUI();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
-<script>
|
|
||||||
-/*
|
|
||||||
- var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
|
|
||||||
- if (!isFirefox && platform_id != 'vcs') { $("#best_in_firefox").show(); }
|
|
||||||
-*/
|
|
||||||
-</script>
|
|
||||||
-
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
102
package-lock.json
generated
102
package-lock.json
generated
@ -268,9 +268,9 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "14.0.27",
|
"version": "14.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.2.tgz",
|
||||||
"integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==",
|
"integrity": "sha512-onlIwbaeqvZyniGPfdw/TEhKIh79pz66L1q06WUQqJLnAb6wbjvOtepLYTGHTqzdXgBYIE3ZdmqHDGsRsbBz7A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/sizzle": {
|
"@types/sizzle": {
|
||||||
@ -606,9 +606,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"get-stream": {
|
"get-stream": {
|
||||||
"version": "5.1.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||||
"integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
|
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"pump": "^3.0.0"
|
"pump": "^3.0.0"
|
||||||
@ -678,9 +678,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
"version": "3.4.1",
|
"version": "3.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz",
|
||||||
"integrity": "sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==",
|
"integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"anymatch": "~3.1.1",
|
"anymatch": "~3.1.1",
|
||||||
"braces": "~3.0.2",
|
"braces": "~3.0.2",
|
||||||
@ -886,6 +886,13 @@
|
|||||||
"safe-buffer": "~5.1.1"
|
"safe-buffer": "~5.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"core-js": {
|
||||||
|
"version": "3.6.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
|
||||||
|
"integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||||
@ -1123,9 +1130,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"electron": {
|
"electron": {
|
||||||
"version": "9.1.2",
|
"version": "9.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-9.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-9.2.1.tgz",
|
||||||
"integrity": "sha512-xEYadr3XqIqJ4ktBPo0lhzPdovv4jLCpiUUGc2M1frUhFhwqXokwhPaTUcE+zfu5+uf/ONDnQApwjzznBsRrgQ==",
|
"integrity": "sha512-ZsetaQjXB8+9/EFW1FnfK4ukpkwXCxMEaiKiUZhZ0ZLFlLnFCpe0Bg4vdDf7e4boWGcnlgN1jAJpBw7w0eXuqA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@electron/get": "^1.0.1",
|
"@electron/get": "^1.0.1",
|
||||||
@ -1134,13 +1141,18 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "12.12.53",
|
"version": "12.12.54",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.53.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.54.tgz",
|
||||||
"integrity": "sha512-51MYTDTyCziHb70wtGNFRwB4l+5JNvdqzFSkbDvpbftEgVUBEE+T5f7pROhWMp/fxp07oNIEQZd5bbfAH22ohQ==",
|
"integrity": "sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"electron-is-dev": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz",
|
||||||
|
"integrity": "sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4="
|
||||||
|
},
|
||||||
"electron-notarize": {
|
"electron-notarize": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.0.0.tgz",
|
||||||
@ -1219,9 +1231,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"electron-packager": {
|
"electron-packager": {
|
||||||
"version": "15.0.0",
|
"version": "15.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-15.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-15.1.0.tgz",
|
||||||
"integrity": "sha512-J0yQP7/fKPkjxo9Yz5+vsQVig0dBbSXW8LQYA1pvNMvi+bL00hfI2SAyORP6EU7XaeiXGUIBSG2Px01EkKfGCw==",
|
"integrity": "sha512-THNm4bz1DfvR9f0g51+NjuAYELflM8+1vhQ/iv/G8vyZNKzSMuFd5doobngQKq3rRsLdPNZVnGqDdgS884d7Og==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@electron/get": "^1.6.0",
|
"@electron/get": "^1.6.0",
|
||||||
@ -1240,7 +1252,7 @@
|
|||||||
"rcedit": "^2.0.0",
|
"rcedit": "^2.0.0",
|
||||||
"resolve": "^1.1.6",
|
"resolve": "^1.1.6",
|
||||||
"semver": "^7.1.3",
|
"semver": "^7.1.3",
|
||||||
"yargs-parser": "^18.0.0"
|
"yargs-parser": "^19.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"extract-zip": {
|
"extract-zip": {
|
||||||
@ -1268,9 +1280,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"get-stream": {
|
"get-stream": {
|
||||||
"version": "5.1.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||||
"integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
|
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"pump": "^3.0.0"
|
"pump": "^3.0.0"
|
||||||
@ -1299,14 +1311,10 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"yargs-parser": {
|
"yargs-parser": {
|
||||||
"version": "18.1.3",
|
"version": "19.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-19.0.4.tgz",
|
||||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
"integrity": "sha512-eXeQm7yXRjPFFyf1voPkZgXQZJjYfjgQUmGPbD2TLtZeIYzvacgWX7sQ5a1HsRgVP+pfKAkRZDNtTGev4h9vhw==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"requires": {
|
|
||||||
"camelcase": "^5.0.0",
|
|
||||||
"decamelize": "^1.2.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1790,6 +1798,14 @@
|
|||||||
"assert-plus": "^1.0.0"
|
"assert-plus": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"github-url-to-object": {
|
||||||
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/github-url-to-object/-/github-url-to-object-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-1Ri1pR8XTfzLpbtPz5MlW/amGNdNReuExPsbF9rxLsBfO1GH9RtDBamhJikd0knMWq3RTTQDbTtw0GGvvEAJEA==",
|
||||||
|
"requires": {
|
||||||
|
"is-url": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"glob": {
|
"glob": {
|
||||||
"version": "7.1.6",
|
"version": "7.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||||
@ -1828,13 +1844,6 @@
|
|||||||
"serialize-error": "^7.0.1"
|
"serialize-error": "^7.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": {
|
|
||||||
"version": "3.6.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
|
|
||||||
"integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==",
|
|
||||||
"dev": true,
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "7.3.2",
|
"version": "7.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||||
@ -2165,6 +2174,11 @@
|
|||||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"is-url": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
|
||||||
|
},
|
||||||
"isarray": {
|
"isarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
@ -2934,8 +2948,7 @@
|
|||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"nested-error-stacks": {
|
"nested-error-stacks": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
@ -4140,6 +4153,17 @@
|
|||||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"update-electron-app": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/update-electron-app/-/update-electron-app-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-g7noW9JfQ8Hwq6zw9lmZei+R/ikOIBcaZ04TbmIcU5zNfv23HkN80QLLAyiR/47KvfS4sjnh2/wuDq5nh8+0mQ==",
|
||||||
|
"requires": {
|
||||||
|
"electron-is-dev": "^0.3.0",
|
||||||
|
"github-url-to-object": "^4.0.4",
|
||||||
|
"is-url": "^1.2.4",
|
||||||
|
"ms": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"uri-js": {
|
"uri-js": {
|
||||||
"version": "4.2.2",
|
"version": "4.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
||||||
|
11
package.json
11
package.json
@ -9,24 +9,25 @@
|
|||||||
},
|
},
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": "^3.4.1",
|
"chokidar": "^3.4.2",
|
||||||
"electron-store": "^6.0.0",
|
"electron-store": "^6.0.0",
|
||||||
"jquery": "^3.5.1",
|
"jquery": "^3.5.1",
|
||||||
"reflect-metadata": "^0.1.13"
|
"reflect-metadata": "^0.1.13",
|
||||||
|
"update-electron-app": "^1.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bootbox": "^4.4.36",
|
"@types/bootbox": "^4.4.36",
|
||||||
"@types/bootstrap": "^3.4.0",
|
"@types/bootstrap": "^3.4.0",
|
||||||
"@types/file-saver": "^2.0.1",
|
"@types/file-saver": "^2.0.1",
|
||||||
"@types/jquery": "^3.5.1",
|
"@types/jquery": "^3.5.1",
|
||||||
"@types/node": "^14.0.27",
|
"@types/node": "^14.6.2",
|
||||||
"atob": "^2.1.x",
|
"atob": "^2.1.x",
|
||||||
"bootstrap": "^3.4.1",
|
"bootstrap": "^3.4.1",
|
||||||
"bootstrap-tourist": "^0.2.1",
|
"bootstrap-tourist": "^0.2.1",
|
||||||
"btoa": "^1.2.x",
|
"btoa": "^1.2.x",
|
||||||
"clipboard": "^2.0.6",
|
"clipboard": "^2.0.6",
|
||||||
"electron": "^9.1.2",
|
"electron": "^9.2.1",
|
||||||
"electron-packager": "^15.0.0",
|
"electron-packager": "^15.1.0",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"jsdom": "^12.2.0",
|
"jsdom": "^12.2.0",
|
||||||
"jsfuzz": "^1.0.14",
|
"jsfuzz": "^1.0.14",
|
||||||
|
@ -19,17 +19,19 @@ export class CodeProject {
|
|||||||
mainPath : string;
|
mainPath : string;
|
||||||
pendingWorkerMessages = 0;
|
pendingWorkerMessages = 0;
|
||||||
tools_preloaded = {};
|
tools_preloaded = {};
|
||||||
callbackBuildResult : BuildResultCallback;
|
|
||||||
callbackBuildStatus : BuildStatusCallback;
|
|
||||||
worker : Worker;
|
worker : Worker;
|
||||||
platform_id : string;
|
platform_id : string;
|
||||||
platform : Platform;
|
platform : Platform;
|
||||||
store : any;
|
store : any;
|
||||||
callbackGetRemote : GetRemoteCallback;
|
|
||||||
isCompiling : boolean = false;
|
isCompiling : boolean = false;
|
||||||
filename2path = {}; // map stripped paths to full paths
|
filename2path = {}; // map stripped paths to full paths
|
||||||
persistent : boolean = true; // set to true and won't modify store
|
persistent : boolean = true; // set to true and won't modify store
|
||||||
|
|
||||||
|
callbackBuildResult : BuildResultCallback;
|
||||||
|
callbackBuildStatus : BuildStatusCallback;
|
||||||
|
callbackGetRemote : GetRemoteCallback;
|
||||||
|
callbackStoreFile : IterateFilesCallback;
|
||||||
|
|
||||||
constructor(worker, platform_id:string, platform, store) {
|
constructor(worker, platform_id:string, platform, store) {
|
||||||
this.worker = worker;
|
this.worker = worker;
|
||||||
this.platform_id = platform_id;
|
this.platform_id = platform_id;
|
||||||
@ -155,6 +157,9 @@ export class CodeProject {
|
|||||||
if (this.persistent && !isEmptyString(text)) {
|
if (this.persistent && !isEmptyString(text)) {
|
||||||
this.store.setItem(path, text);
|
this.store.setItem(path, text);
|
||||||
}
|
}
|
||||||
|
if (this.callbackStoreFile != null) {
|
||||||
|
this.callbackStoreFile(path, text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test duplicate files, local paths mixed with presets
|
// TODO: test duplicate files, local paths mixed with presets
|
||||||
|
@ -114,7 +114,7 @@ function newWorker() : Worker {
|
|||||||
return new Worker("./src/worker/loader.js");
|
return new Worker("./src/worker/loader.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
var hasLocalStorage : boolean = function() {
|
const hasLocalStorage : boolean = function() {
|
||||||
try {
|
try {
|
||||||
const key = "__some_random_key_you_are_not_going_to_use__";
|
const key = "__some_random_key_you_are_not_going_to_use__";
|
||||||
localStorage.setItem(key, key);
|
localStorage.setItem(key, key);
|
||||||
@ -151,7 +151,7 @@ function getCurrentPresetTitle() : string {
|
|||||||
|
|
||||||
function setLastPreset(id:string) {
|
function setLastPreset(id:string) {
|
||||||
if (hasLocalStorage) {
|
if (hasLocalStorage) {
|
||||||
if (repo_id && platform_id)
|
if (repo_id && platform_id && !isElectron)
|
||||||
localStorage.setItem("__lastrepo_" + platform_id, repo_id);
|
localStorage.setItem("__lastrepo_" + platform_id, repo_id);
|
||||||
else
|
else
|
||||||
localStorage.removeItem("__lastrepo_" + platform_id);
|
localStorage.removeItem("__lastrepo_" + platform_id);
|
||||||
@ -170,10 +170,10 @@ function unsetLastPreset() {
|
|||||||
function initProject() {
|
function initProject() {
|
||||||
current_project = new CodeProject(newWorker(), platform_id, platform, store);
|
current_project = new CodeProject(newWorker(), platform_id, platform, store);
|
||||||
projectWindows = new ProjectWindows($("#workspace")[0] as HTMLElement, current_project);
|
projectWindows = new ProjectWindows($("#workspace")[0] as HTMLElement, current_project);
|
||||||
if (qs['electron_ws']) {
|
if (isElectronWorkspace) {
|
||||||
current_project.callbackGetRemote = getElectronFile;
|
|
||||||
current_project.persistent = false;
|
current_project.persistent = false;
|
||||||
// TODO: save file when edited
|
current_project.callbackGetRemote = getElectronFile;
|
||||||
|
current_project.callbackStoreFile = putWorkspaceFile;
|
||||||
} else {
|
} else {
|
||||||
current_project.callbackGetRemote = getWithBinary;
|
current_project.callbackGetRemote = getWithBinary;
|
||||||
}
|
}
|
||||||
@ -942,9 +942,11 @@ function _downloadROMImage(e) {
|
|||||||
var suffix = (platform.getROMExtension && platform.getROMExtension(current_output))
|
var suffix = (platform.getROMExtension && platform.getROMExtension(current_output))
|
||||||
|| "-" + getBasePlatform(platform_id) + ".bin";
|
|| "-" + getBasePlatform(platform_id) + ".bin";
|
||||||
saveAs(blob, prefix + suffix);
|
saveAs(blob, prefix + suffix);
|
||||||
} else {
|
} else if (current_output.code != null) {
|
||||||
var blob = new Blob([(<VerilogOutput>current_output).code], {type: "text/plain"});
|
var blob = new Blob([(<VerilogOutput>current_output).code], {type: "text/plain"});
|
||||||
saveAs(blob, prefix + ".js");
|
saveAs(blob, prefix + ".js");
|
||||||
|
} else {
|
||||||
|
alertError(`The "${platform_id}" platform doesn't have downloadable ROMs.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1003,7 +1005,7 @@ function populateExamples(sel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function populateRepos(sel) {
|
function populateRepos(sel) {
|
||||||
if (hasLocalStorage) {
|
if (hasLocalStorage && !isElectron) {
|
||||||
var n = 0;
|
var n = 0;
|
||||||
var repos = getRepos();
|
var repos = getRepos();
|
||||||
if (repos) {
|
if (repos) {
|
||||||
@ -1052,7 +1054,7 @@ async function updateSelector() {
|
|||||||
await populateFiles(sel, "Local Files", "", foundFiles);
|
await populateFiles(sel, "Local Files", "", foundFiles);
|
||||||
finishSelector(sel);
|
finishSelector(sel);
|
||||||
} else {
|
} else {
|
||||||
if (!qs['electron_ws']) {
|
if (!isElectronWorkspace) {
|
||||||
sel.append($("<option />").val('/').text('Leave Repository'));
|
sel.append($("<option />").val('/').text('Leave Repository'));
|
||||||
}
|
}
|
||||||
$("#repo_name").text(getFilenameForPath(repo_id)+'/').show();
|
$("#repo_name").text(getFilenameForPath(repo_id)+'/').show();
|
||||||
@ -1145,6 +1147,7 @@ function setCompileOutput(data: WorkerResult) {
|
|||||||
current_output = rom;
|
current_output = rom;
|
||||||
if (!userPaused) _resume();
|
if (!userPaused) _resume();
|
||||||
measureBuildTime();
|
measureBuildTime();
|
||||||
|
writeOutputROMFile();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
toolbar.addClass("has-errors");
|
toolbar.addClass("has-errors");
|
||||||
@ -1909,6 +1912,9 @@ var qs = (function (a : string[]) {
|
|||||||
return b;
|
return b;
|
||||||
})(window.location.search.substr(1).split('&'));
|
})(window.location.search.substr(1).split('&'));
|
||||||
|
|
||||||
|
const isElectronWorkspace = qs['electron_ws'];
|
||||||
|
const isElectron = qs['electron'] || isElectronWorkspace;
|
||||||
|
|
||||||
function globalErrorHandler(msgevent) {
|
function globalErrorHandler(msgevent) {
|
||||||
var msg = (msgevent.message || msgevent.error || msgevent)+"";
|
var msg = (msgevent.message || msgevent.error || msgevent)+"";
|
||||||
// storage quota full? (Chrome) try to expand it
|
// storage quota full? (Chrome) try to expand it
|
||||||
@ -2263,7 +2269,7 @@ redirectToHTTPS();
|
|||||||
//// ELECTRON STUFF
|
//// ELECTRON STUFF
|
||||||
|
|
||||||
// get remote file from local fs
|
// get remote file from local fs
|
||||||
declare var getWorkspaceFile;
|
declare var getWorkspaceFile, putWorkspaceFile;
|
||||||
export function getElectronFile(url:string, success:(text:string|Uint8Array)=>void, datatype:'text'|'arraybuffer') {
|
export function getElectronFile(url:string, success:(text:string|Uint8Array)=>void, datatype:'text'|'arraybuffer') {
|
||||||
// TODO: we have to split() to strip off presets/platform, yukky
|
// TODO: we have to split() to strip off presets/platform, yukky
|
||||||
var contents = getWorkspaceFile(url.split('/',3)[2], datatype);
|
var contents = getWorkspaceFile(url.split('/',3)[2], datatype);
|
||||||
@ -2277,3 +2283,11 @@ export function reloadWorkspaceFile(path: string) {
|
|||||||
var datatype = typeof current_project.filedata[path] == 'string' ? 'text' : 'arraybuffer';
|
var datatype = typeof current_project.filedata[path] == 'string' ? 'text' : 'arraybuffer';
|
||||||
projectWindows.updateFile(path, getWorkspaceFile(path, datatype));
|
projectWindows.updateFile(path, getWorkspaceFile(path, datatype));
|
||||||
}
|
}
|
||||||
|
function writeOutputROMFile() {
|
||||||
|
if (isElectronWorkspace && current_output instanceof Uint8Array) {
|
||||||
|
var prefix = getFilenamePrefix(getCurrentMainFilename());
|
||||||
|
var suffix = (platform.getROMExtension && platform.getROMExtension(current_output))
|
||||||
|
|| "-" + getBasePlatform(platform_id) + ".bin";
|
||||||
|
putWorkspaceFile(`bin/${prefix}${suffix}`, current_output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user