ESLint upgrade from JSHint (#3906)

* ESLint upgrade from JSHint
* commit corresponding package.json
* `npm run fix` for automatic JS and CSS fixes
* Keep JSHint config for now
This commit is contained in:
Alexandre Alapetite 2021-10-21 11:44:03 +02:00 committed by GitHub
parent cfd625c559
commit b438d8bb3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 979 additions and 909 deletions

3
.eslintignore Normal file
View File

@ -0,0 +1,3 @@
*.min.js
node_modules/
p/scripts/vendor/

26
.eslintrc.json Normal file
View File

@ -0,0 +1,26 @@
{
"env": {
"browser": true
},
"extends": [
"eslint:recommended",
"standard"
],
"rules": {
"camelcase": "off",
"comma-dangle": ["warn", "always-multiline"],
"eqeqeq": "off",
"indent": ["warn", "tab", { "SwitchCase": 1 }],
"linebreak-style": ["error", "unix"],
"max-len": ["warn", 165],
"no-tabs": "off",
"semi": ["warn", "always"],
"space-before-function-paren": ["warn", {
"anonymous": "always",
"named": "never",
"asyncArrow": "always"
}],
"yoda": "off"
},
"root": true
}

2
.gitignore vendored
View File

@ -1,6 +1,6 @@
/bin
/node_modules
package*.json
package-lock.json
constants.local.php
# Temp files

View File

@ -1,8 +1,9 @@
{
"esversion" : 6,
"esversion" : 8,
"browser" : true,
"globals": {
"confirm": true,
"console": true
}
},
"strict": "global"
}

View File

@ -33,11 +33,9 @@
"no-eol-whitespace": true,
"property-no-vendor-prefix": true,
"rule-empty-line-before": [
"always",
"except": [
"after-single-line-comment",
"first-nested"
]
"always", {
"except": ["after-single-line-comment","first-nested"]
}
],
"order/properties-order": [
"margin",

View File

@ -45,12 +45,9 @@ jobs:
env:
- HADOLINT="$HOME/hadolint"
install:
- npm install --save-dev jshint stylelint stylelint-order stylelint-scss stylelint-config-recommended-scss
- npm install
- curl -sL -o ${HADOLINT} "https://github.com/hadolint/hadolint/releases/download/v1.18.0/hadolint-$(uname -s)-$(uname -m)" && chmod 700 ${HADOLINT}
script:
- node_modules/jshint/bin/jshint .
# check SCSS separately
- stylelint --syntax scss "**/*.scss"
- stylelint "**/*.css"
- npm test
- bash tests/shellchecks.sh
- git ls-files --exclude='*Dockerfile*' --ignored | xargs --max-lines=1 "$HADOLINT"

View File

@ -1,6 +1,5 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
"use strict";
/* jshint esversion:6, strict:global */
'use strict';
function check(url, next) {
if (!url || !next) {

View File

@ -1,10 +1,9 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
"use strict";
'use strict';
/* globals context */
/* jshint esversion:6, strict:global */
var loading = false,
dnd_successful = false;
let loading = false;
let dnd_successful = false;
function dragend_process(t) {
t.setAttribute('draggable', 'false');
@ -25,13 +24,14 @@ function dragend_process(t) {
t.remove();
if (p.childElementCount <= 1) {
p.insertAdjacentHTML('afterbegin', '<li class="item feed disabled" dropzone="move"><div class="alert-warn">' + context.i18n.category_empty + '</div></li>');
p.insertAdjacentHTML('afterbegin',
'<li class="item feed disabled" dropzone="move"><div class="alert-warn">' + context.i18n.category_empty + '</div></li>');
}
}
}
var dragFeedId = '',
dragHtml = '';
let dragFeedId = '';
let dragHtml = '';
function init_draggable() {
if (!window.context) {
@ -42,9 +42,9 @@ function init_draggable() {
return;
}
const draggable = '[draggable="true"]',
dropzone = '[dropzone="move"]',
dropSection = document.querySelector('.drop-section');
const draggable = '[draggable="true"]';
const dropzone = '[dropzone="move"]';
const dropSection = document.querySelector('.drop-section');
dropSection.ondragstart = function (ev) {
const li = ev.target.closest ? ev.target.closest(draggable) : null;
@ -77,13 +77,13 @@ function init_draggable() {
dropSection.onddragleave = function (ev) {
const li = ev.target.closest ? ev.target.closest(dropzone) : null;
if (li) {
const scroll_top = document.documentElement.scrollTop,
top = li.offsetTop,
left = li.offsetLeft,
right = left + li.clientWidth,
bottom = top + li.clientHeight,
mouse_x = ev.screenX,
mouse_y = ev.clientY + scroll_top;
const scroll_top = document.documentElement.scrollTop;
const top = li.offsetTop;
const left = li.offsetLeft;
const right = left + li.clientWidth;
const bottom = top + li.clientHeight;
const mouse_x = ev.screenX;
const mouse_y = ev.clientY + scroll_top;
if (left <= mouse_x && mouse_x <= right &&
top <= mouse_y && mouse_y <= bottom) {
@ -97,7 +97,7 @@ function init_draggable() {
dropSection.ondragover = function (ev) {
const li = ev.target.closest ? ev.target.closest(dropzone) : null;
if (li) {
ev.dataTransfer.dropEffect = "move";
ev.dataTransfer.dropEffect = 'move';
return false;
}
};

View File

@ -1,6 +1,5 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
"use strict";
/* jshint esversion:6, strict:global */
'use strict';
const init_draggable_list = function () {
if (!window.context) {

View File

@ -1,7 +1,6 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
"use strict";
'use strict';
/* globals context, openNotification, openPopupWithSource, xmlHttpRequestJson */
/* jshint esversion:6, strict:global */
function fix_popup_preview_selector() {
const link = document.getElementById('popup-preview-selector');
@ -70,9 +69,9 @@ function init_crypto_form() {
openNotification('Invalid user!', 'bad');
} else {
try {
const strong = window.Uint32Array && window.crypto && (typeof window.crypto.getRandomValues === 'function'),
s = dcodeIO.bcrypt.hashSync(document.getElementById('passwordPlain').value, json.salt1),
c = dcodeIO.bcrypt.hashSync(json.nonce + s, strong ? dcodeIO.bcrypt.genSaltSync(4) : poormanSalt());
const strong = window.Uint32Array && window.crypto && (typeof window.crypto.getRandomValues === 'function');
const s = dcodeIO.bcrypt.hashSync(document.getElementById('passwordPlain').value, json.salt1);
const c = dcodeIO.bcrypt.hashSync(json.nonce + s, strong ? dcodeIO.bcrypt.genSaltSync(4) : poormanSalt());
document.getElementById('challenge').value = c;
if (!s || !c) {
openNotification('Crypto error!', 'bad');
@ -113,8 +112,8 @@ function init_password_observers() {
function init_select_observers() {
document.querySelectorAll('.select-change').forEach(function (s) {
s.onchange = function (ev) {
const opt = s.options[s.selectedIndex],
url = opt.getAttribute('data-url');
const opt = s.options[s.selectedIndex];
const url = opt.getAttribute('data-url');
if (url) {
s.disabled = true;
s.value = '';
@ -130,8 +129,8 @@ function init_select_observers() {
}
function init_slider_observers() {
const slider = document.getElementById('slider'),
closer = document.getElementById('close-slider');
const slider = document.getElementById('slider');
const closer = document.getElementById('close-slider');
if (!slider) {
return;
}

View File

@ -1,9 +1,8 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
"use strict";
'use strict';
/* globals context, init_load_more, init_posts, init_stream */
/* jshint esversion:6, strict:global */
var panel_loading = false;
let panel_loading = false;
function load_panel(link) {
if (panel_loading) {
@ -19,9 +18,9 @@ function load_panel(link) {
if (this.status != 200) {
return;
}
const html = this.response,
foreign = html.querySelectorAll('.nav_menu, #stream .day, #stream .flux, #stream .pagination, #stream.prompt'),
panel = document.getElementById('panel');
const html = this.response;
const foreign = html.querySelectorAll('.nav_menu, #stream .day, #stream .flux, #stream .pagination, #stream.prompt');
const panel = document.getElementById('panel');
foreign.forEach(function (el) {
panel.appendChild(document.adoptNode(el));
});

View File

@ -1,6 +1,5 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
"use strict";
/* jshint esversion:6, strict:global */
'use strict';
function show_password(ev) {
const button = ev.currentTarget;
@ -25,8 +24,8 @@ for (let i = 0; i < toggles.length; i++) {
const auth_type = document.getElementById('auth_type');
function auth_type_change() {
if (auth_type) {
const auth_value = auth_type.value,
password_input = document.getElementById('passwordPlain');
const auth_value = auth_type.value;
const password_input = document.getElementById('passwordPlain');
if (auth_value === 'form') {
password_input.required = true;

View File

@ -1,6 +1,5 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
"use strict";
/* jshint esversion:6, strict:global */
'use strict';
const init_integration = function () {
if (!window.context) {

View File

@ -1,12 +1,14 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
"use strict";
/* jshint esversion:6, strict:global */
'use strict';
// <Polyfills>
if (!document.scrollingElement) document.scrollingElement = document.documentElement;
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.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;
do {
if (el.matches(s)) return el;
@ -14,6 +16,7 @@ if (!Element.prototype.closest) Element.prototype.closest = function (s) {
} while (el);
return null;
};
}
if (!Element.prototype.remove) Element.prototype.remove = function () { if (this.parentNode) this.parentNode.removeChild(this); };
// </Polyfills>
@ -32,11 +35,11 @@ function xmlHttpRequestJson(req) {
// </Utils>
// <Global context>
var context;
let context;
(function parseJsonVars() {
const jsonVars = document.getElementById('jsonVars'),
json = JSON.parse(jsonVars.innerHTML);
const jsonVars = document.getElementById('jsonVars');
const json = JSON.parse(jsonVars.innerHTML);
jsonVars.outerHTML = '';
context = json.context;
context.ajax_loading = false;
@ -59,11 +62,13 @@ function badAjax(reload) {
}
function needsScroll(elem) {
const winBottom = document.scrollingElement.scrollTop + document.scrollingElement.clientHeight,
elemTop = elem.offsetParent.offsetTop + elem.offsetTop,
elemBottom = elemTop + elem.offsetHeight;
return (elemTop < document.scrollingElement.scrollTop || elemBottom > winBottom) ?
elemTop - (document.scrollingElement.clientHeight / 2) : 0;
const winBottom = document.scrollingElement.scrollTop + document.scrollingElement.clientHeight;
const elemTop = elem.offsetParent.offsetTop + elem.offsetTop;
const elemBottom = elemTop + elem.offsetHeight;
if (elemTop < document.scrollingElement.scrollTop || elemBottom > winBottom) {
return elemTop - (document.scrollingElement.clientHeight / 2);
}
return 0;
}
function str2int(str) {
@ -79,9 +84,9 @@ function numberFormat(nStr) {
}
// http://www.mredkj.com/javascript/numberFormat.html
nStr += '';
const x = nStr.split('.'),
x2 = x.length > 1 ? '.' + x[1] : '',
rgx = /(\d+)(\d{3})/;
const x = nStr.split('.');
const x2 = x.length > 1 ? '.' + x[1] : '';
const rgx = /(\d+)(\d{3})/;
let x1 = x[0];
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1 $2');
@ -96,9 +101,9 @@ function incLabel(p, inc, spaceAfter) {
function incUnreadsFeed(article, feed_id, nb) {
// Update unread: feed
let elem = document.getElementById(feed_id),
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0,
feed_priority = elem ? str2int(elem.getAttribute('data-priority')) : 0;
let elem = document.getElementById(feed_id);
let feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
const feed_priority = elem ? str2int(elem.getAttribute('data-priority')) : 0;
if (elem) {
elem.setAttribute('data-unread', feed_unreads + nb);
elem = elem.querySelector('.item-title');
@ -138,7 +143,7 @@ function incUnreadsFeed(article, feed_id, nb) {
let isCurrentView = false;
// Update unread: title
document.title = document.title.replace(/^((?:\([ 0-9]+\) )?)/, function (m, p1) {
document.title = document.title.replace(/^((?:\([\s0-9]+\) )?)/, function (m, p1) {
const feed = document.getElementById(feed_id);
if (article || feed.closest('.active')) {
isCurrentView = true;
@ -156,13 +161,13 @@ function incUnreadsFeed(article, feed_id, nb) {
function incUnreadsTag(tag_id, nb) {
let t = document.getElementById(tag_id);
if (t) {
let unreads = str2int(t.getAttribute('data-unread'));
const 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'));
const unreads = str2int(t.getAttribute('data-unread'));
t.setAttribute('data-unread', numberFormat(unreads + nb));
}
}
@ -173,8 +178,8 @@ function removeArticle(div) {
}
let scrollTop = box_to_follow.scrollTop;
let dirty = false;
const p = div.previousElementSibling,
n = div.nextElementSibling;
const p = div.previousElementSibling;
const n = div.nextElementSibling;
if (p && p.classList.contains('day') && n && n.classList.contains('day')) {
scrollTop -= p.offsetHeight;
dirty = true;
@ -190,8 +195,8 @@ function removeArticle(div) {
}
}
var pending_entries = {},
mark_read_queue = [];
const pending_entries = {};
let mark_read_queue = [];
function send_mark_read_queue(queue, asRead, callback) {
const req = new XMLHttpRequest();
@ -212,8 +217,8 @@ function send_mark_read_queue(queue, asRead, callback) {
return req.onerror(e);
}
for (let i = queue.length - 1; i >= 0; i--) {
const div = document.getElementById('flux_' + queue[i]),
myIcons = context.icons;
const div = document.getElementById('flux_' + queue[i]);
const myIcons = context.icons;
let inc = 0;
if (div.classList.contains('not_read')) {
div.classList.remove('not_read');
@ -234,10 +239,10 @@ function send_mark_read_queue(queue, asRead, callback) {
div.querySelectorAll('a.read > .icon').forEach(function (img) { img.outerHTML = myIcons.unread; });
inc++;
}
let feed_link = div.querySelector('.website > a, a.website');
const feed_link = div.querySelector('.website > a, a.website');
if (feed_link) {
const feed_url = feed_link.href,
feed_id = feed_url.substr(feed_url.lastIndexOf('f_'));
const feed_url = feed_link.href;
const feed_id = feed_url.substr(feed_url.lastIndexOf('f_'));
incUnreadsFeed(div, feed_id, inc);
}
delete pending_entries['flux_' + queue[i]];
@ -246,7 +251,7 @@ function send_mark_read_queue(queue, asRead, callback) {
if (json.tags) {
const tagIds = Object.keys(json.tags);
for (let i = tagIds.length - 1; i >= 0; i--) {
let tagId = tagIds[i];
const tagId = tagIds[i];
incUnreadsTag(tagId, (asRead ? -1 : 1) * json.tags[tagId].length);
}
}
@ -263,7 +268,7 @@ function send_mark_read_queue(queue, asRead, callback) {
}));
}
var send_mark_read_queue_timeout = 0;
let send_mark_read_queue_timeout = 0;
function send_mark_queue_tick(callback) {
send_mark_read_queue_timeout = 0;
@ -271,7 +276,7 @@ function send_mark_queue_tick(callback) {
mark_read_queue = [];
send_mark_read_queue(queue, true, callback);
}
var delayedFunction = send_mark_queue_tick;
const delayedFunction = send_mark_queue_tick;
function delayedClick(a) {
if (a) {
@ -289,8 +294,8 @@ function mark_read(div, only_not_read, asBatch) {
}
pending_entries[div.id] = true;
const asRead = div.classList.contains('not_read'),
entryId = div.id.replace(/^flux_/, '');
const asRead = div.classList.contains('not_read');
const entryId = div.id.replace(/^flux_/, '');
if (asRead && asBatch) {
mark_read_queue.push(entryId);
if (send_mark_read_queue_timeout == 0) {
@ -314,8 +319,8 @@ function mark_favorite(div) {
return false;
}
let a = div.querySelector('a.bookmark'),
url = a ? a.href : '';
const a = div.querySelector('a.bookmark');
const url = a ? a.href : '';
if (!url) {
return false;
}
@ -353,14 +358,14 @@ function mark_favorite(div) {
const favourites = document.querySelector('#aside_feed .favorites .title');
if (favourites) {
favourites.textContent = favourites.textContent.replace(/((?: \([ 0-9]+\))?\s*)$/, function (m, p1) {
favourites.textContent = favourites.textContent.replace(/((?: \([\s0-9]+\))?\s*)$/, function (m, p1) {
return incLabel(p1, inc, false);
});
}
if (div.classList.contains('not_read')) {
const elem = document.querySelector('#aside_feed .favorites .title'),
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
const elem = document.querySelector('#aside_feed .favorites .title');
const feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
if (elem) {
elem.setAttribute('data-unread', numberFormat(feed_unreads + inc));
}
@ -375,7 +380,7 @@ function mark_favorite(div) {
}));
}
var freshrssOpenArticleEvent = document.createEvent('Event');
const freshrssOpenArticleEvent = document.createEvent('Event');
freshrssOpenArticleEvent.initEvent('freshrss:openArticle', true, true);
function toggleContent(new_active, old_active, skipping) {
@ -407,12 +412,12 @@ function toggleContent(new_active, old_active, skipping) {
new_active.classList.toggle('active');
}
const relative_move = context.current_view === 'global',
box_to_move = relative_move ? document.getElementById('panel') : document.scrollingElement;
const relative_move = context.current_view === 'global';
const box_to_move = relative_move ? document.getElementById('panel') : document.scrollingElement;
if (context.sticky_post) { // Stick the article to the top when opened
let prev_article = new_active.previousElementSibling,
new_pos = new_active.offsetParent.offsetTop + new_active.offsetTop;
const prev_article = new_active.previousElementSibling;
let new_pos = new_active.offsetParent.offsetTop + new_active.offsetTop;
if (prev_article && new_active.offsetTop - prev_article.offsetTop <= 150) {
new_pos = prev_article.offsetParent.offsetTop + prev_article.offsetTop;
@ -627,8 +632,8 @@ function toggle_media() {
}
function user_filter(key) {
const filter = document.getElementById('dropdown-query'),
filters = filter.parentElement.querySelectorAll('.dropdown-menu > .query > a');
const filter = document.getElementById('dropdown-query');
const filters = filter.parentElement.querySelectorAll('.dropdown-menu > .query > a');
if (typeof key === 'undefined') {
if (!filters.length) {
return;
@ -683,7 +688,7 @@ function auto_share(key) {
}
}
var box_to_follow;
let box_to_follow;
function onScroll() {
if (!box_to_follow) {
@ -710,8 +715,8 @@ function onScroll() {
function init_posts() {
if (context.auto_load_more || context.auto_mark_scroll || context.auto_remove_article) {
box_to_follow = context.current_view === 'global' ? document.getElementById('panel') : document.scrollingElement;
let lastScroll = 0, //Throttle
timerId = 0;
let lastScroll = 0; // Throttle
let timerId = 0;
(box_to_follow === document.scrollingElement ? window : box_to_follow).onscroll = function () {
clearTimeout(timerId);
if (lastScroll + 500 < Date.now()) {
@ -791,13 +796,13 @@ function init_column_categories() {
a = ev.target.closest('.tree-folder-items > .feed .dropdown-toggle');
if (a) {
const itemId = a.closest('.item').id,
templateId = itemId.substring(0, 2) === 't_' ? 'tag_config_template' : 'feed_config_template',
id = itemId.substr(2),
feed_web = a.getAttribute('data-fweb'),
div = a.parentElement,
dropdownMenu = div.querySelector('.dropdown-menu'),
template = document.getElementById(templateId)
const itemId = a.closest('.item').id;
const templateId = itemId.substring(0, 2) === 't_' ? 'tag_config_template' : 'feed_config_template';
const id = itemId.substr(2);
const feed_web = a.getAttribute('data-fweb');
const div = a.parentElement;
const dropdownMenu = div.querySelector('.dropdown-menu');
const template = document.getElementById(templateId)
.innerHTML.replace(/------/g, id).replace('http://example.net/', feed_web);
if (!dropdownMenu) {
a.href = '#dropdown-' + id;
@ -896,8 +901,8 @@ function init_shortcuts() {
} else if (ev.shiftKey) {
first_feed();
} else {
const old_active = document.querySelector('.flux.current'),
first = document.querySelector('.flux');
const old_active = document.querySelector('.flux.current');
const first = document.querySelector('.flux');
if (first.classList.contains('flux')) {
toggleContent(first, old_active, false);
}
@ -910,8 +915,8 @@ function init_shortcuts() {
} else if (ev.shiftKey) {
last_feed();
} else {
const old_active = document.querySelector('.flux.current'),
last = document.querySelector('.flux:last-of-type');
const old_active = document.querySelector('.flux.current');
const last = document.querySelector('.flux:last-of-type');
if (last.classList.contains('flux')) {
toggleContent(last, old_active, false);
}
@ -992,7 +997,7 @@ function init_stream(stream) {
el = ev.target.closest('.item.share > a[data-type="print"]');
if (el) { // Print
const tmp_window = window.open();
for (var i = 0; i < document.styleSheets.length; i++) {
for (let i = 0; i < document.styleSheets.length; i++) {
tmp_window.document.writeln('<link href="' + document.styleSheets[i].href + '" rel="stylesheet" type="text/css" />');
}
tmp_window.document.writeln(el.closest('.flux_content').querySelector('.content').innerHTML);
@ -1026,8 +1031,8 @@ function init_stream(stream) {
// setting for not-closing after clicking outside article area
return false;
}
const old_active = document.querySelector('.flux.current'),
new_active = el.parentNode;
const old_active = document.querySelector('.flux.current');
const new_active = el.parentNode;
if (ev.target.tagName.toUpperCase() === 'A') { // Leave real links alone
if (context.auto_mark_article) {
mark_read(new_active, true, false);
@ -1080,11 +1085,11 @@ function init_stream(stream) {
const checkboxTag = ev.target.closest('.checkboxTag');
if (checkboxTag) { // Dynamic tags
ev.stopPropagation();
const isChecked = checkboxTag.checked,
tagId = checkboxTag.name.replace(/^t_/, ''),
tagName = checkboxTag.nextElementSibling ? checkboxTag.nextElementSibling.value : '',
entry = checkboxTag.closest('div.flux'),
entryId = entry.id.replace(/^flux_/, '');
const isChecked = checkboxTag.checked;
const tagId = checkboxTag.name.replace(/^t_/, '');
const tagName = checkboxTag.nextElementSibling ? checkboxTag.nextElementSibling.value : '';
const entry = checkboxTag.closest('div.flux');
const entryId = entry.id.replace(/^flux_/, '');
checkboxTag.disabled = true;
const req = new XMLHttpRequest();
@ -1132,9 +1137,9 @@ function init_nav_entries() {
return false;
};
nav_entries.querySelector('.up').onclick = function (e) {
const active_item = (document.querySelector('.flux.current') || document.querySelector('.flux')),
windowTop = document.scrollingElement.scrollTop,
item_top = active_item.offsetParent.offsetTop + active_item.offsetTop;
const active_item = (document.querySelector('.flux.current') || document.querySelector('.flux'));
const windowTop = document.scrollingElement.scrollTop;
const item_top = active_item.offsetParent.offsetTop + active_item.offsetTop;
document.scrollingElement.scrollTop = windowTop > item_top ? item_top : 0;
return false;
@ -1176,7 +1181,7 @@ function loadDynamicTags(div) {
}
// <actualize>
var feed_processed = 0;
let feed_processed = 0;
function updateFeed(feeds, feeds_count) {
const feed = feeds.pop();
@ -1286,9 +1291,9 @@ function init_actualize() {
// </actualize>
// <notification>
var notification = null,
notification_interval = null,
notification_working = false;
let notification = null;
let notification_interval = null;
let notification_working = false;
function openNotification(msg, status) {
if (notification_working === true) {
@ -1324,12 +1329,14 @@ function init_notifications() {
// </notification>
// <popup>
let popup = null,
popup_iframe_container = null,
popup_iframe = null,
popup_txt = null,
popup_working = false;
let popup = null;
let popup_iframe_container = null;
let popup_iframe = null;
let popup_txt = null;
let popup_working = false;
/* eslint-disable no-unused-vars */
// TODO: Re-enable no-unused-vars
function openPopupWithMessage(msg) {
if (popup_working === true) {
return false;
@ -1355,6 +1362,7 @@ function openPopupWithSource(source) {
popup_iframe_container.style.display = 'table-row';
popup.style.display = 'block';
}
/* eslint-enable no-unused-vars */
function closePopup() {
popup.style.display = 'none';
@ -1390,7 +1398,7 @@ function init_popup() {
// </popup>
// <notifs html5>
var notifs_html5_permission = 'denied';
let notifs_html5_permission = 'denied';
function notifs_html5_is_supported() {
return window.Notification !== undefined;
@ -1452,8 +1460,8 @@ function refreshUnreads() {
Object.keys(json.feeds).forEach(function (feed_id) {
const nbUnreads = json.feeds[feed_id];
feed_id = 'f_' + feed_id;
const elem = document.getElementById(feed_id),
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
const elem = document.getElementById(feed_id);
const feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
if ((incUnreadsFeed(null, feed_id, nbUnreads - feed_unreads) || isAll) && // Update of current view?
(nbUnreads - feed_unreads > 0)) {
@ -1482,8 +1490,8 @@ function refreshUnreads() {
tags.querySelector('.title').setAttribute('data-unread', numberFormat(nbUnreadTags));
}
const title = document.querySelector('.category.all .title'),
nb_unreads = title ? str2int(title.getAttribute('data-unread')) : 0;
const title = document.querySelector('.category.all .title');
const nb_unreads = title ? str2int(title.getAttribute('data-unread')) : 0;
if (nb_unreads > 0 && new_articles) {
faviconNbUnread(nb_unreads);
@ -1494,9 +1502,9 @@ function refreshUnreads() {
}
// <endless_mode>
var url_load_more = '',
load_more = false,
box_load_more = null;
let url_load_more = '';
let load_more = false;
let box_load_more = null;
function load_more_posts() {
if (load_more || !url_load_more || !box_load_more) {
@ -1509,16 +1517,16 @@ function load_more_posts() {
req.open('GET', url_load_more, true);
req.responseType = 'document';
req.onload = function (e) {
const html = this.response,
formPagination = document.getElementById('mark-read-pagination');
const html = this.response;
const formPagination = document.getElementById('mark-read-pagination');
const streamAdopted = document.adoptNode(html.getElementById('stream'));
streamAdopted.querySelectorAll('.flux, .day').forEach(function (div) {
box_load_more.insertBefore(div, formPagination);
});
const paginationOld = formPagination.querySelector('.pagination'),
paginationNew = streamAdopted.querySelector('.pagination');
const paginationOld = formPagination.querySelector('.pagination');
const paginationNew = streamAdopted.querySelector('.pagination');
formPagination.replaceChild(paginationNew, paginationOld);
const bigMarkAsRead = document.getElementById('bigMarkAsRead');
@ -1552,7 +1560,7 @@ function load_more_posts() {
req.send();
}
var freshrssLoadMoreEvent = document.createEvent('Event');
const freshrssLoadMoreEvent = document.createEvent('Event');
freshrssLoadMoreEvent.initEvent('freshrss:load-more', true, true);
function init_load_more(box) {
@ -1595,9 +1603,9 @@ function faviconNbUnread(n) {
n = t ? str2int(t.getAttribute('data-unread')) : 0;
}
// http://remysharp.com/2010/08/24/dynamic-favicons/
const canvas = document.createElement('canvas'),
link = document.getElementById('favicon').cloneNode(true),
ratio = window.devicePixelRatio;
const canvas = document.createElement('canvas');
const link = document.getElementById('favicon').cloneNode(true);
const ratio = window.devicePixelRatio;
if (canvas.getContext && link) {
canvas.height = canvas.width = 16 * ratio;
const img = document.createElement('img');

View File

@ -1,12 +1,10 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
"use strict";
/* jshint esversion:6, strict:global */
let rendered_node = null,
rendered_view = null,
raw_node = null,
raw_view = null;
'use strict';
let rendered_node = null;
let rendered_view = null;
let raw_node = null;
let raw_view = null;
function update_ui() {
if (rendered_node.checked && !raw_node.checked) {
@ -29,7 +27,6 @@ function init_afterDOM() {
raw_node.addEventListener('click', update_ui);
}
if (document.readyState && document.readyState !== 'loading') {
init_afterDOM();
} else {

View File

@ -1,7 +1,6 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-3.0
"use strict";
'use strict';
/* globals Chart */
/* jshint esversion:6, strict:global */
function initCharts() {
if (!window.Chart) {
@ -14,10 +13,10 @@ function initCharts() {
const jsonData = document.getElementsByClassName('jsonData-stats');
var jsonDataParsed;
var chartConfig;
let jsonDataParsed;
let chartConfig;
for (var i = 0; i < jsonData.length; i++) {
for (let i = 0; i < jsonData.length; i++) {
jsonDataParsed = JSON.parse(jsonData[i].innerHTML);
switch (jsonDataParsed.charttype) {
@ -28,13 +27,13 @@ function initCharts() {
chartConfig = jsonChartDoughnut(jsonDataParsed.labels, jsonDataParsed.data);
break;
case 'barWithAverage':
chartConfig = jsonChartBarWithAvarage(jsonDataParsed.labelBarChart, jsonDataParsed.dataBarChart, jsonDataParsed.labelAverage, jsonDataParsed.dataAverage, jsonDataParsed.xAxisLabels);
chartConfig = jsonChartBarWithAvarage(jsonDataParsed.labelBarChart, jsonDataParsed.dataBarChart,
jsonDataParsed.labelAverage, jsonDataParsed.dataAverage, jsonDataParsed.xAxisLabels);
}
new Chart(
document.getElementById(jsonDataParsed.canvasID),
chartConfig
);
/* eslint-disable no-new */
new Chart(document.getElementById(jsonDataParsed.canvasID), chartConfig);
/* eslint-enable no-new */
}
if (window.console) {
@ -55,25 +54,25 @@ function jsonChartBar(label, data, xAxisLabels = '') {
barPercentage: 1.0,
categoryPercentage: 1.0,
order: 2,
}]
}],
},
options: {
scales: {
y: {
beginAtZero: true
beginAtZero: true,
},
x: {
grid: {
display: false,
}
}
},
},
},
plugins: {
legend: {
display: false,
}
}
}
},
},
},
};
}
@ -99,7 +98,7 @@ function jsonChartDoughnut(labels, data) {
'#8dddd0', // turkis
],
data: data,
}]
}],
},
options: {
layout: {
@ -109,9 +108,9 @@ function jsonChartDoughnut(labels, data) {
legend: {
position: 'bottom',
align: 'start',
}
}
}
},
},
},
};
}
@ -140,8 +139,8 @@ function jsonChartBarWithAvarage(labelBarChart, dataBarChart, labelAverage, data
'-1': dataAverage,
},
order: 1,
}
]
},
],
},
options: {
@ -157,17 +156,17 @@ function jsonChartBarWithAvarage(labelBarChart, dataBarChart, labelAverage, data
} else {
return val;
}
}
},
},
grid: {
display: false,
}
}
},
},
},
elements: {
point: {
radius: 0,
}
},
},
plugins: {
tooltip: {
@ -178,14 +177,14 @@ function jsonChartBarWithAvarage(labelBarChart, dataBarChart, labelAverage, data
} else {
return tooltipitem[0].label;
}
}
}
},
},
},
legend: {
display: false,
}
}
}
},
},
},
};
}

View File

@ -879,7 +879,7 @@ input[type="search"] {
}
.subtitle > div:not(:first-of-type)::before {
content: ' · ';
content: ' · ';
}
br {

View File

@ -465,7 +465,7 @@ a.btn {
/*=== Boxes */
.box {
margin: 20px 10px;
margin: 20px 0 20px 20px;
display: inline-block;
max-width: 95%;
width: 20rem;
@ -473,6 +473,11 @@ a.btn {
vertical-align: top;
}
.box.visible-semi {
border-style: dashed;
opacity: 0.5;
}
.box .box-title {
position: relative;
font-size: 1.2rem;
@ -874,7 +879,7 @@ input[type="search"] {
}
.subtitle > div:not(:first-of-type)::before {
content: ' · ';
content: ' · ';
}
br {
@ -1114,7 +1119,7 @@ br {
display: none;
position: fixed;
top: 2%; bottom: 2%;
left: 3%; right: 3%;
right: 3%; left: 3%;
overflow: auto;
}

42
package.json Normal file
View File

@ -0,0 +1,42 @@
{
"name": "freshrss",
"description": "A free, self-hostable aggregator",
"homepage": "https://freshrss.org/",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/FreshRSS/FreshRSS/issues"
},
"keywords": [
"news",
"aggregator",
"RSS",
"Atom",
"WebSub"
],
"repository": {
"type": "git",
"url": "https://github.com/FreshRSS/FreshRSS.git"
},
"license": "AGPL-3.0",
"scripts": {
"eslint": "eslint --ext .js .",
"eslint_fix": "eslint --fix --ext .js .",
"rtlcss": "rtlcss -d p/themes && find . -type f -name '*.rtl.rtl.css' -delete",
"stylelint": "stylelint '**/*.css' && stylelint --syntax scss '**/*.scss'",
"stylelint_fix": "stylelint --fix '**/*.css' && stylelint --fix --syntax scss '**/*.scss'",
"test": "npm run eslint && npm run stylelint",
"fix": "npm run rtlcss && npm run stylelint_fix && npm run eslint_fix"
},
"devDependencies": {
"eslint": "^7.32.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"rtlcss": "^3.4.0",
"stylelint": "^13.13.1",
"stylelint-config-recommended-scss": "^4.3.0",
"stylelint-order": "^4.1.0",
"stylelint-scss": "^3.21.0"
}
}