// ==UserScript==
// @name Gmail Sender Shield
// @name:es Gmail Escudo de Correos
// @namespace http://tampermonkey.net/
// @version 1.6
// @description Gmail Sender Shield enhances your Gmail experience by displaying sender domains and icons for quick identification and offering tools to highlight untrusted emails.
// @description:es Gmail Escudo de Correos mejora tu experiencia en Gmail mostrando los dominios e íconos de los remitentes para una identificación rápida y ofreciendo herramientas para resaltar correos no confiables.
// @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) => {
refreshAllowedDomains();
updateAllDomainStates();
console.log('Mensaje recibido:', event.data);
};
if (!addIcon && !addDomain && !hasDomains) return;
const processedElements = new Set();
function refreshAllowedDomains() {
allowedCommonDomains = GM_getValue('allowedDomains', []);
allowedUserDomains = GM_getValue('allowedUserDomains', {});
userDomains = allowedUserDomains[userId] || [];
allowedDomains = allowedCommonDomains.concat(userDomains);
}
function addDomainContainer(element, email) {
const domain = extractDomain(email);
const domainContainer = document.createElement('div');
domainContainer.className = 'domain-container';
domainContainer.onclick = () => domainContainerEvent(domainContainer, email);
updateDomainState(domainContainer, email);
addIconToContainer(domainContainer, domain);
addDomainToContainer(domainContainer, domain);
element.appendChild(domainContainer);
return domainContainer;
}
function updateDomainState(container, email) {
const domain = extractDomain(email);
container.classList.remove('not-allowed-domain', 'allowed-domain');
if (allowedDomains.includes(email) || allowedDomains.includes(domain)) {
container.classList.add('allowed-domain');
} else {
container.classList.add('not-allowed-domain');
}
}
function domainContainerEvent(domainContainer, email) {
event.preventDefault();
event.stopPropagation();
const domain = extractDomain(email);
let message;
if (userDomains.includes(domain)) {
userDomains.splice(userDomains.indexOf(domain), 1);
allowedCommonDomains.push(domain);
message = `+ Empresa (Todas las cuentas)`;
} else if (allowedCommonDomains.includes(domain)) {
allowedCommonDomains.splice(allowedCommonDomains.indexOf(domain), 1);
userDomains.push(email);
message = `+ Correo (Esta cuenta)`;
} else if (userDomains.includes(email)) {
userDomains.splice(userDomains.indexOf(email), 1);
allowedCommonDomains.push(email);
message = `+ Correo (Todas las cuentas)`;
} else if (allowedCommonDomains.includes(email)) {
allowedCommonDomains.splice(allowedCommonDomains.indexOf(email), 1);
message = `Eliminado`;
} else {
userDomains.push(domain);
message = `+ Empresa (Esta cuenta)`;
}
allowedUserDomains[userId] = userDomains;
GM_setValue('allowedUserDomains', allowedUserDomains);
GM_setValue('allowedDomains', allowedCommonDomains);
refreshAllowedDomains();
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, email);
} else {
addDomainContainer(element, email);
}
});
}
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);
}
}, 3000);
}
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;
}
.domain-container:hover {
background-color: #b1b1b1;
}
.domain-container.not-allowed-domain:hover {
background-color: #e5afaf;
}
`;
}
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;
color: inherit; /* Hereda el color del contenedor */
}
`;
}
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;
}
.custom-tooltip:has(+ .custom-tooltip) {
display: none;
}
.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, email);
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();
});
})();