Size
5.0 KB
Version
1.0.3
Created
Apr 7, 2026
Updated
10 days ago
1// ==UserScript==
2// @name Gmail Domain Sorter
3// @description Sort Gmail emails by sender domain name
4// @version 1.0.3
5// @match https://*.mail.google.com/*
6// @icon https://ssl.gstatic.com/ui/v1/icons/mail/rfr/gmail.ico
7// ==/UserScript==
8(function() {
9 'use strict';
10
11 // Add custom styles
12 TM_addStyle(`
13 .domain-sort-btn {
14 background: #0b57d0;
15 color: white;
16 border: none;
17 padding: 8px 16px;
18 border-radius: 18px;
19 cursor: pointer;
20 font-size: 14px;
21 font-weight: 500;
22 margin-left: 8px;
23 transition: background 0.2s, box-shadow 0.2s;
24 }
25
26 .domain-sort-btn:hover {
27 background: #0842a0;
28 box-shadow: 0 1px 3px rgba(0,0,0,0.2);
29 }
30
31 .domain-sort-btn:active {
32 background: #062d6e;
33 }
34
35 .domain-sort-btn.sorted {
36 background: #1a73e8;
37 }
38
39 .domain-indicator {
40 font-size: 10px;
41 color: #5f6368;
42 margin-left: 4px;
43 }
44 `);
45
46 let isSorted = false;
47 let originalOrder = [];
48
49 // Extract domain from email address
50 function extractDomain(email) {
51 if (!email) return '';
52 const match = email.match(/@([^\s>]+)/);
53 return match ? match[1].toLowerCase() : '';
54 }
55
56 // Get all email rows
57 function getEmailRows() {
58 return Array.from(document.querySelectorAll('div.zA'));
59 }
60
61 // Sort emails by domain
62 function sortEmails() {
63 const container = document.querySelector('div.Nr.UI.S2.vy div.Nu.tf.aZ6 > div > div.aDP');
64 if (!container) {
65 console.log('Container not found');
66 return;
67 }
68
69 const emailRows = getEmailRows();
70
71 if (emailRows.length === 0) {
72 console.log('No email rows found');
73 return;
74 }
75
76 // Store original order if not already stored
77 if (originalOrder.length === 0) {
78 originalOrder = [...emailRows];
79 }
80
81 if (isSorted) {
82 // Restore original order
83 originalOrder.forEach(row => {
84 container.appendChild(row);
85 });
86 isSorted = false;
87 updateButton();
88 console.log('Restored original order');
89 return;
90 }
91
92 // Sort by domain
93 const sortedRows = [...emailRows].sort((a, b) => {
94 const emailA = a.querySelector('span[data-hovercard-id]')?.getAttribute('data-hovercard-id') || '';
95 const emailB = b.querySelector('span[data-hovercard-id]')?.getAttribute('data-hovercard-id') || '';
96 const domainA = extractDomain(emailA);
97 const domainB = extractDomain(emailB);
98 return domainA.localeCompare(domainB);
99 });
100
101 // Re-append in sorted order
102 sortedRows.forEach(row => {
103 container.appendChild(row);
104 });
105
106 isSorted = true;
107 updateButton();
108 console.log('Sorted by domain');
109 }
110
111 // Update button state
112 function updateButton() {
113 const btn = document.querySelector('.domain-sort-btn');
114 if (btn) {
115 btn.textContent = isSorted ? 'Eredeti sorrend' : 'Domain szerinti rendezés';
116 btn.classList.toggle('sorted', isSorted);
117 }
118 }
119
120 // Create sort button
121 function createSortButton() {
122 // Check if button already exists
123 if (document.querySelector('.domain-sort-btn')) return;
124
125 // Find toolbar
126 const toolbar = document.querySelector('div.G-tF');
127 if (!toolbar) {
128 console.log('Toolbar not found');
129 return;
130 }
131
132 const btn = document.createElement('div');
133 btn.className = 'domain-sort-btn';
134 btn.setAttribute('role', 'button');
135 btn.setAttribute('tabindex', '0');
136 btn.textContent = 'Domain szerinti rendezés';
137 btn.onclick = sortEmails;
138
139 // Make it keyboard accessible
140 btn.onkeydown = (e) => {
141 if (e.key === 'Enter' || e.key === ' ') {
142 e.preventDefault();
143 sortEmails();
144 }
145 };
146
147 // Insert as first child of toolbar
148 toolbar.insertBefore(btn, toolbar.firstChild);
149 console.log('Sort button added');
150 }
151
152 // Initialize
153 function init() {
154 console.log('Gmail Domain Sorter initialized');
155
156 // Create button with delay to ensure Gmail is loaded
157 setTimeout(createSortButton, 1000);
158
159 // Observe DOM changes to re-add button if needed
160 const observer = new MutationObserver((mutations) => {
161 if (!document.querySelector('.domain-sort-btn')) {
162 createSortButton();
163 }
164 });
165
166 observer.observe(document.body, {
167 childList: true,
168 subtree: true
169 });
170 }
171
172 // Wait for Gmail to load
173 if (document.readyState === 'loading') {
174 document.addEventListener('DOMContentLoaded', init);
175 } else {
176 init();
177 }
178})();