From 63e297da167713e17fd271958b4109ea44e7075a Mon Sep 17 00:00:00 2001 From: ache Date: Fri, 9 Aug 2024 04:12:37 +0200 Subject: Lint JavaScript --- src/build/article.mjs | 12 ++- src/build/i18n.mjs | 94 +++++++++++++---------- src/build/index.mjs | 108 +++++++++++++++----------- src/build/load-svg.mjs | 10 +-- src/build/remove-footnote-header.mjs | 11 ++- src/build/rss.mjs | 33 ++++---- src/build/special_box.mjs | 35 +++++---- src/build/to-html.mjs | 68 ++++++++-------- src/build/utils.mjs | 7 +- src/js/love.js | 145 +++++++++++++++++++---------------- src/js/sidenotes.js | 40 ++++++---- src/js/theme.js | 60 +++++++-------- src/js/zen.js | 49 +++++++----- 13 files changed, 368 insertions(+), 304 deletions(-) diff --git a/src/build/article.mjs b/src/build/article.mjs index 1a7b09b..fc9a2f9 100644 --- a/src/build/article.mjs +++ b/src/build/article.mjs @@ -14,11 +14,17 @@ function getArticleYear(article) { function getArticleDate(article) { if (article.metaData.pubDate.getDate) { - return article.metaData.pubDate.getFullYear() * 100 + article.metaData.pubDate.getDate(); + return ( + article.metaData.pubDate.getFullYear() * 100 + + article.metaData.pubDate.getDate() + ); } if (article.metaData.pubDate.getUTCDate) { - return article.metaData.pubDate.getUTCFullYear() * 100 + article.metaData.pubDate.getDate(); + return ( + article.metaData.pubDate.getUTCFullYear() * 100 + + article.metaData.pubDate.getDate() + ); } return 0; @@ -28,4 +34,4 @@ function cmpArticles(a, b) { return getArticleDate(b) - getArticleDate(a); } -export {getArticleDate, getArticleYear, cmpArticles}; +export { getArticleDate, getArticleYear, cmpArticles }; diff --git a/src/build/i18n.mjs b/src/build/i18n.mjs index d1cebe6..b348c09 100644 --- a/src/build/i18n.mjs +++ b/src/build/i18n.mjs @@ -1,76 +1,85 @@ - const i18n = { fr: { intro: { - 'description': 'Éternel étudiant en Math-Info.', - 'about': 'Autodidacte passionné,
désormais ingénieur.', - 'about_tags': 'GNU\\Linux, C, C++, Python, Math, autohébergement, décentralisation, P2P, commun, ...
', + description: "Éternel étudiant en Math-Info.", + about: + 'Autodidacte passionné,
désormais ingénieur.', + about_tags: + "GNU\\Linux, C, C++, Python, Math, autohébergement, décentralisation, P2P, commun, ...
", }, title: { - 'main': 'ache: Blog personnel', - 'home': 'L\'accueil', - 'git': 'Dépôt git personnel', - 'mastodon': 'Mon mastodon', + main: "ache: Blog personnel", + home: "L'accueil", + git: "Dépôt git personnel", + mastodon: "Mon mastodon", }, articles: [ - 'framasoft-et-les-mascottes-du-libre.md', - 'les-trains-et-la-publicité.md', - 'formats-images-web.md', - 'bizarreries-du-langage-c.md', - 'retour-sur-laoc-2021-semaine-1.md', - '2FA-discord-sur-pc.md', - 'duckduckgo-google-en-mieux.md', + "framasoft-et-les-mascottes-du-libre.md", + "les-trains-et-la-publicité.md", + "formats-images-web.md", + "bizarreries-du-langage-c.md", + "retour-sur-laoc-2021-semaine-1.md", + "2FA-discord-sur-pc.md", + "duckduckgo-google-en-mieux.md", ], rss: { - 'title': 'ache: Blog personnel', - 'quick_description': 'Programmation, Algorithmique, Système, *pick you poison*', - 'description': `Ceci est un flux RSS à destination des agrégateurs de contenu.
\nEn tant qu'être humain vous cherchez certainement mon site web.` + title: "ache: Blog personnel", + quick_description: + "Programmation, Algorithmique, Système, *pick you poison*", + description: `Ceci est un flux RSS à destination des agrégateurs de contenu.
\nEn tant qu'être humain vous cherchez certainement mon site web.`, }, toc_keyword: "Sommaire", tag_desc: "Liste des articles ayant le tag", - index_desc: "Blog personnel à propos de programmation, logiciel libre et autohébergement. Essayons de rendre le monde meilleur.", + index_desc: + "Blog personnel à propos de programmation, logiciel libre et autohébergement. Essayons de rendre le monde meilleur.", like_title: "Si vous avez aimez cet article cliquez sur le cœur !", - like_text: "Vous pouvez même envoyez plusieurs cœurs !
Le délais d'attente entre deux cœurs double à chaque fois.", + like_text: + 'Vous pouvez même envoyez plusieurs cœurs !
Le délais d\'attente entre deux cœurs double à chaque fois.', }, en: { intro: { - 'description': 'Eternal student in computer science.', - 'quick_description': 'Programmation, Algorithmique, Système, *pick you poison*', - 'about': 'Self-taught developper,
now engineer.', - 'about_tags': 'GNU\\Linux, C, C++, Python, Math, self-hosted, dececntralisation, P2P, ...
', + description: "Eternal student in computer science.", + quick_description: + "Programmation, Algorithmique, Système, *pick you poison*", + about: + 'Self-taught developper,
now engineer.', + about_tags: + "GNU\\Linux, C, C++, Python, Math, self-hosted, dececntralisation, P2P, ...
", }, title: { - 'main': 'ache: Personal blog', - 'home': 'Home', - 'git': 'Personnel git repository', - 'mastodon': 'Mastodon account', + main: "ache: Personal blog", + home: "Home", + git: "Personnel git repository", + mastodon: "Mastodon account", }, articles: [ - 'rail-and-advertising.md', - 'web-image-formats.md', - 'c-language-quirks.md', + "rail-and-advertising.md", + "web-image-formats.md", + "c-language-quirks.md", ], rss: { - 'title': 'ache: Personal blog', - 'description': `This is a RSS feed for content agreagator.
\nAs a human being, you are certainly looking for my website.` + title: "ache: Personal blog", + description: `This is a RSS feed for content agreagator.
\nAs a human being, you are certainly looking for my website.`, }, toc_keyword: "Table of contents", tag_desc: "List of articles with the tag", - index_desc: "Personal blog about programming, free software and self-hosting. Let's try to make the world a better place.", + index_desc: + "Personal blog about programming, free software and self-hosting. Let's try to make the world a better place.", like_title: "If you liked this article click on the heart!", - like_text: "You can even send multiple hearts!
The waiting time between two hearts doubles each time.", - } -} + like_text: + 'You can even send multiple hearts!
The waiting time between two hearts doubles each time.', + }, +}; const lang_desc = { fr: "Version Française", en: "English version", -} +}; export function addDescription(alt_lang) { if (alt_lang) { - alt_lang.forEach(e => { - e.description = lang_desc[e.lang] + alt_lang.forEach((e) => { + e.description = lang_desc[e.lang]; }); } @@ -78,8 +87,9 @@ export function addDescription(alt_lang) { } export function getTocHeading() { - return Object.entries(i18n).map(([_, v]) => v.toc_keyword).join('|'); + return Object.entries(i18n) + .map(([_, v]) => v.toc_keyword) + .join("|"); } - export default i18n; diff --git a/src/build/index.mjs b/src/build/index.mjs index a14cdc7..cb918b7 100644 --- a/src/build/index.mjs +++ b/src/build/index.mjs @@ -1,26 +1,25 @@ -import process from 'node:process'; -import fs from 'node:fs'; -import mustache from 'mustache'; -import loadSVG from './load-svg.mjs'; -import getRSS from './rss.mjs'; -import loadMD from './loadMD.mjs'; -import {cmpArticles} from './article.mjs'; -import i18n from './i18n.mjs'; -import {addDescription} from './i18n.mjs'; -import {minifyHTML} from './utils.mjs'; - -import { SitemapStream, streamToPromise } from 'sitemap' -import { Readable } from 'stream' - - -const leftPanelTmpl = fs.readFileSync('src/templates/left.tmpl', 'utf8'); -const likesTmpl = fs.readFileSync('src/templates/likes.tmpl', 'utf8'); -const headerTmpl = fs.readFileSync('src/templates/header.tmpl', 'utf8'); -const articleTmpl = fs.readFileSync('src/templates/article.tmpl', 'utf8'); -const indexTmpl = fs.readFileSync('src/templates/index.tmpl', 'utf8'); -const tagTmpl = fs.readFileSync('src/templates/tag.tmpl', 'utf8'); -const hidTmpl = fs.readFileSync('src/templates/hid.tmpl', 'utf8'); -const baseUrl = 'https://ache.one/'; +import process from "node:process"; +import fs from "node:fs"; +import mustache from "mustache"; +import loadSVG from "./load-svg.mjs"; +import getRSS from "./rss.mjs"; +import loadMD from "./loadMD.mjs"; +import { cmpArticles } from "./article.mjs"; +import i18n from "./i18n.mjs"; +import { addDescription } from "./i18n.mjs"; +import { minifyHTML } from "./utils.mjs"; + +import { SitemapStream, streamToPromise } from "sitemap"; +import { Readable } from "stream"; + +const leftPanelTmpl = fs.readFileSync("src/templates/left.tmpl", "utf8"); +const likesTmpl = fs.readFileSync("src/templates/likes.tmpl", "utf8"); +const headerTmpl = fs.readFileSync("src/templates/header.tmpl", "utf8"); +const articleTmpl = fs.readFileSync("src/templates/article.tmpl", "utf8"); +const indexTmpl = fs.readFileSync("src/templates/index.tmpl", "utf8"); +const tagTmpl = fs.readFileSync("src/templates/tag.tmpl", "utf8"); +const hidTmpl = fs.readFileSync("src/templates/hid.tmpl", "utf8"); +const baseUrl = "https://ache.one/"; const partials = { header: headerTmpl, @@ -37,8 +36,11 @@ let links = []; for (const lang in i18n) { const tagsArticle = new Map(); const filter = process.argv.slice(2); - const listArticle = (filter.length > 0) ? i18n[lang].articles.filter((article) => filter.includes(article.name)) : i18n[lang].articles; - const articles = loadMD(listArticle, 'articles', lang); + const listArticle = + filter.length > 0 + ? i18n[lang].articles.filter((article) => filter.includes(article.name)) + : i18n[lang].articles; + const articles = loadMD(listArticle, "articles", lang); for (const article of articles) { const context = { @@ -61,7 +63,12 @@ for (const lang in i18n) { console.log(`Create : ${article.title}`); fs.writeFileSync(`articles/${article.name}.html`, minifyHTML(output)); - links.push({url: context.canonical, changefreq: 'yearly', priority: 0.6, img: [{url: article.imageUrl}]}) + links.push({ + url: context.canonical, + changefreq: "yearly", + priority: 0.6, + img: [{ url: article.imageUrl }], + }); for (const tag of article.metaData.tags) { if (tagsArticle.has(tag)) { @@ -72,12 +79,12 @@ for (const lang in i18n) { } } -// Set of pages language dependant + // Set of pages language dependant try { - fs.mkdirSync(`${lang}/tag`, {recursive: true}); + fs.mkdirSync(`${lang}/tag`, { recursive: true }); } catch { - fs.rmSync(`${lang}/tag`, {force: true, recursive: true}); - fs.mkdirSync(`${lang}/tag`, {recursive: true}); + fs.rmSync(`${lang}/tag`, { force: true, recursive: true }); + fs.mkdirSync(`${lang}/tag`, { recursive: true }); } for (const [tag, articles] of tagsArticle.entries()) { @@ -92,28 +99,36 @@ for (const lang in i18n) { lang, tag, articles, - description: `${i18n[lang]['tag_desc']} ${tag}.`, + description: `${i18n[lang]["tag_desc"]} ${tag}.`, }; const output = mustache.render(tagTmpl, context, partials); fs.writeFileSync(`${lang}/tag/${tag}.html`, minifyHTML(output)); - links.push({url: `${baseUrl}${lang}/tag/${tag}`, changefreq: 'monthly', priority: 0.3}) + links.push({ + url: `${baseUrl}${lang}/tag/${tag}`, + changefreq: "monthly", + priority: 0.3, + }); } console.log(`Create RSS Flux: ${lang}/rss.xml`); const xmlFeed = getRSS(articles, baseUrl, lang); fs.writeFileSync(`${lang}/rss.xml`, xmlFeed); - links.push({url: `${baseUrl}${lang}/rss.xml`, changefreq: 'monthly', priority: 0.3}) + links.push({ + url: `${baseUrl}${lang}/rss.xml`, + changefreq: "monthly", + priority: 0.3, + }); { const alt_lang = { fr: { - lang: 'en', - url: '/en/', + lang: "en", + url: "/en/", }, en: { - lang: 'fr', - url: '/fr/', + lang: "fr", + url: "/fr/", }, }; const context = { @@ -131,20 +146,21 @@ for (const lang in i18n) { console.log(`Create : Home page ${lang}`); const output = mustache.render(indexTmpl, context, partials); fs.writeFileSync(`${lang}/index.html`, minifyHTML(output)); - links.push({url: `${baseUrl}${lang}`, changefreq: 'monthly', priority: 0.7, img: [{url: "https://ache.one/res/ache.svg"}]}) + links.push({ + url: `${baseUrl}${lang}`, + changefreq: "monthly", + priority: 0.7, + img: [{ url: "https://ache.one/res/ache.svg" }], + }); } } console.log(`Create: sitemap.xml`); // Create a stream to write to -const stream = new SitemapStream({hostname: 'https://ache.one'}); +const stream = new SitemapStream({ hostname: "https://ache.one" }); // Return a promise that resolves with your XML string -streamToPromise( - Readable.from(links) - .pipe(stream)) - .then(data => data.toString()) - .then(sitemapXML => fs.writeFileSync("sitemap.xml", sitemapXML) -); - +streamToPromise(Readable.from(links).pipe(stream)) + .then((data) => data.toString()) + .then((sitemapXML) => fs.writeFileSync("sitemap.xml", sitemapXML)); diff --git a/src/build/load-svg.mjs b/src/build/load-svg.mjs index 6bf8db4..eb7bf3c 100644 --- a/src/build/load-svg.mjs +++ b/src/build/load-svg.mjs @@ -1,12 +1,12 @@ -import fs from 'node:fs'; +import fs from "node:fs"; const loadSVG = () => { const svg = {}; - for (const file of fs.readdirSync('s/imgM')) { - if (file.endsWith('.svg')) { - const contentFile = fs.readFileSync(`s/imgM/${file}`, 'utf8'); - const name = file.slice(0, -'.svg'.length); + for (const file of fs.readdirSync("s/imgM")) { + if (file.endsWith(".svg")) { + const contentFile = fs.readFileSync(`s/imgM/${file}`, "utf8"); + const name = file.slice(0, -".svg".length); svg[name] = contentFile; } } diff --git a/src/build/remove-footnote-header.mjs b/src/build/remove-footnote-header.mjs index a238692..95f481b 100644 --- a/src/build/remove-footnote-header.mjs +++ b/src/build/remove-footnote-header.mjs @@ -1,17 +1,16 @@ -import {visit} from 'unist-util-visit'; +import { visit } from "unist-util-visit"; // This plugin is an example to let users write HTML with directives. // It’s informative but rather useless. // See below for others examples. /** @type {import('unified').Plugin<[], import('mdast').Root>} */ export default function specialBox() { - return tree => { - visit(tree, node => { - if (node?.tagName === 'h2' && node?.properties?.id === 'footnote-label') { - node.tagName = 'hr'; + return (tree) => { + visit(tree, (node) => { + if (node?.tagName === "h2" && node?.properties?.id === "footnote-label") { + node.tagName = "hr"; node.children = []; // Exposure of children, Roman's way } }); }; } - diff --git a/src/build/rss.mjs b/src/build/rss.mjs index 6394af5..73b7803 100644 --- a/src/build/rss.mjs +++ b/src/build/rss.mjs @@ -1,14 +1,14 @@ -import RSS from 'rss'; -import i18n from './i18n.mjs'; +import RSS from "rss"; +import i18n from "./i18n.mjs"; const getRSS = (articles, baseUrl, lang) => { - console.log(i18n[lang]['rss']['title']); + console.log(i18n[lang]["rss"]["title"]); const rssFeed = new RSS({ - title: i18n[lang]['rss']['title'], - description: i18n[lang]['rss']['description'], + title: i18n[lang]["rss"]["title"], + description: i18n[lang]["rss"]["description"], // eslint-disable-next-line camelcase custom_namespaces: { - 'visible_description': i18n[lang]['rss']['description'] + visible_description: i18n[lang]["rss"]["description"], }, site_url: "https://ache.one", feed_url: `${baseUrl}rss.xml`, @@ -19,31 +19,34 @@ const getRSS = (articles, baseUrl, lang) => { image_url: `${baseUrl}ache.svg`, language: lang, pubDate: Date(), - ttl: '1440', + ttl: "1440", }); for (const article of articles.slice(0, 10)) { - let image_url = (article.imageUrl[0] != '/') ? `/${article.imageUrl}` : article.imageUrl; + let image_url = + article.imageUrl[0] != "/" ? `/${article.imageUrl}` : article.imageUrl; rssFeed.item({ title: article.title, - description: '
' + article.content + '
', + description: "
" + article.content + "
", // eslint-disable-next-line camelcase image_url, url: `${baseUrl}articles/${article.name}`, guid: article.domTitle, - author: 'ache', + author: "ache", date: article.metaData.pubDateISO, categories: article.metaData.tags, // eslint-disable-next-line camelcase - custom_elements: [ - {logo: image_url}, - {intro: article.introDesc}, - ], + custom_elements: [{ logo: image_url }, { intro: article.introDesc }], }); } - return rssFeed.xml({indent: false}).replace(/<\?xml version="1.0" encoding="UTF-8"\?>/g, ''); + return rssFeed + .xml({ indent: false }) + .replace( + /<\?xml version="1.0" encoding="UTF-8"\?>/g, + '', + ); }; export default getRSS; diff --git a/src/build/special_box.mjs b/src/build/special_box.mjs index 1457a98..f1631b6 100644 --- a/src/build/special_box.mjs +++ b/src/build/special_box.mjs @@ -1,39 +1,40 @@ -import {visit} from 'unist-util-visit'; +import { visit } from "unist-util-visit"; // This plugin is an example to let users write HTML with directives. // It’s informative but rather useless. // See below for others examples. /** @type {import('unified').Plugin<[], import('mdast').Root>} */ export default function specialBox() { - return tree => { - visit(tree, node => { - if (node.type === 'containerDirective' && ( - node.name === 'attention' - || node.name === 'question' - || node.name === 'note' - || node.name === 'information')) { + return (tree) => { + visit(tree, (node) => { + if ( + node.type === "containerDirective" && + (node.name === "attention" || + node.name === "question" || + node.name === "note" || + node.name === "information") + ) { const data = node.data || (node.data = {}); - data.hName = 'div'; + data.hName = "div"; data.hProperties = { - className: 'special-box ' + node.name, + className: "special-box " + node.name, }; } - if (node.type === 'containerDirective' && node.name === 'details') { - if(node.children.length > 0 && node.children[0].type == "paragraph") { + if (node.type === "containerDirective" && node.name === "details") { + if (node.children.length > 0 && node.children[0].type == "paragraph") { node.children[0] = { type: "containerDirective", data: { - hName: 'summary' + hName: "summary", }, - children: node.children[0].children + children: node.children[0].children, }; - const data = node.data || (node.data = {}); - data.hName = 'details'; + const data = node.data || (node.data = {}); + data.hName = "details"; } } }); }; } - diff --git a/src/build/to-html.mjs b/src/build/to-html.mjs index 786f91d..5c08242 100644 --- a/src/build/to-html.mjs +++ b/src/build/to-html.mjs @@ -1,43 +1,43 @@ -import {unified} from 'unified'; -import remarkParse from 'remark-parse'; -import remarkGfm from 'remark-gfm'; -import remarkToc from 'remark-toc'; -import remarkDirective from 'remark-directive'; -import remarkMath from 'remark-math'; -import remarkFrontmatter from 'remark-frontmatter'; -import remarkRehype from 'remark-rehype'; -import rehypeSlug from 'rehype-slug'; -import rehypePicture from 'rehype-picture' -import rehypeKaTeX from 'rehype-katex'; -import rehypeRaw from 'rehype-raw'; -import rehypeAutolinkHeadings from 'rehype-autolink-headings'; -import rehypeStringify from 'rehype-stringify'; -import rehypeHighlight from 'rehype-highlight'; -import remarkSpecialBox from './special_box.mjs'; -import remarkRemoveFootnoteHeader from './remove-footnote-header.mjs'; -import {getTocHeading} from './i18n.mjs'; +import { unified } from "unified"; +import remarkParse from "remark-parse"; +import remarkGfm from "remark-gfm"; +import remarkToc from "remark-toc"; +import remarkDirective from "remark-directive"; +import remarkMath from "remark-math"; +import remarkFrontmatter from "remark-frontmatter"; +import remarkRehype from "remark-rehype"; +import rehypeSlug from "rehype-slug"; +import rehypePicture from "rehype-picture"; +import rehypeKaTeX from "rehype-katex"; +import rehypeRaw from "rehype-raw"; +import rehypeAutolinkHeadings from "rehype-autolink-headings"; +import rehypeStringify from "rehype-stringify"; +import rehypeHighlight from "rehype-highlight"; +import remarkSpecialBox from "./special_box.mjs"; +import remarkRemoveFootnoteHeader from "./remove-footnote-header.mjs"; +import { getTocHeading } from "./i18n.mjs"; const autoLinkOption = { - behavior: 'wrap', + behavior: "wrap", properties: { tabIndex: 0, - className: 'anchor', + className: "anchor", }, }; const pictureOptions = { - 'png': {avif: 'image/avif'} -} + png: { avif: "image/avif" }, +}; const generator = unified() .use(remarkParse) .use(remarkGfm) - .use(remarkToc, {heading: getTocHeading(), tight: true, ordered: true}) + .use(remarkToc, { heading: getTocHeading(), tight: true, ordered: true }) .use(remarkMath) .use(remarkDirective) .use(remarkSpecialBox) - .use(remarkFrontmatter, {type: 'toml', marker: '-'}) - .use(remarkRehype, {allowDangerousHtml: true}) + .use(remarkFrontmatter, { type: "toml", marker: "-" }) + .use(remarkRehype, { allowDangerousHtml: true }) .use(rehypeRaw) .use(remarkRemoveFootnoteHeader) .use(rehypePicture, pictureOptions) @@ -50,14 +50,14 @@ const generator = unified() const generatorMd = unified() .use(remarkParse) .use(remarkGfm) - .use(remarkToc, {heading: getTocHeading(), tight: true, ordered: true}) + .use(remarkToc, { heading: getTocHeading(), tight: true, ordered: true }) .use(remarkMath) .use(remarkDirective) .use(remarkSpecialBox) - .use(remarkFrontmatter, {type: 'toml', marker: '-'}); + .use(remarkFrontmatter, { type: "toml", marker: "-" }); const generatorHTML = unified() - .use(remarkRehype, {allowDangerousHtml: true}) + .use(remarkRehype, { allowDangerousHtml: true }) .use(rehypeRaw) .use(remarkRemoveFootnoteHeader) .use(rehypePicture, pictureOptions) @@ -67,11 +67,13 @@ const generatorHTML = unified() .use(rehypeAutolinkHeadings, autoLinkOption) .use(rehypeStringify); -const toHtml = content => generator.processSync(content); +const toHtml = (content) => generator.processSync(content); -export const toMdRaw = content => generatorMd.runSync(generatorMd.parse(content)); -export const mdToHtmlRaw = content => generatorHTML.runSync(content); +export const toMdRaw = (content) => + generatorMd.runSync(generatorMd.parse(content)); +export const mdToHtmlRaw = (content) => generatorHTML.runSync(content); -export const toHtmlRaw = content => generator.runSync(generator.parse(content)); -export const toString = content => generator.stringify(content); +export const toHtmlRaw = (content) => + generator.runSync(generator.parse(content)); +export const toString = (content) => generator.stringify(content); export default toHtml; diff --git a/src/build/utils.mjs b/src/build/utils.mjs index fa85ee6..f76f74c 100644 --- a/src/build/utils.mjs +++ b/src/build/utils.mjs @@ -1,10 +1,11 @@ -import { minify } from 'html-minifier'; +import { minify } from "html-minifier"; -export const minifyHTML = (html) => minify(html, { +export const minifyHTML = (html) => + minify(html, { removeAttributeQuotes: true, removeComments: true, minifyJS: true, minifyCSS: true, collapseWhitespace: true, collapseBooleanAttributes: true, -}) + }); diff --git a/src/js/love.js b/src/js/love.js index 66f47d4..59ecccc 100644 --- a/src/js/love.js +++ b/src/js/love.js @@ -1,15 +1,18 @@ -window.addEventListener('DOMContentLoaded', () => { +window.addEventListener("DOMContentLoaded", () => { // This script insert a love button at the end of an article page - const articles = document.querySelectorAll('article'); + const articles = document.querySelectorAll("article"); function getCurrentPageLang() { - return document.documentElement.lang || "en"; + return document.documentElement.lang || "en"; } function getLikeEndPoint() { - let currentArticleName = window.location.pathname.split('/')[2]; - if (currentArticleName.indexOf('.') > 0) { - currentArticleName = currentArticleName.slice(0, currentArticleName.lastIndexOf('.')) + let currentArticleName = window.location.pathname.split("/")[2]; + if (currentArticleName.indexOf(".") > 0) { + currentArticleName = currentArticleName.slice( + 0, + currentArticleName.lastIndexOf("."), + ); } return `${window.location.origin}/like/${currentArticleName}`; @@ -19,20 +22,20 @@ window.addEventListener('DOMContentLoaded', () => { if (isAnArticle) { const article = articles[0]; - const likes = article.querySelector('.likes'); - const nbLikes = article.querySelector('.nbLikes'); - const footnotes = article.querySelector('.footnotes'); + const likes = article.querySelector(".likes"); + const nbLikes = article.querySelector(".nbLikes"); + const footnotes = article.querySelector(".footnotes"); - likes.style="display: 'block';"; + likes.style = "display: 'block';"; const updateNbLikes = () => { fetch(getLikeEndPoint(), { - method: 'GET', + method: "GET", headers: { - 'i-love-what-you-do': '<3', + "i-love-what-you-do": "<3", }, }).then((res) => { if (res.ok) { - res.text().then((text) => nbLikes.textContent = text); + res.text().then((text) => (nbLikes.textContent = text)); } else { nbLikes.textContent = ""; } @@ -46,80 +49,88 @@ window.addEventListener('DOMContentLoaded', () => { footnotes.before(likes); } - const icon = likes.querySelector('.icon'); - const messagesLike = likes.querySelector('.likesNotes'); + const icon = likes.querySelector(".icon"); + const messagesLike = likes.querySelector(".likesNotes"); - icon.addEventListener('mouseover', () => { + icon.addEventListener("mouseover", () => { for (const c of icon.children) { - const path = c.querySelector('path'); - path?.classList.add('anim'); + const path = c.querySelector("path"); + path?.classList.add("anim"); } }); - icon.addEventListener('mouseout', () => { + icon.addEventListener("mouseout", () => { for (const c of icon.children) { - const path = c.querySelector('path'); - path?.classList.remove('anim'); + const path = c.querySelector("path"); + path?.classList.remove("anim"); } }); - icon.addEventListener('click', () => { + icon.addEventListener("click", () => { const c = icon.children[1]; const lang = getCurrentPageLang(); - const path = c.querySelector('path'); + const path = c.querySelector("path"); - path.classList.add('anim-click'); - path.getAnimations().forEach(anim => { + path.classList.add("anim-click"); + path.getAnimations().forEach((anim) => { anim.cancel(); anim.play(); }); fetch(getLikeEndPoint(), { - method: 'POST', + method: "POST", headers: { - 'i-love-what-you-do': '<3', - 'lang': lang, + "i-love-what-you-do": "<3", + lang: lang, }, - }).then(response => { - const t = response.text(); - - if (response.ok) { - messagesLike.classList.remove('err'); - t.then(t => messagesLike.textContent = t); - updateNbLikes(); - } else { - t.then(t => { - // In case of error, we want to be able to set the initial message back - const previousText = messagesLike.textContent; - const timeoutErr = 3000; - const wasAnError = messagesLike.classList.contains('err'); - - // Set the error - messagesLike.classList.add('err'); - if (Math.floor(response.status / 100) == 4) { - messagesLike.textContent = t; - } else { - messagesLike.textContent = lang == 'fr' ? 'Désolé, le service est indisponible.' : 'Sorry, service unavailable.'; - } - - // Set the initial message back - if(!wasAnError) { - setTimeout(() => { - if(messagesLike.classList.contains('err')) { - messagesLike.classList.remove('err'); - messagesLike.textContent = previousText; - } - }, timeoutErr); - } - }); - } - }).catch(() => { - // In case of exception error. We don't want to set back the initial message. - messagesLike.classList.add('err'); - messagesLike.textContent = lang == 'fr' ? 'Désolé, le service est indisponible.' : 'Sorry, service unavailable.'; - messageText = ''; - }); + }) + .then((response) => { + const t = response.text(); + + if (response.ok) { + messagesLike.classList.remove("err"); + t.then((t) => (messagesLike.textContent = t)); + updateNbLikes(); + } else { + t.then((t) => { + // In case of error, we want to be able to set the initial message back + const previousText = messagesLike.textContent; + const timeoutErr = 3000; + const wasAnError = messagesLike.classList.contains("err"); + + // Set the error + messagesLike.classList.add("err"); + if (Math.floor(response.status / 100) == 4) { + messagesLike.textContent = t; + } else { + messagesLike.textContent = + lang == "fr" + ? "Désolé, le service est indisponible." + : "Sorry, service unavailable."; + } + + // Set the initial message back + if (!wasAnError) { + setTimeout(() => { + if (messagesLike.classList.contains("err")) { + messagesLike.classList.remove("err"); + messagesLike.textContent = previousText; + } + }, timeoutErr); + } + }); + } + }) + .catch(() => { + // In case of exception error. We don't want to set back the initial message. + messagesLike.classList.add("err"); + messagesLike.textContent = + lang == "fr" + ? "Désolé, le service est indisponible." + : "Sorry, service unavailable."; + messageText = ""; + }); }); } }); diff --git a/src/js/sidenotes.js b/src/js/sidenotes.js index 851e11b..591f856 100644 --- a/src/js/sidenotes.js +++ b/src/js/sidenotes.js @@ -19,19 +19,23 @@ let articles; const resize = () => { for (const [article, sidenote] of articles) { if (sidenote.offsetWidth < 200 || window.screen.width < 1400) { - sidenote.innerHTML = ''; + sidenote.innerHTML = ""; return; } - const notes = Array.from(article.querySelectorAll('li')) - .filter(element => element.id.startsWith('user-content-fn')); - const newSidenotes = notes.map(sidenoteLi => { - const div = document.createElement('div'); - const refName = sidenoteLi.querySelector('.data-footnote-backref').attributes.href.value; - const refSideNode = article.querySelector(`#${CSS.escape(refName.slice(1))}`); + const notes = Array.from(article.querySelectorAll("li")).filter((element) => + element.id.startsWith("user-content-fn"), + ); + const newSidenotes = notes.map((sidenoteLi) => { + const div = document.createElement("div"); + const refName = sidenoteLi.querySelector(".data-footnote-backref") + .attributes.href.value; + const refSideNode = article.querySelector( + `#${CSS.escape(refName.slice(1))}`, + ); - const sup = document.createElement('sup'); - sup.textContent = refSideNode.textContent + ' '; + const sup = document.createElement("sup"); + sup.textContent = refSideNode.textContent + " "; for (const element of sidenoteLi.children) { const child = element.cloneNode(true); @@ -40,7 +44,7 @@ const resize = () => { div.children[0].prepend(sup); div.style.top = `${getPos(refSideNode).y}px`; - div.classList.add('sidenote'); + div.classList.add("sidenote"); return div; }); @@ -48,21 +52,25 @@ const resize = () => { sidenote.replaceChildren(...newSidenotes); if (sidenote.offsetWidth < 100 || window.screen.width < 1400) { - sidenote.innerHTML = ''; + sidenote.innerHTML = ""; return; } } }; -window.addEventListener('DOMContentLoaded', () => { - articles = Array.from(document.querySelectorAll('article')); +window.addEventListener("DOMContentLoaded", () => { + articles = Array.from(document.querySelectorAll("article")); if (articles.length > 0) { - articles = articles.map(x => [x, x.parentElement.querySelector('.sidenotes')]); + articles = articles.map((x) => [ + x, + x.parentElement.querySelector(".sidenotes"), + ]); new ResizeObserver(resize).observe(articles[0][1]); } - if (document.querySelectorAll('.math-display').length > 0) { - document.head.innerHTML += ''; + if (document.querySelectorAll(".math-display").length > 0) { + document.head.innerHTML += + ''; } }); diff --git a/src/js/theme.js b/src/js/theme.js index 8239c69..a49fc8c 100644 --- a/src/js/theme.js +++ b/src/js/theme.js @@ -1,30 +1,32 @@ -window.addEventListener('DOMContentLoaded', () => { - const storageTheme = window.localStorage?.getItem('theme'); - const preferesDark = window.matchMedia('(prefers-color-scheme: dark)').matches; +window.addEventListener("DOMContentLoaded", () => { + const storageTheme = window.localStorage?.getItem("theme"); + const preferesDark = window.matchMedia( + "(prefers-color-scheme: dark)", + ).matches; let isDark = preferesDark; - const hid = document.querySelector('#hid'); - const html = document.querySelector('html'); - const aside = document.querySelector('#side-bar'); - const sidenotes = document.querySelector('.sidenotes'); - const footnotes = document.querySelector('.footnotes'); - const harr = document.querySelector('#harr'); - const links = document.querySelectorAll('a'); - const likes = document.querySelectorAll('.likes'); - const tables = document.querySelectorAll('table'); - const codes = document.querySelectorAll('p code'); - - if (storageTheme === 'dark' || storageTheme === 'light') { + const hid = document.querySelector("#hid"); + const html = document.querySelector("html"); + const aside = document.querySelector("#side-bar"); + const sidenotes = document.querySelector(".sidenotes"); + const footnotes = document.querySelector(".footnotes"); + const harr = document.querySelector("#harr"); + const links = document.querySelectorAll("a"); + const likes = document.querySelectorAll(".likes"); + const tables = document.querySelectorAll("table"); + const codes = document.querySelectorAll("p code"); + + if (storageTheme === "dark" || storageTheme === "light") { const theme = storageTheme; - isDark = storageTheme === 'dark'; + isDark = storageTheme === "dark"; hid.classList.add(theme); html.classList.add(theme); aside.classList.add(theme); sidenotes.classList.add(theme); harr.classList.add(theme); - if(footnotes) { + if (footnotes) { footnotes.classList.add(theme); } @@ -41,17 +43,17 @@ window.addEventListener('DOMContentLoaded', () => { code.classList.add(theme); } - for (const article of document.querySelectorAll('article')) { + for (const article of document.querySelectorAll("article")) { article.classList.add(theme); } - for (const article of document.querySelectorAll('article')) { + for (const article of document.querySelectorAll("article")) { article.classList.add(theme); } } function toogleTheme() { - const arg = isDark ? ['dark', 'light'] : ['light', 'dark']; + const arg = isDark ? ["dark", "light"] : ["light", "dark"]; const theme = arg[1]; if (!hid.classList.replace(...arg)) { @@ -73,8 +75,6 @@ window.addEventListener('DOMContentLoaded', () => { footnotes.classList.add(theme); } - - if (!harr.classList.replace(...arg)) { harr.classList.add(theme); } @@ -100,7 +100,7 @@ window.addEventListener('DOMContentLoaded', () => { } } - for (const article of document.querySelectorAll('article')) { + for (const article of document.querySelectorAll("article")) { if (!article.classList.replace(...arg)) { article.classList.add(theme); } @@ -108,19 +108,19 @@ window.addEventListener('DOMContentLoaded', () => { isDark = !isDark; if (window.localStorage) { - window.localStorage.setItem('theme', isDark ? 'dark' : 'light'); + window.localStorage.setItem("theme", isDark ? "dark" : "light"); } } - const sun = document.querySelector('.sun'); - const moon = document.querySelector('.moon'); + const sun = document.querySelector(".sun"); + const moon = document.querySelector(".moon"); - sun.addEventListener('click', toogleTheme); - moon.addEventListener('click', toogleTheme); + sun.addEventListener("click", toogleTheme); + moon.addEventListener("click", toogleTheme); if (isDark) { - hid.classList.add('dark'); + hid.classList.add("dark"); } else { - hid.classList.add('light'); + hid.classList.add("light"); } }); diff --git a/src/js/zen.js b/src/js/zen.js index be5f7d7..8437c81 100644 --- a/src/js/zen.js +++ b/src/js/zen.js @@ -1,19 +1,19 @@ -window.addEventListener('DOMContentLoaded', () => { - let firstTime = window.location.pathname != '/' && window.pageYOffset < 800; - const toggleArrow = document.querySelector('#harr'); - const hid = document.querySelector('#hid'); - const initValue = document.body.style.getPropertyValue('--width_panel_bis'); - - toggleArrow.addEventListener('click', () => { - if (toggleArrow.classList.contains('hide_arrow_off')) { +window.addEventListener("DOMContentLoaded", () => { + let firstTime = window.location.pathname != "/" && window.pageYOffset < 800; + const toggleArrow = document.querySelector("#harr"); + const hid = document.querySelector("#hid"); + const initValue = document.body.style.getPropertyValue("--width_panel_bis"); + + toggleArrow.addEventListener("click", () => { + if (toggleArrow.classList.contains("hide_arrow_off")) { firstTime = false; showAbout(); showHID(); setTimeout(() => { - toggleArrow.classList.remove('hide_arrow_off'); + toggleArrow.classList.remove("hide_arrow_off"); }, 1000); } else { - toggleArrow.classList.add('hide_arrow_off'); + toggleArrow.classList.add("hide_arrow_off"); hideAbout(); // If the screen is smaller than 500px, hide the HID @@ -24,37 +24,44 @@ window.addEventListener('DOMContentLoaded', () => { }); function hideAbout() { - document.body.style.setProperty('--width_panel_bis', '0px'); + document.body.style.setProperty("--width_panel_bis", "0px"); } function showAbout() { - document.body.style.setProperty('--width_panel_bis', initValue); + document.body.style.setProperty("--width_panel_bis", initValue); } function hideHID() { - hid.style.setProperty('display', 'none'); + hid.style.setProperty("display", "none"); } function showHID() { - hid.style.setProperty('display', ''); + hid.style.setProperty("display", ""); } - window.addEventListener('scroll', () => { - if(!toggleArrow) return; + window.addEventListener("scroll", () => { + if (!toggleArrow) return; if (window.pageYOffset >= 800) { - if (firstTime && document.body.style.getPropertyValue('--width_panel_bis') === initValue) { + if ( + firstTime && + document.body.style.getPropertyValue("--width_panel_bis") === initValue + ) { toggleArrow.click(); firstTime = true; } - toggleArrow.classList.add('hide_arrow_show'); + toggleArrow.classList.add("hide_arrow_show"); // A hideAbout(header, articles); - } else if (!toggleArrow.classList.contains('hide_arrow_off')) { + } else if (!toggleArrow.classList.contains("hide_arrow_off")) { // A showAbout(header, articles); - toggleArrow.classList.remove('hide_arrow_show'); + toggleArrow.classList.remove("hide_arrow_show"); } - if(firstTime && window.pageYOffset === 0 && document.body.style.getPropertyValue('--width_panel_bis') !== initValue) { + if ( + firstTime && + window.pageYOffset === 0 && + document.body.style.getPropertyValue("--width_panel_bis") !== initValue + ) { toggleArrow.click(); firstTime = true; } -- cgit v1.2.3-70-g09d2