#668640 by casey, aspilicious, et al: Re-implement Overlay without jQuery UI Dialog; massive performance improvement, helps address several critical issues.

merge-requests/26/head
Angie Byron 2010-06-08 05:16:29 +00:00
parent b5e696702d
commit 8e8d8274d6
10 changed files with 832 additions and 873 deletions

View File

@ -7,7 +7,7 @@
Drupal.behaviors.dashboard = {
attach: function (context, settings) {
$('#dashboard', context).once(function () {
$(this).prepend('<div class="customize"><ul class="action-links"><li><a href="#">' + Drupal.t('Customize dashboard') + '</a></li></ul><div class="canvas"></div></div>');
$(this).prepend('<div class="customize clearfix"><ul class="action-links"><li><a href="#">' + Drupal.t('Customize dashboard') + '</a></li></ul><div class="canvas"></div></div>');
$('.customize .action-links a', this).click(Drupal.behaviors.dashboard.enterCustomizeMode);
});
Drupal.behaviors.dashboard.addPlaceholders();

View File

@ -0,0 +1,142 @@
html.js {
background: transparent !important;
overflow-y: scroll;
}
html.js body {
background: transparent !important;
padding: 20px 0;
}
#overlay {
margin: 0 auto;
min-height: 100px;
min-width: 700px;
position: relative;
padding: .2em;
padding-right: 26px;
width: 78%;
}
#overlay-titlebar {
padding: 0 20px;
position: relative;
white-space: nowrap;
z-index: 100;
}
#overlay-content {
background: #fff;
clear: both;
color: #000;
padding: .5em 1em;
position: relative;
}
#overlay-title-wrapper {
overflow: hidden;
}
#overlay-title {
color: #fff;
float: left;
font-family: Verdana,sans-serif;
font-size: 20px;
margin: 0;
padding: 0.3em 0;
}
#overlay-title:active,
#overlay-title:focus {
outline: 0;
}
#overlay-close-wrapper {
position: absolute;
right: 0;
}
#overlay-close,
#overlay-close:hover {
background: transparent url(images/close.png) no-repeat;
-moz-border-radius-topleft: 0;
-webkit-border-top-left-radius: 0;
border-top-left-radius: 0;
display: block;
height: 26px;
margin: 0;
padding: 0;
/* Replace with position:fixed to get a scrolling close button. */
position: absolute;
width: 26px;
}
#overlay-title:active,
#overlay-close:hover,
#overlay-close:focus {
padding: 0;
}
#overlay-close span {
display: none;
}
/**
* Tabs on the overlay.
*/
#overlay-tabs {
line-height: 27px;
margin: -27px 0 0 0;
position: absolute;
right: 20px;
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 {
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;
display: inline-block;
font-size: 11px;
font-weight: bold;
margin: 0 0 2px 0;
outline: 0;
padding: 0 14px;
text-decoration: none;
}
#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;
margin: 0;
padding-bottom: 2px;
}
#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;
}
/**
* IE6 shows elements with position:fixed as position:static so replace
* it with position:absolute;
*/
* html #overlay-close,
* html #overlay-close:hover {
position: absolute;
}

View File

@ -2,31 +2,24 @@
(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) {
window.location = window.location.href.replace(/([?&]?)render=overlay&?/g, '$1').replace(/\?$/, '');
}
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) {
@ -34,12 +27,11 @@ Drupal.behaviors.overlayChild = {
// Use setTimeout to close the child window from a separate thread,
// because the current one is busy processing Drupal behaviors.
setTimeout(function () {
// We need to store the parent variable locally because it will
// disappear as soon as we close the iframe.
var p = parent;
p.Drupal.overlay.close();
if (typeof settings.redirect == 'string') {
p.Drupal.overlay.redirect(settings.redirect);
parent.Drupal.overlay.redirect(settings.redirect);
}
else {
parent.Drupal.overlay.close();
}
}, 1);
return;
@ -54,11 +46,23 @@ Drupal.behaviors.overlayChild = {
// 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(window.scrollX, window.scrollY);
// 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.
*/
@ -68,16 +72,6 @@ Drupal.overlayChild.attachBehaviors = function (context, settings) {
});
};
/**
* 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.
*
@ -86,7 +80,7 @@ Drupal.overlayChild.behaviors.scrollToTop = function (context, settings) {
* 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 mouseup.drupal-overlay', $.proxy(parent.Drupal.overlay, 'eventhandlerOverrideLink'));
};
/**
@ -111,4 +105,70 @@ Drupal.overlayChild.behaviors.parseForms = function (context, settings) {
});
};
/**
* Replace the overlay title with a message while loading another page.
*/
Drupal.overlayChild.behaviors.loading = function (context, settings) {
var $title;
var text = Drupal.t('Loading');
var dots = '';
$(document).bind('drupalOverlayBeforeLoad.drupal-overlay.drupal-overlay-child-loading', function () {
$title = $('#overlay-title').text(text);
var id = setInterval(function () {
dots = (dots.length > 10) ? '' : dots + '.';
$title.text(text + dots);
}, 500);
});
};
/**
* 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');
}
$(document).bind('drupalOverlayBeforeLoad.drupal-overlay.drupal-overlay-child-loading', function () {
$('#overlay-titlebar').find('.add-or-remove-shortcuts').remove();
});
};
/**
* Use displacement from parent window.
*/
Drupal.overlayChild.behaviors.alterTableHeaderOffset = function (context, settings) {
if (Drupal.settings.tableHeaderOffset) {
Drupal.overlayChild.prevTableHeaderOffset = Drupal.settings.tableHeaderOffset;
}
Drupal.settings.tableHeaderOffset = 'Drupal.overlayChild.tableHeaderOffset';
};
/**
* 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'));
};
})(jQuery);

View File

@ -1,165 +1,48 @@
/* $Id$ */
/**
* ui-dialog overlay.
*/
.ui-widget-overlay {
opacity: 1;
filter: none;
html.overlay-open,
html.overlay-open body {
height: 100%;
overflow: hidden;
}
#overlay-container,
.overlay-modal-background,
.overlay-element {
height: 100%;
left: 0;
position: fixed;
top: 0;
width: 100%;
z-index: 500;
}
.overlay-modal-background {
/* Using a transparent png renders faster than using opacity */
background: transparent url(images/background.png) repeat;
}
body.overlay-autofit {
overflow-y: scroll;
}
/**
* Overlay wrapper.
*/
#overlay-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
.overlay-element {
background: transparent;
left: -200%;
z-index: 501;
padding: 20px 0 15px 0;
}
.overlay-element.overlay-active {
left: 0;
}
html.overlay-open .displace-top,
html.overlay-open .displace-bottom {
z-index: 600;
}
/**
* jQuery UI Dialog classes.
* IE6 shows elements with position:fixed as position:static so replace
* it with position:absolute;
*/
.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%;
}
/**
* Tabs on the overlay.
*/
.overlay .ui-dialog-titlebar ul {
* html #overlay-container,
* html .overlay-modal-background,
* html .overlay-element
{
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 .ui-dialog-titlebar ul li.active a:hover {
color: #000;
}
/**
* Add to shortcuts link
*/
.overlay div.add-or-remove-shortcuts {
padding-top: 0.9em;
}
/**
* IE 6 Fix.
*
* Use filter to support transparency in IE6 for the overlay background.
*/
* html .ui-widget-overlay {
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='modules/overlay/images/background.png', sizingMethod='scale');
background: none;
}

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,18 @@ function overlay_permission() {
);
}
/**
* Implements hook_theme().
*/
function overlay_theme() {
return array(
'overlay' => array(
'render element' => 'page',
'template' => 'overlay',
),
);
}
/**
* Implements hook_init().
*
@ -150,8 +162,7 @@ function overlay_library() {
$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 @@ function overlay_library() {
'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 @@ function overlay_page_alter(&$page) {
$page[$skipped_region]['#access'] = FALSE;
}
}
if (overlay_get_mode() == 'child') {
// Add the overlay wrapper before the html wrapper.
array_unshift($page['#theme_wrappers'], 'overlay');
}
}
/**
@ -255,7 +271,7 @@ function overlay_system_info_alter(&$info, $file, $type) {
}
/**
* Preprocess template variables for html.tpl.php.
* Implements hook_preprocess_html().
*
* If the current page request is inside the overlay, add appropriate classes
* to the <body> element, and simplify the page title.
@ -272,7 +288,7 @@ function overlay_preprocess_html(&$variables) {
}
/**
* Preprocess template variables for maintenance-page.tpl.php.
* Implements hook_preprocess_maintenance_page().
*
* If the current page request is inside the overlay, add appropriate classes
* to the <body> element, and simplify the page title.
@ -284,7 +300,30 @@ function overlay_preprocess_maintenance_page(&$variables) {
}
/**
* Preprocess template variables for page.tpl.php.
* Preprocesses template variables for overlay.tpl.php
*
* @see overlay.tpl.php
*/
function template_preprocess_overlay(&$variables) {
$variables['tabs'] = menu_primary_local_tasks();
$variables['title'] = drupal_get_title();
$variables['content_attributes_array']['class'][] = 'clearfix';
}
/**
* Processes variables for overlay.tpl.php
*
* @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'];
}
/**
* Implements hook_preprocess_page().
*
* Display breadcrumbs correctly inside the overlay.
*
@ -296,17 +335,10 @@ function overlay_preprocess_page(&$variables) {
$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 +509,6 @@ function overlay_set_mode($mode = NULL) {
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');

View File

@ -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.
* - $tabs (array): Tabs linking to any sub-pages beneath the current page
* (e.g., the view and edit tabs when displaying a node).
*
* 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" <?php print $attributes; ?>>
<div id="overlay-titlebar" class="clearfix">
<div id="overlay-title-wrapper" class="clearfix">
<h1 id="overlay-title"<?php print $title_attributes; ?>><?php print $title; ?></h1>
</div>
<div id="overlay-close-wrapper">
<a id="overlay-close" href="#" class="overlay-close"><span><?php t('Close overlay'); ?></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>

View File

@ -15,9 +15,8 @@ Drupal.behaviors.toolbar = {
// Toggling toolbar drawer.
$('#toolbar a.toggle', context).once('toolbar-toggle').click(function(e) {
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');
// Allow resize event handlers to recalculate sizes/positions.
$(window).triggerHandler('resize');
return false;
});
}

View File

@ -150,6 +150,16 @@ function toolbar_preprocess_html(&$vars) {
}
}
/**
* Implements hook_preprocess_toolbar().
*
* 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().
*

View File

@ -629,16 +629,32 @@ div#branding strong {
margin-bottom: 2em;
}
/* Don't display any header elements when within the overlay, and adjust the
page height accordingly. */
body.overlay #header * {
/**
* Overlay
*/
#overlay #overlay-tabs li a {
background: #d9eaf5;
color: #000;
}
#overlay #overlay-tabs li a:hover,
#overlay #overlay-tabs li a:focus {
background: #fff;
}
#overlay #overlay-tabs li.active a {
background: url("images/body.png") repeat-x scroll 50% -58px #edf5fa;
color: #fff;
}
#overlay-content {
padding: 1px;
}
#overlay-content #header {
display: none;
}
body.overlay {
margin-top: -80px;
#overlay-content #wrapper {
background-position: 50% -80px;
}
/**
* Primary navigation
*/