added linters and fixed the issues (#169)
* added the rules * fixed QuickCollapse * fixed readingtime * fixed stickyfeeds * fix const/var quick_collapse_vars I do not understand why const does not work * update version number --------- Co-authored-by: math-gh <>
This commit is contained in:
parent
9e007bd730
commit
5a1be06d01
15 changed files with 4928 additions and 129 deletions
29
.eslintrc.json
Normal file
29
.eslintrc.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"env": {
|
||||
"browser": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"standard"
|
||||
],
|
||||
"rules": {
|
||||
"camelcase": "off",
|
||||
"comma-dangle": ["warn", {
|
||||
"arrays": "always-multiline",
|
||||
"objects": "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
2
.gitignore
vendored
|
|
@ -1 +1,3 @@
|
|||
tmp
|
||||
/node_modules/
|
||||
.vscode/
|
||||
|
|
|
|||
3
.jshintignore
Normal file
3
.jshintignore
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.git/
|
||||
node_modules/
|
||||
|
||||
9
.jshintrc
Normal file
9
.jshintrc
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"esversion" : 8,
|
||||
"browser" : true,
|
||||
"globals": {
|
||||
"confirm": true,
|
||||
"console": true
|
||||
},
|
||||
"strict": "global"
|
||||
}
|
||||
2
.stylelintignore
Normal file
2
.stylelintignore
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
.git/
|
||||
node_modules/
|
||||
72
.stylelintrc.json
Normal file
72
.stylelintrc.json
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"extends": "stylelint-config-recommended-scss",
|
||||
"plugins": [
|
||||
"stylelint-order",
|
||||
"stylelint-scss"
|
||||
],
|
||||
"rules": {
|
||||
"at-rule-empty-line-before": [
|
||||
"always", {
|
||||
"ignoreAtRules": [ "after-comment", "else" ]
|
||||
}
|
||||
],
|
||||
"at-rule-name-space-after": [
|
||||
"always", {
|
||||
"ignoreAtRules": [ "after-comment" ]
|
||||
}
|
||||
],
|
||||
"block-closing-brace-newline-after": [
|
||||
"always", {
|
||||
"ignoreAtRules": [ "if", "else" ]
|
||||
}
|
||||
],
|
||||
"block-closing-brace-newline-before": "always-multi-line",
|
||||
"block-opening-brace-newline-after": "always-multi-line",
|
||||
"block-opening-brace-space-before": "always",
|
||||
"color-hex-case": "lower",
|
||||
"color-hex-length": "short",
|
||||
"color-no-invalid-hex": true,
|
||||
"declaration-colon-space-after": "always",
|
||||
"declaration-colon-space-before": "never",
|
||||
"indentation": "tab",
|
||||
"no-descending-specificity": null,
|
||||
"no-eol-whitespace": true,
|
||||
"property-no-vendor-prefix": true,
|
||||
"rule-empty-line-before": [
|
||||
"always", {
|
||||
"except": ["after-single-line-comment","first-nested"]
|
||||
}
|
||||
],
|
||||
"order/properties-order": [
|
||||
"margin",
|
||||
"padding",
|
||||
"background",
|
||||
"display",
|
||||
"float",
|
||||
"max-width",
|
||||
"width",
|
||||
"max-height",
|
||||
"height",
|
||||
"color",
|
||||
"font",
|
||||
"font-family",
|
||||
"font-size",
|
||||
"border",
|
||||
"border-top",
|
||||
"border-top-color",
|
||||
"border-right",
|
||||
"border-right-color",
|
||||
"border-bottom",
|
||||
"border-bottom-color",
|
||||
"border-left",
|
||||
"border-left-color",
|
||||
"border-radius",
|
||||
"box-shadow"
|
||||
],
|
||||
"scss/at-else-closing-brace-newline-after": "always-last-in-chain",
|
||||
"scss/at-else-closing-brace-space-after": "always-intermediate",
|
||||
"scss/at-else-empty-line-before": "never",
|
||||
"scss/at-if-closing-brace-newline-after": "always-last-in-chain",
|
||||
"scss/at-if-closing-brace-space-after": "always-intermediate"
|
||||
}
|
||||
}
|
||||
4633
package-lock.json
generated
Normal file
4633
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
43
package.json
Normal file
43
package.json
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"name": "freshrss extensions",
|
||||
"description": "Extensions for FreshRSS",
|
||||
"homepage": "https://freshrss.org/",
|
||||
"readmeFilename": "README.md",
|
||||
"bugs": {
|
||||
"url": "https://github.com/FreshRSS/Extensions/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"freshrss",
|
||||
"extensions"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/FreshRSS/Extensions.git"
|
||||
},
|
||||
"license": "see each extension",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"scripts": {
|
||||
"eslint": "eslint --ext .js .",
|
||||
"eslint_fix": "eslint --fix --ext .js .",
|
||||
"markdownlint": "markdownlint '**/*.md'",
|
||||
"markdownlint_fix": "markdownlint --fix '**/*.md'",
|
||||
"stylelint": "stylelint '**/*.css' && stylelint --custom-syntax postcss-scss '**/*.scss'",
|
||||
"stylelint_fix": "stylelint --fix '**/*.css' && stylelint --fix --custom-syntax postcss-scss '**/*.scss'",
|
||||
"test": "npm run eslint && npm run stylelint && npm run markdownlint",
|
||||
"fix": "npm run rtlcss && npm run stylelint_fix && npm run eslint_fix && npm run markdownlint_fix"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.45.0",
|
||||
"eslint-config-standard": "^17.1.0",
|
||||
"eslint-plugin-import": "^2.27.5",
|
||||
"eslint-plugin-n": "^16.0.1",
|
||||
"eslint-plugin-promise": "^6.1.1",
|
||||
"markdownlint-cli": "^0.35.0",
|
||||
"sass": "^1.63.6",
|
||||
"stylelint": "^15.10.2",
|
||||
"stylelint-config-recommended-scss": "^12.0.0",
|
||||
"stylelint-order": "^6.0.3"
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Quick Collapse",
|
||||
"author": "romibi and Marien Fressinaud",
|
||||
"description": "Quickly change from folded to unfolded articles",
|
||||
"version": 0.1,
|
||||
"version": 0.1.1,
|
||||
"entrypoint": "QuickCollapse",
|
||||
"type": "user"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,68 +1,70 @@
|
|||
/* globals context, quick_collapse_vars */
|
||||
|
||||
(function () {
|
||||
function toggleCollapse() {
|
||||
const streamElem = document.getElementById('stream');
|
||||
const toggleElem = document.getElementById('toggle-collapse');
|
||||
const wasCollapsed = streamElem.classList.contains('hide_posts');
|
||||
function toggleCollapse() {
|
||||
const streamElem = document.getElementById('stream');
|
||||
const toggleElem = document.getElementById('toggle-collapse');
|
||||
const wasCollapsed = streamElem.classList.contains('hide_posts');
|
||||
|
||||
if (wasCollapsed) {
|
||||
streamElem.classList.remove('hide_posts');
|
||||
toggleElem.classList.remove('collapsed');
|
||||
} else {
|
||||
streamElem.classList.add('hide_posts');
|
||||
toggleElem.classList.add('collapsed');
|
||||
}
|
||||
if (wasCollapsed) {
|
||||
streamElem.classList.remove('hide_posts');
|
||||
toggleElem.classList.remove('collapsed');
|
||||
} else {
|
||||
streamElem.classList.add('hide_posts');
|
||||
toggleElem.classList.add('collapsed');
|
||||
}
|
||||
|
||||
if (context.does_lazyload && wasCollapsed) {
|
||||
const lazyloadedElements = streamElem.querySelectorAll(
|
||||
'img[data-original], iframe[data-original]'
|
||||
);
|
||||
lazyloadedElements.forEach(function (el) {
|
||||
el.src = el.getAttribute('data-original');
|
||||
el.removeAttribute('data-original');
|
||||
});
|
||||
}
|
||||
}
|
||||
if (context.does_lazyload && wasCollapsed) {
|
||||
const lazyloadedElements = streamElem.querySelectorAll(
|
||||
'img[data-original], iframe[data-original]'
|
||||
);
|
||||
lazyloadedElements.forEach(function (el) {
|
||||
el.src = el.getAttribute('data-original');
|
||||
el.removeAttribute('data-original');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function syncWithContext() {
|
||||
if (!window.context || !window.quick_collapse_vars) {
|
||||
// The variables might not be available yet, so we need to wait for them.
|
||||
return setTimeout(syncWithContext, 10);
|
||||
}
|
||||
function syncWithContext() {
|
||||
if (!window.context || !window.quick_collapse_vars) {
|
||||
// The variables might not be available yet, so we need to wait for them.
|
||||
return setTimeout(syncWithContext, 10);
|
||||
}
|
||||
|
||||
const toggleElem = document.getElementById('toggle-collapse');
|
||||
toggleElem.title = quick_collapse_vars.i18n.toggle_collapse;
|
||||
toggleElem.innerHTML = `<img class="icon uncollapse" src="${quick_collapse_vars.icon_url_out}" alt="↕" />`;
|
||||
toggleElem.innerHTML += `<img class="icon collapse" src="${quick_collapse_vars.icon_url_in}" alt="✖" />`;
|
||||
const toggleElem = document.getElementById('toggle-collapse');
|
||||
toggleElem.title = quick_collapse_vars.i18n.toggle_collapse;
|
||||
toggleElem.innerHTML = `<img class="icon uncollapse" src="${quick_collapse_vars.icon_url_out}" alt="↕" />`;
|
||||
toggleElem.innerHTML += `<img class="icon collapse" src="${quick_collapse_vars.icon_url_in}" alt="✖" />`;
|
||||
|
||||
if (context.hide_posts) {
|
||||
toggleElem.classList.add('collapsed');
|
||||
}
|
||||
}
|
||||
if (context.hide_posts) {
|
||||
toggleElem.classList.add('collapsed');
|
||||
}
|
||||
}
|
||||
|
||||
const streamElem = document.getElementById('stream');
|
||||
if (!streamElem || !streamElem.classList.contains('normal')) {
|
||||
// The button should be enabled only on "normal" view
|
||||
return;
|
||||
}
|
||||
const streamElem = document.getElementById('stream');
|
||||
if (!streamElem || !streamElem.classList.contains('normal')) {
|
||||
// The button should be enabled only on "normal" view
|
||||
return;
|
||||
}
|
||||
|
||||
// create the new button
|
||||
const toggleElem = document.createElement('button');
|
||||
toggleElem.id = 'toggle-collapse';
|
||||
toggleElem.classList.add('btn');
|
||||
toggleElem.addEventListener('click', toggleCollapse);
|
||||
// create the new button
|
||||
const toggleElem = document.createElement('button');
|
||||
toggleElem.id = 'toggle-collapse';
|
||||
toggleElem.classList.add('btn');
|
||||
toggleElem.addEventListener('click', toggleCollapse);
|
||||
|
||||
// replace the "order" button by a stick containing the order and the
|
||||
// collapse buttons
|
||||
const orderElem = document.getElementById('toggle-order');
|
||||
// replace the "order" button by a stick containing the order and the
|
||||
// collapse buttons
|
||||
const orderElem = document.getElementById('toggle-order');
|
||||
|
||||
const stickElem = document.createElement('div');
|
||||
stickElem.classList.add('stick');
|
||||
const stickElem = document.createElement('div');
|
||||
stickElem.classList.add('stick');
|
||||
|
||||
orderElem.parentNode.insertBefore(stickElem, orderElem);
|
||||
stickElem.appendChild(orderElem);
|
||||
stickElem.appendChild(toggleElem);
|
||||
orderElem.parentNode.insertBefore(stickElem, orderElem);
|
||||
stickElem.appendChild(orderElem);
|
||||
stickElem.appendChild(toggleElem);
|
||||
|
||||
// synchronizes the collapse button with dynamic vars passed via the
|
||||
// backend (async mode).
|
||||
syncWithContext();
|
||||
// synchronizes the collapse button with dynamic vars passed via the
|
||||
// backend (async mode).
|
||||
syncWithContext();
|
||||
}());
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
/* exported quick_collapse_vars */
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
var quick_collapse_vars = {
|
||||
icon_url_in: "<?= $this->icon_url_in ?>",
|
||||
icon_url_out: "<?= $this->icon_url_out ?>",
|
||||
i18n: {
|
||||
toggle_collapse: "<?= $this->i18n_toggle_collapse ?>",
|
||||
},
|
||||
icon_url_in: '<?= $this->icon_url_in ?>',
|
||||
icon_url_out: '<?= $this->icon_url_out ?>',
|
||||
i18n: {
|
||||
toggle_collapse: '<?= $this->i18n_toggle_collapse ?>',
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "ReadingTime",
|
||||
"author": "Lapineige",
|
||||
"description": "Add a reading time estimation next to each article",
|
||||
"version": 1.3,
|
||||
"version": 1.3.1,
|
||||
"entrypoint": "ReadingTime",
|
||||
"type": "user"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +1,77 @@
|
|||
/* globals $ */
|
||||
|
||||
(function reading_time() {
|
||||
'use strict';
|
||||
'use strict';
|
||||
|
||||
var reading_time = {
|
||||
flux_list: null,
|
||||
flux: null,
|
||||
textContent: null,
|
||||
words_count: null,
|
||||
read_time: null,
|
||||
reading_time: null,
|
||||
const reading_time = {
|
||||
flux_list: null,
|
||||
flux: null,
|
||||
textContent: null,
|
||||
words_count: null,
|
||||
read_time: null,
|
||||
reading_time: null,
|
||||
|
||||
init: function() {
|
||||
var flux_list = document.querySelectorAll('[id^="flux_"]');
|
||||
init: function () {
|
||||
const flux_list = document.querySelectorAll('[id^="flux_"]');
|
||||
|
||||
for (var i = 0; i < flux_list.length; i++) {
|
||||
for (let i = 0; i < flux_list.length; i++) {
|
||||
if ('readingTime' in flux_list[i].dataset) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ("readingTime" in flux_list[i].dataset) {
|
||||
continue;
|
||||
}
|
||||
reading_time.flux = flux_list[i];
|
||||
|
||||
reading_time.flux = flux_list[i];
|
||||
reading_time.words_count = reading_time.flux_words_count(flux_list[i]); // count the words
|
||||
// change this number (in words) to your prefered reading speed:
|
||||
reading_time.reading_time = reading_time.calc_read_time(reading_time.words_count, 300);
|
||||
|
||||
reading_time.words_count = reading_time.flux_words_count(flux_list[i]); // count the words
|
||||
reading_time.reading_time = reading_time.calc_read_time(reading_time.words_count, 300); // change this number (in words) to your prefered reading speed
|
||||
flux_list[i].dataset.readingTime = reading_time.reading_time;
|
||||
|
||||
flux_list[i].dataset.readingTime = reading_time.reading_time;
|
||||
const li = document.createElement('li');
|
||||
li.setAttribute('class', 'item date');
|
||||
li.style.width = 'min-content';
|
||||
li.style.minWidth = '40px';
|
||||
li.style.overflow = 'hidden';
|
||||
li.style.textAlign = 'right';
|
||||
li.style.display = 'table-cell';
|
||||
li.textContent = reading_time.reading_time + '\u2009m';
|
||||
|
||||
const li = document.createElement("li");
|
||||
li.setAttribute("class", "item date");
|
||||
li.style.width = "min-content";
|
||||
li.style.minWidth = "40px";
|
||||
li.style.overflow = "hidden";
|
||||
li.style.textAlign = "right";
|
||||
li.style.display = "table-cell";
|
||||
li.textContent = reading_time.reading_time + '\u2009m';
|
||||
const ul = document.querySelector('#' + reading_time.flux.id + ' ul.horizontal-list');
|
||||
ul.insertBefore(li, ul.children[ul.children.length - 1]);
|
||||
}
|
||||
},
|
||||
|
||||
const ul = document.querySelector("#" + reading_time.flux.id + " ul.horizontal-list");
|
||||
ul.insertBefore(li, ul.children[ul.children.length - 1]);
|
||||
}
|
||||
},
|
||||
flux_words_count: function flux_words_count(flux) {
|
||||
// get textContent, from the article itself (not the header, not the bottom line):
|
||||
reading_time.textContent = flux.querySelector('.flux_content .content').textContent;
|
||||
|
||||
flux_words_count: function flux_words_count(flux) {
|
||||
// split the text to count the words correctly (source: http://www.mediacollege.com/internet/javascript/text/count-words.html)
|
||||
reading_time.textContent = reading_time.textContent.replace(/(^\s*)|(\s*$)/gi, ''); // exclude start and end white-space
|
||||
reading_time.textContent = reading_time.textContent.replace(/[ ]{2,}/gi, ' '); // 2 or more space to 1
|
||||
reading_time.textContent = reading_time.textContent.replace(/\n /, '\n'); // exclude newline with a start spacing
|
||||
|
||||
reading_time.textContent = flux.querySelector('.flux_content .content').textContent; // get textContent, from the article itself (not the header, not the bottom line).
|
||||
return reading_time.textContent.split(' ').length;
|
||||
},
|
||||
|
||||
// split the text to count the words correctly (source: http://www.mediacollege.com/internet/javascript/text/count-words.html)
|
||||
reading_time.textContent = reading_time.textContent.replace(/(^\s*)|(\s*$)/gi,"");//exclude start and end white-space
|
||||
reading_time.textContent = reading_time.textContent.replace(/[ ]{2,}/gi," ");//2 or more space to 1
|
||||
reading_time.textContent = reading_time.textContent.replace(/\n /,"\n"); // exclude newline with a start spacing
|
||||
calc_read_time: function calc_read_time(wd_count, speed) {
|
||||
reading_time.read_time = Math.round(wd_count / speed);
|
||||
|
||||
return reading_time.textContent.split(' ').length;
|
||||
},
|
||||
if (reading_time.read_time === 0) {
|
||||
reading_time.read_time = '<1';
|
||||
}
|
||||
|
||||
calc_read_time : function calc_read_time(wd_count, speed) {
|
||||
reading_time.read_time = Math.round(wd_count/speed);
|
||||
if (reading_time.read_time === 0) { reading_time.read_time = '<1'; }
|
||||
return reading_time.read_time;
|
||||
},
|
||||
};
|
||||
return reading_time.read_time;
|
||||
},
|
||||
};
|
||||
|
||||
function add_load_more_listener() {
|
||||
reading_time.init();
|
||||
document.body.addEventListener('freshrss:load-more', function (e) {
|
||||
reading_time.init();
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState && document.readyState !== 'loading') {
|
||||
add_load_more_listener();
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener('DOMContentLoaded', add_load_more_listener, false);
|
||||
}
|
||||
function add_load_more_listener() {
|
||||
reading_time.init();
|
||||
document.body.addEventListener('freshrss:load-more', function (e) {
|
||||
reading_time.init();
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState && document.readyState !== 'loading') {
|
||||
add_load_more_listener();
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener('DOMContentLoaded', add_load_more_listener, false);
|
||||
}
|
||||
}());
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Sticky Feeds",
|
||||
"author": "Marien Fressinaud",
|
||||
"description": "Set the feed aside in the main stream following the window scroll.",
|
||||
"version": 0.1,
|
||||
"version": 0.1.1,
|
||||
"entrypoint": "StickyFeeds",
|
||||
"type": "user"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
"use strict";
|
||||
/* globals $ */
|
||||
'use strict';
|
||||
|
||||
var sticky_feeds = {
|
||||
const sticky_feeds = {
|
||||
aside: null,
|
||||
tree: null,
|
||||
window: null,
|
||||
|
||||
init: function() {
|
||||
if (window.matchMedia("(max-width: 840px)").matches) {
|
||||
init: function () {
|
||||
if (window.matchMedia('(max-width: 840px)').matches) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -34,14 +35,14 @@ var sticky_feeds = {
|
|||
}
|
||||
},
|
||||
|
||||
scroller: function() {
|
||||
var pos_top_window = sticky_feeds.window.scrollTop();
|
||||
scroller: function () {
|
||||
const pos_top_window = sticky_feeds.window.scrollTop();
|
||||
|
||||
if (pos_top_window < sticky_feeds.aside.initial_pos.top + sticky_feeds.tree.initial_pos.top) {
|
||||
// scroll top has not reached the top of the sticky tree yet so it
|
||||
// stays in place but its height must adapted:
|
||||
// window height - sticky tree pos top + actual scroll top
|
||||
var real_tree_pos_top = sticky_feeds.aside.initial_pos.top + sticky_feeds.tree.initial_pos.top;
|
||||
const real_tree_pos_top = sticky_feeds.aside.initial_pos.top + sticky_feeds.tree.initial_pos.top;
|
||||
sticky_feeds.tree.css('top', sticky_feeds.tree.initial_pos.top);
|
||||
sticky_feeds.tree.css('height', sticky_feeds.window.height - real_tree_pos_top + pos_top_window);
|
||||
} else {
|
||||
|
|
@ -55,5 +56,4 @@ var sticky_feeds = {
|
|||
},
|
||||
};
|
||||
|
||||
|
||||
window.onload = sticky_feeds.init;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue