Last active
September 22, 2023 00:00
-
-
Save drfloob/870e63b9e0ce479d88ab1d9a18886f9e to your computer and use it in GitHub Desktop.
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 Github gRPC status check sort | |
// @namespace https://github.com/ | |
// @version 1.0.2 | |
// @description Sort the status checks on a PR by Required status, Success status (errors first), and then by name | |
// @author hork | |
// @match https://github.com/*/*/pull/* | |
// @icon https://github.githubassets.com/favicons/favicon.svg | |
// @grant none | |
// @updateURL https://gist.github.com/drfloob/870e63b9e0ce479d88ab1d9a18886f9e/raw/github-grpc-status-check-sort.user.js | |
// @downloadURL https://gist.github.com/drfloob/870e63b9e0ce479d88ab1d9a18886f9e/raw/github-grpc-status-check-sort.user.js | |
// ==/UserScript== | |
// Derived from https://gist.github.com/skjnldsv/eb7b894ae996affde4a7d0e00e0d80a1 | |
// Modified for better handling of the github.com/grpc/grpc repo. | |
(function () { | |
'use strict'; | |
const targetNode = document.querySelector('.discussion-timeline-actions') | |
const config = { attributes: false, childList: true, subtree: false } | |
const callback = (mutationList) => { | |
if ([...mutationList[0].removedNodes].length > 0) { | |
// Find all children | |
const container = document.querySelector('.merge-status-list > div.merge-status-item').parentElement | |
const children = Array.prototype.slice.call(container.querySelectorAll('div.merge-status-item'), 0) | |
while (container.firstChild) { | |
container.removeChild(container.firstChild); | |
} | |
// Identify if a check is required | |
function isRequired(el) { | |
const strongEl = el.querySelector('div span.Label--primary'); | |
if (!strongEl) return false; | |
return strongEl.textContent === 'Required'; | |
} | |
function isNotRequired(el) { return !isRequired(el); } | |
// Identify if a check was successful | |
function isSuccess(el) { | |
return el.querySelector('svg.octicon-check') !== undefined; | |
} | |
// Identify if a check is pending | |
function isPending(el) { | |
return el.querySelector('svg.hx_dot-fill-pending-icon') !== undefined; | |
} | |
// Returns the check status in a numeric sortable order | |
function getStatus(el) { | |
// valued by sort order | |
const Status = { | |
Error: 0, | |
Pending: 1, | |
Success: 2 | |
}; | |
if (isSuccess(el)) return Status.Success; | |
if (isPending(el)) return Status.Pending; | |
return Status.Error; | |
} | |
function statusSort(a, b) { | |
const aStatus = getStatus(a); | |
const bStatus = getStatus(b); | |
if (aStatus == bStatus) a.innerText.localeCompare(b.innerText); | |
return aStatus < bStatus; | |
} | |
container.append(...children.filter(isRequired).sort(statusSort)); | |
container.append(...children.filter(isNotRequired).sort(statusSort)); | |
} | |
} | |
const observer = new MutationObserver(callback) | |
observer.observe(targetNode, config) | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment