// ==UserScript== // @name NoMouseGoogle // @namespace com.gmail.fujifruity.greasemonkey // @version 1.7 // @description Shortcut for Google search results. j/k to move focus, l/h to open in new/background tab. // @author fujifruity // @include https://www.google.com/search* // @grant GM.openInTab // @license MIT // @downloadURL none // ==/UserScript== { const items = [...document.querySelectorAll('#rso div[data-hveid][data-ved]')] const open = inBackground => { const url = findCurrentItem().querySelector('a').href GM.openInTab(url, inBackground) } const tag = "noMouseGoogleCurrentItem" const findCurrentItem = () => items.find(e => e.hasAttribute(tag)) const moveCursor = step => { const currentItem = findCurrentItem() const r = currentItem.getBoundingClientRect(); const isCurrentItemVisible = 0 < r.top && r.top < window.innerHeight || 0 < r.bottom && r.bottom < window.innerHeight if (!isCurrentItemVisible) { const dist = e => { const r = e.getBoundingClientRect() return Math.abs(window.innerHeight - (r.top + r.bottom)) } const nearestItem = items.reduce((acc,e) => dist(acc) < dist(e) ? acc : e ) select(nearestItem) return } const nextIdx = (items.indexOf(currentItem) + step + items.length) % items.length select(items[nextIdx]) } const highlight = e => { const isDarkTheme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches e.style.backgroundColor = isDarkTheme ? '#2a2a2a' : 'WhiteSmoke' } const select = item => { // Deselect current item. const currentItem = findCurrentItem() currentItem?.setAttribute('style', "background-color: null;") currentItem?.removeAttribute(tag) // Select the item. item.setAttribute(tag, '') highlight(item) item.scrollIntoView({ behavior: "smooth", block: "center" }) } // Select the first item without scrolling. items[0].setAttribute(tag, '') highlight(items[0]) window.addEventListener('keydown', event => { if (event.target.tagName == "INPUT" || event.ctrlKey || event.altKey) return if (event.key == 'j') moveCursor(+1) if (event.key == 'k') moveCursor(-1) if (event.key == 'l') open(false) if (event.key == 'h') open(true) }) }