]> git.mjollnir.org Git - moodle.git/commitdiff
Bug 6101 - Automatically scroll to any errors when upgrading the database. JavaScript...
authortjhunt <tjhunt>
Thu, 13 Jul 2006 09:48:56 +0000 (09:48 +0000)
committertjhunt <tjhunt>
Thu, 13 Jul 2006 09:48:56 +0000 (09:48 +0000)
admin/index.php
backup/lib.php
lib/adminlib.php
lib/blocklib.php
lib/datalib.php
lib/locallib.php
lib/scroll_to_errors.js [new file with mode: 0644]

index 01a7f01c9c096dc0b0d228f544445585eab25ffc..b9358f1a0370fffac83e41f3d558681d825f9d4a 100644 (file)
@@ -93,6 +93,7 @@
         }
     }
 
+    $linktoscrolltoerrors = '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>';
     if (! $maintables) {
         if (empty($agreelicence)) {
             $strlicense = get_string("license");
 
         $strdatabasesetup    = get_string("databasesetup");
         $strdatabasesuccess  = get_string("databasesuccess");
-        print_header($strdatabasesetup, $strdatabasesetup, $strdatabasesetup, "", "", false, "&nbsp;", "&nbsp;");
+        print_header($strdatabasesetup, $strdatabasesetup, $strdatabasesetup,
+                        "", $linktoscrolltoerrors, false, "&nbsp;", "&nbsp;");
         if (file_exists("$CFG->libdir/db/$CFG->dbtype.sql")) {
             $db->debug = true;
             if (modify_database("$CFG->libdir/db/$CFG->dbtype.sql")) {
             } else {
                 $strdatabasesuccess  = get_string("databasesuccess");
                 print_header($strdatabasechecking, $stradministration, $strdatabasechecking,
-                        "", "", false, "&nbsp;", "&nbsp;");
+                        "", $linktoscrolltoerrors, false, "&nbsp;", "&nbsp;");
                 print_heading($strdatabasechecking);
                 $db->debug=true;
                 if (main_upgrade($CFG->version)) {
index c7947e0cce6a4df71309c898467d539e6c72c374..6bcee82997f5eece5dfb1140e33c41c6569e0c1e 100644 (file)
 
         if (empty($CFG->backup_version)) {                  // Backup has never been installed.
             $strdatabaseupgrades = get_string("databaseupgrades");
-            print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades, 
-                         "", "", false, "&nbsp;", "&nbsp;");
+            print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades, "", 
+                    '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
+                    false, "&nbsp;", "&nbsp;");
 
             $db->debug=true;
             if (modify_database("$CFG->dirroot/backup/db/$CFG->dbtype.sql")) {
 
         if ($backup_version > $CFG->backup_version) {       // Upgrade tables
             $strdatabaseupgrades = get_string("databaseupgrades");
-            print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades);
+            print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades, '',
+                     '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>');
 
             require_once ("$CFG->dirroot/backup/db/$CFG->dbtype.php");
 
index e3c7bcbd4fbde657c2d800abb0081b86f1a39609..a7f814498d7dd62c7075776cf531346416e7fe4e 100644 (file)
@@ -73,7 +73,9 @@ function upgrade_plugins($type, $dir, $return) {
         } else if ($CFG->$pluginversion < $plugin->version) {
             if (empty($updated_plugins)) {
                 $strpluginsetup  = get_string('pluginsetup');
-                print_header($strpluginsetup, $strpluginsetup, $strpluginsetup, '', '', false, '&nbsp;', '&nbsp;');
+                print_header($strpluginsetup, $strpluginsetup, $strpluginsetup, '', 
+                        '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
+                        false, '&nbsp;', '&nbsp;');
             }
             print_heading($plugin->name .' plugin needs upgrading');
 
@@ -186,7 +188,9 @@ function upgrade_activity_modules($return) {
             } else if ($currmodule->version < $module->version) {
                 if (empty($updated_modules)) {
                     $strmodulesetup  = get_string('modulesetup');
-                    print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '', '', false, '&nbsp;', '&nbsp;');
+                    print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '', 
+                            '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
+                            false, '&nbsp;', '&nbsp;');
                 }
                 print_heading($module->name .' module needs upgrading');
                 $upgrade_function = $module->name.'_upgrade';
@@ -215,7 +219,9 @@ function upgrade_activity_modules($return) {
         } else {    // module not installed yet, so install it
             if (empty($updated_modules)) {
                 $strmodulesetup    = get_string('modulesetup');
-                print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '', '', false, '&nbsp;', '&nbsp;');
+                print_header($strmodulesetup, $strmodulesetup, $strmodulesetup, '', 
+                        '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
+                        false, '&nbsp;', '&nbsp;');
             }
             print_heading($module->name);
             $updated_modules = true;
index 6196d01427309db9f475f88a5100472ba3615998..2b0cf5927f2ab4d548d9576f054956e123f40568 100644 (file)
@@ -908,8 +908,9 @@ function upgrade_blocks_db($continueto) {
 
     if (empty($CFG->blocks_version)) {                  // Blocks have never been installed.
         $strdatabaseupgrades = get_string('databaseupgrades');
-        print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades,
-                     '', '', false, '&nbsp;', '&nbsp;');
+        print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades, '', 
+                '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
+                false, '&nbsp;', '&nbsp;');
 
         $db->debug=true;
         if (modify_database($CFG->dirroot .'/blocks/db/'. $CFG->dbtype .'.sql')) {
@@ -930,8 +931,8 @@ function upgrade_blocks_db($continueto) {
 
     if ($blocks_version > $CFG->blocks_version) {       // Upgrade tables
         $strdatabaseupgrades = get_string('databaseupgrades');
-        print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades);
-
+        print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades, '',
+                '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>');
         require_once ($CFG->dirroot .'/blocks/db/'. $CFG->dbtype .'.php');
 
         $db->debug=true;
@@ -1064,7 +1065,9 @@ function upgrade_blocks_plugins($continueto) {
             } else if ($currblock->version < $block->version) {
                 if (empty($updated_blocks)) {
                     $strblocksetup    = get_string('blocksetup');
-                    print_header($strblocksetup, $strblocksetup, $strblocksetup, '', '', false, '&nbsp;', '&nbsp;');
+                    print_header($strblocksetup, $strblocksetup, $strblocksetup, '', 
+                            '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
+                            false, '&nbsp;', '&nbsp;');
                 }
                 print_heading('New version of '.$blocktitle.' ('.$block->name.') exists');
                 $upgrade_function = $block->name.'_upgrade';
@@ -1116,7 +1119,9 @@ function upgrade_blocks_plugins($continueto) {
             }
             if (empty($updated_blocks)) {
                 $strblocksetup    = get_string('blocksetup');
-                print_header($strblocksetup, $strblocksetup, $strblocksetup, '', '', false, '&nbsp;', '&nbsp;');
+                print_header($strblocksetup, $strblocksetup, $strblocksetup, '', 
+                        '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>',
+                        false, '&nbsp;', '&nbsp;');
             }
             print_heading($block->name);
             $updated_blocks = true;
index 93f3ee039cda225977b066bdfb3ec56610e53b3e..a8f1012a5ad65a0a6d8b1de922e17ffd9260bac1 100644 (file)
@@ -57,7 +57,7 @@ function execute_sql($command, $feedback=true) {
         return true;
     } else {
         if ($feedback) {
-            echo '<p><font color="red"><strong>'. get_string('error') .'</strong></font></p>';
+            notify('<strong>' . get_string('error') . '</strong>');
         }
         if (!empty($CFG->dblogerror)) {
             $debug=array_shift(debug_backtrace());
index ba8de57d2485d4143df466d05042ba8eae4b8157..01a2db0ea10c5fd66e42a3333b349a62d147d723 100644 (file)
@@ -90,7 +90,8 @@ function upgrade_local_db($continueto) {
 
     if ($local_version > $CFG->local_version) { // upgrade! 
         $strdatabaseupgrades = get_string('databaseupgrades');
-        print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades);
+        print_header($strdatabaseupgrades, $strdatabaseupgrades, $strdatabaseupgrades, '',
+                 '<script type="text/javascript" src="' . $CFG->wwwroot . '/lib/scroll_to_errors.js"></script>');
         
         require_once ($CFG->dirroot .'/local/db/'. $CFG->dbtype .'.php');
 
diff --git a/lib/scroll_to_errors.js b/lib/scroll_to_errors.js
new file mode 100644 (file)
index 0000000..741f181
--- /dev/null
@@ -0,0 +1,160 @@
+// keep the global scope clean
+(function() {
+
+    var id = null;
+    var warnings = null;
+    var continueBtn = null;
+
+    var getElementPosY = function(obj) {
+        var y = 0;
+        while (obj.offsetParent) {
+            y += obj.offsetTop;
+            obj = obj.offsetParent;
+        }
+        return y;
+    };
+
+    // ugh, find scroll position in 3 possible ways
+    var getScrollY = function() {
+        return self.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop;
+    };
+
+    var initScroll = function(obj) {
+        // if we scroll to the warning div itself the sql that caused the warning will be off the top of the page 
+        // so we can look through the page for a preceeding div and base the scroll position on that        
+        var prevDiv = findPreviousSibling(obj, 'div');
+        // if the warning div doesn't have a previous sibling div scroll to the top of the page instead
+        var y = (prevDiv) ? getElementPosY(prevDiv) + prevDiv.offsetHeight : 0;
+
+        if (id) {
+            clearInterval(id);
+        }
+
+        // scroll with a little bit of easing, I guess it's a matter of personal taste whether it would be 
+        // better to scroll the page directly to the point using window.scrollTo(0, y). But I think easing 
+        // makes it a little clearer to the user that they're scrolling through the page :-)
+        id = setInterval(function() {
+            var ys = getScrollY();
+            // the stuff on arguments.callee is a check to stop scrolling if we've reached the end of the page 
+            // and can't scroll any further
+            if ((arguments.callee.oldPos && arguments.callee.oldPos == ys) || Math.abs(y - ys) < 5) {
+                arguments.callee.oldPos = null;
+                window.scrollTo(0, y);
+                clearInterval(id);
+                id = null;
+            } else {
+                window.scrollTo(0, Math.round(ys + ((y - ys) / 2)));
+            }
+            arguments.callee.oldPos = ys;
+        }, 60);
+    };
+
+    // return nodes with a class name that matches regexp - if individual is set we're only looking 
+    // for a single node
+    var filterNodesByClassName = function(nodes, regexp, individual) {
+        var filtered = [];
+        var n = nodes.length;
+        for (var i = 0; i < n; ++i) {
+            if (nodes[i].className && nodes[i].className.match(regexp)) {
+                if (individual) {
+                    return nodes[i];
+                }
+                filtered.push(nodes[i]);
+            }
+        }
+        return filtered;
+    };
+
+    // look through the previous siblings of an element and find the first one with a given node name
+    var findPreviousSibling = function(obj, nodeName) {
+        while (obj = obj.previousSibling) {
+            if (obj.nodeName.toLowerCase() == nodeName) {
+                return obj;
+            }
+        }
+        return false;
+    };
+
+    // create the links to scroll around the page. warningIndex is used to look up the element in the 
+    // warnings array that should be scrolled to
+    var createWarningSkipLink = function(linkText, warningIndex, style) {
+        var link = document.createElement('a');
+        link.href = 'javascript:;';
+        link.warningIndex = warningIndex;
+        link.appendChild(document.createTextNode(linkText));
+        link.onclick = function() {
+             initScroll(warnings[this.warningIndex]);
+        };
+
+        if (style) {
+            for (var x in style) {
+                link.style[x] = style[x];
+            }
+        }
+        return link;
+    };
+   
+
+    var checkWarnings = function() {
+        // look for div tags with the class name notifyproblem
+        warnings = filterNodesByClassName(document.getElementsByTagName('div'), /(^|\b)notifyproblem(\b|$)/);
+        // and find the continue button
+        continueBtn = filterNodesByClassName(document.getElementsByTagName('div'), /(^|\b)continuebutton(\b|$)/, true);
+                
+        var n = warnings.length; // find how many warnings
+        warnings[warnings.length] = continueBtn; // then add the continue button to the array
+
+        var link;
+        for (var i = 0; i < n; ++i) {
+            // add a "next" link to all warnings except the last one on the page
+            if (i < n - 1) {
+                link = createWarningSkipLink('Scroll to next warning', i + 1, {paddingLeft: '1em'});
+            } else { 
+                // on the last link add a link to go to the continue button
+                link = createWarningSkipLink('Scroll to continue button', i + 1, {paddingLeft: '1em'});
+            }
+            warnings[i].appendChild(link);
+            // and add a "previous" link to all except the first
+            if (i > 0) {
+                link = createWarningSkipLink('Scroll to previous warning', i - 1, {paddingRight: '1em'});
+                warnings[i].insertBefore(link, warnings[i].firstChild);
+            }
+        }
+        
+        
+        var contentDiv = document.getElementById('content');
+        if (contentDiv) {
+            // create a message to display at the top of the page, with a link to the first warning
+            // or to the continue button if there were no warnings on the page
+            var p = document.createElement('p');
+            if (n > 0) {
+                var warningText = (n == 1) ? 'warning' : 'warnings';
+                link = createWarningSkipLink('Scroll to the first warning', 0);
+                p.appendChild(document.createTextNode('This script generated ' + n + ' ' + warningText + ' - '));
+                p.className = 'notifyproblem';
+            } else {
+                link = createWarningSkipLink('Scroll to the continue button', 0);
+                p.appendChild(document.createTextNode('No warnings - '));
+                p.className = 'notifysuccess';
+            }
+            p.appendChild(link);
+            contentDiv.insertBefore(p, contentDiv.firstChild);
+        }
+        
+        // automatically scroll to the first warning or continue button
+        initScroll(warnings[0]);
+    };
+
+    // load should be a document event, but most browsers use window 
+    if (window.addEventListener) {
+        window.addEventListener('load', checkWarnings, false);
+    } else if (document.addEventListener) {
+        document.addEventListener('load', checkWarnings, false);
+    } else if (window.attachEvent) {
+        // sometimes IE doesn't report scrollTop correctly (it might be a quirk of this specific page, I don't know)
+        // but using scrollTo once to begin makes sure things work
+        window.scrollTo(0, 1);
+        window.attachEvent('onload', checkWarnings);
+    }
+
+})();
\ No newline at end of file