VK top comments

Топовые комментарии VK!

  1. // ==UserScript==
  2. // @name VK top comments
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.2
  5. // @description Топовые комментарии VK!
  6. // @author Me
  7. // @match *://vk.com/*
  8. // @match *://*.vk.com/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15.  
  16. function CommentSorter(box) {
  17. if (window.location.host == 'vk.com') {
  18. box.setAttribute("data-sorter-init", "true");
  19. this.rootNode = box;
  20. this.statNode = box.querySelector('.post_full_like');
  21. if (this.statNode === null && this.rootNode.id == "wl_post") {
  22. this.statNode = box.querySelector('#wl_post_actions_wrap');
  23. this.singlePost = true;
  24. }
  25. this.init();
  26. }
  27. }
  28.  
  29. CommentSorter.getResource = function () {
  30. var scriptNode = document.querySelector("#VKCommentsSorterRootEx");
  31. return JSON.parse( scriptNode.getAttribute("data-resource") );
  32. };
  33.  
  34. CommentSorter.hookComments = function () {
  35. var arCommentsBox = document.querySelectorAll(".post");
  36. var box = null;
  37. var commentBox = null;
  38. var i;
  39. for (i = 0; i < arCommentsBox.length; i++) {
  40. box = arCommentsBox[i];
  41. commentBox = null;
  42. if (
  43. !box.hasAttribute("data-sorter-init") && (commentBox = box.querySelector(".replies_wrap.clear")) && commentBox.style.display != "none"
  44. )
  45. {
  46. box.commentSorter = new CommentSorter(box);
  47. }
  48. }
  49. box = document.getElementById('wl_post');
  50. if ( box &&
  51. !box.hasAttribute("data-sorter-init") && (commentBox = box.querySelector(".wl_replies")) && commentBox.style.display != "none"
  52. )
  53. {
  54. //console.log("Init for post");
  55. box.commentSorter = new CommentSorter(box);
  56. }
  57. arCommentsBox = document.querySelectorAll(".wall_fixed");
  58. box = null;
  59. commentBox = null;
  60. for (i = 0; i < arCommentsBox.length; i++) {
  61. box = arCommentsBox[i];
  62. commentBox = null;
  63. if (
  64. !box.hasAttribute("data-sorter-init") && ((commentBox = box.querySelector(".replies_wrap.clear")) || (commentBox = box.querySelector('.wall_fixed_replies'))) && commentBox.style.display != "none"
  65. )
  66. {
  67. box.commentSorter = new CommentSorter(box);
  68. }
  69. }
  70. };
  71.  
  72. CommentSorter.setSortAfterInit = function () {
  73. CommentSorter.sortAfterInit = true;
  74. };
  75.  
  76. CommentSorter.getSortAfterInit = function () {
  77. if (CommentSorter.sortAfterInit) {
  78. CommentSorter.sortAfterInit = false;
  79. return true;
  80. } else {
  81. return false;
  82. }
  83. };
  84.  
  85.  
  86. CommentSorter.getTextOnBtn = function () {
  87. return 'Топ';//CommentSorter.getResource().lang.top;
  88. };
  89.  
  90. CommentSorter.getButtonNodeForFullPost = function(self) {
  91. var btn = document.createElement("a");
  92. btn.className = "flat_button secondary button_light wl_action_link wl_post_share";
  93. btn.href = "#";
  94. btn.innerHTML = "<img style='margin-left:5px; float:right; margin-top:1px; width:17px' src='http://topcomments.burlaka.net/icon.svg'><span>"+CommentSorter.getTextOnBtn()+"</span>";
  95. btn.addEventListener("click", function (event) {
  96. event.preventDefault();
  97. self.onSortFullPostClick(event);
  98. });
  99. return btn;
  100. };
  101.  
  102. CommentSorter.getButtonNode = function (self) {
  103. if (self.singlePost) {
  104. return CommentSorter.getButtonNodeForFullPost(self);
  105. }
  106. var btn = document.createElement("div");
  107. btn.className = "post_share fl_r";
  108. btn.innerHTML = "<img style='float:right; margin-top:0px;width:17px;opacity:0.5' src='http://topcomments.burlaka.net/icon.svg'>"+'<span style="display: block" class="post_share_link fl_l">'+CommentSorter.getTextOnBtn()+'</span>';
  109. btn.style.position = "absolute";
  110. btn.style.width = "40px";
  111. btn.style.left = "-48px";
  112. btn.addEventListener("click", function (event) {self.onSortClick(event);} );
  113. return btn;
  114. };
  115.  
  116. CommentSorter.prototype.init = function () {
  117. var btn = CommentSorter.getButtonNode(this);
  118. if (this.singlePost) {
  119. this.btnText = btn.querySelector("span");
  120. } else {
  121. this.btnText = btn.querySelector('.post_share_link');
  122. }
  123. if (this.statNode) {
  124. this.statNode.appendChild( btn );
  125. } else {
  126. //console.log("Init without button");
  127. }
  128. if (CommentSorter.getSortAfterInit()) {
  129. btn.click();
  130. }
  131. };
  132.  
  133. CommentSorter.prototype.onFinishLoadAllComment = function () {
  134. this.btnText.innerHTML = CommentSorter.getTextOnBtn();
  135. clearInterval(this.loaderTimer);
  136. this.sortingAnimation = false;
  137. };
  138.  
  139. CommentSorter.prototype.onStartLoadAllComment = function() {
  140. if (this.sortingAnimation) return false;
  141. this.sortingAnimation = true;
  142. this.btnTextPonts = ".";
  143. this.btnText.innerHTML = CommentSorter.getTextOnBtn()+this.btnTextPonts;
  144. var self = this;
  145. this.loaderTimer = setInterval( function () { self.onLoadProgress(); }, 400 );
  146. return true;
  147. };
  148.  
  149. CommentSorter.prototype.onLoadProgress = function () {
  150. if (this.btnTextPonts.length >= 3) {
  151. this.btnTextPonts = ".";
  152. } else {
  153. this.btnTextPonts += '.';
  154. }
  155. this.btnText.innerHTML = CommentSorter.getTextOnBtn()+this.btnTextPonts;
  156. };
  157.  
  158. CommentSorter.prototype.onSortClick = function (event) {
  159. CommentSorter.setSortAfterInit();
  160. //console.log(event);
  161. var obj;
  162. if (obj == this.rootNode.querySelector(".wall_post_text")) {
  163. obj.click();
  164. }
  165. if (obj == this.rootNode.querySelector(".published_comment") ) obj.click();
  166. if (obj == this.rootNode.querySelector(".reply_link_wrap") ) obj.click();
  167. if (obj == this.rootNode.querySelector(".post_media") ) obj.click();
  168. if (obj == this.rootNode.querySelector(".event_share") ) obj.click();
  169. if (obj == this.rootNode.querySelector(".public_share") ) obj.click();
  170. if (obj == this.rootNode.querySelector(".group_share") ) obj.click();
  171. this.rootNode.click();
  172. //return;
  173. /*this.onStartLoadAllComment();
  174. var commentLoader = this.rootNode.querySelector('.wr_header');
  175. var self = this;
  176. if (commentLoader) {
  177. var progressBar = commentLoader.querySelector('.progress');
  178. if (progressBar && progressBar.style.display == "block") {
  179. setTimeout( function () {self.onSortClick(null);}, 100 );
  180. //console.log("Load wait");
  181. } else {
  182. if (!commentLoader.classList.contains('wrh_all')) {
  183. commentLoader.click();
  184. setTimeout( function () {self.onSortClick(null);}, 100 );
  185. //console.log("open all");
  186. }
  187. if (event === null) {
  188. setTimeout(function () {
  189. self.resortComments();
  190. }, 400);
  191. //console.log("resort all after load");
  192. this.onFinishLoadAllComment();
  193. }
  194. }
  195. }
  196. this.resortComments();*/
  197. };
  198.  
  199. CommentSorter.prototype.onSortFullPostClick = function (event) {
  200. var self = this;
  201. if (this.onStartLoadAllComment()) {
  202. this.resortComments();
  203. }
  204. if (wkcur)
  205. wkcur.limit = 100;
  206. var loaderState = this.rootNode.querySelector('#wl_replies_more_link');
  207. if (loaderState && loaderState.style.display != 'none' ) {
  208. var progressBar = this.rootNode.querySelector('#wl_replies_more_progress');
  209. if (progressBar && progressBar.style.display != 'block') {
  210. loaderState.click();
  211. //console.log("Click on load more");
  212. this.resortComments();
  213. } else {
  214. //console.log("Progress bar is hidden");
  215. }
  216. //console.log("Wait for loader");
  217. setTimeout( function () {self.onSortFullPostClick(0);}, 100 );
  218. } else {
  219. //console.log("Loader is hidden");
  220. if (event !== -1 && event !== -2) {
  221. setTimeout( function () {self.onSortFullPostClick(-1);}, 400 );
  222. //console.log("Waiting for loader this");
  223. } else {
  224. //console.log("Waiting twice");
  225. if (event !== -2) {
  226. setTimeout( function () {self.onSortFullPostClick(-2);}, 1200 );
  227. } else {
  228. //console.log("Loading too long, return");
  229. this.resortComments();
  230. this.onFinishLoadAllComment();
  231. }
  232. }
  233. }
  234. };
  235.  
  236. CommentSorter.prototype.resortComments = function () {
  237. var arComments = this.rootNode.querySelectorAll(".reply.reply_dived");
  238. var arSort = [];
  239. console.log("Start sort "+arComments.length);
  240. for (var i = 0; i < arComments.length; i++) {
  241. var node = arComments[i];
  242. var sortObject = {"node":node, "rating":0};
  243. var likeNode = node.querySelector(".like_count");
  244. if (likeNode && likeNode.innerHTML.length) {
  245. sortObject.rating = parseInt( likeNode.innerHTML );
  246. }
  247. arSort.push(sortObject);
  248. }
  249.  
  250. arSort.sort( function compare(b, a) {
  251. if (a.rating < b.rating) {
  252. return -1;
  253. }
  254. if (a.rating > b.rating) {
  255. return 1;
  256. }
  257. return 0;
  258. } );
  259.  
  260. for (var j = 0; j < arSort.length; j++) {
  261. var prent = arSort[j].node.parentNode;
  262. prent.removeChild(arSort[j].node);
  263. prent.appendChild(arSort[j].node);
  264. }
  265. };
  266.  
  267. CommentSorter.hookComments();
  268. setInterval(function () {CommentSorter.hookComments();}, 500);
  269. })();