Create a stylish, draggable search form with persistent inputs, paste buttons, and a copy dynamic link button for Google search r###lts. The form retains user-given values and is initially positioned on the right side but can be moved anywhere. Includes a copy dynamic link button that copies the first available link from specified classes. Now with smaller text size, larger checkboxes, and aligned buttons.
// ==UserScript== // @name Draggable Google Search Tool with Copy Link // @namespace http://tampermonkey.net/ // @version 1.27 // @description Create a stylish, draggable search form with persistent inputs, paste buttons, and a copy dynamic link button for Google search r###lts. The form retains user-given values and is initially positioned on the right side but can be moved anywhere. Includes a copy dynamic link button that copies the first available link from specified classes. Now with smaller text size, larger checkboxes, and aligned buttons. // @author Mahmudul Hasan Shawon // @match https://www.google.com/search?* // @license MIT // @grant none // ==/UserScript== (function() { 'use strict'; // Load Inter font const interFontLink = document.createElement('link'); interFontLink.href = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap'; interFontLink.rel = 'stylesheet'; document.head.appendChild(interFontLink); // Default values const defaultInput1Value = 'Company Name'; const defaultInput2Value = 'City,State'; const defaultInput3Value = 'Headquarter'; // Retrieve stored values or use default const storedInput1Value = localStorage.getItem('input1') || defaultInput1Value; const storedInput2Value = localStorage.getItem('input2') || defaultInput2Value; const storedInput3Value = localStorage.getItem('input3') || defaultInput3Value; // Create a container for the form const formContainer = document.createElement('div'); formContainer.style.position = 'fixed'; formContainer.style.top = '10px'; formContainer.style.right = '20px'; // Positioning to the right side formContainer.style.padding = '10px'; formContainer.style.backgroundColor = '#d8d3ff'; //formContainer.style.backdropFilter = 'blur(10px)'; //formContainer.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'; // Optional for semi-transparent background formContainer.style.border = '2px solid #ffff'; formContainer.style.borderRadius = '16px'; formContainer.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.1)'; formContainer.style.zIndex = '10000'; formContainer.style.fontFamily = "'Inter', sans-serif"; formContainer.style.cursor = 'move'; formContainer.style.maxWidth = '300px'; // Adjusted width for right-side positioning formContainer.style.boxSizing = 'border-box'; // Create the form element const form = document.createElement('form'); form.style.display = 'flex'; form.style.flexDirection = 'column'; form.style.gap = '8px'; // Adjusted gap // Function to create input field with paste button and optional checkbox const createInputFieldWithExtras = (id, value, includeCheckbox = false) => { const inputWrapper = document.createElement('div'); inputWrapper.style.position = 'relative'; inputWrapper.style.display = 'flex'; inputWrapper.style.alignItems = 'center'; inputWrapper.style.gap = '8px'; // Adjusted gap const input = document.createElement('input'); input.type = 'text'; input.value = value; input.id = id; input.style.padding = '8px'; // Adjusted padding input.style.border = '0px solid #ffffff'; input.style.borderRadius = '8px'; // Adjusted border radius input.style.fontFamily = "'Inter', sans-serif"; input.style.fontSize = '12px'; // Adjusted font size //input.style.backgroundColor = '#ffffff'; input.style.backdropFilter = 'blur(10px)'; input.style.backgroundColor = 'rgba(255, 255, 255, 0.4)'; // Optional for semi-transparent background input.style.boxShadow = '0 1px 3px rgba(0, 0, 0, 0.1)'; // Adjusted shadow input.style.color = '#000000'; // Add event listener to save to localStorage on change input.addEventListener('input', () => { localStorage.setItem(id, input.value.trim()); }); inputWrapper.appendChild(input); const pasteButton = document.createElement('button'); pasteButton.type = 'button'; pasteButton.innerText = '📝'; pasteButton.style.padding = '8px 8px'; // Adjusted padding pasteButton.style.border = 'none'; //pasteButton.style.backgroundColor = '#7469B6'; pasteButton.style.backdropFilter = 'blur(10px)'; pasteButton.style.backgroundColor = 'rgba(255, 255, 255, 0.4)'; // Optional for semi-transparent background pasteButton.style.color = '#fff'; pasteButton.style.borderRadius = '8px'; // Adjusted border radius pasteButton.style.cursor = 'pointer'; pasteButton.style.fontFamily = "'Inter', sans-serif"; pasteButton.style.fontSize = '12px'; // Adjusted font size pasteButton.addEventListener('click', async () => { input.value = await navigator.clipboard.readText(); localStorage.setItem(id, input.value.trim()); // Save updated value to localStorage }); inputWrapper.appendChild(pasteButton); if (includeCheckbox) { const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.id = `checkbox-${id}`; checkbox.style.width = '20px'; // Adjusted width checkbox.style.height = '20px'; // Adjusted height checkbox.style.marginLeft = '8px'; // Adjusted margin checkbox.style.cursor = 'pointer'; checkbox.style.border = '0px solid #cccccc'; // Optional: Border for visibility checkbox.style.borderRadius = '12px'; checkbox.style.appearance = 'none'; // Remove default checkbox styles checkbox.style.backgroundColor = '#ffffff'; // Default to white checkbox.style.display = 'inline-block'; // Change background color when selected checkbox.addEventListener('change', () => { checkbox.style.backgroundColor = checkbox.checked ? '#0ad400' : '#ffffff'; // Green when checked, white otherwise }); inputWrapper.appendChild(checkbox); } return inputWrapper; }; // Create the input fields const input1 = createInputFieldWithExtras('input1', storedInput1Value, false); const input2 = createInputFieldWithExtras('input2', storedInput2Value, true); const input3 = createInputFieldWithExtras('input3', storedInput3Value, true); // Create a container for the buttons const buttonContainer = document.createElement('div'); buttonContainer.style.display = 'flex'; buttonContainer.style.justifyContent = 'space-between'; // Align buttons to the edges buttonContainer.style.alignItems = 'center'; // Align items vertically buttonContainer.style.gap = '8px'; // Adjusted gap // Create the copy dynamic link button const copyLinkButton = document.createElement('button'); copyLinkButton.type = 'button'; copyLinkButton.innerText = 'Copy Link'; copyLinkButton.style.padding = '8px'; // Adjusted padding copyLinkButton.style.width = '48%'; copyLinkButton.style.backgroundColor = '#8700ff'; copyLinkButton.style.color = '#fff'; copyLinkButton.style.border = 'none'; copyLinkButton.style.borderRadius = '60px'; // Adjusted border radius copyLinkButton.style.cursor = 'pointer'; copyLinkButton.style.fontSize = '12px'; // Adjusted font size copyLinkButton.style.fontWeight = 'bold'; copyLinkButton.style.fontFamily = "'Inter', sans-serif"; copyLinkButton.addEventListener('click', async () => { const link = getFirstAvailableLink(); if (link) { await copyToClipboard(link); } else { showCustomAlert('No link available to copy.'); } }); // Create the search button const searchButton = document.createElement('button'); searchButton.type = 'button'; searchButton.innerText = 'Search'; searchButton.style.padding = '8px'; // Adjusted padding searchButton.style.width = '48%'; searchButton.style.backgroundColor = '#000000'; searchButton.style.color = '#fff'; searchButton.style.border = 'none'; searchButton.style.borderRadius = '60px'; // Adjusted border radius searchButton.style.cursor = 'pointer'; searchButton.style.fontSize = '12px'; // Adjusted font size searchButton.style.fontWeight = 'bold'; searchButton.style.fontFamily = "'Inter', sans-serif"; searchButton.style.marginLeft = 'auto'; // Push search button to the right searchButton.addEventListener('click', () => { let query = input1.querySelector('input').value.trim(); const checkbox2 = document.getElementById(`checkbox-input2`); const checkbox3 = document.getElementById(`checkbox-input3`); if (checkbox2.checked) query += ` ${input2.querySelector('input').value.trim()}`; if (checkbox3.checked) query += ` ${input3.querySelector('input').value.trim()}`; const searchUrl = `https://www.google.com/search?q=${encodeURIComponent(query)}`; window.location.href = searchUrl; // Save values to localStorage localStorage.setItem('input1', input1.querySelector('input').value.trim()); localStorage.setItem('input2', input2.querySelector('input').value.trim()); localStorage.setItem('input3', input3.querySelector('input').value.trim()); }); // Append buttons to the button container buttonContainer.appendChild(copyLinkButton); buttonContainer.appendChild(searchButton); // Append input fields and button container to the form form.appendChild(input1); form.appendChild(input2); form.appendChild(input3); form.appendChild(buttonContainer); // Append form to the container formContainer.appendChild(form); // Append form container to the body document.body.appendChild(formContainer); // Function to show custom alerts const showCustomAlert = (message) => { const alertBox = document.createElement('div'); alertBox.textContent = message; alertBox.style.position = 'fixed'; alertBox.style.bottom = '680px'; alertBox.style.right = '20px'; alertBox.style.padding = '10px'; alertBox.style.backgroundColor = '#ff0000'; alertBox.style.color = '#fff'; alertBox.style.borderRadius = '5px'; alertBox.style.boxShadow = '0 2px 4px rgba(0, 0, 0, 0.2)'; alertBox.style.zIndex = '10001'; alertBox.style.fontFamily = "'Inter', sans-serif"; alertBox.style.opacity = '1'; alertBox.style.transition = 'opacity 0.5s ease'; // Smooth transition document.body.appendChild(alertBox); setTimeout(() => { alertBox.style.opacity = '0'; setTimeout(() => alertBox.remove(), 500); // Delay removal until fade-out completes }, 1000); }; // Draggable functionality formContainer.addEventListener('mousedown', (e) => { if (e.target === formContainer) { let offsetX = e.clientX - formContainer.getBoundingClientRect().left; let offsetY = e.clientY - formContainer.getBoundingClientRect().top; const mouseMoveHandler = (e) => { formContainer.style.left = `${e.clientX - offsetX}px`; formContainer.style.top = `${e.clientY - offsetY}px`; }; const mouseUpHandler = () => { document.removeEventListener('mousemove', mouseMoveHandler); document.removeEventListener('mouseup', mouseUpHandler); }; document.addEventListener('mousemove', mouseMoveHandler); document.addEventListener('mouseup', mouseUpHandler); } }); // Function to copy text to clipboard const copyToClipboard = async (text) => { try { await navigator.clipboard.writeText(text); showCustomAlert('Link copied to clipboard!'); } catch (err) { console.error('Failed to copy: ', err); showCustomAlert('Failed to copy link.'); } }; const getFirstAvailableLink = () => { // Extended class names to check const classNamesToCheck = ['n1obkb', 'ab_button', 'ellip', 'PZPZlf']; // Check for direct <a> tags and those within a <div> or other container for (const className of classNamesToCheck) { // Select all <a> elements with the class const links = document.querySelectorAll(`a.${className}[href]`); // If direct matches are found, return the first href if (links.length > 0) { return links[0].href; // Return the href of the first found link } // Check for <a> tags within other elements with the class name const containers = document.querySelectorAll(`div.${className}, button.${className}`); for (let container of containers) { const childLinks = container.querySelectorAll('a[href]'); if (childLinks.length > 0) { return childLinks[0].href; } } } // Return null if no link is found return null; }; })();