[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 5667
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.10 2008/05/05 17:24:31 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
100 103
101These functions are automatically defined for use for 104These functions are automatically defined for use for
102any javaScript placed in the text of a PG question. 105any javaScript placed in the text of a PG question.
103 106
104 getFlashMovie(appletName) -- finds the applet path in the DOM 107 getApplet(appletName) -- finds the applet path in the DOM
105 108
106 submitAction() -- calls the submit action of the applet 109 submitAction() -- calls the submit action of the applets
107 -- the submitAction is defined 110
108 111
109 initialize() -- calls the initialize action of the applet 112 initializeAction() -- calls the initialize action of the applets
110 113
111 getQE(name) -- gets an HTML element of the question by name 114 getQE(name) -- gets an HTML element of the question by name
112 or by id. Be sure to keep all names and ids 115 or by id. Be sure to keep all names and ids
113 unique within a given PG question. 116 unique within a given PG question.
114 117
121 just before END_DOCUMENT(): 124 just before END_DOCUMENT():
122 125
123 TEXT(qq!<script> listQuestionElements() </script>!); 126 TEXT(qq!<script> listQuestionElements() </script>!);
124 ENDDOCUMENT(); 127 ENDDOCUMENT();
125 128
129 list of accessor methods format: current_value = $self->method(new_value or empty)
130
131 appletId for simplicity and reliability appletId and appletName are always the same
132 appletName
133
134 archive the name of the .jar file containing the applet code
135 code the name of the applet code in the .jar archive
136 codebase a prefix url used to find the archive and the applet itself
137
138 height rectangle alloted in the html page for displaying the applet
139 width
140
141 params an anonymous array containing name/value pairs
142 to configure the applet [name =>'value, ...]
143
144 header stores the text to be added to the header section of the html page
145 object stores the text which places the applet on the html page
146
147 debug in debug mode several alerts mark progress through the procedure of calling the applet
148
149 config configuration are those customizable attributes of the applet which don't
150 change as it is used. When stored in hidden answer fields
151 it is usually stored in base64 encoded format.
152 base64_config base64 encode version of the contents of config
153
154 configAlias (default: config ) names the applet command called with the contents of $self->config
155 to configure the applet. The parameters are passed to the applet in plain text using <xml>
156 The outer tags must be <xml> ..... </xml>
157 state state consists of those customizable attributes of the applet which change
158 as the applet is used. It is stored by the calling .pg question so that
159 when revisiting the question the applet
160 will be restored to the same state it was left in when the question was last
161 viewed.
162
163 getStateAlias (default: getState) alias for command called to read the current state of the applet.
164 The state is passed in plain text xml format with outer tags: <xml>....</xml>
165 setStateAlias (default: setState) alias for the command called to reset the state of the applet.
166 The state is passed in plain text in xml format with outer tags: <xml>....</xml>
167
168 base64_state returns the base64 encoded version of the state stored in the applet object.
169
170 initializeActionAlias -- (default: initializeAction) the name of the javaScript subroutine called to initialize the applet (some overlap with config/ and setState
171 submitActionAlias -- (default: submitAction)the name of the javaScript subroutine called when the submit button of the
172 .pg question is pressed.
173
174 returnFieldName
175
176
177
178
126 179
127=cut 180=cut
128 181
129 182
183
184
185sub new {
186 my $class = shift;
187 my $self = {
188 appletName =>'',
189 code=>'',
190 codebase=>'',
191# appletId =>'', #always use identical applet Id's and applet Names
192 params =>undef,
193 width => 550,
194 height => 400,
195 base64_state => undef, # this is an state to use for initializing the first occurence of the question.
196 base64_config => undef, # this is the initial (and final?) configuration
197 getStateAlias => 'getXML',
198 setStateAlias => 'setXML',
199 configAlias => 'config',
200 initializeActionAlias => 'setXML',
201 submitActionAlias => 'getXML',
202 returnFieldName => 'receivedField',
203 headerText => DEFAULT_HEADER_TEXT(),
204 objectText => '',
205 debug => 0,
206 @_,
207 };
208 bless $self, $class;
209 $self->state('<xml></xml>');
210 $self->config('<xml></xml>');
211 return $self;
212}
213
214sub header {
215 my $self = shift;
216 if ($_[0] eq "reset") { # $applet->header('reset'); erases default header text.
217 $self->{headerText}='';
218 } else {
219 $self->{headerText} .= join("",@_); # $applet->header(new_text); concatenates new_text to existing header.
220 }
221 $self->{headerText};
222}
223sub object {
224 my $self = shift;
225 if ($_[0] eq "reset") {
226 $self->{objectText}='';
227 } else {
228 $self->{objectText} .= join("",@_);
229 }
230 $self->{objectText};
231}
232sub params {
233 my $self = shift;
234 if (ref($_[0]) =~/HASH/) {
235 $self->{params} = shift;
236 } elsif ( !defined($_[0]) or $_[0] =~ '') {
237 # do nothing (read)
238 } else {
239 warn "You must enter a reference to a hash for the parameter list";
240 }
241 $self->{params};
242}
243
244sub initializeActionAlias {
245 my $self = shift;
246 $self->{initializeActionAlias} = shift ||$self->{initializeActionAlias}; # replace the current contents if non-empty
247 $self->{initializeActionAlias};
248}
249
250sub submitActionAlias {
251 my $self = shift;
252 $self->{submitActionAlias} = shift ||$self->{submitActionAlias}; # replace the current contents if non-empty
253 $self->{submitActionAlias};
254}
255sub getStateAlias {
256 my $self = shift;
257 $self->{getStateAlias} = shift ||$self->{getStateAlias}; # replace the current contents if non-empty
258 $self->{getStateAlias};
259}
260
261sub setStateAlias {
262 my $self = shift;
263 $self->{setStateAlias} = shift ||$self->{setStateAlias}; # replace the current contents if non-empty
264 $self->{setStateAlias};
265}
266sub configAlias {
267 my $self = shift;
268 $self->{configAlias} = shift ||$self->{configAlias}; # replace the current contents if non-empty
269 $self->{configAlias};
270}
271sub returnFieldName {
272 my $self = shift;
273 $self->{returnFieldName} = shift ||$self->{returnFieldName}; # replace the current contents if non-empty
274 $self->{returnFieldName};
275}
276sub codebase {
277 my $self = shift;
278 $self->{codebase} = shift ||$self->{codebase}; # replace the current codebase if non-empty
279 $self->{codebase};
280}
281sub code {
282 my $self = shift;
283 $self->{code} = shift ||$self->{code}; # replace the current code if non-empty
284 $self->{code};
285}
286sub height {
287 my $self = shift;
288 $self->{height} = shift ||$self->{height}; # replace the current height if non-empty
289 $self->{height};
290}
291sub width {
292 my $self = shift;
293 $self->{width} = shift ||$self->{width}; # replace the current width if non-empty
294 $self->{width};
295}
296sub archive {
297 my $self = shift;
298 $self->{archive} = shift ||$self->{archive}; # replace the current archive if non-empty
299 $self->{archive};
300}
301sub appletName {
302 my $self = shift;
303 $self->{appletName} = shift ||$self->{appletName}; # replace the current appletName if non-empty
304 $self->{appletName};
305}
306sub debug {
307 my $self = shift;
308 my $new_flag = shift;
309 $self->{debug} = $new_flag if defined($new_flag);
310 $self->{debug};
311}
312sub appletId {
313 appletName(@_);
314}
315sub state {
316 my $self = shift;
317 my $str = shift;
318 $self->{base64_state} = encode_base64($str) ||$self->{base64_state}; # replace the current string if non-empty
319 $self->{base64_state} =~ s/\n//g;
320 decode_base64($self->{base64_state});
321}
322
323sub base64_state{
324 my $self = shift;
325 $self->{base64_state} = shift ||$self->{base64_state}; # replace the current string if non-empty
326 $self->{base64_state};
327}
328sub config {
329 my $self = shift;
330 my $str = shift;
331 $self->{base64_config} = encode_base64($str) || $self->{base64_config}; # replace the current string if non-empty
332 $self->{base64_config} =~ s/\n//g;
333 decode_base64($self->{base64_config});
334}
335sub base64_config {
336 my $self = shift;
337 $self->{base64_config} = shift ||$self->{base64_config}; # replace the current string if non-empty
338 $self->{base64_config} =$self->{base64_config};
339 $self->{base64_config};
340}
341#FIXME
342# need to be able to adjust header material
343
344sub insertHeader {
345 my $self = shift;
346 my $codebase = $self->codebase;
347 my $appletId = $self->appletId;
348 my $appletName = $self->appletName;
349 my $base64_initialState = $self->base64_state;
350 my $initializeAction = $self->initializeActionAlias;
351 my $submitAction = $self->submitActionAlias;
352 my $setState = $self->setStateAlias;
353 my $getState = $self->getStateAlias;
354 my $config = $self->configAlias;
355 my $base64_config = $self->base64_config;
356 my $debugMode = ($self->debug) ? "1": "0";
357 my $returnFieldName = $self->{returnFieldName};
358# my $encodeStateQ = ($self->debug)?'' : "state = Base64.encode(state);"; # in debug mode base64 encoding is not used.
359# my $decodeStateQ = "if (!state.match(/<XML>*/i) ) {state = Base64.decode(state)}"; # decode if <XML> is not present
360 my $headerText = $self->header();
361
362 $headerText =~ s/(\$\w+)/$1/gee; # interpolate variables p17 of Cookbook
363
364 return $headerText;
365
366
367}
368
369sub insertObject {
370 my $self = shift;
371 my $code = $self->{code};
372 my $codebase = $self->{codebase};
373 my $appletId = $self->{appletName};
374 my $appletName = $self->{appletName};
375 my $archive = $self->{archive};
376 my $width = $self->{width};
377 my $height = $self->{height};
378 my $javaParameters = '';
379 my $flashParameters = '';
380 my %param_hash = %{$self->params()};
381 foreach my $key (keys %param_hash) {
382 $javaParameters .= qq!<param name ="$key" value = "$param_hash{$key}">\n!;
383 $flashParameters .= uri_escape($key).'='.uri_escape($param_hash{$key}).'&';
384 }
385 $flashParameters =~ s/\&$//; # trim last &
386
387
388 $objectText = $self->{objectText};
389 $objectText =~ s/(\$\w+)/$1/gee;
390 return $objectText;
391}
392sub initialize {
393 my $self = shift;
394 return q{
395 <script>
396 initializeAction();
397 // this should really be done in the <body> tag
398 </script>
399 };
400
401}
402########################################################
403# HEADER material for one flash or java applet
404########################################################
405
130use constant DEFAULT_HEADER_TEXT =><<'END_HEADER_SCRIPT'; 406use constant DEFAULT_HEADER_TEXT =><<'END_HEADER_SCRIPT';
131 <script language="javascript">AC_FL_RunContent = 0;</script> 407
132 <script src="http://hosted2.webwork.rochester.edu/webwork2_files/applets/AC_RunActiveContent.js" language="javascript">
133 </script>
134
135
136 <script language="JavaScript"> 408 <script language="JavaScript">
137 409
138 var flash; 410 // set debug mode for this applet
139 function getFlashMovie(appletName) { 411 set_debug($debugMode);
140 var isIE = navigator.appName.indexOf("Microsoft") != -1; 412
141 var obj = (isIE) ? window[appletName] : window.document[appletName]; 413 //////////////////////////////////////////////////////////
142 //return window.document[appletName]; 414 //CONFIGURATIONS
143 if (obj.name = appletName) { 415 //
144 return( obj ); 416 // configurations are "permanent"
145 } else { 417 //////////////////////////////////////////////////////////
146 alert ("can't find applet " + appletName); 418
147 } 419 applet_config_list["$appletName"] = function() {
148 } 420 debug_add("applet_config_list:\n attempt to configure $appletName . $config ( $base64_config ) if config function is defined: "
149 421 );
150 function submitAction() { 422 try {
151 getQE("$returnFieldName").value = getFlashMovie("$appletId").$submitAction(); 423 if (( typeof(getApplet("$appletName").$config) == "function" ) ) {
152 } 424 debug_add("CONFIGURE $appletName");
153 function initialize() { 425 getApplet("$appletName").$config(Base64.decode("$base64_config"));
154 getFlashMovie("$appletId").$initializeAction("$base64_xmlString"); 426 }
155 } 427 } catch(e) {
156 function getQE(name1) { // get Question Element in problemMainForm by name 428 alert("Error executing configuration command $config for $appletName: " + e );
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 } 429 }
430 }
431 ////////////////////////////////////////////////////////////
432 //
433 //STATE:
434 // state can vary as the applet is manipulated -- it is reset from the questions _state values
435 //
436 //////////////////////////////////////////////////////////
437
438 applet_setState_list["$appletName"] = function(state) {
439 debug_add("Begin setState for applet $appletName");
440 debug_add("Obtain state from $appletName"+"_state");
441 state = state || getQE("$appletName"+"_state").value;
442 if ( base64Q(state) ) {
443 state=Base64.decode(state);
444 }
445 if (state.match(/<xml/i) || state.match(/<?xml/i) ) { // if state starts with <?xml
446
447 debug_add("applet_setState_list: \n set (decoded) state for $appletName to " +
448 state +"\nfunction type is " +typeof(getApplet("$appletName").$setState)
449 );
450 try {
451 if (( typeof(getApplet("$appletName").$setState) =="function" ) ) {
452 debug_add("setState for $appletName");
453 getApplet("$appletName").$setState( state );
454 }
455 } catch(e) {
456 alert("Error in setting state of $appletName using command $setState : " + e );
457 }
458 } else if (debug) {
459 alert("new state was empty string or did not begin with <xml-- state was not reset");
460 }
461 };
462 applet_getState_list["$appletName"] = function () {
463 debug_add("get current state for applet $appletName and store it in $appletName"+"_state");
464 var applet = getApplet("$appletName");
465 try {
466 if (( typeof(applet.$getState) == "function" ) ) { // there may be no state function
467 state = applet.$getState(); // get state in xml format
468 }
469
470 if (!debug) {state = Base64.encode(state) }; // replace state by encoded version unless in debug mode
471 debug_add("state is "+state); // this should still be in plain text
472 getQE("$appletName"+"_state").value = state; //place state in input item (debug: textarea, otherwise: hidden)
473 } catch (e) {
474 alert("Error in getting state for $appletName " + e );
475 }
476 };
477
478 ////////////////////////////////////////////////////////////
479 //
480 //INITIALIZE
481 //
482 ////////////////////////////////////////////////////////////
483
484
485 applet_checkLoaded_list["$appletName"] = function() { // this function returns 0 unless:
486 // applet has already been flagged as ready in applet_isReady_list
487 // applet.config is defined (or alias for .config)
488 // applet.setState is defined
489 // applet.isActive is defined
490 // applet reported that it is loaded by calling loadQ()
491 var ready = 0;
492 var applet = getApplet("$appletName");
493 if (!debug && applet_isReady_list["$appletName"]) {return(1)}; // memorize readiness in non-debug mode
494 if ( typeof(applet.$config) == "function") {
495 debug_add( "applet.config is " + typeof(applet.$config) );
496 ready = 1;
497 }
498 if( typeof(applet.$getState) == "function") {
499 debug_add( "applet.getState is " + typeof(applet.$getState) );
500 ready =1;
501 }
502 if (typeof(applet.isActive) == "function" && applet.isActive ) {
503 debug_add( "applet.isActive is " + typeof(applet.isActive) );
504 ready =1;
505 }
506 if (typeof(applet_reportsLoaded_list["$appletName"]) !="undefined" && applet_reportsLoaded_list["$appletName"] != 0 ) {
507 debug_add( "applet reports that it is loaded " + applet_reportsLoaded_list["$appletName"] );
508 ready =1;
509 }
510 applet_isReady_list["$appletName"]= ready;
511 return(ready);
512 }
167 513
514 applet_initializeAction_list["$appletName"] = function (state) {
515 applet_setState_list["$appletName"](state);
516 };
517
518 applet_submitAction_list["$appletName"] = function () {
519 if (! applet_isReady_list["$appletName"] ) {
520 alert("$appletName is not ready");
521 }
522 applet_getState_list["$appletName"]();
523 //getQE("$returnFieldName").value = getApplet("$appletName").sendData(); //FIXME -- not needed in general?
168 } 524 };
169 function getQuestionElement(name1) {
170 return getQE(name1);
171 }
172
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 }
185
186
187 </script> 525 </script>
188 526
189END_HEADER_SCRIPT 527END_HEADER_SCRIPT
190 528
529package FlashApplet;
530@ISA = qw(Applet);
191 531
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" 532
193# width="550" height="400" id="$appletId" align="middle">
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 533
207=pod 534=pod
208 535
209The secret to making this applet work with IE in addition to normal browsers 536The 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. 537is 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) 543This 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: 544Method1 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 545http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
219http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933 546http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
220 547
221 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT'; 548 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
222 <form></form> 549 <form></form>
223 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 550 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
224 id="$appletName" width="500" height="375" 551 id="$appletName" width="500" height="375"
225 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"> 552 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
226 <param name="movie" value="$codebase/$appletName.swf" /> 553 <param name="movie" value="$codebase/$appletName.swf" />
227 <param name="quality" value="high" /> 554 <param name="quality" value="high" />
228 <param name="bgcolor" value="#869ca7" /> 555 <param name="bgcolor" value="#869ca7" />
229 <param name="allowScriptAccess" value="sameDomain" /> 556 <param name="allowScriptAccess" value="sameDomain" />
230 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7" 557 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7"
231 width="550" height="400" name="$appletName" align="middle" id="$appletID" 558 width="$width" height="$height" name="$appletName" align="middle" id="$appletName"
232 play="true" loop="false" quality="high" allowScriptAccess="sameDomain" 559 play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
233 type="application/x-shockwave-flash" 560 type="application/x-shockwave-flash"
234 pluginspage="http://www.macromedia.com/go/getflashplayer"> 561 pluginspage="http://www.macromedia.com/go/getflashplayer">
235 </embed> 562 </embed>
236 563
237 </object> 564 </object>
238 END_OBJECT_TEXT 565 END_OBJECT_TEXT
566
239 567
240=cut 568=cut
241 569
242use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT'; 570use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
243 <form></form> 571 <form></form>
246 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"> 574 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
247 <param name="movie" value="$codebase/$appletName.swf" /> 575 <param name="movie" value="$codebase/$appletName.swf" />
248 <param name="quality" value="high" /> 576 <param name="quality" value="high" />
249 <param name="bgcolor" value="#869ca7" /> 577 <param name="bgcolor" value="#869ca7" />
250 <param name="allowScriptAccess" value="sameDomain" /> 578 <param name="allowScriptAccess" value="sameDomain" />
579 <param name="FlashVars" value="$flashParameters"/>
251 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7" 580 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7"
252 width="550" height="400" name="$appletName" align="middle" id="$appletID" 581 width="$width" height="$height" name="$appletName" align="middle" id="$appletName"
253 play="true" loop="false" quality="high" allowScriptAccess="sameDomain" 582 play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
254 type="application/x-shockwave-flash" 583 type="application/x-shockwave-flash"
255 pluginspage="http://www.macromedia.com/go/getflashplayer"> 584 pluginspage="http://www.macromedia.com/go/getflashplayer"
585 FlashVars="$flashParameters">
256 </embed> 586 </embed>
257 587
258 </object> 588 </object>
259END_OBJECT_TEXT 589END_OBJECT_TEXT
260 590
261
262sub new { 591sub new {
263 my $class = shift; 592 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(), 593 $class -> SUPER::new( objectText => DEFAULT_OBJECT_TEXT(),
278 @_, 594 @_
279 }; 595 );
280 bless $self, $class;
281 #$self -> _initialize(@_);
282 return $self;
283}
284 596
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} 597}
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 598
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 599
354sub base64_xmlString{ 600package JavaApplet;
355 my $self = shift; 601@ISA = qw(Applet);
356 $self->{base64_xmlString} = shift ||$self->{base64_xmlString}; # replace the current string if non-empty
357 $self->{base64_xmlString};
358}
359 602
360#FIXME
361# need to be able to adjust header material
362 603
363sub insertHeader { 604
605=pod
606
607The secret to making this applet work with IE in addition to normal browsers
608is the addition of the C(<form></form>) construct just before the object.
609
610For some reason IE has trouble locating a flash object which is contained
611within a form. Adding this second blank form with the larger problemMainForm
612seems to solve the problem.
613
614This follows method2 of the advice given in url(http://kb.adobe.com/selfservice/viewContent.do?externalId=kb400730&sliceId=2)
615Method1 and methods involving SWFObject(Geoff Stearns) and SWFFormFix (Steve Kamerman) have yet to be fully investigated:
616http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
617http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
618
619 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
620 <form></form>
621 <applet
622 code = "$code"
623 codebase = "$codebase"
624 archive = "$archive"
625 name = "$appletName"
626 id = "$appletName"
627 width = "$width"
628 height = "$height"
629 MAYSCRIPT
630 >
631 $javaParameters
632 </applet>
633 END_OBJECT_TEXT
634
635=cut
636
637use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
638 <form></form>
639 <applet
640 code = "$code"
641 codebase = "$codebase"
642 archive = "$archive"
643 name = "$appletName"
644 id = "$appletName"
645 width = "$width"
646 height = "$height"
647 MAYSCRIPT
648 >
649 $javaParameters
650
651 Sorry, the Applet could not be started. Please make sure that
652Java 1.4.2 (or later) is installed and activated.
653(<a href="http://java.sun.com/getjava">click here to install Java now</a>)
654 </applet>
655END_OBJECT_TEXT
656
657sub new {
364 my $self = shift; 658 my $class = shift;
365 my $codebase = $self->{codebase}; 659 $class -> SUPER::new( objectText => DEFAULT_OBJECT_TEXT(),
366 my $appletId = $self->{appletId}; 660 @_
367 my $appletName = $self->{appletName}; 661 );
368 my $base64_xmlString = $self->{base64_xmlString};
369 my $initializeAction = $self->{initializeActionAlias};
370 my $submitAction = $self->{submitActionAlias};
371 my $returnFieldName= $self->{returnFieldName};
372 my $headerText = $self->header();
373 $headerText =~ s/(\$\w+)/$1/gee; # interpolate variables p17 of Cookbook
374
375 return $headerText;
376 662
377
378} 663}
379 664
380 665
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;
411 my $codebase = $self->{codebase};
412 my $appletId = $self->{appletId};
413 my $appletName = $self->{appletName};
414 $codebase = findAppletCodebase("$appletName.swf") unless $codebase;
415 $objectText = $self->{objectText};
416 $objectText =~ s/(\$\w+)/$1/gee;
417 return $objectText;
418}
419
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}
430 666
4311; 6671;

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9