Smarty_Pants / FFS User Blocker for Firefox 57+

// ==UserScript==
// @name        FFS User Blocker for Firefox 57+
// @namespace   Smarty Pants
// @author	    Smarty Pants
// @version     3.0
// @include     http://www.fantasyfootballscout.co.uk/*
// @description Block users on Fantasy Football Scout
// @grant       GM.getValue
// @grant       GM.setValue
// @run-at      document-end
// @require     https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js
// @license     MIT
// ==/UserScript==

/* MENU POP UP */
/* create box with lists of blocked users, delete a profile on click */


function createModalBox(){
  
  // popup html structure
  var html = "";
  var modal_div = document.createElement("DIV");
  modal_div.id = "gr-container";
  
  var modal_div_content = document.createElement("DIV");
  modal_div_content.id = "gr-content";
  
  var mdc_header = document.createElement("DIV");
  mdc_header.className = "gr-content-header";
  var mdc_content = document.createElement("DIV");
  mdc_content.className = "gr-content-content";
  var mdc_footer = document.createElement("DIV");
  mdc_footer.className = "gr-content-footer";
  
  // "close" button
  var modal_div_close = document.createElement("SPAN");
  modal_div_close.className = "gr-close";
  modal_div_close.innerHTML = "x";
  modal_div_close.onclick = function(){
    var modal = document.getElementById('gr-container');
    $(modal).remove();
  };
  
  // add content 
  var mdc_header_text = document.createElement("H4");
  mdc_header_text.innerHTML = "Blocked Users";
  mdc_content.appendChild(createMoronsListDiv());
  mdc_content.appendChild(createMoronsListDiv(true));
  mdc_footer.innerHTML = "Click on a link to unblock a user. Reload page for changes to kick in.";
  
  // add to dom
  $(modal_div).append(modal_div_content);
  $(modal_div_content).append(mdc_header);
  $(modal_div_content).append(mdc_footer);
  $(modal_div_content).append(mdc_content);
  $(mdc_header).append(modal_div_close);
  $(mdc_header).append(mdc_header_text);
  $("body").append(modal_div);
 
  // add css styles 
  $(modal_div).css({"display": "none",
    "position": "fixed",
    "z-index": "10000",
    "left": "0",
    "top": "0",
    "width": "100%",
    "height": "100%",
    "overflow": "auto",
    "background-color": "rgba(0,0,0,0.4)"
  });
  
  $(modal_div_content).css({
    "background-color": "#fefefe",
    "margin": "5% auto",
    "padding": "20px",
    "border": "1px solid #888",
    "width": "80%",
    "box-shadow": "0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)"
  });
    
  $(".gr-close").css({
    "color": "#ffffff",
    "float": "right",
    "font-size": "28px",
    "line-height": "1",
    "font-weight": "bold"
  });

  $(".gr-close").hover(
    function () {
      $(this).css({          
        "color": "#000000",
        "text-decoration": "none",
        "cursor": "pointer"
      })
    },
    function () {
      $(this).css({          
        "color": "#ffffff",
        "cursor": "default"
      })
    }
  );
  
  $(mdc_header).css({
    "padding": "2px 16px",
    "background-color":"rgb(0, 121, 77)",
    "color": "#FFF"
  });
  
  $(mdc_footer).css({
    "padding": "2px 16px",
    "background-color":"rgb(0, 121, 77)",
    "color": "#FFF"
  });
  
  $("UL.gr-blocked-users").css({
    "list-style-type": "none",
    "padding": "0",
    "margin": "0",
  });
  
  $("DIV.gr-blocked-users-header").css({
    "border": "1px solid #ddd",
    "margin-top": "-1px",
    "background-color":"#5cb85c",
    "padding": "2px 16px",
    "font-size": "17px",
    "color": "#FFF",
    "display": "block",
    "font-weight": "bold"
  })
                      
  $("LI.gr-blocked-user").css({
    "border": "1px solid #ddd",
    "margin-top": "-1px",
    "background-color":"#f6f6f6",
    "padding": "6px 12px",
    "font-size": "15px",
    "color": "#000",
    "display": "block"
  })
  
  $("LI.gr-blocked-user").hover(
    function () {
      $(this).css({          
        "background-color": "#555",
        "color":"#fff",
        "font-size": "18px",
        "padding": "3px 12px",
        "cursor": "pointer"
      })
    },
    function () {
      $(this).css({          
        "background-color":"#f6f6f6",
        "color": "#000",
        "font-size": "15px",
        "padding": "6px 12px",
        "cursor": "default"
      })
    }
  );
  
  // callback functions to remove link from blocked 
  $("LI.gr-blocked-user.minimized").click(
    function () {
      removeFromMorons(this.innerHTML);
      $(this).remove();
    }
  );

  $("LI.gr-blocked-user.chidden").click(
    function () {
      $(this).remove();
      removeFromCompleteMorons(this.innerHTML);
    }
  );
}

// return a div with list of blocked profiles
function createMoronsListDiv(complete=false){
  var list_div = document.createElement("UL");
  var list_header = document.createElement("DIV");
  list_header.className = "gr-blocked-users-header";
  list_header.innerHTML = (complete == true ? "Completely Hidden Users (all posts and replies to them hidden completely)" : "Partially Hidden Users (there is an option to expand comment)");
  list_div.appendChild(list_header);
  list_div.className = "gr-blocked-users";
  var items = [];
  var list = (complete == true ? complete_morons : morons);
  for (var i = 0; i < list.length; i++){
    items.push(document.createElement("LI"));
    items[i].innerHTML = list[i];
    items[i].className = (complete == true ? "gr-blocked-user chidden" : "gr-blocked-user minimized");
    list_div.appendChild(items[i]);
  }
  return list_div
}





/* COMMENT SECTION */
/* Hide comments with specified classes */
function hideMorons(){
  // minimize messages, add callbacks to open thread
  var comments_to_block = $(".annoying-moron")
  for (var i = 0; i<comments_to_block.length; i++){
    comment = comments_to_block[i];
    $(comment).children().css("display","None");
    $(comment).parent().children("ol").css("display","None");

    var new_node = document.createElement("DIV");
    new_node.className = "block-message";
    new_node.innerHTML = "Hidden comment by " + comment.getAttribute("user_name") + " (" + ($(comment).parent().find(".hc-comment").length-1) + ")";
    $(new_node).css({"font-size":"10px", "padding":"2px 10px"});
    
    $(new_node).hover(
      function(){
      $(this).css({"cursor":"pointer", "background-color":"RGBA(0,0,0,0.5)"})
    },
      function(){
      $(this).css({"cursor":"default", "background-color":"RGBA(0,0,0,0)"})
    });
    
    $(new_node).click(function(){
      $(this).parent().children(":not(.block-message)").css("display","block"); // show comment
      $(this).parent().parent().children("ol").css("display","block"); // show replies
      $(this).css("display","None") // hide message
    });
    
    comment.appendChild(new_node);
  }
  // hide whole threads
  var comments_to_block = $(".complete-moron");
  for (var j = 0; j<comments_to_block.length; j++){
    comment = comments_to_block[j];
    $(comment).parent().children().css("display","None");
  }
}


/* Run a loop through comments and add classes (where applicable) and buttons */
/* Use boolean arguments to limit only to buttons or classes */
function addClassesAndButtons(classes, buttons){
  var comments = $(".hc-comment")
  for (var i = 0; i<comments.length; i++){
    try{
    var comment = comments[i];
    var actions = comment.getElementsByClassName("hc-comment-actions");
    var usertitle = comment.getElementsByClassName("hc-title");
    var userlink = usertitle[0].href;
    var username = usertitle[0].getAttribute("oldtitle");
    if (username === null) {username = usertitle[0].getAttribute("title")}
    comment.setAttribute("user_name", username);
    comment.user_name = username; // for Chrome
    
    
    if (buttons) {actions[0].appendChild(addMoronButton(userlink));
                 actions[0].appendChild(addCompleteMoronButton(userlink));}
    if (classes) {addClass(comment, userlink);}
    }
    catch(e){console.log("ERROR: "+e)}
  }
}

/* Add button to each comment */
function addMoronButton(link){
  var new_node = document.createElement("LI");
  new_node.className = "hc-permalink";
  new_node.setAttribute("profile_link", link);
  new_node.onclick = function() { 
    addToMorons(this.getAttribute("profile_link")) // add to array
    addClassesAndButtons(true, false) // add classes once again according to new array of blocked users
    hideMorons() // re-hide
  };
  new_node.innerHTML = "&#128169;"
  return new_node;
}

function addCompleteMoronButton(link){
  var new_node = document.createElement("LI");
  new_node.className = "hc-permalink";
  new_node.setAttribute("profile_link", link);
  new_node.onclick = function() { 
    addToCompleteMorons(this.getAttribute("profile_link")) // add to array
    addClassesAndButtons(true, false) // add classes once again according to new array of blocked users
    hideMorons() // re-hide
  };
  new_node.innerHTML = "&#128683;"
  return new_node;
}


/* Function that checks whether a profile is among blocked and adds a new class if true */
function addClass(node, userlink){  
  if (morons.length > 0) {
    if (morons.indexOf(userlink)!=-1){
      $(node).addClass("annoying-moron");
    }
  }
  if (complete_morons.length > 0) {
    if (complete_morons.indexOf(userlink)!=-1){
      $(node).addClass("complete-moron");
    }
  }
}

/* Functions to add a profile to a corresponding array */
function addToMorons(profile_link){
  if (morons.indexOf(profile_link)==-1){
    morons.push(profile_link);
  }
  morons.sort();
  saveList("ffs_blocked_users", morons);
}
function addToCompleteMorons(profile_link){
  if (complete_morons.indexOf(profile_link)==-1){
    complete_morons.push(profile_link);
  }
  complete_morons.sort();
  saveList("ffs_hidden_users", complete_morons);
}

/* Functions to remove a profile from a corresponding array */
function removeFromMorons(profile_link){
  if (morons.indexOf(profile_link)!=-1){
    morons.splice(morons.indexOf(profile_link),1);
  }
  morons.sort();
  saveList("ffs_blocked_users", morons)
}
function removeFromCompleteMorons(profile_link){
  if (complete_morons.indexOf(profile_link)!=-1){
    complete_morons.splice(complete_morons.indexOf(profile_link),1);
  }
  complete_morons.sort();
  saveList("ffs_hidden_users", complete_morons);
}

/* Functions to get stored arrays of blocked user profiles */
async function getList(name) {
  var str = await GM.getValue(name, "");
  var data = str.split(" ");
  if (data[0]=="") {data = []};
  return data;
}
async function saveList(name, data) {
  str = data.join(" ");
  console.log("setting value", str);
  let a = await GM.setValue(name, str);
  return 0;
}

/* Add an item to main menu to show lists of blocked users */
function addMenuItem(){
  var new_node = document.createElement("LI");
  $(new_node).append("<a>&#128169;</a>");
  $(new_node).addClass("menu-item menu-item-type-custom");
  $(new_node).click(function() {
    createModalBox() //create box with current list values
    $('#gr-container').css("display","block")
    window.onclick = function(event) {
      var modal = document.getElementById('gr-container');
      if (event.target == modal) {
          $(modal).remove();
      }
    }
  })
  $("ul#menu-main-nav.menu").append(new_node);
}


var morons;
var complete_morons;
getList("ffs_blocked_users").then(v => {
	morons=v;
  getList("ffs_hidden_users").then(w => {
    complete_morons=w;

    addMenuItem()
    addClassesAndButtons(true, true);
    hideMorons();
  });
});