From 73ad4f1bfdf104055104907c11f97315d6fb2ebe Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Tue, 09 Jul 2013 17:41:40 -0400
Subject: [PATCH] Finally: make message list header stay on top when scrolling (#1295420)

---
 program/js/list.js |   57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/program/js/list.js b/program/js/list.js
index 8b8a719..e8f7210 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -33,6 +33,7 @@
   this.tagname = this.list ? this.list.nodeName.toLowerCase() : 'table';
   this.thead;
   this.tbody;
+  this.fixed_header;
   this.frame = null;
   this.rows = [];
   this.selection = [];
@@ -152,6 +153,14 @@
   if (this.thead) {
     this.colcount = 0;
 
+    if (this.fixed_header) {  // copy (modified) fixed header back to the actual table
+      $(this.list.tHead).replaceWith($(this.fixed_header).find('thead').clone());
+      $(this.list.tHead).find('tr td').attr('style', '');  // remove fixed widths
+    }
+    else if (!bw.ie7 && this.list.className.indexOf('fixedheader') >= 0) {
+      this.init_fixed_header();
+    }
+
     var col, r, p = this;
     // add events for list columns moving
     if (this.column_movable && this.thead && this.thead.rows) {
@@ -166,6 +175,47 @@
   }
 },
 
+init_fixed_header: function()
+{
+  var clone = $(this.list.tHead).clone();
+
+  if (!this.fixed_header) {
+    this.fixed_header = $('<table>')
+      .attr('class', this.list.className)
+      .css({ position:'fixed' })
+      .append(clone)
+      .append('<tbody></tbody>');
+    $(this.list).before(this.fixed_header);
+
+    var me = this;
+    $(window).resize(function(){ me.resize() });
+  }
+  else {
+    $(this.fixed_header).find('thead').replaceWith(clone);
+  }
+
+  this.thead = clone.get(0);
+  this.resize();
+},
+
+resize: function()
+{
+    if (!this.fixed_header)
+      return;
+
+    var column_widths = [];
+
+    // get column widths from original thead
+    $(this.tbody).parent().find('thead tr td').each(function(index) {
+      column_widths[index] = $(this).width();
+    });
+
+    // apply fixed widths to fixed table header
+    $(this.thead).parent().width($(this.tbody).parent().width());
+    $(this.thead).find('tr td').each(function(index) {
+      $(this).css('width', column_widths[index]);
+    });
+},
 
 /**
  * Remove all list rows
@@ -494,6 +544,7 @@
     new_row = new_row.nextSibling;
   }
 
+  this.resize();
   this.triggerEvent('listupdate');
   return false;
 },
@@ -542,6 +593,7 @@
     new_row = new_row.nextSibling;
   }
 
+  this.resize();
   this.triggerEvent('listupdate');
   return false;
 },
@@ -585,6 +637,7 @@
     new_row = new_row.nextSibling;
   }
 
+  this.resize();
   this.triggerEvent('listupdate');
   return false;
 },
@@ -623,6 +676,7 @@
     new_row = new_row.nextSibling;
   }
 
+  this.resize();
   this.triggerEvent('listupdate');
   return false;
 },
@@ -1531,6 +1585,9 @@
   else if (this.subject_col > from && to >= this.subject_col)
     this.subject_col--;
 
+  if (this.fixed_header)
+    this.init_header();
+
   this.triggerEvent('column_replace');
 }
 

--
Gitblit v1.9.1