More Node-related module tidying (but still doesn't solve ES6 browser issues with uncompiled code)

This commit is contained in:
Jeff Parsons 2017-01-02 16:51:09 -08:00 committed by Jeff Parsons
commit 67e1e66cb1
16 changed files with 1049 additions and 1050 deletions

View file

@ -503,7 +503,12 @@ HTMLOut.filter = function(req, res, next)
/*
* This is a hack to strip ES6 syntax from JavaScript files that is not (yet) supported by browsers;
* specifically, "import" and "export" statements.
* specifically, import (or require) and export (or module.exports) statements.
*
* What's particularly annoying, especially at this late stage of ES6 adoption, is that Node is perfectly
* capable of processing require() statements for modules with classes, but browsers are not; browsers appear
* to feel that a var declaration (which is what a require() statement, um, requires) is incompatible with
* a class declaration.
*/
if (sBaseExt == "js") {
HTMLOut.logDebug("HTMLOut.filter(" + sBaseName + "): stripping unsupported ES6 syntax");

View file

@ -520,7 +520,7 @@ class Computer8080 extends Component {
this.stateFailSafe.store();
var fValidate = this.resume && !this.fServerState;
if (resume == Computer8080.RESUME_AUTO || Web.confirmUser("Click OK to restore the previous " + PC8080.APPNAME + " machine state, or CANCEL to reset the machine.")) {
if (resume == Computer8080.RESUME_AUTO || Component.confirmUser("Click OK to restore the previous " + PC8080.APPNAME + " machine state, or CANCEL to reset the machine.")) {
fRestore = stateComputer.parse();
if (fRestore) {
var sCode = /** @type {string} */ (stateComputer.get(UserAPI.RES.CODE));
@ -781,7 +781,7 @@ class Computer8080 extends Component {
}
if (iComponent == aComponents.length) component = this;
var s = "The " + component.type + " component (" + component.id + ") is not " + (!component.flags.ready? "ready yet" + (component.fnReady? " (waiting for notification)" : "") : "powered yet") + ".";
Web.alertUser(s);
Component.alertUser(s);
return false;
}
@ -793,7 +793,7 @@ class Computer8080 extends Component {
*/
powerReport(stateComputer)
{
if (Web.confirmUser("There may be a problem with your " + PC8080.APPNAME + " machine.\n\nTo help us diagnose it, click OK to send this " + PC8080.APPNAME + " machine state to http://" + SITEHOST + ".")) {
if (Component.confirmUser("There may be a problem with your " + PC8080.APPNAME + " machine.\n\nTo help us diagnose it, click OK to send this " + PC8080.APPNAME + " machine state to http://" + SITEHOST + ".")) {
Web.sendReport(PC8080.APPNAME, PC8080.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());
}
}
@ -1139,7 +1139,7 @@ class Computer8080 extends Component {
* merely a precaution, because ordinarily, setBinding() should have already determined if we are
* running from pcjs.org and disabled any "Save" button.
*/
sUserID = Web.promptUser("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.");
sUserID = Component.promptUser("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.");
if (sUserID) {
sUserID = this.verifyUserID(sUserID);
if (!sUserID) this.notice("The user ID is invalid.");
@ -1337,7 +1337,7 @@ class Computer8080 extends Component {
* I used to bypass the prompt if this.resume == Computer8080.RESUME_AUTO, setting fSave to true automatically,
* but that gives the user no means of resetting a resumable machine that contains errors in its resume state.
*/
var fSave = (/* this.resume == Computer8080.RESUME_AUTO || */ Web.confirmUser("Click OK to save changes to this " + PC8080.APPNAME + " machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded."));
var fSave = (/* this.resume == Computer8080.RESUME_AUTO || */ Component.confirmUser("Click OK to save changes to this " + PC8080.APPNAME + " machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded."));
this.powerOff(fSave, true);
/*
* Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()

View file

@ -30,7 +30,6 @@
if (NODE) {
var Str = require("../../shared/es6/strlib");
var Usr = require("../../shared/es6/usrlib");
var Component = require("../../shared/es6/component");
var Messages8080 = require("./messages");
}
@ -750,7 +749,7 @@ class CPU8080 extends Component {
}
this.addCycles(this.nRunCycles);
this.nRunCycles = 0;
this.msStartRun = Usr.getTime();
this.msStartRun = Component.getTime();
this.msEndThisRun = 0;
this.calcCycles();
return fSuccess;
@ -785,7 +784,7 @@ class CPU8080 extends Component {
this.calcCycles(true);
}
this.nCyclesThisRun = 0;
this.msStartThisRun = Usr.getTime();
this.msStartThisRun = Component.getTime();
/*
* Try to detect situations where the browser may have throttled us, such as when the user switches
@ -838,7 +837,7 @@ class CPU8080 extends Component {
*/
calcRemainingTime()
{
this.msEndThisRun = Usr.getTime();
this.msEndThisRun = Component.getTime();
var msYield = this.msPerYield;
if (this.nCyclesThisRun) {
@ -1053,7 +1052,7 @@ class CPU8080 extends Component {
{
if (!this.setBusy(true)) {
this.updateCPU();
if (this.cmp) this.cmp.stop(Usr.getTime(), this.getCycles());
if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());
return;
}
@ -1110,7 +1109,7 @@ class CPU8080 extends Component {
catch (e) {
this.stopCPU();
this.updateCPU();
if (this.cmp) this.cmp.stop(Usr.getTime(), this.getCycles());
if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());
this.setBusy(false);
this.setError(e.stack || e.message);
return;

View file

@ -507,7 +507,7 @@ class ComputerPDP11 extends Component {
this.stateFailSafe.store();
var fValidate = this.resume && !this.fServerState;
if (resume == ComputerPDP11.RESUME_AUTO || Web.confirmUser("Click OK to restore the previous " + PDP11.APPNAME + " machine state, or CANCEL to reset the machine.")) {
if (resume == ComputerPDP11.RESUME_AUTO || Component.confirmUser("Click OK to restore the previous " + PDP11.APPNAME + " machine state, or CANCEL to reset the machine.")) {
fRestore = stateComputer.parse();
if (fRestore) {
var sCode = /** @type {string} */ (stateComputer.get(UserAPI.RES.CODE));
@ -776,7 +776,7 @@ class ComputerPDP11 extends Component {
}
if (iComponent == aComponents.length) component = this;
var s = "The " + component.type + " component (" + component.id + ") is not " + (!component.flags.ready? "ready yet" + (component.fnReady? " (waiting for notification)" : "") : "powered yet") + ".";
Web.alertUser(s);
Component.alertUser(s);
return false;
}
@ -788,7 +788,7 @@ class ComputerPDP11 extends Component {
*/
powerReport(stateComputer)
{
if (Web.confirmUser("There may be a problem with your " + PDP11.APPNAME + " machine.\n\nTo help us diagnose it, click OK to send this " + PDP11.APPNAME + " machine state to http://" + SITEHOST + ".")) {
if (Component.confirmUser("There may be a problem with your " + PDP11.APPNAME + " machine.\n\nTo help us diagnose it, click OK to send this " + PDP11.APPNAME + " machine state to http://" + SITEHOST + ".")) {
Web.sendReport(PDP11.APPNAME, PDP11.APPVERSION, this.url, this.getUserID(), ReportAPI.TYPE.BUG, stateComputer.toString());
}
}
@ -1179,7 +1179,7 @@ class ComputerPDP11 extends Component {
* merely a precaution, because ordinarily, setBinding() should have already determined if we are
* running from pcjs.org and disabled any "Save" button.
*/
sUserID = Web.promptUser("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.");
sUserID = Component.promptUser("Saving machine states on the pcjs.org server is currently unsupported.\n\nIf you're running your own server, enter your user ID below.");
if (sUserID) {
sUserID = this.verifyUserID(sUserID);
if (!sUserID) this.notice("The user ID is invalid.");
@ -1377,7 +1377,7 @@ class ComputerPDP11 extends Component {
* I used to bypass the prompt if this.resume == ComputerPDP11.RESUME_AUTO, setting fSave to true automatically,
* but that gives the user no means of resetting a resumable machine that contains errors in its resume state.
*/
var fSave = (/* this.resume == ComputerPDP11.RESUME_AUTO || */ Web.confirmUser("Click OK to save changes to this " + PDP11.APPNAME + " machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded."));
var fSave = (/* this.resume == ComputerPDP11.RESUME_AUTO || */ Component.confirmUser("Click OK to save changes to this " + PDP11.APPNAME + " machine.\n\nWARNING: If you CANCEL, all disk changes will be discarded."));
this.powerOff(fSave, true);
/*
* Forcing the page to reload is an expedient option, but ugly. It's preferable to call powerOn()

View file

@ -34,7 +34,6 @@
if (NODE) {
var Str = require("../../shared/es6/strlib");
var Usr = require("../../shared/es6/usrlib");
var Component = require("../../shared/es6/component");
var MessagesPDP11 = require("./messages");
}
@ -733,7 +732,7 @@ class CPUPDP11 extends Component {
}
this.addCycles(this.nRunCycles);
this.nRunCycles = 0;
this.msStartRun = Usr.getTime();
this.msStartRun = Component.getTime();
this.msEndThisRun = 0;
this.calcCycles();
return fSuccess;
@ -768,7 +767,7 @@ class CPUPDP11 extends Component {
this.calcCycles(true);
}
this.nCyclesThisRun = 0;
this.msStartThisRun = Usr.getTime();
this.msStartThisRun = Component.getTime();
/*
* Try to detect situations where the browser may have throttled us, such as when the user switches
@ -821,7 +820,7 @@ class CPUPDP11 extends Component {
*/
calcRemainingTime()
{
this.msEndThisRun = Usr.getTime();
this.msEndThisRun = Component.getTime();
var msYield = this.msPerYield;
if (this.nCyclesThisRun) {
@ -1111,7 +1110,7 @@ class CPUPDP11 extends Component {
}
catch (e) {
this.stopCPU();
if (this.cmp) this.cmp.stop(Usr.getTime(), this.getCycles());
if (this.cmp) this.cmp.stop(Component.getTime(), this.getCycles());
this.setError(e.stack || e.message);
return;
}
@ -1193,7 +1192,7 @@ class CPUPDP11 extends Component {
var controlRun = this.bindings["run"];
if (controlRun) controlRun.textContent = "Run";
if (this.cmp) {
this.cmp.stop(Usr.getTime(), this.getCycles());
this.cmp.stop(Component.getTime(), this.getCycles());
}
fStopped = true;
if (!this.dbg) this.status("Stopped");

View file

@ -217,7 +217,7 @@ class RK11 extends Component {
if (disk) {
if (DEBUG) rk11.println("saving disk " + disk.sDiskPath + "...");
var sAlert = Web.downloadFile(disk.encodeAsBase64(), "octet-stream", true, disk.sDiskFile.replace(".json", ".img"));
Web.alertUser(sAlert);
Component.alertUser(sAlert);
} else {
rk11.notice("No disk loaded in drive.");
}

View file

@ -219,7 +219,7 @@ class RL11 extends Component {
if (disk) {
if (DEBUG) rl11.println("saving disk " + disk.sDiskPath + "...");
var sAlert = Web.downloadFile(disk.encodeAsBase64(), "octet-stream", true, disk.sDiskFile.replace(".json", ".img"));
Web.alertUser(sAlert);
Component.alertUser(sAlert);
} else {
rl11.notice("No disk loaded in drive.");
}

View file

@ -49,9 +49,6 @@
"use strict";
var Usr = require("../../shared/es6/usrlib");
var Web = require("../../shared/es6/weblib");
/**
* Since the Closure Compiler treats ES6 classes as @struct rather than @dict by default,
* it deters us from defining named properties on our components; eg:
@ -210,6 +207,16 @@ class Component {
return Component.machines[idMachine];
}
/**
* Component.getTime()
*
* @return {number} the current time, in milliseconds
*/
static getTime()
{
return Date.now() || +new Date();
}
/**
* Component.log(s, type)
*
@ -225,9 +232,9 @@ class Component {
var sElapsed = "", sMsg = (type? (type + ": ") : "") + s;
if (typeof Usr != "undefined") {
if (Component.msStart === undefined) {
Component.msStart = Usr.getTime();
Component.msStart = Component.getTime();
}
sElapsed = (Usr.getTime() - Component.msStart) + "ms: ";
sElapsed = (Component.getTime() - Component.msStart) + "ms: ";
}
if (window && window.console) console.log(sElapsed + sMsg.replace(/\n/g, " "));
}
@ -290,7 +297,7 @@ class Component {
if (!COMPILED) {
Component.println(s, "notice", id);
}
if (!fPrintOnly && Web.alertUser) Web.alertUser((id? (id + ": ") : "") + s);
if (!fPrintOnly) Component.alertUser((id? (id + ": ") : "") + s);
}
/**
@ -303,7 +310,7 @@ class Component {
if (!COMPILED) {
Component.println(s, "warning");
}
if (Web.alertUser) Web.alertUser(s);
Component.alertUser(s);
}
/**
@ -316,7 +323,52 @@ class Component {
if (!COMPILED) {
Component.println(s, "error");
}
if (Web.alertUser) Web.alertUser(s);
Component.alertUser(s);
}
/**
* Component.alertUser(sMessage)
*
* @param {string} sMessage
*/
static alertUser(sMessage)
{
if (window) {
window.alert(sMessage);
} else {
Component.log(sMessage);
}
};
/**
* Component.confirmUser(sPrompt)
*
* @param {string} sPrompt
* @returns {boolean} true if the user clicked OK, false if Cancel/Close
*/
static confirmUser(sPrompt)
{
var fResponse = false;
if (window) {
fResponse = window.confirm(sPrompt);
}
return fResponse;
}
/**
* Component.promptUser()
*
* @param {string} sPrompt
* @param {string} [sDefault]
* @returns {string|null}
*/
static promptUser(sPrompt, sDefault)
{
var sResponse = null;
if (window) {
sResponse = window.prompt(sPrompt, sDefault === undefined? "" : sDefault);
}
return sResponse;
}
/**
@ -638,7 +690,7 @@ class Component {
};
}(control));
/**
* Override this.notice() with a replacement function that eliminates the Web.alertUser() call
* Override this.notice() with a replacement function that eliminates the Component.alertUser() call
*
* @this {Component}
* @param {string} s
@ -1062,4 +1114,4 @@ if (!Function.prototype.bind) {
};
}
module.exports = Component;
if (NODE) module.exports = Component;

View file

@ -62,7 +62,7 @@ function savePC(idMachine, sPCJSFile, callback)
});
return true;
}
Web.alertUser("Unable to identify machine '" + idMachine + "'");
Component.alertUser("Unable to identify machine '" + idMachine + "'");
return false;
}
@ -98,7 +98,7 @@ function downloadCSS(sURL, sPCJS, nErrorCode, aMachineInfo)
}
return;
}
Web.alertUser("Error (" + nErrorCode + ") requesting " + sURL);
Component.alertUser("Error (" + nErrorCode + ") requesting " + sURL);
}
/**
@ -208,10 +208,10 @@ function downloadPC(sURL, sCSS, nErrorCode, aMachineInfo)
sAlert += '<script type="text/javascript" src="' + sScript + '"></script>\n';
sAlert += '<script type="text/javascript">embedPC("' + idMachine + '","' + sXMLFile + '","' + sXSLFile + '");</script>\n\n';
sAlert += 'The machine should appear where the <div> is located.';
Web.alertUser(sAlert);
Component.alertUser(sAlert);
return;
}
Web.alertUser("Missing XML/XSL resources");
Component.alertUser("Missing XML/XSL resources");
}
/**

View file

@ -93,16 +93,6 @@ class Usr {
}
}
/**
* getTime()
*
* @return {number} the current time, in milliseconds
*/
static getTime()
{
return Date.now() || +new Date();
}
/**
* getTimestamp()
*
@ -245,7 +235,6 @@ class Usr {
bfs[f] = {mask: mask, shift: bit};
bit += width;
}
// Component.assert(bit <= 32);
return bfs;
}
@ -288,7 +277,6 @@ class Usr {
*/
static setBitField(bf, v, n)
{
// Component.assert(!(n & ~(bf.mask >>> bf.shift)));
return (v & ~bf.mask) | ((n << bf.shift) & bf.mask);
}

View file

@ -135,8 +135,6 @@ class Web {
/**
* notice(s, fPrintOnly, id)
*
* If Component.notice() calls Web.alertUser(), it will fall back to Web.log() if all else fails.
*
* @param {string} s is the message text
* @param {boolean} [fPrintOnly]
* @param {string} [id] is the caller's ID, if any
@ -201,7 +199,7 @@ class Web {
return Net.getResource(sURL, dataPost, fAsync, done);
}
var xmlHTTP = (window.XMLHttpRequest ? new window.XMLHttpRequest() : new window.ActiveXObject("Microsoft.XMLHTTP"));
var xmlHTTP = (window.XMLHttpRequest? new window.XMLHttpRequest() : new window.ActiveXObject("Microsoft.XMLHTTP"));
if (fAsync) {
xmlHTTP.onreadystatechange = function()
{
@ -413,7 +411,7 @@ class Web {
dataPost[ReportAPI.QUERY.USER] = sUser;
dataPost[ReportAPI.QUERY.TYPE] = sType;
dataPost[ReportAPI.QUERY.DATA] = sReport;
var sReportURL = (sHostName ? sHostName : "http://" + SITEHOST) + ReportAPI.ENDPOINT;
var sReportURL = (sHostName? sHostName : "http://" + SITEHOST) + ReportAPI.ENDPOINT;
Web.getResource(sReportURL, dataPost, true);
}
@ -424,7 +422,7 @@ class Web {
*/
static getHost()
{
return ("http://" + (window ? window.location.host : SITEHOST));
return ("http://" + (window? window.location.host : SITEHOST));
}
/**
@ -434,7 +432,7 @@ class Web {
*/
static getHostURL()
{
return (window ? window.location.href : null);
return (window? window.location.href : null);
}
/**
@ -444,7 +442,7 @@ class Web {
*/
static getHostProtocol()
{
return (window ? window.location.protocol : "file:");
return (window? window.location.protocol : "file:");
}
/**
@ -454,48 +452,7 @@ class Web {
*/
static getUserAgent()
{
return (window ? window.navigator.userAgent : "");
}
/**
* alertUser(sMessage)
*
* @param {string} sMessage
*/
static alertUser(sMessage)
{
if (window) window.alert(sMessage); else Web.log(sMessage);
};
/**
* confirmUser(sPrompt)
*
* @param {string} sPrompt
* @returns {boolean} true if the user clicked OK, false if Cancel/Close
*/
static confirmUser(sPrompt)
{
var fResponse = false;
if (window) {
fResponse = window.confirm(sPrompt);
}
return fResponse;
}
/**
* promptUser()
*
* @param {string} sPrompt
* @param {string} [sDefault]
* @returns {string|null}
*/
static promptUser(sPrompt, sDefault)
{
var sResponse = null;
if (window) {
sResponse = window.prompt(sPrompt, sDefault === undefined ? "" : sDefault);
}
return sResponse;
return (window? window.navigator.userAgent : "");
}
/**
@ -729,12 +686,12 @@ class Web {
static downloadFile(sData, sType, fBase64, sFileName)
{
var link = null, sAlert;
var sURI = "data:application/" + sType + (fBase64 ? ";base64" : "") + ",";
var sURI = "data:application/" + sType + (fBase64? ";base64" : "") + ",";
if (!Web.isUserAgent("Firefox")) {
sURI += (fBase64 ? sData : encodeURI(sData));
sURI += (fBase64? sData : encodeURI(sData));
} else {
sURI += (fBase64 ? sData : encodeURIComponent(sData));
sURI += (fBase64? sData : encodeURIComponent(sData));
}
if (sFileName) {
link = document.createElement('a');
@ -749,7 +706,7 @@ class Web {
sAlert = 'Check your Downloads folder for ' + sFileName + '.';
} else {
window.open(sURI);
sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName ? (' (' + sFileName + ')') : '') + '.';
sAlert = 'Check your browser for a new window/tab containing the requested data' + (sFileName? (' (' + sFileName + ')') : '') + '.';
}
return sAlert;
}