Skip to content

Instantly share code, notes, and snippets.

@phdd
Last active January 2, 2018 23:43
Show Gist options
  • Select an option

  • Save phdd/f3e8cf831c1c0b6fe324 to your computer and use it in GitHub Desktop.

Select an option

Save phdd/f3e8cf831c1c0b6fe324 to your computer and use it in GitHub Desktop.
Enhance Trello-cards with markdown based description with this Greasemonkey script.
// ==UserScript==
// @name Trello Card Enhancer
// @namespace https://gist.github.com/phdd/f3e8cf831c1c0b6fe324
// @description Enhance cards with markdown based description
// @copyright 2015+, Peter Heisig
// @version 1.3
// @updateURL https://gist.githubusercontent.com/raw/f3e8cf831c1c0b6fe324/trello-card-enhancer.js
//
// @match https://trello.com/*
// @match https://*.trello.com/*
//
// @require https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
// @require https://api.trello.com/1/client.js?key=5fd1b9324345b17684be897ba58c5752
// @require https://raw.github.com/sizzlemctwizzle/GM_config/master/gm_config.js
//
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
//
// ==/UserScript==
GM_registerMenuCommand('Trello Card Enhancer Settings', function() {
GM_config.open();
});
GM_config.init({
'id': 'TrelloCardEnhancer',
'fields': {
'ListWidth': {
'label': 'Board list width',
'type': 'int',
'default': '270'
},
'LogoutAction': {
'label': 'Disconnect Trello',
'type': 'button',
'size': 100,
'click': Trello.deauthorize
}
},
'events': {
'save': function () { initialize(); GM_config.close(); },
'reset': initialize
}
});
function initializeCss() {
var width = GM_config.get('ListWidth');
GM_addStyle('.list-card .markeddown li { margin-left: 0px !important; }');
GM_addStyle('.list-card .markeddown ul,' +
'.list-card .markeddown ol { margin-left: 20px !important; }');
GM_addStyle('.list { width: ' + width + 'px !important; max-width: ' + width + 'px !important; flex: 0 0 ' + width + 'px !important; }');
GM_addStyle('.list-wrapper { width: ' + width + 'px !important; }');
GM_addStyle('.list-card { max-width: ' + width + 'px !important; }');
GM_addStyle('.list-card img { max-width: 100% !important; }');
}
function enhanceCard(response, idMap) {
var card = idMap[idFromShortUrl(response.shortUrl)];
var markdown = "### " + response.name + "\n" + response.desc;
$(card).html(marked(markdown));
}
function enhanceCards(idMap) {
$($('.icon-description')).parent().remove();
$('.list-card-title').each(function(index, item) {
$(item).addClass('markeddown');
});
var urls = [];
for (var id in idMap) {
urls.push("/cards/" + id);
}
Trello.get('batch', { gmRequest: true, urls: urls.join(',') }, function(responses) {
$(responses).each(function(index, response) {
enhanceCard(response[200], idMap);
});
});
}
function initializeCards() {
var idMap = {};
$('.list-card-title[href]').each(function(index, item) {
var path = $(item).attr('href');
var cardId = idFromShortPath(path);
idMap[cardId] = item;
});
enhanceCards(idMap);
}
function initialize() {
initializeCss();
initializeCards();
}
function authorize() {
Trello.authorize({
name: 'Card Enhancer',
type: 'popup',
success: initialize
});
}
function isBoardPage() {
return window.location.href.match(/trello\.com\/b\//);
}
function enhance() {
if (!Trello.authorized()) {
authorize();
} else {
initialize();
}
}
$(document).ready(function() {
if (isBoardPage()) {
enhance();
}
});
function idFromShortPath(path) {
return path.split('/')[2];
}
function idFromShortUrl(url) {
return url.split('/')[4];
}
function updateFrom(response) {
if (defined(response.shortUrl)) {
var shortId = idFromShortUrl(response.shortUrl);
if (typeof response.id !== "undefined") {
var card = $(".list-card-title[href*='" + shortId + "']")[0];
var idMap = {};
idMap[shortId] = card;
enhanceCards(idMap);
}
}
}
function defined(val) {
return typeof val !== "undefined";
}
function monitor(request, args) {
if ( request.responseURL.match(/\/1\/cards/) &&
!request.responseURL.match(/gmRequest=true/)
) {
var response = $.parseJSON(request.responseText);
if (defined(response)) {
updateFrom(response);
}
} else if (request.responseURL.match(/markAsViewed/)) {
initializeCards();
}
}
(function() {
var proxied = window.XMLHttpRequest.prototype.send;
window.XMLHttpRequest.prototype.send = function() {
var sendArguments = arguments;
//Here is where you can add any code to process the request.
//If you want to pass the Ajax request object, pass the 'pointer' below
var pointer = this;
var intervalId = window.setInterval(function() {
if (pointer.readyState != 4) {
return;
}
if (pointer.status == 200) {
monitor(pointer, sendArguments);
}
//Here is where you can add any code to process the response.
//If you want to pass the Ajax request object, pass the 'pointer' below
clearInterval(intervalId);
}, 1); //I found a delay of 1 to be sufficient, modify it as you need.
return proxied.apply(this, [].slice.call(arguments));
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment