您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
This script adds vote counts (+ and -) to the visible points on comments. They're normally not viewable on the web site. It also removes the "via Android" and "via iPhone" badges, because I have a tendency to click on them accidentally and don't feel that they add any value.
当前为
// ==UserScript== // @name Imgur: add vote counts to comment scores in the old design // @namespace http://tampermonkey.net/ // @version 0.3 // @description This script adds vote counts (+ and -) to the visible points on comments. They're normally not viewable on the web site. It also removes the "via Android" and "via iPhone" badges, because I have a tendency to click on them accidentally and don't feel that they add any value. // @author Corrodias // @match https://imgur.com/gallery/* // @match https://imgur.com/user/* // @icon https://www.google.com/s2/favicons?sz=64&domain=imgur.com // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // The comments container is not necessarily loaded before the script runs. Wait for it. function waitForElement(selector) { return new Promise(resolve => { if (document.querySelector(selector)) return resolve(document.querySelector(selector)); const observer = new MutationObserver(() => { if (document.querySelector(selector)) { observer.disconnect(); resolve(document.querySelector(selector)); } }); observer.observe(document.body, { childList: true, subtree: true }); }); } waitForElement('#captions').then(commentsSection => { const mutationObserver = new MutationObserver(mutations => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (node.nodeType === Node.ELEMENT_NODE) processAddedElement(node); } } }); function processAddedElement(node) { //console.log(node); if (window.location.pathname.startsWith('/gallery/') && node.classList.contains('children')) { // Replies were expanded, or navigation to a new post loaded a whole, new set of comments. We can safely update just the new nodes. updateComments(node); } else if (window.location.pathname.startsWith('/gallery/') && node.classList.contains('comment')) { // The user navigated to the "context" or "permalink" of an already displayed comment. Imgur modifies the existing structure rather than replace the nodes. updateComments(document.querySelector('#captions')); // The node that was added was a reply, not the top level comment, to replace all of them. } else if (window.location.pathname.startsWith('/user/') && node.classList.length === 0 && node.tagName === 'DIV') { // Comments on a user's page or replies just loaded. updateComments(node); } } function updateComments(node) { hideMobileBadges(node); removeOldPointsDetails(node); addPointsDetails(node); } function hideMobileBadges(node) { // Hide the Android/iPhone badges. Do not remove them, or React will break. let via = node.querySelectorAll('.via'); for (const a of via) { a.style.display = 'none'; } } function removeOldPointsDetails(node) { // Remove any existing vote counts so that we can calculate them fresh. // This is needed because navigating to the "context" or "permalink" of a comment doesn't necessarily add new nodes but rather can modify existing ones. let oldPoints = node.querySelectorAll('.points-detail'); for (const a of oldPoints) { a.remove(); } } function addPointsDetails(node) { let captionElements = node.querySelectorAll('.caption'); for (const element of captionElements) { // Pull the comment data from the React objects. let commentData = getCommentData(element); if (commentData === undefined || commentData === null) continue; // no data found // Build then add an element with the vote counts. let newElement = document.createElement('span'); newElement.textContent = '(+' + commentData.ups + ', -' + commentData.downs + ')'; newElement.setAttribute('class', 'comment-meta-spacer points-detail'); let points = element.firstChild.firstChild.querySelector('.comment-meta-spacer'); points.after(newElement); } } function getCommentData(node) { for (const propertyKey in node) { if (propertyKey.startsWith('__reactInternalInstance$')) // The rest of the name is not always identical. return node[propertyKey]._currentElement._owner._instance.props.comment; } return null; } // Update all currently displayed comments. updateComments(commentsSection); // Do the same on any comment that is loaded dynamically. mutationObserver.observe(commentsSection, { childList: true, subtree: true }); }); })();