Last active
January 9, 2023 15:22
-
-
Save Ivanca/a90848f8ee4d7f62e939630013e214d8 to your computer and use it in GitHub Desktop.
Userscript: Rewind Commands For Ultimate-guitar Web Player
This file contains hidden or 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
// ==UserScript== | |
// @name Rewind Commands For Ultimate-guitar Web Player | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description Use Enter Key to Rewind, twice for current section, great to use with a USB Pedal | |
// @author Ivan Castellanos | |
// @match https://tabs.ultimate-guitar.com/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=ultimate-guitar.com | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
function isPlaying() { | |
const buttons = getPlayerButtons(); | |
return getComputedStyle(buttons[2]).background.startsWith('rgb(68, 219, 94)'); | |
} | |
function getPlayerButtons() { | |
return [...document.querySelectorAll('article > div > section button')].filter( | |
e => window.innerHeight - e.getBoundingClientRect().top < 100 | |
); | |
} | |
function simulateClick(element, x = 0, y = 0) { | |
const clickEvent = new MouseEvent('click', { | |
currentTarget: element, | |
view: window, | |
bubbles: true, | |
cancelable: true, | |
clientX: x, | |
clientY: y, | |
nativeEvent: { | |
clientX: x, | |
clientY: y | |
} | |
}); | |
element.dispatchEvent(clickEvent); | |
} | |
let timeoutId = null; | |
function handleKeypress(e) { | |
if (e.key !== 'Enter') { | |
return; | |
} | |
if (timeoutId == null) { | |
timeoutId = setTimeout(() => { | |
restartFromSelection(); | |
timeoutId = null; | |
}, 600); | |
} else { | |
goToStartOfCurrentPart(); | |
clearTimeout(timeoutId); | |
timeoutId = null; | |
} | |
} | |
function restartFromSelection() { | |
const [, restartBtn, playBtn] = getPlayerButtons(); | |
const playing = isPlaying() | |
simulateClick(restartBtn); | |
simulateClick(playBtn); | |
if (playing) { | |
// This is because we need to pause then unpause to get the coundown feature to work | |
setTimeout(e => simulateClick(playBtn), 10); | |
} | |
} | |
function goToStartOfCurrentPart() { | |
const playing = isPlaying(); | |
const playButton = getPlayerButtons()[2]; | |
const playHead = document.querySelector('.XXwY0'); | |
const headOffset = parseFloat(playHead.style.transform.replace(/[^\d.]+/g, '')); | |
const headOffsetAsPercent = headOffset / playHead.parentElement.offsetWidth * 100; | |
const allParts = [...document.querySelectorAll('.XCWM7')]; | |
const clientRect = playHead.parentElement.getBoundingClientRect(); | |
let clickOffsetPercent = 0; | |
for (let index = 0; index < allParts.length; index++) { | |
const nextPartOffset = clickOffsetPercent + parseFloat(allParts[index].style.width); | |
if (nextPartOffset > headOffsetAsPercent) { | |
break; | |
} | |
clickOffsetPercent = nextPartOffset; | |
} | |
let clientXClick = playHead.parentElement.offsetWidth * clickOffsetPercent / 100 + clientRect.left; | |
let clientYClick = clientRect.top + 1; | |
simulateClick(playHead.parentElement, clientXClick, clientYClick); | |
simulateClick(playButton); | |
if (playing) { | |
// This is because we need to pause then unpause to get the coundown feature to work | |
setTimeout(() => simulateClick(playButton), 10); | |
} | |
} | |
document.addEventListener('keypress', handleKeypress); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment