Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Userscript Version #564

Open
Explosion-Scratch opened this issue Oct 10, 2023 · 2 comments · May be fixed by #565
Open

Userscript Version #564

Explosion-Scratch opened this issue Oct 10, 2023 · 2 comments · May be fixed by #565

Comments

@Explosion-Scratch
Copy link

Self explanatory. Installing more extensions clutters the browser, a userscript version would be pretty easy to build using CI or something right?

@infokiller
Copy link
Owner

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.

@Explosion-Scratch Explosion-Scratch linked a pull request Oct 12, 2023 that will close this issue
@Explosion-Scratch
Copy link
Author

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();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants