Comments (3)
Here's the built UserScript version for anyone else wanting it:
Expand
// ==UserScript==
// @name Web Search Navigator
// @version 0.5.2
// @description Keyboard shortcuts for Google search, YouTube, Startpage, Brave Search, Google Scholar, Github, Gitlab, and Amazon.
// @author Web Search Navigator
// @match *://www.google.com/search*
// @match *://www.google.ad/search*
// @match *://www.google.ae/search*
// @match *://www.google.com.af/search*
// @match *://www.google.com.ag/search*
// @match *://www.google.com.ai/search*
// @match *://www.google.al/search*
// @match *://www.google.am/search*
// @match *://www.google.co.ao/search*
// @match *://www.google.com.ar/search*
// @match *://www.google.as/search*
// @match *://www.google.at/search*
// @match *://www.google.com.au/search*
// @match *://www.google.az/search*
// @match *://www.google.ba/search*
// @match *://www.google.com.bd/search*
// @match *://www.google.be/search*
// @match *://www.google.bf/search*
// @match *://www.google.bg/search*
// @match *://www.google.com.bh/search*
// @match *://www.google.bi/search*
// @match *://www.google.bj/search*
// @match *://www.google.com.bn/search*
// @match *://www.google.com.bo/search*
// @match *://www.google.com.br/search*
// @match *://www.google.bs/search*
// @match *://www.google.bt/search*
// @match *://www.google.co.bw/search*
// @match *://www.google.by/search*
// @match *://www.google.com.bz/search*
// @match *://www.google.ca/search*
// @match *://www.google.cd/search*
// @match *://www.google.cf/search*
// @match *://www.google.cg/search*
// @match *://www.google.ch/search*
// @match *://www.google.ci/search*
// @match *://www.google.co.ck/search*
// @match *://www.google.cl/search*
// @match *://www.google.cm/search*
// @match *://www.google.cn/search*
// @match *://www.google.com.co/search*
// @match *://www.google.co.cr/search*
// @match *://www.google.com.cu/search*
// @match *://www.google.cv/search*
// @match *://www.google.com.cy/search*
// @match *://www.google.cz/search*
// @match *://www.google.de/search*
// @match *://www.google.dj/search*
// @match *://www.google.dk/search*
// @match *://www.google.dm/search*
// @match *://www.google.com.do/search*
// @match *://www.google.dz/search*
// @match *://www.google.com.ec/search*
// @match *://www.google.ee/search*
// @match *://www.google.com.eg/search*
// @match *://www.google.es/search*
// @match *://www.google.com.et/search*
// @match *://www.google.fi/search*
// @match *://www.google.com.fj/search*
// @match *://www.google.fm/search*
// @match *://www.google.fr/search*
// @match *://www.google.ga/search*
// @match *://www.google.ge/search*
// @match *://www.google.gg/search*
// @match *://www.google.com.gh/search*
// @match *://www.google.com.gi/search*
// @match *://www.google.gl/search*
// @match *://www.google.gm/search*
// @match *://www.google.gp/search*
// @match *://www.google.gr/search*
// @match *://www.google.com.gt/search*
// @match *://www.google.gy/search*
// @match *://www.google.com.hk/search*
// @match *://www.google.hn/search*
// @match *://www.google.hr/search*
// @match *://www.google.ht/search*
// @match *://www.google.hu/search*
// @match *://www.google.co.id/search*
// @match *://www.google.ie/search*
// @match *://www.google.co.il/search*
// @match *://www.google.im/search*
// @match *://www.google.co.in/search*
// @match *://www.google.iq/search*
// @match *://www.google.is/search*
// @match *://www.google.it/search*
// @match *://www.google.je/search*
// @match *://www.google.com.jm/search*
// @match *://www.google.jo/search*
// @match *://www.google.co.jp/search*
// @match *://www.google.co.ke/search*
// @match *://www.google.com.kh/search*
// @match *://www.google.ki/search*
// @match *://www.google.kg/search*
// @match *://www.google.co.kr/search*
// @match *://www.google.com.kw/search*
// @match *://www.google.kz/search*
// @match *://www.google.la/search*
// @match *://www.google.com.lb/search*
// @match *://www.google.li/search*
// @match *://www.google.lk/search*
// @match *://www.google.co.ls/search*
// @match *://www.google.lt/search*
// @match *://www.google.lu/search*
// @match *://www.google.lv/search*
// @match *://www.google.com.ly/search*
// @match *://www.google.co.ma/search*
// @match *://www.google.md/search*
// @match *://www.google.me/search*
// @match *://www.google.mg/search*
// @match *://www.google.mk/search*
// @match *://www.google.ml/search*
// @match *://www.google.com.mm/search*
// @match *://www.google.mn/search*
// @match *://www.google.ms/search*
// @match *://www.google.com.mt/search*
// @match *://www.google.mu/search*
// @match *://www.google.mv/search*
// @match *://www.google.mw/search*
// @match *://www.google.com.mx/search*
// @match *://www.google.com.my/search*
// @match *://www.google.co.mz/search*
// @match *://www.google.com.na/search*
// @match *://www.google.com.nf/search*
// @match *://www.google.com.ng/search*
// @match *://www.google.com.ni/search*
// @match *://www.google.ne/search*
// @match *://www.google.nl/search*
// @match *://www.google.no/search*
// @match *://www.google.com.np/search*
// @match *://www.google.nr/search*
// @match *://www.google.nu/search*
// @match *://www.google.co.nz/search*
// @match *://www.google.com.om/search*
// @match *://www.google.com.pa/search*
// @match *://www.google.com.pe/search*
// @match *://www.google.com.pg/search*
// @match *://www.google.com.ph/search*
// @match *://www.google.com.pk/search*
// @match *://www.google.pl/search*
// @match *://www.google.pn/search*
// @match *://www.google.com.pr/search*
// @match *://www.google.ps/search*
// @match *://www.google.pt/search*
// @match *://www.google.com.py/search*
// @match *://www.google.com.qa/search*
// @match *://www.google.ro/search*
// @match *://www.google.ru/search*
// @match *://www.google.rw/search*
// @match *://www.google.com.sa/search*
// @match *://www.google.com.sb/search*
// @match *://www.google.sc/search*
// @match *://www.google.se/search*
// @match *://www.google.com.sg/search*
// @match *://www.google.sh/search*
// @match *://www.google.si/search*
// @match *://www.google.sk/search*
// @match *://www.google.com.sl/search*
// @match *://www.google.sn/search*
// @match *://www.google.so/search*
// @match *://www.google.sm/search*
// @match *://www.google.sr/search*
// @match *://www.google.st/search*
// @match *://www.google.com.sv/search*
// @match *://www.google.td/search*
// @match *://www.google.tg/search*
// @match *://www.google.co.th/search*
// @match *://www.google.com.tj/search*
// @match *://www.google.tk/search*
// @match *://www.google.tl/search*
// @match *://www.google.tm/search*
// @match *://www.google.tn/search*
// @match *://www.google.to/search*
// @match *://www.google.com.tr/search*
// @match *://www.google.tt/search*
// @match *://www.google.com.tw/search*
// @match *://www.google.co.tz/search*
// @match *://www.google.com.ua/search*
// @match *://www.google.co.ug/search*
// @match *://www.google.co.uk/search*
// @match *://www.google.com.uy/search*
// @match *://www.google.co.uz/search*
// @match *://www.google.com.vc/search*
// @match *://www.google.co.ve/search*
// @match *://www.google.vg/search*
// @match *://www.google.co.vi/search*
// @match *://www.google.com.vn/search*
// @match *://www.google.vu/search*
// @match *://www.google.ws/search*
// @match *://www.google.rs/search*
// @match *://www.google.co.za/search*
// @match *://www.google.co.zm/search*
// @match *://www.google.co.zw/search*
// @match *://www.google.cat/search*
// ==/UserScript==
globalThis.IS_USERSCRIPT=!0,globalThis._localStorage_browser_polyfill={get:async(...args)=>(console.log("[localStorage] Get: ",...args),[]),set:async(...args)=>{console.log("[localStorage] Set: ",...args)},clear:async()=>{console.log("[localStorage] Clear")}},globalThis._browser_userscript_polyfill={runtime:{sendMessage:msg=>{"tabsCreate"===msg.type&&window.open(msg.options.url,"_blank")},id:"093889f3-43be-45e3-bc5a-e257e75b466d"},storage:{sync:globalThis._localStorage_browser_polyfill,local:globalThis._localStorage_browser_polyfill},permissions:{remove:()=>{},add:()=>{},request:()=>{},getAll:()=>({})}},console.log(globalThis.browser,_browser_userscript_polyfill),Object.assign(globalThis,{browser:globalThis._browser_userscript_polyfill,chrome:globalThis._browser_userscript_polyfill}),function(global,factory){"function"==typeof define&&define.amd?define("webextension-polyfill",["module"],factory):"undefined"!=typeof exports?factory(module):(factory(factory={exports:{}}),global.browser=factory.exports)}("undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:this,function(module){"use strict";if(!globalThis.chrome?.runtime?.id)throw new Error("This script should only be loaded in a browser extension.");if(void 0===globalThis.browser||Object.getPrototypeOf(globalThis.browser)!==Object.prototype)module.exports=(extensionAPIs=>{var apiMetadata={alarms:{clear:{minArgs:0,maxArgs:1},clearAll:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getAll:{minArgs:0,maxArgs:0}},bookmarks:{create:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},getChildren:{minArgs:1,maxArgs:1},getRecent:{minArgs:1,maxArgs:1},getSubTree:{minArgs:1,maxArgs:1},getTree:{minArgs:0,maxArgs:0},move:{minArgs:2,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeTree:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}},browserAction:{disable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},enable:{minArgs:0,maxArgs:1,fallbackToNoCallback:!0},getBadgeBackgroundColor:{minArgs:1,maxArgs:1},getBadgeText:{minArgs:1,maxArgs:1},getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},openPopup:{minArgs:0,maxArgs:0},setBadgeBackgroundColor:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setBadgeText:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},browsingData:{remove:{minArgs:2,maxArgs:2},removeCache:{minArgs:1,maxArgs:1},removeCookies:{minArgs:1,maxArgs:1},removeDownloads:{minArgs:1,maxArgs:1},removeFormData:{minArgs:1,maxArgs:1},removeHistory:{minArgs:1,maxArgs:1},removeLocalStorage:{minArgs:1,maxArgs:1},removePasswords:{minArgs:1,maxArgs:1},removePluginData:{minArgs:1,maxArgs:1},settings:{minArgs:0,maxArgs:0}},commands:{getAll:{minArgs:0,maxArgs:0}},contextMenus:{remove:{minArgs:1,maxArgs:1},removeAll:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},cookies:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:1,maxArgs:1},getAllCookieStores:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},devtools:{inspectedWindow:{eval:{minArgs:1,maxArgs:2,singleCallbackArg:!1}},panels:{create:{minArgs:3,maxArgs:3,singleCallbackArg:!0},elements:{createSidebarPane:{minArgs:1,maxArgs:1}}}},downloads:{cancel:{minArgs:1,maxArgs:1},download:{minArgs:1,maxArgs:1},erase:{minArgs:1,maxArgs:1},getFileIcon:{minArgs:1,maxArgs:2},open:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},pause:{minArgs:1,maxArgs:1},removeFile:{minArgs:1,maxArgs:1},resume:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},extension:{isAllowedFileSchemeAccess:{minArgs:0,maxArgs:0},isAllowedIncognitoAccess:{minArgs:0,maxArgs:0}},history:{addUrl:{minArgs:1,maxArgs:1},deleteAll:{minArgs:0,maxArgs:0},deleteRange:{minArgs:1,maxArgs:1},deleteUrl:{minArgs:1,maxArgs:1},getVisits:{minArgs:1,maxArgs:1},search:{minArgs:1,maxArgs:1}},i18n:{detectLanguage:{minArgs:1,maxArgs:1},getAcceptLanguages:{minArgs:0,maxArgs:0}},identity:{launchWebAuthFlow:{minArgs:1,maxArgs:1}},idle:{queryState:{minArgs:1,maxArgs:1}},management:{get:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},getSelf:{minArgs:0,maxArgs:0},setEnabled:{minArgs:2,maxArgs:2},uninstallSelf:{minArgs:0,maxArgs:1}},notifications:{clear:{minArgs:1,maxArgs:1},create:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:0},getPermissionLevel:{minArgs:0,maxArgs:0},update:{minArgs:2,maxArgs:2}},pageAction:{getPopup:{minArgs:1,maxArgs:1},getTitle:{minArgs:1,maxArgs:1},hide:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setIcon:{minArgs:1,maxArgs:1},setPopup:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},setTitle:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0},show:{minArgs:1,maxArgs:1,fallbackToNoCallback:!0}},permissions:{contains:{minArgs:1,maxArgs:1},getAll:{minArgs:0,maxArgs:0},remove:{minArgs:1,maxArgs:1},request:{minArgs:1,maxArgs:1}},runtime:{getBackgroundPage:{minArgs:0,maxArgs:0},getPlatformInfo:{minArgs:0,maxArgs:0},openOptionsPage:{minArgs:0,maxArgs:0},requestUpdateCheck:{minArgs:0,maxArgs:0},sendMessage:{minArgs:1,maxArgs:3},sendNativeMessage:{minArgs:2,maxArgs:2},setUninstallURL:{minArgs:1,maxArgs:1}},sessions:{getDevices:{minArgs:0,maxArgs:1},getRecentlyClosed:{minArgs:0,maxArgs:1},restore:{minArgs:0,maxArgs:1}},storage:{local:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}},managed:{get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1}},sync:{clear:{minArgs:0,maxArgs:0},get:{minArgs:0,maxArgs:1},getBytesInUse:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}}},tabs:{captureVisibleTab:{minArgs:0,maxArgs:2},create:{minArgs:1,maxArgs:1},detectLanguage:{minArgs:0,maxArgs:1},discard:{minArgs:0,maxArgs:1},duplicate:{minArgs:1,maxArgs:1},executeScript:{minArgs:1,maxArgs:2},get:{minArgs:1,maxArgs:1},getCurrent:{minArgs:0,maxArgs:0},getZoom:{minArgs:0,maxArgs:1},getZoomSettings:{minArgs:0,maxArgs:1},goBack:{minArgs:0,maxArgs:1},goForward:{minArgs:0,maxArgs:1},highlight:{minArgs:1,maxArgs:1},insertCSS:{minArgs:1,maxArgs:2},move:{minArgs:2,maxArgs:2},query:{minArgs:1,maxArgs:1},reload:{minArgs:0,maxArgs:2},remove:{minArgs:1,maxArgs:1},removeCSS:{minArgs:1,maxArgs:2},sendMessage:{minArgs:2,maxArgs:3},setZoom:{minArgs:1,maxArgs:2},setZoomSettings:{minArgs:1,maxArgs:2},update:{minArgs:1,maxArgs:2}},topSites:{get:{minArgs:0,maxArgs:0}},webNavigation:{getAllFrames:{minArgs:1,maxArgs:1},getFrame:{minArgs:1,maxArgs:1}},webRequest:{handlerBehaviorChanged:{minArgs:0,maxArgs:0}},windows:{create:{minArgs:0,maxArgs:1},get:{minArgs:1,maxArgs:2},getAll:{minArgs:0,maxArgs:1},getCurrent:{minArgs:0,maxArgs:1},getLastFocused:{minArgs:0,maxArgs:1},remove:{minArgs:1,maxArgs:1},update:{minArgs:2,maxArgs:2}}};if(0===Object.keys(apiMetadata).length)throw new Error("api-metadata.json has not been included in browser-polyfill");class DefaultWeakMap extends WeakMap{constructor(createItem,items=void 0){super(items),this.createItem=createItem}get(key){return this.has(key)||this.set(key,this.createItem(key)),super.get(key)}}const makeCallback=(promise,metadata)=>(...callbackArgs)=>{extensionAPIs.runtime.lastError?promise.reject(new Error(extensionAPIs.runtime.lastError.message)):metadata.singleCallbackArg||callbackArgs.length<=1&&!1!==metadata.singleCallbackArg?promise.resolve(callbackArgs[0]):promise.resolve(callbackArgs)},pluralizeArguments=numArgs=>1==numArgs?"argument":"arguments",wrapMethod=(target,method,wrapper)=>new Proxy(method,{apply(targetMethod,thisObj,args){return wrapper.call(thisObj,target,...args)}});let hasOwnProperty=Function.call.bind(Object.prototype.hasOwnProperty);const wrapObject=(target,wrappers={},metadata={})=>{let cache=Object.create(null);var handlers={has(proxyTarget,prop){return prop in target||prop in cache},get(proxyTarget,prop,receiver){if(prop in cache)return cache[prop];if(prop in target){let value=target[prop];var wrapper;if("function"==typeof value)value="function"==typeof wrappers[prop]?wrapMethod(target,target[prop],wrappers[prop]):hasOwnProperty(metadata,prop)?(wrapper=((name,metadata)=>function(target,...args){if(args.length<metadata.minArgs)throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got `+args.length);if(args.length>metadata.maxArgs)throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got `+args.length);return new Promise((resolve,reject)=>{if(metadata.fallbackToNoCallback)try{target[name](...args,makeCallback({resolve:resolve,reject:reject},metadata))}catch(cbError){console.warn(name+" API method doesn't seem to support the callback parameter, falling back to call it without a callback: ",cbError),target[name](...args),metadata.fallbackToNoCallback=!1,metadata.noCallback=!0,resolve()}else metadata.noCallback?(target[name](...args),resolve()):target[name](...args,makeCallback({resolve:resolve,reject:reject},metadata))})})(prop,metadata[prop]),wrapMethod(target,target[prop],wrapper)):value.bind(target);else if("object"==typeof value&&null!==value&&(hasOwnProperty(wrappers,prop)||hasOwnProperty(metadata,prop)))value=wrapObject(value,wrappers[prop],metadata[prop]);else{if(!hasOwnProperty(metadata,"*"))return Object.defineProperty(cache,prop,{configurable:!0,enumerable:!0,get(){return target[prop]},set(value){target[prop]=value}}),value;value=wrapObject(value,wrappers[prop],metadata["*"])}return cache[prop]=value}},set(proxyTarget,prop,value,receiver){return prop in cache?cache[prop]=value:target[prop]=value,!0},defineProperty(proxyTarget,prop,desc){return Reflect.defineProperty(cache,prop,desc)},deleteProperty(proxyTarget,prop){return Reflect.deleteProperty(cache,prop)}},proxyTarget=Object.create(target);return new Proxy(proxyTarget,handlers)};var wrapEvent=wrapperMap=>({addListener(target,listener,...args){target.addListener(wrapperMap.get(listener),...args)},hasListener(target,listener){return target.hasListener(wrapperMap.get(listener))},removeListener(target,listener){target.removeListener(wrapperMap.get(listener))}}),onRequestFinishedWrappers=new DefaultWeakMap(listener=>"function"!=typeof listener?listener:function(req){req=wrapObject(req,{},{getContent:{minArgs:0,maxArgs:0}});listener(req)}),onMessageWrappers=new DefaultWeakMap(listener=>"function"!=typeof listener?listener:function(message,sender,sendResponse){let didCallSendResponse=!1,wrappedSendResponse;var sendResponsePromise=new Promise(resolve=>{wrappedSendResponse=function(response){didCallSendResponse=!0,resolve(response)}});let result;try{result=listener(message,sender,wrappedSendResponse)}catch(err){result=Promise.reject(err)}sender=!0!==result&&(message=result)&&"object"==typeof message&&"function"==typeof message.then;return!(!0!==result&&!sender&&!didCallSendResponse||((promise=>{promise.then(msg=>{sendResponse(msg)},error=>{let message;message=error&&(error instanceof Error||"string"==typeof error.message)?error.message:"An unexpected error occurred",sendResponse({__mozWebExtensionPolyfillReject__:!0,message:message})}).catch(err=>{console.error("Failed to send onMessage rejected reply",err)})})(sender?result:sendResponsePromise),0))});var wrappedSendMessage=(name,metadata,apiNamespaceObj,...args)=>{if(args.length<metadata.minArgs)throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got `+args.length);if(args.length>metadata.maxArgs)throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got `+args.length);return new Promise((resolve,reject)=>{resolve=(({reject,resolve},reply)=>{extensionAPIs.runtime.lastError?"The message port closed before a response was received."===extensionAPIs.runtime.lastError.message?resolve():reject(new Error(extensionAPIs.runtime.lastError.message)):reply&&reply.__mozWebExtensionPolyfillReject__?reject(new Error(reply.message)):resolve(reply)}).bind(null,{resolve:resolve,reject:reject});args.push(resolve),apiNamespaceObj.sendMessage(...args)})},onRequestFinishedWrappers={devtools:{network:{onRequestFinished:wrapEvent(onRequestFinishedWrappers)}},runtime:{onMessage:wrapEvent(onMessageWrappers),onMessageExternal:wrapEvent(onMessageWrappers),sendMessage:wrappedSendMessage.bind(null,"sendMessage",{minArgs:1,maxArgs:3})},tabs:{sendMessage:wrappedSendMessage.bind(null,"sendMessage",{minArgs:2,maxArgs:3})}},wrapEvent={clear:{minArgs:1,maxArgs:1},get:{minArgs:1,maxArgs:1},set:{minArgs:1,maxArgs:1}};return apiMetadata.privacy={network:{"*":wrapEvent},services:{"*":wrapEvent},websites:{"*":wrapEvent}},wrapObject(extensionAPIs,onRequestFinishedWrappers,apiMetadata)})(chrome);else module.exports=globalThis.browser}),function(window,document){if(window){for(var _REVERSE_MAP,_MAP={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"ins",46:"del",91:"meta",93:"meta",224:"meta"},_KEYCODE_MAP={106:"*",107:"+",109:"-",110:".",111:"/",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},_SHIFT_MAP={"~":"`","!":"1","@":"2","#":"3",$:"4","%":"5","^":"6","&":"7","*":"8","(":"9",")":"0",_:"-","+":"=",":":";",'"':"'","<":",",">":".","?":"/","|":"\\"},_SPECIAL_ALIASES={option:"alt",command:"meta",return:"enter",escape:"esc",plus:"+",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},i=1;i<20;++i)_MAP[111+i]="f"+i;for(i=0;i<=9;++i)_MAP[i+96]=i.toString();Mousetrap.prototype.bind=function(keys,callback,action){return keys=keys instanceof Array?keys:[keys],this._bindMultiple.call(this,keys,callback,action),this},Mousetrap.prototype.unbind=function(keys,action){return this.bind.call(this,keys,function(){},action)},Mousetrap.prototype.trigger=function(keys,action){return this._directMap[keys+":"+action]&&this._directMap[keys+":"+action]({},keys),this},Mousetrap.prototype.reset=function(){return this._callbacks={},this._directMap={},this},Mousetrap.prototype.stopCallback=function(e,element){var initialEventTarget;return!(-1<(" "+element.className+" ").indexOf(" mousetrap ")||function _belongsTo(element,ancestor){return null!==element&&element!==document&&(element===ancestor||_belongsTo(element.parentNode,ancestor))}(element,this.target))&&("INPUT"==(element="composedPath"in e&&"function"==typeof e.composedPath&&(initialEventTarget=e.composedPath()[0])!==e.target?initialEventTarget:element).tagName||"SELECT"==element.tagName||"TEXTAREA"==element.tagName||element.isContentEditable)},Mousetrap.prototype.handleKey=function(){return this._handleKey.apply(this,arguments)},Mousetrap.addKeycodes=function(object){for(var key in object)object.hasOwnProperty(key)&&(_MAP[key]=object[key]);_REVERSE_MAP=null},(Mousetrap.init=function(){var method,documentMousetrap=Mousetrap(document);for(method in documentMousetrap)"_"!==method.charAt(0)&&(Mousetrap[method]=function(method){return function(){return documentMousetrap[method].apply(documentMousetrap,arguments)}}(method))})(),window.Mousetrap=Mousetrap,"undefined"!=typeof module&&module.exports&&(module.exports=Mousetrap),"function"==typeof define&&define.amd&&define(function(){return Mousetrap})}function _addEvent(object,type,callback){object.addEventListener?object.addEventListener(type,callback,!1):object.attachEvent("on"+type,callback)}function _characterFromEvent(e){var character;return"keypress"==e.type?(character=String.fromCharCode(e.which),e.shiftKey?character:character.toLowerCase()):_MAP[e.which]||_KEYCODE_MAP[e.which]||String.fromCharCode(e.which).toLowerCase()}function _isModifier(key){return"shift"==key||"ctrl"==key||"alt"==key||"meta"==key}function _pickBestAction(key,modifiers,action){return action="keypress"==(action=action||(function(){if(!_REVERSE_MAP)for(var key in _REVERSE_MAP={},_MAP)95<key&&key<112||_MAP.hasOwnProperty(key)&&(_REVERSE_MAP[_MAP[key]]=key);return _REVERSE_MAP}()[key]?"keydown":"keypress"))&&modifiers.length?"keydown":action}function _getKeyInfo(combination,action){for(var key,modifiers=[],keys=function(combination){return"+"===combination?["+"]:(combination=combination.replace(/\+{2}/g,"+plus")).split("+")}(combination),i=0;i<keys.length;++i)key=keys[i],_SPECIAL_ALIASES[key]&&(key=_SPECIAL_ALIASES[key]),action&&"keypress"!=action&&_SHIFT_MAP[key]&&(key=_SHIFT_MAP[key],modifiers.push("shift")),_isModifier(key)&&modifiers.push(key);return{key:key,modifiers:modifiers,action:action=_pickBestAction(key,modifiers,action)}}function Mousetrap(targetElement){var self=this;if(targetElement=targetElement||document,!(self instanceof Mousetrap))return new Mousetrap(targetElement);self.target=targetElement,self._callbacks={},self._directMap={};var _resetTimer,_sequenceLevels={},_ignoreNextKeyup=!1,_ignoreNextKeypress=!1,_nextExpectedAction=!1;function _resetSequences(doNotReset){doNotReset=doNotReset||{};var key,activeSequences=!1;for(key in _sequenceLevels)doNotReset[key]?activeSequences=!0:_sequenceLevels[key]=0;activeSequences||(_nextExpectedAction=!1)}function _getMatches(character,modifiers,e,sequenceName,combination,level){var i,matches=[],action=e.type;if(!self._callbacks[character])return[];for("keyup"==action&&_isModifier(character)&&(modifiers=[character]),i=0;i<self._callbacks[character].length;++i){var modifiers1,modifiers2,callback=self._callbacks[character][i];!sequenceName&&callback.seq&&_sequenceLevels[callback.seq]!=callback.level||action!=callback.action||("keypress"!=action||e.metaKey||e.ctrlKey)&&(modifiers1=modifiers,modifiers2=callback.modifiers,modifiers1.sort().join(",")!==modifiers2.sort().join(","))||(modifiers1=!sequenceName&&callback.combo==combination,modifiers2=sequenceName&&callback.seq==sequenceName&&callback.level==level,(modifiers1||modifiers2)&&self._callbacks[character].splice(i,1),matches.push(callback))}return matches}function _fireCallback(callback,e,combo,sequence){self.stopCallback(e,e.target||e.srcElement,combo,sequence)||!1===callback(e,combo)&&(function(e){e.preventDefault?e.preventDefault():e.returnValue=!1}(e),function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}(e))}function _handleKeyEvent(e){"number"!=typeof e.which&&(e.which=e.keyCode);var character=_characterFromEvent(e);character&&("keyup"==e.type&&_ignoreNextKeyup===character?_ignoreNextKeyup=!1:self.handleKey(character,function(e){var modifiers=[];return e.shiftKey&&modifiers.push("shift"),e.altKey&&modifiers.push("alt"),e.ctrlKey&&modifiers.push("ctrl"),e.metaKey&&modifiers.push("meta"),modifiers}(e),e))}function _bindSequence(combo,keys,callback,action){function _increaseSequence(nextAction){return function(){_nextExpectedAction=nextAction,++_sequenceLevels[combo],clearTimeout(_resetTimer),_resetTimer=setTimeout(_resetSequences,1e3)}}function _callbackAndReset(e){_fireCallback(callback,e,combo),"keyup"!==action&&(_ignoreNextKeyup=_characterFromEvent(e)),setTimeout(_resetSequences,10)}for(var i=_sequenceLevels[combo]=0;i<keys.length;++i){var wrappedCallback=i+1===keys.length?_callbackAndReset:_increaseSequence(action||_getKeyInfo(keys[i+1]).action);_bindSingle(keys[i],wrappedCallback,action,combo,i)}}function _bindSingle(combination,callback,action,sequenceName,level){self._directMap[combination+":"+action]=callback;var sequence=(combination=combination.replace(/\s+/g," ")).split(" ");1<sequence.length?_bindSequence(combination,sequence,callback,action):(sequence=_getKeyInfo(combination,action),self._callbacks[sequence.key]=self._callbacks[sequence.key]||[],_getMatches(sequence.key,sequence.modifiers,{type:sequence.action},sequenceName,combination,level),self._callbacks[sequence.key][sequenceName?"unshift":"push"]({callback:callback,modifiers:sequence.modifiers,action:sequence.action,seq:sequenceName,level:level,combo:combination}))}self._handleKey=function(character,modifiers,e){for(var callbacks=_getMatches(character,modifiers,e),doNotReset={},maxLevel=0,processedSequenceCallback=!1,i=0;i<callbacks.length;++i)callbacks[i].seq&&(maxLevel=Math.max(maxLevel,callbacks[i].level));for(i=0;i<callbacks.length;++i)callbacks[i].seq?callbacks[i].level==maxLevel&&(processedSequenceCallback=!0,doNotReset[callbacks[i].seq]=1,_fireCallback(callbacks[i].callback,e,callbacks[i].combo,callbacks[i].seq)):processedSequenceCallback||_fireCallback(callbacks[i].callback,e,callbacks[i].combo);modifiers="keypress"==e.type&&_ignoreNextKeypress;e.type!=_nextExpectedAction||_isModifier(character)||modifiers||_resetSequences(doNotReset),_ignoreNextKeypress=processedSequenceCallback&&"keydown"==e.type},self._bindMultiple=function(combinations,callback,action){for(var i=0;i<combinations.length;++i)_bindSingle(combinations[i],callback,action)},_addEvent(targetElement,"keypress",_handleKeyEvent),_addEvent(targetElement,"keydown",_handleKeyEvent),_addEvent(targetElement,"keyup",_handleKeyEvent)}}("undefined"!=typeof window?window:null,"undefined"!=typeof window?document:null),function(Mousetrap){var _globalCallbacks,_originalStopCallback;Mousetrap&&(_globalCallbacks={},_originalStopCallback=Mousetrap.prototype.stopCallback,Mousetrap.prototype.stopCallback=function(e,element,combo,sequence){return!!this.paused||!_globalCallbacks[combo]&&!_globalCallbacks[sequence]&&_originalStopCallback.call(this,e,element,combo)},Mousetrap.prototype.bindGlobal=function(keys,callback,action){if(this.bind(keys,callback,action),keys instanceof Array)for(var i=0;i<keys.length;i++)_globalCallbacks[keys[i]]=!0;else _globalCallbacks[keys]=!0},Mousetrap.init())}("undefined"!=typeof Mousetrap?Mousetrap:void 0);const DEFAULT_CSS=`/* NOTE:
*
* - Using !important is needed for some styles because otherwise they get
* overriden by the search engine stylesheets
* - Using outline works better than border sometimes because creating the
* border can move other elements, for example the page numbers are moved in
* Google Scholar when highlighting the prev/next buttons.
*/
:root {
--result-outline: 1px solid black;
}
@media (prefers-color-scheme: dark) {
:root {
--result-outline: 1px solid #aaaaaa;
}
}
html[dark], [dark] {
--result-outline: 1px solid #aaaaaa;
}
.wsn-google-focused-link {
position: relative;
/* This is required for the arrow to appear when navigating sub-results, see
* also: https://github.com/infokiller/web-search-navigator/issues/357 */
overflow: visible !important;
}
.wsn-google-focused-link::before,
.wsn-google-focused-map::before,
.wsn-gitlab-focused-link::before,
.wsn-brave-search-focused-link::before,
.wsn-startpage-focused-link::before {
content: "►";
margin-right: 25px;
left: -25px;
position: absolute;
}
.wsn-brave-search-focused-news {
position: relative;
}
.wsn-brave-search-focused-news::before {
content: "►";
top: 5px;
left: -45px;
position: absolute;
}
.wsn-google-focused-image {
outline: var(--result-outline) !important;
/* Images are less visible with a thin outline */
outline-width: 2px;
}
.wsn-google-focused-card,
.wsn-brave-search-focused-card,
.wsn-google-focused-job-card {
border: var(--result-outline) !important;
}
.wsn-google-focused-map,
.wsn-google-card-item,
.wsn-gitlab-focused-group-row {
outline: var(--result-outline) !important;
}
.wsn-google-focused-memex-result {
border: var(--result-outline) !important;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
}
/* Startpage has dark themes where a black outline won't be visible */
.wsn-startpage-focused-link {
outline: 1px solid #435a69 !important;
outline-offset: 3px;
}
.wsn-youtube-focused-video {
outline: var(--result-outline) !important;
outline-offset: 1px;
}
.wsn-youtube-focused-grid-video {
border: var(--result-outline) !important;
}
.wsn-google-scholar-next-page {
/* Using outline works better than border for the Scholar previous/next
* buttons because border moves the page numbers a bit. */
outline: var(--result-outline) !important;
}
.wsn-amazon-focused-item {
outline: var(--result-outline) !important;
outline-offset: 3px;
}
.wsn-amazon-focused-cart-item,
.wsn-amazon-focused-carousel-item {
border: var(--result-outline) !important;
}
.wsn-github-focused-item,
.wsn-github-focused-pagination {
outline: var(--result-outline) !important;
outline-offset: 2px;
}
/* This rule is only used when the "hide outline" option is enabled, and is used
* to disable the website's default search result outlining */
.wsn-no-outline,
.wsn-no-outline:focus {
outline: none;
}`,DEFAULT_KEYBINDINGS={nextKey:["down","j"],previousKey:["up","k"],navigatePreviousResultPage:["left","h"],navigateNextResultPage:["right","l"],navigateKey:["return","space"],navigateNewTabBackgroundKey:["ctrl+return","command+return","ctrl+space"],navigateNewTabKey:["ctrl+shift+return","command+shift+return","ctrl+shift+space"],navigateSearchTab:["a","s"],navigateImagesTab:["i"],navigateVideosTab:["v"],navigateMapsTab:["m"],navigateNewsTab:["n"],navigateShoppingTab:["alt+s"],navigateBooksTab:["b"],navigateFlightsTab:["alt+l"],navigateFinancialTab:["f"],focusSearchInput:["/","escape"],navigateShowAll:["z z"],navigateShowHour:["z h"],navigateShowDay:["z d"],navigateShowWeek:["z w"],navigateShowMonth:["z m"],navigateShowYear:["z y"],toggleSort:["z s"],toggleVerbatimSearch:["z v"],showImagesLarge:["z l"],showImagesMedium:["z e"],showImagesIcon:["z i"]},DEFAULT_OPTIONS={...DEFAULT_KEYBINDINGS,wrapNavigation:!1,autoSelectFirst:!0,hideOutline:!1,delay:0,googleIncludeCards:!0,googleIncludeMemex:!1,googleIncludePlaces:!0,customCSS:DEFAULT_CSS,simulateMiddleClick:!1,customGitlabUrl:"^https://(www.)?\\.*git.*\\."},keybindingStringToArray=kb=>kb.split(",").map(t=>t.trim()),keybindingArrayToString=kb=>kb.join(", ");class BrowserStorage{constructor(storage,defaultValues){this.storage=storage,this.values={},this.defaultValues=defaultValues}load(){return this.storage.get(null).then(values=>{this.values=values;let migrated=!1;for(var[key,value]of Object.entries(this.values))key in DEFAULT_KEYBINDINGS&&!Array.isArray(value)&&(migrated=!0,this.values[key]=keybindingStringToArray(value));if(migrated)return this.save()})}save(){return this.storage.set(this.values)}get(key){var value=this.values[key];return null!=value?value:this.defaultValues[key]}set(key,value){this.values[key]=value}clear(){return this.storage.clear().then(()=>{this.values={}})}getAll(){return{...this.defaultValues,...this.values}}}const STORAGE_KEY="webSearchNavigator";class LocalStorage{constructor(defaultValues){this.values={},this.defaultValues=defaultValues,this.load()}load(){var storedData=localStorage.getItem(STORAGE_KEY);storedData?this.values=JSON.parse(storedData):(this.values={...this.defaultValues},this.save())}save(){localStorage.setItem(STORAGE_KEY,JSON.stringify(this.values))}get(key){var value=this.values[key];return null!=value?value:this.defaultValues[key]}set(key,value){this.values[key]=value,this.save()}clear(){localStorage.removeItem(STORAGE_KEY),this.values={...this.defaultValues}}getAll(){return{...this.defaultValues,...this.values}}}const createSyncedOptions=()=>globalThis.IS_USERSCRIPT?new LocalStorage(DEFAULT_OPTIONS):new BrowserStorage(browser.storage.sync,DEFAULT_OPTIONS);class ExtensionOptions{constructor(){this.sync=createSyncedOptions(),globalThis.IS_USERSCRIPT?this.local=createSyncedOptions():this.local=new BrowserStorage(browser.storage.local,{lastQueryUrl:null,lastFocusedIndex:0})}load(){return Promise.all([this.local.load(),this.sync.load()])}}class SearchResult{#element;#anchorSelector;#highlightedElementSelector;#containerSelector;constructor(element,anchorSelector,highlightClass,highlightedElementSelector,containerSelector){this.#element=element,this.#anchorSelector=anchorSelector,this.highlightClass=highlightClass,this.#highlightedElementSelector=highlightedElementSelector,this.#containerSelector=containerSelector}get anchor(){return this.#anchorSelector?this.#anchorSelector(this.#element):this.#element}get container(){return this.#containerSelector?this.#containerSelector(this.#element):this.#element}get highlightedElement(){return this.#highlightedElementSelector?this.#highlightedElementSelector(this.#element):this.#element}}const getSortedSearchResults=(includedSearchResults,excludedNodeList=[])=>{var excludedResultsSet=new Set;for(const node of excludedNodeList)excludedResultsSet.add(node);var searchResults=[];for(const results of includedSearchResults)for(const node of results.nodes){var searchResult=new SearchResult(node,results.anchorSelector,results.highlightClass,results.highlightedElementSelector,results.containerSelector),anchor=searchResult.anchor;null==anchor||excludedResultsSet.has(anchor)||null===anchor.offsetParent||(excludedResultsSet.add(anchor),searchResults.push(searchResult))}return searchResults.sort((a,b)=>{a=a.anchor.compareDocumentPosition(b.anchor);return a&Node.DOCUMENT_POSITION_FOLLOWING?-1:a&Node.DOCUMENT_POSITION_PRECEDING?1:0}),searchResults},getFixedSearchBoxTopMargin=(searchBoxContainer,element)=>!searchBoxContainer||searchBoxContainer.contains(element)?0:searchBoxContainer.getBoundingClientRect().height,isFirefox=()=>0<=navigator.userAgent.toLowerCase().indexOf("firefox"),getDefaultBottomMargin=element=>28,selectorElementGetter=selector=>()=>document.querySelector(selector),nParent=(element,n)=>{for(;0<n&&element;)element=element.parentElement,n--;return element},debounce=(callback,delayMs)=>{let timeoutId;return(...args)=>{clearTimeout(timeoutId),timeoutId=setTimeout(()=>callback(...args),delayMs)}};class GoogleSearch{constructor(options){this.options=options}get urlPattern(){return/^https:\/\/(www\.)?google\./}get searchBoxSelector(){return"form[role=search] [name=q]"}getTopMargin(element){return getFixedSearchBoxTopMargin(document.querySelector("#searchform.minidiv"),element)}getBottomMargin(element){return isFirefox()?0:getDefaultBottomMargin()}onChangedResults(callback){var container;return GoogleSearch.#isImagesTab()?GoogleSearch.#onImageSearchResults(callback):this.options.googleIncludeMemex?GoogleSearch.#onMemexResults(callback):void((container=document.querySelector("#rcnt"))&&new MutationObserver(debounce((mutationsList,observer)=>{callback(!0)},50)).observe(container,{attributes:!1,childList:!0,subtree:!0}))}static#isImagesTab(){return"isch"===new URLSearchParams(window.location.search).get("tbm")}static#getImagesTabResults(){var includedElements=[{nodes:document.querySelectorAll('.islrc a[data-nav="1"]'),highlightClass:"wsn-google-focused-image"},{nodes:document.querySelectorAll('#islmp [type="button"]'),highlightClass:"wsn-google-focused-image"}];return getSortedSearchResults(includedElements,[])}static#regularResults(){return[{nodes:document.querySelectorAll("#search .r > a:first-of-type"),highlightClass:"wsn-google-focused-link",containerSelector:n=>n.parentElement.parentElement},{nodes:document.querySelectorAll("#search .r g-link > a:first-of-type"),highlightClass:"wsn-google-focused-link",containerSelector:n=>n.parentElement.parentElement},{nodes:document.querySelectorAll('#botstuff a[href^="/search"][href*="start="] h3'),highlightClass:"wsn-google-focused-link",anchorSelector:n=>n.closest("a")},{nodes:document.querySelectorAll("#botstuff a h3"),highlightClass:"wsn-google-focused-link",containerSelector:n=>nParent(n,5),highlightedElementSelector:n=>nParent(n,5),anchorSelector:n=>n.closest("a")},{nodes:document.querySelectorAll(".xpdopen .g a"),highlightClass:"wsn-google-focused-link",highlightedElementSelector:n=>n.querySelector("h3")},{nodes:document.querySelectorAll('h3 a[href*="youtube.com"]'),highlightClass:"wsn-google-focused-link",highlightedElementSelector:n=>n.closest("h3")},{nodes:document.querySelectorAll("#search h3 a:first-of-type"),highlightClass:"wsn-google-focused-link",highlightedElementSelector:n=>n.closest("h3"),containerSelector:n=>n.closest("tr")},{nodes:document.querySelectorAll("#rso a h4"),anchorSelector:n=>n.closest("a"),highlightClass:"wsn-google-focused-card",highlightedElementSelector:n=>n.closest(".sh-dgr__content")},{nodes:document.querySelectorAll("#search g-card a"),highlightClass:"wsn-google-focused-link"},{nodes:document.querySelectorAll('#search a:is([href*="ibp=htl;jobs"],[href*="htivrt=jobs"]) [role=heading][aria-level="2"]'),anchorSelector:n=>n.closest("a"),highlightClass:"wsn-google-focused-job-card"},{nodes:document.querySelectorAll('#search li a[href*="htivrt=jobs"]'),highlightedElementSelector:n=>n.closest("li"),highlightClass:"wsn-google-focused-job-card"},{nodes:document.querySelectorAll("#search [data-hveid] a h3"),anchorSelector:n=>n.closest("a"),containerSelector:n=>n.closest("[data-hveid]"),highlightedElementSelector:n=>n.closest("[data-hveid]"),highlightClass:"wsn-google-focused-link"},{nodes:document.querySelectorAll("#pnprev, #pnnext"),highlightClass:"wsn-google-card-item"}]}static#cardResults(){var nearestChildOrSiblingOrParentAnchor=element=>{var childAnchor=element.querySelector("a");return childAnchor&&childAnchor.href||(childAnchor=element.parentElement.querySelector("a"))&&childAnchor.href?childAnchor:element.closest("a")},nearestCardContainer=element=>element.closest("g-inner-card");return[{nodes:document.querySelectorAll("#search [data-init-vis=true] [role=heading]"),anchorSelector:nearestChildOrSiblingOrParentAnchor,highlightedElementSelector:nearestCardContainer,highlightClass:"wsn-google-focused-card"},{nodes:document.querySelectorAll("#search [role=text] [role=heading]"),anchorSelector:nearestChildOrSiblingOrParentAnchor,highlightClass:"wsn-google-focused-link"},{nodes:document.querySelectorAll("#search video-voyager a [role=heading]"),anchorSelector:nearestChildOrSiblingOrParentAnchor,containerSelector:nearestChildOrSiblingOrParentAnchor,highlightedElementSelector:nearestChildOrSiblingOrParentAnchor,highlightClass:"wsn-google-focused-link"},{nodes:document.querySelectorAll("#search g-scrolling-carousel g-inner-card a [role=heading]"),anchorSelector:nearestChildOrSiblingOrParentAnchor,containerSelector:nearestCardContainer,highlightedElementSelector:nearestCardContainer,highlightClass:"wsn-google-card-item"},{nodes:document.querySelectorAll("#search a.a-no-hover-decoration [role=heading]"),anchorSelector:nearestChildOrSiblingOrParentAnchor,containerSelector:nearestChildOrSiblingOrParentAnchor,highlightedElementSelector:nearestChildOrSiblingOrParentAnchor,highlightClass:"wsn-google-focused-link"},{nodes:document.querySelectorAll("td a [role=heading]"),anchorSelector:nearestChildOrSiblingOrParentAnchor,containerSelector:n=>n.closest("td"),highlightedElementSelector:n=>n.closest("td"),highlightClass:"wsn-google-card-item"},{nodes:document.querySelectorAll("a [role=heading]"),anchorSelector:nearestChildOrSiblingOrParentAnchor,containerSelector:nearestChildOrSiblingOrParentAnchor,highlightedElementSelector:nearestChildOrSiblingOrParentAnchor,highlightClass:"wsn-google-card-item"}]}static#placesResults(){var nodes=document.querySelectorAll(".vk_c a");let map,links=nodes;null!=nodes[0]&&nodes[0].querySelector("img")&&(map=nodes[0],links=Array.from(nodes).slice(1));nodes=[];return null!=map&&nodes.push({nodes:[map],highlightedElementSelector:n=>n.parentElement,highlightClass:"wsn-google-focused-map"}),nodes.push({nodes:links,highlightClass:"wsn-google-focused-link"}),nodes}static#memexResults(){return[{nodes:document.querySelectorAll("#memexResults ._3d3zwUrsb4CVi1Li4H6CBw a"),highlightClass:"wsn-google-focused-memex-result"}]}getSearchResults(){var includedElements,excludedElements;return GoogleSearch.#isImagesTab()?GoogleSearch.#getImagesTabResults():(includedElements=GoogleSearch.#regularResults(),this.options.googleIncludeCards&&includedElements.push(...GoogleSearch.#cardResults()),this.options.googleIncludePlaces&&includedElements.push(...GoogleSearch.#placesResults()),this.options.googleIncludeMemex&&includedElements.push(...GoogleSearch.#memexResults()),excludedElements=document.querySelectorAll([".related-question-pair a","#search .kp-blk:not(.c2xzTb) .r > a:first-of-type","#rhs a"].join(", ")),getSortedSearchResults(includedElements,excludedElements))}static#onImageSearchResults(callback){var container=document.querySelector(".islrc");container&&new MutationObserver(debounce((mutationsList,observer)=>{callback(!0)},50)).observe(container,{attributes:!1,childList:!0,subtree:!1})}static#onMemexResults(callback){var container=document.querySelector("#rhs");container&&new MutationObserver(debounce((mutationsList,observer)=>{null!=document.querySelector("#memexResults")&&callback(!0)},50)).observe(container,{attributes:!1,childList:!0,subtree:!0})}static#imageSearchTabs(){return{navigateSearchTab:document.querySelectorAll(".T47uwc > a")[0],navigateMapsTab:selectorElementGetter('.T47uwc > a[href*="maps.google."]'),navigateVideosTab:selectorElementGetter('.T47uwc > a[href*="&tbm=vid"]'),navigateNewsTab:selectorElementGetter('.T47uwc > a[href*="&tbm=nws"]'),navigateShoppingTab:selectorElementGetter('a[role="menuitem"][href*="&tbm=shop"]'),navigateBooksTab:selectorElementGetter('a[role="menuitem"][href*="&tbm=bks"]'),navigateFlightsTab:selectorElementGetter('a[role="menuitem"][href*="&tbm=flm"]'),navigateFinancialTab:selectorElementGetter('a[role="menuitem"][href*="/finance?"]')}}get previousPageButton(){return GoogleSearch.#isImagesTab()?null:selectorElementGetter("#pnprev")}get nextPageButton(){return GoogleSearch.#isImagesTab()?null:selectorElementGetter("#pnnext")}get tabs(){return GoogleSearch.#isImagesTab()?GoogleSearch.#imageSearchTabs():{navigateSearchTab:selectorElementGetter('a[href*="/search?q="]:not([href*="&tbm="]):not([href*="maps.google."])'),navigateImagesTab:selectorElementGetter('a[href*="&tbm=isch"]'),navigateVideosTab:selectorElementGetter('a[href*="&tbm=vid"]'),navigateMapsTab:selectorElementGetter('a[href*="maps.google."]'),navigateNewsTab:selectorElementGetter('a[href*="&tbm=nws"]'),navigateShoppingTab:selectorElementGetter('a[href*="&tbm=shop"]'),navigateBooksTab:selectorElementGetter('a[href*="&tbm=bks"]'),navigateFlightsTab:selectorElementGetter('a[href*="&tbm=flm"]'),navigateFinancialTab:selectorElementGetter('[href*="/finance?"]')}}changeTools(period){var searchParams=new URLSearchParams(window.location.search),allTbsValues=searchParams.getAll("tbs"),allTbsValues=allTbsValues[allTbsValues.length-1]||"",allTbsValues=/(qdr:.|li:1)(,sbd:.)?/.exec(allTbsValues),currentPeriod=allTbsValues&&allTbsValues[1]||"",allTbsValues=allTbsValues&&allTbsValues[2]||"";if("a"===period)searchParams.delete("tbs");else if(period){let newTbs="";newTbs="v"===period?"li:1"===currentPeriod?"":"li:1":"qdr:"+period,searchParams.set("tbs",""+newTbs+allTbsValues)}else currentPeriod&&searchParams.set("tbs",currentPeriod+(allTbsValues?"":",sbd:1"));period="?"+searchParams.toString();return period!==window.location.search&&(window.location.search=period),!1}changeImageSize(size){const sizeOptions_LARGE={value:0,name:"Large",code:"l"},sizeOptions_MEDIUM={value:1,name:"Medium",code:"e"},sizeOptions_ICON={value:2,name:"Icon",code:"i"};var openTool=document.querySelector('[class="PNyWAd ZXJQ7c"][jsname="I4bIT"]'),openTool=(null!=openTool&&openTool.click(),document.querySelector('[aria-label="Size"]')),dropDownWithSize=(null!=openTool&&openTool.click(),document.querySelector('[class="xFo9P r9PaP Fmo8N"][jsname="wLFV5d"]'));const getButton=selector=>{let button;return button=null!=document.querySelector(selector)?document.querySelector(selector):null};var setImageSize=(dropDownWithSize,buttonSelector)=>{let button=getButton(buttonSelector);null==dropDownWithSize&&null!=button?button.click():null!=dropDownWithSize&&null==button?(dropDownWithSize.click(),(button=getButton(buttonSelector)).click()):null!=dropDownWithSize&&null!=button&&button.click()};switch(size){case sizeOptions_LARGE.code:null!=dropDownWithSize&&dropDownWithSize.getAttribute("aria-label")==sizeOptions_LARGE.name||setImageSize(dropDownWithSize,'[class="MfLWbb"][aria-label="Large"]');break;case sizeOptions_MEDIUM.code:null!=dropDownWithSize&&dropDownWithSize.getAttribute("aria-label")==sizeOptions_MEDIUM.name||setImageSize(dropDownWithSize,'[class="MfLWbb"][aria-label="Medium"]');break;case sizeOptions_ICON.code:null!=dropDownWithSize&&dropDownWithSize.getAttribute("aria-label")==sizeOptions_ICON.name||setImageSize(dropDownWithSize,'[class="MfLWbb"][aria-label="Icon"]')}}}class BraveSearch{constructor(options){this.options=options}get urlPattern(){return/^https:\/\/search\.brave\.com/}get searchBoxSelector(){return".form-input, input[id=searchbox]"}getTopMargin(element){return getFixedSearchBoxTopMargin(document.querySelector("header.navbar"),element)}onChangedResults(callback){var containers=document.querySelectorAll("#results"),observer=new MutationObserver(debounce((mutationsList,observer)=>{callback(!0)},50));for(const container of containers)observer.observe(container,{attributes:!1,childList:!0,subtree:!0})}static#getNewsTabResults(){var includedElements=[{nodes:document.querySelectorAll(".snippet a"),highlightClass:"wsn-brave-search-focused-news",containerSelector:n=>n.parentElement}];return getSortedSearchResults(includedElements)}static#getVideosTabResults(){var includedElements=[{nodes:document.querySelectorAll(".card a"),highlightClass:"wsn-brave-search-focused-card",highlightedElementSelector:n=>n.closest(".card"),containerSelector:n=>n.parentElement}];return getSortedSearchResults(includedElements)}getSearchResults(){var includedElements;return BraveSearch.#isTabActive(this.tabs.navigateNewsTab)?BraveSearch.#getNewsTabResults():BraveSearch.#isTabActive(this.tabs.navigateVideosTab)?BraveSearch.#getVideosTabResults():(includedElements=[{nodes:document.querySelectorAll(".snippet.fdb > a"),highlightClass:"wsn-brave-search-focused-link",containerSelector:n=>n.parentElement},{nodes:document.querySelectorAll('.card[data-type="news"]:nth-child(-n+3)'),highlightClass:"wsn-brave-search-focused-card"},{nodes:document.querySelectorAll('.card[data-type="videos"]:nth-child(-n+3)'),highlightClass:"wsn-brave-search-focused-card"}],getSortedSearchResults(includedElements))}static#isTabActive(tab){return tab&&tab.parentElement.classList.contains("active")}get tabs(){return{navigateSearchTab:document.querySelector('a[href*="/search?q="]'),navigateImagesTab:document.querySelector("#tab-images > a:first-of-type"),navigateNewsTab:document.querySelector('a[href*="/news?q="]'),navigateVideosTab:document.querySelector("#tab-videos > a:first-of-type")}}}class StartPage{constructor(options){this.options=options}get urlPattern(){return/^https:\/\/(www\.)?startpage\./}get searchBoxSelector(){return"#q"}getTopMargin(element){return getFixedSearchBoxTopMargin(document.querySelector("div.layout-web__header"),element)}getBottomMargin(element){return isFirefox()?0:getDefaultBottomMargin()}static#isSearchTab(){return null!=document.querySelector("div.layout-web")}static#isImagesTab(){return null!=document.querySelector("div.layout-images")}getSearchResults(){var containerSelector,excludedElements;return StartPage.#isImagesTab()?[]:(containerSelector=element=>StartPage.#isSearchTab()?element.closest(".w-gl__result"):element,containerSelector=[{nodes:document.querySelectorAll("a.w-gl__result-url"),highlightedElementSelector:containerSelector,highlightClass:"wsn-startpage-focused-link",containerSelector:containerSelector},{nodes:document.querySelectorAll(".pagination--desktop button"),highlightClass:"wsn-startpage-focused-link"},{nodes:document.querySelectorAll(".vo-sp.vo-sp--default > a.vo-sp__link"),highlightedElementSelector:containerSelector,highlightClass:"wsn-startpage-focused-link"}],excludedElements=document.querySelectorAll("button[disabled]"),getSortedSearchResults(containerSelector,excludedElements))}get previousPageButton(){var menuLinks=document.querySelectorAll(".inline-nav-menu__link");return!menuLinks||menuLinks.length<4?null:document.querySelector("form.pagination__form.next-prev-form--desktop:first-of-type")}get nextPageButton(){var menuLinks=document.querySelectorAll(".inline-nav-menu__link");return!menuLinks||menuLinks.length<4?null:document.querySelector("form.pagination__form.next-prev-form--desktop:last-of-type")}get tabs(){var menuLinks=document.querySelectorAll(".inline-nav-menu__link");return!menuLinks||menuLinks.length<4?{}:{navigateSearchTab:menuLinks[0],navigateImagesTab:menuLinks[1],navigateVideosTab:menuLinks[2],navigateNewsTab:menuLinks[3]}}changeTools(period){var forms=document.forms;let timeForm;for(let i=0;i<forms.length;i++)"search-filter-time__form"===forms[i].className&&(timeForm=forms[i]);switch(period){case"d":timeForm.elements.with_date[1].click();break;case"w":timeForm.elements.with_date[2].click();break;case"m":timeForm.elements.with_date[3].click();break;case"y":timeForm.elements.with_date[4].click()}}}class YouTube{constructor(options){this.options=options,this.gridNavigation=!1}get urlPattern(){return/^https:\/\/(www)\.youtube\./}get searchBoxSelector(){return"input#search"}getTopMargin(element){return getFixedSearchBoxTopMargin(document.querySelector("#masthead-container"),element)}onChangedResults(callback){const YT_CONTAINER_SELECTOR=["ytd-section-list-renderer",".ytd-section-list-renderer","ytd-rich-grid-renderer","ytd-shelf-renderer"].join(","),resultsObserver=new MutationObserver(debounce((mutationsList,observer)=>{callback(!0)},50));let lastLoadedURL=null;new MutationObserver(debounce((mutationsList,observer)=>{var url=window.location.pathname+window.location.search;if(url!==lastLoadedURL){resultsObserver.disconnect();var containers=document.querySelectorAll(YT_CONTAINER_SELECTOR);if(0!=containers.length){lastLoadedURL=url,callback(!1);for(const container of containers)resultsObserver.observe(container,{attributes:!1,childList:!0,subtree:!0})}}},50)).observe(document.querySelector("#page-manager"),{attributes:!1,childList:!0,subtree:!0})}getSearchResults(){var includedElements=[{nodes:document.querySelectorAll("a#video-title.ytd-video-renderer"),highlightClass:"wsn-youtube-focused-video",highlightedElementSelector:n=>n.closest("ytd-video-renderer"),containerSelector:n=>n.closest("ytd-video-renderer")},{nodes:document.querySelectorAll('ytd-playlist-renderer a[href*="/playlist"]'),highlightClass:"wsn-youtube-focused-video",highlightedElementSelector:n=>n.closest("ytd-playlist-renderer"),containerSelector:n=>n.closest("ytd-playlist-renderer")},{nodes:document.querySelectorAll("a.ytd-playlist-video-renderer"),highlightClass:"wsn-youtube-focused-video",highlightedElementSelector:n=>n.closest("ytd-playlist-video-renderer"),containerSelector:n=>n.closest("ytd-playlist-video-renderer")},{nodes:document.querySelectorAll("div#content a.ytd-radio-renderer"),highlightClass:"wsn-youtube-focused-video"},{nodes:document.querySelectorAll('ytd-grid-video-renderer a#video-title:not([aria-hidden="true"])'),highlightClass:"wsn-youtube-focused-grid-video",highlightedElementSelector:n=>n.closest("ytd-grid-video-renderer"),containerSelector:n=>n.closest("ytd-grid-video-renderer")}],homePageElements={nodes:document.querySelectorAll("ytd-rich-item-renderer a#video-title-link"),highlightClass:"wsn-youtube-focused-video",highlightedElementSelector:n=>n.closest("ytd-rich-item-renderer"),containerSelector:n=>n.closest("ytd-rich-item-renderer")},includedElements=getSortedSearchResults([...includedElements,homePageElements],[]),homePageElements=Array.from(homePageElements.nodes).some(n=>null!=n.offsetParent),gridRow=document.querySelector("ytd-rich-grid-row");return homePageElements&&null!=gridRow&&(includedElements.itemsPerRow=gridRow.getElementsByTagName("ytd-rich-item-renderer").length,includedElements.gridNavigation=0<includedElements.itemsPerRow),includedElements}changeTools(period){document.querySelector("div#collapse-content")||((toggleButton=document.querySelectorAll("a.ytd-toggle-button-renderer")[0]).click(),toggleButton.click());var toggleButton,forms=document.querySelectorAll("div#collapse-content > *:first-of-type ytd-search-filter-renderer");let neededForm=null;switch(period){case"h":neededForm=forms[0];break;case"d":neededForm=forms[1];break;case"w":neededForm=forms[2];break;case"m":neededForm=forms[3];break;case"y":neededForm=forms[4]}neededForm&&neededForm.childNodes[1].click()}}class GoogleScholar{constructor(options){this.options=options}get urlPattern(){return/^https:\/\/scholar\.google\./}get searchBoxSelector(){return"#gs_hdr_tsi"}getSearchResults(){var includedElements=[{nodes:document.querySelectorAll(".gs_rt a"),highlightClass:"wsn-google-focused-link",highlightedElementSelector:n=>n.closest(".gs_rt"),containerSelector:n=>n.parentElement.parentElement},{nodes:document.querySelectorAll(".gs_ico_nav_previous, .gs_ico_nav_next"),anchorSelector:n=>n.parentElement,highlightClass:"wsn-google-scholar-next-page",highlightedElementSelector:n=>n.parentElement.children[1],containerSelector:n=>n.parentElement.children[1]}];return getSortedSearchResults(includedElements,[])}get previousPageButton(){var previousPageElement=document.querySelector(".gs_ico_nav_previous");return null!==previousPageElement?previousPageElement.parentElement:null}get nextPageButton(){var nextPageElement=document.querySelector(".gs_ico_nav_next");return null!==nextPageElement?nextPageElement.parentElement:null}}class Amazon{constructor(options){this.options=options}get urlPattern(){return/^https:\/\/(www\.)?amazon\./}get searchBoxSelector(){return"#twotabsearchtextbox"}onChangedResults(callback){var container=document.querySelector(".s-main-slot");container&&new MutationObserver(debounce((mutationsList,observer)=>{callback(!1)},50)).observe(container,{attributes:!1,childList:!0,subtree:!1})}getSearchResults(){var includedElements=[{nodes:document.querySelectorAll(".s-main-slot .a-carousel-card h2 .a-link-normal.a-text-normal"),highlightedElementSelector:n=>n.closest(".a-carousel-card"),highlightClass:"wsn-amazon-focused-carousel-item",containerSelector:n=>n.closest(".a-carousel-card")},{nodes:document.querySelectorAll(".s-main-slot h2 .a-link-normal.a-text-normal"),highlightedElementSelector:n=>n.closest(".a-section").parentElement.closest(".a-section"),highlightClass:"wsn-amazon-focused-item",containerSelector:n=>n.closest(".a-section").parentElement.closest(".a-section")},{nodes:document.querySelectorAll("a.s-pagination-item"),highlightClass:"wsn-amazon-focused-item"},{nodes:document.querySelectorAll(".sc-list-item-content .a-list-item .a-link-normal"),highlightClass:"wsn-amazon-focused-cart-item",highlightedElementSelector:n=>n.closest(".sc-list-item-content"),containerSelector:n=>n.closest(".sc-list-item-content")}],excludedElements=document.querySelectorAll('.a-pagination .a-selected a, .a-carousel-card[aria-hidden="true"] a');return getSortedSearchResults(includedElements,excludedElements)}get previousPageButton(){return document.querySelector("a.s-pagination-previous")}get nextPageButton(){return document.querySelector("a.s-pagination-next")}}class Github{constructor(options){this.options=options}get urlPattern(){return/^https:\/\/(www\.)?github\.com/}get searchBoxSelector(){return'input[name="q"]'}static#getCommitSearchLinks(){var commits=[];for(const con of document.querySelectorAll("#commit_search_results .text-normal")){var links=con.querySelectorAll("a");0!==links.length&&(1===links.length?commits.push(links[0]):null!=(links=con.querySelector('a[data-hovercard-type="pull_request"]'))&&commits.push(links))}return commits}getSearchResults(){var includedElements=[{nodes:document.querySelectorAll(".repo-list a"),highlightClass:"wsn-github-focused-item",containerSelector:n=>n.closest(".mt-n1")},{nodes:document.querySelectorAll("#code_search_results .text-normal a"),highlightClass:"wsn-github-focused-item"},{nodes:Github.#getCommitSearchLinks(),highlightClass:"wsn-github-focused-item"},{nodes:document.querySelectorAll("#issue_search_results .text-normal a"),highlightClass:"wsn-github-focused-item"},{nodes:document.querySelectorAll("#marketplace_search_results .text-normal a"),highlightClass:"wsn-github-focused-item"},{nodes:document.querySelectorAll("#topic_search_results .text-normal a"),highlightClass:"wsn-github-focused-item"},{nodes:document.querySelectorAll("#wiki_search_results .text-normal a"),highlightClass:"wsn-github-focused-item"},{nodes:document.querySelectorAll("#user_search_results .text-normal a"),highlightClass:"wsn-github-focused-item"},{nodes:document.querySelectorAll(".pinned-item-list-item-content span.repo"),highlightClass:"wsn-github-focused-item",highlightedElementSelector:n=>n.closest("a"),containerSelector:n=>n.closest("a"),anchorSelector:n=>n.closest("a")},{nodes:document.querySelectorAll('#user-repositories-list a[itemprop*="codeRepository"]'),highlightClass:"wsn-github-focused-item",containerSelector:n=>n.closest("li")||n},{nodes:document.querySelectorAll(".paginate-container a"),highlightClass:"wsn-github-focused-pagination"}],excludedElements=("stars"===new URLSearchParams(window.location.search).get("tab")&&includedElements.push({nodes:document.querySelectorAll("h3 a"),highlightClass:"wsn-github-focused-item"}),[...document.querySelectorAll(".muted-link, .Link--muted"),...document.querySelectorAll(".topic-tag")]);return getSortedSearchResults(includedElements,excludedElements)}onChangedResults(callback){var container=document.querySelector("body");if(container){let lastURL=window.location.href;new MutationObserver(debounce((mutationsList,observer)=>{let appendOnly=!0;window.location.href!==lastURL&&(lastURL=window.location.href,appendOnly=!1),callback(appendOnly)},50)).observe(container,{attributes:!1,childList:!0,subtree:!1})}}get tabs(){return{}}}class Gitlab{constructor(options){this.options=options}get urlPattern(){return/^https:\/\/(www\.)?gitlab\.com/}get searchBoxSelector(){return".form-input, input[id=search]"}getTopMargin(element){return getFixedSearchBoxTopMargin(document.querySelector("header.navbar"),element)}onChangedResults(callback){var containers=document.querySelectorAll(".projects-list, .groups-list, #content-body"),observer=new MutationObserver(async(mutationsList,observer)=>{callback(!0)});for(const container of containers)observer.observe(container,{attributes:!1,childList:!0,subtree:!0})}getSearchResults(){var includedElements=[{nodes:document.querySelectorAll("li.project-row h2 a"),containerSelector:n=>n.closest("li.project-row"),highlightedElementSelector:n=>n.closest("li.project-row"),highlightClass:"wsn-gitlab-focused-group-row"},{nodes:document.querySelectorAll("ul.groups-list li.group-row a[aria-label]"),containerSelector:n=>n.closest("li.group-row"),highlightedElementSelector:n=>n.closest("li.group-row"),highlightClass:"wsn-gitlab-focused-group-row"},{nodes:document.querySelectorAll("li.page-item a.page-link"),containerSelector:n=>n.closest("li.page-item"),highlightedElementSelector:n=>n.closest("li.group-row"),highlightClass:"wsn-gitlab-focused-group-row"}];return getSortedSearchResults(includedElements)}}class CustomGitlab extends Gitlab{get urlPattern(){return new RegExp(this.options.customGitlabUrl)}}const getSearchEngine=options=>{var searchEngines=[new GoogleSearch(options),new BraveSearch(options),new StartPage(options),new YouTube(options),new GoogleScholar(options),new Amazon(options),new Github(options),new Gitlab(options),new CustomGitlab(options)],href=window.location.href;for(let i=0;i<searchEngines.length;i++)if(href.match(searchEngines[i].urlPattern))return searchEngines[i];return null},FOCUS_SCROLL_OFF=0,FOCUS_SCROLL_ON=1,FOCUS_SCROLL_ONLY=2,scrollToElement=(searchEngine,element)=>{if(null!=element){let topMargin=0,bottomMargin=(searchEngine.getTopMargin&&(topMargin=searchEngine.getTopMargin(element)),getDefaultBottomMargin());searchEngine.getBottomMargin&&(bottomMargin=searchEngine.getBottomMargin(element));var searchEngine=element.getBoundingClientRect(),scrollY=window.scrollY;return searchEngine.top<topMargin?(element.scrollIntoView(!0),window.scrollBy(0,-topMargin)):searchEngine.bottom+bottomMargin>window.innerHeight&&(element.scrollIntoView(!1),window.scrollBy(0,bottomMargin)),.01<Math.abs(window.scrollY-scrollY)}console.error("Cannot scroll to null element")},bindKeys=(bindings,toggle)=>{bindings.sort((a,b)=>b[0].split(" ").length-a[0].split(" ").length);let lastEvent,lastHandlerResult;for(const[shortcut,element,global,callback]of bindings){var wrappedCallback=event=>!toggle.active||(event!==lastEvent||lastHandlerResult?(lastEvent=event,lastHandlerResult=callback(event)):void 0);global?Mousetrap(element).bindGlobal(shortcut,wrappedCallback):Mousetrap(element).bind(shortcut,wrappedCallback)}};class SearchResultsManager{constructor(searchEngine,options){this.searchEngine=searchEngine,this.options=options,this.focusedIndex=-1,this.isInitialFocusSet=!1}reloadSearchResults(){this.searchResults=this.searchEngine.getSearchResults(),this.isInitialFocusSet||this.setInitialFocus()}setInitialFocus(){var lastNavigation;0!==this.searchResults.length&&(lastNavigation=this.options.local.values,location.href===lastNavigation.lastQueryUrl&&0<=lastNavigation.lastFocusedIndex&&lastNavigation.lastFocusedIndex<this.searchResults.length?this.focus(lastNavigation.lastFocusedIndex,FOCUS_SCROLL_ON):this.options.sync.get("autoSelectFirst")&&this.focus(0,FOCUS_SCROLL_OFF))}getElementToNavigate(linkOnly=!1){var isLink,focusedElement=document.activeElement;return null==focusedElement||"body"===focusedElement.localName?this.focusedIndex<0||this.focusedIndex>=this.searchResults.length?null:this.searchResults[this.focusedIndex].anchor:(isLink="a"===focusedElement.localName&&focusedElement.hasAttribute("href"),!linkOnly||isLink?focusedElement:void 0)}highlight(searchResult){var highlighted=searchResult.highlightedElement;null==highlighted?console.error("No element to highlight: %o",highlighted):(highlighted.classList.add(searchResult.highlightClass),!this.options.sync.get("hideOutline")&&searchResult.anchor===highlighted||searchResult.anchor.classList.add("wsn-no-outline"))}unhighlight(searchResult){var highlighted=searchResult.highlightedElement;null==highlighted?console.error("No element to unhighlight: %o",highlighted):(highlighted.classList.remove(searchResult.highlightClass),highlighted.classList.remove("wsn-no-outline"))}focus(index,scroll=FOCUS_SCROLL_ONLY){if(0<=this.focusedIndex){const searchResult=this.searchResults[this.focusedIndex];if(scroll===FOCUS_SCROLL_ONLY&&scrollToElement(this.searchEngine,searchResult.container))return;this.unhighlight(searchResult)}const searchResult=this.searchResults[index];searchResult?(this.highlight(searchResult),searchResult.anchor.focus({preventScroll:!0}),scroll!==FOCUS_SCROLL_OFF&&scrollToElement(this.searchEngine,searchResult.container),this.focusedIndex=index,this.isInitialFocusSet=!0):this.focusedIndex=-1}focusNext(shouldWrap){this.focusedIndex<this.searchResults.length-1?this.focus(this.focusedIndex+1):shouldWrap&&this.focus(0)}focusPrevious(shouldWrap){0<this.focusedIndex?this.focus(this.focusedIndex-1):shouldWrap?this.focus(this.searchResults.length-1):window.scrollTo(window.scrollX,0)}focusDown(shouldWrap){this.focusedIndex+this.searchResults.itemsPerRow<this.searchResults.length?this.focus(this.focusedIndex+this.searchResults.itemsPerRow):shouldWrap&&(shouldWrap=this.focusedIndex%this.searchResults.itemsPerRow,this.focus(shouldWrap))}focusUp(shouldWrap){0<=this.focusedIndex-this.searchResults.itemsPerRow?this.focus(this.focusedIndex-this.searchResults.itemsPerRow):shouldWrap?(shouldWrap=this.focusedIndex%this.searchResults.itemsPerRow,this.focus(this.searchResults-1-this.searchResults.itemsPerRow+shouldWrap)):window.scrollTo(window.scrollY,0)}}class WebSearchNavigator{constructor(){this.bindings=[],this.bindingsToggle={active:!0}}async init(){var milliseconds;this.options=new ExtensionOptions,await this.options.load(),this.searchEngine=await getSearchEngine(this.options.sync.getAll()),null!=this.searchEngine&&(milliseconds=this.options.sync.get("delay"),await new Promise(resolve=>setTimeout(resolve,milliseconds)),this.injectCSS(),this.initKeybindings())}injectCSS(){var style=document.createElement("style");style.textContent=this.options.sync.get("customCSS"),document.head.append(style)}initKeybindings(){this.bindingsToggle.active=!1;for(var[shortcut,element,,]of this.bindings){element=Mousetrap(element);element.unbind(shortcut),element.reset()}var isFirstCall=0===this.bindings.length;this.bindings=[],window.location.href.match(/^https:\/\/(www)\.youtube\.com\/watch/)||this.initResultsNavigation(isFirstCall),this.initTabsNavigation(),this.initChangeToolsNavigation(),this.initSearchInputNavigation(),this.bindingsToggle={active:!0},bindKeys(this.bindings,this.bindingsToggle)}initSearchInputNavigation(){let searchInput=document.querySelector(this.searchEngine.searchBoxSelector);if(null!=searchInput){const shouldHandleSearchInputKey=event=>event.ctrlKey||event.metaKey||"Escape"===event.key,detectSearchInput=()=>null!=searchInput&&null!=searchInput.offsetParent||null!=(searchInput=document.querySelector(this.searchEngine.searchBoxSelector))&&null!=searchInput.offsetParent;let lastEvent;this.register(this.options.sync.get("focusSearchInput"),event=>{if(detectSearchInput())return event===lastEvent?!shouldHandleSearchInputKey(event):!(!(event=document.activeElement).isContentEditable&&!["textarea","input"].includes(event.tagName.toLowerCase())&&(scrollToElement(this.searchEngine,searchInput),searchInput.select(),1))}),this.register(this.options.sync.get("focusSearchInput"),event=>{if(detectSearchInput()){if(lastEvent=event,shouldHandleSearchInputKey(event)){if(0===searchInput.selectionStart&&searchInput.selectionEnd===searchInput.value.length)return scrollToElement(this.searchEngine,searchInput),searchInput.setSelectionRange(searchInput.value.length,searchInput.value.length),!1;window.setTimeout(()=>searchInput.blur())}return!0}},searchInput,!0)}}registerObject(obj){for(const[optionName,elementOrGetter]of Object.entries(obj))this.register(this.options.sync.get(optionName),()=>{if(null==elementOrGetter)return!0;let element;return null==(element=elementOrGetter instanceof HTMLElement?elementOrGetter:elementOrGetter())||("FORM"==element.tagName?element.submit():element.click(),!1)})}initTabsNavigation(){var tabs=this.searchEngine.tabs||{};this.registerObject(tabs)}initResultsNavigation(isFirstCall){this.registerObject({navigatePreviousResultPage:this.searchEngine.previousPageButton,navigateNextResultPage:this.searchEngine.nextPageButton}),this.resetResultsManager();let gridNavigation=this.resultsManager.searchResults.gridNavigation;this.registerResultsNavigationKeybindings(gridNavigation),isFirstCall&&this.searchEngine.onChangedResults&&this.searchEngine.onChangedResults(appendedOnly=>{appendedOnly?this.resultsManager.reloadSearchResults():this.resetResultsManager(),gridNavigation!=this.resultsManager.searchResults.gridNavigation&&(gridNavigation=this.resultsManager.searchResults.gridNavigation,this.initKeybindings())})}resetResultsManager(){var searchResult;null!=this.resultsManager&&0<=this.resultsManager.focusedIndex&&null!=(searchResult=this.resultsManager.searchResults[this.resultsManager.focusedIndex])&&this.resultsManager.unhighlight(searchResult),this.resultsManager=new SearchResultsManager(this.searchEngine,this.options),this.resultsManager.reloadSearchResults()}registerResultsNavigationKeybindings(gridNavigation){const getOpt=key=>this.options.sync.get(key);var onFocusChange=callback=>()=>{return this.resultsManager.isInitialFocusSet?callback.bind(this.resultsManager)(getOpt("wrapNavigation")):this.resultsManager.focus(0),!1};gridNavigation?(this.register(getOpt("nextKey"),onFocusChange(this.resultsManager.focusDown)),this.register(getOpt("previousKey"),onFocusChange(this.resultsManager.focusUp)),this.register(getOpt("navigatePreviousResultPage"),onFocusChange(this.resultsManager.focusPrevious)),this.register(getOpt("navigateNextResultPage"),onFocusChange(this.resultsManager.focusNext))):(this.register(getOpt("nextKey"),onFocusChange(this.resultsManager.focusNext)),this.register(getOpt("previousKey"),onFocusChange(this.resultsManager.focusPrevious))),this.register(getOpt("navigateKey"),()=>{var lastNavigation,link=this.resultsManager.getElementToNavigate();return null==link||((lastNavigation=this.options.local.values).lastQueryUrl=location.href,lastNavigation.lastFocusedIndex=this.resultsManager.focusedIndex,this.options.local.save(),"a"===link.localName&&link.href?window.location.href=link.href:link.click(),!1)}),this.register(getOpt("navigateNewTabKey"),()=>{var link=this.resultsManager.getElementToNavigate(!0);return null==link||(browser.runtime.sendMessage({type:"tabsCreate",options:{url:link.href,active:!0}}),!1)}),this.register(getOpt("navigateNewTabBackgroundKey"),()=>{var mouseEventParams,middleClickMousedown,link=this.resultsManager.getElementToNavigate(!0);return null==link||(getOpt("simulateMiddleClick")&&(mouseEventParams={bubbles:!0,cancelable:!1,view:window,button:1,which:2,buttons:0,clientX:link.getBoundingClientRect().x,clientY:link.getBoundingClientRect().y},middleClickMousedown=new MouseEvent("mousedown",mouseEventParams),link.dispatchEvent(middleClickMousedown),middleClickMousedown=new MouseEvent("mouseup",mouseEventParams),link.dispatchEvent(middleClickMousedown)),browser.runtime.sendMessage({type:"tabsCreate",options:{url:link.href,active:!1}}),!1)})}initChangeToolsNavigation(){var getOpt;null!=this.searchEngine.changeTools&&(this.register((getOpt=key=>this.options.sync.get(key))("navigateShowAll"),()=>this.searchEngine.changeTools("a")),this.register(getOpt("navigateShowHour"),()=>this.searchEngine.changeTools("h")),this.register(getOpt("navigateShowDay"),()=>this.searchEngine.changeTools("d")),this.register(getOpt("navigateShowWeek"),()=>this.searchEngine.changeTools("w")),this.register(getOpt("navigateShowMonth"),()=>this.searchEngine.changeTools("m")),this.register(getOpt("navigateShowYear"),()=>this.searchEngine.changeTools("y")),this.register(getOpt("toggleVerbatimSearch"),()=>this.searchEngine.changeTools("v")),this.register(getOpt("toggleSort"),()=>this.searchEngine.changeTools(null)),this.register(getOpt("showImagesLarge"),()=>this.searchEngine.changeImageSize("l")),this.register(getOpt("showImagesMedium"),()=>this.searchEngine.changeImageSize("e")),this.register(getOpt("showImagesIcon"),()=>this.searchEngine.changeImageSize("i")))}register(shortcuts,callback,element=document,global=!1){for(const shortcut of shortcuts)this.bindings.push([shortcut,element,global,callback])}}const extension=new WebSearchNavigator;extension.init();
from web-search-navigator.
Probably not too hard, but I have no personal interest in that and I doubt that many users have. Feel free to send a PR.
from web-search-navigator.
@Explosion-Scratch Just tried this and I'm surprised how well it works. Have you got an updated version that fixes the issue with 'i' for the Images tab?
eslint in Tampermonkey shows a lot of warnings and errors?
from web-search-navigator.
Related Issues (20)
- Cannot use J to pass Related Searches on Google SERPs HOT 1
- Doesn't seem to work with Brave Search on Firefox HOT 2
- [Bug] "Focus search box" no longer works HOT 1
- Open tabs in same tab group HOT 4
- Bing Search HOT 3
- [Bug]: Pressing Enter on "More results" in Google loads a page without "More results" HOT 6
- 🗞️ Hackernews Support HOT 2
- Yandex support HOT 3
- FR: Key to copy current link HOT 1
- Auto-scroll such that page view has cursor vertically centred HOT 1
- [Bug]: The arrow is not shown next to the focused result when continuous scrolling is activated HOT 2
- Feature request: Copy selected link HOT 1
- [Bug]: google search open result in new windows always fails , when using web-search-navigator shortcut. HOT 6
- [Bug]: "i" shortcut does nothing on Google search, "a" and "s" both go to images tab instead HOT 5
- Feature request add duckduckgo search support
- [Bug]: i for Images not working (other too possibly) HOT 3
- Focus on a search box without highlighting the text
- [Bug]: Brave search: Cycling through web results doesn't work HOT 2
- DuckDuckGo support
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from web-search-navigator.