From 4888f919f104b2d170302565e481a0b731eb4145 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 25 Dec 2018 01:30:28 +0100 Subject: Prepare for batch mark as read --- p/scripts/main.js | 62 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 27 deletions(-) (limited to 'p/scripts') diff --git a/p/scripts/main.js b/p/scripts/main.js index 4ba329dc1..65310fe9f 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -7,6 +7,8 @@ var $stream = null, shares = 0, ajax_loading = false; +if (!NodeList.prototype.forEach) { NodeList.prototype.forEach = Array.prototype.forEach; } //IE11 + function redirect(url, new_tab) { if (url) { if (new_tab) { @@ -89,7 +91,7 @@ function incUnreadsFeed(article, feed_id, nb) { } //Update unread: favourites - if (article && article.closest('div').hasClass('favorite')) { + if (article && $(article).closest('div').hasClass('favorite')) { elem = $('#aside_feed .favorites .title').get(0); if (elem) { feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0; @@ -115,7 +117,7 @@ function incUnreadsFeed(article, feed_id, nb) { } function incUnreadsTag(tag_id, nb) { - var $t = $('#t_' + tag_id); + var $t = $('#' + tag_id); var unreads = str2int($t.attr('data-unread')); $t.attr('data-unread', unreads + nb) .children('.item-title').attr('data-unread', numberFormat(unreads + nb)); @@ -126,20 +128,20 @@ function incUnreadsTag(tag_id, nb) { } var pending_entries = {}; -function mark_read(active, only_not_read) { - if ((active.length === 0) || (!active.attr('id')) || - context.anonymous || - (only_not_read && !active.hasClass("not_read"))) { +function mark_read($active, only_not_read) { + let div = $active ? $active[0] : null; + if (!div || !div.id || context.anonymous || + (only_not_read && !div.classList.contains('not_read'))) { return false; } - if (pending_entries[active.attr('id')]) { + if (pending_entries[div.id]) { return false; } - pending_entries[active.attr('id')] = true; + pending_entries[div.id] = true; - var url = '.?c=entry&a=read&id=' + active.attr('id').replace(/^flux_/, '') + - (active.hasClass('not_read') ? '' : '&is_read=0'); + let url = '.?c=entry&a=read&id=' + div.id.replace(/^flux_/, '') + + (div.classList.contains('not_read') ? '' : '&is_read=0'); $.ajax({ type: 'POST', @@ -149,35 +151,39 @@ function mark_read(active, only_not_read) { _csrf: context.csrf, }, }).done(function (data) { - var $r = active.find("a.read").attr("href", data.url), - inc = 0; - if (active.hasClass("not_read")) { - active.removeClass("not_read"); + let inc = 0; + if (div.classList.contains('not_read')) { + div.classList.remove('not_read'); + div.querySelectorAll('a.read').forEach(function (a) { a.setAttribute('href', a.getAttribute('href').replace('&is_read=0', '') + '&is_read=1'); }); + div.querySelectorAll('a.read > .icon').forEach(function (img) { img.outerHTML = icons.read; }); inc--; } else { - active.addClass("not_read"); - active.addClass("keep_unread"); + div.classList.add('not_read', 'keep_unread'); + div.querySelectorAll('a.read').forEach(function (a) { a.setAttribute('href', a.getAttribute('href').replace('&is_read=1', '')); }); + div.querySelectorAll('a.read > .icon').forEach(function (img) { img.outerHTML = icons.unread; }); inc++; } - $r.find('.icon').replaceWith(data.icon); - var feed_url = active.find(".website>a").attr("href"); - if (feed_url) { - var feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); - incUnreadsFeed(active, feed_id, inc); + let feed_link = div.querySelector('.website > a'); + if (feed_link) { + let feed_url = feed_link.getAttribute('href'); + let feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); + incUnreadsFeed(div, feed_id, inc); } faviconNbUnread(); if (data.tags) { - for (var i = data.tags.length - 1; i >= 0; i--) { - incUnreadsTag(data.tags[i], inc); + let tagIds = Object.keys(data.tags); + for (let i = tagIds.length - 1; i >= 0; i--) { + let tagId = tagIds[i]; + incUnreadsTag(tagId, inc * data.tags[tagId].length); } } - delete pending_entries[active.attr('id')]; + delete pending_entries[div.id]; }).fail(function (data) { openNotification(i18n.notif_request_failed, 'bad'); - delete pending_entries[active.attr('id')]; + delete pending_entries[div.id]; }); } @@ -911,7 +917,7 @@ function init_dynamic_tags() { }) .done(function () { if ($entry.hasClass('not_read')) { - incUnreadsTag(tagId, isChecked ? 1 : -1); + incUnreadsTag('t_' + tagId, isChecked ? 1 : -1); } }) .fail(function () { @@ -1079,7 +1085,7 @@ function notifs_html5_show(nb) { var notification = new window.Notification(i18n.notif_title_articles, { icon: "../themes/icons/favicon-256.png", body: i18n.notif_body_articles.replace('%d', nb), - tag: "freshRssNewArticles" + tag: 'freshRssNewArticles', }); notification.onclick = function() { @@ -1491,6 +1497,8 @@ function parseJsonVars() { window.url = json.url; window.i18n = json.i18n; window.icons = json.icons; + icons.read = decodeURIComponent(icons.read); + icons.unread = decodeURIComponent(icons.unread); } function init_normal() { -- cgit v1.2.3 From eefeb2341915d677e446cd733fc58b45efb7f5d9 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 25 Dec 2018 05:11:38 +0100 Subject: jQuery ES6 partial refactoring Prefix jQuery variables with $ Start avoiding jQuery in easy cases Use let/const --- app/views/helpers/javascript_vars.phtml | 2 +- p/scripts/main.js | 681 ++++++++++++++++---------------- 2 files changed, 346 insertions(+), 337 deletions(-) (limited to 'p/scripts') diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml index b950b6a1f..b62263ecf 100644 --- a/app/views/helpers/javascript_vars.phtml +++ b/app/views/helpers/javascript_vars.phtml @@ -42,7 +42,7 @@ echo htmlspecialchars(json_encode(array( 'reading_view' => @$s['reading_view'], 'rss_view' => @$s['rss_view'], ), - 'url' => array( + 'urls' => array( 'index' => _url('index', 'index'), 'login' => Minz_Url::display(array('c' => 'auth', 'a' => 'login'), 'php'), 'logout' => Minz_Url::display(array('c' => 'auth', 'a' => 'logout'), 'php'), diff --git a/p/scripts/main.js b/p/scripts/main.js index 65310fe9f..555e92a40 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -1,13 +1,44 @@ "use strict"; -/* globals $, jQuery, context, i18n, shortcut, shortcuts, url */ -/* jshint strict:global */ +/* globals $, jQuery, shortcut */ +/* jshint esversion:6, strict:global */ + +// +if (!NodeList.prototype.forEach) NodeList.prototype.forEach = Array.prototype.forEach; +if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.webkitMatchesSelector; +if (!Element.prototype.closest) { + Element.prototype.closest = function (s) { + let el = this; + if (!document.documentElement.contains(el)) return null; + do { + if (el.matches(s)) return el; + el = el.parentElement || el.parentNode; + } while (el !== null && el.nodeType == 1); + return null; + }; +} +// + +// +var context, i18n, icons, shortcuts, urls; + +(function parseJsonVars() { + const jsonVars = document.getElementById('jsonVars'), + json = JSON.parse(jsonVars.innerHTML); + jsonVars.outerHTML = ''; + context = json.context; + i18n = json.i18n; + shortcuts = json.shortcuts; + urls = json.urls; + icons = json.icons; + icons.read = decodeURIComponent(icons.read); + icons.unread = decodeURIComponent(icons.unread); +}()); var $stream = null, + ajax_loading = false, isCollapsed = true, - shares = 0, - ajax_loading = false; - -if (!NodeList.prototype.forEach) { NodeList.prototype.forEach = Array.prototype.forEach; } //IE11 + $nav_entries = null; +// function redirect(url, new_tab) { if (url) { @@ -20,7 +51,7 @@ function redirect(url, new_tab) { } function needsScroll($elem) { - var $win = $(window), + const $win = $(window), winTop = $win.scrollTop(), winHeight = $win.height(), winBottom = winTop + winHeight, @@ -42,10 +73,10 @@ function numberFormat(nStr) { } // http://www.mredkj.com/javascript/numberFormat.html nStr += ''; - var x = nStr.split('.'), - x1 = x[0], + const x = nStr.split('.'), x2 = x.length > 1 ? '.' + x[1] : '', rgx = /(\d+)(\d{3})/; + let x1 = x[0]; while (rgx.test(x1)) { x1 = x1.replace(rgx, '$1' + ' ' + '$2'); } @@ -53,29 +84,29 @@ function numberFormat(nStr) { } function incLabel(p, inc, spaceAfter) { - var i = str2int(p) + inc; + const i = str2int(p) + inc; return i > 0 ? ((spaceAfter ? '' : ' ') + '(' + numberFormat(i) + ')' + (spaceAfter ? ' ' : '')) : ''; } function incUnreadsFeed(article, feed_id, nb) { //Update unread: feed - var elem = $('#' + feed_id).get(0), + let elem = document.getElementById(feed_id), feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0, feed_priority = elem ? str2int(elem.getAttribute('data-priority')) : 0; if (elem) { elem.setAttribute('data-unread', feed_unreads + nb); - elem = $(elem).children('.item-title').get(0); + elem = elem.querySelector('.item-title'); if (elem) { elem.setAttribute('data-unread', numberFormat(feed_unreads + nb)); } } //Update unread: category - elem = $('#' + feed_id).parents('.category').get(0); + elem = document.getElementById(feed_id).closest('.category'); feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0; if (elem) { elem.setAttribute('data-unread', feed_unreads + nb); - elem = $(elem).find('.title').get(0); + elem = elem.querySelector('.title'); if (elem) { elem.setAttribute('data-unread', numberFormat(feed_unreads + nb)); } @@ -83,7 +114,7 @@ function incUnreadsFeed(article, feed_id, nb) { //Update unread: all if (feed_priority > 0) { - elem = $('#aside_feed .all .title').get(0); + elem = document.querySelector('#aside_feed .all .title'); if (elem) { feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0; elem.setAttribute('data-unread', numberFormat(feed_unreads + nb)); @@ -91,22 +122,22 @@ function incUnreadsFeed(article, feed_id, nb) { } //Update unread: favourites - if (article && $(article).closest('div').hasClass('favorite')) { - elem = $('#aside_feed .favorites .title').get(0); + if (article && article.closest('div').classList.contains('favorite')) { + elem = document.querySelector('#aside_feed .favorites .title'); if (elem) { feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0; elem.setAttribute('data-unread', numberFormat(feed_unreads + nb)); } } - var isCurrentView = false; + let isCurrentView = false; // Update unread: title document.title = document.title.replace(/^((?:\([ 0-9]+\) )?)/, function (m, p1) { - var $feed = $('#' + feed_id); - if (article || ($feed.closest('.active').length > 0 && $feed.siblings('.active').length === 0)) { + const feed = document.getElementById(feed_id); + if (article || (feed.closest('.active') && $(feed).siblings('.active').length === 0)) { isCurrentView = true; return incLabel(p1, nb, true); - } else if ($('.all.active').length > 0) { + } else if (document.querySelector('.all.active')) { isCurrentView = feed_priority > 0; return incLabel(p1, feed_priority > 0 ? nb : 0, true); } else { @@ -117,19 +148,22 @@ function incUnreadsFeed(article, feed_id, nb) { } function incUnreadsTag(tag_id, nb) { - var $t = $('#' + tag_id); - var unreads = str2int($t.attr('data-unread')); - $t.attr('data-unread', unreads + nb) - .children('.item-title').attr('data-unread', numberFormat(unreads + nb)); - - $t = $('.category.tags').find('.title'); - unreads = str2int($t.attr('data-unread')); - $t.attr('data-unread', numberFormat(unreads + nb)); + let t = document.getElementById(tag_id); + if (t) { + let unreads = str2int(t.getAttribute('data-unread')); + t.setAttribute('data-unread', unreads + nb); + t.querySelector('.item-title').setAttribute('data-unread', numberFormat(unreads + nb)); + } + t = document.querySelector('.category.tags .title'); + if (t) { + let unreads = str2int(t.getAttribute('data-unread')); + t.setAttribute('data-unread', numberFormat(unreads + nb)); + } } var pending_entries = {}; -function mark_read($active, only_not_read) { - let div = $active ? $active[0] : null; + +function mark_read(div, only_not_read) { if (!div || !div.id || context.anonymous || (only_not_read && !div.classList.contains('not_read'))) { return false; @@ -187,20 +221,21 @@ function mark_read($active, only_not_read) { }); } -function mark_favorite(active) { - if (active.length === 0) { +function mark_favorite(div) { + if (!div) { return false; } - var url = active.find("a.bookmark").attr("href"); - if (url === undefined) { + let a = div.querySelector('a.bookmark'), + url = a ? a.getAttribute('href') : ''; + if (!url) { return false; } - if (pending_entries[active.attr('id')]) { + if (pending_entries[div.id]) { return false; } - pending_entries[active.attr('id')] = true; + pending_entries[div.id] = true; $.ajax({ type: 'POST', @@ -210,77 +245,77 @@ function mark_favorite(active) { _csrf: context.csrf, }, }).done(function (data) { - var $b = active.find("a.bookmark").attr("href", data.url), - inc = 0; - if (active.hasClass("favorite")) { - active.removeClass("favorite"); + let inc = 0; + if (div.classList.contains('favorite')) { + div.classList.remove('favorite'); inc--; } else { - active.addClass("favorite").find('.bookmark'); + div.classList.add('favorite'); inc++; } - $b.find('.icon').replaceWith(data.icon); + div.querySelectorAll('a.bookmark').forEach(function (a) { a.setAttribute('href', data.url); }); + div.querySelectorAll('a.bookmark > .icon').forEach(function (img) { img.outerHTML = data.icon; }); - var favourites = $('#aside_feed .favorites .title').contents().last().get(0); + const favourites = $('#aside_feed .favorites .title').contents().last().get(0); if (favourites && favourites.textContent) { favourites.textContent = favourites.textContent.replace(/((?: \([ 0-9]+\))?\s*)$/, function (m, p1) { return incLabel(p1, inc, false); }); } - if (active.closest('div').hasClass('not_read')) { - var elem = $('#aside_feed .favorites .title').get(0), + if (div.classList.contains('not_read')) { + const elem = document.querySelector('#aside_feed .favorites .title'), feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0; if (elem) { elem.setAttribute('data-unread', numberFormat(feed_unreads + inc)); } } - delete pending_entries[active.attr('id')]; + delete pending_entries[div.id]; }).fail(function (data) { openNotification(i18n.notif_request_failed, 'bad'); - delete pending_entries[active.attr('id')]; + delete pending_entries[div.id]; }); } -function toggleContent(new_active, old_active, skipping) { +function toggleContent($new_active, $old_active, skipping) { // If skipping, move current without activating or marking as read - if (new_active.length === 0) { + if ($new_active.length === 0) { return; } if (context.does_lazyload && !skipping) { - new_active.find('img[data-original], iframe[data-original]').each(function () { + $new_active.find('img[data-original], iframe[data-original]').each(function () { this.setAttribute('src', this.getAttribute('data-original')); this.removeAttribute('data-original'); }); } - if (old_active[0] !== new_active[0]) { + if ($old_active[0] !== $new_active[0]) { if (isCollapsed && !skipping) { // BUG?: isCollapsed can only ever be true - new_active.addClass("active"); + $new_active.addClass('active'); } - old_active.removeClass("active current"); - new_active.addClass("current"); - if (context.auto_remove_article && !old_active.hasClass('not_read') && !skipping) { - auto_remove(old_active); + $old_active.removeClass('active current'); + $new_active.addClass('current'); + if (context.auto_remove_article && !$old_active.hasClass('not_read') && !skipping) { + auto_remove($old_active); } } else { // collapse_entry calls toggleContent(flux_current, flux_current, false) - new_active.toggleClass('active'); + $new_active.toggleClass('active'); } - var relative_move = context.current_view === 'global', - box_to_move = $(relative_move ? "#panel" : "html,body"); + const relative_move = context.current_view === 'global', + $box_to_move = $(relative_move ? '#panel' : 'html,body'); if (context.sticky_post) { - var prev_article = new_active.prevAll('.flux'), - new_pos = new_active.offset().top, - old_scroll = box_to_move.scrollTop(); + let prev_article = $new_active.prevAll('.flux'), + new_pos = $new_active.offset().top, + old_scroll = $box_to_move.scrollTop(); if (prev_article.length > 0 && new_pos - prev_article.offset().top <= 150) { new_pos = prev_article.offset().top; if (relative_move) { - new_pos -= box_to_move.offset().top; + new_pos -= $box_to_move.offset().top; } } @@ -293,104 +328,104 @@ function toggleContent(new_active, old_active, skipping) { new_pos += old_scroll; } - new_active.children(".flux_content").first().each(function () { - box_to_move.scrollTop(new_pos).scrollTop(); + $new_active.children('.flux_content').first().each(function () { + $box_to_move.scrollTop(new_pos).scrollTop(); }); } else { if (relative_move) { new_pos += old_scroll; } - box_to_move.scrollTop(new_pos).scrollTop(); + $box_to_move.scrollTop(new_pos).scrollTop(); } } - if (context.auto_mark_article && new_active.hasClass('active') && !skipping) { - mark_read(new_active, true); + if (context.auto_mark_article && $new_active.hasClass('active') && !skipping) { + mark_read($new_active[0], true); } } -function auto_remove(element) { - var p = element.prev(); - var n = element.next(); - if (p.hasClass('day') && n.hasClass('day')) { - p.remove(); +function auto_remove($element) { + let $p = $element.prev(), + $n = $element.next(); + if ($p.hasClass('day') && $n.hasClass('day')) { + $p.remove(); } - element.remove(); + $element.remove(); $('#stream > .flux:not(.not_read):not(.active)').remove(); } function prev_entry() { - var old_active = $(".flux.current"), - new_active = old_active.length === 0 ? $(".flux:last") : old_active.prevAll(".flux:first"); - toggleContent(new_active, old_active, false); + let $old_active = $('.flux.current'), + $new_active = $old_active.length === 0 ? $('.flux:last') : $old_active.prevAll('.flux:first'); + toggleContent($new_active, $old_active, false); } function next_entry() { - var old_active = $(".flux.current"), - new_active = old_active.length === 0 ? $(".flux:first") : old_active.nextAll(".flux:first"); - toggleContent(new_active, old_active, false); + let $old_active = $('.flux.current'), + $new_active = $old_active.length === 0 ? $('.flux:first') : $old_active.nextAll('.flux:first'); + toggleContent($new_active, $old_active, false); - if (new_active.nextAll().length < 3) { + if ($new_active.nextAll().length < 3) { load_more_posts(); } } function skip_prev_entry() { - var old_active = $(".flux.current"), - new_active = old_active.length === 0 ? $(".flux:last") : old_active.prevAll(".flux:first"); - toggleContent(new_active, old_active, true); + let $old_active = $('.flux.current'), + $new_active = $old_active.length === 0 ? $('.flux:last') : $old_active.prevAll('.flux:first'); + toggleContent($new_active, $old_active, true); } function skip_next_entry() { - var old_active = $(".flux.current"), - new_active = old_active.length === 0 ? $(".flux:first") : old_active.nextAll(".flux:first"); - toggleContent(new_active, old_active, true); + let $old_active = $('.flux.current'), + $new_active = $old_active.length === 0 ? $('.flux:first') : $old_active.nextAll('.flux:first'); + toggleContent($new_active, $old_active, true); - if (new_active.nextAll().length < 3) { + if ($new_active.nextAll().length < 3) { load_more_posts(); } } function prev_feed() { - var active_feed = $("#aside_feed .tree-folder-items .item.active"); - if (active_feed.length > 0) { - active_feed.prevAll(':visible:first').find('a').each(function(){this.click();}); + let $active_feed = $('#aside_feed .tree-folder-items .item.active'); + if ($active_feed.length > 0) { + $active_feed.prevAll(':visible:first').find('a').each(function () { this.click(); }); } else { last_feed(); } } function next_feed() { - var active_feed = $("#aside_feed .tree-folder-items .item.active"); - if (active_feed.length > 0) { - active_feed.nextAll(':visible:first').find('a').each(function(){this.click();}); + let $active_feed = $('#aside_feed .tree-folder-items .item.active'); + if ($active_feed.length > 0) { + $active_feed.nextAll(':visible:first').find('a').each(function () { this.click(); }); } else { first_feed(); } } function first_feed() { - var feed = $("#aside_feed .tree-folder-items.active .item:visible:first"); - if (feed.length > 0) { - feed.find('a')[1].click(); + let $feed = $('#aside_feed .tree-folder-items.active .item:visible:first'); + if ($feed.length > 0) { + $feed.find('a')[1].click(); } } function last_feed() { - var feed = $("#aside_feed .tree-folder-items.active .item:visible:last"); - if (feed.length > 0) { - feed.find('a')[1].click(); + let $feed = $('#aside_feed .tree-folder-items.active .item:visible:last'); + if ($feed.length > 0) { + $feed.find('a')[1].click(); } } function prev_category() { - var active_cat = $("#aside_feed .tree-folder.active"); + let $active_cat = $('#aside_feed .tree-folder.active'); - if (active_cat.length > 0) { - var prev_cat = active_cat.prevAll(':visible:first').find('.tree-folder-title .title'); - if (prev_cat.length > 0) { - prev_cat[0].click(); + if ($active_cat.length > 0) { + let $prev_cat = $active_cat.prevAll(':visible:first').find('.tree-folder-title .title'); + if ($prev_cat.length > 0) { + $prev_cat[0].click(); } } else { last_category(); @@ -399,12 +434,12 @@ function prev_category() { } function next_category() { - var active_cat = $("#aside_feed .tree-folder.active"); + let $active_cat = $('#aside_feed .tree-folder.active'); - if (active_cat.length > 0) { - var next_cat = active_cat.nextAll(':visible:first').find('.tree-folder-title .title'); - if (next_cat.length > 0) { - next_cat[0].click(); + if ($active_cat.length > 0) { + let $next_cat = $active_cat.nextAll(':visible:first').find('.tree-folder-title .title'); + if ($next_cat.length > 0) { + $next_cat[0].click(); } } else { first_category(); @@ -413,35 +448,35 @@ function next_category() { } function first_category() { - var cat = $("#aside_feed .tree-folder:visible:first"); - if (cat.length > 0) { - cat.find('.tree-folder-title .title')[0].click(); + let $cat = $('#aside_feed .tree-folder:visible:first'); + if ($cat.length > 0) { + $cat.find('.tree-folder-title .title')[0].click(); } } function last_category() { - var cat = $("#aside_feed .tree-folder:visible:last"); - if (cat.length > 0) { - cat.find('.tree-folder-title .title')[0].click(); + let $cat = $('#aside_feed .tree-folder:visible:last'); + if ($cat.length > 0) { + $cat.find('.tree-folder-title .title')[0].click(); } } function collapse_entry() { - var flux_current = $(".flux.current"); - toggleContent(flux_current, flux_current, false); + let $flux_current = $('.flux.current'); + toggleContent($flux_current, $flux_current, false); } function user_filter(key) { - var filter = $('#dropdown-query'); - var filters = filter.siblings('.dropdown-menu').find('.item.query a'); - if (typeof key === "undefined") { + const filter = $('#dropdown-query'), + filters = filter.siblings('.dropdown-menu').find('.item.query a'); + if (typeof key === 'undefined') { if (!filter.length) { return; } // Display the filter div window.location.hash = filter.attr('id'); // Force scrolling to the filter div - var scroll = needsScroll($('.header')); + const scroll = needsScroll($('.header')); if (scroll !== 0) { $('html,body').scrollTop(scroll); } @@ -460,21 +495,21 @@ function user_filter(key) { } function auto_share(key) { - var share = $(".flux.current.active").find('.dropdown-target[id^="dropdown-share"]'); - var shares = share.siblings('.dropdown-menu').find('.item a'); - if (typeof key === "undefined") { - if (!share.length) { + const $share = $('.flux.current.active').find('.dropdown-target[id^="dropdown-share"]'), + $shares = $share.siblings('.dropdown-menu').find('.item a'); + if (typeof key === 'undefined') { + if (!$share.length) { return; } // Display the share div - window.location.hash = share.attr('id'); + window.location.hash = $share.attr('id'); // Force scrolling to the share div - var scroll = needsScroll(share.closest('.bottom')); + const scroll = needsScroll($share.closest('.bottom')); if (scroll !== 0) { $('html,body').scrollTop(scroll); } // Force the key value if there is only one action, so we can trigger it automatically - if (shares.length === 1) { + if ($shares.length === 1) { key = 1; } else { return; @@ -482,54 +517,54 @@ function auto_share(key) { } // Trigger selected share action and hide the share div key = parseInt(key); - if (key <= shares.length) { - shares[key - 1].click(); - share.siblings('.dropdown-menu').find('.dropdown-close a')[0].click(); + if (key <= $shares.length) { + $shares[key - 1].click(); + $share.siblings('.dropdown-menu').find('.dropdown-close a')[0].click(); } } -function scrollAsRead(box_to_follow) { - var minTop = 40 + (context.current_view === 'global' ? box_to_follow.offset().top : box_to_follow.scrollTop()); +function scrollAsRead($box_to_follow) { + const minTop = 40 + (context.current_view === 'global' ? $box_to_follow.offset().top : $box_to_follow.scrollTop()); $('.not_read:not(.keep_unread):visible').each(function () { - var $this = $(this); + const $this = $(this); if ($this.offset().top + $this.height() < minTop) { - mark_read($this, true); + mark_read(this, true); } }); } function init_posts() { - var box_to_follow = context.current_view === 'global' ? $("#panel") : $(window); + let $box_to_follow = context.current_view === 'global' ? $('#panel') : $(window); if (context.auto_mark_scroll) { - var lastScroll = 0, //Throttle + let lastScroll = 0, //Throttle timerId = 0; - box_to_follow.scroll(function () { + $box_to_follow.scroll(function () { window.clearTimeout(timerId); if (lastScroll + 500 < Date.now()) { lastScroll = Date.now(); - scrollAsRead(box_to_follow); + scrollAsRead($box_to_follow); } else { timerId = window.setTimeout(function() { - scrollAsRead(box_to_follow); + scrollAsRead($box_to_follow); }, 500); } }); } if (context.auto_load_more) { - box_to_follow.scroll(function () { - var load_more = $("#load_more"); - if (!load_more.is(':visible')) { + $box_to_follow.scroll(function () { + const $load_more = $('#load_more'); + if (!$load_more.is(':visible')) { return; } - var boxBot = box_to_follow.scrollTop() + box_to_follow.height(), - load_more_top = load_more.offset().top; + const boxBot = $box_to_follow.scrollTop() + $box_to_follow.height(), + load_more_top = $load_more.offset().top; if (boxBot >= load_more_top) { load_more_posts(); } }); - box_to_follow.scroll(); + $box_to_follow.scroll(); } } @@ -548,9 +583,9 @@ function init_column_categories() { this.alt = '▽'; } }); - $(this).parent().next(".tree-folder-items").slideToggle(300, function () { + $(this).parent().next('.tree-folder-items').slideToggle(300, function () { //Workaround for Gecko bug in Firefox 64-65(+?): - var sidebar = document.getElementById('sidebar'); + const sidebar = document.getElementById('sidebar'); if (sidebar && sidebar.scrollHeight > sidebar.clientHeight && //if needs scrollbar sidebar.scrollWidth >= sidebar.offsetWidth) { //but no scrollbar sidebar.style['overflow-y'] = 'scroll'; //then force scrollbar @@ -561,7 +596,7 @@ function init_column_categories() { }); $('#aside_feed').on('click', '.tree-folder-items .feed .dropdown-toggle', function () { - var itemId = $(this).closest('.item').attr('id'), + const itemId = $(this).closest('.item').attr('id'), templateId = itemId.substring(0, 2) === 't_' ? 'tag_config_template' : 'feed_config_template', id = itemId.substr(2), feed_web = $(this).data('fweb'), @@ -572,10 +607,10 @@ function init_column_categories() { .append(template).find('button.confirm').removeAttr('disabled'); } else { if ($(this).next('.dropdown-menu').css('display') === 'none') { - id = $(this).closest('.item').attr('id').substr(2); - $(this).attr('href', '#dropdown-' + id); + const id2 = $(this).closest('.item').attr('id').substr(2); + $(this).attr('href', '#dropdown-' + id2); } else { - $(this).attr('href', "#close"); + $(this).attr('href', '#close'); } } }); @@ -592,21 +627,19 @@ function init_shortcuts() { // Manipulation shortcuts shortcut.add(shortcuts.mark_read, function () { // Toggle the read state - var active = $(".flux.current"); - mark_read(active, false); + mark_read(document.querySelector('.flux.current'), false); }, { 'disable_in_input': true }); - shortcut.add("shift+" + shortcuts.mark_read, function () { + shortcut.add('shift+' + shortcuts.mark_read, function () { // Mark everything as read - $(".nav_menu .read_all").click(); + $('.nav_menu .read_all').click(); }, { 'disable_in_input': true }); shortcut.add(shortcuts.mark_favorite, function () { // Toggle the favorite state - var active = $(".flux.current"); - mark_favorite(active); + mark_favorite(document.querySelector('.flux.current')); }, { 'disable_in_input': true }); @@ -637,7 +670,7 @@ function init_shortcuts() { auto_share(String.fromCharCode(evt.keyCode)); } } - for (var i = 1; i < 10; i++) { + for (let i = 1; i < 10; i++) { shortcut.add(i.toString(), addShortcut, { 'disable_in_input': true }); @@ -651,11 +684,11 @@ function init_shortcuts() { 'disable_in_input': true }); shortcut.add(shortcuts.first_entry, function () { - var old_active = $(".flux.current"), - first = $(".flux:first"); + const $old_active = $('.flux.current'), + $first = $('.flux:first'); - if (first.hasClass("flux")) { - toggleContent(first, old_active, false); + if ($first.hasClass('flux')) { + toggleContent($first, $old_active, false); } }, { 'disable_in_input': true @@ -667,48 +700,48 @@ function init_shortcuts() { 'disable_in_input': true }); shortcut.add(shortcuts.last_entry, function () { - var old_active = $(".flux.current"), - last = $(".flux:last"); + const $old_active = $('.flux.current'), + $last = $('.flux:last'); - if (last.hasClass("flux")) { - toggleContent(last, old_active, false); + if ($last.hasClass('flux')) { + toggleContent($last, $old_active, false); } }, { 'disable_in_input': true }); // Feed navigation shortcuts - shortcut.add("shift+" + shortcuts.prev_entry, prev_feed, { + shortcut.add('shift+' + shortcuts.prev_entry, prev_feed, { 'disable_in_input': true }); - shortcut.add("shift+" + shortcuts.next_entry, next_feed, { + shortcut.add('shift+' + shortcuts.next_entry, next_feed, { 'disable_in_input': true }); - shortcut.add("shift+" + shortcuts.first_entry, first_feed, { + shortcut.add('shift+' + shortcuts.first_entry, first_feed, { 'disable_in_input': true }); - shortcut.add("shift+" + shortcuts.last_entry, last_feed, { + shortcut.add('shift+' + shortcuts.last_entry, last_feed, { 'disable_in_input': true }); // Category navigation shortcuts - shortcut.add("alt+" + shortcuts.prev_entry, prev_category, { + shortcut.add('alt+' + shortcuts.prev_entry, prev_category, { 'disable_in_input': true }); - shortcut.add("alt+" + shortcuts.next_entry, next_category, { + shortcut.add('alt+' + shortcuts.next_entry, next_category, { 'disable_in_input': true }); - shortcut.add("alt+" + shortcuts.first_entry, first_category, { + shortcut.add('alt+' + shortcuts.first_entry, first_category, { 'disable_in_input': true }); - shortcut.add("alt+" + shortcuts.last_entry, last_category, { + shortcut.add('alt+' + shortcuts.last_entry, last_category, { 'disable_in_input': true }); shortcut.add(shortcuts.go_website, function () { - var url_website = $('.flux.current a.go_website').attr("href"); + const url_website = $('.flux.current a.go_website').attr('href'); if (context.auto_mark_site) { - $(".flux.current").each(function () { - mark_read($(this), true); + $('.flux.current').each(function () { + mark_read(this, true); }); } @@ -730,7 +763,7 @@ function init_shortcuts() { }); shortcut.add(shortcuts.help, function () { - redirect(url.help, true); + redirect(urls.help, true); }, { 'disable_in_input': true }); @@ -775,8 +808,8 @@ function init_stream(divStream) { // setting for not-closing after clicking outside article area return; } - var old_active = $(".flux.current"), - new_active = $(this).parent(); + const old_active = document.querySelector('.flux.current'), + new_active = this.parentNode; isCollapsed = true; if (e.target.tagName.toUpperCase() === 'A') { //Leave real links alone if (context.auto_mark_article) { @@ -784,21 +817,20 @@ function init_stream(divStream) { } return true; } - toggleContent(new_active, old_active, false); + toggleContent($(new_active), $(old_active), false); }); divStream.on('click', '.flux a.read', function () { - var active = $(this).parents(".flux"); - if (context.auto_remove_article && active.hasClass('not_read')) { - auto_remove(active); + const $active = $(this).parents('.flux'); + if (context.auto_remove_article && $active.hasClass('not_read')) { + auto_remove($active); } - mark_read(active, false); + mark_read($active[0], false); return false; }); divStream.on('click', '.flux a.bookmark', function () { - var active = $(this).parents(".flux"); - mark_favorite(active); + mark_favorite(this.closest('.flux')); return false; }); @@ -815,7 +847,7 @@ function init_stream(divStream) { if (e.which == 2) { // If middle click, we want same behaviour as CTRL+click. - var ev = jQuery.Event("click"); + const ev = jQuery.Event('click'); ev.ctrlKey = true; $(this).trigger(ev); } else if(e.which == 1) { @@ -838,13 +870,11 @@ function init_stream(divStream) { return; } - mark_read($(this).parents(".flux"), true); + mark_read(this.closest('.flux'), true); }); } } -var $nav_entries = null; - function init_nav_entries() { $nav_entries = $('#nav_entries'); $nav_entries.find('.previous_entry').click(function () { @@ -856,14 +886,14 @@ function init_nav_entries() { return false; }); $nav_entries.find('.up').click(function () { - var active_item = $(".flux.current"), + const $active_item = $('.flux.current'), windowTop = $(window).scrollTop(), - item_top = active_item.offset().top; + item_top = $active_item.offset().top; if (windowTop > item_top) { - $("html,body").scrollTop(item_top); + $('html,body').scrollTop(item_top); } else { - $("html,body").scrollTop(0); + $('html,body').scrollTop(0); } return false; }); @@ -872,14 +902,14 @@ function init_nav_entries() { function loadDynamicTags($div) { $div.removeClass('dynamictags'); $div.find('li.item').remove(); - var entryId = $div.closest('div.flux').attr('id').replace(/^flux_/, ''); + const entryId = $div.closest('div.flux').attr('id').replace(/^flux_/, ''); $.getJSON('./?c=tag&a=getTagsForEntry&id_entry=' + entryId) .done(function (data) { - var $ul = $div.find('.dropdown-menu'); + const $ul = $div.find('.dropdown-menu'); $ul.append('
  • '); if (data && data.length) { - for (var i = 0; i < data.length; i++) { - var tag = data[i]; + for (let i = 0; i < data.length; i++) { + const tag = data[i]; $ul.append('
  • '); } @@ -897,13 +927,13 @@ function init_dynamic_tags() { }); $stream.on('change', '.checkboxTag', function (ev) { - var $checkbox = $(this); + const $checkbox = $(this), + isChecked = $checkbox.prop('checked'), + tagId = $checkbox.attr('name').replace(/^t_/, ''), + tagName = $checkbox.siblings('input[name]').val(), + $entry = $checkbox.closest('div.flux'), + entryId = $entry.attr('id').replace(/^flux_/, ''); $checkbox.prop('disabled', true); - var isChecked = $checkbox.prop('checked'); - var tagId = $checkbox.attr('name').replace(/^t_/, ''); - var tagName = $checkbox.siblings('input[name]').val(); - var $entry = $checkbox.closest('div.flux'); - var entryId = $entry.attr('id').replace(/^flux_/, ''); $.ajax({ type: 'POST', url: './?c=tag&a=tagEntry', @@ -936,7 +966,7 @@ function init_dynamic_tags() { var feed_processed = 0; function updateFeed(feeds, feeds_count) { - var feed = feeds.pop(); + const feed = feeds.pop(); if (!feed) { return; } @@ -949,8 +979,8 @@ function updateFeed(feeds, feeds_count) { }, }).always(function (data) { feed_processed++; - $("#actualizeProgress .progress").html(feed_processed + " / " + feeds_count); - $("#actualizeProgress .title").html(feed.title); + $('#actualizeProgress .progress').html(feed_processed + ' / ' + feeds_count); + $('#actualizeProgress .title').html(feed.title); if (feed_processed === feeds_count) { $.ajax({ //Empty request to commit new articles @@ -970,9 +1000,9 @@ function updateFeed(feeds, feeds_count) { } function init_actualize() { - var auto = false; + let auto = false; - $("#actualize").click(function () { + $('#actualize').click(function () { if (ajax_loading) { return false; } @@ -985,7 +1015,7 @@ function init_actualize() { return false; } if (data.feeds.length === 0) { - openNotification(data.feedback_no_refresh, "good"); + openNotification(data.feedback_no_refresh, 'good'); $.ajax({ //Empty request to force refresh server database cache type: 'POST', url: './?c=feed&a=actualize&id=-1&ajax=1', @@ -999,11 +1029,11 @@ function init_actualize() { return; } //Progress bar - var feeds_count = data.feeds.length; + const feeds_count = data.feeds.length; $('body').after('
    ' + data.feedback_actualize + '
    /
    0 / ' + feeds_count + '
    '); - for (var i = 10; i > 0; i--) { + for (let i = 10; i > 0; i--) { updateFeed(data.feeds, feeds_count); } }); @@ -1013,13 +1043,13 @@ function init_actualize() { if (context.auto_actualize_feeds) { auto = true; - $("#actualize").click(); + $('#actualize').click(); } } // // -var notification = null, +var $notification = null, notification_interval = null, notification_working = false; @@ -1030,19 +1060,19 @@ function openNotification(msg, status) { notification_working = true; - notification.removeClass(); - notification.addClass("notification"); - notification.addClass(status); - notification.find(".msg").html(msg); - notification.fadeIn(300); + $notification.removeClass(); + $notification.addClass('notification'); + $notification.addClass(status); + $notification.find('.msg').html(msg); + $notification.fadeIn(300); notification_interval = window.setTimeout(closeNotification, 4000); } function closeNotification() { - notification.fadeOut(600, function() { - notification.removeClass(); - notification.addClass('closed'); + $notification.fadeOut(600, function() { + $notification.removeClass(); + $notification.addClass('closed'); window.clearInterval(notification_interval); notification_working = false; @@ -1050,14 +1080,14 @@ function closeNotification() { } function init_notifications() { - notification = $("#notification"); + $notification = $('#notification'); - notification.find("a.close").click(function () { + $notification.find('a.close').click(function () { closeNotification(); return false; }); - if (notification.find(".msg").html().length > 0) { + if ($notification.find('.msg').html().length > 0) { notification_working = true; notification_interval = window.setTimeout(closeNotification, 4000); } @@ -1078,12 +1108,12 @@ function notifs_html5_ask_permission() { } function notifs_html5_show(nb) { - if (notifs_html5_permission !== "granted") { + if (notifs_html5_permission !== 'granted') { return; } - var notification = new window.Notification(i18n.notif_title_articles, { - icon: "../themes/icons/favicon-256.png", + const notification = new window.Notification(i18n.notif_title_articles, { + icon: '../themes/icons/favicon-256.png', body: i18n.notif_body_articles.replace('%d', nb), tag: 'freshRssNewArticles', }); @@ -1112,12 +1142,12 @@ function init_notifs_html5() { function refreshUnreads() { $.getJSON('./?c=javascript&a=nbUnreadsPerFeed').done(function (data) { - var isAll = $('.category.all.active').length > 0, - new_articles = false; + const isAll = document.querySelector('.category.all.active'); + let new_articles = false; $.each(data.feeds, function(feed_id, nbUnreads) { feed_id = 'f_' + feed_id; - var elem = $('#' + feed_id).get(0), + const elem = document.getElementById(feed_id), feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0; if ((incUnreadsFeed(null, feed_id, nbUnreads - feed_unreads) || isAll) && //Update of current view? @@ -1127,7 +1157,7 @@ function refreshUnreads() { } }); - var nbUnreadTags = 0; + let nbUnreadTags = 0; $.each(data.tags, function(tag_id, nbUnreads) { nbUnreadTags += nbUnreads; @@ -1138,7 +1168,7 @@ function refreshUnreads() { $('.category.tags').attr('data-unread', nbUnreadTags) .find('.title').attr('data-unread', numberFormat(nbUnreadTags)); - var nb_unreads = str2int($('.category.all .title').attr('data-unread')); + const nb_unreads = str2int($('.category.all .title').attr('data-unread')); if (nb_unreads > 0 && new_articles) { faviconNbUnread(nb_unreads); @@ -1148,7 +1178,7 @@ function refreshUnreads() { } // -var url_load_more = "", +var url_load_more = '', load_more = false, box_load_more = null; @@ -1158,7 +1188,7 @@ function load_more_posts() { } load_more = true; - $('#load_more').addClass('loading'); + document.getElementById('load_more').classList.add('loading'); $.get(url_load_more, function (data) { box_load_more.children('.flux:last').after($('#stream', data).children('.flux, .day')); $('.pagination').replaceWith($('.pagination', data)); @@ -1173,7 +1203,7 @@ function load_more_posts() { } $('[id^=day_]').each(function (i) { - var ids = $('[id="' + this.id + '"]'); + const ids = $('[id="' + this.id + '"]'); if (ids.length > 1) { $('[id="' + this.id + '"]:gt(0)').remove(); } @@ -1181,8 +1211,8 @@ function load_more_posts() { init_load_more(box_load_more); - $('#load_more').removeClass('loading'); - $('#bigMarkAsRead').removeAttr('disabled'); + document.getElementById('load_more').classList.remove('loading'); + document.getElementById('bigMarkAsRead').removeAttribute('disabled'); load_more = false; }); } @@ -1198,14 +1228,14 @@ function init_load_more(box) { box_load_more = box; document.body.dispatchEvent(freshrssLoadMoreEvent); - var $next_link = $("#load_more"); + const $next_link = $('#load_more'); if (!$next_link.length) { // no more article to load - url_load_more = ""; + url_load_more = ''; return; } - url_load_more = $next_link.attr("href"); + url_load_more = $next_link.attr('href'); $next_link.click(function () { load_more_posts(); @@ -1216,9 +1246,9 @@ function init_load_more(box) { // function poormanSalt() { //If crypto.getRandomValues is not available - var text = '$2a$04$', - base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789/abcdefghijklmnopqrstuvwxyz'; - for (var i = 22; i > 0; i--) { + const base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789/abcdefghijklmnopqrstuvwxyz'; + let text = '$2a$04$'; + for (let i = 22; i > 0; i--) { text += base.charAt(Math.floor(Math.random() * 64)); } return text; @@ -1226,7 +1256,7 @@ function poormanSalt() { //If crypto.getRandomValues is not available function init_crypto_form() { /* globals dcodeIO */ - var $crypto_form = $('#crypto-form'); + const $crypto_form = $('#crypto-form'); if ($crypto_form.length === 0) { return; } @@ -1240,10 +1270,10 @@ function init_crypto_form() { } $crypto_form.on('submit', function() { - var $submit_button = $(this).find('button[type="submit"]'); + const $submit_button = $(this).find('button[type="submit"]'); $submit_button.attr('disabled', ''); - var success = false; + let success = false; $.ajax({ url: './?c=javascript&a=nonce&user=' + $('#username').val(), dataType: 'json', @@ -1253,7 +1283,7 @@ function init_crypto_form() { openNotification('Invalid user!', 'bad'); } else { try { - var strong = window.Uint32Array && window.crypto && (typeof window.crypto.getRandomValues === 'function'), + const strong = window.Uint32Array && window.crypto && (typeof window.crypto.getRandomValues === 'function'), s = dcodeIO.bcrypt.hashSync($('#passwordPlain').val(), data.salt1), c = dcodeIO.bcrypt.hashSync(data.nonce + s, strong ? dcodeIO.bcrypt.genSaltSync(4) : poormanSalt()); $('#challenge').val(c); @@ -1278,7 +1308,7 @@ function init_crypto_form() { function init_confirm_action() { $('body').on('click', '.confirm', function () { - var str_confirmation = $(this).attr('data-str-confirm'); + let str_confirmation = $(this).attr('data-str-confirm'); if (!str_confirmation) { str_confirmation = i18n.confirmation_default; } @@ -1290,15 +1320,15 @@ function init_confirm_action() { function init_print_action() { $('.item.share > a[href="#"]').click(function (e) { - var content = "" + + const content = '' + $(e.target).closest('.flux_content').find('.content').html() + - ""; + ''; - var tmp_window = window.open(); + const tmp_window = window.open(); tmp_window.document.writeln(content); tmp_window.document.close(); tmp_window.focus(); @@ -1310,25 +1340,27 @@ function init_print_action() { } function init_post_action() { - $('.item.share > a[href="POST"]').click(function (event) { - event.preventDefault(); - var form = $(this).next('form'); - $.post(form.data('url'), form.serialize()); + $('.item.share > a[href="POST"]').click(function (e) { + e.preventDefault(); + const $form = $(this).next('form'); + $.post($form.data('url'), $form.serialize()); }); } +var shares = 0; + function init_share_observers() { shares = $('.group-share').length; - $('.share.add').on('click', function(e) { - var opt = $(this).siblings('select').find(':selected'); - var row = $(this).parents('form').data(opt.data('form')); - row = row.replace(/##label##/g, opt.html().trim()); - row = row.replace(/##type##/g, opt.val()); - row = row.replace(/##help##/g, opt.data('help')); + $('.share.add').on('click', function (e) { + const $opt = $(this).siblings('select').find(':selected'); + let row = $(this).parents('form').data($opt.data('form')); + row = row.replace(/##label##/g, $opt.html().trim()); + row = row.replace(/##type##/g, $opt.val()); + row = row.replace(/##help##/g, $opt.data('help')); row = row.replace(/##key##/g, shares); - row = row.replace(/##method##/g, opt.data('method')); - row = row.replace(/##field##/g, opt.data('field')); + row = row.replace(/##method##/g, $opt.data('method')); + row = row.replace(/##field##/g, $opt.data('field')); $(this).parents('.form-group').before(row); shares++; @@ -1343,44 +1375,39 @@ function init_stats_observers() { } function init_remove_observers() { - $('.post').on('click', 'a.remove', function(e) { - var remove_what = $(this).attr('data-remove'); - + $('.post').on('click', 'a.remove', function (e) { + const remove_what = $(this).attr('data-remove'); if (remove_what !== undefined) { - var remove_obj = $('#' + remove_what); - remove_obj.remove(); + $('#' + remove_what).remove(); } - return false; }); } function init_feed_observers() { - $('select[id="category"]').on('change', function() { - var detail = $('#new_category_name').parent(); + $('select[id="category"]').on('change', function () { + const $detail = $('#new_category_name').parent(); if ($(this).val() === 'nc') { - detail.attr('aria-hidden', 'false').show(); - detail.find('input').focus(); + $detail.attr('aria-hidden', 'false').show(); + $detail.find('input').focus(); } else { - detail.attr('aria-hidden', 'true').hide(); + $detail.attr('aria-hidden', 'true').hide(); } }); } function init_password_observers() { - $('.toggle-password').on('mousedown', function(e) { - var button = $(this); - var passwordField = $('#' + button.attr('data-toggle')); - passwordField.attr('type', 'text'); - button.addClass('active'); - + $('.toggle-password').on('mousedown', function (e) { + const $button = $(this), + $passwordField = $('#' + $button.attr('data-toggle')); + $passwordField.attr('type', 'text'); + $button.addClass('active'); return false; - }).on('mouseup', function(e) { - var button = $(this); - var passwordField = $('#' + button.attr('data-toggle')); - passwordField.attr('type', 'password'); - button.removeClass('active'); - + }).on('mouseup', function (e) { + const $button = $(this), + $passwordField = $('#' + $button.attr('data-toggle')); + $passwordField.attr('type', 'password'); + $button.removeClass('active'); return false; }); } @@ -1390,16 +1417,16 @@ function faviconNbUnread(n) { n = str2int($('.category.all .title').attr('data-unread')); } //http://remysharp.com/2010/08/24/dynamic-favicons/ - var canvas = document.createElement('canvas'), + const canvas = document.createElement('canvas'), link = document.getElementById('favicon').cloneNode(true); if (canvas.getContext && link) { canvas.height = canvas.width = 16; - var img = document.createElement('img'); + const img = document.createElement('img'); img.onload = function () { - var ctx = canvas.getContext('2d'); + const ctx = canvas.getContext('2d'); ctx.drawImage(this, 0, 0, canvas.width, canvas.height); if (n > 0) { - var text = ''; + let text = ''; if (n < 1000) { text = n; } else if (n < 100000) { @@ -1422,9 +1449,9 @@ function faviconNbUnread(n) { } function init_slider_observers() { - var slider = $('#slider'), - closer = $('#close-slider'); - if (slider.length < 1) { + const $slider = $('#slider'), + $closer = $('#close-slider'); + if ($slider.length < 1) { return; } @@ -1434,51 +1461,47 @@ function init_slider_observers() { } ajax_loading = true; - var url_slide = $(this).attr('href'); $.ajax({ type: 'GET', - url: url_slide, + url: $(this).attr('href'), data: { ajax: true } }).done(function (data) { - slider.html(data); - closer.addClass('active'); - slider.addClass('active'); + $slider.html(data); + $closer.addClass('active'); + $slider.addClass('active'); ajax_loading = false; }); return false; }); - closer.on('click', function() { - closer.removeClass('active'); - slider.removeClass('active'); + $closer.on('click', function() { + $closer.removeClass('active'); + $slider.removeClass('active'); return false; }); } function init_configuration_alert() { - $(window).on('submit', function(e) { + $(window).on('submit', function (e) { window.hasSubmit = true; }); - $(window).on('beforeunload', function(e) { + $(window).on('beforeunload', function (e) { if (window.hasSubmit) { return; } - var fields = $("[data-leave-validation]"); - for (var i = 0; i < fields.length; i++) { - if ($(fields[i]).attr('type') === 'checkbox' || $(fields[i]).attr('type') === 'radio') { - // The use of != is done on purpose to check boolean against integer - if ($(fields[i]).is(':checked') != $(fields[i]).attr('data-leave-validation')) { - return false; - } - } else { - if ($(fields[i]).attr('data-leave-validation') !== $(fields[i]).val()) { + const inputs = document.querySelectorAll('[data-leave-validation]'); + for (let i = inputs.length - 1; i >= 0; i--) { + const input = inputs[i]; + if (input.type === 'checkbox' || input.type === 'radio') { + if (input.checked != input.getAttribute('data-leave-validation')) { return false; } + } else if (input.value != input.getAttribute('data-leave-validation')) { + return false; } } - return; }); } @@ -1488,19 +1511,6 @@ function init_subscription() { }); } -function parseJsonVars() { - var jsonVars = document.getElementById('jsonVars'), - json = JSON.parse(jsonVars.innerHTML); - jsonVars.outerHTML = ''; - window.context = json.context; - window.shortcuts = json.shortcuts; - window.url = json.url; - window.i18n = json.i18n; - window.icons = json.icons; - icons.read = decodeURIComponent(icons.read); - icons.unread = decodeURIComponent(icons.unread); -} - function init_normal() { $stream = $('#stream'); if ($stream.length < 1) { @@ -1567,7 +1577,6 @@ function init_afterDOM() { } } -parseJsonVars(); init_beforeDOM(); //Can be called before DOM is fully loaded if (document.readyState && document.readyState !== 'loading') { -- cgit v1.2.3 From cd9a9a93099b80fb3f8c2ba09266aa31955cbdd6 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 25 Dec 2018 15:34:25 +0100 Subject: First version of batch scroll as read Mark-as-read requests are queued and sent max once per second --- p/scripts/main.js | 109 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 71 insertions(+), 38 deletions(-) (limited to 'p/scripts') diff --git a/p/scripts/main.js b/p/scripts/main.js index 555e92a40..a3a9317d6 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -161,22 +161,15 @@ function incUnreadsTag(tag_id, nb) { } } -var pending_entries = {}; +var pending_entries = {}, + mark_read_queue = []; -function mark_read(div, only_not_read) { - if (!div || !div.id || context.anonymous || - (only_not_read && !div.classList.contains('not_read'))) { - return false; +function send_mark_read_queue(queue, asRead) { + let url = '.?c=entry&a=read' + (asRead ? '' : '&is_read=0'); + for (let i = queue.length - 1; i >= 0; i--) { + url += '&id[]=' + queue[i]; } - if (pending_entries[div.id]) { - return false; - } - pending_entries[div.id] = true; - - let url = '.?c=entry&a=read&id=' + div.id.replace(/^flux_/, '') + - (div.classList.contains('not_read') ? '' : '&is_read=0'); - $.ajax({ type: 'POST', url: url, @@ -185,42 +178,75 @@ function mark_read(div, only_not_read) { _csrf: context.csrf, }, }).done(function (data) { - let inc = 0; - if (div.classList.contains('not_read')) { - div.classList.remove('not_read'); - div.querySelectorAll('a.read').forEach(function (a) { a.setAttribute('href', a.getAttribute('href').replace('&is_read=0', '') + '&is_read=1'); }); - div.querySelectorAll('a.read > .icon').forEach(function (img) { img.outerHTML = icons.read; }); - inc--; - } else { - div.classList.add('not_read', 'keep_unread'); - div.querySelectorAll('a.read').forEach(function (a) { a.setAttribute('href', a.getAttribute('href').replace('&is_read=1', '')); }); - div.querySelectorAll('a.read > .icon').forEach(function (img) { img.outerHTML = icons.unread; }); - inc++; - } - - let feed_link = div.querySelector('.website > a'); - if (feed_link) { - let feed_url = feed_link.getAttribute('href'); - let feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); - incUnreadsFeed(div, feed_id, inc); + for (let i = queue.length - 1; i >= 0; i--) { + const div = document.getElementById('flux_' + queue[i]), + myIcons = icons; + let inc = 0; + if (div.classList.contains('not_read')) { + div.classList.remove('not_read'); + div.querySelectorAll('a.read').forEach(function (a) { a.setAttribute('href', a.getAttribute('href').replace('&is_read=0', '') + '&is_read=1'); }); + div.querySelectorAll('a.read > .icon').forEach(function (img) { img.outerHTML = myIcons.read; }); + inc--; + } else { + div.classList.add('not_read', 'keep_unread'); + div.querySelectorAll('a.read').forEach(function (a) { a.setAttribute('href', a.getAttribute('href').replace('&is_read=1', '')); }); + div.querySelectorAll('a.read > .icon').forEach(function (img) { img.outerHTML = myIcons.unread; }); + inc++; + } + let feed_link = div.querySelector('.website > a'); + if (feed_link) { + let feed_url = feed_link.getAttribute('href'); + let feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); + incUnreadsFeed(div, feed_id, inc); + } + delete pending_entries[queue[i]]; } faviconNbUnread(); - if (data.tags) { let tagIds = Object.keys(data.tags); for (let i = tagIds.length - 1; i >= 0; i--) { let tagId = tagIds[i]; - incUnreadsTag(tagId, inc * data.tags[tagId].length); + incUnreadsTag(tagId, (asRead ? -1 : 1) * data.tags[tagId].length); } } - - delete pending_entries[div.id]; }).fail(function (data) { openNotification(i18n.notif_request_failed, 'bad'); - delete pending_entries[div.id]; + for (let i = queue.length - 1; i >= 0; i--) { + delete pending_entries[queue[i]]; + } }); } +var send_mark_read_queue_timeout = 0; + +function mark_read(div, only_not_read) { + if (!div || !div.id || context.anonymous || + (only_not_read && !div.classList.contains('not_read'))) { + return false; + } + const entryId = div.id.replace(/^flux_/, ''); + if (pending_entries[entryId]) { + return false; + } + pending_entries[entryId] = true; + + const asRead = div.classList.contains('not_read'); + if (asRead) { + mark_read_queue.push(entryId); + if (send_mark_read_queue_timeout == 0) { + send_mark_read_queue_timeout = setTimeout(function () { + send_mark_read_queue_timeout = 0; + const queue = mark_read_queue.slice(0); + mark_read_queue = []; + send_mark_read_queue(queue, asRead); + }, 1000); + } + } else { + const queue = [ entryId ]; + send_mark_read_queue(queue, asRead); + } +} + function mark_favorite(div) { if (!div) { return false; @@ -1211,8 +1237,15 @@ function load_more_posts() { init_load_more(box_load_more); - document.getElementById('load_more').classList.remove('loading'); - document.getElementById('bigMarkAsRead').removeAttribute('disabled'); + const bigMarkAsRead = document.getElementById('bigMarkAsRead'), + div_load_more = document.getElementById('load_more'); + if (bigMarkAsRead) { + bigMarkAsRead.removeAttribute('disabled'); + } + if (div_load_more) { + div_load_more.classList.remove('loading'); + } + load_more = false; }); } -- cgit v1.2.3 From 6fa09318ce4d510535c7c13723502b9917a78e85 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 25 Dec 2018 16:09:48 +0100 Subject: Semove superfluous window. object --- p/scripts/main.js | 56 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'p/scripts') diff --git a/p/scripts/main.js b/p/scripts/main.js index a3a9317d6..d6d018bda 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -500,7 +500,7 @@ function user_filter(key) { return; } // Display the filter div - window.location.hash = filter.attr('id'); + location.hash = filter.attr('id'); // Force scrolling to the filter div const scroll = needsScroll($('.header')); if (scroll !== 0) { @@ -528,7 +528,7 @@ function auto_share(key) { return; } // Display the share div - window.location.hash = $share.attr('id'); + location.hash = $share.attr('id'); // Force scrolling to the share div const scroll = needsScroll($share.closest('.bottom')); if (scroll !== 0) { @@ -566,12 +566,12 @@ function init_posts() { let lastScroll = 0, //Throttle timerId = 0; $box_to_follow.scroll(function () { - window.clearTimeout(timerId); + clearTimeout(timerId); if (lastScroll + 500 < Date.now()) { lastScroll = Date.now(); scrollAsRead($box_to_follow); } else { - timerId = window.setTimeout(function() { + timerId = setTimeout(function () { scrollAsRead($box_to_follow); }, 500); } @@ -600,7 +600,7 @@ function init_column_categories() { } $('#aside_feed').on('click', '.tree-folder>.tree-folder-title>a.dropdown-toggle', function () { - $(this).children().each(function() { + $(this).children().each(function () { if (this.alt === '▽') { this.src = this.src.replace('/icons/down.', '/icons/up.'); this.alt = '△'; @@ -643,11 +643,11 @@ function init_column_categories() { } function init_shortcuts() { - if (!(window.shortcut && window.shortcuts)) { + if (!(window.shortcut)) { if (window.console) { console.log('FreshRSS waiting for shortcut.js…'); } - window.setTimeout(init_shortcuts, 200); + setTimeout(init_shortcuts, 200); return; } // Manipulation shortcuts @@ -795,7 +795,7 @@ function init_shortcuts() { }); shortcut.add(shortcuts.close_dropdown, function () { - window.location.hash = null; + location.hash = null; }, { 'disable_in_input': true }); @@ -1017,7 +1017,7 @@ function updateFeed(feeds, feeds_count) { noCommit: 0, }, }).always(function (data) { - window.location.reload(); + location.reload(); }); } else { updateFeed(feeds, feeds_count); @@ -1092,15 +1092,15 @@ function openNotification(msg, status) { $notification.find('.msg').html(msg); $notification.fadeIn(300); - notification_interval = window.setTimeout(closeNotification, 4000); + notification_interval = setTimeout(closeNotification, 4000); } function closeNotification() { - $notification.fadeOut(600, function() { + $notification.fadeOut(600, function () { $notification.removeClass(); $notification.addClass('closed'); - window.clearInterval(notification_interval); + clearInterval(notification_interval); notification_working = false; }); } @@ -1115,7 +1115,7 @@ function init_notifications() { if ($notification.find('.msg').html().length > 0) { notification_working = true; - notification_interval = window.setTimeout(closeNotification, 4000); + notification_interval = setTimeout(closeNotification, 4000); } } // @@ -1144,14 +1144,14 @@ function notifs_html5_show(nb) { tag: 'freshRssNewArticles', }); - notification.onclick = function() { - window.location.reload(); + notification.onclick = function () { + location.reload(); window.focus(); notification.close(); }; if (context.html5_notif_timeout !== 0) { - setTimeout(function() { + setTimeout(function () { notification.close(); }, context.html5_notif_timeout * 1000); } @@ -1171,7 +1171,7 @@ function refreshUnreads() { const isAll = document.querySelector('.category.all.active'); let new_articles = false; - $.each(data.feeds, function(feed_id, nbUnreads) { + $.each(data.feeds, function (feed_id, nbUnreads) { feed_id = 'f_' + feed_id; const elem = document.getElementById(feed_id), feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0; @@ -1185,7 +1185,7 @@ function refreshUnreads() { let nbUnreadTags = 0; - $.each(data.tags, function(tag_id, nbUnreads) { + $.each(data.tags, function (tag_id, nbUnreads) { nbUnreadTags += nbUnreads; $('#t_' + tag_id).attr('data-unread', nbUnreads) .children('.item-title').attr('data-unread', numberFormat(nbUnreads)); @@ -1298,11 +1298,11 @@ function init_crypto_form() { if (window.console) { console.log('FreshRSS waiting for bcrypt.js…'); } - window.setTimeout(init_crypto_form, 100); + setTimeout(init_crypto_form, 100); return; } - $crypto_form.on('submit', function() { + $crypto_form.on('submit', function () { const $submit_button = $(this).find('button[type="submit"]'); $submit_button.attr('disabled', ''); @@ -1329,7 +1329,7 @@ function init_crypto_form() { openNotification('Crypto exception! ' + e, 'bad'); } } - }).fail(function() { + }).fail(function () { openNotification('Communication error!', 'bad'); }); @@ -1402,7 +1402,7 @@ function init_share_observers() { } function init_stats_observers() { - $('.select-change').on('change', function(e) { + $('.select-change').on('change', function (e) { redirect($(this).find(':selected').data('url')); }); } @@ -1488,7 +1488,7 @@ function init_slider_observers() { return; } - $('.post').on('click', '.open-slider', function() { + $('.post').on('click', '.open-slider', function () { if (ajax_loading) { return false; } @@ -1509,7 +1509,7 @@ function init_slider_observers() { return false; }); - $closer.on('click', function() { + $closer.on('click', function () { $closer.removeClass('active'); $slider.removeClass('active'); return false; @@ -1550,7 +1550,7 @@ function init_normal() { if (window.console) { console.log('FreshRSS waiting for content…'); } - window.setTimeout(init_normal, 100); + setTimeout(init_normal, 100); return; } init_column_categories(); @@ -1565,7 +1565,7 @@ function init_beforeDOM() { if (window.console) { console.log('FreshRSS waiting for jQuery…'); } - window.setTimeout(init_beforeDOM, 100); + setTimeout(init_beforeDOM, 100); return; } if (['normal', 'reader', 'global'].indexOf(context.current_view) >= 0) { @@ -1578,7 +1578,7 @@ function init_afterDOM() { if (window.console) { console.log('FreshRSS waiting again for jQuery…'); } - window.setTimeout(init_afterDOM, 100); + setTimeout(init_afterDOM, 100); return; } init_notifications(); @@ -1592,7 +1592,7 @@ function init_afterDOM() { init_print_action(); init_post_action(); init_notifs_html5(); - window.setInterval(refreshUnreads, 120000); + setInterval(refreshUnreads, 120000); } else { init_subscription(); init_crypto_form(); -- cgit v1.2.3 From 8f03b370cc79f275e92b04ca6f25ef2b13fa867f Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 25 Dec 2018 16:10:20 +0100 Subject: Send item queue as POST Which also simplifies the request --- p/scripts/main.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'p/scripts') diff --git a/p/scripts/main.js b/p/scripts/main.js index d6d018bda..5d5679839 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -165,17 +165,13 @@ var pending_entries = {}, mark_read_queue = []; function send_mark_read_queue(queue, asRead) { - let url = '.?c=entry&a=read' + (asRead ? '' : '&is_read=0'); - for (let i = queue.length - 1; i >= 0; i--) { - url += '&id[]=' + queue[i]; - } - $.ajax({ type: 'POST', - url: url, + url: '.?c=entry&a=read' + (asRead ? '' : '&is_read=0'), data: { ajax: true, _csrf: context.csrf, + 'id[]': queue, }, }).done(function (data) { for (let i = queue.length - 1; i >= 0; i--) { -- cgit v1.2.3 From caa893e14b46bc9b52f251ca93eada0c57634302 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 27 Dec 2018 03:34:56 +0100 Subject: Optimise onscroll routines Much lighter rework: auto-mark-as-read, auto-remove-articles, auto-load-more. In particular, use a single onscroll event handler with a throtte. Continue removing jQuery when possible. --- p/scripts/main.js | 350 ++++++++++++++++++++++++------------------------------ 1 file changed, 157 insertions(+), 193 deletions(-) (limited to 'p/scripts') diff --git a/p/scripts/main.js b/p/scripts/main.js index 5d5679839..227a4b47a 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -5,17 +5,15 @@ // if (!NodeList.prototype.forEach) NodeList.prototype.forEach = Array.prototype.forEach; if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.webkitMatchesSelector; -if (!Element.prototype.closest) { - Element.prototype.closest = function (s) { +if (!Element.prototype.closest) Element.prototype.closest = function (s) { let el = this; - if (!document.documentElement.contains(el)) return null; do { if (el.matches(s)) return el; - el = el.parentElement || el.parentNode; - } while (el !== null && el.nodeType == 1); + el = el.parentElement; + } while (el); return null; }; -} +if (!Element.prototype.remove) Element.prototype.remove = function () { if (this.parentNode) this.parentNode.removeChild(this); }; // // @@ -36,7 +34,6 @@ var context, i18n, icons, shortcuts, urls; var $stream = null, ajax_loading = false, - isCollapsed = true, $nav_entries = null; // @@ -50,14 +47,11 @@ function redirect(url, new_tab) { } } -function needsScroll($elem) { - const $win = $(window), - winTop = $win.scrollTop(), - winHeight = $win.height(), - winBottom = winTop + winHeight, - elemTop = $elem.offset().top, - elemBottom = elemTop + $elem.outerHeight(); - return (elemTop < winTop || elemBottom > winBottom) ? elemTop - (winHeight / 2) : 0; +function needsScroll(elem) { + const winBottom = document.documentElement.scrollTop + document.documentElement.clientHeight, + elemBottom = elem.offsetTop + elem.offsetHeight; + return (elem.offsetTop < document.documentElement.scrollTop || elemBottom > winBottom) ? + elem.offsetTop - (document.documentElement.clientHeight / 2) : 0; } function str2int(str) { @@ -134,7 +128,7 @@ function incUnreadsFeed(article, feed_id, nb) { // Update unread: title document.title = document.title.replace(/^((?:\([ 0-9]+\) )?)/, function (m, p1) { const feed = document.getElementById(feed_id); - if (article || (feed.closest('.active') && $(feed).siblings('.active').length === 0)) { + if (article || feed.closest('.active')) { isCurrentView = true; return incLabel(p1, nb, true); } else if (document.querySelector('.all.active')) { @@ -195,7 +189,7 @@ function send_mark_read_queue(queue, asRead) { let feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); incUnreadsFeed(div, feed_id, inc); } - delete pending_entries[queue[i]]; + delete pending_entries['flux_' + queue[i]]; } faviconNbUnread(); if (data.tags) { @@ -205,10 +199,11 @@ function send_mark_read_queue(queue, asRead) { incUnreadsTag(tagId, (asRead ? -1 : 1) * data.tags[tagId].length); } } + onScroll(); }).fail(function (data) { openNotification(i18n.notif_request_failed, 'bad'); for (let i = queue.length - 1; i >= 0; i--) { - delete pending_entries[queue[i]]; + delete pending_entries['flux_' + queue[i]]; } }); } @@ -220,13 +215,13 @@ function mark_read(div, only_not_read) { (only_not_read && !div.classList.contains('not_read'))) { return false; } - const entryId = div.id.replace(/^flux_/, ''); - if (pending_entries[entryId]) { + if (pending_entries[div.id]) { return false; } - pending_entries[entryId] = true; + pending_entries[div.id] = true; - const asRead = div.classList.contains('not_read'); + const asRead = div.classList.contains('not_read'), + entryId = div.id.replace(/^flux_/, ''); if (asRead) { mark_read_queue.push(entryId); if (send_mark_read_queue_timeout == 0) { @@ -278,8 +273,8 @@ function mark_favorite(div) { div.querySelectorAll('a.bookmark').forEach(function (a) { a.setAttribute('href', data.url); }); div.querySelectorAll('a.bookmark > .icon').forEach(function (img) { img.outerHTML = data.icon; }); - const favourites = $('#aside_feed .favorites .title').contents().last().get(0); - if (favourites && favourites.textContent) { + const favourites = document.querySelector('#aside_feed .favorites .title'); + if (favourites) { favourites.textContent = favourites.textContent.replace(/((?: \([ 0-9]+\))?\s*)$/, function (m, p1) { return incLabel(p1, inc, false); }); @@ -300,117 +295,77 @@ function mark_favorite(div) { }); } -function toggleContent($new_active, $old_active, skipping) { +function toggleContent(new_active, old_active, skipping) { // If skipping, move current without activating or marking as read - if ($new_active.length === 0) { + if (!new_active) { return; } if (context.does_lazyload && !skipping) { - $new_active.find('img[data-original], iframe[data-original]').each(function () { - this.setAttribute('src', this.getAttribute('data-original')); - this.removeAttribute('data-original'); + new_active.querySelectorAll('img[data-original], iframe[data-original]').forEach(function (elem) { + elem.setAttribute('src', elem.getAttribute('data-original')); + elem.removeAttribute('data-original'); }); } - if ($old_active[0] !== $new_active[0]) { - if (isCollapsed && !skipping) { // BUG?: isCollapsed can only ever be true - $new_active.addClass('active'); + if (old_active !== new_active) { + if (!skipping) { + new_active.classList.add('active'); } - $old_active.removeClass('active current'); - $new_active.addClass('current'); - if (context.auto_remove_article && !$old_active.hasClass('not_read') && !skipping) { - auto_remove($old_active); + new_active.classList.add('current'); + if (old_active) { + old_active.classList.remove('active'); + old_active.classList.remove('current'); //Split for IE11 } } else { // collapse_entry calls toggleContent(flux_current, flux_current, false) - $new_active.toggleClass('active'); + new_active.classList.toggle('active'); } const relative_move = context.current_view === 'global', - $box_to_move = $(relative_move ? '#panel' : 'html,body'); + box_to_move = relative_move ? document.getElementById('#panel') : document.documentElement; if (context.sticky_post) { - let prev_article = $new_active.prevAll('.flux'), - new_pos = $new_active.offset().top, - old_scroll = $box_to_move.scrollTop(); + let prev_article = new_active.previousElementSibling, + new_pos = new_active.offsetTop + document.documentElement.scrollTop, + old_scroll = box_to_move.scrollTop; - if (prev_article.length > 0 && new_pos - prev_article.offset().top <= 150) { - new_pos = prev_article.offset().top; + if (prev_article && new_active.offsetTop - prev_article.offsetTop <= 150) { + new_pos = prev_article.offsetTop; if (relative_move) { - new_pos -= $box_to_move.offset().top; + new_pos -= box_to_move.offsetTop; } } if (skipping) { // when skipping, this feels more natural if it's not so near the top - new_pos -= $(window).height() / 4; + new_pos -= document.body.clientHeight / 4; } - if (context.hide_posts) { - if (relative_move) { - new_pos += old_scroll; - } - - $new_active.children('.flux_content').first().each(function () { - $box_to_move.scrollTop(new_pos).scrollTop(); - }); - } else { - if (relative_move) { - new_pos += old_scroll; - } - - $box_to_move.scrollTop(new_pos).scrollTop(); + if (relative_move) { + new_pos += old_scroll; } + box_to_move.scrollTop = new_pos; } - if (context.auto_mark_article && $new_active.hasClass('active') && !skipping) { - mark_read($new_active[0], true); + if (context.auto_mark_article && new_active.classList.contains('active') && !skipping) { + mark_read(new_active, true); } + onScroll(); } -function auto_remove($element) { - let $p = $element.prev(), - $n = $element.next(); - if ($p.hasClass('day') && $n.hasClass('day')) { - $p.remove(); - } - $element.remove(); - $('#stream > .flux:not(.not_read):not(.active)').remove(); +function prev_entry(skipping) { + const old_active = document.querySelector('.flux.current'), + new_active = old_active ? old_active.previousElementSibling : document.querySelector('.flux'); + toggleContent(new_active, old_active, skipping); } -function prev_entry() { - let $old_active = $('.flux.current'), - $new_active = $old_active.length === 0 ? $('.flux:last') : $old_active.prevAll('.flux:first'); - toggleContent($new_active, $old_active, false); -} - -function next_entry() { - let $old_active = $('.flux.current'), - $new_active = $old_active.length === 0 ? $('.flux:first') : $old_active.nextAll('.flux:first'); - toggleContent($new_active, $old_active, false); - - if ($new_active.nextAll().length < 3) { - load_more_posts(); - } -} - -function skip_prev_entry() { - let $old_active = $('.flux.current'), - $new_active = $old_active.length === 0 ? $('.flux:last') : $old_active.prevAll('.flux:first'); - toggleContent($new_active, $old_active, true); -} - -function skip_next_entry() { - let $old_active = $('.flux.current'), - $new_active = $old_active.length === 0 ? $('.flux:first') : $old_active.nextAll('.flux:first'); - toggleContent($new_active, $old_active, true); - - if ($new_active.nextAll().length < 3) { - load_more_posts(); - } +function next_entry(skipping) { + const old_active = document.querySelector('.flux.current'), + new_active = old_active ? old_active.nextElementSibling : document.querySelector('.flux'); + toggleContent(new_active, old_active, skipping); } function prev_feed() { - let $active_feed = $('#aside_feed .tree-folder-items .item.active'); + const $active_feed = $('#aside_feed .tree-folder-items .item.active'); if ($active_feed.length > 0) { $active_feed.prevAll(':visible:first').find('a').each(function () { this.click(); }); } else { @@ -419,7 +374,7 @@ function prev_feed() { } function next_feed() { - let $active_feed = $('#aside_feed .tree-folder-items .item.active'); + const $active_feed = $('#aside_feed .tree-folder-items .item.active'); if ($active_feed.length > 0) { $active_feed.nextAll(':visible:first').find('a').each(function () { this.click(); }); } else { @@ -428,24 +383,24 @@ function next_feed() { } function first_feed() { - let $feed = $('#aside_feed .tree-folder-items.active .item:visible:first'); - if ($feed.length > 0) { - $feed.find('a')[1].click(); + const a = document.querySelector('#aside_feed .category.active .feed:not([data-unread="0"]) a.item-title'); + if (a) { + a.click(); } } function last_feed() { - let $feed = $('#aside_feed .tree-folder-items.active .item:visible:last'); - if ($feed.length > 0) { - $feed.find('a')[1].click(); + const links = document.querySelectorAll('#aside_feed .category.active .feed:not([data-unread="0"]) a.item-title'); + if (links && links.length > 0) { + links[links.length - 1].click(); } } function prev_category() { - let $active_cat = $('#aside_feed .tree-folder.active'); + const $active_cat = $('#aside_feed .tree-folder.active'); if ($active_cat.length > 0) { - let $prev_cat = $active_cat.prevAll(':visible:first').find('.tree-folder-title .title'); + const $prev_cat = $active_cat.prevAll(':visible:first').find('.tree-folder-title .title'); if ($prev_cat.length > 0) { $prev_cat[0].click(); } @@ -456,10 +411,10 @@ function prev_category() { } function next_category() { - let $active_cat = $('#aside_feed .tree-folder.active'); + const $active_cat = $('#aside_feed .tree-folder.active'); if ($active_cat.length > 0) { - let $next_cat = $active_cat.nextAll(':visible:first').find('.tree-folder-title .title'); + const $next_cat = $active_cat.nextAll(':visible:first').find('.tree-folder-title .title'); if ($next_cat.length > 0) { $next_cat[0].click(); } @@ -470,40 +425,40 @@ function next_category() { } function first_category() { - let $cat = $('#aside_feed .tree-folder:visible:first'); - if ($cat.length > 0) { - $cat.find('.tree-folder-title .title')[0].click(); + const a = document.querySelector('#aside_feed .category:not([data-unread="0"]) a.title'); + if (a) { + a.click(); } } function last_category() { - let $cat = $('#aside_feed .tree-folder:visible:last'); - if ($cat.length > 0) { - $cat.find('.tree-folder-title .title')[0].click(); + const links = document.querySelectorAll('#aside_feed .category:not([data-unread="0"]) a.title'); + if (links && links.length > 0) { + links[links.length - 1].click(); } } function collapse_entry() { - let $flux_current = $('.flux.current'); - toggleContent($flux_current, $flux_current, false); + const flux_current = document.querySelector('.flux.current'); + toggleContent(flux_current, flux_current, false); } function user_filter(key) { - const filter = $('#dropdown-query'), - filters = filter.siblings('.dropdown-menu').find('.item.query a'); + const $filter = $('#dropdown-query'), + $filters = $filter.siblings('.dropdown-menu').find('.item.query a'); if (typeof key === 'undefined') { - if (!filter.length) { + if (!$filters.length) { return; } // Display the filter div - location.hash = filter.attr('id'); + location.hash = $filters.attr('id'); // Force scrolling to the filter div - const scroll = needsScroll($('.header')); + const scroll = needsScroll(document.querySelector('.header')); if (scroll !== 0) { - $('html,body').scrollTop(scroll); + document.documentElement.scrollTop = scroll; } // Force the key value if there is only one action, so we can trigger it automatically - if (filters.length === 1) { + if ($filters.length === 1) { key = 1; } else { return; @@ -511,27 +466,27 @@ function user_filter(key) { } // Trigger selected share action key = parseInt(key); - if (key <= filters.length) { - filters[key - 1].click(); + if (key <= $filters.length) { + $filters[key - 1].click(); } } function auto_share(key) { - const $share = $('.flux.current.active').find('.dropdown-target[id^="dropdown-share"]'), - $shares = $share.siblings('.dropdown-menu').find('.item a'); + const share = document.querySelector('.flux.current.active .dropdown-target[id^="dropdown-share"]'); + if (!share) { + return; + } + const shares = share.parentElement.querySelectorAll('.dropdown-menu .item a'); if (typeof key === 'undefined') { - if (!$share.length) { - return; - } // Display the share div - location.hash = $share.attr('id'); + location.hash = share.id; // Force scrolling to the share div - const scroll = needsScroll($share.closest('.bottom')); - if (scroll !== 0) { - $('html,body').scrollTop(scroll); + const scrollTop = needsScroll(share.closest('.bottom')); + if (scrollTop !== 0) { + document.documentElement.scrollTop = scrollTop; } // Force the key value if there is only one action, so we can trigger it automatically - if ($shares.length === 1) { + if (shares.length === 1) { key = 1; } else { return; @@ -539,54 +494,72 @@ function auto_share(key) { } // Trigger selected share action and hide the share div key = parseInt(key); - if (key <= $shares.length) { - $shares[key - 1].click(); - $share.siblings('.dropdown-menu').find('.dropdown-close a')[0].click(); + if (key <= shares.length) { + shares[key - 1].click(); + share.parentElement.querySelector('.dropdown-menu .dropdown-close a').click(); } } -function scrollAsRead($box_to_follow) { - const minTop = 40 + (context.current_view === 'global' ? $box_to_follow.offset().top : $box_to_follow.scrollTop()); - $('.not_read:not(.keep_unread):visible').each(function () { - const $this = $(this); - if ($this.offset().top + $this.height() < minTop) { - mark_read(this, true); - } - }); +var box_to_follow; + +function onScroll() { + if (!box_to_follow) { + return; + } + if (context.auto_mark_scroll) { + const minTop = 40 + box_to_follow.scrollTop; + document.querySelectorAll('.not_read:not(.keep_unread)').forEach(function (div) { + if (div.offsetHeight > 0 && + div.offsetParent.offsetTop + div.offsetTop + div.offsetHeight < minTop) { + mark_read(div, true); + } + }); + } + if (context.auto_remove_article) { + let maxTop = box_to_follow.scrollTop, + scrollOffset = 0; + document.querySelectorAll('.flux:not(.active):not(.keep_unread)').forEach(function (div) { + if (!pending_entries[div.id] && div.offsetHeight > 0 && + div.offsetParent.offsetTop + div.offsetTop + div.offsetHeight < maxTop) { + const p = div.previousElementSibling, + n = div.nextElementSibling; + if (p && p.classList.contains('day') && n && n.classList.contains('day')) { + p.remove(); + } + maxTop -= div.offsetHeight; + scrollOffset -= div.offsetHeight; + div.remove(); + } + }); + if (scrollOffset != 0) { + box_to_follow.scrollTop += scrollOffset; + return; //onscroll will be called again + } + } + if (context.auto_load_more) { + const load_more = document.getElementById('mark-read-pagination'); + if (load_more && box_to_follow.scrollTop > 0 && + box_to_follow.scrollTop + box_to_follow.offsetHeight >= load_more.offsetTop) { + load_more_posts(); + } + } } function init_posts() { - let $box_to_follow = context.current_view === 'global' ? $('#panel') : $(window); - - if (context.auto_mark_scroll) { + if (context.auto_load_more || context.auto_mark_scroll || context.auto_remove_article) { + box_to_follow = context.current_view === 'global' ? document.getElementById('panel') : document.documentElement; let lastScroll = 0, //Throttle timerId = 0; - $box_to_follow.scroll(function () { + (box_to_follow === document.documentElement ? window : box_to_follow).onscroll = function () { clearTimeout(timerId); if (lastScroll + 500 < Date.now()) { lastScroll = Date.now(); - scrollAsRead($box_to_follow); + onScroll(); } else { - timerId = setTimeout(function () { - scrollAsRead($box_to_follow); - }, 500); - } - }); - } - - if (context.auto_load_more) { - $box_to_follow.scroll(function () { - const $load_more = $('#load_more'); - if (!$load_more.is(':visible')) { - return; + timerId = setTimeout(onScroll, 500); } - const boxBot = $box_to_follow.scrollTop() + $box_to_follow.height(), - load_more_top = $load_more.offset().top; - if (boxBot >= load_more_top) { - load_more_posts(); - } - }); - $box_to_follow.scroll(); + }; + onScroll(); } } @@ -699,10 +672,10 @@ function init_shortcuts() { } // Entry navigation shortcuts - shortcut.add(shortcuts.prev_entry, prev_entry, { + shortcut.add(shortcuts.prev_entry, function () { prev_entry(false); }, { 'disable_in_input': true }); - shortcut.add(shortcuts.skip_prev_entry, skip_prev_entry, { + shortcut.add(shortcuts.skip_prev_entry, function () { prev_entry(true); }, { 'disable_in_input': true }); shortcut.add(shortcuts.first_entry, function () { @@ -715,10 +688,10 @@ function init_shortcuts() { }, { 'disable_in_input': true }); - shortcut.add(shortcuts.next_entry, next_entry, { + shortcut.add(shortcuts.next_entry, function () { next_entry(false); }, { 'disable_in_input': true }); - shortcut.add(shortcuts.skip_next_entry, skip_next_entry, { + shortcut.add(shortcuts.skip_next_entry, function () { next_entry(true); }, { 'disable_in_input': true }); shortcut.add(shortcuts.last_entry, function () { @@ -772,15 +745,11 @@ function init_shortcuts() { 'disable_in_input': true }); - shortcut.add(shortcuts.load_more, function () { - load_more_posts(); - }, { + shortcut.add(shortcuts.load_more, load_more_posts, { 'disable_in_input': true }); - shortcut.add(shortcuts.focus_search, function () { - focus_search(); - }, { + shortcut.add(shortcuts.focus_search, focus_search, { 'disable_in_input': true }); @@ -832,22 +801,17 @@ function init_stream(divStream) { } const old_active = document.querySelector('.flux.current'), new_active = this.parentNode; - isCollapsed = true; if (e.target.tagName.toUpperCase() === 'A') { //Leave real links alone if (context.auto_mark_article) { mark_read(new_active, true); } return true; } - toggleContent($(new_active), $(old_active), false); + toggleContent(new_active, old_active, false); }); divStream.on('click', '.flux a.read', function () { - const $active = $(this).parents('.flux'); - if (context.auto_remove_article && $active.hasClass('not_read')) { - auto_remove($active); - } - mark_read($active[0], false); + mark_read(this.closest('.flux'), false); return false; }); @@ -872,7 +836,7 @@ function init_stream(divStream) { const ev = jQuery.Event('click'); ev.ctrlKey = true; $(this).trigger(ev); - } else if(e.which == 1) { + } else if (e.which == 1) { // Normal click, just toggle article. $(this).parent().click(); } @@ -900,11 +864,11 @@ function init_stream(divStream) { function init_nav_entries() { $nav_entries = $('#nav_entries'); $nav_entries.find('.previous_entry').click(function () { - prev_entry(); + prev_entry(false); return false; }); $nav_entries.find('.next_entry').click(function () { - next_entry(); + next_entry(false); return false; }); $nav_entries.find('.up').click(function () { -- cgit v1.2.3 From f9555db678679d04fdc28bb2d31eb00135209a16 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Thu, 27 Dec 2018 03:49:20 +0100 Subject: IE11 fixes --- p/scripts/main.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'p/scripts') diff --git a/p/scripts/main.js b/p/scripts/main.js index 227a4b47a..7b49ebeb2 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -49,9 +49,10 @@ function redirect(url, new_tab) { function needsScroll(elem) { const winBottom = document.documentElement.scrollTop + document.documentElement.clientHeight, - elemBottom = elem.offsetTop + elem.offsetHeight; - return (elem.offsetTop < document.documentElement.scrollTop || elemBottom > winBottom) ? - elem.offsetTop - (document.documentElement.clientHeight / 2) : 0; + elemTop = elem.offsetParent.offsetTop + elem.offsetTop, + elemBottom = elemTop + elem.offsetHeight; + return (elemTop < document.documentElement.scrollTop || elemBottom > winBottom) ? + elemTop - (document.documentElement.clientHeight / 2) : 0; } function str2int(str) { @@ -178,7 +179,8 @@ function send_mark_read_queue(queue, asRead) { div.querySelectorAll('a.read > .icon').forEach(function (img) { img.outerHTML = myIcons.read; }); inc--; } else { - div.classList.add('not_read', 'keep_unread'); + div.classList.add('not_read'); + div.classList.add('keep_unread'); //Split for IE11 div.querySelectorAll('a.read').forEach(function (a) { a.setAttribute('href', a.getAttribute('href').replace('&is_read=1', '')); }); div.querySelectorAll('a.read > .icon').forEach(function (img) { img.outerHTML = myIcons.unread; }); inc++; -- cgit v1.2.3