// Coverage.py HTML report browser code.
/*jslint browser:true, indent: 4 */
/*global coverage:true, document window $ */
coverage = {};
// Find all the elements with shortkey_* class, and use them to assign a shotrtcut key.
coverage.assign_shortkeys = function() {
$("*[class*='shortkey_']").each(function(i, e) {
$.each($(e).attr("class").split(" "), function(i, c) {
if (/^shortkey_/.test(c)) {
$(document).bind('keydown', c.substr(9), function() {
$(e).click();
});
}
});
});
};
// Loaded on index.html
coverage.index_ready = function($) {
// Look for a cookie containing previous sort settings:
var sort_list = [];
var cookie_name = "COVERAGE_INDEX_SORT";
var i;
// This almost makes it worth installing the jQuery cookie plugin:
if (document.cookie.indexOf(cookie_name) > -1) {
var cookies = document.cookie.split(";");
for (i = 0; i < cookies.length; i++) {
var parts = cookies[i].split("=");
if ($.trim(parts[0]) === cookie_name && parts[1]) {
sort_list = eval("[[" + parts[1] + "]]");
break;
}
}
}
// Create a new widget which exists only to save and restore
// the sort order:
$.tablesorter.addWidget({
id: "persistentSort",
// Format is called by the widget before displaying:
format: function(table) {
if (table.config.sortList.length === 0 && sort_list.length > 0) {
// This table hasn't been sorted before - we'll use
// our stored settings:
$(table).trigger('sorton', [sort_list]);
}
else {
// This is not the first load - something has
// already defined sorting so we'll just update
// our stored value to match:
sort_list = table.config.sortList;
}
}
});
// Configure our tablesorter to handle the variable number of
// columns produced depending on report options:
var headers = {};
var col_count = $("table.index > thead > tr > th").length;
headers[0] = { sorter: 'text' };
for (i = 1; i < col_count-1; i++) {
headers[i] = { sorter: 'digit' };
}
headers[col_count-1] = { sorter: 'percent' };
// Enable the table sorter:
$("table.index").tablesorter({
widgets: ['persistentSort'],
headers: headers
});
coverage.assign_shortkeys();
// Watch for page unload events so we can save the final sort settings:
$(window).unload(function() {
document.cookie = cookie_name + "=" + sort_list.toString() + "; path=/";
});
};
// -- pyfile stuff --
coverage.pyfile_ready = function($) {
// If we're directed to a particular line number, highlight the line.
var frag = location.hash;
if (frag.length > 2 && frag[1] === 'n') {
$(frag).addClass('highlight');
coverage.sel_begin = parseInt(frag.substr(2));
coverage.sel_end = coverage.sel_begin + 1;
}
$(document)
.bind('keydown', 'j', coverage.to_next_chunk)
.bind('keydown', 'k', coverage.to_prev_chunk)
.bind('keydown', '0', coverage.to_top)
.bind('keydown', '1', coverage.to_first_chunk)
;
coverage.assign_shortkeys();
};
coverage.toggle_lines = function(btn, cls) {
btn = $(btn);
var hide = "hide_"+cls;
if (btn.hasClass(hide)) {
$("#source ."+cls).removeClass(hide);
btn.removeClass(hide);
}
else {
$("#source ."+cls).addClass(hide);
btn.addClass(hide);
}
};
// The first line selected, and the next line not selected.
coverage.sel_begin = 0;
coverage.sel_end = 1;
coverage.to_top = function() {
coverage.sel_begin = 0;
coverage.sel_end = 1;
$("html").animate({scrollTop: 0}, 200);
};
coverage.to_first_chunk = function() {
coverage.sel_begin = 0;
coverage.sel_end = 1;
coverage.to_next_chunk();
};
coverage.to_next_chunk = function() {
var c = coverage;
// Find the start of the next colored chunk.
var probe = c.sel_end;
while (true) {
var probe_line = $("#t" + probe);
if (probe_line.length === 0) {
return;
}
var color = probe_line.css("background-color");
if (color !== "transparent") {
break;
}
probe += 1;
}
// There's a next chunk, `probe` points to it.
c.sel_begin = probe;
// Find the end of this chunk.
var next_color = color;
while (next_color === color) {
probe += 1;
next_color = $("#t" + probe).css("background-color");
}
c.sel_end = probe;
coverage.show_selected_chunk();
};
coverage.to_prev_chunk = function() {
var c = coverage;
// Find the end of the prev colored chunk.
var probe = c.sel_begin-1;
var color = $("#t" + probe).css("background-color");
while (probe > 0 && color === "transparent") {
probe -= 1;
var probe_line = $("#t" + probe);
if (probe_line.length === 0) {
return;
}
color = probe_line.css("background-color");
}
// There's a prev chunk, `probe` points to its last line.
c.sel_end = probe+1;
// Find the beginning of this chunk.
var prev_color = color;
while (prev_color === color) {
probe -= 1;
prev_color = $("#t" + probe).css("background-color");
}
c.sel_begin = probe+1;
coverage.show_selected_chunk();
};
coverage.show_selected_chunk = function() {
var c = coverage;
// Highlight the lines in the chunk
$(".linenos p").removeClass("highlight");
var probe = c.sel_begin;
while (probe > 0 && probe < c.sel_end) {
$("#n" + probe).addClass("highlight");
probe += 1;
}
// Scroll the page if the chunk isn't fully visible.
var top = $("#t" + c.sel_begin);
var next = $("#t" + c.sel_end);
if (!top.isOnScreen() || !next.isOnScreen()) {
// Need to move the page.
var top_pos = parseInt(top.offset().top);
$("html").animate({scrollTop: top_pos-30}, 300);
}
};