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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 5594 Revision 6023
1################################################################################ 1################################################################################
2# WeBWorK Online Homework Delivery System 2# WeBWorK Online Homework Delivery System
3# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ 3# Copyright 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: pg/lib/Applet.pm,v 1.3 2007/11/06 16:47:19 gage Exp $ 4# $CVSHeader: pg/lib/Applet.pm,v 1.18 2009/03/10 12:10:36 gage Exp $
5# 5#
6# This program is free software; you can redistribute it and/or modify it under 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 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 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. 9# version, or (b) the "Artistic License" which comes with this package.
35 ################################### 35 ###################################
36 # Configure applet 36 # Configure applet
37 ################################### 37 ###################################
38 38
39 #xml data to set up the problem-rac 39 #xml data to set up the problem-rac
40 $applet->xmlString(qq{<XML> 40 $applet->config(qq{<XML>
41 <point xval='$xval_1' yval='$yval_1' /> 41 <point xval='$xval_1' yval='$yval_1' />
42 <point xval='$xval_2' yval='$yval_2' /> 42 <point xval='$xval_2' yval='$yval_2' />
43 </XML>}); 43 </XML>});
44 44
45 45
75 75
76(not yet completed) 76(not yet completed)
77 77
78The module JavaApplet has defaults for inserting java applets. 78The module JavaApplet has defaults for inserting java applets.
79 79
80The module Applet will store common code for the two types of applet. 80The module Applet stores common code for the two types of applet.
81 81
82=head1 USAGE 82=head1 USAGE
83 83
84This file is included by listing it in the modules section of global.conf. 84These modules are activate by listing it in the modules section of global.conf and rebooting the server.
85The companion file to this one is macros/AppletObjects.pl
86
87qw(Applet FlashApplet JavaApplet)
85 88
86=cut 89=cut
87 90
88 91
89 92
90package Applet; 93package Applet;
91 94
95use URI::Escape;
92 96
93package FlashApplet;
94 97
95 98
96use MIME::Base64 qw( encode_base64 decode_base64); 99use MIME::Base64 qw( encode_base64 decode_base64);
97 100
98 101
99=head2 Default javaScript functions placed in header 102=head2 Default javaScript functions placed in header
103
104=pod
100 105
101These functions are automatically defined for use for 106These functions are automatically defined for use for
102any javaScript placed in the text of a PG question. 107any javaScript placed in the text of a PG question.
103 108
104 getFlashMovie(appletName) -- finds the applet path in the DOM 109 getApplet(appletName) -- finds the applet path in the DOM
105 110
106 submitAction() -- calls the submit action of the applet 111 submitAction() -- calls the submit action of the applets
107 -- the submitAction is defined
108 112
109 initialize() -- calls the initialize action of the applet 113 initializeWWquestion() -- calls the initialize action of the applets
110 114
111 getQE(name) -- gets an HTML element of the question by name 115 getQE(name) -- gets an HTML element of the question by name
112 or by id. Be sure to keep all names and ids 116 or by id. Be sure to keep all names and ids
113 unique within a given PG question. 117 unique within a given PG question.
114 118
115 getQuestionElement(name) -- long form of getQE(name) 119 getQuestionElement(name) -- long form of getQE(name)
116 120
117 listQuestionElements() -- for discovering the names of inputs in the 121 listQuestionElements() -- for discovering the names of inputs in the
118 PG question. An alert dialog will list all 122 PG question. An alert dialog will list all
119 of the elements. 123 of the elements.
120 Usage: Place this at the END of the question, 124 Usage: Place this at the END of the question, just before END_DOCUMENT():
121 just before END_DOCUMENT():
122 125
123 TEXT(qq!<script> listQuestionElements() </script>!); 126 TEXT(qq!<script> listQuestionElements() </script>!);
124 ENDDOCUMENT(); 127 ENDDOCUMENT();
128 to obtain a list of all of the HTML elements in the question
129
130 ----------------------------------------------------------------------------
131
132
133 List of accessor methods made available by the FlashApplet class:
134 Usage: $current_value = $applet->method(new_value or empty)
135 These can also be set when creating the class -- for exampe:
136 $applet = new FlashApplet(
137 # can be replaced by $applet =FlashApplet() when using AppletObjects.pl
138 codebase => findAppletCodebase("$appletName.swf"),
139 appletName => $appletName,
140 appletId => $appletName,
141 submitActionAlias => 'checkAnswer',
142 );
143
144
145 appletId for simplicity and reliability appletId and appletName are always the same
146 appletName
147 archive the name of the .jar file containing the applet code
148 code the name of the applet code in the .jar archive
149 codebase a prefix url used to find the archive and the applet itself
150
151 height rectangle alloted in the html page for displaying the applet
152
153 params an anonymous array containing name/value pairs
154 to configure the applet [name =>'value, ...]
155
156 header stores the text to be added to the header section of the html page
157 object stores the text which places the applet on the html page
158
159 debug in debug mode several alerts mark progress through the procedure of calling the applet
160
161 config configuration are those customizable attributes of the applet which don't
162 change as it is used. When stored in hidden answer fields
163 it is usually stored in base64 encoded format.
164 base64_config base64 encode version of the contents of config
165
166 configAlias (default: setConfig ) names the applet command called with the contents of $self->config
167 to configure the applet. The parameters are passed to the applet in plain text using <xml>
168 The outer tags must be <xml> ..... </xml>
169 setConfigAlias (default: setConfig) -- a synonym for configAlias
170 getConfigAlias (default: getConfig) -- retrieves the configuration from the applet. This is used
171 mainly for debugging. In principal the configuration remains the same for a given instance
172 of the applet -- i.e. for the homework question for a single student. The state however
173 will change depending on the interactions between the student and the applet.
174 initialState the state consists of those customizable attributes of the applet which change
175 as the applet is used by the student. It is stored by the calling .pg question so that
176 when revisiting the question the applet will be restored to the same state it was left in when the question was last
177 viewed.
178
179 getStateAlias (default: getState) alias for command called to read the current state of the applet.
180 The state is passed in plain text xml format with outer tags: <xml>....</xml>
181 setStateAlias (default: setState) alias for the command called to reset the state of the applet.
182 The state is passed in plain text in xml format with outer tags: <xml>....</xml>
183
184 base64_state returns the base64 encoded version of the state stored in the applet object.
185
186 initializeActionAlias -- (default: initializeAction) the name of the javaScript subroutine called to initialize the applet (some overlap with config/ and setState
187 submitActionAlias -- (default: submitAction)the name of the javaScript subroutine called when the submit button of the
188 .pg question is pressed.
189 answerBox -- name of answer box to return answer to: default defaultAnswerBox
190 getAnswer -- (formerly sendData) get student answer from applet and place in answerBox
191 returnFieldName -- (deprecated) synonmym for answerBox
125 192
126 193
127=cut 194=cut
128 195
196=head4 More details
197
198There are three different "images" of the applet. The first is the java or flash applet itself. The object that actually does the work.
199The second is a perl image of the applet -- henceforth the perlApplet -- which is configured in the .pg file and allows a WeBWorK question
200to communicate with the applet. The third image is a javaScript image of the applet -- henceforth the jsApplet which is a mirror of the perlApplet
201but is available to the javaScript code setup and executed in the virtual HTML page defined by the .pg file of the WeBWorK question. One can think of
202the jsApplet as a runtime version of the perlApplet since it can be accessed and modified after the virtual HTML page has been created by
203the PG rendering process.
204
205The perlApplet is initialized by $newApplet = new flashApplet( appletName=>'myApplet',..... ); The jsApplet is automatically defined in
206ww_applet_list["myApplet"] by copying the instance variables of $newApplet to a corresponding javaScript object. So $newApplet->{appletName}
207corresponds to ww_applet_list["myApplet"].appletName. (This paragraph is not yet fully implemented :-().
208
209Currently all messages read by the applet are xml text. If some of the code needs to be printed in the HTML header than it is converted
210to a base64 constant and then converted back to text form when it is read by an javaScript subroutine.
211
212=cut
213
214=head4 Requirements for applets
215
216The following methods are desirable in an applet that preserves state in a WW question. None of them are required.
217
218 setState(str) (default: setXML)
219 -- set the current state of the applet from an xml string
220 -- should be able to accept an empty string or a string of
221 the form <XML>.....</XML> without creating errors
222 -- can be designed to receive other forms of input if it is
223 coordinated with the WW question.
224 getState() (default: getXML)
225 -- return the current state of the applet in an xml string.
226 -- an empty string or a string of the form <XML>.....</XML>
227 are the standard responses.
228 -- can be designed to return other strings if it is
229 coordinated with the WW question.
230 setConfig(str) (default: setConfig)
231 -- If the applet allows configuration this configures the applet
232 from an xml string
233 -- should be able to accept an empty string or a string of the
234 form <XML>.....</XML> without creating errors
235 -- can be designed to receive other forms of input if it is
236 coordinated with the WW question.
237 getConfig (default: getConfig)
238 -- This returns a string defining the configuration of the
239 applet in an xml string
240 -- an empty string or a string of the form <XML>.....</XML>
241 are the standard responses.
242 -- can be designed to return other strings if it is
243 coordinated with the WW question.
244 -- this method is used for debugging to ensure that
245 the configuration was set as expected.
246 getAnswer (default: getAnswer)
247 -- Returns a string (usually NOT xml) which is the
248 response that the student is submitting to answer
249 the WW question.
250
251
252=cut
253
254sub new {
255 my $class = shift;
256 my $self = {
257 appletName =>'',
258 code=>'',
259 codebase=>'',
260# appletId =>'', #always use identical applet Id's and applet Names
261 params =>undef,
262 width => 550,
263 height => 400,
264 bgcolor => "#869ca7",
265 base64_state => undef, # this is a state to use for initializing the first occurence of the question.
266 base64_config => undef, # this is the initial (and final?) configuration
267# configuration => '', # configuration defining the applet
268 initialState => '', # initial state. (I'm considering storing everything as ascii and converting on the fly to base64 when needed.)
269 getStateAlias => 'getXML',
270 setStateAlias => 'setXML',
271 configAlias => '', # deprecated
272 getConfigAlias => 'getConfig',
273 setConfigAlias => 'setConfig',
274 initializeActionAlias => 'setXML',
275 submitActionAlias => 'getXML',
276 submitActionScript => '', # script executed on submitting the WW question
277 answerBoxAlias => 'answerBox',
278 answerBox => '', # deprecated
279 returnFieldName => '', # deprecated
280 headerText => DEFAULT_HEADER_TEXT(),
281 objectText => '',
282 debug => 0,
283 @_,
284 };
285 bless $self, $class;
286 $self->initialState('<xml></xml>');
287 if ($self->{returnFieldName}) or $self->{answerBox} ) { # backward compatibility
288 warn "use answerBoxAlias instead of returnFieldName or answerBox";
289 $self->{answerBox}='';
290 $self->{returnFieldName}='';
291 }
292 if ($self->{configAlias}) { # backward compatibility
293 warn "use setConfigAlias instead of configAlias";
294 $self->{configAlias}='';
295 }
296 $self->config('<xml></xml>');
297 return $self;
298}
299
300sub header {
301 my $self = shift;
302 if ($_[0] eq "reset") { # $applet->header('reset'); erases default header text.
303 $self->{headerText}='';
304 } else {
305 $self->{headerText} .= join("",@_); # $applet->header(new_text); concatenates new_text to existing header.
306 }
307 $self->{headerText};
308}
309sub object {
310 my $self = shift;
311 if ($_[0] eq "reset") {
312 $self->{objectText}='';
313 } else {
314 $self->{objectText} .= join("",@_);
315 }
316 $self->{objectText};
317}
318sub params {
319 my $self = shift;
320 if (ref($_[0]) =~/HASH/) {
321 $self->{params} = shift;
322 } elsif ( !defined($_[0]) or $_[0] =~ '') {
323 # do nothing (read)
324 } else {
325 warn "You must enter a reference to a hash for the parameter list";
326 }
327 $self->{params};
328}
329
330sub initializeActionAlias {
331 my $self = shift;
332 $self->{initializeActionAlias} = shift ||$self->{initializeActionAlias}; # replace the current contents if non-empty
333 $self->{initializeActionAlias};
334}
335
336sub submitActionAlias {
337 my $self = shift;
338 $self->{submitActionAlias} = shift ||$self->{submitActionAlias}; # replace the current contents if non-empty
339 $self->{submitActionAlias};
340}
341sub submitActionScript {
342 my $self = shift;
343 $self->{submitActionScript} = shift ||$self->{submitActionScript}; # replace the current contents if non-empty
344 $self->{submitActionScript};
345}
346sub getStateAlias {
347 my $self = shift;
348 $self->{getStateAlias} = shift ||$self->{getStateAlias}; # replace the current contents if non-empty
349 $self->{getStateAlias};
350}
351
352sub setStateAlias {
353 my $self = shift;
354 $self->{setStateAlias} = shift ||$self->{setStateAlias}; # replace the current contents if non-empty
355 $self->{setStateAlias};
356}
357sub configAlias {
358 my $self = shift;
359 $self->{setConfigAlias} = shift ||$self->{setConfigAlias}; # replace the current contents if non-empty
360 $self->{setConfigAlias};
361}
362sub setConfigAlias {
363 my $self = shift;
364 $self->{setConfigAlias} = shift ||$self->{setConfigAlias}; # replace the current contents if non-empty
365 $self->{setConfigAlias};
366}
367sub getConfigAlias {
368 my $self = shift;
369 $self->{getConfigAlias} = shift ||$self->{getConfigAlias}; # replace the current contents if non-empty
370 $self->{getConfigAlias};
371}
372
373sub answerBoxName {
374 my $self = shift;
375 $self->{answerBox} = shift ||$self->{answerBox}; # replace the current contents if non-empty
376 $self->{answerBox};
377}
378sub codebase {
379 my $self = shift;
380 $self->{codebase} = shift ||$self->{codebase}; # replace the current codebase if non-empty
381 $self->{codebase};
382}
383sub code {
384 my $self = shift;
385 $self->{code} = shift ||$self->{code}; # replace the current code if non-empty
386 $self->{code};
387}
388sub height {
389 my $self = shift;
390 $self->{height} = shift ||$self->{height}; # replace the current height if non-empty
391 $self->{height};
392}
393sub width {
394 my $self = shift;
395 $self->{width} = shift ||$self->{width}; # replace the current width if non-empty
396 $self->{width};
397}
398sub bgcolor {
399 my $self = shift;
400 $self->{bgcolor} = shift ||$self->{bgcolor}; # replace the current background color if non-empty
401 $self->{bgcolor};
402}
403sub archive {
404 my $self = shift;
405 $self->{archive} = shift ||$self->{archive}; # replace the current archive if non-empty
406 $self->{archive};
407}
408sub appletName {
409 my $self = shift;
410 $self->{appletName} = shift ||$self->{appletName}; # replace the current appletName if non-empty
411 $self->{appletName};
412}
413sub debug {
414 my $self = shift;
415 my $new_flag = shift;
416 $self->{debug} = $new_flag if defined($new_flag);
417 $self->{debug};
418}
419sub appletId {
420 appletName(@_);
421}
422
423sub initialState {
424 my $self = shift;
425 my $str = shift;
426 $self->{initialState} = $str ||$self->{initialState}; # replace the current string if non-empty
427 $self->{initialState};
428}
429
430sub config {
431 my $self = shift;
432 my $str = shift;
433 $self->{base64_config} = encode_base64($str) || $self->{base64_config}; # replace the current string if non-empty
434 $self->{base64_config} =~ s/\n//g;
435 decode_base64($self->{base64_config});
436}
437#######################
438# soon to be deprecated?
439#######################
440sub state {
441 my $self = shift;
442 my $str = shift;
443 $self->{base64_state} = encode_base64($str) ||$self->{base64_state}; # replace the current string if non-empty
444 $self->{base64_state} =~ s/\n//g;
445 decode_base64($self->{base64_state});
446}
447sub base64_state{
448 my $self = shift;
449 $self->{base64_state} = shift ||$self->{base64_state}; # replace the current string if non-empty
450 $self->{base64_state};
451}
452
453sub base64_config {
454 my $self = shift;
455 $self->{base64_config} = shift ||$self->{base64_config}; # replace the current string if non-empty
456 $self->{base64_config} =$self->{base64_config};
457 $self->{base64_config};
458}
459
460sub returnFieldName {
461 my $self = shift;
462 warn "use answerBoxName instead of returnFieldName";
463}
464sub answerBox {
465 my $self = shift;
466 warn "use answerBoxName instead of AnswerBox";
467}
468#########################
469#FIXME
470# need to be able to adjust header material
471
472sub insertHeader {
473 my $self = shift;
474
475 my $codebase = $self->codebase;
476 my $appletId = $self->appletId;
477 my $appletName = $self->appletName;
478 my $base64_initialState = $self->base64_state;
479 my $initializeAction = $self->initializeActionAlias;
480 my $submitActionAlias = $self->submitActionAlias;
481 my $submitActionScript = $self->submitActionScript;
482 my $setStateAlias = $self->setStateAlias;
483 my $getStateAlias = $self->getStateAlias;
484
485 my $setConfigAlias = $self->setConfigAlias;
486 my $getConfigAlias = $self->getConfigAlias;
487 my $base64_config = $self->base64_config;
488 my $debugMode = ($self->debug) ? "1": "0";
489 my $returnFieldName = $self->{returnFieldName};
490 my $answerBox = $self->{answerBox};
491 my $headerText = $self->header();
492
493
494 $submitActionScript =~ s/"/\\"/g; # escape quotes for ActionScript
495 # other variables should not have quotes.
496
497 $submitActionScript =~ s/\n/ /g; # replace returns with spaces -- returns in the wrong spot can cause trouble with javaScript
498 $submitActionScript =~ s/\r/ /g; # replace returns with spaces -- returns can cause trouble
499
500 $headerText =~ s/(\$\w+)/$1/gee; # interpolate variables p17 of Cookbook
501
502 return $headerText;
503
504
505}
506
507sub insertObject {
508 my $self = shift;
509 my $code = $self->{code};
510 my $codebase = $self->{codebase};
511 my $appletId = $self->{appletName};
512 my $appletName = $self->{appletName};
513 my $archive = $self->{archive};
514 my $width = $self->{width};
515 my $height = $self->{height};
516 my $applet_bgcolor = $self->{bgcolor};
517 my $javaParameters = '';
518 my $flashParameters = '';
519 my %param_hash = %{$self->params()};
520 foreach my $key (keys %param_hash) {
521 $javaParameters .= qq!<param name ="$key" value = "$param_hash{$key}">\n!;
522 $flashParameters .= uri_escape($key).'='.uri_escape($param_hash{$key}).'&';
523 }
524 $flashParameters =~ s/\&$//; # trim last &
525
526
527 $objectText = $self->{objectText};
528 $objectText =~ s/(\$\w+)/$1/gee;
529 return $objectText;
530}
531# sub initialize {
532# my $self = shift;
533# return q{
534# <script>
535# initializeAllApplets();
536# // this should really be done in the <body> tag
537# </script>
538# };
539#
540# }
541########################################################
542# HEADER material for one flash or java applet
543########################################################
129 544
130use constant DEFAULT_HEADER_TEXT =><<'END_HEADER_SCRIPT'; 545use constant DEFAULT_HEADER_TEXT =><<'END_HEADER_SCRIPT';
131 <script language="javascript">AC_FL_RunContent = 0;</script> 546 <script src="/webwork2_files/js/Base64.js" language="javascript">
132 <script src="http://hosted2.webwork.rochester.edu/webwork2_files/applets/AC_RunActiveContent.js" language="javascript"> 547 </script>
548 <script src="/webwork2_files/js/ww_applet_support.js" language="javascript">
549 //upload functions stored in /opt/webwork/webwork2/htdocs/js ...
550
133 </script> 551 </script>
134
135
136 <script language="JavaScript"> 552 <script language="JavaScript">
137 553
138 var flash; 554 // set debug mode for this applet
139 function getFlashMovie(appletName) { 555 set_debug($debugMode);
140 var isIE = navigator.appName.indexOf("Microsoft") != -1; 556
141 var obj = (isIE) ? window[appletName] : window.document[appletName]; 557 //////////////////////////////////////////////////////////
142 //return window.document[appletName]; 558 //TEST code
143 if (obj.name = appletName) { 559 //
144 return( obj ); 560 //
145 } else { 561 //////////////////////////////////////////////////////////
146 alert ("can't find applet " + appletName);
147 }
148 }
149
150 function submitAction() {
151 getQE("$returnFieldName").value = getFlashMovie("$appletId").$submitAction();
152 }
153 function initialize() {
154 getFlashMovie("$appletId").$initializeAction("$base64_xmlString");
155 }
156 function getQE(name1) { // get Question Element in problemMainForm by name
157 var isIE = navigator.appName.indexOf("Microsoft") != -1;
158 var obj = (isIE) ? document.getElementById(name1)
159 :document.problemMainForm[name1];
160 // needed for IE -- searches id and name space so it can be unreliable if names are not unique
161 if (obj.name = name1 ) {
162 return( obj );
163 } else {
164 alert("Can't find " + name1);
165 listQuestionElements();
166 }
167 562
168 } 563 ww_applet_list["$appletName"] = new ww_applet("$appletName");
169 function getQuestionElement(name1) {
170 return getQE(name1);
171 }
172 564
173 function listQuestionElements() { // list all HTML elements in main problem form
174 var isIE = navigator.appName.indexOf("Microsoft") != -1;
175 var mainForm = (isIE) ? document.getElementsByTagName("input") : document.getElementsByTagName("input");
176 var str=mainForm.length +" Question Elements\n type | name = value < id > \n";
177 for( var i=0; i< mainForm.length; i++) {
178 str = str + " "+i+" " + mainForm[i].type
179 + " | " + mainForm[i].name
180 + "= " + mainForm[i].value +
181 " <" + mainForm[i].id + ">\n";
182 }
183 alert(str +"\n Place listQuestionElements() at end of document in order to get all form elements!");
184 } 565
185 566 ww_applet_list["$appletName"].code = "$code";
567 ww_applet_list["$appletName"].codebase = "$codebase";
568 ww_applet_list["$appletName"].appletID = "$appletID";
569 ww_applet_list["$appletName"].base64_state = "$base64_initializationState";
570 ww_applet_list["$appletName"].base64_config = "$base64_config";
571 ww_applet_list["$appletName"].getStateAlias = "$getStateAlias";
572 ww_applet_list["$appletName"].setStateAlias = "$setStateAlias";
573 ww_applet_list["$appletName"].setConfigAlias = "$setConfigAlias";
574 ww_applet_list["$appletName"].getConfigAlias = "$getConfigAlias";
575 ww_applet_list["$appletName"].initializeActionAlias = "$initializeAction";
576 ww_applet_list["$appletName"].submitActionAlias = "$submitActionAlias";
577 ww_applet_list["$appletName"].submitActionScript = "$submitActionScript";
578 ww_applet_list["$appletName"].answerBox = "$answerBox";
579 ww_applet_list["$appletName"].debug = "$debugMode";
186 580
187 </script> 581 </script>
188 582
189END_HEADER_SCRIPT 583END_HEADER_SCRIPT
190 584
585package FlashApplet;
586@ISA = qw(Applet);
191 587
192# <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" 588
193# width="550" height="400" id="$appletId" align="middle"> 589=head2 Insertion HTML code for FlashApplet
194# <param name="allowScriptAccess" value="sameDomain" />
195# <param name="allowFullScreen" value="false" />
196# <param name="movie" value="$appletName.swf" />
197# <param name="quality" value="high" />
198# <param name="bgcolor" value="#ffffcc" />
199# <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#ffffcc" width="550" height="400" name="$appletName"
200# align="middle" id="$appletId",
201# align="middle" allowScriptAccess="sameDomain"
202# allowFullScreen="false"
203# type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
204# <param name="quality" value="high" /><param name="bgcolor" value="#ffffcc" />
205# </object>
206 590
207=pod 591=pod
208 592
209The secret to making this applet work with IE in addition to normal browsers 593The secret to making this applet work with IE in addition to normal browsers
210is the addition of the C(<form></form>) construct just before the object. 594is the addition of the C(<form></form>) construct just before the object.
216This follows method2 of the advice given in url(http://kb.adobe.com/selfservice/viewContent.do?externalId=kb400730&sliceId=2) 600This follows method2 of the advice given in url(http://kb.adobe.com/selfservice/viewContent.do?externalId=kb400730&sliceId=2)
217Method1 and methods involving SWFObject(Geoff Stearns) and SWFFormFix (Steve Kamerman) have yet to be fully investigated: 601Method1 and methods involving SWFObject(Geoff Stearns) and SWFFormFix (Steve Kamerman) have yet to be fully investigated:
218http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js 602http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
219http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933 603http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
220 604
221 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT'; 605 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
222 <form></form> 606 <form></form>
223 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 607 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
224 id="$appletName" width="500" height="375" 608 id="$appletName" width="500" height="375"
225 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"> 609 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
226 <param name="movie" value="$codebase/$appletName.swf" /> 610 <param name="movie" value="$codebase/$appletName.swf" />
227 <param name="quality" value="high" /> 611 <param name="quality" value="high" />
228 <param name="bgcolor" value="#869ca7" /> 612 <param name="bgcolor" value="$applet_bgcolor" />
229 <param name="allowScriptAccess" value="sameDomain" /> 613 <param name="allowScriptAccess" value="sameDomain" />
230 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7" 614 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="$applet_bgcolor"
231 width="550" height="400" name="$appletName" align="middle" id="$appletID" 615 width="$width" height="$height" name="$appletName" align="middle" id="$appletName"
232 play="true" loop="false" quality="high" allowScriptAccess="sameDomain" 616 play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
233 type="application/x-shockwave-flash" 617 type="application/x-shockwave-flash"
234 pluginspage="http://www.macromedia.com/go/getflashplayer"> 618 pluginspage="http://www.macromedia.com/go/getflashplayer">
235 </embed> 619 </embed>
236 620
237 </object> 621 </object>
238 END_OBJECT_TEXT 622 END_OBJECT_TEXT
623
239 624
240=cut 625=cut
241 626
242use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT'; 627use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
243 <form></form> 628 <form></form>
244 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 629 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
245 id="$appletName" width="500" height="375" 630 id="$appletName" width="500" height="375"
246 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"> 631 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
247 <param name="movie" value="$codebase/$appletName.swf" /> 632 <param name="movie" value="$codebase/$appletName.swf" />
248 <param name="quality" value="high" /> 633 <param name="quality" value="high" />
249 <param name="bgcolor" value="#869ca7" /> 634 <param name="bgcolor" value="$applet_bgcolor" />
250 <param name="allowScriptAccess" value="sameDomain" /> 635 <param name="allowScriptAccess" value="sameDomain" />
636 <param name="FlashVars" value="$flashParameters"/>
251 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7" 637 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="$applet_bgcolor"
252 width="550" height="400" name="$appletName" align="middle" id="$appletID" 638 width="$width" height="$height" name="$appletName" align="middle" id="$appletName"
253 play="true" loop="false" quality="high" allowScriptAccess="sameDomain" 639 play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
254 type="application/x-shockwave-flash" 640 type="application/x-shockwave-flash"
255 pluginspage="http://www.macromedia.com/go/getflashplayer"> 641 pluginspage="http://www.macromedia.com/go/getflashplayer"
642 FlashVars="$flashParameters">
256 </embed> 643 </embed>
257 644
258 </object> 645 </object>
259END_OBJECT_TEXT 646END_OBJECT_TEXT
260 647
261
262sub new { 648sub new {
263 my $class = shift; 649 my $class = shift;
264 my $self = {
265 host =>'',
266 port => '',
267 path => '',
268 appletName =>'',
269 codebase=>'',
270 appletId =>'',
271 params =>undef,
272 base64_xmlString => 'foobar',
273 initializeActionAlias => 'setupProblem',
274 submitActionAlias => 'checkAnswer',
275 returnFieldName => 'receivedField',
276 headerText => DEFAULT_HEADER_TEXT(),
277 objectText => DEFAULT_OBJECT_TEXT(), 650 $class -> SUPER::new( objectText => DEFAULT_OBJECT_TEXT(),
278 @_, 651 @_
279 }; 652 );
280 bless $self, $class;
281 #$self -> _initialize(@_);
282 return $self;
283}
284 653
285sub header {
286 my $self = shift;
287 if ($_[0] eq "reset") { # $applet->header('reset'); erases default header text.
288 $self->{headerText}='';
289 } else {
290 $self->{headerText} .= join("",@_); # $applet->header(new_text); concatenates new_text to existing header.
291 }
292 $self->{headerText};
293} 654}
294sub object {
295 my $self = shift;
296 if ($_[0] eq "reset") {
297 $self->{objectText}='';
298 } else {
299 $self->{objectText} .= join("",@_);
300 }
301 $self->{objectText};
302}
303sub params {
304 my $self = shift;
305 if (ref($_[0]) =~/HASH/) {
306 $self->{params} = shift;
307 } elsif ( $_[0] =~ '') {
308 # do nothing (read)
309 } else {
310 warn "You must enter a reference to a hash for the parameter list";
311 }
312 $self->{params};
313}
314
315sub initializeActionAlias {
316 my $self = shift;
317 $self->{initializeActionAlias} = shift ||$self->{initializeActionAlias}; # replace the current contents if non-empty
318 $self->{initializeActionAlias};
319}
320 655
321sub submitActionAlias {
322 my $self = shift;
323 $self->{submitActionAlias} = shift ||$self->{submitActionAlias}; # replace the current contents if non-empty
324 $self->{submitActionAlias};
325}
326sub returnFieldName {
327 my $self = shift;
328 $self->{returnFieldName} = shift ||$self->{returnFieldName}; # replace the current contents if non-empty
329 $self->{returnFieldName};
330}
331sub codebase {
332 my $self = shift;
333 $self->{codebase} = shift ||$self->{codebase}; # replace the current codebase if non-empty
334 $self->{codebase};
335}
336sub appletName {
337 my $self = shift;
338 $self->{appletName} = shift ||$self->{appletName}; # replace the current appletName if non-empty
339 $self->{appletName};
340}
341sub appletId {
342 my $self = shift;
343 $self->{appletId} = shift ||$self->{appletId}; # replace the current appletName if non-empty
344 $self->{appletId};
345}
346sub xmlString {
347 my $self = shift;
348 my $str = shift;
349 $self->{base64_xmlString} = encode_base64($str) ||$self->{base64_xmlString}; # replace the current string if non-empty
350 $self->{base64_xmlString} =~ s/\n//g;
351 decode_base64($self->{base64_xmlString});
352}
353 656
354sub base64_xmlString{ 657package JavaApplet;
355 my $self = shift; 658@ISA = qw(Applet);
356 $self->{base64_xmlString} = shift ||$self->{base64_xmlString}; # replace the current string if non-empty
357 $self->{base64_xmlString};
358}
359 659
360#FIXME 660=head2 Insertion HTML code for JavaApplet
361# need to be able to adjust header material
362 661
363sub insertHeader { 662=pod
364 my $self = shift; 663
365 my $codebase = $self->{codebase}; 664The secret to making this applet work with IE in addition to normal browsers
366 my $appletId = $self->{appletId}; 665is the addition of the C(<form></form>) construct just before the object.
367 my $appletName = $self->{appletName}; 666
368 my $base64_xmlString = $self->{base64_xmlString}; 667For some reason IE has trouble locating a flash object which is contained
369 my $initializeAction = $self->{initializeActionAlias}; 668within a form. Adding this second blank form with the larger problemMainForm
370 my $submitAction = $self->{submitActionAlias}; 669seems to solve the problem.
371 my $returnFieldName= $self->{returnFieldName}; 670
372 my $headerText = $self->header(); 671This follows method2 of the advice given in url(http://kb.adobe.com/selfservice/viewContent.do?externalId=kb400730&sliceId=2)
373 $headerText =~ s/(\$\w+)/$1/gee; # interpolate variables p17 of Cookbook 672Method1 and methods involving SWFObject(Geoff Stearns) and SWFFormFix (Steve Kamerman) have yet to be fully investigated:
673http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
674http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
675
676 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
677 <form></form>
678 <applet
679 code = "$code"
680 codebase = "$codebase"
681 archive = "$archive"
682 name = "$appletName"
683 id = "$appletName"
684 width = "$width"
685 height = "$height"
686 MAYSCRIPT
687 >
688 $javaParameters
689 </applet>
690 END_OBJECT_TEXT
691
692=cut
693
694use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
695 <form></form>
696 <applet
697 code = "$code"
698 codebase = "$codebase"
699 archive = "$archive"
700 name = "$appletName"
701 id = "$appletName"
702 width = "$width"
703 height = "$height"
704 bgcolor = "$applet_bgcolor"
705 MAYSCRIPT
706 >
707 $javaParameters
374 708
375 return $headerText; 709 Sorry, the Applet could not be started. Please make sure that
710Java 1.4.2 (or later) is installed and activated.
711(<a href="http://java.sun.com/getjava">click here to install Java now</a>)
712 </applet>
713END_OBJECT_TEXT
376 714
377 715sub new {
378}
379
380
381# <script language="javascript">
382# if (AC_FL_RunContent == 0) {
383# alert("This page requires AC_RunActiveContent.js.");
384# } else {
385# AC_FL_RunContent(
386# 'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0',
387# 'width', '100%',
388# 'height', '100%',
389# 'src', 'http://$codebase/$appletName',
390# 'quality', 'high',
391# 'pluginspage', 'http://www.macromedia.com/go/getflashplayer',
392# 'align', 'middle',
393# 'play', 'true',
394# 'loop', 'true',
395# 'scale', 'showall',
396# 'wmode', 'window',
397# 'devicefont', 'false',
398# 'id', '$appletId',
399# 'bgcolor', '#ffffcc',
400# 'name', '$appletName',
401# 'menu', 'true',
402# 'allowFullScreen', 'false',
403# 'allowScriptAccess','sameDomain',
404# 'movie', '$appletName',
405# 'salign', ''
406# ); //end AC code
407# }
408# </script>
409sub insertObject {
410 my $self = shift; 716 my $class = shift;
411 my $codebase = $self->{codebase}; 717 $class -> SUPER::new( objectText => DEFAULT_OBJECT_TEXT(),
412 my $appletId = $self->{appletId}; 718 @_
413 my $appletName = $self->{appletName}; 719 );
414 $codebase = findAppletCodebase("$appletName.swf") unless $codebase;
415 $objectText = $self->{objectText};
416 $objectText =~ s/(\$\w+)/$1/gee;
417 return $objectText;
418}
419 720
420sub initialize {
421 my $self = shift;
422 return q{
423 <script>
424 initialize();
425 // this should really be done in the <body> tag
426 </script>
427 };
428
429} 721}
722
723
430 724
4311; 7251;

Legend:
Removed from v.5594  
changed lines
  Added in v.6023

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9