Final preparations for open source roll-out
This commit is contained in:
parent
e96f0eecd9
commit
60669365f9
40 changed files with 2814 additions and 2639 deletions
|
|
@ -14,7 +14,7 @@ global *Buffer* object, as indicated by:
|
|||
/* global Buffer: false */
|
||||
|
||||
And [weblib.js](weblib.js) is appropriate only for client modules, because it contains code that relies on the
|
||||
brower's global *window* object, as indicated by:
|
||||
browser's global *window* object, as indicated by:
|
||||
|
||||
/* global window: true */
|
||||
|
||||
|
|
@ -25,4 +25,4 @@ when running within Node, allowing any other code to test the existence of *wind
|
|||
|
||||
instead of:
|
||||
|
||||
if (typeof window !== 'undefined') {...}
|
||||
if (typeof window !== "undefined") {...}
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ function Component(type, parms, constructor)
|
|||
*
|
||||
if (this.initStep) this.initStep(parms);
|
||||
*/
|
||||
|
||||
this.fnReady = null;
|
||||
this.fReady = false;
|
||||
this.fBusy = this.fBusyCancel = false;
|
||||
|
|
@ -244,12 +245,14 @@ Component.add = function(component)
|
|||
Component.log = function(s, type)
|
||||
{
|
||||
if (DEBUG) {
|
||||
var msElapsed, sMsg = (type? (type + ": ") : "") + (s || "");
|
||||
if (Component.msStart === undefined) {
|
||||
Component.msStart = usr.getTime();
|
||||
if (s) {
|
||||
var msElapsed, sMsg = (type? (type + ": ") : "") + s;
|
||||
if (Component.msStart === undefined) {
|
||||
Component.msStart = usr.getTime();
|
||||
}
|
||||
msElapsed = usr.getTime() - Component.msStart;
|
||||
console.log(msElapsed + "ms: " + sMsg.replace(/\n/g, " "));
|
||||
}
|
||||
msElapsed = usr.getTime() - Component.msStart;
|
||||
console.log(sMsg? (msElapsed + "ms: " + sMsg.replace(/\n/g, " ")) : "");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -266,13 +269,10 @@ Component.assert = function(f, s)
|
|||
{
|
||||
if (DEBUG) {
|
||||
if (!f) {
|
||||
if (!s) {
|
||||
/*
|
||||
* TODO: An accompanying source file/line number/function call would be nice, if there was a browser-independent way....
|
||||
*/
|
||||
s = "assertion failure";
|
||||
}
|
||||
Component.log(s);
|
||||
/*
|
||||
* TODO: An accompanying source file/line number/function call would be nice, if there was a browser-independent way....
|
||||
*/
|
||||
Component.log(s || "assertion failure");
|
||||
throw new Error(s);
|
||||
}
|
||||
}
|
||||
|
|
@ -363,7 +363,7 @@ Component.getComponents = function(idRelated)
|
|||
if ((i = idRelated.indexOf('.')) > 0)
|
||||
idRelated = idRelated.substr(0, i + 1);
|
||||
else
|
||||
idRelated = undefined;
|
||||
idRelated = "";
|
||||
}
|
||||
for (i = 0; i < Component.all.length; i++) {
|
||||
var component = Component.all[i];
|
||||
|
|
@ -427,7 +427,7 @@ Component.getComponentByType = function(sType, idRelated, componentPrev)
|
|||
if ((i = idRelated.indexOf('.')) > 0) {
|
||||
idRelated = idRelated.substr(0, i + 1);
|
||||
} else {
|
||||
idRelated = undefined;
|
||||
idRelated = "";
|
||||
}
|
||||
}
|
||||
for (i = 0; i < Component.all.length; i++) {
|
||||
|
|
@ -605,10 +605,7 @@ Component.prototype = {
|
|||
/**
|
||||
* setBinding(sHTMLClass, sHTMLType, sBinding, control)
|
||||
*
|
||||
* Component's setBinding() method is intended to be overridden by subclasses. The only
|
||||
* exception is the Panel component, which passes two special bindings ("clear" and "print")
|
||||
* back to us if no one else accepted them, so that we can redirect all println() requests
|
||||
* to those controls.
|
||||
* Component's setBinding() method is intended to be overridden by subclasses.
|
||||
*
|
||||
* @this {Component}
|
||||
* @param {string|null} sHTMLClass is the class of the HTML control (eg, "input", "output")
|
||||
|
|
@ -619,67 +616,63 @@ Component.prototype = {
|
|||
*/
|
||||
setBinding: function(sHTMLClass, sHTMLType, sBinding, control) {
|
||||
switch (sBinding) {
|
||||
case "clear":
|
||||
if (!this.bindings[sBinding]) {
|
||||
this.bindings[sBinding] = control;
|
||||
control.onclick = (function(component) {
|
||||
return function() {
|
||||
if (component.bindings['print']) {
|
||||
component.bindings['print'].value = "";
|
||||
}
|
||||
};
|
||||
}(this));
|
||||
}
|
||||
return true;
|
||||
case "print":
|
||||
if (!this.bindings[sBinding]) {
|
||||
this.bindings[sBinding] = control;
|
||||
control.value = ""; // this was added for Firefox (Safari automatically clears the <textarea> on a page reload, but Firefox does not)
|
||||
/*
|
||||
* TODO: Get rid of these Component method overrides, because they're going to cause issues
|
||||
* if the day ever comes (and it WILL) that we want multiple machines on a single page with their
|
||||
* own Control Panels.
|
||||
*/
|
||||
Component.println = (function(control) {
|
||||
return function printControl(s, type) {
|
||||
s = (type !== undefined? (type + ": ") : "") + (s || "");
|
||||
if (!DEBUG) { // in non-DEBUG builds, prevent the <textarea> from getting too large, otherwise printing becomes slower and slower
|
||||
if (control.value.length > 8192) {
|
||||
control.value = control.value.substr(control.value.length - 4096);
|
||||
}
|
||||
}
|
||||
control.value += s + "\n";
|
||||
control.scrollTop = control.scrollHeight;
|
||||
if (DEBUG) console.log(s);
|
||||
};
|
||||
}(control));
|
||||
/*
|
||||
* Override Component.notice() with a replacement function that eliminates the web.alertUser() call
|
||||
*/
|
||||
Component.notice = function(s, fPrintOnly, id) {
|
||||
Component.println(s, "notice", id);
|
||||
case "clear":
|
||||
if (!this.bindings[sBinding]) {
|
||||
this.bindings[sBinding] = control;
|
||||
control.onclick = (function(component) {
|
||||
return function clearPanel() {
|
||||
if (component.bindings['print']) {
|
||||
component.bindings['print'].value = "";
|
||||
}
|
||||
};
|
||||
/*
|
||||
* HACK: Save this particular HTML element so that the Debugger can access it, too
|
||||
*/
|
||||
Component.controlPrint = control;
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
}(this));
|
||||
}
|
||||
return true;
|
||||
case "print":
|
||||
if (!this.bindings[sBinding]) {
|
||||
this.bindings[sBinding] = control;
|
||||
/*
|
||||
* Now that we're giving the Panel component multiple shots at binding its controls,
|
||||
* to relax initialization dependencies, we need to chill when unrecognized requests come in.
|
||||
*
|
||||
if (sHTMLClass == "input") {
|
||||
control.onclick = function() {
|
||||
Component.println("unsupported " + sHTMLType + ": " + sBinding);
|
||||
};
|
||||
}
|
||||
this.log("setBinding(\"" + sHTMLClass + "\",\"" + sHTMLType + "\",\"" + sBinding + "\"): unrecognized binding");
|
||||
* HACK: Save this particular HTML element so that the Debugger can access it, too
|
||||
*/
|
||||
break;
|
||||
this.controlPrint = control;
|
||||
/*
|
||||
* This was added for Firefox (Safari automatically clears the <textarea> on a page reload,
|
||||
* but Firefox does not).
|
||||
*/
|
||||
control.value = "";
|
||||
this.println = (function(control) {
|
||||
return function printPanel(s, type) {
|
||||
s = (type !== undefined? (type + ": ") : "") + (s || "");
|
||||
/*
|
||||
* In non-DEBUG builds, prevent the <textarea> from getting too large;
|
||||
* otherwise, printing becomes slower and slower.
|
||||
*/
|
||||
if (!DEBUG) {
|
||||
if (control.value.length > 8192) {
|
||||
control.value = control.value.substr(control.value.length - 4096);
|
||||
}
|
||||
}
|
||||
control.value += s + "\n";
|
||||
control.scrollTop = control.scrollHeight;
|
||||
if (DEBUG) console.log(s);
|
||||
};
|
||||
}(control));
|
||||
/**
|
||||
* Override this.notice() with a replacement function that eliminates the web.alertUser() call
|
||||
*
|
||||
* @this {Component}
|
||||
* @param {string} s
|
||||
* @param {boolean} [fPrintOnly]
|
||||
* @param {string} [id]
|
||||
*/
|
||||
this.notice = function noticePanel(s, fPrintOnly, id) {
|
||||
this.println(s, "notice", id);
|
||||
};
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
/**
|
||||
* log(s, type)
|
||||
|
|
@ -695,7 +688,9 @@ Component.prototype = {
|
|||
* @param {string} [type] is the message type
|
||||
*/
|
||||
log: function(s, type) {
|
||||
if (DEBUG) Component.log(s, type || this.id || this.type);
|
||||
if (DEBUG) {
|
||||
Component.log(s, type || this.id || this.type);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* println(s, type)
|
||||
|
|
@ -724,9 +719,9 @@ Component.prototype = {
|
|||
/**
|
||||
* notice(s, fPrintOnly)
|
||||
*
|
||||
* notice() is like println() but implies a need for user notification, which means calling log() isn't good enough, so we alert() as well;
|
||||
* however, if Component.println() is overridden, Component.notice will be replaced with the same override, on the assumption that the override
|
||||
* is taking care of user notification.
|
||||
* notice() is like println() but implies a need for user notification, which means calling log() isn't good enough,
|
||||
* so we alert() as well; however, if Component.println() is overridden, Component.notice will be replaced with the
|
||||
* same override, on the assumption that the override is taking care of alerting the user.
|
||||
*
|
||||
* @this {Component}
|
||||
* @param {string} s is the message text
|
||||
|
|
@ -736,24 +731,6 @@ Component.prototype = {
|
|||
notice: function(s, fPrintOnly, id) {
|
||||
Component.notice(s, fPrintOnly, id || this.id);
|
||||
},
|
||||
/**
|
||||
* warning(s)
|
||||
*
|
||||
* @this {Component}
|
||||
* @param {string} s describes the warning
|
||||
*/
|
||||
warning: function(s) {
|
||||
Component.warning(s);
|
||||
},
|
||||
/**
|
||||
* error(s)
|
||||
*
|
||||
* @this {Component}
|
||||
* @param {string} s describes the error; an alert() is displayed as well
|
||||
*/
|
||||
error: function(s) {
|
||||
Component.error(s);
|
||||
},
|
||||
/**
|
||||
* setError(s)
|
||||
*
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ usr.binarySearch = function(a, v, fnCompare) {
|
|||
|
||||
/**
|
||||
* binaryInsert(a, v, fnCompare)
|
||||
*
|
||||
*
|
||||
* If element v already exists in array a, the array is unchanged (we don't allow duplicates); otherwise, the
|
||||
* element is inserted into the array at the appropriate index.
|
||||
*
|
||||
|
|
@ -151,7 +151,7 @@ usr.aMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|||
* i: minutes, with leading zeros (00,...,59)
|
||||
* j: day of the month, without leading zeros (1,...,31)
|
||||
* l: day of the week ("Sunday",...,"Saturday")
|
||||
* m: month, with leading zeros (01,...,12)
|
||||
* m: month, with leading zeros (01,...,12)
|
||||
* s: seconds, with leading zeros (00,...,59)
|
||||
* F: month ("January",...,"December")
|
||||
* H: hour in 24-hour format, with leading zeros (00,...,23)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
* decodeURI() Decodes a URI
|
||||
* decodeURIComponent() Decodes a URI component
|
||||
* encodeURI() Encodes a URI
|
||||
* encodeURIComponent() Encodes a URI component
|
||||
* encodeURIComponent() Encodes a URI component
|
||||
* escape() Deprecated in version 1.5. Use encodeURI() or encodeURIComponent() instead
|
||||
* eval() Evaluates a string and executes it as if it was script code
|
||||
* isFinite() Determines whether a value is a finite, legal number
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
* parseInt() Parses a string and returns an integer
|
||||
* String() Converts an object's value to a string
|
||||
* unescape() Deprecated in version 1.5. Use decodeURI() or decodeURIComponent() instead
|
||||
*
|
||||
*
|
||||
* And according to http://www.w3schools.com/jsref/obj_window.asp, these are the properties and functions
|
||||
* of the *window* object.
|
||||
*
|
||||
|
|
@ -86,7 +86,7 @@
|
|||
* self Returns the current window
|
||||
* status Sets or returns the text in the statusbar of a window
|
||||
* top Returns the topmost browser window
|
||||
*
|
||||
*
|
||||
* Method Description
|
||||
* ---
|
||||
* alert() Displays an alert box with a message and an OK button
|
||||
|
|
@ -122,7 +122,7 @@
|
|||
* We must defer loading the Component module until the function(s) requiring it are
|
||||
* called; otherwise, we create an initialization cycle in which Component requires weblib
|
||||
* and weblib requires Component.
|
||||
*
|
||||
*
|
||||
* In an ideal world, weblib would not be dependent on Component, but we really want to use
|
||||
* its logging functions.
|
||||
*/
|
||||
|
|
@ -155,16 +155,16 @@ var web = {};
|
|||
*/
|
||||
web.loadResource = function(sURL, fAsync, data, componentNotify, fnNotify, pNotify)
|
||||
{
|
||||
fAsync = !!fAsync; // ensure that fAsync is a valid boolean (Internet Explorer xmlHTTP functions insist on it)
|
||||
fAsync = !!fAsync; // ensure that fAsync is a valid boolean (Internet Explorer xmlHTTP functions insist on it)
|
||||
if (typeof module !== 'undefined') {
|
||||
/*
|
||||
* We don't even need to load Component, because we can't use any of the code below
|
||||
* within Node anyway. Instead, we must hand this request off to our network library.
|
||||
*
|
||||
*
|
||||
* if (!Component) Component = require("./component");
|
||||
*/
|
||||
var net = require("./netlib");
|
||||
return net.loadResource(sURL, fAsync, data, componentNotify, fnNotify, pNotify);
|
||||
return net.loadResource(sURL, fAsync, data, componentNotify, fnNotify, pNotify);
|
||||
}
|
||||
var nErrorCode = 0;
|
||||
var sURLData = null;
|
||||
|
|
@ -312,7 +312,7 @@ web.confirmUser = function(sPrompt)
|
|||
|
||||
/**
|
||||
* promptUser()
|
||||
*
|
||||
*
|
||||
* @param {string} sPrompt
|
||||
* @param {string} [sDefault]
|
||||
* @returns {string|null}
|
||||
|
|
@ -330,7 +330,7 @@ web.promptUser = function(sPrompt, sDefault)
|
|||
* getLocalStorageItem(sKey)
|
||||
*
|
||||
* Returns the requested key value, or null if the key does not exist, or undefined if localStorage is not available
|
||||
*
|
||||
*
|
||||
* @param {string} sKey
|
||||
* @return {string|null|undefined} sValue
|
||||
*/
|
||||
|
|
@ -345,7 +345,7 @@ web.getLocalStorageItem = function(sKey)
|
|||
|
||||
/**
|
||||
* setLocalStorageItem(sKey, sValue)
|
||||
*
|
||||
*
|
||||
* @param {string} sKey
|
||||
* @param {string} sValue
|
||||
* return {boolean} true if localStorage is available, false if not
|
||||
|
|
@ -427,13 +427,13 @@ web.getURLParameters = function(sParms)
|
|||
* Note that window.location.href returns the entire URL, whereas window.location.search
|
||||
* returns only the parameters, if any (starting with the '?', which we skip over with a substr() call).
|
||||
*/
|
||||
sParms = window.location.search.substr(1);
|
||||
sParms = window.location.search.substr(1);
|
||||
}
|
||||
var match;
|
||||
var pl = /\+/g; // RegExp for replacing addition symbol with a space
|
||||
var search = /([^&=]+)=?([^&]*)/g;
|
||||
var decode = function(s) { return decodeURIComponent(s.replace(pl, " ")); };
|
||||
|
||||
|
||||
while ((match = search.exec(sParms))) {
|
||||
aParms[decode(match[1])] = decode(match[2]);
|
||||
}
|
||||
|
|
@ -482,7 +482,7 @@ web.onCountRepeat = function(n, fn, fnComplete, msDelay)
|
|||
web.onClickRepeat = function(e, msDelay, msRepeat, fn)
|
||||
{
|
||||
var ms = 0, timer = null, fIgnoreMouseEvents = false;
|
||||
|
||||
|
||||
var fnRepeat = function doClickRepeat() {
|
||||
if (fn(ms === msRepeat)) {
|
||||
timer = setTimeout(fnRepeat, ms);
|
||||
|
|
@ -628,7 +628,7 @@ web.enablePageEvents = function(fEnable)
|
|||
|
||||
/**
|
||||
* sendPageEvent(sEvent)
|
||||
*
|
||||
*
|
||||
* This allows us to manually trigger page events.
|
||||
*
|
||||
* @param {string} sEvent (one of 'init', 'show' or 'exit')
|
||||
|
|
|
|||
Loading…
Reference in a new issue