Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Friend or Foe

By: a guest on Nov 1st, 2010  |  syntax: JavaScript  |  size: 10.49 KB  |  views: 46  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. // ==UserScript==
  2. // @name           Friend or Foe
  3. // @version        1.0.2
  4. // @author         TheRedTeam
  5. // @namespace      reddit
  6. // @description    Create list of friends and foes and perform actions on them
  7. // @include        *reddit.com/r/*
  8. // @exclude        *iframe*reddit.com/*
  9. // ==/UserScript==
  10.  
  11. /*
  12. Changelog:
  13. 09/23/10:1.0.0: First release, works decent
  14. 09/23/10:1.0.1: Fixed race condition if multiple tabs open
  15. 11/01/10:1.0.2: Fixed opacity disallowing link clicking on right floating div
  16.  
  17. */
  18.  
  19.  
  20. // current lists
  21. var friend_list = [];
  22. var foe_list = [];
  23. var fof_user = "";
  24. var fof_usercolors = []; // cache of link colors
  25.  
  26. // reddit can't handle clicking things too fast or it will miss some
  27. // so we save all objects to click in an array, and use an interval on a timer
  28. // this does the clicking asycronously in the background for us
  29. var clicklist = new Array();
  30. var clickinterval = null;
  31.  
  32. // prototype the crap out of the array object
  33. Array.prototype.has = function (obj) {
  34.         for (var i = 0, j = this.length; i < j; i++) {
  35.                 if (this[i] == obj)
  36.                         return true;
  37.         }
  38.         return false;
  39. };
  40. Array.prototype.remove = function(obj) {
  41.   for(i=0; i<this.length; i++)
  42.         if(this[i] == obj){
  43.                 this.splice(i, 1);
  44.                 i--;
  45.         }
  46. };
  47.  
  48.  
  49. // get jquery from reddit
  50. $ = unsafeWindow.$;
  51.  
  52. // add menu bar items
  53. var mymenu = document.createElement("div");
  54. mymenu.className = "sidecontentbox";
  55. var side = document.getElementsByClassName("side")[0];
  56. side.style.zIndex = 100;
  57. side.insertBefore(mymenu,side.firstChild);
  58. // we do inline CSS here to override reddit's styles because
  59. // they use the !important attribute on everything >:(
  60. mymenu.innerHTML = "<div class='content' style='-moz-border-radius-bottomright: 10px; -moz-border-radius-bottomleft: 10px; border-top: 0px; background-color: #FFFFBB;'> \
  61.                                         <div style='text-align: center; border-bottom: 1px solid #888;'><span style='font-family: arial; font-size: 14px; font-weight: bold; color: #996633;'>Friend or Foe</span></div> \
  62.                                         <div style='margin-bottom: 5px; font-family: arial; font-size: 10px; color: #444;'><span id='fofcounts'></span> (<a href='javascript:userViewLists();'>details</a>)</div> \
  63.                                         <ul>   \
  64.                                                 <li><a href='javascript: autoh();'>auto-hide</a></li> \
  65.                                         </ul> \
  66.                                         <div style='margin-top: 5px; font-family: arial; font-size: 10px; color: #444;' id='fofstatus'></div> \
  67.                                         </div>";
  68.  
  69.  
  70.  
  71.  
  72. /*
  73. ########################  Start Helper Functions ############################
  74. */
  75.  
  76. unsafeWindow.userViewLists =
  77. function(){
  78.         alert("Friends: "+friend_list.toString()+"\n\nFoes: "+foe_list.toString());
  79. };
  80.  
  81.  
  82. function userSetCounts(){
  83.         var counts = document.getElementById('fofcounts');
  84.         counts.innerHTML = friend_list.length+" friends and "+foe_list.length+" foes";
  85. };
  86.  
  87. // pull lists
  88. function getlists(){
  89.         var t1 = GM_getValue('fof_foelist','');
  90.         var t2 = GM_getValue('fof_friendlist','');
  91.         // see if there is a difference
  92.         if(t1=='') foe_list = [];
  93.         else foe_list = t1.split(',');
  94.         if(t2=='') friend_list = [];
  95.         else friend_list = t2.split(',');
  96. }
  97.  
  98. // save changes to lists
  99. function savelists(){
  100.         // get current lists again to see if another tab/window updated anything
  101.         var t1 = GM_getValue('fof_foelist','');
  102.         var t2 = GM_getValue('fof_friendlist','');
  103.         // if difference save changes
  104.         if(t1 != foe_list.toString()){
  105.                 GM_setValue('fof_foelist',foe_list.toString());
  106.         }
  107.         if(t2 != friend_list.toString()){
  108.                 GM_setValue('fof_friendlist',friend_list.toString());
  109.         }
  110. }
  111.  
  112.  
  113.  
  114. // Add a Foe function
  115. unsafeWindow.userAddFoe =  
  116. function(s){
  117.         fof_user = s;
  118.         // run in timeout so we can call GM_ funcs
  119.         setTimeout(
  120.                 function (){
  121.                         if(foe_list.has(fof_user))
  122.                                 return;
  123.                         getlists();
  124.                         foe_list.push(fof_user);
  125.                         savelists();
  126.                         addButtons();
  127.                         userSetCounts();
  128.                         setstatus("Set '"+fof_user+"' as Foe");
  129.                 },
  130.         0);
  131. };
  132.  
  133. // Add a Friend function
  134. unsafeWindow.userAddFriend =  
  135. function (s){
  136.         fof_user = s;
  137.         // run in timeout so we can call GM_ funcs
  138.         setTimeout(
  139.                 function (){
  140.                         if(friend_list.has(fof_user))
  141.                                 return;
  142.                         getlists();
  143.                         friend_list.push(fof_user);
  144.                         savelists();
  145.                         addButtons();
  146.                         userSetCounts();
  147.                         setstatus("Set '"+fof_user+"' as Friend");
  148.                 },
  149.         0);
  150. };
  151.  
  152. // unset user from both friend and foe lists
  153. unsafeWindow.userUnset =  
  154. function (s){
  155.         fof_user = s;
  156.         // run in timeout so we can call GM_ funcs
  157.         setTimeout(
  158.                 function (){
  159.                         getlists()
  160.                         friend_list.remove(fof_user);
  161.                         foe_list.remove(fof_user);
  162.                         savelists();
  163.                         addButtons();
  164.                         userSetCounts();
  165.                         setstatus("Removed '"+fof_user+"' from lists");
  166.                 },
  167.         0);
  168. };
  169.  
  170. // create click event to use on divs and anchor tags
  171. function clickevent(){
  172.         var evt = document.createEvent("MouseEvents");
  173.         evt.initMouseEvent("click", true, true, window,0, 0, 0, 0, 0, false, false, false, false, 0, null);
  174.         return evt;
  175. }
  176.  
  177. // shortcut to set the status
  178. function setstatus(s){
  179.         var stat = document.getElementById('fofstatus');
  180.         stat.innerHTML = stat.innerHTML+s+"<br>";
  181. }
  182.  
  183. // loop through and click everything in the list
  184. // note we kill the interval that calls this when the list is empty
  185. function clickloop(){
  186.         if(clicklist.length==0){
  187.                 clickinterval = null;
  188.                 return;
  189.         }
  190.         var elm = clicklist.pop();
  191.         elm.dispatchEvent(clickevent());
  192. }
  193.  
  194. // get a css property, you'd think this would be easier...
  195. function getStyle(x,styleProp)
  196. {
  197.         if (x.currentStyle)
  198.                 var y = x.currentStyle[styleProp];
  199.         else if (window.getComputedStyle)
  200.                 var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
  201.         return y;
  202. }
  203.  
  204.  
  205.  
  206.  
  207.  
  208. /*
  209. ########################  Start Main Functions ############################
  210. */
  211.  
  212.  
  213. function addButtons(){
  214.         // div that holds all the submissions
  215.         var t = document.getElementsByClassName("midcol");
  216.         // loop through submissions
  217.         for(i=0; i < t.length; i++){
  218.                 // parent node is the div container for the submission
  219.                 submission = t[i].parentNode;
  220.                 // try to find the username
  221.                 var userbox = submission.getElementsByClassName("tagline")[0];
  222.                 var title = submission.getElementsByClassName("title loggedin")[0];
  223.                 // if in the recently viewed box (no username shown there) skip it
  224.                 try{
  225.                         var user = userbox.getElementsByTagName("a")[0];
  226.                 }catch(e){
  227.                         continue; // no username section
  228.                 }
  229.                 if(user == undefined)
  230.                         continue; // user is [deleted]
  231.                 var username = user.innerHTML;
  232.                 // save reddit's user colors so we can reset if needed
  233.                 if(fof_usercolors[username]==undefined){
  234.                         fof_usercolors[username] = getStyle(user, "color");
  235.                 }
  236.                 // now chose what colors to use according to the user
  237.                 if(foe_list.has(username)){
  238.                         user.style.color = fof_usercolors[username]; //"#336699"
  239.                         $(submission).css('opacity',0.3);
  240.                         submission.style.marginRight = "300px"; // opacity annoyance
  241.                 }
  242.                 else if(friend_list.has(username)){
  243.                         user.style.color = "#00AA00";
  244.                         title.style.color = "#00AA00";
  245.                         $(submission).css('opacity',1);
  246.                 }
  247.                 else{
  248.                         user.style.color = fof_usercolors[username]; //"#336699"
  249.                         title.style.color = "inherit";
  250.                         $(submission).css('opacity',1);
  251.                 }
  252.                 // see if userops is already set, if not append it
  253.                 var userops = userbox.getElementsByClassName("userops")[0];
  254.                 if(userops == undefined){
  255.                         userops = document.createElement("span");
  256.                         userops.className = "userops";
  257.                         userbox.appendChild(userops);
  258.                 }
  259.                 // now fill with appropriate links
  260.                 if(foe_list.has(username) | friend_list.has(username))
  261.                         userops.innerHTML = " (<a style='color: #666;' href=\"javascript:userUnset('"+username+"');\">unset</a>)";
  262.                 else
  263.                         userops.innerHTML = " (<a style='color: #666;' href=\"javascript:userAddFoe('"+username+"');\">foe</a>|<a style='color: #666;' href=\"javascript:userAddFriend('"+username+"');\">friend</a>)";
  264.         }
  265. }
  266.  
  267.  
  268. // This goes through and clicks the "hide" button on the submissions
  269. // we add it to the reddit context so the link we add can call it
  270. unsafeWindow.autoh =  
  271. function (){
  272.         // div that holds all the submissions
  273.         var t = document.getElementsByClassName("midcol");
  274.         var c = 0;
  275.         var v = 0;
  276.         // loop through submissions
  277.         for(i=0; i < t.length; i++){
  278.                 // parent node is the div container for the submission
  279.                 submission = t[i].parentNode;
  280.                 var userbox = submission.getElementsByClassName("tagline")[0];
  281.                 // if in the recently viewed box (no username shown there) skip it
  282.                 try{
  283.                         var username = userbox.getElementsByTagName("a")[0].innerHTML;
  284.                 }catch(e){
  285.                         continue; // no username section
  286.                 }
  287.                 // if not a bad user, skip this iteration
  288.                 if(!foe_list.has(username))
  289.                         continue;
  290.                 c++;
  291.                 // hide it if it's down voted only
  292.                 if(t[i].className == "midcol dislikes"){
  293.                         // add object to click to the clicklist
  294.                         clicklist.push(submission.getElementsByClassName('state-button hide-button')[0].getElementsByTagName('a')[0]);
  295.                         v++;
  296.                 }
  297.     }
  298.         // start hiding (3 second time due to stupid fade out effect)
  299.         clickinterval = setInterval(clickloop, 3000);
  300.         // set status
  301.         setstatus("Hid "+v+" of "+c+" bad submissions");
  302. };
  303.  
  304.  
  305.  
  306.  
  307. // function to perform action on submissions
  308. function autov(){
  309.         try{
  310.         // get all submissions
  311.         var t = document.getElementsByClassName("midcol");
  312.         // loop through unvoted submissions
  313.         var c = 0;
  314.         var v = 0;
  315.         for(i=0; i < t.length; i++){
  316.                 // parent node is the div container for the submission
  317.                 var submission = t[i].parentNode;
  318.                 // now get the appropriate objects we check
  319.                 var downarrow = submission.getElementsByClassName("arrow down")[0];
  320.                 var userbox = submission.getElementsByClassName("tagline")[0];
  321.                 // if in the recently viewed box (no username shown there) skip it
  322.                 try{
  323.                         var username = userbox.getElementsByTagName("a")[0].innerHTML;
  324.                 }catch(e){
  325.                         continue; // no username section
  326.                 }
  327.                 // if not a bad user, skip this iteration
  328.                 if(!foe_list.has(username))
  329.                         continue;
  330.                 c++;
  331.                 // if not already down voted, down vote it
  332.                 if(t[i].className == "midcol unvoted"){
  333.                         // save arrow to an array for down-voting later
  334.                         clicklist.push(downarrow);
  335.                         v++;
  336.                 }
  337.     }
  338.         // start down voting form the list we made (1 second timer)
  339.         clickinterval = setInterval(clickloop, 1000);
  340.         // set status
  341.         if(c==0)
  342.                 setstatus("No bad submissions found");
  343.         else
  344.                 setstatus("Auto down voted "+v+" of "+c+" bad submissions");
  345.         }
  346.         catch(e){
  347.                 setstatus("Error: "+e);
  348.         }
  349. }
  350.  
  351.  
  352.  
  353.  
  354. /*
  355. ########################  Begin auto-procedures ############################
  356. */
  357.                                        
  358. // do auto-voting only if we are on a table with submissions listed
  359. if(document.getElementById('siteTable') != null){
  360.         getlists();
  361.         userSetCounts();
  362.         autov();
  363.         addButtons();
  364. }