// ==UserScript== // @name 8chan.moe Bigger Deletion Checkbox with Toggle // @namespace Violentmonkey Scripts // @match https://8chan.moe/mod.js?boardUri=*&threadId=* // @match https://8chan.moe/*/res/* // @grant none // @version 1.4 // @author Anonymous // @license MIT // @description Adds a larger checkbox to the right of each post's deletion checkbox on 8chan.moe mod.js and thread pages, hidden by default with a toggle button in the OP title bar. // @downloadURL none // ==/UserScript== (function() { 'use strict'; // Track toggle state (hidden by default) let areLargeCheckboxesVisible = false; // Function to add a larger checkbox to a post function addLargeCheckbox(post) { const deletionCheckbox = post.querySelector('input.deletionCheckBox'); if (!deletionCheckbox) return; // Skip if no deletion checkbox found // Find the postInfo or opHead div to append the new checkbox const postInfo = post.querySelector('.postInfo.title, .opHead.title'); if (!postInfo) return; // Create a container for the large checkbox const largeCheckboxContainer = document.createElement('span'); largeCheckboxContainer.className = 'large-checkbox-container'; largeCheckboxContainer.style.marginLeft = '12px'; // Spacing for larger checkbox largeCheckboxContainer.style.display = areLargeCheckboxesVisible ? 'inline-block' : 'none'; largeCheckboxContainer.style.verticalAlign = 'middle'; // Create the large checkbox const largeCheckbox = document.createElement('input'); largeCheckbox.type = 'checkbox'; largeCheckbox.style.width = '48px'; // 2x larger (24px * 2 = 48px) largeCheckbox.style.height = '48px'; largeCheckbox.style.border = '4px solid black'; // Thicker border largeCheckbox.style.cursor = 'pointer'; // Sync the large checkbox with the original largeCheckbox.checked = deletionCheckbox.checked; largeCheckbox.addEventListener('change', () => { deletionCheckbox.checked = largeCheckbox.checked; // Trigger change event on original checkbox to ensure form functionality const event = new Event('change', { bubbles: true }); deletionCheckbox.dispatchEvent(event); }); // Sync the original checkbox with the large one deletionCheckbox.addEventListener('change', () => { largeCheckbox.checked = deletionCheckbox.checked; }); // Append the large checkbox to the container largeCheckboxContainer.appendChild(largeCheckbox); // Append the container to the postInfo div postInfo.appendChild(largeCheckboxContainer); } // Function to add toggle button to OP post function addToggleButton() { const opPost = document.querySelector('.innerOP'); if (!opPost) { console.log('No .innerOP found for toggle button'); return; } const opTitle = opPost.querySelector('.opHead.title, .postInfo.title'); if (!opTitle) { console.log('No .opHead.title or .postInfo.title found in .innerOP'); return; } // Remove existing toggle button to prevent duplicates const existingButton = opTitle.querySelector('.toggle-checkboxes-button'); if (existingButton) { existingButton.remove(); } // Create toggle button const toggleButton = document.createElement('button'); toggleButton.type = 'button'; // Prevent form submission toggleButton.className = 'toggle-checkboxes-button glowOnHover'; toggleButton.textContent = areLargeCheckboxesVisible ? 'Hide Big Checkboxes' : 'Show Big Checkboxes'; toggleButton.style.cursor = 'pointer'; toggleButton.style.marginLeft = '10px'; toggleButton.style.padding = '2px 6px'; toggleButton.style.border = '1px solid #ccc'; toggleButton.style.backgroundColor = areLargeCheckboxesVisible ? '#e0e0e0' : '#f0f0f0'; toggleButton.style.borderRadius = '3px'; toggleButton.style.verticalAlign = 'middle'; toggleButton.style.fontSize = '12px'; // Toggle functionality toggleButton.addEventListener('click', (event) => { event.preventDefault(); // Prevent any default behavior event.stopPropagation(); // Prevent bubbling to parent elements areLargeCheckboxesVisible = !areLargeCheckboxesVisible; const containers = document.querySelectorAll('.large-checkbox-container'); containers.forEach(container => { container.style.display = areLargeCheckboxesVisible ? 'inline-block' : 'none'; }); toggleButton.textContent = areLargeCheckboxesVisible ? 'Hide Big Checkboxes' : 'Show Big Checkboxes'; toggleButton.style.backgroundColor = areLargeCheckboxesVisible ? '#e0e0e0' : '#f0f0f0'; }); // Append button to OP title bar opTitle.appendChild(toggleButton); console.log('Toggle button added to OP title bar'); } // Process all posts (OP and replies) function processPosts() { // Handle OP const opPost = document.querySelector('.innerOP'); if (opPost) { addLargeCheckbox(opPost); } // Handle replies const replyPosts = document.querySelectorAll('.innerPost'); replyPosts.forEach(post => { addLargeCheckbox(post); }); } // Initial processing processPosts(); addToggleButton(); // Observe for dynamically added posts (e.g., via auto-refresh or new replies) const observer = new MutationObserver((mutations) => { mutations.forEach(mutation => { if (mutation.addedNodes.length) { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { // Check if the added node is a post if (node.classList.contains('innerPost') || node.classList.contains('innerOP')) { addLargeCheckbox(node); // Add toggle button if OP is added dynamically if (node.classList.contains('innerOP')) { addToggleButton(); } } // Check for posts within the added node node.querySelectorAll('.innerPost, .innerOP').forEach(post => { addLargeCheckbox(post); // Add toggle button if OP is found if (post.classList.contains('innerOP')) { addToggleButton(); } }); } }); } }); }); // Observe changes in the thread list const threadList = document.getElementById('threadList'); if (threadList) { observer.observe(threadList, { childList: true, subtree: true }); } else { console.log('No #threadList found for MutationObserver'); } })();