// ==UserScript==
// @name Gmail Sender Icons
// @name:es Gmail Iconos de Remitente
// @namespace http://tampermonkey.net/
// @version 1.5
// @description Quickly identify the sender of email messages in Gmail without opening the message. Now marks emails in red if the domain is not allowed, and applies changes to all Gmail tabs.
// @description:es Identifica rápidamente al remitente de los mensajes de correo en Gmail sin abrir el mensaje. Ahora marca los correos en rojo si el dominio no está permitido y aplica cambios a todas las pestañas de Gmail.
// @author IgnaV
// @match https://mail.google.com/*
// @icon https://ssl.gstatic.com/ui/v1/icons/mail/rfr/gmail.ico
// @license MIT
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
(function() {
'use strict';
if (window.self !== window.top) return;
const userId = window.location.href.match(/\/u\/(\d+)\//)[1];
const addIcon = GM_getValue('addIcon', true);
const addDomain = GM_getValue('addDomain', true);
let allowedCommonDomains = GM_getValue('allowedDomains', []);
let allowedUserDomains = GM_getValue('allowedUserDomains', {});
let userDomains = allowedUserDomains[userId] || [];
allowedUserDomains[userId] = userDomains;
GM_setValue('addIcon', addIcon);
GM_setValue('addDomain', addDomain);
GM_setValue('allowedUserDomains', allowedUserDomains);
let allowedDomains = allowedCommonDomains.concat(userDomains);
const hasDomains = allowedDomains.length !== 0;
const channel = new BroadcastChannel('mi-canal');
channel.onmessage = (event) => {
allowedCommonDomains = GM_getValue('allowedDomains', []);
allowedUserDomains = GM_getValue('allowedUserDomains', {});
allowedDomains = allowedCommonDomains.concat(userDomains);
updateAllDomainStates();
console.log('Mensaje recibido:', event.data);
};
if (!addIcon && !addDomain && !hasDomains) return;
const processedElements = new Set();
function addDomainContainer(element, domain) {
const domainContainer = document.createElement('div');
domainContainer.className = 'domain-container';
domainContainer.onclick = () => domainContainerEvent(domainContainer, domain);
updateDomainState(domainContainer, domain, userDomains, allowedCommonDomains);
addIconToContainer(domainContainer, domain);
addDomainToContainer(domainContainer, domain);
element.appendChild(domainContainer);
return domainContainer;
}
function updateDomainState(container, domain, userDomains, globalDomains) {
container.classList.remove('not-allowed-domain', 'allowed-domain');
if (userDomains.includes(domain) || globalDomains.includes(domain)) {
container.classList.add('allowed-domain');
} else {
container.classList.add('not-allowed-domain');
}
}
function domainContainerEvent(domainContainer, domain) {
event.preventDefault();
event.stopPropagation();
let message;
if (userDomains.includes(domain)) {
userDomains.splice(userDomains.indexOf(domain), 1);
allowedCommonDomains.push(domain);
message = 'Añadido a global';
} else if (allowedCommonDomains.includes(domain)) {
allowedCommonDomains.splice(allowedCommonDomains.indexOf(domain), 1);
message = 'Eliminado';
} else {
userDomains.push(domain);
message = 'Añadido a personal';
}
allowedUserDomains[userId] = userDomains;
GM_setValue('allowedUserDomains', allowedUserDomains);
GM_setValue('allowedDomains', allowedCommonDomains);
updateAllDomainStates();
showTooltip(domainContainer, message);
setTimeout(() => channel.postMessage(message), 200);
};
function updateAllDomainStates() {
const nameElements = document.querySelectorAll('.bA4, .bAK, .bAp');
nameElements.forEach((element) => {
const emailElement = element.querySelector('[email]');
if (!emailElement) return;
const email = emailElement.getAttribute('email');
const domain = extractDomain(email);
const domainContainer = element.querySelector('.domain-container');
if (domainContainer) {
updateDomainState(domainContainer, domain, userDomains, allowedCommonDomains);
} else {
addDomainContainer(element, domain);
}
});
}
function showTooltip(element, message) {
const tooltip = document.createElement('span');
tooltip.className = 'custom-tooltip';
tooltip.textContent = message;
element.appendChild(tooltip);
setTimeout(() => {
if (element.contains(tooltip)) {
element.removeChild(tooltip);
}
}, 2000);
}
function addIconToContainer(domainContainer, domain) {
const icon = document.createElement('img');
icon.src = `https://www.google.com/s2/favicons?domain=${domain}`;
icon.className = 'domain-icon';
domainContainer.appendChild(icon);
}
function addDomainToContainer(domainContainer, domain) {
const domainSpan = document.createElement('span');
domainSpan.className = 'domain-text';
domainSpan.textContent = domain;
domainContainer.appendChild(domainSpan);
}
function addStyles(addIcon, addDomain, hasDomains) {
const style = document.createElement('style');
style.type = 'text/css';
let css = ``;
if (addIcon || addDomain) {
css += `
.bA4, .bAK, .bAp {
padding-top: 9px;
}
.domain-container {
display: flex;
align-items: center;
margin-top: -4px;
font-size: 10px;
color: #888;
width: fit-content;
height: 11px;
padding: 1px 2px;
}
`;
}
if (addIcon) {
css += `
.domain-icon {
width: 10px;
height: 10px;
margin-right: 3px;
}
`;
}
if (addDomain) {
css += `
.domain-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 10px;
color: #888;
}
`;
}
if (hasDomains) {
css += `
.not-allowed-domain {
background-color: #f8d7da;
color: #721c24;
}
.allowed-domain {
background-color: transparent;
color: inherit;
}
.custom-tooltip {
position: absolute;
background-color: #000;
color: #fff;
padding: 4px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
z-index: 1000;
top: 40px;
opacity: 0;
transition: opacity 0.3s ease-in-out;
}
.domain-container:hover .custom-tooltip {
opacity: 1;
}
`;
}
style.appendChild(document.createTextNode(css));
document.head.appendChild(style);
}
addStyles(addIcon, addDomain, hasDomains);
function addDomainBelowName() {
const nameElements = document.querySelectorAll('.bA4, .bAK, .bAp');
nameElements.forEach((element) => {
if (processedElements.has(element)) return;
const emailElement = element.querySelector('[email]');
if (!emailElement) return;
const email = emailElement.getAttribute('email');
const domain = extractDomain(email);
const domainElement = addDomainContainer(element, domain);
processedElements.add(element);
});
}
function extractDomain(email) {
const domainParts = email.split('@')[1].split('.');
if (domainParts[domainParts.length - 2] === 'com') {
return domainParts.slice(-3).join('.');
}
return domainParts.slice(-2).join('.');
}
const observer = new MutationObserver((mutations) => {
mutations.forEach(() => {
addDomainBelowName();
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
window.addEventListener('load', () => {
addDomainBelowName();
});
})();