the home site for me: also iteration 3 or 4 of my site
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: make webring use my formating not default table formating

+235 -8
+115
sass/css/_copy-button.scss
··· 1 + i.icon { 2 + display: inline-block; 3 + mask-size: cover; 4 + background-color: currentColor; 5 + width: 1rem; 6 + height: 1rem; 7 + font-style: normal; 8 + font-variant: normal; 9 + line-height: 0; 10 + text-rendering: auto; 11 + } 12 + 13 + .pre-container { 14 + --icon-copy: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' height='16' width='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 3c0-1.645 1.355-3 3-3h5c1.645 0 3 1.355 3 3 0 .55-.45 1-1 1s-1-.45-1-1c0-.57-.43-1-1-1H3c-.57 0-1 .43-1 1v5c0 .57.43 1 1 1 .55 0 1 .45 1 1s-.45 1-1 1c-1.645 0-3-1.355-3-3zm5 5c0-1.645 1.355-3 3-3h5c1.645 0 3 1.355 3 3v5c0 1.645-1.355 3-3 3H8c-1.645 0-3-1.355-3-3zm2 0v5c0 .57.43 1 1 1h5c.57 0 1-.43 1-1V8c0-.57-.43-1-1-1H8c-.57 0-1 .43-1 1m0 0'/%3E%3C/svg%3E"); 15 + --icon-done: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M7.883 0q-.486.008-.965.074a7.98 7.98 0 0 0-4.602 2.293 8.01 8.01 0 0 0-1.23 9.664 8.015 8.015 0 0 0 9.02 3.684 8 8 0 0 0 5.89-7.75 1 1 0 1 0-2 .008 5.986 5.986 0 0 1-4.418 5.816 5.996 5.996 0 0 1-6.762-2.766 5.99 5.99 0 0 1 .922-7.25 5.99 5.99 0 0 1 7.239-.984 1 1 0 0 0 1.363-.371c.273-.48.11-1.09-.371-1.367A8 8 0 0 0 9.492.14 8 8 0 0 0 7.882 0m7.15 1.998-.1.002a1 1 0 0 0-.687.34L7.95 9.535 5.707 7.29A1 1 0 0 0 4 8a1 1 0 0 0 .293.707l3 3c.195.195.465.3.742.293.277-.012.535-.133.719-.344l7-8A1 1 0 0 0 16 2.934a1 1 0 0 0-.34-.688 1 1 0 0 0-.627-.248'/%3E%3C/svg%3E"); 16 + 17 + margin: 1rem 0 1rem; 18 + border-radius: 0.75rem; 19 + 20 + .header { 21 + display: flex; 22 + justify-content: space-between; 23 + align-items: center; 24 + border-radius: 0.2em 0.2em 0 0; 25 + background-color: var(--accent); 26 + background-size: 200%; 27 + padding: 0.25rem; 28 + height: 2.5rem; 29 + 30 + span { 31 + margin-inline-start: 0.75rem; 32 + color: var(--purple-gray); 33 + font-weight: bold; 34 + line-height: 1; 35 + } 36 + 37 + button { 38 + appearance: none; 39 + transition: 200ms; 40 + cursor: pointer; 41 + border: none; 42 + border-radius: 0.4rem; 43 + background-color: transparent; 44 + padding: 0.5rem; 45 + color: var(--purple-gray); 46 + line-height: 0; 47 + 48 + &:hover { 49 + background-color: color-mix( 50 + in oklab, 51 + var(--accent) 80%, 52 + var(--purple-gray) 53 + ); 54 + } 55 + 56 + &:focus { 57 + background-color: color-mix( 58 + in oklab, 59 + var(--accent) 80%, 60 + var(--purple-gray) 61 + ); 62 + } 63 + 64 + &:active { 65 + transform: scale(0.9); 66 + } 67 + 68 + &:disabled { 69 + cursor: not-allowed; 70 + 71 + &:active { 72 + transform: none; 73 + } 74 + } 75 + 76 + .icon { 77 + -webkit-mask-image: var(--icon-copy); 78 + mask-image: var(--icon-copy); 79 + transition: 200ms; 80 + 81 + :root[dir*="rtl"] & { 82 + transform: scaleX(-1); 83 + } 84 + } 85 + } 86 + 87 + &.active { 88 + button { 89 + animation: active-copy 0.3s; 90 + 91 + color: var(--purple-gray); 92 + 93 + .icon { 94 + -webkit-mask-image: var(--icon-done); 95 + mask-image: var(--icon-done); 96 + } 97 + } 98 + 99 + @keyframes active-copy { 100 + 50% { 101 + transform: scale(0.9); 102 + } 103 + 100% { 104 + transform: none; 105 + } 106 + } 107 + } 108 + } 109 + 110 + pre { 111 + margin: 0; 112 + box-shadow: none; 113 + border-radius: 0 0 0.2em 0.2em; 114 + } 115 + }
-4
sass/css/main.sass
··· 1 - @import "reset" 2 - @import "suCSS" 3 - @import "syntax-theme" 4 - @import "mods"
+7
sass/css/main.scss
··· 1 + @use "reset"; 2 + 3 + @use "suCSS"; 4 + @use "syntax-theme"; 5 + @use "mods"; 6 + 7 + @use "copy-button";
+69
static/js/copy-button.js
··· 1 + // Based on https://www.roboleary.net/2022/01/13/copy-code-to-clipboard-blog.html 2 + document.addEventListener("DOMContentLoaded", () => { 3 + const blocks = document.querySelectorAll("pre[class^='language-']"); 4 + 5 + for (const block of blocks) { 6 + if (navigator.clipboard) { 7 + // Code block header title 8 + const title = document.createElement("span"); 9 + const lang = block.getAttribute("data-lang"); 10 + const comment = 11 + block.previousElementSibling && 12 + (block.previousElementSibling.tagName === "blockquote" || 13 + block.previousElementSibling.nodeName === "BLOCKQUOTE") 14 + ? block.previousElementSibling 15 + : null; 16 + if (comment) block.previousElementSibling.remove(); 17 + title.innerHTML = 18 + lang + (comment ? ` (${comment.textContent.trim()})` : ""); 19 + 20 + // Copy button icon 21 + const icon = document.createElement("i"); 22 + icon.classList.add("icon"); 23 + 24 + // Copy button 25 + const button = document.createElement("button"); 26 + const copyCodeText = "Copy code"; // Use hardcoded text instead of getElementById 27 + button.setAttribute("title", copyCodeText); 28 + button.appendChild(icon); 29 + 30 + // Code block header 31 + const header = document.createElement("div"); 32 + header.classList.add("header"); 33 + header.appendChild(title); 34 + header.appendChild(button); 35 + 36 + // Container that holds header and the code block itself 37 + const container = document.createElement("div"); 38 + container.classList.add("pre-container"); 39 + container.appendChild(header); 40 + 41 + // Move code block into the container 42 + block.parentNode.insertBefore(container, block); 43 + container.appendChild(block); 44 + 45 + button.addEventListener("click", async () => { 46 + await copyCode(block, header, button); // Pass the button here 47 + }); 48 + } 49 + } 50 + 51 + async function copyCode(block, header, button) { 52 + const code = block.querySelector("code"); 53 + const text = code.innerText; 54 + 55 + await navigator.clipboard.writeText(text); 56 + 57 + header.classList.add("active"); 58 + button.setAttribute("disabled", true); 59 + 60 + header.addEventListener( 61 + "animationend", 62 + () => { 63 + header.classList.remove("active"); 64 + button.removeAttribute("disabled"); 65 + }, 66 + { once: true }, 67 + ); 68 + } 69 + });
static/js/script.js static/js/theme-toggle.js
+35 -2
templates/footer.html
··· 6 6 get_env(name="CF_PAGES_COMMIT_SHA", default=load_data(path=".git/refs/heads/main", required=false))%}{% if hash is not string %}{% set hash = "unknown" %}{% endif %}<a href=https://github.com/taciturnaxolotl/zera/tree/{{ hash }}>zera@{{ hash | 7 7 truncate(length=7, end="")}}</a> 8 8 </p> 9 + <p style="margin-bottom: 0.5rem"> 10 + Member of the 11 + <a href="https://w.elr.sh">elr</a> 12 + webring - 13 + <span class='webring-links'> 14 + <a href='javascript:void(0)' onclick='randomSite()'>random</a> | 15 + <a href='#' id='prev-link'>previous</a> | 16 + <a href='#' id='next-link'>next</a> 17 + </span> 18 + </p> 9 19 <p> 10 20 Content licensed under 11 21 <a ··· 24 34 >AGPL 3.0</a 25 35 > 26 36 </p> 27 - <div id='elr'> 28 37 <script type="text/javascript" src="https://w.elr.sh/onionring-variables.js"></script> 29 - <script type="text/javascript" src="https://w.elr.sh/onionring-widget.js"></script> 38 + <script> 39 + thisSite = "https://dunkirk.sh" 40 + thisIndex = null; 41 + 42 + for (i = 0; i < sites.length; i++) { 43 + if (thisSite.startsWith(sites[i])) { 44 + thisIndex = i; 45 + break; 46 + } 47 + } 48 + 49 + function randomSite() { 50 + otherSites = sites.slice(); 51 + otherSites.splice(thisIndex, 1); 52 + randomIndex = Math.floor(Math.random() * otherSites.length); 53 + location.href = otherSites[randomIndex]; 54 + } 55 + 56 + 57 + previousIndex = (thisIndex-1 < 0) ? sites.length-1 : thisIndex-1; 58 + nextIndex = (thisIndex+1 >= sites.length) ? 0 : thisIndex+1; 59 + 60 + document.getElementById('prev-link').href = sites[previousIndex]; 61 + document.getElementById('next-link').href = sites[nextIndex]; 62 + </script> 30 63 </div>
+9 -2
templates/head.html
··· 78 78 type="text/css" 79 79 href="{{ get_url(path='css/main.css?' ~ cssHash, trailing_slash=false) | safe }}" 80 80 /> 81 - {% endblock css %} {% set jsHash = get_hash(path="js/script.js", sha_type=256, 81 + {% endblock css %} {% set jsHash = get_hash(path="js/theme-toggle.js", sha_type=256, 82 + base64=true) %} 83 + <script 84 + src="{{ get_url(path='js/theme-toggle.js?' ~ jsHash, trailing_slash=false) | safe }}" 85 + defer 86 + ></script> 87 + 88 + {% set jsHash = get_hash(path="js/copy-button.js", sha_type=256, 82 89 base64=true) %} 83 90 <script 84 - src="{{ get_url(path='js/script.js?' ~ jsHash, trailing_slash=false) | safe }}" 91 + src="{{ get_url(path='js/copy-button.js?' ~ jsHash, trailing_slash=false) | safe }}" 85 92 defer 86 93 ></script> 87 94 <script>