# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: moodle/lib/form/form.js
--- moodle/lib/form/form.js No Base Revision
+++ moodle/lib/form/form.js Locally New
@@ -0,0 +1,411 @@
+/**
+ * Get the value of the 'virtual form element' with a particular name. That is,
+ * abstracts away the difference between a normal form element, like a select
+ * which is a single HTML element with a .value property, and a set of radio
+ * buttons, which is several HTML elements.
+ *
+ * @param form a HTML form.
+ * @param master the name of an element in that form.
+ * @return the value of that element.
+ */
+function get_form_element_value(form, name) {
+    var element = form[name];
+    if (!element) {
+        return null;
+    }
+    if (element.tagName) {
+        // Ordinarly thing like a select box.
+        return element.value;
+    }
+    // Array of things, like radio buttons.
+    for (var j = 0; j < element.length; j++) {
+        var el = element[j];
+        if (el.checked) {
+            return el.value;
+        }
+    }
+    return null;
+}
+
+
+/**
+ * Set the disabled state of the 'virtual form element' with a particular name.
+ * This abstracts away the difference between a normal form element, like a select
+ * which is a single HTML element with a .value property, and a set of radio
+ * buttons, which is several HTML elements.
+ *
+ * @param form a HTML form.
+ * @param master the name of an element in that form.
+ * @param disabled the disabled state to set.
+ */
+function set_form_element_disabled(form, name, disabled) {
+    var element = form[name];
+    if (!element) {
+        return;
+    }
+    if (element.tagName) {
+        // Ordinarly thing like a select box.
+        element.disabled = disabled;
+    }
+    // Array of things, like radio buttons.
+    for (var j = 0; j < element.length; j++) {
+        var el = element[j];
+        el.disabled = disabled;
+    }
+}
+
+function lockoptionsall(formid) {
+    var form = document.forms[formid];
+    var dependons = eval(formid + 'items');
+    var tolock = [];
+    for (var dependon in dependons) {
+        // change for MooTools compatibility
+        if (!dependons.propertyIsEnumerable(dependon)) {
+            continue;
+        }
+        if (!form[dependon]) {
+            continue;
+        }
+        for (var condition in dependons[dependon]) {
+            for (var value in dependons[dependon][condition]) {
+                var lock;
+                switch (condition) {
+                  case 'notchecked':
+                      lock = !form[dependon].checked; break;
+                  case 'checked':
+                      lock = form[dependon].checked; break;
+                  case 'noitemselected':
+                      lock = form[dependon].selectedIndex == -1; break;
+                  case 'eq':
+                      lock = get_form_element_value(form, dependon) == value; break;
+                  default:
+                      lock = get_form_element_value(form, dependon) != value; break;
+                }
+                for (var ei in dependons[dependon][condition][value]) {
+                    // change for MooTools compatibility
+                    if (!window.webkit && (!dependons[dependon][condition][value].propertyIsEnumerable(ei))) {
+                        continue;
+                    }
+                    var eltolock = dependons[dependon][condition][value][ei];
+                    if (tolock[eltolock] != null) {
+                        tolock[eltolock] = lock || tolock[eltolock];
+                    } else {
+                        tolock[eltolock] = lock;
+                    }
+                }
+            }
+        }
+    }
+    for (var el in tolock) {
+        // change for MooTools compatibility
+        if (!tolock.propertyIsEnumerable(el)) {
+            continue;
+        }
+        set_form_element_disabled(form, el, tolock[el]);
+    }
+    return true;
+}
+
+function lockoptionsallsetup(formid) {
+    var form = document.forms[formid];
+    var dependons = eval(formid+'items');
+    for (var dependon in dependons) {
+        // change for MooTools compatibility
+        if (!dependons.propertyIsEnumerable(dependon)) {
+            continue;
+        }
+        var masters = form[dependon];
+        if (!masters) {
+            continue;
+        }
+        if (masters.tagName) {
+            // If master is radio buttons, we get an array, otherwise we don't.
+            // Convert both cases to an array for convinience.
+            masters = [masters];
+        }
+        for (var j = 0; j < masters.length; j++) {
+            master = masters[j];
+            master.formid = formid;
+            master.onclick  = function() {return lockoptionsall(this.formid);};
+            master.onblur   = function() {return lockoptionsall(this.formid);};
+            master.onchange = function() {return lockoptionsall(this.formid);};
+        }
+    }
+    for (var i = 0; i < form.elements.length; i++) {
+        var formelement = form.elements[i];
+        if (formelement.type=='reset') {
+            formelement.formid = formid;
+            formelement.onclick  = function() {this.form.reset();return lockoptionsall(this.formid);};
+            formelement.onblur   = function() {this.form.reset();return lockoptionsall(this.formid);};
+            formelement.onchange = function() {this.form.reset();return lockoptionsall(this.formid);};
+        }
+    }
+    return lockoptionsall(formid);
+}
+
+
+function showAdvancedInit(addBefore, nameAttr, buttonLabel, hideText, showText) {
+    var showHideButton = document.createElement("input");
+    showHideButton.type = 'button';
+    showHideButton.value = buttonLabel;
+    showHideButton.name = nameAttr;
+    showHideButton.moodle = {
+        hideLabel: mstr.form.hideadvanced,
+        showLabel: mstr.form.showadvanced
+    };
+    YAHOO.util.Event.addListener(showHideButton, 'click', showAdvancedOnClick);
+    el = document.getElementById(addBefore);
+    el.parentNode.insertBefore(showHideButton, el);
+}
+
+/*
+    elementSetHide (elements, hide)
+
+    Adds or removes the "hide" class for the specified elements depending on boolean hide.
+*/
+function elementShowAdvanced(elements, show) {
+    for (var elementIndex in elements) {
+        element = elements[elementIndex];
+        element.className = element.className.replace(new RegExp(' ?hide'), '')
+        if(!show) {
+            element.className += ' hide';
+        }
+    }
+}
+
+function showAdvancedOnClick(e) {
+    var button = e.target ? e.target : e.srcElement;
+
+    var toSet=findChildNodes(button.form, null, 'advanced');
+    var buttontext = '';
+    if (button.form.elements['mform_showadvanced_last'].value == '0' ||  button.form.elements['mform_showadvanced_last'].value == '' ) {
+        elementShowAdvanced(toSet, true);
+        buttontext = button.moodle.hideLabel;
+        button.form.elements['mform_showadvanced_last'].value = '1';
+    } else {
+        elementShowAdvanced(toSet, false);
+        buttontext = button.moodle.showLabel;
+        button.form.elements['mform_showadvanced_last'].value = '0';
+    }
+    var formelements = button.form.elements;
+    // Fixed MDL-10506
+    for (var i = 0; i < formelements.length; i++) {
+        if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')) {
+            formelements[i].value = buttontext;
+        }
+    }
+    //never submit the form if js is enabled.
+    return false;
+}
+
+/**
+ * Search a Moodle form to find all the fdate_time_selector and fdate_selector
+ * elements, and add date_selector_calendar instance to each.
+ */
+function init_date_selectors(firstdayofweek) {
+    var els = YAHOO.util.Dom.getElementsByClassName('fdate_time_selector', 'fieldset');
+    for (var i = 0; i < els.length; i++) {
+        new date_selector_calendar(els[i], firstdayofweek);
+    }
+    els = YAHOO.util.Dom.getElementsByClassName('fdate_selector', 'fieldset');
+    for (i = 0; i < els.length; i++) {
+        new date_selector_calendar(els[i], firstdayofweek);
+    }
+}
+
+/**
+ * Constructor for a JavaScript object that connects to a fdate_time_selector
+ * or a fdate_selector in a Moodle form, and shows a popup calendar whenever
+ * that element has keyboard focus.
+ * @param el the fieldset class="fdate_time_selector" or "fdate_selector".
+ */
+function date_selector_calendar(el, firstdayofweek) {
+    // Ensure that the shared div and calendar exist.
+    if (!date_selector_calendar.panel) {
+        date_selector_calendar.panel = new YAHOO.widget.Panel('date_selector_calendar_panel',
+                {visible: false, draggable: false});
+        var div = document.createElement('div');
+        date_selector_calendar.panel.setBody(div);
+        date_selector_calendar.panel.render(document.body);
+
+        YAHOO.util.Event.addListener(document, 'click', date_selector_calendar.document_click);
+        date_selector_calendar.panel.showEvent.subscribe(function() {
+            date_selector_calendar.panel.fireEvent('changeContent');
+        });
+        date_selector_calendar.panel.hideEvent.subscribe(date_selector_calendar.release_current);
+
+        date_selector_calendar.calendar = new YAHOO.widget.Calendar(div,
+                {iframe: false, hide_blank_weeks: true, start_weekday: firstdayofweek});
+        date_selector_calendar.calendar.renderEvent.subscribe(function() {
+            date_selector_calendar.panel.fireEvent('changeContent');
+            date_selector_calendar.delayed_reposition();
+        });
+    }
+
+    this.fieldset = el;
+    var controls = el.getElementsByTagName('select');
+    for (var i = 0; i < controls.length; i++) {
+        if (/\[year\]$/.test(controls[i].name)) {
+            this.yearselect = controls[i];
+        } else if (/\[month\]$/.test(controls[i].name)) {
+            this.monthselect = controls[i];
+        } else if (/\[day\]$/.test(controls[i].name)) {
+            this.dayselect = controls[i];
+        } else {
+            YAHOO.util.Event.addFocusListener(controls[i], date_selector_calendar.cancel_any_timeout, this);
+            YAHOO.util.Event.addBlurListener(controls[i], this.blur_event, this);
+        }
+    }
+    if (!(this.yearselect && this.monthselect && this.dayselect)) {
+        throw 'Failed to initialise calendar.';
+    }
+    YAHOO.util.Event.addFocusListener([this.yearselect, this.monthselect, this.dayselect], this.focus_event, this);
+    YAHOO.util.Event.addBlurListener([this.yearselect, this.monthselect, this.dayselect], this.blur_event, this);
+
+    this.enablecheckbox = el.getElementsByTagName('input')[0];
+    if (this.enablecheckbox) {
+        YAHOO.util.Event.addFocusListener(this.enablecheckbox, this.focus_event, this);
+        YAHOO.util.Event.addListener(this.enablecheckbox, 'change', this.focus_event, this);
+        YAHOO.util.Event.addBlurListener(this.enablecheckbox, this.blur_event, this);
+    }
+}
+
+/** The pop-up calendar that contains the calendar. */
+date_selector_calendar.panel = null;
+
+/** The shared YAHOO.widget.Calendar used by all date_selector_calendars. */
+date_selector_calendar.calendar = null;
+
+/** The date_selector_calendar that currently owns the shared stuff. */
+date_selector_calendar.currentowner = null;
+
+/** Used as a timeout when hiding the calendar on blur - so we don't hide the calendar
+ * if we are just jumping from on of our controls to another. */
+date_selector_calendar.hidetimeout = null;
+
+/** Timeout for repositioning after a delay after a change of months. */
+date_selector_calendar.repositiontimeout = null;
+
+/** Member variables. Pointers to various bits of the DOM. */
+date_selector_calendar.prototype.fieldset = null;
+date_selector_calendar.prototype.yearselect = null;
+date_selector_calendar.prototype.monthselect = null;
+date_selector_calendar.prototype.dayselect = null;
+date_selector_calendar.prototype.enablecheckbox = null;
+
+date_selector_calendar.cancel_any_timeout = function() {
+    if (date_selector_calendar.hidetimeout) {
+        clearTimeout(date_selector_calendar.hidetimeout);
+        date_selector_calendar.hidetimeout = null;
+    }
+    if (date_selector_calendar.repositiontimeout) {
+        clearTimeout(date_selector_calendar.repositiontimeout);
+        date_selector_calendar.repositiontimeout = null;
+    }
+}
+
+date_selector_calendar.delayed_reposition = function() {
+    if (date_selector_calendar.repositiontimeout) {
+        clearTimeout(date_selector_calendar.repositiontimeout);
+        date_selector_calendar.repositiontimeout = null;
+    }
+    date_selector_calendar.repositiontimeout = setTimeout(date_selector_calendar.fix_position, 500);
+}
+
+date_selector_calendar.fix_position = function() {
+    if (date_selector_calendar.currentowner) {
+        date_selector_calendar.panel.cfg.setProperty('context', [date_selector_calendar.currentowner.fieldset, 'bl', 'tl']);
+    }
+}
+
+date_selector_calendar.release_current = function() {
+    if (date_selector_calendar.currentowner) {
+        date_selector_calendar.currentowner.release_calendar();
+    }
+}
+
+date_selector_calendar.prototype.focus_event = function(e, me) {
+    date_selector_calendar.cancel_any_timeout();
+    if (me.enablecheckbox == null || me.enablecheckbox.checked) {
+        me.claim_calendar();
+    } else {
+        if (date_selector_calendar.currentowner) {
+            date_selector_calendar.currentowner.release_calendar();
+        }
+    }
+}
+
+date_selector_calendar.prototype.blur_event = function(e, me) {
+    date_selector_calendar.hidetimeout = setTimeout(date_selector_calendar.release_current, 300);
+}
+
+date_selector_calendar.prototype.handle_select_change = function(e, me) {
+    me.set_date_from_selects();
+}
+
+date_selector_calendar.document_click = function(event) {
+    if (date_selector_calendar.currentowner) {
+        var currentcontainer = date_selector_calendar.currentowner.fieldset;
+        var eventarget = YAHOO.util.Event.getTarget(event);
+        if (YAHOO.util.Dom.isAncestor(currentcontainer, eventarget)) {
+            setTimeout(function() {date_selector_calendar.cancel_any_timeout()}, 100);
+        } else {
+            date_selector_calendar.currentowner.release_calendar();
+        }
+    }
+}
+
+date_selector_calendar.prototype.claim_calendar = function() {
+    date_selector_calendar.cancel_any_timeout();
+    if (date_selector_calendar.currentowner == this) {
+        return;
+    }
+    if (date_selector_calendar.currentowner) {
+        date_selector_calendar.currentowner.release_calendar();
+    }
+
+    if (date_selector_calendar.currentowner != this) {
+        this.connect_handlers();
+    }
+    date_selector_calendar.currentowner = this;
+
+    date_selector_calendar.calendar.cfg.setProperty('mindate', new Date(this.yearselect.options[0].value, 0, 1));
+    date_selector_calendar.calendar.cfg.setProperty('maxdate', new Date(this.yearselect.options[this.yearselect.options.length - 1].value, 11, 31));
+    this.fieldset.insertBefore(date_selector_calendar.panel.element, this.yearselect.nextSibling);
+    this.set_date_from_selects();
+    date_selector_calendar.panel.show();
+    var me = this;
+    setTimeout(function() {date_selector_calendar.cancel_any_timeout()}, 100);
+}
+
+date_selector_calendar.prototype.set_date_from_selects = function() {
+    var year = parseInt(this.yearselect.value);
+    var month = parseInt(this.monthselect.value) - 1;
+    var day = parseInt(this.dayselect.value);
+    date_selector_calendar.calendar.select(new Date(year, month, day));
+    date_selector_calendar.calendar.setMonth(month);
+    date_selector_calendar.calendar.setYear(year);
+    date_selector_calendar.calendar.render();
+    date_selector_calendar.fix_position();
+}
+
+date_selector_calendar.prototype.set_selects_from_date = function(eventtype, args) {
+    var date = args[0][0];
+    var newyear = date[0];
+    var newindex = newyear - this.yearselect.options[0].value;
+    this.yearselect.selectedIndex = newindex;
+    this.monthselect.selectedIndex = date[1] - this.monthselect.options[0].value;
+    this.dayselect.selectedIndex = date[2] - this.dayselect.options[0].value;
+}
+
+date_selector_calendar.prototype.connect_handlers = function() {
+    YAHOO.util.Event.addListener([this.yearselect, this.monthselect, this.dayselect], 'change', this.handle_select_change, this);
+    date_selector_calendar.calendar.selectEvent.subscribe(this.set_selects_from_date, this, true);
+}
+
+date_selector_calendar.prototype.release_calendar = function() {
+    date_selector_calendar.panel.hide();
+    date_selector_calendar.currentowner = null;
+    YAHOO.util.Event.removeListener([this.yearselect, this.monthselect, this.dayselect], this.handle_select_change);
+    date_selector_calendar.calendar.selectEvent.unsubscribe(this.set_selects_from_date, this);
+}
Index: moodle/lib/formslib.php
--- moodle/lib/formslib.php Base (1.187)
+++ moodle/lib/formslib.php Locally Modified (Based On 1.187)
@@ -69,10 +69,11 @@
     global $PAGE;
     static $done = false;
     if (!$done) {
+        $PAGE->requires->js('lib/form/form.js');
         $PAGE->requires->yui_lib('calendar');
         $PAGE->requires->yui_lib('container');
         $PAGE->requires->js_function_call('init_date_selectors',
-                array(get_string('firstdayofweek')));
+                array(get_string('firstdayofweek')))->on_dom_ready();
         $done = true;
     }
 }
@@ -1667,18 +1668,17 @@
      * @return string
      */
     function getLockOptionEndScript(){
+        global $PAGE;
 
         $iname = $this->getAttribute('id').'items';
-        $js = '<script type="text/javascript">'."\n";
-        $js .= '//<![CDATA['."\n";
-        $js .= "var $iname = Array();\n";
 
+        $args = array();
         foreach ($this->_dependencies as $dependentOn => $conditions){
-            $js .= "{$iname}['$dependentOn'] = Array();\n";
+            $args[$dependentOn] = array();
             foreach ($conditions as $condition=>$values) {
-                $js .= "{$iname}['$dependentOn']['$condition'] = Array();\n";
+                $args[$dependentOn][$condition] = array();
                 foreach ($values as $value=>$dependents) {
-                    $js .= "{$iname}['$dependentOn']['$condition']['$value'] = Array();\n";
+                    $args[$dependentOn][$condition][$value] = array();
                     $i = 0;
                     foreach ($dependents as $dependent) {
                         $elements = $this->_getElNamesRecursive($dependent);
@@ -1690,17 +1690,18 @@
                             if ($element == $dependentOn) {
                                 continue;
                             }
-                            $js .= "{$iname}['$dependentOn']['$condition']['$value'][$i]='$element';\n";
+                            $args[$dependentOn][$condition][$value][$i] = $element;
                             $i++;
                         }
                     }
                 }
             }
         }
-        $js .="lockoptionsallsetup('".$this->getAttribute('id')."');\n";
-        $js .='//]]>'."\n";
-        $js .='</script>'."\n";
-        return $js;
+
+        $PAGE->requires->js('lib/form/form.js');
+        $PAGE->requires->data_for_js($iname, $args);
+        $PAGE->requires->js_function_call('lockoptionsallsetup', array($this->getAttribute('id')))->on_dom_ready();
+        return '';
     }
 
     /**
@@ -2158,9 +2159,10 @@
             $button_nojs = '<input name="'.$elementName.'" id="'.$elementName.(string)$advformcount.'" class="showadvancedbtn" value="'.$buttonlabel.'" type="submit" />';
 
             $buttonlabel = addslashes_js($buttonlabel);
+            $PAGE->requires->js('lib/form/form.js');
             $PAGE->requires->string_for_js('showadvanced', 'form');
             $PAGE->requires->string_for_js('hideadvanced', 'form');
-            $PAGE->requires->js_function_call('showAdvancedInit', Array($elementName.(string)$advformcount, $elementName, $buttonlabel));
+            $PAGE->requires->js_function_call('showAdvancedInit', Array($elementName.(string)$advformcount, $elementName, $buttonlabel))->on_dom_ready();
             
             $advformcount++;
             $header_html = str_replace('{button}', $button_nojs, $header_html);
Index: moodle/lib/javascript-deprecated.js
--- moodle/lib/javascript-deprecated.js Base (1.1)
+++ moodle/lib/javascript-deprecated.js Locally Modified (Based On 1.1)
@@ -1,5 +1,70 @@
-// Deprecated core Javascript functions for Moodle
+/**
+ * Deprecated core Javascript functions for Moodle
+ */
 function submitFormById(id) {
     submit_form_by_id(null, {id: id});
 }
 
+var DEPRECATE_ALERT = 1;
+var DEPRECATE_RETURN = 2;
+var DEPRECATE_RETURN_TRUE = 4;
+var DEPRECATE_RETURN_FALSE = 8;
+var DEPRECATE_RETURN_ARG = 16;
+var DEPRECATE_FUNCTION_CALL = 32;
+
+function deprecate(func, message, output) {
+    if (typeof this.window[func] != 'function'){
+        var args = arguments;
+        this.window[func] = function(){
+            if (output) {
+                if ((output & DEPRECATE_ALERT) && moodle_cfg.developer_debug) {
+                    alert('The function `'+func+"` has been deprecated.\n\n"+message);
+                }
+                if (output & DEPRECATE_RETURN_TRUE) {
+                    return true;
+                }
+                if (output & DEPRECATE_RETURN_FALSE) {
+                    return false;
+                }
+                if (output & DEPRECATE_RETURN) {
+                    return;
+                }
+                if ((output & DEPRECATE_RETURN_ARG) && args.length == 4) {
+                    return args[3]; // The third argument
+                }
+                if ((output & DEPRECATE_FUNCTION_CALL) && args.length == 4) {
+                    func = this.window['deprecated_'+func];
+                    if (typeof func == 'function') {
+                        return func.apply(null, Array.prototype.slice.call(args, 3));
+                    }
+                }
+            }
+        }
+    }
+}
+
+deprecate('popupchecker', 'Has been moved to mod/quiz/quiz.js as it was only been used in this one place.', DEPRECATE_ALERT & DEPRECATE_RETURN);
+deprecate('lockoption','Has been moved to mod/forum/forum.js as it was only been used here in core', DEPRECATE_ALERT & DEPRECATE_RETURN);
+deprecate('lockoptions','Has been moved to mod/forum/forum.js as it was only been used here in core', DEPRECATE_ALERT & DEPRECATE_RETURN);
+deprecate('unlockoption','Has been moved to mod/forum/forum.js as it was only been used here in core', DEPRECATE_ALERT & DEPRECATE_RETURN);
+deprecate('select_all_in_element_with_id','Has been moved to question/qbank.js as it was only been used here in core', DEPRECATE_ALERT & DEPRECATE_RETURN);
+deprecate('confirm_if','This function was not used anywhere in CORE and has been deprecated', DEPRECATE_ALERT & DEPRECATE_FUNCTION_CALL);
+deprecate('insertAtCursor','Has been moved to mod/data/data.js as it was only been used here in core', DEPRECATE_ALERT & DEPRECATE_RETURN);
+deprecate('addonload','This function was not used anywhere in CORE and has been deprecated', DEPRECATE_ALERT & DEPRECATE_FUNCTION_CALL);
+deprecate('moodle_initialise_body','Has been deprecated as it happens within a script tag right after body is opened', DEPRECATE_ALERT & DEPRECATE_RETURN);
+deprecate('dialog_callback','Has been deprecated as it is not used anywhere within core', DEPRECATE_ALERT & DEPRECATE_RETURN);
+
+function deprecated_confirm_if(expr, message) {
+    if(!expr) {
+        return true;
+    }
+    return confirm(message);
+}
+
+function deprecated_addonload(fn) {
+    var oldhandler=window.onload;
+    window.onload=function() {
+        if(oldhandler) oldhandler();
+            fn();
+    }
+}
Index: moodle/lib/javascript-static-priority.js
--- moodle/lib/javascript-static-priority.js No Base Revision
+++ moodle/lib/javascript-static-priority.js Locally New
@@ -0,0 +1,326 @@
+/**
+ * Functions within this file may be required within the page before the load event or
+ * on dom ready events have been fired.
+ * Because of this javascript-static-priority is included in the HTML head tag
+ * to ensure it is available ASAP
+ *
+ * Please only add functions to this file is you ABSOLUTLY must.
+ */
+
+function unmaskPassword(id) {
+  var pw = document.getElementById(id);
+  var chb = document.getElementById(id+'unmask');
+
+  try {
+    // first try IE way - it can not set name attribute later
+    if (chb.checked) {
+      var newpw = document.createElement('<input type="text" name="'+pw.name+'">');
+    } else {
+      var newpw = document.createElement('<input type="password" name="'+pw.name+'">');
+    }
+    newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue;
+  } catch (e) {
+    var newpw = document.createElement('input');
+    newpw.setAttribute('name', pw.name);
+    if (chb.checked) {
+      newpw.setAttribute('type', 'text');
+    } else {
+      newpw.setAttribute('type', 'password');
+    }
+    newpw.setAttribute('class', pw.getAttribute('class'));
+  }
+  newpw.id = pw.id;
+  newpw.size = pw.size;
+  newpw.onblur = pw.onblur;
+  newpw.onchange = pw.onchange;
+  newpw.value = pw.value;
+  pw.parentNode.replaceChild(newpw, pw);
+}
+
+/**
+ * Replacement for getElementsByClassName in browsers that aren't cool enough
+ *
+ * Relying on the built-in getElementsByClassName is far, far faster than
+ * using YUI.
+ *
+ * Note: the third argument used to be an object with odd behaviour. It now
+ * acts like the 'name' in the HTML5 spec, though the old behaviour is still
+ * mimicked if you pass an object.
+ *
+ * @param {Node} oElm The top-level node for searching. To search a whole
+ *                    document, use `document`.
+ * @param {String} strTagName filter by tag names
+ * @param {String} name same as HTML5 spec
+ */
+function getElementsByClassName(oElm, strTagName, name) {
+    // for backwards compatibility
+    if(typeof name == "object") {
+        var names = new Array();
+        for(var i=0; i<name.length; i++) names.push(names[i]);
+        name = names.join('');
+    }
+    // use native implementation if possible
+    if (oElm.getElementsByClassName && Array.filter) {
+        if (strTagName == '*') {
+            return oElm.getElementsByClassName(name);
+        } else {
+            return Array.filter(oElm.getElementsByClassName(name), function(el) {
+                return el.nodeName.toLowerCase() == strTagName.toLowerCase();
+            });
+        }
+    }
+    // native implementation unavailable, fall back to slow method
+    var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
+    var arrReturnElements = new Array();
+    var arrRegExpClassNames = new Array();
+    var names = name.split(' ');
+    for(var i=0; i<names.length; i++) {
+        arrRegExpClassNames.push(new RegExp("(^|\\s)" + names[i].replace(/\-/g, "\\-") + "(\\s|$)"));
+    }
+    var oElement;
+    var bMatchesAll;
+    for(var j=0; j<arrElements.length; j++) {
+        oElement = arrElements[j];
+        bMatchesAll = true;
+        for(var k=0; k<arrRegExpClassNames.length; k++) {
+            if(!arrRegExpClassNames[k].test(oElement.className)) {
+                bMatchesAll = false;
+                break;
+            }
+        }
+        if(bMatchesAll) {
+            arrReturnElements.push(oElement);
+        }
+    }
+    return (arrReturnElements)
+}
+
+/**
+ * Makes a best effort to connect back to Moodle to update a user preference,
+ * however, there is no mechanism for finding out if the update succeeded.
+ *
+ * Before you can use this function in your JavsScript, you must have called
+ * user_preference_allow_ajax_update from moodlelib.php to tell Moodle that
+ * the udpate is allowed, and how to safely clean and submitted values.
+ *
+ * @param String name the name of the setting to udpate.
+ * @param String the value to set it to.
+ */
+function set_user_preference(name, value) {
+    // Don't generate a script error if the library has not been loaded,
+    // unless we are a Developer, in which case we want the error.
+    if (YAHOO && YAHOO.util && YAHOO.util.Connect || moodle_cfg.developerdebug) {
+        var url = moodle_cfg.wwwroot + '/lib/ajax/setuserpref.php?sesskey=' +
+                moodle_cfg.sesskey + '&pref=' + encodeURI(name) + '&value=' + encodeURI(value);
+
+        // If we are a developer, ensure that failures are reported.
+        var callback = {};
+        if (moodle_cfg.developerdebug) {
+            callback.failure = function() {
+                var a = document.createElement('a');
+                a.href = url;
+                a.classname = 'error';
+                a.appendChild(document.createTextNode("Error updating user preference '" + name + "' using ajax. Clicking this link will repeat the Ajax call that failed so you can see the error."));
+                document.body.insertBefore(a, document.body.firstChild);
+            }
+        }
+
+        // Make the request.
+        YAHOO.util.Connect.asyncRequest('GET', url, callback);
+    }
+}
+
+/** Close the current browser window. */
+function close_window(e) {
+    YAHOO.util.Event.preventDefault(e);
+    self.close();
+}
+
+/**
+ * Close the current browser window, forcing the window/tab that opened this
+ * popup to reload itself. */
+function close_window_reloading_opener() {
+    if (window.opener) {
+        window.opener.location.reload(1);
+        close_window();
+        // Intentionally, only try to close the window if there is some evidence we are in a popup.
+    }
+}
+
+/**
+ * Used in a couple of modules to hide navigation areas when using AJAX
+ */
+function hide_item(itemid) {
+    var item = document.getElementById(itemid);
+    if (item) {
+        item.style.display = "none";
+    }
+}
+
+function show_item(itemid) {
+    var item = document.getElementById(itemid);
+    if (item) {
+        item.style.display = "";
+    }
+}
+
+function destroy_item(itemid) {
+    var item = document.getElementById(itemid);
+    if (item) {
+        item.parentNode.removeChild(item);
+    }
+}
+
+function scroll_to_end() {
+    window.scrollTo(0, 5000000);
+}
+
+var scrolltoendtimeout;
+function repeatedly_scroll_to_end() {
+    scrolltoendtimeout = setInterval(scroll_to_end, 50);
+}
+
+function cancel_scroll_to_end() {
+    if (scrolltoendtimeout) {
+        clearTimeout(scrolltoendtimeout);
+        scrolltoendtimeout = null;
+    }
+}
+
+function create_UFO_object(eid) {
+    UFO.create(FO, eid);
+}
+function build_querystring(obj) {
+    if (typeof obj !== 'object') {
+        return null;
+    }
+    var list = [];
+    for(var k in obj) {
+        k = encodeURIComponent(k);
+        var value = obj[k];
+        if(obj[k] instanceof Array) {
+            for(var i in value) {
+                list.push(k+'[]='+encodeURIComponent(value[i]));
+            }
+        } else {
+            list.push(k+'='+encodeURIComponent(value));
+        }
+    }
+    return list.join('&');
+}
+function stripHTML(str) {
+    var re = /<\S[^><]*>/g;
+    var ret = str.replace(re, "");
+    return ret;
+}
+
+function json_decode(json) {
+    try {
+        var obj = YAHOO.lang.JSON.parse(json);
+    } catch (e) {
+        alert(e.toString() + "\n" + stripHTML(json));
+    }
+    return obj;
+}
+
+function json_encode(data) {
+    try {
+        var json = YAHOO.lang.JSON.stringify(data);
+    } catch (e) {
+        alert(e.toString());
+    }
+    return json;
+}
+
+/**
+ * Prints a confirmation dialog in the style of DOM.confirm().
+ * @param object event A DOM event
+ * @param string message The message to show in the dialog
+ * @param string url The URL to forward to if YES is clicked. Disabled if fn is given
+ * @param function fn A JS function to run if YES is clicked.
+ */
+function confirm_dialog(event, args) {
+    var message = args.message;
+    var target = this;
+    target.args = args;
+    YAHOO.util.Event.preventDefault(event);
+
+    var simpledialog = new YAHOO.widget.SimpleDialog('confirmdialog',
+        { width: '300px',
+          fixedcenter: true,
+          modal: true,
+          visible: false,
+          draggable: false
+        }
+    );
+
+    simpledialog.setHeader(mstr.admin.confirmation);
+    simpledialog.setBody(message);
+    simpledialog.cfg.setProperty('icon', YAHOO.widget.SimpleDialog.ICON_WARN);
+
+    this.handle_cancel = function() {
+        this.hide();
+    };
+
+    this.handle_yes = function() {
+        this.hide();
+
+        if (target.args.callback) {
+            // args comes from PHP, so callback will be a string, needs to be evaluated by JS
+            var callback = eval('('+target.args.callback+')');
+            callback.apply(this);
+        }
+
+        if (target.tagName.toLowerCase() == 'a') {
+            window.location = target.href;
+        } else if (target.tagName.toLowerCase() == 'input') {
+            var parentelement = target.parentNode;
+            while (parentelement.tagName.toLowerCase() != 'form' && parentelement.tagName.toLowerCase() != 'body') {
+                parentelement = parentelement.parentNode;
+            }
+            if (parentelement.tagName.toLowerCase() == 'form') {
+                parentelement.submit();
+            }
+        } else if(moodle_cfg.developerdebug) {
+            alert("Element of type " + target.tagName + " is not supported by the confirm_dialog function. Use A or INPUT");
+        }
+    };
+
+    var buttons = [ { text: mstr.moodle.cancel, handler: this.handle_cancel, isDefault: true },
+                    { text: mstr.moodle.yes, handler: this.handle_yes } ];
+
+    simpledialog.cfg.queueProperty('buttons', buttons);
+
+    simpledialog.render(document.body);
+    simpledialog.show();
+    return simpledialog;
+}
+
+Number.prototype.fixed=function(n){
+    with(Math)
+        return round(Number(this)*pow(10,n))/pow(10,n);
+}
+function update_progress_bar (id, width, pt, msg, es){
+    var percent = pt*100;
+    var status = document.getElementById("status_"+id);
+    var percent_indicator = document.getElementById("pt_"+id);
+    var progress_bar = document.getElementById("progress_"+id);
+    var time_es = document.getElementById("time_"+id);
+    status.innerHTML = msg;
+    percent_indicator.innerHTML = percent.fixed(2) + '%';
+    if(percent == 100) {
+        progress_bar.style.background = "green";
+        time_es.style.display = "none";
+    } else {
+        progress_bar.style.background = "#FFCC66";
+        if (es == Infinity){
+            time_es.innerHTML = "Initializing...";
+        }else {
+            time_es.innerHTML = es.fixed(2)+" sec";
+            time_es.style.display
+                = "block";
+        }
+    }
+    progress_bar.style.width = width + "px";
+
+}
Index: moodle/lib/javascript-static.js
--- moodle/lib/javascript-static.js Base (1.91)
+++ moodle/lib/javascript-static.js Locally Modified (Based On 1.91)
@@ -1,14 +1,12 @@
-// Miscellaneous core Javascript functions for Moodle
+/**
+ * Miscellaneous core Javascript functions for Moodle
+ *
+ * This file is loaded right before the closing body tag.
+ * If you require your javascript function during the page while it is being
+ * processed then please add you function to javascript-static-priority instead.
+ * You should only do that is you absolutly must.
+ */
 
-function popupchecker(msg) {
-    var testwindow = window.open('itestwin.html', '', 'width=1,height=1,left=0,top=0,scrollbars=no');
-    if (!testwindow) {
-        alert(msg);
-    } else {
-        testwindow.close();
-    }
-}
-
 function checkall() {
     var inputs = document.getElementsByTagName('input');
     for (var i = 0; i < inputs.length; i++) {
@@ -27,185 +25,7 @@
     }
 }
 
-function lockoptions(formid, master, subitems) {
-  // Subitems is an array of names of sub items.
-  // Optionally, each item in subitems may have a
-  // companion hidden item in the form with the
-  // same name but prefixed by "h".
-  var form = document.forms[formid];
-
-  if (eval("form."+master+".checked")) {
-    for (i=0; i<subitems.length; i++) {
-      unlockoption(form, subitems[i]);
-    }
-  } else {
-    for (i=0; i<subitems.length; i++) {
-      lockoption(form, subitems[i]);
-    }
-  }
-  return(true);
-}
-
-function lockoption(form,item) {
-  eval("form."+item+".disabled=true");/* IE thing */
-  if(form.elements['h'+item]) {
-    eval("form.h"+item+".value=1");
-  }
-}
-
-function unlockoption(form,item) {
-  eval("form."+item+".disabled=false");/* IE thing */
-  if(form.elements['h'+item]) {
-    eval("form.h"+item+".value=0");
-  }
-}
-
 /**
- * Get the value of the 'virtual form element' with a particular name. That is,
- * abstracts away the difference between a normal form element, like a select
- * which is a single HTML element with a .value property, and a set of radio
- * buttons, which is several HTML elements.
- *
- * @param form a HTML form.
- * @param master the name of an element in that form.
- * @return the value of that element.
- */
-function get_form_element_value(form, name) {
-    var element = form[name];
-    if (!element) {
-        return null;
-    }
-    if (element.tagName) {
-        // Ordinarly thing like a select box.
-        return element.value;
-    }
-    // Array of things, like radio buttons.
-    for (var j = 0; j < element.length; j++) {
-        var el = element[j];
-        if (el.checked) {
-            return el.value;
-        }
-    }
-    return null;
-}
-
-
-/**
- * Set the disabled state of the 'virtual form element' with a particular name.
- * This abstracts away the difference between a normal form element, like a select
- * which is a single HTML element with a .value property, and a set of radio
- * buttons, which is several HTML elements.
- *
- * @param form a HTML form.
- * @param master the name of an element in that form.
- * @param disabled the disabled state to set.
- */
-function set_form_element_disabled(form, name, disabled) {
-    var element = form[name];
-    if (!element) {
-        return;
-    }
-    if (element.tagName) {
-        // Ordinarly thing like a select box.
-        element.disabled = disabled;
-    }
-    // Array of things, like radio buttons.
-    for (var j = 0; j < element.length; j++) {
-        var el = element[j];
-        el.disabled = disabled;
-    }
-}
-
-function lockoptionsall(formid) {
-    var form = document.forms[formid];
-    var dependons = eval(formid + 'items');
-    var tolock = [];
-    for (var dependon in dependons) {
-        // change for MooTools compatibility
-        if (!dependons.propertyIsEnumerable(dependon)) {
-            continue;
-        }
-        if (!form[dependon]) {
-            continue;
-        }
-        for (var condition in dependons[dependon]) {
-            for (var value in dependons[dependon][condition]) {
-                var lock;
-                switch (condition) {
-                  case 'notchecked':
-                      lock = !form[dependon].checked; break;
-                  case 'checked':
-                      lock = form[dependon].checked; break;
-                  case 'noitemselected':
-                      lock = form[dependon].selectedIndex == -1; break;
-                  case 'eq':
-                      lock = get_form_element_value(form, dependon) == value; break;
-                  default:
-                      lock = get_form_element_value(form, dependon) != value; break;
-                }
-                for (var ei in dependons[dependon][condition][value]) {
-                    // change for MooTools compatibility
-                    if (!window.webkit && (!dependons[dependon][condition][value].propertyIsEnumerable(ei))) {
-                        continue;
-                    }
-                    var eltolock = dependons[dependon][condition][value][ei];
-                    if (tolock[eltolock] != null) {
-                        tolock[eltolock] = lock || tolock[eltolock];
-                    } else {
-                        tolock[eltolock] = lock;
-                    }
-                }
-            }
-        }
-    }
-    for (var el in tolock) {
-        // change for MooTools compatibility
-        if (!tolock.propertyIsEnumerable(el)) {
-            continue;
-        }
-        set_form_element_disabled(form, el, tolock[el]);
-    }
-    return true;
-}
-
-function lockoptionsallsetup(formid) {
-    var form = document.forms[formid];
-    var dependons = eval(formid+'items');
-    for (var dependon in dependons) {
-        // change for MooTools compatibility
-        if (!dependons.propertyIsEnumerable(dependon)) {
-            continue;
-        }
-        var masters = form[dependon];
-        if (!masters) {
-            continue;
-        }
-        if (masters.tagName) {
-            // If master is radio buttons, we get an array, otherwise we don't.
-            // Convert both cases to an array for convinience.
-            masters = [masters];
-        }
-        for (var j = 0; j < masters.length; j++) {
-            master = masters[j];
-            master.formid = formid;
-            master.onclick  = function() {return lockoptionsall(this.formid);};
-            master.onblur   = function() {return lockoptionsall(this.formid);};
-            master.onchange = function() {return lockoptionsall(this.formid);};
-        }
-    }
-    for (var i = 0; i < form.elements.length; i++) {
-        var formelement = form.elements[i];
-        if (formelement.type=='reset') {
-            formelement.formid = formid;
-            formelement.onclick  = function() {this.form.reset();return lockoptionsall(this.formid);};
-            formelement.onblur   = function() {this.form.reset();return lockoptionsall(this.formid);};
-            formelement.onchange = function() {this.form.reset();return lockoptionsall(this.formid);};
-        }
-    }
-    return lockoptionsall(formid);
-}
-
-/**
  * Helper function mainly for drop-down menus' onchange events,
  * submits the form designated by args.id. If args.selectid is also
  * given, it only submits the form if the selected <option> is not
@@ -238,24 +58,6 @@
     return theform.submit();
 }
 
-/**
- * Either check, or uncheck, all checkboxes inside the element with id is
- * @param id the id of the container
- * @param checked the new state, either '' or 'checked'.
- */
-function select_all_in_element_with_id(id, checked) {
-    var container = document.getElementById(id);
-    if (!container) {
-        return;
-    }
-    var inputs = container.getElementsByTagName('input');
-    for (var i = 0; i < inputs.length; ++i) {
-        if (inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
-            inputs[i].checked = checked;
-        }
-    }
-}
-
 function select_all_in(elTagName, elClass, elId) {
     var inputs = document.getElementsByTagName('input');
     inputs = filterByParent(inputs, function(el) {return findParentNode(el, elTagName, elClass, elId);});
@@ -276,14 +78,6 @@
     }
 }
 
-function confirm_if(expr, message) {
-    if(!expr) {
-        return true;
-    }
-    return confirm(message);
-}
-
-
 /*
     findParentNode (start, elementName, elementClass, elementID)
 
@@ -340,302 +134,7 @@
     }
     return children;
 }
-/*
-    elementSetHide (elements, hide)
 
-    Adds or removes the "hide" class for the specified elements depending on boolean hide.
-*/
-function elementShowAdvanced(elements, show) {
-    for (var elementIndex in elements) {
-        element = elements[elementIndex];
-        element.className = element.className.replace(new RegExp(' ?hide'), '')
-        if(!show) {
-            element.className += ' hide';
-        }
-    }
-}
-
-function showAdvancedInit(addBefore, nameAttr, buttonLabel, hideText, showText) {
-    var showHideButton = document.createElement("input");
-    showHideButton.type = 'button';
-    showHideButton.value = buttonLabel;
-    showHideButton.name = nameAttr;
-    showHideButton.moodle = {
-        hideLabel: mstr.form.hideadvanced,
-        showLabel: mstr.form.showadvanced
-    };
-    YAHOO.util.Event.addListener(showHideButton, 'click', showAdvancedOnClick);
-    el = document.getElementById(addBefore);
-    el.parentNode.insertBefore(showHideButton, el);
-}
-
-function showAdvancedOnClick(e) {
-    var button = e.target ? e.target : e.srcElement;
-
-    var toSet=findChildNodes(button.form, null, 'advanced');
-    var buttontext = '';
-    if (button.form.elements['mform_showadvanced_last'].value == '0' ||  button.form.elements['mform_showadvanced_last'].value == '' ) {
-        elementShowAdvanced(toSet, true);
-        buttontext = button.moodle.hideLabel;
-        button.form.elements['mform_showadvanced_last'].value = '1';
-    } else {
-        elementShowAdvanced(toSet, false);
-        buttontext = button.moodle.showLabel;
-        button.form.elements['mform_showadvanced_last'].value = '0';
-    }
-    var formelements = button.form.elements;
-    // Fixed MDL-10506
-    for (var i = 0; i < formelements.length; i++) {
-        if (formelements[i] && formelements[i].name && (formelements[i].name=='mform_showadvanced')) {
-            formelements[i].value = buttontext;
-        }
-    }
-    //never submit the form if js is enabled.
-    return false;
-}
-
-function unmaskPassword(id) {
-  var pw = document.getElementById(id);
-  var chb = document.getElementById(id+'unmask');
-
-  try {
-    // first try IE way - it can not set name attribute later
-    if (chb.checked) {
-      var newpw = document.createElement('<input type="text" name="'+pw.name+'">');
-    } else {
-      var newpw = document.createElement('<input type="password" name="'+pw.name+'">');
-    }
-    newpw.attributes['class'].nodeValue = pw.attributes['class'].nodeValue;
-  } catch (e) {
-    var newpw = document.createElement('input');
-    newpw.setAttribute('name', pw.name);
-    if (chb.checked) {
-      newpw.setAttribute('type', 'text');
-    } else {
-      newpw.setAttribute('type', 'password');
-    }
-    newpw.setAttribute('class', pw.getAttribute('class'));
-  }
-  newpw.id = pw.id;
-  newpw.size = pw.size;
-  newpw.onblur = pw.onblur;
-  newpw.onchange = pw.onchange;
-  newpw.value = pw.value;
-  pw.parentNode.replaceChild(newpw, pw);
-}
-
-/**
- * Search a Moodle form to find all the fdate_time_selector and fdate_selector
- * elements, and add date_selector_calendar instance to each.
- */
-function init_date_selectors(firstdayofweek) {
-    var els = YAHOO.util.Dom.getElementsByClassName('fdate_time_selector', 'fieldset');
-    for (var i = 0; i < els.length; i++) {
-        new date_selector_calendar(els[i], firstdayofweek);
-    }
-    els = YAHOO.util.Dom.getElementsByClassName('fdate_selector', 'fieldset');
-    for (i = 0; i < els.length; i++) {
-        new date_selector_calendar(els[i], firstdayofweek);
-    }
-}
-
-/**
- * Constructor for a JavaScript object that connects to a fdate_time_selector
- * or a fdate_selector in a Moodle form, and shows a popup calendar whenever
- * that element has keyboard focus.
- * @param el the fieldset class="fdate_time_selector" or "fdate_selector".
- */
-function date_selector_calendar(el, firstdayofweek) {
-    // Ensure that the shared div and calendar exist.
-    if (!date_selector_calendar.panel) {
-        date_selector_calendar.panel = new YAHOO.widget.Panel('date_selector_calendar_panel',
-                {visible: false, draggable: false});
-        var div = document.createElement('div');
-        date_selector_calendar.panel.setBody(div);
-        date_selector_calendar.panel.render(document.body);
-
-        YAHOO.util.Event.addListener(document, 'click', date_selector_calendar.document_click);
-        date_selector_calendar.panel.showEvent.subscribe(function() {
-            date_selector_calendar.panel.fireEvent('changeContent');
-        });
-        date_selector_calendar.panel.hideEvent.subscribe(date_selector_calendar.release_current);
-
-        date_selector_calendar.calendar = new YAHOO.widget.Calendar(div,
-                {iframe: false, hide_blank_weeks: true, start_weekday: firstdayofweek});
-        date_selector_calendar.calendar.renderEvent.subscribe(function() {
-            date_selector_calendar.panel.fireEvent('changeContent');
-            date_selector_calendar.delayed_reposition();
-        });
-    }
-
-    this.fieldset = el;
-    var controls = el.getElementsByTagName('select');
-    for (var i = 0; i < controls.length; i++) {
-        if (/\[year\]$/.test(controls[i].name)) {
-            this.yearselect = controls[i];
-        } else if (/\[month\]$/.test(controls[i].name)) {
-            this.monthselect = controls[i];
-        } else if (/\[day\]$/.test(controls[i].name)) {
-            this.dayselect = controls[i];
-        } else {
-            YAHOO.util.Event.addFocusListener(controls[i], date_selector_calendar.cancel_any_timeout, this);
-            YAHOO.util.Event.addBlurListener(controls[i], this.blur_event, this);
-        }
-    }
-    if (!(this.yearselect && this.monthselect && this.dayselect)) {
-        throw 'Failed to initialise calendar.';
-    }
-    YAHOO.util.Event.addFocusListener([this.yearselect, this.monthselect, this.dayselect], this.focus_event, this);
-    YAHOO.util.Event.addBlurListener([this.yearselect, this.monthselect, this.dayselect], this.blur_event, this);
-
-    this.enablecheckbox = el.getElementsByTagName('input')[0];
-    if (this.enablecheckbox) {
-        YAHOO.util.Event.addFocusListener(this.enablecheckbox, this.focus_event, this);
-        YAHOO.util.Event.addListener(this.enablecheckbox, 'change', this.focus_event, this);
-        YAHOO.util.Event.addBlurListener(this.enablecheckbox, this.blur_event, this);
-    }
-}
-
-/** The pop-up calendar that contains the calendar. */
-date_selector_calendar.panel = null;
-
-/** The shared YAHOO.widget.Calendar used by all date_selector_calendars. */
-date_selector_calendar.calendar = null;
-
-/** The date_selector_calendar that currently owns the shared stuff. */
-date_selector_calendar.currentowner = null;
-
-/** Used as a timeout when hiding the calendar on blur - so we don't hide the calendar
- * if we are just jumping from on of our controls to another. */
-date_selector_calendar.hidetimeout = null;
-
-/** Timeout for repositioning after a delay after a change of months. */
-date_selector_calendar.repositiontimeout = null;
-
-/** Member variables. Pointers to various bits of the DOM. */
-date_selector_calendar.prototype.fieldset = null;
-date_selector_calendar.prototype.yearselect = null;
-date_selector_calendar.prototype.monthselect = null;
-date_selector_calendar.prototype.dayselect = null;
-date_selector_calendar.prototype.enablecheckbox = null;
-
-date_selector_calendar.cancel_any_timeout = function() {
-    if (date_selector_calendar.hidetimeout) {
-        clearTimeout(date_selector_calendar.hidetimeout);
-        date_selector_calendar.hidetimeout = null;
-    }
-    if (date_selector_calendar.repositiontimeout) {
-        clearTimeout(date_selector_calendar.repositiontimeout);
-        date_selector_calendar.repositiontimeout = null;
-    }
-}
-
-date_selector_calendar.delayed_reposition = function() {
-    if (date_selector_calendar.repositiontimeout) {
-        clearTimeout(date_selector_calendar.repositiontimeout);
-        date_selector_calendar.repositiontimeout = null;
-    }
-    date_selector_calendar.repositiontimeout = setTimeout(date_selector_calendar.fix_position, 500);
-}
-
-date_selector_calendar.fix_position = function() {
-    if (date_selector_calendar.currentowner) {
-        date_selector_calendar.panel.cfg.setProperty('context', [date_selector_calendar.currentowner.fieldset, 'bl', 'tl']);
-    }
-}
-
-date_selector_calendar.release_current = function() {
-    if (date_selector_calendar.currentowner) {
-        date_selector_calendar.currentowner.release_calendar();
-    }
-}
-
-date_selector_calendar.prototype.focus_event = function(e, me) {
-    date_selector_calendar.cancel_any_timeout();
-    if (me.enablecheckbox == null || me.enablecheckbox.checked) {
-        me.claim_calendar();
-    } else {
-        if (date_selector_calendar.currentowner) {
-            date_selector_calendar.currentowner.release_calendar();
-        }
-    }
-}
-
-date_selector_calendar.prototype.blur_event = function(e, me) {
-    date_selector_calendar.hidetimeout = setTimeout(date_selector_calendar.release_current, 300);
-}
-
-date_selector_calendar.prototype.handle_select_change = function(e, me) {
-    me.set_date_from_selects();
-}
-
-date_selector_calendar.document_click = function(event) {
-    if (date_selector_calendar.currentowner) {
-        var currentcontainer = date_selector_calendar.currentowner.fieldset;
-        var eventarget = YAHOO.util.Event.getTarget(event);
-        if (YAHOO.util.Dom.isAncestor(currentcontainer, eventarget)) {
-            setTimeout(function() {date_selector_calendar.cancel_any_timeout()}, 100);
-        } else {
-            date_selector_calendar.currentowner.release_calendar();
-        }
-    }
-}
-
-date_selector_calendar.prototype.claim_calendar = function() {
-    date_selector_calendar.cancel_any_timeout();
-    if (date_selector_calendar.currentowner == this) {
-        return;
-    }
-    if (date_selector_calendar.currentowner) {
-        date_selector_calendar.currentowner.release_calendar();
-    }
-
-    if (date_selector_calendar.currentowner != this) {
-        this.connect_handlers();
-    }
-    date_selector_calendar.currentowner = this;
-
-    date_selector_calendar.calendar.cfg.setProperty('mindate', new Date(this.yearselect.options[0].value, 0, 1));
-    date_selector_calendar.calendar.cfg.setProperty('maxdate', new Date(this.yearselect.options[this.yearselect.options.length - 1].value, 11, 31));
-    this.fieldset.insertBefore(date_selector_calendar.panel.element, this.yearselect.nextSibling);
-    this.set_date_from_selects();
-    date_selector_calendar.panel.show();
-    var me = this;
-    setTimeout(function() {date_selector_calendar.cancel_any_timeout()}, 100);
-}
-
-date_selector_calendar.prototype.set_date_from_selects = function() {
-    var year = parseInt(this.yearselect.value);
-    var month = parseInt(this.monthselect.value) - 1;
-    var day = parseInt(this.dayselect.value);
-    date_selector_calendar.calendar.select(new Date(year, month, day));
-    date_selector_calendar.calendar.setMonth(month);
-    date_selector_calendar.calendar.setYear(year);
-    date_selector_calendar.calendar.render();
-    date_selector_calendar.fix_position();
-}
-
-date_selector_calendar.prototype.set_selects_from_date = function(eventtype, args) {
-    var date = args[0][0];
-    var newyear = date[0];
-    var newindex = newyear - this.yearselect.options[0].value;
-    this.yearselect.selectedIndex = newindex;
-    this.monthselect.selectedIndex = date[1] - this.monthselect.options[0].value;
-    this.dayselect.selectedIndex = date[2] - this.dayselect.options[0].value;
-}
-
-date_selector_calendar.prototype.connect_handlers = function() {
-    YAHOO.util.Event.addListener([this.yearselect, this.monthselect, this.dayselect], 'change', this.handle_select_change, this);
-    date_selector_calendar.calendar.selectEvent.subscribe(this.set_selects_from_date, this, true);
-}
-
-date_selector_calendar.prototype.release_calendar = function() {
-    date_selector_calendar.panel.hide();
-    date_selector_calendar.currentowner = null;
-    YAHOO.util.Event.removeListener([this.yearselect, this.monthselect, this.dayselect], this.handle_select_change);
-    date_selector_calendar.calendar.selectEvent.unsubscribe(this.set_selects_from_date, this);
-}
-
 function filterByParent(elCollection, parentFinder) {
     var filteredCollection = [];
     for (var i = 0; i < elCollection.length; ++i) {
@@ -686,99 +185,6 @@
     }
 }
 
-
-/*
-   Insert myValue at current cursor position
- */
-function insertAtCursor(myField, myValue) {
-    // IE support
-    if (document.selection) {
-        myField.focus();
-        sel = document.selection.createRange();
-        sel.text = myValue;
-    }
-    // Mozilla/Netscape support
-    else if (myField.selectionStart || myField.selectionStart == '0') {
-        var startPos = myField.selectionStart;
-        var endPos = myField.selectionEnd;
-        myField.value = myField.value.substring(0, startPos)
-            + myValue + myField.value.substring(endPos, myField.value.length);
-    } else {
-        myField.value += myValue;
-    }
-}
-
-
-/*
-        Call instead of setting window.onload directly or setting body onload=.
-        Adds your function to a chain of functions rather than overwriting anything
-        that exists.
-*/
-function addonload(fn) {
-    var oldhandler=window.onload;
-    window.onload=function() {
-        if(oldhandler) oldhandler();
-            fn();
-    }
-}
-/**
- * Replacement for getElementsByClassName in browsers that aren't cool enough
- * 
- * Relying on the built-in getElementsByClassName is far, far faster than
- * using YUI.
- * 
- * Note: the third argument used to be an object with odd behaviour. It now
- * acts like the 'name' in the HTML5 spec, though the old behaviour is still
- * mimicked if you pass an object.
- *
- * @param {Node} oElm The top-level node for searching. To search a whole
- *                    document, use `document`.
- * @param {String} strTagName filter by tag names
- * @param {String} name same as HTML5 spec
- */
-function getElementsByClassName(oElm, strTagName, name) {
-    // for backwards compatibility
-    if(typeof name == "object") {
-        var names = new Array();
-        for(var i=0; i<name.length; i++) names.push(names[i]);
-        name = names.join('');
-    }
-    // use native implementation if possible
-    if (oElm.getElementsByClassName && Array.filter) {
-        if (strTagName == '*') {
-            return oElm.getElementsByClassName(name);
-        } else {
-            return Array.filter(oElm.getElementsByClassName(name), function(el) {
-                return el.nodeName.toLowerCase() == strTagName.toLowerCase();
-            });
-        }
-    }
-    // native implementation unavailable, fall back to slow method
-    var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
-    var arrReturnElements = new Array();
-    var arrRegExpClassNames = new Array();
-    var names = name.split(' ');
-    for(var i=0; i<names.length; i++) {
-        arrRegExpClassNames.push(new RegExp("(^|\\s)" + names[i].replace(/\-/g, "\\-") + "(\\s|$)"));
-    }
-    var oElement;
-    var bMatchesAll;
-    for(var j=0; j<arrElements.length; j++) {
-        oElement = arrElements[j];
-        bMatchesAll = true;
-        for(var k=0; k<arrRegExpClassNames.length; k++) {
-            if(!arrRegExpClassNames[k].test(oElement.className)) {
-                bMatchesAll = false;
-                break;
-            }
-        }
-        if(bMatchesAll) {
-            arrReturnElements.push(oElement);
-        }
-    }
-    return (arrReturnElements)
-}
-
 function openpopup(event, args) {
 
     YAHOO.util.Event.preventDefault(event);
@@ -831,46 +237,7 @@
 }
 
 /**
- * Makes a best effort to connect back to Moodle to update a user preference,
- * however, there is no mechanism for finding out if the update succeeded.
- *
- * Before you can use this function in your JavsScript, you must have called
- * user_preference_allow_ajax_update from moodlelib.php to tell Moodle that
- * the udpate is allowed, and how to safely clean and submitted values.
- *
- * @param String name the name of the setting to udpate.
- * @param String the value to set it to.
- */
-function set_user_preference(name, value) {
-    // Don't generate a script error if the library has not been loaded,
-    // unless we are a Developer, in which case we want the error.
-    if (YAHOO && YAHOO.util && YAHOO.util.Connect || moodle_cfg.developerdebug) {
-        var url = moodle_cfg.wwwroot + '/lib/ajax/setuserpref.php?sesskey=' +
-                moodle_cfg.sesskey + '&pref=' + encodeURI(name) + '&value=' + encodeURI(value);
-
-        // If we are a developer, ensure that failures are reported.
-        var callback = {};
-        if (moodle_cfg.developerdebug) {
-            callback.failure = function() {
-                var a = document.createElement('a');
-                a.href = url;
-                a.classname = 'error';
-                a.appendChild(document.createTextNode("Error updating user preference '" + name + "' using ajax. Clicking this link will repeat the Ajax call that failed so you can see the error."));
-                document.body.insertBefore(a, document.body.firstChild);
-            }
-        }
-
-        // Make the request.
-        YAHOO.util.Connect.asyncRequest('GET', url, callback);
-    }
-}
-
-function moodle_initialise_body() {
-    document.body.className += ' jsenabled';
-}
-
-/**
- * Oject to handle a collapsible region, see print_collapsible_region in weblib.php
+ * Object to handle a collapsible region, see print_collapsible_region in weblib.php
  * @constructor
  * @param String id the HTML id for the div.
  * @param String userpref the user preference that records the state of this box. false if none.
@@ -1067,47 +434,7 @@
     }
 }
 
-/** Close the current browser window. */
-function close_window(e) {
-    YAHOO.util.Event.preventDefault(e);
-    self.close();
-}
-
 /**
- * Close the current browser window, forcing the window/tab that opened this
- * popup to reload itself. */
-function close_window_reloading_opener() {
-    if (window.opener) {
-        window.opener.location.reload(1);
-        close_window();
-        // Intentionally, only try to close the window if there is some evidence we are in a popup.
-    }
-}
-
-/**
- * Used in a couple of modules to hide navigation areas when using AJAX
- */
-function hide_item(itemid) {
-    var item = document.getElementById(itemid);
-    if (item) {
-        item.style.display = "none";
-    }
-}
-
-function show_item(itemid) {
-    var item = document.getElementById(itemid);
-    if (item) {
-        item.style.display = "";
-    }
-}
-
-function destroy_item(itemid) {
-    var item = document.getElementById(itemid);
-    if (item) {
-        item.parentNode.removeChild(item);
-    }
-}
-/**
  * Tranfer keyboard focus to the HTML element with the given id, if it exists.
  * @param controlid the control id.
  */
@@ -1128,68 +455,6 @@
     }
 }
 
-function scroll_to_end() {
-    window.scrollTo(0, 5000000);
-}
-
-var scrolltoendtimeout;
-function repeatedly_scroll_to_end() {
-    scrolltoendtimeout = setInterval(scroll_to_end, 50);
-}
-
-function cancel_scroll_to_end() {
-    if (scrolltoendtimeout) {
-        clearTimeout(scrolltoendtimeout);
-        scrolltoendtimeout = null;
-    }
-}
-
-function create_UFO_object(eid) {
-    UFO.create(FO, eid);
-}
-function build_querystring(obj) {
-    if (typeof obj !== 'object') {
-        return null;
-    }
-    var list = [];
-    for(var k in obj) {
-        k = encodeURIComponent(k);
-        var value = obj[k];
-        if(obj[k] instanceof Array) {
-            for(var i in value) {
-                list.push(k+'[]='+encodeURIComponent(value[i]));
-            }
-        } else {
-            list.push(k+'='+encodeURIComponent(value));
-        }
-    }
-    return list.join('&');
-}
-
-function stripHTML(str) {
-    var re = /<\S[^><]*>/g;
-    var ret = str.replace(re, "");
-    return ret;
-}
-
-function json_decode(json) {
-    try {
-        var obj = YAHOO.lang.JSON.parse(json);
-    } catch (e) {
-        alert(e.toString() + "\n" + stripHTML(json));
-    }
-    return obj;
-}
-
-function json_encode(data) {
-    try {
-        var json = YAHOO.lang.JSON.stringify(data);
-    } catch (e) {
-        alert(e.toString());
-    }
-    return json;
-}
-
 /**
  * Finds all help icons on the page and initiates YUI tooltips for
  * each of them, which load a truncated version of the help's content
@@ -1244,100 +509,3 @@
         }
     );
 }
-
-/**
- * Prints a confirmation dialog in the style of DOM.confirm().
- * @param object event A DOM event
- * @param string message The message to show in the dialog
- * @param string url The URL to forward to if YES is clicked. Disabled if fn is given
- * @param function fn A JS function to run if YES is clicked.
- */
-function confirm_dialog(event, args) {
-    var message = args.message;
-    var target = this;
-    target.args = args;
-    YAHOO.util.Event.preventDefault(event);
-
-    var simpledialog = new YAHOO.widget.SimpleDialog('confirmdialog',
-        { width: '300px',
-          fixedcenter: true,
-          modal: true,
-          visible: false,
-          draggable: false
-        }
-    );
-
-    simpledialog.setHeader(mstr.admin.confirmation);
-    simpledialog.setBody(message);
-    simpledialog.cfg.setProperty('icon', YAHOO.widget.SimpleDialog.ICON_WARN);
-
-    this.handle_cancel = function() {
-        this.hide();
-    };
-
-    this.handle_yes = function() {
-        this.hide();
-
-        if (target.args.callback) {
-            // args comes from PHP, so callback will be a string, needs to be evaluated by JS
-            var callback = eval('('+target.args.callback+')');
-            callback.apply(this);
-        }
-
-        if (target.tagName.toLowerCase() == 'a') {
-            window.location = target.href;
-        } else if (target.tagName.toLowerCase() == 'input') {
-            var parentelement = target.parentNode;
-            while (parentelement.tagName.toLowerCase() != 'form' && parentelement.tagName.toLowerCase() != 'body') {
-                parentelement = parentelement.parentNode;
-            }
-            if (parentelement.tagName.toLowerCase() == 'form') {
-                parentelement.submit();
-            }
-        } else if(moodle_cfg.developerdebug) {
-            alert("Element of type " + target.tagName + " is not supported by the confirm_dialog function. Use A or INPUT");
-        }
-    };
-
-    var buttons = [ { text: mstr.moodle.cancel, handler: this.handle_cancel, isDefault: true },
-                    { text: mstr.moodle.yes, handler: this.handle_yes } ];
-
-    simpledialog.cfg.queueProperty('buttons', buttons);
-
-    simpledialog.render(document.body);
-    simpledialog.show();
-    return simpledialog;
-}
-
-function dialog_callback() {
-    console.debug(this);
-    console.debug(this.args);
-}
-Number.prototype.fixed=function(n){
-    with(Math)
-        return round(Number(this)*pow(10,n))/pow(10,n);
-}
-function update_progress_bar (id, width, pt, msg, es){
-    var percent = pt*100;
-    var status = document.getElementById("status_"+id);
-    var percent_indicator = document.getElementById("pt_"+id);
-    var progress_bar = document.getElementById("progress_"+id);
-    var time_es = document.getElementById("time_"+id);
-    status.innerHTML = msg;
-    percent_indicator.innerHTML = percent.fixed(2) + '%';
-    if(percent == 100) {
-        progress_bar.style.background = "green";
-        time_es.style.display = "none";
-    } else {
-        progress_bar.style.background = "#FFCC66";
-        if (es == Infinity){
-            time_es.innerHTML = "Initializing...";
-        }else {
-            time_es.innerHTML = es.fixed(2)+" sec";
-            time_es.style.display
-                = "block";
-        }
-    }
-    progress_bar.style.width = width + "px";
-
-}
Index: moodle/lib/outputrenderers.php
--- moodle/lib/outputrenderers.php Base (1.29)
+++ moodle/lib/outputrenderers.php Locally Modified (Based On 1.29)
@@ -489,9 +489,10 @@
             $output .= '<meta http-equiv="refresh" content="'.$this->page->periodicrefreshdelay.';url='.$this->page->url->out().'" />';
         }
 
-        $this->page->requires->js('lib/javascript-static.js')->in_head();
+        $this->page->requires->js('lib/javascript-static-priority.js')->in_head();
         $this->page->requires->js('lib/javascript-deprecated.js')->in_head();
         $this->page->requires->js('lib/javascript-mod.php')->in_head();
+        $this->page->requires->js('lib/javascript-static.js');
         $this->page->requires->js_function_call('setTimeout', array('fix_column_widths()', 20));
 
         $focus = $this->page->focuscontrol;
Index: moodle/mod/data/data.js
--- moodle/mod/data/data.js Base (1.1)
+++ moodle/mod/data/data.js Locally Modified (Based On 1.1)
@@ -36,3 +36,24 @@
         }
     }
 }
+
+/*
+   Insert myValue at current cursor position
+ */
+function insertAtCursor(myField, myValue) {
+    // IE support
+    if (document.selection) {
+        myField.focus();
+        sel = document.selection.createRange();
+        sel.text = myValue;
+    }
+    // Mozilla/Netscape support
+    else if (myField.selectionStart || myField.selectionStart == '0') {
+        var startPos = myField.selectionStart;
+        var endPos = myField.selectionEnd;
+        myField.value = myField.value.substring(0, startPos)
+            + myValue + myField.value.substring(endPos, myField.value.length);
+    } else {
+        myField.value += myValue;
+    }
+}
Index: moodle/mod/forum/forum.js
--- moodle/mod/forum/forum.js Base (1.3)
+++ moodle/mod/forum/forum.js Locally Modified (Based On 1.3)
@@ -24,3 +24,36 @@
 function lockoptions_timefromitems() {
     lockoptions('searchform','timetorestrict', timetoitems);
 }
+
+function lockoptions(formid, master, subitems) {
+  // Subitems is an array of names of sub items.
+  // Optionally, each item in subitems may have a
+  // companion hidden item in the form with the
+  // same name but prefixed by "h".
+  var form = document.forms[formid];
+
+  if (eval("form."+master+".checked")) {
+    for (i=0; i<subitems.length; i++) {
+      unlockoption(form, subitems[i]);
+    }
+  } else {
+    for (i=0; i<subitems.length; i++) {
+      lockoption(form, subitems[i]);
+    }
+  }
+  return(true);
+}
+
+function lockoption(form,item) {
+  eval("form."+item+".disabled=true");/* IE thing */
+  if(form.elements['h'+item]) {
+    eval("form.h"+item+".value=1");
+  }
+}
+
+function unlockoption(form,item) {
+  eval("form."+item+".disabled=false");/* IE thing */
+  if(form.elements['h'+item]) {
+    eval("form.h"+item+".value=0");
+  }
+}
Index: moodle/mod/quiz/quiz.js
--- moodle/mod/quiz/quiz.js Base (1.19)
+++ moodle/mod/quiz/quiz.js Locally Modified (Based On 1.19)
@@ -268,3 +268,12 @@
 function reveal_start_button() {
     document.getElementById('quizstartbutton').style.cssText = '';
 }
+
+function popupchecker(msg) {
+    var testwindow = window.open('itestwin.html', '', 'width=1,height=1,left=0,top=0,scrollbars=no');
+    if (!testwindow) {
+        alert(msg);
+    } else {
+        testwindow.close();
+    }
+}
Index: moodle/mod/quiz/view.php
--- moodle/mod/quiz/view.php Base (1.175)
+++ moodle/mod/quiz/view.php Locally Modified (Based On 1.175)
@@ -64,9 +64,9 @@
     }
 
 /// Print the page header
-    $bodytags = '';
     if ($accessmanager->securewindow_required($canpreview)) {
-        $bodytags = 'onload="popupchecker(\'' . get_string('popupblockerwarning', 'quiz') . '\');"';
+        $PAGE->requires->js('mod/quiz/quiz.js');
+        $PAGE->requires->js_function_call('popupchecker', array(get_string('popupblockerwarning', 'quiz')))->on_dom_ready();
     }
     $PAGE->requires->yui_lib('event');
 
Index: moodle/question/qbank.js
--- moodle/question/qbank.js Base (1.4)
+++ moodle/question/qbank.js Locally Modified (Based On 1.4)
@@ -134,3 +134,21 @@
         YAHOO.util.Event.preventDefault(e);
     }
 };
+
+/**
+ * Either check, or uncheck, all checkboxes inside the element with id is
+ * @param id the id of the container
+ * @param checked the new state, either '' or 'checked'.
+ */
+function select_all_in_element_with_id(id, checked) {
+    var container = document.getElementById(id);
+    if (!container) {
+        return;
+    }
+    var inputs = container.getElementsByTagName('input');
+    for (var i = 0; i < inputs.length; ++i) {
+        if (inputs[i].type == 'checkbox' || inputs[i].type == 'radio') {
+            inputs[i].checked = checked;
+        }
+    }
+}