mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-21 07:33:14 +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)
|
||||
|
||||
The latest release is online at http://8bitworkshop.com/
|
||||
The latest release is online at https://8bitworkshop.com/
|
||||
|
||||
## Install
|
||||
|
||||
|
@ -15,20 +15,15 @@ TODO:
|
||||
- watchpoints
|
||||
- step over (line, instruction)
|
||||
- slowdown beam for all platforms?
|
||||
- show errors in list (maybe window list?)
|
||||
- click to go to error
|
||||
- what if error in include file you can't edit b/c it never appears?
|
||||
- online help
|
||||
- intro/help text for each platform
|
||||
- show self-modifying code insns left of editor
|
||||
- update Javatari version? (and others?)
|
||||
- sound mute?
|
||||
- $error updates source editor
|
||||
- online tools for music etc
|
||||
- text log debugging script
|
||||
- intro/help text for each platform
|
||||
- vscode/atom extension?
|
||||
- click to break on raster position
|
||||
- restructure src/ folders
|
||||
- debug bankswitching for funky formats
|
||||
- 'undefined' for bitmap replacer
|
||||
- requestInterrupt needs to be disabled after breakpoint?
|
||||
|
@ -24,9 +24,18 @@ process.once('loaded', () => {
|
||||
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
|
||||
ipcRenderer.on('setWorkspaceRoot', (event, data) => {
|
||||
wsroot = data.root;
|
||||
var binpath = modpath.join(wsroot, 'bin');
|
||||
if (!fs.existsSync(binpath)) fs.mkdirSync(binpath, {});
|
||||
console.log('setWorkspaceRoot', wsroot);
|
||||
});
|
||||
// from electron.js: file changed
|
||||
|
@ -14,6 +14,29 @@ body {
|
||||
</head>
|
||||
<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 -->
|
||||
<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 Store = require('electron-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
|
||||
// TODO: add workspace metadata for platform, ROM output, README, etc.
|
||||
class Workspace {
|
||||
constructor(directory, mainfile, wnd) {
|
||||
constructor(directory, meta, wnd) {
|
||||
this.directory = directory;
|
||||
this.mainfile = mainfile;
|
||||
wnd.webContents.send('setWorkspaceRoot', {root:this.directory});
|
||||
this.watcher = chokidar.watch(modpath.join(directory, mainfile));
|
||||
this.mainfile = meta.mainfile;
|
||||
this.platform = meta.platform;
|
||||
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) => {
|
||||
console.log(event, path);
|
||||
switch (event) {
|
||||
@ -38,34 +55,51 @@ class Workspace {
|
||||
}
|
||||
}
|
||||
|
||||
function openFile(path, wnd) {
|
||||
if (!fs.existsSync(path)) {
|
||||
dialog.showMessageBox({
|
||||
type: "error",
|
||||
message: "File not found.",
|
||||
detail: path
|
||||
});
|
||||
return;
|
||||
function readWorkspaceMetadata(directory) {
|
||||
// check README file
|
||||
var readmepath = modpath.join(directory, README_FILENAME);
|
||||
if (fs.existsSync(readmepath)) {
|
||||
let readme = fs.readFileSync(readmepath, 'utf8');
|
||||
let sess = {};
|
||||
// check README for main file
|
||||
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);
|
||||
var filename = modpath.basename(path);
|
||||
if (!wnd) wnd = BrowserWindow.getFocusedWindow();
|
||||
var ws = new Workspace(dirname, filename, wnd);
|
||||
// check JSON file
|
||||
var metapath = modpath.join(directory, WSMETA_FILENAME);
|
||||
if (fs.existsSync(metapath)) {
|
||||
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(); }
|
||||
wnd.workspace = ws;
|
||||
wnd.on('closed', () => {
|
||||
ws.close();
|
||||
});
|
||||
openWorkspace(wnd, ws);
|
||||
app.addRecentDocument(path);
|
||||
store.set(KEY_lastWorkspaceFilePath, path);
|
||||
}
|
||||
|
||||
function openWorkspace(wnd, ws) {
|
||||
var qs = new URLSearchParams();
|
||||
qs.set('electron_ws', 1);
|
||||
qs.set('repo', ws.directory);
|
||||
qs.set('file', ws.mainfile);
|
||||
qs.set('platform', ws.platform);
|
||||
console.log(qs);
|
||||
wnd.loadURL(`file://${__dirname}/electron.html?${qs}`).then(() => {
|
||||
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({
|
||||
title: "Open File",
|
||||
properties: ['openFile','promptToCreate'],
|
||||
title: "Open Workspace",
|
||||
properties: ['openDirectory'],
|
||||
message: "Choose the directory that holds your source files.",
|
||||
}).then((rtn) => {
|
||||
if (!rtn.canceled && rtn.filePaths && rtn.filePaths.length > 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) {
|
||||
return async () => {
|
||||
const { shell } = require('electron')
|
||||
@ -147,8 +227,13 @@ function buildMenu() {
|
||||
label: 'File',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Open File...',
|
||||
click: openFileDialog,
|
||||
label: 'New Playground',
|
||||
click: openDefaultWorkspace,
|
||||
accelerator: 'CmdOrCtrl+N',
|
||||
},
|
||||
{
|
||||
label: 'Open Workspace...',
|
||||
click: openWorkspaceDialog,
|
||||
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.
|
||||
@ -239,13 +324,18 @@ function buildMenu() {
|
||||
label: 'Latest News',
|
||||
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',
|
||||
click: openURL('https://twitter.com/8bitworkshop')
|
||||
},
|
||||
{
|
||||
label: 'Report an Issue',
|
||||
click: openURL('https://github.com/sehugg/8bitworkshop/issues/new')
|
||||
label: 'Become a Patreon',
|
||||
click: openURL('https://www.patreon.com/8bitworkshop')
|
||||
},
|
||||
]
|
||||
}
|
||||
@ -286,7 +376,7 @@ function createWindow () {
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// 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
|
||||
// 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
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
openDefaultWorkspace()
|
||||
}
|
||||
})
|
||||
|
||||
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
|
||||
|
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="msapplication-starturl" content="/redir.html">
|
||||
<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">
|
||||
body {
|
||||
overflow: hidden;
|
||||
@ -38,14 +39,15 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
|
||||
<script defer src="config.js"></script>
|
||||
|
||||
<!-- Sentry error reporting -->
|
||||
<script
|
||||
src="https://browser.sentry-cdn.com/5.20.1/bundle.min.js"
|
||||
integrity="sha384-O8HdAJg1h8RARFowXd2J/r5fIWuinSBtjhwQoPesfVILeXzGpJxvyY/77OaPPXUo"
|
||||
crossorigin="anonymous"></script>
|
||||
<script>
|
||||
<script defer
|
||||
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')) {
|
||||
Sentry.init({
|
||||
dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@sentry.io/1813925',
|
||||
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
|
||||
|
@ -1,6 +1,6 @@
|
||||
--- index.html 2020-08-11 11:10:30.000000000 -0500
|
||||
+++ electron.html 2020-08-11 14:47:38.000000000 -0500
|
||||
@@ -3,16 +3,6 @@
|
||||
--- index.html 2020-08-29 13:22:47.000000000 -0500
|
||||
+++ electron.html 2020-08-29 13:22:40.000000000 -0500
|
||||
@@ -3,18 +3,7 @@
|
||||
|
||||
<head>
|
||||
<title>8bitworkshop IDE</title>
|
||||
@ -15,9 +15,11 @@
|
||||
-<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
-<meta name="msapplication-starturl" content="/redir.html">
|
||||
<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">
|
||||
body {
|
||||
@@ -21,46 +11,6 @@
|
||||
overflow: hidden;
|
||||
@@ -22,50 +11,32 @@
|
||||
}
|
||||
</style>
|
||||
<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-auth.js"></script>
|
||||
-<script defer src="config.js"></script>
|
||||
-
|
||||
-<!-- Sentry error reporting -->
|
||||
-<script
|
||||
- src="https://browser.sentry-cdn.com/5.20.1/bundle.min.js"
|
||||
- integrity="sha384-O8HdAJg1h8RARFowXd2J/r5fIWuinSBtjhwQoPesfVILeXzGpJxvyY/77OaPPXUo"
|
||||
- crossorigin="anonymous"></script>
|
||||
-<script>
|
||||
+</head>
|
||||
+<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"
|
||||
+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')) {
|
||||
- Sentry.init({
|
||||
- dsn: 'https://bf329df3d1b34afa9f5b5e8ecd80ad11@sentry.io/1813925',
|
||||
- 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
|
||||
@ -59,12 +67,29 @@
|
||||
- },
|
||||
- });
|
||||
-}
|
||||
-</script>
|
||||
-
|
||||
</head>
|
||||
<body>
|
||||
+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>
|
||||
|
||||
@@ -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>
|
||||
<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>
|
||||
@ -91,7 +116,7 @@
|
||||
</ul>
|
||||
</li>
|
||||
<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>
|
||||
</ul>
|
||||
</li>
|
||||
@ -128,7 +153,7 @@
|
||||
</ul>
|
||||
</span>
|
||||
|
||||
@@ -258,39 +158,6 @@
|
||||
@@ -260,39 +181,6 @@
|
||||
<span class="label"><span id="settle_label"></span> evals/clk</span>
|
||||
</span>
|
||||
|
||||
@ -168,7 +193,7 @@
|
||||
<!-- 8bitworkshop logo -->
|
||||
<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>
|
||||
@ -242,16 +267,3 @@
|
||||
|
||||
<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
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.0.27",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz",
|
||||
"integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==",
|
||||
"version": "14.6.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.6.2.tgz",
|
||||
"integrity": "sha512-onlIwbaeqvZyniGPfdw/TEhKIh79pz66L1q06WUQqJLnAb6wbjvOtepLYTGHTqzdXgBYIE3ZdmqHDGsRsbBz7A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/sizzle": {
|
||||
@ -606,9 +606,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
|
||||
"integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pump": "^3.0.0"
|
||||
@ -678,9 +678,9 @@
|
||||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.1.tgz",
|
||||
"integrity": "sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g==",
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz",
|
||||
"integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==",
|
||||
"requires": {
|
||||
"anymatch": "~3.1.1",
|
||||
"braces": "~3.0.2",
|
||||
@ -886,6 +886,13 @@
|
||||
"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": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
@ -1123,9 +1130,9 @@
|
||||
}
|
||||
},
|
||||
"electron": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-9.1.2.tgz",
|
||||
"integrity": "sha512-xEYadr3XqIqJ4ktBPo0lhzPdovv4jLCpiUUGc2M1frUhFhwqXokwhPaTUcE+zfu5+uf/ONDnQApwjzznBsRrgQ==",
|
||||
"version": "9.2.1",
|
||||
"resolved": "https://registry.npmjs.org/electron/-/electron-9.2.1.tgz",
|
||||
"integrity": "sha512-ZsetaQjXB8+9/EFW1FnfK4ukpkwXCxMEaiKiUZhZ0ZLFlLnFCpe0Bg4vdDf7e4boWGcnlgN1jAJpBw7w0eXuqA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@electron/get": "^1.0.1",
|
||||
@ -1134,13 +1141,18 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "12.12.53",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.53.tgz",
|
||||
"integrity": "sha512-51MYTDTyCziHb70wtGNFRwB4l+5JNvdqzFSkbDvpbftEgVUBEE+T5f7pROhWMp/fxp07oNIEQZd5bbfAH22ohQ==",
|
||||
"version": "12.12.54",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.54.tgz",
|
||||
"integrity": "sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w==",
|
||||
"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": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.0.0.tgz",
|
||||
@ -1219,9 +1231,9 @@
|
||||
}
|
||||
},
|
||||
"electron-packager": {
|
||||
"version": "15.0.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-15.0.0.tgz",
|
||||
"integrity": "sha512-J0yQP7/fKPkjxo9Yz5+vsQVig0dBbSXW8LQYA1pvNMvi+bL00hfI2SAyORP6EU7XaeiXGUIBSG2Px01EkKfGCw==",
|
||||
"version": "15.1.0",
|
||||
"resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-15.1.0.tgz",
|
||||
"integrity": "sha512-THNm4bz1DfvR9f0g51+NjuAYELflM8+1vhQ/iv/G8vyZNKzSMuFd5doobngQKq3rRsLdPNZVnGqDdgS884d7Og==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@electron/get": "^1.6.0",
|
||||
@ -1240,7 +1252,7 @@
|
||||
"rcedit": "^2.0.0",
|
||||
"resolve": "^1.1.6",
|
||||
"semver": "^7.1.3",
|
||||
"yargs-parser": "^18.0.0"
|
||||
"yargs-parser": "^19.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"extract-zip": {
|
||||
@ -1268,9 +1280,9 @@
|
||||
}
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
|
||||
"integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pump": "^3.0.0"
|
||||
@ -1299,14 +1311,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
"version": "19.0.4",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-19.0.4.tgz",
|
||||
"integrity": "sha512-eXeQm7yXRjPFFyf1voPkZgXQZJjYfjgQUmGPbD2TLtZeIYzvacgWX7sQ5a1HsRgVP+pfKAkRZDNtTGev4h9vhw==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1790,6 +1798,14 @@
|
||||
"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": {
|
||||
"version": "7.1.6",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||
@ -1828,13 +1844,6 @@
|
||||
"serialize-error": "^7.0.1"
|
||||
},
|
||||
"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": {
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||
@ -2165,6 +2174,11 @@
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
||||
"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": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
@ -2934,8 +2948,7 @@
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"nested-error-stacks": {
|
||||
"version": "2.1.0",
|
||||
@ -4140,6 +4153,17 @@
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"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": {
|
||||
"version": "4.2.2",
|
||||
"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",
|
||||
"dependencies": {
|
||||
"chokidar": "^3.4.1",
|
||||
"chokidar": "^3.4.2",
|
||||
"electron-store": "^6.0.0",
|
||||
"jquery": "^3.5.1",
|
||||
"reflect-metadata": "^0.1.13"
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"update-electron-app": "^1.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bootbox": "^4.4.36",
|
||||
"@types/bootstrap": "^3.4.0",
|
||||
"@types/file-saver": "^2.0.1",
|
||||
"@types/jquery": "^3.5.1",
|
||||
"@types/node": "^14.0.27",
|
||||
"@types/node": "^14.6.2",
|
||||
"atob": "^2.1.x",
|
||||
"bootstrap": "^3.4.1",
|
||||
"bootstrap-tourist": "^0.2.1",
|
||||
"btoa": "^1.2.x",
|
||||
"clipboard": "^2.0.6",
|
||||
"electron": "^9.1.2",
|
||||
"electron-packager": "^15.0.0",
|
||||
"electron": "^9.2.1",
|
||||
"electron-packager": "^15.1.0",
|
||||
"file-saver": "^2.0.2",
|
||||
"jsdom": "^12.2.0",
|
||||
"jsfuzz": "^1.0.14",
|
||||
|
@ -19,17 +19,19 @@ export class CodeProject {
|
||||
mainPath : string;
|
||||
pendingWorkerMessages = 0;
|
||||
tools_preloaded = {};
|
||||
callbackBuildResult : BuildResultCallback;
|
||||
callbackBuildStatus : BuildStatusCallback;
|
||||
worker : Worker;
|
||||
platform_id : string;
|
||||
platform : Platform;
|
||||
store : any;
|
||||
callbackGetRemote : GetRemoteCallback;
|
||||
isCompiling : boolean = false;
|
||||
filename2path = {}; // map stripped paths to full paths
|
||||
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) {
|
||||
this.worker = worker;
|
||||
this.platform_id = platform_id;
|
||||
@ -155,6 +157,9 @@ export class CodeProject {
|
||||
if (this.persistent && !isEmptyString(text)) {
|
||||
this.store.setItem(path, text);
|
||||
}
|
||||
if (this.callbackStoreFile != null) {
|
||||
this.callbackStoreFile(path, text);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: test duplicate files, local paths mixed with presets
|
||||
|
@ -114,7 +114,7 @@ function newWorker() : Worker {
|
||||
return new Worker("./src/worker/loader.js");
|
||||
}
|
||||
|
||||
var hasLocalStorage : boolean = function() {
|
||||
const hasLocalStorage : boolean = function() {
|
||||
try {
|
||||
const key = "__some_random_key_you_are_not_going_to_use__";
|
||||
localStorage.setItem(key, key);
|
||||
@ -151,7 +151,7 @@ function getCurrentPresetTitle() : string {
|
||||
|
||||
function setLastPreset(id:string) {
|
||||
if (hasLocalStorage) {
|
||||
if (repo_id && platform_id)
|
||||
if (repo_id && platform_id && !isElectron)
|
||||
localStorage.setItem("__lastrepo_" + platform_id, repo_id);
|
||||
else
|
||||
localStorage.removeItem("__lastrepo_" + platform_id);
|
||||
@ -170,10 +170,10 @@ function unsetLastPreset() {
|
||||
function initProject() {
|
||||
current_project = new CodeProject(newWorker(), platform_id, platform, store);
|
||||
projectWindows = new ProjectWindows($("#workspace")[0] as HTMLElement, current_project);
|
||||
if (qs['electron_ws']) {
|
||||
current_project.callbackGetRemote = getElectronFile;
|
||||
if (isElectronWorkspace) {
|
||||
current_project.persistent = false;
|
||||
// TODO: save file when edited
|
||||
current_project.callbackGetRemote = getElectronFile;
|
||||
current_project.callbackStoreFile = putWorkspaceFile;
|
||||
} else {
|
||||
current_project.callbackGetRemote = getWithBinary;
|
||||
}
|
||||
@ -942,9 +942,11 @@ function _downloadROMImage(e) {
|
||||
var suffix = (platform.getROMExtension && platform.getROMExtension(current_output))
|
||||
|| "-" + getBasePlatform(platform_id) + ".bin";
|
||||
saveAs(blob, prefix + suffix);
|
||||
} else {
|
||||
} else if (current_output.code != null) {
|
||||
var blob = new Blob([(<VerilogOutput>current_output).code], {type: "text/plain"});
|
||||
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) {
|
||||
if (hasLocalStorage) {
|
||||
if (hasLocalStorage && !isElectron) {
|
||||
var n = 0;
|
||||
var repos = getRepos();
|
||||
if (repos) {
|
||||
@ -1052,7 +1054,7 @@ async function updateSelector() {
|
||||
await populateFiles(sel, "Local Files", "", foundFiles);
|
||||
finishSelector(sel);
|
||||
} else {
|
||||
if (!qs['electron_ws']) {
|
||||
if (!isElectronWorkspace) {
|
||||
sel.append($("<option />").val('/').text('Leave Repository'));
|
||||
}
|
||||
$("#repo_name").text(getFilenameForPath(repo_id)+'/').show();
|
||||
@ -1145,6 +1147,7 @@ function setCompileOutput(data: WorkerResult) {
|
||||
current_output = rom;
|
||||
if (!userPaused) _resume();
|
||||
measureBuildTime();
|
||||
writeOutputROMFile();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
toolbar.addClass("has-errors");
|
||||
@ -1909,6 +1912,9 @@ var qs = (function (a : string[]) {
|
||||
return b;
|
||||
})(window.location.search.substr(1).split('&'));
|
||||
|
||||
const isElectronWorkspace = qs['electron_ws'];
|
||||
const isElectron = qs['electron'] || isElectronWorkspace;
|
||||
|
||||
function globalErrorHandler(msgevent) {
|
||||
var msg = (msgevent.message || msgevent.error || msgevent)+"";
|
||||
// storage quota full? (Chrome) try to expand it
|
||||
@ -2263,7 +2269,7 @@ redirectToHTTPS();
|
||||
//// ELECTRON STUFF
|
||||
|
||||
// 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') {
|
||||
// TODO: we have to split() to strip off presets/platform, yukky
|
||||
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';
|
||||
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