datawebring

A webring for data people who write
git clone https://git.eamoncaddigan.net/datawebring.git
Log | Files | Refs | README

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 }