Skip to content

Instantly share code, notes, and snippets.

@knl
Last active March 30, 2021 03:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save knl/7ea46ca2ba17649d62c96103fe5fc438 to your computer and use it in GitHub Desktop.
Save knl/7ea46ca2ba17649d62c96103fe5fc438 to your computer and use it in GitHub Desktop.
Greasemonkey user script to link back to JIRA from GitHub
// ==UserScript==
// @name GitHub/JIRA Links
// @namespace http://github.com/knl
// @author knl
// @version 1.2.2
// @description Link to JIRA tickets from Github
// @match https://github.com/**
// @run-at document-end
// @noframes
// @grant none
// ==/UserScript==
const jiraUrl = "https://dfinity.atlassian.net";
const issueRegExp = /\b((?:[A-Z]+|M1)\-[0-9]+)\b/g;
function doIt(node) {
// we actually iterate over the whole document now
document.querySelectorAll("p, pre, h1, span, td").forEach(function(elem) {
const tagsRe = /(<(?:.|\n)+?>|&\\w+;)/;
// track if we are in the same link, and prevent replacement
var insideOurLink = false;
// This goes through the inner content of the element, and then
// makes sure it only replaces the visible content. Using plain 'replace'
// would possibly replace the href of a link or any other attribute of an
// element.
// To avoid this, the code splits the inner HTML by tags, and leaves tags
// untouched, while modifying all the other content, which should be text
// in this case.
// In order to avoid recursion with our own links, we keep track of the
// location in 'insideOurLink'.
const htmlParts = elem.innerHTML.split(tagsRe);
const r = htmlParts.map((item) => {
if (tagsRe.test(item)) {
if (item.startsWith(`<a class="github-jira-link"`) || item.startsWith(`<a class="issue-link`)) {
insideOurLink = true;
}
if (item === "</a>") {
insideOurLink = false;
};
return item;
} else {
return insideOurLink ? item : item.replace(issueRegExp, `<a class="github-jira-link" href="${jiraUrl}/browse/$1">$1</a>`);
}
}).join('');
elem.innerHTML = r;
});
}
/* Wait for selected elements to appear on the page and process them */
function waitForKeyElements (
selectorTxt, /* Required: The selector string that specifies the desired element(s). */
actionFunction, /* Required: The code to run when elements are found. Gets a node to the matched element. */
) {
document.querySelectorAll(selectorTxt).forEach(function(node) {
var alreadyFound = node.alreadyFound || false;
if (!alreadyFound) {
//--- Call the payload function.
actionFunction(node);
node.alreadyFound = true;
}
});
var timeControl = waitForKeyElements.timeControl;
//--- Set a timer, if needed.
if (!timeControl) {
timeControl = setInterval(function () {
waitForKeyElements(selectorTxt, actionFunction);
},
1000
);
waitForKeyElements.timeControl = timeControl;
}
}
waitForKeyElements ("#commits_bucket, #discussion_bucket, #files_bucket, .subnav, .repository-content", doIt);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment