Merge branch 'master' into gh-pages

# Conflicts:
#	modules/shared/es6/component.js
This commit is contained in:
Jeff Parsons 2017-01-02 16:54:07 -08:00 • committed by Jeff Parsons
commit 6c21a2722c
16 changed files with 1048 additions and 1051 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,11 +49,6 @@
"use strict";
if (NODE) {
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:
@ -212,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)
*
@ -227,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, " "));
}
@ -292,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);
}
/**
@ -305,7 +310,7 @@ class Component {
if (!COMPILED) {
Component.println(s, "warning");
}
if (Web.alertUser) Web.alertUser(s);
Component.alertUser(s);
}
/**
@ -318,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;
}
/**
@ -640,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

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

View file

@ -149,10 +149,10 @@
"./modules/shared/es6/reportapi.js",
"./modules/shared/es6/userapi.js",
"./modules/shared/es6/keys.js",
"./modules/shared/es6/component.js",
"./modules/shared/es6/strlib.js",
"./modules/shared/es6/usrlib.js",
"./modules/shared/es6/weblib.js",
"./modules/shared/es6/component.js",
"./modules/pc8080/lib/defines.js",
"./modules/pc8080/lib/cpudef.js",
"./modules/pc8080/lib/messages.js",
@ -181,10 +181,10 @@
"./modules/shared/es6/reportapi.js",
"./modules/shared/es6/userapi.js",
"./modules/shared/es6/keys.js",
"./modules/shared/es6/component.js",
"./modules/shared/es6/strlib.js",
"./modules/shared/es6/usrlib.js",
"./modules/shared/es6/weblib.js",
"./modules/shared/es6/component.js",
"./modules/pdp11/lib/defines.js",
"./modules/pdp11/lib/messages.js",
"./modules/pdp11/lib/panel.js",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long