// ==UserScript==
// @name 消えろX
// @namespace https://twitter.com/hiyokunohane
// @version 0.334
// @description Convert "X" in tweets to "Twitter"
// @author hiyokunohane
// @match https://twitter.com/*
// @match https://x.com/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Configuration list: [enabled, searchValue, replaceValue, replaceIfSurroundedByLetters]
const replacements = [
[true, 'x', 'twitter', true],
[true, 'X', 'Twitter', true],
[false, 'X', 'TWITTER', true],
[true, 'x', 'twitter', true],
[true, 'X', 'Twitter', true],
[true, 'エックス', 'ツイッター', true],
[true, 'えっくす', 'ついったー', true],
[true, 'エックス', 'ツイッター', true],
[true, 'エッカス', 'ツイッカス', true],
[true, 'ポスト', 'ツイート', false],
[true, 'ぽすと', 'ついーと', true],
[false, 'いいね', 'ふぁぼ', true],
[true, 'イイネ', 'ファボ', true],
[true, 'post', 'tweet', true],
[true, 'Post', 'Tweet', true],
[true, 'POST', 'TWEET', true],
[false, 'like', 'fav', true],
[true, 'RP', 'RT', true]
];
// Function to replace text in a node
function replaceText(node) {
if (node.nodeType === Node.TEXT_NODE) {
let textContent = node.textContent;
replacements.forEach(replacement => {
if (replacement[0]) {
const searchValue = replacement[1];
const replaceValue = replacement[2];
const replaceIfSurroundedByLetters = replacement[3];
if (replaceIfSurroundedByLetters) {
// Replace only if the search value is not surrounded by letters
const regex = new RegExp(`(?<![a-wyzA-WYZ])${escapeRegExp(searchValue)}(?![a-wyzA-WYZ])`, 'g');
textContent = textContent.replace(regex, replaceValue);
} else {
// Replace normally
const regex = new RegExp(escapeRegExp(searchValue), 'g');
textContent = textContent.replace(regex, replaceValue);
}
}
});
node.textContent = textContent;
} else {
for (let i = 0; i < node.childNodes.length; i++) {
replaceText(node.childNodes[i]);
}
}
}
// Function to escape special characters for regex
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
// Function to replace text in tweets only
function replaceTextInTweets() {
const tweetSelectors = [
'article div[lang]', // Twitter's tweet text container
'div.css-901oao', // Possible alternative for tweet text container
'div[data-testid="tweetText"]' // Test id used in some Twitter text containers
];
tweetSelectors.forEach(selector => {
document.querySelectorAll(selector).forEach(tweetNode => {
replaceText(tweetNode);
});
});
}
// Initial replacement
replaceTextInTweets();
// Update every second
setInterval(replaceTextInTweets, 1000);
})();