diff -urp --strip-trailing-cr ../drupal-6.x-dev/misc/tableheader.js ./misc/tableheader.js
--- ../drupal-6.x-dev/misc/tableheader.js	2007-10-02 09:09:51.000000000 +0200
+++ ./misc/tableheader.js	2007-12-18 02:08:13.000000000 +0100
@@ -9,12 +9,13 @@ Drupal.behaviors.tableHeader = function 
   // Keep track of all header cells.
   var cells = [];
 
-  var z = 0;
+  // Only first time: Clone all table headers and initialize data.
   $('table thead:not(.tableHeader-processed)', context).each(function () {
     // Find table height.
     var table = $(this).parent('table')[0];
     var height = $(table).addClass('sticky-table').height();
     var i = 0;
+    var z = 1;
 
     // Find all header cells.
     $('th', this).each(function () {
@@ -28,48 +29,121 @@ Drupal.behaviors.tableHeader = function 
         html = '<span>'+ html +'</span>';
       }
 
-      // Clone and wrap cell contents in sticky wrapper that overlaps the cell's padding.
-      $('<div class="sticky-header" style="position: fixed; visibility: hidden; top: 0px;">'+ html +'</div>').prependTo(this);
+      // Clone and wrap cell contents in sticky wrapper that overlaps the cell's padding,
+      // and emulates its borders.
+      $('<div class="sticky-header" style="position: fixed; visibility: hidden; top: 0px; margin: 0; padding: 0">'+ html +'</div>').prependTo(this);
       var div = $('div.sticky-header', this).css({
-        'marginLeft': '-'+ $(this).css('paddingLeft'),
-        'marginRight': '-'+ $(this).css('paddingRight'),
-        'paddingLeft': $(this).css('paddingLeft'),
-        'paddingTop': $(this).css('paddingTop'),
-        'paddingBottom': $(this).css('paddingBottom'),
+        'borderLeft': $(this).css('borderLeft'),
+        'borderRight': $(this).css('borderRight'),
+        'borderTop': $(this).css('borderTop'),
+        'borderBottom': $(this).css('borderBottom'),
         'z-index': ++z
       })[0];
       cells.push(div);
 
-      // Adjust width to fit cell/table.
-      var ref = this;
+      // Prepare various dimensions for the cell
+      var paddingL = parseInt($(this).css('paddingLeft'));
+      var paddingR = parseInt($(this).css('paddingRight'));
+      var paddingT = parseInt($(this).css('paddingTop'));
+      var paddingB = parseInt($(this).css('paddingBottom'));
+
+      if ($(this).css('borderCollapse') == 'collapse') {
+        div.addH = paddingL + paddingR + parseInt($(this).css('borderRightWidth'));
+      }
+      else {
+        div.addH = paddingL + paddingR;
+      }
+
+      div.addV = paddingB + paddingT;
+      div.cellOffset = parseInt($(this).css('borderLeftWidth')) + parseInt($(table).css('borderLeftWidth'));
+      var scrollH = document.documentElement.scrollLeft || document.body.scrollLeft;
+
+      // Note that height() and width() are not used, because they sometimes
+      // return distorted values.
+      div.cellWidth = parseInt($(this).css('width')) + div.addH;
+      div.cellHeight = parseInt($(this).css('height')) + div.addV;
+      div.cellLeft = $(this).offset().left - div.cellOffset - scrollH;
+
+      // Wrap the contents in another wrapper, to re-introduce its padding.
+      $(div).wrapInner('<div style="border: 0; margin: 0;"></div>');
+      $(div).children().css({
+        'paddingLeft': paddingL,
+        'paddingRight': paddingR,
+        'paddingTop': paddingT,
+        'paddingBottom': paddingB
+      })[0];
+
+      // Remember first/last cell.
       if (!i++) {
-        // The first cell is as wide as the table to prevent gaps.
-        ref = table;
-        div.wide = true;
+        table.first = div;
       }
-      $(div).width(Math.max(0, $(ref).width() - parseInt($(div).css('paddingLeft'))));
+      table.last = div;
+
+      // Set position and size of the cloned cell.
+      $(div).css({
+        'left': div.cellLeft,
+        'width': div.cellWidth,
+        'height': div.cellHeight
+      });
 
-      // Get position and store.
+      // Store data for later updates.
       div.cell = this;
       div.table = table;
       div.stickyMax = height;
       div.stickyPosition = $(this).offset().top;
+      div.savedScrollH = scrollH;
     });
+
+    // Adjust first/last cell order for RTL.
+    if ($('body').css('direction') == 'rtl') {
+      var temp = table.first;
+      table.first = table.last;
+      table.last = temp;
+    }
+
+    // Wrap the contents of leftmost cell into yet another sticky wrapper, to
+    // ensure correct position and alignment, and make the outer wrapper as
+    // wide as the table, to serve as background and mask any gaps between
+    // cloned cells.
+    table.first.innerOffset = parseInt($(table.first).css('borderLeftWidth'));
+    $(table.first).wrapInner('<div style="position: fixed; top: 0px; margin: 0; padding: 0; border: 0;"></div>');
+    $(table.first).children().css({
+      'z-index': parseInt($(table.first).css('z-index')),
+      'left': table.first.cellLeft + table.first.innerOffset,
+      'width': table.first.cellWidth
+    })[0];
+
+    $(table.first).css({
+      'z-index': 1,
+      'width': table.last.cellLeft - table.first.cellLeft + table.last.cellWidth
+    })[0];
+    table.first.wide = true;
+
     $(this).addClass('tableHeader-processed');
   });
 
   // Track scrolling.
   var scroll = function() {
     $(cells).each(function () {
-      // Fetch scrolling position.
+      // Vertical.
       var scroll = document.documentElement.scrollTop || document.body.scrollTop;
       var offset = scroll - this.stickyPosition - 4;
-      if (offset > 0 && offset < this.stickyMax - 100) {
+      if (offset > 0 && offset < this.stickyMax - 50) {
         $(this).css('visibility', 'visible');
       }
       else {
         $(this).css('visibility', 'hidden');
       }
+      // Horizontal.
+      var scrollH = document.documentElement.scrollLeft || document.body.scrollLeft;
+      if (this.savedScrollH != scrollH) {
+        this.savedScrollH = scrollH;
+        var cellLeft = $(this.cell).offset().left - this.cellOffset - scrollH;
+        if (this.wide) {
+          $(this).children('div').css('left', cellLeft + this.innerOffset);
+        }
+        $(this).css('left', cellLeft);
+      }
     });
   };
   $(window).scroll(scroll);
@@ -87,22 +161,38 @@ Drupal.behaviors.tableHeader = function 
       // Precalculate table heights
       $('table.sticky-table').each(function () {
         this.savedHeight = $(this).height();
-      });
-
-      $('table.sticky-table div.sticky-header').each(function () {
-        // Get position.
-        this.stickyPosition = $(this.cell).offset().top;
-        this.stickyMax = this.table.savedHeight;
 
-        // Reflow the cell.
-        var ref = this.cell;
-        if (this.wide) {
-          // Resize the first cell to fit the table.
-          ref = this.table;
-        }
-        $(this).width(Math.max(0, $(ref).width() - parseInt($(this).css('paddingLeft'))));
+        $('div.sticky-header', this).each(function () {
+          // Get position.
+          this.stickyPosition = $(this.cell).offset().top;
+          this.stickyMax = this.table.savedHeight;
+          var scrollH = document.documentElement.scrollLeft || document.body.scrollLeft;
+          this.cellWidth = parseInt($(this.cell).css('width')) + this.addH;
+          this.cellLeft = $(this.cell).offset().left - this.cellOffset - scrollH;
+          this.cellHeight = parseInt($(this.cell).css('height')) + this.addV;
+
+          // Reflow the cell.
+          $(this).css({
+            'left': this.cellLeft,
+            'width': this.cellWidth,
+            'height': this.cellHeight
+          });
+        });
+
+        // Update the special leftmost cell.
+        $(this.first).children('div').css({
+          'left': this.first.cellLeft + this.first.innerOffset,
+          'width': this.first.cellWidth
+        })[0];
+
+        $(this.first).css({
+          'width': this.last.cellLeft - this.first.cellLeft + this.last.cellWidth
+        })[0];
       });
 
+      // Resizing may change position of the tables, so update visibility.
+      $(scroll);
+
       // Reset timer
       time = null;
     }, 250);
