[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 5618 - (download) (as text) (annotate)
Sun Mar 16 14:39:14 2008 UTC (11 years, 6 months ago) by gage
File size: 11566 byte(s)
New version of Applet.pm and AppletObjects.pl that supports both flash
new FlashApplet();
and java applets
new JavaApplet();

see pod docs in those two files for more details.

    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.3 2008/01/03 15:17:40 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);
   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           <input type="button"  value="setState"
  229                  onClick="applet_setState_list['$appletName']();
  230                    var tmp = getQE('$appletStateName').value;">
  231     !;
  232   my $state_input_element = ($self->debug == 1) ? $debug_input_element :
  233         qq!\n<input type="hidden" name = "$appletStateName" value ="$base_64_encoded_answer_value">!;
  234     my $reset_button_str = ($reset_button) ?
  235             qq!<br/><input type='button' value='reset applet' onClick="applet_setState_list['$appletName']('<xml></xml>')">!
  236             : ''
  237     ;
  238   # always base64 encode the hidden answer value to prevent problems with quotes.
  239     #
  240   $state_storage_html_code =
  241                       $reset_button_str.
  242                       $state_input_element.
  243                         qq!<input type="hidden"  name="previous_$appletStateName" value = "$base_64_encoded_answer_value">!;
  244     #######
  245     # insert header material
  246     #######
  247   main::HEADER_TEXT($self->insertHeader());
  248     return main::MODES(TeX=>' {\bf  applet } ', HTML=>$self->insertObject.$main::BR.$state_storage_html_code);
  249 }
  250 
  251 =head3 Example problem
  252 
  253 
  254 =cut
  255 
  256 
  257 
  258 =pod
  259 
  260 
  261   DOCUMENT();
  262 
  263   # Load whatever macros you need for the problem
  264   loadMacros("PG.pl",
  265          "PGbasicmacros.pl",
  266          "PGchoicemacros.pl",
  267          "PGanswermacros.pl",
  268          "AppletObjects.pl",
  269          "MathObjects.pl",
  270          "source.pl"
  271         );
  272 
  273   ## Do NOT show partial correct answers
  274   $showPartialCorrectAnswers = 0;
  275 
  276 
  277 
  278   ###################################
  279   # Create  link to applet
  280   ###################################
  281 
  282   $applet = FlashApplet();
  283   my $appletName = "ExternalInterface";
  284   $applet->codebase(findAppletCodebase("$appletName.swf"));
  285   $applet->appletName($appletName);
  286   $applet->appletId($appletName);
  287 
  288   # findAppletCodebase looks for the applet in a list
  289   # of locations specified in global.conf
  290 
  291   ###################################
  292   # Add additional javaScript functions to header section of HTML to
  293   # communicate with the "ExternalInterface" applet.
  294   ###################################
  295 
  296   $applet->header(<<'END_HEADER');
  297   <script type="text/javascript" src="https://devel.webwork.rochester.edu:8002/webwork2_files/js/BrowserSniffer.js">
  298   </script>
  299 
  300 
  301   <script language="JavaScript">
  302     function getBrowser() {
  303         //alert("look for sniffer");
  304       var sniffer = new BrowserSniffer();
  305       //alert("found sniffer" +sniffer);
  306       return sniffer;
  307     }
  308 
  309     function updateStatus(sMessage) {
  310         getQE("playbackStatus").value = sMessage;
  311     }
  312 
  313     function newColor() {
  314 
  315       getApplet("ExternalInterface").updateColor(Math.round(Math.random() * 0xFFFFFF));
  316     }
  317 
  318   </script>
  319   END_HEADER
  320 
  321   ###################################
  322   # Configure applet
  323   ###################################
  324 
  325   # not used here.  Allows for uploading an xml string for the applet
  326 
  327 
  328 
  329 
  330   ###################################
  331   # write the text for the problem
  332   ###################################
  333 
  334   TEXT(beginproblem());
  335 
  336 
  337 
  338   BEGIN_TEXT
  339   \{ $applet->insertAll() \}
  340     $PAR
  341 
  342     The Flash object operates above this line.  The box and button below this line are part of
  343     the WeBWorK problem.  They communicate with the Flash object.
  344     $HR
  345     Status <input type="text" id="playbackStatus" value="started" /><br />
  346     Color <input type="button" value="new color" name="newColorButton" onClick="newColor()" />
  347      $PAR $HR
  348      This flash applet was created by Barbara Kaskosz.
  349 
  350   END_TEXT
  351 
  352   ENDDOCUMENT();
  353 
  354 
  355 
  356 
  357 =cut

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9