'use strict'; /* globals app, define, ajaxify, utils, config */ define('navigator', ['forum/pagination', 'components'], function(pagination, components) { var navigator = {}; var index = 1; var count = 0; navigator.scrollActive = false; navigator.init = function(selector, count, toTop, toBottom, callback, calculateIndex) { index = 1; navigator.selector = selector; navigator.callback = callback; toTop = toTop || function() {}; toBottom = toBottom || function() {}; $(window).on('scroll', navigator.update); $('.pagination-block .dropdown-menu').off('click').on('click', function(e) { e.stopPropagation(); }); $('.pagination-block').off('shown.bs.dropdown', '.dropdown').on('shown.bs.dropdown', '.dropdown', function() { setTimeout(function() { $('.pagination-block input').focus(); }, 100); }); $('.pagination-block .pageup').off('click').on('click', navigator.scrollUp); $('.pagination-block .pagedown').off('click').on('click', navigator.scrollDown); $('.pagination-block .pagetop').off('click').on('click', toTop); $('.pagination-block .pagebottom').off('click').on('click', toBottom); $('.pagination-block input').on('keydown', function(e) { if (e.which === 13) { var input = $(this); if (!utils.isNumber(input.val())) { input.val(''); return; } var index = parseInt(input.val(), 10); if (typeof calculateIndex === 'function') { index = calculateIndex(index, count); } var url = generateUrl(index); input.val(''); $('.pagination-block .dropdown-toggle').trigger('click'); ajaxify.go(url); } }); navigator.setCount(count); navigator.update(); }; function generateUrl(index) { var pathname = window.location.pathname.replace(config.relative_path, ''); var parts = pathname.split('/'); return parts[1] + '/' + parts[2] + '/' + parts[3] + (index ? '/' + index : ''); } navigator.setCount = function(value) { count = parseInt(value, 10); navigator.updateTextAndProgressBar(); }; navigator.show = function() { toggle(true); }; navigator.hide = function() { toggle(false); }; function toggle(flag) { var path = ajaxify.removeRelativePath(window.location.pathname.slice(1)); if (flag && (!path.startsWith('topic') && !path.startsWith('category'))) { return; } $('.pagination-block').toggleClass('invisible', !flag); } navigator.update = function() { toggle(!!count); var topIndex = 0; var bottomIndex = 0; $(navigator.selector).each(function() { var el = $(this); if (elementInView(el)) { if (!topIndex) { topIndex = parseInt(el.attr('data-index'), 10) + 1; } else { bottomIndex = parseInt(el.attr('data-index'), 10) + 1; } } else if (topIndex && bottomIndex) { return false; } }); if (topIndex && !bottomIndex) { bottomIndex = topIndex; } if (typeof navigator.callback === 'function' && topIndex && bottomIndex) { index = navigator.callback(topIndex, bottomIndex, count); navigator.updateTextAndProgressBar(); } }; navigator.updateTextAndProgressBar = function() { index = index > count ? count : index; $('#pagination').translateHtml('[[global:pagination.out_of, ' + index + ', ' + count + ']]'); $('.pagination-block .progress-bar').width((index / count * 100) + '%'); }; navigator.scrollUp = function () { $('body,html').animate({ scrollTop: $(window).scrollTop() - $(window).height() }); }; navigator.scrollDown = function () { $('body,html').animate({ scrollTop: $(window).scrollTop() + $(window).height() }); }; navigator.scrollTop = function(index) { if ($('li[data-index="' + index + '"]').length) { navigator.scrollToPost(index, true); } else { ajaxify.go(generateUrl()); } }; navigator.scrollBottom = function(index) { if (parseInt(index, 10) < 0) { return; } if ($('li[data-index="' + index + '"]').length) { navigator.scrollToPost(index, true); } else { index = parseInt(index, 10) + 1; ajaxify.go(generateUrl(index)); } }; function elementInView(el) { var scrollTop = $(window).scrollTop() + $('#header-menu').height(); var scrollBottom = scrollTop + $(window).height(); var elTop = el.offset().top; var elBottom = elTop + Math.floor(el.height()); return (elTop >= scrollTop && elBottom < scrollBottom) || (elTop < scrollTop && elBottom > scrollTop); } navigator.scrollToPost = function(postIndex, highlight, duration, offset) { if (!utils.isNumber(postIndex) || !components.get('topic').length) { return; } offset = offset || 0; duration = duration !== undefined ? duration : 400; navigator.scrollActive = true; if (components.get('post/anchor', postIndex).length) { return navigator.scrollToPostIndex(postIndex, highlight, duration, offset); } if (config.usePagination) { var page = Math.max(1, Math.ceil(postIndex / config.postsPerPage)); if (parseInt(page, 10) !== pagination.currentPage) { pagination.loadPage(page, function() { navigator.scrollToPostIndex(postIndex, highlight, duration, offset); }); } else { navigator.scrollToPostIndex(postIndex, highlight, duration, offset); } } else { navigator.scrollActive = false; postIndex = parseInt(postIndex, 10) + 1; ajaxify.go(generateUrl(postIndex)); } }; navigator.scrollToPostIndex = function(postIndex, highlight, duration, offset) { var scrollTo = components.get('post/anchor', postIndex); if (!scrollTo.length) { navigator.scrollActive = false; return; } offset = offset || 0; duration = duration !== undefined ? duration : 400; navigator.scrollActive = true; var done = false; function animateScroll() { var scrollTop = (scrollTo.offset().top - ($(window).height() / 2) - offset) + 'px'; $('html, body').animate({ scrollTop: scrollTop }, duration, function() { if (done) { return; } done = true; navigator.scrollActive = false; navigator.update(); highlightPost(); $('body').scrollTop($('body').scrollTop() - 1); $('html').scrollTop($('html').scrollTop() - 1); }); } function highlightPost() { if (highlight) { scrollTo.parents('[component="post"]').addClass('highlight'); setTimeout(function() { scrollTo.parents('[component="post"]').removeClass('highlight'); }, 3000); } } if (components.get('topic').length) { animateScroll(); } else { navigator.scrollActive = false; } }; return navigator; });