[system] / trunk / pg / macros / AppletObjects.pl Repository:
ViewVC logotype

View of /trunk/pg/macros/AppletObjects.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5662 - (download) (as text) (annotate)
Mon May 5 17:24:46 2008 UTC (11 years, 7 months ago) by gage
File size: 14295 byte(s)
fix method of setting debug

    1 ################################################################################
    2 # WeBWorK Online Homework Delivery System
    3 # Copyright  2000-2007 The WeBWorK Project, http://openwebwork.sf.net/
    4 # $CVSHeader: pg/macros/AppletObjects.pl,v 1.7 2008/04/26 21:19:14 gage Exp $
    5 #
    6 # This program is free software; you can redistribute it and/or modify it under
    7 # the terms of either: (a) the GNU General Public License as published by the
    8 # Free Software Foundation; either version 2, or (at your option) any later
    9 # version, or (b) the "Artistic License" which comes with this package.
   10 #
   11 # This program is distributed in the hope that it will be useful, but WITHOUT
   12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   13 # FOR A PARTICULAR PURPOSE.  See either the GNU General Public License or the
   14 # Artistic License for more details.
   15 ################################################################################
   16 
   17 =head1 NAME
   18 
   19 AppletObjects.pl - Macro-based front end for the Applet.pm module.
   20 
   21 
   22 =head1 DESCRIPTION
   23 
   24 This subroutines in this
   25 file provide mechanisms to insert Flash applets (and later Java applets)
   26 into a WeBWorK problem.
   27 
   28 
   29 =head1 SEE ALSO
   30 
   31 L<Applets.pm>.
   32 
   33 =cut
   34 
   35 
   36 sub _AppletObjects_init{}; # don't reload this file
   37 
   38 
   39 main::HEADER_TEXT(<<'END_HEADER_TEXT');
   40   <script language="javascript">AC_FL_RunContent = 0;</script>
   41     <script src="/webwork2_files/applets/AC_RunActiveContent.js" language="javascript">
   42     </script>
   43     <script src="/webwork2_files/js/Base64.js" language="javascript">
   44     </script>
   45 
   46 <script language="JavaScript">
   47 
   48 //////////////////////////////////////////////////////////
   49 // applet lists
   50 //////////////////////////////////////////////////////////
   51 
   52     var  applet_initializeAction_list = new Object;  // functions for initializing question with an applet
   53     var  applet_submitAction_list     = new Object;  // functions for submitting question with applet
   54     var  applet_setState_list         = new Object;  // functions for setting state (XML) from applets
   55     var  applet_getState_list         = new Object;  // functions for getting state (XML) from applets
   56     var  applet_config_list           = new Object;  // functions for  configuring on applets
   57   var  applet_checkLoaded_list      = new Object;  // functions for probing the applet to see if it is loaded
   58   var  applet_reportsLoaded_list    = new Object;  // flag set by applet
   59   var  applet_isReady_list          = new Object;  // flag set by javaScript in checkLoaded
   60 
   61 //////////////////////////////////////////////////////////
   62 // DEBUGGING tools
   63 //////////////////////////////////////////////////////////
   64   var debug;
   65   var debugText = "";
   66   function set_debug(num) { // setting debug for any applet sets it for all of them
   67     if (num) {
   68       debug =1;
   69     }
   70   }
   71   function debug_add(str) {
   72     if (debug) {
   73       debugText = debugText + "\n\n" +str;
   74     }
   75   }
   76 
   77 //////////////////////////////////////////////////////////
   78 // INITIALIZE and SUBMIT actions
   79 //////////////////////////////////////////////////////////
   80 
   81     function submitAction()  {
   82         //alert("submit Action" );
   83     for (var applet in applet_submitAction_list)  {
   84        //alert(applet);
   85        applet_submitAction_list[applet]();
   86     }
   87 
   88     }
   89     function initializeAction() {
   90         var iMax = 10;
   91         debugText="start intializeAction() with up to " +iMax + " attempts\n";
   92       for (var appletName in applet_initializeAction_list)  {
   93       safe_applet_initialize(appletName, iMax);
   94       }
   95 
   96     }
   97 
   98     // applet can set isReady flag by calling applet_loaded(appletName, loaded);
   99     function applet_loaded(appletName,loaded) {
  100         applet_reportsLoaded_list[appletName] = loaded; // 0 means not loaded
  101       debug_add("applet reporting that it has been loaded = " + loaded );
  102     }
  103 
  104     // insures that applet is loaded before initializing it
  105   function safe_applet_initialize(appletName, i) {
  106     debug_add("Iteration " + i + " of safe_applet_initialize with applet " + appletName );
  107 
  108     i--;
  109     var applet_loaded = applet_checkLoaded_list[appletName]();
  110     debug_add("applet is ready = " + applet_loaded  );
  111 
  112     if ( 0 < i && !applet_loaded ) { // wait until applet is loaded
  113       debug_add("applet " + appletName + "not ready try again");
  114       window.setTimeout( "safe_applet_initialize(\"" + appletName + "\"," + i +  ")",1);
  115     } else if( 0 < i ){  // now that applet is loaded configure it and initialize it with saved data.
  116       debug_add(" Ready to initialize applet " + appletName + " with " + i +  " iterations left. ");
  117 
  118       // in-line handler -- configure and initialize
  119       try{
  120         if (debug && typeof(getApplet(appletName).debug) == "function" ) {
  121           getApplet(appletName).debug(1);
  122         }
  123       } catch(e) {
  124         alert("Unable to set debug mode for applet " + appletName);
  125       }
  126       try{
  127         applet_config_list[appletName]();
  128       } catch(e) {
  129         alert("Unable to configure " + appletName + " \n " +e );
  130       }
  131       try{
  132         applet_initializeAction_list[appletName]();
  133       } catch(e) {
  134         alert("unable to initialize " + appletName + " \n " +e );
  135       }
  136 
  137     } else {
  138       if (debug) {alert("Error: timed out waiting for applet " +appletName + " to load");}
  139     }
  140     if (debug) {alert(debugText); debugText="";};
  141   }
  142 
  143 ///////////////////////////////////////////////////////
  144 // Utility functions
  145 ///////////////////////////////////////////////////////
  146 
  147 
  148   function getApplet(appletName) {
  149       var isIE = navigator.appName.indexOf("Microsoft") != -1;
  150       var obj = (isIE) ? window[appletName] : window.document[appletName];
  151       //return window.document[appletName];
  152       if (obj && (obj.name = appletName)) {
  153         return( obj );
  154       } else {
  155        // alert ("can't find applet " + appletName);
  156       }
  157    }
  158 
  159   function listQuestionElements() { // list all HTML input and textarea elements in main problem form
  160      var isIE = navigator.appName.indexOf("Microsoft") != -1;
  161      var elementList = (isIE) ?  document.getElementsByTagName("input") : document.problemMainForm.getElementsByTagName("input");
  162      var str=elementList.length +" Question Elements\n type | name = value  < id > \n";
  163      for( var i=0; i< elementList.length; i++) {
  164        str = str + " "+i+" " + elementList[i].type
  165                + " | " + elementList[i].name
  166                + "= " + elementList[i].value +
  167                " <" + elementList[i].id + ">\n";
  168      }
  169      elementList = (isIE) ?  document.getElementsByTagName("textarea") : document.problemMainForm.getElementsByTagName("textarea");
  170      for( var i=0; i< elementList.length; i++) {
  171        str = str + " "+i+" " + elementList[i].type
  172                + " | " + elementList[i].name
  173                + "= " + elementList[i].value +
  174                " <" + elementList[i].id + ">\n";
  175      }
  176      alert(str +"\n Place listQuestionElements() at end of document in order to get all form elements!");
  177   }
  178 
  179   function base64Q(str) {
  180     return ( !str.match(/<XML/i) && !str.match(/<?xml/i));
  181   }
  182   function setEmptyState(appletName){
  183     var newState = "<xml></xml>";
  184     applet_setState_list[appletName](newState);
  185     var applet = getApplet(appletName);
  186     getQE(appletName+"_state").value = newState;
  187     getQE("previous_" + appletName + "_state").value = newState
  188   }
  189 
  190   function getQE(name1) { // get Question Element in problemMainForm by name
  191     var isIE = navigator.appName.indexOf("Microsoft") != -1;
  192     var obj = (isIE) ? document.getElementById(name1)
  193               :document.problemMainForm[name1];
  194     // needed for IE -- searches id and name space so it can be unreliable if names are not unique
  195     if (!obj || obj.name != name1) {
  196       alert("Can't find element " + name1);
  197       listQuestionElements();
  198     } else {
  199       return( obj );
  200     }
  201 
  202   }
  203   function getQuestionElement(name1) {
  204     return getQE(name1);
  205   }
  206 
  207  </script>
  208 
  209 END_HEADER_TEXT
  210 
  211 
  212 
  213 =head3
  214   FlashApplet
  215 
  216   Useage:    $applet = FlashApplet();
  217 
  218 =cut
  219 
  220 sub FlashApplet {
  221   return new FlashApplet(@_);
  222 
  223 }
  224 
  225 sub JavaApplet {
  226   return new JavaApplet(@_);
  227 
  228 }
  229 
  230 package Applet;
  231 
  232 
  233 
  234 =head2 Methods
  235 
  236 =cut
  237 
  238 ## this method is defined in this file
  239 ## because the main subroutines HEADER_TEXT and MODES are
  240 ## not available to the module FlashApplet when that file
  241 ## is compiled (at the time the apache child process is first initialized)
  242 
  243 =head3  insertAll
  244 
  245   Useage:   TEXT( $applet->insertAll() );
  246             \{ $applet->insertAll() \}     (used within BEGIN_TEXT/END_TEXT blocks)
  247 
  248 =cut
  249 
  250 =pod
  251 
  252 Inserts applet at this point in the HTML code.  (In TeX mode a message "Applet" is written.)  This method
  253 also adds the applets header material into the header portion of the HTML page. It effectively inserts
  254 the outputs of both C<$applet-E<gt>insertHeader> and C<$applet-E<gt>insertObject> (defined in L<Applet.pm> )
  255 in the appropriate places.
  256 
  257 Note: This method is defined here rather than in Applet.pl because it
  258       requires access to the RECORD_FORM_LABEL subroutine
  259       and to the routine accessing the stored values of the answers.  These are defined in main::.
  260 
  261 =cut
  262 
  263 sub insertAll {  ## inserts both header text and object text
  264   my $self = shift;
  265   my %options = @_;
  266   $self->debug( (defined($options{debug}) and $options{debug}==1) ? 1 : 0 );
  267   my $reset_button = $options{reset_button} || 0;
  268   # prepare html code for storing state
  269   my $appletName      = $self->appletName;
  270   my $appletStateName = "${appletName}_state";
  271   my $getState        = $self->getStateAlias;
  272   my $setState        = $self->setStateAlias;
  273   my $base64_initialState     = $self->base64_state;
  274   main::RECORD_FORM_LABEL($appletStateName);            #this insures that they'll be saved from one invocation to the next
  275   #main::RECORD_FORM_LABEL("previous_$appletStateName");
  276     my $answer_value = '';
  277   $answer_value = ${$main::inputs_ref}{$appletStateName} if defined(${$main::inputs_ref}{$appletStateName});
  278 
  279   if ( defined( $main::rh_sticky_answers->{$appletStateName} ) ) {
  280     $answer_value = shift( @{ $main::rh_sticky_answers->{$appletStateName} });
  281     $answer_value = '' unless defined($answer_value);
  282   }
  283   $answer_value =~ tr/\\$@`//d;   #`## make sure student answers can not be interpolated by e.g. EV3
  284   $answer_value =~ s/\s+/ /g;     ## remove excessive whitespace from student answer
  285 
  286   #######
  287   # insert a hidden variable to hold the applet's state (debug =>1 makes it visible for debugging and provides debugging buttons)
  288   #######
  289   my $base_64_encoded_answer_value = ($answer_value =~/<XML>/i)? encode_base64($answer_value) : $answer_value;
  290   my $decoded_answer_value         = ($answer_value =~/<XML>/i) ? $answer_value : decode_base64($answer_value);
  291     my $debug_input_element  = qq!\n<textarea  rows="4" cols="80"
  292      name = "$appletStateName">$decoded_answer_value</textarea><br/>
  293           <input type="button"  value="$getState"
  294                  onClick="applet_getState_list['$appletName']()"
  295           >
  296           <input type="button"  value="$setState"
  297                  onClick="var tmp = getQE('$appletStateName').value;
  298                           applet_setState_list['$appletName'](tmp);"
  299           >
  300     !;
  301   my $state_input_element = ($self->debug == 1) ? $debug_input_element :
  302         qq!\n<input type="hidden" name = "$appletStateName" value ="$base_64_encoded_answer_value">!;
  303     my $reset_button_str = ($reset_button) ?
  304             qq!<br/><input type='button' value='set applet state empty' onClick="setEmptyState('$appletName')">
  305                     <input type="button" value="reinitialize applet" onClick="getQE('$appletStateName').value='$base64_initialState'"/>!
  306             : ''
  307     ;
  308   # always base64 encode the hidden answer value to prevent problems with quotes.
  309     #
  310   $state_storage_html_code =
  311                       $reset_button_str.
  312                       $state_input_element.
  313                         qq!<input type="hidden"  name="previous_$appletStateName" value = "$base_64_encoded_answer_value">!;
  314     #######
  315     # insert header material
  316     #######
  317   main::HEADER_TEXT($self->insertHeader());
  318     return main::MODES(TeX=>' {\bf  applet } ', HTML=>$self->insertObject.$main::BR.$state_storage_html_code);
  319 }
  320 
  321 =head3 Example problem
  322 
  323 
  324 =cut
  325 
  326 
  327 
  328 =pod
  329 
  330 
  331   DOCUMENT();
  332 
  333   # Load whatever macros you need for the problem
  334   loadMacros("PG.pl",
  335          "PGbasicmacros.pl",
  336          "PGchoicemacros.pl",
  337          "PGanswermacros.pl",
  338          "AppletObjects.pl",
  339          "MathObjects.pl",
  340          "source.pl"
  341         );
  342 
  343   ## Do NOT show partial correct answers
  344   $showPartialCorrectAnswers = 0;
  345 
  346 
  347 
  348   ###################################
  349   # Create  link to applet
  350   ###################################
  351 
  352   $applet = FlashApplet();
  353   my $appletName = "ExternalInterface";
  354   $applet->codebase(findAppletCodebase("$appletName.swf"));
  355   $applet->appletName($appletName);
  356   $applet->appletId($appletName);
  357 
  358   # findAppletCodebase looks for the applet in a list
  359   # of locations specified in global.conf
  360 
  361   ###################################
  362   # Add additional javaScript functions to header section of HTML to
  363   # communicate with the "ExternalInterface" applet.
  364   ###################################
  365 
  366   $applet->header(<<'END_HEADER');
  367   <script type="text/javascript" src="https://devel.webwork.rochester.edu:8002/webwork2_files/js/BrowserSniffer.js">
  368   </script>
  369 
  370 
  371   <script language="JavaScript">
  372     function getBrowser() {
  373         //alert("look for sniffer");
  374       var sniffer = new BrowserSniffer();
  375       //alert("found sniffer" +sniffer);
  376       return sniffer;
  377     }
  378 
  379     function updateStatus(sMessage) {
  380         getQE("playbackStatus").value = sMessage;
  381     }
  382 
  383     function newColor() {
  384 
  385       getApplet("ExternalInterface").updateColor(Math.round(Math.random() * 0xFFFFFF));
  386     }
  387 
  388   </script>
  389   END_HEADER
  390 
  391   ###################################
  392   # Configure applet
  393   ###################################
  394 
  395   # not used here.  Allows for uploading an xml string for the applet
  396 
  397 
  398 
  399 
  400   ###################################
  401   # write the text for the problem
  402   ###################################
  403 
  404   TEXT(beginproblem());
  405 
  406 
  407 
  408   BEGIN_TEXT
  409   \{ $applet->insertAll() \}
  410     $PAR
  411 
  412     The Flash object operates above this line.  The box and button below this line are part of
  413     the WeBWorK problem.  They communicate with the Flash object.
  414     $HR
  415     Status <input type="text" id="playbackStatus" value="started" /><br />
  416     Color <input type="button" value="new color" name="newColorButton" onClick="newColor()" />
  417      $PAR $HR
  418      This flash applet was created by Barbara Kaskosz.
  419 
  420   END_TEXT
  421 
  422   ENDDOCUMENT();
  423 
  424 
  425 
  426 
  427 =cut

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9