Handle mousewheel events properly in modals, different tabs, and compose box

Fixes #109.

(imported from commit ebcc90deeba712296998bfaa2df46ec6be305219)
This commit is contained in:
Keegan McAllister
2012-11-30 12:28:23 -05:00
parent 11487a0fd8
commit 45e515cc20
2 changed files with 44 additions and 9 deletions

View File

@@ -24,15 +24,10 @@ function process_hotkey(e) {
var code = e.which; var code = e.which;
var next_message; var next_message;
// Disable hotkeys on settings page etc. // Disable hotkeys on settings page etc., and when a modal pop-up
if (!$('#home').hasClass('active')) { // is visible.
if (!ui.home_tab_active())
return false; return false;
}
// Disable hotkeys when a modal pop-up is visible.
if ($('.modal:visible').length > 0) {
return false;
}
// Process hotkeys specially when in an input, textarea, or send button // Process hotkeys specially when in an input, textarea, or send button
if ($('input:focus,textarea:focus,#compose-send-button:focus').length > 0) { if ($('input:focus,textarea:focus,#compose-send-button:focus').length > 0) {

View File

@@ -2,6 +2,11 @@ var ui = (function () {
var exports = {}; var exports = {};
// Is the home tab visible, and not covered by a modal?
exports.home_tab_active = function () {
return $('#home').hasClass('active') && ($('.modal:visible').length === 0);
};
// We want to remember how far we were scrolled on each 'tab'. // We want to remember how far we were scrolled on each 'tab'.
// To do so, we need to save away the old position of the // To do so, we need to save away the old position of the
// scrollbar when we switch to a new tab (and restore it // scrollbar when we switch to a new tab (and restore it
@@ -395,11 +400,46 @@ $(function () {
// page, the pointer may still need to move. // page, the pointer may still need to move.
move_pointer_at_page_top_and_bottom(delta); move_pointer_at_page_top_and_bottom(delta);
}); });
$(window).mousewheel(throttled_mousewheelhandler);
$(window).mousewheel(function (e, delta) {
// Ignore mousewheel events if a modal is visible. It's weird if the
// user can scroll the main view by wheeling over the greyed-out area.
// Similarly, ignore events on settings page etc.
//
// The modal itself has a handler invoked before this one (see below).
//
// We don't handle the compose box here, because it *should* work to
// select the compose box and then wheel over the message stream.
if (exports.home_tab_active()) {
throttled_mousewheelhandler(e, delta);
} else {
e.preventDefault();
}
});
var throttled_resizehandler = $.throttle(50, resizehandler); var throttled_resizehandler = $.throttle(50, resizehandler);
$(window).resize(throttled_resizehandler); $(window).resize(throttled_resizehandler);
// Scrolling in modals and input boxes should not scroll the main view.
// Stop propagation in all cases. Also, ignore the event if the element
// is already at the top or bottom. Otherwise we get a new scroll event
// on the parent (?).
$('.modal-body, input, textarea').mousewheel(function (e, delta) {
var self = $(this);
var scroll = self.scrollTop();
e.stopPropagation();
if ( ((delta > 0) && (scroll <= 0))
|| ((delta < 0) && (scroll >= (this.scrollHeight - self.innerHeight())))) {
e.preventDefault();
}
});
// Ignore wheel events in the compose area which weren't already handled above.
$('#compose').mousewheel(function (e) {
e.stopPropagation();
e.preventDefault();
});
function clear_password_change() { function clear_password_change() {
// Clear the password boxes so that passwords don't linger in the DOM // Clear the password boxes so that passwords don't linger in the DOM
// for an XSS attacker to find. // for an XSS attacker to find.