further (and final) merge of changes from Moodle 1.9

This commit is contained in:
Gordon Bateson 2010-05-14 03:46:30 +00:00
parent 2e93bc3819
commit 9e43b1db73
6 changed files with 246 additions and 106 deletions

View File

@ -1092,7 +1092,7 @@ function GetJCrossQuestionDetails(hp, v) {
if (JCross[0]) {
qDetails += makeSeparator(Q);
}
if (JCross[5]) {
if (JCross[3]) {
var x = (HP[_correct][AD] && HP[_correct][AD][q]) ? HP[_correct][AD][q] : '';
qDetails += hpHiddenField(Q+'correct', x);
}
@ -1548,7 +1548,7 @@ function hpClickClue(hp, t, v, args) {
}
function hpClickCheck(hp, t, v, args) {
if (t==2) { // JCloze
if (v==5 || v==6) {
if (v==5 || v==6) {
var r = hpRottmeier();
var already_correct = 'true';
if (r==0) {
@ -1844,7 +1844,12 @@ function hpClickCheckJCrossV5V6(hp, v, AD, q, row, col) {
var check = false;
var guess = GetJCrossWord(G, row, col, (AD=='D'));
var correct = GetJCrossWord(L, row, col, (AD=='D'));
if (guess==correct) {
if (window.CaseSensitive) {
var is_correct = (guess==correct);
} else {
var is_correct = (guess.toUpperCase()==correct.toUpperCase());
}
if (is_correct) {
HP[_correct][AD][q] = correct;
check = true;
} else if (guess) {
@ -2922,14 +2927,23 @@ hpInterceptClues();
hpInterceptChecks();
function hpFindForm(formname, w) {
if (w==null) w = self;
var f = w.document.forms[formname];
if (f==null && w.frames) {
var f = w.document.getElementById(formname);
if (f) {
return f;
}
var f = w.document.forms[formname];
if (f) {
return f;
}
if (w.frames) {
for (var i=0; i<w.frames.length; i++) {
f = hpFindForm(formname, w.frames[i]);
if (f) break;
var f = hpFindForm(formname, w.frames[i]);
if (f) {
return f;
}
}
}
return f;
return null;
}
function Finish(quizstatus) {
var mark = hpScore();
@ -2995,4 +3009,4 @@ if (p && c) {
window.SendResults = SendAllResults;
// set start time
var Start_Time = new Date();
//-->
//-->

View File

@ -1,52 +1,76 @@
<!--
function domSniffer() {
var t = true;
var s = navigator.userAgent;
if (s.indexOf("Mac") >=0) this.mac = t;
if (s.indexOf("Opera") >=0) this.opera = t;
var d = document;
if (d.layers) this.n4 = t;
if (d.childNodes) this.dom = t;
if (d.all && d.plugins) this.ie = t;
var t = true;
var s = navigator.userAgent;
if (s.indexOf("Mac") >=0) this.mac = t;
if (s.indexOf("Opera") >=0) this.opera = t;
var d = document;
if (d.layers) this.n4 = t;
if (d.childNodes) this.dom = t;
if (d.all && d.plugins) this.ie = t;
}
function getContentH(lyr) {
return (is.n4) ? lyr.document.height : (is.ie) ? (is.mac ? lyr.offsetHeight : lyr.scrollHeight) : (is.opera) ? lyr.style.pixelHeight : (is.dom) ? lyr.offsetHeight : 0;
return (is.n4) ? lyr.document.height : (is.ie) ? (is.mac ? lyr.offsetHeight : lyr.scrollHeight) : (is.opera) ? lyr.style.pixelHeight : (is.dom) ? lyr.offsetHeight : 0;
}
function px(i) {
return i + "px";
return i + "px";
}
function setSize(obj, w, h) {
if (is.n4) {
if (w) obj.width = w;
if (h) obj.height = h;
} else if (is.opera) {
// opera 5 needs pixelWidth/Height
if (w) obj.style.pixelWidth = w;
if (h) obj.style.pixelHeight = h;
} else {
if (w) obj.style.width = px(w);
if (h) obj.style.height = px(h);
}
if (is.n4) {
if (w) obj.width = w;
if (h) obj.height = h;
} else if (is.opera) {
// opera 5 needs pixelWidth/Height
if (w) obj.style.pixelWidth = w;
if (h) obj.style.pixelHeight = h;
} else {
if (w) obj.style.width = px(w);
if (h) obj.style.height = px(h);
}
}
function getElement(id, lyr) {
var d = (document.layers && lyr) ? lyr.document : document;
var obj = (document.layers) ? eval("d."+id) : (d.all) ? d.all[id] : (d.getElementById) ? d.getElementById(id) : null;
return obj;
var d = (document.layers && lyr) ? lyr.document : document;
var obj = (document.layers) ? eval("d."+id) : (d.all) ? d.all[id] : (d.getElementById) ? d.getElementById(id) : null;
return obj;
}
is = new domSniffer();
function set_iframe_height(id) {
var iframe = getElement(id);
if (iframe) {
var obj = iframe.document || iframe.contentDocument || null; // IE || FireFox
if (obj) {
if (obj.body) {
obj = obj.body;
}
var h = getContentH(obj);
if (h) {
setSize(iframe, 0, h);
}
}
}
function set_embed_object_height(evt, embed_object) {
if (typeof(embed_object)=='undefined') {
if (evt) {
// we are being called by the onload event handler
if (evt.target) { // most browsers
embed_object = evt.target;
} else if (evt.srcElement) { // IE
embed_object = evt.srcElement;
}
}
}
var obj = null;
if (embed_object) {
if (document.frames) { // IE
switch (embed_object.tagName) {
case 'IFRAME':
obj = document.frames[embed_object.name].document;
break;
case 'OBJECT':
obj = embed_object; // already an HTML document element
break;
}
} else { // Firefox, Safari, Opera, Chrome
obj = embed_object.document || embed_object.contentDocument || null;
}
}
if (obj) {
if (obj.body) {
obj = obj.body;
}
var h = getContentH(obj);
if (h) {
setSize(embed_object, 0, h + 65);
}
// at some point the next two lines were important, but now it doesn't seeme to matter ?!
// if (document.all) {
// embed_object.allowTransparency = true;
// obj.style.backgroundColor = 'transparent';
// }
}
}
//-->
is = new domSniffer();

View File

@ -483,9 +483,20 @@ function hotpot_restore_logs($restore, $log) {
}
function hotpot_decode_content_links($content, $restore) {
$search = '/\$@(HOTPOT)\*([a-z]+)\*([a-z]+)\*([0-9]+)@\$/ise';
$replace = 'hotpot_decode_content_link("$2", "$3", "$4", $restore)';
return preg_replace($search, $replace, $content);
$search = '/\$@(HOTPOT)\*([a-z]+)\*([a-z]+)\*([0-9]+)@\$/is';
if (preg_match_all($search, $content, $matches, PREG_OFFSET_CAPTURE)) {
$i_max = count($matches[0]) - 1;
for ($i=$i_max; $i>=0; $i--) {
$start = $matches[0][$i][1];
$length = strlen($matches[0][$i][0]);
$replace = hotpot_decode_content_link(
// $scriptname, $paramname, $paramvalue, $restore
$matches[2][$i][0], $matches[3][$i][0], $matches[4][$i][0], $restore
);
$content = substr_replace($content, $replace, $start, $length);
}
}
return $content;
}
function hotpot_decode_content_link($scriptname, $paramname, $paramvalue, &$restore) {

View File

@ -78,11 +78,14 @@ class hotpot_xml_template_default {
$str = strtr($str, array("\r\n"=>$nl, "\r"=>$nl, "\n"=>$nl));
// convert (hex and decimal) html entities to unicode, if required
if ($convert_to_unicode) {
$str = preg_replace('|&#x([0-9A-F]+);|i', '\\u\\1', $str);
$str = preg_replace('|&#(\d+);|e', "'\\u'.sprintf('%04X', '\\1')", $str);
$str = preg_replace('/&#x([0-9A-F]+);/i', '\\u\\1', $str);
$str = preg_replace_callback('/&#(\d+);/', array(&$this, 'js_safe_callback'), $str);
}
return $str;
}
function js_safe_callback(&$matches) {
return '\\u'.sprintf('%04X', $matches[1]);
}
function get_halfway_color($x, $y) {
// returns the $color that is half way between $x and $y
$color = $x; // default

View File

@ -1,6 +1,9 @@
<?PHP
class hotpot_xml_quiz_template extends hotpot_xml_template_default {
// left and right items for JMatch
var $l_items = array();
var $r_items = array();
// constructor function for this class
function hotpot_xml_quiz_template(&$parent) {
@ -45,6 +48,12 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
if (!empty($pattern)) {
$this->expand_strings('html', $pattern);
}
// fix doctype (convert short dtd to long dtd)
$this->html = preg_replace(
'/<!DOCTYPE[^>]*>/',
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
$this->html, 1
);
}
// captions and messages
@ -65,7 +74,7 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
return $this->int_value('hotpot-config-file,global,include-back');
}
function v6_expand_BackCaption() {
return $this->parent->xml_value('hotpot-config-file,global,back-caption');
return str_replace('<=', '&lt;=', $this->parent->xml_value('hotpot-config-file,global,back-caption'));
}
function v6_expand_ClickToAdd() {
return $this->parent->xml_value('hotpot-config-file,'.$this->parent->quiztype.',click-to-add');
@ -112,8 +121,7 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
return $this->int_value('hotpot-config-file,global,include-next-ex');
}
function v6_expand_NextExCaption() {
$caption = $this->parent->xml_value('hotpot-config-file,global,next-ex-caption');
return ($caption=='=>' ? '=&gt;' : $caption);
return str_replace('=>', '=&gt;', $this->parent->xml_value('hotpot-config-file,global,next-ex-caption'));
}
function v6_expand_NextQCaption() {
return $this->parent->xml_value('hotpot-config-file,global,next-q-caption');
@ -420,28 +428,26 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
return $i;
}
function v6_expand_MatchDivItems() {
$l_items = array();
$r_items = array();
$this->get_jmatch_items($l_items, $r_items);
$this->set_jmatch_items();
$l_keys = $this->shuffle_jmatch_items($l_items);
$r_keys = $this->shuffle_jmatch_items($r_items);
$l_keys = $this->shuffle_jmatch_items($this->l_items);
$r_keys = $this->shuffle_jmatch_items($this->r_items);
$options = '<option value="x">'.$this->parent->xml_value('data,matching-exercise,default-right-item').'</option>';
foreach ($r_keys as $key) {
if (empty($r_items[$key]['fixed'][0]['#'])) {
$options .= '<option value="'.$key.'">'.$r_items[$key]['text'][0]['#'].'</option>'."\n";
if (! $this->r_items[$key]['fixed']) {
$options .= '<option value="'.$key.'">'.$this->r_items[$key]['text'].'</option>'."\n";
}
}
$str = '';
foreach ($l_keys as $key) {
$str .= '<tr><td class="LeftItem">'.$l_items[$key]['text'][0]['#'].'</td>';
$str .= '<tr><td class="LeftItem">'.$this->l_items[$key]['text'].'</td>';
$str .= '<td class="RightItem">';
if (empty($r_items[$key]['fixed'][0]['#'])) {
$str .= '<select id="s'.$key.'_'.$key.'">'.$options.'</select>';
if ($this->r_items[$key]['fixed']) {
$str .= $this->r_items[$key]['text'];
} else {
$str .= $r_items[$key]['text'][0]['#'];
$str .= '<select id="s'.$key.'_'.$key.'">'.$options.'</select>';
}
$str .= '</td><td></td></tr>';
}
@ -711,46 +717,67 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
// specials (JMatch)
function v6_expand_FixedArray() {
$l_items = array();
$r_items = array();
$this->get_jmatch_items($l_items, $r_items);
$this->set_jmatch_items();
$str = '';
foreach ($l_items as $i=>$item) {
foreach ($this->l_items as $i=>$item) {
for ($ii=0; $ii<$i; $ii++) {
if ($this->r_items[$ii]['text']==$this->r_items[$i]['text']) {
break;
}
}
$str .= "F[$i] = new Array();\n";
$str .= "F[$i][0] = '".$this->js_safe($item['text'][0]['#'], true)."';\n";
$str .= "F[$i][1] = ".($i+1).";\n";
$str .= "F[$i][0] = '".$this->js_safe($item['text'], true)."';\n";
$str .= "F[$i][1] = ".($ii+1).";\n";
}
return $str;
}
function v6_expand_DragArray() {
$l_items = array();
$r_items = array();
$this->get_jmatch_items($l_items, $r_items);
$this->set_jmatch_items();
$str = '';
foreach ($r_items as $i=>$item) {
foreach ($this->r_items as $i=>$item) {
for ($ii=0; $ii<$i; $ii++) {
if ($this->r_items[$ii]['text']==$this->r_items[$i]['text']) {
break;
}
}
$str .= "D[$i] = new Array();\n";
$str .= "D[$i][0] = '".$this->js_safe($item['text'][0]['#'], true)."';\n";
$str .= "D[$i][1] = ".($i+1).";\n";
$str .= "D[$i][2] = '".(empty($item['fixed'][0]['#']) ? 0 : 1)."';\n";
$str .= "D[$i][0] = '".$this->js_safe($item['text'], true)."';\n";
$str .= "D[$i][1] = ".($ii+1).";\n";
$str .= "D[$i][2] = ".$item['fixed'].";\n";
}
return $str;
}
function get_jmatch_items(&$l_items, &$r_items) {
function set_jmatch_items() {
if (count($this->l_items)) {
return;
}
$tags = 'data,matching-exercise,pair';
$i = 0;
while($item = $this->parent->xml_value($tags,"[$i]['#']['left-item'][0]['#']")) {
if (!empty($item['text'][0]['#'])) {
$l_items[] = $item;
while (($item = "[$i]['#']") && $this->parent->xml_value($tags, $item)) {
$leftitem = $item."['left-item'][0]['#']";
$lefttext = $this->parent->xml_value($tags, $leftitem."['text'][0]['#']");
$rightitem = $item."['right-item'][0]['#']";
$righttext = $this->parent->xml_value($tags, $rightitem."['text'][0]['#']");
if (strlen($righttext)) {
$addright = true;
} else {
$addright = false;
}
$i++;
}
$i = 0;
while($item = $this->parent->xml_value($tags,"[$i]['#']['right-item'][0]['#']")) {
if (!empty($item['text'][0]['#'])) {
$r_items[] = $item;
if (strlen($lefttext)) {
$this->l_items[] = array(
'text' => $lefttext,
'fixed' => $this->int_value($tags, $leftitem."['fixed'][0]['#']")
);
$addright = true; // force right item to be added
}
if ($addright) {
$this->r_items[] = array(
'text' => $righttext,
'fixed' => $this->int_value($tags, $rightitem."['fixed'][0]['#']")
);
}
$i++;
}
@ -759,7 +786,7 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
// get moveable items
$moveable_keys = array();
for($i=0; $i<count($items); $i++) {
if(empty($items[$i]['fixed'][0]['#'])) {
if(empty($items[$i]['fixed'])) {
$moveable_keys[] = $i;
}
}
@ -769,7 +796,7 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
$keys = array();
for($i=0, $ii=0; $i<count($items); $i++) {
if(empty($items[$i]['fixed'][0]['#'])) {
if(empty($items[$i]['fixed'])) {
// moveable items are inserted in a shuffled order
$keys[] = $moveable_keys[$ii++];
} else {
@ -902,7 +929,9 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
$gap .= '<select id="Gap'.$q.'"><option value=""></option>'.$dropdownlist.'</select>';
} else {
// minimum gap size
$gapsize = 6;
if (! $gapsize = $this->int_value('hotpot-config-file,'.$this->parent->quiztype.',minimum-gap-size')) {
$gapsize = 6;
}
// increase gap size to length of longest answer for this gap
$a = 0;
@ -1035,10 +1064,20 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
}
}
function v6_expand_Correct() {
return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',guesses-correct');
if ($this->parent->quiztype=='jcloze') {
$tag = 'guesses-correct';
} else {
$tag = 'guess-correct';
}
return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.','.$tag);
}
function v6_expand_Incorrect() {
return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',guesses-incorrect');
if ($this->parent->quiztype=='jcloze') {
$tag = 'guesses-incorrect';
} else {
$tag = 'guess-incorrect';
}
return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.','.$tag);
}
function v6_expand_GiveHint() {
return $this->js_value('hotpot-config-file,'.$this->parent->quiztype.',next-correct-letter');
@ -1263,8 +1302,23 @@ class hotpot_xml_quiz_template extends hotpot_xml_template_default {
$question_type==HOTPOT_JQUIZ_SHORTANSWER ||
$question_type==HOTPOT_JQUIZ_HYBRID
) {
$size = 9; // default size
$a = 0;
$answers = $question."['answers'][0]['#']";
while (($answer = $answers."['answer'][$a]['#']") && $this->parent->xml_value($tags, $answer)) {
$text = $this->parent->xml_value($tags, $answer."['text'][0]['#']");
$text = preg_replace('/&[#a-zA-Z0-9]+;/', 'x', $text);
$size = max($size, strlen($text));
$a++;
}
$str .= '<div class="ShortAnswer" id="Q_'.$q.'_SA"><form method="post" action="" onsubmit="return false;"><div>';
$str .= '<input type="text" id="Q_'.$q.'_Guess" onfocus="TrackFocus('."'".'Q_'.$q.'_Guess'."'".')" onblur="LeaveGap()" class="ShortAnswerBox" size="9"></input><br /><br />';
if ($size<=25) { // text box
$str .= '<input type="text" id="Q_'.$q.'_Guess" onfocus="TrackFocus('."'".'Q_'.$q.'_Guess'."'".')" onblur="LeaveGap()" class="ShortAnswerBox" size="'.$size.'"></input>';
} else { // textarea (29 cols wide)
$str .= '<textarea id="Q_'.$q.'_Guess" onfocus="TrackFocus('."'".'Q_'.$q.'_Guess'."'".')" onblur="LeaveGap()" class="ShortAnswerBox" cols="29" rows="'.ceil($size/25).'"></textarea>';
}
$str .= '<br /><br />';
$caption = $this->v6_expand_CheckCaption();
$str .= $this->v6_expand_jquiz_button($caption, "CheckShortAnswer($q)");
@ -1428,15 +1482,15 @@ function hotpot_sort_keypad_chars($a, $b) {
function hotpot_keypad_sort_value($char) {
// hexadecimal
if (preg_match('|&#x([0-9A-F]+);|ie', $char, $matches)) {
if (preg_match('/&#x([0-9A-F]+);/i', $char, $matches)) {
$ord = hexdec($matches[1]);
// decimal
} else if (preg_match('|&#(\d+);|i', $char, $matches)) {
} else if (preg_match('/&#(\d+);/i', $char, $matches)) {
$ord = intval($matches[1]);
// other html entity
} else if (preg_match('|&[^;]+;|', $char, $matches)) {
} else if (preg_match('/&[^;]+;/', $char, $matches)) {
$char = html_entity_decode($matches[0]);
$ord = empty($char) ? 0 : ord($char);

View File

@ -164,8 +164,43 @@
$hp->insert_giveup_form($attemptid, '<!-- BeginTopNavButtons -->', '<!-- EndTopNavButtons -->');
break;
case HOTPOT_NAVIGATION_FRAME:
$targetframe = $CFG->framename;
// drop through to remove nav buttons too
case HOTPOT_NAVIGATION_IFRAME:
if (empty($CFG->framename)) {
$targetframe = '_top';
} else {
$targetframe = $CFG->framename;
}
if ($pos = strpos($hp->html, '</body>')) {
$insert = ''
.'<script type="text/javascript">'."\n"
.'//<![CDATA['."\n"
."var obj = document.getElementsByTagName('a');\n"
."if (obj) {\n"
." var i_max = obj.length;\n"
." for (var i=0; i<i_max; i++) {\n"
." if (obj[i].href && ! obj[i].target) {\n"
." obj[i].target = '$targetframe';\n"
." }\n"
." }\n"
." var obj = null;\n"
."}\n"
."var obj = document.getElementsByTagName('form');\n"
."if (obj) {\n"
." var i_max = obj.length;\n"
." for (var i=0; i<i_max; i++) {\n"
." if (obj[i].action && ! obj[i].target) {\n"
." obj[i].target = '$targetframe';\n"
." }\n"
." }\n"
." var obj = null;\n"
."}\n"
.'//]]>'."\n"
.'</script>'."\n"
;
$hp->html = substr_replace($hp->html, $insert, $pos, 0);
}
$hp->remove_nav_buttons();
break;
default:
$hp->remove_nav_buttons();
}
@ -451,7 +486,6 @@
print '<!--> <![endif]-->'."\n";
print $footer;
break;
} // end switch $framename
break;
case HOTPOT_NAVIGATION_GIVEUP: