153 lines
7.8 KiB
JavaScript
153 lines
7.8 KiB
JavaScript
(function () {
|
|
var SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 16" role="presentation" focusable="false"><path d="M5 4h22L5 12h22" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/></svg>';
|
|
var BRAND = '<span class="brand-mark" aria-hidden="true">' + SVG + '</span><span class="brand-name">Zektyc</span>';
|
|
|
|
var SUN = '<svg class="icon-sun" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>';
|
|
var MOON = '<svg class="icon-moon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>';
|
|
|
|
var THEME_BTN = '<button type="button" class="theme-btn" aria-label="Theme">' + MOON + SUN + '</button>';
|
|
|
|
function path() { return location.pathname; }
|
|
function lang() { return /^\/en(\/|$)/.test(path()) ? 'en' : 'fr'; }
|
|
function isHome() { var p = path(); return p === '/' || p === '/index.html' || p === '/fr/' || p === '/fr/index.html' || p === '/en/' || p === '/en/index.html'; }
|
|
|
|
function buildHeader() {
|
|
var h = lang();
|
|
var l = h === 'fr' ? '/fr' : '/en';
|
|
var skip = h === 'fr' ? 'Aller au contenu' : 'Skip to content';
|
|
var html = '<a class="skip-link" href="#main">' + skip + '</a>';
|
|
html += '<a class="brand" href="' + (h === 'fr' ? '/fr/' : '/en/') + '">' + BRAND + '</a>';
|
|
html += '<input type="checkbox" id="nav-toggle" class="nav-toggle-input" />';
|
|
html += '<label for="nav-toggle" class="nav-burger" aria-label="Menu">';
|
|
html += '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 6h16M4 12h16M4 18h16"/></svg>';
|
|
html += '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg>';
|
|
html += '</label>';
|
|
|
|
html += '<nav class="site-nav" aria-label="Navigation">';
|
|
|
|
html += '<a href="' + l + '/blog" data-lang-path="/blog" data-i18n="nav.blog">Blog</a>';
|
|
html += '<a href="' + l + '/projets" data-lang-path="/projets" data-i18n="nav.projects">Projets</a>';
|
|
html += '<a href="' + l + '/equipe" data-lang-path="/equipe" data-i18n="nav.team">\u00c9quipe</a>';
|
|
if (isHome()) {
|
|
html += '<a href="#principes" data-i18n="nav.principes">Nos principes</a>';
|
|
html += '<a href="#faq" data-i18n="nav.faq">FAQ</a>';
|
|
html += '<a href="#contact" data-i18n="nav.contact">Contact</a>';
|
|
}
|
|
|
|
html += '<div class="lang-switch" role="group" aria-label="Langue / Language">';
|
|
html += '<button type="button" data-lang="fr" class="lang-btn' + (h === 'fr' ? ' active' : '') + '">' + (h === 'fr' ? '<strong>FR</strong>' : 'FR') + '</button>';
|
|
html += '<button type="button" data-lang="en" class="lang-btn' + (h === 'en' ? ' active' : '') + '">' + (h === 'en' ? '<strong>EN</strong>' : 'EN') + '</button>';
|
|
html += '</div>';
|
|
html += THEME_BTN;
|
|
html += '</nav>';
|
|
|
|
return '<header class="site-header">' + html + '</header>';
|
|
}
|
|
|
|
function buildFooter() {
|
|
var h = lang();
|
|
var tos = h === 'fr' ? "Conditions d\u2019utilisation" : 'Terms of Service';
|
|
var priv = h === 'fr' ? 'Confidentialit\u00e9' : 'Privacy';
|
|
var lic = h === 'fr' ? 'Licence' : 'License';
|
|
var note = h === 'fr' ? 'Le site ne pose qu\'un cookie de pr\u00e9f\u00e9rence de langue, sans suivi.' : 'This site only sets a language-preference cookie, with no tracking.';
|
|
var tosHref = h === 'fr' ? '/fr/tos' : '/en/tos';
|
|
var privHref = h === 'fr' ? '/fr/privacy-policy' : '/en/privacy-policy';
|
|
var licHref = h === 'fr' ? '/fr/licence' : '/en/licence';
|
|
|
|
var html = '';
|
|
html += '<p>Zektyc \u00b7 France</p>';
|
|
html += '<p class="footer-note">' + note + '</p>';
|
|
html += '<nav class="footer-nav" aria-label="Legal">';
|
|
html += '<a rel="me" href="https://piaille.fr/@zektyc"><img src="/icons/mastodon.svg" alt="" width="14" height="14" class="footer-icon" /> Mastodon</a>';
|
|
html += '<span class="footer-sep" aria-hidden="true">\u00b7</span>';
|
|
html += '<a href="' + tosHref + '">' + tos + '</a>';
|
|
html += '<span class="footer-sep" aria-hidden="true">\u00b7</span>';
|
|
html += '<a href="' + privHref + '">' + priv + '</a>';
|
|
html += '<span class="footer-sep" aria-hidden="true">\u00b7</span>';
|
|
html += '<a href="' + licHref + '">' + lic + '</a>';
|
|
html += '<span class="footer-sep" aria-hidden="true">\u00b7</span>';
|
|
html += '<a href="/docs/maxspeed">API</a>';
|
|
html += '<span class="footer-sep" aria-hidden="true">\u00b7</span>';
|
|
html += '<a href="/.well-known/security.txt">security.txt</a>';
|
|
html += '<span class="footer-sep" aria-hidden="true">\u00b7</span>';
|
|
html += '<a href="http://l5cbkqmok4rnkhbtpltmtlf3pa5i5rfw23z2mtj5tugpo3quta3b5hqd.onion">Tor</a>';
|
|
html += '</nav>';
|
|
return '<footer class="site-footer">' + html + '</footer>';
|
|
}
|
|
|
|
function inject() {
|
|
var hs = document.getElementById('h');
|
|
var fs = document.getElementById('f');
|
|
if (hs) hs.outerHTML = buildHeader();
|
|
if (fs) fs.outerHTML = buildFooter();
|
|
|
|
var nav = document.getElementById('nav-toggle');
|
|
if (nav) {
|
|
document.addEventListener('click', function (e) {
|
|
if (e.target.closest && e.target.closest('.site-nav')) nav.checked = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
function isTorBrowser() {
|
|
if (isOnion()) return true;
|
|
if (window.TorSensor) return true;
|
|
if (/TorBrowser|Tor\/|Tor Project/i.test(navigator.userAgent)) return true;
|
|
|
|
var gmt = new Date().getTimezoneOffset() === 0;
|
|
var letterboxed = !!(window.screen &&
|
|
window.screen.width === window.innerWidth &&
|
|
window.screen.height === window.innerHeight);
|
|
var noPlugins = !navigator.plugins || navigator.plugins.length === 0;
|
|
var vendor = navigator.vendor;
|
|
|
|
if (gmt && letterboxed) return true;
|
|
if (vendor === '' && gmt && noPlugins) return true;
|
|
return false;
|
|
}
|
|
|
|
function isOnion() {
|
|
return location.hostname.indexOf('.onion') !== -1;
|
|
}
|
|
|
|
function showTorToast() {
|
|
if (!isTorBrowser() || isOnion()) return;
|
|
|
|
var onionBase = 'http://l5cbkqmok4rnkhbtpltmtlf3pa5i5rfw23z2mtj5tugpo3quta3b5hqd.onion';
|
|
var path = location.pathname + location.search + location.hash;
|
|
var onionUrl = onionBase + path;
|
|
|
|
var toast = document.createElement('div');
|
|
toast.className = 'tor-toast';
|
|
toast.setAttribute('role', 'alert');
|
|
|
|
var h = lang();
|
|
var msg = h === 'fr'
|
|
? 'Vous utilisez Tor. Acc\u00e9dez \u00e0 la version .onion pour plus de s\u00e9curit\u00e9.'
|
|
: 'You are using Tor. Access the .onion version for better security.';
|
|
|
|
toast.innerHTML =
|
|
'<p>' + msg + '</p>' +
|
|
'<a href="' + onionUrl + '" class="tor-toast-btn">' + (h === 'fr' ? 'Ouvrir en .onion' : 'Open .onion') + '</a>' +
|
|
'<button type="button" class="tor-toast-close" aria-label="Fermer">×</button>';
|
|
|
|
document.body.appendChild(toast);
|
|
|
|
toast.querySelector('.tor-toast-close').addEventListener('click', function () {
|
|
toast.remove();
|
|
});
|
|
|
|
setTimeout(function () { toast.remove(); }, 30000);
|
|
}
|
|
|
|
function boot() {
|
|
inject();
|
|
showTorToast();
|
|
}
|
|
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', boot);
|
|
} else {
|
|
boot();
|
|
}
|
|
})();
|