[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 5623 - (download) (as text) (annotate)
Tue Mar 25 22:00:23 2008 UTC (11 years, 5 months ago) by gage
File size: 11620 byte(s)
corrected typos in setState macros.

    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.4 2008/03/16 14:39: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     var  applet_initializeAction_list = new Object;
   48     var  applet_submitAction_list     = new Object;
   49     var  applet_setState_list         = new Object;
   50     var  applet_getState_list         = new Object;
   51     var  applet_config_list           = new Object;
   52 
   53 
   54     function base64Q(str) {
   55       return !str.match(/<XML/i && !str.match(/<?xml/i));
   56     }
   57 
   58     function submitAction()  {
   59         //alert("submit Action" );
   60     for (var applet in applet_submitAction_list)  {
   61        //alert(applet);
   62        applet_submitAction_list[applet]();
   63     }
   64 
   65     }
   66     // Give some time delay before initializing
   67     function initializeAction() {
   68       //alert("ready to initialize");
   69       // give some delay to allow flash applet to load.  FIXME
   70       window.setTimeout("initializeAction1()",200);
   71       //initializeAction1();
   72     }
   73     function initializeAction1() {
   74 
   75       for (var appletName in applet_initializeAction_list)  {
   76         //alert("initialize: " + appletName);
   77         try{
   78             applet_config_list[appletName]();
   79         } catch(e) {
   80           alert("unable to configure " + appletName + " It may have been slow to load. " +e );
   81         }
   82         try{
   83           applet_initializeAction_list[appletName]();
   84         } catch(e) {
   85           alert("unable to initialize " + appletName + " It may have been slow to load. " +e );
   86         }
   87       }
   88     }
   89 
   90 
   91   var flash;
   92   function getApplet(appletName) {
   93       var isIE = navigator.appName.indexOf("Microsoft") != -1;
   94       var obj = (isIE) ? window[appletName] : window.document[appletName];
   95       //return window.document[appletName];
   96       if (obj && (obj.name = appletName)) {
   97           return( obj );
   98       } else {
   99          alert ("can't find applet " + appletName);
  100       }
  101    }
  102 
  103     function listQuestionElements() { // list all HTML input and textarea elements in main problem form
  104        var isIE = navigator.appName.indexOf("Microsoft") != -1;
  105        var elementList = (isIE) ?  document.getElementsByTagName("input") : document.problemMainForm.getElementsByTagName("input");
  106        var str=elementList.length +" Question Elements\n type | name = value  < id > \n";
  107        for( var i=0; i< elementList.length; i++) {
  108            str = str + " "+i+" " + elementList[i].type
  109                            + " | " + elementList[i].name
  110                            + "= " + elementList[i].value +
  111                            " <" + elementList[i].id + ">\n";
  112        }
  113        elementList = (isIE) ?  document.getElementsByTagName("textarea") : document.problemMainForm.getElementsByTagName("textarea");
  114        for( var i=0; i< elementList.length; i++) {
  115            str = str + " "+i+" " + elementList[i].type
  116                            + " | " + elementList[i].name
  117                            + "= " + elementList[i].value +
  118                            " <" + elementList[i].id + ">\n";
  119        }
  120        alert(str +"\n Place listQuestionElements() at end of document in order to get all form elements!");
  121    }
  122 
  123     function getQE(name1) { // get Question Element in problemMainForm by name
  124         var isIE = navigator.appName.indexOf("Microsoft") != -1;
  125       var obj = (isIE) ? document.getElementById(name1)
  126                           :document.problemMainForm[name1];
  127       // needed for IE -- searches id and name space so it can be unreliable if names are not unique
  128       if (!obj || obj.name != name1) {
  129           alert("Can't find element " + name1);
  130         listQuestionElements();
  131       } else {
  132         return( obj );
  133       }
  134 
  135     }
  136     function getQuestionElement(name1) {
  137       return getQE(name1);
  138     }
  139 
  140  </script>
  141 
  142 END_HEADER_TEXT
  143 
  144 
  145 
  146 =head3
  147   FlashApplet
  148 
  149   Useage:    $applet = FlashApplet();
  150 
  151 =cut
  152 
  153 sub FlashApplet {
  154   return new FlashApplet(@_);
  155 
  156 }
  157 
  158 sub JavaApplet {
  159   return new JavaApplet(@_);
  160 
  161 }
  162 
  163 package Applet;
  164 
  165 
  166 
  167 =head2 Methods
  168 
  169 =cut
  170 
  171 ## this method is defined in this file
  172 ## because the main subroutines HEADER_TEXT and MODES are
  173 ## not available to the module FlashApplet when that file
  174 ## is compiled (at the time the apache child process is first initialized)
  175 
  176 =head3  insertAll
  177 
  178   Useage:   TEXT( $applet->insertAll() );
  179             \{ $applet->insertAll() \}     (used within BEGIN_TEXT/END_TEXT blocks)
  180 
  181 =cut
  182 
  183 =pod
  184 
  185 Inserts applet at this point in the HTML code.  (In TeX mode a message "Applet" is written.)  This method
  186 also adds the applets header material into the header portion of the HTML page. It effectively inserts
  187 the outputs of both C<$applet-E<gt>insertHeader> and C<$applet-E<gt>insertObject> (defined in L<Applet.pm> )
  188 in the appropriate places.
  189 
  190 Note: This method is defined here rather than in Applet.pl because it
  191       requires access to the RECORD_FORM_LABEL subroutine
  192       and to the routine accessing the stored values of the answers.  These are defined in main::.
  193 
  194 =cut
  195 
  196 sub insertAll {  ## inserts both header text and object text
  197   my $self = shift;
  198   my %options = @_;
  199   $self->debug( (defined($options{debug}) and $options{debug}==1) ? 1 : 0 );
  200   my $reset_button = $options{reset_button} || 0;
  201   # prepare html code for storing state
  202   my $appletName      = $self->appletName;
  203   my $appletStateName = "${appletName}_state";
  204   my $getState        = $self->getStateAlias;
  205   my $setState        = $self->setStateAlias;
  206   my $base64_initialState     = $self->base64_state;
  207   main::RECORD_FORM_LABEL($appletStateName);            #this insures that they'll be saved from one invocation to the next
  208   #main::RECORD_FORM_LABEL("previous_$appletStateName");
  209     my $answer_value = '';
  210   $answer_value = ${$main::inputs_ref}{$appletStateName} if defined(${$main::inputs_ref}{$appletStateName});
  211 
  212   if ( defined( $main::rh_sticky_answers->{$appletStateName} ) ) {
  213     $answer_value = shift( @{ $main::rh_sticky_answers->{$appletStateName} });
  214     $answer_value = '' unless defined($answer_value);
  215   }
  216   $answer_value =~ tr/\\$@`//d;   #`## make sure student answers can not be interpolated by e.g. EV3
  217   $answer_value =~ s/\s+/ /g;     ## remove excessive whitespace from student answer
  218 
  219   #######
  220   # insert a hidden variable to hold the applet's state (debug =>1 makes it visible for debugging and provides debugging buttons)
  221   #######
  222   my $base_64_encoded_answer_value = ($answer_value =~/<XML>/i)? encode_base64($answer_value) : $answer_value;
  223   my $decoded_answer_value         = ($answer_value =~/<XML>/i) ? $answer_value : decode_base64($answer_value);
  224     my $debug_input_element  = qq!\n<textarea  rows="4" cols="80"
  225      name = "$appletStateName">$decoded_answer_value</textarea><br/>
  226           <input type="button"  value="$getState"
  227                  onClick="applet_getState_list['$appletName']()"
  228           >
  229           <input type="button"  value="$setState"
  230                  onClick="var tmp = getQE('$appletStateName').value;
  231                           applet_setState_list['$appletName'](tmp);"
  232           >
  233     !;
  234   my $state_input_element = ($self->debug == 1) ? $debug_input_element :
  235         qq!\n<input type="hidden" name = "$appletStateName" value ="$base_64_encoded_answer_value">!;
  236     my $reset_button_str = ($reset_button) ?
  237             qq!<br/><input type='button' value='reset applet' onClick="applet_setState_list['$appletName']('<xml></xml>')">!
  238             : ''
  239     ;
  240   # always base64 encode the hidden answer value to prevent problems with quotes.
  241     #
  242   $state_storage_html_code =
  243                       $reset_button_str.
  244                       $state_input_element.
  245                         qq!<input type="hidden"  name="previous_$appletStateName" value = "$base_64_encoded_answer_value">!;
  246     #######
  247     # insert header material
  248     #######
  249   main::HEADER_TEXT($self->insertHeader());
  250     return main::MODES(TeX=>' {\bf  applet } ', HTML=>$self->insertObject.$main::BR.$state_storage_html_code);
  251 }
  252 
  253 =head3 Example problem
  254 
  255 
  256 =cut
  257 
  258 
  259 
  260 =pod
  261 
  262 
  263   DOCUMENT();
  264 
  265   # Load whatever macros you need for the problem
  266   loadMacros("PG.pl",
  267          "PGbasicmacros.pl",
  268          "PGchoicemacros.pl",
  269          "PGanswermacros.pl",
  270          "AppletObjects.pl",
  271          "MathObjects.pl",
  272          "source.pl"
  273         );
  274 
  275   ## Do NOT show partial correct answers
  276   $showPartialCorrectAnswers = 0;
  277 
  278 
  279 
  280   ###################################
  281   # Create  link to applet
  282   ###################################
  283 
  284   $applet = FlashApplet();
  285   my $appletName = "ExternalInterface";
  286   $applet->codebase(findAppletCodebase("$appletName.swf"));
  287   $applet->appletName($appletName);
  288   $applet->appletId($appletName);
  289 
  290   # findAppletCodebase looks for the applet in a list
  291   # of locations specified in global.conf
  292 
  293   ###################################
  294   # Add additional javaScript functions to header section of HTML to
  295   # communicate with the "ExternalInterface" applet.
  296   ###################################
  297 
  298   $applet->header(<<'END_HEADER');
  299   <script type="text/javascript" src="https://devel.webwork.rochester.edu:8002/webwork2_files/js/BrowserSniffer.js">
  300   </script>
  301 
  302 
  303   <script language="JavaScript">
  304     function getBrowser() {
  305         //alert("look for sniffer");
  306       var sniffer = new BrowserSniffer();
  307       //alert("found sniffer" +sniffer);
  308       return sniffer;
  309     }
  310 
  311     function updateStatus(sMessage) {
  312         getQE("playbackStatus").value = sMessage;
  313     }
  314 
  315     function newColor() {
  316 
  317       getApplet("ExternalInterface").updateColor(Math.round(Math.random() * 0xFFFFFF));
  318     }
  319 
  320   </script>
  321   END_HEADER
  322 
  323   ###################################
  324   # Configure applet
  325   ###################################
  326 
  327   # not used here.  Allows for uploading an xml string for the applet
  328 
  329 
  330 
  331 
  332   ###################################
  333   # write the text for the problem
  334   ###################################
  335 
  336   TEXT(beginproblem());
  337 
  338 
  339 
  340   BEGIN_TEXT
  341   \{ $applet->insertAll() \}
  342     $PAR
  343 
  344     The Flash object operates above this line.  The box and button below this line are part of
  345     the WeBWorK problem.  They communicate with the Flash object.
  346     $HR
  347     Status <input type="text" id="playbackStatus" value="started" /><br />
  348     Color <input type="button" value="new color" name="newColorButton" onClick="newColor()" />
  349      $PAR $HR
  350      This flash applet was created by Barbara Kaskosz.
  351 
  352   END_TEXT
  353 
  354   ENDDOCUMENT();
  355 
  356 
  357 
  358 
  359 =cut

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9