Guest User

NN.RU User Hide v.0.2.0

a guest
Jun 25th, 2015
350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        User Hide
  3. // @namespace   nnru
  4. // @description Hides user messages for selected users
  5. // @include     http://www.nn.ru/*
  6. // @version     0.2.0
  7. // @grant       none
  8. // @noframes
  9.  
  10. // ==/UserScript==
  11.  
  12. function Config() {
  13. }
  14. Config.opacity = 0.6;
  15. Config.updateAtSingleCall = 80;
  16.  
  17.  
  18. function BranchItem() {
  19. }
  20. BranchItem.getItemHeader = function(el) {
  21.   return el.querySelector(".branch-head");
  22. }
  23. BranchItem.getItemBody = function(el) {
  24.   return el.querySelector(".branch-body");
  25. }
  26. BranchItem.getId = function(el) {
  27.   return el.querySelector(".PortraitLink").getAttribute("usid");
  28. }
  29. BranchItem.getUserControl = function(el) {
  30.   return el.querySelector(".userControl");
  31. }
  32. BranchItem.getMessageHideControl = function(el) {
  33.   return el.querySelector(".messageHide");
  34. }
  35. BranchItem.getOverlay = function(el) {
  36.   return el.querySelector(".shadowOverlay");
  37. }
  38. BranchItem.getContainer = function(a) {
  39.   return a.parentNode.parentNode;
  40. }
  41. BranchItem.hide = function(el) {
  42.   var b = BranchItem.getItemBody(el);
  43.   var o = BranchItem.getOverlay(el);
  44.   b.style.display = 'none';
  45.   o.style.display = 'block';
  46. }
  47. BranchItem.show = function(el) {
  48.   var b = BranchItem.getItemBody(el);
  49.   if (b.style.display != undefined)
  50.     b.style.display = 'block';
  51.   var o = BranchItem.getOverlay(el);
  52.   o.style.display = 'none';
  53. }
  54.  
  55. function User(id = 0, name = "") {
  56.   this.id = id;
  57.   this.name = "";
  58.  
  59.   this.valid = function() {
  60.     return this.id != 0;
  61.   }
  62.   this.init = function(obj) {
  63.     if (obj) {
  64.       if ("id" in obj) this.id = obj.id;
  65.       if ("name" in obj) this.name = obj.name;
  66.     }
  67.     if (this.id && !this.name) {
  68.       var el = document.querySelector("a[usid='" + this.id + "']");
  69.       if (el) this.name = el.text;
  70.     }
  71.     //console.log("User: id: " + this.id + ", name: " + this.name);
  72.   }
  73.   this.data = function() {
  74.     var obj = {
  75.       id: this.id,
  76.       name: this.name
  77.     };
  78.     return obj;
  79.   }
  80.  
  81.   this.init();
  82. }
  83.  
  84. function UserControl(el, userManager) {
  85.   this.parent = el;
  86.   this.toggleBox = document.createElement("a");
  87.   this.div = document.createElement("div");
  88.   this.div1 = document.createElement("div");
  89.   this.label = document.createElement("label");
  90.   this.checkbox = document.createElement("input");
  91.   this.vline = document.createElement("label");
  92.   this.optButton = document.createElement("label");
  93.   this.overlay = document.createElement("div");
  94.   // -- Options --
  95.   /*this.options = document.createElement("div");
  96.   this.input = document.createElement("input");
  97.   this.import = document.createElement("button");
  98.   this.export = document.createElement("button");*/
  99.   // ----
  100.   this.userManager = userManager;
  101.   this.id = BranchItem.getId(el);
  102.   this.mid = Math.floor(Math.random() * (999999 - 100000)) + 100000;
  103.  
  104.   this.show = function() {
  105.     this.div1.style.border = "1px solid #AAA";
  106.     this.checkbox.checked = !!this.userManager.find(this.id);
  107.     this.label.style.display = 'inline';
  108.     this.checkbox.style.display = 'inline';
  109.     this.vline.style.display = 'inline';
  110.     this.optButton.style.display = 'inline';
  111.   }
  112.   this.hide = function() {
  113.     this.div1.style.border = "0px";
  114.     this.label.style.display = 'none';
  115.     this.checkbox.style.display = 'none';
  116.     this.vline.style.display = 'none';
  117.     this.optButton.style.display = 'none';
  118.   }
  119.   this.showOptions = function() {
  120.     console.log("Show options");
  121.     /*console.log(this.options, this.input);
  122.     this.input.value = this.userManager.getJSON();
  123.     this.options.style.position = 'absolute';
  124.     this.options.top = window.width / 2;
  125.     this.options.left = window.height / 2;
  126.    
  127.     document.body.appendChild(this.options);*/
  128.     var json = prompt("Скопируйте содержимое, чтобы перенести настройки в другой браузер",
  129.                                                                  this.userManager.getJSON());
  130.     //console.log(json);
  131.     if (json) {
  132.       this.userManager.importJSON(json);
  133.       this.userManager.update();
  134.     }
  135.   }
  136.   this.hideOptions = function() {
  137.     var b = BranchItem.getItemBody(this.parent);
  138.     return b.style.display == 'none';
  139.   }
  140.   this.createOverlay = function() {
  141.     //console.log("Creating overlay");
  142.     var b = BranchItem.getItemHeader(this.parent);
  143.     b.style.position = 'relative';
  144.     var firstElement = b.querySelector("a");
  145.     var left = firstElement.offsetLeft;
  146.     var top = 0;
  147.     var width = this.div.offsetLeft - left;
  148.     var height = 50;
  149.     var color = getComputedStyle(document.querySelector(".author-item"), null).backgroundColor;
  150.    
  151.     this.overlay.className = "shadowOverlay";
  152.     this.overlay.style.position = 'absolute';
  153.     this.overlay.style.left = left + "px";
  154.     this.overlay.style.top = top + "px";
  155.     this.overlay.style.width = width + "px";
  156.     this.overlay.style.height = height + "px";
  157.     this.overlay.style.backgroundColor = color;
  158.     this.overlay.style.opacity = Config.opacity;
  159.     this.overlay.style.borderRadius = "5px";
  160.     this.overlay.style.pointerEvents = 'none';
  161.     this.overlay.style.display = 'none';
  162.    
  163.     b.appendChild(this.overlay);
  164.   }
  165.   this.init = function() {
  166.     var self = this;
  167.     BranchItem.getItemHeader(this.parent).appendChild(this.div);
  168.     this.div.style.display = 'inline-block';
  169.     this.div.className = "userControl";
  170.    
  171.     this.div.appendChild(this.toggleBox);  
  172.     this.div.appendChild(this.div1);
  173.    
  174.     this.toggleBox.text = "[⨪]";
  175.     this.toggleBox.style.color = "grey";
  176.     this.toggleBox.className = "messageHide";
  177.     this.toggleBox.title = "Скрыть/Показать сообщение";
  178.     this.toggleBox.style.textDecoration = 'none';
  179.     this.toggleBox.style.cursor = 'default';
  180.     this.toggleBox.style.paddingLeft = '0px';
  181.     this.toggleBox.style.paddingRight = '3px';
  182.     this.toggleBox.onclick = function() {
  183.       console.log("Hide/Show message event");
  184.       var b = BranchItem.getItemBody(self.parent);
  185.       if (b.style.display == 'none') {
  186.         b.style.display = 'block';
  187.         self.overlay.style.display = 'none';
  188.       } else {
  189.         b.style.display = 'none';
  190.         self.overlay.style.display = 'block';
  191.       }
  192.     }
  193.     this.div1.style.display = 'inline-block';
  194.     this.div1.style.borderRadius = "4px";
  195.     this.div1.style.paddingTop = "1px";
  196.     this.div1.style.paddingBottom = "1px";
  197.    
  198.     var label = document.createElement("a");
  199.     label.text = "⪢";
  200.     label.style.color = "grey";
  201.     label.style.textDecoration = 'none';
  202.     label.style.cursor = 'default';
  203.     label.onclick = function() { return false; }
  204.     this.div1.appendChild(label);
  205.    
  206.     this.label.innerHTML = "Скрыть пользователя";
  207.     this.label.for = "userCheckbox" + this.mid;
  208.     this.label.style.display = 'none';
  209.     this.label.style.paddingLeft = '2px';
  210.     this.label.style.paddingRight = '4px';
  211.     this.div1.appendChild(this.label);
  212.    
  213.     this.checkbox.title = "Block User";
  214.     this.checkbox.type = 'checkbox';
  215.     this.checkbox.className = "userCheckbox";
  216.     this.checkbox.id = "userCheckbox" +  this.mid;
  217.     this.checkbox.style.top = '-1px';
  218.     this.checkbox.style.position = 'relative';
  219.     this.checkbox.style.verticalAlign = 'middle';
  220.     this.checkbox.checked = !!this.userManager.find(this.id);
  221.     this.checkbox.style.display = 'none'
  222.     this.checkbox.onclick = function() {
  223.       if (self.checkbox.checked) {
  224.         self.userManager.addUser(self.id);
  225.       } else {
  226.         self.userManager.removeUser(self.id);
  227.       }
  228.     }
  229.     this.div1.appendChild(this.checkbox);
  230.    
  231.     this.vline.innerHTML = "|";
  232.     this.vline.style.font = '16px';
  233.     this.vline.style.color = 'grey';
  234.     this.vline.style.padding = "1px";
  235.     this.vline.style.top = '1px';
  236.     this.vline.style.position = 'relative';
  237.     this.vline.style.verticalAlign = 'top';
  238.     this.vline.style.display = 'none';
  239.     this.div1.appendChild(this.vline);
  240.    
  241.     this.optButton.innerHTML = '⚙';
  242.     this.optButton.style.backgroundImage = 'linear-gradient(to bottom, #fafafa, #ebf1f5)';
  243.     this.optButton.style.verticalAlign = 'middle';
  244.     this.optButton.style.top = '-1px';
  245.     this.optButton.style.paddingLeft = '2px';
  246.     this.optButton.style.paddingRight = '2px';
  247.     this.optButton.style.position = 'relative';
  248.     this.optButton.style.margin = '2px';
  249.     this.optButton.style.display = 'none';
  250.     this.optButton.onmouseover = function() {
  251.       self.optButton.style.backgroundImage = 'linear-gradient(to bottom, #e8edf0, #caced1)';
  252.     }
  253.     this.optButton.onmouseout = function() {
  254.       self.optButton.style.backgroundImage = 'linear-gradient(to bottom, #fafafa, #ebf1f5)';
  255.     }
  256.     this.optButton.onclick = function(event) {
  257.       self.showOptions(event);
  258.     }
  259.     this.div1.appendChild(this.optButton);
  260.    
  261.     this.div1.onmouseover = function() {
  262.       self.show();
  263.     }
  264.     this.div1.onmouseout = function() {
  265.       self.hide();
  266.     }
  267.    
  268.     //setTimeout(this.createOverlay.bind(this), 600);
  269.     this.createOverlay();
  270.     // Options
  271.     /*this.input.type = 'text';
  272.     this.input.width = 80;
  273.     this.input.value = this.userManager.getJSON();
  274.     this.options.appendChild(this.input);
  275.    
  276.     this.options.style.textDecorations = 'none';
  277.     this.options.style.color = 'grey';
  278.     this.options.title = "Import";
  279.     this.options.appendChild(this.import);
  280.    
  281.     this.options.appendChild(this.export);*/
  282.   }
  283.   this.init();
  284. }
  285. UserControl.updateOverlays = function() {
  286.   console.log("Updating overlays");
  287.   var ol = document.querySelectorAll(".branch-head");
  288.   for (var b of ol) {
  289.     var overlay = BranchItem.getOverlay(b);
  290.     var userControl = BranchItem.getUserControl(b);
  291.     var firstElement = b.querySelector("a");
  292.     var width = userControl.offsetLeft - firstElement.offsetLeft;
  293.     overlay.style.width = width + "px";
  294.   }
  295.   console.log(ol.length + " overlays updated");
  296. }
  297.  
  298. function UserManager() {
  299.   this.users = {};
  300.   this.length = 0;
  301.   this.obs = null;
  302.  
  303.   this.init = function() {
  304.     console.log("Initializing UserManager...");
  305.     this.loadFromStorage();
  306.     this.register();
  307.     this.refresh();
  308.     setTimeout(UserControl.updateOverlays, 2000);
  309.     console.log("UserManager initialization complete");
  310.     console.log("==================================================");
  311.   }
  312.   this.register = function() {
  313.     console.log("Registering...");
  314.     var self = this;
  315.     //r target = document.getElementById("contentMainAll");
  316.     var target = document.querySelector("div");
  317.     var conf = { childList: true, subtree: true };    
  318.     this.obs = new MutationObserver(function(mutations) {
  319.       //console.log(mutations.length);
  320.       var nodes = [];
  321.       var targetNode = null;
  322.       for (var i = mutations.length - 1; i >= 0; --i) {
  323.         var mutation = mutations[i];
  324.         //console.log(mutation.type, mutation.target, mutation.addedNodes.length);
  325.         //Array.prototype.map.call(mutation.addedNodes, function (node) {
  326.         //   console.log(node);
  327.         //});
  328.         if (mutation.target.className == 'active_new_topic') {
  329.           setTimeout(self.refresh.bind(self), 500);
  330.           return;
  331.         }
  332.         if (mutation.target.className == 'branch-cont' &&
  333.             mutation.addedNodes.length > 0) {
  334.           nodes = mutation.target.querySelectorAll(".branch-item");
  335.           break;
  336.         }
  337.       }
  338.       console.log("DOM Changed. " + mutations.length + " mutations, " + nodes.length + " branch-item nodes");
  339.       if (nodes.length)
  340.         self.refresh(nodes);
  341.     });
  342.     this.obs.observe(target, conf);
  343.   }
  344.   this.loadFromArray = function(a) {
  345.     console.log("Loading ids from array");
  346.     // a - is the array of User Ids
  347.     var self = this;
  348.     a.forEach(function(id) {
  349.       if (!(id in self.users)) {
  350.         self.users[id] = new User(id);
  351.         ++self.length;
  352.       }
  353.     });
  354.     console.log("Loaded " + a.length + " records");
  355.   }
  356.   this.loadFromStorage = function() {
  357.     console.log("Loading from storage...");
  358.     var newIds = this.importJSON(localStorage.getItem("nnru_blacklist"));
  359.     console.log(newIds.length + " records loaded");
  360.   }
  361.   this.saveToStorage = function() {
  362.     console.log("Saving to storage...")
  363.     localStorage.setItem("nnru_blacklist", this.getJSON());
  364.     console.log("Records saved");
  365.   }
  366.   this.clearStorage = function() {
  367.     localStorage.setItem("nnru_blacklist", "[]");
  368.   }
  369.   this.find = function(id) {
  370.     if (id in this.users) {
  371.       return this.users[id];
  372.     }
  373.     return undefined;
  374.   }
  375.   this.getJSON = function() {
  376.     var a = { users: [] };
  377.     for (var id in this.users) {
  378.       //console.log(this.users[id].data(), id != 0);
  379.       if (id != "0") a.users.push(this.users[id].data());
  380.     }
  381.     console.log(JSON.stringify(a));
  382.     return JSON.stringify(a);
  383.   }
  384.   this.importJSON = function(json) {
  385.     var a = JSON.parse(json);
  386.     var newIds = [];
  387.     if (a) {
  388.       console.log("Reading records: " +json);
  389.       var users = a.users ? a.users : a;
  390.       for (var user of users) {
  391.         if (user.id != "0") {
  392.           if (!(user.id in this.users)) {
  393.             this.users[user.id] = new User();
  394.             newIds.push(this.users[user.id]);
  395.             ++this.length;
  396.           }
  397.           //console.log(user);
  398.           this.users[user.id].init(user);
  399.           //console.log(this.users[user.id]);
  400.         }
  401.       }
  402.     }
  403.     return newIds;
  404.   }
  405.   this.addUser = function(id) {
  406.     console.log("Adding User " + id)
  407.     if (!(id in this.users)) {
  408.       var user = new User(id);
  409.       this.users[id] = user;
  410.       ++this.length;
  411.       Array.prototype.forEach.call(document.querySelectorAll("a[usid='" + id + "']"), function(a) {
  412.         BranchItem.hide(BranchItem.getContainer(a));
  413.       });
  414.       this.saveToStorage();
  415.     }
  416.   }
  417.   this.removeUser = function(id) {
  418.     console.log("Removing User " + id)
  419.     var user = this.find(id);
  420.     if (user) {
  421.       Array.prototype.forEach.call(document.querySelectorAll("a[usid='" + id + "']"), function(a) {
  422.         BranchItem.show(BranchItem.getContainer(a));
  423.       });
  424.       delete this.users[id];
  425.       --this.length;
  426.       this.saveToStorage();
  427.     }
  428.   }
  429.   var getBranchItemNodes = function() {
  430.     return Array.prototype.filter.call(document.querySelectorAll(".branch-item"),
  431.                                           function(node) {
  432.                                             return !BranchItem.getMessageHideControl(node);
  433.                                           });
  434.   }
  435.   this.refresh = function(nodes = null) {
  436.     console.log("Refreshing...");
  437.     var augmented = 0, updated = 0, checked = 0;
  438.     if (!nodes) nodes = getBranchItemNodes();
  439.     var remainder = null;
  440.     if (nodes.length > Config.updateAtSingleCall) {
  441.       remainder = Array.prototype.slice.call(nodes, Config.updateAtSingleCall);
  442.       nodes = Array.prototype.slice.call(nodes, 0, Config.updateAtSingleCall);
  443.     }
  444.     for (var node of nodes) {
  445.       if (!BranchItem.getMessageHideControl(node)) {
  446.         new UserControl(node, this);
  447.         ++augmented;
  448.       }
  449.       var id = BranchItem.getId(node);
  450.       var user = this.find(id);
  451.       if (user) {
  452.         BranchItem.hide(node);
  453.         ++updated;
  454.       }
  455.       ++checked;
  456.     }
  457.     if (remainder)
  458.       setTimeout(this.refresh.bind(this, remainder), 100);
  459.     console.log("Nodes augmented: " + augmented + ", updated: " + updated + ", checked: " + checked);
  460.   }
  461. }
  462.  
  463. var userManager = new UserManager();
  464.  
  465. function onLoad() {
  466.   console.log("UserHide init...");
  467.   userManager.init();
  468. }
  469.  
  470. onLoad();
Advertisement
Add Comment
Please, Sign In to add comment