Last active
May 10, 2025 20:51
-
-
Save tinder-tannerbennett/7ab2091184dbad71f5387cca3960e65f to your computer and use it in GitHub Desktop.
Tampermonkey userscripts for github.com that I use for work
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 pull/:id/files helpers (Approve PR) | |
// @namespace http://tampermonkey.net/ | |
// @version 1.0 | |
// @description Automatically clicks the "Review Changes" and "Approve" buttons on key press (\) | |
// @author Tanner Bennett | |
// @match https://github.com/TinderApp/tinder_ios/pull/*/files | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=github.com | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
function click(element) { | |
if (element) element.click(); | |
} | |
document.addEventListener('keydown', function(event) { | |
// Skip modifier keys | |
if (event.ctrlKey || event.altKey || event.metaKey) { | |
return; | |
} | |
// Abort if a text field is active | |
if (event.target.tagName === 'TEXTAREA' || event.target.tagName === 'INPUT') { | |
return; | |
} | |
// Go to back to conversation | |
if (event.key === 'b') { | |
click(document.querySelector('a[href^="/TinderApp/tinder_ios/pull/"]')) | |
} | |
// Approve PR | |
if (event.key === '\\') { | |
const button = document.getElementById('overlay-show-review-changes-modal'); | |
if (button) { | |
button.click(); | |
const radio = document.getElementById('pull_request_review[event]_approve'); | |
if (radio) { | |
radio.click(); | |
const button = document.querySelector('button.Button--primary.Button--small.Button.float-left'); | |
if (button) { | |
button.click(); | |
} | |
} | |
} | |
} | |
}); | |
})(); |
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 pull/:id helpers | |
// @namespace http://tampermonkey.net/ | |
// @version 1.0 | |
// @description Keyboard shortcuts for the GitHub PR page (pull/:id) | |
// @author Tanner Bennett | |
// @match https://github.com/TinderApp/tinder_ios/pull/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=github.com | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// A little jquery lite kinda API | |
function matches(el, text) { | |
return el && el.textContent.trim() === text; | |
} | |
function $(elOrSelector, selector) { | |
let target = elOrSelector; | |
// Case: only given a selector, use document | |
if (typeof elOrSelector === 'string') { | |
target = document; | |
selector = elOrSelector; | |
} | |
// Case: given an object and a selector | |
else { | |
selector = selector || ''; | |
} | |
if (target.querySelector) { | |
return target.querySelector(selector); | |
} | |
return undefined; | |
} | |
function find(selector, where) { | |
const list = Array.from(document.querySelectorAll(selector)); | |
return where ? list.find(where) : list; | |
} | |
function findByText(selector, text) { | |
return find(selector, el => { | |
const innerSpan = el.querySelector('span[data-component="text"]'); | |
return matches(innerSpan, text); | |
}); | |
} | |
function findByTextAll(selector, text) { | |
return Array.from(document.querySelectorAll(selector)).filter(el => { | |
const innerSpan = el.querySelector('span[data-component="text"]'); | |
return innerSpan && innerSpan.textContent.trim() === text; | |
}); | |
} | |
function gh_buttonByInnerText(text) { | |
return find('button span[data-component="text"]', btn => matches(btn, text)); | |
} | |
function click(element) { | |
if (element) element.click(); | |
} | |
function scrollToEndOfPage() { | |
window.scrollTo(0, document.body.scrollHeight); | |
} | |
document.addEventListener('keydown', function(event) { | |
// Skip modifier keys | |
if (event.ctrlKey || event.altKey || event.metaKey) { | |
return; | |
} | |
// Abort if a text field is active | |
if (event.target.tagName === 'TEXTAREA' || event.target.tagName === 'INPUT') { | |
return; | |
} | |
// Ready for review / merge when ready | |
// Press r repeatedly to hit each of the 3 buttons below | |
if (event.key === 'r') { | |
scrollToEndOfPage(); | |
// Find the button by the inner text of the innermost span | |
click(gh_buttonByInnerText('Ready for review')); | |
click(gh_buttonByInnerText('Merge when ready')); | |
click(gh_buttonByInnerText('Confirm merge when ready')); | |
} | |
// Go to changed files | |
if (event.key === 'f') { | |
click($('a[href$="/files"][href*="/pull/"]')) | |
} | |
// On shift + x, click "Close pull request" | |
if (event.key === 'X') { | |
scrollToEndOfPage(); | |
click($('button[name="comment_and_close"]')); // Close pull request | |
click(gh_buttonByInnerText('Delete branch')); | |
} | |
// Copy some text in this format: | |
// @codeowner1 @codeowner2 | |
// [PR title](PR URL) `+X -Y` | |
if (event.key === 'c') { | |
const prTitle = $('.js-issue-title.markdown-title'); | |
const prUrl = window.location.href; | |
const prDiffText = $('.diffstat').innerText.trim(); | |
// Codeowners buttons look like this: | |
/* <button name="button" type="button" id="codeowner-TinderApp/revenue-growth-ios" class="mr-2 btn-link muted-icon" aria-labelledby="tooltip-8cc9d586-5932-4bd5-9b62-4f9081d93b0e"> */ | |
const codeownersButtons = find('button[id^="codeowner-"]'); | |
const codeowners = Array.from(codeownersButtons).map(button => { | |
const id = button.id; | |
const codeowner = id.split('TinderApp/')[1]; | |
return `@${codeowner}`; | |
}); | |
// Copy to clipboard | |
const msg = `${codeowners.join(' ')}\n[${prTitle.innerText.trim()}](${prUrl}) \`${prDiffText}\``; | |
navigator.clipboard.writeText(msg); | |
console.log('Copied to clipboard:\n', msg); | |
} | |
}); | |
})(); |
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 SSO Helper | |
// @namespace http://tampermonkey.net/ | |
// @version 1.0 | |
// @description Trigger the SSO 'Continue' button with any keypress | |
// @author Tanner Bennett | |
// @match https://github.com/TinderApp/tinder_ios/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=gotinder.com | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
function $(elOrSelector, selector) { | |
let target = elOrSelector; | |
// Case: only given a selector, use document | |
if (typeof elOrSelector === 'string') { | |
target = document; | |
selector = elOrSelector; | |
} | |
// Case: given an object and a selector | |
else { | |
selector = selector || ''; | |
} | |
if (target.querySelector) { | |
return target.querySelector(selector); | |
} | |
return undefined; | |
} | |
function matches(el, text) { | |
return el && el.textContent.trim() === text; | |
} | |
function find(selector, where) { | |
const list = Array.from(document.querySelectorAll(selector)); | |
return where ? list.find(where) : list; | |
} | |
function gh_buttonByInnerText(text) { | |
return find('button', btn => matches(btn, text)); | |
} | |
function click(element) { | |
if (element) element.click(); | |
} | |
document.addEventListener('keydown', function(event) { | |
// Skip modifier keys | |
if (event.ctrlKey || event.altKey || event.metaKey) { | |
return; | |
} | |
// Abort if a text field is active | |
if (event.target.tagName === 'TEXTAREA' || event.target.tagName === 'INPUT') { | |
return; | |
} | |
// If we're on the SSO page, click continue on any key press | |
if ($('h1.sso-title')) { | |
click(gh_buttonByInnerText('Continue')); | |
} | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Summary of Features
Continue with SSO Page
/pull/XXXXX
#ios-code-review
/pull/XXXXX/files