From d9e14621b5a0de1c189486bbc8c18a7b007d6965 Mon Sep 17 00:00:00 2001 From: romibi Date: Fri, 8 Jul 2016 19:12:43 +0200 Subject: Make Sidebar Sticky --- p/scripts/main.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'p/scripts/main.js') diff --git a/p/scripts/main.js b/p/scripts/main.js index f1b82900e..7ff43343e 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -508,7 +508,7 @@ function init_column_categories() { this.alt = '▽'; } }); - $(this).parent().next(".tree-folder-items").slideToggle(); + $(this).parent().next(".tree-folder-items").slideToggle( 400 , function() { $(document.body).trigger("sticky_kit:recalc"); } ); return false; }); $('#aside_feed').on('click', '.tree-folder-items .item .dropdown-toggle', function () { @@ -519,6 +519,9 @@ function init_column_categories() { $(this).attr('href', '#dropdown-' + feed_id).prev('.dropdown-target').attr('id', 'dropdown-' + feed_id).parent().append(template); } }); + if( $('.toggle_aside').css('display')=='none') { + $('#aside_feed .tree').stick_in_parent(); + } } function init_shortcuts() { -- cgit v1.2.3 From b382f266de0369352344324f88bc5d3dc136119d Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 2 Aug 2016 00:29:31 +0200 Subject: Fix bug articles not marked as read https://github.com/FreshRSS/FreshRSS/issues/1123 https://github.com/FreshRSS/FreshRSS/issues/423 --- p/scripts/main.js | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'p/scripts/main.js') diff --git a/p/scripts/main.js b/p/scripts/main.js index f1b82900e..c6e108ca1 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -113,7 +113,7 @@ function incUnreadsFeed(article, feed_id, nb) { return isCurrentView; } -var pending_feeds = []; +var pending_entries = {}; function mark_read(active, only_not_read) { if (active.length === 0 || (only_not_read === true && !active.hasClass("not_read"))) { @@ -126,14 +126,12 @@ function mark_read(active, only_not_read) { } var feed_url = active.find(".website>a").attr("href"), - feed_id = feed_url.substr(feed_url.lastIndexOf('f_')), - index_pending = pending_feeds.indexOf(feed_id); + feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); - if (index_pending !== -1) { + if (pending_entries[active.attr('id')]) { return false; } - - pending_feeds.push(feed_id); + pending_entries[active.attr('id')] = true; $.ajax({ type: 'POST', @@ -154,10 +152,10 @@ function mark_read(active, only_not_read) { incUnreadsFeed(active, feed_id, inc); faviconNbUnread(); - pending_feeds.splice(index_pending, 1); + delete pending_entries[active.attr('id')]; }).fail(function (data) { openNotification(i18n.notif_request_failed, 'bad'); - pending_feeds.splice(index_pending, 1); + delete pending_entries[active.attr('id')]; }); } @@ -172,14 +170,12 @@ function mark_favorite(active) { } var feed_url = active.find(".website>a").attr("href"), - feed_id = feed_url.substr(feed_url.lastIndexOf('f_')), - index_pending = pending_feeds.indexOf(feed_id); + feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); - if (index_pending !== -1) { + if (pending_entries[active.attr('id')]) { return false; } - - pending_feeds.push(feed_id); + pending_entries[active.attr('id')] = true; $.ajax({ type: 'POST', @@ -212,10 +208,10 @@ function mark_favorite(active) { } } - pending_feeds.splice(index_pending, 1); + delete pending_entries[active.attr('id')]; }).fail(function (data) { openNotification(i18n.notif_request_failed, 'bad'); - pending_feeds.splice(index_pending, 1); + delete pending_entries[active.attr('id')]; }); } -- cgit v1.2.3 From 75d2fa3fd325f98a98304e7b1e1bdb56bf0f2af7 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 2 Aug 2016 00:30:11 +0200 Subject: JS load optimization Start loading what we can already before DOM is ready --- p/scripts/main.js | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) (limited to 'p/scripts/main.js') diff --git a/p/scripts/main.js b/p/scripts/main.js index c6e108ca1..69d0e33da 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -1294,27 +1294,46 @@ function parseJsonVars() { window.icons = json.icons; } -function init_all() { +function init_beforeDOM() { if (!window.$) { if (window.console) { - console.log('FreshRSS waiting for JS…'); + console.log('FreshRSS waiting for jQuery…'); } - window.setTimeout(init_all, 50); + window.setTimeout(init_beforeDOM, 50); return; } - parseJsonVars(); - init_notifications(); init_confirm_action(); + if (['normal', 'reader', 'global'].indexOf(context['current_view']) >= 0) { + $stream = $('#stream'); + if ($stream.length < 1) { + if (window.console) { + console.log('FreshRSS waiting for content…'); + } + window.setTimeout(init_beforeDOM, 50); + return; + } + init_column_categories(); + init_stream($stream); + init_shortcuts(); + init_actualize(); + faviconNbUnread(); + } +} + +function init_afterDOM() { + if (!window.$) { + if (window.console) { + console.log('FreshRSS waiting again for jQuery…'); + } + window.setTimeout(init_afterDOM, 50); + return; + } + init_notifications(); $stream = $('#stream'); if ($stream.length > 0) { - init_actualize(); - init_column_categories(); init_load_more($stream); init_posts(); - init_stream($stream); init_nav_entries(); - init_shortcuts(); - faviconNbUnread(); init_print_action(); init_notifs_html5(); window.setInterval(refreshUnreads, 120000); @@ -1335,16 +1354,16 @@ function init_all() { } } +parseJsonVars(); +init_beforeDOM(); //Can be called before DOM is fully loaded + if (document.readyState && document.readyState !== 'loading') { - if (window.console) { - console.log('FreshRSS immediate init…'); - } - init_all(); + init_afterDOM(); } else if (document.addEventListener) { document.addEventListener('DOMContentLoaded', function () { if (window.console) { console.log('FreshRSS waiting for DOMContentLoaded…'); } - init_all(); + init_afterDOM(); }, false); } -- cgit v1.2.3 From 32b6ecc3afdc0cac3345ff89ee42f88c95c1775a Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 2 Aug 2016 00:42:07 +0200 Subject: JS unused variables, syntax --- p/scripts/main.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'p/scripts/main.js') diff --git a/p/scripts/main.js b/p/scripts/main.js index 69d0e33da..01c8c9cf5 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -125,9 +125,6 @@ function mark_read(active, only_not_read) { return false; } - var feed_url = active.find(".website>a").attr("href"), - feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); - if (pending_entries[active.attr('id')]) { return false; } @@ -149,6 +146,9 @@ function mark_read(active, only_not_read) { } $r.find('.icon').replaceWith(data.icon); + var feed_url = active.find(".website>a").attr("href"), + feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); + incUnreadsFeed(active, feed_id, inc); faviconNbUnread(); @@ -169,9 +169,6 @@ function mark_favorite(active) { return false; } - var feed_url = active.find(".website>a").attr("href"), - feed_id = feed_url.substr(feed_url.lastIndexOf('f_')); - if (pending_entries[active.attr('id')]) { return false; } @@ -901,7 +898,7 @@ function notifs_html5_show(nb) { notification.onclick = function() { window.location.reload(); - } + }; if (context['html5_notif_timeout'] !== 0) { setTimeout(function() { -- cgit v1.2.3 From 3652dea854200f31492a71243727f6a1be317c4a Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 6 Aug 2016 13:18:46 +0200 Subject: JSHint and safer async init_normal --- p/scripts/category.js | 4 +- p/scripts/global_view.js | 3 + p/scripts/install.js | 1 + p/scripts/main.js | 140 +++++++++++++++++++++++++---------------------- p/scripts/repartition.js | 18 +++--- p/scripts/stats.js | 3 + 6 files changed, 93 insertions(+), 76 deletions(-) (limited to 'p/scripts/main.js') diff --git a/p/scripts/category.js b/p/scripts/category.js index c33e68528..be9605bec 100644 --- a/p/scripts/category.js +++ b/p/scripts/category.js @@ -1,4 +1,6 @@ "use strict"; +/* globals i18n */ +/* jshint globalstrict: true */ var loading = false, dnd_successful = false; @@ -20,7 +22,7 @@ function dragend_process(t) { $(t).remove(); if (parent.children().length <= 0) { - parent.append('
  • ' + i18n['category_empty'] + '
  • '); + parent.append('
  • ' + i18n.category_empty + '
  • '); } } } diff --git a/p/scripts/global_view.js b/p/scripts/global_view.js index 7d7ba22b5..f1b9c8ad4 100644 --- a/p/scripts/global_view.js +++ b/p/scripts/global_view.js @@ -1,4 +1,7 @@ "use strict"; +/* globals init_load_more, init_posts, init_stream */ +/* jshint globalstrict: true */ + var panel_loading = false; function load_panel(link) { diff --git a/p/scripts/install.js b/p/scripts/install.js index 57fc2450a..d7f4e7b02 100644 --- a/p/scripts/install.js +++ b/p/scripts/install.js @@ -1,4 +1,5 @@ "use strict"; +/* jshint globalstrict: true */ function show_password() { var button = this; diff --git a/p/scripts/main.js b/p/scripts/main.js index 01c8c9cf5..21e26d6df 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -1,4 +1,7 @@ "use strict"; +/* globals context, i18n, shortcut, shortcuts, url */ +/* jshint globalstrict: true */ + var $stream = null, isCollapsed = true, shares = 0, @@ -49,9 +52,7 @@ function numberFormat(nStr) { function incLabel(p, inc, spaceAfter) { var i = str2int(p) + inc; - return i > 0 - ? ((spaceAfter ? '' : ' ') + '(' + numberFormat(i) + ')' + (spaceAfter ? ' ' : '')) - : ''; + return i > 0 ? ((spaceAfter ? '' : ' ') + '(' + numberFormat(i) + ')' + (spaceAfter ? ' ' : '')) : ''; } function incUnreadsFeed(article, feed_id, nb) { @@ -217,7 +218,7 @@ function toggleContent(new_active, old_active) { return; } - if (context['does_lazyload']) { + if (context.does_lazyload) { new_active.find('img[data-original], iframe[data-original]').each(function () { this.setAttribute('src', this.getAttribute('data-original')); this.removeAttribute('data-original'); @@ -230,17 +231,17 @@ function toggleContent(new_active, old_active) { } old_active.removeClass("active current"); new_active.addClass("current"); - if (context['auto_remove_article'] && !old_active.hasClass('not_read')) { + if (context.auto_remove_article && !old_active.hasClass('not_read')) { auto_remove(old_active); } } else { new_active.toggleClass('active'); } - var relative_move = context['current_view'] === 'global', + var relative_move = context.current_view === 'global', box_to_move = $(relative_move ? "#panel" : "html,body"); - if (context['sticky_post']) { + if (context.sticky_post) { var prev_article = new_active.prevAll('.flux'), new_pos = new_active.offset().top, old_scroll = box_to_move.scrollTop(); @@ -252,7 +253,7 @@ function toggleContent(new_active, old_active) { } } - if (context['hide_posts']) { + if (context.hide_posts) { if (relative_move) { new_pos += old_scroll; } @@ -271,7 +272,7 @@ function toggleContent(new_active, old_active) { } } - if (context['auto_mark_article'] && new_active.hasClass('active')) { + if (context.auto_mark_article && new_active.hasClass('active')) { mark_read(new_active, true); } } @@ -381,7 +382,7 @@ function collapse_entry() { var flux_current = $(".flux.current"); flux_current.toggleClass("active"); - if (isCollapsed && context['auto_mark_article']) { + if (isCollapsed && context.auto_mark_article) { mark_read(flux_current, true); } } @@ -456,11 +457,11 @@ function inMarkViewport(flux, box_to_follow) { function init_posts() { var box_to_follow = $(window); - if (context['current_view'] === 'global') { + if (context.current_view === 'global') { box_to_follow = $("#panel"); } - if (context['auto_mark_scroll']) { + if (context.auto_mark_scroll) { box_to_follow.scroll(function () { $('.not_read:visible').each(function () { if ($(this).children(".flux_content").is(':visible') && inMarkViewport($(this), box_to_follow)) { @@ -470,7 +471,7 @@ function init_posts() { }); } - if (context['auto_load_more']) { + if (context.auto_load_more) { box_to_follow.scroll(function () { var load_more = $("#load_more"); if (!load_more.is(':visible')) { @@ -487,7 +488,7 @@ function init_posts() { } function init_column_categories() { - if (context['current_view'] !== 'normal') { + if (context.current_view !== 'normal') { return; } @@ -559,14 +560,16 @@ function init_shortcuts() { }, { 'disable_in_input': true }); - for(var i = 1; i < 10; i++){ - shortcut.add(i.toString(), function (e) { - if ($('#dropdown-query').siblings('.dropdown-menu').is(':visible')) { - user_filter(String.fromCharCode(e.keyCode)); - } else { - auto_share(String.fromCharCode(e.keyCode)); - } - }, { + + function addShortcut(evt) { + if ($('#dropdown-query').siblings('.dropdown-menu').is(':visible')) { + user_filter(String.fromCharCode(evt.keyCode)); + } else { + auto_share(String.fromCharCode(evt.keyCode)); + } + } + for(var i = 1; i < 10; i++) { + shortcut.add(i.toString(), addShortcut, { 'disable_in_input': true }); } @@ -628,7 +631,7 @@ function init_shortcuts() { shortcut.add(shortcuts.go_website, function () { var url_website = $('.flux.current > .flux_header > .title > a').attr("href"); - if (context['auto_mark_site']) { + if (context.auto_mark_site) { $(".flux.current").each(function () { mark_read($(this), true); }); @@ -652,7 +655,7 @@ function init_shortcuts() { }); shortcut.add(shortcuts.help, function () { - redirect(url['help'], true); + redirect(url.help, true); }, { 'disable_in_input': true }); @@ -674,7 +677,7 @@ function init_stream(divStream) { new_active = $(this).parent(); isCollapsed = true; if (e.target.tagName.toUpperCase() === 'A') { //Leave real links alone - if (context['auto_mark_article']) { + if (context.auto_mark_article) { mark_read(new_active, true); } return true; @@ -684,7 +687,7 @@ function init_stream(divStream) { divStream.on('click', '.flux a.read', function () { var active = $(this).parents(".flux"); - if (context['auto_remove_article'] && active.hasClass('not_read')) { + if (context.auto_remove_article && active.hasClass('not_read')) { auto_remove(active); } mark_read(active, false); @@ -710,9 +713,9 @@ function init_stream(divStream) { if (e.which == 2) { // If middle click, we want same behaviour as CTRL+click. - var e = jQuery.Event("click"); - e.ctrlKey = true; - $(this).trigger(e); + var ev = jQuery.Event("click"); + ev.ctrlKey = true; + $(this).trigger(ev); } else if(e.which == 1) { // Normal click, just toggle article. $(this).parent().click(); @@ -723,7 +726,7 @@ function init_stream(divStream) { $(this).attr('target', '_blank'); }); - if (context['auto_mark_site']) { + if (context.auto_mark_site) { // catch mouseup instead of click so we can have the correct behaviour // with middle button click (scroll button). divStream.on('mouseup', '.flux .link > a', function (e) { @@ -765,17 +768,17 @@ var feed_processed = 0; function updateFeed(feeds, feeds_count) { var feed = feeds.pop(); - if (feed == undefined) { + if (!feed) { return; } $.ajax({ type: 'POST', - url: feed['url'], + url: feed.url, }).complete(function (data) { feed_processed++; $("#actualizeProgress .progress").html(feed_processed + " / " + feeds_count); - $("#actualizeProgress .title").html(feed['title']); + $("#actualizeProgress .title").html(feed.title); if (feed_processed === feeds_count) { window.location.reload(); @@ -819,7 +822,7 @@ function init_actualize() { return false; }); - if (context['auto_actualize_feeds']) { + if (context.auto_actualize_feeds) { auto = true; $("#actualize").click(); } @@ -887,12 +890,12 @@ function notifs_html5_ask_permission() { function notifs_html5_show(nb) { if (notifs_html5_permission !== "granted") { - return + return; } - var notification = new window.Notification(i18n['notif_title_articles'], { + var notification = new window.Notification(i18n.notif_title_articles, { icon: "../themes/icons/favicon-256.png", - body: i18n['notif_body_articles'].replace('%d', nb), + body: i18n.notif_body_articles.replace('%d', nb), tag: "freshRssNewArticles" }); @@ -900,10 +903,10 @@ function notifs_html5_show(nb) { window.location.reload(); }; - if (context['html5_notif_timeout'] !== 0) { + if (context.html5_notif_timeout !== 0) { setTimeout(function() { notification.close(); - }, context['html5_notif_timeout'] * 1000); + }, context.html5_notif_timeout * 1000); } } @@ -930,7 +933,7 @@ function refreshUnreads() { (nbUnreads - feed_unreads > 0)) { $('#new-article').attr('aria-hidden', 'false').show(); new_articles = true; - }; + } }); var nb_unreads = str2int($('.category.all .title').attr('data-unread')); @@ -957,7 +960,7 @@ function load_more_posts() { $.get(url_load_more, function (data) { box_load_more.children('.flux:last').after($('#stream', data).children('.flux, .day')); $('.pagination').replaceWith($('.pagination', data)); - if (context['display_order'] === 'ASC') { + if (context.display_order === 'ASC') { $('#nav_menu_read_all > .read_all').attr( 'formaction', $('#bigMarkAsRead').attr('formaction') ); @@ -988,7 +991,7 @@ function focus_search() { function init_load_more(box) { box_load_more = box; - if (!context['does_lazyload']) { + if (!context.does_lazyload) { $('img[postpone], audio[postpone], iframe[postpone], video[postpone]').each(function () { this.removeAttribute('postpone'); }); @@ -1027,6 +1030,7 @@ function poormanSalt() { //If crypto.getRandomValues is not available } function init_crypto_form() { + /* globals dcodeIO */ var $crypto_form = $('#crypto-form'); if ($crypto_form.length === 0) { return; @@ -1050,7 +1054,7 @@ function init_crypto_form() { dataType: 'json', async: false }).done(function (data) { - if (data.salt1 == '' || data.nonce == '') { + if (!data.salt1 || !data.nonce) { openNotification('Invalid user!', 'bad'); } else { try { @@ -1058,7 +1062,7 @@ function init_crypto_form() { s = dcodeIO.bcrypt.hashSync($('#passwordPlain').val(), data.salt1), c = dcodeIO.bcrypt.hashSync(data.nonce + s, strong ? dcodeIO.bcrypt.genSaltSync(4) : poormanSalt()); $('#challenge').val(c); - if (s == '' || c == '') { + if (!s || !c) { openNotification('Crypto error!', 'bad'); } else { success = true; @@ -1083,7 +1087,7 @@ function init_confirm_action() { $('body').on('click', '.confirm', function () { var str_confirmation = $(this).attr('data-str-confirm'); if (!str_confirmation) { - str_confirmation = i18n['confirmation_default']; + str_confirmation = i18n.confirmation_default; } return confirm(str_confirmation); @@ -1092,13 +1096,13 @@ function init_confirm_action() { function init_print_action() { $('.item.share > a[href="#"]').click(function () { - var content = "" - + $(".flux.current .content").html() - + ""; + var content = "" + + $(".flux.current .content").html() + + ""; var tmp_window = window.open(); tmp_window.document.writeln(content); @@ -1291,6 +1295,22 @@ function parseJsonVars() { window.icons = json.icons; } +function init_normal() { + $stream = $('#stream'); + if ($stream.length < 1) { + if (window.console) { + console.log('FreshRSS waiting for content…'); + } + window.setTimeout(init_normal, 50); + return; + } + init_column_categories(); + init_stream($stream); + init_shortcuts(); + init_actualize(); + faviconNbUnread(); +} + function init_beforeDOM() { if (!window.$) { if (window.console) { @@ -1300,20 +1320,8 @@ function init_beforeDOM() { return; } init_confirm_action(); - if (['normal', 'reader', 'global'].indexOf(context['current_view']) >= 0) { - $stream = $('#stream'); - if ($stream.length < 1) { - if (window.console) { - console.log('FreshRSS waiting for content…'); - } - window.setTimeout(init_beforeDOM, 50); - return; - } - init_column_categories(); - init_stream($stream); - init_shortcuts(); - init_actualize(); - faviconNbUnread(); + if (['normal', 'reader', 'global'].indexOf(context.current_view) >= 0) { + init_normal(); } } diff --git a/p/scripts/repartition.js b/p/scripts/repartition.js index a391de2f2..be70456fa 100644 --- a/p/scripts/repartition.js +++ b/p/scripts/repartition.js @@ -1,4 +1,7 @@ "use strict"; +/* globals Flotr, numberFormat */ +/* jshint globalstrict: true */ + function initStats() { if (!window.Flotr) { if (window.console) { @@ -19,9 +22,8 @@ function initStats() { { grid: {verticalLines: false}, xaxis: {noTicks: 23, - tickFormatter: function(x) { - var x = parseInt(x); - return x + 1; + tickFormatter: function(x1) { + return 1 + parseInt(x1); }, min: -0.9, max: 23.9, @@ -38,9 +40,8 @@ function initStats() { { grid: {verticalLines: false}, xaxis: {noTicks: 6, - tickFormatter: function(x) { - var x = parseInt(x); - return stats.days[x]; + tickFormatter: function(x2) { + return stats.days[parseInt(x2)]; }, min: -0.9, max: 6.9, @@ -57,9 +58,8 @@ function initStats() { { grid: {verticalLines: false}, xaxis: {noTicks: 12, - tickFormatter: function(x) { - var x = parseInt(x); - return stats.months[(x - 1)]; + tickFormatter: function(x3) { + return stats.months[parseInt(x3) - 1]; }, min: 0.1, max: 12.9, diff --git a/p/scripts/stats.js b/p/scripts/stats.js index 2e8ab6e27..9cd14721c 100644 --- a/p/scripts/stats.js +++ b/p/scripts/stats.js @@ -1,4 +1,7 @@ "use strict"; +/* globals Flotr, numberFormat */ +/* jshint globalstrict: true */ + function initStats() { if (!window.Flotr) { if (window.console) { -- cgit v1.2.3 From a051970d5b15a60e79ac2428280652486644c11c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 6 Aug 2016 14:13:03 +0200 Subject: jQuery 3 compatibility https://jquery.com/upgrade-guide/3.0/ * event.props removed https://jquery.com/upgrade-guide/3.0/#breaking-change-jquery-event-props-and-jquery-event-fixhooks-removed https://github.com/jquery/api.jquery.com/issues/405 * jqXHR.success(), jqXHR.error(), and jqXHR.complete() removed --- p/scripts/category.js | 18 ++++++++---------- p/scripts/main.js | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) (limited to 'p/scripts/main.js') diff --git a/p/scripts/category.js b/p/scripts/category.js index c33e68528..8c7ba37b0 100644 --- a/p/scripts/category.js +++ b/p/scripts/category.js @@ -34,15 +34,13 @@ function init_draggable() { return; } - $.event.props.push('dataTransfer'); - var draggable = '[draggable="true"]', dropzone = '[dropzone="move"]'; $('.drop-section').on('dragstart', draggable, function(e) { - e.dataTransfer.effectAllowed = 'move'; - e.dataTransfer.setData('text/html', e.target.outerHTML); - e.dataTransfer.setData('text', e.target.getAttribute('data-feed-id')); + e.originalEvent.dataTransfer.effectAllowed = 'move'; + e.originalEvent.dataTransfer.setData('text/html', e.target.outerHTML); + e.originalEvent.dataTransfer.setData('text', e.target.getAttribute('data-feed-id')); e.target.style.opacity = 0.3; dnd_successful = false; @@ -74,13 +72,13 @@ function init_draggable() { $(this).removeClass('drag-hover'); }); $('.drop-section').on('dragover', dropzone, function(e) { - e.dataTransfer.dropEffect = "move"; + e.originalEvent.dataTransfer.dropEffect = "move"; e.preventDefault(); return false; }); $('.drop-section').on('drop', dropzone, function(e) { - var feed_id = e.dataTransfer.getData('text'), + var feed_id = e.originalEvent.dataTransfer.getData('text'), cat_id = e.target.parentNode.getAttribute('data-cat-id'); loading = true; @@ -92,13 +90,13 @@ function init_draggable() { f_id: feed_id, c_id: cat_id } - }).success(function() { - $(e.target).after(e.dataTransfer.getData('text/html')); + }).done(function() { + $(e.target).after(e.originalEvent.dataTransfer.getData('text/html')); if ($(e.target).hasClass('disabled')) { $(e.target).remove(); } dnd_successful = true; - }).complete(function() { + }).always(function() { loading = false; }); diff --git a/p/scripts/main.js b/p/scripts/main.js index 01c8c9cf5..c95df54fa 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -772,7 +772,7 @@ function updateFeed(feeds, feeds_count) { $.ajax({ type: 'POST', url: feed['url'], - }).complete(function (data) { + }).always(function (data) { feed_processed++; $("#actualizeProgress .progress").html(feed_processed + " / " + feeds_count); $("#actualizeProgress .title").html(feed['title']); -- cgit v1.2.3 From e6fd34bdda5d067a9e74714aaae10c89ed998a46 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 13 Aug 2016 17:49:31 +0200 Subject: CSRF token, update HTTP Referrer policy to same-origin https://www.w3.org/TR/referrer-policy/#referrer-policy-no-referrer https://github.com/FreshRSS/FreshRSS/issues/570 https://github.com/FreshRSS/FreshRSS/issues/955 https://github.com/FreshRSS/FreshRSS/issues/1198 https://github.com/FreshRSS/FreshRSS/issues/565 https://github.com/FreshRSS/FreshRSS/issues/554 --- app/FreshRSS.php | 2 +- app/Models/Auth.php | 21 +++++++++++++ app/layout/aside_feed.phtml | 1 + app/layout/layout.phtml | 2 +- app/layout/nav_menu.phtml | 1 + app/views/auth/formLogin.phtml | 1 + app/views/auth/index.phtml | 1 + app/views/auth/register.phtml | 55 +++++++++++++++++---------------- app/views/configure/archiving.phtml | 2 ++ app/views/configure/display.phtml | 1 + app/views/configure/queries.phtml | 1 + app/views/configure/reading.phtml | 1 + app/views/configure/sharing.phtml | 1 + app/views/configure/shortcut.phtml | 1 + app/views/configure/system.phtml | 1 + app/views/extension/index.phtml | 1 + app/views/feed/add.phtml | 1 + app/views/helpers/feed/update.phtml | 1 + app/views/helpers/javascript_vars.phtml | 1 + app/views/helpers/pagination.phtml | 1 + app/views/importExport/index.phtml | 2 ++ app/views/index/logs.phtml | 1 + app/views/stats/idle.phtml | 1 + app/views/subscription/index.phtml | 7 ++++- app/views/user/manage.phtml | 2 ++ app/views/user/profile.phtml | 2 ++ lib/lib_rss.php | 2 +- p/scripts/main.js | 13 ++++++-- 28 files changed, 94 insertions(+), 33 deletions(-) (limited to 'p/scripts/main.js') diff --git a/app/FreshRSS.php b/app/FreshRSS.php index 20640266e..f9c371d27 100644 --- a/app/FreshRSS.php +++ b/app/FreshRSS.php @@ -57,7 +57,7 @@ class FreshRSS extends Minz_FrontController { private static function initAuth() { FreshRSS_Auth::init(); - if (Minz_Request::isPost() && !is_referer_from_same_domain()) { + if (Minz_Request::isPost() && !(is_referer_from_same_domain() && FreshRSS_Auth::isCsrfOk())) { // Basic protection against XSRF attacks FreshRSS_Auth::removeAccess(); $http_referer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['HTTP_REFERER']; diff --git a/app/Models/Auth.php b/app/Models/Auth.php index d689f7cdb..f0e8db5a2 100644 --- a/app/Models/Auth.php +++ b/app/Models/Auth.php @@ -124,6 +124,7 @@ class FreshRSS_Auth { self::$login_ok = false; $conf = Minz_Configuration::get('system'); Minz_Session::_param('currentUser', $conf->default_user); + Minz_Session::_param('csrf'); switch ($conf->auth_type) { case 'form': @@ -156,6 +157,26 @@ class FreshRSS_Auth { $auth_type = $conf->auth_type; return $auth_type === 'form'; } + + public static function csrfToken() { + $csrf = Minz_Session::param('csrf'); + if ($csrf == '') { + $salt = FreshRSS_Context::$system_conf->salt; + $csrf = sha1($salt . uniqid(mt_rand(), true)); + Minz_Session::_param('csrf', $csrf); + } + return $csrf; + } + public static function isCsrfOk($token = null) { + $csrf = Minz_Session::param('csrf'); + if ($csrf == '') { + return true; //Not logged in yet + } + if ($token === null) { + $token = Minz_Request::param('_csrf'); + } + return $token === $csrf; + } } diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml index 67507b88d..e8fdbf842 100644 --- a/app/layout/aside_feed.phtml +++ b/app/layout/aside_feed.phtml @@ -20,6 +20,7 @@
    +
    • diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml index 2aeba40a9..189d93fbe 100644 --- a/app/layout/layout.phtml +++ b/app/layout/layout.phtml @@ -42,7 +42,7 @@ ?> allow_referrer) { ?> - + allow_robots) { ?> diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml index 92268ff67..17655acbf 100644 --- a/app/layout/nav_menu.phtml +++ b/app/layout/nav_menu.phtml @@ -88,6 +88,7 @@ type="submit">