您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a block button to every tweet in order to quickly block people.
当前为
- // ==UserScript==
- // @name Twitter One-Click Block Button
- // @namespace https://gist.github.com/toxicwind
- // @version 1.1
- // @description Adds a block button to every tweet in order to quickly block people.
- // @author toxicwind
- // @license MIT
- // @match https://twitter.com/*
- // @icon https://www.google.com/s2/favicons?sz=64&domain=twitter.com
- // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js
- // @require https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js
- // @grant none
- // @run-at document-end
- // ==/UserScript==
- const css = `
- a.block-button {
- display: flex;
- align-items: center;
- justify-content: center;
- }
- a.block-button svg {
- width: 1em;
- height: 1em;
- fill: currentcolor;
- }
- a.block-button {
- transition: color 0.5s;
- }
- a.block-button:hover {
- color: red;
- }
- @keyframes wide {
- 0% {
- width: 0%
- }
- 100% {
- width: 60%;
- }
- }`;
- const style = document.createElement("style");
- style.textContent = css;
- document.head.appendChild(style);
- (async () => {
- let fetchToken = async () => {
- let mainUrl = null;
- for (let script of document.body.querySelectorAll("script[src]"))
- if (/\/main\.[^\/]*\.js$/.test(script.src)) mainUrl = script.src;
- if (!mainUrl) return null;
- let response = await fetch(mainUrl);
- let mainSource = await response.text();
- let result = /\"AAAAAAA[^"]+\"/.exec(mainSource);
- if (!result || result.length != 1) return null;
- return JSON.parse(result[0]);
- };
- let authToken = await fetchToken();
- let getCookie = (cname) => {
- const name = `${cname}=`;
- const decodedCookie = decodeURIComponent(document.cookie);
- const ca = decodedCookie.split(";");
- for (let i = 0; i < ca.length; i++) {
- let c = ca[i];
- while (c.charAt(0) == " ") {
- c = c.substring(1);
- }
- if (c.indexOf(name) == 0) {
- return c.substring(name.length, c.length);
- }
- }
- return "";
- };
- let blockUser = async (userName) => {
- return await fetch("https://api.twitter.com/1.1/blocks/create.json", {
- credentials: "include",
- referrer: "https://api.twitter.com/1.1/blocks/create.json",
- body: `screen_name=${userName}`,
- method: "POST",
- mode: "cors",
- headers: {
- "x-twitter-auth-type": "OAuth2Session",
- "x-twitter-client-language": "en",
- "x-twitter-active-user": "yes",
- "x-csrf-token": getCookie("ct0"),
- authorization: `Bearer ${authToken}`,
- "Content-Type": "application/x-www-form-urlencoded",
- },
- });
- };
- let buttonClick = async (e) => {
- let userName = e.currentTarget.dataset.blockUser;
- let blockResult = await blockUser(userName);
- if (blockResult.status === 200) {
- $("article")
- .find("a[data-block-user=" + userName + "]")
- .parents("article[data-testid=tweet]")
- .slideUp(200);
- //alert("User blocked successfully.");
- } else {
- alert(
- "The block operation failed, see the network tab for detailes of the failure."
- );
- }
- };
- const icon = `<span> · </span><svg xmlns="http://www.w3.org/2000/svg" clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m17.069 6.546 2.684-2.359c.143-.125.32-.187.497-.187.418 0 .75.34.75.75 0 .207-.086.414-.254.562l-16.5 14.501c-.142.126-.319.187-.496.187-.415 0-.75-.334-.75-.75 0-.207.086-.414.253-.562l2.438-2.143c-1.414-1.132-2.627-2.552-3.547-4.028-.096-.159-.144-.338-.144-.517s.049-.358.145-.517c2.111-3.39 5.775-6.483 9.853-6.483 1.815 0 3.536.593 5.071 1.546zm2.318 1.83c.967.943 1.804 2.013 2.475 3.117.092.156.138.332.138.507s-.046.351-.138.507c-2.068 3.403-5.721 6.493-9.864 6.493-1.298 0-2.553-.313-3.73-.849l2.624-2.307c.352.102.724.156 1.108.156 2.208 0 4-1.792 4-4 0-.206-.016-.408-.046-.606zm-4.932.467c-.678-.528-1.53-.843-2.455-.843-2.208 0-4 1.792-4 4 0 .741.202 1.435.553 2.03l1.16-1.019c-.137-.31-.213-.651-.213-1.011 0-1.38 1.12-2.5 2.5-2.5.474 0 .918.132 1.296.362z" fill-rule="nonzero"/>`;
- let observer;
- const interval = setInterval(init, 500);
- const DEBUG = true;
- function debug() {
- if (DEBUG) {
- console.log.apply(null, arguments);
- }
- }
- function init() {
- const el = document.querySelectorAll(
- 'div[data-testid="primaryColumn"] section article'
- );
- if (el && el.length > 0) {
- clearInterval(interval);
- debug("articles found");
- //add links to already exisiting articles
- observer = new MutationObserver(newTweets);
- observer.observe(document.body, {
- childList: true,
- attributes: false,
- subtree: true,
- characterData: false,
- });
- el.forEach((article) => {
- createLink(article);
- });
- }
- }
- function newTweets(mutationList, observer) {
- mutationList.forEach((mut) => {
- if (mut.addedNodes.length > 0) {
- mut.addedNodes.forEach((node) => {
- if (node.innerHTML && node.innerHTML.indexOf("<article ") > -1) {
- createLink(node.querySelector("article"));
- }
- });
- }
- });
- }
- function createLink(t) {
- if (!t.querySelector("a[block-button]")) {
- const profileName = t
- .querySelector("div[data-testid=User-Names]")
- .querySelector("a")
- .pathname.substr(1);
- const time = t.querySelector('a[href*="/status/"] time[datetime]');
- if (!time) return;
- const statuslink = time.parentNode;
- const block_link = document.createElement("a");
- block_link.setAttribute("class", "block-button");
- block_link.setAttribute("data-block-user", profileName);
- block_link.innerHTML = icon;
- statuslink.insertAdjacentElement("afterend", block_link);
- block_link.title = "Block User: " + profileName;
- block_link.onclick = buttonClick;
- }
- }
- })();