[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 5594 branches/gage_dev/pg/lib/Applet.pm Revision 6324
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$
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->xmlString(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
75 71
76(not yet completed) 72(not yet completed)
77 73
78The module JavaApplet has defaults for inserting java applets. 74The module JavaApplet has defaults for inserting java applets.
79 75
80The module Applet will store common code for the two types of applet. 76The module Applet stores common code for the two types of applet.
81 77
82=head1 USAGE 78=head1 USAGE
83 79
84This file is included by listing it in the modules section of global.conf. 80These modules are activate by listing it in the modules section of global.conf and rebooting the server.
81The companion file to this one is macros/AppletObjects.pl
82
83qw(Applet FlashApplet JavaApplet)
85 84
86=cut 85=cut
87 86
88 87
89 88
90package Applet; 89package Applet;
91 90
91use URI::Escape;
92 92
93package FlashApplet;
94 93
95 94
96use MIME::Base64 qw( encode_base64 decode_base64); 95use MIME::Base64 qw( encode_base64 decode_base64);
97 96
98 97
99=head2 Default javaScript functions placed in header 98=head2 Default javaScript functions placed in header
99
100=pod
100 101
101These functions are automatically defined for use for 102These functions are automatically defined for use for
102any javaScript placed in the text of a PG question. 103any javaScript placed in the text of a PG question.
103 104
104 getFlashMovie(appletName) -- finds the applet path in the DOM 105 getApplet(appletName) -- finds the applet path in the DOM
105 106
106 submitAction() -- calls the submit action of the applet 107 submitAction() -- calls the submit action of the applets
107 -- the submitAction is defined
108 108
109 initialize() -- calls the initialize action of the applet 109 initializeWWquestion() -- calls the initialize action of the applets
110 110
111 getQE(name) -- gets an HTML element of the question by name 111 getQE(name) -- gets an HTML element of the question by name
112 or by id. Be sure to keep all names and ids 112 or by id. Be sure to keep all names and ids
113 unique within a given PG question. 113 unique within a given PG question.
114 114
115 getQuestionElement(name) -- long form of getQE(name) 115 getQuestionElement(name) -- long form of getQE(name)
116 116
117 listQuestionElements() -- for discovering the names of inputs in the 117 listQuestionElements() -- for discovering the names of inputs in the
118 PG question. An alert dialog will list all 118 PG question. An alert dialog will list all
119 of the elements. 119 of the elements.
120
120 Usage: Place this at the END of the question, 121 Usage: Place this at the END of the question, just before END_DOCUMENT():
121 just before END_DOCUMENT():
122 122
123 TEXT(qq!<script> listQuestionElements() </script>!); 123 TEXT(qq!<script> listQuestionElements() </script>!);
124 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 );
125 140
126 141
127=cut 142 appletId for simplicity and reliability appletId and appletName are always the same
143 appletName
144 archive the name of the .jar file containing the applet code
145 code the name of the applet code in the .jar archive
146 codebase a prefix url used to find the archive and the applet itself
147
148 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
128 153
154 bgcolor background color of the applet rectangle
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
129 158
130use constant DEFAULT_HEADER_TEXT =><<'END_HEADER_SCRIPT';
131 <script language="javascript">AC_FL_RunContent = 0;</script>
132 <script src="http://hosted2.webwork.rochester.edu/webwork2_files/applets/AC_RunActiveContent.js" language="javascript">
133 </script>
134 159
135 160 configuration configuration contains those customizable attributes of the applet which don't
136 <script language="JavaScript"> 161 change as it is used. When stored in hidden answer fields
162 it is usually stored in base64 encoded format.
163 initialState the state consists of those customizable attributes of the applet which change
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.
179 setConfigAlias (default: setConfig ) names the applet command called with the contents of $self->config
180 to configure the applet. The parameters are passed to the applet in plain text using <xml>
181 The outer tags must be <xml> ..... </xml>
182
183
184 initializeActionAlias -- (default: initializeAction) the name of the javaScript subroutine called
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
194 submitActionAlias -- (default: getXML) applet subroutine called when the submit button of the
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
209
210
211 Methods:
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 );
221
222
223=cut
224
225=head4 More details
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
137 315
138 var flash; 316 getConfig -- retrieves the configuration information -- this is used mainly for debugging and may not be defined in most applets
139 function getFlashMovie(appletName) {
140 var isIE = navigator.appName.indexOf("Microsoft") != -1;
141 var obj = (isIE) ? window[appletName] : window.document[appletName];
142 //return window.document[appletName];
143 if (obj.name = appletName) {
144 return( obj );
145 } else {
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
168 }
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>
188 317
189END_HEADER_SCRIPT
190
191
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"
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
207=pod
208
209The 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.
211
212For some reason IE has trouble locating a flash object which is contained
213within a form. Adding this second blank form with the larger problemMainForm
214seems to solve the problem.
215
216This 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:
218http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
219http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
220
221 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
222 <form></form>
223 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
224 id="$appletName" width="500" height="375"
225 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
226 <param name="movie" value="$codebase/$appletName.swf" />
227 <param name="quality" value="high" />
228 <param name="bgcolor" value="#869ca7" />
229 <param name="allowScriptAccess" value="sameDomain" />
230 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7"
231 width="550" height="400" name="$appletName" align="middle" id="$appletID"
232 play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
233 type="application/x-shockwave-flash"
234 pluginspage="http://www.macromedia.com/go/getflashplayer">
235 </embed>
236 318
237 </object> 319 setState -- sets the current state (1) from the appletName_state HTML element if this contains an <xml>...</xml> string
238 END_OBJECT_TEXT 320 -- if the value contains <xml>restart_applet</xml> then set the current state to ww_applet_list[appletName].initialState
239 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
240=cut 327=cut
241 328
242use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT'; 329=head4 Requirements for applets
243 <form></form>
244 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
245 id="$appletName" width="500" height="375"
246 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
247 <param name="movie" value="$codebase/$appletName.swf" />
248 <param name="quality" value="high" />
249 <param name="bgcolor" value="#869ca7" />
250 <param name="allowScriptAccess" value="sameDomain" />
251 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="#869ca7"
252 width="550" height="400" name="$appletName" align="middle" id="$appletID"
253 play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
254 type="application/x-shockwave-flash"
255 pluginspage="http://www.macromedia.com/go/getflashplayer">
256 </embed>
257 330
258 </object> 331The following methods are desirable in an applet that preserves state in a WW question. None of them are required.
259END_OBJECT_TEXT 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
260 397
261 398
262sub new { 399sub new {
263 my $class = shift; 400 my $class = shift;
264 my $self = { 401 my $self = {
265 host =>'',
266 port => '',
267 path => '',
268 appletName =>'', 402 appletName => '',
403 appletId => '', #always use identical applet Id's and applet Names
404 archive => '',
405 code => '',
269 codebase=>'', 406 codebase => '',
270 appletId =>'',
271 params =>undef, 407 params =>undef,
272 base64_xmlString => 'foobar', 408 width => 550,
409 height => 400,
410 bgcolor => "#869ca7",
411 configuration => '', # configuration defining the applet
412 initialState => '', # initial state.
413 getStateAlias => 'getXML',
414 setStateAlias => 'setXML',
415 configAlias => '', # deprecated
416 getConfigAlias => 'getConfig',
417 setConfigAlias => 'setConfig',
273 initializeActionAlias => 'setupProblem', 418 initializeActionAlias => 'setXML',
419 maxInitializationAttempts => 5, # number of attempts to initialize applet
274 submitActionAlias => 'checkAnswer', 420 submitActionAlias => 'getXML',
275 returnFieldName => 'receivedField', 421 submitActionScript => '', # script executed on submitting the WW question
422 answerBoxAlias => 'answerBox',
423 answerBox => '', # deprecated
424 returnFieldName => '', # deprecated
276 headerText => DEFAULT_HEADER_TEXT(), 425 headerText => DEFAULT_HEADER_TEXT(),
277 objectText => DEFAULT_OBJECT_TEXT(), 426 objectText => '',
427 debugMode => 0,
278 @_, 428 @_,
279 }; 429 };
280 bless $self, $class; 430 bless $self, $class;
281 #$self -> _initialize(@_); 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>');
282 return $self; 442 return $self;
443}
444sub appletId {
445 appletName(@_);
446}
447sub appletName {
448 my $self = shift;
449 $self->{appletName} = shift ||$self->{appletName}; # replace the current appletName if non-empty
450 $self->{appletName};
451}
452sub archive {
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
460 $self->{code};
461}
462sub codebase {
463 my $self = shift;
464 $self->{codebase} = shift ||$self->{codebase}; # replace the current codebase if non-empty
465 $self->{codebase};
466}
467sub params {
468 my $self = shift;
469 if (ref($_[0]) =~/HASH/) {
470 $self->{params} = shift;
471 } elsif ( !defined($_[0]) or $_[0] =~ '') {
472 # do nothing (read)
473 } else {
474 warn "You must enter a reference to a hash for the parameter list";
475 }
476 $self->{params};
477}
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};
283} 493}
284 494
285sub header { 495sub header {
286 my $self = shift; 496 my $self = shift;
287 if ($_[0] eq "reset") { # $applet->header('reset'); erases default header text. 497 if ($_[0] eq "reset") { # $applet->header('reset'); erases default header text.
298 } else { 508 } else {
299 $self->{objectText} .= join("",@_); 509 $self->{objectText} .= join("",@_);
300 } 510 }
301 $self->{objectText}; 511 $self->{objectText};
302} 512}
303sub params { 513sub configuration {
514 my $self = shift;
304 my $self = shift; 515 my $str = shift;
305 if (ref($_[0]) =~/HASH/) { 516 $self->{configuration} = $str || $self->{configuration}; # replace the current string if non-empty
306 $self->{params} = shift; 517 $self->{configuration} =~ s/\n//g;
307 } elsif ( $_[0] =~ '') { 518 $self->{configuration};
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} 519}
314 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
315sub initializeActionAlias { 551sub initializeActionAlias {
316 my $self = shift; 552 my $self = shift;
317 $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
318 $self->{initializeActionAlias}; 554 $self->{initializeActionAlias};
319} 555}
320 556sub maxInitializationAttempts {
557 my $self = shift;
558 $self->{maxInitializationAttempts} = shift || $self->{maxInitializationAttempts};
559 $self->{maxInitializationAttempts};
560}
321sub submitActionAlias { 561sub submitActionAlias {
322 my $self = shift; 562 my $self = shift;
323 $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
324 $self->{submitActionAlias}; 564 $self->{submitActionAlias};
325} 565}
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;
592 my $str = shift;
593 warn "use $self->configuration instead of $self->config. Internally this string is ascii, not base64 encoded", join(' ', caller());
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});
597}
598sub state {
599 my $self = shift;
600 my $str = shift;
601 warn "use $self->initialState instead of $self->state. Internally this string is ascii, not base64 encoded", join(' ', caller());
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
326sub returnFieldName { 618sub returnFieldName {
327 my $self = shift; 619 my $self = shift;
328 $self->{returnFieldName} = shift ||$self->{returnFieldName}; # replace the current contents if non-empty 620 warn "use answerBoxName instead of returnFieldName";
329 $self->{returnFieldName};
330} 621}
331sub codebase { 622sub answerBox {
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; 623 my $self = shift;
349 $self->{base64_xmlString} = encode_base64($str) ||$self->{base64_xmlString}; # replace the current string if non-empty 624 warn "use answerBoxAlias instead of AnswerBox";
350 $self->{base64_xmlString} =~ s/\n//g;
351 decode_base64($self->{base64_xmlString});
352} 625}
353 626sub configAlias {
354sub base64_xmlString{
355 my $self = shift; 627 my $self = shift;
356 $self->{base64_xmlString} = shift ||$self->{base64_xmlString}; # replace the current string if non-empty 628 warn "use setConfigAlias instead of configAlias";
357 $self->{base64_xmlString};
358} 629}
359 630#########################
360#FIXME 631#FIXME
361# need to be able to adjust header material 632# need to be able to adjust header material
362 633
363sub insertHeader { 634sub insertHeader {
364 my $self = shift; 635 my $self = shift;
636
365 my $codebase = $self->{codebase}; 637 my $codebase = $self->codebase;
366 my $appletId = $self->{appletId}; 638 my $appletId = $self->appletId;
367 my $appletName = $self->{appletName}; 639 my $appletName = $self->appletName;
368 my $base64_xmlString = $self->{base64_xmlString}; 640 my $initializeActionAlias = $self->initializeActionAlias;
369 my $initializeAction = $self->{initializeActionAlias};
370 my $submitAction = $self->{submitActionAlias}; 641 my $submitActionScript = $self->submitActionScript;
371 my $returnFieldName= $self->{returnFieldName}; 642 my $setStateAlias = $self->setStateAlias;
643 my $getStateAlias = $self->getStateAlias;
644
645 my $setConfigAlias = $self->setConfigAlias;
646 my $getConfigAlias = $self->getConfigAlias;
647 my $maxInitializationAttempts = $self->maxInitializationAttempts;
648 my $debugMode = ($self->debugMode) ? "1": "0";
649 my $answerBoxAlias = $self->{answerBoxAlias};
372 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
665
373 $headerText =~ s/(\$\w+)/$1/gee; # interpolate variables p17 of Cookbook 666 $headerText =~ s/(\$\w+)/$1/gee; # interpolate variables p17 of Cookbook
374 667
375 return $headerText; 668 return $headerText;
376 669
377 670
378} 671}
379 672
380 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>
381# <script language="javascript"> 685 <script language="JavaScript">
382# if (AC_FL_RunContent == 0) { 686
383# alert("This page requires AC_RunActiveContent.js."); 687 function getApplet(appletName) {
384# } else { 688 var isIE = navigator.appName.indexOf("Microsoft") != -1; // ie8 uses this for java and firefox uses it for flash.
385# AC_FL_RunContent( 689 var obj = (isIE) ? window[appletName] : window.document[appletName];
386# 'codebase', 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0', 690 //return window.document[appletName];
387# 'width', '100%', 691 if (!obj) { obj = document.getElementById(appletName) }
388# 'height', '100%', 692 if (obj ) { //RECENT FIX to ==
389# 'src', 'http://$codebase/$appletName', 693 return( obj );
390# 'quality', 'high', 694 } else {
391# 'pluginspage', 'http://www.macromedia.com/go/getflashplayer', 695 alert ("can't find applet " + appletName);
392# 'align', 'middle', 696 }
393# 'play', 'true', 697 }
394# 'loop', 'true', 698
395# 'scale', 'showall', 699 //////////////////////////////////////////////////////////
396# 'wmode', 'window', 700 //TEST code
397# 'devicefont', 'false', 701 //
398# 'id', '$appletId', 702 //
399# 'bgcolor', '#ffffcc', 703 //////////////////////////////////////////////////////////
400# 'name', '$appletName', 704
401# 'menu', 'true', 705 ww_applet_list["$appletName"] = new ww_applet("$appletName");
402# 'allowFullScreen', 'false', 706
403# 'allowScriptAccess','sameDomain', 707
404# 'movie', '$appletName', 708 ww_applet_list["$appletName"].code = "$code";
405# 'salign', '' 709 ww_applet_list["$appletName"].codebase = "$codebase";
406# ); //end AC code 710 ww_applet_list["$appletName"].appletID = "$appletID";
407# } 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
408# </script> 725 </script>
726
727END_HEADER_SCRIPT
728
729
730
409sub insertObject { 731sub insertObject {
410 my $self = shift; 732 my $self = shift;
733 my $code = $self->{code};
411 my $codebase = $self->{codebase}; 734 my $codebase = $self->{codebase};
412 my $appletId = $self->{appletId}; 735 my $appletId = $self->{appletName};
413 my $appletName = $self->{appletName}; 736 my $appletName = $self->{appletName};
414 $codebase = findAppletCodebase("$appletName.swf") unless $codebase; 737 my $archive = $self->{archive};
738 my $width = $self->{width};
739 my $height = $self->{height};
740 my $applet_bgcolor = $self->{bgcolor};
741 my $javaParameters = '';
742 my $flashParameters = '';
743 my %param_hash = %{$self->params()};
744 foreach my $key (keys %param_hash) {
745 $javaParameters .= qq!<param name ="$key" value = "$param_hash{$key}">\n!;
746 $flashParameters .= uri_escape($key).'='.uri_escape($param_hash{$key}).'&';
747 }
748 $flashParameters =~ s/\&$//; # trim last &
749
750
415 $objectText = $self->{objectText}; 751 $objectText = $self->{objectText};
416 $objectText =~ s/(\$\w+)/$1/gee; 752 $objectText =~ s/(\$\w+)/$1/gee;
417 return $objectText; 753 return $objectText;
418} 754}
419 755
420sub initialize { 756
757###############################################################################################################
758#
759# FLASH APPLET PACKAGE
760#
761###############################################################################################################
762
763package FlashApplet;
764@ISA = qw(Applet);
765
766
767=head2 Insertion HTML code for FlashApplet
768
769=pod
770
771The secret to making this applet work with IE in addition to normal browsers
772is the addition of the C(<form></form>) construct just before the object.
773
774For some reason IE has trouble locating a flash object which is contained
775within a form. Adding this second blank form with the larger problemMainForm
776seems to solve the problem.
777
778This follows method2 of the advice given in url(http://kb.adobe.com/selfservice/viewContent.do?externalId=kb400730&sliceId=2)
779Method1 and methods involving SWFObject(Geoff Stearns) and SWFFormFix (Steve Kamerman) have yet to be fully investigated:
780http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
781http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
782
783 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
784 <form></form>
785 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
786 id="$appletName" width="500" height="375"
787 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
788 <param name="movie" value="$codebase/$appletName.swf" />
789 <param name="quality" value="high" />
790 <param name="bgcolor" value="$applet_bgcolor" />
791 <param name="allowScriptAccess" value="sameDomain" />
792 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="$applet_bgcolor"
793 width="$width" height="$height" name="$appletName" align="middle" id="$appletName"
794 play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
795 type="application/x-shockwave-flash"
796 pluginspage="http://www.macromedia.com/go/getflashplayer">
797 </embed>
798
799 </object>
800 END_OBJECT_TEXT
801
802
803=cut
804
805use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
806<<<<<<< .working
807
808 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
809 id="$appletName" width="500" height="375"
810=======
811
812 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
813 id="$appletName" width="500" height="375"
814>>>>>>> .merge-right.r6319
815 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab">
816 <param name="movie" value="$codebase/$appletName.swf" />
817 <param name="quality" value="high" />
818 <param name="bgcolor" value="$applet_bgcolor" />
819 <param name="allowScriptAccess" value="sameDomain" />
820 <param name="FlashVars" value="$flashParameters"/>
821 <embed src="$codebase/$appletName.swf" quality="high" bgcolor="$applet_bgcolor"
822 width="$width" height="$height" name="$appletName" align="middle" id="$appletName"
823 play="true" loop="false" quality="high" allowScriptAccess="sameDomain"
824 type="application/x-shockwave-flash"
825 pluginspage="http://www.macromedia.com/go/getflashplayer"
826 FlashVars="$flashParameters">
827 </embed>
828
829 </object>
830END_OBJECT_TEXT
831
832sub new {
421 my $self = shift; 833 my $class = shift;
422 return q{ 834 $class -> SUPER::new( objectText => DEFAULT_OBJECT_TEXT(),
423 <script> 835 @_
424 initialize(); 836 );
425 // this should really be done in the <body> tag 837
838}
839
840###############################################################################################################
841#
842# JAVA APPLET PACKAGE
843#
844###############################################################################################################
845
846package JavaApplet;
847@ISA = qw(Applet);
848
849=head2 Insertion HTML code for JavaApplet
850
851=pod
852
853The secret to making this applet work with IE in addition to normal browsers
854is the addition of the C(<form></form>) construct just before the object.
855
856For some reason IE has trouble locating a flash object which is contained
857within a form. Adding this second blank form with the larger problemMainForm
858seems to solve the problem.
859
860This follows method2 of the advice given in url(http://kb.adobe.com/selfservice/viewContent.do?externalId=kb400730&sliceId=2)
861Method1 and methods involving SWFObject(Geoff Stearns) and SWFFormFix (Steve Kamerman) have yet to be fully investigated:
862http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
863http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
864
865 use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
866 <form></form>
867 <applet
868 code = "$code"
869 codebase = "$codebase"
870 archive = "$archive"
871 name = "$appletName"
872 id = "$appletName"
873 width = "$width"
874 height = "$height"
875 MAYSCRIPT
876 >
877 $javaParameters
878 </applet>
879 END_OBJECT_TEXT
880
881=cut
882
883
884=pod
885
886use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
887
888 <applet
889 code = "$code"
890 codebase = "$codebase"
891 archive = "$archive"
892 name = "$appletName"
893 id = "$appletName"
894 width = "$width"
895 height = "$height"
896 bgcolor = "$applet_bgcolor"
897 MAYSCRIPT
898 >
899 $javaParameters
900
901 Sorry, the Applet could not be started. Please make sure that
902Java 1.4.2 (or later) is installed and activated.
903(<a href="http://java.sun.com/getjava">click here to install Java now</a>)
904 </applet>
905END_OBJECT_TEXT
906
907=cut
908
909# classid = "java:MyApplet.class"
910
911
912use constant DEFAULT_OBJECT_TEXT =><<'END_OBJECT_TEXT';
913
914<object
915 id = "$appletName"
916 name = "$appletName"
917 code = "$code"
918 type = "application/x-java-applet"
919 codebase = "$codebase"
920 archive = "$archive"
921 height = "$height"
922 width = "$width"
923 bgcolor = "$applet_bgcolor"
924 >
925 <PARAM NAME="MAYSCRIPT" VALUE="true">
926 $javaParameters
927
928 Sorry, the Applet could not be started. Please make sure that
929 Java 1.4.2 (or later) is installed and activated.
930 (<a href="http://java.sun.com/getjava">click here to install Java now</a>)
931</object>
932END_OBJECT_TEXT
933
934
935
936sub new {
937 my $class = shift;
938 $class -> SUPER::new( objectText => DEFAULT_OBJECT_TEXT(),
939 @_
940 );
941
942}
943
944###############################################################################################################
945#
946# CANVAS APPLET PACKAGE
947#
948###############################################################################################################
949
950package CanvasApplet;
951@ISA = qw(Applet);
952
953
954=head2 Insertion HTML code for CanvasApplet
955
956=pod
957
958The secret to making this applet work with IE in addition to normal browsers
959is the addition of the C(<form></form>) construct just before the object.
960
961For some reason IE has trouble locating a flash object which is contained
962within a form. Adding this second blank form with the larger problemMainForm
963seems to solve the problem.
964
965This follows method2 of the advice given in url(http://kb.adobe.com/selfservice/viewContent.do?externalId=kb400730&sliceId=2)
966Method1 and methods involving SWFObject(Geoff Stearns) and SWFFormFix (Steve Kamerman) have yet to be fully investigated:
967http://devel.teratechnologies.net/swfformfix/swfobject_swfformfix_source.js
968http://www.teratechnologies.net/stevekamerman/index.php?m=01&y=07&entry=entry070101-033933
969
970use constant CANVAS_OBJECT_TEXT =><<'END_OBJECT_TEXT';
971 <form></form>
972 <script> var width = 200; var height = 200;</script>
973 <canvas name="cv" id="cv" data-src="http://localhost/webwork2_files/js/sketchgraphhtml5b/SketchGraph.pjs" width="400" height="400"></canvas>
974END_OBJECT_TEXT
975
976
977
978=cut
979
980
981use constant CANVAS_OBJECT_HEADER_TEXT =><<'END_HEADER_SCRIPT';
982 <script src="/webwork2_files/js/Base64.js" language="javascript">
983 </script>
984 <script src="/webwork2_files/js/ww_applet_support.js" language="javascript">
985 //upload functions stored in /opt/webwork/webwork2/htdocs/js ...
986
987 </script>
988 <script language="JavaScript">
989
990
991
992 //////////////////////////////////////////////////////////
993 //CANVAS OBJECT HEADER CODE
994 //
995 //////////////////////////////////////////////////////////
996
997 ww_applet_list["$appletName"] = new ww_applet("$appletName");
998
999
1000 ww_applet_list["$appletName"].code = "$code";
1001 ww_applet_list["$appletName"].codebase = "$codebase";
1002 ww_applet_list["$appletName"].appletID = "$appletID";
1003 ww_applet_list["$appletName"].base64_state = "$base64_initializationState";
1004 ww_applet_list["$appletName"].initialState = Base64.decode("$base64_initialState");
1005 ww_applet_list["$appletName"].configuration = Base64.decode("$base64_configuration");;
1006 ww_applet_list["$appletName"].getStateAlias = "$getStateAlias";
1007 ww_applet_list["$appletName"].setStateAlias = "$setStateAlias";
1008 ww_applet_list["$appletName"].setConfigAlias = "$setConfigAlias";
1009 ww_applet_list["$appletName"].getConfigAlias = "$getConfigAlias";
1010 ww_applet_list["$appletName"].initializeActionAlias = "$initializeActionAlias";
1011 ww_applet_list["$appletName"].submitActionAlias = "$submitActionAlias";
1012 ww_applet_list["$appletName"].submitActionScript = Base64.decode("$base64_submitActionScript");
1013 ww_applet_list["$appletName"].answerBoxAlias = "$answerBoxAlias";
1014 ww_applet_list["$appletName"].maxInitializationAttempts = $maxInitializationAttempts;
1015 ww_applet_list["$appletName"].debugMode = "$debugMode";
1016
1017
1018 ww_applet_list["$appletName"].reportsLoaded = 1;
1019 ww_applet_list["$appletName"].object = $appletName;
1020
1021 function getApplet(appletName) {
1022 //var isIE = navigator.appName.indexOf("Microsoft") != -1;
1023 //var obj = (isIE) ? window[appletName] : window.document[appletName];
1024 //return window.document[appletName];
1025 var obj = ww_applet_list[appletName].object; // define fake applet for this object
1026 if (obj && (obj.name == appletName)) { //RECENT FIX to ==
1027 //alert("getting fake applet " + obj.name);
1028 return( obj );
1029 } else {
1030 alert ("can't find fake applet " + appletName + " in object "+obj.name);
1031 }
1032 }
426 </script> 1033 </script>
427 }; 1034
1035END_HEADER_SCRIPT
428 1036
1037
1038#FIXME need to get rid of hardcoded url
1039
1040
1041use constant CANVAS_OBJECT_TEXT =><<'END_OBJECT_TEXT';
1042
1043 <canvas name="cv" id="cv" data-src="/webwork2_files/js/sketchgraphhtml5b/SketchGraph.pjs" width="$width" height="$height"></canvas>
1044END_OBJECT_TEXT
1045
1046sub new {
1047 my $class = shift;
1048 $class -> SUPER::new( objectText => CANVAS_OBJECT_TEXT(),
1049 headerText => CANVAS_OBJECT_HEADER_TEXT(),
1050 @_
1051 );
1052
429} 1053}
1054
430 1055
4311; 10561;

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9