? misc/displace.js
Index: modules/system/system.base.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.base.css,v
retrieving revision 1.3
diff -u -p -r1.3 system.base.css
--- modules/system/system.base.css	25 Sep 2010 02:28:14 -0000	1.3
+++ modules/system/system.base.css	22 Nov 2010 04:45:18 -0000
@@ -179,6 +179,7 @@ tr .ajax-progress .throbber {
   width: 16em;
 }
 
+
 /**
  * Inline items.
  */
Index: modules/overlay/overlay-child.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/overlay/overlay-child.js,v
retrieving revision 1.11
diff -u -p -r1.11 overlay-child.js
--- modules/overlay/overlay-child.js	6 Nov 2010 00:18:24 -0000	1.11
+++ modules/overlay/overlay-child.js	22 Nov 2010 04:45:19 -0000
@@ -172,22 +172,23 @@ Drupal.overlayChild.behaviors.shortcutAd
 };
 
 /**
- * Use displacement from parent window.
+ * Allow resize event handlers to recalculate sizes/positions when parent window
+ * is being resized.
  */
-Drupal.overlayChild.behaviors.alterTableHeaderOffset = function (context, settings) {
-  if (Drupal.settings.tableHeaderOffset) {
-    Drupal.overlayChild.prevTableHeaderOffset = Drupal.settings.tableHeaderOffset;
-  }
-  Drupal.settings.tableHeaderOffset = 'Drupal.overlayChild.tableHeaderOffset';
+Drupal.overlayChild.behaviors.parentResize = function (context, settings) {
+  $(document).bind('drupalOverlayResize.drupal-overlay', function () {
+    $(window).triggerHandler('resize');
+  });
 };
 
-/**
- * Callback for Drupal.settings.tableHeaderOffset.
- */
-Drupal.overlayChild.tableHeaderOffset = function () {
-  var topOffset = Drupal.overlayChild.prevTableHeaderOffset ? eval(Drupal.overlayChild.prevTableHeaderOffset + '()') : 0;
-
-  return topOffset + parseInt($(document.body).css('marginTop'));
+// Override Drupal.displace so it includes displacement of parent document.
+Drupal.displace.forceHandlers = true;
+var _getDisplacement = Drupal.displace.getDisplacement;
+Drupal.displace.getDisplacement = function (region) {
+  if (parent && parent.Drupal && parent.Drupal.displace) {
+    Drupal.displace.initialOffset = parent.Drupal.displace.getDisplacement(region);
+  }
+  return _getDisplacement.apply(Drupal.displace, arguments);
 };
 
 })(jQuery);
Index: modules/overlay/overlay-parent.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/overlay/overlay-parent.js,v
retrieving revision 1.57
diff -u -p -r1.57 overlay-parent.js
--- modules/overlay/overlay-parent.js	6 Nov 2010 00:18:24 -0000	1.57
+++ modules/overlay/overlay-parent.js	22 Nov 2010 04:45:19 -0000
@@ -128,7 +128,7 @@ Drupal.overlay.create = function () {
           ' drupalOverlayBeforeLoad' + eventClass +
           ' drupalOverlayResize' + eventClass, $.proxy(this, 'eventhandlerDispatchEvent'));
 
-  if ($('.overlay-displace-top, .overlay-displace-bottom').length) {
+  if (Drupal.displace) {
     $(document)
       .bind('drupalOverlayResize' + eventClass, $.proxy(this, 'eventhandlerAlterDisplacedElements'))
       .bind('drupalOverlayClose' + eventClass, $.proxy(this, 'eventhandlerRestoreDisplacedElements'));
@@ -400,14 +400,6 @@ Drupal.overlay.eventhandlerAlterDisplace
     return;
   }
 
-  $(this.iframeWindow.document.body).css({
-    marginTop: Drupal.overlay.getDisplacement('top'),
-    marginBottom: Drupal.overlay.getDisplacement('bottom')
-  })
-  // IE7 isn't reflowing the document immediately.
-  // @todo This might be fixed in a cleaner way.
-  .addClass('overlay-trigger-reflow').removeClass('overlay-trigger-reflow');
-
   var documentHeight = this.iframeWindow.document.body.clientHeight;
   var documentWidth = this.iframeWindow.document.body.clientWidth;
   // IE6 doesn't support maxWidth, use width instead.
@@ -415,7 +407,7 @@ Drupal.overlay.eventhandlerAlterDisplace
 
   // Consider any element that should be visible above the overlay (such as
   // a toolbar).
-  $('.overlay-displace-top, .overlay-displace-bottom').each(function () {
+  Drupal.displace.getDisplacedElements().each(function () {
     var data = $(this).data();
     var maxWidth = documentWidth;
     // In IE, Shadow filter makes element to overlap the scrollbar with 1px.
@@ -451,7 +443,7 @@ Drupal.overlay.eventhandlerAlterDisplace
  *   - event.currentTarget: any
  */
 Drupal.overlay.eventhandlerRestoreDisplacedElements = function (event) {
-  var $displacedElements = $('.overlay-displace-top, .overlay-displace-bottom');
+  var $displacedElements = Drupal.displace.getDisplacedElements();
   try {
     $displacedElements.css({ maxWidth: null, clip: null });
   }
@@ -669,8 +661,13 @@ Drupal.overlay.eventhandlerRefreshPage =
  *   - event.currentTarget: any
  */
 Drupal.overlay.eventhandlerDispatchEvent = function (event) {
+  var self = this;
   if (this.iframeWindow && this.iframeWindow.document) {
-    this.iframeWindow.jQuery(this.iframeWindow.document).trigger(event);
+    window.setTimeout(function() {
+      if (self.iframeWindow && self.iframeWindow.document) {
+        self.iframeWindow.jQuery(self.iframeWindow.document).trigger(event);
+      }
+    }, 1);
   }
 };
 
@@ -738,10 +735,14 @@ Drupal.overlay.refreshRegions = function
  *   Path to match links against.
  */
 Drupal.overlay.resetActiveClass = function(activePath) {
+  if (!Drupal.displace) {
+    return;
+  }
+
   var self = this;
   var windowDomain = window.location.protocol + window.location.hostname;
 
-  $('.overlay-displace-top, .overlay-displace-bottom')
+  Drupal.displace.getDisplacedElements()
   .find('a[href]')
   // Remove active class from all links in displaced elements.
   .removeClass('active')
@@ -794,30 +795,6 @@ Drupal.overlay.getPath = function (link,
 };
 
 /**
- * Get the total displacement of given region.
- *
- * @param region
- *   Region name. Either "top" or "bottom".
- *
- * @return
- *   The total displacement of given region in pixels.
- */
-Drupal.overlay.getDisplacement = function (region) {
-  var displacement = 0;
-  var lastDisplaced = $('.overlay-displace-' + region + ':last');
-  if (lastDisplaced.length) {
-    displacement = lastDisplaced.offset().top + lastDisplaced.outerHeight();
-
-    // Remove height added by IE Shadow filter.
-    if (lastDisplaced[0].filters && lastDisplaced[0].filters.length && lastDisplaced[0].filters.item('DXImageTransform.Microsoft.Shadow')) {
-      displacement -= lastDisplaced[0].filters.item('DXImageTransform.Microsoft.Shadow').strength;
-      displacement = Math.max(0, displacement);
-    }
-  }
-  return displacement;
-};
-
-/**
  * Makes elements outside the overlay unreachable via the tab key.
  *
  * @param context
Index: modules/overlay/overlay.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/overlay/overlay.module,v
retrieving revision 1.33
diff -u -p -r1.33 overlay.module
--- modules/overlay/overlay.module	20 Nov 2010 04:03:51 -0000	1.33
+++ modules/overlay/overlay.module	22 Nov 2010 04:45:19 -0000
@@ -215,7 +215,10 @@ function overlay_library() {
     'website' => 'http://drupal.org/handbook/modules/overlay',
     'version' => '1.0',
     'js' => array(
-      $module_path . '/overlay-child.js' => array(),
+      // Always include displace.js as any displacement inside the parent window
+      // has to be taken into account.
+      'misc/displace.js' => array('weight' => JS_LIBRARY + 1),
+      $module_path . '/overlay-child.js' => array('weight' => JS_LIBRARY + 2),
     ),
     'css' => array(
       $module_path . '/overlay-child.css' => array(),
Index: modules/toolbar/toolbar.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.css,v
retrieving revision 1.26
diff -u -p -r1.26 toolbar.css
--- modules/toolbar/toolbar.css	11 Sep 2010 14:45:23 -0000	1.26
+++ modules/toolbar/toolbar.css	22 Nov 2010 04:45:19 -0000
@@ -1,13 +1,5 @@
 /* $Id: toolbar.css,v 1.26 2010/09/11 14:45:23 dries Exp $ */
 
-body.toolbar {
-  padding-top: 2.2em;
-}
-
-body.toolbar-drawer {
-  padding-top: 5.3em;
-}
-
 /**
  * Aggressive resets so we can achieve a consistent look in hostile CSS
  * environments.
@@ -35,19 +27,23 @@ body.toolbar-drawer {
   font: normal small "Lucida Grande", Verdana, sans-serif;
   background: #666;
   color: #ccc;
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
+}
+.displace-processed #toolbar {
   margin: 0 -20px;
   padding: 0 20px;
-  z-index: 600;
   box-shadow: 0 3px 20px #000;
   -moz-box-shadow: 0 3px 20px #000;
   -webkit-box-shadow: 0 3px 20px #000;
   filter: progid:DXImageTransform.Microsoft.Shadow(color=#000000, direction='180', strength='10');
   -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(color=#000000, direction='180', strength='10')";
 }
+.displace-unsupported #toolbar {
+  margin: 0;
+  padding-right: 0;
+  left: -20px;
+  right: 0;
+  width: 100%;
+}
 
 #toolbar div.collapsed {
   display: none;
Index: modules/toolbar/toolbar.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.js,v
retrieving revision 1.19
diff -u -p -r1.19 toolbar.js
--- modules/toolbar/toolbar.js	8 Jun 2010 05:16:29 -0000	1.19
+++ modules/toolbar/toolbar.js	22 Nov 2010 04:45:19 -0000
@@ -48,7 +48,6 @@ Drupal.toolbar.collapse = function() {
     .removeClass('toggle-active')
     .attr('title',  toggle_text)
     .html(toggle_text);
-  $('body').removeClass('toolbar-drawer').css('paddingTop', Drupal.toolbar.height());
   $.cookie(
     'Drupal.toolbar.collapsed',
     1,
@@ -70,7 +69,6 @@ Drupal.toolbar.expand = function() {
     .addClass('toggle-active')
     .attr('title',  toggle_text)
     .html(toggle_text);
-  $('body').addClass('toolbar-drawer').css('paddingTop', Drupal.toolbar.height());
   $.cookie(
     'Drupal.toolbar.collapsed',
     0,
@@ -94,14 +92,4 @@ Drupal.toolbar.toggle = function() {
   }
 };
 
-Drupal.toolbar.height = function() {
-  var height = $('#toolbar').outerHeight();
-  // In IE, Shadow filter adds some extra height, so we need to remove it from
-  // the returned height.
-  if ($('#toolbar').css('filter').match(/DXImageTransform\.Microsoft\.Shadow/)) {
-    height -= $('#toolbar').get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength;
-  }
-  return height;
-};
-
 })(jQuery);
Index: modules/toolbar/toolbar.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.module,v
retrieving revision 1.46
diff -u -p -r1.46 toolbar.module
--- modules/toolbar/toolbar.module	5 Oct 2010 19:59:10 -0000	1.46
+++ modules/toolbar/toolbar.module	22 Nov 2010 04:45:20 -0000
@@ -155,9 +155,11 @@ function toolbar_preprocess_html(&$vars)
  *
  * Adding the 'overlay-displace-top' class to the toolbar pushes the overlay
  * down, so it appears below the toolbar.
+ *
+ * @see misc/displace.js
  */
 function toolbar_preprocess_toolbar(&$variables) {
-  $variables['classes_array'][] = "overlay-displace-top";
+  $variables['classes_array'][] = "displace-top";
 }
 
 /**
@@ -187,12 +189,10 @@ function toolbar_view() {
     '#theme' => 'toolbar',
     '#attached'=> array(
       'js' => array(
-        $module_path . '/toolbar.js',
+         // Make sure the toolbar won't overlap any focused elements.
+         array('data' => 'misc/displace.js', 'weight' => JS_LIBRARY + 1),
         array('data' => 'misc/jquery.cookie.js', 'group' => JS_LIBRARY, 'weight' => 2),
-        array(
-          'data' => array('tableHeaderOffset' => 'Drupal.toolbar.height'),
-          'type' => 'setting'
-        ),
+         $module_path . '/toolbar.js',
       ),
       'css' => array(
         $module_path . '/toolbar.css',
Index: misc/tableheader.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/tableheader.js,v
retrieving revision 1.32
diff -u -p -r1.32 tableheader.js
--- misc/tableheader.js	28 Jul 2010 01:38:28 -0000	1.32
+++ misc/tableheader.js	22 Nov 2010 04:45:20 -0000
@@ -33,9 +33,9 @@ Drupal.tableHeader = function (table) {
   // the table to avoid a flash of the header clone upon page load.
   this.stickyTable = $('<table class="sticky-header"/>')
     .insertBefore(this.originalTable)
-    .css({ position: 'fixed', top: '0px' });
+    .css({ position: 'fixed', top: '0px', zIndex: 1 + (parseInt(this.originalTable.css('zIndex')) || 0) });
   this.stickyHeader = this.originalHeader.clone(true)
-    .hide()
+    .css('visibility', 'hidden')
     .appendTo(this.stickyTable);
   this.stickyHeaderCells = this.stickyHeader.find('> tr > th');
 
@@ -43,11 +43,6 @@ Drupal.tableHeader = function (table) {
   $(window)
     .bind('scroll.drupal-tableheader', $.proxy(this, 'eventhandlerRecalculateStickyHeader'))
     .bind('resize.drupal-tableheader', { calculateWidth: true }, $.proxy(this, 'eventhandlerRecalculateStickyHeader'))
-    // Make sure the anchor being scrolled into view is not hidden beneath the
-    // sticky table header. Adjust the scrollTop if it does.
-    .bind('drupalDisplaceAnchor.drupal-tableheader', function () {
-      window.scrollBy(0, -self.stickyTable.outerHeight());
-    })
     // Make sure the element being focused is not hidden beneath the sticky
     // table header. Adjust the scrollTop if it does.
     .bind('drupalDisplaceFocus.drupal-tableheader', function (event) {
@@ -59,7 +54,7 @@ Drupal.tableHeader = function (table) {
 
   // We hid the header to avoid it showing up erroneously on page load;
   // we need to unhide it now so that it will show up when expected.
-  this.stickyHeader.show();
+  this.stickyHeader.css('visibility', '');
 };
 
 /**
@@ -73,14 +68,14 @@ Drupal.tableHeader.prototype.eventhandle
   var calculateWidth = event.data && event.data.calculateWidth;
 
   // Reset top position of sticky table headers to the current top offset.
-  this.stickyOffsetTop = Drupal.settings.tableHeaderOffset ? eval(Drupal.settings.tableHeaderOffset + '()') : 0;
+  this.stickyOffsetTop = Drupal.displace ? Drupal.displace.getDisplacement('top') : 0;
   this.stickyTable.css('top', this.stickyOffsetTop + 'px');
 
   // Save positioning data.
   var viewHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
   if (calculateWidth || this.viewHeight !== viewHeight) {
     this.viewHeight = viewHeight;
-    this.vPosition = this.originalTable.offset().top - 4 - this.stickyOffsetTop;
+    this.vPosition = this.originalTable.offset().top - this.stickyOffsetTop;
     this.hPosition = this.originalTable.offset().left;
     this.vLength = this.originalTable[0].clientHeight - 100;
     calculateWidth = true;
@@ -90,22 +85,15 @@ Drupal.tableHeader.prototype.eventhandle
   var hScroll = document.documentElement.scrollLeft || document.body.scrollLeft;
   var vOffset = (document.documentElement.scrollTop || document.body.scrollTop) - this.vPosition;
   this.stickyVisible = vOffset > 0 && vOffset < this.vLength;
-  this.stickyTable.css({ left: (-hScroll + this.hPosition) + 'px', visibility: this.stickyVisible ? 'visible' : 'hidden' });
+  this.stickyTable.css({ left: parseInt(-hScroll + this.hPosition) + 'px', visibility: this.stickyVisible ? 'visible' : 'hidden' });
 
   // Only perform expensive calculations if the sticky header is actually
   // visible or when forced.
   if (this.stickyVisible && (calculateWidth || !this.widthCalculated)) {
     this.widthCalculated = true;
     // Resize header and its cell widths.
-    this.stickyHeaderCells.each(function (index) {
-      var cellWidth = self.originalHeaderCells.eq(index).css('width');
-      // Exception for IE7.
-      if (cellWidth == 'auto') {
-        cellWidth = self.originalHeaderCells.get(index).clientWidth + 'px';
-      }
-      $(this).css('width', cellWidth);
-    });
-    this.stickyTable.css('width', this.originalTable.css('width'));
+    this.stickyHeaderCells.width(function (index) { return self.originalHeaderCells.eq(index).width(); });
+    this.stickyTable.width(this.originalTable.css('width'));
   }
 };
 
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.623
diff -u -p -r1.623 theme.inc
--- includes/theme.inc	20 Nov 2010 04:03:51 -0000	1.623
+++ includes/theme.inc	22 Nov 2010 04:45:22 -0000
@@ -1623,6 +1623,8 @@ function theme_table($variables) {
 
   // Add sticky headers, if applicable.
   if (count($header) && $sticky) {
+    // Make sure the sticky tableheader won't overlap any focused elements.
+    drupal_add_js('misc/displace.js', array('weight' => JS_LIBRARY + 1));
     drupal_add_js('misc/tableheader.js');
     // Add 'sticky-enabled' class to the table to identify it for JS.
     // This is needed to target tables constructed by this function.
