// ==UserScript== // @name Language Switcher for Google™ // @author gb.ianni // @namespace gb.ianni // @version 2.2.0 // @copyright Copyright 2015 gb.ianni // @description a port of Language Switcher for Google™ to userscript.js // @include *://www.google.com/* // @include *://www.google.ad/* // @include *://www.google.ae/* // @include *://www.google.com.af/* // @include *://www.google.com.ag/* // @include *://www.google.com.ai/* // @include *://www.google.am/* // @include *://www.google.co.ao/* // @include *://www.google.com.ar/* // @include *://www.google.as/* // @include *://www.google.at/* // @include *://www.google.com.au/* // @include *://www.google.az/* // @include *://www.google.ba/* // @include *://www.google.com.bd/* // @include *://www.google.be/* // @include *://www.google.bf/* // @include *://www.google.bg/* // @include *://www.google.com.bh/* // @include *://www.google.bi/* // @include *://www.google.bj/* // @include *://www.google.com.bn/* // @include *://www.google.com.bo/* // @include *://www.google.com.br/* // @include *://www.google.bs/* // @include *://www.google.co.bw/* // @include *://www.google.by/* // @include *://www.google.com.bz/* // @include *://www.google.ca/* // @include *://www.google.cd/* // @include *://www.google.cf/* // @include *://www.google.cg/* // @include *://www.google.ch/* // @include *://www.google.ci/* // @include *://www.google.co.ck/* // @include *://www.google.cl/* // @include *://www.google.cm/* // @include *://www.google.cn/* // @include *://www.google.com.co/* // @include *://www.google.co.cr/* // @include *://www.google.com.cu/* // @include *://www.google.cz/* // @include *://www.google.de/* // @include *://www.google.dj/* // @include *://www.google.dk/* // @include *://www.google.dm/* // @include *://www.google.com.do/* // @include *://www.google.dz/* // @include *://www.google.com.ec/* // @include *://www.google.ee/* // @include *://www.google.com.eg/* // @include *://www.google.es/* // @include *://www.google.com.et/* // @include *://www.google.fi/* // @include *://www.google.com.fj/* // @include *://www.google.fm/* // @include *://www.google.fr/* // @include *://www.google.ga/* // @include *://www.google.ge/* // @include *://www.google.gg/* // @include *://www.google.com.gh/* // @include *://www.google.com.gi/* // @include *://www.google.gl/* // @include *://www.google.gm/* // @include *://www.google.gp/* // @include *://www.google.gr/* // @include *://www.google.com.gt/* // @include *://www.google.gy/* // @include *://www.google.com.hk/* // @include *://www.google.hn/* // @include *://www.google.hr/* // @include *://www.google.ht/* // @include *://www.google.hu/* // @include *://www.google.co.id/* // @include *://www.google.ie/* // @include *://www.google.co.il/* // @include *://www.google.im/* // @include *://www.google.co.in/* // @include *://www.google.iq/* // @include *://www.google.is/* // @include *://www.google.it/* // @include *://www.google.je/* // @include *://www.google.com.jm/* // @include *://www.google.jo/* // @include *://www.google.co.jp/* // @include *://www.google.co.ke/* // @include *://www.google.com.kh/* // @include *://www.google.ki/* // @include *://www.google.kg/* // @include *://www.google.co.kr/* // @include *://www.google.com.kw/* // @include *://www.google.kz/* // @include *://www.google.la/* // @include *://www.google.com.lb/* // @include *://www.google.li/* // @include *://www.google.lk/* // @include *://www.google.co.ls/* // @include *://www.google.lt/* // @include *://www.google.lu/* // @include *://www.google.lv/* // @include *://www.google.com.ly/* // @include *://www.google.co.ma/* // @include *://www.google.md/* // @include *://www.google.me/* // @include *://www.google.mg/* // @include *://www.google.mk/* // @include *://www.google.ml/* // @include *://www.google.mn/* // @include *://www.google.ms/* // @include *://www.google.com.mt/* // @include *://www.google.mu/* // @include *://www.google.mv/* // @include *://www.google.mw/* // @include *://www.google.com.mx/* // @include *://www.google.com.my/* // @include *://www.google.co.mz/* // @include *://www.google.com.na/* // @include *://www.google.com.nf/* // @include *://www.google.com.ng/* // @include *://www.google.com.ni/* // @include *://www.google.ne/* // @include *://www.google.nl/* // @include *://www.google.no/* // @include *://www.google.com.np/* // @include *://www.google.nr/* // @include *://www.google.nu/* // @include *://www.google.co.nz/* // @include *://www.google.com.om/* // @include *://www.google.com.pa/* // @include *://www.google.com.pe/* // @include *://www.google.com.ph/* // @include *://www.google.com.pk/* // @include *://www.google.pl/* // @include *://www.google.pn/* // @include *://www.google.com.pr/* // @include *://www.google.ps/* // @include *://www.google.pt/* // @include *://www.google.com.py/* // @include *://www.google.com.qa/* // @include *://www.google.ro/* // @include *://www.google.ru/* // @include *://www.google.rw/* // @include *://www.google.com.sa/* // @include *://www.google.com.sb/* // @include *://www.google.sc/* // @include *://www.google.se/* // @include *://www.google.com.sg/* // @include *://www.google.sh/* // @include *://www.google.si/* // @include *://www.google.sk/* // @include *://www.google.com.sl/* // @include *://www.google.sn/* // @include *://www.google.sm/* // @include *://www.google.st/* // @include *://www.google.com.sv/* // @include *://www.google.td/* // @include *://www.google.tg/* // @include *://www.google.co.th/* // @include *://www.google.com.tj/* // @include *://www.google.tk/* // @include *://www.google.tl/* // @include *://www.google.tm/* // @include *://www.google.tn/* // @include *://www.google.to/* // @include *://www.google.com.tr/* // @include *://www.google.tt/* // @include *://www.google.com.tw/* // @include *://www.google.co.tz/* // @include *://www.google.com.ua/* // @include *://www.google.co.ug/* // @include *://www.google.co.uk/* // @include *://www.google.com.uy/* // @include *://www.google.co.uz/* // @include *://www.google.com.vc/* // @include *://www.google.co.ve/* // @include *://www.google.vg/* // @include *://www.google.co.vi/* // @include *://www.google.com.vn/* // @include *://www.google.vu/* // @include *://www.google.ws/* // @include *://www.google.rs/* // @include *://www.google.co.za/* // @include *://www.google.co.zm/* // @include *://www.google.co.zw/* // @downloadURL none // ==/UserScript== var debug = false; cLog("Start"); // // Parses and puts in a hash map CGI URL parameters. // cLog("Window href:"+window.location.href); //debugLayer = { 'FORM3' : 1, 'PROF' : 1 }; debugLayer = { 'INJ' : 1 }; var vars = null; function getUrlVars() { if (!vars) { vars = []; var hash; var positionQ = window.location.href.indexOf('?'); var positionS = window.location.href.indexOf('#'); if (positionQ > 0 && positionS > 0) position = Math.min(positionQ,positionS); else if (positionQ > 0) position = positionQ; else position = positionS; var hashes = window.location.href.slice(position+1).split(/&|#/); for(var i = 0; i < hashes.length; i++) { cLog('VALUE:'+hashes[i]); hash = hashes[i].split('='); //vars.push(hash[0]); vars[hash[0]] = hash[1]; } // Possibly missing hl value is filled with languages value corresponding to TLD value if (!vars['hl']) vars['hl'] = domainsToLang[getTLD()]; // Possibly missing lr value is filled with languages value corresponding to TLD value if (!vars['lr']) vars['lr'] = "lang_" + domainsToLang[getTLD()]; } return vars; } function getTLD() { var tld = window.location.href.match(/\.(\w+?)(\/|$)/)[1]; cLog('TLD='+tld); return tld; } cLog('TLD:'+getTLD()); // // Main // //var addPath = "/html/body/div/*/div/div[2]/div"; //var addPath = "/html/body/div/div/div[2]/div[@id='resultStats']"; //var addPath = "/html/body/div[@id='main']/div[@id='cnt']/div[@id='subform_ctrl']"; //var addSelector = '#resultStats'; var addPaths = [ "//*[@id='resultStats']", "//*[@id='gbx1']" ]; // // Add Possible Injection points below // // Places where to try injection of Language switcher box var addSelectors = { "#resultStats" : 1, "#slim_appbar" : 1, "#extabar" : 1, "#topabar" : 1, ".med" : 1, ".g" : 1, ".appbar" : 1}; var languageVars = [ "hl", "#hl" ]; var documentFormName = 'gbqf'; /* * Injected Code for querying as a different language */ var labels = ["en-US", "en-UK", "it", "fr","de","es","cn/hk","jp","ru","nl"]; //,"nl","ru","gr","jp","tr","cn","arb","il"); var languages = ["en","en", "it","fr","de","es","zh-CN","ja","ru","nl"]; //,"nl","ru","el","ja","tr","zh-CN","ar","iw"); var domains = ["com", "co.uk", "it", "fr", "de", "es", "com.hk", "co.jp","ru","nl"]; var tlds = ["com", "uk", "it", "fr", "de", "es", "cn", "jp","ru","nl"]; var wikipediaDomains = ["en","en", "it","fr","de","es","zh","ja","ru","nl"]; var domainsToLang = []; for (var i = 0; i < domains.length; i++) { domainsToLang[tlds[i]] = languages[i]; } var injectedObjectName = 'AGB_language_switcher'; var status = new Array(); var radioOn = "checked=\"checked\""; var radioOff = ""; for (var i = 0; i < labels.length; i++) { if ("lang_" + languages[i] != getUrlVars()["lr"] ) status[languages[i]] = radioOff; else status[languages[i]] = radioOn; } cLog("GetURlVars="+getUrlVars()); cLog("n_lang is="+getUrlVars()["n_lang"]); cLog("hl is="+getUrlVars()["hl"]); cLog("lr is="+getUrlVars()["lr"]); cLog("q is="+getUrlVars()["q"]); cLog("Languages[n_lang] is="+status[getUrlVars()["hl"]]); var inject = "

Ask again on another local version: \
\ \ "; // // Prepare code for radio buttons to be injected in Google page results // for (var i = 0; i < languages.length; i++) { //var clicInject = "document."+documentFormName+".hl.value ='"+languages[i]+"'; document."+documentFormName+".submit(); "; cLog("Injecting "+domains[i]+" code"); var clicInject = "console.log('clic"+domains[i]+"'); var a = window.location.href.slice(0); " + "console.log(a); a = a.replace(/google\\.(.*?)\\//,'google."+domains[i]+"/');" + "console.log(a); if (!a.match( /(\\?|\\&)hl=/ )) a = a + '&hl='; " + "console.log(a); if (!a.match( /(\\?|\\&)lr=/ )) a = a + '&lr='; " + "a = a.replace(/hl=(.*?)(&|$)/,'hl="+languages[i]+"$2'); " + "a = a.replace(/lr=(.*?)(&|$)/,'lr=lang_"+languages[i]+"$2'); " + "console.log(a); " + "window.location.href =a; " + "console.log('clac"+domains[i]+"');"; var checked = ("lang_" + languages[i] == getUrlVars()["lr"]) && (tlds[i] == getTLD() || true); inject += ""; } inject += ""; cLog("This is what I'm injecting:"+inject); /* function getClicFunction(i) { return function() { document[documentFormName].hl.value = languages[i]; document[documentFormName].submit(); }; } for (var i = 0; i < languages.length; i++) { inject.append($('"; var query = getUrlVars()["q"]; for (var i = 0; i < languages.length; i++) { var clicWikiInject = "window.location = 'http://"+wikipediaDomains[i]+".wikipedia.org/?search="+query+"';"; inject += ""; } inject += "
Google:   ').attr({ 'valign' : 'middle' }) .append($('').attr( { id : 'g_'+languages[i], type : 'radio', name : 'n_lang', value : languages[i]} ) )); } */ // // Adds Wikipedia radio buttons. Constructs xx.wikipedia.org for xx taken from wikipediaDomains[] // inject += "
Wikipedia:   
"; tryInjection(); document.addEventListener("DOMNodeInserted", function(event){ var element = event.target; //cLog("Node INSERTED "+element.name); //if (element.className == 'med') { tryInjection(); //} }); var alreadyInjected = false; function tryInjection() { if (alreadyInjected) return; var placeToInject = null; if (!document.getElementById(injectedObjectName)) { lLog("Starting injection","INJ"); for (var selector in addSelectors) { lLog("Attempting injection point: "+selector,"INJ"); if (placeToInject = document.querySelectorAll(selector)[0]) { lLog("Matched Selector:"+selector,"INJ"); break; } } lLog("Place to inject:"+placeToInject,"INJ"); if (placeToInject) { //placeToInject.innerHTML = ""+inject+"
" + placeToInject.innerHTML; document.querySelectorAll(selector).forEach(el => el.after(new DOMParser().parseFromString(inject, "text/html").body.firstChild)); alreadyInjected = true; } lLog("Ending injection","INJ"); } else lLog("Looks like there is already a language_switcher here.","INJ2"); } function cLog(str) { if (debug) console.log(str); } /** * main logging function * @param str String to be printed * @param level debugLayer triggering the printout. Will be printed only if level is in the currently active debugLayers */ function lLog(str, level) { //console.log("Logging:"+str); if (!isNaN(level)) str += " USING NUMBERS FOR DEBUG LEVELS IS DEPRECATED - "; else if (level.match(/PROF/)) { str = this.debug.getPace() + "\n" + str; }; // console.log("mid Logging:"+this.debugLayer+" "+this.localLog); if (debugLayer == level || debugLayer == "ALL" || (debugLayer instanceof Object && debugLayer[level]) ) { cLog(str); } //console.log("end Logging:"+str); }; // // XPath evaluation wrapping function. // function xpath(query,node) { return document.evaluate(query, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); } // // Returns the first element of a given XPath query // function fXPath(query,node) { var elements = xpath(query,node); return elements.snapshotItem(0); } // // Returns the last element of a given XPath query // function lXPath(query,node) { cLog("Asking for "+query); var elements = xpath(query,node); cLog("Elements are "+elements.snapshotLength); return elements.snapshotItem(elements.snapshotLength-1); } // // 0-ize NaN and non-number strings // function normalize(str) { var temp = (str != null) ? parseInt(str) : 0; return (isNaN(temp)) ? 0 : temp; }