### Eclipse Workspace Patch 1.0
#P drupal 7
Index: modules/overlay/overlay-child.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/overlay/overlay-child.js,v
retrieving revision 1.8
diff -u -r1.8 overlay-child.js
--- modules/overlay/overlay-child.js	24 Apr 2010 07:14:29 -0000	1.8
+++ modules/overlay/overlay-child.js	3 May 2010 23:22:13 -0000
@@ -3,30 +3,27 @@
 (function ($) {
 
 /**
- * Overlay object for child windows.
- */
-Drupal.overlayChild = Drupal.overlayChild || { processed: false, behaviors: {} };
-
-/**
  * Attach the child dialog behavior to new content.
  */
 Drupal.behaviors.overlayChild = {
   attach: function (context, settings) {
-    var self = Drupal.overlayChild;
-    var settings = settings.overlayChild || {};
-
     // Make sure this behavior is not processed more than once.
-    if (self.processed) {
+    if (this.processed) {
       return;
     }
-    self.processed = true;
+    this.processed = true;
 
-    // If we cannot reach the parent window, then we have nothing else to do
-    // here.
-    if (!$.isPlainObject(parent.Drupal) || !$.isPlainObject(parent.Drupal.overlay)) {
-      return;
+    // If we cannot reach the parent window, break out of the overlay.
+    if (!parent.Drupal || !parent.Drupal.overlay) {
+      var leave = confirm(Drupal.t('Parent window couldn\'t be accessed. Do you want to leave the overlay?'));
+      if (leave) {
+        window.location = window.location.href.replace(/([?&]?)render=overlay&?/g, '$1').replace(/\?$/, '');
+        return;
+      }
     }
 
+    var settings = settings.overlayChild || {};
+
     // If a form has been submitted successfully, then the server side script
     // may have decided to tell us the parent window to close the popup dialog.
     if (settings.closeOverlay) {
@@ -54,12 +51,24 @@
     // Ok, now we can tell the parent window we're ready.
     parent.Drupal.overlay.bindChild(window);
 
+    // IE8 crashes on certain pages if this isn't called; reason unknown.
+    window.scrollTo(0, 0);
+
     // Attach child related behaviors to the iframe document.
-    self.attachBehaviors(context, settings);
+    Drupal.overlayChild.attachBehaviors(context, settings);
   }
 };
 
 /**
+ * Overlay object for child windows.
+ */
+Drupal.overlayChild = Drupal.overlayChild || {
+  behaviors: {}
+};
+
+Drupal.overlayChild.prototype = {};
+
+/**
  * Attach child related behaviors to the iframe document.
  */
 Drupal.overlayChild.attachBehaviors = function (context, settings) {
@@ -69,16 +78,6 @@
 };
 
 /**
- * Scroll to the top of the page.
- *
- * This makes the overlay visible to users even if it is not as tall as the
- * previously shown overlay was.
- */
-Drupal.overlayChild.behaviors.scrollToTop = function (context, settings) {
-  window.scrollTo(0, 0);
-};
-
-/**
  * Capture and handle clicks.
  *
  * Instead of binding a click event handler to every link we bind one to the
@@ -86,7 +85,7 @@
  * to bind their own handlers to links and also to prevent overlay's handling.
  */
 Drupal.overlayChild.behaviors.addClickHandler = function (context, settings) {
-  $(document).bind('click.overlay-event', parent.Drupal.overlay.clickHandler);
+  $(document).bind('click.drupal-overlay', $.proxy(parent.Drupal.overlay, 'clickHandler'));
 };
 
 /**
@@ -111,4 +110,48 @@
   });
 };
 
+/**
+ * Replace the overlay title with a message while loading another page.
+ */
+Drupal.overlayChild.behaviors.loading = function (context, settings) {
+  var text = Drupal.t('Loading...');
+
+  $(document).bind('drupalOverlayBeforeLoad.drupal-overlay.drupal-overlay-child-loading', function () {
+    $('#overlay-title').text(text);
+  });
+};
+
+/**
+ * Switch active tab immediately.
+ */
+Drupal.overlayChild.behaviors.tabs = function (context, settings) {
+  var $tabsLinks = $('#overlay-tabs > li > a');
+
+  $('#overlay-tabs > li > a').bind('click.drupal-overlay', function () {
+    var active_tab = Drupal.t('(active tab)');
+    $tabsLinks.parent().siblings().removeClass('active').find('element-invisible:contains(' + active_tab + ')').appendTo(this);
+    $(this).parent().addClass('active');
+  });
+};
+
+/**
+ * If the shortcut add/delete button exists, move it to the overlay titlebar.
+ */
+Drupal.overlayChild.behaviors.shortcutAddLink = function (context, settings) {
+  // Remove any existing shortcut button markup from the titlebar.
+  $('#overlay-titlebar').find('.add-or-remove-shortcuts').remove();
+  // If the shortcut add/delete button exists, move it to the titlebar.
+  var $addToShortcuts = $('.add-or-remove-shortcuts');
+  if ($addToShortcuts.length) {
+    $addToShortcuts.insertAfter('#overlay-title');
+  }
+};
+
+/**
+ * Override the tableHeaderOffset callback for tableheader.js.
+ */
+Drupal.overlayChild.behaviors.displace = function (context, settings) {
+  Drupal.displace = parent.Drupal.displace;
+};
+
 })(jQuery);
Index: modules/overlay/overlay-parent.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/overlay/overlay-parent.css,v
retrieving revision 1.14
diff -u -r1.14 overlay-parent.css
--- modules/overlay/overlay-parent.css	28 Apr 2010 20:08:39 -0000	1.14
+++ modules/overlay/overlay-parent.css	3 May 2010 23:22:13 -0000
@@ -1,165 +1,52 @@
 /* $Id: overlay-parent.css,v 1.14 2010/04/28 20:08:39 dries Exp $ */
 
-/**
- * ui-dialog overlay.
- */
-.ui-widget-overlay {
-  opacity: 1;
-  filter: none;
-  /* Using a transparent png renders faster than using opacity */
-  background: transparent url(images/background.png) repeat;
+html.overlay-open,
+html.overlay-open body {
+  height: 100%;
+  overflow: hidden;
 }
 
-body.overlay-autofit {
-  overflow-y: scroll;
+html.overlay-scrollbar {
+  overflow: scroll;
 }
 
-/**
- * Overlay wrapper.
- */
-#overlay-wrapper {
-  position: absolute;
+#overlay-container,
+.overlay-modal-background,
+.overlay-element {
+  position: fixed;
   top: 0;
   left: 0;
+  z-index: 500;
+  height: 100%;
   width: 100%;
-  z-index: 501;
-  padding: 20px 0 15px 0;
-}
-
-/**
- * jQuery UI Dialog classes.
- */
-.overlay {
-  position: static;
-  padding-right: 26px;
-  margin: 0 auto;
-  width: 88%;
-  min-width: 700px;
-  min-height: 100px;
-}
-
-.overlay.ui-widget-content,
-.overlay .ui-widget-header {
-  background: none;
-  border: none;
-}
-
-.overlay .ui-dialog-titlebar {
-  white-space: nowrap;
-  padding: 0 20px;
-}
-
-.overlay .ui-dialog-title {
-  margin: 0;
-  padding: 0.3em 0;
-  color: #fff;
-  font-size: 20px;
-}
-.overlay .ui-dialog-title:active,
-.overlay .ui-dialog-title:focus {
-  outline: 0;
-}
-.overlay .ui-dialog-titlebar-close,
-.overlay .ui-dialog-titlebar-close:hover {
-  display: block;
-  right: -25px;
-  top: 100%;
-  margin: 0;
-  border: none;
-  padding: 0;
-  width: 26px;
-  height: 36px;
-  background: transparent url(images/close.png) no-repeat;
-  border-top-left-radius: 0;
-  -moz-border-radius-topleft: 0;
-  -webkit-border-top-left-radius: 0;
-}
-.overlay .ui-dialog-titlebar-close span {
-  display: none;
-}
-.overlay .ui-dialog-content {
-  color: #292929;
-  background-color: #f8f8f8;
 }
 
-/**
- * Overlay content.
- */
-.overlay #overlay-container {
-  margin: 0;
-  padding: 0;
-  width: 100%;
-  overflow: visible;
-  background: #fff;
-}
-.overlay #overlay-element {
-  overflow: hidden;
-  width: 100%;
-  height: 100%;
+.overlay-modal-background {
+  /* Using a transparent png renders faster than using opacity */
+  background: transparent url(images/background.png) repeat;
 }
 
-/**
- * Tabs on the overlay.
- */
-.overlay .ui-dialog-titlebar ul {
-  position: absolute;
-  right: 20px;
-  bottom: 0;
-  margin: 0;
-  line-height: 27px;
-  text-transform: uppercase;
-}
-.overlay .ui-dialog-titlebar ul li {
-  display: inline;
-  list-style: none;
-  margin: 0 0 0 -3px;
-  padding: 0;
-}
-
-.overlay .ui-dialog-titlebar ul li a,
-.overlay .ui-dialog-titlebar ul li a:active,
-.overlay .ui-dialog-titlebar ul li a:visited,
-.overlay .ui-dialog-titlebar ul li a:hover {
-  display: inline-block;
-  background-color: #a6a7a2;
-  border-radius: 8px 8px 0 0;
-  -moz-border-radius: 8px 8px 0 0;
-  -webkit-border-top-left-radius: 8px;
-  -webkit-border-top-right-radius: 8px;
-  color: #000;
-  font-weight: bold;
-  padding: 0 14px;
-  text-decoration: none;
-  font-size: 11px;
-  margin: 0;
-}
-.overlay .ui-dialog-titlebar ul li.active a,
-.overlay .ui-dialog-titlebar ul li.active a.active,
-.overlay .ui-dialog-titlebar ul li.active a:active,
-.overlay .ui-dialog-titlebar ul li.active a:visited {
-  background-color: #fff;
-  margin: 0;
-}
-.overlay .ui-dialog-titlebar ul li a:hover {
-  color: #fff;
+.overlay-element {
+  z-index: 501;
+  background: transparent;
+  left: -200%;
 }
-.overlay .ui-dialog-titlebar ul li.active a:hover {
-  color: #000;
+.overlay-element.overlay-active {
+  left: 0;
 }
 
-/**
- * Add to shortcuts link
- */
-.overlay div.add-or-remove-shortcuts {
-  padding-top: 0.9em;
+.overlay-displace-top,
+.overlay-displace-bottom {
+  z-index: 600;
 }
 
 /**
- * IE 6 Fix.
- *
- * Use filter to support transparency in IE6 for the overlay background.
+ * IE6 shows elements with position:fixed as position:static so replace
+ * it with position:absolute;
  */
-* html .ui-widget-overlay {
-  filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='modules/overlay/images/background.png', sizingMethod='scale');
-  background: none;
+* html #overlay-container,
+* html .overlay-modal-background,
+* html .overlay-element
+{
+  position: absolute;
 }
Index: modules/overlay/overlay.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/overlay/overlay.module,v
retrieving revision 1.17
diff -u -r1.17 overlay.module
--- modules/overlay/overlay.module	24 Apr 2010 07:14:29 -0000	1.17
+++ modules/overlay/overlay.module	3 May 2010 23:22:14 -0000
@@ -46,6 +46,18 @@
 }
 
 /**
+ * Implements hook_theme().
+ */
+function overlay_theme() {
+  return array(
+    'overlay' => array(
+      'render element' => 'page',
+      'template' => 'overlay',
+    ),
+  );
+}
+
+/**
  * Implements hook_init().
  *
  * Determine whether the current page request is destined to appear in the
@@ -150,8 +162,7 @@
       $module_path . '/overlay-parent.css' => array(),
     ),
     'dependencies' => array(
-      array('system', 'ui.dialog'),
-      array('system', 'ui.position'),
+      array('system', 'ui'),
       array('system', 'jquery-bbq'),
     ),
   );
@@ -163,8 +174,8 @@
     'js' => array(
       $module_path . '/overlay-child.js' => array(),
     ),
-    'dependencies' => array(
-      array('system', 'ui'),
+    'css' => array(
+      $module_path . '/overlay-child.css' => array(),
     ),
   );
 
@@ -221,6 +232,11 @@
       $page[$skipped_region]['#access'] = FALSE;
     }
   }
+
+  if (overlay_get_mode() == 'child') {
+    // Add the overlay wrapper before the html wrapper.
+    array_unshift($page['#theme_wrappers'], 'overlay');
+  }
 }
 
 /**
@@ -284,6 +300,43 @@
 }
 
 /**
+ * Process variables for overlay.tpl.php
+ *
+ * Prepare the values passed to the theme_block function to be passed
+ * into a pluggable template engine. Uses block properties to generate a
+ * series of template file suggestions. If none are found, the default
+ * block.tpl.php is used.
+ *
+ * Most themes utilize their own copy of block.tpl.php. The default is located
+ * inside "modules/block/block.tpl.php". Look in there for the full list of
+ * variables.
+ *
+ * The $variables array contains the following arguments:
+ * - $block
+ *
+ * @see overlay.tpl.php
+ */
+function template_preprocess_overlay(&$variables) {
+  $variables['tabs']              = menu_primary_local_tasks();
+  $variables['title']             = drupal_get_title();
+}
+
+/**
+ * Process variables for overlay.tpl.php
+ *
+ * Perform final addition and modification of variables before passing into
+ * the template. To customize these variables, call drupal_render() on elements
+ * in $variables['page'] during THEME_preprocess_page().
+ *
+ * @see template_preprocess_overlay()
+ * @see overlay.tpl.php
+ */
+function template_process_overlay(&$variables) {
+  // Place the rendered HTML for the page body into a top level variable.
+  $variables['page'] = $variables['page']['#children'];
+}
+
+/**
  * Preprocess template variables for page.tpl.php.
  *
  * Display breadcrumbs correctly inside the overlay.
@@ -296,17 +349,10 @@
     $overlay_breadcrumb = drupal_get_breadcrumb();
     array_shift($overlay_breadcrumb);
     $variables['breadcrumb'] = theme('breadcrumb', array('breadcrumb' => $overlay_breadcrumb));
-  }
-}
 
-/**
- * Preprocess template variables for toolbar.tpl.php.
- *
- * Adding the 'overlay-displace-top' class to the toolbar pushes the overlay
- * down, so it appears below the toolbar.
- */
-function overlay_preprocess_toolbar(&$variables) {
-  $variables['classes_array'][] = "overlay-displace-top";
+    $variables['tabs'] = '';
+    $variables['primary_local_tasks'] = '';
+  }
 }
 
 /**
@@ -477,9 +523,6 @@
 
     case 'child':
       drupal_add_library('overlay', 'child');
-      // Pass child's document height on to parent document as quickly as
-      // possible so it can be updated accordingly.
-      drupal_add_js('if (parent.Drupal && parent.Drupal.overlay) { parent.Drupal.overlay.innerResize(jQuery(document.body).outerHeight()); }', array('type' => 'inline', 'scope' => 'footer'));
 
       // Allow modules to act upon overlay events.
       module_invoke_all('overlay_child_initialize');
Index: modules/overlay/overlay-parent.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/overlay/overlay-parent.js,v
retrieving revision 1.40
diff -u -r1.40 overlay-parent.js
--- modules/overlay/overlay-parent.js	30 Apr 2010 05:25:19 -0000	1.40
+++ modules/overlay/overlay-parent.js	3 May 2010 23:22:14 -0000
@@ -4,28 +4,26 @@
 
 /**
  * Open the overlay, or load content into it, when an admin link is clicked.
- *
- * http://docs.jquery.com/Namespaced_Events
  */
 Drupal.behaviors.overlayParent = {
   attach: function (context, settings) {
-    // Make sure the onhashchange handling below is only processed once.
     if (this.processed) {
       return;
     }
     this.processed = true;
 
-    // Bind event handlers to the parent window.
     $(window)
-    // When the hash (URL fragment) changes, open the overlay if needed.
-    .bind('hashchange.overlay-event', Drupal.overlay.hashchangeHandler)
-    // Trigger the hashchange event once, after the page is loaded, so that
-    // permalinks open the overlay.
-    .trigger('hashchange.overlay-event');
-    // Instead of binding a click event handler to every link we bind one to the
-    // document and only handle events that bubble up. This allows other scripts
-    // to bind their own handlers to links and also to prevent overlay's handling.
-    $(document).bind('click.overlay-event', Drupal.overlay.clickHandler);
+      // When the hash (URL fragment) changes, open the overlay if needed.
+      .bind('hashchange.drupal-overlay', $.proxy(Drupal.overlay, 'hashchangeHandler'))
+      // Trigger the hashchange handler once, after the page is loaded, so that
+      // permalinks open the overlay.
+      .triggerHandler('hashchange.drupal-overlay');
+
+    $(document)
+      // Instead of binding a click event handler to every link we bind one to the
+      // document and only handle events that bubble up. This allows other scripts
+      // to bind their own handlers to links and also to prevent overlay's handling.
+      .bind('click.drupal-overlay mouseup.drupal-overlay', $.proxy(Drupal.overlay, 'clickHandler'));
   }
 };
 
@@ -42,226 +40,82 @@
  *   is loaded into the overlay.
  * - drupalOverlayLoad: This event is triggered when the overlay is finished
  *   loading.
+ * - drupalOverlayResize: This event is triggered when the overlay is being
+ *   resized to match the parent window.
  */
 Drupal.overlay = Drupal.overlay || {
-  options: {},
   isOpen: false,
   isOpening: false,
   isClosing: false,
   isLoading: false,
 
-  resizeTimeoutID: null,
-  lastHeight: 0,
-
-  $wrapper: null,
-  $dialog: null,
-  $dialogTitlebar: null,
   $container: null,
-  $iframe: null,
+  $iframeA: null,
+  $iframeB: null,
 
-  $iframeWindow: null,
-  $iframeDocument: null,
-  $iframeBody: null
+  iframeWindow: null
 };
 
+Drupal.overlay.prototype = {};
+
 /**
- * Open an overlay.
+ * Open the overlay.
  *
- * Ensure that only one overlay is opened ever. Use Drupal.overlay.load() if
- * the overlay is already open but a new page needs to be opened.
- *
- * @param options
- *   Properties of the overlay to open:
- *   - url: the URL of the page to open in the overlay.
- *   - width: width of the overlay in pixels.
- *   - height: height of the overlay in pixels.
- *   - autoFit: boolean indicating whether the overlay should be resized to
- *     fit the contents of the document loaded.
- *   - customDialogOptions: an object with custom jQuery UI Dialog options.
+ * @param url
+ *   The URL of the page to open in the overlay.
  *
  * @return
  *   If the overlay was opened true, otherwise false.
  */
-Drupal.overlay.open = function (options) {
-  var self = this;
-
+Drupal.overlay.open = function (url) {
   // Just one overlay is allowed.
-  if (self.isOpen || self.isOpening) {
-    return false;
+  if (this.isOpen || this.isOpening) {
+    return this.load(url);
   }
-  self.isOpening = true;
-
-  var defaultOptions = {
-    url: options.url,
-    width: options.width,
-    height: options.height,
-    autoFit: (options.autoFit == undefined || options.autoFit),
-    customDialogOptions: options.customDialogOptions || {}
-  };
-
-  self.options = $.extend(defaultOptions, options);
+  this.isOpening = true;
 
   // Create the dialog and related DOM elements.
-  self.create();
+  this.create();
 
-  // Open the dialog.
-  self.$container.dialog('open');
+  this.isOpening = false;
+  this.isOpen = true;
+  $(document.documentElement).addClass('overlay-open');
 
   // Allow other scripts to respond to this event.
   $(document).trigger('drupalOverlayOpen');
 
-  return true;
+  return this.load(url);
 };
 
 /**
  * Create the underlying markup and behaviors for the overlay.
- *
- * Reuses jQuery UI's dialog component to construct the overlay markup and
- * behaviors, sanitizing the options previously set in self.options.
  */
 Drupal.overlay.create = function () {
   var self = this;
-  var $window = $(window);
-  var $body = $('body');
 
-  var delayedOuterResize = function() {
-    setTimeout(self.outerResize, 1);
-  };
-
-  // Open callback for jQuery UI Dialog.
-  var dialogOpen = function () {
-    // Unbind the keypress handler installed by ui.dialog itself.
-    // IE does not fire keypress events for some non-alphanumeric keys
-    // such as the tab character. http://www.quirksmode.org/js/keys.html
-    // Also, this is not necessary here because we need to deal with an
-    // iframe element that contains a separate window.
-    // We'll try to provide our own behavior from bindChild() method.
-    self.$dialog.unbind('keypress.ui-dialog');
-
-    // Add title to close button features for accessibility.
-    self.$dialogTitlebar.find('.ui-dialog-titlebar-close').attr('title', Drupal.t('Close'));
-
-    // Replace the title span element with an h1 element for accessibility.
-    var $dialogTitle = self.$dialogTitlebar.find('.ui-dialog-title');
-    $dialogTitle.replaceWith(Drupal.theme('overlayTitleHeader', $dialogTitle.html()));
-
-    // Wrap the dialog into a div so we can center it using CSS.
-    self.$dialog.wrap(Drupal.theme('overlayWrapper'));
-    self.$wrapper = self.$dialog.parent();
-
-    self.$dialog.css({
-      // Remove some CSS properties added by ui.dialog itself.
-      position: '', left: '', top: '', height: ''
-    });
-
-    // Add a class to the body to indicate the overlay is open.
-    $body.addClass('overlay-open');
-
-    // Adjust overlay size when window is resized.
-    $window.bind('resize.overlay-event', delayedOuterResize);
-
-    if (self.options.autoFit) {
-      $body.addClass('overlay-autofit');
-    }
-    else {
-      // Add scrollbar to the iframe when autoFit is disabled.
-      self.$iframe.css('overflow', 'auto').attr('scrolling', 'yes');
-    }
-
-    // Compute initial dialog size.
-    self.outerResize();
-
-    // Load the document on hidden iframe (see bindChild method).
-    self.load(self.options.url);
-
-    if ($.isFunction(self.options.onOverlayOpen)) {
-      self.options.onOverlayOpen(self);
-    }
+  this.$container = $(Drupal.theme('overlayContainer'))
+    .appendTo(document.body);
 
-    self.isOpen = true;
-    self.isOpening = false;
-  };
-
-  // Before close callback for jQuery UI Dialog.
-  var dialogBeforeClose = function () {
-    // Prevent double execution when close is requested more than once.
-    if (!self.isOpen || self.isClosing) {
-      return false;
-    }
-
-    // Allow other scripts to decide if the overlay can be closed. If an event-
-    // handler returns false the overlay won't be closed. The external script
-    // should call Drupal.overlay.close() again when it is ready for closing.
-    var event = $.Event('drupalOverlayBeforeClose');
-    $(document).trigger(event);
-    if (event.isDefaultPrevented()) {
-      return false;
-    }
-
-    self.isClosing = true;
-
-    // Stop all animations.
-    $window.unbind('resize.overlay-event', delayedOuterResize);
-    clearTimeout(self.resizeTimeoutID);
-  };
-
-  // Close callback for jQuery UI Dialog.
-  var dialogClose = function () {
-    $(document).unbind('keydown.overlay-event');
-
-    $body.removeClass('overlay-open').removeClass('overlay-autofit');
-
-    // When the iframe is still loading don't destroy it immediately but after
-    // the content is loaded (see self.load).
-    if (!self.isLoading) {
-      // As some browsers (webkit) fire a load event when the iframe is removed,
-      // load handlers need to be unbound before removing the iframe.
-      self.$iframe.unbind('load.overlay-event');
-      self.destroy();
-    }
-
-    self.isOpen = false;
-    self.isClosing = false;
-
-    self.lastHeight = 0;
-
-    // Allow other scripts to respond to this event.
-    $(document).trigger('drupalOverlayClose');
-  };
-
-  // Default jQuery UI Dialog options.
-  var dialogOptions = {
-    autoOpen: false,
-    closeOnEscape: true,
-    dialogClass: 'overlay',
-    draggable: false,
-    modal: true,
-    resizable: false,
-    title: Drupal.t('Loading...'),
-    zIndex: 500,
-
-    // When the width is not set, use an empty string instead, so that CSS will
-    // be able to handle it.
-    width: self.options.width || '',
-    height: self.options.height,
-
-    open: dialogOpen,
-    beforeclose: dialogBeforeClose,
-    close: dialogClose
-  };
-
-  // Create the overlay container and iframe.
-  self.$iframe = $(Drupal.theme('overlayElement'));
-  self.$container = $(Drupal.theme('overlayContainer')).append(self.$iframe);
-
-  // Allow external script to override the default jQuery UI Dialog options.
-  $.extend(dialogOptions, self.options.customDialogOptions);
-
-  // Create the jQuery UI Dialog.
-  self.$container.dialog(dialogOptions);
-  // Cache dialog selector.
-  self.$dialog = self.$container.parents('.' + dialogOptions.dialogClass);
-  self.$dialogTitlebar = self.$dialog.find('.ui-dialog-titlebar');
+  // Use two frames as some browsers show a white background instead of our
+  // transparent one when loading a page into an iframe. By loading the page
+  // in a hidden (inactive) iframe the user doesn't see the white background.
+  // When the page is loaded we switch the inactive and the active iframe.
+  this.activeFrame = this.$iframeA = $(Drupal.theme('overlayElement'))
+    .appendTo(this.$container);
+
+  this.inactiveFrame = this.$iframeB = $(Drupal.theme('overlayElement'))
+    .appendTo(this.$container);
+
+  this.$iframeA.bind('load.drupal-overlay', { sibling: this.$iframeB }, $.proxy(this, 'loadChild'));
+  this.$iframeB.bind('load.drupal-overlay', { sibling: this.$iframeA }, $.proxy(this, 'loadChild'));
+
+  $(window)
+    .bind('resize.drupal-overlay', $.proxy(this, 'outerResize'));
+  $(document)
+    .bind('drupalOverlayLoad.drupal-overlay', $.proxy(this, 'outerResize'))
+    .bind('drupalOverlayClose.drupal-overlay', $.proxy(this, 'resetDisplacedElements'))
+    //.bind('keydown.drupal-overlay', $.proxy(this, 'keydownHandlerNavigation'))
+    .bind('focusin.drupal-overlay', $.proxy(this, 'focusinHandlerNavigation'));
 };
 
 /**
@@ -271,317 +125,166 @@
  * already open.
  */
 Drupal.overlay.load = function (url) {
-  var self = this;
-  var iframeElement = self.$iframe.get(0);
-
-  self.isLoading = true;
-
-  // Change the overlay title.
-  self.$container.dialog('option', 'title', Drupal.t('Loading...'));
-  // Remove any existing shortcut button markup in the title section.
-  self.$dialogTitlebar.find('.add-or-remove-shortcuts').remove();
-
-  // Remove any existing tabs in the title section, but only if requested url
-  // is not one of those tabs. If the latter, set that tab active. Only check
-  // for tabs when the overlay is not empty.
-  if (self.$iframeBody) {
-    var urlPath = self.getPath(url);
-
-    // Get the primary tabs
-    var $tabs = self.$dialogTitlebar.find('ul');
-    var $tabsLinks = $tabs.find('> li > a');
-
-    // Check if clicked on a primary tab
-    var $activeLink = $tabsLinks.filter(function () { return self.getPath(this) == urlPath; });
-
-    if ($activeLink.length) {
-      var active_tab = Drupal.t('(active tab)');
-      $tabsLinks.parent().removeClass('active').find('element-invisible:contains(' + active_tab + ')').appendTo($activeLink);
-      $activeLink.parent().addClass('active');
-      removeTabs = false;
-    }
-    else {
-      // Get the secondary tabs
-      var $secondary = self.$iframeBody.find('ul.secondary');
-      var $secondaryLinks = $secondary.find('> li > a');
-
-      // Check if clicked on a secondary tab
-      var $activeLinkSecondary = $secondaryLinks.filter(function () { return self.getPath(this) == urlPath; });
-
-      if ($activeLinkSecondary.length) {
-        var active_tab = Drupal.t('(active tab)');
-        $secondaryLinks.parent().removeClass('active').find('element-invisible:contains(' + active_tab + ')').appendTo($activeLinkSecondary);
-        $activeLinkSecondary.parent().addClass('active');
-        removeTabs = false;
-      }
-      else {
-        $tabs.remove();
-      }
-    }
+  if (!this.isOpen) {
+    return false;
   }
 
-  self.$iframeWindow = null;
-  self.$iframeDocument = null;
-  self.$iframeBody = null;
-
-  // No need to resize while loading.
-  clearTimeout(self.resizeTimeoutID);
-
   // Allow other scripts to respond to this event.
   $(document).trigger('drupalOverlayBeforeLoad');
 
-  // While the overlay is loading, we remove the loaded class from the dialog.
-  // After the loading is finished, the loaded class is added back. The loaded
-  // class is being used to hide the iframe while loading.
-  // See overlay-parent.css .overlay-loaded #overlay-element.
-  self.$dialog.removeClass('overlay-loaded');
-  self.$iframe.once('overlay-event-load')
-    .bind('load.overlay-event', function () {
-      self.isLoading = false;
-
-      // Only continue when overlay is still open and not closing.
-      if (self.isOpen && !self.isClosing) {
-        self.$dialog.addClass('overlay-loaded');
+  $(document.documentElement).addClass('overlay-loading');
 
-        // Allow other scripts to respond to this event.
-        $(document).trigger('drupalOverlayLoad');
-      }
-      else {
-        self.destroy();
-      }
-  });
-
-  // Get the document object of the iframe window.
-  // See http://xkr.us/articles/dom/iframe-document/.
-  var iframeDocument = (iframeElement.contentWindow || iframeElement.contentDocument);
-  if (iframeDocument.document) {
-    iframeDocument = iframeDocument.document;
-  }
+  var iframeElement = this.inactiveFrame[0];
+  // The contentDocument property is not supported in IE until IE8.
+  var iframeDocument = iframeElement.contentDocument || iframeElement.contentWindow.document;
 
   // location.replace doesn't create a history entry. location.href does.
   // In this case, we want location.replace, as we're creating the history
   // entry using URL fragments.
   iframeDocument.location.replace(url);
+
+  return true;
 };
 
 /**
  * Close the overlay and remove markup related to it from the document.
+ *
+ * @return
+ *   If the overlay was closed true, otherwise false.
  */
 Drupal.overlay.close = function () {
-  return this.$container.dialog('close');
+  // Prevent double execution when close is requested more than once.
+  if (!this.isOpen || this.isClosing) {
+    return false;
+  }
+
+  // Allow other scripts to respond to this event.
+  var event = $.Event('drupalOverlayBeforeClose');
+  $(document).trigger(event);
+  // If a handler returned false, the close will be prevented.
+  if (event.isDefaultPrevented()) {
+    return false;
+  }
+
+  this.isClosing = true;
+
+  // When the iframe is still loading don't destroy it immediately but after
+  // the content is loaded (see self.load).
+  if (!this.isLoading) {
+    this.destroy();
+  }
+
+  this.isOpen = false;
+  $(document.documentElement).removeClass('overlay-open');
+
+  // Allow other scripts to respond to this event.
+  $(document).trigger('drupalOverlayClose');
+
+  if (!this.isLoading) {
+    this.isClosing = false;
+  }
+
+  return true;
 };
 
 /**
  * Destroy the overlay.
  */
 Drupal.overlay.destroy = function () {
-  var self = this;
-
-  self.$container.dialog('destroy').remove();
-  self.$wrapper.remove();
+  this.$iframeA.unbind('.drupal-overlay');
+  this.$iframeB.unbind('.drupal-overlay');
+  this.$container.remove();
+
+  this.$container = null;
+  this.$iframeA = null;
+  this.$iframeB = null;
 
-  self.$wrapper = null;
-  self.$dialog = null;
-  self.$dialogTitlebar = null;
-  self.$container = null;
-  self.$iframe = null;
-
-  self.$iframeWindow = null;
-  self.$iframeDocument = null;
-  self.$iframeBody = null;
+  this.iframeWindow = null;
 };
 
 /**
  * Redirect the overlay parent window to the given URL.
  *
- * @param link
+ * @param url
  *   Can be an absolute URL or a relative link to the domain root.
  */
-Drupal.overlay.redirect = function (link) {
-  if (link.indexOf('http') != 0 && link.indexOf('https') != 0) {
-    var absolute = location.href.match(/https?:\/\/[^\/]*/)[0];
-    link = absolute + link;
-  }
+Drupal.overlay.redirect = function (url) {
+  // Create a native Link object, so we can use its object methods.
+  var link = $(url.link(url)).get(0);
 
   // If the link is already open, force the hashchange event to simulate reload.
-  if (location.href == link) {
-    $(window).trigger('hashchange.overlay-event');
+  if (window.location.href == link.href) {
+    $(window).trigger('hashchange.drupal-overlay');
   }
 
-  location.href = link;
+  window.location.href = link.href;
   return true;
 };
 
 /**
+ * Load event handler for the overlay iframe.
+ */
+Drupal.overlay.loadChild = function (event) {
+  var iframe = event.target;
+  var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
+  var iframeWindow = iframeDocument.defaultView || iframeDocument.parentWindow;
+  if (iframeDocument.location == 'about:blank') {
+    return;
+  }
+
+  this.isLoading = false;
+  $(document.documentElement).removeClass('overlay-loading');
+  event.data.sibling.removeClass('overlay-active');
+
+  // Only continue when overlay is still open and not closing.
+  if (this.isOpen && !this.isClosing) {
+    // And child document is an actual overlayChild.
+    if (iframeWindow.Drupal && iframeWindow.Drupal.overlayChild) {
+      this.activeFrame = $(iframe)
+        .addClass('overlay-active')
+        .attr({ tabindex: null, unselectable: null });
+      this.inactiveFrame = event.data.sibling
+        .attr({ tabindex: -1, unselectable: 'on' });
+
+      // Allow other scripts to respond to this event.
+      $(document).trigger('drupalOverlayLoad');
+    }
+    else {
+      var leave = confirm(Drupal.t('A non-overlay document was loaded into the overlay. Do you want to load the document?'));
+      if (leave) {
+        window.location.href = window.location.href.replace(window.location.hash, '');
+      }
+
+    }
+  }
+  else {
+    this.destroy();
+  }
+};
+
+/**
  * Bind the child window.
- *
- * Add tabs on the overlay, keyboard actions and display animation.
  */
 Drupal.overlay.bindChild = function (iframeWindow, isClosing) {
-  var self = this;
-  self.$iframeWindow = iframeWindow.jQuery;
-  self.$iframeDocument = self.$iframeWindow(iframeWindow.document);
-  self.$iframeBody = self.$iframeWindow('body');
+  this.iframeWindow = iframeWindow;
 
   // We are done if the child window is closing.
-  if (isClosing || self.isClosing || !self.isOpen) {
+  if (isClosing || this.isClosing || !this.isOpen) {
     return;
   }
 
   // Make sure the parent window URL matches the child window URL.
-  self.syncChildLocation(iframeWindow.document.location);
+  this.syncChildLocation(iframeWindow.document.location);
 
-  // Unbind the mousedown handler installed by ui.dialog because the
-  // handler interferes with use of the scroll bar in Chrome & Safari.
-  // After unbinding from the document we bind a handler to the dialog overlay
-  // which returns false to prevent event bubbling.
-  // See http://dev.jqueryui.com/ticket/4671.
-  // See https://bugs.webkit.org/show_bug.cgi?id=19033.
-  // Do the same for the click handler as prevents default handling of clicks in
-  // displaced regions (e.g. opening a link in a new browser tab when CTRL was
-  // pressed while clicking).
-  $(document).unbind('mousedown.dialog-overlay click.dialog-overlay');
-  $('.ui-widget-overlay').bind('mousedown.dialog-overlay click.dialog-overlay', function (){return false;});
-
-  // Unbind the keydown and keypress handlers installed by ui.dialog because
-  // they interfere with use of browser's keyboard hotkeys like CTRL+w.
-  // This may cause problems when using modules that implement keydown or
-  // keypress handlers as they aren't blocked when overlay is open.
-  $(document).unbind('keydown.dialog-overlay keypress.dialog-overlay');
-
-  // Reset the scroll to the top of the window so that the overlay is visible again.
-  window.scrollTo(0, 0);
-
-  var iframeTitle = self.$iframeDocument.attr('title');
-
-  // Update the dialog title with the child window title.
-  self.$container.dialog('option', 'title', iframeTitle);
-  self.$dialogTitlebar.find('.ui-dialog-title').focus();
   // Add a title attribute to the iframe for accessibility.
-  self.$iframe.attr('title', Drupal.t('@title dialog', { '@title': iframeTitle }));
+  this.activeFrame.attr('title', Drupal.t('@title dialog', { '@title': iframeWindow.document.title }));
 
-  // Remove any existing shortcut button markup in the title section.
-  self.$dialogTitlebar.find('.add-or-remove-shortcuts').remove();
-  // If the shortcut add/delete button exists, move it to the dialog title.
-  var $addToShortcuts = self.$iframeWindow('.add-or-remove-shortcuts');
-  if ($addToShortcuts.length) {
-    // Move the button markup to the title section. We need to copy markup
-    // instead of moving the DOM element, because Webkit and IE browsers will
-    // not move DOM elements between two DOM documents.
-    $addToShortcuts = $(self.$iframeWindow('<div>').append($addToShortcuts).remove().html());
-
-    self.$dialogTitlebar.find('.ui-dialog-title').after($addToShortcuts);
-  }
-
-  // Remove any existing tabs in the title section.
-  self.$dialogTitlebar.find('ul').remove();
-  // If there are tabs in the page, move them to the titlebar.
-  var $tabs = self.$iframeWindow('ul.primary');
-  if ($tabs.length) {
-    // Move the tabs markup to the title section. We need to copy markup
-    // instead of moving the DOM element, because Webkit and IE browsers will
-    // not move DOM elements between two DOM documents.
-    $tabs = $(self.$iframeWindow('<div>').append($tabs).remove().html());
-
-    self.$dialogTitlebar.append($tabs);
-
-    // Remove any classes from the list element to avoid theme styles
-    // clashing with our styling.
-    $tabs.removeAttr('class');
-  }
-
-  // Re-attach the behaviors we lost while copying elements from the iframe
-  // document to the parent document.
-  Drupal.attachBehaviors(self.$dialogTitlebar);
-
-  // Try to enhance keyboard based navigation of the overlay.
-  // Logic inspired by the open() method in ui.dialog.js, and
-  // http://wiki.codetalks.org/wiki/index.php/Docs/Keyboard_navigable_JS_widgets
-
-  // Get a reference to the close button.
-  var $closeButton = self.$dialogTitlebar.find('.ui-dialog-titlebar-close');
-
-  // Search tabbable elements on the iframed document to speed up related
-  // keyboard events.
-  // @todo: Do we need to provide a method to update these references when
-  // AJAX requests update the DOM on the child document?
-  var $iframeTabbables = self.$iframeWindow(':tabbable:not(form)');
-  var $firstTabbable = $iframeTabbables.filter(':first');
-  var $lastTabbable = $iframeTabbables.filter(':last');
-
-  // Unbind keyboard event handlers that may have been enabled previously.
-  $(document).unbind('keydown.overlay-event');
-  $closeButton.unbind('keydown.overlay-event');
-
-  // When the focus leaves the close button, then we want to jump to the
-  // first/last inner tabbable element of the child window.
-  $closeButton.bind('keydown.overlay-event', function (event) {
-    if (event.keyCode && event.keyCode == $.ui.keyCode.TAB) {
-      var $target = (event.shiftKey ? $lastTabbable : $firstTabbable);
-      if (!$target.size()) {
-        $target = self.$iframeDocument;
-      }
-      $target.focus();
-      return false;
-    }
-  });
-
-  // When the focus leaves the child window, then drive the focus to the
-  // close button of the dialog.
-  self.$iframeDocument.bind('keydown.overlay-event', function (event) {
-    if (event.keyCode) {
-      if (event.keyCode == $.ui.keyCode.TAB) {
-        if (event.shiftKey && event.target == $firstTabbable.get(0)) {
-          $closeButton.focus();
-          return false;
-        }
-        else if (!event.shiftKey && event.target == $lastTabbable.get(0)) {
-          $closeButton.focus();
-          return false;
-        }
-      }
-      else if (event.keyCode == $.ui.keyCode.ESCAPE) {
-        self.close();
-        return false;
-      }
-    }
-  });
-
-  // When the focus is captured by the parent document, then try
-  // to drive the focus back to the first tabbable element, or the
-  // close button of the dialog (default).
-  $(document).bind('keydown.overlay-event', function (event) {
-    if (event.keyCode && event.keyCode == $.ui.keyCode.TAB) {
-      if (!self.$iframeWindow(':tabbable:not(form):first').focus().size()) {
-          $closeButton.focus();
-      }
-      return false;
+  // Dispatch events to the overlay document.
+  $(document).bind('drupalOverlayBeforeClose drupalOverlayBeforeLoad drupalOverlayResize', function (event) {
+    if (iframeWindow && iframeWindow.document) {
+      iframeWindow.jQuery(iframeWindow.document).trigger(event);
     }
   });
-
-  // Adjust overlay to fit the iframe content?
-  if (self.options.autoFit) {
-    self.innerResize();
-
-    var delayedResize = function() {
-      if (!self.isOpen) {
-        clearTimeout(self.resizeTimeoutID);
-        return;
-      }
-
-      self.innerResize();
-      iframeWindow.scrollTo(0, 0);
-      self.resizeTimeoutID = setTimeout(delayedResize, 150);
-    };
-
-    clearTimeout(self.resizeTimeoutID);
-    self.resizeTimeoutID = setTimeout(delayedResize, 150);
-  }
-
-  // Scroll to anchor in overlay. This needs to be done after delayedResize().
-  if (iframeWindow.document.location.hash) {
-    window.scrollTo(0, self.$iframeWindow(iframeWindow.document.location.hash).position().top);
-  }
 };
 
 /**
@@ -593,126 +296,107 @@
  *   TRUE if the URL represents an administrative link, FALSE otherwise.
  */
 Drupal.overlay.isAdminLink = function (url) {
-  var self = this;
-  var path = self.getPath(url);
+  var path = this.getPath(url);
 
   // Turn the list of administrative paths into a regular expression.
-  if (!self.adminPathRegExp) {
+  if (!this.adminPathRegExp) {
     var adminPaths = '^(' + Drupal.settings.overlay.paths.admin.replace(/\s+/g, ')$|^(') + ')$';
     var nonAdminPaths = '^(' + Drupal.settings.overlay.paths.non_admin.replace(/\s+/g, ')$|^(') + ')$';
     adminPaths = adminPaths.replace(/\*/g, '.*');
     nonAdminPaths = nonAdminPaths.replace(/\*/g, '.*');
-    self.adminPathRegExp = new RegExp(adminPaths);
-    self.nonAdminPathRegExp = new RegExp(nonAdminPaths);
+    this.adminPathRegExp = new RegExp(adminPaths);
+    this.nonAdminPathRegExp = new RegExp(nonAdminPaths);
   }
 
-  return self.adminPathRegExp.exec(path) && !self.nonAdminPathRegExp.exec(path);
+  return this.adminPathRegExp.exec(path) && !this.nonAdminPathRegExp.exec(path);
 };
 
 /**
- * Resize overlay according to the size of its content.
- *
- * @todo: Watch for experience in the way we compute the size of the iframed
- * document. There are many ways to do it, and none of them seem to be perfect.
- * Note, though, that the size of the iframe itself may affect the size of the
- * child document, especially on fluid layouts.
+ * Resize overlay according to the size of the parent window.
  */
-Drupal.overlay.innerResize = function (height) {
-  var self = Drupal.overlay;
-  // Proceed only if the dialog still exists.
-  if (!self.isOpen || self.isClosing) {
+Drupal.overlay.outerResize = function () {
+  // Proceed only if the overlay still exists.
+  if (!(this.isOpen || this.isOpening) || this.isClosing || !this.iframeWindow) {
     return;
   }
 
-  // When no height is given try to get height when iframe content is loaded.
-  if (!height && self.$iframeBody) {
-    height = self.$iframeBody.outerHeight() + 25;
+  if (Drupal.displace) {
+    $(this.iframeWindow.document.body).css({
+      marginTop: Drupal.displace.getDisplacement('top'),
+      marginBottom: Drupal.displace.getDisplacement('bottom')
+    });
   }
+  
+  var documentHeight = this.iframeWindow.document.body.clientHeight;
+  var documentWidth = this.iframeWindow.document.body.clientWidth;
+  // IE6 doesn't support maxWidth, use width instead.
+  var maxWidthName = (typeof document.body.style.maxWidth == 'string') ? 'maxWidth' : 'width';
+
+  // Consider any element that should be visible above the overlay (such as
+  // a toolbar).
+  $('.displace-top, .displace-bottom').each(function () {
+    var maxWidth = documentWidth;
+    // In IE, Shadow filter makes element to overlap the scrollbar with 1px.
+    if (this.filters && this.filters.item('DXImageTransform.Microsoft.Shadow')) {
+      maxWidth -= 1;
+    }
+
+    // Prevent displaced elements overlapping window's scrollbar.
+    var currentMaxWidth = parseInt($(this).css(maxWidthName));
+    if (isNaN(currentMaxWidth) || currentMaxWidth > maxWidth || currentMaxWidth <= 0) {
+      $(this).css(maxWidthName, maxWidth);
+    }
+
+    // Use a more rigerous approach if the displaced element still overlaps
+    // window's scrollbar; clip the element on the right.
+    var offset = $(this).offset();
+    var offsetRight = offset.left + $(this).outerWidth();
+    if (offsetRight > maxWidth) {
+      $(this).css('clip', 'rect(auto, ' + (maxWidth - offset.left) + 'px, ' + (documentHeight - offset.top) + 'px, auto)');
+    }
+  });
 
-  // Only resize when height actually is changed.
-  if (height && height != self.lastHeight) {
-    // Resize the container.
-    self.$container.height(height);
-    // Keep the dim background grow or shrink with the dialog.
-    $.ui.dialog.overlay.resize();
-
-    self.lastHeight = height;
-  }
+  // Allow other scripts to respond to this event.
+  $(document).trigger('drupalOverlayResize');
 };
 
 /**
- * Resize overlay according to the size of the parent window.
+ * Reset position of displaced elements as they where before overlay was opened.
  */
-Drupal.overlay.outerResize = function () {
-  var self = Drupal.overlay;
-  // Proceed only if the dialog still exists.
-  if (!(self.isOpen || self.isOpening) || self.isClosing) {
-    return;
-  }
-
-  // Consider any region that should be visible above the overlay (such as
-  // an admin toolbar).
-  var $displaceTop = $('.overlay-displace-top');
-  var displaceTopHeight = 0;
-  $displaceTop.each(function () {
-    displaceTopHeight += $(this).height();
-  });
-
-  self.$wrapper.css('top', displaceTopHeight);
-
-  // When the overlay has no height yet, make it fit exactly in the window,
-  // or the configured height when autoFit is disabled.
-  if (!self.lastHeight) {
-    var titleBarHeight = self.$dialogTitlebar.outerHeight(true);
-
-    if (self.options.autoFit || self.options.height == undefined ||!isNan(self.options.height)) {
-      self.lastHeight = parseInt($(window).height() - displaceTopHeight - titleBarHeight - 45);
-    }
-    else {
-      self.lastHeight = self.options.height;
-    }
-
-    self.$container.height(self.lastHeight);
+Drupal.overlay.resetDisplacedElements = function () {
+  // IE bug that doesn't allow unsetting style.clip (http://dev.jquery.com/ticket/6512).
+  try {
+    $('.displace-top, .displace-bottom').css({ maxWidth: null, clip: null });
   }
-
-  if (self.options.autoFit) {
-    self.innerResize();
+  catch (err) {
+    $('.displace-top, .displace-bottom').each(function () {
+      $(this).css({ maxWidth: null, clip: 'rect(auto, auto, ' + document.body.clientHeight + 'px, auto)' });
+    });
   }
-
-  // Make the dim background grow or shrink with the dialog.
-  $.ui.dialog.overlay.resize();
 };
 
 /**
  * Click event handler.
  *
- * Instead of binding a click event handler to every link we bind one to the
- * document and handle events that bubble up. This allows other scripts to bind
- * their own handlers to links and also to prevent overlay's handling.
- *
- * This handler makes links in displaced regions work correctly, even when the
- * overlay is open.
- *
- * This click event handler should be bound any document (for example the
+ * This click event handler should be bound to any document (for example the
  * overlay iframe) of which you want links to open in the overlay.
  *
  * @see Drupal.overlayChild.behaviors.addClickHandler
  */
 Drupal.overlay.clickHandler = function (event) {
-  var self = Drupal.overlay;
+  // In some browsers the click event isn't fired for right-clicks. Use the
+  // mouseup event for right-clicks and the click event for everything else.
+  if ((event.type == 'click' && event.button == 2) || (event.type == 'mouseup' && event.button != 2)) {
+    return;
+  }
 
   var $target = $(event.target);
 
-  if (self.isOpen && $target.closest('.overlay-displace-top, .overlay-displace-bottom').length) {
+  if (this.isOpen && $target.closest('.overlay-displace-top, .overlay-displace-bottom').length) {
     // Click events in displaced regions could potentionally change the size of
     // that region (e.g. the toggle button of the toolbar module). Trigger the
     // resize event to force a recalculation of overlay's size/position.
-    $(window).triggerHandler('resize.overlay-event');
-  }
-
-  // Only continue by left-click or right-click.
-  if (!(event.button == 0 || event.button == 2)) {
-    return;
+    $(window).triggerHandler('resize.drupal-overlay');
   }
 
   // Only continue if clicked target (or one of its parents) is a link.
@@ -728,19 +412,24 @@
     return;
   }
 
-  var href = $target.attr('href');
-  // Only continue if link has an href attribute and is not just linking to
-  // an anchor.
-  if (href != undefined && href != '' && href.charAt(0) != '#') {
+  var target = $target[0];
+  var href = target.href;
+  // Only handle links that have an href attribute, uses the http(s) or the
+  // special overlay protocol and is not just linking to an anchor.
+  if (href != undefined && href != '' && target.protocol.match(/(https?|overlay)\:/) && href != window.location.href.replace(window.location.hash, target.hash)) {
+    // Using the overlay: protocol links can easily operate the overlay.
+    if (target.protocol == 'overlay:') {
+      eval('Drupal.overlay.' + target.href.replace('overlay:', '') + '()');
+    }
     // Open admin links in the overlay.
-    if (self.isAdminLink(href)) {
-      href = self.fragmentizeLink($target.get(0));
+    else if (this.isAdminLink(href)) {
+      href = this.fragmentizeLink(target);
       // Only override default behavior when left-clicking and user is not
       // pressing the ALT, CTRL, META (Command key on the Macintosh keyboard)
       // or SHIFT key.
       if (event.button == 0 && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
         // Redirect to a fragmentized href. This will trigger a hashchange event.
-        self.redirect(href);
+        this.redirect(href);
         // Prevent default action and further propagation of the event.
         return false;
       }
@@ -751,7 +440,7 @@
       }
     }
     // Open external links in a new window.
-    else if ($target.get(0).hostname != window.location.hostname) {
+    else if (target.hostname != window.location.hostname) {
       // Add a target attribute to the clicked link. This is being picked up by
       // the default action handler.
       if (!$target.attr('target')) {
@@ -761,33 +450,18 @@
     // Non-admin links should close the overlay and open in the main window.
     // Only handle them if the overlay is open and the clicked link is inside
     // the overlay iframe, else default action will do fine.
-    else if (self.isOpen) {
-      var inFrame = false;
-      // W3C: http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-UIEvent-view
-      if (event.view && event.view.frameElement != null) {
-        inFrame = true;
-      }
-      // IE: http://msdn.microsoft.com/en-us/library/ms534331%28VS.85%29.aspx
-      else if (event.target.ownerDocument.parentWindow && event.target.ownerDocument.parentWindow.frameElement != null) {
-        inFrame = true;
+    else if (this.isOpen && target.ownerDocument === this.iframeWindow.document) {
+      // When the link has a destination query parameter and that destination
+      // is an admin link we need to fragmentize it. This will make it reopen
+      // in the overlay.
+      var params = $.deparam.querystring(href);
+      if (params.destination && this.isAdminLink(params.destination)) {
+        var fragmentizedDestination = $.param.fragment(this.getPath(window.location), { overlay: params.destination });
+        $target.attr('href', $.param.querystring(href, { destination: fragmentizedDestination }));
       }
 
-      // Add a target attribute to the clicked link. This is being picked up by
-      // the default action handler.
-      if (inFrame) {
-        // When the link has a destination query parameter and that destination
-        // is an admin link we need to fragmentize it. This will make it reopen
-        // in the overlay.
-        var params = $.deparam.querystring(href);
-        if (params.destination && self.isAdminLink(params.destination)) {
-          var fragmentizedDestination = $.param.fragment(self.getPath(window.location), { overlay: params.destination });
-          href = $.param.querystring(href, { destination: fragmentizedDestination });
-          $target.attr('href', href);
-        }
-
-        // Make the link to be opening in the immediate parent of the frame.
-        $target.attr('target', '_parent');
-      }
+      // Make the link to be opening in the immediate parent of the frame.
+      $target.attr('target', '_parent');
     }
   }
 };
@@ -796,7 +470,7 @@
  * Open, reload, or close the overlay, based on the current URL fragment.
  */
 Drupal.overlay.hashchangeHandler = function (event) {
-  var self = Drupal.overlay;
+  var self = this;
 
   // If we changed the hash to reflect an internal redirect in the overlay,
   // its location has already been changed, so don't do anything.
@@ -809,35 +483,31 @@
   var state = $.bbq.getState('overlay');
   if (state) {
     // Append render variable, so the server side can choose the right
-    // rendering and add child modal frame code to the page if needed.
-    var linkURL = Drupal.settings.basePath + state;
-    linkURL = $.param.querystring(linkURL, {'render': 'overlay'});
-
-    var path = self.getPath(state);
-    self.resetActiveClass(path);
-
-    // If the modal frame is already open, replace the loaded document with
-    // this new one.
-    if (self.isOpen) {
-      self.load(linkURL);
-    }
-    else {
-      // There is not an overlay opened yet; we should open a new one.
-      var overlayOptions = {
-        url: linkURL
-      };
-      $(document).one('drupalOverlayClose', function () {
-        // Clear the overlay URL fragment.
-        $.bbq.pushState();
-        self.resetActiveClass(self.getPath(window.location));
-      });
-      self.open(overlayOptions);
-    }
+    // rendering and add child frame code to the page if needed.
+    var url = $.param.querystring(Drupal.settings.basePath + state, { render: 'overlay' });
+
+    $(document).one('drupalOverlayClose', function (event) {
+      // Clear the overlay URL fragment.
+      $.bbq.pushState();
+      self.resetActiveClass(self.getPath(window.location));
+    });
+
+    this.open(url);
+    this.resetActiveClass(this.getPath(url));
   }
   // If there is no overlay URL in the fragment and the overlay is (still)
   // open, close the overlay.
-  else if (self.isOpen && !self.isClosing) {
-    self.close();
+  else if (this.isOpen && !this.isClosing) {
+    this.close();
+  }
+};
+
+/**
+ * Focusin event handler to alter keyboard (TAB) navigation.
+ */
+Drupal.overlay.focusinHandlerNavigation = function (event) {
+  if (this.iframeWindow) {
+    $(this.iframeWindow.document).find(':tabbable:first').focus();
   }
 };
 
@@ -851,7 +521,6 @@
  *   /node/1#overlay=admin/config).
  */
 Drupal.overlay.fragmentizeLink = function (link) {
-  var self = this;
   // Don't operate on links that are already overlay-ready.
   var params = $.deparam.fragment(link.href);
   if (params.overlay) {
@@ -861,9 +530,10 @@
   // Determine the link's original destination. Set ignorePathFromQueryString to
   // true to prevent transforming this link into a clean URL while clean URLs
   // may be disabled.
-  var path = self.getPath(link, true);
-  // Preserve existing query and fragment parameters in the URL.
-  var destination = path + link.search + link.hash;
+  var path = this.getPath(link, true);
+  // Preserve existing query and fragment parameters in the URL, except for
+  // "render=overlay" which is re-added in Drupal.overlay.hashchangeHandler.
+  var destination = path + link.search.replace(/&?render=overlay/, '').replace(/\?$/, '') + link.hash;
 
   // Assemble and return the overlay-ready link.
   return $.param.fragment(window.location.href, { overlay: destination });
@@ -877,22 +547,21 @@
  * parent URL fragment will be out of date. This is a sanity check to make
  * sure we're in the right place.
  *
- * @param childLocation
- *   The child window's location object.
+ * @param overlayLocation
+ *   The overlay's location object.
  */
-Drupal.overlay.syncChildLocation = function (childLocation) {
+Drupal.overlay.syncChildLocation = function (overlayLocation) {
   var expected = $.bbq.getState('overlay');
   // This is just a sanity check, so we're comparing paths, not query strings.
-  expected = Drupal.settings.basePath + expected.replace(/\?.+/, '');
-  var actual = childLocation.pathname;
-  if (expected !== actual) {
+  if (this.getPath(Drupal.settings.basePath + expected) != this.getPath(overlayLocation)) {
     // There may have been a redirect inside the child overlay window that the
     // parent wasn't aware of. Update the parent URL fragment appropriately.
-    var newLocation = Drupal.overlay.fragmentizeLink(childLocation);
+    var newLocation = Drupal.overlay.fragmentizeLink(overlayLocation);
     // Set a 'redirect' flag on the new location so the hashchange event handler
     // knows not to change the overlay's content.
     $.data(window.location, newLocation, 'redirect');
-    window.location.href = newLocation;
+    // Use location.replace() so we don't create an extra history entry.
+    window.location.replace(newLocation);
   }
 };
 
@@ -911,6 +580,8 @@
     $.each(region_info, function (regionClass) {
       var regionName = region_info[regionClass];
       var regionSelector = '.' + regionClass;
+      // Allow special behaviors to detach.
+      Drupal.detachBehaviors($(regionSelector));
       $.get(Drupal.settings.basePath + Drupal.settings.overlay.ajaxCallback + '/' + regionName, function (newElement) {
         $(regionSelector).replaceWith($(newElement));
         Drupal.attachBehaviors($(regionSelector), Drupal.settings);
@@ -965,11 +636,11 @@
   if (path.charAt(0) != '/') {
     path = '/' + path;
   }
-  path = path.replace(new RegExp(Drupal.settings.basePath + "(?:index.php)?"), '');
+  path = path.replace(new RegExp(Drupal.settings.basePath + '(?:index.php)?'), '');
   if (path == '' && !ignorePathFromQueryString) {
     // If the path appears empty, it might mean the path is represented in the
     // query string (clean URLs are not used).
-    var match = new RegExp("([?&])q=(.+)([&#]|$)").exec(link.search);
+    var match = new RegExp('([?&])q=(.+)([&#]|$)').exec(link.search);
     if (match && match.length == 4) {
       path = match[2];
     }
@@ -981,29 +652,15 @@
 /**
  * Theme function to create the overlay iframe element.
  */
-Drupal.theme.prototype.overlayElement = function () {
-  return '<iframe id="overlay-element" frameborder="0" name="overlay-element" scrolling="no" allowtransparency="true"/>';
-};
-
-/**
- * Theme function to create a container for the overlay iframe element.
- */
 Drupal.theme.prototype.overlayContainer = function () {
-  return '<div id="overlay-container"/>';
-};
-
-/**
- * Theme function for the overlay title markup.
- */
-Drupal.theme.prototype.overlayTitleHeader = function (text) {
-  return '<h1 id="ui-dialog-title-overlay-container" class="ui-dialog-title" tabindex="-1" unselectable="on">' + text + '</h1>';
+  return '<div id="overlay-container" role="dialog"><div class="overlay-modal-background"/></div>';
 };
 
 /**
- * Theme function to create a wrapper for the jquery UI dialog.
+ * Theme function to create an overlay iframe element.
  */
-Drupal.theme.prototype.overlayWrapper = function () {
-  return '<div id="overlay-wrapper"/>';
+Drupal.theme.prototype.overlayElement = function (url) {
+  return '<iframe class="overlay-element" frameborder="0" scrolling="auto" allowtransparency="true" role="document"/>';
 };
 
 })(jQuery);
Index: misc/tableheader.js
===================================================================
RCS file: /cvs/drupal/drupal/misc/tableheader.js,v
retrieving revision 1.29
diff -u -r1.29 tableheader.js
--- misc/tableheader.js	18 Dec 2009 08:17:26 -0000	1.29
+++ misc/tableheader.js	3 May 2010 23:22:13 -0000
@@ -1,12 +1,9 @@
 // $Id: tableheader.js,v 1.29 2009/12/18 08:17:26 dries Exp $
 (function ($) {
 
-Drupal.tableHeaderDoScroll = function () {
-  if ($.isFunction(Drupal.tableHeaderOnScroll)) {
-    Drupal.tableHeaderOnScroll();
-  }
-};
-
+/**
+ * Attaches sticky table headers.
+ */
 Drupal.behaviors.tableHeader = {
   attach: function (context, settings) {
     // This breaks in anything less than IE 7. Prevent it from running.
@@ -14,105 +11,116 @@
       return;
     }
 
-    $('table.sticky-enabled thead', context).once('tableheader', function () {
-      // Clone the table header so it inherits original jQuery properties. Hide
-      // the table to avoid a flash of the header clone upon page load.
-      var headerClone = $(this).clone(true).hide().insertBefore(this.parentNode).wrap('<table class="sticky-header"></table>').parent().css({
-        position: 'fixed',
-        top: '0px'
-      });
-
-      headerClone = $(headerClone)[0];
+    $('table.sticky-enabled', context).once('tableheader', function () {
+      $(this).data("drupal-tableheader", new Drupal.tableHeader(this));
+    });
+  }
+};
 
-      // Store parent table.
-      var table = $(this).parent('table')[0];
-      headerClone.table = table;
-      // Finish initializing header positioning.
-      tracker(headerClone);
-      // 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.
-      $(headerClone).children('thead').show();
+/**
+ * Constructor for the tableHeader object. Provides sticky table headers.
+ *
+ * @param table
+ *   DOM object for the table to add a sticky header to.
+ */
+Drupal.tableHeader = function (table) {
+  var self = this;
+
+  this.delay = null;
+
+  this.originalTable = $(table);
+  this.originalHeader = $(table).children('thead');
+  this.originalHeaderCells = this.originalHeader.find('> tr > th');
+
+  // Clone the table header so it inherits original jQuery properties. Hide
+  // 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' });
+  this.stickyHeader = this.originalHeader.clone(true)
+    .hide()
+    .appendTo(this.stickyTable);
+  this.stickyHeaderCells = this.stickyHeader.find('> tr > th');
+
+  this.recalculate(true);
+
+  // 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.originalTable.addClass('sticky-table');
+
+  $(window)
+    .bind('scroll.drupal-tableheader', $.proxy(this, 'recalculate'))
+    .bind('resize.drupal-tableheader', function () {
+      // Ensure minimum time between adjustments.
+      if (self.delay) {
+        return;
+      }
+      self.delay = setTimeout(function () {
+       // Force cell width calculation.
+        self.viewHeight = 0;
+        self.recalculate(true);
 
-      $(table).addClass('sticky-table');
+        // Reset timer.
+        self.delay = null;
+      }, 250);
     });
+  $(document.documentElement).bind('scroll.drupal-tableheader', $.proxy(this, 'recalculate'));
+};
 
-    // Define the anchor holding var.
-    var prevAnchor = '';
+/**
+ * Recalculates position and visibility of the sticky table header.
+ */
+Drupal.tableHeader.prototype.recalculate = function (calculateWidth) {
+  var self = this;
+  // Reset top position of sticky table headers to the current top offset.
+  var topOffset = Drupal.displace ? Drupal.displace.getDisplacement('top') : 0;
+  this.stickyTable.css('top', topOffset + 'px');
+
+  // Save positioning data.
+  var viewHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
+  if (this.viewHeight != viewHeight) {
+    this.viewHeight = viewHeight;
+    this.vPosition = this.originalTable.offset().top - 4 - topOffset;
+    this.hPosition = this.originalTable.offset().left;
+    this.vLength = this.originalTable[0].clientHeight - 100;
+    calculateWidth = true;
+  }
 
-    // Track positioning and visibility.
-    function tracker(e) {
-      // Reset top position of sticky table headers to the current top offset.
-      var topOffset = Drupal.settings.tableHeaderOffset ? eval(Drupal.settings.tableHeaderOffset + '()') : 0;
-      $('.sticky-header').css('top', topOffset + 'px');
-      // Save positioning data.
-      var viewHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
-      if (e.viewHeight != viewHeight) {
-        e.viewHeight = viewHeight;
-        e.vPosition = $(e.table).offset().top - 4 - topOffset;
-        e.hPosition = $(e.table).offset().left;
-        e.vLength = e.table.clientHeight - 100;
-        // Resize header and its cell widths.
-        var parentCell = $('th', e.table);
-        $('th', e).each(function (index) {
-          var cellWidth = parentCell.eq(index).css('width');
-          // Exception for IE7.
-          if (cellWidth == 'auto') {
-            cellWidth = parentCell.get(index).clientWidth + 'px';
-          }
-          $(this).css('width', cellWidth);
-        });
-        $(e).css('width', $(e.table).css('width'));
-      }
+  // Track horizontal positioning relative to the viewport and set visibility.
+  var hScroll = document.documentElement.scrollLeft || document.body.scrollLeft;
+  var vOffset = (document.documentElement.scrollTop || document.body.scrollTop) - this.vPosition;
+  var visState = (vOffset > 0 && vOffset < this.vLength) ? 'visible' : 'hidden';
+  this.stickyTable.css({ left: (-hScroll + this.hPosition) + 'px', visibility: visState });
+
+  // Only perform costly calculations if the sticky header is actually visible.
+  if (visState == 'visible') {
+    if (calculateWidth) {
+      // 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'));
+    }
 
-      // Track horizontal positioning relative to the viewport and set visibility.
-      var hScroll = document.documentElement.scrollLeft || document.body.scrollLeft;
-      var vOffset = (document.documentElement.scrollTop || document.body.scrollTop) - e.vPosition;
-      var visState = (vOffset > 0 && vOffset < e.vLength) ? 'visible' : 'hidden';
-      $(e).css({ left: -hScroll + e.hPosition + 'px', visibility: visState });
-
-      // Check the previous anchor to see if we need to scroll to make room for the header.
-      // Get the height of the header table and scroll up that amount.
-      if (prevAnchor != location.hash) {
-        if (location.hash != '') {
-          var scrollLocation = $('td' + location.hash).offset().top - $(e).height();
+    // Check the previous anchor to see if we need to scroll to make room for the header.
+    // Get the height of the header table and scroll up that amount.
+    if (this.prevAnchor != location.hash) {
+      if (location.hash != '') {
+        var $anchored = this.originalTable.find(location.hash);
+        if ($anchored.length) {
+          var scrollLocation = $anchored.offset().top - this.stickyTable.height();
           $('body, html').scrollTop(scrollLocation);
         }
-        prevAnchor = location.hash;
       }
+      this.prevAnchor = location.hash;
     }
-
-    // Only attach to scrollbars once, even if Drupal.attachBehaviors is called
-    //  multiple times.
-    $('body').once(function () {
-      $(window).scroll(Drupal.tableHeaderDoScroll);
-      $(document.documentElement).scroll(Drupal.tableHeaderDoScroll);
-    });
-
-    // Track scrolling.
-    Drupal.tableHeaderOnScroll = function () {
-      $('table.sticky-header').each(function () {
-        tracker(this);
-      });
-    };
-
-    // Track resizing.
-    var time = null;
-    var resize = function () {
-      // Ensure minimum time between adjustments.
-      if (time) {
-        return;
-      }
-      time = setTimeout(function () {
-        $('table.sticky-header').each(function () {
-          // Force cell width calculation.
-          this.viewHeight = 0;
-          tracker(this);
-        });
-        // Reset timer.
-        time = null;
-      }, 250);
-    };
-    $(window).resize(resize);
   }
 };
 
Index: modules/toolbar/toolbar.tpl.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.tpl.php,v
retrieving revision 1.9
diff -u -r1.9 toolbar.tpl.php
--- modules/toolbar/toolbar.tpl.php	10 Feb 2010 10:54:12 -0000	1.9
+++ modules/toolbar/toolbar.tpl.php	3 May 2010 23:22:14 -0000
@@ -22,7 +22,7 @@
  * @see template_preprocess_toolbar()
  */
 ?>
-<div id="toolbar" class="<?php print $classes; ?> clearfix">
+<div id="toolbar" class="<?php print $classes; ?> displace-top clearfix">
   <div class="toolbar-menu clearfix">
     <?php print render($toolbar['toolbar_home']); ?>
     <?php print render($toolbar['toolbar_user']); ?>
Index: modules/toolbar/toolbar.js
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.js,v
retrieving revision 1.16
diff -u -r1.16 toolbar.js
--- modules/toolbar/toolbar.js	4 Apr 2010 20:27:08 -0000	1.16
+++ modules/toolbar/toolbar.js	3 May 2010 23:22:14 -0000
@@ -17,7 +17,7 @@
       Drupal.toolbar.toggle();
       // As the toolbar is an overlay displaced region, overlay should be
       // notified of it's height change to adapt its position.
-      $(window).triggerHandler('resize.overlay-event');
+      $(window).triggerHandler('resize');
       return false;
     });
   }
@@ -49,7 +49,6 @@
     .removeClass('toggle-active')
     .attr('title',  toggle_text)
     .html(toggle_text);
-  $('body').removeClass('toolbar-drawer').css('paddingTop', Drupal.toolbar.height());
   $.cookie(
     'Drupal.toolbar.collapsed',
     1,
@@ -71,7 +70,6 @@
     .addClass('toggle-active')
     .attr('title',  toggle_text)
     .html(toggle_text);
-  $('body').addClass('toolbar-drawer').css('paddingTop', Drupal.toolbar.height());
   $.cookie(
     'Drupal.toolbar.collapsed',
     0,
@@ -95,14 +93,4 @@
   }
 };
 
-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.37
diff -u -r1.37 toolbar.module
--- modules/toolbar/toolbar.module	29 Apr 2010 05:19:50 -0000	1.37
+++ modules/toolbar/toolbar.module	3 May 2010 23:22:14 -0000
@@ -151,6 +151,16 @@
 }
 
 /**
+ * Preprocess template variables for toolbar.tpl.php.
+ *
+ * Adding the 'overlay-displace-top' class to the toolbar pushes the overlay
+ * down, so it appears below the toolbar.
+ */
+function toolbar_preprocess_toolbar(&$variables) {
+  $variables['classes_array'][] = "overlay-displace-top";
+}
+
+/**
  * Implements hook_system_info_alter().
  *
  * Indicate that the 'page_top' region (in which the toolbar will be displayed)
@@ -177,12 +187,9 @@
     '#theme' => 'toolbar',
     '#attached'=> array(
       'js' => array(
-        $module_path . '/toolbar.js',
+        '/misc/displace.js',
         array('data' => 'misc/jquery.cookie.js', 'weight' => JS_LIBRARY + 2),
-        array(
-          'data' => array('tableHeaderOffset' => 'Drupal.toolbar.height'),
-          'type' => 'setting'
-        ),
+        $module_path . '/toolbar.js',
       ),
       'css' => array(
         $module_path . '/toolbar.css',
Index: modules/toolbar/toolbar.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.css,v
retrieving revision 1.20
diff -u -r1.20 toolbar.css
--- modules/toolbar/toolbar.css	4 Apr 2010 17:11:20 -0000	1.20
+++ modules/toolbar/toolbar.css	3 May 2010 23:22:14 -0000
@@ -1,12 +1,6 @@
 /* $Id: toolbar.css,v 1.20 2010/04/04 17:11:20 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
@@ -32,10 +26,8 @@
   font: normal 0.9em "Lucida Grande", Verdana, sans-serif;
   background: #666;
   color: #ccc;
-  position: fixed;
-  top: 0;
-  left: 0;
-  right: 0;
+}
+html.js #toolbar {
   margin: 0 -20px;
   padding: 0 20px;
   z-index: 600;
@@ -134,13 +126,9 @@
 }
 
 /**
- * IE 6 Fix.
- *
- * IE 6 shows elements with position:fixed as position:static so we replace
- * it with position:absolute; toolbar needs it's z-index to stay above overlay.
+ * IE6 fix.
  */
-* html #toolbar {
-  position: absolute;
+* html.js #toolbar {
   margin: 0;
   padding-right: 0;
   left: -20px;
Index: modules/system/system.css
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.css,v
retrieving revision 1.75
diff -u -r1.75 system.css
--- modules/system/system.css	28 Apr 2010 20:08:39 -0000	1.75
+++ modules/system/system.css	3 May 2010 23:22:14 -0000
@@ -255,6 +255,29 @@
 }
 
 /*
+** To be used with displace.js
+*/
+.displace-top,
+.displace-bottom {
+  position: relative;
+  width: 100%;
+}
+html.js .displace-top,
+html.js .displace-bottom {
+  position: fixed;
+  width: auto;
+  left: 0;
+  right: 0;
+}
+/**
+ * IE6 shows elements with position:fixed as position:static so replace
+ * it with position:absolute.
+ */
+* html.js .displace-top {
+  position: absolute;
+}
+
+/*
 ** Floating header for tableheader.js
 */
 table.sticky-header {
Index: modules/overlay/overlay.tpl.php
===================================================================
RCS file: modules/overlay/overlay.tpl.php
diff -N modules/overlay/overlay.tpl.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/overlay/overlay.tpl.php	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,37 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Default theme implementation to display a page in the overlay.
+ *
+ * Available variables:
+ * - $title: the (sanitized) title of the node.
+ * - $page: The rendered page content.
+ * - $classes: String of classes that can be used to style contextually through
+ *   CSS.
+ *
+ * Helper variables:
+ * - $classes_array: Array of html class attribute values. It is flattened
+ *   into a string within the variable $classes.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_overlay()
+ * @see template_process()
+ */
+?>
+
+<div id="overlay" class="<?php print $classes; ?>"<?php print $attributes; ?>>
+  <div id="overlay-titlebar">
+    <div id="overlay-title-wrapper">
+      <h1 id="overlay-title"<?php print $title_attributes; ?>><?php print $title; ?></h1>
+    </div>
+    <div id="overlay-close-wrapper">
+      <a id="overlay-close" href="overlay:close"><span><?php t('Close'); ?></span></a>
+    </div>
+    <?php if ($tabs): ?><ul id="overlay-tabs"><?php print render($tabs); ?></ul><?php endif; ?>
+  </div>
+  <div id="overlay-content"<?php print $content_attributes; ?>>
+    <?php print $page; ?>
+  </div>
+</div>
Index: misc/displace.js
===================================================================
RCS file: misc/displace.js
diff -N misc/displace.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ misc/displace.js	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,92 @@
+// $Id$
+(function ($) {
+
+/**
+ * Attaches the displace behavior.
+ */
+Drupal.behaviors.displace = {
+  attach: function (context, settings) {
+    Drupal.displace.cacheDisplacedElements();
+
+    if (this.processed) {
+      return;
+    }
+    this.processed = true;
+
+    $(window)
+      .bind("resize.drupal-displace", $.proxy(Drupal.displace, "resizeHandlerRefresh"))
+      .triggerHandler("resize.drupal-displace");
+  }
+};
+
+/**
+ * The displace object.
+ */
+Drupal.displace = {
+  /**
+   * CSS property being changed on the body element on refreshing of a region.
+   */
+  bodyCSSProperty: {
+    "top": "paddingTop",
+    "bottom": "paddingBottom"
+  },
+
+  /**
+   * Cache of jQuery objects containing displaced elements per region.
+   */
+  elements: [],
+  
+  /**
+   * Total displacement per region in pixels.
+   */
+  displacement: []
+};
+
+/**
+ * Caches jQuery objects containing displaced elements per region.
+ */
+Drupal.displace.cacheDisplacedElements = function () {
+  this.elements["top"] = $(".displace-top");
+  this.elements["bottom"] = $(".displace-bottom");
+};
+
+/**
+ * Resize event handler: refresh position of displaced elements. 
+ */
+Drupal.displace.resizeHandlerRefresh = function (event) {
+  this.refresh("top");
+  this.refresh("bottom");
+};
+
+/**
+ * Refreshes position of displaced elements. 
+ */
+Drupal.displace.refresh = function (region) {
+  if (this.elements[region].length) {
+    var offset = 0;
+    var height = 0;
+    this.elements[region].each(function () {
+      offset = offset + height;
+      height = $(this).css(region, offset).outerHeight();
+      
+      // In IE, Shadow filter adds some extra height, so we need to remove it from
+      // the returned height.
+      if (this.filters && this.filters.item("DXImageTransform.Microsoft.Shadow")) {
+        height -= this.filters.item("DXImageTransform.Microsoft.Shadow").strength;
+      }
+    });
+
+    // Use offset of latest displaced element as the total displacement.
+    this.displacement[region] = offset + height;
+    $(document.body).css(this.bodyCSSProperty[region], this.displacement[region]);
+  }
+};
+
+/**
+ * Returns the total displacement of given region. 
+ */
+Drupal.displace.getDisplacement = function (region) {
+  return this.displacement[region] || 0;
+};
+
+})(jQuery);
Index: modules/overlay/overlay-child.css
===================================================================
RCS file: modules/overlay/overlay-child.css
diff -N modules/overlay/overlay-child.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/overlay/overlay-child.css	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,135 @@
+
+html.js {
+  background: transparent !important;
+  overflow-y: scroll;
+}
+html.js body {
+  background: transparent !important;
+  padding: 20px 0;
+}
+
+#overlay {
+  position: relative;
+  padding: .2em;
+  padding-right: 26px;
+  margin: 0 auto;
+  width: 78%;
+  min-width: 700px;
+  min-height: 100px;
+}
+#overlay-titlebar {
+  position: relative;
+  z-index: 100;
+  white-space: nowrap;
+  padding: 0 20px;
+}
+#overlay-content {
+  clear: both;
+  position: relative;
+  padding: .5em 1em;
+  color: #000;
+  background: #fff;
+}
+
+#overlay-title-wrapper {
+  overflow: hidden;
+}
+#overlay-title {
+  float: left;
+  font-family: Verdana,sans-serif;
+  margin: 0;
+  padding: 0.3em 0;
+  color: #fff;
+  font-size: 20px;
+}
+#overlay-title:active,
+#overlay-title:focus {
+  outline: 0;
+}
+
+#overlay-close-wrapper {
+  position: absolute;
+  right: 0;
+}
+#overlay-close,
+#overlay-close:hover {
+  display: block;
+  position: fixed;
+  margin: 0;
+  padding: 0;
+  border: none;
+  width: 26px;
+  height: 26px;
+  background: transparent url(images/close.png) no-repeat;
+  border-top-left-radius: 0;
+  -moz-border-radius-topleft: 0;
+  -webkit-border-top-left-radius: 0;
+}
+#overlay-title:active,
+#overlay-close:hover,
+#overlay-close:focus {
+  padding: 0;
+  /*outline: 0;*/
+}
+#overlay-close span {
+  display: none;
+}
+
+/**
+ * Tabs on the overlay.
+ */
+#overlay-tabs {
+  position: absolute;
+  right: 20px;
+  margin: -27px 0 0 0;
+  line-height: 27px;
+  text-transform: uppercase;
+}
+#overlay-tabs li {
+  display: inline;
+  list-style: none;
+  margin: 0 0 0 -3px;
+  padding: 0;
+}
+
+#overlay-tabs li a,
+#overlay-tabs li a:active,
+#overlay-tabs li a:visited,
+#overlay-tabs li a:hover {
+  display: inline-block;
+  background-color: #a6a7a2;
+  -moz-border-radius: 8px 8px 0 0;
+  -webkit-border-top-left-radius: 8px;
+  -webkit-border-top-right-radius: 8px;
+  border-radius: 8px 8px 0 0;
+  color: #000;
+  font-weight: bold;
+  padding: 0 14px;
+  text-decoration: none;
+  font-size: 11px;
+  margin: 0 0 2px 0;
+  outline: 0;
+}
+#overlay-tabs li.active a,
+#overlay-tabs li.active a.active,
+#overlay-tabs li.active a:active,
+#overlay-tabs li.active a:visited {
+  background-color: #fff;
+  padding-bottom: 2px;
+  margin: 0;
+}
+#overlay-tabs li a:focus,
+#overlay-tabs li a:hover {
+  color: #fff;
+}
+#overlay-tabs li.active a:focus,
+#overlay-tabs li.active a:hover {
+  color: #000;
+}
+
+/**
+ * Add to shortcuts link
+ */
+#overlay-titlebar .add-or-remove-shortcuts {
+  padding-top: 0.9em;
+}
