User:Splarka/synaesthesia.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/* Induced Synaesthesia, version [0.5.5]
Originally from: http://en.wikipedia.org/wiki/User:Splarka/synaesthesia.js

This takes a list of <li></li> on a given page and iterates over all link in them.
If it finds a link to a user page or Special:Contributions/User (for IPs and red 
users), it then takes the MD5 of that username and assigns the first 6 characters
as the color for that line (so all lines by that user are the same). Clicking the 
object repeatly adds a numeric salt to the username to completely randomize the 
colors in a predictable way.

User variables:
* synaesthesiaUserSalt = a number you found you like
* synaesthesiaAutoStart = set to true if you don't want to manually activate.

Currently available in:
* All Special: pages
** Perhaps limit to: RecentChanges, RecentChangesLinked, NewPages, Watchlist, Log, IPBlockList
* action=history
* Any others?
*/

mw.loader.load('//en.wikipedia.org/w/index.php?title=User:Lupin/md5-2.2alpha.js&action=raw&ctype=text/javascript');
appendCSS('.cascadecolor * {color:inherit !important;} .cascadecolor a {font-weight:bold;text-decoration:underline;}');
var synaesthesiaSalt = 0;

function synaesthesia() {
  var salt = synaesthesiaSalt;
  var docobj = document.getElementById('bodyContent') || document.getElementById('content') || document.getElementById('mw-content') || document.body
  var li = docobj.getElementsByTagName('li');
  var md5 = {};  //cacheable array, makes it a bit faster.
  for(var i=0;i<li.length;i++) {
    var a = li[i].getElementsByTagName('a');
    for(var k=0;k<a.length;k++) {
      var href = a[k].getAttribute('href',2);
      var uspat = /(?:\/wiki\/User\:|\/Special\:Contributions\/)(.*)$/;
      var user = href.match(uspat);
      if(user && user.length > 1) {
        var usersalt = (salt != 0) ? user[1] + salt : user[1]
        if(!md5[usersalt]) md5[usersalt] = hex_md5(usersalt).substring(0,6)
        var safecol = sanitizeColor(md5[usersalt],'ffffff');
        if(safecol) li[i].style.color = '#' + safecol
        li[i].style.backgroundColor = '#ffffff';
        if(li[i].className.indexOf(' cascadecolor') == -1) li[i].className += ' cascadecolor'
        break; 
        continue;
      }
    }
  }
  document.getElementById('t-syn').getElementsByTagName('a')[0].setAttribute('title','Current salt: ' + synaesthesiaSalt);
  synaesthesiaSalt++;
}

function synaesthesiaStarter() {
  if(window.synaesthesiaUserSalt) synaesthesiaSalt = parseInt(synaesthesiaUserSalt)
  if(isNaN(synaesthesiaSalt) || synaesthesiaSalt > 26 || synaesthesiaSalt < 0) synaesthesiaSalt = 0
  mw.util.addPortletLink('p-tb','javascript:synaesthesia()','Synaesthesia','t-syn','Synaesthesia mode. First salt: ' + synaesthesiaSalt);
  if(window.synaesthesiaAutoStart) synaesthesia()
}
if(mw.config.get('wgNamespaceNumber') == -1 || mw.config.get('wgAction') == 'history') addOnloadHook(synaesthesiaStarter)

//Make sure the color is always a bit visible.
function sanitizeColor(newcolor,basecolor) {
  var bol = (basecolor) ? basecolor.replace(/\#/,'') : 'ffffff'
  var col = newcolor.replace(/\#/,'');

  var c = colorDecimalArray(col);
  if(!c) return false
  var b = colorDecimalArray(bol);
  if(!b) b = [255,255,255]

  var fbright = (c[0] * .117255 + c[1] * .230196 + c[2] * .044706);
  var bbright = (b[0] * .117255 + b[1] * .230196 + b[2] * .044706);
  var contrast = Math.round(Math.abs(fbright - bbright));
  if(contrast > 33) return col

  for(var i=0;i<3;i++) {
    c[i] = (c[i] < 128) ? c[i] + 128 : c[i] - 128
    c[i] = c[i].toString(16).toUpperCase();
    if(c[i].length == 1) c[i] = '0' + c[i]
  }
  return c.join('').toLowerCase();

  function colorDecimalArray(clr) {
    if(clr.length == 3) clr = clr.substr(0,1) + clr.substr(0,1) + clr.substr(1,1) + clr.substr(1,1) + clr.substr(2,1) + clr.substr(2,1)
    if(clr.length != 6) return false
    var obj = [0,0,0];
    for(var i=0;i<3;i++) obj[i] = parseInt(clr.substr(i*2,2),16)
    for(var i=0;i<3;i++) if(isNaN(obj[i])) return false
    return obj;
  }
}