Skip to content

Instantly share code, notes, and snippets.

@marek-saji
Last active December 12, 2015 06:58
Show Gist options
  • Save marek-saji/4732895 to your computer and use it in GitHub Desktop.
Save marek-saji/4732895 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name PurpleMine
// @namespace http://redmine.holonglobe.com/
// @version 0.1
// @description Few tweaks for #redmine. #userscript
// @match https://redmine.*
// @copyright 2013+, Marek `saji` Augustynowicz
// ==/UserScript==
/**
* Add filter input on activity page.
*/
if (/\/activity/.test(window.location.pathname)) {
console.log("Adding activity filter");
(function () {
var context = document.getElementById("activity");
context.innerHTML = '<input type=search class=activity-filter placeholder=Filter style="width:100%;max-width:20em;font-size:2em;">' + context.innerHTML;
context.querySelector('.activity-filter').addEventListener("input", function () {
var regex = new RegExp(this.value, 'im');
Array.prototype.forEach.call(context.querySelectorAll('dd'), function (dd) {
var dt = dd.previousElementSibling,
// this allows searches like "changeset[^]*(#13|#42)[^]*john"
matches = regex.test(dt.getAttribute("class") + dt.textContent + dd.textContent),
display = matches ? 'block' : 'none';
if (dt.style.display !== display) {
dt.style.display = dd.style.display = display;
}
});
}, false);
}());
} // if activity
/**
* Mix-in changesets into issue history.
*/
if (/\/issues\/[0-9]/.test(window.location.pathname)) {
console.log("Adding activity filter");
(function () {
/**
* Get sortable date of an entry
*/
function getEntryDate (entry) {
var dateElement = entry && entry.querySelector('a[href*="/activity?"][title]');
return dateElement && dateElement.title;
}
/**
* Get gravatar for element containing link to a user
*/
function getGravatar (element) {
// look for a gravatar to the same user on the page
var i,
author = element.querySelector('a[href^="/users/"]'),
otherLinks = document.querySelectorAll('.journal:not(.changeset) a[href="' + author.getAttribute('href') + '"]'),
otherGravatar;
for (i = 0 ; i < otherLinks.length ; i++) {
otherGravatar = otherLinks[i].parentNode.querySelector('img.gravatar');
if (otherGravatar) {
return otherGravatar.src;
}
}
// fallback: transparent 1x1px git
return "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
}
var changesetsContainer = document.getElementById('issue-changesets'),
changesets = changesetsContainer.querySelectorAll('.changeset'),
history = document.getElementById('history'),
journals = history.querySelectorAll('.journal'),
jIdx = 0,
journalDate = getEntryDate(journals[jIdx]),
revLinkRegEx = /repository/;
Array.prototype.forEach.call(changesets, function (changeset) {
var newEntry = document.createElement('div'),
changesetDate = getEntryDate(changeset),
metadatas = changeset.querySelector('p'),
author = metadatas.querySelector('.author'),
header = document.createElement('h4');
changeset.classList.remove('odd');
changeset.style.fontFamily = 'Consolas, Source Code Pro, Courier New, monospace';
Array.prototype.forEach.call(metadatas.childNodes, function (metadata) {
if (metadata.tagName && 'BR' !== metadata.tagName) {
header.appendChild(metadata);
if (revLinkRegEx.test(metadata.href)) {
metadata.style.float = "right";
} else if (metadata.classList.contains("author")) {
metadata.innerHTML = '<img class="gravatar" width="24" height="24" src="' + getGravatar(metadata) + '"> ' + metadata.innerHTML;
}
}
});
metadatas.remove();
newEntry.classList.add('changeset');
newEntry.classList.add('journal');
newEntry.appendChild(header);
newEntry.appendChild(changeset);
history.appendChild(newEntry);
while (journalDate && journalDate < changesetDate) {
jIdx++;
journalDate = getEntryDate(journals[jIdx]);
}
if (journalDate) {
journals[jIdx].parentNode.insertBefore(newEntry, journals[jIdx]);
} else {
history.appendChild(newEntry);
}
});
changesetsContainer.remove();
}());
} // if issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment