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) {
@ -43,7 +42,7 @@ check(jsonVars.greader + '/check/compatibility', function next(result1) {
}
});
}
});
});
check(jsonVars.fever + '?api', function next(result1) {
const feverOutput = document.getElementById('feverOutput');
@ -60,5 +59,5 @@ check(jsonVars.fever + '?api', function next(result1) {
}
});
}
});
});
// @license-end

View File

@ -1,16 +1,15 @@
// @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');
if (loading) {
setTimeout(function() {
setTimeout(function () {
dragend_process(t);
}, 50);
return;
@ -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,11 +42,11 @@ 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) {
dropSection.ondragstart = function (ev) {
const li = ev.target.closest ? ev.target.closest(draggable) : null;
if (li) {
const drag = ev.target.closest('[draggable]');
@ -59,14 +59,14 @@ function init_draggable() {
}
};
dropSection.ondragend = function(ev) {
dropSection.ondragend = function (ev) {
const li = ev.target.closest ? ev.target.closest(draggable) : null;
if (li) {
dragend_process(li);
}
};
dropSection.ondragenter = function(ev) {
dropSection.ondragenter = function (ev) {
const li = ev.target.closest ? ev.target.closest(dropzone) : null;
if (li) {
li.classList.add('drag-hover');
@ -74,16 +74,16 @@ function init_draggable() {
}
};
dropSection.onddragleave = function(ev) {
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) {
@ -94,15 +94,15 @@ function init_draggable() {
}
};
dropSection.ondragover = function(ev) {
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;
}
};
dropSection.ondrop = function(ev) {
dropSection.ondrop = function (ev) {
const li = ev.target.closest ? ev.target.closest(dropzone) : null;
if (li) {
loading = true;
@ -143,7 +143,7 @@ function archiving() {
if (e.target.id === 'use_default_purge_options') {
slider.querySelectorAll('.archiving').forEach(function (element) {
element.hidden = e.target.checked;
if (!e.target.checked) element.style.visibility = 'visible'; //Help for Edge 44
if (!e.target.checked) element.style.visibility = 'visible'; // Help for Edge 44
});
}
});

View File

@ -1,8 +1,7 @@
// @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() {
const init_draggable_list = function () {
if (!window.context) {
if (window.console) {
console.log('FreshRSS draggable list waiting for JS…');

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');
@ -20,8 +19,8 @@ function fix_popup_preview_selector() {
});
}
//<crypto form (Web login)>
function poormanSalt() { //If crypto.getRandomValues is not available
// <crypto form (Web login)>
function poormanSalt() { // If crypto.getRandomValues is not available
const base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ.0123456789/abcdefghijklmnopqrstuvwxyz';
let text = '$2a$04$';
for (let i = 22; i > 0; i--) {
@ -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');
@ -91,7 +90,7 @@ function init_crypto_form() {
return success;
};
}
//</crypto form (Web login)>
// </crypto form (Web login)>
function init_password_observers() {
document.querySelectorAll('.toggle-password').forEach(function (a) {
@ -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;
}
@ -204,7 +203,7 @@ function init_extra() {
if (window.console) {
console.log('FreshRSS extra waiting for JS…');
}
window.setTimeout(init_extra, 50); //Wait for all js to be loaded
window.setTimeout(init_extra, 50); // Wait for all js to be loaded
return;
}
init_crypto_form();

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));
});
@ -41,7 +40,7 @@ function load_panel(link) {
panel.scrollTop = 0;
document.documentElement.scrollTop = 0;
//We already have a click listener in main.js
// We already have a click listener in main.js
panel.addEventListener('click', function (ev) {
const b = ev.target.closest('#nav_menu_read_all button, #bigMarkAsRead');
if (b) {
@ -104,7 +103,7 @@ function init_all_global_view() {
if (window.console) {
console.log('FreshRSS Global view waiting for JS…');
}
window.setTimeout(init_all_global_view, 50); //Wait for all js to be loaded
window.setTimeout(init_all_global_view, 50); // Wait for all js to be loaded
return;
}
init_global_view();

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;
@ -13,7 +12,7 @@ function hide_password(ev) {
const button = ev.currentTarget;
const passwordField = document.getElementById(button.getAttribute('data-toggle'));
passwordField.setAttribute('type', 'password');
button.className = button.className.replace(/(?:^|\s)active(?!\S)/g , '');
button.className = button.className.replace(/(?:^|\s)active(?!\S)/g, '');
return false;
}
const toggles = document.getElementsByClassName('toggle-password');
@ -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,8 +1,7 @@
// @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() {
const init_integration = function () {
if (!window.context) {
if (window.console) {
console.log('FreshRSS integration waiting for JS…');

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>
// <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,13 +16,14 @@ 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>
// </Polyfills>
//<Utils>
// <Utils>
function xmlHttpRequestJson(req) {
let json = req.response;
if (req.responseType !== 'json') { //IE11
if (req.responseType !== 'json') { // IE11
try {
json = JSON.parse(req.responseText);
} catch (ex) {
@ -29,14 +32,14 @@ function xmlHttpRequestJson(req) {
}
return json;
}
//</Utils>
// </Utils>
//<Global context>
var context;
// <Global 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;
@ -48,7 +51,7 @@ var context;
context.icons.unread = decodeURIComponent(context.icons.unread);
context.extensions = json.extensions;
}());
//</Global context>
// </Global context>
function badAjax(reload) {
openNotification(context.i18n.notif_request_failed, 'bad');
@ -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');
@ -95,10 +100,10 @@ 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;
// Update unread: feed
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');
@ -107,7 +112,7 @@ function incUnreadsFeed(article, feed_id, nb) {
}
}
//Update unread: category
// Update unread: category
elem = document.getElementById(feed_id).closest('.category');
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
if (elem) {
@ -118,7 +123,7 @@ function incUnreadsFeed(article, feed_id, nb) {
}
}
//Update unread: all
// Update unread: all
if (feed_priority > 0) {
elem = document.querySelector('#aside_feed .all .title');
if (elem) {
@ -127,7 +132,7 @@ function incUnreadsFeed(article, feed_id, nb) {
}
}
//Update unread: favourites
// Update unread: favourites
if (article && article.closest('div').classList.contains('favorite')) {
elem = document.querySelector('#aside_feed .favorites .title');
if (elem) {
@ -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');
@ -227,17 +232,17 @@ function send_mark_read_queue(queue, asRead, callback) {
}
} else {
div.classList.add('not_read');
div.classList.add('keep_unread'); //Split for IE11
div.classList.add('keep_unread'); // Split for IE11
div.querySelectorAll('a.read').forEach(function (a) {
a.href = a.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, 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,15 +294,15 @@ 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) {
send_mark_read_queue_timeout = setTimeout(function () { send_mark_queue_tick(null); }, 1000);
}
} else {
const queue = [ entryId ];
const queue = [entryId];
send_mark_read_queue(queue, asRead);
}
}
@ -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) {
@ -398,7 +403,7 @@ function toggleContent(new_active, old_active, skipping) {
new_active.classList.add('current');
if (old_active) {
old_active.classList.remove('active');
old_active.classList.remove('current'); //Split for IE11
old_active.classList.remove('current'); // Split for IE11
if (context.auto_remove_article) {
removeArticle(old_active);
}
@ -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;
if (context.sticky_post) { // Stick the article to the top when opened
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()) {
@ -750,10 +755,10 @@ function init_column_categories() {
return;
}
//Restore sidebar scroll position
// Restore sidebar scroll position
document.getElementById('sidebar').scrollTop = +sessionStorage.getItem('FreshRSS_sidebar_scrollTop');
//Restore open categories
// Restore open categories
if (context.display_categories === 'remember') {
const open_categories = JSON.parse(localStorage.getItem('FreshRSS_open_categories') || '{}');
Object.keys(open_categories).forEach(function (category_id) {
@ -784,20 +789,20 @@ function init_column_categories() {
}
}
ul.classList.toggle('active');
//CSS transition does not work on max-height:auto
// CSS transition does not work on max-height:auto
ul.style.maxHeight = ul.classList.contains('active') ? (nbVisibleItems * 4) + 'em' : 0;
return false;
}
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;
@ -834,7 +839,7 @@ function init_shortcuts() {
const s = context.shortcuts;
let k = (ev.key.trim() || ev.code || 'Space').toUpperCase();
//IE11
// IE11
if (k === 'SPACEBAR') k = 'SPACE';
else if (k === 'DEL') k = 'DELETE';
else if (k === 'ESC') k = 'ESCAPE';
@ -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);
}
@ -990,9 +995,9 @@ function init_stream(stream) {
}
el = ev.target.closest('.item.share > a[data-type="print"]');
if (el) { //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);
@ -1004,13 +1009,13 @@ function init_stream(stream) {
}
el = ev.target.closest('.item.share > a[data-type="clipboard"]');
if (el && navigator.clipboard) { //Clipboard
if (el && navigator.clipboard) { // Clipboard
navigator.clipboard.writeText(el.href);
return false;
}
el = ev.target.closest('.item.share > a[href="POST"]');
if (el) { //Share by POST
if (el) { // Share by POST
const f = el.parentElement.querySelector('form');
f.disabled = false;
f.submit();
@ -1018,7 +1023,7 @@ function init_stream(stream) {
}
el = ev.target.closest('.flux_header, .flux_content');
if (el) { //flux_toggle
if (el) { // flux_toggle
if (ev.target.closest('.content, .item.website, .item.link, .dropdown-menu')) {
return true;
}
@ -1026,9 +1031,9 @@ 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;
if (ev.target.tagName.toUpperCase() === 'A') { //Leave real links alone
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);
}
@ -1047,14 +1052,14 @@ function init_stream(stream) {
let el = ev.target.closest('.item.title > a');
if (el) {
if (ev.which == 1) {
if (ev.ctrlKey) { //Control+click
if (ev.ctrlKey) { // Control+click
if (context.auto_mark_site) {
mark_read(el.closest('.flux'), true, false);
}
} else {
el.parentElement.click(); //Normal click, just toggle article.
el.parentElement.click(); // Normal click, just toggle article.
}
} else if (ev.which == 2 && !ev.ctrlKey) { //Simple middle click: same behaviour as CTRL+click
} else if (ev.which == 2 && !ev.ctrlKey) { // Simple middle click: same behaviour as CTRL+click
if (context.auto_mark_article) {
const new_active = el.closest('.flux');
mark_read(new_active, true, false);
@ -1078,13 +1083,13 @@ function init_stream(stream) {
stream.onchange = function (ev) {
const checkboxTag = ev.target.closest('.checkboxTag');
if (checkboxTag) { //Dynamic tags
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();
@ -1194,7 +1199,7 @@ function updateFeed(feeds, feeds_count) {
div.querySelector('.progress').innerHTML = feed_processed + ' / ' + feeds_count;
div.querySelector('.title').innerHTML = feed.title;
if (feed_processed === feeds_count) {
//Empty request to commit new articles
// Empty request to commit new articles
const req2 = new XMLHttpRequest();
req2.open('POST', './?c=feed&a=actualize&id=-1&ajax=1', true);
req2.onloadend = function (e) {
@ -1248,7 +1253,7 @@ function init_actualize() {
}
if (json.feeds.length === 0) {
openNotification(json.feedback_no_refresh, 'good');
//Empty request to commit new articles
// Empty request to commit new articles
const req2 = new XMLHttpRequest();
req2.open('POST', './?c=feed&a=actualize&id=-1&ajax=1', true);
req2.onloadend = function (e) {
@ -1261,7 +1266,7 @@ function init_actualize() {
}));
return;
}
//Progress bar
// Progress bar
const feeds_count = json.feeds.length;
document.body.insertAdjacentHTML('beforeend', '<div id="actualizeProgress" class="notification good">' +
json.feedback_actualize + '<br /><span class="title">/</span><br /><span class="progress">0 / ' +
@ -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';
@ -1367,7 +1375,7 @@ function closePopup() {
}
function init_popup() {
//Fetch elements.
// Fetch elements.
popup = document.getElementById('popup');
popup_iframe_container = document.getElementById('popup-iframe-container');
@ -1375,12 +1383,12 @@ function init_popup() {
popup_txt = document.getElementById('popup-txt');
//Configure close button.
// Configure close button.
document.getElementById('popup-close').addEventListener('click', function (ev) {
closePopup();
});
//Configure close-on-click.
// Configure close-on-click.
window.addEventListener('click', function (ev) {
if (ev.target == popup) {
closePopup();
@ -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;
@ -1414,7 +1422,7 @@ function notifs_html5_show(nb) {
});
notification.onclick = function () {
delayedFunction(function() {
delayedFunction(function () {
location.reload();
window.focus();
notification.close();
@ -1452,10 +1460,10 @@ 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?
if ((incUnreadsFeed(null, feed_id, nbUnreads - feed_unreads) || isAll) && // Update of current view?
(nbUnreads - feed_unreads > 0)) {
const newArticle = document.getElementById('new-article');
newArticle.setAttribute('aria-hidden', 'false');
@ -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);
@ -1493,10 +1501,10 @@ function refreshUnreads() {
req.send();
}
//<endless_mode>
var url_load_more = '',
load_more = false,
box_load_more = null;
// <endless_mode>
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');
@ -1532,7 +1540,7 @@ function load_more_posts() {
document.querySelectorAll('[id^=day_]').forEach(function (div) {
const ids = document.querySelectorAll('[id="' + div.id + '"]');
for (let i = ids.length - 1; i > 0; i--) { //Keep only the first
for (let i = ids.length - 1; i > 0; i--) { // Keep only the first
ids[i].remove();
}
});
@ -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) {
@ -1573,7 +1581,7 @@ function init_load_more(box) {
return false;
};
}
//</endless_mode>
// </endless_mode>
function init_confirm_action() {
document.body.onclick = function (ev) {
@ -1594,10 +1602,10 @@ function faviconNbUnread(n) {
const t = document.querySelector('.category.all .title');
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;
// http://remysharp.com/2010/08/24/dynamic-favicons/
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');
@ -1651,7 +1659,7 @@ function init_normal() {
window.onbeforeunload = function (e) {
const sidebar = document.getElementById('sidebar');
if (sidebar) { //Save sidebar scroll position
if (sidebar) { // Save sidebar scroll position
sessionStorage.setItem('FreshRSS_sidebar_scrollTop', sidebar.scrollTop);
}
if (mark_read_queue && mark_read_queue.length > 0) {
@ -1687,7 +1695,7 @@ function init_afterDOM() {
}
}
init_beforeDOM(); //Can be called before DOM is fully loaded
init_beforeDOM(); // Can be called before DOM is fully loaded
if (document.readyState && document.readyState !== 'loading') {
init_afterDOM();

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,13 +13,13 @@ 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) {
switch (jsonDataParsed.charttype) {
case 'bar':
chartConfig = jsonChartBar(jsonDataParsed.label, jsonDataParsed.data, jsonDataParsed.xAxisLabels);
break;
@ -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,
}
}
}
},
},
},
};
}
@ -84,22 +83,22 @@ function jsonChartDoughnut(labels, data) {
labels: labels,
datasets: [{
backgroundColor: [
'#0b84a5', //petrol
'#0b84a5', // petrol
'#f6c85f', // sand
'#6f4e7c', //purple
'#9dd866', //green
'#ca472f', //red
'#ffa056', //orange
'#6f4e7c', // purple
'#9dd866', // green
'#ca472f', // red
'#ffa056', // orange
'#8dddd0', // turkis
'#f6c85f', // sand
'#6f4e7c', //purple
'#9dd866', //green
'#ca472f', //red
'#ffa056', //orange
'#6f4e7c', // purple
'#9dd866', // green
'#ca472f', // red
'#ffa056', // orange
'#8dddd0', // turkis
],
data: data,
}]
}],
},
options: {
layout: {
@ -109,9 +108,9 @@ function jsonChartDoughnut(labels, data) {
legend: {
position: 'bottom',
align: 'start',
}
}
}
},
},
},
};
}
@ -136,12 +135,12 @@ function jsonChartBarWithAvarage(labelBarChart, dataBarChart, labelAverage, data
label: labelAverage, // Todo: i18n
borderColor: 'rgb(192,216,0)',
data: {
'-30' : dataAverage,
'-1' : dataAverage,
'-30': dataAverage,
'-1': dataAverage,
},
order: 1,
}
]
},
],
},
options: {
@ -151,41 +150,41 @@ function jsonChartBarWithAvarage(labelBarChart, dataBarChart, labelAverage, data
},
x: {
ticks: {
callback: function(val){
callback: function (val) {
if (xAxisLabels.length > 0) {
return xAxisLabels[val];
} else {
return val;
}
}
},
},
grid: {
display: false,
}
}
},
},
},
elements: {
point: {
radius: 0,
}
},
},
plugins: {
tooltip: {
callbacks: {
title: function(tooltipitem) {
title: function (tooltipitem) {
if (xAxisLabels.length > 0) {
return xAxisLabels[tooltipitem[0].dataIndex];
} 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"
}
}