Skip to content

Instantly share code, notes, and snippets.

@rossinek
Created August 26, 2021 21:02
Show Gist options
  • Save rossinek/99b84d984771ae510f237747efd3e265 to your computer and use it in GitHub Desktop.
Save rossinek/99b84d984771ae510f237747efd3e265 to your computer and use it in GitHub Desktop.
Harvest (time tracking) arrow navigation
// Browser extension
// - Firefox: https://addons.mozilla.org/pl/firefox/addon/shark-javascript-injector/
// - Other browsers (source code): https://github.com/rossinek/javascript-injector-webextension
// Options:
// - hosts: https://*.harvestapp.com/time*
// - uses shortcuts
const isVisible = (elem) => {
if (!elem) return true;
return window.getComputedStyle(elem, null).getPropertyValue('display') !== 'none'
&& isVisible(elem.parentElement);
};
const getDaysList = () => {
const allElements = [...document.querySelectorAll('.js-week-nav a')];
return allElements.filter(isVisible);
};
const getProjectsList = () => {
const allElements = [...document.querySelectorAll('button.js-edit-entry')];
return allElements.filter(isVisible);
};
const nextElem = (getElems) => (event) => {
const elems = getElems();
const focused = elems.find((el) => el === document.activeElement);
const toFocus = focused ? elems[(elems.indexOf(focused) + 1) % elems.length] : elems[0];
if (toFocus) {
toFocus.focus();
event.preventDefault();
}
};
const prevElem = (getElems) => (event) => {
const elems = getElems();
const focused = elems.find((el) => el === document.activeElement);
const toFocus = focused
? elems[(elems.indexOf(focused) - 1 + elems.length) % elems.length]
: elems[elems.length - 1];
if (toFocus) {
toFocus.focus();
event.preventDefault();
}
};
const prevDay = () => {
const button = document.querySelectorAll('a.js-navigate-by-url')[0]
button && button.click()
}
const nextDay = () => {
const button = document.querySelectorAll('a.js-navigate-by-url')[1]
button && button.click()
}
ShortcutService.registerShortcut('arrowright', {
handler: nextDay,
preventOnInputs: true,
})
ShortcutService.registerShortcut('arrowleft', {
handler: prevDay,
preventOnInputs: true,
})
ShortcutService.registerShortcut('arrowdown', {
handler: nextElem(getProjectsList),
preventOnInputs: true,
})
ShortcutService.registerShortcut('arrowup', {
handler: prevElem(getProjectsList),
preventOnInputs: true,
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment