您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
GSearch in Persian can change Google search results to Persian language, without affecting the RTL (Right-to-Left) direction. (Based on the fork from tgxhx)
// ==UserScript== // @name GSearch in Persian // @name:fa سوییچ جستو در سایتهای فارسی // @version 0.5 // @author Amir // @description GSearch in Persian can change Google search results to Persian language, without affecting the RTL (Right-to-Left) direction. (Based on the fork from tgxhx) // @homepage https://github.com/Amm1rr/GSearch-Toggle/ // @namespace amm1rr // @description:fa با این اسکریپت به راحتی میتوان بین جستجو فقط در سایتهای فارسی در جستجوی گوگل سوییچ کرد، یک گزینه زیر جستجوی گوگل اضافه می شود. البته بدون تغییر در // @require http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js // @icon https://www.google.com/favicon.ico // @match https://www.google.com/search* // @exclude https://www.google.com/maps* // @grant GM_addStyle // ==/UserScript== /* Last Changes: (Sort by Date) 18/07/2023 - Excluded Google Map - Added support for UK/US Google domains - Added support for mobile, tablet, and desktop devices - External library removed */ (function () { "use strict"; // I just added this variable to check if the class is found for the first time, so there's no need to execute multiple times. var iFoundCounter = 0; // How to use: // if( isMobile.any() ) alert('Mobile'); // To check to see if the user is on a specific mobile device: // if( isMobile.iOS() ) alert('iOS'); const isMobile = { Android: function () { return navigator.userAgent.match(/Android/i); }, BlackBerry: function () { return navigator.userAgent.match(/BlackBerry/i); }, iOS: function () { return navigator.userAgent.match(/iPhone|iPad|iPod/i); }, iPhone: function () { return navigator.userAgent.match(/iPhone/i); }, Opera: function () { return navigator.userAgent.match(/Opera Mini/i); }, Windows: function () { return ( navigator.userAgent.match(/IEMobile/i) || navigator.userAgent.match(/WPDesktop/i) ); }, any: function () { return ( isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows() ); }, mobile: function () { return ( isMobile.Android() || isMobile.BlackBerry() || isMobile.iPhone() || isMobile.Opera() ); }, }; //-- Wait for the "Tools" button if (isMobile.mobile()) { waitForKeyElements('div[jsname="yIZuWb"]', onPageLoadedMobile); } else { waitForKeyElements(".PuHHbb", onPageLoaded); } function CreateSeprator() { var seperator = document.createElement("div"); seperator.classList.add("IDFSOe"); //-- Class=> TZqsAd return seperator; } function CreateLink() { var aTag = document.createElement("a"); var query = new URLSearchParams(decodeURIComponent(location.search)); const isFarsi = (query.get("lr") || "").toLowerCase() === "lang_fa"; if (isFarsi) { query.delete("lr"); query.delete("tbs"); aTag.textContent = "Clear"; } else { query.set("lr", "lang_fa"); query.set("tbs", "lr:lang_fa"); aTag.textContent = "Persian"; } const href = `${location.origin}${ location.pathname }?${query.toString()}`; aTag.setAttribute("href", href); aTag.classList.add("hdtb-tl"); aTag.style.cssText = "color: #5f6368;text-decoration: none;"; return aTag; } function onPageLoadedMobile() { onPageLoaded("Mobile"); } // Function to be executed after the page has completely loaded function onPageLoaded(arg) { var ToolsButton; if (arg == "Mobile") { //-- Mobile ToolsButton = document.querySelector('div[jsname="yIZuWb"]'); } else { //-- Desktop ToolsButton = document.querySelector(".PuHHbb"); //-- Tablet if (!ToolsButton) { ToolsButton = document.querySelector(".hdtb-tl-sel"); // alert("1." + ToolsButton); } if (!ToolsButton) { ToolsButton = document.querySelector("#hdtb-tls"); // alert("2." + ToolsButton); } if (!ToolsButton) { ToolsButton = document.querySelector(".TZqsAd"); // alert("3." + ToolsButton); } //-- Tablet } if (ToolsButton) { if (iFoundCounter > 1) { return; } } iFoundCounter++; var seperator = CreateSeprator(); var alink = CreateLink(); ToolsButton.insertAdjacentElement("afterend", seperator); seperator.insertAdjacentElement("afterend", alink); } /*--- waitForKeyElements(): A utility function, for Greasemonkey scripts, that detects and handles AJAXed content. Usage example: waitForKeyElements ( "div.comments" , commentCallbackFunction ); //--- Page-specific function to do what we want when the node is found. function commentCallbackFunction (jNode) { jNode.text ("This comment changed by waitForKeyElements()."); } IMPORTANT: This function requires your script to have loaded jQuery. */ function waitForKeyElements( selectorTxt /* Required: The jQuery selector string that specifies the desired element(s). */, actionFunction /* Required: The code to run when elements are found. It is passed a jNode to the matched element. */, bWaitOnce /* Optional: If false, will continue to scan for new elements even after the first match is found. */, iframeSelector /* Optional: If set, identifies the iframe to search. */ ) { var targetNodes, btargetsFound; if (typeof iframeSelector == "undefined") targetNodes = $(selectorTxt); else targetNodes = $(iframeSelector).contents().find(selectorTxt); if (targetNodes && targetNodes.length > 0) { btargetsFound = true; /*--- Found target node(s). Go through each and act if they are new. */ targetNodes.each(function () { var jThis = $(this); var alreadyFound = jThis.data("alreadyFound") || false; if (!alreadyFound) { //--- Call the payload function. var cancelFound = actionFunction(jThis); if (cancelFound) btargetsFound = false; else jThis.data("alreadyFound", true); } }); } else { btargetsFound = false; } //--- Get the timer-control variable for this selector. var controlObj = waitForKeyElements.controlObj || {}; var controlKey = selectorTxt.replace(/[^\w]/g, "_"); var timeControl = controlObj[controlKey]; //--- Now set or clear the timer as appropriate. if (btargetsFound && bWaitOnce && timeControl) { //--- The only condition where we need to clear the timer. clearInterval(timeControl); delete controlObj[controlKey]; } else { //--- Set a timer, if needed. if (!timeControl) { timeControl = setInterval(function () { waitForKeyElements( selectorTxt, actionFunction, bWaitOnce, iframeSelector ); }, 300); controlObj[controlKey] = timeControl; } } waitForKeyElements.controlObj = controlObj; } //document.addEventListener('DOMContentLoaded', onPageLoaded); // window.onload = onPageLoaded; })();