You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
doushio/client/scroll.js

143 lines
3.2 KiB

var lockTarget, lockKeyHeight;
var $lockTarget, $lockIndicator;
var lockedManually;
var dropAndLockTimer;
var nestLevel = 0;
function with_dom(func) {
var lockHeight, locked = lockTarget, $post;
if (locked == PAGE_BOTTOM)
lockHeight = $DOC.height();
else if (locked) {
$post = $('#' + locked);
var r = $post.length && $post[0].getBoundingClientRect();
if (r && r.bottom > 0 && r.top < window.innerHeight)
lockHeight = r.top;
else
locked = false;
}
var ret;
try {
nestLevel++;
ret = func.call(this);
}
finally {
if (!--nestLevel)
Backbone.trigger('flushDomUpdates');
}
if (locked == PAGE_BOTTOM) {
var height = $DOC.height();
if (height > lockHeight - 10)
window.scrollBy(0, height - lockHeight + 10);
}
else if (locked && lockTarget == locked) {
var newY = $post[0].getBoundingClientRect().top;
window.scrollBy(0, newY - lockHeight);
}
return ret;
}
function set_lock_target(num, manually) {
lockedManually = manually;
if (!num && at_bottom())
num = PAGE_BOTTOM;
if (num == lockTarget)
return;
lockTarget = num;
var bottom = lockTarget == PAGE_BOTTOM;
if ($lockTarget)
$lockTarget.removeClass('scroll-lock');
if (num && !bottom && manually)
$lockTarget = $('#' + num).addClass('scroll-lock');
else
$lockTarget = null;
var $ind = $lockIndicator;
if ($ind) {
var visible = bottom || manually;
$ind.css({visibility: visible ? 'visible' : 'hidden'});
if (bottom)
$ind.text('Locked to bottom');
else if (num) {
$ind.empty().append($('<a/>', {
text: '>>' + num,
href: '#' + num,
}));
}
}
}
oneeSama.hook('menuOptions', function (info) {
var opts = info.options;
if (lockTarget && info.model && lockTarget == info.model.id)
opts.splice(opts.indexOf('Focus'), 1, 'Unfocus');
});
Backbone.on('hide', function (model) {
if (model && model.id == lockTarget)
set_lock_target(null);
});
connSM.on('dropped', function () {
if (!dropAndLockTimer)
dropAndLockTimer = setTimeout(drop_and_lock, 10 * 1000);
});
function drop_and_lock() {
if (connSM.state == 'synced')
return;
// On connection drop, focus the last post.
// This to prevent jumping to thread bottom on reconnect.
if (CurThread && !lockedManually) {
var last = CurThread.get('replies').last();
if (last)
set_lock_target(last.id, false);
}
}
connSM.on('synced', function () {
// If we dropped earlier, stop focusing now.
if (!lockedManually)
set_lock_target(null);
if (dropAndLockTimer) {
clearTimeout(dropAndLockTimer);
dropAndLockTimer = null;
}
});
var at_bottom = function() {
return window.scrollY + window.innerHeight >= $DOC.height() - 5;
}
if (window.scrollMaxY !== undefined)
at_bottom = function () {
return window.scrollMaxY <= window.scrollY;
};
(function () {
menuHandlers.Focus = function (model) {
var num = model && model.id;
set_lock_target(num, true);
};
menuHandlers.Unfocus = function () {
set_lock_target(null);
};
function scroll_shita() {
if (!lockTarget || (lockTarget == PAGE_BOTTOM))
set_lock_target(null);
}
if (THREAD) {
$lockIndicator = $('<span id=lock>Locked to bottom</span>', {
css: {visibility: 'hidden'},
}).appendTo('body');
$DOC.scroll(scroll_shita);
scroll_shita();
}
})();