summaryrefslogtreecommitdiff
path: root/src/js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js')
-rw-r--r--src/js/love.js125
-rw-r--r--src/js/sidenotes.js2
-rw-r--r--src/js/theme.js126
-rw-r--r--src/js/zen.js36
4 files changed, 280 insertions, 9 deletions
diff --git a/src/js/love.js b/src/js/love.js
new file mode 100644
index 0000000..66f47d4
--- /dev/null
+++ b/src/js/love.js
@@ -0,0 +1,125 @@
+window.addEventListener('DOMContentLoaded', () => {
+ // This script insert a love button at the end of an article page
+
+ const articles = document.querySelectorAll('article');
+
+ function getCurrentPageLang() {
+ return document.documentElement.lang || "en";
+ }
+ function getLikeEndPoint() {
+ let currentArticleName = window.location.pathname.split('/')[2];
+ if (currentArticleName.indexOf('.') > 0) {
+ currentArticleName = currentArticleName.slice(0, currentArticleName.lastIndexOf('.'))
+ }
+
+ return `${window.location.origin}/like/${currentArticleName}`;
+ }
+
+ const isAnArticle = articles.length === 1; // The front page have multiple articles.
+
+ if (isAnArticle) {
+ const article = articles[0];
+ const likes = article.querySelector('.likes');
+ const nbLikes = article.querySelector('.nbLikes');
+ const footnotes = article.querySelector('.footnotes');
+
+ likes.style="display: 'block';";
+ const updateNbLikes = () => {
+ fetch(getLikeEndPoint(), {
+ method: 'GET',
+ headers: {
+ 'i-love-what-you-do': '<3',
+ },
+ }).then((res) => {
+ if (res.ok) {
+ res.text().then((text) => nbLikes.textContent = text);
+ } else {
+ nbLikes.textContent = "";
+ }
+ });
+ };
+
+ updateNbLikes();
+
+ if (footnotes) {
+ // We want: article.insertBefore(likes, footnotes);
+ footnotes.before(likes);
+ }
+
+ const icon = likes.querySelector('.icon');
+ const messagesLike = likes.querySelector('.likesNotes');
+
+ icon.addEventListener('mouseover', () => {
+ for (const c of icon.children) {
+ const path = c.querySelector('path');
+ path?.classList.add('anim');
+ }
+ });
+
+ icon.addEventListener('mouseout', () => {
+ for (const c of icon.children) {
+ const path = c.querySelector('path');
+ path?.classList.remove('anim');
+ }
+ });
+
+ icon.addEventListener('click', () => {
+ const c = icon.children[1];
+ const lang = getCurrentPageLang();
+
+ const path = c.querySelector('path');
+
+ path.classList.add('anim-click');
+ path.getAnimations().forEach(anim => {
+ anim.cancel();
+ anim.play();
+ });
+
+ fetch(getLikeEndPoint(), {
+ method: 'POST',
+ headers: {
+ '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 = '';
+ });
+ });
+ }
+});
diff --git a/src/js/sidenotes.js b/src/js/sidenotes.js
index 8ab99f9..851e11b 100644
--- a/src/js/sidenotes.js
+++ b/src/js/sidenotes.js
@@ -28,7 +28,7 @@ const resize = () => {
const newSidenotes = notes.map(sidenoteLi => {
const div = document.createElement('div');
const refName = sidenoteLi.querySelector('.data-footnote-backref').attributes.href.value;
- const refSideNode = article.querySelector(refName);
+ const refSideNode = article.querySelector(`#${CSS.escape(refName.slice(1))}`);
const sup = document.createElement('sup');
sup.textContent = refSideNode.textContent + ' ';
diff --git a/src/js/theme.js b/src/js/theme.js
new file mode 100644
index 0000000..8239c69
--- /dev/null
+++ b/src/js/theme.js
@@ -0,0 +1,126 @@
+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 theme = storageTheme;
+ 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) {
+ footnotes.classList.add(theme);
+ }
+
+ for (let link of links) {
+ link.classList.add(theme);
+ }
+ for (let likeBox of likes) {
+ likeBox.classList.add(theme);
+ }
+ for (let table of tables) {
+ table.classList.add(theme);
+ }
+ for (let code of codes) {
+ code.classList.add(theme);
+ }
+
+ for (const article of document.querySelectorAll('article')) {
+ article.classList.add(theme);
+ }
+
+ for (const article of document.querySelectorAll('article')) {
+ article.classList.add(theme);
+ }
+ }
+
+ function toogleTheme() {
+ const arg = isDark ? ['dark', 'light'] : ['light', 'dark'];
+ const theme = arg[1];
+
+ if (!hid.classList.replace(...arg)) {
+ hid.classList.add(theme);
+ }
+
+ if (!html.classList.replace(...arg)) {
+ html.classList.add(theme);
+ }
+
+ if (!aside.classList.replace(...arg)) {
+ aside.classList.add(theme);
+ }
+
+ if (!sidenotes.classList.replace(...arg)) {
+ sidenotes.classList.add(theme);
+ }
+ if (footnotes && !footnotes.classList.replace(...arg)) {
+ footnotes.classList.add(theme);
+ }
+
+
+
+ if (!harr.classList.replace(...arg)) {
+ harr.classList.add(theme);
+ }
+
+ for (let link of links) {
+ if (!link.classList.replace(...arg)) {
+ link.classList.add(theme);
+ }
+ }
+ for (let table of tables) {
+ if (!table.classList.replace(...arg)) {
+ table.classList.add(theme);
+ }
+ }
+ for (let code of codes) {
+ if (!code.classList.replace(...arg)) {
+ code.classList.add(theme);
+ }
+ }
+ for (let like of likes) {
+ if (!like.classList.replace(...arg)) {
+ like.classList.add(theme);
+ }
+ }
+
+ for (const article of document.querySelectorAll('article')) {
+ if (!article.classList.replace(...arg)) {
+ article.classList.add(theme);
+ }
+ }
+
+ isDark = !isDark;
+ if (window.localStorage) {
+ window.localStorage.setItem('theme', isDark ? 'dark' : 'light');
+ }
+ }
+
+ const sun = document.querySelector('.sun');
+ const moon = document.querySelector('.moon');
+
+ sun.addEventListener('click', toogleTheme);
+ moon.addEventListener('click', toogleTheme);
+
+ if (isDark) {
+ hid.classList.add('dark');
+ } else {
+ hid.classList.add('light');
+ }
+});
diff --git a/src/js/zen.js b/src/js/zen.js
index d897603..be5f7d7 100644
--- a/src/js/zen.js
+++ b/src/js/zen.js
@@ -1,17 +1,25 @@
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');
}, 1000);
} else {
toggleArrow.classList.add('hide_arrow_off');
hideAbout();
+
+ // If the screen is smaller than 500px, hide the HID
+ if (window.screen.availWidth <= 500) {
+ hideHID();
+ }
}
});
@@ -23,20 +31,32 @@ window.addEventListener('DOMContentLoaded', () => {
document.body.style.setProperty('--width_panel_bis', initValue);
}
+ function hideHID() {
+ hid.style.setProperty('display', 'none');
+ }
+
+ function showHID() {
+ hid.style.setProperty('display', '');
+ }
+
window.addEventListener('scroll', () => {
+ if(!toggleArrow) return;
if (window.pageYOffset >= 800) {
- if (toggleArrow) {
- if (firstTime) {
- toggleArrow.click();
- firstTime = false;
- } else {
- toggleArrow.classList.add('hide_arrow_show');
- }
+ if (firstTime && document.body.style.getPropertyValue('--width_panel_bis') === initValue) {
+ toggleArrow.click();
+ firstTime = true;
}
+
+ toggleArrow.classList.add('hide_arrow_show');
// A hideAbout(header, articles);
- } else if (toggleArrow && !toggleArrow.classList.contains('hide_arrow_off')) {
+ } else if (!toggleArrow.classList.contains('hide_arrow_off')) {
// A showAbout(header, articles);
toggleArrow.classList.remove('hide_arrow_show');
}
+
+ if(firstTime && window.pageYOffset === 0 && document.body.style.getPropertyValue('--width_panel_bis') !== initValue) {
+ toggleArrow.click();
+ firstTime = true;
+ }
});
});