// ==UserScript== // @name Better habr script // @namespace ilyachch/userscripts // @version 0.4.1 // @description Custom Script - Better habr // @author ilyachch (https://github.com/ilyachch/userscripts) // @homepageURL https://github.com/ilyachch/userscripts // @source https://github.com/ilyachch/userscripts/blob/main/userscripts/better_habr/better_habr.user.js // @supportURL https://github.com/ilyachch/userscripts/issues // @updateURL https://raw.githubusercontent.com/ilyachch/userscripts/main/userscripts/better_habr/better_habr.user.js // @downloadURL https://raw.githubusercontent.com/ilyachch/userscripts/main/userscripts/better_habr/better_habr.user.js // @license MIT // @run-at document-end // @match https://habr.com/*/post/*/* // @match https://habr.com/*/blog/*/* // @match https://habr.com/*/news/*/* // @match https://habr.com/*/articles/*/* // @match https://habr.com/**/company/**/**/* // @grant GM_addStyle // @icon https://assets.habr.com/habr-web/img/favicons/apple-touch-icon-76.png // ==/UserScript== const STYLE = ` .tm-comment-thread{ border-left: solid 5px grey; margin: 0 0 0 5px; padding-top: 10px; } .tm-comment-thread__children{ padding: 0; } button.tm-comment-thread__breadcrumbs{ width: 40px; } .tm-comment-thread__circle{ right: 16px; } div[data-comment-body]{ margin: 0 0 0 24px; } `; GM_addStyle(STYLE); (function () { "use strict"; ExposeRating(); makeCommentsSortable(); // improveCommentsVisibility(); })(); function ExposeRating() { function Rating( score, side, color = null, sign = null, should_colorize = false, ) { this.score = score; this.side = side; this.color = color; this.sign = sign; this.should_colorize = should_colorize; } let rating = get_rating(); setInterval(() => { colorize_header(rating); set_title(rating); }, 1000); function get_rating() { let rating_el = document.querySelector( ".tm-article-rating span.tm-votes-lever__score-counter", ) || document.querySelector( ".tm-article-rating span.tm-votes-meter__value", ) || document.querySelector( ".tm-article-comments__article-body span.tm-votes-meter__value", ); if (rating_el.innerText.startsWith("+")) { return new Rating( rating_el.innerText.slice(1), "positive", "#7aa600", "+", true, ); } else if (rating_el.innerText.startsWith("-")) { return new Rating( rating_el.innerText.slice(1), "negative", "#d04e4e", "-", true, ); } else { return new Rating(0, "neutral"); } } function colorize_header(rating) { let title_block = document.querySelector("h1.tm-title"); let title_el = document.querySelector("h1.tm-title span"); if (!rating.should_colorize || !title_block) { return; } if (title_block.getAttribute("patched") == "true") { return; } if (!title_block.querySelector(".header_rating")) { title_block.style.color = rating.color; title_el.innerHTML += ` (${rating.sign}${rating.score})`; } title_block.setAttribute("patched", "true"); } function set_title(rating) { let title_el = document.querySelector("head title"); if (title_el.getAttribute("patched") == "true") { return; } let sign = rating.sign ? rating.sign : ""; title_el.innerText = `(${sign}${rating.score}) ${title_el.innerText}`; title_el.setAttribute("patched", "true"); } } function makeCommentsSortable() { function showNotification(text) { let notification = document.createElement("div"); notification.style.position = "fixed"; notification.style.top = "33%"; notification.style.left = "50%"; notification.style.transform = "translate(-50%, -50%)"; notification.style.padding = "20px"; notification.style.backgroundColor = "forestgreen"; notification.style.opacity = "0.8"; notification.classList.add("notification"); notification.innerHTML = text; document.body.appendChild(notification); setTimeout(() => { notification.remove(); }, 2000); } function sortCommentsByRating() { let container = document.querySelector(".tm-comments__tree"); sortComments(container); showNotification("Comments sorted by rating"); } function sortComments(container) { let commentThreads = Array.from( container.querySelectorAll(":scope > section.tm-comment-thread"), ); let commentByRating = []; commentThreads.forEach((thread) => { let ratingEl = thread.querySelector( ":scope > article.tm-comment-thread__comment .tm-votes-lever__score-counter", ) || thread.querySelector( ":scope > article.tm-comment-thread__comment .tm-votes-meter__value", ); let rating = !!ratingEl ? parseInt(ratingEl.innerHTML) : -1; let comment_id = parseInt( thread .querySelector( ":scope > article.tm-comment-thread__comment > div[data-comment-body]", ) .getAttribute("data-comment-body"), ); commentByRating.push({ rating, thread, comment_id }); }); commentByRating.sort(function (a, b) { if (a.rating < b.rating) return 1; if (a.rating > b.rating) return -1; if (a.comment_id < b.comment_id) return -1; if (a.comment_id > b.comment_id) return 1; return 0; }); commentThreads.forEach((thread) => { container.removeChild(thread); }); commentByRating.forEach((comment) => { container.appendChild(comment.thread); let inner_contaner = comment.thread.querySelector( ":scope > .tm-comment-thread__children", ); if (!!inner_contaner) { sortComments(inner_contaner); } }); } function patchCommentsHeader() { let commentsHeader = document.querySelector( "div.tm-comments-wrapper__wrapper > header > h2", ); if (!commentsHeader) { return; } if (commentsHeader.getAttribute("patched") === "true") { return; } commentsHeader.style = ` cursor: pointer; color: rgb(102, 154, 179); `; commentsHeader.innerHTML += ' '; commentsHeader.addEventListener("click", sortCommentsByRating); commentsHeader.setAttribute("patched", true); } patchCommentsHeader(); setInterval(() => { patchCommentsHeader(); }, 1000); }