- Patch #787940 by casey: generic approach for position:fixed elements like toolbar.
parent
d0ddd91f28
commit
fa50f04ee4
|
@ -0,0 +1,122 @@
|
|||
// $Id$
|
||||
(function ($) {
|
||||
|
||||
/**
|
||||
* Provides a generic method to position elements fixed to the viewport.
|
||||
*
|
||||
* Fixed positioning (CSS declaration position:fixed) is done relatively to the
|
||||
* viewport. This makes it hard to position multiple fixed positioned element
|
||||
* relative to each other (e.g. multiple toolbars should come after each other,
|
||||
* not on top of each other).
|
||||
*
|
||||
* To position an element fixed at the top of the viewport add the class
|
||||
* "displace-top" to that element, and to position it to the bottom of the view-
|
||||
* port add the class "displace-bottom".
|
||||
*
|
||||
* When a browser doesn't support position:fixed (like IE6) the element gets
|
||||
* positioned absolutely by default, but this can be overriden by using the
|
||||
* "displace-unsupported" class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Attaches the displace behavior.
|
||||
*/
|
||||
Drupal.behaviors.displace = {
|
||||
attach: function (context, settings) {
|
||||
// Test for position:fixed support as IE6 does not.
|
||||
// http://yura.thinkweb2.com/cft/#IS_POSITION_FIXED_SUPPORTED
|
||||
if (this.supported === undefined) {
|
||||
var el = $('<div style="position:fixed;top:10px"/>').appendTo(document.body);
|
||||
this.supported = el[0].offsetTop === 10;
|
||||
el.remove();
|
||||
|
||||
if (!this.supported) {
|
||||
$(document.documentElement).addClass('displace-unsupported');
|
||||
}
|
||||
}
|
||||
|
||||
$(document.body).once('displace', function () {
|
||||
$(window).bind('resize.drupal-displace', function () {
|
||||
Drupal.displace.clearCache();
|
||||
|
||||
$(document.body).css({
|
||||
paddingTop: Drupal.displace.getDisplacement('top'),
|
||||
paddingBottom: Drupal.displace.getDisplacement('bottom')
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Drupal.displace.clearCache(true);
|
||||
$(window).triggerHandler('resize');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The displace object.
|
||||
*/
|
||||
Drupal.displace = Drupal.displace || {};
|
||||
|
||||
Drupal.displace.elements = [];
|
||||
Drupal.displace.displacement = [];
|
||||
|
||||
/**
|
||||
* Get all displaced elements of given region.
|
||||
*
|
||||
* @param region
|
||||
* Region name. Either "top" or "bottom".
|
||||
*
|
||||
* @return
|
||||
* jQuery object containing all displaced elements of given region.
|
||||
*/
|
||||
Drupal.displace.getDisplacedElements = function (region) {
|
||||
if (!this.elements[region]) {
|
||||
this.elements[region] = $('.displace-' + region);
|
||||
}
|
||||
return this.elements[region];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the total displacement of given region.
|
||||
*
|
||||
* @param region
|
||||
* Region name. Either "top" or "bottom".
|
||||
*
|
||||
* @return
|
||||
* The total displacement of given region in pixels.
|
||||
*/
|
||||
Drupal.displace.getDisplacement = function (region) {
|
||||
if (!this.displacement[region]) {
|
||||
var offset = 0;
|
||||
var height = 0;
|
||||
this.getDisplacedElements(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.length && 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;
|
||||
}
|
||||
|
||||
return this.displacement[region];
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear cache.
|
||||
*
|
||||
* @param selectorCache
|
||||
* Boolean whether to also clear the selector cache.
|
||||
*/
|
||||
Drupal.displace.clearCache = function (selectorCache) {
|
||||
if (selectorCache) {
|
||||
this.elements = [];
|
||||
}
|
||||
this.displacement = [];
|
||||
};
|
||||
|
||||
})(jQuery);
|
|
@ -42,7 +42,7 @@ Drupal.behaviors.tableHeader = {
|
|||
// 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;
|
||||
var topOffset = Drupal.displace ? Drupal.displace.getDisplacement('top') : 0;
|
||||
$('.sticky-header').css('top', topOffset + 'px');
|
||||
// Save positioning data.
|
||||
var viewHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
|
||||
|
|
|
@ -650,15 +650,9 @@ Drupal.overlay.outerResize = function () {
|
|||
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();
|
||||
});
|
||||
var displaceTop = Drupal.displace ? Drupal.displace.getDisplacement('top') : 0;
|
||||
|
||||
self.$wrapper.css('top', displaceTopHeight);
|
||||
self.$wrapper.css('top', displaceTop);
|
||||
|
||||
// When the overlay has no height yet, make it fit exactly in the window,
|
||||
// or the configured height when autoFit is disabled.
|
||||
|
@ -666,7 +660,7 @@ Drupal.overlay.outerResize = function () {
|
|||
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);
|
||||
self.lastHeight = parseInt($(window).height() - displaceTop - titleBarHeight - 45);
|
||||
}
|
||||
else {
|
||||
self.lastHeight = self.options.height;
|
||||
|
@ -703,11 +697,11 @@ Drupal.overlay.clickHandler = function (event) {
|
|||
|
||||
var $target = $(event.target);
|
||||
|
||||
if (self.isOpen && $target.closest('.overlay-displace-top, .overlay-displace-bottom').length) {
|
||||
if (self.isOpen && $target.closest('.displace-top, .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');
|
||||
$(window).triggerHandler('resize');
|
||||
}
|
||||
|
||||
// Only continue by left-click or right-click.
|
||||
|
@ -929,7 +923,7 @@ Drupal.overlay.resetActiveClass = function(activePath) {
|
|||
var self = this;
|
||||
var windowDomain = window.location.protocol + window.location.hostname;
|
||||
|
||||
$('.overlay-displace-top, .overlay-displace-bottom')
|
||||
$('.displace-top, .displace-bottom')
|
||||
.find('a[href]')
|
||||
// Remove active class from all links in displaced regions.
|
||||
.removeClass('active')
|
||||
|
|
|
@ -299,16 +299,6 @@ function overlay_preprocess_page(&$variables) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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";
|
||||
}
|
||||
|
||||
/**
|
||||
* Form after_build callback.
|
||||
*
|
||||
|
|
|
@ -254,6 +254,26 @@ tr.selected td {
|
|||
background: #ffc;
|
||||
}
|
||||
|
||||
/*
|
||||
** To be used with displace.js
|
||||
*/
|
||||
.displace-top,
|
||||
.displace-bottom {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
.displace-processed .displace-top,
|
||||
.displace-processed .displace-bottom {
|
||||
position: fixed;
|
||||
width: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
.displace-unsupported .displace-top,
|
||||
.displace-unsupported .displace-bottom {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/*
|
||||
** Floating header for tableheader.js
|
||||
*/
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* $Id$ */
|
||||
|
||||
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 @@ body.toolbar-drawer {
|
|||
font: normal 0.9em "Lucida Grande", Verdana, sans-serif;
|
||||
background: #666;
|
||||
color: #ccc;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
.displace-processed #toolbar {
|
||||
margin: 0 -20px;
|
||||
padding: 0 20px;
|
||||
z-index: 600;
|
||||
|
@ -45,6 +37,14 @@ body.toolbar-drawer {
|
|||
filter: progid:DXImageTransform.Microsoft.Shadow(color=#000000, direction='180', strength='10');
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Shadow(color=#000000, direction='180', strength='10')";
|
||||
}
|
||||
.displace-unsupported #toolbar {
|
||||
margin: 0;
|
||||
padding-right: 0;
|
||||
left: -20px;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
#toolbar div.collapsed {
|
||||
display: none;
|
||||
|
@ -132,18 +132,3 @@ body.toolbar-drawer {
|
|||
position: relative;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
* html #toolbar {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
padding-right: 0;
|
||||
left: -20px;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
@ -49,7 +48,6 @@ Drupal.toolbar.collapse = function() {
|
|||
.removeClass('toggle-active')
|
||||
.attr('title', toggle_text)
|
||||
.html(toggle_text);
|
||||
$('body').removeClass('toolbar-drawer').css('paddingTop', Drupal.toolbar.height());
|
||||
$.cookie(
|
||||
'Drupal.toolbar.collapsed',
|
||||
1,
|
||||
|
@ -71,7 +69,6 @@ Drupal.toolbar.expand = function() {
|
|||
.addClass('toggle-active')
|
||||
.attr('title', toggle_text)
|
||||
.html(toggle_text);
|
||||
$('body').addClass('toolbar-drawer').css('paddingTop', Drupal.toolbar.height());
|
||||
$.cookie(
|
||||
'Drupal.toolbar.collapsed',
|
||||
0,
|
||||
|
@ -95,14 +92,4 @@ Drupal.toolbar.toggle = function() {
|
|||
}
|
||||
};
|
||||
|
||||
Drupal.toolbar.height = function() {
|
||||
var height = $('#toolbar').outerHeight();
|
||||
// In IE, Shadow filter adds some extra height, so we need to remove it from
|
||||
// the returned height.
|
||||
if ($('#toolbar').css('filter').match(/DXImageTransform\.Microsoft\.Shadow/)) {
|
||||
height -= $('#toolbar').get(0).filters.item("DXImageTransform.Microsoft.Shadow").strength;
|
||||
}
|
||||
return height;
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
|
|
|
@ -177,12 +177,9 @@ function toolbar_view() {
|
|||
'#theme' => 'toolbar',
|
||||
'#attached'=> array(
|
||||
'js' => array(
|
||||
$module_path . '/toolbar.js',
|
||||
array('data' => 'misc/displace.js', 'weight' => JS_LIBRARY - 1),
|
||||
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',
|
||||
|
|
|
@ -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']); ?>
|
||||
|
|
Loading…
Reference in New Issue