onionring-widget.js (3868B)
1 // onionring.js is made up of four files - onionring-widget.js (this one!), onionring-index.js, onionring-variables.js and onionring.css 2 // it's licensed under the cooperative non-violent license (CNPL) v4+ (https://thufie.lain.haus/NPL.html) 3 // it was originally made by joey + mord of allium (蒜) house, last updated 2020-11-24 4 5 // === ONIONRING-WIDGET === 6 //this file contains the code which builds the widget shown on each page in the ring. ctrl+f 'EDIT THIS' if you're looking to change the actual html of the widget 7 8 var tag = document.getElementById(ringID); //find the widget on the page 9 10 thisSite = window.location.href; //get the url of the site we're currently on 11 thisIndex = null; 12 shuffleWithSeed(sites, getDailySeed()) 13 14 // go through the site list to see if this site is on it and find its position 15 for (i = 0; i < sites.length; i++) { 16 if (thisSite.startsWith(sites[i])) { //we use startswith so this will match any subdirectory, users can put the widget on multiple pages 17 thisIndex = i; 18 break; //when we've found the site, we don't need to search any more, so stop the loop 19 } 20 } 21 22 // We want the site array to be shuffled once every day, but be consistent for that day 23 function getDailySeed() { 24 const today = new Date(); 25 today.setHours(0, 0, 0, 0); // Set time to midnight 26 return today.getTime(); // Use timestamp as seed 27 } 28 29 function shuffleWithSeed(array, seed) { 30 // Simple seeded PRNG (not cryptographically secure) 31 function mulberry32(a) { 32 return function() { 33 let t = a += 0x6D2B79F5; 34 t = Math.imul(t ^ t >>> 15, t | 1); 35 t ^= t + Math.imul(t ^ t >>> 7, t | 61); 36 return ((t ^ t >>> 14) >>> 0) / 4294967296; 37 } 38 } 39 40 const rng = mulberry32(seed); 41 42 // Fisher-Yates shuffle algorithm 43 for (let i = array.length - 1; i > 0; i--) { 44 const j = Math.floor(rng() * (i + 1)); 45 [array[i], array[j]] = [array[j], array[i]]; 46 } 47 48 return array; 49 } 50 51 function randomSite() { 52 otherSites = sites.slice(); //create a copy of the sites list 53 otherSites.splice(thisIndex, 1); //remove the current site so we don't just land on it again 54 randomIndex = Math.floor(Math.random() * otherSites.length); 55 location.href = otherSites[randomIndex]; 56 } 57 58 //if we didn't find the site in the list, the widget displays a warning instead 59 if (thisIndex == null) { 60 tag.insertAdjacentHTML('afterbegin', ` 61 <table> 62 <tr> 63 <td>This site isn't part of the ${ringName} webring yet. You should talk to the manager to have your site added to the list!</td> 64 </tr> 65 </table> 66 `); 67 } 68 else { 69 //find the 'next' and 'previous' sites in the ring. this code looks complex 70 //because it's using a shorthand version of an if-else statement to make sure 71 //the first and last sites in the ring join together correctly 72 previousIndex = (thisIndex-1 < 0) ? sites.length-1 : thisIndex-1; 73 nextIndex = (thisIndex+1 >= sites.length) ? 0 : thisIndex+1; 74 75 indexText = "" 76 //if you've chosen to include an index, this builds the link to that 77 if (useIndex) { 78 indexText = `<a href='${indexPage}'>index</a> | `; 79 } 80 81 randomText = "" 82 //if you've chosen to include a random button, this builds the link that does that 83 if (useRandom) { 84 randomText = `<a href='javascript:void(0)' onclick='randomSite()'>random</a> | `; 85 } 86 87 //this is the code that displays the widget - EDIT THIS if you want to change the structure 88 tag.insertAdjacentHTML('afterbegin', ` 89 <table> 90 <tr> 91 <td class='webring-prev'><a href='${sites[previousIndex]}'>← previous</a></td> 92 <td class='webring-info'>This site is part of the ${ringName} webring</br> 93 <span class='webring-links'> 94 ${randomText} 95 ${indexText} 96 <a href='https://github.com/randyau/datawebring/'>what is this?</a></span></td> 97 <td class='webring-next'><a href='${sites[nextIndex]}'>next →</a></td> 98 </tr> 99 </table> 100 `); 101 102 }