From: Mike G. v. a. <we...@ma...> - 2009-03-22 18:42:35
|
Log Message: ----------- refining the applet API Modified Files: -------------- webwork2/htdocs/js: ww_applet_support.js Revision Data ------------- Index: ww_applet_support.js =================================================================== RCS file: /webwork/cvs/system/webwork2/htdocs/js/ww_applet_support.js,v retrieving revision 1.8 retrieving revision 1.9 diff -Lhtdocs/js/ww_applet_support.js -Lhtdocs/js/ww_applet_support.js -u -r1.8 -r1.9 --- htdocs/js/ww_applet_support.js +++ htdocs/js/ww_applet_support.js @@ -20,32 +20,17 @@ // applet lists ////////////////////////////////////////////////////////// -// var applet_initializeAction_list = new Object; // functions for initializing question with an applet -// var applet_submitAction_list = new Object; // functions for submitting question with applet -// var applet_setState_list = new Object; // functions for setting state (XML) from applets -// var applet_getState_list = new Object; // functions for getting state (XML) from applets -// var applet_config_list = new Object; // functions for configuring on applets -// var applet_checkLoaded_list = new Object; // functions for probing the applet to see if it is loaded -// var applet_reportsLoaded_list = new Object; // flag set by applet -// var applet_isReady_list = new Object; // flag set by javaScript in checkLoaded - var ww_applet_list = new Object; // holds intelligent ww_applet objects + var ww_applet_list = new Object; // holds java script version (jsApplet) ww_applet objects ////////////////////////////////////////////////////////// // DEBUGGING tools ////////////////////////////////////////////////////////// - var jsDebugMode; + var jsDebugMode=0; // set this to one when needed for major debugging -- puts all applets in debugMode var debugText = ""; - function set_debug(num) { // setting debug for any applet sets it for all of them - if (num) { - jsDebugMode =1; - } - } - function debug_add(str) { - if (jsDebugMode) { + function debug_add(str) { debugText = debugText + "\n" +str; - } } ////////////////////////////////////////////////////////// @@ -53,16 +38,16 @@ ////////////////////////////////////////////////////////// function submitAction() { // called from the submit button defined in Problem.pm - - if (jsDebugMode) { + + if (jsDebugMode==1) { debugText = "Call submitAction() function on each applet\n"; } for (var appletName in ww_applet_list ) { ww_applet_list[appletName].submitAction(); } - debug_add("\n Done calling submitAction() on each applet.\n"); - if (jsDebugMode) { + if (jsDebugMode==1) { debug_add("\n Done calling submitAction() on each applet.\n");} + if (jsDebugMode==1) { alert(debugText); debugText=""; }; } @@ -73,10 +58,10 @@ } function initializeWWquestion() { // called from <body> tag defined in the webwork2/conf/template - var iMax = 5; - debugText="Initialize each applet. \nUse up to " +iMax + " cycles to wait for each applet to load\n"; - for (var appletName in ww_applet_list) { - safe_applet_initialize(appletName, iMax); + for (var appletName in ww_applet_list) { + var maxInitializationAttempts = ww_applet_list[appletName].maxInitializationAttempts; + // alert("Initialize each applet. \nUse up to " +maxInitializationAttempts + " cycles to load" +"\n"); + ww_applet_list[appletName].safe_applet_initialize(maxInitializationAttempts); } } @@ -91,60 +76,6 @@ // insures that applet is loaded before initializing it -function safe_applet_initialize(appletName, i) { - i--; - debug_add(" Try to initialize applet " + appletName + ". Count down: " + i + ".\n" ); - - - var ww_applet = ww_applet_list[appletName]; - var applet_loaded = ww_applet.checkLoaded(); - if (applet_loaded=="still_loading" && !(i> 0) ) { - // it's possible that the isActive() response of the applet is not working properly - alert("The isActive() method of applet " +appletName + " claims it is still loading! We'll ignore this."); - i=1; - applet_loaded=1; - } else if (applet_loaded=="still_loading") { - applet_loaded=0; // keep trying - } - - - debug_add(" applet is ready = " + applet_loaded ); - - if ( 0 < i && !applet_loaded ) { // wait until applet is loaded - debug_add(" applet " + appletName + " is not yet ready try again"); - window.setTimeout( "safe_applet_initialize(\"" + appletName + "\"," + i + ")",1); - } else if( 0 < i ){ // now that applet is loaded configure it and initialize it with saved data. - debug_add(appletName + " initialization completed with " + i + " possible attempts remaining. \n"); - - // in-line handler -- configure and initialize - try{ - ww_applet.setDebug(jsDebugMode); - } catch(e) { - var msg = "Unable set debug in " + appletName + " \n " +e; - if (jsDebugMode) {debug_add(msg);} else {alert(msg)}; - } - try{ - - ww_applet.config(); - - } catch(e) { - var msg = "Unable to configure " + appletName + " \n " +e; - if (jsDebugMode) {debug_add(msg);} else {alert(msg)}; - } - try{ - - ww_applet.initializeAction(); - - } catch(e) { - var msg = "unable to initialize " + appletName + " \n " +e; - if (jsDebugMode) {debug_add(msg);} else {alert(msg)}; - } - - } else { - if (jsDebugMode) {debug_add("Error: timed out waiting for applet " +appletName + " to load");} - } - if (jsDebugMode) {alert(debugText); debugText="";}; -} /////////////////////////////////////////////////////// // Utility functions @@ -186,7 +117,7 @@ function base64Q(str) { /// determine whether an XML string has been base64 encoded. return ( !str.match(/<XML/i) && !str.match(/<?xml/i)); } -function setAppletStateToRestart(appletName){ +function setAppletStateToRestart(appletName){ var newState = "<xml>restart_applet</xml>"; //ww_applet_list[appletName].setState(newState); getQE(appletName+"_state").value = newState; @@ -200,7 +131,7 @@ // needed for IE -- searches id and name space so it can be unreliable if names are not unique if (!obj || obj.name != name1) { var msg = "Can't find element " + name1; - if (jsDebugMode) { + if (jsDebugMode==1) { debug_add(msg + "\n ( Place listQuestionElements() at end of document in order to get all form elements! )\n" ); } else { alert(msg); listQuestionElements(); @@ -227,8 +158,10 @@ this.code = ''; this.codebase = ''; this.appletID = ''; - this.base64_state = ''; - this.base64_config = ''; +// this.base64_state = ''; +// this.base64_config = ''; + this.configuration = ''; + this.initialState = ''; this.getStateAlias = ''; this.setStateAlias = ''; this.configAlias = ''; @@ -237,55 +170,88 @@ this.submitActionScript = ''; this.getAnswerAlias = ''; this.answerBox = ''; - this.debug = ''; + this.debugMode = 0 ; this.isReady = 0 ; this.reportsLoaded = 0 ; }; +////////////////////////////////////////////////////////// +// methodDefined +// +// make sure that the applet has this function available +////////////////////////////////////////////////////////// +ww_applet.prototype.methodDefined = function(methodName) { + var appletName = this.appletName; + var applet = getApplet(appletName); + try { + if (typeof(applet[methodName]) == "function" ) { + this.debug_add("Method " + methodName + " is defined in " + appletName ); + return(true); + } else { + this.debug_add("Method " + methodName + " is not defined in " + appletName); + return(false); + } + } catch(e) { + var msg = "Error in accessing " + methodName + " in applet " +appletName + "Error: " +e ; + alert(msg); + } + return(false); +} ////////////////////////////////////////////////////////// //CONFIGURATIONS // // configurations are "permanent" ////////////////////////////////////////////////////////// -ww_applet.prototype.config = function () { +ww_applet.prototype.setConfig = function () { var appletName = this.appletName; var applet = getApplet(appletName); var setConfigAlias = this.setConfigAlias; - debug_add(" Calling " + appletName +"."+ setConfigAlias +"( " + Base64.decode(this.base64_config) + " ) " ); - try { + + try { if ( this.methodDefined(setConfigAlias) ) { - applet[setConfigAlias](Base64.decode(this.base64_config)); + applet[setConfigAlias](this.configuration); } + } catch(e) { + var msg = "Error in configuring " + appletName + " using command " + setConfigAlias + " : " + e ; alert(msg); } + this.debug_add(" Calling " + appletName +"."+ setConfigAlias +"( " + this.configuration + " ) " ); + }; + + ww_applet.prototype.getConfig = function() { // used for debugging purposes -- gets the configuration from the applet + + + var appletName = this.appletName; + var applet = getApplet(appletName); + var getConfigAlias = this.getConfigAlias; + + + try { + if (this.methodDefined(getConfigAlias) ) { + alert( applet[getConfigAlias]() ); + } else { + alert("in getConfig " + debugText); + } + } catch(e) { + var msg = " Error in getting configuration from applet " + appletName + " " + e; + alert(msg); + } +} + + + //////////////////////////////////////////////////////////// // //STATE: // state can vary as the applet is manipulated -- it is reset from the questions _state values // ////////////////////////////////////////////////////////// -ww_applet.prototype.methodDefined = function(methodName) { - var appletName = this.appletName; - var applet = getApplet(appletName); - try { - if (typeof(applet[methodName]) == "function" ) { - debug_add("Method " + methodName + " is defined in " + appletName ); - return(true); - } else { - debug_add("Method " + methodName + " is not defined in " + appletName); - return(false); - } - } catch(e) { - var msg = "Error in accessing " + methodName + " in applet " +appletName + "Error: " +e ; - alert(msg); - } - return(false); -} + ww_applet.prototype.setState = function(state) { @@ -293,12 +259,12 @@ var applet = getApplet(appletName); var setStateAlias = this.setStateAlias; - debug_add("\nBegin process of setting state for applet " + appletName); + debug_add("\n++++++++++++++++++++++++++++++++++++++++\nBegin process of setting state for applet " + appletName); if (state) { - debug_add(" Obtain state from calling parameter:\n " + state + "\n"); + debug_add("Obtain state from calling parameter:\n " + state + "\n"); } else { - debug_add(" Obtain state from " + appletName +"_state"); + this.debug_add("Obtain state from " + appletName +"_state"); var ww_preserve_applet_state = getQE(appletName + "_state"); // hidden answer box preserving applet state state = ww_preserve_applet_state.value; @@ -307,20 +273,19 @@ if ( base64Q(state) ) { state=Base64.decode(state); } - // if we are restarting the applet bail -- we don't want to set the state. if (state.match(/^<xml>restart_applet<\/xml>/) ) { - alert("The applet " +appletName + "has been reset to its virgin state."); - ww_preserve_applet_state.value =""; //Fixme? should we set the last answer to blank as well? - return(''); + alert("The applet " +appletName + "has been reset to its virgin state." + this.initialState); + ww_preserve_applet_state.value =this.initialState; //Fixme? should we set the last answer to blank as well? + state = ww_preserve_applet_state.value; } if (state.match(/<xml/i) || state.match(/<?xml/i) ) { // if state starts with <?xml - debug_add(" Set (decoded) state for " + appletName + " to \n\n" + - state +"\n\n Check that applet's setState method " +setStateAlias + " is a function: " +typeof(applet[setStateAlias]) - ); + this.debug_add("Set state for " + appletName + " to \n------------------------------\n" + + state + "\n------------------------------\n"); try { + if ( this.methodDefined(setStateAlias) ) { applet[setStateAlias]( state ); // change the applets current state } @@ -328,8 +293,8 @@ msg = "Error in setting state of " + appletName + " using command " + setStateAlias + " : " + e ; alert(msg); } - } else if (jsDebugMode) { - debug_add(" new state was empty string or did not begin with <xml> -- Applet state was not reset"); + } else if (jsDebugMode==1) { + this.debug_add(" new state was empty string or did not begin with <xml> -- Applet state was not reset"); } return(''); }; @@ -341,7 +306,7 @@ var applet = getApplet(appletName); var getStateAlias = this.getStateAlias; - debug_add(" Begin getState for applet " + appletName ); + this.debug_add(" Begin getState for applet " + appletName ); try { if (this.methodDefined(getStateAlias)) { // there may be no state function @@ -349,9 +314,9 @@ debug_add(" state has type " + typeof(state)); state = String(state); // geogebra returned an object type instead of a string type // this insures that we can view the state as a string - debug_add(" state converted to type " + typeof(state)); + this.debug_add(" state converted to type " + typeof(state)); } else { - debug_add(" Applet does not have a getState method named: "+ getStateAlias + "."); + this.debug_add(" Applet does not have a getState method named: "+ getStateAlias + "."); state ="<xml>undefined_state</xml>"; } @@ -360,28 +325,30 @@ alert(msg); } - if (!jsDebugMode) { + if (this.debugMode==0) { state = Base64.encode(state); }; // replace state by encoded version unless in debug mode - debug_add(" state is \n "+ state + "\n"); // state should still be in plain text + this.debug_add(" state is \n "+ state + "\n"); // state should still be in plain text var ww_preserve_applet_state = getQE(appletName + "_state"); // answer box preserving applet state (jsDebugMode: textarea, otherwise: hidden) ww_preserve_applet_state.value = state; //place state in input item (jsDebugMode: textarea, otherwise: hidden) - debug_add("State stored in answer box "+ appletName + "_state and getState is finished."); + this.debug_add("State stored in answer box "+ appletName + "_state and getState is finished."); }; ww_applet.prototype.setDebug = function(debugMode) { + // sets debug mode in the flash or java applet + // applet's method must be called debug var appletName = this.appletName; var applet = getApplet(appletName); - debugMode = debugMode || this.debug; + debugMode = jsDebugMode || debugMode ; try{ if (this.methodDefined("debug") ) { - applet.debug(1); // turn the applet's debug functions on. + applet.debug(debugMode); // set the applet's debug functions on. } else { - debug_add( " Unable to set debug state in applet " + appletName + "."); + this.debug_add( " Unable to set debug state in applet " + appletName + "."); } } catch(e) { @@ -391,23 +358,7 @@ } -ww_applet.prototype.getConfig = function() { // used for debugging purposes -- gets the configuration from the applet - var config = "foobar"; - var appletName = this.appletName; - var applet = getApplet(appletName); - var getConfigAlias = this.getConfigAlias; - try { - if (this.methodDefined(getConfigAlias) ) { - alert( applet[getConfigAlias]() ); - } else { - alert(debugText); - } - } catch(e) { - var msg = " Error in getting configuration from applet " + appletName + " " + e; - alert(msg); - } -} - + //////////////////////////////////////////////////////////// @@ -421,32 +372,33 @@ this.setState(); }; -ww_applet.prototype.submitAction = function () { +ww_applet.prototype.submitAction = function () { var appletName = this.appletName; // var getAnswer = this.getAnswerAlias; - var ww_preserve_applet_state = getQE(appletName + "_state"); // hidden answer box preserving applet state + var ww_preserve_applet_state = getQE(appletName + "_state"); // hidden HTML input element preserving applet state var saved_state = ww_preserve_applet_state.value; - if (jsDebugMode) {debug_add("Begin submit action for applet " + appletName);} + this.debug_add("Begin submit action for applet " + appletName); var applet = getApplet(appletName); if (! this.isReady ) { alert(appletName + " is not ready"); - initializeAction(); + this.initializeAction(); } // Check to see if we want to restart the applet if (saved_state.match(/^<xml>restart_applet<\/xml>/) ) { - if (jsDebugMode) { debug_add("Restarting the applet "+appletName);} + this.debug_add("Restarting the applet "+appletName); setAppletStateToRestart(appletName); // erases all of the saved state return(''); } // if we are not restarting the applet save the state and submit this.getState(); // have ww_applet retrieve state from applet and store in answerbox - if (jsDebugMode) {debug_add("Submit Action Script " + this.submitActionScript + "\n");} + this.debug_add("Submit Action Script " + this.submitActionScript + "\n"); eval(this.submitActionScript); //getQE(this.answerBox).value = applet.[getAnswer](); //FIXME -- not needed in general? - if (jsDebugMode) {debug_add("Completed submitAction() for applet " + appletName+ "\n");} + this.debug_add("Completed submitAction(" + this.submitActionScript + ") \nfor applet " + appletName+ "\n"); + if (this.debugMode){alert(debugText); debugText="";} }; @@ -459,8 +411,14 @@ var ready = 0; var appletName = this.appletName; var applet = getApplet(appletName); - if (!jsDebugMode && this.isReady) {return(1)}; // memorize readiness in non-debug mode - debug_add("Test 4 methods to see if the applet " + appletName + " has been loaded: \n"); + + // alert("2 jsDebugMode " + jsDebugMode + " applet debugMode " + this.debugMode + " local debugMode " + debugMode); + + if (this.debugMode==0 && this.isReady) {return(1)}; // memorize readiness in non-debug mode + + this.debug_add("Test 4 methods to see if the applet " + appletName + " has been loaded: \n"); + + if ( this.methodDefined(this.setConfigAlias) ) { ready = 1; } @@ -468,23 +426,117 @@ ready =1; } + + if (typeof(this.reportsLoaded) !="undefined" && this.reportsLoaded != 0 ) { + this.debug_add( " " + appletName + " applet self reports that it has completed loading. " ); + ready =1; + } + + // the return value of the isActive() method, when defined, overrides the other indications + // that the applet is ready + if ( this.methodDefined("isActive") ) { if (applet.isActive()) { //this could be zero if applet is loaded, but it is loading auxiliary data. - debug_add( "Applet " +appletName + " signals it is active."); + this.debug_add( "Applet " +appletName + " signals it is active."); ready =1; } else { - debug_add( "Applet " + appletName + " signals it is not active. -- \n it may still be loading data."); + this.debug_add( "Applet " + appletName + " signals it is not active. -- \n it may still be loading data."); ready = "still_loading"; } } - if (typeof(this.reportsLoaded) !="undefined" && this.reportsLoaded != 0 ) { - debug_add( " " + appletName + " applet self reports that it has completed loading. " ); - ready =1; - } + this.isReady = ready; return(ready); } +ww_applet.prototype.debug_add = function(str) { + if (this.debugMode) { + debugText = debugText + "\n" +str; // a global text string + } +} +ww_applet.prototype.safe_applet_initialize = function(i) { + //alert("begin safe_applet_initialize"); + var appletName = this.appletName; + i--; + this.debug_add(" Try to initialize applet " + appletName + ". Count down: " + i + ".\n" ); + //alert("1 jsDebugMode " + jsDebugMode + " applet debugMode " +this.debugMode); + + var applet_loaded = this.checkLoaded(); + + if (applet_loaded=="still_loading" && !(i> 0) ) { + // it's possible that the isActive() response of the applet is not working properly + alert("The isActive() method of applet " +appletName + " claims it is still loading! We'll ignore this."); + i=1; + applet_loaded=1; + } else if (applet_loaded=="still_loading") { + applet_loaded=0; // keep trying + } + + + if ( 0 < i && !applet_loaded ) { // wait until applet is loaded + this.debug_add("Applet " + appletName + " is not yet ready try again\n"); + if (this.debugMode) { + alert(debugText ); + debugText=""; + } + window.setTimeout( "ww_applet_list[\""+ appletName + "\"].safe_applet_initialize(" + i + ")",100); + } else if( 0 < i ) { // now that applet is loaded configure it and initialize it with saved data. + + this.debug_add(" applet is ready = " + applet_loaded ); + + this.debug_add("Applet "+ appletName + " initialization completed\n with " + i + + " possible attempts remaining. \n" + + "------------------------------\n"); + + // in-line handler -- configure and initialize + //alert("setDebug") + try{ + + this.setDebug(this.debugMode); + + } catch(e) { + var msg = "Unable set debug in " + appletName + " \n " +e; + if (this.debugMode) {this.debug_add(msg);} else {alert(msg)}; + } + + //alert("config applet"); + try{ + + this.setConfig(); // for applets that require a configuration (which doesn't change for a given WW question + + } catch(e) { + var msg = "Unable to configure " + appletName + " \n " +e; + if (this.debugMode) {this.debug_add(msg);} else {alert(msg)}; + } + + + //alert("initializeAction"); + try{ + + this.initializeAction(); // this is often the setState action. + + } catch(e) { + var msg = "unable to initialize " + appletName + " \n " +e; + if (this.debugMode) { + this.debug_add(msg); + } else { + alert(msg); + } + } + if (this.debugMode) { + alert("\nBegin debugmode\n " + debugText ); + debugText=""; + }; + } else { + this.debug_add("Error: timed out waiting for applet " +appletName + " to load"); + //alert("4 jsDebugMode " + jsDebugMode + " applet debugMode " +ww_applet.debugMode + " local debugMode " +debugMode); + if (this.debugMode) { + alert(" in safe applet " + debugText ); + debugText=""; + } + } + +} function iamhere() { alert( "javaScript loaded. functions still work"); |