[system] / trunk / pg / macros / AppletObjects.pl Repository:
ViewVC logotype

Diff of /trunk/pg/macros/AppletObjects.pl

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

Revision 6296 Revision 6297
69sub JavaApplet { 69sub JavaApplet {
70 return new JavaApplet(@_); 70 return new JavaApplet(@_);
71 71
72} 72}
73 73
74sub CanvasApplet {
75 return new CanvasApplet(@_);
76}
74package Applet; 77package Applet;
75 78
76 79
77 80
78=head2 Methods 81=head2 Methods
94=pod 97=pod
95 98
96Inserts applet at this point in the HTML code. (In TeX mode a message "Applet" is written.) This method 99Inserts applet at this point in the HTML code. (In TeX mode a message "Applet" is written.) This method
97also adds the applets header material into the header portion of the HTML page. It effectively inserts 100also adds the applets header material into the header portion of the HTML page. It effectively inserts
98the outputs of both C<$applet-E<gt>insertHeader> and C<$applet-E<gt>insertObject> (defined in L<Applet.pm> ) 101the outputs of both C<$applet-E<gt>insertHeader> and C<$applet-E<gt>insertObject> (defined in L<Applet.pm> )
99in the appropriate places. 102in the appropriate places. In addition it creates a hidden answer blank for storing the state of the applet
103and provides mechanisms for revealing the state while debugging the applet.
100 104
101Note: This method is defined here rather than in Applet.pl because it 105Note: This method is defined here rather than in Applet.pl because it
102 requires access to the RECORD_FORM_LABEL subroutine 106 requires access to the RECORD_FORM_LABEL subroutine
103 and to the routine accessing the stored values of the answers. These are defined in main::. 107 and to the routine accessing the stored values of the answers. These are defined in main::.
108 FIXME -- with the creation of the PGcore object this can now be rewritten
104 109
105=cut 110=cut
106 111
107sub insertAll { ## inserts both header text and object text 112sub insertAll { ## inserts both header text and object text
108 my $self = shift; 113 my $self = shift;
109 my %options = @_; 114 my %options = @_;
110 115
116
117 ##########################
118 # determine debug mode
111 # debugMode can be turned on by setting it to 1 in either the applet definition or at insertAll time 119 # debugMode can be turned on by setting it to 1 in either the applet definition or at insertAll time
120 ##########################
121
112 my $debugMode = (defined($options{debug}) and $options{debug}>0) ? $options{debug} : 0; 122 my $debugMode = (defined($options{debug}) and $options{debug}>0) ? $options{debug} : 0;
113 my $includeAnswerBox = (defined($options{includeAnswerBox}) and $options{includeAnswerBox}==1) ? 1 : 0; 123 my $includeAnswerBox = (defined($options{includeAnswerBox}) and $options{includeAnswerBox}==1) ? 1 : 0;
114 $debugMode = $debugMode || $self->debugMode; 124 $debugMode = $debugMode || $self->debugMode;
115 $self->debugMode( $debugMode); 125 $self->debugMode( $debugMode);
116 126
117 127
118 my $reset_button = $options{reinitialize_button} || 0; 128 my $reset_button = $options{reinitialize_button} || 0;
119 warn qq! please change "reset_button=>1" to "reinitialize_button=>1" in the applet->installAll() command \n! if defined($options{reset_button}); 129 warn qq! please change "reset_button=>1" to "reinitialize_button=>1" in the applet->installAll() command \n! if defined($options{reset_button});
130
131 ##########################
132 # Get data to be interpolated into the HTML code defined in this subroutine
133 #
134 # This consists of the name of the applet and the names of the routines
135 # to get and set State of the applet (which is done every time the question page is refreshed
136 # and to get and set Config which is the initial configuration the applet is placed in
137 # when the question is first viewed. It is also the state which is returned to when the
138 # reset button is pressed.
139 ##########################
140
120 # prepare html code for storing state 141 # prepare html code for storing state
121 my $appletName = $self->appletName; 142 my $appletName = $self->appletName;
122 my $appletStateName = "${appletName}_state"; 143 my $appletStateName = "${appletName}_state"; # the name of the hidden "answer" blank storing state FIXME -- use persistent data instead
123 my $getState = $self->getStateAlias; 144 my $getState = $self->getStateAlias; # names of routines for this applet
124 my $setState = $self->setStateAlias; 145 my $setState = $self->setStateAlias;
125 my $getConfig = $self->getConfigAlias; 146 my $getConfig = $self->getConfigAlias;
126 my $setConfig = $self->setConfigAlias; 147 my $setConfig = $self->setConfigAlias;
127 148
128 my $base64_initialState = encode_base64($self->initialState); 149 my $base64_initialState = encode_base64($self->initialState);
129 main::RECORD_FORM_LABEL($appletStateName); #this insures that they'll be saved from one invocation to the next 150 main::RECORD_FORM_LABEL($appletStateName); #this insures that the state will be saved from one invocation to the next
151 # FIXME -- with PGcore the persistant data mechanism can be used instead
130 my $answer_value = ''; 152 my $answer_value = '';
131 153
154 ##########################
155 # implement the sticky answer mechanism for maintaining the applet state when the question page is refreshed
156 # This is important for guest users for whom no permanent record of answers is recorded.
157 ##########################
158
132 if ( defined( ${$main::inputs_ref}{$appletStateName} ) and ${$main::inputs_ref}{$appletStateName} =~ /\S/ ) { 159 if ( defined( ${$main::inputs_ref}{$appletStateName} ) and ${$main::inputs_ref}{$appletStateName} =~ /\S/ ) {
133 $answer_value = ${$main::inputs_ref}{$appletStateName}; 160 $answer_value = ${$main::inputs_ref}{$appletStateName};
134 } elsif ( defined( $main::rh_sticky_answers->{$appletStateName} ) ) { 161 } elsif ( defined( $main::rh_sticky_answers->{$appletStateName} ) ) {
135 warn "type of sticky answers is ", ref( $main::rh_sticky_answers->{$appletStateName} ); 162 warn "type of sticky answers is ", ref( $main::rh_sticky_answers->{$appletStateName} );
136 $answer_value = shift( @{ $main::rh_sticky_answers->{$appletStateName} }); 163 $answer_value = shift( @{ $main::rh_sticky_answers->{$appletStateName} });
137 } 164 }
138 $answer_value =~ tr/\\$@`//d; #`## make sure student answers can not be interpolated by e.g. EV3 165 $answer_value =~ tr/\\$@`//d; #`## make sure student answers can not be interpolated by e.g. EV3
139 $answer_value =~ s/\s+/ /g; ## remove excessive whitespace from student answer 166 $answer_value =~ s/\s+/ /g; ## remove excessive whitespace from student answer
140 ####### 167
141 # insert a hidden variable to hold the applet's state (debug =>1 makes it visible for debugging and provides debugging buttons) 168 ##########################
142 ####### 169 # insert a hidden answer blank to hold the applet's state
170 # (debug =>1 makes it visible for debugging and provides debugging buttons)
171 ##########################
172
173
174 ##########################
175 # Regularize the applet's state -- which could be in either XML format or in XML format encoded by base64
176 # In rare cases it might be simple string -- protect against that by putting xml tags around the state
177 # The result:
178 # $base_64_encoded_answer_value -- a base64 encoded xml string
179 # $decoded_answer_value -- and xml string
180 ##########################
181
143 my $base_64_encoded_answer_value; 182 my $base_64_encoded_answer_value;
144 my $decoded_answer_value; 183 my $decoded_answer_value;
145 if ( $answer_value =~/<XML|<?xml/i) { 184 if ( $answer_value =~/<XML|<?xml/i) {
146 $base_64_encoded_answer_value = encode_base64($answer_value); 185 $base_64_encoded_answer_value = encode_base64($answer_value);
147 $decoded_answer_value = $answer_value; 186 $decoded_answer_value = $answer_value;
152 } else { #WTF?? apparently we don't have XML tags 191 } else { #WTF?? apparently we don't have XML tags
153 $answer_value = "<xml>$answer_value</xml>"; 192 $answer_value = "<xml>$answer_value</xml>";
154 $base_64_encoded_answer_value = encode_base64($answer_value); 193 $base_64_encoded_answer_value = encode_base64($answer_value);
155 $decoded_answer_value = $answer_value; 194 $decoded_answer_value = $answer_value;
156 } 195 }
157 } 196 }
158 $base_64_encoded_answer_value =~ s/\r|\n//g; # get rid of line returns 197 $base_64_encoded_answer_value =~ s/\r|\n//g; # get rid of line returns
198
199 ##########################
200 # Construct answer blank for storing state -- in both regular (answer blank hidden)
201 # and debug (answer blank displayed) modes.
202 ##########################
203
204 ##########################
159 # debug version of the applet state answerBox and controls 205 # debug version of the applet state answerBox and controls (all displayed)
206 # stored in
207 # $debug_input_element
208 ##########################
209
160 my $debug_input_element = qq!\n<textarea rows="4" cols="80" 210 my $debug_input_element = qq!\n<textarea rows="4" cols="80"
161 name = "$appletStateName" id = "$appletStateName">$decoded_answer_value</textarea><br/>!; 211 name = "$appletStateName" id = "$appletStateName">$decoded_answer_value</textarea><br/>!;
162 if ($getState=~/\S/) { # if getStateAlias is not an empty string 212 if ($getState=~/\S/) { # if getStateAlias is not an empty string
163 $debug_input_element .= qq! 213 $debug_input_element .= qq!
164 <input type="button" value="$getState" 214 <input type="button" value="$getState"
165 onClick="debugText=''; 215 onClick=" debugText='';
166 ww_applet_list['$appletName'].getState(); 216 ww_applet_list['$appletName'].getState() ;
167 if (debugText) {alert(debugText)};" 217 if (debugText) {alert(debugText)};"
168 >!; 218 >!;
169 } 219 }
170 if ($setState=~/\S/) { # if setStateAlias is not an empty string 220 if ($setState=~/\S/) { # if setStateAlias is not an empty string
171 $debug_input_element .= qq! 221 $debug_input_element .= qq!
189 onClick="debugText=''; 239 onClick="debugText='';
190 ww_applet_list['$appletName'].setConfig(); 240 ww_applet_list['$appletName'].setConfig();
191 if (debugText) {alert(debugText)};" 241 if (debugText) {alert(debugText)};"
192 >!; 242 >!;
193 } 243 }
244
245 ##########################
246 # Construct answerblank for storing state
247 # using either the debug version (defined above) or the non-debug version
248 # where the state variable is hidden and the definition is very simple
249 # stored in
250 # $state_input_element
251 ##########################
194 252
195 my $state_input_element = ($debugMode) ? $debug_input_element : 253 my $state_input_element = ($debugMode) ? $debug_input_element :
196 qq!\n<input type="hidden" name = "$appletStateName" id = "$appletStateName" value ="$base_64_encoded_answer_value">!; 254 qq!\n<input type="hidden" name = "$appletStateName" id = "$appletStateName" value ="$base_64_encoded_answer_value">!;
255
256 ##########################
257 # Construct the reset button string (this is blank if the button is not to be displayed
258 # $reset_button_str
259 ##########################
260
197 my $reset_button_str = ($reset_button) ? 261 my $reset_button_str = ($reset_button) ?
198 qq!<input type='submit' name='previewAnswers' id ='previewAnswers' value='return this question to its initial state' onClick="setAppletStateToRestart('$appletName')"><br/>! 262 qq!<input type='submit' name='previewAnswers' id ='previewAnswers' value='return this question to its initial state'
263 onClick="setAppletStateToRestart('$appletName')"><br/>!
199 : '' ; 264 : '' ;
200 # <input type="button" value="reinitialize applet" onClick="getQE('$appletStateName').value='$base64_initialState'"/><br/> 265
201 # always base64 encode the hidden answer value to prevent problems with quotes. 266 ##########################
202 # 267 # Combine the state_input_button and the reset button into one string
268 # $state_storage_html_code
269 ##########################
270
271
203 $state_storage_html_code = qq!<input type="hidden" name="previous_$appletStateName" id = "previous_$appletStateName" value = "$base_64_encoded_answer_value">! 272 $state_storage_html_code = qq!<input type="hidden" name="previous_$appletStateName" id = "previous_$appletStateName" value = "$base_64_encoded_answer_value">!
204 . $state_input_element. $reset_button_str 273 . $state_input_element. $reset_button_str
205 ; 274 ;
275 ##########################
276 # Construct the answerBox (if it is requested). This is a default input box for interacting
277 # with the applet. It is separate from maintaining state but it often contains similar data.
278 # Additional answer boxes or buttons can be defined but they must be explicitly connected to
279 # the applet with additional javaScript commands.
280 # Result: $answerBox_code
281 ##########################
282
206 my $answerBox_code =''; 283 my $answerBox_code ='';
207 if ($includeAnswerBox) { 284 if ($includeAnswerBox) {
208 if ($debugMode) { 285 if ($debugMode) {
209 286
210 $answerBox_code = $main::BR . main::NAMED_ANS_RULE('answerBox', 50 ); 287 $answerBox_code = $main::BR . main::NAMED_ANS_RULE('answerBox', 50 );
214 !; 291 !;
215 } else { 292 } else {
216 $answerBox_code = main::NAMED_HIDDEN_ANS_RULE('answerBox', 50 ); 293 $answerBox_code = main::NAMED_HIDDEN_ANS_RULE('answerBox', 50 );
217 } 294 }
218 } 295 }
219 ####### 296
297 ##########################
220 # insert header material 298 # insert header material
221 ####### 299 ##########################
222 main::HEADER_TEXT($self->insertHeader()); 300 main::HEADER_TEXT($self->insertHeader());
223 # update the debug mode for this applet. 301 # update the debug mode for this applet.
224 main::HEADER_TEXT(qq!<script> ww_applet_list["$appletName"].debugMode = $debugMode;\n</script>!); 302 main::HEADER_TEXT(qq!<script> ww_applet_list["$appletName"].debugMode = $debugMode;\n</script>!);
303
304 ##########################
305 # Return HTML or TeX strings to be included in the body of the page
306 ##########################
307
225 return main::MODES(TeX=>' {\bf applet } ', HTML=>$self->insertObject.$main::BR.$state_storage_html_code.$answerBox_code); 308 return main::MODES(TeX=>' {\bf applet } ', HTML=>$self->insertObject.$main::BR.$state_storage_html_code.$answerBox_code);
226} 309}
227 310
228=head3 Example problem 311=head3 Example problem
229 312

Legend:
Removed from v.6296  
changed lines
  Added in v.6297

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9