Display a verified sign next to user's name in AniList.
当前为
// ==UserScript==
// @name VoidVerified
// @namespace http://tampermonkey.net/
// @version 0.2.0
// @description Display a verified sign next to user's name in AniList.
// @author voidnyan
// @match https://anilist.co/*
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
const version = "0.2.0";
const localStorageConfigKey = "VoidVerificationConfig";
const usernameSelector = ["a.name"];
const displaySaveButton = false;
const config = JSON.parse(window.localStorage.getItem(localStorageConfigKey));
const verifiedDefaults = {
enableForProfile: true,
username: {
enabled: true,
enabledForReplies: true,
color: "white",
sign: "✔",
title: "Verified",
},
highlight: {
enabled: true,
enabledForReplies: true,
color: undefined,
size: "5px",
}
};
const verifiedUsersDefault = [
{
username: "voidnyan",
color: "green",
sign: "💻",
title: "devnyan"
},
// "anotheruser"
].map(u => typeof u === "string" ? {username: u} : u);
displaySaveButton && renderSaveButton();
const verified = config?.verified ?? verifiedDefaults;
const verifiedUsers = config?.verifiedUsers ?? verifiedUsersDefault;
const verifiedUsersArray = [
...verifiedUsers.map(user => user.username)
];
const observer = new MutationObserver(observeMutations);
observer.observe(document.body, {childList: true, subtree: true});
function observeMutations(mutations) {
for (const mutation of mutations) {
if (mutation.addedNodes.length > 0) {
mutation.addedNodes.forEach(handleVerified);
}
}
}
function handleVerified(node){
if (!(node instanceof HTMLElement)) {
return;
}
switch (true){
case node.matches("div.reply"):
handleReply(node);
break;
case node.matches("div.activity-anime_list"):
case node.matches("div.activity-manga_list"):
case node.matches("div.container"):
handleListActivity(node);
break;
case node.matches("div.activity-text"):
case node.matches("div.activity-message"):
handleTextActivity(node);
break;
case node.matches("div.user"):
handleProfile(node);
break;
}
}
function handleReply(node) {
const username = node.querySelector(usernameSelector);
addVerifiedMarkToReply(username);
highlightReply(node, username);
}
function handleListActivity(node) {
const isProfileActivity = node.querySelector(".small") !== null;
if (isProfileActivity) {
return;
}
const username = node.querySelector(usernameSelector);
addVerifiedMark(username);
highlightActivity(node, username);
}
function handleTextActivity(node) {
const username = node.querySelector(usernameSelector);
addVerifiedMark(username);
highlightActivity(node, username);
}
function handleProfile(){
if (!verified.enableForProfile){
return;
}
const username = document.querySelector("h1.name");
addVerifiedMarkToProfile(username);
}
function addVerifiedMark(username) {
if (!isVerifiedUser(username) || !verified.username.enabled) {
return;
}
const span = createMarkElement(username);
span.style.width = "min-content";
username.after(span);
}
function addVerifiedMarkToReply(username) {
if (!isVerifiedUser(username) || !verified.username.enabledForReplies) {
return;
}
const span = createMarkElement(username);
span.style.display = "inline-block";
span.style.verticalAlign = "top";
span.style.lineHeight = "25px";
span.style.height = "25px";
username.after(span);
}
function addVerifiedMarkToProfile(username) {
if (!isVerifiedUser(username)) {
return;
}
const span = document.createElement("span");
span.innerHTML = verified.username.sign;
span.title = verified.username.title;
span.style.marginLeft = "6px";
username.after(span);
}
function getLinkColor(username){
var linkColor = getComputedStyle(username).getPropertyValue("--color-blue");
return `rgb(${linkColor})`;
}
function createMarkElement(username){
const span = document.createElement("span");
const dataset = username.dataset;
const id = Object.keys(dataset)[0];
span.setAttribute(`data-${id}`, "");
span.style.color = verified.username.color ?? getLinkColor(username);
span.style.marginLeft = "6px";
span.innerHTML = getSign(username);
span.title = getTitle(username);
return span;
}
function highlightActivity(node, username) {
if (!verified.highlight.enabled || !isVerifiedUser(username)) {
return;
};
const wrapper = node.querySelector("div.wrap");
wrapper.style.marginRight = `-${verified.highlight.size}`;
wrapper.style.borderRight = `${verified.highlight.size} solid ${getColor(username)}`;
}
function highlightReply(node, username) {
if (!verified.highlight.enabledForReplies || !isVerifiedUser(username)) {
return;
}
node.style.marginRight = `-${verified.highlight.size}`;
node.style.borderRight = `${verified.highlight.size} solid ${getColor(username)}`;
}
function isVerifiedUser(username) {
const isVerifiedUser = verifiedUsersArray.includes(username?.innerHTML.trim());
return isVerifiedUser;
}
function getColor(username) {
const user = getUserObject(username);
const color = user?.color ?? verified.highlight.color ?? getLinkColor(username);
return color;
}
function getSign(username){
const user = getUserObject(username);
const sign = user?.sign ?? verified.username.sign;
return sign;
}
function getTitle(username) {
const user = getUserObject(username);
const title = user?.title ?? verified.username.title;
return title;
}
function getUserObject(username){
var usernameAsString = username.innerHTML.trim();
const user = verifiedUsers.find(u => u.username === usernameAsString);
return user;
}
function overrideLocalStorageConfig(verifiedOverride, verifiedUsersOverride) {
const config = {
verified: verifiedOverride,
verifiedUsers: verifiedUsersOverride
}
window.localStorage.setItem(localStorageConfigKey, JSON.stringify(config));
}
function saveConfigToLocalStorage(){
const config = {
verified,
verifiedUsers
};
window.localStorage.setItem(localStorageConfigKey, JSON.stringify(config));
}
function renderSaveButton() {
const footerLinks = document.querySelector("div.footer div.links");
const button = document.createElement("button");
button.onClick = overrideLocalStorageConfig(verifiedDefaults, verifiedUsersDefault);
button.innerHTML = "Save Configuration";
footerLinks.lastChild.append(button);
}
console.log(`VoidVerified ${version} loaded.`);
})();