Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Bookmarklet that will redesigns Redmine for Twitter Bootstrap. NOT for permanent usage OR as a theme JS file. Only to promote better theme support (http://www.redmine.org/issues/9754) for consideration.
// Bookmarklet to alter Redmine theme to look like twitter bootstrap
// Only a concept to test the design
// Suggest you minify first (removing comments), before bookmarking
javascript:(function(e,a,g,h,f,c,b,d){if(!(f=e.jQuery)||g>f.fn.jquery||h(f)){c=a.createElement("script");c.type="text/javascript";c.src="http://ajax.googleapis.com/ajax/libs/jquery/"+g+"/jquery.min.js";c.onload=c.onreadystatechange=function(){if(!b&&(!(d=this.readyState)||d=="loaded"||d=="complete")){h((f=e.jQuery).noConflict(1),b=1);f(c).remove()}};a.documentElement.childNodes[0].appendChild(c)}})(window,document,"1.7.2",function($,L){
// BEGIN
$(function() {
$('link[rel=stylesheet]').remove();
$('head')
.append('<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">');
$('head').append('<style type="text/css">\
.rotate90 {\
-webkit-transform:rotate(90deg);\
-moz-transform:rotate(90deg);\
-ms-transform:rotate(90deg);\
-o-transform:rotate(90deg);\
transform:rotate(90deg);\
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);\
}\
.rotate180 {\
-webkit-transform:rotate(180deg);\
-moz-transform:rotate(180deg);\
-ms-transform:rotate(180deg);\
-o-transform:rotate(180deg);\
transform:rotate(180deg);\
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);\
}\
.rotate270 {\
-webkit-transform:rotate(270deg);\
-moz-transform:rotate(270deg);\
-ms-transform:rotate(270deg);\
-o-transform:rotate(270deg);\
transform:rotate(270deg);\
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);\
}\
.wiki-anchor {\
display: none !important;\
margin-left:6px;\
text-decoration:none;\
}\
</style>');
var navbar = $('<div class="navbar navbar-fixed-top"><div class="navbar-inner"><div class="container"></div></div></div>');
navbar.prependTo(document.body);
var navbarcol = $('<div class="nav-collapse">').appendTo('.container', navbar);
$('#top-menu > ul').addClass('nav').appendTo(navbarcol);
$('#top-menu ul').addClass('nav pull-right').appendTo(navbarcol);
var login = $('#loggedas');
if (login) {
$('<p class="navbar-text pull-right">' + login.html() + '</p>').appendTo(navbarcol);
}
$('#top-menu').remove();
$('<a class="brand" href="#">' + $('#header h1').text() + '</a>').prependTo(navbarcol.parent());
var search = $('#quick-search form').addClass('navbar-search pull-left').appendTo(navbarcol.parent());
$('label', search).remove();
$('input', search).removeClass('small').addClass('search-query span2');
var subnav = $('<div class="navbar"><div class="navbar-inner"><div class="container"><ul class="nav"></ul></div></div></div>').insertAfter(navbar);
$('#main-menu li').appendTo($('ul', subnav));
$('#header').remove();
$('body').css('padding-top', '60px');
$('table.list').addClass('table table-striped table-bordered table-condensed');
var iconTranslate = {
'icon-del': {'icons': 'icon-trash icon-white', 'btn': 'btn-danger'},
'icon-add': {'icons': 'icon-plus-sign', 'btn': 'btn-success'},
'icon-lock': {'icons': 'icon-lock icon-white', 'btn': 'btn-info'},
'icon-time': {'icons': 'icon-clock', 'btn': ''},
'icon-edit': {'icons': 'icon-pencil', 'btn': ''},
'icon-fav': {'icons': 'icon-eye-open', 'btn': ''},
'icon-copy': {'icons': 'icon-camera', 'btn': ''}
};
$('.icon').each(function() {
var el = $(this);
el.removeClass('icon');
var cname = el.attr('class');
if (iconTranslate[cname]) {
el.prepend('<i class="' + iconTranslate[cname].icons + '"></i> ')
.removeClass()
.addClass(iconTranslate[cname].btn);
} else {
el.removeClass();
}
if (el.parent().is('span')) el.unwrap();
});
$('.buttons').css('width', 'auto').wrapInner('<div class="btn-group" />');
$('.buttons a').addClass('btn btn-mini');
var replacements = {
'Move to bottom': 'icon-step-forward rotate90',
'Move to top': 'icon-step-backward rotate90',
'Move down': 'icon-play rotate90',
'Move up': 'icon-play rotate270'
};
$('table td a[title^=Move ]').each(function() {
el = $(this);
el.addClass('btn btn-mini').empty().append('<i class="' + replacements[el.attr('title')] + '"></i>');
if (el.parent().not('div')) {
el.parent().wrapInner('<div class="btn-group"></div>').attr('style', null);
}
});
$('td.checkbox').removeClass('checkbox');
$('a.closed').wrap('<del></del>');
$('div#roadmap .related-issues td:nth-child(1)').css('display', 'none');
$('div.issue').addClass('well');
$('table.attributes').addClass('table');
// --- Side bar ---
var sidenav = $('<div class="well" style="padding:8px 0;"><ul class="nav nav-list"></ul></div>');
var sidenavlist = sidenav.children();
$('#sidebar h3, #sidebar a[href]').each(function() {
var el = $(this);
if (el.is('h3')) {
sidenavlist.append('<li class="nav-header">' + el.html() + '</li>');
el.remove();
} else if (!el.parent().is('h3')) {
sidenavlist.append(el);
el.wrap('<li />');
if (el.hasClass('selected')) {
el.removeClass('selected').parent().addClass('active');
}
}
});
// -- Donation form
var donate = $('#sidebar form').remove();
$('#sidebar').empty().append(sidenav, donate);
var container = $('<div class="container-fluid"></div>').insertAfter(subnav);
var main = $('#main').appendTo(container);
if (main.hasClass('nosidebar')) {
main.removeClass('nosidebar').attr('id', '');
} else {
main.addClass('row-fluid').attr('id', '');
$('#sidebar', main).attr('id', '').addClass('span3');
$('#content', main).attr('id', '').addClass('span9').prependTo(main);
}
// --- Contextual links ---
$('.contextual').each(function() {
el = $(this);
// Remove text inbetween links
var links = $('a', el);//.remove();
//el.html('');
//el.append(links);
el.contents().filter(function() {
return this.nodeType == 3;
}).remove();
links.addClass('btn btn-mini');
el.addClass('btn-group pull-right');
});
// Progress
$('.progress').remove();
$('.pourcent').each(function() {
el = $(this);
$('<div class="progress progress-striped" style="width:40em"><div class="bar" style="width: ' + el.text() + ';"></div></div>').insertBefore(el);
});
$('.progress-info a').each(function() {
var el = $(this);
var txt = el.text().split(' ');
if (txt[1] === 'issues') el.html('<span class="label">')
});
var trackerStyles = {
Defect: 'label label-important',
Feature: 'label label-info',
Patch: 'label label-warning'
};
$('td.tracker').each(function() {
var el = $(this);
if (trackerStyles[el.text()])
el.wrapInner('<span class="' + trackerStyles[el.text()] + '" />');
});
var statusStyles = {
New: 'label label-warning',
Confirmed: 'label label-important',
Assigned: 'label label-info',
Resolved: 'label label-success',
Closed: 'label',
Reopened: 'label label-inverse'
};
$('td.status').each(function() {
var el = $(this);
if (statusStyles[el.text()])
el.wrapInner('<span class="' + statusStyles[el.text()] + '" />');
});
$('td.id').wrapInner('<code />');
$('.pagination').each(function() {
var el = $(this);
for (var i = 0; i < this.childNodes.length; i++) {
if (this.childNodes[i].nodeType === 3) {
txt = $.trim(this.childNodes[i].textContent);
if (txt.match(/^\d+$/)) $('<li class="active"><a href="#">' + txt + '</a></li>').insertAfter(this.childNodes[i]);
else if (txt.match(/^...$/)) $('<li class="disabled"><a href="#">...</a></li>').insertAfter(this.childNodes[i]);
$(this.childNodes[i]).remove();
} else {
$(this.childNodes[i]).wrap('<li></li>');
}
}
el.wrapInner('<div class="pagination"><ul></ul></div>').children().unwrap();
});
// END
});});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment