Skip to content

Instantly share code, notes, and snippets.

@beccasaurus
Last active December 16, 2015 04:19
Show Gist options
  • Save beccasaurus/5376825 to your computer and use it in GitHub Desktop.
Save beccasaurus/5376825 to your computer and use it in GitHub Desktop.
Copy Rally Link
<html>
<head>
<script src='background.js'></script>
<style>
a#link {
color: #15c;
font-family: arial;
font-size: 13px;
}
</style>
</head>
<body>
<div contenteditable=true>
<a id='link'></a>
</div>
</body>
</html>
chrome.contextMenus.create({
title: 'Copy Rally Link',
type: 'normal',
contexts: ['all'],
onclick: copyRallyLink
});
function copyRallyLink(info, tab) {
chrome.tabs.sendMessage(tab.id, 'getRallyLink', function(link) {
if (link) {
var element = document.getElementById('link');
element.textContent = link.text;
element.setAttribute('href', link.href);
copyElementToClipboard(element);
}
});
}
function copyElementToClipboard(element) {
var textRange = document.createRange();
textRange.setStart(element);
textRange.setEndAfter(element);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(textRange);
document.execCommand('Copy');
}
///// Unrelated test!
window.addEventListener('message', function(e) {
console.log('Rally Copy Link got MESSAGE:');
console.log(e);
});
///////////////////////////////////
// TODO include US/DE number in link text
var clickedElement = null;
document.addEventListener('mousedown', function(e) {
var rightMouseButton = 2;
if (e.button == rightMouseButton)
clickedElement = e.target;
});
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request == 'getRallyLink')
sendResponse(getRallyLink());
});
function getRallyLink() {
var path = document.location.hash;
if (path.indexOf('/oiterationstatus') > -1)
return getIterationStatusLink();
else if (path.indexOf('/detail/') > -1)
return getDetailsPageLink();
}
function getIterationStatusLink() {
var workproductRow = _findParent(clickedElement, 'tr');
var idLink = workproductRow.querySelector('td[class="cn_workproduct.idstring0"] > a');
var nameLink = workproductRow.querySelector('td[class="cn_workproduct.name0"] > a');
return {
href: document.location.origin + '/' + idLink.getAttribute('href'),
text: '[' + idLink.textContent + '] ' + nameLink.textContent
};
}
function getDetailsPageLink() {
var idLabel = _findXPath('//div[@class="field-label"][contains(text(),"ID:")]');
var nameLabel = _findXPath('//div[@class="field-label"][contains(text(),"Name:")]');
var id = _findParent(idLabel, 'tr').querySelector('td').textContent;
var name = _findParent(nameLabel, 'tr').querySelector('td').textContent;
return {
href: document.location.toString(),
text: '[' + id + '] ' + name
};
}
function _findParent(element, selector) {
var node = element;
while (node && (! node.webkitMatchesSelector(selector)))
node = node.parentNode;
return node;
}
function _findXPath(xpath) {
return document.evaluate('.' + xpath, document.body, null, XPathResult.ANY_TYPE, null).iterateNext();
}
{
"name": "Copy Rally Link",
"version": "1.0",
"background": {
"page": "background.html"
},
"content_scripts": [
{
"matches": ["https://rally1.rallydev.com/*"],
"js": ["content.js"]
}
],
"permissions": [
"https://rally1.rallydev.com/*",
"contextMenus",
"clipboardWrite",
"clipboardRead"
],
"manifest_version": 2
}
@beccasaurus
Copy link
Author

This isn't well documented. I was just playing around on the bus. But it adds a context menu that copies an HTML link to a Rally story to your clipboard (only tested in Chrome, obviously) when right-clicking on stories in the iteration view or right-clicking anywhere on the user story's main page. (It probably blows up if you try clicking it anywhere else)

@alon-mallik
Copy link

Hey buddy, thanks I found this Chrome Extension very helpful.

One small fix I had to make - in background.js method copyElementToClipboard line 21, method range.setStart takes two parameters, the element and the start point so should read:

textRange.setStart(element, 0);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment