Skip to content

Commit

Permalink
Merge pull request #1 from RogueArt/feature/navigation
Browse files Browse the repository at this point in the history
Update extension to use J and K for navigation instead of number keys
  • Loading branch information
RogueArt authored Sep 8, 2021
2 parents 77fa350 + 6b6f735 commit cf86089
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 80 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dev
32 changes: 19 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,31 @@ keyboard shortcuts and navigation to Google search.

# Features

Shortcuts are not active when focused on the search bar.
To use shortcuts, go to [Google search](https://www.google.com/) and click
anywhere on the page away from the search bar. Shortcuts DO NOT work when
focused on the search bar.

- `\`: Expands all "People also search for" questions
- `0-9`: Will take you to the top level link corresponding to the number pressed
- `Shift + 0-9`: Will take you to nth "People also search for" link, where n is
the number pressed

Note: Pressing 0 is the same as indicating you want to go to the 10th link
Shortcuts:
- `j` - Move one search result up
- `k` - Move one search result down
- `Enter` - Navigates current tab to the link
- `Shift+Enter` - Opens a new window with the link
- `Ctrl+Enter` - Opens new tab in background for the highlighted link

# Installation

This extension is in development, so you can follow installation guidelines for
an unpacked extension for Chrome and Firefox.
This plugin can be found in the Firefox add-ons and Chrome extensions pages.

For developers, please follow the instructions for loading an unpacked extension
onto Firefox or Google Chrome.

# TO-DO

- Shortcut to navigate between links
- Add support for different Google domains (e.g. co.ca, co.in)
- Add some sort of tooltip indicating what number each link is
- Figure out solution to deal with more than 10 links on page
- Improve README with installation guidelines, link to extension
- Highlight whole box rather than just the link
- Allow navigation by pressing a number on the keyboard
- Add a super element to indicate what number each link is
- Improve README with installation guidelines
- Clean up code by splitting functions into separate files via modules
- Add `Shift+L` to open all "People also ask links"
- Improve README with installation guidelines, link to extension
4 changes: 2 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Google Search Shortcuts",
"description": "Keyboards to make searching on Google faster",
"version": "1.0",
"description": "Keyboard shortcuts to make searching on Google faster",
"version": "0.1.0",
"manifest_version": 2,
"content_scripts": [
{
Expand Down
144 changes: 79 additions & 65 deletions script.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,99 @@
function getTopLevelLinks() {
return Array.from(document.querySelectorAll('a > h3'))
let links = filterRelatedQuestionLinks(getAllTopLevelLinks())

let index = 0
setFocus(links[0])

// Check if focused on search bar
function focusedOnSearchBar() {
return document.activeElement.tagName === 'INPUT'
}

function getRelatedQuestionIndex() {
// Get all the links on the page
const allLinkNodes = getTopLevelLinks()
const questionLinkNodes = getRelatedQuestionLinks()
document.addEventListener('keydown', async event => {
const { key } = event

// Index to splice from is where first node is equal
const index = allLinkNodes.findIndex(node => node === questionLinkNodes[0])
// Don't do anything if on search bar
if (focusedOnSearchBar()) return

// Return index and how many elements to splice
return [index, questionLinkNodes.length]
}
// Make sure we can access all 10 questions
if (links.length < 10) {
links = filterRelatedQuestionLinks(getAllTopLevelLinks())
}

function getRelatedQuestionLinks() {
// Get all the related questions as nodes, convert to array from NodeList
const questionPairNodes = document.querySelectorAll('.related-question-pair')
const questionPairArr = Array.from(questionPairNodes)
// Go to link above
if (key === 'j') {
if (index === 0) return

// Return only the links
return questionPairArr.map(node => node.querySelector('a > h3'))
}
// Reset style of current
resetFocus(links[index])
setFocus(links[index - 1])

// Decrease index by one
index -= 1

// Scroll to top if hit first link
if (index === 0) window.scrollTo(0, 0)
}

// Go to link below
if (key === 'k') {
if (index === links.length - 1) return

// Get only links that aren't the related question pair links
function getVisibleTopLevelLinks() {
const [idx, len] = getRelatedQuestionIndex()
resetFocus(links[index])
setFocus(links[index + 1])
index += 1

// Remove len elements starting at idx
const topLevelLinks = getTopLevelLinks()
topLevelLinks.splice(idx, len)
// Scroll to bottom if hit first link
// if (index === links.length - 1) window.scrollTo(0, document.body.scrollHeight)
}
})

// Gets all top level links in the page
function getAllTopLevelLinks() {
const links = Array.from(document.querySelectorAll('a'))
const topLevelLinks = links.filter(link => {
return link.querySelector('h3') !== null
})
return topLevelLinks
}

// <============= UTILS =============>
// Check if focused on search bar
function focusedOnSearchBar() {
return document.activeElement.tagName === 'INPUT'
}
// Filter out related question links
function filterRelatedQuestionLinks(links) {
// Get all related questions that pop up on Google
const relatedQuestionDiv = Array.from(
document.querySelectorAll('.related-question-pair')
)

function convertKeyToIndex(key) {
// Convert to int, subtract one for index
const input = parseInt(key)
// Return links directly if no related questions
if (relatedQuestionDiv.length === 0) return links

// Return 10 if it's equal to 0
return input === 0 ? 10 : input
}
// Get the first link within one of these divs
const firstRelatedLink = relatedQuestionDiv[0].querySelector('a')

document.addEventListener('keydown', event => {
// Do nothing if focused on search bar
if (focusedOnSearchBar()) return
// Get the first related link's index in our array
const firstRelatedLinkIdx = links.findIndex(node => node === firstRelatedLink)

// Get what key was pressed and if shift pressed
const { key, shiftKey } = event
// Trim as many related questions there are
const trimAmount = relatedQuestionDiv.length
links.splice(firstRelatedLinkIdx, trimAmount)

// Return if key is not a number or isn't backslash
const keyIsNumber = !isNaN(parseInt(key))
const keyIsBackslash = key === '\\'
if (!keyIsNumber && !keyIsBackslash) return
// Return the filtered links
return links
}

// Case 1: Pressed shift + number
if (shiftKey && keyIsNumber) {
const relatedLinks = getRelatedQuestionLinks()
const index = convertKeyToIndex(key)
relatedLinks[index - 1].click()
}
// Sets the link back to white
function resetFocus(link) {
const textNode = link.getElementsByTagName('h3')[0]
textNode.style.fontWeight = ''
textNode.style.textDecoration = ''
}

// Case 2: Pressed a number
else if (keyIsNumber) {
const visibleLinks = getVisibleTopLevelLinks()
const index = convertKeyToIndex(key)
visibleLinks[index - 1].click()
}
// Sets the link back to red
function setFocus(link, goingDown) {
const { top } = link.getBoundingClientRect()
console.log('top :>> ', top)
window.scrollTo(0, top + window.scrollY + (goingDown ? 50 : -50))

// Case 3: Pressed backslash \
else if (keyIsBackslash) {
// Get all related questions and expand them
const relatedQuestions = document.querySelectorAll(
'.related-question-pair > div > div'
)
relatedQuestions.forEach(question => question.click())
}
})
const textNode = link.getElementsByTagName('h3')[0]
textNode.style.fontWeight = 'bold'
textNode.style.textDecoration = 'underline'
}

0 comments on commit cf86089

Please sign in to comment.