Middle clicking the search Button on DuckDucjGo search icon opens the r###lts in a new tab. Fork of "Youtube Middle Click Search"v. 2.0.5 Kufii (Adrien Pyke?) without using wait-for-elements/wait-for-elements.js
// ==UserScript== // @name DuckDuckGo Middle Click Search v.2.1 // @author Decembre // @namespace https://greasyfork.org/users/8 // @version 2.1.0 // @description Middle clicking the search Button on DuckDucjGo search icon opens the r###lts in a new tab. Fork of "Youtube Middle Click Search"v. 2.0.5 Kufii (Adrien Pyke?) without using wait-for-elements/wait-for-elements.js // @icon https://external-content.duckduckgo.com/ip3/duckduckgo.com.ico // @include https://duckduckgo.com/* // @grant GM_openInTab // ==/UserScript== /* =========== If you want fork it for an other Site, watch in the code, the 3: // ConFig DuckDuckGo This code completes the event listener attachment for the search suggestions. It checks if the target element is not the remove button, and if so, it constructs the search URL and navigates to the search r###lts page or opens the r###lts in a new tab depending on the mouse button clicked. If the target element is the remove button and the middle mouse button is clicked, i t prevents the default behavior and stops the event propagation. ========== */ // Define an anonymous function to encapsulate the script's functionality (function () { 'use strict'; // Enable strict mode for better error handling // Define the script's name for logging purposes const SCRIPT_NAME = 'YMCS'; // Define a utility object with various helper functions const Util = { // Log a message to the console with the script's name log(...args) { args.unshift(`%c${SCRIPT_NAME}:`, 'font-weight: bold;color: #233c7b;'); console.log(...args); }, // Query the DOM for an element using a CSS selector q(query, context = document) { return context.querySelector(query); }, // Query the DOM for multiple elements using a CSS selector qq(query, context = document) { return Array.from(context.querySelectorAll(query)); }, // Get a query parameter from the current URL getQueryParameter(name, url = window.location.href) { name = name.replace(/[[\]]/gu, '\\$&'); const regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`, 'u'), r###lts = regex.exec(url); if (!r###lts) return null; if (!r###lts[2]) return ''; return decodeURIComponent(r###lts[2].replace(/\+/gu, ' ')); }, // Encode a URI with plus signs encodeURIWithPlus(string) { return encodeURIComponent(string).replace(/%20/gu, '+'); } }; // Define a function to wait for an element to be available in the DOM function waitForElems(options) { // Extract the options object's properties const { sel, onmatch, stop } = options; // Create an interval to check for the element's availability const intervalId = setInterval(() => { // Query the DOM for the element using the provided selector const elem = document.querySelector(sel); // If the element is found, call the onmatch function and clear the interval if stop is true if (elem) { onmatch(elem); if (stop) { clearInterval(intervalId); } } }, 100); // Check every 100ms } // ConFig DuckDuckGo Search Button = .is-link-style-exp .search__button // Wait for the search button to be available and attach event listeners waitForElems({ // Selector for the search button sel: '.is-link-style-exp .search__button', // Stop checking for the element once it's found stop: true, // Function to call when the element is found onmatch(btn) { // Prevent default behavior on middle click btn.onmousedown = function (e) { if (e.button === 1) { e.preventDefault(); } }; // Attach an event listener for clicks btn.onclick = function (e) { // Prevent default behavior e.preventDefault(); e.stopImmediatePropagation(); // DuckDuckGo Search InPut = #search_form_input // Get the search input value const input = Util.q('#search_form_input').value.trim(); // If the input is empty, do nothing if (!input) return false; // DuckDuckGo Search URL // Construct the search URL = ?q= const url = `${location.origin}?q=${Util.encodeURIWithPlus(input)}`; // If the middle mouse button was clicked, open the r###lts in a new tab if (e.button === 1) { GM_openInTab(url, true); } else if (e.button === 0) { // Otherwise, navigate to the search r###lts page window.location.href = url; } return false; }; // Attach an event listener for aux clicks (middle click) btn.onauxclick = btn.onclick; } }); // Wait for the search suggestions to be available and attach event listeners waitForElems({ // Selector for the search suggestions sel: '.sbsb_c', // Function to call when the element is found onmatch(r###lt) { // Attach an event listener for clicks r###lt.onclick = function (e) { // If the target element is not the remove button if (!e.target.classList.contains('sbsb_i')) { // Get the search suggestion text const search = Util.q('.sbpqs_a, .sbqs_c', r###lt).textContent; // Construct the search URL const url = `${location.origin}/search/${Util.encodeURIWithPlus(search)}`; // If the middle mouse button was clicked, open the r###lts in a new tab if (e.button === 1) { GM_openInTab(url, true); } else if (e.button === 0) { // Otherwise, navigate to the search r###lts page window.location.href = url; } } else if (e.button === 1) { // Prevent opening in new tab if they middle click the remove button e.preventDefault(); e.stopImmediatePropagation(); } }; // Attach an event listener for aux clicks (middle click) r###lt.onauxclick = r###lt.onclick; } }); })();