Website Blocker

Block distracting websites with a customizable blocklist

Size

15.0 KB

Version

1.0.1

Created

Feb 2, 2026

Updated

15 days ago

1// ==UserScript==
2// @name		Website Blocker
3// @description		Block distracting websites with a customizable blocklist
4// @version		1.0.1
5// @match		*://*/*
6// @icon		https://robomonkey.io/favicon.ico
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    // Initialize the extension
12    async function init() {
13        console.log('Website Blocker extension loaded');
14        
15        // Check if current site is blocked
16        await checkAndBlockSite();
17        
18        // Add settings button to page
19        addSettingsButton();
20    }
21
22    // Check if the current website should be blocked
23    async function checkAndBlockSite() {
24        const currentUrl = window.location.hostname;
25        console.log('Checking if site is blocked:', currentUrl);
26        
27        // Get blocked sites list from storage
28        const blockedSites = await getBlockedSites();
29        
30        // Check if current site matches any blocked site
31        const isBlocked = blockedSites.some(site => {
32            // Remove protocol and www if present
33            const cleanSite = site.replace(/^(https?:\/\/)?(www\.)?/, '').toLowerCase();
34            const cleanCurrent = currentUrl.replace(/^www\./, '').toLowerCase();
35            
36            // Check if current site contains the blocked site
37            return cleanCurrent.includes(cleanSite) || cleanCurrent === cleanSite;
38        });
39        
40        if (isBlocked) {
41            console.log('Site is blocked, showing block page');
42            showBlockPage();
43        }
44    }
45
46    // Get blocked sites from storage
47    async function getBlockedSites() {
48        const sites = await GM.getValue('blockedSites', '[]');
49        return JSON.parse(sites);
50    }
51
52    // Save blocked sites to storage
53    async function saveBlockedSites(sites) {
54        await GM.setValue('blockedSites', JSON.stringify(sites));
55    }
56
57    // Show block page
58    function showBlockPage() {
59        // Clear the page
60        document.documentElement.innerHTML = '';
61        
62        // Create block page
63        const blockPage = document.createElement('div');
64        blockPage.style.cssText = `
65            position: fixed;
66            top: 0;
67            left: 0;
68            width: 100%;
69            height: 100%;
70            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
71            display: flex;
72            flex-direction: column;
73            justify-content: center;
74            align-items: center;
75            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
76            z-index: 999999;
77        `;
78        
79        blockPage.innerHTML = `
80            <div style="text-align: center; color: white; max-width: 600px; padding: 40px;">
81                <div style="font-size: 80px; margin-bottom: 20px;">🚫</div>
82                <h1 style="font-size: 48px; margin: 0 0 20px 0; font-weight: 700;">Site Blocked</h1>
83                <p style="font-size: 20px; margin: 0 0 30px 0; opacity: 0.9;">
84                    This website is on your block list. Stay focused!
85                </p>
86                <div style="font-size: 16px; margin-bottom: 30px; opacity: 0.8;">
87                    <strong>${window.location.hostname}</strong>
88                </div>
89                <button id="unblock-btn" style="
90                    background: rgba(255, 255, 255, 0.2);
91                    border: 2px solid white;
92                    color: white;
93                    padding: 12px 30px;
94                    font-size: 16px;
95                    border-radius: 8px;
96                    cursor: pointer;
97                    font-weight: 600;
98                    transition: all 0.3s ease;
99                    margin-right: 10px;
100                ">Manage Blocked Sites</button>
101                <button id="go-back-btn" style="
102                    background: white;
103                    border: 2px solid white;
104                    color: #667eea;
105                    padding: 12px 30px;
106                    font-size: 16px;
107                    border-radius: 8px;
108                    cursor: pointer;
109                    font-weight: 600;
110                    transition: all 0.3s ease;
111                ">Go Back</button>
112            </div>
113        `;
114        
115        document.documentElement.appendChild(blockPage);
116        
117        // Add hover effects
118        const unblockBtn = blockPage.querySelector('#unblock-btn');
119        const goBackBtn = blockPage.querySelector('#go-back-btn');
120        
121        unblockBtn.addEventListener('mouseenter', () => {
122            unblockBtn.style.background = 'rgba(255, 255, 255, 0.3)';
123            unblockBtn.style.transform = 'translateY(-2px)';
124        });
125        unblockBtn.addEventListener('mouseleave', () => {
126            unblockBtn.style.background = 'rgba(255, 255, 255, 0.2)';
127            unblockBtn.style.transform = 'translateY(0)';
128        });
129        
130        goBackBtn.addEventListener('mouseenter', () => {
131            goBackBtn.style.background = '#f0f0f0';
132            goBackBtn.style.transform = 'translateY(-2px)';
133        });
134        goBackBtn.addEventListener('mouseleave', () => {
135            goBackBtn.style.background = 'white';
136            goBackBtn.style.transform = 'translateY(0)';
137        });
138        
139        // Add event listeners
140        unblockBtn.addEventListener('click', () => {
141            showSettingsModal();
142        });
143        
144        goBackBtn.addEventListener('click', () => {
145            window.history.back();
146        });
147    }
148
149    // Add settings button to page
150    function addSettingsButton() {
151        const settingsBtn = document.createElement('button');
152        settingsBtn.id = 'website-blocker-settings-btn';
153        settingsBtn.innerHTML = '🚫';
154        settingsBtn.title = 'Website Blocker Settings';
155        settingsBtn.style.cssText = `
156            position: fixed;
157            bottom: 20px;
158            right: 20px;
159            width: 56px;
160            height: 56px;
161            border-radius: 50%;
162            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
163            border: none;
164            color: white;
165            font-size: 24px;
166            cursor: pointer;
167            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
168            z-index: 999998;
169            transition: all 0.3s ease;
170            display: flex;
171            align-items: center;
172            justify-content: center;
173        `;
174        
175        settingsBtn.addEventListener('mouseenter', () => {
176            settingsBtn.style.transform = 'scale(1.1)';
177            settingsBtn.style.boxShadow = '0 6px 16px rgba(0, 0, 0, 0.2)';
178        });
179        
180        settingsBtn.addEventListener('mouseleave', () => {
181            settingsBtn.style.transform = 'scale(1)';
182            settingsBtn.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15)';
183        });
184        
185        settingsBtn.addEventListener('click', () => {
186            showSettingsModal();
187        });
188        
189        document.body.appendChild(settingsBtn);
190    }
191
192    // Show settings modal
193    async function showSettingsModal() {
194        // Remove existing modal if any
195        const existingModal = document.getElementById('website-blocker-modal');
196        if (existingModal) {
197            existingModal.remove();
198        }
199        
200        const blockedSites = await getBlockedSites();
201        
202        const modal = document.createElement('div');
203        modal.id = 'website-blocker-modal';
204        modal.style.cssText = `
205            position: fixed;
206            top: 0;
207            left: 0;
208            width: 100%;
209            height: 100%;
210            background: rgba(0, 0, 0, 0.7);
211            display: flex;
212            justify-content: center;
213            align-items: center;
214            z-index: 999999;
215            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
216        `;
217        
218        const modalContent = document.createElement('div');
219        modalContent.style.cssText = `
220            background: white;
221            border-radius: 12px;
222            padding: 30px;
223            max-width: 500px;
224            width: 90%;
225            max-height: 80vh;
226            overflow-y: auto;
227            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
228        `;
229        
230        modalContent.innerHTML = `
231            <h2 style="margin: 0 0 20px 0; color: #333; font-size: 24px; font-weight: 700;">Website Blocker Settings</h2>
232            
233            <div style="margin-bottom: 20px;">
234                <label style="display: block; margin-bottom: 8px; color: #555; font-weight: 600;">Add Website to Block:</label>
235                <div style="display: flex; gap: 10px;">
236                    <input type="text" id="new-site-input" placeholder="example.com" style="
237                        flex: 1;
238                        padding: 10px 15px;
239                        border: 2px solid #e0e0e0;
240                        border-radius: 8px;
241                        font-size: 14px;
242                        outline: none;
243                        transition: border-color 0.3s ease;
244                    ">
245                    <button id="add-site-btn" style="
246                        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
247                        color: white;
248                        border: none;
249                        padding: 10px 20px;
250                        border-radius: 8px;
251                        cursor: pointer;
252                        font-weight: 600;
253                        font-size: 14px;
254                        transition: all 0.3s ease;
255                    ">Add</button>
256                </div>
257            </div>
258            
259            <div style="margin-bottom: 20px;">
260                <h3 style="margin: 0 0 15px 0; color: #333; font-size: 18px; font-weight: 600;">Blocked Websites:</h3>
261                <div id="blocked-sites-list" style="
262                    max-height: 300px;
263                    overflow-y: auto;
264                ">
265                    ${blockedSites.length === 0 ? 
266                        '<p style="color: #999; text-align: center; padding: 20px;">No websites blocked yet</p>' :
267                        blockedSites.map((site, index) => `
268                            <div class="blocked-site-item" data-index="${index}" style="
269                                display: flex;
270                                justify-content: space-between;
271                                align-items: center;
272                                padding: 12px 15px;
273                                background: #f8f9fa;
274                                border-radius: 8px;
275                                margin-bottom: 8px;
276                            ">
277                                <span style="color: #333; font-size: 14px;">${site}</span>
278                                <button class="remove-site-btn" data-site="${site}" style="
279                                    background: #ff4757;
280                                    color: white;
281                                    border: none;
282                                    padding: 6px 12px;
283                                    border-radius: 6px;
284                                    cursor: pointer;
285                                    font-size: 12px;
286                                    font-weight: 600;
287                                    transition: all 0.3s ease;
288                                ">Remove</button>
289                            </div>
290                        `).join('')
291                    }
292                </div>
293            </div>
294            
295            <div style="display: flex; justify-content: flex-end; gap: 10px;">
296                <button id="close-modal-btn" style="
297                    background: #e0e0e0;
298                    color: #333;
299                    border: none;
300                    padding: 10px 20px;
301                    border-radius: 8px;
302                    cursor: pointer;
303                    font-weight: 600;
304                    font-size: 14px;
305                    transition: all 0.3s ease;
306                ">Close</button>
307            </div>
308        `;
309        
310        modal.appendChild(modalContent);
311        document.body.appendChild(modal);
312        
313        // Add input focus effect
314        const input = modal.querySelector('#new-site-input');
315        input.addEventListener('focus', () => {
316            input.style.borderColor = '#667eea';
317        });
318        input.addEventListener('blur', () => {
319            input.style.borderColor = '#e0e0e0';
320        });
321        
322        // Add site button
323        const addBtn = modal.querySelector('#add-site-btn');
324        addBtn.addEventListener('mouseenter', () => {
325            addBtn.style.transform = 'translateY(-2px)';
326            addBtn.style.boxShadow = '0 4px 12px rgba(102, 126, 234, 0.4)';
327        });
328        addBtn.addEventListener('mouseleave', () => {
329            addBtn.style.transform = 'translateY(0)';
330            addBtn.style.boxShadow = 'none';
331        });
332        
333        addBtn.addEventListener('click', async () => {
334            const newSite = input.value.trim();
335            if (newSite) {
336                const sites = await getBlockedSites();
337                if (!sites.includes(newSite)) {
338                    sites.push(newSite);
339                    await saveBlockedSites(sites);
340                    input.value = '';
341                    showSettingsModal(); // Refresh modal
342                    console.log('Added site to block list:', newSite);
343                }
344            }
345        });
346        
347        // Allow Enter key to add site
348        input.addEventListener('keypress', (e) => {
349            if (e.key === 'Enter') {
350                addBtn.click();
351            }
352        });
353        
354        // Remove site buttons
355        const removeButtons = modal.querySelectorAll('.remove-site-btn');
356        removeButtons.forEach(btn => {
357            btn.addEventListener('mouseenter', () => {
358                btn.style.background = '#ee5a6f';
359                btn.style.transform = 'translateY(-2px)';
360            });
361            btn.addEventListener('mouseleave', () => {
362                btn.style.background = '#ff4757';
363                btn.style.transform = 'translateY(0)';
364            });
365            
366            btn.addEventListener('click', async () => {
367                const siteToRemove = btn.dataset.site;
368                const sites = await getBlockedSites();
369                const updatedSites = sites.filter(site => site !== siteToRemove);
370                await saveBlockedSites(updatedSites);
371                showSettingsModal(); // Refresh modal
372                console.log('Removed site from block list:', siteToRemove);
373            });
374        });
375        
376        // Close button
377        const closeBtn = modal.querySelector('#close-modal-btn');
378        closeBtn.addEventListener('mouseenter', () => {
379            closeBtn.style.background = '#d0d0d0';
380        });
381        closeBtn.addEventListener('mouseleave', () => {
382            closeBtn.style.background = '#e0e0e0';
383        });
384        
385        closeBtn.addEventListener('click', () => {
386            modal.remove();
387        });
388        
389        // Close on background click
390        modal.addEventListener('click', (e) => {
391            if (e.target === modal) {
392                modal.remove();
393            }
394        });
395    }
396
397    // Start the extension
398    init();
399})();
Website Blocker | Robomonkey