[system] / trunk / pg / lib / Applet.pm Repository:
ViewVC logotype

View of /trunk/pg/lib/Applet.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5994 - (download) (as text) (annotate)
Sat Feb 7 22:28:34 2009 UTC (10 years, 9 months ago) by gage
File size: 26297 byte(s)
Reworked support code for applets to use a more object oriented approach.

    1 ################################################################################
    2 # WeBWorK Online Homework Delivery System
    3 # Copyright  2000-2007 The WeBWorK Project, http://openwebwork.sf.net/
    4 # $CVSHeader: pg/lib/Applet.pm,v 1.14 2009/01/28 17:07:08 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 Applet.pl - Provides code for inserting FlashApplets and JavaApplets into webwork problems
   20 
   21 =head1 SYNPOSIS
   22 
   23   ###################################
   24   # Create  link to applet
   25   ###################################
   26   my $appletName = "LineThruPointsWW";
   27   $applet = new FlashApplet(
   28      # can be replaced by $applet =FlashApplet() when using AppletObjects.pl
   29      codebase   => findAppletCodebase("$appletName.swf"),
   30      appletName => $appletName,
   31      appletId   => $appletName,
   32      submitActionAlias => 'checkAnswer',
   33   );
   34 
   35   ###################################
   36   # Configure applet
   37   ###################################
   38 
   39   #xml data to set up the problem-rac
   40   $applet->config(qq{<XML>
   41   <point xval='$xval_1' yval='$yval_1' />
   42   <point xval='$xval_2' yval='$yval_2' />
   43   </XML>});
   44 
   45 
   46   ###################################
   47   # insert applet header material
   48   ###################################
   49   HEADER_TEXT($applet->insertHeader );
   50 
   51   ###################################
   52   # Text section
   53   #
   54 
   55   ###################################
   56   #insert applet into body
   57   ###################################
   58   TEXT( MODES(TeX=>'object code', HTML=>$applet->insertObject));
   59 
   60 
   61 =head1 DESCRIPTION
   62 
   63 This file provides an object to store in one place
   64 all of the information needed to call an applet.
   65 
   66 The object FlashApplet has defaults for inserting flash applets.
   67 
   68 =over
   69 
   70 =item *
   71 
   72 =item *
   73 
   74 =back
   75 
   76 (not yet completed)
   77 
   78 The module JavaApplet has defaults for inserting java applets.
   79 
   80 The module Applet stores common code for the two types of applet.
   81 
   82 =head1 USAGE
   83 
   84 These modules are activate by listing it in the modules section of global.conf and rebooting the server.
   85 The companion file to this one is macros/AppletObjects.pl
   86 
   87 qw(Applet FlashApplet JavaApplet)
   88 
   89 =cut
   90 
   91 
   92 
   93 package Applet;
   94 
   95 use URI::Escape;
   96 
   97 
   98 
   99 use MIME::Base64 qw( encode_base64 decode_base64);
  100 
  101 
  102 =head2 Default javaScript functions placed in header
  103 
  104 =pod
  105 
  106 These functions are automatically defined for use for
  107 any javaScript placed in the text of a PG question.
  108 
  109     getApplet(appletName)  -- finds the applet path in the DOM
  110 
  111     submitAction()            -- calls the submit action of the applets
  112 
  113     initializeWWquestion()        -- calls the initialize action of the applets
  114 
  115     getQE(name)               -- gets an HTML element of the question by name
  116                                  or by id.  Be sure to keep all names and ids
  117                                  unique within a given PG question.
  118 
  119     getQuestionElement(name)  -- long form of getQE(name)
  120 
  121     listQuestionElements()    -- for discovering the names of inputs in the
  122                                  PG question.  An alert dialog will list all
  123                                  of the elements.
  124       Usage: Place this at the END of the question, just before END_DOCUMENT():
  125 
  126                 TEXT(qq!<script> listQuestionElements() </script>!);
  127                 ENDDOCUMENT();
  128              to obtain a list of all of the HTML elements in the question
  129 
  130     List of  accessor methods made available by the FlashApplet class:
  131         Usage:  $current_value = $applet->method(new_value or empty)
  132         These can also be set when creating the class -- for exampe:
  133              $applet = new FlashApplet(
  134                        # can be replaced by $applet =FlashApplet() when using AppletObjects.pl
  135                        codebase   => findAppletCodebase("$appletName.swf"),
  136                        appletName => $appletName,
  137                        appletId   => $appletName,
  138                        submitActionAlias => 'checkAnswer',
  139             );
  140 
  141 
  142         appletId         for simplicity and reliability appletId and appletName are always the same
  143         appletName
  144         archive      the name of the .jar file containing the applet code
  145         code         the name of the applet code in the .jar archive
  146         codebase     a prefix url used to find the archive and the applet itself
  147 
  148         height       rectangle alloted in the html page for displaying the applet
  149 
  150         params       an anonymous array containing name/value pairs
  151                      to configure the applet [name =>'value, ...]
  152 
  153         header       stores the text to be added to the header section of the html page
  154         object       stores the text which places the applet on the html page
  155 
  156         debug        in debug mode several alerts mark progress through the procedure of calling the applet
  157 
  158         config       configuration are those customizable attributes of the applet which don't
  159                      change as it is used.  When stored in hidden answer fields
  160                      it is usually stored in base64 encoded format.
  161         base64_config base64 encode version of the contents of config
  162 
  163         configAlias  (default: config ) names the applet command called with the contents of $self->config
  164                      to configure the applet.  The parameters are passed to the applet in plain text using <xml>
  165                      The outer tags must be   <xml> .....   </xml>
  166         state        state consists of those customizable attributes of the applet which change
  167                      as the applet is used.  It is stored by the calling .pg question so that
  168                      when revisiting the question the applet
  169                      will be restored to the same state it was left in when the question was last
  170                      viewed.
  171 
  172         getStateAlias  (default: getState) alias for command called to read the current state of the applet.
  173                        The state is passed in plain text xml format with outer tags: <xml>....</xml>
  174         setStateAlias  (default: setState) alias for the command called to reset the  state of the applet.
  175                        The state is passed in plain text in xml format with outer tags: <xml>....</xml>
  176 
  177         base64_state   returns the base64 encoded version of the state stored in the applet object.
  178 
  179         initializeActionAlias  -- (default: initializeAction) the name of the javaScript subroutine called to initialize the applet (some overlap with config/ and setState
  180         submitActionAlias      -- (default: submitAction)the name of the javaScript subroutine called when the submit button of the
  181                                   .pg question is pressed.
  182         answerBox              -- name of answer box to return answer to: default defaultAnswerBox
  183         getAnswer              -- (formerly sendData) get student answer from applet and place in answerBox
  184         returnFieldName        -- (deprecated) synonmym for answerBox
  185 
  186 
  187 =cut
  188 
  189 
  190 
  191 
  192 sub new {
  193    my $class = shift;
  194    my $self = {
  195     appletName =>'',
  196     code=>'',
  197     codebase=>'',
  198 #   appletId  =>'',   #always use identical applet Id's and applet Names
  199     params    =>undef,
  200     width     => 550,
  201     height    => 400,
  202     base64_state       =>  undef,     # this is an state to use for initializing the first occurence of the question.
  203     base64_config      =>  undef,     # this is the initial (and final?) configuration
  204     getStateAlias      =>  'getXML',
  205     setStateAlias      =>  'setXML',
  206     configAlias        =>  'config',
  207     initializeActionAlias => 'setXML',
  208     submitActionAlias  =>  'getXML',
  209     submitActionScript  =>  '',        # script executed on submitting the WW question
  210     answerBox          =>  'answerBox',
  211     headerText         =>  DEFAULT_HEADER_TEXT(),
  212     objectText         => '',
  213     debug              => 0,
  214     @_,
  215   };
  216   bless $self, $class;
  217   $self->state('<xml></xml>');
  218   $self->config('<xml></xml>');
  219   return $self;
  220 }
  221 
  222 sub  header {
  223   my $self = shift;
  224   if ($_[0] eq "reset") {  # $applet->header('reset');  erases default header text.
  225     $self->{headerText}='';
  226   } else {
  227     $self->{headerText} .= join("",@_);  # $applet->header(new_text); concatenates new_text to existing header.
  228   }
  229     $self->{headerText};
  230 }
  231 sub  object {
  232   my $self = shift;
  233   if ($_[0] eq "reset") {
  234     $self->{objectText}='';
  235   } else {
  236     $self->{objectText} .= join("",@_);
  237   }
  238     $self->{objectText};
  239 }
  240 sub params {
  241   my $self = shift;
  242   if (ref($_[0]) =~/HASH/) {
  243     $self->{params} = shift;
  244   } elsif ( !defined($_[0]) or $_[0] =~ '') {
  245     # do nothing (read)
  246   } else {
  247     warn "You must enter a reference to a hash for the parameter list";
  248   }
  249   $self->{params};
  250 }
  251 
  252 sub initializeActionAlias {
  253   my $self = shift;
  254   $self->{initializeActionAlias} = shift ||$self->{initializeActionAlias}; # replace the current contents if non-empty
  255     $self->{initializeActionAlias};
  256 }
  257 
  258 sub submitActionAlias {
  259   my $self = shift;
  260   $self->{submitActionAlias} = shift ||$self->{submitActionAlias}; # replace the current contents if non-empty
  261     $self->{submitActionAlias};
  262 }
  263 sub submitActionScript {
  264   my $self = shift;
  265   $self->{submitActionScript} = shift ||$self->{submitActionScript}; # replace the current contents if non-empty
  266     $self->{submitActionScript};
  267 }
  268 sub getStateAlias {
  269   my $self = shift;
  270   $self->{getStateAlias} = shift ||$self->{getStateAlias}; # replace the current contents if non-empty
  271     $self->{getStateAlias};
  272 }
  273 
  274 sub setStateAlias {
  275   my $self = shift;
  276   $self->{setStateAlias} = shift ||$self->{setStateAlias}; # replace the current contents if non-empty
  277     $self->{setStateAlias};
  278 }
  279 sub configAlias {
  280   my $self = shift;
  281   $self->{configAlias} = shift ||$self->{configAlias}; # replace the current contents if non-empty
  282     $self->{configAlias};
  283 }
  284 sub returnFieldName {
  285   my $self = shift;
  286   $self->{answerBox} = shift ||$self->{answerBox}; # replace the current contents if non-empty
  287     $self->{answerBox};
  288 }
  289 sub answerBox {
  290   my $self = shift;
  291   $self->{answerBox} = shift ||$self->{answerBox}; # replace the current contents if non-empty
  292     $self->{answerBox};
  293 }
  294 sub codebase {
  295   my $self = shift;
  296   $self->{codebase} = shift ||$self->{codebase}; # replace the current codebase if non-empty
  297     $self->{codebase};
  298 }
  299 sub code {
  300   my $self = shift;
  301   $self->{code} = shift ||$self->{code}; # replace the current code if non-empty
  302     $self->{code};
  303 }
  304 sub height {
  305   my $self = shift;
  306   $self->{height} = shift ||$self->{height}; # replace the current height if non-empty
  307     $self->{height};
  308 }
  309 sub width {
  310   my $self = shift;
  311   $self->{width} = shift ||$self->{width}; # replace the current width if non-empty
  312     $self->{width};
  313 }
  314 sub archive {
  315   my $self = shift;
  316   $self->{archive} = shift ||$self->{archive}; # replace the current archive if non-empty
  317     $self->{archive};
  318 }
  319 sub appletName {
  320   my $self = shift;
  321   $self->{appletName} = shift ||$self->{appletName}; # replace the current appletName if non-empty
  322     $self->{appletName};
  323 }
  324 sub debug {
  325   my $self = shift;
  326   my $new_flag = shift;
  327   $self->{debug} = $new_flag if defined($new_flag);
  328   $self->{debug};
  329 }
  330 sub appletId {
  331   appletName(@_);
  332 }
  333 sub state {
  334   my $self = shift;
  335   my $str = shift;
  336   $self->{base64_state} =  encode_base64($str)   ||$self->{base64_state}; # replace the current string if non-empty
  337   $self->{base64_state} =~ s/\n//g;
  338     decode_base64($self->{base64_state});
  339 }
  340 
  341 sub base64_state{
  342   my $self = shift;
  343   $self->{base64_state} = shift ||$self->{base64_state}; # replace the current string if non-empty
  344     $self->{base64_state};
  345 }
  346 sub config {
  347   my $self = shift;
  348   my $str = shift;
  349   $self->{base64_config} =  encode_base64($str)   || $self->{base64_config}; # replace the current string if non-empty
  350   $self->{base64_config} =~ s/\n//g;
  351     decode_base64($self->{base64_config});
  352 }
  353 sub base64_config {
  354   my $self = shift;
  355   $self->{base64_config} = shift ||$self->{base64_config}; # replace the current string if non-empty
  356   $self->{base64_config} =$self->{base64_config};
  357     $self->{base64_config};
  358 }
  359 #FIXME
  360 # need to be able to adjust header material
  361 
  362 sub insertHeader {
  363     my $self = shift;
  364     my $codebase         =  $self->codebase;
  365     my $appletId         =  $self->appletId;
  366     my $appletName       =  $self->appletName;
  367     my $base64_initialState     = $self->base64_state;
  368     my $initializeAction =  $self->initializeActionAlias;
  369     my $submitAction     =  $self->submitActionAlias;
  370     my $submitActionScript = $self->submitActionScript;
  371     my $setState         =  $self->setStateAlias;
  372     my $getState         =  $self->getStateAlias;
  373     my $config           =  $self->configAlias;
  374     my $base64_config    =  $self->base64_config;
  375     my $debugMode        =  ($self->debug) ? "1": "0";
  376     my $returnFieldName  =  $self->{returnFieldName};
  377     my $answerBox        =  $self->{answerBox};
  378     my $headerText       =  $self->header();
  379 
  380     $headerText =~ s/(\$\w+)/$1/gee;   # interpolate variables p17 of Cookbook
  381 
  382     return $headerText;
  383 
  384 
  385 }
  386 
  387 sub insertObject {
  388     my $self       = shift;
  389     my $code       = $self->{code};
  390     my $codebase   = $self->{codebase};
  391     my $appletId   = $self->{appletName};
  392     my $appletName = $self->{appletName};
  393     my $archive    = $self->{archive};
  394     my $width      = $self->{width};
  395     my $height     = $self->{height};
  396     my $javaParameters = '';
  397     my $flashParameters = '';
  398     my %param_hash = %{$self->params()};
  399     foreach my $key (keys %param_hash) {
  400       $javaParameters .= qq!<param name ="$key"  value = "$param_hash{$key}">\n!;
  401       $flashParameters .= uri_escape($key).'='.uri_escape($param_hash{$key}).'&';
  402     }
  403     $flashParameters =~ s/\&$//;    # trim last &
  404 
  405 
  406     $objectText = $self->{objectText};
  407     $objectText =~ s/(\$\w+)/$1/gee;
  408     return $objectText;
  409 }
  410 # sub initialize  {
  411 #     my $self = shift;
  412 #   return q{
  413 #     <script>
  414 #       initializeAllApplets();
  415 #       // this should really be done in the <body> tag
  416 #     </script>
  417 #   };
  418 #
  419 # }
  420 ########################################################
  421 # HEADER material for one flash or java applet
  422 ########################################################
  423 
  424 use constant DEFAULT_HEADER_TEXT =><<'END_HEADER_SCRIPT';
  425     <script src="/webwork2_files/js/Base64.js" language="javascript">
  426     </script>
  427     <script src="/webwork2_files/js/ww_applet_support.js">
  428         //upload functions stored in /opt/webwork/webwork2/htdocs/js ...
  429      </script>
  430   <script language="JavaScript">
  431 
  432   // set debug mode for this applet
  433     set_debug($debugMode);
  434 
  435     //////////////////////////////////////////////////////////
  436   //TEST code
  437   //
  438     //
  439     //////////////////////////////////////////////////////////
  440 
  441     ww_applet_list["$appletName"] = new ww_applet("$appletName");
  442 
  443 
  444   ww_applet_list["$appletName"].code = "$code";
  445   ww_applet_list["$appletName"].codebase = "$codebase";
  446     ww_applet_list["$appletName"].appletID = "$appletID";
  447   ww_applet_list["$appletName"].base64_state = "$base64_initializationState";
  448   ww_applet_list["$appletName"].base64_config = "$base64_config";
  449   ww_applet_list["$appletName"].getStateAlias = "$getState";
  450   ww_applet_list["$appletName"].setStateAlias = "$setState";
  451   ww_applet_list["$appletName"].configAlias   = "$config";
  452   ww_applet_list["$appletName"].initializeActionAlias = "$initializeAction";
  453   ww_applet_list["$appletName"].submitActionAlias = "$submitAction";
  454   ww_applet_list["$appletName"].submitActionScript = "$submitActionScript";
  455   ww_applet_list["$appletName"].answerBox = "$answerBox";
  456   ww_applet_list["$appletName"].debug = "$debugMode";
  457 
  458 
  459   //////////////////////////////////////////////////////////
  460   //CONFIGURATIONS
  461   //
  462     // configurations are "permanent"
  463     //////////////////////////////////////////////////////////
  464 
  465 //     applet_config_list["$appletName"]   = function() {
  466 //         debug_add("applet_config_list:\n attempt to configure $appletName . $config ( $base64_config ) if config function is defined: "
  467 //         );
  468 //      try {
  469 //          if (( typeof(getApplet("$appletName").$config)  == "function" ) ) {
  470 //              debug_add("CONFIGURE $appletName");
  471 //          getApplet("$appletName").$config(Base64.decode("$base64_config"));
  472 //        }
  473 //      } catch(e) {
  474 //        alert("Error executing configuration command $config for $appletName: " + e );
  475 //      }
  476 //     }
  477 //     ////////////////////////////////////////////////////////////
  478 //     //
  479 //     //STATE:
  480 //     // state can vary as the applet is manipulated -- it is reset from the questions _state values
  481 //     //
  482 //     //////////////////////////////////////////////////////////
  483 //
  484 //     applet_setState_list["$appletName"] = function(state) {
  485 //    debug_add("Begin setState for applet $appletName");
  486 //    debug_add("Obtain state from $appletName"+"_state");
  487 //    state =  state || getQE("$appletName"+"_state").value;
  488 //    if ( base64Q(state) ) {
  489 //      state=Base64.decode(state);
  490 //    }
  491 //    if (state.match(/<xml/i) || state.match(/<?xml/i) ) {  // if state starts with <?xml
  492 //
  493 //      debug_add("applet_setState_list: \n set (decoded) state for $appletName to " +
  494 //           state +"\nfunction type is " +typeof(getApplet("$appletName").$setState)
  495 //      );
  496 //      try {
  497 //      if (( typeof(getApplet("$appletName").$setState)  =="function" ) ) {
  498 //        debug_add("setState for $appletName");
  499 //        getApplet("$appletName").$setState( state );
  500 //      }
  501 //      } catch(e) {
  502 //      alert("Error in setting state of $appletName using command $setState : " + e );
  503 //      }
  504 //    } else if (debug) {
  505 //      alert("new state was empty string or did not begin with <xml-- state was not reset");
  506 //    }
  507 //  };
  508 //  applet_getState_list["$appletName"] = function () {
  509 //    debug_add("get current state for applet $appletName and store it in $appletName"+"_state");
  510 //    var applet = getApplet("$appletName");
  511 //    try {
  512 //      if (( typeof(applet.$getState)  == "function" ) ) {  // there may be no state function
  513 //        state  = applet.$getState();                     // get state in xml format
  514 //        debug_add("state has type " + typeof(state));
  515 //        state  = String(state);                          // geogebra returned an object type instead of a string type
  516 //        debug_add("state converted to type " + typeof(state));
  517 //      }
  518 //
  519 //      if (!debug) {
  520 //        state = Base64.encode(state);
  521 //      };   // replace state by encoded version unless in debug mode
  522 //
  523 //      debug_add("state is "+state);                  // this should still be in plain text
  524 //      getQE("$appletName"+"_state").value = state;   //place state in input item (debug: textarea, otherwise: hidden)
  525 //    } catch (e) {
  526 //      alert("Error in getting state for $appletName " + e );
  527 //    }
  528 //     };
  529 //
  530 //     ////////////////////////////////////////////////////////////
  531 //     //
  532 //     //INITIALIZE
  533 //     //
  534 //     ////////////////////////////////////////////////////////////
  535 //
  536 //
  537 //     applet_checkLoaded_list["$appletName"] = function() { // this function returns 0 unless:
  538 //                                                       // applet has already been flagged as ready in applet_isReady_list
  539 //                                                       // applet.config is defined  (or alias for .config)
  540 //                                                       // applet.setState is defined
  541 //                                                       // applet.isActive is defined
  542 //                                                       // applet reported that it is loaded by calling loadQ()
  543 //      var ready = 0;
  544 //      var applet = getApplet("$appletName");
  545 //          if (!debug && applet_isReady_list["$appletName"]) {return(1)}; // memorize readiness in non-debug mode
  546 //        if ( typeof(applet.$config) == "function") {
  547 //            debug_add( "applet.config is " + typeof(applet.$config) );
  548 //          ready = 1;
  549 //        }
  550 //        if( typeof(applet.$getState) == "function") {
  551 //            debug_add( "applet.getState is " + typeof(applet.$getState) );
  552 //          ready =1;
  553 //        }
  554 //        if (typeof(applet.isActive) == "function" && applet.isActive ) {
  555 //          debug_add( "applet.isActive is " + typeof(applet.isActive) );
  556 //          ready =1;
  557 //        }
  558 //        if (typeof(applet_reportsLoaded_list["$appletName"]) !="undefined" && applet_reportsLoaded_list["$appletName"] != 0 ) {
  559 //          debug_add( "applet reports that it is loaded " + applet_reportsLoaded_list["$appletName"] );
  560 //          ready =1;
  561 //        }
  562 //      applet_isReady_list["$appletName"]= ready;
  563 //      return(ready);
  564 //     }
  565 //
  566 //     applet_initializeAction_list["$appletName"] = function (state) {
  567 //           applet_setState_list["$appletName"](state);
  568 //  };
  569 //
  570 //  applet_submitAction_list["$appletName"] = function () {
  571 //        if (! applet_isReady_list["$appletName"]  ) {
  572 //          alert("$appletName is not ready");
  573 //        }
  574 //           applet_getState_list["$appletName"]();
  575 //           $submitActionScript
  576 //      //getQE("$answerBox").value = getApplet("$appletName").getAnswer();  //FIXME -- not needed in general?
  577 //     };
  578     </script>
  579 
  580 END_HEADER_SCRIPT
  581 
  582 package FlashApplet;
  583 @ISA = qw(Applet);
  584 
  585 
  586 =head2 Insertion HTML code for FlashApplet
  587 
  588 =pod
  589 
  590 The secret to making this applet work with IE in addition to normal browsers
  591 is the addition of the C(<form></form>) construct just before the object.
  592 
  593 For some reason IE has trouble locating a flash object which is contained
  594 within a form.  Adding this second blank form with the larger problemMainForm
  595 seems to solve the problem.
  596 
  597 This follows method2 of the advice given in url(http://kb.adobe.com/selfservice/viewContent.do?externalId=kb400730&sliceId=2)
  598 Method1 and methods involving SWFObject(Geoff Stearns) and SWFFormFix (Steve Kamerman) have yet to be fully investigated:
  599 http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
  600 http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
  601 
  602     use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
  603       <form></form>
  604       <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
  605            id="$appletName" width="500" height="375"
  606            codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
  607          <param name="movie" value="$codebase/$appletName.swf" />
  608          <param name="quality" value="high" />
  609          <param name="bgcolor" value="#869ca7" />
  610          <param name="allowScriptAccess" value="sameDomain" />
  611          <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7"
  612            width="$width" height="$height" name="$appletName" align="middle" id="$appletName"
  613            play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
  614            type="application/x-shockwave-flash"
  615            pluginspage="http://www.macromedia.com/go/getflashplayer">
  616          </embed>
  617 
  618        </object>
  619     END_OBJECT_TEXT
  620 
  621 
  622 =cut
  623 
  624 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
  625   <form></form>
  626   <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
  627              id="$appletName" width="500" height="375"
  628              codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
  629          <param name="movie" value="$codebase/$appletName.swf" />
  630          <param name="quality" value="high" />
  631          <param name="bgcolor" value="#869ca7" />
  632          <param name="allowScriptAccess" value="sameDomain" />
  633          <param name="FlashVars" value="$flashParameters"/>
  634          <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7"
  635              width="$width" height="$height" name="$appletName" align="middle" id="$appletName"
  636              play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
  637              type="application/x-shockwave-flash"
  638              pluginspage="http://www.macromedia.com/go/getflashplayer"
  639              FlashVars="$flashParameters">
  640          </embed>
  641 
  642      </object>
  643 END_OBJECT_TEXT
  644 
  645 sub new {
  646     my $class = shift;
  647   $class -> SUPER::new( objectText   => DEFAULT_OBJECT_TEXT(),
  648                   @_
  649   );
  650 
  651 }
  652 
  653 
  654 package JavaApplet;
  655 @ISA = qw(Applet);
  656 
  657 =head2 Insertion HTML code for JavaApplet
  658 
  659 =pod
  660 
  661 The secret to making this applet work with IE in addition to normal browsers
  662 is the addition of the C(<form></form>) construct just before the object.
  663 
  664 For some reason IE has trouble locating a flash object which is contained
  665 within a form.  Adding this second blank form with the larger problemMainForm
  666 seems to solve the problem.
  667 
  668 This follows method2 of the advice given in url(http://kb.adobe.com/selfservice/viewContent.do?externalId=kb400730&sliceId=2)
  669 Method1 and methods involving SWFObject(Geoff Stearns) and SWFFormFix (Steve Kamerman) have yet to be fully investigated:
  670 http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
  671 http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
  672 
  673     use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
  674       <form></form>
  675      <applet
  676       code     = "$code"
  677       codebase = "$codebase"
  678       archive  = "$archive"
  679       name     = "$appletName"
  680       id       = "$appletName"
  681       width    = "$width"
  682       height   = "$height"
  683       MAYSCRIPT
  684      >
  685       $javaParameters
  686      </applet>
  687     END_OBJECT_TEXT
  688 
  689 =cut
  690 
  691 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
  692   <form></form>
  693  <applet
  694   code     = "$code"
  695   codebase = "$codebase"
  696   archive  = "$archive"
  697   name     = "$appletName"
  698     id       = "$appletName"
  699     width    = "$width"
  700     height   = "$height"
  701     MAYSCRIPT
  702  >
  703   $javaParameters
  704 
  705   Sorry, the Applet could not be started. Please make sure that
  706 Java 1.4.2 (or later) is installed and activated.
  707 (<a href="http://java.sun.com/getjava">click here to install Java now</a>)
  708  </applet>
  709 END_OBJECT_TEXT
  710 
  711 sub new {
  712     my $class = shift;
  713   $class -> SUPER::new( objectText   => DEFAULT_OBJECT_TEXT(),
  714                   @_
  715   );
  716 
  717 }
  718 
  719 
  720 
  721 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9