document.addEventListener("DOMContentLoaded", function () { changeTheme(); initcolorTheme(); apply_stickies(); initSearch(); }); function initSearch() { const input = document.querySelector('#filter-js'); if(input) { filterElements(input.value); input.addEventListener('input', () => { filterElements(input.value); }); } } function filterElements(input) { const elements = document.querySelectorAll('[data-filterable="true"]'); Array.prototype.forEach.call(elements, (element) => { // set both strings (input & dataset filter) to lowercase to not be case sensitive let filterString = element.dataset.filter?.toLocaleLowerCase(); // bulk hide all elements element.style.display = 'none'; // show if input matches if(filterString?.includes(input.toLocaleLowerCase())) { element.style.display = 'flex'; } }); } function changeTheme() { let toggleBtn = document.querySelector("#theme-toggle-js"); if (toggleBtn) { toggleBtn.addEventListener("click", function () { if (toggleBtn.dataset.theme === "light") { setTheme("dark", true); } else { setTheme("light", true); } }); } } /*** * init javascript * 1) detect native color scheme or use set theme in local storage * 2) detect view (desktop or responsive) if on mobile device with touch screen * 3) set base font size to 112.5% -> 18px */ function initcolorTheme() { colorThemeWatcher(); let theme = localStorage.getItem("theme"); if (theme == null || theme === "auto") { if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) { setTheme("dark", false); } else { setTheme("light", false); } } else { setTheme(theme); } } /*** * Listener operating system native color configuration */ function colorThemeWatcher() { try { window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", (e) => { setTheme(e.matches ? "dark" : "light"); }); } catch { console.warn("color theme watcher not supported"); } } /** * Define color scheme, colors without losing the base font size configuration * and add data-theme to html tag * @param theme */ function setTheme(theme, setLocalStorage = true) { let toggleBtn = document.querySelector("#theme-toggle-js"); if (setLocalStorage) { localStorage.setItem("theme", theme); } if (toggleBtn) toggleBtn.setAttribute("data-theme", theme); if (document.documentElement.dataset.theme === "dark" && theme === "light") { document.documentElement.dataset.theme = "light"; } else if (document.documentElement.dataset.theme === "light" && theme === "dark") { document.documentElement.dataset.theme = "dark"; } } window.addEventListener("scroll", function () { apply_stickies(); }); function apply_stickies() { var _$stickies = [].slice.call(document.querySelectorAll('details[open] .sticky')) _$stickies.forEach(function (_$sticky) { if (CSS.supports && CSS.supports("position", "sticky")) { apply_sticky_class(_$sticky); } }); } function apply_sticky_class(_$sticky) { var currentOffset = _$sticky.getBoundingClientRect().top; var stickyOffset = parseInt(getComputedStyle(_$sticky).top.replace("px", "")); var isStuck = currentOffset <= stickyOffset; _$sticky.classList.toggle("js-is-sticky", isStuck); }