// // $Id: HSapi.js,v 1.39 2006-08-29 23:50:08 bergsma Exp $ // // $Log: HSapi.js,v $ // Revision 1.39 2006-08-29 23:50:08 bergsma // no message // // Revision 1.38 2005/12/20 06:36:25 bergsma // *** empty log message *** // // Revision 1.36 2005/12/16 00:17:51 bergsma // *** empty log message *** // // Revision 1.35 2005/11/25 03:15:34 bergsma // *** empty log message *** // // Revision 1.33 2005/11/14 17:41:05 bergsma // no message // // Revision 1.32 2005/11/06 16:50:29 bergsma // no message // // Revision 1.31 2005/10/20 00:29:30 bergsma // no message // // // Revision 1.6 2005/06/23 01:47:12 bergsma // Dashboard 2005 // // Revision 1.1 2005/02/13 01:15:40 bergsma // Relocated to dist/webpickle/dashboard/js // // Revision 1.2 2005/02/06 18:27:54 jbergsma // Functions to interface HyperScript (i.e. WebPickle) with JavaScript for the dashboard application. // // // GLOBAL VARIABLES var isBootStrapped = false ; var isBootStrapping = false ; var isLoaded = false ; var isLoading = false ; var ab = null ; var isJava = 0 ; var isActiveX = 0 ; var deploy = "" ; var maxLoads = 10 ; var maxBoots = 5 ; var bootIntervalID = null ; var loadIntervalID = null ; var nodeName = "" ; var server = "" ; var portnum = "" ; var target = "" ; /////////////////////////////////////////////////////////////////// // // BOOTSTRAP SECTION // /////////////////////////////////////////////////////////////////// // FUNCTION TO SET THE HANDLE TO HYPERSCRIPT function setAb( fn ) { if ( ab != null ) return ab ; ab = document.HyperScript2 ; if ( ab == null ) alert ( fn+ ": No HyperScript for deploy method '"+deploy+"'" ) ; return ab ; } // BOOTSTRAP - DO THIS BEFORE LOAD_BRAINS!!! function bootstrap ( dm, nn ) { //alert ( "bootstrap" ); deploy = dm ; nodeName = nn ; server = location.host ; portnum = location.port ; if ( portnum == "" ) portnum = 80 ; target = "/" + nn + ".hyp" ; isJava = ( deploy == "java" ) ; isActiveX = ( deploy == "activex" ); // We always invoke bootstrap under a repeating timer. Try every second. if ( bootIntervalID != null ) window.clearInterval(bootIntervalID) ; bootIntervalID = window.setInterval("bootstrap2()",1000) ; } function bootstrap2 ( ) { //alert("bootstrap2"); // Don't try more than maxBoot times maxBoots-- ; // If there are no objects loaded yet, return and // wait for the timer to go off again. // For the ActiveX case, there'll be 2 objects. if ( document.applets.length == 0 && maxBoots > 0 ) return ; // We think we've got HyperScript. Cancel the timer. if ( bootIntervalID != null ) { window.clearInterval ( bootIntervalID ) ; bootIntervalID = null ; } // If we exceeded our timer, then fail. if ( maxBoots <= 0 ) { alert ( "Failed to bootstrap HyperScript2" ) ; if ( loadIntervalID != null ) { window.clearInterval ( loadIntervalID ) ; loadIntervalID = null ; } return ; } // Otherwise, onto booting. bootstrap3() ; } function bootstrap3() { //alert ( "Bootstrap3 "+deploy ) ; // Make sure some other thread isn't doing the work. if ( isBootStrapping ) return ; // Set flag to indicate we are booting isBootStrapping = true ; // Init the DHTML initDHTMLAPI() ; // For activeX we need a console. if ( isActiveX ) openconsole(); var httpRequest = new HttpXMLRequest( '','' ) ; httpRequest.loadXMLDocSync( "GET","/local/run/bootstrap.hyp","",3000) ; var s = httpRequest.responseText() ; // Locate the HyperScript object if ( setAb("Bootstrap") == null ) return ; // Load the bootstrap part of the HyperScript program var ret = ab.Parse( s ) ; if ( typeof(ret) != "undefined" && ret != "$ACK" ) { var e = "Bootstrap: Failed to parse brains, reason is " + ret ; alert ( e ); return ; } // Decide which loopback to use for communication // between JAVA and HYPERSCRIPT // We choose a random localhost port var a = Math.round(Math.random() * 124) ; var b = Math.round(Math.random() * 124) ; var c = Math.round(Math.random() * 124) ; var loopbackAddr = 127 + "." + a + "." + b + "." + c ; var loopbackPort = 8088 ; // Put HS in idle mode, awaiting requests. var bootstrap = 'BOOTSTRAP("' + loopbackAddr + '",' + loopbackPort + '); idle();' ; //alert (bootstrap ); ret = ab.Parse ( bootstrap ) ; if ( typeof(ret) != "undefined" && ret != "$ACK" ) { var e = "Bootstrap: Failed to idle(), reason is " + ret ; alert ( e ); return ; } // ActiveX uses the IE mailbox to send requests to // HyperScript. JAVA uses a loopback connection, // which must be established first. if ( isJava ) { var ret = ab.openSocketStream(loopbackAddr,loopbackPort); if ( ret != "$ACK" ) { var e = "Failed to connect hyperscript, reason is " + ret ; alert ( e ); } } // Set flag to indicate we are done bootstrapping isBootStrapping = false ; isBootStrapped = true ; if ( !isLoading ) { // For netscape / mozilla / firefox, the load_brains() may never // get underway, so we give it a little shove. //alert ( "Load brains not happening, kicking"); if ( loadIntervalID != null ) window.clearInterval(loadIntervalID) ; loadIntervalID = window.setInterval("load_brains2()",3000) ; } } // LOAD_BRAINS - do this after BOOTSTRAP!! function load_brains( dm, nn ) { //alert ( "load_brains"); deploy = dm ; nodeName = nn ; server = location.host ; portnum = location.port ; if ( portnum == "" ) portnum = 80 ; target = "/" + nn + ".hyp" ; isJava = ( deploy == "java" ) ; isActiveX = ( deploy == "activex" ); // We always invoke load_brains under a repeating timer. // Try every 3 seconds, give time for bootstrapping to complete. if ( loadIntervalID != null ) window.clearInterval(loadIntervalID) ; loadIntervalID = window.setInterval("load_brains2()",3000) ; } function load_brains2 () { //alert("load_brains2"); // Don't try more than maxBoot times maxLoads-- ; // If we have not completed bootstrapping, // then we cannot proceed if ( !isBootStrapped ) { // We can wait a bit. if ( maxLoads > 0 ) return ; } // We might be ok, cancel timer if ( loadIntervalID != null ) { window.clearInterval ( loadIntervalID ) ; loadIntervalID = null ; } if ( maxLoads <= 0 ) { alert ( "Failed to load brains for HyperScript2 " ) ; return ; } // Do the real loading of brains load_brains3() ; } function load_brains3() { // Make sure some other thread isn't doing the work. if ( isLoading ) return ; //alert ( "load_brains3" ) ; if ( !isBootStrapped ) { // In case we have not bootstrapped. alert ( "Bootstrap not happening, kicking"); isBootStrapping = false ; if ( bootIntervalID != null ) window.clearInterval(bootIntervalID) ; bootIntervalID = window.setInterval("bootstrap2()",1000) ; return ; } // Now we load isLoading = true ; e = "Load '" + nodeName + "':" + "'" + server+ "':" + "'" + portnum+ "':" + "'" + target+ "'"; if ( setAb("Load Brains") == null ) return ; if ( isActiveX ) openconsole() ; var cmd = 'LOAD_BRAINS("' + server + '",' + portnum + ',"' + target + '","' + deploy + '");' ; //alert( cmd ) ; ret = ab.Eval ( cmd ) ; if ( typeof(ret) != "undefined" && ret != "$ACK" ) { var e = "Load Brains: Failed to Eval(), reason is " + ret ; alert ( e ); return ; } isLoading = false ; isLoaded = true ; } /////////////////////////////////////////////////////////////////// // // HYPERSCRIPT INTERFACE // /////////////////////////////////////////////////////////////////// // HSPARSE is a front-end to calling ab.Parse, the // way in which to get tokens into hyperscript when it // is not in an idle state. Most often used at bootstrap, // to load in the brains of the hyperscript program function hsparse ( cmd ) { if ( setAb("Parse") == null ) return ; ret = ab.Parse( cmd ) ; if ( typeof(ret) != "undefined" && ret != "$ACK" ) { var e = "HSparse: Failed to Parse(), reason is " + ret ; alert ( e ); return ; } } // HSEVAL is a front-end to calling ab.Eval, the // way in which to send program code to Hyperscript // to evaluate. For JAVA, its over the loopback, for // ActiveX its through the mailslot. function hseval ( cmd ) { if ( setAb("Eval") == null ) return ; ret = ab.Eval( cmd ) ; if ( typeof(ret) != "undefined" && ret != "$ACK" ) { var e = "HSeval: Failed to Eval(), reason is " + ret ; alert ( e ); return ; } } // HSCALL is used by JAVASCRIPT, such as FORM elements, // to CALL/INVOKE specific HyperScript method. function hscall ( t, m, argument ) { var c = 'event("' + t + '#"+self(2),"' + m + '",{},' + argument + ');' ; //alert ( c ) ; hseval ( c ) ; // Return false so that the form won't submit. return false ; } function hscall2 ( t, m, argument ) { var c = 'event("' + t + '#"+self(2),"' + m + '",{}, "' + argument + '" );' ; //alert ( c ) ; hseval ( c ) ; // Return false so that the form won't submit. return false ; } function hsputs ( argument ) { var c = 'event( self(2), "' + "PUTS" + '",{}, "' + argument + '" );' ; //alert ( c ) ; hseval ( c ) ; // Return false so that the form won't submit. return false; } // ACTIVEX FUNCTIONS function openconsole() { document.WebPickle.CreateListBox() ; } function writeconsole( message ) { document.WebPickle.Puts( message ) ; } /////////////////////////////////////////////////////////////////////// // // DOM FUNCTIONS // /////////////////////////////////////////////////////////////////////// // Update the innerHTML of a node function updateNode ( nodeName, htmlData ) { var DOMnode = document.getElementById(nodeName); if ( DOMnode ) DOMnode.innerHTML = htmlData ; } // Update the innerHTML of a node function appendTextToNode ( nodeName, text ) { var DOMnode = document.getElementById(nodeName); if ( DOMnode ) { var t = document.createTextNode(text); DOMnode.appendChild(t); var br = document.createElement("BR"); DOMnode.appendChild(br); } } // Update a form element function updateFormElement ( formName, element, value ) { if ( value == undefined ) value = '' ; document.forms[formName].elements[0].value = value ; }