-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from RogueArt/feature/navigation
Update extension to use J and K for navigation instead of number keys
- Loading branch information
Showing
4 changed files
with
101 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' | ||
} |