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.13 2008/11/19 04:39:43 gage Exp $ |
4 | # $CVSHeader: pg/lib/Applet.pm,v 1.14 2009/01/28 17:07:08 gage Exp $ |
5 | # |
5 | # |
6 | # This program is free software; you can redistribute it and/or modify it under |
6 | # This program is free software; you can redistribute it and/or modify it under |
7 | # the terms of either: (a) the GNU General Public License as published by the |
7 | # the terms of either: (a) the GNU General Public License as published by the |
8 | # Free Software Foundation; either version 2, or (at your option) any later |
8 | # Free Software Foundation; either version 2, or (at your option) any later |
9 | # version, or (b) the "Artistic License" which comes with this package. |
9 | # version, or (b) the "Artistic License" which comes with this package. |
… | |
… | |
108 | |
108 | |
109 | getApplet(appletName) -- finds the applet path in the DOM |
109 | getApplet(appletName) -- finds the applet path in the DOM |
110 | |
110 | |
111 | submitAction() -- calls the submit action of the applets |
111 | submitAction() -- calls the submit action of the applets |
112 | |
112 | |
113 | initializeAction() -- calls the initialize action of the applets |
113 | initializeWWquestion() -- calls the initialize action of the applets |
114 | |
114 | |
115 | getQE(name) -- gets an HTML element of the question by name |
115 | getQE(name) -- gets an HTML element of the question by name |
116 | or by id. Be sure to keep all names and ids |
116 | or by id. Be sure to keep all names and ids |
117 | unique within a given PG question. |
117 | unique within a given PG question. |
118 | |
118 | |
… | |
… | |
177 | base64_state returns the base64 encoded version of the state stored in the applet object. |
177 | base64_state returns the base64 encoded version of the state stored in the applet object. |
178 | |
178 | |
179 | initializeActionAlias -- (default: initializeAction) the name of the javaScript subroutine called to initialize the applet (some overlap with config/ and setState |
179 | initializeActionAlias -- (default: initializeAction) the name of the javaScript subroutine called to initialize the applet (some overlap with config/ and setState |
180 | submitActionAlias -- (default: submitAction)the name of the javaScript subroutine called when the submit button of the |
180 | submitActionAlias -- (default: submitAction)the name of the javaScript subroutine called when the submit button of the |
181 | .pg question is pressed. |
181 | .pg question is pressed. |
182 | |
182 | answerBox -- name of answer box to return answer to: default defaultAnswerBox |
183 | returnFieldName |
183 | getAnswer -- (formerly sendData) get student answer from applet and place in answerBox |
|
|
184 | returnFieldName -- (deprecated) synonmym for answerBox |
184 | |
185 | |
185 | |
186 | |
186 | =cut |
187 | =cut |
187 | |
188 | |
188 | |
189 | |
… | |
… | |
204 | setStateAlias => 'setXML', |
205 | setStateAlias => 'setXML', |
205 | configAlias => 'config', |
206 | configAlias => 'config', |
206 | initializeActionAlias => 'setXML', |
207 | initializeActionAlias => 'setXML', |
207 | submitActionAlias => 'getXML', |
208 | submitActionAlias => 'getXML', |
208 | submitActionScript => '', # script executed on submitting the WW question |
209 | submitActionScript => '', # script executed on submitting the WW question |
209 | returnFieldName => 'receivedField', |
210 | answerBox => 'answerBox', |
210 | headerText => DEFAULT_HEADER_TEXT(), |
211 | headerText => DEFAULT_HEADER_TEXT(), |
211 | objectText => '', |
212 | objectText => '', |
212 | debug => 0, |
213 | debug => 0, |
213 | @_, |
214 | @_, |
214 | }; |
215 | }; |
… | |
… | |
280 | $self->{configAlias} = shift ||$self->{configAlias}; # replace the current contents if non-empty |
281 | $self->{configAlias} = shift ||$self->{configAlias}; # replace the current contents if non-empty |
281 | $self->{configAlias}; |
282 | $self->{configAlias}; |
282 | } |
283 | } |
283 | sub returnFieldName { |
284 | sub returnFieldName { |
284 | my $self = shift; |
285 | my $self = shift; |
285 | $self->{returnFieldName} = shift ||$self->{returnFieldName}; # replace the current contents if non-empty |
286 | $self->{answerBox} = shift ||$self->{answerBox}; # replace the current contents if non-empty |
286 | $self->{returnFieldName}; |
287 | $self->{answerBox}; |
|
|
288 | } |
|
|
289 | sub answerBox { |
|
|
290 | my $self = shift; |
|
|
291 | $self->{answerBox} = shift ||$self->{answerBox}; # replace the current contents if non-empty |
|
|
292 | $self->{answerBox}; |
287 | } |
293 | } |
288 | sub codebase { |
294 | sub codebase { |
289 | my $self = shift; |
295 | my $self = shift; |
290 | $self->{codebase} = shift ||$self->{codebase}; # replace the current codebase if non-empty |
296 | $self->{codebase} = shift ||$self->{codebase}; # replace the current codebase if non-empty |
291 | $self->{codebase}; |
297 | $self->{codebase}; |
… | |
… | |
366 | my $getState = $self->getStateAlias; |
372 | my $getState = $self->getStateAlias; |
367 | my $config = $self->configAlias; |
373 | my $config = $self->configAlias; |
368 | my $base64_config = $self->base64_config; |
374 | my $base64_config = $self->base64_config; |
369 | my $debugMode = ($self->debug) ? "1": "0"; |
375 | my $debugMode = ($self->debug) ? "1": "0"; |
370 | my $returnFieldName = $self->{returnFieldName}; |
376 | my $returnFieldName = $self->{returnFieldName}; |
371 | # my $encodeStateQ = ($self->debug)?'' : "state = Base64.encode(state);"; # in debug mode base64 encoding is not used. |
377 | my $answerBox = $self->{answerBox}; |
372 | # my $decodeStateQ = "if (!state.match(/<XML>*/i) ) {state = Base64.decode(state)}"; # decode if <XML> is not present |
|
|
373 | my $headerText = $self->header(); |
378 | my $headerText = $self->header(); |
374 | |
379 | |
375 | $headerText =~ s/(\$\w+)/$1/gee; # interpolate variables p17 of Cookbook |
380 | $headerText =~ s/(\$\w+)/$1/gee; # interpolate variables p17 of Cookbook |
376 | |
381 | |
377 | return $headerText; |
382 | return $headerText; |
… | |
… | |
400 | |
405 | |
401 | $objectText = $self->{objectText}; |
406 | $objectText = $self->{objectText}; |
402 | $objectText =~ s/(\$\w+)/$1/gee; |
407 | $objectText =~ s/(\$\w+)/$1/gee; |
403 | return $objectText; |
408 | return $objectText; |
404 | } |
409 | } |
405 | sub initialize { |
410 | # sub initialize { |
406 | my $self = shift; |
411 | # my $self = shift; |
407 | return q{ |
412 | # return q{ |
408 | <script> |
413 | # <script> |
409 | initializeAction(); |
414 | # initializeAllApplets(); |
410 | // this should really be done in the <body> tag |
415 | # // this should really be done in the <body> tag |
411 | </script> |
416 | # </script> |
412 | }; |
417 | # }; |
413 | |
418 | # |
414 | } |
419 | # } |
415 | ######################################################## |
420 | ######################################################## |
416 | # HEADER material for one flash or java applet |
421 | # HEADER material for one flash or java applet |
417 | ######################################################## |
422 | ######################################################## |
418 | |
423 | |
419 | use constant DEFAULT_HEADER_TEXT =><<'END_HEADER_SCRIPT'; |
424 | use constant DEFAULT_HEADER_TEXT =><<'END_HEADER_SCRIPT'; |
420 | |
425 | <script src="/webwork2_files/js/Base64.js" language="javascript"> |
|
|
426 | </script> |
|
|
427 | <script src="/webwork2_files/js/ww_applet_support.js"> |
|
|
428 | //upload functions stored in /opt/webwork/webwork2/htdocs/js ... |
|
|
429 | </script> |
421 | <script language="JavaScript"> |
430 | <script language="JavaScript"> |
422 | |
431 | |
423 | // set debug mode for this applet |
432 | // set debug mode for this applet |
424 | set_debug($debugMode); |
433 | set_debug($debugMode); |
|
|
434 | |
|
|
435 | ////////////////////////////////////////////////////////// |
|
|
436 | //TEST code |
|
|
437 | // |
|
|
438 | // |
|
|
439 | ////////////////////////////////////////////////////////// |
|
|
440 | |
|
|
441 | ww_applet_list["$appletName"] = new ww_applet("$appletName"); |
|
|
442 | |
|
|
443 | |
|
|
444 | ww_applet_list["$appletName"].code = "$code"; |
|
|
445 | ww_applet_list["$appletName"].codebase = "$codebase"; |
|
|
446 | ww_applet_list["$appletName"].appletID = "$appletID"; |
|
|
447 | ww_applet_list["$appletName"].base64_state = "$base64_initializationState"; |
|
|
448 | ww_applet_list["$appletName"].base64_config = "$base64_config"; |
|
|
449 | ww_applet_list["$appletName"].getStateAlias = "$getState"; |
|
|
450 | ww_applet_list["$appletName"].setStateAlias = "$setState"; |
|
|
451 | ww_applet_list["$appletName"].configAlias = "$config"; |
|
|
452 | ww_applet_list["$appletName"].initializeActionAlias = "$initializeAction"; |
|
|
453 | ww_applet_list["$appletName"].submitActionAlias = "$submitAction"; |
|
|
454 | ww_applet_list["$appletName"].submitActionScript = "$submitActionScript"; |
|
|
455 | ww_applet_list["$appletName"].answerBox = "$answerBox"; |
|
|
456 | ww_applet_list["$appletName"].debug = "$debugMode"; |
|
|
457 | |
425 | |
458 | |
426 | ////////////////////////////////////////////////////////// |
459 | ////////////////////////////////////////////////////////// |
427 | //CONFIGURATIONS |
460 | //CONFIGURATIONS |
428 | // |
461 | // |
429 | // configurations are "permanent" |
462 | // configurations are "permanent" |
430 | ////////////////////////////////////////////////////////// |
463 | ////////////////////////////////////////////////////////// |
431 | |
464 | |
432 | applet_config_list["$appletName"] = function() { |
465 | // applet_config_list["$appletName"] = function() { |
433 | debug_add("applet_config_list:\n attempt to configure $appletName . $config ( $base64_config ) if config function is defined: " |
466 | // debug_add("applet_config_list:\n attempt to configure $appletName . $config ( $base64_config ) if config function is defined: " |
434 | ); |
467 | // ); |
435 | try { |
468 | // try { |
436 | if (( typeof(getApplet("$appletName").$config) == "function" ) ) { |
469 | // if (( typeof(getApplet("$appletName").$config) == "function" ) ) { |
437 | debug_add("CONFIGURE $appletName"); |
470 | // debug_add("CONFIGURE $appletName"); |
438 | getApplet("$appletName").$config(Base64.decode("$base64_config")); |
471 | // getApplet("$appletName").$config(Base64.decode("$base64_config")); |
439 | } |
472 | // } |
440 | } catch(e) { |
473 | // } catch(e) { |
441 | alert("Error executing configuration command $config for $appletName: " + e ); |
474 | // alert("Error executing configuration command $config for $appletName: " + e ); |
442 | } |
475 | // } |
443 | } |
476 | // } |
444 | //////////////////////////////////////////////////////////// |
477 | // //////////////////////////////////////////////////////////// |
445 | // |
478 | // // |
446 | //STATE: |
479 | // //STATE: |
447 | // state can vary as the applet is manipulated -- it is reset from the questions _state values |
480 | // // state can vary as the applet is manipulated -- it is reset from the questions _state values |
448 | // |
481 | // // |
449 | ////////////////////////////////////////////////////////// |
482 | // ////////////////////////////////////////////////////////// |
450 | |
483 | // |
451 | applet_setState_list["$appletName"] = function(state) { |
484 | // applet_setState_list["$appletName"] = function(state) { |
452 | debug_add("Begin setState for applet $appletName"); |
485 | // debug_add("Begin setState for applet $appletName"); |
453 | debug_add("Obtain state from $appletName"+"_state"); |
486 | // debug_add("Obtain state from $appletName"+"_state"); |
454 | state = state || getQE("$appletName"+"_state").value; |
487 | // state = state || getQE("$appletName"+"_state").value; |
455 | if ( base64Q(state) ) { |
488 | // if ( base64Q(state) ) { |
456 | state=Base64.decode(state); |
489 | // state=Base64.decode(state); |
457 | } |
490 | // } |
458 | if (state.match(/<xml/i) || state.match(/<?xml/i) ) { // if state starts with <?xml |
491 | // if (state.match(/<xml/i) || state.match(/<?xml/i) ) { // if state starts with <?xml |
459 | |
492 | // |
460 | debug_add("applet_setState_list: \n set (decoded) state for $appletName to " + |
493 | // debug_add("applet_setState_list: \n set (decoded) state for $appletName to " + |
461 | state +"\nfunction type is " +typeof(getApplet("$appletName").$setState) |
494 | // state +"\nfunction type is " +typeof(getApplet("$appletName").$setState) |
462 | ); |
495 | // ); |
463 | try { |
496 | // try { |
464 | if (( typeof(getApplet("$appletName").$setState) =="function" ) ) { |
497 | // if (( typeof(getApplet("$appletName").$setState) =="function" ) ) { |
465 | debug_add("setState for $appletName"); |
498 | // debug_add("setState for $appletName"); |
466 | getApplet("$appletName").$setState( state ); |
499 | // getApplet("$appletName").$setState( state ); |
467 | } |
500 | // } |
468 | } catch(e) { |
501 | // } catch(e) { |
469 | alert("Error in setting state of $appletName using command $setState : " + e ); |
502 | // alert("Error in setting state of $appletName using command $setState : " + e ); |
470 | } |
503 | // } |
471 | } else if (debug) { |
504 | // } else if (debug) { |
472 | alert("new state was empty string or did not begin with <xml-- state was not reset"); |
505 | // alert("new state was empty string or did not begin with <xml-- state was not reset"); |
473 | } |
506 | // } |
474 | }; |
507 | // }; |
475 | applet_getState_list["$appletName"] = function () { |
508 | // applet_getState_list["$appletName"] = function () { |
476 | debug_add("get current state for applet $appletName and store it in $appletName"+"_state"); |
509 | // debug_add("get current state for applet $appletName and store it in $appletName"+"_state"); |
477 | var applet = getApplet("$appletName"); |
510 | // var applet = getApplet("$appletName"); |
478 | try { |
511 | // try { |
479 | if (( typeof(applet.$getState) == "function" ) ) { // there may be no state function |
512 | // if (( typeof(applet.$getState) == "function" ) ) { // there may be no state function |
480 | state = applet.$getState(); // get state in xml format |
513 | // state = applet.$getState(); // get state in xml format |
481 | debug_add("state has type " + typeof(state)); |
514 | // debug_add("state has type " + typeof(state)); |
482 | state = String(state); // geogebra returned an object type instead of a string type |
515 | // state = String(state); // geogebra returned an object type instead of a string type |
483 | debug_add("state converted to type " + typeof(state)); |
516 | // debug_add("state converted to type " + typeof(state)); |
484 | } |
517 | // } |
485 | |
518 | // |
486 | if (!debug) { |
519 | // if (!debug) { |
487 | state = Base64.encode(state); |
520 | // state = Base64.encode(state); |
488 | }; // replace state by encoded version unless in debug mode |
521 | // }; // replace state by encoded version unless in debug mode |
489 | |
522 | // |
490 | debug_add("state is "+state); // this should still be in plain text |
523 | // debug_add("state is "+state); // this should still be in plain text |
491 | getQE("$appletName"+"_state").value = state; //place state in input item (debug: textarea, otherwise: hidden) |
524 | // getQE("$appletName"+"_state").value = state; //place state in input item (debug: textarea, otherwise: hidden) |
492 | } catch (e) { |
525 | // } catch (e) { |
493 | alert("Error in getting state for $appletName " + e ); |
526 | // alert("Error in getting state for $appletName " + e ); |
494 | } |
527 | // } |
495 | }; |
528 | // }; |
496 | |
529 | // |
497 | //////////////////////////////////////////////////////////// |
530 | // //////////////////////////////////////////////////////////// |
498 | // |
531 | // // |
499 | //INITIALIZE |
532 | // //INITIALIZE |
500 | // |
533 | // // |
501 | //////////////////////////////////////////////////////////// |
534 | // //////////////////////////////////////////////////////////// |
502 | |
535 | // |
503 | |
536 | // |
504 | applet_checkLoaded_list["$appletName"] = function() { // this function returns 0 unless: |
537 | // applet_checkLoaded_list["$appletName"] = function() { // this function returns 0 unless: |
505 | // applet has already been flagged as ready in applet_isReady_list |
538 | // // applet has already been flagged as ready in applet_isReady_list |
506 | // applet.config is defined (or alias for .config) |
539 | // // applet.config is defined (or alias for .config) |
507 | // applet.setState is defined |
540 | // // applet.setState is defined |
508 | // applet.isActive is defined |
541 | // // applet.isActive is defined |
509 | // applet reported that it is loaded by calling loadQ() |
542 | // // applet reported that it is loaded by calling loadQ() |
510 | var ready = 0; |
543 | // var ready = 0; |
511 | var applet = getApplet("$appletName"); |
544 | // var applet = getApplet("$appletName"); |
512 | if (!debug && applet_isReady_list["$appletName"]) {return(1)}; // memorize readiness in non-debug mode |
545 | // if (!debug && applet_isReady_list["$appletName"]) {return(1)}; // memorize readiness in non-debug mode |
513 | if ( typeof(applet.$config) == "function") { |
546 | // if ( typeof(applet.$config) == "function") { |
514 | debug_add( "applet.config is " + typeof(applet.$config) ); |
547 | // debug_add( "applet.config is " + typeof(applet.$config) ); |
515 | ready = 1; |
548 | // ready = 1; |
516 | } |
549 | // } |
517 | if( typeof(applet.$getState) == "function") { |
550 | // if( typeof(applet.$getState) == "function") { |
518 | debug_add( "applet.getState is " + typeof(applet.$getState) ); |
551 | // debug_add( "applet.getState is " + typeof(applet.$getState) ); |
519 | ready =1; |
552 | // ready =1; |
520 | } |
553 | // } |
521 | if (typeof(applet.isActive) == "function" && applet.isActive ) { |
554 | // if (typeof(applet.isActive) == "function" && applet.isActive ) { |
522 | debug_add( "applet.isActive is " + typeof(applet.isActive) ); |
555 | // debug_add( "applet.isActive is " + typeof(applet.isActive) ); |
523 | ready =1; |
556 | // ready =1; |
524 | } |
557 | // } |
525 | if (typeof(applet_reportsLoaded_list["$appletName"]) !="undefined" && applet_reportsLoaded_list["$appletName"] != 0 ) { |
558 | // if (typeof(applet_reportsLoaded_list["$appletName"]) !="undefined" && applet_reportsLoaded_list["$appletName"] != 0 ) { |
526 | debug_add( "applet reports that it is loaded " + applet_reportsLoaded_list["$appletName"] ); |
559 | // debug_add( "applet reports that it is loaded " + applet_reportsLoaded_list["$appletName"] ); |
527 | ready =1; |
560 | // ready =1; |
528 | } |
561 | // } |
529 | applet_isReady_list["$appletName"]= ready; |
562 | // applet_isReady_list["$appletName"]= ready; |
530 | return(ready); |
563 | // return(ready); |
531 | } |
564 | // } |
532 | |
565 | // |
533 | applet_initializeAction_list["$appletName"] = function (state) { |
566 | // applet_initializeAction_list["$appletName"] = function (state) { |
534 | applet_setState_list["$appletName"](state); |
567 | // applet_setState_list["$appletName"](state); |
535 | }; |
568 | // }; |
536 | |
569 | // |
537 | applet_submitAction_list["$appletName"] = function () { |
570 | // applet_submitAction_list["$appletName"] = function () { |
538 | if (! applet_isReady_list["$appletName"] ) { |
571 | // if (! applet_isReady_list["$appletName"] ) { |
539 | alert("$appletName is not ready"); |
572 | // alert("$appletName is not ready"); |
540 | } |
573 | // } |
541 | applet_getState_list["$appletName"](); |
574 | // applet_getState_list["$appletName"](); |
542 | $submitActionScript |
575 | // $submitActionScript |
543 | //getQE("$returnFieldName").value = getApplet("$appletName").sendData(); //FIXME -- not needed in general? |
576 | // //getQE("$answerBox").value = getApplet("$appletName").getAnswer(); //FIXME -- not needed in general? |
544 | }; |
577 | // }; |
545 | </script> |
578 | </script> |
546 | |
579 | |
547 | END_HEADER_SCRIPT |
580 | END_HEADER_SCRIPT |
548 | |
581 | |
549 | package FlashApplet; |
582 | package FlashApplet; |