aboutsummaryrefslogtreecommitdiff
path: root/docs/assets/js/docs.js
diff options
context:
space:
mode:
authorGravatar Inverle <inverle@proton.me> 2025-12-04 20:06:21 +0100
committerGravatar GitHub <noreply@github.com> 2025-12-04 20:06:21 +0100
commit5e9c3617cac1e3eac246e2ae7df6f4b71c33d37c (patch)
tree435618816d2ccc5d29b21fa0c089f814972a2ce7 /docs/assets/js/docs.js
parent78e40c6fe3afe7f815ef9d32646610e2d5436ba3 (diff)
Improve layout of documentation page and add search feature (#8247)
* Improve layout of documentation page and add search feature Closes https://github.com/FreshRSS/FreshRSS/issues/7915, https://github.com/FreshRSS/FreshRSS/issues/5325 Also: anchor headings and fix building site locally * Further improvements * Set color of hyperlinks * Consistent styling of close aside button across devices * Mobile layout 600px -> 1200px * Add suffix to docs `<title>` * Note: titles of pages probably need to be improved, since currently they are just derived from the names of the first heading on every page * Add favicon * Improve font * Try to fix favicon not loading correctly on GH pages * Use local font * Attempt to fix GH pages * Final improvements * Copy to clipboard button * Support for nojs search * Dark mode * Load search.json (200KB json) only on search input focus * Keep scroll state of sidebar across navigations * Clickable images and CSP CSP so we avoid hotlinking resources and clickable images are useful for zooming on mobile for example * Fix typos * Disable Dark Reader extension if dark mode CSS is loaded * Support internationalisation (via language dropdown) * Add Gemfile.lock * Make CI build work with the custom plugin * Make menus closable with Esc * Fix typos CI * Suggestions * Use `ruby/setup-ruby` action in workflow for installing and caching gems. * Run build only when there are changes to `docs/` See: https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows?versionId=free-pro-team%40latest&productId=actions#running-your-workflow-only-when-a-push-to-specific-branches-occurs * Change font to `Open Sans` * Increase line height * Fix Liquid syntax error
Diffstat (limited to 'docs/assets/js/docs.js')
-rw-r--r--docs/assets/js/docs.js63
1 files changed, 63 insertions, 0 deletions
diff --git a/docs/assets/js/docs.js b/docs/assets/js/docs.js
new file mode 100644
index 000000000..c14fce920
--- /dev/null
+++ b/docs/assets/js/docs.js
@@ -0,0 +1,63 @@
+/* globals i18n */
+
+if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
+ document.head.insertAdjacentHTML('beforeend', `
+ <meta name="darkreader-lock">
+ `);
+}
+
+let asideNav;
+
+window.addEventListener('beforeunload', () => {
+ sessionStorage.setItem('sidebar_scrollTop', asideNav.scrollTop);
+});
+
+window.addEventListener('keydown', (e) => {
+ if (e.key === 'Escape') {
+ location.hash = 'close';
+ }
+});
+
+document.addEventListener('DOMContentLoaded', () => {
+ asideNav = document.querySelector('aside > nav.docs');
+
+ const sidebar_scrollTop = sessionStorage.getItem('sidebar_scrollTop');
+ if (sidebar_scrollTop) {
+ asideNav.scrollTo(0, sidebar_scrollTop);
+ sessionStorage.removeItem('sidebar_scrollTop');
+ }
+
+ for (const el of document.querySelectorAll('div.highlight')) {
+ /* eslint-disable @stylistic/max-len */
+ el.insertAdjacentHTML('afterbegin', `
+ <button class="copy" title="${i18n.copy_to_clipboard}">
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
+ <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1z"/>
+ <path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0z"/>
+ </svg>
+ </button>
+ `);
+ /* eslint-enable @stylistic/max-len */
+ const copyBtn = el.querySelector('button.copy');
+ copyBtn.addEventListener('click', () => {
+ const snippet = el.querySelector('code').innerText;
+ if (navigator.clipboard) {
+ navigator.clipboard.writeText(snippet);
+ } else {
+ // Fallback if no HTTPS
+ const input = document.createElement('textarea');
+ input.innerHTML = snippet;
+ document.body.append(input);
+ input.select();
+ document.execCommand('copy');
+ input.remove();
+ }
+ });
+ }
+
+ for (const el of document.querySelectorAll('img')) {
+ if (el.parentNode.tagName !== 'A') {
+ el.outerHTML = `<a href="${el.getAttribute('src')}">${el.outerHTML}</a>`;
+ }
+ }
+});