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

Diff of /branches/gage_dev/pg/lib/Applet.pm

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

trunk/pg/lib/Applet.pm Revision 5625 branches/gage_dev/pg/lib/Applet.pm Revision 6315
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.7 2008/03/26 01:25:52 gage Exp $ 4# $CVSHeader$
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.
21=head1 SYNPOSIS 21=head1 SYNPOSIS
22 22
23 ################################### 23 ###################################
24 # Create link to applet 24 # Create link to applet
25 ################################### 25 ###################################
26 my $appletName = "LineThruPointsWW"; 26 $appletName = "PointGraph";
27 $applet = new FlashApplet( 27$applet = FlashApplet(
28 # can be replaced by $applet =FlashApplet() when using AppletObjects.pl
29 codebase => findAppletCodebase("$appletName.swf"), 28 codebase => findAppletCodebase("$appletName.swf"),
30 appletName => $appletName, 29 appletName => $appletName,
31 appletId => $appletName, 30 appletId => $appletName,
32 submitActionAlias => 'checkAnswer', 31 setStateAlias => 'setXML',
33 ); 32 getStateAlias => 'getXML',
34 33 setConfigAlias => 'config',
34 answerBoxAlias => 'answerBox',
35 submitActionScript => qq{ getQE('answerBox').value = getApplet("$appletName").getAnswer() },
36);
37
35 ################################### 38###################################
36 # Configure applet 39# Configure applet
37 ################################### 40###################################
38 41
39 #xml data to set up the problem-rac 42#data to set up the equation
40 $applet->state(qq{<XML> 43$applet->configuration(qq{<XML expr='(x - $a)^3 + $b/$a * x' />});
41 <point xval='$xval_1' yval='$yval_1' /> 44# initial points
42 <point xval='$xval_2' yval='$yval_2' /> 45$applet->intialState(qq{<XML> </XML>});
43 </XML>});
44
45
46 ################################### 46###################################
47 # insert applet header material 47#insert applet into body
48 ################################### 48###################################
49 HEADER_TEXT($applet->insertHeader ); 49
50
51 ###################################
52 # Text section
53 #
54
55 ###################################
56 #insert applet into body
57 ###################################
58 TEXT( MODES(TeX=>'object code', HTML=>$applet->insertObject)); 50TEXT( MODES(TeX=>'object code', HTML=>$applet->insertAll(
51 includeAnswerBox => 1
52 debug=>0,
53 reinitialize_button=>1,
54 )));
59 55
60 56
61=head1 DESCRIPTION 57=head1 DESCRIPTION
62 58
63This file provides an object to store in one place 59This file provides an object to store in one place
99use MIME::Base64 qw( encode_base64 decode_base64); 95use MIME::Base64 qw( encode_base64 decode_base64);
100 96
101 97
102=head2 Default javaScript functions placed in header 98=head2 Default javaScript functions placed in header
103 99
100=pod
101
104These functions are automatically defined for use for 102These functions are automatically defined for use for
105any javaScript placed in the text of a PG question. 103any javaScript placed in the text of a PG question.
106 104
107 getApplet(appletName) -- finds the applet path in the DOM 105 getApplet(appletName) -- finds the applet path in the DOM
108 106
109 submitAction() -- calls the submit action of the applets 107 submitAction() -- calls the submit action of the applets
110
111 108
112 initializeAction() -- calls the initialize action of the applets 109 initializeWWquestion() -- calls the initialize action of the applets
113 110
114 getQE(name) -- gets an HTML element of the question by name 111 getQE(name) -- gets an HTML element of the question by name
115 or by id. Be sure to keep all names and ids 112 or by id. Be sure to keep all names and ids
116 unique within a given PG question. 113 unique within a given PG question.
117 114
118 getQuestionElement(name) -- long form of getQE(name) 115 getQuestionElement(name) -- long form of getQE(name)
119 116
120 listQuestionElements() -- for discovering the names of inputs in the 117 listQuestionElements() -- for discovering the names of inputs in the
121 PG question. An alert dialog will list all 118 PG question. An alert dialog will list all
122 of the elements. 119 of the elements.
120
123 Usage: Place this at the END of the question, 121 Usage: Place this at the END of the question, just before END_DOCUMENT():
124 just before END_DOCUMENT():
125 122
126 TEXT(qq!<script> listQuestionElements() </script>!); 123 TEXT(qq!<script> listQuestionElements() </script>!);
127 ENDDOCUMENT(); 124 ENDDOCUMENT();
125 to obtain a list of all of the HTML elements in the question
126
127 ----------------------------------------------------------------------------
128
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 );
128 140
129 list of accessor methods format: current_value = $self->method(new_value or empty)
130 141
131 appletId for simplicity and reliability appletId and appletName are always the same 142 appletId for simplicity and reliability appletId and appletName are always the same
132 appletName 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 params an anonymous array containing name/value pairs
149 to configure the applet [name =>'value, ...]
150
151 width rectangle alloted in the html page for displaying the applet
152 height
153
154 bgcolor background color of the applet rectangle
133 155
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 156 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 157 object stores the text which places the applet on the html page
146 158
147 debug in debug mode several alerts mark progress through the procedure of calling the applet 159
148
149 config configuration are those customizable attributes of the applet which don't 160 configuration configuration contains those customizable attributes of the applet which don't
150 change as it is used. When stored in hidden answer fields 161 change as it is used. When stored in hidden answer fields
151 it is usually stored in base64 encoded format. 162 it is usually stored in base64 encoded format.
152 base64_config base64 encode version of the contents of config 163 initialState the state consists of those customizable attributes of the applet which change
153 164 as the applet is used by the student. It is stored by the calling .pg question so that
165 when revisiting the question the applet will be restored to the same state it was
166 left in when the question was last viewed.
167
168 getStateAlias (default: getState) alias for command called to read the current state of the applet.
169 The state is passed in plain text xml format with outer tags: <xml>....</xml>
170 setStateAlias (default: setState) alias for the command called to reset the state of the applet.
171 The state is passed in plain text in xml format with outer tags: <xml>....</xml>
172
173 configAlias (deprecated) -- a synonym for configAlias
174
175 getConfigAlias (default: getConfig) -- retrieves the configuration from the applet. This is used
176 mainly for debugging. In principal the configuration remains the same for a given instance
177 of the applet -- i.e. for the homework question for a single student. The state however
178 will change depending on the interactions between the student and the applet.
154 configAlias (default: config ) names the applet command called with the contents of $self->config 179 setConfigAlias (default: setConfig ) 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> 180 to configure the applet. The parameters are passed to the applet in plain text using <xml>
156 The outer tags must be <xml> ..... </xml> 181 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 182
168 base64_state returns the base64 encoded version of the state stored in the applet object. 183
169 184 initializeActionAlias -- (default: initializeAction) the name of the javaScript subroutine called
170 initializeActionAlias -- (default: initializeAction) the name of the javaScript subroutine called to initialize the applet (some overlap with config/ and setState 185 to initialize the applet (some overlap with config/ and setState
186 maxInitializationAttempts -- (default: 5) number attempts to test applet to see if it is installed.
187 If isActive() exists then the WW question waits until the return value is 1 before
188 calling the applet's confguration commands.
189 Because some applets have isActive return 0 even when they are ready,
190 if isActive() exists but does not return 1 then the applet's configuration commands
191 are called after maxInitializationAttempts number of times. If none of the configuration commands
192 of the applet can be detected then the WW question gives up after maxInitializationAttempts.
193
171 submitActionAlias -- (default: submitAction)the name of the javaScript subroutine called when the submit button of the 194 submitActionAlias -- (default: getXML) applet subroutine called when the submit button of the
172 .pg question is pressed. 195 .pg question is pressed.
196 submitActionScript -- (default: qq{ getQE('answerBox').value = getApplet("$appletName").getAnswer() },
197
198 answerBoxAlias -- name of answer box to return answer to: default defaultAnswerBox
199 returnFieldName -- (deprecated) synonmym for answerBoxAlias
200
201
202 debugMode (default: 0) for debugMode==1 the answerBox and the box preserving the applet state
203 between questions are made visible along with some buttons for manually getting the state of
204 the applet and setting the state of the applet.
205
206 for debugMode==2, in addition to the answerBox and stateBox there are several alerts
207 which mark progress through the procedures of calling the applet. Useful for troubleshooting
208 where in the chain of command a communication failure occurs
173 209
174 returnFieldName 210
175 211 Methods:
176 212
213 insertHeader -- inserts text in header section of HTML page
214 insertObject -- inserts <object></object> or <applet></applet> tag in body of the HTML page
215 insertAll -- (defined in AppletObjects.pl) installs applet by inserting both header text and the object text
216 Usage: $applet->insertAll(
217 includeAnswerBox => 0,
218 debugMode => 0,
219 reinitialize_button =>0,
220 );
177 221
178
179 222
180=cut 223=cut
181 224
225=head4 More details
182 226
227There are three different "images" of the applet. The first is the java or flash applet itself. The object that actually does the work.
228The second is a perl image of the applet -- henceforth the perlApplet -- which is configured in the .pg file and allows a WeBWorK question
229to communicate with the applet. The third image is a javaScript image of the applet -- henceforth the jsApplet which is a mirror of the perlApplet
230but 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
231the jsApplet as a runtime version of the perlApplet since it can be accessed and modified after the virtual HTML page has been created by
232the PG rendering process.
233
234The perlApplet is initialized by $newApplet = new flashApplet( appletName=>'myApplet',..... ); The jsApplet is automatically defined in
235ww_applet_list["myApplet"] by copying the instance variables of $newApplet to a corresponding javaScript object. So $newApplet->{appletName}
236corresponds to ww_applet_list["myApplet"].appletName. (This paragraph is not yet fully implemented :-().
237
238Currently 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
239to a base64 constant and then converted back to text form when it is read by a javaScript subroutine.
240
241The perlApplet has methods that help place the jsApplet code on the HTML page and create the link to the applet itself.
242In particular instance variables such as "setStateAlias", "getStateAlias" connect the WW default of "setState" to subroutine
243name chosen by the applet designer. The aim is to make it easier to connect to applets previously designed to work
244with javaScript in an HTML page or other systems.
245
246
247The jsApplet acts as an intermediary for commands directed at the applet.
248It is not necessary for the minimal operations of
249configuring the applet and maintaining
250state from one viewing of the WW question to address the applet directly.
251The methods such as "setState", "getState", "setConfig" which are part of the jsApplet
252take care of the book keeping details.
253It is also possible to make direct calls to the applet from handcrafted javaScript subroutines,
254but it may be convenient to store these as additional methods in the
255jsApplet.
256
257=cut
258
259=head4 Detecting that the applet is ready
260
261Timing issues are among the pitfalls awaiting when using flash or java applets in WW questions. It is important that the WW question
262does not issue any commands to the applet until the applet is fully loaded, including the uploading of any additional configuration
263information from XML files. This can be tricky since the timing issues usually don't arise when initiating the applet from an HTML page.
264
265The WW API performs the following actions to determine if the applet is loaded:
266
267 check the ww_applet_list[appletName].isReady flag (1== applet is ready)
268 -- this caches the readiness information so that it doesn't
269 have to be repeated within a given viewing of a WW question
270 If this is 1 then the applet is ready.
271 determine whether the applet's isActive subroutine is defined AND returns 1 when called.
272 -- if the return value is 1 the applet is ready, if it is zero or no response then the applet is NOT ready
273 -- If the applet has an isActive() subroutine -- there is no alias for this --
274 then it must return 1 as soon as the applet is ready. Otherwise
275 the applet will timeout.
276 determine whether the applet's setConfig subroutine is defined.
277 -- applet.{setConfigAlias}.
278 determine whether the applet's setState subroutine is defined.
279 determine whether the jsApplets ww_applet_list[appletName].reportsLoaded flag is set to 1
280 -- this can be set by the applet if it calls the javaScript function
281 "applet_loaded(appletName, loaded_status). The loaded_status is 1 or 0
282
283 Logic for determining applet status: if any one of the above checks succeeds (or returns 1) then the applet is
284 consdered to be ready UNLESS the isActive() exists and the call returns a 0 or no response. In this case
285 the applet is assumed to be loading additional data and is not yet ready.
286
287 For this reason if the isActive subroutine
288 is defined in the applet it must return a 1 once the applet is prepared to accept additional commands.
289 (Since there are some extent flashApplets with non-functioning isActive() subroutines a temporary workaround
290 assuems that after C<maxInitializationAttempts> -- 5 by default -- the applet is in fact ready but the
291 isActive() subroutine is non functioning. This can give rise to false "readiness" signals if the applet
292 takes a long time to load auxiliary files.)
293
294The applet itself can take measures to insure that the setConfig subroutine is prepared to respond immediately once the applet is loaded.
295It can include timers that delay execution of the configuring actions until all of the auxiliary files needed by the applet are loaded.
296
297
298=cut
299
300
301
302
303=head4 Instance variables in the javaScript applet ww_applet_list[appletName]
304
305 Most of the instance variables in the perl version of the applet are transferred to the javaScript applet
306
307=cut
308
309
310=head4 Methods defined for the javaScript applet ww_applet_list[appletName]
311
312This is not a comprehensive list
313
314 setConfig -- transmits the information for configuring the applet
315
316 getConfig -- retrieves the configuration information -- this is used mainly for debugging and may not be defined in most applets
317
318
319 setState -- sets the current state (1) from the appletName_state HTML element if this contains an <xml>...</xml> string
320 -- if the value contains <xml>restart_applet</xml> then set the current state to ww_applet_list[appletName].initialState
321 -- if the value is a blank string set the current state to ww_applet_list[appletName].initialState
322
323
324 getState -- retrieves the current state and stores in the appletName_state HTML element.
325
326
327=cut
328
329=head4 Requirements for applets
330
331The following methods are desirable in an applet that preserves state in a WW question. None of them are required.
332
333 setState(str) (default: setXML)
334 -- set the current state of the applet from an xml string
335 -- should be able to accept an empty string or a string of
336 the form <XML>.....</XML> without creating errors
337 -- can be designed to receive other forms of input if it is
338 coordinated with the WW question.
339 getState() (default: getXML)
340 -- return the current state of the applet in an xml string.
341 -- an empty string or a string of the form <XML>.....</XML>
342 are the standard responses.
343 -- can be designed to return other strings if it is
344 coordinated with the WW question.
345 setConfig(str) (default: setConfig)
346 -- If the applet allows configuration this configures the applet
347 from an xml string
348 -- should be able to accept an empty string or a string of the
349 form <XML>.....</XML> without creating errors
350 -- can be designed to receive other forms of input if it is
351 coordinated with the WW question.
352 getConfig (default: getConfig)
353 -- This returns a string defining the configuration of the
354 applet in an xml string
355 -- an empty string or a string of the form <XML>.....</XML>
356 are the standard responses.
357 -- can be designed to return other strings if it is
358 coordinated with the WW question.
359 -- this method is used for debugging to ensure that
360 the configuration was set as expected.
361 getAnswer (default: getAnswer)
362 -- Returns a string (usually NOT xml) which is the
363 response that the student is effectvely submitting to answer
364 the WW question.
365
366
367=cut
368
369=head4 Initialization sequence
370
371When the WW question is loaded the C<initializeWWquestion> javaScript subroutine calls each of the applets used in the question asking them
372to initialize themselves.
373
374The applets initialization method is as follows:
375
376 -- wait until the applet is loaded and the applet has loaded all of its auxiliary files.
377 -- set the debugMode in the applet
378 -- call the setConfig method in the javaScript applet -- (configuration parameters are "permanent" for the life of the applet
379 -- call the setInitialization method in the javaScript applet -- this often calls the setState method in the applet
380
381=cut
382
383
384=head Submit sequence
385
386When the WW question submit button is pressed the form containing the WW question calles the javaScript "submitAction()" which then asks
387each of the applets on the page to perform its submit action which consists of
388
389 -- if the applet is to be reinitialized (appletName_state contains <xml>restart_applet</xml>) then
390 the HTML elements appletName_state and previous_appletName_state are set to <xml>restart_applet</xml>
391 to be interpreted by the next setState command
392 -- Otherwise getState() from the applet and save it to the HTML input element appletName_state
393 -- Perform the javaScript commands in .submitActionScript (default: '' )
394 a typical submitActionScript looks like getQE(this.answerBox).value = getApplet(appletName).getAnswer() )
395
396=cut
183 397
184 398
185sub new { 399sub new {
186 my $class = shift; 400 my $class = shift;
187 my $self = { 401 my $self = {
188 appletName =>'', 402 appletName => '',
189 code=>'',
190 codebase=>'',
191# appletId =>'', #always use identical applet Id's and applet Names 403 appletId => '', #always use identical applet Id's and applet Names
404 archive => '',
405 code => '',
406 codebase => '',
192 params =>undef, 407 params =>undef,
193 width => 550, 408 width => 550,
194 height => 400, 409 height => 400,
195 base64_state => '', 410 bgcolor => "#869ca7",
196 base64_config => '', 411 configuration => '', # configuration defining the applet
412 initialState => '', # initial state.
197 getStateAlias => 'getXML', 413 getStateAlias => 'getXML',
198 setStateAlias => 'setXML', 414 setStateAlias => 'setXML',
415 configAlias => '', # deprecated
199 configAlias => 'config', 416 getConfigAlias => 'getConfig',
417 setConfigAlias => 'setConfig',
200 initializeActionAlias => 'setXML', 418 initializeActionAlias => 'setXML',
419 maxInitializationAttempts => 5, # number of attempts to initialize applet
201 submitActionAlias => 'getXML', 420 submitActionAlias => 'getXML',
202 returnFieldName => 'receivedField', 421 submitActionScript => '', # script executed on submitting the WW question
422 answerBoxAlias => 'answerBox',
423 answerBox => '', # deprecated
424 returnFieldName => '', # deprecated
203 headerText => DEFAULT_HEADER_TEXT(), 425 headerText => DEFAULT_HEADER_TEXT(),
204 objectText => '', 426 objectText => '',
205 debug => 0, 427 debugMode => 0,
206 @_, 428 @_,
207 }; 429 };
208 bless $self, $class; 430 bless $self, $class;
431 $self->initialState('<xml></xml>');
432 if ($self->{returnFieldName} or $self->{answerBox} ) { # backward compatibility
433 warn "use answerBoxAlias instead of returnFieldName or answerBox";
434 $self->{answerBox}='';
435 $self->{returnFieldName}='';
436 }
437 if ($self->{configAlias}) { # backward compatibility
438 warn "use setConfigAlias instead of configAlias";
439 $self->{configAlias}='';
440 }
441 $self->configuration('<xml></xml>');
209 return $self; 442 return $self;
210} 443}
211 444sub appletId {
212sub header { 445 appletName(@_);
446}
447sub appletName {
213 my $self = shift; 448 my $self = shift;
214 if ($_[0] eq "reset") { # $applet->header('reset'); erases default header text. 449 $self->{appletName} = shift ||$self->{appletName}; # replace the current appletName if non-empty
215 $self->{headerText}=''; 450 $self->{appletName};
216 } else { 451}
217 $self->{headerText} .= join("",@_); # $applet->header(new_text); concatenates new_text to existing header. 452sub archive {
218 } 453 my $self = shift;
454 $self->{archive} = shift ||$self->{archive}; # replace the current archive if non-empty
455 $self->{archive};
456}
457sub code {
458 my $self = shift;
459 $self->{code} = shift ||$self->{code}; # replace the current code if non-empty
219 $self->{headerText}; 460 $self->{code};
220} 461}
221sub object { 462sub codebase {
222 my $self = shift; 463 my $self = shift;
223 if ($_[0] eq "reset") { 464 $self->{codebase} = shift ||$self->{codebase}; # replace the current codebase if non-empty
224 $self->{objectText}=''; 465 $self->{codebase};
225 } else {
226 $self->{objectText} .= join("",@_);
227 }
228 $self->{objectText};
229} 466}
230sub params { 467sub params {
231 my $self = shift; 468 my $self = shift;
232 if (ref($_[0]) =~/HASH/) { 469 if (ref($_[0]) =~/HASH/) {
233 $self->{params} = shift; 470 $self->{params} = shift;
236 } else { 473 } else {
237 warn "You must enter a reference to a hash for the parameter list"; 474 warn "You must enter a reference to a hash for the parameter list";
238 } 475 }
239 $self->{params}; 476 $self->{params};
240} 477}
241 478
479sub width {
480 my $self = shift;
481 $self->{width} = shift ||$self->{width}; # replace the current width if non-empty
482 $self->{width};
483}
484sub height {
485 my $self = shift;
486 $self->{height} = shift ||$self->{height}; # replace the current height if non-empty
487 $self->{height};
488}
489sub bgcolor {
490 my $self = shift;
491 $self->{bgcolor} = shift ||$self->{bgcolor}; # replace the current background color if non-empty
492 $self->{bgcolor};
493}
494
495sub header {
496 my $self = shift;
497 if ($_[0] eq "reset") { # $applet->header('reset'); erases default header text.
498 $self->{headerText}='';
499 } else {
500 $self->{headerText} .= join("",@_); # $applet->header(new_text); concatenates new_text to existing header.
501 }
502 $self->{headerText};
503}
504sub object {
505 my $self = shift;
506 if ($_[0] eq "reset") {
507 $self->{objectText}='';
508 } else {
509 $self->{objectText} .= join("",@_);
510 }
511 $self->{objectText};
512}
513sub configuration {
514 my $self = shift;
515 my $str = shift;
516 $self->{configuration} = $str || $self->{configuration}; # replace the current string if non-empty
517 $self->{configuration} =~ s/\n//g;
518 $self->{configuration};
519}
520
521sub initialState {
522 my $self = shift;
523 my $str = shift;
524 $self->{initialState} = $str ||$self->{initialState}; # replace the current string if non-empty
525 $self->{initialState};
526}
527
528sub getStateAlias {
529 my $self = shift;
530 $self->{getStateAlias} = shift ||$self->{getStateAlias}; # replace the current contents if non-empty
531 $self->{getStateAlias};
532}
533
534sub setStateAlias {
535 my $self = shift;
536 $self->{setStateAlias} = shift ||$self->{setStateAlias}; # replace the current contents if non-empty
537 $self->{setStateAlias};
538}
539
540sub getConfigAlias {
541 my $self = shift;
542 $self->{getConfigAlias} = shift ||$self->{getConfigAlias}; # replace the current contents if non-empty
543 $self->{getConfigAlias};
544}
545sub setConfigAlias {
546 my $self = shift;
547 $self->{setConfigAlias} = shift ||$self->{setConfigAlias}; # replace the current contents if non-empty
548 $self->{setConfigAlias};
549}
550
242sub initializeActionAlias { 551sub initializeActionAlias {
243 my $self = shift; 552 my $self = shift;
244 $self->{initializeActionAlias} = shift ||$self->{initializeActionAlias}; # replace the current contents if non-empty 553 $self->{initializeActionAlias} = shift ||$self->{initializeActionAlias}; # replace the current contents if non-empty
245 $self->{initializeActionAlias}; 554 $self->{initializeActionAlias};
246} 555}
247 556sub maxInitializationAttempts {
557 my $self = shift;
558 $self->{maxInitializationAttempts} = shift || $self->{maxInitializationAttempts};
559 $self->{maxInitializationAttempts};
560}
248sub submitActionAlias { 561sub submitActionAlias {
249 my $self = shift; 562 my $self = shift;
250 $self->{submitActionAlias} = shift ||$self->{submitActionAlias}; # replace the current contents if non-empty 563 $self->{submitActionAlias} = shift ||$self->{submitActionAlias}; # replace the current contents if non-empty
251 $self->{submitActionAlias}; 564 $self->{submitActionAlias};
252} 565}
253sub getStateAlias { 566sub submitActionScript {
567 my $self = shift;
568 $self->{submitActionScript} = shift ||$self->{submitActionScript}; # replace the current contents if non-empty
569 $self->{submitActionScript};
570}
571
572sub answerBoxAlias {
573 my $self = shift;
574 $self->{answerBox} = shift ||$self->{answerBox}; # replace the current contents if non-empty
575 $self->{answerBox};
576}
577
578sub debugMode {
579 my $self = shift;
580 my $new_flag = shift;
581 $self->{debugMode} = $new_flag if defined($new_flag);
582 $self->{debugMode};
583}
584
585
586#######################
587# soon to be deprecated?
588#######################
589
590sub config {
591 my $self = shift;
254 my $self = shift; 592 my $str = shift;
255 $self->{getStateAlias} = shift ||$self->{getStateAlias}; # replace the current contents if non-empty 593 warn "use $self->configuration instead of $self->config. Internally this string is ascii, not base64 encoded", join(' ', caller());
256 $self->{getStateAlias}; 594# $self->{base64_config} = encode_base64($str) || $self->{base64_config}; # replace the current string if non-empty
595# $self->{base64_config} =~ s/\n//g;
596# decode_base64($self->{base64_config});
257} 597}
258 598sub state {
259sub setStateAlias { 599 my $self = shift;
260 my $self = shift; 600 my $str = shift;
261 $self->{setStateAlias} = shift ||$self->{setStateAlias}; # replace the current contents if non-empty 601 warn "use $self->initialState instead of $self->state. Internally this string is ascii, not base64 encoded", join(' ', caller());
262 $self->{setStateAlias}; 602# $self->{base64_state} = encode_base64($str) ||$self->{base64_state}; # replace the current string if non-empty
603# $self->{base64_state} =~ s/\n//g;
604# decode_base64($self->{base64_state});
605}
606sub base64_state{
607 my $self = shift;
608 warn "use $self->InitialState instead of $self->state. Internally this string is ascii, not base64 encoded", join(' ', caller());
609
610
611}
612
613sub base64_config {
614 my $self = shift;
615 warn "use $self->configuration instead of $self->config. Internally this string is ascii, not base64 encoded";
616}
617
618sub returnFieldName {
619 my $self = shift;
620 warn "use answerBoxName instead of returnFieldName";
621}
622sub answerBox {
623 my $self = shift;
624 warn "use answerBoxAlias instead of AnswerBox";
263} 625}
264sub configAlias { 626sub configAlias {
265 my $self = shift; 627 my $self = shift;
266 $self->{configAlias} = shift ||$self->{configAlias}; # replace the current contents if non-empty 628 warn "use setConfigAlias instead of configAlias";
267 $self->{configAlias};
268} 629}
269sub returnFieldName { 630#########################
270 my $self = shift;
271 $self->{returnFieldName} = shift ||$self->{returnFieldName}; # replace the current contents if non-empty
272 $self->{returnFieldName};
273}
274sub codebase {
275 my $self = shift;
276 $self->{codebase} = shift ||$self->{codebase}; # replace the current codebase if non-empty
277 $self->{codebase};
278}
279sub code {
280 my $self = shift;
281 $self->{code} = shift ||$self->{code}; # replace the current code if non-empty
282 $self->{code};
283}
284sub height {
285 my $self = shift;
286 $self->{height} = shift ||$self->{height}; # replace the current height if non-empty
287 $self->{height};
288}
289sub width {
290 my $self = shift;
291 $self->{width} = shift ||$self->{width}; # replace the current width if non-empty
292 $self->{width};
293}
294sub archive {
295 my $self = shift;
296 $self->{archive} = shift ||$self->{archive}; # replace the current archive if non-empty
297 $self->{archive};
298}
299sub appletName {
300 my $self = shift;
301 $self->{appletName} = shift ||$self->{appletName}; # replace the current appletName if non-empty
302 $self->{appletName};
303}
304sub debug {
305 my $self = shift;
306 my $new_flag = shift;
307 $self->{debug} = $new_flag if defined($new_flag);
308 $self->{debug};
309}
310sub appletId {
311 appletName(@_);
312}
313sub state {
314 my $self = shift;
315 my $str = shift;
316 $self->{base64_state} = encode_base64($str) ||$self->{base64_state}; # replace the current string if non-empty
317 $self->{base64_state} =~ s/\n//g;
318 decode_base64($self->{base64_state});
319}
320
321sub base64_state{
322 my $self = shift;
323 $self->{base64_state} = shift ||$self->{base64_state}; # replace the current string if non-empty
324 $self->{base64_state};
325}
326sub config {
327 my $self = shift;
328 my $str = shift;
329 $self->{base64_config} = encode_base64($str) || $self->{base64_config}; # replace the current string if non-empty
330 $self->{base64_config} =~ s/\n//g;
331 decode_base64($self->{base64_config});
332}
333sub base64_config {
334 my $self = shift;
335 $self->{base64_config} = shift ||$self->{base64_config}; # replace the current string if non-empty
336 $self->{base64_config} =$self->{base64_config};
337 $self->{base64_config};
338}
339#FIXME 631#FIXME
340# need to be able to adjust header material 632# need to be able to adjust header material
341 633
342sub insertHeader { 634sub insertHeader {
343 my $self = shift; 635 my $self = shift;
636
344 my $codebase = $self->codebase; 637 my $codebase = $self->codebase;
345 my $appletId = $self->appletId; 638 my $appletId = $self->appletId;
346 my $appletName = $self->appletName; 639 my $appletName = $self->appletName;
347 my $base64_initialState = $self->base64_state;
348 my $initializeAction = $self->initializeActionAlias; 640 my $initializeActionAlias = $self->initializeActionAlias;
349 my $submitAction = $self->submitActionAlias; 641 my $submitActionScript = $self->submitActionScript;
350 my $setState = $self->setStateAlias; 642 my $setStateAlias = $self->setStateAlias;
351 my $getState = $self->getStateAlias; 643 my $getStateAlias = $self->getStateAlias;
644
352 my $config = $self->configAlias; 645 my $setConfigAlias = $self->setConfigAlias;
353 my $base64_config = $self->base64_config; 646 my $getConfigAlias = $self->getConfigAlias;
647 my $maxInitializationAttempts = $self->maxInitializationAttempts;
354 my $debugMode = ($self->debug) ? "1": "0"; 648 my $debugMode = ($self->debugMode) ? "1": "0";
355 my $returnFieldName = $self->{returnFieldName}; 649 my $answerBoxAlias = $self->{answerBoxAlias};
356# my $encodeStateQ = ($self->debug)?'' : "state = Base64.encode(state);"; # in debug mode base64 encoding is not used.
357# my $decodeStateQ = "if (!state.match(/<XML>*/i) ) {state = Base64.decode(state)}"; # decode if <XML> is not present
358 my $headerText = $self->header(); 650 my $headerText = $self->header();
651
652
653 #$submitActionScript =~ s/"/\\"/g; # escape quotes for ActionScript
654 # other variables should not have quotes.
655
656 $submitActionScript =~ s/\n/ /g; # replace returns with spaces -- returns in the wrong spot can cause trouble with javaScript
657 $submitActionScript =~ s/\r/ /g; # replace returns with spaces -- returns can cause trouble
658 my $base64_submitActionScript = encode_base64($submitActionScript);
659 my $base64_configuration = encode_base64($self->configuration);
660 my $base64_initialState = encode_base64($self->initialState);
661
662 $base64_submitActionScript =~s/\n//g;
663 $base64_initialState =~s/\n//g; # base64 encoded xml
664 $base64_configuration =~s/\n//g; # base64 encoded xml
359 665
360 $headerText =~ s/(\$\w+)/$1/gee; # interpolate variables p17 of Cookbook 666 $headerText =~ s/(\$\w+)/$1/gee; # interpolate variables p17 of Cookbook
361 667
362 return $headerText; 668 return $headerText;
363 669
364 670
365} 671}
672
673
674########################################################
675# HEADER material for one flash or java applet
676########################################################
677
678use constant DEFAULT_HEADER_TEXT =><<'END_HEADER_SCRIPT';
679 <script src="/webwork2_files/js/Base64.js" language="javascript">
680 </script>
681 <script src="/webwork2_files/js/ww_applet_support.js" language="javascript">
682 //upload functions stored in /opt/webwork/webwork2/htdocs/js ...
683
684 </script>
685 <script language="JavaScript">
686
687 function getApplet(appletName) {
688 var isIE = navigator.appName.indexOf("Microsoft") != -1; // ie8 uses this for java and firefox uses it for flash.
689 var obj = (isIE) ? window[appletName] : window.document[appletName];
690 //return window.document[appletName];
691 if (!obj) { obj = document.getElementById(appletName) }
692 if (obj ) { //RECENT FIX to ==
693 return( obj );
694 } else {
695 alert ("can't find applet " + appletName);
696 }
697 }
698
699 //////////////////////////////////////////////////////////
700 //TEST code
701 //
702 //
703 //////////////////////////////////////////////////////////
704
705 ww_applet_list["$appletName"] = new ww_applet("$appletName");
706
707
708 ww_applet_list["$appletName"].code = "$code";
709 ww_applet_list["$appletName"].codebase = "$codebase";
710 ww_applet_list["$appletName"].appletID = "$appletID";
711 ww_applet_list["$appletName"].base64_state = "$base64_initializationState";
712 ww_applet_list["$appletName"].initialState = Base64.decode("$base64_initialState");
713 ww_applet_list["$appletName"].configuration = Base64.decode("$base64_configuration");;
714 ww_applet_list["$appletName"].getStateAlias = "$getStateAlias";
715 ww_applet_list["$appletName"].setStateAlias = "$setStateAlias";
716 ww_applet_list["$appletName"].setConfigAlias = "$setConfigAlias";
717 ww_applet_list["$appletName"].getConfigAlias = "$getConfigAlias";
718 ww_applet_list["$appletName"].initializeActionAlias = "$initializeActionAlias";
719 ww_applet_list["$appletName"].submitActionAlias = "$submitActionAlias";
720 ww_applet_list["$appletName"].submitActionScript = Base64.decode("$base64_submitActionScript");
721 ww_applet_list["$appletName"].answerBoxAlias = "$answerBoxAlias";
722 ww_applet_list["$appletName"].maxInitializationAttempts = $maxInitializationAttempts;
723 ww_applet_list["$appletName"].debugMode = "$debugMode";
724
725 </script>
726
727END_HEADER_SCRIPT
728
729
366 730
367sub insertObject { 731sub insertObject {
368 my $self = shift; 732 my $self = shift;
369 my $code = $self->{code}; 733 my $code = $self->{code};
370 my $codebase = $self->{codebase}; 734 my $codebase = $self->{codebase};
371 my $appletId = $self->{appletName}; 735 my $appletId = $self->{appletName};
372 my $appletName = $self->{appletName}; 736 my $appletName = $self->{appletName};
373 my $archive = $self->{archive}; 737 my $archive = $self->{archive};
374 my $width = $self->{width}; 738 my $width = $self->{width};
375 my $height = $self->{height}; 739 my $height = $self->{height};
740 my $applet_bgcolor = $self->{bgcolor};
376 my $javaParameters = ''; 741 my $javaParameters = '';
377 my $flashParameters = ''; 742 my $flashParameters = '';
378 my %param_hash = %{$self->params()}; 743 my %param_hash = %{$self->params()};
379 foreach my $key (keys %param_hash) { 744 foreach my $key (keys %param_hash) {
380 $javaParameters .= qq!<param name ="$key" value = "$param_hash{$key}">\n!; 745 $javaParameters .= qq!<param name ="$key" value = "$param_hash{$key}">\n!;
385 750
386 $objectText = $self->{objectText}; 751 $objectText = $self->{objectText};
387 $objectText =~ s/(\$\w+)/$1/gee; 752 $objectText =~ s/(\$\w+)/$1/gee;
388 return $objectText; 753 return $objectText;
389} 754}
390sub initialize {
391 my $self = shift;
392 return q{
393 <script>
394 initializeAction();
395 // this should really be done in the <body> tag
396 </script>
397 };
398 755
399}
400 756
401 757###############################################################################################################
402use constant DEFAULT_HEADER_TEXT =><<'END_HEADER_SCRIPT'; 758#
403 759# FLASH APPLET PACKAGE
404 <script language="JavaScript"> 760#
405 var debug = $debugMode; 761###############################################################################################################
406 //
407 //CONFIGURATIONS
408 //
409 // configurations are "permanent"
410 applet_config_list["$appletName"] = function() {
411 if (debug) { alert("configure $appletName . $config ( $base64_config )");}
412 try {
413 if (debug || !( typeof(getApplet("$appletName").$config) == "undefined" ) ) {
414
415 getApplet("$appletName").$config(Base64.decode("$base64_config"));
416 }
417 } catch(e) {
418 alert("error executing configuration command $config for $appletName: " + e );
419 }
420 }
421 //
422 //STATE
423 //
424 // state can vary as the applet is manipulated.
425 applet_setState_list["$appletName"] = function(state) {
426 if (debug) { alert("set state for $appletName to " + state);}
427 state = state || getQE("$appletName"+"_state").value
428 if (state.match(/<xml/i) || state.match(/<?xml/i) ) { // if state is not all white space
429 if ( base64Q(state) ) {
430 state=Base64.decode(state);
431 }
432 alert("set (decoded) state for $appletName to " + state);
433 try {
434 if (debug || !( typeof(getApplet("$appletName").$setState) =="undefined" ) ) {
435 getApplet("$appletName").$setState( state );
436 }
437 } catch(e) {
438 alert("Error in setting state of $appletName using command $setState : " + e );
439 }
440 } else if (debug) {
441 alert("new state was empty string or did not begin with <xml-- state was not reset");
442 }
443 };
444 applet_getState_list["$appletName"] = function () {
445 if (debug) { alert("getState for applet $appletName");}
446 try {
447 var applet = getApplet("$appletName");
448 var state;
449 if (!( typeof(getApplet("$appletName").$getState) =="undefined" ) ) {
450 state = applet.$getState(); // get state in xml format
451 }
452 if (!debug) {state = Base64.encode(state) }; // replace state by encoded version
453 getQE("$appletName"+"_state").value = state; //place in state htmlItem (debug: textarea, otherwise hidden)
454 } catch (e) {
455 alert("Error in getting state for $appletName " + e );
456 }
457 };
458 //
459 //INITIALIZE
460 //
461 applet_initializeAction_list["$appletName"] = function () {
462 applet_setState_list["$appletName"]();
463 };
464
465 applet_submitAction_list["$appletName"] = function () {
466 applet_getState_list["$appletName"]();
467 getQE("$returnFieldName").value = getApplet("$appletName").sendData();
468 };
469 </script>
470
471END_HEADER_SCRIPT
472 762
473package FlashApplet; 763package FlashApplet;
474@ISA = qw(Applet); 764@ISA = qw(Applet);
475 765
476 766
767=head2 Insertion HTML code for FlashApplet
477 768
478=pod 769=pod
479 770
480The secret to making this applet work with IE in addition to normal browsers 771The secret to making this applet work with IE in addition to normal browsers
481is the addition of the C(<form></form>) construct just before the object. 772is the addition of the C(<form></form>) construct just before the object.
494 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 785 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
495 id="$appletName" width="500" height="375" 786 id="$appletName" width="500" height="375"
496 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"> 787 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
497 <param name="movie" value="$codebase/$appletName.swf" /> 788 <param name="movie" value="$codebase/$appletName.swf" />
498 <param name="quality" value="high" /> 789 <param name="quality" value="high" />
499 <param name="bgcolor" value="#869ca7" /> 790 <param name="bgcolor" value="$applet_bgcolor" />
500 <param name="allowScriptAccess" value="sameDomain" /> 791 <param name="allowScriptAccess" value="sameDomain" />
501 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7" 792 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="$applet_bgcolor"
502 width="$width" height="$height" name="$appletName" align="middle" id="$appletName" 793 width="$width" height="$height" name="$appletName" align="middle" id="$appletName"
503 play="true" loop="false" quality="high" allowScriptAccess="sameDomain" 794 play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
504 type="application/x-shockwave-flash" 795 type="application/x-shockwave-flash"
505 pluginspage="http://www.macromedia.com/go/getflashplayer"> 796 pluginspage="http://www.macromedia.com/go/getflashplayer">
506 </embed> 797 </embed>
510 801
511 802
512=cut 803=cut
513 804
514use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT'; 805use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
515 <form></form> 806
516 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 807 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
517 id="$appletName" width="500" height="375" 808 id="$appletName" width="500" height="375"
518 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab"> 809 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
519 <param name="movie" value="$codebase/$appletName.swf" /> 810 <param name="movie" value="$codebase/$appletName.swf" />
520 <param name="quality" value="high" /> 811 <param name="quality" value="high" />
521 <param name="bgcolor" value="#869ca7" /> 812 <param name="bgcolor" value="$applet_bgcolor" />
522 <param name="allowScriptAccess" value="sameDomain" /> 813 <param name="allowScriptAccess" value="sameDomain" />
523 <param name="FlashVars" value="$flashParameters"/> 814 <param name="FlashVars" value="$flashParameters"/>
524 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7" 815 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="$applet_bgcolor"
525 width="$width" height="$height" name="$appletName" align="middle" id="$appletName" 816 width="$width" height="$height" name="$appletName" align="middle" id="$appletName"
526 play="true" loop="false" quality="high" allowScriptAccess="sameDomain" 817 play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
527 type="application/x-shockwave-flash" 818 type="application/x-shockwave-flash"
528 pluginspage="http://www.macromedia.com/go/getflashplayer" 819 pluginspage="http://www.macromedia.com/go/getflashplayer"
529 FlashVars="$flashParameters"> 820 FlashVars="$flashParameters">
538 @_ 829 @_
539 ); 830 );
540 831
541} 832}
542 833
834###############################################################################################################
835#
836# JAVA APPLET PACKAGE
837#
838###############################################################################################################
543 839
544package JavaApplet; 840package JavaApplet;
545@ISA = qw(Applet); 841@ISA = qw(Applet);
546 842
547 843=head2 Insertion HTML code for JavaApplet
548 844
549=pod 845=pod
550 846
551The secret to making this applet work with IE in addition to normal browsers 847The secret to making this applet work with IE in addition to normal browsers
552is the addition of the C(<form></form>) construct just before the object. 848is the addition of the C(<form></form>) construct just before the object.
577 END_OBJECT_TEXT 873 END_OBJECT_TEXT
578 874
579=cut 875=cut
580 876
581use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT'; 877use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
582 <form></form> 878
583 <applet 879 <applet
584 code = "$code" 880 code = "$code"
585 codebase = "$codebase" 881 codebase = "$codebase"
586 archive = "$archive" 882 archive = "$archive"
587 name = "$appletName" 883 name = "$appletName"
588 id = "$appletName" 884 id = "$appletName"
589 width = "$width" 885 width = "$width"
590 height = "$height" 886 height = "$height"
887 bgcolor = "$applet_bgcolor"
591 MAYSCRIPT 888 MAYSCRIPT
592 > 889 >
593 $javaParameters 890 $javaParameters
891
892 Sorry, the Applet could not be started. Please make sure that
893Java 1.4.2 (or later) is installed and activated.
894(<a href="http://java.sun.com/getjava">click here to install Java now</a>)
594 </applet> 895 </applet>
595END_OBJECT_TEXT 896END_OBJECT_TEXT
596 897
597sub new { 898sub new {
598 my $class = shift; 899 my $class = shift;
600 @_ 901 @_
601 ); 902 );
602 903
603} 904}
604 905
906###############################################################################################################
907#
908# CANVAS APPLET PACKAGE
909#
910###############################################################################################################
911
912package CanvasApplet;
913@ISA = qw(Applet);
914
915
916=head2 Insertion HTML code for CanvasApplet
917
918=pod
919
920The secret to making this applet work with IE in addition to normal browsers
921is the addition of the C(<form></form>) construct just before the object.
922
923For some reason IE has trouble locating a flash object which is contained
924within a form. Adding this second blank form with the larger problemMainForm
925seems to solve the problem.
926
927This follows method2 of the advice given in url(http://kb.adobe.com/selfservice/viewContent.do?externalId=kb400730&sliceId=2)
928Method1 and methods involving SWFObject(Geoff Stearns) and SWFFormFix (Steve Kamerman) have yet to be fully investigated:
929http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
930http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
931
932use constant CANVAS_OBJECT_TEXT =><<'END_OBJECT_TEXT';
933 <form></form>
934 <script> var width = 200; var height = 200;</script>
935 <canvas name="cv" id="cv" data-src="http://localhost/webwork2_files/js/sketchgraphhtml5b/SketchGraph.pjs" width="400" height="400"></canvas>
936END_OBJECT_TEXT
937
938
939
940=cut
941
942
943use constant CANVAS_OBJECT_HEADER_TEXT =><<'END_HEADER_SCRIPT';
944 <script src="/webwork2_files/js/Base64.js" language="javascript">
945 </script>
946 <script src="/webwork2_files/js/ww_applet_support.js" language="javascript">
947 //upload functions stored in /opt/webwork/webwork2/htdocs/js ...
948
949 </script>
950 <script language="JavaScript">
951
952
953
954 //////////////////////////////////////////////////////////
955 //CANVAS OBJECT HEADER CODE
956 //
957 //////////////////////////////////////////////////////////
958
959 ww_applet_list["$appletName"] = new ww_applet("$appletName");
960
961
962 ww_applet_list["$appletName"].code = "$code";
963 ww_applet_list["$appletName"].codebase = "$codebase";
964 ww_applet_list["$appletName"].appletID = "$appletID";
965 ww_applet_list["$appletName"].base64_state = "$base64_initializationState";
966 ww_applet_list["$appletName"].initialState = Base64.decode("$base64_initialState");
967 ww_applet_list["$appletName"].configuration = Base64.decode("$base64_configuration");;
968 ww_applet_list["$appletName"].getStateAlias = "$getStateAlias";
969 ww_applet_list["$appletName"].setStateAlias = "$setStateAlias";
970 ww_applet_list["$appletName"].setConfigAlias = "$setConfigAlias";
971 ww_applet_list["$appletName"].getConfigAlias = "$getConfigAlias";
972 ww_applet_list["$appletName"].initializeActionAlias = "$initializeActionAlias";
973 ww_applet_list["$appletName"].submitActionAlias = "$submitActionAlias";
974 ww_applet_list["$appletName"].submitActionScript = Base64.decode("$base64_submitActionScript");
975 ww_applet_list["$appletName"].answerBoxAlias = "$answerBoxAlias";
976 ww_applet_list["$appletName"].maxInitializationAttempts = $maxInitializationAttempts;
977 ww_applet_list["$appletName"].debugMode = "$debugMode";
978
979
980 ww_applet_list["$appletName"].reportsLoaded = 1;
981 ww_applet_list["$appletName"].object = $appletName;
982
983 function getApplet(appletName) {
984 //var isIE = navigator.appName.indexOf("Microsoft") != -1;
985 //var obj = (isIE) ? window[appletName] : window.document[appletName];
986 //return window.document[appletName];
987 var obj = ww_applet_list[appletName].object; // define fake applet for this object
988 if (obj && (obj.name == appletName)) { //RECENT FIX to ==
989 //alert("getting fake applet " + obj.name);
990 return( obj );
991 } else {
992 alert ("can't find fake applet " + appletName + " in object "+obj.name);
993 }
994 }
995 </script>
996
997END_HEADER_SCRIPT
998
999
1000#FIXME need to get rid of hardcoded url
1001
1002
1003use constant CANVAS_OBJECT_TEXT =><<'END_OBJECT_TEXT';
1004
1005 <canvas name="cv" id="cv" data-src="/webwork2_files/js/sketchgraphhtml5b/SketchGraph.pjs" width="$width" height="$height"></canvas>
1006END_OBJECT_TEXT
1007
1008sub new {
1009 my $class = shift;
1010 $class -> SUPER::new( objectText => CANVAS_OBJECT_TEXT(),
1011 headerText => CANVAS_OBJECT_HEADER_TEXT(),
1012 @_
1013 );
1014
1015}
605 1016
606 1017
6071; 10181;

Legend:
Removed from v.5625  
changed lines
  Added in v.6315

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9